标签:innodb auto-increment mysql
以下情况可能吗?
MySQL版本5.6.15
CREATE TABLE my_table (
id int NOT NULL AUTO_INCREMENT.
data1 int,
data2 timestamp,
PRIMARY KEY (id)
) ENGINE=InnoDB;
innodb_autoinc_lock_mode = 1
AUTO_INCREMENT = 101
> 0 ms:运行查询A:插入到my_table(data1,data2)值(101,FROM_TIMESTAMP(1418501101)),(102,FROM_TIMESTAMP(1418501102)),.. [总共200个值] ..,(300, FROM_TIMESTAMP(1418501300));
> 500 ms:运行查询B:INSERT INTO my_table(data1,data2)VALUES(301,FROM_TIMESTAMP(1418501301));
> 505 ms:查询B完成.该行的ID为301.
> 1000毫秒:从my_table中选择ID,其中id> = 300; —将返回一行(id = 301).
> 1200 ms:查询A完成.这些行的id为101到id为300.
> 1500毫秒:从my_table中选择ID,其中ID> == 300; —将返回两行(id = 300,id = 301).
换句话说,是否可以选择id = 301的行早于选择id = 300的行?
以及如何避免呢?
解决方法:
为什么查询A要花一秒钟以上的时间来运行? !是的,您所看到的正是我所期望的行为.
在插入新行时立即保留主键101到300.这需要几毫秒的时间.然后,它花费超过1秒钟的时间来重建索引,并在运行所有查询的过程中完成了所有操作,并使用下一个可用的auto_increment:301插入了新行.
正如Alin Purcaru所说的那样,您可以通过更改锁定模式来避免此特定问题,但是它将引起性能问题(查询B而不是在5毫秒内执行,而是需要700毫秒来执行.
在高负载情况下,问题成倍恶化,最终您将看到“连接过多”错误,有效地使整个数据库脱机.
另外,在其他少数情况下,auto_increment可以给出“乱序”的增量,这不能通过锁定解决.
我个人认为最好的选择是使用UUID代替auto_increment作为主键,然后使用一个timestamp列(以微秒为单位的两倍)来确定将哪些顺序行插入到数据库中.
标签:innodb,auto-increment,mysql 来源: https://codeday.me/bug/20191120/2047975.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。