Jaki jest najbezpieczniejszy sposób zmiany formatu binlog w czasie wykonywania?

25

Z powodu następującego ostrzeżenia w mysqld.log:

[Ostrzeżenie] Niebezpieczna instrukcja zapisana w dzienniku binarnym przy użyciu formatu instrukcji, ponieważ BINLOG_FORMAT = STATEMENT. Instrukcja jest niebezpieczna, ponieważ używa klauzuli LIMIT. Jest to niebezpieczne, ponieważ nie można przewidzieć zestawu zawartych wierszy.

Chcę zmienić format replikacji na MIXED.

Ale zgodnie z dokumentem MySQL:

Przełączanie formatu replikacji w czasie wykonywania nie jest zalecane, jeśli istnieją tabele tymczasowe, ponieważ tabele tymczasowe są rejestrowane tylko w przypadku replikacji opartej na instrukcjach, natomiast w przypadku replikacji wierszowej nie są rejestrowane.

Pytanie brzmi: w jaki sposób mogę stwierdzić, czy istnieją tabele tymczasowe umożliwiające bezpieczne przełączanie formatu dziennika binarnego?

kwanty
źródło
1
Szybkie ostrzeżenie. Uważaj na to, przechodząc z RBR-> SBR i wykorzystując polecenie odczytu: bugs.mysql.com/bug.php?id=62493
Morgan Tocker

Odpowiedzi:

35

Ponieważ binlog będzie miał określony format w chwili, gdy to zrobisz, możesz zdecydować się nie grać razem z tymi dwoma formatami, chociaż MySQL (eh Oracle [wciąż nie może zrzucić mojego języka]) zbudował tę funkcję.

Aby zagrać całkowicie bezpiecznie bez ponownego uruchomienia mysql, spróbuj wykonać następujące czynności:

FLUSH TABLES WITH READ LOCK;
FLUSH LOGS;
SET GLOBAL binlog_format = 'MIXED';
FLUSH LOGS;
UNLOCK TABLES;

Spowoduje to pozostawienie ostatniego binlogu w formacie „MIXED”. Przedostatni (obok ostatniego) binlog istnieje po prostu przynosząc zamknięcie ostatniego binlogu, który był w poprzednim formacie.

Wszystkie istniejące sesje przed pierwszą FLUSH LOGS;zaczną zapisywać w ostatnim binlogu po UNLOCK TABLES;wykonaniu.

Spróbuj !!!

CAVEAT

Przyznawanie kredytu w miejscu, w którym należy się kredyt, moja odpowiedź naprawdę polega na udzieleniu odpowiedzi @ Jonathan . Poza tym po prostu zamykam i otwieram binlogi. Otrzymuje +1 za wydobycie tego jako pierwszego.

AKTUALIZACJA 2011-10-12 13:58 EDT

Jeśli robisz to aktywnemu Mistrzowi i istnieje co najmniej jeden Slave replikujący się z tego Mistrza, musisz się martwić, że dzienniki przekaźników mają również nowy format. Oto, co możesz zrobić:

Uruchom Slave STOP SLAVE;

W trybie głównym uruchom następujące:

FLUSH TABLES WITH READ LOCK;
FLUSH LOGS;
SET GLOBAL binlog_format = 'MIXED';
FLUSH LOGS;
UNLOCK TABLES;

Uruchom Slave START SLAVE;

Uruchamianie STOP SLAVE;i START SLAVE;obracanie dzienników przekazywania powoduje, że nowe wpisy są replikowane w dowolnym formacie. Możesz także zastosować zmianę binlog_format w Slave.

RolandoMySQLDBA
źródło
3
Należy pamiętać, że ustawienia replikacji mysql są tak naprawdę ustawiane dla poszczególnych sesji klienta. Ustawienie globalnego formatu binlog_ zmienia jedynie wartość NOWYCH sesji. Dlatego jeśli uruchamiasz go w systemie z klientami trwale połączonymi, wszelkie zmiany wprowadzone w ustawieniach nie będą natychmiast stosowane, nawet jeśli wykonasz opróżnianie i blokowanie zgodnie z opisem tutaj - nie będą obowiązywać, dopóki klienci nie zostaną zastosowani połącz ponownie (lub ustaw wartość we własnej sesji, ale z mojego doświadczenia wynika, że ​​ta pierwsza jest bardziej prawdopodobna).
Austin Mills
Dla ciekawskich możesz także umieścić to „binlog_format = 'MIXED';” do twojego my.cnf.
Christian
2
Do Twojej wiadomości, ta odpowiedź nie jest zgodna z odpowiedzią tutaj: dba.stackexchange.com/questions/58539/…
HTTP500
Stany ręczne : Oznacza to, że zmiana formatu rejestrowania w replikacji wzorcowej nie powoduje, że slave zmienia format rejestrowania, aby pasował. (..snip ..) Zmiana formatu rejestrowania binarnego w systemie nadrzędnym podczas replikacji w toku lub bez zmiany go w urządzeniu podrzędnym może w ten sposób spowodować nieoczekiwane wyniki, a nawet spowodować całkowitą awarię replikacji.
Halfgaar
@Halfgaar W zeszłym tygodniu trzy razy zmieniłem niewolnika z MIESZANEGO na OŚWIADCZENIE, bez żadnych złych efektów. Robiłem to, ponieważ replikacja pękała z powodu warunków wyścigu. Tabela przestała istnieć na slave przed wykonaniem zapytania. Więc przełączyłem się na STATEMENT na stabilny jak ta sytuacja. Oczywiście wszystkie zapisy zostały zatrzymane, gdy to zrobiłem. BTW też zrobiłem Master.
RolandoMySQLDBA
6

Aby zmienić binlog_format w czasie wykonywania, możesz:

set global binlog_format = 'MIXED';

Spowoduje to ustawienie wszystkich NOWYCH sesji na mieszany format binlog. Wszystkie istniejące sesje będą miały wszystko, co zostało ustawione wcześniej, aż do ich zakończenia.

Możesz także zrobić to set session binlog_format = 'MIXED';ręcznie, aby rozwiązać problemy z konkretną sesją.

Jonathan
źródło
Nie pytam o sposób, pytam o najbezpieczniejszy sposób i jak mogę sprawdzić, czy istnieją jakieś tabele tymczasowe.
kwanty
3
Najbezpieczniejszym sposobem jest ustawienie zmiennej globalnej jako pierwszej i oczekiwanie na zakończenie pozostałych sesji.
Jonathan