首页 > 解决方案 > 除了删除数据库集群之外,还保留一个静态的大型 Postgres 数据库吗?

问题描述

我有一个用于本地开发的应用程序,它有多个 Docker 容器(在 Docker Compose 下组织)。其中一个容器是基于官方postgres:10图像的 Postgres 10 实例。该实例将其数据目录挂载为 Docker 卷,该卷在容器运行中持久保存数据。到目前为止一切都很好。

作为测试 postgres 集群的创建和初始化的一部分,我经常需要删除保存数据的 Docker 卷。(官方的 postgres 映像运行 cluster init if-and-only-如果在容器启动时发现数据目录为空。)这也很好。

然而!我现在有一种情况,为了测试和使用第三方 Postgres 扩展,我需要从 Postgres 备份转储文件将大约 6GB(完全静态)地理编码查找数据加载到集群上的数据库中。当然可以在容器启动时从本地挂载点加载数据,并且生成的(非常大的)表将在包含整个集群的卷中在容器重新启动时持续存在。

不幸的是,它们将无法在移除 docker 卷后幸存下来,这再次需要以某种频率发生。我正在寻找一种方法来加快或避免重建保存地理编码数据的单个数据库。

我曾经或目前正在考虑的方法:

  1. 在同一容器上使用单独的 Docker 卷为单独的 Postgres 表空间创建持久存储,该表空间仅包含地理编码器数据库。这似乎是行不通的,因为虽然我可以肯定地设置它,但官方 PG 文档说表空间和集群是密不可分的,因此集群其余部分的丢失会导致额外的表空间无法使用。我很想错了,因为这似乎是最简单的解决方案。
  2. 创建一个运行 Postgres 的完全独立的容器,该容器安装一个卷来保存一个单独的集群,该集群仅包含地理编码数据。大概我需要对外部数据包装器(或一些我目前不知道的更神秘的 postgres 管理技巧)做一些笨拙的事情,以使数据可以从应用程序代码无缝访问。

所以,我的问题是:有没有人知道一种方法可以从 dockerized Postgres 集群中持久化单个数据库,而不使用转储和重新加载策略?

标签: postgresqldockerdocker-volumepostgresql-10tablespace

解决方案


如果您想加快速度,则可以将数据库转储转换为数据目录(将转储导入干净的 postgres 容器,停止它并创建数据目录的 tarball,然后将其上传到某处)。现在,当您需要创建一个新的 postgres 容器时,使用初始化脚本来停止数据库,下载并将压缩包解压到数据目录并再次启动数据库,这样您就可以跳过整个数据库恢复过程。

注意:数据 tarball 必须与 postgres 主要版本匹配,因此容器从它开始没有问题。

如果您想进一步加快速度,请创建一个自定义的 postgres 映像,其中捆绑了 tarball 和 init 脚本,这样每次启动时它都会擦除空集群并复制您自己的集群。

您甚至可以更改入口点以使用您的自定义脚本并加载数据库数据,然后调用 docker-entrypoint.sh,这样就无需删除可能的空集群。

这只有在您每次想要运行测试时都可以更换整个集群时才有效,否则您将无法导入数据库转储。


推荐阅读