PostgreSQL中的 .ready 和 .done 文件有什么作用?
翻译自:https://www.dbi-services.com/blog/__trashed-3/
2021年2月7日 丹尼尔·韦斯特曼(Daniel Westermann)
当您在生产环境中运行 PostgreSQL 工作负载时,必须有一个备份(backup)和还原(restore)实施方案。即使对于开发实例,对于开发人员而言,也应该有一个经过充分测试的备份和还原步骤,因为开发实例(Development Instances)对于开发人员来说就像生产一样。社区版 PostgreSQL 附带了 pg_basebackup,以帮助您创建一个完全一致的 PostgreSQL 集群备份。如果您希望能够进行时间点恢复(PITR),则需要归档 WAL 段,以便稍后可以从基础备份中进行回滚。WAL 段存储在 pg_wal 目录中,但如果您仔细查看此目录,您会看到更多内容(如果您启用了归档)。
如果查看一个新初始化的 PostgreSQL 集群,pg_wal 的内容如下所示:
postgres@debian11:/home/postgres/[pgdev] ls -la $PGDATA/pg_wal
total 16396
drwx------3 postgres postgres 4096Jul411:47.
drwx------20 postgres postgres 4096Jul411:47..
-rw-------1 postgres postgres 16777216Jul411:52000000010000000000000001
drwx------2 postgres postgres 4096Jul411:47 archive_status
在这里有一个 WAL 段和一个名为“archive_status”的目录,目前是空的:
postgres@debian11:/home/postgres/[pgdev] ls -la $PGDATA/pg_wal/archive_status/
total 8
drwx------2 postgres postgres 4096Jul411:47.
drwx------3 postgres postgres 4096Jul411:47..
要查看此目录中发生的情况,我们需要启用归档,并告诉 PostgreSQL 在需要归档 WAL 段时要执行什么操作:
postgres@debian11:/home/postgres/[pgdev] mkdir /tmp/archived_wal
postgres@debian11:/home/postgres/[pgdev] psql -c "alter system set archive_mode='on'" postgres
ALTER SYSTEM
postgres@debian11:/home/postgres/[pgdev] psql -c "alter system set archive_command='test ! -f /tmp/archived_wal/%f && cp %p /tmp/archived_wal/%f'" postgres
ALTER SYSTEM
当然,您不应该将归档目录设置为 /tmp,也不应该使用 cp,因为这不能保证归档的段实际上已写入磁盘。在本文的范围内,这样做是可以接受的。<br />更改归档命令(archive_command)可以在线完成,但启用或禁用归档(archive_mode)需要重新启动:
postgres@debian11:/home/postgres/[pgdev] pg_ctl restart
让我们看看如果我们强制归档当前段会发生什么:
postgres@debian11:/home/postgres/[pgdev] psql -c "select pg_switch_wal()" postgres
pg_switch_wal
---------------
0/167AF68
(1 row)
postgres@debian11:/home/postgres/[pgdev] ls -la /tmp/archived_wal/
total 16392
drwxr-xr-x 2 postgres postgres 4096Jul412:08.
drwxrwxrwt 10 root root 4096Jul412:07..
-rw-------1 postgres postgres 16777216Jul412:08000000010000000000000001
正如预期的那样,我们在归档命令中指定的目录中看到了已归档的段。此外,PostgreSQL还在pg_wal的archive_status目录中生成了一个“.done”文件:
postgres@debian11:/home/postgres/[pgdev] ls -la $PGDATA/pg_wal/archive_status/
total 8
drwx------2 postgres postgres 4096Jul412:08.
drwx------3 postgres postgres 4096Jul412:08..
-rw-------1 postgres postgres 0Jul412:08000000010000000000000001.done
因此,每当成功归档一个段时,您都会得到相应的“.done”文件。那么什么时候会看到“.ready”文件呢?答案很简单:当相反的情况发生时,即出现了某种原因导致段的归档失败:
postgres@debian11:/home/postgres/[pgdev] psql -c "alter system set archive_command='/bin/false'" postgres
ALTER SYSTEM
postgres@debian11:/home/postgres/[pgdev] psql -c "select pg_reload_conf()";
pg_reload_conf
----------------
t
(1 row)
postgres@debian11:/home/postgres/[pgdev] psql -c "select pg_switch_wal()" postgres
pg_switch_wal
---------------
0/2000160
(1 row)
postgres@debian11:/home/postgres/[pgdev] ls -la $PGDATA/pg_wal/archive_status/
total 8
drwx------2 postgres postgres 4096Jul412:13.
drwx------3 postgres postgres 4096Jul412:12..
-rw-------1 postgres postgres 0Jul412:13000000010000000000000002.ready
此文件将一直存在,直到再次成功归档:
postgres@debian11:/home/postgres/[pgdev] psql -c "alter system set archive_command='test ! -f /tmp/archived_wal/%f && cp %p /tmp/archived_wal/%f'" postgres
ALTER SYSTEM
postgres@debian11:/home/postgres/[pgdev] psql -c "select pg_reload_conf()";
pg_reload_conf
----------------
t
(1 row)
postgres@debian11:/home/postgres/[pgdev] ls -la $PGDATA/pg_wal/archive_status/
total 8
drwx------2 postgres postgres 4096Jul412:15.
drwx------3 postgres postgres 4096Jul412:12..
-rw-------1 postgres postgres 0Jul412:13000000010000000000000002.done
当您看到许多“.ready”文件时,这可能意味着您的归档命令当前正在失败,或者系统负载过高,无法跟上归档的速度。