INSERT DELAYED ...
Опция DELAYED для команды INSERT является специфической для MySQL
возможностью, которая очень полезна, если клиент не может ждать завершения
команды INSERT. Такая проблема встречается часто - она возникает, когда
MySQL используется для ведения журналов (проще говоря, для логгинга) и при
этом периодически запускаются команды SELECT и UPDATE, для выполнения
которых требуется много времени. Оператор DELAYED был введен в версию
MySQL 3.22.15. Он является расширением MySQL к ANSI SQL92.
INSERT DELAYED работает только с таблицами типа ISAM и MyISAM. Следует
учитывать, что таблицы MyISAM поддерживают одновременное выполнение SELECT
и INSERT, поэтому если нет свободных блоков в середине файла данных, то
необходимость в применении INSERT DELAYED возникает очень редко.
See Раздел 7.1, «Таблицы MyISAM».
При использовании оператора INSERT DELAYED клиент сразу же получает
успешный ответ от сервера, а запись будет добавлена в таблицу сразу же
после того, как эту таблицу перестанет использовать другой поток.
Еще одно существенное преимущество применения оператора INSERT DELAYED
заключается в том, что данные от многих клиентов собираются вместе и
записываются одним блоком. Это намного быстрее, чем несколько отдельных
операций вставки.
Обратите внимание: в настоящее время все записи, поставленные в очередь на
добавление, хранятся только в памяти до тех пор, пока они не будут
записаны на диск. Отсюда следует, что если выполнение mysqld будет
завершено принудительно (kill -9) или программа умрет, то все находящиеся
в очереди данные, которые не записаны на диск, будут потеряны!.
Ниже детально описано, что происходит при использовании опции DELAYED в
командах INSERT или REPLACE. В этом описании ``поток'' понимается как
поток, принимающий команду INSERT DELAYED, а ``обработчик'' - это поток,
который обрабатывает все команды INSERT DELAYED в конкретной таблице.
При выполнении потоком команды
DELAYEDдля таблицы создается поток-обработчик для обработки всех командDELAYEDв данной таблице, если подобный обработчик уже не существует.Данный поток проверяет, выполнил ли уже обработчик блокировку
DELAYED; если нет, то он предписывает обработчику сделать это. БлокировкаDELAYEDможет быть осуществлена даже в случае, если блокировкиREADилиWRITEна данной таблице уже выполнены другими потоками. Однако обработчик будет ожидать всех блокировокALTER TABLEи завершения всех командFLUSH TABLES, чтобы убедиться в том, что структура таблицы соответствует последнему обновлению.Поток выполняет команду
INSERT, но вместо записи строки в таблицу он ставит финальную копию этой строки в очередь, управляемую потоком-обработчиком. Поток отмечает все синтаксические ошибки и сообщает о них клиентской программе.Клиент не может уведомить о количестве дубликатов или значении
AUTO_INCREMENTдля данной результирующей строки; он также не может получить эти данные с сервера, поскольку командаINSERTвозвращает результат до полного завершения операции вставки. По той же причине ничего существенного не даст и использование функции C APImysql_info().-
Обновление журнала обновлений производится потоком-обработчиком после вставки строки в таблицу. В случае многострочной вставки обновление журнала обновлений производится при записи первой строки.
После записи каждых
delayed_insert_limitстрок, обработчик проверяет, не находятся ли в ожидании выполнения какие-либо командыSELECT. Если да, то обработчик перед продолжением своей работы ``пропускает их вперед'' на выполнение.Если очередь обработчика больше не содержит строк, то с данной таблицы будет снята блокировка. Если в течение
delayed_insert_timeoutсекунд не поступят никакие новые командыINSERT DELAYED, то обработчик завершит свою работу.Если более, чем
delayed_queue_sizeстрок уже ожидают в очереди обработчика, то поток, запрашивающийINSERT DELAYED, будет ждать, пока не освободится место в очереди. Таким образом можно иметь уверенность в том, чтоmysqldне займет всю память сервера для хранения запросов данной очереди.Поток-обработчик будет наблюдаться в списке процессов MySQL со значением
delayed_insertв столбцеCommand. Поток-обработчик можно уничтожить запуском командыFLUSH TABLESили командойKILL номер_потока. Однако перед своим завершением он вначале сохранит в таблице все поставленные в очередь строки. В процессе сохранения он не будет принимать никаких новых командINSERTот иного потока. При выполнении после этого командыINSERT DELAYEDбудет создан новый поток-обработчик. Обратите внимание: отсюда следует, что командыINSERT DELAYEDимеют более высокий приоритет, чем обычные командыINSERT, если уже существует запущенный обработчикINSERT DELAYED! Другие команды обновления должны ожидать, пока не опустеет очередьINSERT DELAYEDили же пока кто-либо не прекратит выполнение потока-обработчика (с помощьюKILL номер_потока) или не выполнитFLUSH TABLES.-
Представленные в таблице переменные обеспечивают информацию об
INSERT DELAYED:Переменная Значение Delayed_insert_threadsКоличество потоков-обработчиков Delayed_writesКоличество строк, записанных INSERT DELAYEDNot_flushed_delayed_rowsКоличество строк, ожидающих записи Чтобы увидеть эти переменные, следует вызвать команду
SHOW STATUSили выполнить командуmysqladmin extended-status.
Обратите внимание: если данная таблица не используется, то команда INSERT DELAYED работает медленнее, чем обычная команда INSERT. Кроме того,
возникает дополнительная нагрузка на сервер, поскольку требуется управлять
отдельным потоком для каждой таблицы, для которой используется INSERT DELAYED. Это означает, что команду INSERT DELAYED следует применять
только тогда, когда в ней есть реальная необходимость!