PG备份恢复(二)

二、物理备份

2.1 冷备

物理冷备就是将数据库停止掉后,通过对PGDATA目录进行物理拷贝进行物理备份。该方式最大的缺点就是为保证数据一致性必须停止数据库。

2.2 热备

1、快照备份

通过对服务器进行快照备份,使用文件系统或者块设备级别的快照功能完成备份,保证数据为备份时刻的一致性。

2、PITR热备份(point-in-time-recover)

RITR的实现主要是基于PG数据库的WAL日志,数据库所有的变更操作都会记录在WAL日志中。在PG数据库中WAL日志可用于做崩溃恢复,当数据库宕机重启后,数据库定位最后一次checkpoint的位点,并通过WAL日志恢复checkpoint之后的所有变更操作,以便于数据库达到一个一致性状态。也正是基于此原理,PITR也是通过WAL日志来保障数据备份的一致性。

PG的物理热备主要分为两部分,第一部分是数据文件的在线拷贝,这部分也被称为基础备份,基础备份无法保证数据的一致性;第二部分是WAL日志的备份。基础备份 + WAL日志备份 才称得上PG数据库的一个完整的备份,才能保障备份数据库的一致性。

1)pg_hba.conf 文件

pg_hba.conf文件为pg的认证配置文件,无论是我们用户登录还是主从复制,都需要在该文件下填写相关的认证配置,保证可正常联通数据库。

pg_hba.conf主要由5个参数组成:Type(主机类型)、Database(数据库名)、User(用户名)、Address(IP地址和掩码)、 Method(加密方法)

  • Type

表示允许的连接方式。

"local"表示使用 Unix-domain socket 进行连接;

“host” 表示可以使用 ssl或者非ssl加密的 TCP/IP socket 进行连接;

“hostssl” 表示必须通过ssl加密的 TCP/IP socket 进行连接;

“hostnossl” 表示通过使用非ssl的 TCP/IP socket 进行连接。

  • Database

表示可以访问数据库信息,可以为 “all”, “sameuser”, “samerole”, “replication”,或者业务数据库名称;

“all"并不包括"replication”,若需要方通replication需要单独编写放通规则;

多个数据库使用逗号分隔

  • User

表示认证配置的数据库用户信息,可以为"all"也可以指定某个数据库用户;

多个用户授权可使用逗号分隔;

可引用外部文件中配置信息信息认证配置,@${filename}

  • Address

表示认证配置的主机IP信息,可以是一个主机名,也可以是IP+掩码;

0.0.0.0/0表示所有主机

  • Method

表示密码加密策略,可以设置为"trust", “reject”, “md5”, “password”, “scram-sha-256”, “gss”, “sspi”, “ident”, “peer”, “pam”, “ldap”, “radius” or “cert”;

password表示以明文方式发送密码;

2)wal日志备份

方式 特点
wal日志归档 总是落后一个wal日志,通过cp、scp等命令实现
流复制 主要有同步和异步两种模式,准实时备份,主从复制搭建基于此方式实现
  • wal日志归档配置
# 相关参数配置,修改后需要重启数据库
# 归档目录需要对postgres进行授权

$ vi postgresql.conf
wal_level = replica             # minimal, replica, or logical
archive_mode = on               # enables archiving; off, on, or always
                                # (change requires restart)
archive_command = 'cp %p /data/pgsql12/archive/%f && echo %f >> /data/pgsql12/archive/archive.list'             # command to use to archive a logfile segment


# 重启数据库
$ psql -D /data/pgsql12/data stop
$ psql -D /data/pgsql12/data start


# 查看归档wal日志
$ pwd
/data/pgsql12/archive
$ ll
total 16388
-rw------- 1 postgres postgres 16777216 Sep  5 16:44 00000001000000000000000D
-rw------- 1 postgres postgres       25 Sep  5 16:44 archive.list

3)pg_basebackup 工具

pg_basebackup工具必须通过 replication协议连接数据库实例,所以在使用 pg_basebackup 工具之前,我们需要先根据实际情况配置 pg_hba.conf 认证信息。

pg_basebackup工具只能对整个数据库实例进行备份,无法单独选择某个数据库、某张表进行备份。该工具可以连接到一个主数据库进行备份,也可以通过连接到一个standby数据库实例进行备份。

  • 基本语法以及重要参数:
