怎样在MySQL触发器中避免无限递归导致的1436错误?

千敏姑娘_7167

千敏姑娘_7167

2026-08-08

684人浏览

原创

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

怎样在mysql触发器中避免无限递归导致的1436错误?

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 启动时生效,无法运行时动态修改。需编辑配置文件:

MySQL
MySQL

编写正确的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;而一个塞满变量和函数调用的触发器,连单次执行都可能爆栈。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

mysql mysql触发器 字节

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
mysql修改数据表名
mysql修改数据表名

MySQL修改数据表:1、首先查看数据库中所有的表,代码为:‘SHOW TABLES;’;2、修改表名,代码为:‘ALTER TABLE 旧表名 RENAME [TO] 新表名;’。php中文网还提供MySQL的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.20

2093

6

MySQL创建存储过程
MySQL创建存储过程

存储程序可以分为存储过程和函数,MySQL中创建存储过程和函数使用的语句分别为CREATE PROCEDURE和CREATE FUNCTION。使用CALL语句调用存储过程智能用输出变量返回值。函数可以从语句外调用(通过引用函数名),也能返回标量值。存储过程也可以调用其他存储过程。php中文网还提供MySQL创建存储过程的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.21

1279

5

mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

755

5

mysql密码忘了怎么查看
mysql密码忘了怎么查看

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql密码忘了怎么办呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.19

2812

5

mysql创建数据库
mysql创建数据库

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql怎么创建数据库呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.25

4668

4

mysql默认事务隔离级别
mysql默认事务隔离级别

MySQL是一种广泛使用的关系型数据库管理系统,它支持事务处理。事务是一组数据库操作,它们作为一个逻辑单元被一起执行。为了保证事务的一致性和隔离性,MySQL提供了不同的事务隔离级别。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.08

1079

3

sqlserver和mysql区别
sqlserver和mysql区别

SQL Server和MySQL是两种广泛使用的关系型数据库管理系统。它们具有相似的功能和用途,但在某些方面存在一些显著的区别。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.11

4931

4

mysql忘记密码
mysql忘记密码

MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。那么忘记mysql密码我们该怎么解决呢?php中文网给大家带来了相关的教程以及其他关于mysql的文章,欢迎大家前来学习阅读。

2023.08.14

4402

7

mysql事务隔离级别
mysql事务隔离级别

mysql规范中定义了四种事务隔离级别,不同的隔离级别对事务的处理有所不同。本专题为大家提供mysql事务隔离级别相关的文章内容,大家可以免费体验。

2023.08.16

5734

11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 178人学习

使用phpenv集成环境安装极致CMS
使用phpenv集成环境安装极致CMS

共2课时 | 286人学习