postgres 备份/恢复:恢复的数据库小得多?

owe*_*mck 5 postgresql

我担心我恢复的数据库与原始数据库有很大不同:

#check size of postgres database
postgres@db1:/tmp$ psql -c "select pg_size_pretty(pg_database_size('test_db'));"
 pg_size_pretty
----------------
 2105 MB
(1 row)

#backup database
postgres@db1:/tmp$ pg_dump -Fc test_db > test_db_Fc.dump

#rename postgres database (i.e. park it nearby)
postgres@db1:/tmp$ psql -c "alter database test_db rename to test_db_20130322;"
ALTER DATABASE
-------
(1 row)

#restore test_db
postgres@db1:/tmp$ pg_restore -Fc -C -d postgres test_db_Fc.dump

#check size of restored postgres database
postgres@db1:/tmp$ psql -c "select pg_size_pretty(pg_database_size('test_db'));"
 pg_size_pretty
----------------
 257 MB
(1 row)
Run Code Online (Sandbox Code Playgroud)

原始数据库比恢复的数据库大很多倍。这里发生了什么?据我所知,test_db 服务的网站在恢复后仍然运行良好,但在实时上下文中使用备份之前,我需要知道发生了什么。

仅供参考,如果我在每个数据库上运行vacuumdb,数据库大小似乎没有变化。

[附录,稍后添加] 在 RTFM 的传统中,我已经在 PostgreSQL 的手册中进行了搜索。这里还有一些拼图

#is the autovacuum switched on?
postgres@db1:/tmp$ psql -c "SHOW autovacuum;"
 autovacuum
------------
 on
(1 row)

#The "track counts" parameter is needed by autovacuum which uses statistics from database activity to know where to do its job
postgres@db1:/tmp$ psql -c "SHOW track_counts;"
 track_counts
--------------
 on
(1 row)

#is there an autovacuum daemon resident in memory?
postgres@db1:/tmp$ ps  -ef | grep 'autovacuum'
postgres  1261  1021  0 Jan23 ?        00:08:27 postgres: autovacuum launcher process                             
postgres 18347 18149  0 00:33 pts/0    00:00:00 grep autovacuum


#what's been happening on the live server?
postgres@LIVEdb1:/tmp$ psql -c "SELECT relname, last_vacuum, last_autovacuum, last_analyze, last_autoanalyze from pg_stat_all_tables;"
#result is list of 65 tables (out about 300), all empty (no dates at all)
Run Code Online (Sandbox Code Playgroud)

非常感谢@craig-ringer 的建议,VACUUM FULL我转向了PostgreSQL 文档,(释义)“......在你的磁盘几乎已满的最坏情况下,VACUUM FULL 可能是唯一可行的选择。......(但是) 常规清理的通常目标是避免需要 VACUUM FULL。autovacuum 守护进程尝试执行标准 VACUUM 的频率足以维持磁盘空间的稳定使用......”

我将遵循@chris-travers 的建议,并从每个版本的数据库中绘制出表中的行数。我认为就我而言,可以公平地说 VACUUM FULL 将减轻磁盘空间的压力,并且会使 original_vs_restored 看起来更好,但仍然存在过度膨胀的危险信号。我认为 autovacuum 没有做任何事情,这很令人担忧!到目前为止,感谢您的指导,这很有趣。

Dan*_*ité 5

也许这只是索引膨胀。VACUUM FULL相反,如 8.4 的文档中所述,对索引膨胀没有帮助:

不建议将 FULL 选项用于日常使用,但在特殊情况下可能有用。例如,当您删除或更新表中的大部分行并希望表物理缩小以占用更少的磁盘空间并允许更快的表扫描时。VACUUM FULL 通常会比普通的 VACUUM 缩小表格更多。FULL 选项不会收缩索引;仍然建议定期进行 REINDEX。事实上,删除所有索引、VACUUM FULL 并重新创建索引通常更快。

(在最近的版本中,此建议已消失,因为 VACUUM FULL 已以不同方式重新实现)。

请参阅例行驯服REINDEX命令。

重新索引的最简单方法是使用拥有它的 db 用户连接到数据库并发出:

REINDEX database test_db;
Run Code Online (Sandbox Code Playgroud)

理想情况下,它应该在此之后立即完成,VACUUM FULL并且此时数据库应该缩小到其可能的最低大小。


Chr*_*ers 2

您使用什么版本的 PostgreSQL?如果是 9.0 (iirc) 之前的版本,则您的可用空间映射设置可能不充分,从而导致真空无法有效恢复的空间泄漏。在这种情况下,您所看到的那种膨胀将影响生产数据库。

与此同时,这确实引发了危险信号。问题是这些危险信号意味着什么。这是一个配置错误的服务器吗?备份是否损坏?要进行测试,您应该做的是绘制生产服务器和备份上表中的行数。如果它们很接近(请记住生产服务器可能有新的更新和删除)那么您可能相当不错。如果存在较大偏差,您可能需要更仔细地研究这些偏差。假设那里什么也没有出现,我会怀疑自由空间贴图设置有问题。