首页 > 代码库 > mysql主键设置成auto_increment时,进行并发性能测试出现主键重复Duplicate entry 'xxx' for key 'PRIMARY'

mysql主键设置成auto_increment时,进行并发性能测试出现主键重复Duplicate entry 'xxx' for key 'PRIMARY'

mysql主键设置成auto_increment时,进行并发性能测试出现主键重复Duplicate entry ‘xxx‘ for key ‘PRIMARY‘

解决方法:

在my.cnf的[mysqld]片段中添加设置innodb_autoinc_lock_mode=0

同时注意调大jdbc的活跃链接数,如设置 jdbc.maxActive=300,因为设置innodb_autoinc_lock_mode=0可能导致链接过多。

注意,这种方式只需要在并发性能测试时设置,因为这种方式在插入记录时需进行全表锁定,性能较差,平时生产环境中只需使用默认的设置innodb_autoinc_lock_mode=1即可,mysql的官方文档有说明:


http://dev.mysql.com/doc/refman/5.6/en/innodb-auto-increment-configurable.html

innodb_autoinc_lock_mode属性的含义如下:

1、innodb_autoinc_lock_mode = 0 (“traditional” lock mode)
这种方式就和mysql5.1.22以前一样,这种方式的特点就是“表级锁定”,并发性较差


2、innodb_autoinc_lock_mode = 1 (“consecutive” lock mode)
这种方式是新版本中的默认方式,推荐使用,并发性相对较高,特点是“consecutive”,即保证同一条insert语句中新插入的auto_increment id都是连续的。
这种模式下:
“Simple inserts”:直接通过分析语句,获得要插入的数量,然后一次性分配足够的auto_increment id,只会将整个分配的过程锁住。
“Bulk inserts”:因为不能确定插入的数量,因此使用和以前的模式相同的表级锁定。
“Mixed-mode inserts”:直接分析语句,获得最坏情况下需要插入的数量,然后一次性分配足够的auto_increment id,只会将整个分配的过程锁住。需要注意的是,这种方式下,会分配过多的id,而导致”浪费“。比如INSERT INTO t1 (c1,c2) VALUES (1,’a‘), (NULL,’b‘), (5,’c‘), (NULL,’d‘);会一次性的分配5个id,而不管用户是否指定了部分id;INSERT … ON DUPLICATE KEY UPDATE一次性分配,而不管将来插入过程中是否会因为duplicate key而仅仅执行update操作。
注意:当master mysql版本<5.1.22,slave mysql版本>=5.1.22时,slave需要将innodb_autoinc_lock_mode设置为0,因为默认的 innodb_autoinc_lock_mode为1,对于INSERT … ON DUPLICATE KEY UPDATE和INSERT INTO t1 (c1,c2) VALUES (1,’a‘), (NULL,’b‘), (5,’c‘), (NULL,’d‘);的执行结果不同,现实环境一般会使用INSERT … ON DUPLICATE KEY UPDATE。


3、innodb_autoinc_lock_mode = 2 (“interleaved” lock mode)
这种模式是来一个分配一个,而不会锁表,只会锁住分配id的过程,和innodb_autoinc_lock_mode = 1的区别在于,不会预分配多个,这种方式并发性最高。但是在replication中当binlog_format为statement-based时 (简称SBR statement-based replication)存在问题,因为是来一个分配一个,这样当并发执行时,“Bulk inserts”在分配的时会同时向其他的INSERT分配,会出现主从不一致(从库执行结果和主库执行结果不一样),因为binlog只会记录开始的 insert id。

参考文档:

http://biancheng.dnbcw.info/mysql/356243.html

mysql主键设置成auto_increment时,进行并发性能测试出现主键重复Duplicate entry 'xxx' for key 'PRIMARY'