Alter table transact sql: MS SQL Server и T-SQL
Содержание
CHECK CONSTRAINT в MS SQL — Грабли по которым мы прошлись / Хабр
Данная статья будет про то, как одна дружная команда веб разработчиков, не имея в своём составе опытного SQL разработчика, добавила Check Constraint в таблицу и прошлась по нескольким простым, но не сразу очевидным граблям. Будут разобраны особенности синтаксиса T-SQL, а также нюансы работы ограничений (СONSTRAINT’ов), не зная которые, можно потратить не мало времени на попытки понять, почему что-то работает не так. Так же будет затронута особенность работы SSDT, а именно как генерируется миграционный скрипт, при необходимости добавить или изменить ограничения (CONSTRAINT’ы).
Дабы читатель поскорей понял, стоит читать статью или нет, я сначала рассмотрю абстрактную задачу, по ходу решения которой будут заданы вопросы «А почему так?». Если вы сразу будете знать ответ, то смело бросайте чтение и переходите к следующей статье.
Разработаем гарем?
«Гарем» — система, которая будет позволять вести учёт людей в «храме любви».
Для простоты разработки примем следующее:
- гости в гареме запрещены и, соответственно, в базе не хранятся, т. е. хранятся только «хозяева» и их жёны
- у жён и их «хозяина» фамилия совпадает
- по фамилии можно уникально идентифицировать каждый гарем, т. е. одна и та же фамилия в разных гаремах встретиться не может.
Для хранения людей создаётся таблица Persons:
В последний момент, приходит озарение, что на уровне схемы базы мы не гарантируем существование только одного мужчины в гареме. Решаем это исправить путём добавления проверочного ограничения (check constraint):
основанного на скалярной пользовательской функции (scalar-valued Function):
«А почему так?» №1.
При попытке вставить абсолютно валидные данные (как женщин, так и мужчин), понимаем, что мы всё поломали. Insert валится со следующей ошибкой:
«А почему так?» №2.
После того как побороли проблему вставки данных, решаем задеплоиться в QA окружение. Создаём миграционный скрипт при помощи SSDT, быстро просматриваем его. Находим какую-то не очень понятную строку (выделена красной рамкой).
Из комментария в инструкции PRINT кажется, что это запуск проверки ограничения на уже существующих строках. Но при создании ограничения мы же указали, что существующие строки проверять не нужно («Check Existing Data On Creation Or Re-Enabling» был установлен в “No”). Поэтому начинаем гуглить и находим «полезный» пост. Прочитав ответ и все комментарии к нему, обретаем глубокую уверенность, что эта инструкция включает проверку при вставке новых строк, а не валидирует существующие, т. е. нам обязательно нужно оставить эту строку, иначе ограничение вообще никогда не будет проверяться.
С гордостью за проделанную работу, отправляем скрипт, ждёмс… Спустя Х часов приходит отчёт, что наш миграционный скрипт успешно провалился. Смотрим отчёт.
Понимаем, что именно подозрительная инструкция провалила миграцию.
«А почему так?» №1 – Объяснение.
Тут всё предельно просто. Мы забыли, что проверка условий CHECK CONSTRAINT’а происходит уже после вставки строки в таблицу и в момент вставки первого мужчины в гарем, правильным условием будет равенство единице, а не нулю. В итоге функция была переписана на много проще.
Вычисляемые колонки (Computed column)
В выражении ограничения можно использовать вычисляемые колонки, но только если они физически сохраняются, т.е. у них свойство IsPersited установлено в Yes. На этапе выполнения проверки, все вычисляемые колонки будут иметь правильные значения и если вы обновите значения, от которых зависит вычисляемое значение, то в выражении CHECK CONSTRAINT’а будут переданы уже пересчитанные значения.
Оправдание
Дабы хоть как-то оправдать такую невнимательность скажу, что в нашем случае условия проверки ограничения были на много более витиеватые, и далеко не все были связаны с количеством строк в обновляемой таблице. А данные вставлялись в таблицу только в результате запуска сложного скрипта, разобраться с которым было крайне непросто.
«А почему так?» №2 – Объяснение.
Тут всё оказалось не столь прозрачно. Сначала пришлось всё-таки разобраться в истинном назначении упавшей инструкции. И, к превеликому нашему удивлению, мы поняли, что она делает именно то, что сказано в комментарии, а не то, что описано в найденном «полезном» посте (разбор синтаксиса будет ниже).
Узнав это, было логично предположить, что при создании миграционного скрипта была выбрана база, в которой на CK_Persons значение «Check Existing Data On Creation Or Re-Enabling» было “Yes”, а не “No”. Но эта теория провалилась. Меняя это значение и генерируя новый скрипт, стало понятно, что SSDT, вообще игнорируют это значение. Начали грешить на наличие бага в SSDT.
Очередной этап поисков навёл нас на следующий пост, из которого мы уже поняли, что это «фича, а не баг».
Согласно дизайна SSDT, при создании скрипта всегда создаётся ограничение, которое включено, т.е. проверяется для всех будущих INSERT/UPDATE. За это отвечает первая инструкция ALTER в нашем миграционном скрипте.
Вторая же инструкция ALTER (выделена красной рамкой) отвечает за валидацию существующих данных и является опциональной. За то будет ли эта инструкция добавлена в миграционный скрип, отвечает специальная опция генерации скрипта:
Включив её, мы для каждого нового миграционного скрипта активируем валидацию существующих данных, т.е. в него будет вставлена опциональная инструкция (второй ALTER). Иначе, инструкция попросту отсутствует и на существующих данных проверка не выполняется. Как это не прискорбно получается, но SSDT генерирует миграционный скрипт по принципу всё или ничего. Можно либо для всех вновь добавляемых ограничений включить проверку на существующих данных, либо для всех её пропустить. Для более тонкой настройки поведения придётся править скрипт вручную.
Ограничения (Constraints) в MS SQL
Как уже говорилось выше, в данной статье осталось разобраться с премудростями синтаксиса создания и обновления проверочных ограничений. Но прежде чем мы приступим, давайте для полноты картины вспомним немного общей информации об ограничениях в MS SQL Server.
Ограничения – механизм, который позволяет задавать набор правил, направленных на поддержание целостности данных. Правила могут быть заданы как на уровне колонки в таблице, так и на уровне всей таблицы.
MS SQL Server поддерживает следующие виды ограничений:
- NULL / NOT NULL ограничение – задаётся на уровне какого-то столбца и определяет, может ли хранится значение NULL в колонке.
- UNIQUE ограничение – позволяет обеспечить уникальность значений в одном или нескольких столбцах.
- PRIMARY KEY ограничение – практически тоже самое, что и UNIQUE ограничение, но в отличие от него, PRIMARY KEY не позволяет хранить NULL.
- CHECK ограничение – позволяет задать некое логическое условие, которое должно быть истинным (TRUE) при вставке или обновлении данных в таблице. Может быть задано как на уровне одного столбца, так и на уровне таблицы.
- FOREIGN KEY ограничение – позволяет обеспечить ссылочную связность двух таблиц. При вставке значения в колонку (или колонки) с FOREIGN KEY ограничением, будет производится проверка на наличие такого же значения в таблице, на которую указывает FOREIGN KEY. Если значения нет, то обновление или вставка строки завершается с ошибкой. Исключением может быть только значение NULL, если на колонке не задано ограничение NOT NULL. Кроме того, ссылаться можно только на колонку с уникальными значениями, т.е. с UNIQUE или PRIMARY KEY ограничением. Так же можно задать поведение, на случай обновления или удаления строки, в «отцовской» таблице:
- NO ACTION – отцовскую таблицу запрещено менять
- CASCADE – подчинённые строки будут обновлены или удалены, в зависимости от выполняемого действием над отцовской таблицей
- SET NULL – значение в подчинённой таблице будет установлено в NULL
- SET DEFAULT — значение в подчинённой таблице будет установлено в значение по умолчанию.
Теперь немного подробней о CHECK CONSTRAINT’ах. Рассмотрим ограничение, которое было упомянуто выше. Ниже представлено окно свойств этого ограничения в Management Studio:
Основными свойствами являются:
- Expression – любое допустимое T-SQL выражение в котором можно ссылаться на значения в проверяемой строке по имени столбцов
- Name – имя, уникально идентифицирующее ограничение в пределах базы данных
- Check Existing Data On Creation Or Re-Enabling – если ограничение создаётся на уже существующей таблице, то это значение “No” позволяет не пропустить валидацию существующих строк; в виду того, что существующую проверку можно временно выключить, то данное свойство так же определяет будет ли проводиться валидация имеющихся строк при включении ограничения.
- Enforce For INSERTs And UPDATEs – включает (Yes) или выключает (No) ограничение
- Enforce For Replication – позволяет пропустить проверку при вставке или обновлении строк агентом репликации
Вся эта информация доступна нам так же из системного представления (view) sys. check_constraints. Оно содержит по одной строке для каждого CHECK CONSTRAINT в базе данных. Мы его иногда используем в миграционных скриптах, когда нужно убедится в существовании или в отсутствии какого-либо ограничения.
Примеры использования sys.check_constraints
Sql
DECLARE @name NVARCHAR(128) = 'CK_Persons' SELECT CASE [is_not_trusted] WHEN 1 THEN 'No' ELSE 'Yes' END AS [Check Existing Data], CASE [is_disabled] WHEN 1 THEN 'No' ELSE 'Yes' END AS [Enabled], CASE [is_not_for_replication] WHEN 1 THEN 'NO' ELSE 'YES' END AS [Enforce For Replication] FROM [sys].[check_constraints] WHERE name = @name
Можно получить ответ в более привычном формате, воспользовавшись оператором UNPIVOT:
Sql
DECLARE @name NVARCHAR(128) = 'CK_Persons' SELECT [Properties], [Values] FROM (SELECT CAST([definition] AS VARCHAR(MAX)) AS [Expression], CAST(CASE [is_not_trusted] WHEN 1 THEN 'No' ELSE 'Yes' END AS VARCHAR(MAX)) AS [Check Existing Data On Creation Or Re-Enabling], CAST(CASE [is_disabled] WHEN 1 THEN 'No' ELSE 'Yes' END AS VARCHAR(MAX)) AS [Enforce For INSERTs And UPDATEs], CAST(CASE [is_not_for_replication] WHEN 1 THEN 'NO' ELSE 'YES' END AS VARCHAR(MAX)) AS [Enforce For Replication], CAST([create_date] AS VARCHAR(MAX)) as [Created], CAST([modify_date] AS VARCHAR(MAX)) as [Modified] FROM [sys]. [check_constraints] WHERE name = @name) p UNPIVOT ( [Values] FOR [Properties] IN ( [Expression], [Check Existing Data On Creation Or Re-Enabling] , [Enforce For INSERTs And UPDATEs], [Enforce For Replication], [Created], [Modified] ) ) AS unpvt;
Особенности работы CHECK CONSTRAINT:
- Срабатывает только при INSERT и UPDATE операциях, при выполнении DELETE условие не проверяется
- Если проверочное условие равно NULL, то считается, что CHECK CONSTRAINT не нарушен
Синтаксис CHECK CONSTRAINT
У проверочного ограничения есть ряд свойств, которые необходимо задать при создании. Некоторые из них можно задать только при создании, а некоторые доступны для изменения, только на уже созданном ограничении. В таблице ниже отображены эти особенности.
“…ADD CONSTRAINT…” (создание) | “ALTER…CONSTRAINT…” (изменение) | |
---|---|---|
Name | + | — |
Expression | + | — |
Check Existing Data On Creation Or Re-Enabling | + | + |
Enforce For INSERTs And UPDATEs | — | + |
Enforce For Replication | + | — |
Добавление нового CHECK CONSTRAINT
Основы синтаксиса шаблонов T-SQL
- В квадратных скобках «[ ]» – указываются опциональные конструкции и могут быть опущены из конечного выражения
- В фигурных скобках «{ }» — указывается список возможных конструкций, из которых необходимо выбрать одну
- Вертикальная черта «|» — отделяет элементы в фигурных скобках, среди которых необходимо выбрать единственный элемент
Опциональные секции:
- [ WITH { CHECK | NOCHECK } ] – в случае отсутствия применяется значение WITH CHECK
- [ NOT FOR REPLICATION ] – если конструкция указана, то ограничение не проверяется при вставке или обновлении данных в момент репликации; если конструкция пропущена –ограничение проверяется.
Примечание: шаблон приведён для случая создания ограничения на существующей таблице. Также можно создать ограничение в момент создания таблицы, тогда команда будет начинаться со слова CREATE и до слова WITH будет идти описание колонок таблицы.
Примеры:
Таблица для примеров
Примеры команд будут приведены для простейшей таблицы Employees, которая выглядит следующим образом:
Изменение существующего CHECK CONSTRAINT
Для обновления существующего проверочного ограничения используется конструкция ALTER TABLE. Для изменения доступны только следующие свойства:
- Check Existing Data On Creation Or Re-Enabling
- Enforce For INSERTs And UPDATEs
Опциональные секции:
- [ WITH { CHECK | NOCHECK } ] – в случае отсутствия применяется значение WITH NOCHECK
- [, …n] – позволяет задать имя более чем одного ограничения, к которым будут применены изменения; использование слова ALL изменения применятся ко всем проверочным ограничениям на таблице
Примечание 1: хоть имя и нельзя переименовать при помощи синтаксиса ALTER TABLE, это всё же возможно сделать, используя системную хранимую процедуру sp_rename.
Примечание 2: при необходимости изменить свойства «Expression» или «Enforce For Replication», необходимо сначала удалить существующее ограничение, а потом заново его создать с нужными значениями этих свойств.
Примеры:
Недокументированное поведение
Есть ряд случаев, когда выполнение команд приводит к неожиданным результатам. Причём я не смог найти объяснение на сайте msdn.
Что бы это увидеть, необходимо рассмотреть все возможные комбинации состояний в сочетании со всеми возможными вариантами команд. Тогда будет видно, что в 5-ти случаях получаемое значение свойства «Check Existing Data» не соответствует ожиданиям.
Состояние до выполнения команды | T-SQL команда | Состояние после выполнения команды | ||
---|---|---|---|---|
Check Existing Data | Enforce For INSERTs And UPDATEs | Check Existing Data | Enforce For INSERTs And UPDATEs | |
No | No | NOCHECK | No | No |
No | Yes | NOCHECK | No | No |
Yes | Yes | NOCHECK | No | No |
No | No | CHECK | No | Yes |
No | Yes | CHECK | No | Yes |
Yes | Yes | CHECK | Yes* | Yes |
No | No | WITH NOCHECK NOCHECK | No | No |
No | Yes | WITH NOCHECK NOCHECK | No | No |
Yes | Yes | WITH NOCHECK NOCHECK | No | No |
No | No | WITH NOCHECK CHECK | No | Yes |
No | Yes | WITH NOCHECK CHECK | No | Yes |
Yes | Yes | WITH NOCHECK CHECK | Yes* | Yes |
No | No | WITH CHECK NOCHECK | No** | No |
No | Yes | WITH CHECK NOCHECK | No** | No |
Yes | Yes | WITH CHECK NOCHECK | No** | No |
No | No | WITH CHECK CHECK | Yes | Yes |
No | Yes | WITH CHECK CHECK | Yes | Yes |
Yes | Yes | WITH CHECK CHECK | Yes | Yes |
(*) Значение свойства «Check Existing Data» может быть переведено из значения «Yes» в значение «No», только если текущее значение свойства «Enforce For INSERTs And UPDATEs» отличается от заданного в команде.
(**) «Check Existing Data» может быть «Yes», только если ограничение включено (Enforce For INSERTs And UPDATEs = “Yes”). Т. е. в команде WITH CHECK NOCHECK часть WITH CHECK будет проигнорирована и «Check Existing Data» не будет установлено в «Yes». Это так же объясняет почему в качестве начальных состояний есть только 3 варианта для каждой команды (а не 4).
Удаление существующего CHECK CONSTRAINT
Команда очень проста и не требует дополнительных объяснений. Ещё шаблон:
Заключение
Искренне надеюсь, что после прочтения данной статьи, вы не пройдётесь по граблям, набившие нам пару неприятных шишек. А так же вы сможете комфортно создавать и поддерживать миграционные скрипты, в которых есть логика по работе с CHECK CONSTRAINT. Удачи!
операторов SQL, вызывающих неявную фиксацию
Некоторые операторы SQL вызывают неявную фиксацию. Как правило, такие операторы являются операторами DDL. Те же операторы (кроме SHUTDOWN) вызывают ошибку 1400 (SQLSTATE ‘XAE09’), если действует транзакция XA.
Вот список:
ИЗМЕНИТЬ БАЗУ ДАННЫХ... ОБНОВИТЬ ИМЯ КАТАЛОГ ДАННЫХ ИЗМЕНИТЬ СОБЫТИЕ ИЗМЕНИТЬ ФУНКЦИЮ ИЗМЕНИТЬ ПРОЦЕДУРУ ИЗМЕНИТЬ ПОСЛЕДОВАТЕЛЬНОСТЬ ИЗМЕНИТЬ СЕРВЕР ИЗМЕНИТЬ ТАБЛИЦУ ИЗМЕНИТЬ ВИД АНАЛИЗ ТАБЛИЦЫ НАЧИНАТЬ ИНДЕКС КЭША ИЗМЕНИТЬ МАСТЕР НА ПРОВЕРКА ТАБЛИЦЫ СОЗДАТЬ БАЗУ ДАННЫХ СОЗДАТЬ СОБЫТИЕ СОЗДАТЬ ФУНКЦИЮ СОЗДАТЬ ИНДЕКС СОЗДАТЬ ПРОЦЕДУРУ СОЗДАТЬ РОЛЬ СОЗДАТЬ ПОСЛЕДОВАТЕЛЬНОСТЬ СОЗДАТЬ СЕРВЕР СОЗДАТЬ ТАБЛИЦУ СОЗДАТЬ ТРИГГЕР СОЗДАТЬ ПОЛЬЗОВАТЕЛЯ СОЗДАТЬ ВИД УДАЛИТЬ БАЗУ ДАННЫХ УДАЛИТЬ СОБЫТИЕ ФУНКЦИЯ ПАДЕНИЯ ИНДЕКС ПАДЕНИЯ ПРОЦЕДУРА СБРОСА УДАЛИТЬ РОЛЬ ПОСЛЕДОВАТЕЛЬНОСТЬ СБРОСА УДАЛИТЬ СЕРВЕР УДАЛИТЬ ТАБЛИЦУ БРОСИТЬ ТРИГГЕР УДАЛИТЬ ПОЛЬЗОВАТЕЛЯ КАПЕЛЬНЫЙ ПРОСМОТР РУМЯНЕЦ ГРАНТ ЗАГРУЗИТЬ ИНДЕКС В КЭШ БЛОКИРОВКА СТОЛОВ ОПТИМИЗИРОВАТЬ ТАБЛИЦУ ПЕРЕИМЕНОВАТЬ ТАБЛИЦУ ПЕРЕИМЕНОВАТЬ ПОЛЬЗОВАТЕЛЯ ТАБЛИЦА РЕМОНТА ПЕРЕЗАГРУЗИТЬ ОТЗЫВ УСТАНОВКА ПАРОЛЯ НЕИСПРАВНОСТЬ НАЧАТЬ ПОДЧИНЕННЫЙ НАЧАТЬ СДЕЛКУ СТОП ПОДЧИНЕННЫЙ ОБРЕЗАТЬ ТАБЛИЦУ
SET autocommit = 1
вызывает неявную фиксацию, если значение равно 0.
Все эти инструкции вызывают неявную фиксацию перед выполнением. Это означает, что даже если оператор завершается с ошибкой, транзакция фиксируется. Некоторые из них, например CREATE TABLE ... SELECT
, также вызывают фиксацию сразу после выполнения. Такие заявления ни в коем случае нельзя было отменить.
Если вы не уверены, что оператор неявно зафиксировал текущую транзакцию, вы можете запросить системную переменную сервера in_transaction.
Обратите внимание, что при запуске транзакции (не в режиме автоматической фиксации) все блокировки, полученные с помощью LOCK TABLES, снимаются. И получение таких блокировок всегда фиксирует текущую транзакцию. Чтобы сохранить целостность данных между транзакционными и нетранзакционными таблицами, можно использовать функцию GET_LOCK().
Исключения
Эти операторы не вызывают неявную фиксацию в следующих случаях:
-
CREATE TABLE
иDROP TABLE
, когдаИспользуется ключевое слово TEMPORARY
.- Однако TRUNCATE TABLE вызывает неявную фиксацию даже при использовании во временной таблице.
-
CREATE FUNCTION
иDROP FUNCTION
при использовании для создания пользовательской функции (вместо сохраненной функции). ОднакоCREATE INDEX
иDROP INDEX
вызывают фиксации даже при использовании с временными таблицами. -
UNLOCK TABLES
вызывает фиксацию, только еслиLOCK TABLES
использовалась для нетранзакционных таблиц. -
START SLAVE
,STOP SLAVE
,RESET SLAVE
иCHANGE MASTER TO
вызывают только неявную фиксацию начиная с MariaDB 10.0.
Комментарии
Контент, воспроизведенный на этом сайте, является собственностью его соответствующих владельцев,
и этот контент не проверяется заранее MariaDB. Взгляды, информация и мнения
выраженные в этом контенте, не обязательно представляют собой материалы MariaDB или любой другой стороны.
Запуск ALTER TABLE в производственной среде MySql с миллионами записей… | Харсимар Сингх | Javarevisited
Опубликовано в
·
Чтение: 6 мин.
·
9 октября 2021 г.
Некоторые вещи нам не нравится делать, но мы должны их делать!
Фото Тейлора Вика на Unsplash
Изменения схемы в производственных базах данных всегда были проблемой, проблема только усиливается, когда мы говорим о миллионах записей, если вы запускали ALTER на рабочем сервере в прошлом, вы бы знали ALTER TABLE
команда в основном чтение блокирует всю таблицу, а затем запись блокирует ее на короткое время — в конце. Если есть миллионы записей, это означает, что простой ДОБАВИТЬ СТОЛБЦ
займет 20–30 минут и приведет к простою производства.
Примечание. Для версий MySQL < 5.6 требуются блокировки, но если вы используете 5.6+ и InnoDB, блокировок можно избежать во многих операциях ALTER TABLE.
Percona Toolkit Helper поставляется с pt-online-schema-change согласно документации …
pt-online-schema-change изменяет структуру таблицы без блокировки чтения или записи. Укажите базу данных и таблицу в DSN. Не используйте этот инструмент, пока не прочитаете его документацию и не проверите свои резервные копии.
По сути, pt-online-schema-change работает аналогично тому, как MySql ALTER работает внутри, но единственное отличие состоит в том, что он работает с копией изменяемой таблицы. Вот что он делает за кулисами:
- Создает пустую копию таблицы для изменения и модифицирует ее по желанию.
- Копирует содержимое из исходной таблицы и создает триггеры из исходной таблицы для обновления соответствующих строк в новой таблице в случае каких-либо обновлений.
- Данные копируются небольшими порциями, которыми может управлять пользователь, мы вернемся к этому позже.
- Когда копирование завершено, выполняется атомарное переименование одновременно как исходной, так и новой таблицы, после чего исходная таблица удаляется.
В течение всего этого процесса исходная база данных была свободна и готова обслуживать как чтение, так и запись.
Дополнительную информацию см. в разделе загрузки на веб-сайте набора инструментов Percona.
sudo apt install percona-toolkit
wget percona.com/get/percona-toolkit.tar.gz
wget percona.com/get/percona-toolkit.rpm
wget percona.com/get/percona-toolkit.deb
Пример использования:
pt-online-schema-change --host--user --ask-pass --alter "добавить столбец " D= ,t= <ТАБЛИЦА> --выполнить
Обязательные опции:
- — host: здесь указать хост БД
- — ask-pass: запросить пароль при выполнении или использовать
— пароль 901 00 : введите пароль в самой команде - — alter: команда ALTER для запуска
- — D : имя вашей базы данных
- — T : имя таблицы
- — выполнить: 90 100 из соображений безопасности, это должно быть указано
- — пробный запуск: , как следует из названия, он не выполняет ALTER TABLE, а проверяет все и возможные проблемы при выполнении команды. Вы можете думать об этом как о фиктивном ALTER для вашего запроса
(это нельзя использовать с — выполнить, оба являются взаимоисключающими) - — метод изменения внешних ключей: ALTER с использованием внешних ключей сложны. Здесь доступны следующие опции:
— reboot_constrains: Этот метод удаляет и повторно добавляет внешний ключ, который ссылается на новую таблицу. Обычно это предпочтительнее, если только дочерние таблицы не слишком велики и их изменение не займет слишком много времени.
drop_swap: этот параметр отключит проверку внешнего ключа, а затем удалит исходную таблицу с последующим переименованием новой таблицы на ее место. Эта операция переименования не является атомарной, поэтому она более рискованна, поскольку исходная таблица не существует в течение короткого промежутка времени, что может привести к сбою запросов.
auto: Позвольте Percona решить, что лучше всего подходит для вашего стола. - — check-alter: проверяет команду alter и предупреждает о возможном непредвиденном поведении
- — check-slave-lag: приостановить копирование данных, если задержка реплики больше — max-lag
- — размер блока: нет строк, определяющих блок данных. (данные копируются фрагментами)
- — критическая нагрузка: после копирования каждого фрагмента Percona проверяет состояние и прерывает работу, если нагрузка слишком высока. Вы можете добавить разделенный запятыми список переменных состояния и пороговых значений MySql
- — drop-new-table: определяет, хотите ли вы удалить новую таблицу, если копирование данных не удалось
- — drop-old-table: определяет, хотите ли вы удалить старую таблицу после завершения операции
- — print: вывести команды SQL, запущенные инструментом
- — max-lag: пауз запросы, если задержка реплики превышает установленное значение
- — max-load: после копирования каждого фрагмента, Percona проверяет статус и приостанавливает запросы, если нагрузка слишком высока
- — new-table-name: вы можете указать имя для новой таблицы
- — sleep: как долго делать паузу между копированием каждого фрагмента
- ALTER не будет работать, если в таблице нет PRIMARY KEY или UNIQUE INDEX.
- ALTER не будет работать для таблицы с внешними ключами, если не указана опция внешнего ключа. ( Отметьте № 2 в разделе параметров)
- Инструмент автоматически приостанавливается, если нагрузка слишком велика или обнаруживается запаздывание подчиненного устройства. Их значения можно контролировать с помощью параметров командной строки.
- Здесь отслеживаются известные ошибки.
- Согласно документации, он работает для
Percona XtraDB Cluster (PXC) 5.5.28–23.7
, но в нашем тестировании он работал на MySQL 5.7. Дополнительные сведения см. в следующем разделе.
Вот некоторые наблюдения за результатом:
Время выполнения примерно такое же, если вы выполняете ALTER TABLE на MySql напрямую, однако это не влияет на трафик чтения/записи приложения.
Следующий результат — запустить его на Тестовая база данных и непроизводственная среда. В таблице было несколько отношений внешнего ключа, и с более чем 5 миллионами записей общее время выполнения составило около 10 минут.
Вот пример вывода выполнения
(Примечание: имена баз данных и таблиц скрыты для сохранения конфиденциальности):
Не проверять отставание ведомых устройств, поскольку ведомые устройства не были найдены и --check-slave-lag не был указан.
Операция, попытки, ожидание:
analysis_table, 10, 1
copy_rows, 10, 0,25
create_triggers, 10, 1
drop_triggers, 10, 1
swap_tables, 10, 1
update_foreign_keys, 10, 1
Дочерние таблицы:
``.` ` (примерно 257042 строки) 9013 3 `<БАЗА ДАННЫХ >`.` ` (приблизительно 1194 строки)
``.` ` (приблизительно 931229 строк)
Автоматически выберет метод обновления внешних ключей.
Изменение ``.` `...
Создание новой таблицы...
Создана новая таблица._ _new OK.
Изменение новой таблицы...
Изменено ``.`_ _new` ОК.
2021-10-08T19:11:08 Создание триггеров. ..
2021-10-08T19:11:08 Триггеры созданы ОК.
2021-10-08T19:11:08 Копирование примерно 5564340 строк...
Копирование ``.` `: осталось 6% 06:39
Копирование ``.` ` : 15% 05:39 осталось
Копирование ``.` `: 23% 04:56 осталось
Копирование ``.` `: 31% 04:23 осталось
Копирование ``.` `: 37% 04:09 осталось
Копирование ``.` `: 45% 03:34 осталось
Копирование ``.`< TABLE>`: 53% 03:01 осталось
Копирование ``.` `: 60% 02:35 осталось
Копирование ``.` `: 65% 02:20 осталось
Копирование ``.` `: осталось 72% 01:52
Копирование ``.` `: осталось 80% 01:21
Копирование ``.`< ТАБЛИЦА>`: 86% 00:55 осталось
Копирование ``.` `: 92% 00:32 осталось
Копирование ``.` `: 99% 00:02 осталось
2021-10-08T19:18:19 Скопированные строки в порядке.
2021-10-08T19:18:19 Максимальное количество строк для метода reboot_constraints: 28380
Определение метода обновления внешних ключей...
2021-10-08T19:18:19 ``.` ` : слишком много строк: 257042; необходимо использовать drop_swap
2021-10-08T19:18:19 Удаление таблиц подкачки...
2021-10-08T19:18:19 Анализ новой таблицы...
2021-10-08T19:18:19 Сброшенные и поменявшиеся местами таблицы в порядке.
Старая таблица не удаляется, так как был указан параметр --no-drop-old-table.
2021-10-08T19:18:19 Сброс триггеров...
2021-10-08T19:18:19 Сброс триггеров в порядке.
Успешно изменена ``.` `.
Заключение
Инструмент предлагает множество функций для безопасного выполнения операций ALTER на больших рабочих столах. Тем не менее, есть некоторые примечательные вещи, о которых следует знать, прежде чем использовать этот инструмент. Кроме того, в документации рекомендуется сделать резервную копию рабочей среды и протестировать команду в тестовой среде, прежде чем запускать ее в рабочей среде.