Jaki pakiet max_allowed_package jest wystarczająco duży i dlaczego muszę go zmieniać?

14

Mam MySQL (5.5) w konfiguracji master-slave i stworzyłem inny serwer slave.

Zatrzymałem pierwotnego niewolnika, zrzuciłem dane, skopiowałem i ponownie zaimportowałem i działało dobrze. Zauważyłem pozycję master_log oryginalnego slave i użyłem tych poleceń, aby ustawić go na nowym slave

CHANGE MASTER TO MASTER_HOST='<ipaddress>', 
MASTER_USER='<username>', MASTER_PASSWORD='<password>', 
MASTER_PORT=3306, MASTER_LOG_FILE='mysql-bin.000851', 
MASTER_LOG_POS=15824150, 
MASTER_CONNECT_RETRY=10;

Kiedy założyłem nowego niewolnika, dostałem

Last_IO_Error: Wystąpił błąd krytyczny 1236 z urządzenia master podczas odczytu danych z dziennika binarnego: „wpis zdarzenia dziennika przekroczył max_allowed_packet; Zwiększ max_allowed_packet na master '

Jednak kiedy założyłem pierwotnego niewolnika, wszystko wróciło do normy i jest teraz zsynchronizowane.

Więc pytania:

  • aktualna wartość to 16 mln, skąd mam wiedzieć, jak duży iść? (Wolałbym raczej unikać prób i błędów z serwerem produkcyjnym).

  • dlaczego muszę zwiększać wartość nadrzędną, skoro oryginalny slave radził sobie dobrze, czy problem może być naprawdę związany z nowym slave?

aktualizacja

Zwiększyłem pakiet max_allowed_packet do 1073741824, jak Rolando zasugerował dla mistrza, starego niewolnika i nowego niewolnika, i zrestartowałem je ( SET GLOBAL max_allowed_packet = 1073741824;z jakiegoś powodu wydawało się, że nie biorą)

teraz ostatni błąd we / wy jest taki sam jak poprzednio, ale teraz widzę

Last_SQL_Error: Błąd odczytu dziennika przekazywania: Nie można przeanalizować pozycji zdarzenia dziennika przekazywania. Możliwe przyczyny to: dziennik binarny urządzenia nadrzędnego jest uszkodzony (można to sprawdzić, uruchamiając dziennik mysqlbinlog w dzienniku binarnym), dziennik przekaźnika urządzenia podrzędnego jest uszkodzony (można to sprawdzić, uruchamiając dziennik mysqlbinlog w dzienniku przekazywania), problem z siecią lub błąd w kodzie MySQL master lub slave. Jeśli chcesz sprawdzić dziennik binarny urządzenia nadrzędnego lub dziennik przekaźników urządzenia podrzędnego, będziesz mógł poznać ich nazwy, wydając „STATUS POKAŻ SLAVE” na tym urządzeniu podrzędnym.

Jeśli zrobię mysqlbinlog na pliku master, przewija on przeszłość z poleceniami całkiem szczęśliwie przez wieki - plik ma rozmiar 722M - jeśli zrobię to dla dziennika przekaźników slave, otrzymam

BŁĄD: Błąd w Log_event :: read_log_event (): „Sprawdzanie poprawności nie powiodło się”, data_len: 38916267, typ zdarzenia: 69

BŁĄD: Nie można odczytać wpisu z przesunięciem 253: Błąd w formacie dziennika lub błąd odczytu.

Sprawdziłem zmienne i zmiany zadziałały

mysql> pokaż zmienne LIKE '% max_allowed_packet%';

na nowym niewolniku pokazał max_allowed_packetORAZ slave_max_allowed_packetgdzie, jak u mistrza, ma tylkomax_allowed_packet

więc sprawdziłem wersję na masterie:

mysql> show variables LIKE '%version%';
+-------------------------+--------------------------------------+
| Variable_name           | Value                                |
+-------------------------+--------------------------------------+
| innodb_version          | 1.1.6                                |
| protocol_version        | 10                                   |
| slave_type_conversions  |                                      |
| version                 | 5.5.11-log                           |
| version_comment         | MySQL Community Server (GPL) by Remi |
| version_compile_machine | x86_64                               |
| version_compile_os      | Linux                                |
+-------------------------+--------------------------------------+

i na nowym niewolniku

mysql> show variables LIKE '%version%';
+-------------------------+--------------------------------------+
| Variable_name           | Value                                |
+-------------------------+--------------------------------------+
| innodb_version          | 5.5.32                               |
| protocol_version        | 10                                   |
| slave_type_conversions  |                                      |
| version                 | 5.5.32-log                           |
| version_comment         | MySQL Community Server (GPL) by Remi |
| version_compile_machine | x86_64                               |
| version_compile_os      | Linux                                |
+-------------------------+--------------------------------------+

