揪出那个无主键的表

2023-03-14 00:00:00 索引 主键 主从 延迟 新增

前言:

在 MySQL 中,建表时一般都会要求有主键。若要求不规范难免会出现几张无主键的表,本篇文章让我们一起揪出那个无主键的表。

1.无主键表的危害

以 InnoDB 表为例,我们都知道,在 InnoDB 中,表都是根据主键顺序以索引的形式存放的,这种存储方式的表称为索引组织表。一张 InnoDB 表必须有一个聚簇索引,当有主键时,会以主键作为聚簇索引;如果没有显式定义主键,InnoDB 会选择一个的非空索引代替。如果没有这样的索引,则 MySQL 自动为 InnoDB 表生成一个隐含字段作为主键。

也就是说,好我们可以显式定义主键,那么无主键表可能会产生哪些危害呢?首先没有主键就意味着无法用到主键索引,可能影响查询效率。其次是对维护不友好,比如想升级为 MGR 集群或使用某些开源工具时,都会要求表要有主键。还有一点,对于无主键的表批量更新或删除,极易引起很长时间的主从延迟。

这里也顺便提下,当主库对于无主键表(特别是既无主键又无索引的表)大量更新或删除时,从库会发生极大的主从延迟,甚至会一直卡着执行不下去,别问我怎么知道的,前段时间遇到过。发生这种情况的现象是从库延迟不断增大,且正在执行的主库 binlog pos 位点一直不变,这个时候需要去主库解析下从库卡着的 binlog pos 位点,发现是对某个无主键表的操作,这时若想从库尽快赶上,可以手动设置下忽略该表的同步,处理 SQL 如下:

# 假设检查发现是 testtb 表导致了主从延迟 可以再从库忽略该表的同步
mysql> STOP SLAVE SQL_THREAD;
Query OK, 0 rows affected (0.00 sec)

mysql> CHANGE REPLICATION FILTER REPLICATE_IGNORE_TABLE = (db.testtb);
Query OK, 0 rows affected (0.00 sec)

mysql> START SLAVE SQL_THREAD;
Query OK, 0 rows affected (0.01 sec)

相关文章