3bd*_*lla 7 postgresql storage
我们有一个系统可以将一些数据归档到 PostgreSQL 数据库。我们发现由于数据库归档,PC 存储空间已满。问题是我检查了驻留在其中的数据文件/var/lib/pgsql/data/base/
,它们总共大约 70 GB,而当我使用pg_dump
输出文件转储所有数据库时,它们没有超过 24 GB。我在这里遗漏了什么或误解了什么?这么大的尺寸差异去哪儿了?
编辑:我确实pg_dump
包含模式和数据,并带有-c
允许删除和创建的选项。
编辑 2:我调查了 DB 模式文件,发现包含 24 GB(约 3.324 亿行)数据中的近 23.9 GB 的表上有一个索引。另一个表上有另一个索引,但该表为空。
编辑 3:程序定期存储大约 1500 个变量的值,我的意思是所有变量的记录时间为 0.1 秒到 1 分钟或更长时间,所以我认为这里有一个巨大的数据库访问。
编辑 4:我在这里执行第二个查询以查找模式中每个关系的大小,我发现以下内容:
我的目的是我想经常(每隔几个月)进行一次备份和恢复。在进行备份和恢复时,我应该关心这些数据库索引还是只关注我的数据表?
hru*_*ske 12
由于以下几个原因,尺寸可能会有所不同:
索引占用磁盘空间以促进更快的查找。您拥有的索引越多,您的数据库占用的磁盘空间就越多。GIN 索引通常较小,但在使用范围查询时没有用。
PostgreSQL 支持并发访问,它的实现方式是,对记录的更新和删除只会改变记录的可见性,而不会实际删除或覆盖数据,因为一个记录可能会被另一个事务使用。通过更新,然后添加一个新的(更新的)副本。两者都意味着旧数据仍写入磁盘。为了释放它,PostgreSQL 会定期执行清理,这会真正删除已删除的记录(在没有事务使用它们之后)。
PostgreSQL 的默认块大小为 8KB。如果你的记录很大,比如 5KB,你只能在一个块中得到一条记录,有相当大的 (~3KB) slack。
一些可能的解决方案是:
编辑:
pg_dump
pg_dump 没问题,如果您指定转储数据,正如您所说的那样。如果您使用自定义格式(-Fc 标志),pg_restore 将能够用它做一些额外的事情,例如只加载指定的表,另见 pg_dump 的手册页。默认情况下自定义格式 gzip 转储。这可能会减慢您的转储速度,因此您可能希望禁用它,如果您仍希望对数据进行 gzip,则可以使用并行 gzip (pigz)。
备份
备份时,您备份表中的数据。从表中的数据重新创建索引。如果您在进行备份和恢复时能够承受数据库的大量 IO,那么 pg_dump 和 pg_restore 可能适合您的需求。转储时,pg_dump 仅转储表,而在恢复时,索引会作为恢复的一部分自动重建。所以要说清楚:备份不关心索引。
如果大量 IO 和性能下降是不可接受的,那么您可能希望拥有一个辅助复制服务器,它将拥有数据副本,但不会为您的普通查询提供服务,因此您可以使用它进行转储。
如果您需要时间点恢复功能,您可以设置 WAL 日志(预写日志)归档,然后您可以恢复到特定事务,但这是非常先进的。有一些工具可以提供帮助,例如Barman。
大索引
正如您已经发现的那样,索引会占用大量空间。如果您将数据和索引相加,您的数据库大小为:28GB + 42GB = 70GB。
拥有大索引意味着使用了大量额外的磁盘空间。索引数据也缓存在内存中,因此拥有大索引意味着您可能在 RAM 中有两个索引数据副本,这意味着用于在磁盘上缓存数据的 RAM 更少,并且您会遇到更多缓存未命中。有一些选项可以评估以缩小索引:
但是……这在很大程度上取决于数据的访问方式,这通常只有应用程序的开发人员知道。
pg_dump 仅包含重新创建数据库所需的 SQL 语句。
实际的数据文件包含您插入的数据和所有其他数据库对象,特别是索引:聚集索引(数据本身)和非聚集索引:按指定键排序的选定列。
pd_dump 包含 CREATE INDEX 语句,数据文件包含索引本身(它可能非常大)。