Я был немного удивлен, обнаружив, что операторы DDL ( alter table
и create index
т. Д.) Неявно фиксируют текущую транзакцию в MySQL. Исходя из MS SQL Server, возможность вносить изменения в базу данных в транзакции локально (что затем было отменено) была важной частью моего рабочего процесса. Для непрерывной интеграции использовался откат, если миграция по какой-либо причине зависала, так что, по крайней мере, мы не оставили базу данных в полу-перенастроенном состоянии.
Как люди решают эти две проблемы при использовании MySQL с миграциями и непрерывной интеграцией?
mysql
transaction
ddl
rollback
Сеннетт
источник
источник
Ответы:
Для многих ахиллесова пята 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
блоковВНИМАНИЕ: Если вы используете MyISAM для какого-либо из этих действий, вы можете (не) любезно добавить MyISAM в список вещей, которые могут прервать транзакцию, возможно, не с точки зрения неявного принятия, но определенно с точки зрения согласованности данных, если откат когда-либо будет необходимо.
ПОЧЕМУ НЕ ЛВМ?
Снимки LVM великолепны, и идеальным является восстановление целых экземпляров баз данных без необходимости интенсивной обработки SQL. Однако, когда дело доходит до MySQL, вы должны учитывать два механизма хранения: InnoDB и MyISAM.
База данных All-InnoDB
Посмотрите на архитектуру InnoDB (Фото любезно предоставлено техническим директором Percona Вадимом Ткаченко)
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';
service mysql stop
service mysql stop
Если вы не можете завершить работу, но сделайте снимок с 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;
База данных 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';
service mysql stop
service mysql stop
Если вы не можете завершить работу, но сделайте снимок с MySQL Live
Вы можете принудительно сбросить некоторые таблицы InnoDB
SET GLOBAL innodb_max_dirty_pages_pct = 0;
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
FLUSH TABLES innodb_tbl1,... FOR EXPORT;
на критических таблицах InnoDBFLUSH TABLES WITH READ LOCK;
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.
ПОСЛЕДНИЕ МЫСЛИ
источник
Если говорить о непрерывной интеграции, то я предполагаю, что это среда разработки. В этом случае я бы сказал, что человек, делающий структурные изменения, должен проверить их, чтобы убедиться, что они не сломаны для других, почти так же, как кто-то обновляет общую библиотеку: тестируйте в своей песочнице, прежде чем вносить такие изменения.
В процессе производственного развертывания вы, как правило, проходите через dev, QA или даже подготовительные среды для тестирования своих изменений, так же, как и для любых изменений кода.
Обратите внимание, что это не специфично для MySQL: базы данных Oracle также неявно выполняют COMMIT при выдаче «alter table» и т. Д.
Теперь, если вы хотите защитить себя, вы, конечно, можете сделать резервную копию заранее, или снимок LVM или файловой системы, если ваша система может это сделать. У вас также может быть подчиненный, которого вы могли бы задержать / остановить в качестве обеспечения безопасности перед конфиденциальными операциями.
источник