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 API
mysql_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
DELAYED
|
Not_flushed_delayed_rows |
Количество строк, ожидающих записи |
Чтобы увидеть эти переменные,
следует вызвать команду SHOW
STATUS или выполнить команду
mysqladmin extended-status.
Обратите внимание: если данная
таблица не используется, то
команда INSERT DELAYED
работает медленнее, чем обычная
команда INSERT. Кроме того,
возникает дополнительная нагрузка
на сервер, поскольку требуется
управлять отдельным потоком для
каждой таблицы, для которой
используется INSERT DELAYED.
Это означает, что команду INSERT
DELAYED следует применять только
тогда, когда в ней есть реальная
необходимость!
This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.
© 1995-2005 MySQL AB. All rights reserved.
