Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP][MYSQL] Migracja, przenoszenie dużej bazy danych (o. 100MB)
Forum PHP.pl > Forum > Bazy danych > MySQL
Shinu
Witam,
muszę dokonać migracji: stary niewydajny skrypt forum -> nowy wydajny skrypt forum. Baza ma około 100MB.
Struktura skryptów jest nieco inna, muszę więc przetwarzać dane z pierwszego skryptu, aby je móc wrzucić do drugiego.
I tu mam mały problem, przy próbie parsowania i importu prawie 200k postów "MySQL server has gone away"...

To co udało mi się wykombinować to:
- select w pętli po 5000 rekordów
- jeden insert dodający na raz te 5k rekordów

LOW_PRIORITY nic nie dało,
sleep(5) - prawie nic nie dało (po padzie serwera, daję mysql_close(); sleep(5); ponownie łączę i ponawiam inserta

Pytanie, jak to zrobić by serwer nie umierał?

Skrypt działa w PHP5, baza to MYSQL5

Co ciekawe na początku udaje się dodać kilkadziesiąt tysięcy rekordów (kilka obrotów pętli po 5k), później serwer zdycha już po 5k...

Nie wiem, co jeszcze mogę napisać, co by pomogło w wyjaśnieniu mojego problemu.

Sama pętla mająca za zadanie sparsować i przenieść 200k postów:
Kod
for($ll = 1; $ll <= 39; ++$ll) { // 39*5000 = 195k (to nieco wiecej niz wszystkich postow w bazie)
    $query = 'SELECT f.id, u.uzytkownik, f.id_usera, f.ip, u.email, f.tresc, f.data, f.data_modyfikacji, f.zmodyfikowal, id_watku FROM `forum` f LEFT JOIN `userzy` u ON u.id = f.id_usera ORDER BY f.id ASC';
    $query .= ' LIMIT '. (($ll-1)*5000) . ',' . 5000;

    $resa = mysql_query($query,$ansi);
    if(!$resa) {
        echo '<br>ll= ',$ll,' ansi padło= ', mysql_error($ansi) ,'<br>q= ',$query;

        mysql_close($ansi);
        // wskrzeszamy ANSI
        $host = 'x';
        $db = 'x';
        $user = 'x';
        $pass = 'x';

        $ansi = mysql_connect($host, $user, $pass);
        if($ansi) { echo '<br>Połączenie z ansi...<br>'; }
        else { echo 'nie wskrzeszono :/'; exit(); }
        mysql_select_db($db,$ansi);
        mysql_query("SET NAMES 'latin2'",$ansi);

        $resa = mysql_query($query,$ansi);
        if(!$resa) {
            echo '<br>ll= ',$ll,' ansi padło po wskrzeszeniu :/= ', mysql_error($ansi) ,'<br>q= ',$query;
            break;
        }
    }

    $symbol = array('~','#','@');
    $encje = array('"','>','<','–','“','”','„', '‘', '’','…','[cytuj=~','[cytuj=#','[cytuj=@','[/cytuj]');
    $znaki = array('"',     '>',   '<',   '-',      '"',      '"',      '"',       '\'',      '\'',     '...',    '[quote=', '[quote=', '[quote=', '[/quote]');
    $ii=0;
    $adds=0;
    $query = null;
    while($row = mysql_fetch_assoc($resa)) {

        // konwertujemy i wywalamy encje
        $row['tresc'] = str_replace($encje,$znaki,iconv("latin2", "UTF-8",$row['tresc']));
        // przerabiamy łącza do postów
        $row['tresc'] = preg_replace('|(watek\.php\?WT)=(\d+)#(\d+)([^]]*)]|i','viewtopic.php?pid=$3#$3]',$row['tresc']);
        // przerabiamy łącza do tematów
        $row['tresc'] = preg_replace('|(watek\.php\?WT)=(\d+)([^]]*)]|i','viewtopic.php?id=$2]',$row['tresc']);

        if(!$ii) {
            $query = "INSERT INTO `fbb_posts` (`id`, `poster`, `poster_id`, `poster_ip`, `message`, `posted`, `edited`, `edited_by`, `topic_id`)
        VALUES ";
        }
        $query .=  "(
        '". $row['id'] ."',
        '". iconv("latin2", "UTF-8",$row['uzytkownik']) ."',
        '". ($row['id_usera']==1?'9':$row['id_usera']) ."',
        '". $row['ip'] ."',
        '". mysql_real_escape_string($row['tresc'],$flux) ."',
        '". strtotime($row['data']) ."',
        ". ( strtotime($row['data_modyfikacji'])==0?'NULL': "'".strtotime($row['data_modyfikacji'])."'" ) .",
        ". ( $row['zmodyfikowal']==''?'NULL': "'".str_replace($symbol,'',iconv("latin2", "UTF-8",$row['zmodyfikowal']))."'" ) .",
        '". $row['id_watku'] ."'),";

        ++ $ii;
    }
    mysql_free_result($resa);
    $adds=$adds+$ii;

    $query = rtrim($query, ',');

    if($ii>0) {
        $resf = mysql_query($query,$flux);
        if(!$resf) {
            echo '<br>ll= ',$ll,' flux zdechł e= ', mysql_error($flux) ,'<br>'; //q= <div style="width:100%; height:300px; overflow:scroll;">',$query,'</div>';

            mysql_close($ansi);
            sleep(5);

            // połączenie z FluxBB
            $host = 'x;
            $db = 'x';
            $user = 'x';
            $pass = 'x';

            $flux = mysql_connect($host, $user, $pass);
            if($flux) { echo 'Połączenie z flux...<br>'; }
            else { exit(); }
            mysql_select_db($db,$flux);
            mysql_query("SET NAMES 'utf8'",$flux);

            $resf = mysql_query($query,$flux);
            if(!$resf) {
                echo '<br>ll= ',$ll,' flux zdechł po wskrzeszeniu :/= ', mysql_error($flux) ,'<br>'; //q= <div style="width:100%; height:300px; overflow:scroll;">',$query,'</div>';
                break;
            }
        }
    }
}
suchy1
Cytat(Shinu @ 11.07.2008, 06:27:33 ) *
MySQL server has gone away


Kiedys mialem podobny problem, moze nie staraj sie polepszac kodu php tylko zajmij sie konfiguracją serwera mysql. W pliku mysql.ini zmień wartośc zmiennej "max_allowed_packet " i zapraszam na oficialna strone link
Shinu
Hmm... dokumentację MYSQL'a przeglądałem... tak czy siak tę bazę w końcu przepchnąłem "z łapy" (ręcznie inkrementowałem licznik pętli po każdym padzie tongue.gif i tak po kilkunastu razach przeszło wszytko).

A tak czy inaczej, da się jakoś 'zakolejkować' zapytania do bazy aby nie zdychała?
Przecież musi być jakiś sposób na przenoszenie takich baz danych.
yalus
oczywiscie ze jest inny sposob,
robisz kopie calej bazy (backup) do jednego pliku sql,
a pozniej robisz restore na serwerze na ktory chcesz przeniesc baze

moja baza sklada sie z 17 tabel i srednio w kazdej tabeli jest ok 100 tys. rekordow
caly proces migracj z jednego serwera na inny zajmuje mi ok 30-40min.

uzywam do tego narzedzi ze strony mysql - polecam
Shinu
Ale nie o to chodziło. Przenieść bazę z serwera na serwer to jak napisałeś nie problem.

Problem jest kiedy masz przenieść dane z jednej bazy do drugiej (o nieco innej strukturze i dodatkowo parsować kilkanaście kolumn przed wykonaniem inserta).
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.