Serwer MySQL zniknął, utrudniając import dużych zrzutów

14

Próbuję zaimportować duży zrzut sql (2 GB) do mojego lokalnego mysql na komputerze Mac. Byłem w stanie to zrobić w przeszłości (korzystałem z MAMP), ale teraz dostaję ERROR 2006 (HY000) w linii 7758: Serwer MySQL znika za każdym razem, gdy próbuję zaimportować zrzut. Baza danych zawiera tabele innodb.

Próbowałem skopiować plik my-innodb-heavy-4G.cnf do mojego my.cnf, aby sprawdzić, czy te ustawienia by pomogły, ale bez powodzenia.

Wszelkie pomysły na to, co poprawić?

Używam „Mac OS X wer. 10.6 (x86, 64-bit), Archiwum DMG” stąd: http://dev.mysql.com/downloads/mysql/

naxoc
źródło

Odpowiedzi:

15

Jednym z cichych zabójców połączeń MySQL jest pakiet MySQL. Nawet wątek we / wy replikacji MySQL może być ofiarą tego.

Według dokumentacji MySQL

  • Te błędy można również uzyskać, wysyłając zapytanie do serwera, które jest niepoprawne lub zbyt duże. Jeśli mysqld otrzyma pakiet, który jest zbyt duży lub nie działa, zakłada, że ​​coś poszło nie tak z klientem i zamyka połączenie. Jeśli potrzebujesz dużych zapytań (na przykład, jeśli pracujesz z dużymi kolumnami BLOB), możesz zwiększyć limit zapytań, ustawiając zmienną max_allowed_packet serwera, która ma domyślną wartość 1 MB. Konieczne może być również zwiększenie maksymalnego rozmiaru pakietu po stronie klienta. Więcej informacji na temat ustawiania rozmiaru pakietu znajduje się w rozdziale C.5.2.10, „Pakiet za duży”.

  • Instrukcja INSERT lub REPLACE, która wstawia wiele wierszy, może również powodować tego rodzaju błędy. Każda z tych instrukcji wysyła pojedyncze żądanie do serwera, niezależnie od liczby wstawianych wierszy; w ten sposób często można uniknąć błędu, zmniejszając liczbę wierszy wysłanych na WSTAW lub WYMIANA.

Przynajmniej musisz upewnić się, że rozmiary pakietów zarówno dla maszyny, z której wykonałeś mysqldump, jak i dla maszyny, którą ładujesz, są identyczne.

Mogą istnieć dwa (2) podejścia:

PODEJŚCIE 1: Wykonaj mysqldump za pomocą --skip-Extended-Insert

Dzięki temu pakiet MySQL nie będzie zalewany wieloma polami BLOB, polami TEXT. W ten sposób WSTAWKI SQL są wykonywane pojedynczo. Główne wady to

  1. mysqldump jest znacznie większy
  2. przeładowanie takiego zrzutu zajmuje znacznie więcej czasu.

PODEJŚCIE 2: Zwiększyć max_allowed_packet

Może to być preferowane podejście, ponieważ implementacja tego jest po prostu restartem mysql. Zrozumienie, czym jest pakiet MySQL, może to wyjaśnić.

Zgodnie ze stroną 99 „Understanding MySQL Internals” (ISBN 0-596-00957-7) poniżej wyjaśniono w paragrafach 1-3:

Kod komunikacji sieciowej MySQL został napisany przy założeniu, że zapytania są zawsze rozsądnie krótkie, a zatem mogą być wysyłane i przetwarzane przez serwer w jednym kawałku, co w terminologii MySQL nazywa się pakietem . Serwer przydziela pamięć na tymczasowy bufor do przechowywania pakietu i żąda wystarczającej ilości, aby go całkowicie dopasować. Ta architektura wymaga środków ostrożności, aby uniknąć wyczerpania pamięci serwera --- ograniczenie rozmiaru pakietu, co osiąga ta opcja.

Kod zainteresowania związany z tą opcją znajduje się w sql / net_serv.cc . Spójrz na my_net_read () , a następnie postępuj zgodnie z wywołaniem my_real_read () i zwróć szczególną uwagę na net_realloc () .

Ta zmienna ogranicza również długość wyniku wielu funkcji strunowych. Szczegółowe informacje można znaleźć w sql / field.cc i sql / intem_strfunc.cc .

