Транзакционный рабочий процесс DDL для MySQL

25

Я был немного удивлен, обнаружив, что операторы DDL ( alter tableи create indexт. Д.) Неявно фиксируют текущую транзакцию в MySQL. Исходя из MS SQL Server, возможность вносить изменения в базу данных в транзакции локально (что затем было отменено) была важной частью моего рабочего процесса. Для непрерывной интеграции использовался откат, если миграция по какой-либо причине зависала, так что, по крайней мере, мы не оставили базу данных в полу-перенастроенном состоянии.

Как люди решают эти две проблемы при использовании MySQL с миграциями и непрерывной интеграцией?

Сеннетт
источник
Крест выложен из ТАК. stackoverflow.com/q/28197013/614523 Не получил много любви там.
Сеннет
1
Для непрерывной интеграции рассмотрите моментальные снимки LVM как способ очень быстрого создания всей среды, которая находится в известном состоянии.
Рик Джеймс
5
Вы всегда можете перейти на Postgres - он поддерживает транзакционный DDL (SCNR).
a_horse_with_no_name
3
Я согласен с @a_horse_with_no_name, если это ваш рабочий процесс, серьезно подумайте об использовании PosgreSQL, который имеет транзакционный DDL вместе со многими другими приятными функциями.
Renzo

Ответы:

9

Для многих ахиллесова пята MySQL - неявная фиксация.

В соответствии с пунктом 3 книги

Руководство по сертификации MySQL 5.0

Следующие команды могут прервать транзакцию

  • 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 Сантехника

InnoDB имеет много движущихся частей

  • Системное табличное пространство
    • Словарь с данными
    • Double Write Buffer (поддержка согласованности данных; используется для восстановления после сбоев)
    • Вставить буфер (изменения буферов для вторичных неуникальных индексов)
    • Откат сегментов
    • Undo Space (где может произойти самый неконтролируемый рост)
  • InnoDB буферный пул
    • Грязные страницы данных
    • Грязные страницы указателя
    • Изменения в неуникальных индексах
  • Другие важные кеши памяти

Взятие LVM снимка базы данных all-InnoDB с незафиксированными изменениями, плавающими в кеше пула буферов и памяти, приведет к набору данных, который потребует восстановления после сбоя InnoDB после восстановления LUN и запуска mysqld.

ПРЕДЛОЖЕНИЕ ДЛЯ ALL-InnoDB

Если вы можете выключить MySQL, прежде чем делать снимок

    1. Бег SET GLOBAL innodb_fast_shutdown = 0;
    1. Бег SET GLOBAL innodb_max_dirty_pages_pct = 0;
    1. Бег SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
    1. Повторяйте шаг 3 до тех пор, пока Innodb_buffer_pool_pages_dirty не станет равным 0 или максимально приближенным к 0
    1. service mysql stop
    1. Сделайте снимок LVM
    1. service mysql stop

Если вы не можете завершить работу, но сделайте снимок с MySQL Live

    1. Бег SET GLOBAL innodb_max_dirty_pages_pct = 0;
    1. Бег SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
    1. Повторяйте шаг 2 до тех пор, пока Innodb_buffer_pool_pages_dirty не станет равным 0 или максимально приближенным к 0
    1. Сделайте снимок LVM
    1. Бег 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, прежде чем делать снимок

    1. Бег SET GLOBAL innodb_fast_shutdown = 0;
    1. Бег SET GLOBAL innodb_max_dirty_pages_pct = 0;
    1. Бег SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
    1. Повторяйте шаг 3 до тех пор, пока Innodb_buffer_pool_pages_dirty не станет равным 0 или максимально приближенным к 0
    1. service mysql stop
    1. Сделайте снимок LVM
    1. service mysql stop

Если вы не можете завершить работу, но сделайте снимок с MySQL Live

Вы можете принудительно сбросить некоторые таблицы InnoDB

    1. Бег SET GLOBAL innodb_max_dirty_pages_pct = 0;
    1. Бег SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
    1. Повторяйте шаг 2 до тех пор, пока Innodb_buffer_pool_pages_dirty не станет равным 0 или максимально приближенным к 0
    1. Запускать FLUSH TABLES innodb_tbl1,... FOR EXPORT;на критических таблицах InnoDB
    1. Бег FLUSH TABLES WITH READ LOCK;
    1. Сделайте снимок LVM
    1. Бег UNLOCK TABLES;
    1. Бег 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 с уже очищенными данными.
RolandoMySQLDBA
источник
4

Если говорить о непрерывной интеграции, то я предполагаю, что это среда разработки. В этом случае я бы сказал, что человек, делающий структурные изменения, должен проверить их, чтобы убедиться, что они не сломаны для других, почти так же, как кто-то обновляет общую библиотеку: тестируйте в своей песочнице, прежде чем вносить такие изменения.

В процессе производственного развертывания вы, как правило, проходите через dev, QA или даже подготовительные среды для тестирования своих изменений, так же, как и для любых изменений кода.

Обратите внимание, что это не специфично для MySQL: базы данных Oracle также неявно выполняют COMMIT при выдаче «alter table» и т. Д.

Теперь, если вы хотите защитить себя, вы, конечно, можете сделать резервную копию заранее, или снимок LVM или файловой системы, если ваша система может это сделать. У вас также может быть подчиненный, которого вы могли бы задержать / остановить в качестве обеспечения безопасности перед конфиденциальными операциями.

phil_w
источник