Czy te 2 wersje są zbyt daleko od siebie?

CodeMonkey
źródło
Jest rzeczą interesującą niektórzy tutaj . Mam nadzieję, że to byłoby pomocne.
Sathish D

Odpowiedzi:

18

Można maksymalnie max_allowed_packetzwiększyć do 1G. Za każdym razem, gdy tworzony jest pakiet MySQL, od samego początku nie przeskakuje do 1G. Dlaczego?

Najpierw musisz wiedzieć, co to jest pakiet MySQL. Strona 99 książki

Zrozumienie wewnętrznych elementów MySQL

wyjaśnia to w ust. 1-3 w następujący sposób:

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 .

Porównaj to z Dokumentacją MySQL na max_allowed_packet:

Maksymalny rozmiar jednego pakietu lub dowolnego wygenerowanego / pośredniego łańcucha lub dowolnego parametru wysłanego przez funkcję API mysql_stmt_send_long_data () C. Wartość domyślna to 4 MB według MySQL 5.6.6, wcześniej 1 MB.

Bufor komunikatów pakietowych jest inicjowany w bajtach długość_pakietu, ale w razie potrzeby może wzrosnąć do maksymalnie bajtów_pakietów. Ta wartość jest domyślnie mała, aby złapać duże (być może niepoprawne) pakiety.

Musisz zwiększyć tę wartość, jeśli używasz dużych kolumn BLOB lub długich łańcuchów. Powinien być tak duży, jak największy BLOB, którego chcesz użyć. Limit protokołu dla pakietu max_allowed_packet wynosi 1 GB. Wartość powinna być wielokrotnością 1024; niepodzielne są zaokrąglane w dół do najbliższej wielokrotności.

Gdy zmieniasz rozmiar bufora komunikatów poprzez zmianę wartości zmiennej max_allowed_packet, powinieneś również zmienić rozmiar bufora po stronie klienta, jeśli twój program kliencki na to pozwala. Po stronie klienta max_allowed_packet ma domyślnie 1 GB. Niektóre programy, takie jak mysql i mysqldump, umożliwiają zmianę wartości po stronie klienta przez ustawienie max_allowed_packet w wierszu polecenia lub w pliku opcji.

Biorąc pod uwagę te informacje, powinieneś się cieszyć, że MySQL w razie potrzeby rozszerzy i zawrze pakiet MySQL. Dlatego śmiało i

Master i Slave powinny się zgadzać pod względem tego, kogo przesyłają dane, zwłaszcza dane BLOB.

AKTUALIZACJA 2013-07-04 07:03 EDT

Z wiadomości dotyczących dziennika przekazywania wynika, że ​​masz następujące elementy

  • uszkodzony dziennik przekazywania
  • dobry dziennik główny

SUGESTIA

SHOW SLAVE STATUS\G
STOP SLAVE;
CHANGE MASTER TO
MASTER_LOG_FILE='(Relay_Master_Log_File from SHOW SLAVE STATUS\G)',
MASTER_LOG_POS=(Exec_Master_Log_Pos from SHOW SLAVE STATUS\G);
START SLAVE;

Uruchomienie CHANGE MASTER TOusuwa wszystkie dzienniki przekazywania i rozpoczyna się od nowego. Będziesz się replikować z ostatniego głównego zdarzenia BinLog (BinLog, Position), które zostało wykonane w Slave.

Spróbuj !!!

RolandoMySQLDBA
źródło
dzięki, to świetnie, że jest bezpieczny; ale wciąż nie rozumiem, dlaczego muszę go w ogóle zmieniać, gdy bieżąca wartość odpowiada masterowi i drugiemu, który działa doskonale?
CodeMonkey,
coś innego się dzieje, dodałem więcej szczegółów
CodeMonkey
1
Tylko dla twojej informacji: zdarzyło mi się to, kiedy zresetowałem proces replikacji i przypadkowo wpisałem niewłaściwą MASTER_LOG_FILEnazwę. Np używany mysql-bin.000001kiedy należy Użyłem mysql-bin.000003od SHOW MASTER STATUSw CHANGE MASTER TO.
Mikko Ohtamaa
8

Problemem było raczej zawstydzające, że niepoprawne nazwy plików dla dzienników powodowały dziwne wyniki, zostały ponownie zaimportowane z poprawnymi nazwami plików i wszystko było w porządku, zawstydza się ze wstydu

CodeMonkey
źródło
Wielkie dzięki! Nie tylko ty popełniłeś ten błąd.
Mikko Ohtamaa
3
Zawsze warto opublikować odpowiedź, nawet jeśli jest głupia. Wszyscy popełniamy głupie błędy, ponieważ wszyscy jesteśmy ludźmi. Oprócz tych z nas, które są robotami.
John Hunt