问题描述
我们正在使用 pgbackrest 将我们的数据库备份到 Amazon S3。我们每周做一次完整备份,每隔一天做一次增量备份。 我们的数据库大小在 1TB 左右,完整备份在 600GB 左右,增量备份也在 400GB 左右!
我们发现,即使是对数据库的读取访问(纯选择语句)也会导致底层数据文件(在 /usr/local/pgsql/data/base/xxxxxx 中)发生变化。这会导致大量增量备份以及 Amazon S3 上非常大的存储(成本)。
通常具有低索引名称(例如 391089.1)的文件在读取访问时会发生变化。
在更新时,我们看到一个或多个文件发生变化 - 索引可能与表中行的年龄相关。
更多事实:
- Postgres 13.1 版
- 数据库正在 docker 容器中运行(docker 版本 20.10.0)
- 操作系统是 CentOS 7
我们在多台服务器上看到了这种现象。
有人可以解释一下,为什么 postgresql 在纯读取访问时更改数据文件? 我们在没有任何其他资源访问数据库的情况下在纯数据库上进行了测试。
解决方法
这是正常的。我马上能想到的一些情况是:
-
一个
SELECT
或其他 SQL 语句设置一个提示位这是访问数据的后续语句的快捷方式,因此它们不必再查阅提交日志。
-
一个
SELECT ... FOR UPDATE
写一个行锁 -
autovacuum 删除死行版本
这些是
DELETE
或UPDATE
的剩菜。 -
autovacuum 冻结旧的可见行版本
如果事务 ID 计数器回绕,这对于防止数据损坏是必要的。
相当可靠地防止 PostgreSQL 将来修改表的唯一方法是:
-
切勿对其执行
INSERT
、UPDATE
或DELETE
-
在表上运行
VACUUM (FREEZE)
并确保没有并发事务