如何更新部署在Kubernetes上的数据库Schema与数据?
Kubernetes集群Postgres补丁更新与Schema变更实操方案
一、Postgres补丁版本更新操作流程
这里说的补丁更新指同大版本下的小版本迭代(比如14.2升级到14.10),Postgres官方对同大版本的小补丁做了数据格式100%兼容承诺,不需要做数据导出导入,按以下流程操作即可:
- 前置准备:更新前先给Postgres绑定的Persistent Volume打快照做全量备份,云环境直接打云盘快照,本地集群可以用
pg_basebackup做热备,备份校验完成前不要操作线上实例。同时确认目标补丁镜像和当前运行的数据库大版本完全一致,跨大版本升级不能走这个流程。 - 调整更新策略:如果用Deployment/StatefulSet部署数据库,先把工作负载的更新策略改成
OnDelete,不要用默认的RollingUpdate,避免K8s自动拉起新实例导致新旧两个Postgres进程同时挂载同一个PVC,触发数据文件锁冲突甚至损坏数据。 - 切流:把所有指向数据库的业务流量切走,或者将数据库Service的后端权重置0,确保更新过程中没有新的写入请求。
- 替换镜像触发更新:修改工作负载的镜像字段为目标补丁版本的Postgres镜像,手动删除当前运行的旧版本Pod,等待K8s自动拉取新镜像拉起实例。
- 校验回切:新Pod启动后先查看运行日志确认无报错,执行
psql -U <用户名> -c "SELECT version();"确认版本符合预期,再做简单的读写验证确认数据完整,最后把业务流量切回即可。
如果你是用Patroni、CloudNativePG、Zalando这类Postgres Operator部署的高可用集群,不需要手动做以上步骤,直接修改Operator里的镜像版本字段,Operator会自动按主从顺序做滚动更新、切主、流量切换,避免人为操作失误。
二、生产环境Schema与数据SQL更新可行方案
生产环境不建议直接进入Pod执行psql命令跑变更,没有审计记录也容易误操作,常用的可靠方案有三类:
- 一次性K8s Job执行(适合变更频率低、SQL耗时短的场景)
编写K8s Job资源,用和线上数据库同版本的Postgres镜像,启动后自动执行预定义的SQL脚本,执行完成后Job自动退出,执行记录可以直接通过K8s日志留存。SQL脚本可以直接写在启动参数里,也可以挂载ConfigMap存储长脚本。参考配置示例:
注意这类Job执行前,必须在和生产同数据量级的预发环境跑通全流程,记录SQL执行耗时,避开业务高峰执行,大表变更要使用Postgres的低锁语法,避免长事务锁表影响线上业务。apiVersion: batch/v1 kind: Job metadata: name: pg-schema-update-20240520 spec: template: spec: restartPolicy: Never containers: - name: psql-runner image: postgres:14.10 command: ["psql"] args: ["-h", "pg-service.default.svc.cluster.local", "-U", "postgres", "-d", "app_db", "-f", "/sql/update.sql"] volumeMounts: - name: sql-script mountPath: /sql env: - name: PGPASSWORD valueFrom: secretKeyRef: name: pg-admin-cred key: password volumes: - name: sql-script configMap: name: pg-update-sql-20240520 - 版本化迁移工具集成(适合迭代频繁、变更多的生产场景)
用Flyway、Liquibase、golang-migrate这类专业的数据库版本迁移工具,把每一次Schema、数据变更写成带唯一版本号的脚本,工具会自动在数据库里建变更记录表,记录已经执行过的脚本,避免重复执行、漏执行,同时支持回滚逻辑。把这类工具封装成K8s Job,在每次业务发版前先执行迁移Job,确认变更成功后再上线业务版本,是目前生产环境最常用的落地方案。 - Operator原生变更能力(适用于用PG Operator部署的集群)
主流的Postgres Operator都自带SQL变更的能力,可以直接在数据库自定义资源(CR)里定义要执行的SQL,Operator会自动在主库节点按顺序执行,同时自带执行前备份、执行结果校验、失败暂停的能力,比手动写Job的可靠性更高。
所有涉及表结构修改、批量数据更新的操作,执行前必须做全量数据备份,一旦出现执行错误可以快速回滚恢复。
内容的提问来源于stack exchange,提问作者Salvatore Calla'
相关产品推荐
相关产品推荐

