在讨论问题之前,先看下面的mysql信息
mysql> show status like "%table_lock%";
+-----------------------+---------+
| Variable_name | Value |
+-----------------------+---------+
| Table_locks_immediate | 1290950 |
| Table_locks_waited | 1069 |
+-----------------------+---------+
2 rows in set (0.01 sec)
mysql版本5.0.77, 使用的存储引擎是innodb,而该引擎最主要的特点是transactional和row lock。按理说不会出现表锁才对,但是事实是出现了,并且锁的争用很严重。
查看mysql文档会发现,虽然innodb使用的的row lock,但是在处理具有auto increment字段的表的时候,会使用一种特殊的表锁——AUTO-INC。简单来说就是innodb会在内存里保存一个计数器用来记录auto_increment的值,当插入数据时,就会用一个表锁来锁住这个计数器,直到插入结束。一条一条插入问题不大,但是如果高并发插入,就会造成sql阻塞。
目前已知的解决方法有两种:
不用auto increment字段,自己维护主键生成。该方法中选择主键生成策略很重要, 要综合考虑简单和效率问题。假设使用uuid,虽然简单但是会造成该表的主键效率很低(innodb的主键是特殊的index,其他的index会引用主键,详见mysql文档)。
升级到最新的5.1版本。mysql在5.1.22版本以后提供了不同方式的auto-inc配置
innodb_autoinc_lock_mode = 0 (“traditional” lock mode)
innodb_autoinc_lock_mode = 1 (“consecutive” lock mode)
innodb_autoinc_lock_mode = 2 (“interleaved” lock mode)
PS:使用复制功能时请详细阅读文档
分享到:
2009-02-23 13:27
浏览 3515
论坛回复 / 浏览 (1 / 3982)
分类:数据库
评论
1 楼
sdh5724
2009-03-06
不错, 不过, 你要这么高的写入性能? innodb合适么