无主键大表在主从复制中特别危险,因为从库执行delete或update时需依赖binlog中的行数据定位目标行,但缺失主键导致无法高效匹配;innodb隐藏row_id不写入binlog,迫使从库对每行变更执行全表扫描,致使sql线程卡死、seconds_behind_master持续飙升甚至停滞。

为什么无主键大表在主从复制中特别危险
因为从库执行 DELETE 或 UPDATE 时,binlog 记录的是行数据(row image),但没有主键就无法快速定位目标行。InnoDB 自动生成的隐藏 ROW_ID 不会写入 binlog,所以从库只能全表扫描匹配——一张 50GB 的表,可能扫几小时,SQL 线程卡死,Seconds_Behind_Master 持续飙升,甚至停在某个 binlog_pos 不动。
用 information_schema 找出无主键 + 大体积的表
不能分开查“无主键”和“大表”再人工比对,得一步到位。核心是把两个条件合并在一个 JOIN 查询里:
SELECT
t.table_schema,
t.table_name,
ROUND((t.data_length + t.index_length) / 1024 / 1024 / 1024, 2) AS size_gb
FROM information_schema.tables t
LEFT JOIN information_schema.key_column_usage k
ON t.table_schema = k.table_schema
AND t.table_name = k.table_name
AND k.constraint_name = 'PRIMARY'
WHERE t.table_schema NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys')
AND t.table_type = 'BASE TABLE'
AND k.table_name IS NULL
AND (t.data_length + t.index_length) > 1024 * 1024 * 1024 * 5 -- 大于 5GB
ORDER BY (t.data_length + t.index_length) DESC;
-
size_gb是真实占用空间,别信table_rows,InnoDB 下它只是估算值 - 过滤掉系统库必须写全,漏掉
sys可能误报sys.x$innodb_buffer_stats_by_schema这类视图 - 条件里用
AND (t.data_length + t.index_length) > ...而不是HAVING,否则 MySQL 8.0+ 可能报错或性能差
确认这张表是否正在引发复制延迟
光查出来不够,得验证它是不是当前延迟元凶:
- 在从库执行
SHOW SLAVE STATUS\G,看Exec_Master_Log_Pos长时间不动,同时Seconds_Behind_Master持续上涨 - 用
mysqlbinlog解析卡住位置的 binlog:mysqlbinlog -v --base64-output=DECODE-ROWS master-bin.000001 | grep -A 10 -B 5 "table_name",确认操作对象 - 查从库正在执行的事务:
SELECT * FROM performance_schema.events_statements_current WHERE SQL_TEXT LIKE '%DELETE%table_name%'; - 如果
Replicate_Ignore_Table已配置但没生效,注意格式必须是db_name.table_name,不能带反引号
删或加主键前必须核对的三件事
别急着 ALTER TABLE ... ADD PRIMARY KEY,尤其大表:
- 确认该表没被外键引用:查
SELECT * FROM information_schema.KEY_COLUMN_USAGE WHERE REFERENCED_TABLE_NAME = 'xxx'; - 确认没长事务锁表:
SELECT * FROM information_schema.INNODB_TRX WHERE trx_mysql_thread_id IN (SELECT ID FROM information_schema.PROCESSLIST WHERE INFO LIKE '%table_name%'); - 加主键要重建表,磁盘空间至少预留
data_length + index_length的 1.5 倍;如果用ALGORITHM=INPLACE,MySQL 5.6+ 支持,但只适用于新增自增主键且原无主键的情况
最常被忽略的是:加完主键后,必须手动触发一次 FLUSH LOGS 并检查从库是否开始正常追,否则旧 binlog 里的无主键操作仍会反复触发全表扫描。











