软件数据库测试为什么一行UPDATE能拖垮整个DB?
在电商大促秒杀、票务秒杀或金融交易等高并发业务场景,数据库最常遇到的是锁等待。有物流企业大促复盘发现,订单创建接口在高峰期响应时间从20ms暴增至2s,监控显示数据库的锁等待时间占据了90%以上。
在MySQL InnoDB引擎中,锁的本质是对数据库共享资源的并发访问控制,是实现事务ACID中隔离性的支撑。锁机制可分为多个方面:
按锁粒度划分:全局锁、表级锁、行级锁、页级锁。行级锁是InnoDB的重要优势,粒度最细,并发度最高,但开销大、加锁慢、会出现死锁。
按锁权限划分:共享锁(S锁)和排他锁(X锁)。S锁多个事务可同时持有,互不阻塞;X锁则和所有锁互斥。所有锁均在事务提交或回滚后释放。
按行锁算法划分(RR隔离级别下):记录锁(Record Lock)锁定具体行;间隙锁(Gap Lock)锁定记录间的空隙,防止其他事务插入;临键锁(Next-Key Lock)是记录锁+间隙锁的组合,完整包括索引记录及其间隙,是InnoDB解决幻读的机制。RC级别下间隙锁完全关闭,只存在记录行锁,锁范围更小,也是互联网业务的第一选择隔离级别。
规则:InnoDB的锁永远是加在索引上的,而不是物理数据行上。如果SQL没有命中任何索引,InnoDB无法定位到具体行,会对全表所有记录加锁,直接退化为表级锁。
死锁是指两个或多个事务互相等待对方释放资源,形成循环等待。当事务A持有锁X、事务B持有锁Y,而A需要Y、B需要X时,就会形成死锁。InnoDB会自动检测并回滚其中一个事务来释放资源,但高并发下的死锁风暴仍会严重冲击系统稳定性。
在高并发写入中,快速途径数组(Fast Path Array) 的物理限制也常被忽视。为了加速高频锁请求,数据库内核会使用快速途径数组缓存锁信息,位数一般是固定的(如16位),当并发锁请求数量超出此限制时,系统必须回退到主锁定表,性能骤降。