PostgreSQL Docker从17版本升级到18版本

PostgreSQL Docker从17升级到18版本,有一些大的变动,因此升级过程需要进行一些额外的操作。

首先,17版本默认是不开启数据检验和的,因此需要先把17版本的数据库启用校验和,才能正确迁移升级到18版本。

  1. 开启校验和的第一步,一定要把数据库服务停止
  2. 然后执行:
    • docker run --rm -it \
        --mount "type=bind,src=17版本数据库目录路径,dst=/var/lib/postgresql/data" \
        postgres:17 \
        pg_checksums --enable --verbose --progress -D /var/lib/postgresql/data

      如果出现类似这样的错误:`pg_checksums: error: invalid segment number 0 in file name “/var/lib/postgresql/data/base/24699/pgrn.conf”`,可能是插件生成的文件此工具无法识别,暂时把它们移走,等执行完以上命令之后再移动回来。

  3. 完成后应该看到类似这样的结果提示:
    • Checksum operation completed
      Files scanned:   1991
      Blocks scanned:  7209262
      Files written:  1674
      Blocks written: 7209185
      pg_checksums: syncing data directory
      pg_checksums: updating control file
      Data checksum version: 1
      Checksums enabled in cluster

现在数据库的校验和就开启完成了,然后就是改变数据库的目录结构,17版本以及之前的数据目录在`/var/lib/postgresql/data`中,但18版本开始,数据目录需要在以大版本号命名的子目录中,使用以下流程进行迁移:

  1. 保持数据库服务处于停止的状态
  2. 首先你需要把原来的17版本数据库目录中的内容从`pgsql数据目录/data`中移动到`pgsql数据目录/17/docker`中(部分17版本已经把数据移动到了此目录中,视情况操作),也就是数据不再存放在”data”目录中,而是放在”版本号/docker”目录中。之后18版本的数据库将被生成在`pgsql数据目录/18/docker`目录中。
  3. 创建一个新的18版本空数据库,可以使用你自己的dockerfile或者compose文件创建,把17版本对应的配置文件复制一份改一下版本就行,以下是注意点:
    1. 注意使用”tianon/postgres-upgrade”工具需要确保新老版本的超级用户名一致,否则会报”FATAL: role “xxx” does not exist”的错误,而且我测试出来它没法通过环境变量指定新创建数据库的用户名和密码,只能使用”PGUSER”环境变量指定执行迁移时使用的用户,因此才有这一节独立创建空库的步骤,如果你原本数据库的超级用户是”postgres”,则可以尝试直接跳到下一个大步骤。
    2. 新建一个临时目录”pgsql数据目录/tmp”映射到将启动容器的”/var/lib/postgresql/”,创建完成后再把生成的”18″目录移动出来。(如果不使用临时目录,在创建新的容器时检测到数据目录中有其它包含数据库文件的目录它会拒绝启动)
    3. 创建空数据库示例:
        1. 确保你没有数据库容器在运行。
        2. 启动一个18版本的临时容器来创建数据库文件
          docker run --name temp-pg-18 \
            --mount "type=bind,src=pgsql数据目录/tmp,dst=/var/lib/postgresql/" \
            -e POSTGRES_USER=超级用户名 \
            -e POSTGRES_PASSWORD=超级用户密码 \
            -e POSTGRES_DB=postgres \
            -d postgres:18

          容器成功运行后等十几秒钟,检查”pgsql数据目录/tmp”目录中是否已经生成了数据库文件,有了的话执行命令清除临时容器:

          docker stop temp-pg-18 && docker rm temp-pg-18
        3. 最后把生成的目录从临时目录移出来(如果你刚刚已经手动创建了18目录,就把它先删除,再执行):
          mv tmp/18 ./18
          rm -r tmp
  4. 开始迁移,注意,如果你的17版本数据库使用了额外的扩展库,那么在迁移时你需要确保当前迁移环境中也有对应的扩展库,否则会提示”Your installation references loadable libraries that are missing from the new installation. You can add these libraries to the new installation, or remove the functions using them from the old installation.”。运行以下工具容器进行迁移:
    • docker run --rm \
        --mount "type=bind,src=pgsql数据目录,dst=/var/lib/postgresql" \
        --env "PGDATAOLD=/var/lib/postgresql/17/docker" \
        --env "PGDATANEW=/var/lib/postgresql/18/docker" \
        --env "PGUSER=超级用户名" \
        tianon/postgres-upgrade:17-to-18 \
          /bin/bash -c "apt update && \ #在这里执行你的依赖安装命令,如果不需要安装依赖的话可以把这个apt命令也去掉,仅占位示例用
          /usr/local/bin/docker-upgrade --link"

      不算安装依赖的时间,迁移过程应该很快会完成,并且给出如下提示:

      Upgrade Complete
      ----------------
      Some statistics are not transferred by pg_upgrade.
      Once you start the new server, consider running these two commands:
          /usr/lib/postgresql/18/bin/vacuumdb --all --analyze-in-stages --missing-stats-only
          /usr/lib/postgresql/18/bin/vacuumdb --all --analyze-only
      Running this script will delete the old cluster's data files:
          ./delete_old_cluster.sh
  5. 迁移完成之后使用18版本的数据库容器检查迁移状态:
    • 启动18版本服务之前:
      •  检查校验和(可选,如果是前面17版本刚刚生成的校验和则不用执行):
        docker run --rm -it \
          --mount "type=bind,src=pgsql数据目录,dst=/var/lib/postgresql/data" \
          postgres:18 \
          pg_checksums --check -D /var/lib/postgresql/data/18/docker
    • 启动18版本的服务
      • 重建统计信息,进入容器执行: vacuumdb -U 超级用户名 --all --analyze-in-stages

 

这样基本上就完成了迁移工作。

 



本文发布于 https://luojia.me

本站文章未经文下加注授权不得拷贝发布。

0 0 投票数
打分
订阅评论
提醒
guest
0 评论