PostgreSQL 最佳实践 - pg_rman 数据库恢复示例 与 软件限制解说

简介: 背景 pg_rman备份已经讲完了,接下来讲一下数据恢复。 由于pg_rman使用了物理备份,所以恢复时,与普通物理备份的恢复原理是一样的。 需要将数据文件恢复,同时需要提供recovery.conf,在recovery.conf中指定需要恢复到哪个位置,以及如何获取XLOG归档文件等配置。

背景

pg_rman备份已经讲完了,接下来讲一下数据恢复。

由于pg_rman使用了物理备份,所以恢复时,与普通物理备份的恢复原理是一样的。

需要将数据文件恢复,同时需要提供recovery.conf,在recovery.conf中指定需要恢复到哪个位置,以及如何获取XLOG归档文件等配置。

数据库恢复

pg_rman数据恢复时的两个必要要素
1. 新的$PGDATA
2. 备份目录

命令的选项也很简单,甚至可以不指定任何option

Restore options:  
The parameters which are started with –recovery are same as parameters in recovery.conf. See also “Recovery Configuration” for details.  

接下来的几个配置,与recovery.conf的意思对齐。

如果不指定时间线,则使用$PGDATA/global/pg_control,如果没有$PGDATA/global/pg_control,则使用最新的全量备份集的时间线。

--recovery-target-timeline TIMELINE  
Specifies recovering into a particular timeline. If not specified, the current timeline from ($PGDATA/global/pg_control) is used.  

如果不指定,则恢复到最新时间

--recovery-target-time TIMESTAMP  
This parameter specifies the time stamp up to which recovery will proceed. If not specified, continue recovery to the latest time.  

如果不指定,则恢复到最新xid

--recovery-target-xid XID  
This parameter specifies the transaction ID up to which recovery will proceed. If not specified, continue recovery to the latest xid.  

如果不指定,则默认使用true,即恢复到包含恢复目标XID的commit record为止,或者第一笔commit record ts>指定ts的 commit redo record为止;
如果是false则不apply恢复目标XID的commit record,或者不apply第一笔commit record ts>=指定ts的 commit redo record。

--recovery-target-inclusive  
Specifies whether we stop just after the specified recovery target (true), or just before the recovery target (false). Default is true.  

是否使用硬链接复制archive log,而不需要拷贝文件

The following parameter determines the behavior of restore.  
--hard-copy  
The archive WAL are copied to archive WAL storage area. If not specified, pg_rman makes symbolic link to archive WAL where are in the backup catalog directory.  

例子

恢复时,需要注意,你可以选择原地恢复(覆盖式),或者使用新的$PGDATA作为恢复目标。

但是请注意,不管是哪种恢复方式,如果在本机恢复的话,pg_rman可能会覆盖原有的数据文件,arch, pg_xlog目录中的文件,所以,如果你要保留原数据,建议先将原数据目录重命名。

1. 原地恢复

2. 使用新的$PGDATA恢复

在本机恢复的例子
1. 停库

pg_ctl stop -m fast -D /data04/digoal/pg_root_1922  

2. 重命名原数据相关目录

  $PGDATA  
mv /data04/digoal/pg_root_1922 /data04/digoal/old_pg_root_1922  

  PG_XLOG  
mv /data05/digoal/pg_xlog_1922 /data05/digoal/old_pg_xlog_1922  

  表空间  
mv /data02/digoal/tbs1_1922 /data02/digoal/old_tbs1_1922  

  归档目录,除了要重命名,还需要新建一个原目录  
mv /data04/digoal/arc_log1922 /data04/digoal/old_arc_log1922  
mkdir /data04/digoal/arc_log1922  

...  

3. pg_rman restore

pg_rman restore -B /data05/digoal/pgstdbak -D /data04/digoal/pg_restore_root   

