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",

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

被折叠的 条评论
为什么被折叠?



