PG 自动升级 – Docker (和 K8s) 容器,用于自动升级你的数据库
PG Auto Upgrade – Docker (and K8s) container to auto upgrade your database

原始链接: https://github.com/pgautoupgrade/docker-pgautoupgrade

## pgautoupgrade: 自动化PostgreSQL Docker镜像 `pgautoupgrade` Docker镜像简化了PostgreSQL数据库升级,这是官方PostgreSQL镜像中缺失的功能。它会自动检测数据目录中的现有PostgreSQL版本,并使用`pg_upgrade --link`将其升级到所需版本。**备份至关重要**,因为这是一次就地升级,会删除旧集群数据。 主要功能包括:自动版本检测和升级、删除旧数据以及自定义健康检查(删除任何现有的健康检查)。提供基于Alpine和Debian的镜像(例如,`pgautoupgrade/pgautoupgrade:17-alpine`或`pgautoupgrade/pgautoupgrade:17-bookworm`)。 “一次性”模式 (`PGAUTO_ONESHOT=yes`) 在不启动服务器的情况下执行升级。 可以使用 `PGAUTO_REINDEX=no` 跳过重新索引。 从Bitnami容器升级需要特别考虑,需要root权限才能进入一次性模式,并正确设置环境变量。 该镜像还提供调试断点和使用AdventureWorks数据库的全面测试。 在Docker Hub上找到它:[https://hub.docker.com/r/pgautoupgrade/pgautoupgrade](https://hub.docker.com/r/pgautoupgrade/pgautoupgrade)

一个新的工具,**PG Auto Upgrade**,允许使用 Docker 和 Kubernetes 容器进行自动数据库升级 (github.com/pgautoupgrade)。Hacker News 的讨论引发了关于在生产环境中容器化数据库的争论。 有些人认为数据库传统上*不应该*被容器化,特别是对于性能关键型应用,而另一些人则认为在较小的设置中是可以接受的。一位具有丰富 Kubernetes 经验的用户建议将数据库运行在*集群外部*。 然而,容器化正变得越来越普遍,像 Crunchydata 这样的工具提供 Kubernetes 准备就绪的数据库解决方案。该工具现在支持 Kubernetes 和 Bitnami 镜像,使得在容器化环境中升级数据库更加容易。最终,决定取决于规模、性能需求和可用专业知识。
相关文章

原文

This is a PostgreSQL Docker image to automatically upgrade your database.

Its whole purpose in life is to automatically detect the version of PostgreSQL used in the existing PostgreSQL data directory, then automatically upgrade it (if needed) to the required version of PostgreSQL using pg_upgrade with the --link option.

After this, the PostgreSQL server starts and runs as per normal. The old cluster data will be removed.

The reason this Docker image is needed, is because the official Docker PostgreSQL image has no ability to handle version upgrades, which leaves people to figure it out manually (not great): docker-library/postgres#37

Warning

Backup your data! This Docker image does an in-place upgrade of the database data, so if something goes wrong you are expected to already have backups you can restore from.

Important

Also, remove any healthchecks. Due to how we perform the update process, we had to implement our own healthcheck. So no extra healthcheck is needed.

This image is on Docker Hub:

https://hub.docker.com/r/pgautoupgrade/pgautoupgrade

To always use the latest version of PostgreSQL, use the tag latest:

pgautoupgrade/pgautoupgrade:latest

Please note that our latest tag is based on Alpine Linux, whereas the latest tag used by the official Docker Postgres container is based on Debian (see also the section on Debian vs Alpine based images).

If you instead want to run a specific version of PostgreSQL then pick a matching tag on our Docker Hub. For example, to use PostgreSQL 17 you can use the 17-alpine tag:

pgautoupgrade/pgautoupgrade:17-alpine

Note

The images available in Github Container Registry are for debugging purposes only. They are built from specific code branches for easier distribution and testing of fixes.

Debian vs Alpine based images

The default official Docker PostgreSQL image is Debian Linux based, and upgrading from that to one of our Alpine Linux based images doesn't always work out well.

To solve that problem, we have Debian based images (17-bookworm and 16-bookworm) available now as well.

To use either of those, choose the version of PostgreSQL you'd like to upgrade to, then change your docker image to match:

pgautoupgrade/pgautoupgrade:17-bookworm

If you just want to perform the upgrade without running PostgreSQL afterwards, then you can use "One Shot" mode.

To do that, add an environment variable called PGAUTO_ONESHOT (equal to yes) when you run the container. Like this:

