mysql为什么占用_为什么mysql有时占用cpu很高

2023年 9月 2日 33.7k 0

在某些还不算高并发的场景下,为什么mysql服务器的cpu使用率会飙的很高,但是磁盘IO和网络IO的量却没有很大呢?这个和mysql的死锁检测机制有关系了。

Innodb引擎是支持行锁的,在一个事务中,如果对某一行加了锁后想释放掉锁,需要等到提交事务后才会释放,是不能立刻释放的。

假设在某个秒杀场景下,用户下单后需要对秒杀商品进行减库存的操作,为了防止超卖,就需要对库存加行锁,这个操作本身其实是不消耗cpu的,但mysql默认是开启死锁检测机制的,就导致每个加锁的线程都要判断,自己的加入是否会导致死锁,时间复杂度是O(n)。如果有一万个线程并发访问,死锁检测就是一亿的量级,会消耗大量的cpu资源,这就是我们看到cpu升高的主要原因。那么如何解决这个问题呢?

mysql通过innodb_deadlock_on来控制是否开启死锁检测,通过innodb_lock_wait_timeout来控制超时时间。一种方法是关闭死锁检测,或将超时时间降低。如果项目已经上线,这是一种临时的解决方案,但如果其他的业务存在死锁,关闭死锁检测就可能会影响业务的正常运行。如果我们的业务是一个大事务,本身没有死锁,但是耗时确实比较久,降低超时时间的方式可能会误杀了正常运行的事务。

还有一种方法,是将加锁的行进行拆分,也就是库存拆分成100行,这样就通过增加业务复杂度的方式,降低了死锁检测的cpu消耗。这是比较常用的方式。当然之前最好对加锁的线程进行限流,否则简单的拆分库存可能也扛不住瞬时的并发量。

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论