Заморозка и блокировка таблицы

«Заморозка» таблицы полезна, когда вы хотите сделать физическую копию или резервную копию. Она помечает файлы таблицы как замороженные и показывает, где они хранятся. После заморозки вы можете безопасно скопировать эти файлы в другое место. Вы всё ещё можете добавлять новые документы в замороженную таблицу до тех пор, пока она не достигнет rt_mem_limit, но новые данные остаются в памяти и не записываются на диск, пока таблица не будет разморожена. Если таблица превысит rt_mem_limit, все изменения приостанавливаются до разморозки. Если демон остановится неожиданно, любые несохранённые данные восстанавливаются из binlog.

«Блокировка» таблицы полезна для логических резервных копий. Она не останавливает внутренние задачи обслуживания, такие как операции слияния дисковых чанков или запись RAM-чанка на диск. Она блокирует только операции записи. Это значит, что вы не можете вставлять, заменять или обновлять данные в заблокированной таблице. Это полезно для таких инструментов, как mysqldump, потому что блокировка гарантирует логическую согласованность данных. Например, без блокировки, если вы замените документ во время дампа, старая версия может уже попасть в дамп, а новая версия появится позже, обе с одним и тем же ID документа. Блокировка таблицы предотвращает такую ситуацию.

Заморозка таблицы

FREEZE tbl1[, tbl2, ...]

FREEZE подготавливает таблицу real-time/plain для безопасного резервного копирования. В частности, он:

  1. Деактивирует сжатие таблицы. Если таблица в данный момент сжимается, FREEZE аккуратно прервет этот процесс.
  2. Переносит текущий RAM-чанк в дисковый чанк.
  3. Сбрасывает атрибуты.
  4. Отключает неявные операции, которые могут изменить файлы на диске.
  5. Увеличивает счётчик блокировок таблицы.
  6. Показывает фактический список файлов, связанных с таблицей.

Если таблица уже заморожена (заблокирована), FREEZE:

  1. Увеличит счётчик блокировок таблицы.
  2. Покажет фактический список файлов, связанных с таблицей.

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

  1. FREEZE одну или несколько таблиц.
  2. Сохраните вывод команды FREEZE и сделайте резервную копию указанных файлов.
  3. UNFREEZE таблицу(ы) после завершения.
‹›
  • Example
Example
📋
FREEZE t;
‹›
Response
+-------------------+---------------------------------+
| file              | normalized                      |
+-------------------+---------------------------------+
| data/t/t.0.spa    | /work/anytest/data/t/t.0.spa    |
| data/t/t.0.spd    | /work/anytest/data/t/t.0.spd    |
| data/t/t.0.spds   | /work/anytest/data/t/t.0.spds   |
| data/t/t.0.spe    | /work/anytest/data/t/t.0.spe    |
| data/t/t.0.sph    | /work/anytest/data/t/t.0.sph    |
| data/t/t.0.sphi   | /work/anytest/data/t/t.0.sphi   |
| data/t/t.0.spi    | /work/anytest/data/t/t.0.spi    |
| data/t/t.0.spm    | /work/anytest/data/t/t.0.spm    |
| data/t/t.0.spp    | /work/anytest/data/t/t.0.spp    |
| data/t/t.0.spt    | /work/anytest/data/t/t.0.spt    |
| data/t/t.meta     | /work/anytest/data/t/t.meta     |
| data/t/t.ram      | /work/anytest/data/t/t.ram      |
| data/t/t.settings | /work/anytest/data/t/t.settings |
+-------------------+---------------------------------+
13 rows in set (0.01 sec)

Столбец file указывает пути к файлам таблицы внутри data_dir запущенного экземпляра. Столбец normalized отображает абсолютные пути к тем же файлам. Чтобы сделать резервную копию таблицы, просто скопируйте указанные файлы без дополнительной подготовки.

Когда таблица заморожена, выполнение запросов UPDATE невозможно; они будут ждать, пока таблица не будет разморожена.

Также запросы DELETE и REPLACE имеют некоторые ограничения во время заморозки таблицы:

  • Если DELETE затрагивает документ в текущем RAM-чанке — это разрешено.
  • Если DELETE влияет на документ в дисковом чанке, но он был ранее удалён — это разрешено.
  • Если DELETE изменит фактический дисковый чанк — запрос будет ждать, пока таблица не будет разморожена.

Ручной FLUSH RAM-чанка замороженной таблицы сообщит об «успехе», но реального сохранения не произойдет.

DROP/TRUNCATE замороженной таблицы разрешены, так как эти операции не являются неявными. Предполагается, что если вы удаляете или очищаете таблицу, вам не нужна её резервная копия; значит, её изначально не следовало замораживать.

INSERT в замороженную таблицу поддерживается, но с ограничениями: новые данные будут храниться в RAM (как обычно) до достижения rt_mem_limit; затем новые вставки будут ждать, пока таблица не будет разморожена.

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

