PostgreSQL 10 基于日志的备份与还原

本文详细介绍了PostgreSQL10中基于wal日志的备份与还原过程,包括配置日志备份、创建基础备份及日志文件的管理。通过实例演示如何利用日志进行数据库恢复,确保数据安全性。

PostgreSQL 10 基于日志的备份与还原

wal,即预写式日志,是日志的标准实现方式,简单而言就是将对数据库的变动先记录到日志中,而后在将具体的新数据刷新到磁盘。PostgreSQL将该日志维护在数据文件夹下的子文件夹pg_wal中。当数据库崩溃后,可以通过“重放(replay)”日志中的“动作”,将数据库恢复。也就是说,只要拥有一个基础备份和完整的日志文件,理论上可以将数据库库恢复到任意基础备份以来的任意时刻点。不仅如此,如果在另一个实例上将这些日志不停的“重放”,那么就拥有了一个完整的在线备份,也就是“复制”。

pg_wal下日志文件不会无限制增多,也就是说并不用担心日志的增多使得磁盘空间捉襟见肘。默认每个日志文件为16M大小,即当增长到16M时,就会切换到别的文件,并复用之前的文件 。因此,为了保证有个完整的日志链,必须将写满的文件复制保存到一个特定的文件 夹。对于最后一个还未满16M的日志文件,可以手动触发一次切换。

备份 (操作均使用postgres用户完成)

1. 登录数据库创建测试数据库

[postgres@localhost ~]$ psql 
psql (10.10)
Type "help" for help.

postgres=# create database test;
CREATE DATABASE
postgres=# 

2. 修改配置文件, 开启日志备份, 将写满的文件复制到archivedir目录下

注: PG9.x 中 wal_level 归档的的取值为archive, PG10.x 中修改为了 replica . replica代表了"流复制"或"归档".

wal_level = replica            # minimal, replica, or logical

archive_mode = on

archive_command = 'test ! -f /home/postgres/archivedir/%f && cp %p /home/postgres/archivedir/%f'       # command to use to archive a logfile segment
220                 # placeholders: %p = path of file to archive
221                 #               %f = file name only
222                 # e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'

3. 创建archivedir目录, 并重启数据库服务

[postgres@localhost ~]$ mkdir archivedir
[postgres@localhost ~]$ pg_ctl -D db1 restart
waiting for server to shut down....2020-02-17 20:18:53.755 CST [50766] LOG:  received fast shutdown request
2020-02-17 20:18:53.756 CST [50766] LOG:  aborting any active transactions
2020-02-17 20:18:53.757 CST [50766] LOG:  worker process: logical replication launcher (PID 50773) exited with exit code 1
2020-02-17 20:18:53.757 CST [50768] LOG:  shutting down
2020-02-17 20:18:53.769 CST [50766] LOG:  database system is shut down
 done
server stopped
waiting for server to start....2020-02-17 20:18:53.867 CST [50861] LOG:  listening on IPv6 address "::1", port 5432
2020-02-17 20:18:53.867 CST [50861] LOG:  listening on IPv4 address "127.0.0.1", port 5432
2020-02-17 20:18:53.871 CST [50861] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2020-02-17 20:18:53.888 CST [50862] LOG:  database system was shut down at 2020-02-17 20:18:53 CST
2020-02-17 20:18:53.891 CST [50861] LOG:  database system is ready to accept connections
 done
server started
[postgres@localhost ~]$ 

4. 创建测试表

[postgres@localhost ~]$ psql
psql (10.10)
Type "help" for help.

postgres=# \c test
You are now connected to database "test" as user "postgres".
test=# CREATE TABLE testPITR1 AS SELECT * FROM pg_class, pg_description;
SELECT 1338084
test=# 
[postgres@localhost ~]$ ll -h archivedir/
total 336M
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000001
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000002
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000003
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000004
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000005
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000006
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000007
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000008
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000009
-rw------- 1 postgres postgres 16M Feb 17 20:19 00000001000000000000000A
-rw------- 1 postgres postgres 16M Feb 17 20:19 00000001000000000000000B
-rw------- 1 postgres postgres 16M Feb 17 20:19 00000001000000000000000C
-rw------- 1 postgres postgres 16M Feb 17 20:19 00000001000000000000000D
-rw------- 1 postgres postgres 16M Feb 17 20:19 00000001000000000000000E
-rw------- 1 postgres postgres 16M Feb 17 20:19 00000001000000000000000F
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000010
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000011
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000012
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000013
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000014
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000015
[postgres@localhost ~]$ 

5. 创建基础备份

[postgres@localhost ~]$ psql -c "SELECT pg_start_backup('base', true)"
 pg_start_backup 
-----------------
 0/17000028
(1 row)


