备份/还原Docker化的PostgreSQL数据库


155

我正在尝试按照Docker网站上的说明备份/还原PostgreSQL数据库,但数据未还原。

数据库映像使用的卷为:

VOLUME  ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"]

CMD为:

CMD ["/usr/lib/postgresql/9.3/bin/postgres", "-D", "/var/lib/postgresql/9.3/main", "-c", "config_file=/etc/postgresql/9.3/main/postgresql.conf"]

我使用以下命令创建数据库容器:

docker run -it --name "$DB_CONTAINER_NAME" -d "$DB_IMAGE_NAME"

然后,我连接另一个容器以手动插入一些数据:

docker run -it --rm --link "$DB_CONTAINER_NAME":db "$DB_IMAGE_NAME" sh -c 'exec bash'
psql -d test -h $DB_PORT_5432_TCP_ADDR
# insert some data in the db
<CTRL-D>
<CTRL-D>

然后创建tar归档文件:

$ sudo docker run --volumes-from "$DB_CONTAINER_NAME" --rm -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /etc/postgresql /var/log/postgresql /var/lib/postgresql

现在,我删除用于数据库的容器,并创建另一个具有相同名称的容器,然后尝试恢复之前插入的数据:

$ sudo docker run --volumes-from "$DB_CONTAINER_NAME" --rm -v $(pwd):/backup ubuntu tar xvf /backup/backup.tar 

但是表是空的,为什么不能正确还原数据?


Answers:


457

备份数据库

docker exec -t your-db-container pg_dumpall -c -U postgres > dump_`date +%d-%m-%Y"_"%H_%M_%S`.sql

恢复数据库

cat your_dump.sql | docker exec -i your-db-container psql -U postgres

2
是的,这是postgres的方法,但我认为使用docker方法时应始终首选它
Carl Levasseur 2015年

42
为了节省磁盘空间,您可能需要将转储通过管道传输到gzip: docker exec -t your-db-container pg_dumpall -c -U postgres | gzip > /var/data/postgres/backups/dump_date +%d-%m-%Y“ _”%H_%M_%S.gz
Tarion

1
在还原数据之前,只需解压缩数据即可。要将其作为一个衬板执行,您必须将其替换cat your_dump.sql为unzip命令,然后将其通过管道cat传递给docker exec。
Tarion '17

2
日期格式混乱,因此在复制和粘贴之前请仔细检查。
vidstige '18年

1
对于那些将无法弄清楚如何使用日期格式的人: docker exec -t your-db-container pg_dumpall -c -U postgres | gzip > ./tmp/dump_$(date +"%Y-%m-%d_%H_%M_%S").gz
user1230795

18

我认为您也可以使用potgres备份容器,该容器将在给定的时间内备份​​数据库。

  pgbackups:
    container_name: Backup
    image: prodrigestivill/postgres-backup-local
    restart: always
    volumes:
      - ./backup:/backups
    links:
      - db:db
    depends_on:
      - db
    environment:
      - POSTGRES_HOST=db
      - POSTGRES_DB=${DB_NAME} 
      - POSTGRES_USER=${DB_USER}
      - POSTGRES_PASSWORD=${DB_PASSWORD}
      - POSTGRES_EXTRA_OPTS=-Z9 --schema=public --blobs
      - SCHEDULE=@every 0h30m00s
      - BACKUP_KEEP_DAYS=7
      - BACKUP_KEEP_WEEKS=4
      - BACKUP_KEEP_MONTHS=6
      - HEALTHCHECK_PORT=81

1
完美的作品!谢谢
CaM2091

15

好的,我知道了。一旦启动,PostgreSQL不会检测到对/ var / lib / postgresql文件夹的更改,至少不会检测到我希望它检测到的更改。

第一种解决方案是使用bash启动容器,而不是直接启动postgres服务器,还原数据,然后手动启动服务器。

第二种解决方案是使用数据容器。我以前没有明白这一点,现在知道了。该数据容器允许在启动postgres容器之前还原数据。因此,当postgres服务器启动时,数据已经存在。


1
羊群或护卫舰可能有助于处理数据容器。
2015年

24
请填写更多详细信息。这听起来更像是解决方案的草图,而不是实际的解决方案
nafg

5

另一种方法(基于docker-postgresql-workflow

本地运行的数据库(不在docker中,但可以使用相同的方法)导出:

pg_dump -F c -h localhost mydb -U postgres export.dmp

容器数据库导入:

docker run -d -v /local/path/to/postgres:/var/lib/postgresql/data postgres #ex runs container as `CONTAINERNAME` #find via `docker ps`
docker run -it --link CONTAINERNAME:postgres  --volume $PWD/:/tmp/  postgres  bash -c 'exec pg_restore -h postgres -U postgres -d mydb -F c /tmp/sonar.dmp'

1
这对我pg_dump mydb -U postgres > export.psql有用:在docker container bash中
Sepultura '18

3

尝试使用db_dump还原数据库时遇到此问题。我通常使用dbeaver进行还原-但是收到了psql转储,因此不得不找出一种使用docker容器进行还原的方法。

Forth建议并由Soviut编辑的方法为我工作:

cat your_dump.sql | docker exec -i your-db-container psql -U postgres -d dbname

(因为这是一个数据库转储,而不是多个数据库,所以我添加了名称)

但是,为了使其正常工作,我还必须进入docker容器和项目所在的virtualenv。在弄清楚它之前,这使我有些困惑-因为我收到以下docker错误。

read unix @->/var/run/docker.sock: read: connection reset by peer

这可能是由于文件/var/lib/docker/network/files/local-kv.db引起的。我不知道该语句的准确性:但是我相信我已经看到了这一点,因为我不在本地使用docker,因此,使用Forth的答案,它没有要查找的文件。

然后,我导航到正确的目录(与项目一起),激活了virtualenv,然后运行了接受的答案。景气,像顶一样。希望这可以帮助其他人!



1

cat db.dump | docker exec ...方式对我的转储(〜2Gb)不起作用。花了几个小时,最终出现内存不足错误。

相反,我将其cp转储到容器中,然后从内部进行pg_restore。

假设容器标识为CONTAINER_ID,数据库名称为DB_NAME

# copy dump into container
docker cp local/path/to/db.dump CONTAINER_ID:/db.dump

# shell into container
docker exec -it CONTAINER_ID bash

# restore it from within
pg_restore -U postgres -d DB_NAME --no-owner -1 /db.dump

0

dksnaphttps://github.com/kelda/dksnap)通过自动化运行pg_dumpall和加载转储的过程/docker-entrypoint-initdb.d

它显示了一个正在运行的容器列表,并选择了要备份的容器。生成的工件是常规的Docker映像,因此您可以然后docker run将其推送到Docker注册表,或将其共享。

(免责声明:我是该项目的维护者)


0

以下命令可用于从docker postgress容器中进行转储

docker exec -t <postgres-container-name> pg_dump --no-owner -U <db-username> <db-name> > file-name-to-backup-to.sql
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.