PostgreSQL数据库系列之六:增量备份和恢复
[概述]
备份是恢复的前提。不发生故障时,世界很太平,但发生故障时,如果不能顺利进行恢复,那将是一场噩梦!甚至可能对于企业是致命打击,这绝对不是危言耸听!
日常的备份有效性的检查就显得尤其重要,一个无效的备份集和没有备份是一样的,例如备份文件无法解压,或者存储备份的介质损坏等等。除了制定备份恢复策略,还应该制定一套定期、定时的恢复测试方案。我们在恢复测试中,应该考量恢复需要花费的时间,日常测试时,也应该记录和统计恢复花费的时间,如果恢复时间太长,还应该优化恢复方案,消除恢复瓶颈实现业务SLA要求等级。
PostgreSQL 只能向后恢复, 而不能前恢复。因此PostgreSQL恢复时,必须要搭配基础备份实施。
[增量备份]
- 启用WAL日志功能
PostgreSQL增量备份是基于WAL日志实施的,它的开启与配置方法参考<PostgreSQL数据库系列之五:预写式日志WAL>。
启用功能核心参数
参数 | 说明 |
---|---|
wal_level | WAL日志启用等级,参数值minimal、replica(9.6前分别是archive和hot_standby)、logical |
archive_mode | 归档模式,参数值on 启用,off 关闭 |
archive_command | 归档命令,通过灵活的命令来实现日志归档动作 |
fsync | 磁盘同步,参数值on 启用 |
min_wal_size | 最小保留这个值的WAL日志量 |
max_wal_size | 最大不超过这个值的WAL日志量,这是软限制。 |
max_wal_senders | 同时运行的WAL发送器进程的最大数 |
wal_keep_segments | 指定保留在pg_xlog/pg_wal目录中的过去日志文件段的最小数量,以防备用服务器需要获取它们以进行流复制 |
- 创建基础备份
从PostgreSQL 9.1版本开始有了pg_basebackup实用程序,使得创建基础备份更便捷,pg_basebackup用普通文件或创建tar包的方式进行基础备份,它在内部也是使用pg_start_backup和pg_stop_backup低级命令。
pg_basebackup备份脚本:
@echo off
REM The script sets environment variables helpful for PostgreSQLSET PATH="C:\Program Files\PostgreSQL\11\bin";%PATH%
SET PGDATA=D:\pgdata\11\data
SET PGDATABASE=postgres
SET PGUSER=postgres
SET PGPASSWORD=123456
SET PGPORT=5432
SET LOGDATE=%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%
SET LOGTIME=%time:~0,2%%time:~3,2%
SET BAKPATH=D:\pgdata\11\backup\%LOGDATE%
SET LOGFILE=D:\pgdata\11\backup\backuplog%LOGDATE%.txtif not exist %BAKPATH% (
mkdir %BAKPATH% 2>> %LOGFILE% 1>&2
echo Backup Start Time:%DATE:~0,4%%DATE:~5,2%%DATE:~8,2% %time:~0,2%%time:~3,2%%time:~6,2% >> %LOGFILE%
pg_basebackup.exe -v -R -P --format=t --gzip --compress=4 -D %BAKPATH% 2>> %LOGFILE% 1>&2
echo Backup End Time:%DATE:~0,4%%DATE:~5,2%%DATE:~8,2% %time:~0,2%%time:~3,2%%time:~6,2% >> %LOGFILE%
) else (
move %BAKPATH% %BAKPATH%_%LOGTIME% 2>> %LOGFILE% 1>&2
move %LOGFILE% %BAKPATH%_%LOGTIME%\ 2>> %LOGFILE% 1>&2
mkdir %BAKPATH% 2>> %LOGFILE% 1>&2
echo Backup Start Time:%DATE:~0,4%%DATE:~5,2%%DATE:~8,2% %time:~0,2%%time:~3,2%%time:~6,2% >> %LOGFILE%
pg_basebackup.exe -v -R -P --format=t --gzip --compress=4 -D %BAKPATH% 2>> %LOGFILE% 1>&2
echo Backup End Time:%DATE:~0,4%%DATE:~5,2%%DATE:~8,2% %time:~0,2%%time:~3,2%%time:~6,2% >> %LOGFILE%
)echo Delete Backup Files >> %LOGFILE%
forfiles /p %RCPATH% /m * /d -%RCDATE% /c "cmd /c echo deleting @file ... && del /f @path" >> %LOGFILE%echo Delete Archive WAL Files >> %LOGFILE%
forfiles /p %WALPATH% /m * /d -%RCDATE% /c "cmd /c echo deleting @file ... && del /f @path" >> %LOGFILE%
pg_basebackup核心参数解释:
参数 | 说明 |
---|---|
-v | 输出详细日志信息 |
-P |
表示允许在备份过程中实时的打印备份的进度信息
|
-R | 表示备份文件将会写入一个最小化的recovery.conf文件 |
-F | 表示备份格式,它有两个参数 p(lain) 明文格式复制到其他路径 t(ar) 压缩格式 |
–gzip | 表示压缩的方式 |
–compress | 表示压缩的等级,1是不压缩,9是最佳压缩(速度极慢);我建议设置为3 - 5。 |
-D | 表示备份目的地(此目录必须为空,否则会报错) |
效果展示:
文件说明:
# | 文件名 | 说明 |
---|---|---|
1 | base.tar.gz | Base与Global默认表空间相关备份数据 |
2 | 16396.tar.gz | 用户创建的表空间(每个表空间按照OID独立打包) |
3 | pg_wal.tar.gz | WAL日志备份 |
[恢复]
- 恢复到最近的时间点
—构建测试环境—
:# 创建测试表
create table tbl (
id SERIAL PRIMARY KEY,
ival INT NOT NULL DEFAULT 0,
description TEXT,
create_time TIMESTAMPTZ NOT NULL DEFAULT now()
);
:# 初始化测试数据
INSERT INTO tbl (ival) VALUES (1);
:# 查询表数据状态
SELECT id,ival,description,created_time FROM tbl;
:# 手工切换WAL日志
SELECT pg_switch_wal();
:# 初始化测试数据
INSERT INTO tbl (ival) VALUES (2);
:# 查询表数据状态
SELECT id,ival,description,created_time FROM tbl;
—构建测试环境—
关闭服务
迁移故障数据库的数据目录
※1 有空间的情况之下,我们尽可能不要删除源数据保障自己还有活路,不至于删库跑路!
※2 注意用户自定义表空间也需要进行迁移的。
创建数据目录并解压使用pg_basebackup创建的基础备份
※1 用户自定义表空间必须要自行将其目录结构恢复到指定的目录里。创建recovery.conf文件并进行配置
restore_command = 'copy "D:\\pgdata\\11\\archive_wals\\%f" "%p"'
recovery_target_timeline = 'latest'
重新启动服务
验证恢复数据
日志信息
2019-12-09 01:08:52.706 HKT [2408] 日志: 数据库系统中断;上一次的启动时间是在2019-12-08 23:51:11 HKT
2019-12-09 01:08:53.478 HKT [2408] 日志: 开始归档恢复
2019-12-09 01:08:53.655 HKT [2408] 日志: 从归档中恢复日志文件 "000000010000000000000019"
2019-12-09 01:08:53.725 HKT [2408] 日志: redo 在 0/19000028 开始
2019-12-09 01:08:53.741 HKT [2408] 日志: 在0/19000130上已到达一致性恢复状态
2019-12-09 01:08:53.750 HKT [1036] 日志: 数据库系统准备接受只读请求的连接
2019-12-09 01:08:53.900 HKT [2408] 日志: 从归档中恢复日志文件 "00000001000000000000001A"
2019-12-09 01:08:54.042 HKT [2408] 日志: 从归档中恢复日志文件 "00000001000000000000001B"
2019-12-09 01:08:54.108 HKT [2408] 日志: redo 在 0/1B0001F0 完成
2019-12-09 01:08:54.108 HKT [2408] 日志: 上一次完成事务是在日志时间2019-12-09 00:24:23.682133+08完成的.
2019-12-09 01:08:54.223 HKT [2408] 日志: 从归档中恢复日志文件 "00000001000000000000001B"
2019-12-09 01:08:54.302 HKT [2408] 日志: 已选择的新时间线ID:5
2019-12-09 01:08:54.371 HKT [2408] 日志: 归档恢复完毕
2019-12-09 01:08:54.780 HKT [1036] 日志: 数据库系统准备接受连接
※ 每次恢复都会生成一条新的时间线,如果正常启动数据库并不是你所需要的数据,则你需要正确的判断数据所在的时间线。
- 恢复到指定时间点
recovery.conf配置参考
restore_command = 'copy "D:\\pgdata\\11\\archive_wals\\%f" "%p"'
recovery_target_timeline = 2
recovery_target_time = '2019-12-08 18:25:00.185701+08'
※1 此处是第二条时间线中的WAL日志中查找。
- 恢复到还原点
有时候,我们会希望将数据库恢复到某一个重要事件发生之前的状态,例如MRP动作之前、财务盘点动作之前。这种情况可以在重要事件发生时创建一个还原点,通过基础备份和归档恢复到时间发生之前的状态。
还原点创建方法:
SELECT pg_create_restore_point('restore_point_test');
recovery.conf配置参考
restore_command = 'copy "D:\pgdata\11\archive_wals\%f" "%p"'
recovery_target_name = 'restore_point_test'
- 恢复到指定事务
recovery.conf配置参考
restore_command = 'copy "D:\\pgdata\\11\\archive_wals\\%f" "%p"'
recovery_target_xid = 561
[SQL转储操作]
SQL转储可以将PG数据库中的某些表的数据迁移到其他关系型数据库中。
- SQL转储备份
pg_dump -Fp -a --insert --column-inserts -t tbl -p 5432 mydb > dump.sql
参数说明:
参数 | 说明 |
---|---|
-F c/d/t/p | c=>输出一个自定义的格式;d=>将表和其他对象输出为文件,并保存在一个目录中;t=>输出为tar包;p=>输出为纯文本SQL脚本; |
-a,–data-only | 只dump表中的数据 |
-c,–clean | 在重建前先DROP准备重建的对象 |
-C,–create | 包含创建Database的命令 |
-n,–schema | 指定schema |
-N,–exclude-schema | 排除指定schema |
-s,–schema-only | 只输出schema架构 |
-t,–table | 指定table |
-T,–exclude-table | 排除指定表 |
–insert | 导出INSERT命令 |
–column-inserts | 导出包含列名称 |
pg_dumpall -r -p 5432
- SQL转储恢复
:# 当转储的格式是纯文本形式时,使用psql运行转储出的SQL文本即可。
psql -p 5432 mydb < dump.sql
:# 当转储的格式指定为自定义格式时,需要使用pg_restore命令进行恢复。
pg_dump -Fc -p 5432 mydb > dump.dat
pg_restore -p 5432 -d mydb dump.dat
补充信息:时间线概述
时间线是这样的,无论何时,一个恢复完成后,会创建一个新的时间线来标识此次恢复之后产生的WAL日志。时间线的id号是WAL日志文件名字的一部分,因此不会覆盖其他时间线上的WAL日志文件。
每次创建一个新的时间线时,PostgreSQL会创建一个新的时间线历史文件,后缀为.history。历史文件会标识此时间线是什么时候从那个时间线分支而来的。
有了时间线历史文件,PostgreSQL就可以在含有多个时间线的归档文件中找到正确的WAL归档日志。虽然时间线看起来的确很高能,但是无论如何也不可能恢复到制作基础备份之前的时间。
新时间线创建场景
新的时间线会在什么情况下出现呢?
- 即时恢复(PITR)
设置好recovery.conf文件后,启动数据库,将会产生新的timeline,而且会生成一个新的history文件。
- 备库抢占角色()
搭建一个PG主备,然后停止主库,在备库机器执行:
pg_ctl promote –D $PGDATA
这时候备库将会升为主备,同时产生一个新的timeline,同样生成一个新的history文件。
history文件
每次创建一个新的时间线,PostgreSQL都会创建一个“时间线历史”文件,文件名类似.history,它里面的内容是由原时间线history文件的内容再追加一条当前时间线切换记录。
PostgreSQL数据库系列之六:增量备份和恢复相关推荐
- mysql整备_【mysql】使用xtrabackup在线增量备份及恢复数据库
一.Percona Xtrabackup 简介 1.Xtrabackup bin目录文件 介绍 1)innobackupex innobackupex 是xtrabackup的一个符号链接 . in ...
- 数据库损坏了怎么办?——完全备份及恢复、增量备份及恢复
文章目录 一.数据库备份的分类 1.数据备份的重要性 2.数据库备份的分类-1 3.数据库备份的分类-2 4.常见的备份方法 二.MySQL完全备份与恢复 1.MySQL完全备份-1 2.MySQL完 ...
- mysql增量备份及恢复解决方案
2019独角兽企业重金招聘Python工程师标准>>> 前言 操作系统崩溃.电源故障.文件系统崩溃和硬件故障等异常状况都可能导致我们正在使用的数据库出现故障而产生数据库中数据不一致的 ...
- MySQL8增量备份_mysql增量备份及恢复解决方案
前言 操作系统崩溃.电源故障.文件系统崩溃和硬件故障等异常状况都可能导致我们正在使用的数据库出现故障而产生数据库中数据不一致的情况.为了保证数据库使用安全,必须定期备份数据库:数据库备份可以分为:完全 ...
- Oracle数据库教程(Oracle备份、恢复、升级、迁移)视频教程
Oracle数据库教程(Oracle备份.恢复.升级.迁移)视频教程 风哥Oracle备份恢复与迁移升级专题包括:Oracle备份恢复基础.用户模式的备份恢复.RMAN备份恢复.Flashback闪回 ...
- postgresql数据库系列之:cmd命令行访问远程postgresql数据库
postgresql数据库系列之:cmd命令行访问远程postgresql数据库 psql -h 10.129.88.141 -U iris_read -d iris_test Password fo ...
- PostgreSQL 最佳实践 - 在线增量备份与任意时间点恢复
背景 冷备份, 以及逻辑备份都是某一个时间点的备份, 没有增量的概念. 如果数据库在运行过程中发生故障, 使用逻辑备份只能将数据库还原到备份时刻, 无法恢复到故障发生前的那个时刻. 又或者在使用过程中 ...
- oracle增量备份如何恢复,【Oracle】增量备份和全库备份怎么恢复数据库
在线QQ客服:1922638 专业的SQL Server.MySQL数据库同步软件 ? 为了演示增量备份的效果,我们在执行0级备份后对数据库进行了一些更改. ? 执行另一级1差异增量备份: < ...
- 数据库系列之TiDB备份恢复
BR工具用于TiDB集群的备份恢复,适合大数据量的备份恢复场景.本文简单介绍BR备份恢复原理和流程以及BR命令行的使用,并结合实际备份恢复场景加以测试验证. TiDB集群数据的备份恢复使用Backup ...
最新文章
- WebSocket在容器化管理平台的应用
- linux mysql 停止,linux 里 重启 和停止 mysql的原理
- 苹果开发者用计算机语言,苹果的编程语言 Swift 是用什么开发的?
- 安装nagios中php安装报错 configure error xml2-config not foud
- 集成微信支付的代码。兼容小程序,扫码,app,公众号。h5 支付 ,以及 服务商提现...
- excel文件打不开怎么办_电脑设备管理器打不开怎么办
- 使用spss做各种相关性分析的方法和步骤
- 机器学习数据不平衡问题及其解决方法
- 阿里云商标注册查询入口(支持图形检索/45分类注册风险)
- 如何在ubuntu上解压压缩包
- 拼写检查(深度讲解,普通方法+进阶版)
- 【2058】简单计算器
- 在组装机上安装ubuntu系统-配置pytorch-GPU学习环境
- 使用jQuery的click事件没反应
- Leetcode刷题——栈与队列
- vue-pdf使用+分页预览(踩坑 + 使用本地字体库)
- 教你用Vue 做一个简单的比较两个数字的大小的页面
- 微信小程序 SKU设计与实现 前端 数据结构分析
- 计算机维修员周记300字,计算机实习周记300字.doc
- fm2008 数据的计算方法