Разморозка таблицы

UNFREEZE tbl1[, tbl2, ...]

Команда UNFREEZE уменьшает счётчик блокировок таблицы, и если он достигает нуля, повторно активирует ранее заблокированные операции и возобновляет внутреннюю службу сжатия. Все операции, ожидавшие разморозки таблицы, также возобновятся и завершатся нормально.

‹›
  • Example
Example
📋
UNFREEZE tbl;

Проверка состояния блокировки таблицы

Вы можете использовать SHOW table_name STATUS, чтобы проверить, заморожена таблица или нет.

Счётчик блокировок отображается в статусе таблицы в столбце locked. Значение ноль означает, что таблица не заморожена, а ненулевое значение отражает количество активных блокировок. Каждая явная команда FREEZE и неявная блокировка (например, когда таблица является частью кластера и репликационная процедура выбирает её в качестве донора для реплики) увеличивает счётчик. Каждая команда UNFREEZE уменьшает счётчик, в конечном итоге до нуля.

‹›
  • Example
Example
📋
SHOW TABLE `foo` STATUS LIKE 'locked';
‹›
Response
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| locked        | 2     |
+---------------+-------+
1 row in set (0,00 sec)

Блокировка таблицы

lock tables tbl1 read[, tbl2 read, ...]

Вы можете явно блокировать таблицы в сессии SQL-клиента, чтобы координировать доступ с другими сессиями или чтобы остановить другие сессии от изменения данных, пока вам нужен эксклюзивный доступ. Сессия может блокировать или разблокировать таблицы только для себя. Она не может блокировать или разблокировать таблицы от имени другой сессии. Блокировки можно использовать только в SQL-сессиях, подключённых через протокол MySQL. Пока таблица заблокирована, ни один протокол не может изменить её данные (SQL / HTTP / бинарный). Блокировки также не работают для таблиц, которые принадлежат репликационному кластеру.

Manticore поддерживает только чтение (shared) блокировки. Запись (exclusive) блокировки не поддерживаются.

Когда сессия запрашивает блокировку на чтение, Manticore:

  1. Проверяет, что соединение использует протокол MySQL.
  2. Проверяет, что таблицу можно заблокировать. Она должна быть локальной real-time или percolate таблицей и не должна быть частью репликационного кластера.
  3. Автоматически снимает любые блокировки, которые сессия уже держит.
  4. Ожидает завершения всех текущих операций вставки, замены, обновления или удаления в таблице.
  5. Увеличивает счетчик блокировок на чтение таблицы (см. SHOW LOCKS).

Любое изменяющее выражение (insert/replace/update/delete) сначала проверяет, заблокирована ли таблица на чтение. Если да, выражение завершается с ошибкой table is locked.

‹›
  • Example
Example
📋
--------------
LOCK TABLES tbl READ
--------------
Query OK, 0 rows affected (0.000 sec)
--------------
LOCK TABLES tbl READ, tbl2 WRITE
--------------
Query OK, 0 rows affected, 1 warning (0.000 sec)
--------------
SHOW WARNINGS
--------------
+---------+------+--------------------------------+
| Level   | Code | Message                        |
+---------+------+--------------------------------+
| warning | 1000 | Write lock is not implemented. |
+---------+------+--------------------------------+
1 row in set (0.000 sec)

UNLOCK TABLES

Команда UNLOCK TABLES явно снимает любые блокировки таблиц, удерживаемые текущей SQL-сессией.

Если соединение для клиентской сессии завершается, нормально или ненормально, демон неявно снимает все блокировки таблиц, удерживаемые сессией. Если клиент переподключается, блокировки больше не действуют.

‹›
  • Example
Example
📋
UNLOCK TABLES;

SHOW LOCKS

Команда SHOW LOCKS выводит список всех таблиц, которые в данный момент заблокированы или заморожены.
Каждая строка показывает тип таблицы, ее имя, вид блокировки и счетчик, указывающий, сколько раз эта блокировка была применена.

Тип блокировки может быть:

  • read — таблица защищена блокировкой на чтение. Изменяющие выражения будут завершаться с ошибкой, пока блокировка не будет снята.
  • freeze — таблица заморожена. Это останавливает любые операции, которые записывают данные на диск, пока таблица не будет разморожена.
‹›
  • Example
Example
📋
SHOW LOCKS;
‹›
Response
+-----------+------+-----------+-----------------+
| Type      | Name | Lock Type | Additional Info |
+-----------+------+-----------+-----------------+
| rt        | a    | read      | Count: 1        |
| percolate | bar  | freeze    | Count: 3        |
| rt        | foo  | freeze    | Count: 2        |
+-----------+------+-----------+-----------------+
3 rows in set (0,01 sec)
Last modified: November 20, 2025