Для багатьох людей п'ята ахіллеса MySQL - це неявна фіксація.
Відповідно до пункту 3 книги
наступні команди можуть і порушують транзакцію
ALTER TABLE
BEGIN
CREATE INDEX
DROP DATABASE
DROP INDEX
DROP TABLE
RENAME TABLE
TRUNCATE TABLE
LOCK TABLES
UNLOCK TABLES
SET AUTOCOMMIT = 1
START TRANSACTION
ПРОПОЗИЦІЯ
Якщо мова йде про MySQL, будь-які створені вами завдання ContinuousIntegration (CI) / SelfService завжди повинні робити завдання Transaction та сценарії DDL взаємно виключними.
Це дає можливість створити парадигми, які б це зробили
- підтримка транзакцій, які належним чином ізольовані
START TRANSACTION/COMMIT
блоками
- керування DDL шляхом скриптування DDL самостійно, запуск такого DDL, як конструктор чи деструктор
- Конструктор: DDL для створення таблиць з новим дизайном
- Destructor: DDL для повернення таблиць назад до попереднього дизайну
- ніколи не поєднуйте ці операції під одним завданням
ПОПЕРЕДЖЕННЯ. Якщо ви використовуєте MyISAM для будь-якого цього, ви можете (не) люб'язно додати MyISAM до списку речей, які можуть порушити транзакцію, можливо, не з точки зору неявної фіксації, але, безумовно, з точки зору узгодженості даних, якщо відкат коли-небудь буде. потрібні.
ЧОМУ НЕ ЛВМ?
Знімки LVM є чудовими, і відновлення цілих примірників баз даних без необхідності виконувати важку обробку SQL є ідеальним. Однак, якщо мова йде про MySQL, вам доведеться враховувати два двигуни зберігання даних: InnoDB і MyISAM.
База даних All-InnoDB
Подивіться на архітектуру InnoDB (малюнок люб’язно наданий КТ Percona Вадиму Ткаченку)
InnoDB має багато рухомих частин
- Простір системних таблиць
- Словник даних
- Подвійний буфер запису (послідовність підтримки даних; використовується для відновлення аварійних ситуацій)
- Вставити буфер (зміни буфера для вторинних унікальних індексів)
- Відхилення сегментів
- Скасувати пробіл (де може статися найконтрольованіше зростання)
- Буферний басейн InnoDB
- Брудні сторінки даних
- Брудні покажчики
- Зміни до індексів UnUnique
- Інші важливі кеші пам'яті
Зйомка LVM бази даних All-InnoDB із невмілими змінами, що плавають у кешах пулу та пам'яті, дасть набір даних, що потребує відновлення аварії InnoDB після відновлення LUN та запуску mysqld.
ПЕРЕВАГА ДЛЯ ALL-InnoDB
Якщо ви можете вимкнути MySQL перед тим, як зробити знімок
- Біжи
SET GLOBAL innodb_fast_shutdown = 0;
- Біжи
SET GLOBAL innodb_max_dirty_pages_pct = 0;
- Біжи
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
- Повторіть крок 3, поки Innodb_buffer_pool_pages_dirty не дорівнює 0 або максимально наблизиться до 0.
service mysql stop
- Зробіть знімок LVM
service mysql stop
Якщо ви не можете відключити, але зробити знімок із MySQL Live
- Біжи
SET GLOBAL innodb_max_dirty_pages_pct = 0;
- Біжи
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
- Повторіть крок 2, поки Innodb_buffer_pool_pages_dirty не дорівнює 0 або максимально наблизиться до 0.
- Зробіть знімок LVM
- Біжи
SET GLOBAL innodb_max_dirty_pages_pct = 75;
База даних All-MyISAM або суміш InnoDB / MyISAM
При зверненні MyISAM підтримує кількість відкритих файлів для обробки. Якщо MySQL виходить з ладу, будь-яка таблиця MyISAM з числом відкритих файлів кількість файлів> 0 буде позначена як збій і потребує ремонту (навіть якщо з даними нічого не буває).
Зйомка LVM бази даних, яка використовує таблиці MyISAM, матиме одну чи більше таблиць MyISAM, які потребують ремонту, коли знімок буде відновлено та запущено mysqld.
ПЕРЕВАГА ДЛЯ All-MyISAM або InnoDB / MyISAM Mix
Якщо ви можете вимкнути MySQL перед тим, як зробити знімок
- Біжи
SET GLOBAL innodb_fast_shutdown = 0;
- Біжи
SET GLOBAL innodb_max_dirty_pages_pct = 0;
- Біжи
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
- Повторіть крок 3, поки Innodb_buffer_pool_pages_dirty не дорівнює 0 або максимально наблизиться до 0.
service mysql stop
- Зробіть знімок LVM
service mysql stop
Якщо ви не можете відключити, але зробити знімок із MySQL Live
Ви можете застосувати прошивання певних таблиць InnoDB
- Біжи
SET GLOBAL innodb_max_dirty_pages_pct = 0;
- Біжи
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
- Повторіть крок 2, поки Innodb_buffer_pool_pages_dirty не дорівнює 0 або максимально наблизиться до 0.
- Запуск
FLUSH TABLES innodb_tbl1,... FOR EXPORT;
на критичних таблицях InnoDB
- Біжи
FLUSH TABLES WITH READ LOCK;
- Зробіть знімок LVM
- Біжи
UNLOCK TABLES;
- Біжи
SET GLOBAL innodb_max_dirty_pages_pct = 75;
Чи може допомогти реплікація MySQL?
У той час як ви можете відновити один знімок LVM на двох серверах і встановити MySQL Master / Slave Replication, це стає додатковим джерелом очищення будинку при відновленні знімків.
Якщо ви запускаєте завдання CI на Master і ці завдання невеликі, тиражування може бути певним часом за певних обставин. Ви можете просто бігти STOP SLAVE;
на Рабі, запускати завдання CI на Майстрі та бігати START SLAVE;
на Рабі, коли дані Магістра підтверджуються.
Якщо завдання CI попереджають занадто багато даних, ви можете відновити знімок LVM та налаштування реплікації з нуля. Якщо ви часто виявляєте, що це робите часто, ви, можливо, могли б зробити це з налаштуванням MySQL Replication.
ЗАКЛЮЧНІ МИСЛИ
- Найкраще використовувати декілька серверів БД (3 або більше) для проведення тестів на відновлення та регресію.
- Перетворіть залишилися таблиці MyISAM в InnoDB, якщо ці таблиці не повинні залишатися MyISAM.
- Якщо вміст ваших даних є чутливим, вам слід виконати завдання CI для очищення даних після відновлення знімка перед початком будь-яких тестів. В якості альтернативи ви можете зробити знімки MySQL з уже прочищеними даними.