Skip to content

[Bug] GORM AutoMigrate triggers full table rewrite on PostgreSQL partitioned logs table every restart due to type:varchar(64) tag #4054

@xiangsx

Description

@xiangsx

问题描述

使用 PostgreSQL 时,每次服务启动 GORM AutoMigrate 都会对 request_id 列执行无意义的 ALTER TABLE,即使 schema 没有任何变化。

根因

model/log.goRequestId 字段定义:

RequestId string `json:"request_id,omitempty" gorm:"type:varchar(64);index:idx_logs_request_id;default:''"`

当前项目依赖的 gorm.io/driver/postgres v1.5.2 存在已知 bug,导致每次启动都触发:

ALTER TABLE "logs" ALTER COLUMN "request_id" TYPE varchar(64) USING "request_id"::varchar(64)
ALTER TABLE "logs" ALTER COLUMN "request_id" SET DEFAULT ''

涉及两个上游已修复的问题:

  1. 类型比对大小写不一致DatabaseTypeName() 返回小写,fileType.SQL 返回大写,导致同类型被误判为不同。已在 go-gorm/postgres#261 修复。
  2. 默认值 typecast 比对 — PostgreSQL 返回 ''::character varying,与 tag 中的 '' 字符串不匹配。已在 go-gorm/postgres#211 修复。

相同场景的上游 issue:go-gorm/gorm#6543

影响

USING 子句的 ALTER COLUMN TYPE 会触发全表重写,对数据量大的 logs 表或分区表影响尤为严重。

建议修复

升级 GORM 依赖(这些 bug 均在 v1.5.2 之后修复):

  • gorm.io/driver/postgres v1.5.2 → v1.6.0
  • gorm.io/gorm v1.25.2 → v1.31.1

已通过自动化测试验证:升级后 PostgreSQL / MySQL / SQLite 三个数据库 AutoMigrate 均稳定,不再触发多余 ALTER。

PR: #4055

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions