Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Wolny czas startu MySQL w trybie GTID? Problemem może być rozmiar pliku dziennika binarnego

Czy masz wolne czasy uruchamiania MySQL w trybie GTID? Niedawno napotkaliśmy ten problem w jednym z naszych wdrożeń hostingu MySQL i postanowiliśmy go rozwiązać. Na tym blogu opisujemy problem, który może spowalniać czas ponownego uruchamiania MySQL, opisujemy, jak debugować wdrożenie i co możesz zrobić, aby skrócić czas rozpoczęcia i poprawić zrozumienie replikacji opartej na GTID.

Jak znaleźliśmy problem

Badaliśmy wolne czasy uruchamiania MySQL w niskonakładowym, dyskowym wdrożeniu MySQL 5.7.21 z włączonym trybem GTID. System był częścią pary master-slave i był pod umiarkowanym obciążeniem zapisu. Podczas ponownego uruchamiania podczas zaplanowanej konserwacji zauważyliśmy, że serwer bazy danych potrzebował 5-10 minut na uruchomienie i rozpoczęcie akceptowania połączeń. Tego rodzaju opóźnienie nie miało sensu, więc postanowiliśmy zbadać sprawę.

Debugowanie powolnego czasu rozpoczęcia MySQL

Użyliśmy popularnego narzędzia Percona pt-ioprofile, aby zobaczyć, co robi baza danych. pt-ioprofile to bardzo ważne narzędzie w popularnym zestawie narzędzi Percony, które służy do debugowania problemów z MySQL. Pełną listę funkcji można znaleźć w ich dokumentacji. pt-ioprofil narzędzie używa strace i lsof do obserwowania operacji we/wy procesu i drukowania tabeli plików i aktywności we/wy.

Zaczęliśmy więc MySQL, czekaliśmy na mysqld proces, aby się spawnować i rozpoczął pt-ioprofile aby zobaczyć, jaki może być problem:

# pt-ioprofile --profile-process mysqld --run-time 200
Tue Oct 9 15:42:24 UTC 2018
Tracing process ID 18677
total      pread       read     pwrite      write      fsync  fdatasync       open      close   getdents      lseek      fcntl filename
...
216.550641   0.000000  216.550565   0.000000   0.000000   0.000000   0.000000   0.000015   0.000040   0.000000   0.000021   0.000000 /mysql_data/binlogs/mysql-bin.000014
...

Co spowalnia ponowne uruchomienie MySQL?

Podczas wielokrotnego uruchamiania tego zaobserwowaliśmy, co następuje:

  • mysqld proces spędzał większość czasu na czytaniu najnowszego binarnego pliku dziennika. Miało to miejsce nawet wtedy, gdy serwer został zatrzymany z wdziękiem i nie było potrzeby odzyskiwania po awarii itp.
  • Serwer spędził również znaczną ilość czasu na ładowaniu plików danych InnoDB, ale ten czas był znacznie krótszy w porównaniu z czasem spędzonym na czytaniu najnowszego binarnego pliku dziennika.
  • Jeśli serwer zostałby zrestartowany od razu, ten kolejny restart byłby znacznie szybszy.
  • Ponieważ zamknięcie bazy danych opróżnia dziennik binarny i tworzy nowy podczas uruchamiania, przeprowadziliśmy dodatkowy eksperyment – ​​przed wyłączeniem serwera opróżniliśmy dzienniki binarne. Kolejne uruchomienie serwera było znowu szybkie.

Obserwacje te wyraźnie wskazywały na fakt, że MySQL spędzał dużo czasu na czytaniu najnowszego binarnego pliku dziennika. Jeśli plik był mały, tak jak w przypadku opróżniania pliku dziennika przed zamknięciem, uruchamianie przebiegało szybko.

Wolny czas startu MySQL w GTID? Problemem może być rozmiar pliku dziennika binarnegoKliknij, aby tweetować

Zrozumienie odzyskiwania identyfikatora GTID Binlog

Jak się okazuje, aby wypełnić wartościami gtid_executed i gtid_purged, serwer MySQL musi przeanalizować pliki dziennika binarnego.

Oto podsumowanie zaleceń dotyczących metody dokumentacji MySQL 5.7 na podstawie odczytu FAŁSZ lub PRAWDA:

Kiedy binlog_gtid_simple_recovery =FAŁSZ:

Aby obliczyć gtid_executed:

  • Iterowanie plików dziennika binarnego od najnowszych, zatrzymując się na pierwszym pliku, który ma Previous_gtids_log_event wpis.
  • Wykorzystaj wszystkie identyfikatory GTID z Previous_gtids_log_event i Gtid_log_events z tego binarnego pliku dziennika i zapisz ten zestaw GTID wewnętrznie. Nazywa się to gtids_in_binlog.
  • Wartość gtid_executed jest obliczana jako suma gtids_in_binlog i identyfikatory GTID w tabeli mysql.gtid_executed .

Ten proces może być bardzo czasochłonny, jeśli istnieje duża liczba plików dziennika binarnego bez identyfikatorów GTID, na przykład utworzonych w trybie gtid_mode =WYŁ.

Podobnie, aby obliczyć gtid_purged:

  • Iterowanie plików dziennika binarnego od najstarszego do najnowszego, zatrzymując się na pierwszym dzienniku binarnym, który zawiera niepuste Previous_gtids_log_event (ma co najmniej jeden GTID) lub ma co najmniej jedno Gtid_log_event .
  • Przeczytaj Previous_gtids_log_event z tego pliku. Oblicz zmienną wewnętrzną gtids_in_binlog_not_purge ponieważ ten zestaw GTID jest odejmowany od gtids_in_binlog.
  • Wartość gtid_purge jest ustawiony na gtid_executed , minus gtids_in_binlog_not_purged .

Tak więc stanowi to podstawę naszego zrozumienia, jak rzeczy działały w starszych wersjach. Jednak pewnych optymalizacji można dokonać, gdy binlog_gtid_simple_recovery jest prawdziwy. To jest przypadek, który nas interesuje:

Kiedy binlog_gtid_simple_recovery =PRAWDA:

(Uwaga, jest to ustawienie domyślne w MySQL 5.7.7 i nowszych)

  • Przeczytaj tylko najstarsze i najnowsze binarne pliki dziennika.
  • Oblicz gtid_purge z Previous_gtids_log_event lub Gtid_log_event znalezione w najstarszym binarnym pliku dziennika.
  • Oblicz gtid_executedPrevious_gtids_log_event lub Gtid_log_event znalezione w najnowszym binarnym pliku dziennika.
  • Tak więc tylko dwa binarne pliki dziennika są odczytywane podczas restartu serwera lub podczas czyszczenia dzienników binarnych.

Tak więc w przypadku MySQL w wersji 5.7.7 i nowszych najnowsze i stare pliki dziennika binarnego są zawsze odczytywane podczas uruchamiania systemu, aby poprawnie zainicjować zmienne systemowe GTID. Odczyt najstarszego pliku dziennika binarnego nie jest tak drogi, ponieważ zdarzenie, którego szuka MySQL, Previous_gtids_log_event, jest zawsze pierwszym zdarzeniem w pliku dziennika binarnego.

Jednak, aby poprawnie obliczyć gtid_executed , serwer musi odczytać cały najnowszy plik dziennika binarnego i zebrać wszystkie zdarzenia w tym pliku. Tak więc czas uruchamiania systemu staje się wprost proporcjonalny do rozmiaru najnowszego binarnego pliku dziennika .

Zauważ, że sytuacja jest jeszcze gorsza, gdy binlog_gtid_simple_recovery jest FAŁSZ . Ponieważ nie jest to już domyślna opcja w ostatnich wydaniach, nie stanowi to większego problemu.

Jak rozwiązać problem z powolnym czasem startu

Po zrozumieniu przyczyny problemu, na który się natknęliśmy, rozwiązanie, na które się zdecydowaliśmy, było dość oczywiste – zmniejsz rozmiar binarnych plików dziennika. Domyślny rozmiar plików dziennika binarnego to 1 GB. Przeanalizowanie pliku o tym rozmiarze podczas uruchamiania zajmuje trochę czasu, więc warto zmniejszyć wartość max_binlog_size do niższej wartości.

Jeśli zmniejszenie rozmiaru binarnego pliku dziennika nie jest opcją, opróżnienie binarnych plików dziennika tuż przed konserwacyjnym zamknięciem procesu mysqld może pomóc aby skrócić czasy odzyskiwania GTID logów binlogowych.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak pozyskiwać nowych użytkowników dziennie w MySQL?

  2. Jak mogę wyświetlić te same dane identyfikatora z pętlą while w PHP?

  3. Jak obliczyć sumę bieżącą w MySQL

  4. Błąd przygotowanej instrukcji mysql:MySQLSyntaxErrorException

  5. MySql pobiera rekordy lub dane według dziennych, tygodniowych, miesięcznych i rocznych