WARNING: could not open pg_controldata file "/data04/digoal/pg_restore_root/global/pg_control": No such file or directory  
WARNING: could not open pg_controldata file "/data04/digoal/pg_restore_root/global/pg_control": No such file or directory  
INFO: the recovery target timeline ID is not given  
INFO: use timeline ID of latest full backup as recovery target: 1  
INFO: calculating timeline branches to be used to recovery target point  
INFO: searching latest full backup which can be used as restore start point  
INFO: found the full backup can be used as base in recovery: "2016-08-29 15:05:32"  
INFO: copying online WAL files and server log files  
INFO: clearing restore destination  
INFO: validate: "2016-08-29 15:05:32" backup, archive log files and server log files by SIZE  
INFO: backup "2016-08-29 15:05:32" is valid  
INFO: restoring database files from the full mode backup "2016-08-29 15:05:32"  
INFO: searching incremental backup to be restored  
INFO: validate: "2016-08-29 15:13:10" backup, archive log files and server log files by SIZE  
INFO: backup "2016-08-29 15:13:10" is valid  
INFO: restoring database files from the incremental mode backup "2016-08-29 15:13:10"  
INFO: searching backup which contained archived WAL files to be restored  
INFO: backup "2016-08-29 15:13:10" is valid  
INFO: restoring WAL files from backup "2016-08-29 15:13:10"  
INFO: restoring online WAL files and server log files  
INFO: generating recovery.conf  
INFO: restore complete  
HINT: Recovery will start automatically when the PostgreSQL server is started.  

4. 修改postgresql.conf, recovery.conf
根据实际情况调整,本例不修改

cd /data04/digoal/pg_restore_root/  

digoal@iZ28tqoemgtZ-> ll  
total 124K  
-rw------- 1 digoal digoal  193 Aug 29 17:05 backup_label.old  
drwx------ 7 digoal digoal 4.0K Aug 29 17:05 base  
drwx------ 2 digoal digoal 4.0K Aug 29 17:05 global  
drwx------ 2 digoal digoal 4.0K Aug 29 17:05 pg_clog  
drwx------ 2 digoal digoal 4.0K Aug 29 17:05 pg_commit_ts  
drwx------ 2 digoal digoal 4.0K Aug 29 17:05 pg_dynshmem  
-rw------- 1 digoal digoal 4.4K Aug 29 17:05 pg_hba.conf  
-rw------- 1 digoal digoal 1.6K Aug 29 17:05 pg_ident.conf  
drwx------ 2 digoal digoal 4.0K Aug 29 17:05 pg_log  
drwx------ 4 digoal digoal 4.0K Aug 29 17:05 pg_logical  
drwx------ 4 digoal digoal 4.0K Aug 29 17:05 pg_multixact  
drwx------ 2 digoal digoal 4.0K Aug 29 17:05 pg_notify  
drwx------ 2 digoal digoal 4.0K Aug 29 17:05 pg_replslot  
drwx------ 2 digoal digoal 4.0K Aug 29 17:05 pg_serial  
drwx------ 2 digoal digoal 4.0K Aug 29 17:05 pg_snapshots  
drwx------ 2 digoal digoal 4.0K Aug 29 17:05 pg_stat  
drwx------ 2 digoal digoal 4.0K Aug 29 17:05 pg_stat_tmp  
drwx------ 2 digoal digoal 4.0K Aug 29 17:05 pg_subtrans  
drwx------ 2 digoal digoal 4.0K Aug 29 17:05 pg_tblspc  
drwx------ 2 digoal digoal 4.0K Aug 29 17:05 pg_twophase  
-rw------- 1 digoal digoal    4 Aug 29 17:05 PG_VERSION  
lrwxrwxrwx 1 digoal digoal   27 Aug 29 17:05 pg_xlog -> /data05/digoal/pg_xlog_1922  
-rw------- 1 digoal digoal   88 Aug 29 17:05 postgresql.auto.conf  
-rw------- 1 digoal digoal  22K Aug 29 17:05 postgresql.conf  
-rw------- 1 digoal digoal   44 Aug 29 17:05 postmaster.opts  
-rw-r--r-- 1 digoal digoal  130 Aug 29 17:06 recovery.conf  

digoal@iZ28tqoemgtZ-> cd pg_tblspc/  
digoal@iZ28tqoemgtZ-> ll  
total 0  
lrwxrwxrwx 1 digoal digoal 24 Aug 29 17:05 16719 -> /data02/digoal/tbs1_1922  

cd ..  
vi postgresql.conf  
archive_command = 'cp %p /data04/digoal/arc_log1922/%f'  

vi recovery.conf  
# recovery.conf generated by pg_rman 1.3.2  
restore_command = 'cp /data04/digoal/arc_log1922/%f %p'  
recovery_target_timeline = '1'  

5. 如果备份集的时间线发生了变化,需要先手工拷贝到归档目录,再执行restore

