# 修改表结构为什么会导致库挂了

场景重现

# 时序展示

session A session B session C session D
begin;
select * from t where id =?
begin;
select * from t where id =?
alter table t
add column age int(3) not null
begin;
select * from t where id =?

以上时序中session C需要获取到MDL写锁而要等待其他事务释放MDL读锁, 在等待锁释放期间, session D等之类的其他事务又需要对表进行操作进而申请MDL读锁, 此时数据库连接都会被阻塞, 如果应用程序有重起连接重试的场景或者突然高并发的情况发生, 都会导致数据库连接瞬间爆满, 最终数据库挂了.

# 解决方案

# 1. 停掉应用程序修改热点表数据结构

# 2. 避免长事务或kill掉长事务再执行

# 3. 设置DDL语句等待时间, 尝试拿锁, 尽量避免阻塞其他线程

如果未拿到锁超时, 可以下次再重试执行.

# AliSQL分支提供的此功能, 已被MariaDB合并.
ALTER TABLE tbl_name NOWAIT add column ...;
ALTER TABLE tbl_name WAIT N add column ...;
修改于: 8/11/2022, 3:17:56 PM