MySQL 8.0 不会触发 Linux 内核死锁,dmesg 中的 “possible circular locking dependency” 是内核 lockdep 的静态路径警告,非真实死锁;真正卡死源于 InnoDB 事务死锁(如 SHOW ENGINE INNODB STATUS 可见 LATEST DETECTED DEADLOCK),可通过关闭 innodb_deadlock_detect 或禁用 native AIO 缓解。

MySQL 8.0 本身不会直接触发 Linux 内核死锁;所谓“内核死锁”通常是误判,真实情况多为 lockdep 报告的潜在死锁警告(possible recursive locking detected),或因内核模块(如 ext4、overlayfs、cgroup v1)与 MySQL 高频 futex/epoll/syscall 行为交互引发的调度僵局。真正导致 MySQL 进程卡死、不可响应的,99% 是用户态问题——比如 InnoDB 层事务死锁被误读为“内核级死锁”。
为什么 dmesg 里会看到 “possible circular locking dependency”?
这是内核 lockdep 子系统在检测到加锁顺序不一致时发出的**静态路径警告**,不是运行时死锁。MySQL 8.0 启用 innodb_deadlock_detect=ON(默认)后,会高频调用 futex_wait 和 epoll_wait,若内核版本较老(如 4.4–4.15),且启用了某些调试配置(CONFIG_LOCKDEP=y + CONFIG_DEBUG_LOCK_ALLOC=y),就容易触发该警告。
- 典型日志片段:
possible recursive locking detected: mysqld/12345 is trying to acquire lock (&rq->lock) at: __schedule+0x4a0/0x8e0 - 这不是 MySQL 崩溃,而是内核在“喊话”:这个锁路径以前没被见过,你确认没搞错顺序?
- 影响:仅增加内核日志噪音,不影响 MySQL 功能;但若频繁出现,可能掩盖真实问题(如 OOM killer 杀进程)
哪些内核版本和配置组合风险最高?
问题集中出现在以下组合:
-
Linux 4.9.x ~ 4.15.x(尤其 Ubuntu 16.04/18.04 默认内核)+ext4+cgroup v1 -
Linux 5.4.0-xx-generic(Ubuntu 20.04 早期补丁版)+overlayfs(Docker 容器场景) - 所有内核启用
CONFIG_PROVE_LOCKING=y且 MySQL 启动参数含--innodb-use-native-aio=ON(默认)
根本原因:InnoDB 的异步 I/O 调度器(libaio)与内核块层锁(&q->queue_lock)、cgroup 的 task_group 锁之间存在 lockdep 未覆盖的交叉路径。这不是 bug,是 lockdep 的保守策略。
怎么确认不是内核真死锁,而是 MySQL 自身事务死锁?
三步快速区分:
- 执行
mysql -e "SHOW ENGINE INNODB STATUS\G"—— 如果输出里有*** (1) TRANSACTION:和*** (2) TRANSACTION:区块,并带WAITING FOR THIS LOCK TO BE GRANTED,那就是标准 InnoDB 事务死锁,跟内核无关 - 查
/var/log/mysql/error.log—— 真内核问题通常伴随kernel: INFO: rcu_preempt detected stalls或Call Trace:,而 MySQL 死锁只报ERROR 1213 (40001): Deadlock found when trying to get lock - 运行
ps aux | grep mysqld+cat /proc/$(pidof mysqld)/stack—— 若 stack 显示大量__futex_wait或ep_poll且无回溯中断,说明进程还在内核等待队列里;若 stack 卡在row_sel_store_mysql_rec或lock_wait_suspend_thread,就是事务锁等待
真正要改的不是内核,而是这三处配置
多数所谓“内核死锁”现象,只需调整 MySQL 层行为即可缓解:
- 关闭 InnoDB 死锁检测(仅限高并发写场景):
SET GLOBAL innodb_deadlock_detect=OFF,用超时代替主动检测(配合innodb_lock_wait_timeout=10) - 禁用原生 AIO(规避 libaio 与内核锁交互):
mysqld --innodb-use-native-aio=OFF(MySQL 8.0.23+ 支持) - 强制使用
io_uring(Linux 5.10+):mysqld --innodb-use-io-thread-pool=OFF --innodb-use-io-thread-pool=OFF并确保kernel.unprivileged_userns_clone=1已设(容器环境)
关键点:别急着升级内核。先看 SHOW ENGINE INNODB STATUS 输出里的 LATEST DETECTED DEADLOCK 区块——如果它存在,你面对的就是应用逻辑问题,不是内核问题。

