digoal@iZ28tqoemgtZ-> pg_rman restore -B /data05/digoal/pgstdbak -D /data04/digoal/pg_restore_root   

WARNING: could not open pg_controldata file "/data04/digoal/pg_restore_root/global/pg_control": No such file or directory  
WARNING: could not open pg_controldata file "/data04/digoal/pg_restore_root/global/pg_control": No such file or directory  
INFO: the recovery target timeline ID is not given  
INFO: use timeline ID of latest full backup as recovery target: 2  
INFO: calculating timeline branches to be used to recovery target point  
ERROR: could not open destination file "/data04/digoal/arc_log1922/00000002.history": No such file or directory  

digoal@iZ28tqoemgtZ-> mkdir /data04/digoal/arc_log1922  

digoal@iZ28tqoemgtZ-> cp /data05/digoal/pgstdbak/timeline_history/00000002.history /data04/digoal/arc_log1922/  

digoal@iZ28tqoemgtZ-> pg_rman restore -B /data05/digoal/pgstdbak -D /data04/digoal/pg_restore_root   

WARNING: could not open pg_controldata file "/data04/digoal/pg_restore_root/global/pg_control": No such file or directory  
WARNING: could not open pg_controldata file "/data04/digoal/pg_restore_root/global/pg_control": No such file or directory  
INFO: the recovery target timeline ID is not given  
INFO: use timeline ID of latest full backup as recovery target: 2  
INFO: calculating timeline branches to be used to recovery target point  
INFO: searching latest full backup which can be used as restore start point  
INFO: found the full backup can be used as base in recovery: "2016-08-29 17:14:20"  
INFO: copying online WAL files and server log files  
INFO: clearing restore destination  
INFO: validate: "2016-08-29 17:14:20" backup and archive log files by SIZE  
INFO: backup "2016-08-29 17:14:20" is valid  
INFO: restoring database files from the full mode backup "2016-08-29 17:14:20"  
INFO: searching incremental backup to be restored  
INFO: searching backup which contained archived WAL files to be restored  
INFO: backup "2016-08-29 17:14:20" is valid  
INFO: restoring WAL files from backup "2016-08-29 17:14:20"  
INFO: restoring online WAL files and server log files  
INFO: generating recovery.conf  
INFO: restore complete  
HINT: Recovery will start automatically when the PostgreSQL server is started.  

digoal@iZ28tqoemgtZ-> cd /data04/digoal/arc_log1922  
digoal@iZ28tqoemgtZ-> ll  
total 16K  
lrwxrwxrwx 1 digoal digoal 71 Aug 29 17:18 00000002000000470000000C -> /data05/digoal/pgstdbak/20160829/171420/arclog/00000002000000470000000C  
lrwxrwxrwx 1 digoal digoal 71 Aug 29 17:18 00000002000000470000000D -> /data05/digoal/pgstdbak/20160829/171420/arclog/00000002000000470000000D  
lrwxrwxrwx 1 digoal digoal 87 Aug 29 17:18 00000002000000470000000D.00000028.backup -> /data05/digoal/pgstdbak/20160829/171420/arclog/00000002000000470000000D.00000028.backup  
-rw------- 1 digoal digoal 42 Aug 29 17:18 00000002.history  

6. 启动恢复目标数据库

digoal@iZ28tqoemgtZ-> pg_ctl start -D /data04/digoal/pg_restore_root  
server starting  
digoal@iZ28tqoemgtZ-> LOG:  00000: redirecting log output to logging collector process  
HINT:  Future log output will appear in directory "pg_log".  
LOCATION:  SysLogger_Start, syslogger.c:622  

digoal@iZ28tqoemgtZ-> psql -h 127.0.0.1 -p 1922  
psql (9.5.3)  
Type "help" for help.  

postgres=# select pg_is_in_recovery();  
 pg_is_in_recovery   
-------------------  
 f  
(1 row)  

postgres=# \l+  
                                                                   List of databases  
        Name        |  Owner   | Encoding | Collate | Ctype |   Access privileges   |  Size   | Tablespace |                Description                   
