INSERT DELAYED ...
该语句的DELAYED
选项
INSERT
是标准 SQL 的 MySQL 扩展,可用于某些类型的表(例如MyISAM
)。当客户端使用
INSERT DELAYED
时,它会立即从服务器获得一个 okay,并且当该表未被任何其他线程使用时,该行将排队等待插入。
INSERT DELAYED
INSERT
如果该表未以其他方式使用,则比正常速度慢。服务器还需要额外的开销来为每个有延迟行的表处理一个单独的线程。这意味着您应该
INSERT DELAYED
仅在确实确定需要时才使用它。
从 MySQL 5.6.6 开始,INSERT
DELAYED
已弃用;希望在未来的版本中将其删除。使用INSERT
(without DELAYED
) 代替。
排队的行仅保存在内存中,直到它们被插入到表中。这意味着如果您强行终止
mysqld(例如,with
kill -9
)或者如果mysqld意外终止,则任何尚未写入磁盘的排队行都会丢失。
使用 有一些限制
DELAYED
:
INSERT DELAYED
仅适用于MyISAM
、MEMORY
、ARCHIVE
和BLACKHOLE
表格。对于不支持的引擎,会DELAYED
出现错误。INSERT DELAYED
如果与已锁定的表一起使用, 则会发生错误,LOCK TABLES
因为插入必须由单独的线程处理,而不是由持有锁的会话处理。对于
MyISAM
表,如果数据文件中间没有空闲块,则支持concurrentSELECT
andINSERT
statements。在这些情况下,您很少需要使用INSERT DELAYED
withMyISAM
。INSERT DELAYED
应该只用于INSERT
指定值列表的语句。服务器忽略DELAYED
forINSERT ... SELECT
或INSERT ... ON DUPLICATE KEY UPDATE
语句。因为该
INSERT DELAYED
语句立即返回,所以在插入行之前,您不能使用LAST_INSERT_ID()
来获取AUTO_INCREMENT
该语句可能生成的值。DELAYED
SELECT
行在实际插入之前 对语句不可见 。INSERT DELAYED
只要 的值为 或,就作为简单INSERT
(即没有DELAYED
选项)处理。(在后一种情况下,该语句不会触发切换到基于行的日志记录,因此使用基于语句的格式进行记录。)binlog_format
STATEMENT
MIXED
binlog_format
这在使用基于行的二进制日志记录模式(设置为ROW
) 时不适用,在该模式下,INSERT DELAYED
语句始终使用DELAYED
指定的选项执行,并记录为行更新事件。DELAYED
在副本服务器上被忽略,因此在副本服务器上INSERT DELAYED
被视为正常INSERT
。这是因为DELAYED
可能导致从站具有与源不同的数据。如果表被写锁定并用于修改表结构, 挂起
INSERT DELAYED
的语句将丢失 。ALTER TABLE
INSERT DELAYED
不支持视图。INSERT DELAYED
分区表不支持。
下面详细描述当您使用
或
DELAYED
选项
时会发生什么。在此描述中,
“ thread ”是接收
语句
的线程, “ handler ”是处理
特定表的所有语句的线程。
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
语句仍在挂起。如果是这样,它允许这些在继续之前执行。当处理程序的队列中没有更多行时,表将解锁。如果在几秒钟
INSERT DELAYED
内没有收到新的语句delayed_insert_timeout
,处理程序将终止。delayed_queue_size
如果特定处理程序队列中有 多个 行待处理,则请求线程INSERT DELAYED
会一直等待,直到队列中有空间为止。这样做是为了确保 mysqld不会将所有内存用于延迟内存队列。处理程序线程显示在列中的 MySQL 进程列表
delayed_insert
中Command
。如果您执行一条FLUSH TABLES
语句或用 .kill 杀死它,它就会被杀死。但是,在退出之前,它首先将所有排队的行存储到表中。在此期间它不接受 来自其他线程的任何新语句。如果在此之后执行一条语句,则会创建一个新的处理程序线程。KILL
thread_id
INSERT
INSERT DELAYED
这意味着如果有处理程序正在运行,
INSERT DELAYED
语句的优先级高于普通语句 。其他更新语句必须等到队列为空、有人终止处理程序线程(使用 )或有人执行.INSERT
INSERT DELAYED
INSERT DELAYED
KILL
thread_id
FLUSH TABLES
以下状态变量提供有关
INSERT DELAYED
语句的信息。状态变量 意义 Delayed_insert_threads
处理程序线程数 Delayed_writes
写的行数 INSERT DELAYED
Not_flushed_delayed_rows
等待写入的行数 您可以通过发出
SHOW STATUS
语句或执行mysqladmin 扩展状态 命令来查看这些变量。