
直接用 INFORMATION_SCHEMA.INNODB_METRICS 查表级活跃度
MySQL 原生不支持“监控某张表的增删改查频次”,innodb_monitor(含 innodb_table_monitor)是旧版调试工具,仅输出内部结构快照,**不实时、不按表粒度、不记录 DML 行为**,且 8.0+ 已废弃。真要观测表变化,得换思路:走指标聚合或代理层捕获。
最轻量可行的是启用 INNODB_METRICS 并过滤表名:
-
SET GLOBAL innodb_monitor_enable = 'table.*';—— 开启表相关指标(如table_open_count、table_read_rows) -
SELECT * FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'table%';—— 查当前累积值 - 注意:这些是全局累计值,不是实时流;需定时采样做差值才能算出变化率
- 性能影响极小,但无法区分具体 SQL 或事务来源
用 P6Spy 拦截 JDBC 层 SQL,精准定位哪张表被操作
如果你的应用走 Java + JDBC(尤其 Spring Boot / Hibernate),P6Spy 是最接地气的方案——它不改数据库,只替换驱动,在应用侧把所有发往 MySQL 的 SQL 记下来,自然就包含表名、操作类型、参数和耗时。
- 把
p6spy.jar放进WEB-INF/lib,spy.properties放进src/main/resources - 关键配置必须改对:
realdriver=com.mysql.cj.jdbc.Driver(注意 8.0+ 驱动类名带cj,不是mysql.jdbc.Driver) -
driver=com.p6spy.engine.spy.P6SpyDriver,并确保数据源配置里 driver class 换成这个 - 常见坑:
spy.log为空?大概率是realdriver写错,或没重启应用;日志里出现oracle.jdbc.OracleDriver?说明配置文件里有残留的其他realdriver未注释
触发器方案慎用:能记录变更,但会拖慢写入且难维护
给目标表加 BEFORE INSERT/UPDATE/DELETE 触发器,把操作写进审计日志表,看似直接,实际问题一堆。
- 每次写操作都多一次额外 INSERT,QPS 高时延迟明显上升,尤其日志表没建好索引或用了 MyISAM
- 触发器无法捕获
TRUNCATE、DROP、ALTER等 DDL,表结构变化照样漏掉 - 如果业务本身用批量
INSERT ... VALUES (...),(...),一个语句触发一次,但你没法知道具体影响了哪几行 - 示例陷阱:
CREATE TRIGGER log_user_change BEFORE UPDATE ON user FOR EACH ROW INSERT INTO audit_log(table_name, op, time) VALUES('user', 'UPDATE', NOW());—— 看似 OK,但没记录 old/new 值,也没防并发写 audit_log 失败导致主事务回滚
真正要监控表结构变化,盯紧 information_schema.TABLES 和 binlog
表字段增减、索引变更属于 DDL,INNODB_METRICS 和触发器都看不到。information_schema.TABLES 和 COLUMNS 是只读元数据视图,只能轮询比对,不适合高频场景。
- 更可靠的是解析 binlog:
mysqlbinlog --base64-output=decode-rows -v mysql-bin.000001 | grep -A 2 -B 2 'ALTER TABLE\|CREATE TABLE' - 但 binlog 默认不记录 DDL 的完整语句(尤其 5.7+ row 格式),需确认
binlog_format = STATEMENT或启用binlog_row_image = FULL并配合解析工具(如 Maxwell、Canal) - 云数据库(如腾讯云 MySQL)控制台里的“结构变更审计”功能,底层就是拉取 binlog + 过滤 DDL,比自己搭稳定得多
别指望一个开关打开就能全自动监控表变化——要么接受低精度指标(INNODB_METRICS),要么在应用层拦截(P6Spy),要么下沉到日志解析(binlog)。选哪个,取决于你愿意在哪一层担风险、调精度、扛性能。










