怎样将设置主键与自增列同步至生产环境_DDL脚本生成与执行

胖浩小哥_6243

胖浩小哥_6243

2026-04-14

735人浏览

原创

会锁表,且是全表DML锁;MySQL 5.7及以前必锁,8.0+加自增主键也不支持INSTANT算法;PostgreSQL需建序列、设默认值、同步当前值才能安全转SERIAL主键。

MySQL 用 ALTER TABLE ... MODIFY 加自增主键会锁表吗

会,而且是全表 dml 锁(在 innodb_lock_wait_timeout 范围内阻塞 insert/update/delete),不是只读锁。5.7 及以前版本基本没得选;8.0+ 启用 algorithm=instant 才可能免锁,但仅限添加列、重命名列等极少数操作——加自增主键不在其中。

常见错误现象:ALTER TABLE t1 ADD id BIGINT PRIMARY KEY AUTO_INCREMENT FIRST; 在生产表上执行数分钟无响应,监控显示 Waiting for table metadata lock,连 SELECT 都卡住(因元数据锁升级)。

  • 必须确认表大小:千万级行以上,别直接跑 DDL,先在从库或影子表验证耗时
  • 避免在业务高峰执行;若必须在线,优先考虑 pt-online-schema-change 或 gh-ost
  • AUTO_INCREMENT 值不能靠 MODIFY 自动推导——必须显式指定 START WITH 或先查最大值再设 ALTER TABLE ... AUTO_INCREMENT = N

PostgreSQL 怎么安全地把普通列转成 SERIAL 主键

PostgreSQL 没有真正的 “自增类型”,SERIAL 只是语法糖,底层是 SEQUENCE + DEFAULT。直接 ALTER COLUMN ... TYPE SERIAL 会报错,因为 SERIAL 不是真实类型。

使用场景:已有表带 id 列但无主键和默认值,现在要补上自增逻辑。

  • 先建序列:CREATE SEQUENCE t1_id_seq OWNED BY t1.id;
  • 设默认值:ALTER TABLE t1 ALTER COLUMN id SET DEFAULT nextval('t1_id_seq');
  • 设主键:ALTER TABLE t1 ADD PRIMARY KEY (id);
  • 关键一步:同步序列当前值,否则下次插入可能冲突:SELECT setval('t1_id_seq', COALESCE((SELECT MAX(id) FROM t1), 0));

注意:OWNED BY 表示该序列被列“拥有”,删列会自动删序列;但若列已存在值,必须手动调用 setval,否则新插入从 1 开始。

生成可回滚的 DDL 脚本要注意哪几个硬性条件

DDL 本身不可事务回滚(MySQL 的 DROP/CREATE 类操作,PostgreSQL 的多数 ALTER 除外),所谓“可回滚”是指人工能快速切回旧结构,不是数据库层面支持 ROLLBACK。

容易踩的坑:脚本里只写了 ADD COLUMN,没写对应 DROP COLUMN;或者主键变更后,没保留原索引名,导致回滚语句执行失败。

  • 每个 ADD 操作,必须配对写出 DROP(如 ADD PRIMARY KEY → DROP CONSTRAINT,不是 DROP PRIMARY KEY)
  • 显式命名所有约束:ADD CONSTRAINT pk_t1_id PRIMARY KEY (id),否则 PostgreSQL 自动生成名如 t1_pkey,不同环境不一致
  • MySQL 中,ENGINE=InnoDB 和 CHARSET=utf8mb4 必须显式声明,避免从库因默认值差异导致复制中断

上线前怎么验证 DDL 脚本在目标版本真能跑通

开发环境 MySQL 8.0,生产还是 5.7?PostgreSQL 从 12 升到 15?版本差一个点,JSON 字段行为、GENERATED COLUMN 语法、甚至 IF NOT EXISTS 支持都可能不兼容。

最简单的验证方式:拿生产环境同版本的只读实例(或 mysqldump 出的 CREATE TABLE 语句),在本地起个 Docker 实例,用 mysql -u root -h 127.0.0.1 直接跑。

  • 检查错误信息是否含 ERROR 1064(语法错误)、ERROR 1832(MySQL 不支持的 ALGORITHM)
  • 特别注意注释:MySQL 5.7 不识别 /*+ INVISIBLE */ 这类优化器提示,会当语法错误
  • PostgreSQL 要确认 pg_dump --no-owner --no-privileges 导出的建表语句,和你要执行的 DDL 是否字段顺序、约束名完全一致

复杂点在于自增初始值和序列状态必须人工核对,工具不会帮你检查这个。

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

4583

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

951

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

1209

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

6561

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

3323

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

6540

11

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

2024.04.29

8981

6

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1210

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1072

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 134.1万人学习