下面的内容将详细介绍 MySQL 8.0.32 引入的 GIPK(Generated Invisible Primary Keys,生成不可见主键) 特性。
01. 特性概述
MySQL 8.0.30 引入,8.0.32 进一步完善复制支持。当创建 InnoDB 表时如果未显式定义主键,MySQL 会自动为其生成一个不可见的自增主键列,避免"无主键表"带来的性能和复制问题。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| mysql> CREATE TABLE t1( -> my_row_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT INVISIBLE PRIMARY KEY -> , c1 INT -> ); Query OK, 0 rows affected (0.29 sec)
mysql> show create table t1\G *************************** 1. row *************************** Table: t1 Create Table: CREATE TABLE `t1` ( `my_row_id` bigint unsigned NOT NULL AUTO_INCREMENT , `c1` int DEFAULT NULL, PRIMARY KEY (`my_row_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci 1 row in set (0.00 sec)
|
02. 为什么需要 GIPK?
无主键表的问题
在 MySQL 中,没有主键的表会带来多方面问题:
- 复制性能。Row-Based Replication(RBR)模式下,无主键表进行 UPDATE/DELETE 时需要全表扫描定位记录,导致严重主从延迟。
- 在线 DDL。使用 pt-online-schema-change、gh-ost 等工具进行在线变更时,必须依赖主键进行分片处理。
- 集群环境。InnoDB Cluster、Galera、Percona XtraDB Cluster 等集群方案强制要求表必须有主键。
- 数据一致性。逻辑备份(mysqldump)和 Binlog 回放时,无主键表难以唯一标识行。
GIPK 的优势
- 对应用透明:INVISIBLE 属性意味着
SELECT * 不会返回该列,不影响现有业务代码
- 自动维护:无需人工干预,自动为新表添加主键
- 性能提升:使 RBR 复制效率提升 50% 以上,支持在线 DDL 工具正常工作
03. 配置与使用
两个核心参数
sql_generate_invisible_primary_key
全局、会话级参数。表示是否启用 GIPK 自动生成
show_gipk_in_create_table_and_information_schema
会话级参数,默认为 ON,表示是否在 SHOW CREATE TABLE 和 Information Schema 中显示 GIPK 列。
启用方法
1 2 3 4 5 6 7 8 9
| SET GLOBAL sql_generate_invisible_primary_key = ON;
SET SESSION sql_generate_invisible_primary_key = ON;
[mysqld] sql_generate_invisible_primary_key=ON
|
实际效果示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| mysql> SET SESSION sql_generate_invisible_primary_key = OFF; Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE t2(id INT, c1 INT); Query OK, 0 rows affected (0.20 sec)
mysql> show create table t2\G *************************** 1. row *************************** Table: t2 Create Table: CREATE TABLE `t2` ( `id` int DEFAULT NULL, `c1` int DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci 1 row in set (0.00 sec)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| mysql> SET sql_generate_invisible_primary_key = ON; Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE t3(id INT, c1 INT); Query OK, 0 rows affected (0.14 sec)
mysql> show create table t3\G *************************** 1. row *************************** Table: t3 Create Table: CREATE TABLE `t3` ( `my_row_id` bigint unsigned NOT NULL AUTO_INCREMENT , `id` int DEFAULT NULL, `c1` int DEFAULT NULL, PRIMARY KEY (`my_row_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci 1 row in set (0.00 sec)
|
查询表现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| mysql> insert t3 select 1,1; Query OK, 1 row affected (0.01 sec) Records: 1 Duplicates: 0 Warnings: 0
mysql> table t3; + | id | c1 | + | 1 | 1 | + 1 row in set (0.00 sec)
mysql> select my_row_id, id, c1 from t3; + | my_row_id | id | c1 | + | 1 | 1 | 1 | + 1 row in set (0.00 sec)
|
04. 技术细节与限制
1. 触发条件
GIPK 只在以下情况自动生成:
- 表引擎为 InnoDB
- 创建时未显式定义主键(PRIMARY KEY)
- 配置项已开启
注意:如果表有 UNIQUE KEY 但不是 PRIMARY KEY,仍会生成 GIPK 。
2. 命名冲突处理
如果手动创建了名为 my_row_id 的列但未指定主键,会报错:
1 2
| mysql> create table t_my_row_id (my_row_id int); ERROR 4108 (HY000): Failed to generate invisible primary key. Column 'my_row_id' already exists.
|
解决方案:
- 将现有
my_row_id 设为主键
- 或创建其他列作为主键
- 或临时关闭 GIPK 功能
3. 列操作限制
GIPK 列处于 INVISIBLE 状态时,不能进行以下操作:
- 重命名列(RENAME COLUMN)
- 修改列定义
- 删除列
必须先将其设为 VISIBLE 才能修改 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| ALTER TABLE t3 RENAME COLUMN my_row_id TO id; mysql> ALTER TABLE t3 ALTER COLUMN my_row_id SET VISIBLE; Query OK, 0 rows affected (0.06 sec) Records: 0 Duplicates: 0 Warnings: 0
mysql> ALTER TABLE t3 RENAME COLUMN my_row_id TO pkid; Query OK, 0 rows affected (0.04 sec) Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table t3\G *************************** 1. row *************************** Table: t3 Create Table: CREATE TABLE `t3` ( `pkid` bigint unsigned NOT NULL AUTO_INCREMENT, `id` int DEFAULT NULL, `c1` int DEFAULT NULL, PRIMARY KEY (`pkid`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci 1 row in set (0.00 sec)
|
4. 与显式主键的共存
为已有 GIPK 的表添加显式主键时:
1 2 3 4 5 6 7 8
| mysql> alter table t4 add primary key (id); ERROR 1068 (42000): Multiple primary key defined
mysql> alter table t4 drop column my_row_id, add primary key (id); Query OK, 0 rows affected (0.12 sec) Records: 0 Duplicates: 0 Warnings: 0
|
05. 复制场景处理
主从复制行为
关键规则:sql_generate_invisible_primary_key 设置不会随复制传播 。
- 主库开启 GIPK,从库不会自动为无主键表生成主键
- 主库关闭 GIPK,从库开启也不会影响主库创建的表
8.0.32+ 的复制增强
从 MySQL 8.0.32 开始,副本端可以强制为复制的无主键表添加 GIPK:
1 2 3 4
| CHANGE REPLICA SOURCE TO REQUIRE_TABLE_PRIMARY_KEY_CHECK = GENERATE FOR CHANNEL ch1;
|
副本现在会为通道 ch1 复制创建的表添加一个不可见的主键
注意:GENERATE 模式与 MySQL Group Replication 不兼容 。
06. mysqldump 备份
为防止导出文件包含自动生成的 GIPK 列(这会导致导入时与目标库 GIPK 设置冲突),应使用专用参数:
1 2 3 4 5
| mysqldump -uroot -p1 --skip-generated-invisible-primary-key mydb > backup.sql
mysqldump -uroot -p1 mydb > backup_gipk.sql
|
对比两次导出的结果集:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| [mysql@shawnyan ~]$ diff backup.sql backup_gipk.sql 27,28c27,30 < `id` int DEFAULT NULL < ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; --- > `my_row_id` bigint unsigned NOT NULL AUTO_INCREMENT /*!80023 INVISIBLE */, > `id` int DEFAULT NULL, > PRIMARY KEY (`my_row_id`) > ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; 37c39 < INSERT INTO `t1` VALUES (1); --- > INSERT INTO `t1` (`my_row_id`, `id`) VALUES (1,1); 50c52 [mysql@shawnyan ~]$
|
如果不使用该参数,在目标库开启 GIPK 的情况下导入,可能会出现主键冲突或重复列错误。
07. 应用场景与最佳实践
适用场景
- 遗留系统改造:老旧应用有大量无主键表,无法修改表结构,通过 GIPK 零侵入解决
- 云数据库环境:Azure Database for MySQL 等云厂商默认开启 GIPK,确保所有表都有主键
- 集群环境准备:迁移到 InnoDB Cluster 前开启 GIPK,避免主键缺失导致加入集群失败
- 大数据同步:使用 Canal、Maxwell 等 Binlog 解析工具时,确保表有主键以提高同步效率
与 sql_require_primary_key 的配合
MySQL 8.0.13 引入的 sql_require_primary_key 可以强制要求创建表必须有主键,与 GIPK 配合使用效果更佳 :
1 2 3 4 5 6
| SET GLOBAL sql_require_primary_key = ON; SET GLOBAL sql_generate_invisible_primary_key = ON;
CREATE TABLE legacy_table (data VARCHAR(100));
|
Have a nice day ~ ☕
🌻 近期内容 ▼
👉 这里有得聊
如果对国产基础软件(操作系统、数据库、中间件)、AI、Vibe Coding、OpenClaw 、Hermes Agent 等感兴趣,可以加群一起聊聊。关注微信公众号:(少安事务所),后台回复[群],即可看到入口。如果这篇文章为你带来了灵感或启发,请帮忙『点赞、推荐、转发』吧,感谢!ღ( ´・ᴗ・` )~
Author:
Shawn Yan
Link:
https://shawnyan.cn/2025/mysql/mysql-8-0-30-gipk-feature/index.html
License:
All articles on this site are original unless otherwise stated. Please indicate the source when reprinting!