--------------------+----------+----------+---------+-------+-----------------------+---------+------------+--------------------------------------------  
 contrib_regression | postgres | UTF8     | C       | C     |                       | 7137 kB | pg_default |   
 db1                | postgres | UTF8     | C       | C     |                       | 111 MB  | tbs1       |   
 postgres           | postgres | UTF8     | C       | C     |                       | 797 MB  | pg_default | default administrative connection database  
 template0          | postgres | UTF8     | C       | C     | =c/postgres          +| 7137 kB | pg_default | unmodifiable empty database  
                    |          |          |         |       | postgres=CTc/postgres |         |            |   
 template1          | postgres | UTF8     | C       | C     | =c/postgres          +| 7137 kB | pg_default | default template for new databases  
                    |          |          |         |       | postgres=CTc/postgres |         |            |   
(5 rows)  

注意事项

1. 小心覆盖原有的部分

2. 建议先将原有的目录重命名,或者在其他机器恢复,

3. 软链接的处理,会恢复到目标,并且重新建立软链接,所以目录结构必须与备份时保持一致。

4. 用户可以指定$PGDATA,恢复到新的目标目录,但是arch_log, 表空间, pg_xlog目录无法指定新的位置,所以原地还原时,必须注意这些目录可能被覆盖,先重命名是比较好的手段。

pg_rman 可以优化的地方

1. 检查哪些要恢复的块与目标块的CRC是否一致,如果一致,不需要拷贝,减少WRITE。

pg_rman 软件限制

pg_rman的使用限制

pg_rman has the following restrictions.

1. Requires to read database cluster directory and write backup catalog directory.
For example, you need to mount the disk where backup catalog is placed with NFS from database server.
实际上不是必须的,如果没有指定原来的$PGDATA,则使用备份集的元数据。

2. Block sizes of pg_rman and server should be matched. BLCKSZ and XLOG_BLCKSZ also should be matched.
编译pg_rman时,最好使用启动数据集的集群软件的pg_config。 确保块大小一致。
因为需要做块的校验。 读取LSN等,都与块大小有关。

3. If there are some unreadable files/directories in database cluster directory, WAL directory or archived WAL directory, the backup or restore would be failed.

4. When taking an incremental backup, pg_rman check the timeline ID of the target database whether it is the same with the one of the full backup in backup list.
But, pg_rman does not check whether the data itself is same with the full backup in backup list.
So, you can take an incremental backup over the full backup against the database which has the same timeline ID but has different data.

从standby备份时的软件限制

Getting backup from standby-site, pg_rman has the follow restrictions too.

1. The environment of replication should be built right, or the backup will not finish.

2. You can’t get backups on master and standby at the same time.
因为pg_rman使用的是exclusive bakcup,(pg_start_backup),所以同一时间,只能跑一次pg_start_backup。
pg_basebackup则使用的是shared backup,可以跑多个。

3. You can’t get backups on multi standbys at the same time too.
道理同上

4. Basically, the backup from standby-site is used for restoring on MASTER.
pg_rman doesn’t treat the backup as restoring on standby automatically.

5. If you want to restore the backup on STANDBY, you have to manage archive logs with your self.
因为备库不归档,所以从standby备份时,需要解决归档备份的问题。
我在前面的文档中已经提及,包括解决思路。

如果使用快照备份,有哪些软件限制

When using storage snapshot, pg_rman has the following restrictions too.

1. If your snapshot does not have any file update time, incremental backup is same with full backup.

2. Because pg_rman judges performing full backup or incremental backup by update time for files.
If files don’t have update time because of storage snapshot specification, pg_rman performs full backup every time.

3. You can’t backup for one side works storage with split mirror snapshot.

4. Before you execute pg_rman, you should perform storage “RESYNC”.

5. After pg_rman performs backup with split mirror snapshot, storeage will be “SPLITTED”(works on one side).
pg_rman perform SPLIT command for getting snapshot, but doesn’t perform RESYNC command.
6. You cant’t get snapshot from different vendor storages in a time.

7. You cant’t use some vendor storages which have different commands for getting snapshot.

8. The script and commands for getting storage snapshot should be executable.

9. It’s expected to have authority of root for getting snapshot or mounting volumes.
So a user, performs pg_rman, is granted to execute any commands in the script.

10. If you use LVM(Logical Volume Manager), it’s needed root authority for mount, umount, lvcreate, lvremove, lvscan commands.
You should granted to these commands with sudo command to non-password executable.