[postgres@localhost ~]$ tar -cvf db1.tar db1
......
[postgres@localhost ~]$ psql -c "SELECT pg_stop_backup()"
NOTICE:  pg_stop_backup complete, all required WAL segments have been archived
 pg_stop_backup 
----------------
 0/17000168
(1 row)
[postgres@localhost ~]$ 
[postgres@localhost ~]$ ll -h archivedir/
total 369M
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000001
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000002
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000003
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000004
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000005
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000006
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000007
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000008
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000009
-rw------- 1 postgres postgres 16M Feb 17 20:19 00000001000000000000000A
-rw------- 1 postgres postgres 16M Feb 17 20:19 00000001000000000000000B
-rw------- 1 postgres postgres 16M Feb 17 20:19 00000001000000000000000C
-rw------- 1 postgres postgres 16M Feb 17 20:19 00000001000000000000000D
-rw------- 1 postgres postgres 16M Feb 17 20:19 00000001000000000000000E
-rw------- 1 postgres postgres 16M Feb 17 20:19 00000001000000000000000F
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000010
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000011
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000012
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000013
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000014
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000015
-rw------- 1 postgres postgres 16M Feb 17 20:20 000000010000000000000016
-rw------- 1 postgres postgres 16M Feb 17 20:21 000000010000000000000017
-rw------- 1 postgres postgres 291 Feb 17 20:21 000000010000000000000017.00000028.backup
[postgres@localhost ~]$

6. 继续创建测试表, 切换日志

注: pg9.x 中 为 select pg_switch_xlog(); pg10.x中为 select pg_switch_wal();

[postgres@localhost ~]$ psql
psql (10.10)
Type "help" for help.

postgres=# \c test
You are now connected to database "test" as user "postgres".
test=# CREATE TABLE testPITR2 AS SELECT * FROM pg_class, pg_description;
SELECT 1349856
test=# select * from current_timestamp;
       current_timestamp       
-------------------------------
 2020-02-17 20:22:46.40963+08
(1 row)

test=# CREATE TABLE testPITR3 AS SELECT * FROM pg_class, pg_description;
SELECT 1361628
test=# select * from current_timestamp;
       current_timestamp       
-------------------------------
 2020-02-17 20:23:08.669018+08
(1 row)

test=# select pg_switch_wal();
 pg_switch_wal 
---------------
 0/431112D0
(1 row)

test=# 

7. 恢复

关闭数据库,模拟数据库宕机,此时,数据库test中应该有3张表,其中1张表在基础备份前,也就是恢复完数据文件即可找回,而另2张表则需恢复相应的日志文件。模拟恢复到testPITR2创建时刻点。

test=# \d
           List of relations
 Schema |   Name    | Type  |  Owner   
--------+-----------+-------+----------
 public | testpitr1 | table | postgres
 public | testpitr2 | table | postgres
 public | testpitr3 | table | postgres
(3 rows)

test=# 

看看archivedir的情况:

