参考文档:
http://postgres.cn/docs/14/app-pgbasebackup.html
http://postgres.cn/docs/12/runtime-config-wal.html
postgres版本
test=# select version();
version
-------------------------------------------------------------------------------------------------------
PostgreSQL 15.2 on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0, 64-bit
(1 row)
test=#
--使用pg_basebackup进行备份
pg_basebackup -D /postgres/pg15/backups/ -Ft -Pv -U postgres -h 192.168.2.101 -p5432 -R
参数说明:
-D 设置目标目录以将输出写入。如果该目录不存在,pg_basebackup将创建该目录(以及所有丢失的父目录)。如果已经存在,则必须为空。
-Ft F ,foramt ,t 以tar的方式
-Pv P ,启用进度报告,v verbose
-R --write-recovery-conf 。创建一个standby.signal 文件,并将连接设置附加到目标目录(或使用tar格式的基本存档文件中)的postgresql.auto.conf文件中。 这样可以简化使用备份结果设置备用服务器的过程。数据目录中存在 standby.signal 文件,服务器进入standby模式。
-- 修改pg_hba.conf中replication connection的连接,否则备份报错 -- 修改pg_hba后,开始备份 ,加入一行
postgres@pg15:/postgres/pg15/backups$ pg_basebackup -D /postgres/pg15/backups/ -Ft -Pv -U postgres -h 192.168.2.101 -p5432 -R
pg_basebackup: error: connection to server at "192.168.2.101", port 5432 failed: FATAL: no pg_hba.conf entry for replication connection from host "192.168.2.101", user "postgres", no encryption
postgres@pg15:/postgres/pg15/backups$
vi pg_hba.conf
host replication all 192.168.2.0/24 trust
-- 重新加载conf文件后,再次备份,可以发现备份到的wal位置是 0/51000100 ,后面恢复也恢复到这个位置
postgres@pg15:/postgres/pg15/backups$ pg_ctl reload
server signaled
postgres@pg15:/postgres/pg15/backups$ pg_basebackup -D /postgres/pg15/backups/ -Ft -Pv -U postgres -h 192.168.2.101 -p5432 -R
pg_basebackup: initiating base backup, waiting for checkpoint to complete
pg_basebackup: checkpoint completed
pg_basebackup: write-ahead log start point: 0/51000028 on timeline 1
pg_basebackup: starting background WAL receiver
pg_basebackup: created temporary replication slot "pg_basebackup_190335"
80913/80913 kB (100%), 2/2 tablespaces
pg_basebackup: write-ahead log end point: 0/51000100
pg_basebackup: waiting for background process to finish streaming ...
pg_basebackup: syncing data to disk ...
pg_basebackup: renaming backup_manifest.tmp to backup_manifest
pg_basebackup: base backup completed
postgres@pg15:/postgres/pg15/backups$
-- 从备份的结果看,16389.tar是新建立的表空间, base.tar和pg_wal.tar分别是pgdata目录下的base目录和归档目录的内容。在pg_wal.tar中,可以看到备份了51号归档
postgres@pg15:/postgres/pg15/backups$ ls -l
total 97592
-rw------- 1 postgres postgres 44314112 May 4 10:33 16389.tar
-rw------- 1 postgres postgres 289562 May 4 10:33 backup_manifest
-rw------- 1 postgres postgres 38541824 May 4 10:33 base.tar
-rw------- 1 postgres postgres 16778752 May 4 10:33 pg_wal.tar
postgres@pg15:/postgres/pg15/backups$ pwd
/postgres/pg15/backups
postgres@pg15:/postgres/pg15/backups$ postgres@pg15:/postgres/pg15/backups$ tar -tvf pg_wal.tar
-rw------- postgres/postgres 16777216 2023-05-04 10:33 000000010000000000000051
postgres@pg15:/postgres/pg15/backups$ postgres@pg15:/postgres/pg15/data/pg_wal$ ls -l *.backup
-rw------- 1 postgres postgres 341 May 4 10:33 000000010000000000000051.00000028.backup
postgres@pg15:/postgres/pg15/data/pg_wal$ postgres@pg15:/postgres/pg15/data/pg_wal/archive_status$ ls -l
total 0
-rw------- 1 postgres postgres 0 May 4 10:33 000000010000000000000051.00000028.backup.done
postgres@pg15:/postgres/pg15/data/pg_wal/archive_status$
-- 删除掉数据,进行恢复。删除掉data目录,
postgres@pg15:/postgres/pg15$ rm -rf data
postgres@pg15:/postgres/pg15$
-- 恢复
postgres@pg15:/postgres/pg15/backups$ ls
16389.tar backup_manifest base.tar pg_wal.tar
postgres@pg15:/postgres/pg15/backups$ cp 16389.tar ../data/pg_tablespaces/
postgres@pg15:/postgres/pg15/backups$ cp pg_wal.tar ../data/pg_wal/
postgres@pg15:/postgres/pg15/backups$
复制base.tar到data目录,解压开
postgres@pg15:/postgres/pg15/backups$ cp base.tar ../data/
postgres@pg15:/postgres/pg15/backups$ tar xvf base.tar
复制16389.tar到data/pg_tablespaces目录,解压开
postgres@pg15:/postgres/pg15/data/pg_tablespaces$ ls
16389.tar PG_15_202209061
postgres@pg15:/postgres/pg15/data/pg_tablespaces$
复制pg_wal.tar到pg-wal目录 ,解压开
postgres@pg15:/postgres/pg15/backups$ cp pg_wal.tar ../data/pg_wal/
postgres@pg15:/postgres/pg15/backups$
编辑postgres.auto.conf文件,因为在备份的时候,加上了参数-R,备份的时候,自动生成了连接信息。这里 没有打算设置成备库,所以修改掉
(postgresql.auto.conf文件将记录连接设置(如果有)以及pg_basebackup所使用的复制槽,这样流复制后面就会使用相同的设置。)
postgres@pg15:/postgres/pg15/data$ more postgresql.auto.conf20230504
# Do not edit this file manually!
# It will be overwritten by the ALTER SYSTEM command.
lc_monetary = 'zh_CN.UTF-8'
primary_conninfo = 'user=postgres passfile=''/home/postgres/.pgpass'' channel_binding=disable host=192.168.2.101 port=5432 sslmode=disable sslcompression=0 sslsni=1 ssl
_min_protocol_version=TLSv1.2 gssencmode=disable krbsrvname=postgres target_session_attrs=any'
postgres@pg15:/postgres/pg15/data$
vi postgresql.auto.conf restore_command = 'cp /postgres/pg15/backups/%f %p'
recovery_target = 'immediate'
修改后的postgresql.auto.conf内容 ,restore_command用于获取 WAL 文件系列的一个已归档段的本地 shell 命令
recovery_target ,这个参数指定恢复应该在达到一个一致状态后尽快结束,即尽早结束。在从一个在线备份中恢复时,这意味着备份结束的那个点,也就是0/51000100
postgres@pg15:/postgres/pg15/data$ cat postgresql.auto.conf
# Do not edit this file manually!
# It will be overwritten by the ALTER SYSTEM command.
restore_command = 'cp /postgres/pg15/archive_wals/%f %p'
recovery_target = 'immediate'
postgres@pg15:/postgres/pg15/data$
默认情况下,恢复将会一直恢复到 WAL 日志的末尾。下面的参数可以被用来指定一个更早的停止点。 在recovery_target、recovery_target_lsn、recovery_target_name、recovery_target_time和recovery_target_xid中, 最多只能使用一个,如果在配置文件中使用了多个,将会产生一个错误。这个参数只能在服务器启动时设置。
要启动服务器为目标恢复模式,需在数据目录中建立名为recovery.signal的文件。 如果同时创建了standby.signal 和 recovery.signal 文件,则优先使用备用模式。 目标恢复模式在归档的WAL全部回放或到达recovery_target时结束。
cd $PGDATA
touch recovery.signal
-- 启动 pg_ctl start,会提示data目录需要设置成700或750
postgres@pg15:/postgres/pg15/data$ pg_ctl start
waiting for server to start....2023-05-04 11:28:02.267 CST [191427] FATAL: data directory "/postgres/pg15/data" has invalid permissions
2023-05-04 11:28:02.267 CST [191427] DETAIL: Permissions should be u=rwx (0700) or u=rwx,g=rx (0750).stopped waiting
pg_ctl: could not start server
Examine the log output.
postgres@pg15:/postgres/pg15/data$postgres@pg15:/postgres/pg15$ chmod 700 data
postgres@pg15:/postgres/pg15$ pg_ctl start
waiting for server to start....2023-05-04 11:28:44.870 CST [191435] LOG: redirecting log output to logging collector process
2023-05-04 11:28:44.870 CST [191435] HINT: Future log output will appear in directory "log".done
server started
postgres@pg15:/postgres/pg15$
--查看数据库的启动日志(也就是恢复过程),并且要求执行pg_wal_replay_resume()提升到读写模式,否则是只读模式。另外可以看到恢复到了0/51000100这个位置。另外,在备份的归档目录中,也可以看到0/51000100 。恢复完成后,recovery.signal文件消失,为了防止下次数据库启动后进行恢复。
2023-05-04 14:38:43.097 CST [192652] LOG: starting PostgreSQL 15.2 on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0, 64-bit
2023-05-04 14:38:43.097 CST [192652] LOG: listening on IPv4 address "0.0.0.0", port 5432
2023-05-04 14:38:43.098 CST [192652] LOG: listening on IPv6 address "::", port 5432
2023-05-04 14:38:43.099 CST [192652] LOG: listening on Unix socket "/tmp/.s.PGSQL.5432"
2023-05-04 14:38:43.101 CST [192656] LOG: database system was interrupted; last known up at 2023-05-04 10:33:20 CST
2023-05-04 14:38:43.114 CST [192656] LOG: restored log file "00000002.history" from archive
cp: cannot stat '/postgres/pg15/archive_wals/00000003.history': No such file or directory
2023-05-04 14:38:43.115 CST [192656] LOG: starting point-in-time recovery to earliest consistent point
2023-05-04 14:38:43.116 CST [192656] LOG: restored log file "00000002.history" from archive
2023-05-04 14:38:43.144 CST [192656] LOG: restored log file "000000020000000000000051" from archive
2023-05-04 14:38:43.170 CST [192656] LOG: redo starts at 0/51000028
2023-05-04 14:38:43.170 CST [192656] LOG: consistent recovery state reached at 0/51000100
2023-05-04 14:38:43.170 CST [192656] LOG: recovery stopping after reaching consistency
2023-05-04 14:38:43.170 CST [192656] LOG: pausing at the end of recovery
2023-05-04 14:38:43.170 CST [192656] HINT: Execute pg_wal_replay_resume() to promote.
2023-05-04 14:38:43.170 CST [192652] LOG: database system is ready to accept read-only connections
postgres@pg15:/postgres/pg15/archive_wals$ more 00000002.history
1 0/51000100 reached consistency
postgres@pg15:/postgres/pg15/archive_wals$ postgres@pg15:/postgres/pg15/archive_wals$ more 00000003.history
1 0/51000100 reached consistency2 0/51000100 reached consistency
postgres@pg15:/postgres/pg15/archive_wals$ more 00000002.history
1 0/51000100 reached consistency
postgres@pg15:/postgres/pg15/archive_wals$
--连接到数据库 ,数据库为只读模式 ,执行pg_wal_replay_resume()
select pg_wal_replay_resume();test=# select pg_wal_replay_resume();pg_wal_replay_resume
----------------------(1 row)
--通过pg_controldata查看时间线,2和3 (因为为了测试,恢复了2次。11点多和14点多 )
postgres@pg15:/postgres/pg15/data/pg_wal$ pg_controldata | grep TimeLineID
Latest checkpoint's TimeLineID: 2
Latest checkpoint's PrevTimeLineID: 1
postgres@pg15:/postgres/pg15/data/pg_wal$ postgres@pg15:/postgres/pg15/archive_wals$ pg_controldata | grep TimeLineID
Latest checkpoint's TimeLineID: 3
Latest checkpoint's PrevTimeLineID: 1
postgres@pg15:/postgres/pg15/archive_wals$
END