【问题标题】:PostgreSQL: improving pg_dump, pg_restore performancePostgreSQL:提高 pg_dump、pg_restore 性能
【发布时间】:2011-01-06 21:18:39
【问题描述】:

当我开始时,我使用pg_dump 和默认的纯格式。我没有开悟。

研究向我揭示了pg_dump -Fc | gzip -9 -c > dumpfile.gz 的时间和文件大小改进。我开悟了。

当需要重新创建数据库时,

# create tablespace dbname location '/SAN/dbname';
# create database dbname tablespace dbname;
# alter database dbname set temp_tablespaces = dbname;

% gunzip dumpfile.gz              # to evaluate restore time without a piped uncompression
% pg_restore -d dbname dumpfile   # into a new, empty database defined above

我感到很茫然:恢复需要 12 个小时才能创建数据库,而这只是它的一小部分:

# select pg_size_pretty(pg_database_size('dbname'));
47 GB

因为预测这个数据库将有几 TB,所以我现在需要考虑提高性能。

请赐教。

【问题讨论】:

    标签: performance postgresql backup restore


    【解决方案1】:

    首先检查您是否从磁盘设置中获得了合理的 IO 性能。然后检查您的 PostgreSQL 安装是否经过适当调整。特别是shared_buffers应该设置正确,maintenance_work_mem应该在恢复过程中增加,full_page_writes应该在恢复过程中关闭,wal_buffers应该在恢复过程中增加到16MB,checkpoint_segments应该增加一些像 16 一样在恢复过程中,你不应该有任何不合理的登录(比如记录每个执行的语句),auto_vacuum 应该在恢复过程中被禁用。

    如果您使用的是 8.4,还可以尝试并行恢复,pg_restore 的 --jobs 选项。

    【讨论】:

    • 如果您连接了从属服务器,并且主服务器上的负载已经相当大,那么您可能只想在从服务器上进行备份。特别是由于奴隶是只读的,我想这在某种程度上也可能有所帮助。在大型集群中,如果备份需要很长时间,则让一个或多个从属服务器专门用于交错备份可能会有所帮助。为了不遗漏任何内容,您希望这些备用服务器通过流复制连接,以便它们从主服务器上的 WAL 写入。
    • shared_buffers should be set correctly 什么意思?
    • @JuanCarlosOropeza — 我遇到了以下关于 shared_buffers 的文档,它可能会有所帮助。
    【解决方案2】:

    改进 pg 转储和恢复

    PG_DUMP |始终使用格式目录和-j 选项

    time pg_dump -j 8 -Fd -f /tmp/newout.dir fsdcm_external
    

    PG_RESTORE |始终对 postgres.conf 和 format-directory 和 -j 选项进行调整

    work_mem = 32MB
    shared_buffers = 4GB
    maintenance_work_mem = 2GB
    full_page_writes = off
    autovacuum = off
    wal_buffers = -1
    
    time pg_restore -j 8 --format=d -C -d postgres /tmp/newout.dir/
    

    【讨论】:

    • 此处使用的配置参数显着提高了性能
    • 链接失效
    • 哇!这对我帮助很大!谢谢!
    【解决方案3】:

    两个问题/想法:

    1. 通过指定 -Fc,pg_dump 输出已经被压缩。压缩不是最大的,因此您可能会发现使用“gzip -9”可以节省一些空间,但我敢打赌这不足以保证用于压缩和解压缩 -Fc 版本的备份的额外时间(和 I/O) .

    2. 如果您使用的是 PostgreSQL 8.4.x,您可以使用新的 pg_restore 命令行选项“-jn”加速从 -Fc 备份的恢复,其中 n=用于恢复的并行连接数.这将允许 pg_restore 加载多个表的数据或同时生成多个索引。

    【讨论】:

    • 我们目前是8.3;升级的新理由。
    • 您可以将 8.4 版本的 pg_restore 与 8.3 版本的服务器一起使用。只需确保使用 8.3 中的 pg_dump 即可。
    • 呸。我们被困在 8.3,因为我们使用 Postgres 的 Solaris10 软件包安装,并且“目前没有将 PG8.4 集成到 S10 的计划”。 [参考。 mail-archive.com/pgsql-general@postgresql.org/msg136829.html] 我必须承担安装和维护开源 postgres 的任务。不确定我们是否可以在这里这样做...... Feh。
    【解决方案4】:

    我假设您需要备份,而不是对数据库进行重大升级。

    对于大型数据库的备份,您应该设置continuous archiving 而不是pg_dump

    1. Set up WAL archiving.

    2. 例如每天使用
      psql template1 -c "select pg_start_backup('`date +%F-%T``')" rsync -a --delete /var/lib/pgsql 进行基本备份/data/ /var/backups/pgsql/base/ psql template1 -c "select pg_stop_backup()"`

    恢复就像从备份位置恢复数据库和不早于pg_start_backup 时间的 WAL 日志并启动 Postgres 一样简单。而且速度会更快。

    【讨论】:

    • 我们没有看 PITR(WAL 归档),因为系统不是很重的事务,而是会保留许多历史记录。但是,现在我考虑一下,更“增量”的备份可能会有所帮助。我会调查的。谢谢。
    【解决方案5】:
    zcat dumpfile.gz | pg_restore -d db_name
    

    删除将未压缩数据完整写入磁盘,这是您当前的瓶颈。

    【讨论】:

      【解决方案6】:

      您可能已经猜到了压缩备份可以提高性能这一事实,您的备份受 I/O 限制。这应该不足为奇,因为备份几乎总是受 I/O 限制。压缩数据以 I/O 负载换取 CPU 负载,而且由于大多数 CPU 在巨量数据传输期间处于空闲状态,因此压缩是一种净赢。

      因此,为了加快备份/恢复时间,您需要更快的 I/O。除了将数据库重组为不是一个巨大的单一实例之外,您几乎可以做到这一点。

      【讨论】:

      • 如果只优化 pg_dump 时间,从 v9.3 开始使用并行转储,压缩 >0 会造成很大的伤害!这是因为 pg_dump 和 postmaster 进程已经占用了足够多的 CPU,以至于添加 >=1 的压缩使得整个任务显着受 CPU 限制而不是 I/O 限制。基本上,CPU 在没有压缩的情况下处于空闲状态的旧假设对于并行转储是无效的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-03
      • 2013-02-17
      • 1970-01-01
      • 1970-01-01
      • 2011-09-30
      相关资源
      最近更新 更多