From 41b83e3a645c78fa97c358fecd41e2228ae1827d Mon Sep 17 00:00:00 2001 From: "34047007@qq.com" <34047007@qq.com> Date: Mon, 10 Aug 2026 06:06:41 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=89=B9=E6=AC=A11=E7=88=86=E7=9B=98?= =?UTF-8?q?=E6=A0=B9=E5=9B=A0=20=E2=80=94=20alembic=20=E7=8B=AC=E7=AB=8B?= =?UTF-8?q?=E4=BA=8B=E5=8A=A1=20+=205=E6=97=A5=E6=9C=9F=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E5=90=88=E5=B9=B6=E5=8D=95=E6=9D=A1ALTER?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 生产 123 万行表(9.8GB)跑批次1时磁盘满回滚(2026-08-10)。 根因二:① alembic 无 transaction_per_migration,批次1的 01+02+03 全在一个 事务,JSON→JSONB 重写空间不释放、与后续重写叠加;② 1421ea169bb6 循环逐个 ALTER 5 个日期字段 = 5 次整表重写,同一事务累积。 修复:alembic.ini 开启 transaction_per_migration(每迁移独立提交,前序空间 释放);1421ea169bb6 合并 5 列为单条 ALTER(一次重写)。 本地 DB 已在 head 不受影响,heads 仍单一头 55105f0bb1d7。 --- backend/alembic/alembic.ini | 6 +++++ ...21ea169bb6_change_5_date_fields_to_date.py | 26 +++++++++---------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/backend/alembic/alembic.ini b/backend/alembic/alembic.ini index 37b1a50..160fab4 100644 --- a/backend/alembic/alembic.ini +++ b/backend/alembic/alembic.ini @@ -1,6 +1,12 @@ [alembic] script_location = alembic sqlalchemy.url = postgresql://scilit:scilit_dev@localhost:5432/scilit +# Commit each migration in its own transaction (default: whole upgrade in one). +# Rewrite-heavy migrations (JSON->JSONB / ALTER COLUMN TYPE DATE) on the +# 1.23M-row prod table peak at huge disk usage; one shared txn accumulates +# them -> disk-full (2026-08-10 batch 1 incident root cause). +# Independent commits release space early. +transaction_per_migration = true [loggers] keys = root,sqlalchemy,alembic diff --git a/backend/alembic/versions/1421ea169bb6_change_5_date_fields_to_date.py b/backend/alembic/versions/1421ea169bb6_change_5_date_fields_to_date.py index a58c009..a6db69e 100644 --- a/backend/alembic/versions/1421ea169bb6_change_5_date_fields_to_date.py +++ b/backend/alembic/versions/1421ea169bb6_change_5_date_fields_to_date.py @@ -21,19 +21,19 @@ DATE_FIELDS = ["pubmed_revised", "date_completed", "meshed_date", "create_date", def upgrade() -> None: - for col in DATE_FIELDS: - op.alter_column("global_literature", col, - existing_type=postgresql.TIMESTAMP(timezone=True), - type_=sa.Date(), - existing_nullable=True, - postgresql_using=f"{col}::date", - ) + # 合并为单条 ALTER:5 列一次全表重写。 + # 原实现循环逐个 ALTER = 5 次整表重写,同一事务内空间峰值叠加, + # 生产 123 万行表(~9.8GB)会爆盘(2026-08-10 批次 1 事故根因)。 + _cols = ", ".join( + f'ALTER COLUMN "{col}" TYPE DATE USING "{col}"::date' + for col in DATE_FIELDS + ) + op.execute(f"ALTER TABLE global_literature {_cols}") def downgrade() -> None: - for col in reversed(DATE_FIELDS): - op.alter_column("global_literature", col, - existing_type=sa.Date(), - type_=postgresql.TIMESTAMP(timezone=True), - existing_nullable=True, - ) + _cols = ", ".join( + f'ALTER COLUMN "{col}" TYPE TIMESTAMP WITH TIME ZONE' + for col in reversed(DATE_FIELDS) + ) + op.execute(f"ALTER TABLE global_literature {_cols}")