【问题标题】:restore postgres within docker在 docker 中恢复 postgres
【发布时间】:2014-12-14 05:14:07
【问题描述】:

我在尝试使用 docker exec 和 postgresql psql 实用程序来恢复在 docker 1.3 中运行的 postgresql 安装时遇到了一系列问题。我有一个通过docker exec mycontainer pg_dumpall --clean --user=postgres --no-password > /tmp/backup.sql 运行正常的备份。

我在尝试恢复时遇到了问题,包括:

  • docker exec 仅在容器运行时有效,但 psql 无法通过主动连接的客户端正确恢复内容
  • pg_ctl stop 将退出 postgres 服务器进程,这将停止主容器和您正在运行的 docker exec 进程。
  • docker exec 以 root 身份运行,但 pg_ctl 必须以 postgres 身份运行(我试图使用 pg_ctl 来停止 postgres 以便恢复工作)

所以考虑到 postgresql 容器正在运行并为应用程序提供活动连接的场景,我该如何恢复它?寻找有关完全停止、运行还原、启动等的详细信息。

Env 是 docker 1.3,postgresql 9.4,数据存在于容器中安装在 /var/lib/postgresql/data 的数据卷中。我在 docker 主机文件系统上有一个有效的 .sql 备份文件。

更新:仅供参考,我愿意接受任何可行的解决方案,无论是否涉及docker exec。例如,如果我应该运行一个单独的容器并链接到主 postgresql 容器并通过 TCP 与其通信,那么只要我得到一些可行的流程就可以了。


这是我目前所拥有的。欢迎提出建议。它是一个 bash 脚本(带有一些在构建过程中插入的小胡子变量),旨在在 docker 主机上运行。

#!/bin/bash
docker_sql() {
  docker exec \
    --interactive \
    --tty \
    "${container}" \
    psql --user="${user}" --no-password --file="$1"
}

export DOCKER_HOST=tcp://localhost:2375
container="{{appName}}_db"
user=postgres
backup_path="$1"
if [[ -z "${backup_path}" ]]; then
  echo "Provide a path to a backup file" 1>&2
  exit 1
fi
backup_file=$(basename "${backup_path}")

restore_file=$(echo "${backup_file}" | sed -e s/.\bz2//)
restore_path="/var/lib/postgresql/data/${restore_file}"
bunzip2 --stdout "${backup_path}" > "/var/local/"${container}/"${restore_file}"

terminate_path="/var/lib/postgresql/data/terminate.sql"
cat <<EOF > "/var/local/${container}/terminate.sql"
revoke connect on database {{appName}} from public;
alter database {{appName}} connection limit 0;
select pg_terminate_backend(pid)
  from pg_stat_activity
  where pid <> pg_backend_pid()
  and datname='{{appName}}';
EOF

docker_sql "${terminate_path}"
docker_sql "${restore_path}"

【问题讨论】:

  • 在恢复数据库时不能停止活动连接吗?您还可以启动一个新的 postgres 容器,在那里恢复数据库,然后生成一个链接到它的新应用程序容器,停止前一个容器。
  • 如果您要提供正确的命令,是的,我想我可以“只是”停止活动连接。请参阅上面的我的 sn-p。我要求提供详细信息,因为细节很重要,而这在 docker 环境中并非易事。你关于生成一个新容器的建议听起来很合理,但由于容器命名需要一些脚本来避免冲突等。有一个 sn-p 吗?
  • 您的脚本在我看来是正确的...您禁止所有非超级用户的新连接,然后终止现有连接。你会得到哪些错误?我唯一缺少的是在恢复后打开新连接。
  • 上面的脚本可以正常工作。即使明确重新启用连接,我的应用似乎也能够在之后连接。可能是因为在还原过程中重新创建了数据库本身。

标签: postgresql docker restore


【解决方案1】:

如何正常启动和停止数据库?

①同一个容器

如果我有一个将数据库捆绑在同一个容器中的设置,我将有一个容器启动脚本,它首先在后台启动 PostgreSQL,然后execs 应用程序。

这种情况下,很容易在应用的exec前插入restore命令,关闭容器,

②分离容器

当然,如您所说,将数据库服务与应用程序分开是总体最好的解决方案——毕竟它们是独立的服务。

③管理容器

您编写的应用程序具有“安装的数据卷”数据库文件。在这种情况下,您可以创建一个管理容器,该容器也安装了这些文件,它只启动 PostgreSQL,恢复备份,然后再次退出。然后,关闭您的应用容器,在同一数据库卷上启动恢复容器,等待它退出,然后再次启动您的应用容器。

④主机

同样,您可以在主机上的数据库卷上运行 PostgreSQL。这违反了隔离原则,并且需要在主机上设置数据库,因此您可能不想这样做。

我的个人建议

我会先选择②,然后是①,然后是(在你的设置中)③,然后是④,按照优先顺序。

【讨论】:

  • 我的应用在单独的容器中运行。我正在使用官方的library/postgres:9.4 postgres 图像。我用“docker start”和“docker stop”来启动和停止它们。您的建议似乎并没有真正解决我的问题。 1 和 4 似乎与 docker 完全不协调。 2. 不是答案。 3.似乎可以,但是你不能让2个容器同时写入同一个数据卷,所以我必须协调停止数据库,开始恢复,等待恢复退出,启动数据库。
  • 从备份恢复是一个希望永远不会发生的操作。我不希望它在启动脚本中。我目前没有使用启动脚本,因为我只是在运行股票 postgres 容器。如果我这样做,则会发生还原,并且无论出于何种原因,BAM,数据丢失,我都忘记在下一次数据库重新启动之前删除还原文件。听起来很危险。你读过我上面的剧本吗?有什么相关的吗?
猜你喜欢
  • 2017-08-17
  • 2015-10-21
  • 1970-01-01
  • 2023-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-27
  • 1970-01-01
相关资源
最近更新 更多