Count

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍如何基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
3月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS费用价格:MySQL、SQL Server、PostgreSQL和MariaDB引擎收费标准
阿里云RDS数据库支持MySQL、SQL Server、PostgreSQL、MariaDB,多种引擎优惠上线!MySQL倚天版88元/年,SQL Server 2核4G仅299元/年,PostgreSQL 227元/年起。高可用、可弹性伸缩,安全稳定。详情见官网活动页。
790 152
|
3月前
|
关系型数据库 MySQL 分布式数据库
阿里云PolarDB云原生数据库收费价格:MySQL和PostgreSQL详细介绍
阿里云PolarDB兼容MySQL、PostgreSQL及Oracle语法,支持集中式与分布式架构。标准版2核4G年费1116元起,企业版最高性能达4核16G,支持HTAP与多级高可用,广泛应用于金融、政务、互联网等领域,TCO成本降低50%。
|
3月前
|
关系型数据库 分布式数据库 数据库
阿里云数据库收费价格:MySQL、PostgreSQL、SQL Server和MariaDB引擎费用整理
阿里云数据库提供多种类型,包括关系型与NoSQL,主流如PolarDB、RDS MySQL/PostgreSQL、Redis等。价格低至21元/月起,支持按需付费与优惠套餐,适用于各类应用场景。
|
8月前
|
存储 缓存 数据库
数据库数据删除策略:硬删除vs软删除的最佳实践指南
在项目开发中,“删除”操作常见但方式多样,主要分为硬删除与软删除。硬删除直接从数据库移除数据,操作简单、高效,但不可恢复;适用于临时或敏感数据。软删除通过标记字段保留数据,支持恢复和审计,但增加查询复杂度与数据量;适合需追踪历史或可恢复的场景。两者各有优劣,实际开发中常结合使用以满足不同需求。
745 4
|
6月前
|
SQL 关系型数据库 MySQL
Go语言数据库编程:使用 `database/sql` 与 MySQL/PostgreSQL
Go语言通过`database/sql`标准库提供统一数据库操作接口,支持MySQL、PostgreSQL等多种数据库。本文介绍了驱动安装、连接数据库、基本增删改查操作、预处理语句、事务处理及错误管理等内容,涵盖实际开发中常用的技巧与注意事项,适合快速掌握Go语言数据库编程基础。
497 62
|
3月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎,提供高性价比、稳定安全的云数据库服务,适用于多种行业与业务场景。
|
7月前
|
SQL 数据库 开发者
Python中使用Flask-SQLAlchemy对数据库的增删改查简明示例
这样我们就对Flask-SQLAlchemy进行了一次简明扼要的旅程,阐述了如何定义模型,如何创建表,以及如何进行基本的数据库操作。希望你在阅读后能对Flask-SQLAlchemy有更深入的理解,这将为你在Python世界中从事数据库相关工作提供极大的便利。
690 77
|
4月前
|
存储 关系型数据库 数据库
【赵渝强老师】PostgreSQL数据库的WAL日志与数据写入的过程
PostgreSQL中的WAL(预写日志)是保证数据完整性的关键技术。在数据修改前,系统会先将日志写入WAL,确保宕机时可通过日志恢复数据。它减少了磁盘I/O,提升了性能,并支持手动切换日志文件。WAL文件默认存储在pg_wal目录下,采用16进制命名规则。此外,PostgreSQL提供pg_waldump工具解析日志内容。
402 0
|
6月前
|
存储 关系型数据库 分布式数据库
【赵渝强老师】基于PostgreSQL的分布式数据库:Citus
Citus 是基于 PostgreSQL 的开源分布式数据库,采用 shared nothing 架构,具备良好的扩展性。它以插件形式集成,部署简单,适用于处理大规模数据和高并发场景。本文介绍了 Citus 的基础概念、安装配置步骤及其在单机环境下的集群搭建方法。
531 2
|
6月前
|
SQL 数据库
软考软件评测师——数据库系统应用
本文介绍了关系数据库的基础知识与应用,涵盖候选码定义、自然连接特点、实体间关系(如1:n和m:n)、属性分类(复合、多值与派生属性)以及数据库设计规范。同时详细解析了E-R图转换原则、范式应用(如4NF)及Armstrong公理体系。通过历年真题分析,结合具体场景(如银行信用卡额度、教学管理等),深入探讨了候选键求解、视图操作规范及SQL语句编写技巧。内容旨在帮助读者全面掌握关系数据库理论与实践技能。

相关产品

  • 云原生数据库 PolarDB
  • 云数据库 RDS PostgreSQL 版
  • 推荐镜像

    更多