Biorąc pod uwagę to wytłumaczenie, dokonywanie masowych WSTAWEK spowoduje dość szybkie ładowanie / rozładowywanie pakietu MySQL. Jest to szczególnie prawdziwe, gdy pakiet max_allowed_packet jest zbyt mały, aby mógł nadejść dany ładunek danych.

WNIOSEK

W większości instalacji MySQL zwykle ustawiam to na 256M lub 512M. Powinieneś eksperymentować z większymi wartościami, gdy ładowanie danych powoduje błędy „MySQL odszedł”.

RolandoMySQLDBA
źródło
Próbowałem ustawić się max_allowed_packetna 900M i --skip-extended-insertużywałem (i masz rację - to sprawia, że ​​huuuge db-dumps), ale nadal nie działa. Podejrzewam teraz konkretną linię na zrzucie, którą prawdopodobnie mogę obejść. Ale to wciąż dziwne - zrzut można zaimportować w porządku na moim serwerze CentOS.
naxoc
W końcu usunąłem wstawkę z zrzutu SQL, która była bardzo, bardzo długą linią. To naprawiło (i linia nie była potrzebna).
naxoc
BTW, upewnij się, że domyślny znak zrzutu danych może być obsługiwany w systemie operacyjnym MacOSX i MySQL.
RolandoMySQLDBA
@naxov - Jestem ciekawy jednej linii, którą podejrzewasz na wysypisku. Czy są zaangażowane jakieś pola TEKST lub BLOB?
RolandoMySQLDBA
Tak, bardzo długie pole tekstowe.
naxoc
2

Jak długo to trwa, zanim upłynie limit czasu? Pierwszym krokiem byłoby sprawdzenie wait_timeouti interactive_timeoutustawienia, aby upewnić się, że są wystarczająco duże do importu:

SHOW VARIABLES LIKE '%_timeout';
SET SESSION wait_timeout=28800;

Domyślnie jest to 8 godzin (28800), więc potencjalnie nie jest to problem. Inne wskazówki dotyczące tego problemu można znaleźć tutaj . Jednym z nich jest:

Aplikacja kliencka działająca na innym hoście nie ma niezbędnych uprawnień do łączenia się z serwerem MySQL z tego hosta.

Najpierw sprawdź uprawnienia, a następnie przejrzyj listę potencjalnych problemów.

Derek Downey
źródło
Wszystko jest na localhost, więc albo nie rozumiem, co masz na myśli, albo to nie jest problem. Czy chodziło Ci o uprawnienia jak w uprawnieniach w mysql?
naxoc
2

Tak, zazwyczaj granie z pakietami wait_timeout i max_allowed_packets pozwala mi obejść komunikat o błędzie.

p4guru
źródło
To nie działało dla mnie. Musiałem edytować sql w pliku zrzutu i usunąć bardzo długą linię, która była przyczyną problemu.
naxoc
nie należy bawić się parametrami, których nie rozumie
Jeredepp
2

Może nie jest to „poprawne” działanie, ale może działać (załatwione, prawda?):

Spróbuj podzielić duży zrzut na wiele plików i uruchamiać je pojedynczo po kolei. Moje podejście polegałoby na rozbiciu go na pół i przetestowaniu. Następnie rozbij każdą połówkę na pół, ponownie przetestuj i tak dalej.

Jestem nieco ciekawy, czy ilość pamięci RAM na twoim pudełku może mieć z tym coś wspólnego. Czy MySQL ładuje cały zrzut do pamięci, kiedy chce go uruchomić? Nie wiem ... ale jeśli masz tylko 2 GB pamięci RAM, a część z nich jest używana w systemie operacyjnym i innych aplikacjach, może to być problem.

Dzień Davis Waterbury
źródło
2

Ci, którzy nie odnieśli sukcesu w przypadku innych sugestii, mogą rozważyć przyjrzenie się skryptowi importującemu zrzut MySQL w BigDump PHP .

Jest to obejście dla importowania dużych zrzutów bazy danych do MySQL. Z powodzeniem wykorzystałem go do zaimportowania dużego zrzutu MySQL do mojego lokalnego środowiska programistycznego (w tym przypadku używam MAMP).

Marcus Barnes
źródło