MySQL|select+alter 造成阻塞

哦这个MDL钥匙真是让人头疼啊,我实话告诉你吧。
去年我在上海,那个项目因数据库瓶颈而变得疯狂。
这是 SELECT 和 ALTER 相互锁定的情况。

当时有朋友写了一个定时任务,每天早上加一个字段。
因此,在未提交的系统中始终存在 SELECT 查询。
有可能是某些操作员停止运行而忘记回滚。
他添加字段的ALTER TABLE总是卡在那里,等待,最终拖慢了整个数据库的速度。

这就是 MDL 锁正在做的事情。
您的 SELECT 查询持有读锁(MDL S 锁),因为事务尚未提交。
如果你再次去ALTER TABLE。
您必须等待读锁被释放。
如果你不想错过的话,你可以盯着看。
这时,其他想要读取的SELECT操作或者想要改变的DML操作就必须等待,造成连锁反应。

然后我对他们说,你必须先检查任何交易是否被锁定,而不提交。
可以使用SHOW进程列表查看是否有很多人在等待表元数据锁。
如果您看不到此命令,则可以对任何线程采取更积极的方法您必须检查 Performance_schema 中的表以找出哪个事务持有密钥。

这就是解决方案。
要求运营商快速回滚交易,或者以后不要长时间无法提交交易。
如果没有其他办法,就必须找一个业务低峰时段,比如午夜,进行ALTER操作。
或者使用像 pt-online-schema-change 这样的在线模式更改工具,表不会被锁定,但性能会更差。

对于开发者来说,最重要的是培养良好的实践。
交易完成后提交;不要总是兑现诺言。
这是最实用、最有效的。
想一想,如果每笔交易都按时提交,您是否还在担心MDL锁定问题?它根本不会存在。

所以说到底,这次MDL停摆问题还是一个管理问题,一个人员流动问题。
技术层面能做的就是检查锁;就是改变计划并监控情况,防止再次发生。
其他一切都必须由人民来管理。

MySQL中AUTO_INCREMENT达到最大值怎么办

坦白说,MySQL的自增ID已经结束了,这是相当令人担忧的。
我们必须找到一种方法来应对它。

第一种方法是将 INTSIGNED 更改为 INTUNSIGNED。
你看,INTSIGNED最大为2 1 4 7 4 8 3 6 4 7 ,修改后可以达到4 2 9 4 9 6 7 2 9 5 ,这意味着空间多了很多。
但是,如果使用ALTER TABLE修改表,则需要重建表,这可能会导致问题。

其次,尝试该方法而不重新创建它。
例如,在 ALTER TABLE 时添加 ALGORITHM=INPLACE 或 ALGORITHM=INSTANT。
但说实话,这两个方法可能不支持改变类型。
如果改不了,就得用ALGORITHM=COPY,还是需要重新构建,可能有点不方便。

第三种方法是使用外部工具。
就像 pt-online-schema-change 或 gh-ost。
这些东西可以改变表结构而不阻塞服务。
你做了什么?只需先创建影子表,同步数据,然后更改名称即可。
这个影响不大。

第四种方法是创建一个新时钟。
结构与旧表相同,但ID改为INTUNSIGNED,并且从对应的值开始递增。
然后,您从旧表中移动数据并更改名称。
使用这种方法一定要小心,确保数据正确,不要让老客户感到困惑。

第五种方法是使用MySQL Shell或Percona Toolkit。
这些工具可以更快地传输数据并且需要更少的精力。

最后,最好提前知道会很拥挤。
如何使用自增ID进行监控监控以及什么时候结束?结束前把它整理好。
无论采用上述哪种方式,如果提前这样做,服务都不会中断。

在更改表之前,您必须备份表,评估影响,并找到合适的时间来执行此操作。
读写分离或者负载均衡也可以分担一些压力。
这样就可以解决自增ID问题,服务也不会延迟。