通俗的来说,归档就是WAL日志的备份,开启归档的目的时能够实现基于时间点的恢复(PITR),因为WAL日志会被覆盖,为了保证WAL日志的持久保存,因此需要将WAL日志存放到持久可靠的存储上。
1.归档相关参数
postgres=# select name,setting from pg_settings where name like '%archive%';
name | setting
---------------------------+------------
archive_cleanup_command |
archive_command | (disabled)
archive_mode | off
archive_timeout | 0
max_standby_archive_delay | 30000
wal_level :需要将参数配置位replica或更高。
archive_mode:确定是否开启归档,on为开启,off为关闭。
archive_command:配置一个shell命令,%p表示归档文件路径,%f会被wal文件名替代。linux下参考配置如下:
archive_command = 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'
在操作系统中真正执行的是:
test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/00000001000000A900000065 /mnt/server/archivedir/00000001000000A900000065
archive_timeout:在事务量很少的系统上,pg可能很久不会归档,可以使用archive_timeout来强制周期性的切换到一个新的WAL segment, 当这个参数被设置为大于零时,只要从上次段文件切换后过了参数所设置的时间量,并且已经有过任何数据库活动(包括一个单一检查点),服务器将切换到一个新的段文件(如果没有数据库活动则会跳过检查点)。 注意,由于强制切换而提早关闭的被归档文件仍然与完整的归档文件长度相同。因此,使用非常短的archive_timeout
是不明智的 — 它将占用巨大的归档存储。一分钟左右的archive_timeout
设置通常比较合理。如果你希望数据能被更快地从主服务器上复制下来,你应该考虑使用流复制而不是归档。如果指定值时没有单位,则以秒为单位。这个参数只能在postgresql.conf
文件中或在服务器命令行上设置。
2.归档管理——pg_archivecleanup
pg_archivecleanup是管理归档的工具,默认会安装在PGHOME/bin目录下。他会清理所有的归档日志,使用方法如下:
[root@test bin]# pg_archivecleanup --help
pg_archivecleanup removes older WAL files from PostgreSQL archives.
Usage:
pg_archivecleanup [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE
Options:
-d generate debug output (verbose mode)
-n dry run, show the names of the files that would be removed
-V, --version output version information, then exit
-x EXT clean up files if they have this extension
-?, --help show this help, then exit
For use as archive_cleanup_command in postgresql.conf:
archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %r'
e.g.
archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %r'
Or for use as a standalone archive cleaner:
e.g.
pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup
Report bugs to <pgsql-bugs@lists.postgresql.org>.
PostgreSQL home page: <https://www.postgresql.org/>
一般会被archive_cleanup_command调用。这个可选参数指定了一个 shell 命令,它将在每一个重启点被执行。 archive_cleanup_command
的目的是提供一种清除不再被后备服务器需要的旧的已归档 WAL 文件的机制。 任何%r
会被替换为包含最后一个可用重启点的文件的名称。 那是使一次恢复变成可重启的所必须被保留的最早的文件,并且因此比%r
更早的所有文件可以被安全地移除。 这个信息可以被用来把归档截断为支持从当前恢复重启所需的最小值。一般在备库配置,清理不需要的归档。
archive_cleanup_command = 'pg_archivecleanup /mnt/server/archivedir %r'
3.实验
#开归档
[root@test pgdata]# mkdir pg_arch
postgres=# alter system set archive_mode=on;
ALTER SYSTEM
postgres=# alter system set archive_command='cp %p /data/pgdata/pg_arch/%f';
ALTER SYSTEM
[pg14@test ~]$ pg_ctl stop -D $PGDATA -l /tmp/logfile
waiting for server to shut down.... done
server stopped
[pg14@test ~]$ pg_ctl start -D $PGDATA -l /tmp/logfile
waiting for server to start.... done
server started
#切换WAL
postgres=# select pg_walfile_name(pg_current_wal_lsn());
pg_walfile_name
--------------------------
00000001000000000000000C
(1 row)
postgres=# select pg_switch_wal();
pg_switch_wal
---------------
0/C000710
(1 row)
postgres=# select pg_switch_wal();
pg_switch_wal
---------------
0/D000000
(1 row)
postgres=# select pg_walfile_name(pg_current_wal_lsn());
pg_walfile_name
--------------------------
00000001000000000000000C
(1 row)
postgres=# select pg_walfile_name(pg_current_wal_lsn());
pg_walfile_name
--------------------------
00000001000000000000000D
#查看归档路径
[root@test pg_arch]# ll
total 0
并没有生成
#查看日志
[root@test ~]# tail -f /tmp/logfile
cp: cannot create regular file ‘/data/pgdata/pg_arch/00000001000000000000000C’: Permission denied
2024-03-16 18:57:48.113 CST [18363] LOG: archive command failed with exit code 1
2024-03-16 18:57:48.113 CST [18363] DETAIL: The failed archive command was: cp pg_wal/00000001000000000000000C /data/pgdata/pg_arch/00000001000000000000000C
cp: cannot create regular file ‘/data/pgdata/pg_arch/00000001000000000000000C’: Permission denied
2024-03-16 18:57:49.118 CST [18363] LOG: archive command failed with exit code 1
2024-03-16 18:57:49.118 CST [18363] DETAIL: The failed archive command was: cp pg_wal/00000001000000000000000C /data/pgdata/pg_arch/00000001000000000000000C
cp: cannot create regular file ‘/data/pgdata/pg_arch/00000001000000000000000C’: Permission denied
2024-03-16 18:57:50.125 CST [18363] LOG: archive command failed with exit code 1
2024-03-16 18:57:50.125 CST [18363] DETAIL: The failed archive command was: cp pg_wal/00000001000000000000000C /data/pgdata/pg_arch/00000001000000000000000C
权限不对
修改权限
chown pg14:pg14 -R pg_arch/
#查看归档路径
[root@test pg_arch]# ll
total 81920
-rw------- 1 pg14 pg14 16777216 Mar 16 19:01 00000001000000000000000C
-rw------- 1 pg14 pg14 16777216 Mar 16 19:01 00000001000000000000000D
-rw------- 1 pg14 pg14 16777216 Mar 16 19:01 00000001000000000000000E
-rw------- 1 pg14 pg14 16777216 Mar 16 19:01 00000001000000000000000F
-rw------- 1 pg14 pg14 16777216 Mar 16 19:01 000000010000000000000010
#手动清理归档,查看当前WAL
postgres=# select pg_walfile_name(pg_current_wal_lsn());
pg_walfile_name
--------------------------
000000010000000000000013
#清理
[pg14@test pg_arch]$ pg_archivecleanup /data/pgdata/pg_arch/ 000000010000000000000012 -d
pg_archivecleanup: keeping WAL file "/data/pgdata/pg_arch//000000010000000000000012" and later
pg_archivecleanup: removing file "/data/pgdata/pg_arch//00000001000000000000000C"
pg_archivecleanup: removing file "/data/pgdata/pg_arch//00000001000000000000000D"
pg_archivecleanup: removing file "/data/pgdata/pg_arch//00000001000000000000000E"
pg_archivecleanup: removing file "/data/pgdata/pg_arch//00000001000000000000000F"
pg_archivecleanup: removing file "/data/pgdata/pg_arch//000000010000000000000010"
pg_archivecleanup: removing file "/data/pgdata/pg_arch//000000010000000000000011"
[pg14@test pg_arch]$ ll
total 16384
-rwxrwxr-x 1 pg14 pg14 16777216 Mar 16 19:06 000000010000000000000012
12之前的都被清理掉了
#备库设置自动归档清理
postgres=# alter system set archive_cleanup_command='pg_archivecleanup /data/pgdata/pg_arch/ %r';
ALTER SYSTEM
postgres=# exit
[pg14@test ~]$ pg_ctl stop -D $PGDATA -l /tmp/logfile
waiting for server to shut down.... done
server stopped
[pg14@test ~]$ pg_ctl start -D $PGDATA -l /tmp/logfile