我正在尝试加快转储和恢复数据库的过程。目前,我们执行
pg_dump --no-privileges --no-owner -w source_db | psql target_db
(数据库是在此之前创建的)。我读到自定义格式更可取,并且我希望二进制格式比文本表示更快。
hyperfine --prepare './drop_db.sh target_db ; ./create_db.sh target_db' --runs=3 -i --export-markdown report.md \
'pg_dump --no-privileges --format=custom source_db | pg_restore --dbname=target_db' \
'pg_dump --no-privileges --no-owner -w source_db | psql target_db'
命令 | 平均[s] | 分钟[秒] | 最大[秒] | 亲戚 | 资源 |
---|---|---|---|---|---|
|
693.527±5.741 | 688.635 | 699.848 | 1.03±0.03 | 用户:165.459 秒,系统:18.331 秒 |
|
673.223±8.535 | 663.433 | 679.100 | 1.00 | 用户:12.348 秒,系统:25.697 秒 |
→ psql 快了 20 秒
我测试了不同级别的压缩,因为我读到压缩速度很慢。
hyperfine --prepare './drop_db.sh target_db ; ./create_db.sh target_db' --runs=3 -i --export-markdown report.md \
'pg_dump --compress=0 --no-privileges --format=custom source_db | pg_restore --dbname=target_db' \
'pg_dump --compress=1 --no-privileges --format=custom source_db | pg_restore --dbname=target_db' \
'pg_dump --compress=5 --no-privileges --format=custom source_db | pg_restore --dbname=target_db' \
'pg_dump --no-privileges --no-owner -w source_db | psql target_db'
命令 | 平均[s] | 分钟[秒] | 最大[秒] | 亲戚 | 资源 |
---|---|---|---|---|---|
|
702.692±6.316 | 698.376 | 709.942 | 1.05±0.03 | 用户:18.090 秒,系统:28.934 秒 |
|
672.341±15.539 | 655.448 | 686.025 | 1.00 | 用户:89.223秒,系统:21.904秒 |
|
693.527±5.741 | 688.635 | 699.848 | 1.03±0.03 | 用户:165.459 秒,系统:18.331 秒 |
|
673.223±8.535 | 663.433 | 679.100 | 1.00±0.03 | 用户:12.348 秒,系统:25.697 秒 |
→ 最好情况下具有相同的性能
按照@Bergi和@Nick的要求,我分别测量了转储和恢复。
hyperfine --runs=3 -i --export-markdown report.md \
'pg_dump --compress=0 --no-privileges --format=custom source_db > ./1' \
'pg_dump --compress=1 --no-privileges --format=custom source_db > ./2' \
'pg_dump --no-privileges --no-owner -w source_db > ./3'
命令 | 平均[s] | 分钟[秒] | 最大[秒] | 亲戚 |
---|---|---|---|---|
|
77.648±8.720 | 71.724 | 87.660 | 1.09±0.12 |
|
104.646±0.911 | 103.804 | 105.614 | 1.47±0.02 |
|
71.412±1.037 | 70.321 | 72.385 | 1.00 |
→ psql 快 7 秒
hyperfine --prepare './drop_db.sh target_db ; ./create_db.sh target_db' --runs=3 -i --export-markdown report.md \
'cat ./1 | pg_restore --dbname=target_db' \
'cat ./2 | pg_restore --dbname=target_db' \
'cat ./3 | psql target_db'
命令 | 平均[s] | 分钟[秒] | 最大[秒] | 亲戚 |
---|---|---|---|---|
|
658.715±24.712 | 637.183 | 685.697 | 1.11±0.04 |
|
591.001±8.025 | 582.334 | 598.172 | 1.00 |
|
691.756±15.320 | 680.285 | 709.154 | 1.17±0.03 |
→ 恢复比转储慢 10 倍,但与转储分离时更慢。
我可以做些什么来使其更快而不将转储写入磁盘(=使用
--format=directory
这将启用并行化)?
您自己回答了问题:使用
pg_dump -F c -Z 0 ... | pg_restore ...
也就是说,不要压缩转储。如果纯格式转储对您来说稍快一些,请使用它。
由于恢复速度对您来说很慢,因此请调整该作业的目标数据库:
增加
max_wal_size
很多
增加
maintenance_work_mem
很多
设置
wal_level = minimal
并将--single-transaction
与psql
或pg_restore
一起使用,这样PostgreSQL就可以跳过写入WAL