[postgres@localhost ~]$ ll -h archivedir/
total 1.1G
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000001
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000002
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000003
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000004
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000005
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000006
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000007
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000008
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000009
-rw------- 1 postgres postgres 16M Feb 17 20:19 00000001000000000000000A
-rw------- 1 postgres postgres 16M Feb 17 20:19 00000001000000000000000B
-rw------- 1 postgres postgres 16M Feb 17 20:19 00000001000000000000000C
-rw------- 1 postgres postgres 16M Feb 17 20:19 00000001000000000000000D
-rw------- 1 postgres postgres 16M Feb 17 20:19 00000001000000000000000E
-rw------- 1 postgres postgres 16M Feb 17 20:19 00000001000000000000000F
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000010
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000011
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000012
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000013
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000014
-rw------- 1 postgres postgres 16M Feb 17 20:19 000000010000000000000015
-rw------- 1 postgres postgres 16M Feb 17 20:20 000000010000000000000016
-rw------- 1 postgres postgres 16M Feb 17 20:21 000000010000000000000017
-rw------- 1 postgres postgres 291 Feb 17 20:21 000000010000000000000017.00000028.backup
-rw------- 1 postgres postgres 16M Feb 17 20:22 000000010000000000000018
-rw------- 1 postgres postgres 16M Feb 17 20:22 000000010000000000000019
-rw------- 1 postgres postgres 16M Feb 17 20:22 00000001000000000000001A
-rw------- 1 postgres postgres 16M Feb 17 20:22 00000001000000000000001B
-rw------- 1 postgres postgres 16M Feb 17 20:22 00000001000000000000001C
-rw------- 1 postgres postgres 16M Feb 17 20:22 00000001000000000000001D
-rw------- 1 postgres postgres 16M Feb 17 20:22 00000001000000000000001E
-rw------- 1 postgres postgres 16M Feb 17 20:22 00000001000000000000001F
-rw------- 1 postgres postgres 16M Feb 17 20:22 000000010000000000000020
-rw------- 1 postgres postgres 16M Feb 17 20:22 000000010000000000000021
-rw------- 1 postgres postgres 16M Feb 17 20:22 000000010000000000000022
-rw------- 1 postgres postgres 16M Feb 17 20:22 000000010000000000000023
-rw------- 1 postgres postgres 16M Feb 17 20:22 000000010000000000000024
-rw------- 1 postgres postgres 16M Feb 17 20:22 000000010000000000000025
-rw------- 1 postgres postgres 16M Feb 17 20:22 000000010000000000000026
-rw------- 1 postgres postgres 16M Feb 17 20:22 000000010000000000000027
-rw------- 1 postgres postgres 16M Feb 17 20:22 000000010000000000000028
-rw------- 1 postgres postgres 16M Feb 17 20:22 000000010000000000000029
-rw------- 1 postgres postgres 16M Feb 17 20:22 00000001000000000000002A
-rw------- 1 postgres postgres 16M Feb 17 20:22 00000001000000000000002B
-rw------- 1 postgres postgres 16M Feb 17 20:22 00000001000000000000002C
-rw------- 1 postgres postgres 16M Feb 17 20:22 00000001000000000000002D
-rw------- 1 postgres postgres 16M Feb 17 20:22 00000001000000000000002E
-rw------- 1 postgres postgres 16M Feb 17 20:23 00000001000000000000002F
-rw------- 1 postgres postgres 16M Feb 17 20:23 000000010000000000000030
-rw------- 1 postgres postgres 16M Feb 17 20:23 000000010000000000000031
-rw------- 1 postgres postgres 16M Feb 17 20:23 000000010000000000000032
-rw------- 1 postgres postgres 16M Feb 17 20:23 000000010000000000000033
-rw------- 1 postgres postgres 16M Feb 17 20:23 000000010000000000000034
-rw------- 1 postgres postgres 16M Feb 17 20:23 000000010000000000000035
-rw------- 1 postgres postgres 16M Feb 17 20:23 000000010000000000000036
-rw------- 1 postgres postgres 16M Feb 17 20:23 000000010000000000000037
-rw------- 1 postgres postgres 16M Feb 17 20:23 000000010000000000000038
-rw------- 1 postgres postgres 16M Feb 17 20:23 000000010000000000000039
-rw------- 1 postgres postgres 16M Feb 17 20:23 00000001000000000000003A
-rw------- 1 postgres postgres 16M Feb 17 20:23 00000001000000000000003B
-rw------- 1 postgres postgres 16M Feb 17 20:23 00000001000000000000003C
-rw------- 1 postgres postgres 16M Feb 17 20:23 00000001000000000000003D
-rw------- 1 postgres postgres 16M Feb 17 20:23 00000001000000000000003E
-rw------- 1 postgres postgres 16M Feb 17 20:23 00000001000000000000003F
-rw------- 1 postgres postgres 16M Feb 17 20:23 000000010000000000000040
-rw------- 1 postgres postgres 16M Feb 17 20:23 000000010000000000000041
-rw------- 1 postgres postgres 16M Feb 17 20:23 000000010000000000000042
-rw------- 1 postgres postgres 16M Feb 17 20:23 000000010000000000000043
[postgres@localhost ~]$ 

7.1 关闭数据库服务, 重命名数据目录

[postgres@localhost ~]$ pg_ctl -D db1 stop
waiting for server to shut down....2020-02-17 20:25:17.173 CST [50861] LOG:  received fast shutdown request
2020-02-17 20:25:17.177 CST [50861] LOG:  aborting any active transactions
2020-02-17 20:25:17.178 CST [51099] FATAL:  terminating autovacuum process due to administrator command
2020-02-17 20:25:17.179 CST [50861] LOG:  worker process: logical replication launcher (PID 50869) exited with exit code 1
2020-02-17 20:25:17.180 CST [50863] LOG:  shutting down
2020-02-17 20:25:17.494 CST [50861] LOG:  database system is shut down
 done
server stopped
[postgres@localhost ~]$ 
[postgres@localhost ~]$ mv db1 db1.old

7.2 解压备份数据文件, 启动服务, 验证此时只有基础备份前的testpitr1

[postgres@localhost ~]$ tar -xvf db1.tar
......
[postgres@localhost ~]$ pg_ctl -D db1 start
pg_ctl: another server might be running; trying to start server anyway
waiting for server to start....2020-02-17 20:26:28.315 CST [51138] LOG:  listening on IPv6 address "::1", port 5432
2020-02-17 20:26:28.315 CST [51138] LOG:  listening on IPv4 address "127.0.0.1",
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值