为什么并行 pg_restore 命令可能需要更长的时间才能完成其非并行等效命令?

mik*_*lus 3 postgresql parallelism pg-restore postgresql-10

我使用 pg_restore 从目录备份恢复 50 GB 数据库,使用以下命令,该命令使用了 4 个作业:

pg_restore -d analytics -U postgres  -j 4 -v "D:\Program Files\PostgreSQL\10\backups\Analytics_08_2018__7_53_21.36.compressed"
Run Code Online (Sandbox Code Playgroud)

我从命令行运行了这个。恢复时间比非并行恢复长约 2 小时。它似乎在恢复作业结束时继续创建索引

pg_restore: launching item 2817 INDEX nidx_bigrams_inc_hits
pg_restore: creating INDEX "public.nidx_bigrams_inc_hits"
pg_restore: finished item 2965 TABLE DATA trigrams
pg_restore: launching item 2822 INDEX nidx_trigrams_inc_hits
pg_restore: creating INDEX "public.nidx_trigrams_inc_hits"
pg_restore: finished item 2823 INDEX nidx_unigrams_inc_hits
pg_restore: finished item 2822 INDEX nidx_trigrams_inc_hits
pg_restore: finished item 2817 INDEX nidx_bigrams_inc_hits
pg_restore: finished main parallel loop
Run Code Online (Sandbox Code Playgroud)

每个 pg_restore“创建索引”作业在 pg_stat_activity 中的状态均为“空闲”。另一个 pg_restore 作业在提交时“空闲”。

我希望并行恢复能够比默认恢复快得多,而且它似乎一直在这样做,直到大约 15 分钟后挂起。该服务器上没有发生太多其他事情。当我在作业完成之前检查索引时,索引似乎是完整的,即它们与原始数据库索引的大小相同。与非并行恢复相比,并行恢复作业需要更长的时间才能完成/提交,是否有任何特殊原因?我想在灾难恢复情况下为此做好准备,如果我不能依赖工作持续时间,则排除并行。

顺便说一句,我知道基于文件系统的备份而不是逻辑备份,但我暂时只对逻辑感兴趣。

Phi*_* W. 5

这可能只是数据库争用。

通过并行转储,您的 postgres 可以一次写入许多不同的文件,因此可以分散负载。

进行并行恢复时,postgres 必须管理来自 jobs+1 连接的所有[重量级]流量,所有流量都填充缓冲区缓存中的数据页并将它们写入磁盘,全部一次。要创建索引,您需要读回数据页并扫描它们;同时对大量表执行此操作会给缓冲区高速缓存带来很大压力... postgres 需要做 更多工作。

另外,您已经指定了四个作业 - 您的数据库 [服务器] 是否有足够的 CPU/内核来支持它?如果没有,那么额外的作业仍然会启动,但会在操作系统级别遭受争用,因为当[可怜的]机器试图“同时”运行它们时,它们会在内存不足的情况下切换。在较小的服务器上,您可能会从运行两个作业中获得[一些]好处,但不仅如此,而且好处很快就会被成本所抵消。

  • 只是为了补充菲尔的答案,在任何给定时刻只有一名工作人员会处理关系。这意味着,如果您有一张巨大的桌子和几张小桌子,您可能只会看到很少的速度提升。如果你有很多张大小相似的桌子,那就更有趣了。 (2认同)