error 1436是线程栈溢出错误,非递归逻辑导致,而是因触发器或嵌套存储过程耗尽mysql分配的固定大小线程栈(默认192k–256k),表现为“thread stack overrun”及字节数对比;根本解决需调高thread_stack配置并重启服务,或重构触发器以轻量化逻辑、避免嵌套调用与栈密集操作。

ERROR 1436 不是递归导致的,而是线程栈溢出(Thread stack overrun),和触发器递归无关。真正由递归引发的典型错误是 ERROR 1442、ERROR 1422 或 ERROR 1424。如果你看到 ERROR 1436,说明触发器或其调用链(比如嵌套存储过程)耗尽了 MySQL 的线程栈空间,不是逻辑循环,是内存资源不足。
为什么触发器会触发 ERROR 1436?
MySQL 为每个连接分配固定大小的线程栈(thread_stack),默认值通常为 192K 或 256K。当触发器内部做了以下操作时,容易快速吃光栈空间:
- 深度嵌套调用多个存储过程(哪怕只嵌套 3–4 层,每层带大量局部变量或复杂表达式)
- 在触发器里执行长递归式逻辑(例如手动模拟树遍历但没设终止条件)
- 调用含大参数列表或长字符串拼接的函数
- 触发器本身代码过长,含大量
IF/CASE嵌套、重复子查询或未优化的循环
如何确认是 thread_stack 不足?
报错信息明确包含关键词:Thread stack overrun 和具体字节数对比(如 6656 bytes used of a 8496 byte stack, and 128000 bytes needed)。此时应立即检查当前配置:
SHOW VARIABLES LIKE 'thread_stack';
若返回值 ≤ 256K(如 196608 = 192K),且你的触发器逻辑较重,就极可能撞限。
临时缓解:调高 thread_stack(仅限测试/临时环境)
该参数必须在 MySQL 启动时生效,无法运行时动态修改。需编辑配置文件:
- Linux:在
/etc/my.cnf的[mysqld]段下添加thread_stack = 512K - Windows:修改
my.ini,同样加thread_stack = 512K - 重启 MySQL 服务后执行
SHOW VARIABLES LIKE 'thread_stack';确认生效
⚠️ 注意:盲目调高(如设成 1M+)可能增加内存压力,尤其在高并发场景下;生产环境应优先重构逻辑而非堆参数。
根治方案:从触发器设计上减栈压
比调参数更可靠的是让触发器“轻量化”:
- 禁止在触发器内调用其他存储过程——尤其避免多层嵌套;把逻辑拆到应用层或单层存储过程里
- 移除所有非必要变量声明,合并短
IF判断,用CASE WHEN替代深层IF ELSEIF - 避免在触发器中执行复杂计算(如 JSON 解析、正则匹配、大字段 SUBSTRING_INDEX 循环)——这些都极耗栈
- 把日志写入、状态同步等副作用操作移到异步队列(如写
event_log表 + 应用消费),不留在触发器执行路径中 - 用
INSERT ... ON DUPLICATE KEY UPDATE替代先SELECT再INSERT/UPDATE的模式,减少语句数量和上下文开销
真正危险的不是“有没有递归”,而是“有没有在栈上叠太多东西”。一个干净的触发器,哪怕跨表更新几次,也几乎不会触发 ERROR 1436;而一个塞满变量和函数调用的触发器,连单次执行都可能爆栈。











