【问题标题】:Backup/Restore a dockerized PostgreSQL database备份/恢复 dockerized PostgreSQL 数据库
【发布时间】:2014-09-03 07:36:48
【问题描述】:

我正在尝试按照 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 

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

【问题讨论】:

标签: database postgresql backup docker


【解决方案1】:

备份您的数据库

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

【讨论】:

  • 是的,这是 postgres 的方式,但我认为使用 docker 方式时应该总是首选
  • 为了节省一些磁盘空间,您可能希望将转储通过管道传输到 gzip:docker exec -t your-db-container pg_dumpall -c -U postgres | gzip &gt; /var/data/postgres/backups/dump_date +%d-%m-%Y"_"%H_%M_%S.gz
  • 日期格式有问题,所以在复制和粘贴之前请仔细检查。
  • 对于那些不知道如何使日期格式正常工作的人:docker exec -t your-db-container pg_dumpall -c -U postgres | gzip &gt; ./tmp/dump_$(date +"%Y-%m-%d_%H_%M_%S").gz
  • 还原数据库时,请确保将-d your-db-name 添加到还原命令如果您的数据库未命名为postgres
【解决方案2】:

我认为您还可以使用 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

【讨论】:

  • 你运行这个命令有多精确? docker 等新手
  • 这不是@JackB 命令,而是docker-compose 文件。 docs.docker.com/compose
  • 是的。正确只需使用它插入您的 docker-compose 文件,然后运行 ​​docker-compose 文件
  • @TharinduPradeep 谢谢。我可以看到容器,但备份在哪里?
  • 对于想要定期自动备份数据库的人来说非常有用。
【解决方案3】:

备份数据库

生成sql:

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

要减小 sql 的大小,您可以生成压缩文件:

  • docker exec -t your-db-container pg_dumpall -c -U your-db-user | gzip &gt; ./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 &lt; your_dump.sql.gz | docker exec -i your-db-container psql -U your-db-user -d your-db-name

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

【讨论】:

  • 使用“cat your_dump.sql | ....”来恢复我认为性能非常低的数据库,我错了吗?
【解决方案4】:

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

相反,我 cp'ed 转储到容器中并从内部 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

【讨论】:

  • 这种方法与公认的方法不同,它帮助我在 Windows 中执行此操作时获得正确的编码。 (实际上,我通过 cat /home/db.sql | psql -U postgres -d DB_NAME -p DB_PORT 应用了转储)
  • 这工作得更快。可以基于此制作备份脚本,使用包含的脚本构建映像,并通过 cronjob 从主机触发脚本。将主机卷挂载到容器上,并让备份服务器拉取每日 sql-dumps。
  • 我很感激,因为我遇到了与cat db.dum |...完全相同的问题
【解决方案5】:

好的,我想通了。 Postgresql 在启动后不会检测到文件夹 /var/lib/postgresql 的更改,至少不是我希望它检测到的那种更改。

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

第二种解决方案是使用数据容器。以前没明白,现在明白了。 此数据容器允许在启动 postgres 容器之前恢复数据。因此,当 postgres 服务器启动时,数据已经存在。

【讨论】:

  • flocker 或 convoy 可能有助于处理数据容器。
  • 请填写详细信息。这听起来更像是一个解决方案的草图,而不是一个实际的解决方案
【解决方案6】:

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

【讨论】:

  • 这对我有用:pg_dump mydb -U postgres &gt; export.psql 在 docker 容器 bash 中
【解决方案7】:

以下命令可用于从 docker postgress 容器中获取转储

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

【讨论】:

    【解决方案8】:

    我在尝试使用 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 @-&gt;/var/run/docker.sock: read: connection reset by peer

    这可能是由文件 /var/lib/docker/network/files/local-kv.db 引起的。我不知道这个陈述的准确性:但我相信我看到了这个,因为我不是用户docker 本地,因此没有这个文件,它正在寻找,使用 Forth 的答案。

    然后我导航到正确的目录(带有项目)激活了 virtualenv,然后运行了接受的答案。繁荣,工作就像一个顶部。希望这对其他人有帮助!

    【讨论】:

      【解决方案9】:

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

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

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

      【讨论】:

      • 太棒了!期待“可编写脚本的非图形 CLI 界面”。这样我就可以从 Robot Framework 测试中使用它:)
      【解决方案10】:

      最佳答案对我不起作用。我一直收到这个错误:

      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
      

      【讨论】:

        【解决方案11】:

        这是对我有用的命令。

        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
        

        参考GMartinez-Sisti 在此讨论中给出的解决方案。 https://gist.github.com/gilyes/525cc0f471aafae18c3857c27519fc4b

        【讨论】:

        • 当我运行命令cat your_dump.sql | sudo docker exec -i {docker-postgres-container} psql -U {user} -d {database_name} 时,我在终端返回invalid command \N
        【解决方案12】:

        我想为backups and restores 添加官方 docker 文档。这适用于卷中的所有类型的数据,而不仅仅是 postegres。

        备份容器

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

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

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

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

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

        • 将压缩 dbdata 卷内容的命令传递给 /backup 目录中的 backup.tar 文件。

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

        当命令完成并且容器停止时,我们留下了 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"
        

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

        【讨论】:

          【解决方案13】:

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

          Docker 编写示例

          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"
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-10-10
            • 1970-01-01
            • 2013-10-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多