Znalazłem wiele witryn mówiących o tym, ale brakuje mi kilku ważnych szczegółów. Ogólne kroki są
- Biegać
FLUSH TABLES WITH READ LOCK
- Zrób migawkę ZFS
- Biegać
UNLOCK TABLES
Różne źródła podają, że InnoDB, którego używam, tak naprawdę nie honoruje FLUSH
. Podręcznik użytkownika MySQL zauważa, że istnieje FLUSH TABLES...FOR EXPORT
wariant do użycia z InnoDB, ale wymaga on indywidualnego określenia każdej tabeli, zamiast tworzenia kopii zapasowej całej bazy danych. Wolałbym unikać określania każdej tabeli indywidualnie, ponieważ istnieje spora szansa, że lista tabel nie będzie zsynchronizowana z tabelami, które faktycznie istnieją.
Innym problemem, jaki mam, jest to, że planuję zrobić coś takiego mysql -h"$HOST" -u"$USERNAME" -p"$PASSWORD" --execute="FLUSH TABLES WITH READ LOCK"
. Spowoduje to jednak opuszczenie blokady natychmiast po zakończeniu sesji. Ma to sens, ale jest również dość irytujące, ponieważ muszę trzymać blokadę odczytu, gdy wykonuję migawkę.
Moim drugim pomysłem jest zrobienie kopii zapasowej na gorąco za pomocą narzędzia takiego jak Percona XtraBackup i zrobienie migawek kopii zapasowej, ale wolałbym nie ponosić kosztów zapisania wszystkich moich danych w drugiej lokalizacji, aby je wykonać.
Odpowiedzi:
Jeśli używasz InnoDB tylko dla wszystkich tabel i ustaw
innodb_flush_log_at_trx_commit
na:1
(zawartość bufora dziennika InnoDB jest zapisywana do pliku dziennika przy każdym zatwierdzeniu transakcji, a plik dziennika jest opróżniany na dysk) lub,2
(zawartość bufora dziennika InnoDB jest zapisywana do pliku dziennika po każdym zatwierdzeniu transakcji, a plik dziennika jest opróżniany na dysk około raz na sekundę),wtedy nie potrzebujesz FLUSH TABLES przed zrobieniem migawki, po prostu uruchom migawkę ZFS bezpośrednio. InnoDB może odzyskiwać dane z dzienników zatwierdzania transakcji bez utraty danych.
Ref: https://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar_innodb_flush_log_at_trx_commit
źródło
Potrzebujesz pełnej blokady bazy danych, aby konsekwentnie tworzyć kopie zapasowe (większości) baz danych.
Podręcznik https://dev.mysql.com/doc/refman/5.5/en/backup-methods.html mówi, że TABLICE PŁUKUJĄCE Z BLOKADĄ CZYTANIA są właściwe dla migawek ZFS.
To niby śmieszne , że pominięty fakt, że trzeba
FLUSH TABLES table_a, table_b, table_c FOR EXPORT
dla InnoDB z tymi instrukcjami. Głupio jest też wymieniać takie tabele. Ale, jak mówi EEAA, możesz dość łatwo wygenerować listę tabel, gdy zaczniesz tworzenie kopii zapasowej.Jeśli chodzi o trzymanie blokady, musisz zachować aktywne połączenie db podczas wykonywania migawki
Zasadniczo użyłbym czegoś takiego jak Perl lub inny język programowania, który może łączyć, blokować db i utrzymując połączenie db wziąć migawkę, a następnie odblokować i rozłączyć. To nie jest skomplikowane. Założę się, że istnieją narzędzia, które już to robią, ale napisanie jednego jest łatwe.
Mówię kilka razy łatwo, nie skomplikowane itp. Zakładam, że masz jakieś podstawowe umiejętności programowania lub pisania skryptów.
źródło
FLUSH TABLES WITH READ LOCK
i drugieFLUSH TABLES...FOR EXPORT
, podczas gdy moje czytanie podręcznika MySQL mówi, że tylko jedna powinna być potrzebna.Zerwałem i dostosowałem koncepcyjnie prosty skrypt w Bash, który znalazłem w innym poście o błędzie serwera autorstwa Tobii . To powinno zapewnić ci około 90% drogi.
Tutaj używane
mysql
polecenie jest uruchamiane w tle i dotyka pliku. Czeka w tle, aż plik zniknie, przed wyjściem i odblokowaniem tabel. Tymczasem główny skrypt czeka na istnienie pliku, a następnie tworzy migawkę i usuwa plik.Plik wskazany przez
$mysql_locked
musi być dostępny dla obu komputerów, co powinieneś być w stanie zrobić wystarczająco łatwo, ponieważ oba mogą uzyskać dostęp do wspólnego zestawu danych (chociaż mogą one używać różnych ścieżek, i powinieneś to uwzględnić).źródło
system zfs snapshot...
tego w głównym skrypcie? A może migawki muszą przebiegać w osobnym procesie?SYSTEM
Polecenie uruchamia rzeczy lokalnie. Jeśli uruchomię klienta mysql na polu FreeBSD i wykonamLOCK; SYSTEM zfs snapshot; UNLOCK
, wydaje się, że to zadziała.Do myisam potrzebujesz FLUSH TABLES WITH READ LOCK, ponieważ nie jest to kronikowanie.
Naprawdę nie potrzebujesz niczego dla innodb, IMO, ponieważ jest to księgowanie. I tak będzie spójny, po prostu automatycznie cofa dziennik, jeśli coś dzieje się w momencie, gdy migawka jest atomowa.
Jeśli chcesz mieć spójność na poziomie aplikacji, powinna ona wykorzystywać transakcje. Jeśli twoja aplikacja korzysta z transakcji i innodb, każda migawka będzie spójna, pytaj automatycznie o poziom aplikacji.
źródło
Oto moje rozwiązanie, jak utworzyć migawkę ZFS przy zachowaniu blokady:
źródło