Для многих ахиллесова пята 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 всегда должны делать транзакционные задания и сценарии DDL взаимоисключающими.
Это дает вам возможность создавать парадигмы, которые бы
- поддерживать транзакции, которые должным образом изолированы с помощью
START TRANSACTION/COMMIT
блоков
- управление DDL путем сценария DDL самостоятельно, запускающего такой DDL как конструктор или деструктор
- Конструктор: DDL для создания таблиц с новым дизайном
- Деструктор: DDL для возврата таблиц к предыдущему дизайну
- никогда не объединяйте эти операции под одной работой
ВНИМАНИЕ: Если вы используете MyISAM для какого-либо из этих действий, вы можете (не) любезно добавить MyISAM в список вещей, которые могут прервать транзакцию, возможно, не с точки зрения неявного принятия, но определенно с точки зрения согласованности данных, если откат когда-либо будет необходимо.
ПОЧЕМУ НЕ ЛВМ?
Снимки LVM великолепны, и идеальным является восстановление целых экземпляров баз данных без необходимости интенсивной обработки SQL. Однако, когда дело доходит до MySQL, вы должны учитывать два механизма хранения: InnoDB и MyISAM.
База данных All-InnoDB
Посмотрите на архитектуру InnoDB (Фото любезно предоставлено техническим директором Percona Вадимом Ткаченко)
InnoDB имеет много движущихся частей
- Системное табличное пространство
- Словарь с данными
- Double Write Buffer (поддержка согласованности данных; используется для восстановления после сбоев)
- Вставить буфер (изменения буферов для вторичных неуникальных индексов)
- Откат сегментов
- Undo Space (где может произойти самый неконтролируемый рост)
- InnoDB буферный пул
- Грязные страницы данных
- Грязные страницы указателя
- Изменения в неуникальных индексах
- Другие важные кеши памяти
Взятие 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 Mix
При доступе к 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 Replication Help?
Хотя вы можете восстановить один снимок LVM на двух серверах и настроить MySQL Master / Slave Replication, это становится дополнительным источником очистки при восстановлении снимков.
Если вы выполняете задания CI на главном сервере, и эти задания невелики, репликация при определенных обстоятельствах может сэкономить время. Вы можете просто запустить STOP SLAVE;
Slave, запустить задания CI на Master и запустить START SLAVE;
Slave, когда данные Master сертифицированы.
Если задания CI предупреждают слишком много данных, вы можете восстановить моментальный снимок LVM и настроить репликацию с нуля. Если вы обнаружите, что делаете это часто, вы, вероятно, можете сделать это с настройкой MySQL Replication.
ПОСЛЕДНИЕ МЫСЛИ
- Лучше всего использовать несколько серверов БД (3 или более) для восстановления и регрессионных тестов.
- Преобразуйте оставшиеся таблицы MyISAM в InnoDB, если эти таблицы не должны оставаться MyISAM.
- Если ваш контент данных является конфиденциальным, вы должны выполнить задание CI для очистки данных после восстановления снимка перед началом любых тестов. В качестве альтернативы вы можете сделать снимки MySQL с уже очищенными данными.