在大型数据库上使用pg_dump和pg_restore

5

我目前有一个任务,需要改进数据库结构。为此,我们想要有效地转储和恢复一个单一的巨大数据库。(约1TB并不断增长)

为了测试这个数据库,我们想将其转移到另一个服务器节点,使用pg_dumppg_restore实现。

我们正在运行一个v10(https://www.postgresql.org/docs/10/app-pgdump.html)服务器,因此我们受到其可能参数的限制。同时,必须转储整个数据库,而不仅仅是部分内容。

为此,我尝试了几种方法,以下资源对我帮助很大:

最重要的是:

问题在于,你几乎只能同时改善这两个任务中的一个,而不能同时改善两个。
案例1
以目录格式转储非常快(~1小时),但还原不快。
pg_dump --blobs --dbname="$DBNAME" --file=$DUMPDIR --format=directory --host=$SERVERHOSTNAME --jobs=$THREADS --port=$SERVERPORT--username="$SERVERUSERNAME"
pg_restore --clean --create --format=directory --jobs=$THREADS --host=$SERVERHOSTNAME --port=$SERVERPORT --username="$SERVERUSERNAME" "./"

这个恢复方法存在的问题是,即使我分配了多个核心给它,它仅使用一个核心,在服务器核心上仅使用了不到4%的CPU。
案例2
以自定义格式转储非常缓慢,以至于服务器甚至无法在一夜之间完成(会话超时)。
pg_dump --blobs --compress=9 --dbname="$dbname" --file="$DUMPDIR/db.dump" --format=custom --host=$SERVERHOSTNAME --port=$SERVERPORT --username=$SERVERUSERNAME

我有不同的方法:
  1. 使用方法1进行转储,之后进行转换(如何?),并使用更快的恢复方法(变体2?)
  2. 在不同的核心上同时创建具有不同模式的多个转储(共6个),然后将它们合并(如何?)
根据上述作者所述,管道似乎是一种无效的转储方式。
有人对此有更多经验吗?我的方法是否有用,还是你有完全不同的解决方案?
哦,我忘了说:我们目前在外部服务器上限制为5TB,运行数据库的内部服务器不应该被数据碎片弄得过大,即使是暂时的。
1个回答

4
一种并行使用目录格式的pg_restore应该可以加速处理。
如果不是这样,我怀疑大部分数据都在一个大表中,pg_restore(和pg_dump)无法并行化。
确保禁用压缩(-z 0)以提高速度(除非您的网络较弱)。
在线文件系统备份可能会更快:
- pg_basebackup简单易用,但不能并行化。 - 使用低级API,您可以使用操作系统或存储技术并行备份。
缺点是使用文件系统备份只能复制整个数据库集群。

谢谢回复!是的,我们有一个大表,因此无法进行并行处理。(请参见案例#1)我希望压缩可以提高还原性能,但可惜并没有。我正在考虑使用简单的rsync来获取至少初始参考备份,以便我们可以在其他节点上运行测试,然后稍后迁移到另一个pg_dump解决方案。我会查看您建议的两种方法。 - AtroCty
1
发现了多线程恢复时的问题所在:dbname没有明确指定,toc.dat似乎使用了错误的dbname,并尝试将所有内容还原到输出文件而不是数据库中。手动设置dbname解决了还原问题,现在运行得非常顺畅。尽管如此,仍有很大的改进空间,非常感谢! - AtroCty
1
我有一个类似的情况,需要在AWS基础设施上移动一个更大的5TB数据库。因此,转储将被放置在S3上,恢复将在另一个帐户RDS上完成。你用了多长时间来进行1TB的恢复,并且你为恢复生成了多少个线程? - Akash Yellappa
请注意,在AWS上,您可以将RDS快照共享给其他账户并启动它们。 - dotcomly
@AtroCty 那一定是pg_restore的一个旧版本。现在,它要求指定 -f-d - Laurenz Albe

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