INSERT 的完成,这将会是很有用的。This is a common problem when you use MySQL for logging and 当你打开日志记录使用 MySQL 并且你周期性的需花费很长时间才完成的 SELECT 和 UPDATE 语句时,这将是一个很普遍的问题。DELAYED 在 MySQL 3.22.15 中被引入。它是 MySQL 对 ANSI SQL92 的一个扩展。
INSERT DELAYED 仅仅工作与 ISAM 和 MyISAM 表。注意,因为 MyISAM 表支持并发的 SELECT 和 INSERT,如果在数据文件中没有空闲的块,那你将很少需要对 MyISAM 表使用 INSERT DELAYED。查看章节 7.1 MyISAM 表。
当你使用 INSERT DELAYED 时,客户端将立即得到一个 OK,当表不被任何其它线程使用时,该行将被插入。
使用 INSERT DELAYED 的另一个主要的好处就是,从很多客户端来的插入请求会被打包在一起并写入一个块中。这比做许多单独的插入要快的多。
注意,当前的记录行队列是被存储在内存中的,一直到他们被插入到表中。这就意味着,如果你使用强制的方法(kill -9) 杀死 mysqld,或者如果意外地死掉,任何没有写到磁盘中的记录行队列都将会丢失!
下面详细地描述当你为 INSERT 或 REPLACE 使用 DELAYED 选项时会发生什么。在这个描述中,“线程”是遇到一个 INSERT DELAYED 命令的线程,“处理器”是处理所有对于一个特定表的 INSERT DELAYED 语句的线程。
- 当一个线程对一个表执行一个
DELAYED语句时,将会创建一个处理器线程用以处理对该表的所有DELAYED语句,除非这样的处理器已经存在。 - 线程检查处理器是否已经获得了一个
DELAYED锁;如果还没有,这告诉处理程序去获得。即使其它的线程已在表上加了一个READ或WRITE锁,也能获得DELAYED锁。然而,处理器将等待所有的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 进程列表中的
Command列上显示为delayed_insert。如果执行一个FLUSH TABLES命令或以KILL thread_id杀死它,它将会被杀死。然而,它在退出前会首先将所队列记录行保存到表中。这些期间,它将不再接收其它线程的任何新的INSERT命令。如果再此之后执行一个INSERT DELAYED命令,一个新处理器线程将会被创建。 注意,上面的意思是,如果一个INSERT DELAYED处理器已在运行,那么INSERT DELAYED


