Dla wielu osób piętą achillesową MySQL jest niejawne zatwierdzenie.
Zgodnie z § 4 książki
następujące polecenia mogą i spowodują zerwanie transakcji
ALTER TABLE
BEGIN
CREATE INDEX
DROP DATABASE
DROP INDEX
DROP TABLE
RENAME TABLE
TRUNCATE TABLE
LOCK TABLES
UNLOCK TABLES
SET AUTOCOMMIT = 1
START TRANSACTION
SUGESTIA
Jeśli chodzi o MySQL, wszelkie tworzone przez ciebie zadania ContinuousIntegration (CI) / SelfService powinny zawsze wykluczać wzajemnie wykluczające się zadania transakcyjne i skrypty DDL.
Daje to możliwość stworzenia paradygmatów, które by to zrobiły
- obsługują transakcje, które są odpowiednio izolowane za pomocą
START TRANSACTION/COMMIT
bloków
- kontrola nad DDL poprzez samodzielne skryptowanie DDL, uruchamianie takiego DDL jako konstruktora lub destruktora
- Konstruktor: DDL do tworzenia tabel o nowym projekcie
- Destructor: DDL, aby przywrócić tabele do poprzedniego projektu
- nigdy nie łącz tych operacji w ramach jednego zadania
OSTRZEŻENIE: Jeśli używasz do tego MyISAM, możesz (nie) uprzejmie dodać MyISAM do listy rzeczy, które mogą przerwać transakcję, być może nie pod względem domniemanego zatwierdzenia, ale zdecydowanie pod względem spójności danych, gdyby kiedykolwiek wycofanie potrzebne.
DLACZEGO NIE LVM?
Migawki LVM są świetne, a przywracanie całych instancji baz danych bez konieczności wykonywania intensywnego przetwarzania SQL jest idealne. Jednak jeśli chodzi o MySQL, musisz wziąć pod uwagę dwa silniki pamięci: InnoDB i MyISAM.
Baza danych All-InnoDB
Spójrz na architekturę InnoDB (Zdjęcie dzięki uprzejmości Percona CTO Vadim Tkachenko)
InnoDB ma wiele ruchomych części
- Systemowa przestrzeń tabel
- Słownik danych
- Podwójny bufor zapisu (spójność danych pomocniczych; używany do odzyskiwania po awarii)
- Wstaw bufor (zmiany buforów na wtórne nieunikalne indeksy)
- Wycofywanie segmentów
- Cofnij przestrzeń (gdzie może nastąpić najbardziej niekontrolowany wzrost)
- Pula buforów InnoDB
- Brudne strony danych
- Brudne strony indeksu
- Zmiany w indeksach NonUnique
- Inne ważne pamięci podręczne
Wykonanie migawki LVM dla bazy danych All-InnoDB z niezatwierdzonymi zmianami pływającymi w puli buforów i pamięciach podręcznych dałoby zestaw danych, który wymagałby odzyskiwania po awarii InnoDB po przywróceniu LUN i uruchomieniu mysqld.
SUGESTIA DLA WSZYSTKICH InnoDB
Jeśli możesz zamknąć MySQL przed zrobieniem migawki
- Biegać
SET GLOBAL innodb_fast_shutdown = 0;
- Biegać
SET GLOBAL innodb_max_dirty_pages_pct = 0;
- Biegać
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
- Powtarzaj krok 3, aż Innodb_buffer_pool_pages_dirty wyniesie 0 lub będzie możliwie jak najbliżej 0
service mysql stop
- Wykonaj migawkę LVM
service mysql stop
Jeśli nie możesz zamknąć systemu, ale zrób migawkę za pomocą MySQL Live
- Biegać
SET GLOBAL innodb_max_dirty_pages_pct = 0;
- Biegać
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
- Powtarzaj krok 2, aż Innodb_buffer_pool_pages_dirty wyniesie 0 lub będzie możliwie jak najbliżej 0
- Wykonaj migawkę LVM
- Biegać
SET GLOBAL innodb_max_dirty_pages_pct = 75;
Baza danych All-MyISAM lub InnoDB / MyISAM Mix
Po uzyskaniu dostępu do MyISAM zachowuje liczbę otwartych uchwytów plików. Jeśli MySQL ulegnie awarii, każda tabela MyISAM z liczbą uchwytów otwartego pliku> 0 zostanie oznaczona jako awaria i wymaga naprawy (nawet jeśli nic nie jest nie tak z danymi).
Wykonanie migawki LVM dla bazy danych, w której są używane tabele MyISAM, będzie wymagało naprawy jednej lub wielu tabel MyISAM po przywróceniu migawki i uruchomieniu mysqld.
PROPOZYCJA DLA All-MyISAM lub InnoDB / MyISAM Mix
Jeśli możesz zamknąć MySQL przed zrobieniem migawki
- Biegać
SET GLOBAL innodb_fast_shutdown = 0;
- Biegać
SET GLOBAL innodb_max_dirty_pages_pct = 0;
- Biegać
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
- Powtarzaj krok 3, aż Innodb_buffer_pool_pages_dirty wyniesie 0 lub będzie możliwie jak najbliżej 0
service mysql stop
- Wykonaj migawkę LVM
service mysql stop
Jeśli nie możesz zamknąć systemu, ale zrób migawkę za pomocą MySQL Live
Możesz wymusić opróżnianie niektórych tabel InnoDB
- Biegać
SET GLOBAL innodb_max_dirty_pages_pct = 0;
- Biegać
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
- Powtarzaj krok 2, aż Innodb_buffer_pool_pages_dirty wyniesie 0 lub będzie możliwie jak najbliżej 0
- Uruchom
FLUSH TABLES innodb_tbl1,... FOR EXPORT;
na krytycznych tabelach InnoDB
- Biegać
FLUSH TABLES WITH READ LOCK;
- Wykonaj migawkę LVM
- Biegać
UNLOCK TABLES;
- Biegać
SET GLOBAL innodb_max_dirty_pages_pct = 75;
Czy replikacja MySQL może pomóc?
Chociaż można przywrócić jedną migawkę LVM na dwóch serwerach i skonfigurować replikację MySQL Master / Slave, staje się ona dodatkowym źródłem czyszczenia domu podczas przywracania migawek.
Jeśli uruchamiasz zadania CI na Master, a te zadania są małe, replikacja może w pewnych okolicznościach zaoszczędzić czas. Możesz po prostu uruchomić STOP SLAVE;
Slave, uruchomić zadania CI na Master i uruchomić START SLAVE;
Slave, gdy dane Master będą certyfikowane.
Jeśli zadania CI ostrzegają o zbyt dużej ilości danych, możesz przywrócić migawkę LVM i replikację konfiguracji od zera. Jeśli często to robisz, prawdopodobnie możesz zrobić to z konfiguracją replikacji MySQL.
KOŃCOWE PRZEMYŚLENIA
- Najlepiej jest używać wielu serwerów DB (3 lub więcej) do wykonywania testów przywracania i regresji.
- Konwertuj pozostałe tabele MyISAM na InnoDB, jeśli tabele te nie muszą pozostać MyISAM.
- Jeśli zawartość danych jest wrażliwa, należy wykonać zadanie CI w celu wyczyszczenia danych po przywróceniu migawki przed rozpoczęciem jakichkolwiek testów. Alternatywnie możesz chcieć zrobić migawki MySQL z już wyczyszczonymi danymi.