在生产服务器上,我有两个数据库:
- db,这是执行常见查询的地方
- db_archive,其中包含从数据库中清除的旧数据
在db_archive上,有一个表x,1.3 Go大小,InnoDB。该表没有外键(也没有任何键)。在 db_archive 上,除了我正在执行的查询(或连接)之外,没有其他查询(或连接):
ALTER TABLE x ADD COLUMN z INT(10) UNSIGNED NULL AFTER y;
我通过 watch 'du -m\#* x.*'
跟踪服务器上 x
重建的进度。一开始,一切都很顺利。重建正在进行,并且 SHOW PROCESSLIST;
是干净的(< 30 个打开的连接)。
在 925 Mo(超过 1342 Mo)左右的某个时刻,重建卡住,并且 SHOW PROCESSLIST;
显示连接堆积在 db
上。
这会一直持续到达到连接限制(2000 个连接),导致服务器不可用。那时,我别无选择,只能终止查询,以避免对生产造成太大损害。
Debian 6.0.5
上的 MySQL 版本为 5.2.12-MariaDB
。
我知道有一些解决方案可以避免这个问题(例如将 db_archive 移动到另一台服务器),但是,我只是不明白 db
数据库如何受到对另一个数据库的操作的影响,没有任何关系。
最佳答案
更仔细地查看PROCESSLIST
。我希望您找到一个归档进程,该进程在写入 db_archive
时锁定它在 db
中读取的表。 时间
列中的最大值很可能表明是坏人。
可能涉及ALTER
,也可能是转移注意力。
以下是意外锁定的常见模式:
- 冗长的
SELECT
正在读取 table1。 - 某些写入(
ALTER
合格)尝试访问 table1,但它处于事务中或以其他方式接触 table2。SELECT
会阻止对 table1 的写入,因此写入会挂起。 - 现在,甚至 table1 和 table2 上的
SELECT
也可能被阻止。
关于mysql - 如何防止在 ALTER 不相关表期间整个服务器被锁定?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50871722/