Когда mysqldump запускается с --lock-tables для базы данных, использующей таблицы MyISAM, в документации указано, что каждая таблица заблокирована с помощью READ LOCAL. Насколько я понимаю, READ LOCAL допускает одновременные вставки из других сеансов.
У меня есть несколько вопросов по этому поводу.
С READ LOCAL единственными операциями, недоступными для других сеансов, являются TRUNCATE, UPDATE и DELETE. INSERTS и SELECTS будут нормально обрабатываться в таблице, заблокированной с помощью READ LOCAL из других сеансов, при условии, что в таблице нет «дыр». Это правильное предположение?
В случае создания резервных копий с помощью mysqldump, поскольку одновременные вставки разрешены, а таблицы блокируются последовательно (несколько резервных копий таблиц), то что мешает реляционным таблицам стать несовместимыми? Будет ли дамп таблицы содержать данные, которые, возможно, были добавлены после выдачи LOCK TABLE?
Спасибо за уделенное время.
В документации это совсем не ясно. Я считаю, что здесь происходит то, что LOCK TABLE
заставляет сеанс читать только строки или байты или что-то еще, что существовало, когда таблица была заблокирована, независимо от того, какого размера таблица на самом деле, когда она доходит до нее. Строки можно продолжать вставлять в таблицу, но только в конце, за заблокированной частью таблицы.
Думаю, ваше предположение верно. Я просто проверил, чтобы подтвердить, и READ LOCAL позволяет одновременно выполнять INSERT из других сеансов, которые не будут видны сеансу блокировки, пока он не вызовет UNLOCK TABLE. UPDATE, TRUNCATE и DELETE блокируются, пока удерживается блокировка READ LOCAL. Я не проверял состояние отверстий.
Что касается ссылочной целостности, опция mysqldump --lock-tables (которая включена по умолчанию, начиная с версии 5.1, не уверен насчет более ранних версий) блокирует сразу все таблицы в базе данных с помощью одного оператора LOCK TABLES перед сбросом данных, поэтому не должно быть возможности для несогласованного представления данных. Вы можете подтвердить это, включив общий журнал запросов и запустив mysqldump.
Однако обратите внимание на это на странице руководства:
Please note that when dumping multiple databases, --lock-tables locks tables for each database separately. Therefore, this option does not guarantee that the tables in the dump file are logically consistent between databases. Tables in different databases may be dumped in completely different states.
Кроме того, я знаю, что вы, вероятно, это понимаете, но MyISAM может быть неправильным механизмом хранения, если вас беспокоит ссылочная целостность.
Вот простой код, который я использовал для подтверждения вашего предположения:
ПЕРВАЯ СЕССИЯ
create database testing;
use testing;
create table t1 (a int not null, primary key(a));
insert into t1 values (1),(2),(3),(4),(5),(6);
select * from t1;
lock tables t1 read local;
ВТОРАЯ СЕССИЯ
use testing;
insert into t1 values (7);
-- Shows row with a=7
select * from t1;
ПЕРВАЯ СЕССИЯ
-- Does not show row with a=7
select * from t1;
ВТОРАЯ СЕССИЯ
-- Blocked
update t1 set a=8 where a=2;
Надеюсь, это поможет.