如何从Docker容器中生成PostgreSQL转储?

76

我希望有一种方法能够进入Postgresql容器并从中获取数据转储。

10个回答

85

从UNIX或Windows终端使用以下命令:

docker exec <container_name> pg_dump <schema_name> > backup
以下命令将只从所有表中转储插入语句:
docker exec <container_name> pg_dump --column-inserts --data-only  <schema_name> > inserts.sql

9
您需要指定用户和用户密码的位置在哪里? - VaTo
9
您可以这样指定用户: docker exec <container_name> pg_dump -U <user> --column-inserts --data-only <schema_name> > inserts.sql - LondonAppDev
如果您的容器中没有设置PGUSER,则需要export PGUSER=postgres才能使其正常工作(在Postgres 9.6中进行了测试)。 - Stefan Höltker
这也适用于Windows命令提示符。 - Tobias Grunwald
如果您需要输入密码,请运行上面相同的命令,但在docker exec后添加“-it”(即“docker exec -it ...”)。输入此命令后,您将获得一个空白光标。输入您的数据库密码并再次按Enter键。现在它将执行pd_dump。注意:i代表交互式,因此添加此标志允许您在pg_dump要求输入密码时输入密码。不幸的是,您将看不到“密码”提示,但如果您只是输入密码并按Enter键,它将起作用。 - Andrew Einhorn

32

我有一个名为 postgres 的容器,挂载了卷 -v /backups:/backups

要备份已压缩的数据库 my_db,我使用以下命令:

docker exec postgres pg_dump -U postgres -F t my_db | gzip >/backups/my_db-$(date +%Y-%m-%d).tar.gz

现在我有:
user@my-server:/backups$ ls
my_db-2016-11-30.tar.gz

1
我得到了一个 no such file or directory: /backups/my_db-2017-03-19.tar.gz 的错误,你有什么想法为什么会出现这个错误? - drskullster
3
我成功地用docker exec -t postgres bash -c 'pg_dump -U postgres -F t my_db | gzip >/backups/my_db-$(date +%Y-%m-%d).tar.gz'解决了这个问题。 - drskullster
也许你没有/backups目录,或者它没有挂载? - Jekis
已经挂载。问题似乎来自于docker无法理解该命令:https://dev59.com/jVoU5IYBdhLWcg3wAjcs - drskullster
@drskullster 的命令字符串很好用,感谢您的参考。 - Pham
3
小细节:实际上这并不是在执行 tar gz,而是仅仅进行了 gz 压缩,但你给 SQL 文件命名时使用了 .tar 扩展名,然后对其进行了 gzip 压缩。如果你通过 gunzip 解压它,你会得到一个名为 my_db-date.tar 的无法读取的文件,但如果你将 .tar 改成 .sql,它就是一个 SQL 文件了。建议你将输出文件命名为 "filename.gz" 或者使用 tar -cz 如果你确实想要一个 .tar.gz 文件扩展名。 - Matt Fletcher

18

虽然上面的安装点解决方案看起来很有前途,但在多次尝试后,以下是唯一有效的解决方案:

docker run -it  -e PGPASSWORD=my_password postgres:alpine  pg_dump  -h hostname -U my_user my_db > backup.sql

我这种情况的独特之处在于:我的数据库有一个需要传递的密码;需要传递标签(alpine);最后,主机上的psql工具版本与docker版本不同。


5
和前面的回答类似,这条命令也可以用来备份 PostgreSQL 数据库:docker exec -e PGPASSWORD=mypass container pg_dump -U myuser mydb > file.bkup.sql - Stefano Scarpanti

6

这个使用 container_name 而不是 database_scheme 的那个,对我来说有效:

docker exec {container_name} pg_dump -U {user_name} > {backup_file_name}

例如,对于我来说,数据库名称、用户和密码应该在docker-compose.yaml文件中声明。
希望这能对某些人有所帮助。

3

针对那些在权限方面遇到问题的用户,我成功地使用了以下命令来执行我的转储:

docker exec -i MY_CONTAINER_NAME /bin/bash -c "PGPASSWORD=MY_PASSWORD pg_dump -Fc -h localhost -U postgres MY_DB_NAME" > /home/MY_USER/db-$(date +%d-%m-%y).backup

2
这将挂载当前目录并包含您的环境变量。
docker run -it --rm \
--env-file <(env) \
-w /working \
--volume $(pwd):/working \
postgres:latest /usr/bin/pg_dump -Fc -h localhost -U postgres MY_DB_NAME" > /working/db-$(date +%d-%m-%y).backup

2
请参考PostgreSQL备份和还原文档。如其他人所述,使用docker exec在容器内运行命令,在此情况下使用pg_dumppg_dumpall创建转储文件。将它们写入docker volume以防止增加容器大小并提供从容器外部访问的转储。

TLDR

docker exec <container_name> pg_dump [-U db_user] -f [filepath] <db>

例如:

docker exec db pg_dump -U admin -f /db-backups/db.pg_dump.bak nextcloud

说明

尽管输出重定向在文档中随处可见,但使用docker exec时可能会遇到麻烦。

docker exec db pg_dump db > db.pg_dump.bak

您想要发生的事情

docker exec db (pg_dump db > db.pg_dump.bak)

实际上正在发生的事情

(docker exec db pg_dump db) > db.pg_dump.bak

我尝试使用shell引用来解决这个问题,可能是因为它在容器中的处理方式。幸运的是,我们根本不必使用输出重定向。 pg_dump的man页面记录了一个-f选项,该选项接受目标而不是文件名。这完全避免了问题。


1
另一种解决方法是在docker中使用挂载点启动postgre sql到转储位置。例如,docker run -v <文件位置>。然后对正在运行的docker容器执行docker inspect。
docker inspect <image_id>

你可以在其中找到“Volumes”标签以及相应的位置。前往该位置,你可以找到所有的postgresql/mysql文件。这对我有效。如果这对你也有效请告知我们。
祝好运。

0

要运行具有Postgres用户和密码的容器,您需要将预配置的变量作为容器环境变量。

例如:

docker run -it --rm --link <container_name>:<data_container_name> -e POSTGRES_PASSWORD=<password> postgres /usr/bin/pg_dump -h <data_container_name> -d <database_name> -U <postgres_username> > dump.sql


“--link” 是一个遗留功能。 - Melroy van den Berg

0
我使用这个脚本:
docker exec postgres-1 pg_dump -U postgres --column-inserts --data-only  postgres > inserts.sql

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接