查 information_schema.TRIGGERS 表最可靠,因其包含全实例触发器元数据,关键字段 TRIGGER_SCHEMA、EVENT_OBJECT_TABLE、EVENT_MANIPULATION 和 ACTION_TIMING 可精准定位监听关系。

直接查 information_schema.TRIGGERS 表最可靠
想搞清哪些表被触发器“盯上了”,别依赖 SHOW TRIGGERS 的模糊输出——它只显示当前库的触发器,且不带库名前缀,跨库场景下容易误判。真正可控的方式是查系统表 information_schema.TRIGGERS,它存的是全实例所有触发器的元数据。
关键字段要盯住:TRIGGER_SCHEMA(触发器所属库)、EVENT_OBJECT_TABLE(被监听的表名)、EVENT_MANIPULATION(INSERT/UPDATE/DELETE)、ACTION_TIMING(BEFORE/AFTER)。这几个组合起来,就能准确定位“谁在监听谁、什么时候、干啥事”。
- 查所有被监听的表(去重):
SELECT DISTINCT TRIGGER_SCHEMA, EVENT_OBJECT_TABLE FROM information_schema.TRIGGERS; - 查某张表是否被任何触发器监听:
SELECT TRIGGER_SCHEMA, TRIGGER_NAME, ACTION_TIMING, EVENT_MANIPULATION FROM information_schema.TRIGGERS WHERE EVENT_OBJECT_TABLE = 'your_table_name'; - 查某库下所有监听关系:
SELECT TRIGGER_NAME, EVENT_OBJECT_TABLE, EVENT_MANIPULATION, ACTION_TIMING FROM information_schema.TRIGGERS WHERE TRIGGER_SCHEMA = 'your_db_name';
SHOW TRIGGERS 的局限和误用风险
SHOW TRIGGERS 看起来简单,但实际用错概率很高。它默认只返回当前 USE 的数据库里的触发器,如果没提前切库,结果就是空的——不是没触发器,是你没在对的上下文里查。
更麻烦的是,它的输出字段名不标准(比如列名是 Table 而非 EVENT_OBJECT_TABLE),没法直接和其他 SQL 拼接或做聚合;而且不返回 TRIGGER_SCHEMA,遇到同名表跨库时完全分不清归属。
- 错误写法:
SHOW TRIGGERS FROM non_existent_db;→ 报错Unknown database,但你可能误以为是权限问题 - 危险操作:
SHOW TRIGGERS LIKE '%log%';→ 匹配的是触发器名,不是表名,和“影响哪些表”完全无关 - 遗漏风险:执行
SHOW TRIGGERS;前没USE target_db;→ 结果为空,你以为没触发器,其实它在别的库里
跨库监听时,TRIGGER_SCHEMA 和 EVENT_OBJECT_SCHEMA 不一定相同
触发器可以定义在库 A,但监听库 B 里的表——这是合法且常见的设计(比如审计库统一管理各业务库的变更日志)。此时 TRIGGER_SCHEMA 是 A,EVENT_OBJECT_SCHEMA 是 B,两个字段必须同时看,否则会漏掉真实影响范围。
典型场景:DBA 在 audit_db 创建触发器 log_user_update,监听 app_db.users 表的 UPDATE。查 information_schema.TRIGGERS 时,TRIGGER_SCHEMA = 'audit_db',但 EVENT_OBJECT_SCHEMA = 'app_db',EVENT_OBJECT_TABLE = 'users'。
- 务必用
WHERE同时过滤这两个字段,不能只认TRIGGER_SCHEMA - 导出迁移时,光 dump 触发器定义不够,还得确认它依赖的目标库表是否存在、权限是否到位
- 权限检查要分开:创建触发器需要
TRIGGER权限在TRIGGER_SCHEMA,但执行时需对EVENT_OBJECT_SCHEMA有对应 DML 权限
性能与锁要注意:大表 + 高频触发器可能拖慢 DML
查 information_schema.TRIGGERS 本身很快,但如果你在触发器里写了复杂逻辑(比如跨表 JOIN、子查询无索引、调用函数),那每次 INSERT/UPDATE/DELETE 都会额外消耗资源。尤其当目标表本身是热点大表时,容易出现隐性瓶颈。
- 高频写入表上加触发器前,先用
EXPLAIN检查触发器内所有 SELECT 是否走索引 - 避免在 BEFORE 触发器里查同一张表(会触发 ERROR 1442),哪怕查的是视图也不行
- 如果触发器只是记录日志,优先用异步方式(如写入消息队列),而不是同步 INSERT 到另一张表
真正难排查的,是那些没报错但让 INSERT 变慢 3 倍的触发器——它们不会出现在错误日志里,只能靠查 information_schema.TRIGGERS 定位到表,再人工 review 触发器定义里的语句。


