$ docker run --name pgauto -it \
	--mount type=bind,source=/path/to/your/database/directory,target=/var/lib/postgresql/data \
	-e POSTGRES_PASSWORD=password \
	-e PGAUTO_ONESHOT=yes \
	<NAME_OF_THE_PGAUTOUPGRADE_IMAGE>

By default, all databases are reindexed after the migration, which can take some time if they are large. To skip reindexing, set the environment variable PGAUTO_REINDEX to no, for example:

$ docker run --name pgauto -it \
	--mount type=bind,source=/path/to/your/database/directory,target=/var/lib/postgresql/data \
	-e POSTGRES_PASSWORD=password \
	-e PGAUTO_REINDEX=no \
	<NAME_OF_THE_PGAUTOUPGRADE_IMAGE>

Warning

PG v15 and below do not support reindexing system tables in a database concurrently. This means, when we start the indexing operation, database locks are placed which do not allow for any modifications as long as the task is running. We recommend using PG v16 or later where this is not an issue.

Upgrading from a Bitnami container

If you used the Postgres image by Bitnami, we have made a couple of adjustments to make this upgrade work as well.

The Bitnami containers do not persist the postgresql.conf and pg_hba.conf file in the Postgres data directory. If we detect that these files are missing, we will copy a default version of these files into the data directory. If you request the "one shot" mode, these files will be removed again at the end of the upgrade process.

The official Postgres image, and therefore ours as well, use 999 as ID for the postgres user inside the container. Bitnami uses 1001. During the upgrade process, we make a copy of the data, which will be assigned to ID 999. If you request the "one shot" mode, the original file permissions will be restored once the upgrade is completed.

Be aware that we use the environment variables from the official Postgres image. Ensure you set PGDATA to the Bitnami folder (by default /bitnami/postgresql/data) and POSTGRES_PASSWORD to the password of your Postgres user.

The container has to run as root if using one shot mode, otherwise we are unable to restore the existing file permissions of your Postgres data directory. You can run the container as user 999, but then you will have to manually apply the file permissions to your Postgres data directory.

Warning

As of writing this paragraph (14th of November, 2024), we only tested upgrading from Bitnami Postgres v13, v14, v15, v16 to v17. For these versions, we used the latest available container version. Bitnami's script and directory structure could change over time. If you note any issues upgrading from other versions, please provide the exact SHA of the image so we can try to replicate the issue.

One-shot mode in Kubernetes

You can run pgautoupgrade as an initContainer in Kubernetes to enable one-shot mode. Below you can find an example for an upgrade for a Bitnami Postgres container.

initContainers:
- env:
	- name: PGAUTO_ONESHOT
	  value: "yes"
	- name: POSTGRES_DB
	  value: XXX
	- name: PGDATA
	  value: /bitnami/postgresql/data
	- name: POSTGRES_PASSWORD
	  value: password
image: pgautoupgrade/pgautoupgrade:17-bookworm
name: upgrade-postgres
securityContext:
	runAsUser: 0
volumeMounts:
	- mountPath: /bitnami/postgresql
	  name: YYY

The value for POSTGRES_PASSWORD does not really matter, as it's never used in one-shot mode.

To build the development docker image, use:

This will take a few minutes to create the "pgautoupgrade:local" docker image, that you can use in your docker-compose.yml files.

Our wiki now includes instructions for customising the image to include your own extensions:

    https://github.com/pgautoupgrade/docker-pgautoupgrade/wiki/Including-Extensions-(PostGIS)

There are (at present) two predefined er... "breakpoints" in the image. When you run the image with either of them, then the image will start up and keep running, but the docker-entrypoint script will pause at the chosen location.

This way, you can docker exec into the running container to try things out, do development, testing, debugging, etc.

The before breakpoint stops just before the pg_upgrade part of the script runs, so you can try alternative things instead.

The server breakpoint stops after the existing pg_upgrade script has run, but before the PostgreSQL server starts. Useful if you want to investigate the results of the upgrade prior to PostgreSQL acting on them.

To run the tests, use:

The test script imports the AdventureWorks database (ported from Microsoft land) into an older PG version, then starts the pgautoupgrade container to update the database to the latest PostgreSQL version.

It then checks that the database files were indeed updated to the newest PostgreSQL release, and outputs an obvious SUCCESS/FAILURE message for that loop.

The test runs in a loop, testing (in sequence) upgrades from PostgreSQL versions 9.5, 9.6, 10.x, 11.x, 12.x, 13.x, 14.x, 15.x., 16.x and 17.x.

联系我们 contact @ memedata.com