pg_basebackup [OPTION]...
参数 含义
-D/–pg-data 备份文件目录,表示将备份文件写入到那个目录下
-F/–format 默认为p、可选择p、t
-r/–max-rate 传输数据的最大速率限制
-R/–write-recovery-conf 输出用于replication的配置信息
-X, --wal-method 指定复制wal日志的方式,有none、fetch、stream,推荐使用stream避免接收wal信息是源端日志被覆盖
-z, --gzip 是否压缩,配合-F t使用
-Z, --compress=0-9 压缩等级,数字越大压缩率越大、越消耗CPU资源
-c, --checkpoint 设置checkpoint的模式:fast、spread
-C, --create-slot 创建复制槽
-S, --slot=SLOTNAME 指定复制槽名称
-l, --label=LABEL 指定一个备份标识,便于运维人员后续的维护
-n, --no-clean do not clean up after errors
-N, --no-sync do not wait for changes to be written safely to disk
-P, --progress 打印备份进度信息
-v, --verbose 输出详细的信息
  • 常用备份命令示例

用于搭建standby数据库的常用命令:

# -h、-p -U 指定源数据库IP、port、数据库用户 信息
# -D 指定目标端数据目录
# -P、-v 表示打印详细的备份信息
# -R 表示写入replication的恢复文件 ??(有点不要确定具体做了什么)
# -X stream 表示备份开始后,启动一个stream链接从主数据库接收wal日志,避免了featch模式下wal日志被覆盖的风险
# -C、-S 指定了在源数据库创建一个什么名称的复制槽
# -l 若不指定会创建一个默认的标签,建议使用该参数做一些时间标识,便于维护

-bash-4.2$ pg_basebackup -h 192.168.0.175 -p 5432 -D /data/pgsql12/data/ -U repl  -P -v -R -X stream -C -S ${pgstandby_slotname}


-bash-4.2$ cat backup_label.old                             //查看标签信息
START WAL LOCATION: 0/2000028 (file 000000010000000000000002)
CHECKPOINT LOCATION: 0/2000060
BACKUP METHOD: streamed
BACKUP FROM: master
START TIME: 2020-09-05 13:06:31 CST
LABEL: pg_basebackup base backup
START TIMELINE: 1
-bash-4.2$

用于基本的备份恢复常用命令

4)按时间恢复示例

1.先通过pg_basebackup做一次基础备份

$ pg_basebackup -D /data/pg_backup/  -v -P -Urepl -h 127.0.0.1 -p5432 -R
pg_basebackup: initiating base backup, waiting for checkpoint to complete
pg_basebackup: checkpoint completed
pg_basebackup: write-ahead log start point: 0/F000028 on timeline 1
pg_basebackup: starting background WAL receiver
pg_basebackup: created temporary replication slot "pg_basebackup_15981"
32566/32566 kB (100%), 1/1 tablespace
pg_basebackup: write-ahead log end point: 0/F000138
pg_basebackup: waiting for background process to finish streaming ...
pg_basebackup: syncing data to disk ...
pg_basebackup: base backup completed

2.写入部分数据

db1=# create table t3(id int);
CREATE TABLE
db1=# insert into t3 values (generate_series(1,1000));
INSERT 0 1000

db1=# select now();
              now
-------------------------------
 2020-09-05 17:34:21.595701+08
(1 row)

db1=# select pg_current_wal_lsn(),
                  pg_walfile_name(pg_current_wal_lsn()),
                  pg_walfile_name_offset(pg_current_wal_lsn());
 pg_current_wal_lsn |     pg_walfile_name      |      pg_walfile_name_offset
--------------------+--------------------------+-----------------------------------
 0/100201A8         | 000000010000000000000010 | (000000010000000000000010,131496)
(1 row)

db1=# select pg_current_wal_lsn();
 pg_current_wal_lsn
--------------------
 0/100201A8
(1 row)




db1=# create table t4(id int);
CREATE TABLE
db1=# insert into t4 values (generate_series(1,1000));
INSERT 0 1000

3.模拟数据库故障,通过基本备份以及wal归档日志进行恢复

$ pg_ctl -D /data/pgsql12/data/ stop
waiting for server to shut down.... done
server stopped
$ ll /data/pgsql12/archive
total 65544
-rw------- 1 postgres postgres 16777216 Sep  5 16:44 00000001000000000000000D
-rw------- 1 postgres postgres 16777216 Sep  5 17:26 00000001000000000000000E
-rw------- 1 postgres postgres 16777216 Sep  5 17:26 00000001000000000000000F
-rw------- 1 postgres postgres      337 Sep  5 17:26 00000001000000000000000F.00000028.backup
-rw------- 1 postgres postgres 16777216 Sep  5 17:40 000000010000000000000010
-rw------- 1 postgres postgres      141 Sep  5 17:40 archive.list

4.将基础备份拷贝只PGDATA目录下

$ mv data data_bak
$ mv pg_backup data         //该步骤要关注目录的权限,默认备份的目录权限不正确,可使用cp -r来做

