备份/恢复dockerized PostgreSQL数据库

我正在尝试备份/恢复PostgreSQL数据库,正如Docker网站上所解释的那样,但数据没有恢复。

数据库映像使用的卷是:

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"]

我用下面的命令创建DB容器:

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

现在我删除用于db的容器,并创建另一个同名的容器,并尝试恢复之前插入的数据:

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

但是表是空的,为什么数据没有正确恢复?

298418 次浏览

好吧,我想明白了。Postgresql在启动后不会检测对/var/lib/postgresql文件夹的更改,至少不会检测我想要它检测的那种更改。

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

第二个解决方案是使用数据容器。我以前不懂,现在懂了。 这个数据容器允许在启动postgres容器之前恢复数据。因此,当postgres服务器启动时,数据已经在那里了

备份数据库

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

另一种方法(基于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'

我认为您还可以使用postgres备份容器,它可以在给定的时间内备份您的数据库。

  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

我在尝试使用db_dump恢复数据库时遇到了这个问题。我通常使用dbeaver来恢复-但是收到一个psql转储,所以必须想出一个方法来恢复使用docker容器。

Forth推荐并由soviet编辑的方法对我很有效:

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

(因为这是一个单一的db转储,而不是多个db,我包括了名称)

然而,为了让它工作,我还必须进入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,然后运行接受的答案。砰,像陀螺一样工作。希望这能帮助到其他人!

这是对我有用的命令。

cat your_dump.sql | sudo docker exec -i {docker-postgres-container} psql -U {user} -d {database_name}

例如

cat table_backup.sql | docker exec -i 03b366004090 psql -U postgres -d postgres

参考:本讨论中< em > GMartinez-Sisti < / em >给出的解。 https://gist.github.com/gilyes/525cc0f471aafae18c3857c27519fc4b < / p >

cat db.dump | docker exec ...的方式不为我的转储(~2Gb)。它花了几个小时,最后出现内存不足的错误。

相反,我cp'ed dump到容器和pg_restore'ed它从内部。

假设容器id为CONTAINER_ID, db名称为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

dksnap (https://github.com/kelda/dksnap)自动运行pg_dumpall并通过/docker-entrypoint-initdb.d加载转储。

它向您显示正在运行的容器列表,您可以选择要备份的容器。生成的工件是一个常规的Docker映像,所以你可以docker run它,或者通过将它推送到Docker注册表来共享它。

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

下面的命令可以用来从docker postgress容器中获取dump

docker exec -t <postgres-container-name> pg_dump --no-owner -U <db-username> <db-name> > file-name-to-backup-to.sql

备份数据库

生成sql:

  • docker exec -t your-db-container pg_dumpall -c -U your-db-user > dump_$(date +%Y-%m-%d_%H_%M_%S).sql

为了减少SQL的大小,你可以生成一个压缩:

  • docker exec -t your-db-container pg_dumpall -c -U your-db-user | gzip > ./dump_$(date +"%Y-%m-%d_%H_%M_%S").gz

恢复数据库

  • cat your_dump.sql | docker exec -i your-db-container psql -U your-db-user -d your-db-name

恢复已压缩的sql:

  • gunzip < your_dump.sql.gz | docker exec -i your-db-container psql -U your-db-user -d your-db-name

PD:这是对我有用的东西的汇编,以及我从这里和其他地方得到的东西。我开始做贡献,任何反馈将不胜感激。

我想为备份和恢复添加官方docker文档。这适用于卷中的所有类型的数据,而不仅仅是postegres。

备份容器

创建一个名为dbstore的新容器:

$ docker run -v /dbdata --name dbstore ubuntu /bin/bash

然后在下一个命令中,我们:

  • 启动一个新的容器并从dbstore容器挂载卷

  • 挂载本地主机目录为/backup

  • 传递一个命令,将dbdata卷的内容tar到/backup目录下的backup.tar文件。

    $ docker run——rm——volumes-from dbstore -v $(pwd):/backup ubuntu tar CVF /backup/backup.tar /dbdata . zip

当命令完成并且容器停止时,我们只剩下dbdata卷的备份。

从备份中恢复容器

使用刚刚创建的备份,您可以将其恢复到相同的容器中,或者在其他地方创建的另一个容器中。

例如,创建一个名为dbstore2的新容器:

$ docker run -v /dbdata --name dbstore2 ubuntu /bin/bash

然后解压新容器数据卷中的备份文件:

$ docker run --rm --volumes-from dbstore2 -v $(pwd):/backup ubuntu bash -c "cd /dbdata && tar xvf /backup/backup.tar --strip 1"

您可以使用上面的技术,使用您喜欢的工具自动备份、迁移和恢复测试。

上面那个答案对我没用。我一直得到这个错误:

psql: error: FATAL:  Peer authentication failed for user "postgres"

为了让它工作,我必须为docker容器指定一个用户:

备份

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

恢复

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

在Docker卷上使用文件系统级备份

示例Docker Compose

version: "3.9"


services:
db:
container_name: pg_container
image: platerecognizer/parkpow-postgres
# restart: always
volumes:
- postgres_data:/var/lib/postgresql/data/
environment:
POSTGRES_USER: admin
POSTGRES_PASSWORD: admin
POSTGRES_DB: admin


volumes:
postgres_data:

备份Postgresql卷

docker run --rm \
--user root \
--volumes-from pg_container \
-v /tmp/db-bkp:/backup \
ubuntu tar cvf /backup/db.tar /var/lib/postgresql/data

然后复制/tmp/db-bkp到第二台主机

恢复Postgresql卷

docker run --rm \
--user root \
--volumes-from pg_container \
-v /tmp/db-bkp:/backup \
ubuntu bash -c "cd /var && tar xvf /backup/db.tar --strip 1"

docker-compose用户的解决方案:

  1. 首先运行docker-compose文件,使用以下任意一个命令:$ docker-compose -f loca.yml updocker-compose -f loca.yml up -d
  2. 用于备份:$ docker-compose -f local.yml exec postgres backup
  3. 查看容器中的备份列表:$ docker-compose -f local.yml exec postgres backups
  4. 打开另一台终端,执行如下命令:$ docker ps
  5. 寻找postgres映像的容器ID并复制ID。让我们假设容器ID是:< >强ba78c0f9bcee < / >强
  6. 现在,要将备份文件导入本地文件系统,请运行以下命令:$ docker cp ba78c0f9bcee:/backups ./local_backupfolder

希望这能帮助到像我一样迷路的人。

注意:此解决方案的全部细节可以在在这里中找到。

另一种方法是从主机上运行pg_restore(当然,如果您在主机上设置了postgres)命令。

假设您有端口映射"5436:5432;对于docker-compose文件中的postgres服务。有了这个端口映射,就可以通过主机的端口5436访问容器的postgres(运行在端口5432上)

pg_restore -h localhost -p 5436 -U <POSTGRES_USER> -d <POSTGRES_DB>  /Path/to/the/.psql/file/in/your/host_machine

这样,您就不必深入容器的终端或将转储文件复制到容器中。