AUTO-INC锁的一些思考

AUTO-INC锁是一个表级锁,这种锁是作用于语句的而不是事务(即语句执行完了锁就会被释放)。innodb_autoinc_lock_mode用于控制AUTO-INC的锁表逻辑,可能的取值为0,1,2.

innodb_autoinc_lock_mode=0 (每次都会产生表锁)

不管是对于simple inserts(insert into values),bulk inserts(insert into select,replace select),mixed-mode inserts(insert into on deplicate key update,insert into values (1,'test'),(null,'test2'))类型的sql语句,每条sql语句都会产生auto-inc表锁,每一次产生新的行记录就会进行获取一个auto_increment值。此种情况下产生的insert_id是连续的,但是并发性较差。

innodb_autoinc_lock_mode=1 (默认,可预判行数时使用新方式,不可确定数量时使用表锁,对于simple insert会获得批量的锁,保证连续插入)

保证同一条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操作。

innodb_autoinc_lock_mode=2 (不会锁表,来一个sql则处理一个,会出现多个sql产生的insert_id相互交叉的现象)

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

猜你喜欢

转载自www.cnblogs.com/kuafu1104/p/11417788.html