5.修改 postgresql.auto.conf 文件的相关recover参数

# 基于时间点进行恢复
restore_command = 'cp /data/pgsql12/archive/%f %p > /data/pgsql12/archive/recovery.log 2>&1 '
recovery_target_time = '2020-09-05 17:34:21'

# 基于lsn进行恢复
restore_command = 'cp /data/pgsql12/archive/%f %p > /data/pgsql12/archive/recovery.log 2>&1 '
recovery_target_lsn='0/100201A8'

6.启动数据库进行恢复

$ pg_ctl  -D /data/pgsql12/data start -l /data/pgsql12/logs/logfile
waiting for server to start.... done
server started


# 基于时间点恢复的日志
2020-09-05 18:04:14.891 CST [16354] LOG:  starting PostgreSQL 12.2 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39), 64-bit
2020-09-05 18:04:14.891 CST [16354] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2020-09-05 18:04:14.891 CST [16354] LOG:  listening on IPv6 address "::", port 5432
2020-09-05 18:04:14.895 CST [16354] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2020-09-05 18:04:14.912 CST [16355] LOG:  database system was interrupted; last known up at 2020-09-05 17:26:43 CST
2020-09-05 18:04:14.928 CST [16355] LOG:  entering standby mode
2020-09-05 18:04:15.290 CST [16355] LOG:  restored log file "00000001000000000000000F" from archive
2020-09-05 18:04:15.310 CST [16355] LOG:  redo starts at 0/F000028
2020-09-05 18:04:15.312 CST [16355] LOG:  consistent recovery state reached at 0/F000138
2020-09-05 18:04:15.419 CST [16354] LOG:  database system is ready to accept read only connections
2020-09-05 18:04:15.861 CST [16355] LOG:  restored log file "000000010000000000000010" from archive
2020-09-05 18:04:15.875 CST [16355] LOG:  recovery stopping before commit of transaction 496, time 2020-09-05 17:37:55.830747+08
2020-09-05 18:04:15.875 CST [16355] LOG:  recovery has paused
2020-09-05 18:04:15.875 CST [16355] HINT:  Execute pg_wal_replay_resume() to continue.


# 基于lsn恢复的日志

2020-09-05 18:09:51.809 CST [16442] LOG:  starting PostgreSQL 12.2 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39), 64-bit
2020-09-05 18:09:51.809 CST [16442] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2020-09-05 18:09:51.809 CST [16442] LOG:  listening on IPv6 address "::", port 5432
2020-09-05 18:09:51.814 CST [16442] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2020-09-05 18:09:51.919 CST [16443] LOG:  database system was interrupted; last known up at 2020-09-05 17:26:43 CST
2020-09-05 18:09:51.989 CST [16443] LOG:  entering standby mode
2020-09-05 18:09:52.086 CST [16443] LOG:  restored log file "00000001000000000000000F" from archive
2020-09-05 18:09:52.119 CST [16443] LOG:  redo starts at 0/F000028
2020-09-05 18:09:52.121 CST [16443] LOG:  consistent recovery state reached at 0/F000138
2020-09-05 18:09:52.121 CST [16442] LOG:  database system is ready to accept read only connections
2020-09-05 18:09:52.164 CST [16443] LOG:  restored log file "000000010000000000000010" from archive
2020-09-05 18:09:52.179 CST [16443] LOG:  recovery stopping after WAL location (LSN) "0/100201A8"
2020-09-05 18:09:52.179 CST [16443] LOG:  recovery has paused
2020-09-05 18:09:52.179 CST [16443] HINT:  Execute pg_wal_replay_resume() to continue.


7.数据验证

postgres=# \c db1
You are now connected to database "db1" as user "postgres".
db1=# \d
        List of relations
 Schema | Name | Type  |  Owner
--------+------+-------+----------
 public | t1   | table | postgres
 public | t2   | table | postgres
 public | t3   | table | postgres
(3 rows)

db1=# select count(*) from t3;
 count
-------
  1000
(1 row)

db1=# select count(*) from t4;
ERROR:  relation "t4" does not exist
LINE 1: select count(*) from t4;

问题:

1、如果我们基于lsn进行恢复,如何寻找需要恢复到的Lsn位点信息?

2、当主从架构加直接恢复master时会出现以下报错,我们应该如何处理这种情况?


2020-09-05 18:05:48.345 CST [16387] ERROR:  replication slot "pgstandby1" does not exist
2020-09-05 18:05:53.351 CST [16388] ERROR:  replication slot "pgstandby1" does not exist

猜你喜欢

转载自blog.csdn.net/weixin_37692493/article/details/108500420