【发布时间】: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