Byłem trochę zaskoczony, aby odkryć, że DDL ( alter table
, create index
etc) niejawnie popełnić bieżącej transakcji w MySQL. Począwszy od MS SQL Server, możliwość dokonywania lokalnych zmian bazy danych w transakcji (która została następnie wycofana) była ważną częścią mojego przepływu pracy. W celu ciągłej integracji zastosowano wycofanie, jeśli migracja nastąpiła z jakiegokolwiek powodu, dlatego przynajmniej nie pozostawiliśmy bazy danych w stanie częściowo migrowanym.
Jak ludzie rozwiązują te dwa problemy, używając MySQL do migracji i ciągłej integracji?
mysql
transaction
ddl
rollback
sennett
źródło
źródło
Odpowiedzi:
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
START TRANSACTION/COMMIT
blokówOSTRZEŻ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
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
SET GLOBAL innodb_fast_shutdown = 0;
SET GLOBAL innodb_max_dirty_pages_pct = 0;
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
service mysql stop
service mysql stop
Jeśli nie możesz zamknąć systemu, ale zrób migawkę za pomocą MySQL Live
SET GLOBAL innodb_max_dirty_pages_pct = 0;
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
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
SET GLOBAL innodb_fast_shutdown = 0;
SET GLOBAL innodb_max_dirty_pages_pct = 0;
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
service mysql stop
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
SET GLOBAL innodb_max_dirty_pages_pct = 0;
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
FLUSH TABLES innodb_tbl1,... FOR EXPORT;
na krytycznych tabelach InnoDBFLUSH TABLES WITH READ LOCK;
UNLOCK TABLES;
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
źródło
Jeśli mówisz o ciągłej integracji, to zakładam, że jest to środowisko programistyczne. W takim przypadku powiedziałbym, że osoba dokonująca zmian strukturalnych musi je przetestować, aby upewnić się, że nie psują rzeczy innym, podobnie jak ktoś aktualizujący wspólną bibliotekę: Testuj we własnym piaskownicy przed zatwierdzeniem takich zmian.
W procesie wdrażania produkcyjnego zwykle testujesz zmiany w środowisku deweloperskim, kontroli jakości, a nawet przedprodukcyjnym, tak samo jak w przypadku zmian w kodzie.
Zauważ, że nie jest to specyficzne dla MySQL: bazy danych Oracle również domyślnie wykonałyby COMMIT podczas wydawania „alter table” itp.
Teraz, jeśli chcesz się zabezpieczyć, możesz oczywiście wcześniej wykonać kopię zapasową lub LVM lub migawkę systemu plików, jeśli Twój system to potrafi. Możesz także mieć niewolnika, który możesz opóźnić / zatrzymać jako zabezpieczenie przed wrażliwymi operacjami.
źródło