
点击上方蓝色文字关注我们

目录
备份恢复
一、备份恢复的方式
二、逻辑备份与恢复
三、物理备份与恢复
四、基于时间点的恢复(PITR)
一、备份恢复的方式

1. PG备份恢复方式主要分为两类
逻辑备份恢复
1、 将文件中的数据复制到表中:
COPY table_name [ ( column_name [, ...] ) ]FROM { 'filename' | PROGRAM 'command' | STDIN }[ [ WITH ] ( option [, ...] ) ]
2、将表中的数据复制到文件中:
COPY { table_name [ ( column_name [, ...] )] | ( query ) }TO{ 'filename' | PROGRAM 'command' | STDOUT }[[ WITH ] ( option [, ...] ) ]
物理备份恢复
二、逻辑备份与恢复

1. 逻辑备份
pg_dump
可以选择一个数据库或部分表进行备份,恢复过程可以跨平台迁移;
可以在数据库正在使用时进行完整一致的备份,并不阻塞其它用户对数据库的访问;
只能备份单个数据库,不会导出角色和表空间相关的信息。
示例:pg_dump --table=tbl -d dbpg_dump --schema=scm -d dbpg_dump --file=postgres.sql --blobs --schema=public --dbname=postgres --host=127.0.0.1 --port=5432 --username=postgrespsql -h 127.0.0.1 -p 5433 -U postgres -d postgres -f postgres.sqlpg_dump 把一个数据库转储为纯文本文件或者是其它格式.
用法:pg_dump [选项]... [数据库名字]一般选项:-f, --file=FILENAME 输出文件或目录名-F, --format=c|d|t|p 输出文件格式 (定制, 目录, tar)明文 (默认值))-j, --jobs=NUM 执行多个并行任务进行备份转储工作-v, --verbose 详细模式-V, --version 输出版本信息,然后退出-Z, --compress=0-9 被压缩格式的压缩级别--lock-wait-timeout=TIMEOUT 在等待表锁超时后操作失败--no-sync do not wait for changes to be written s-?, --help 显示此帮助, 然后退出控制输出内容选项:-a, --data-only 只转储数据,不包括模式-b, --blobs 在转储中包括大对象-B, --no-blobs exclude large objects in dump-c, --clean 在重新创建之前,先清除(删除)数据库对象-C, --create 在转储中包括命令,以便创建数据库-E, --encoding=ENCODING 转储以ENCODING形式编码的数据-n, --schema=SCHEMA 只转储指定名称的模式-N, --exclude-schema=SCHEMA 不转储已命名的模式-o, --oids 在转储中包括 OID-O, --no-owner 在明文格式中, 忽略恢复对象所属者-s, --schema-only 只转储模式, 不包括数据-S, --superuser=NAME 在明文格式中使用指定的超级用户名-t, --table=TABLE 只转储指定名称的表-T, --exclude-table=TABLE 不转储指定名称的表-x, --no-privileges 不要转储权限 (grant/revoke)--binary-upgrade 只能由升级工具使用--column-inserts 以带有列名的INSERT命令形式转储数据--disable-dollar-quoting 取消美元 (符号) 引号, 使用 SQL 标准引号--disable-triggers 在只恢复数据的过程中禁用触发器--enable-row-security 启用行安全性(只转储用户能够访问的内容)--exclude-table-data=TABLE 不转储指定名称的表中的数据--if-exists 当删除对象时使用IF EXISTS--inserts 以INSERT命令,而不是COPY命令的形式转储数--no-publications do not dump publications--no-security-labels 不转储安全标签的分配--no-subscriptions do not dump subscriptions--no-synchronized-snapshots 在并行工作集中不使用同步快照--no-tablespaces 不转储表空间分配信息--no-unlogged-table-data 不转储没有日志的表数据--quote-all-identifiers 所有标识符加引号,即使不是关键字--section=SECTION 备份命名的节 (数据前, 数据, 及 数据后)--serializable-deferrable 等到备份可以无异常运行--snapshot=SNAPSHOT 为转储使用给定的快照--strict-names 要求每个表和/或schema包括模式以匹配至少--use-set-session-authorization使用 SESSION AUTHORIZATION 命令代替ALTER OWNER 命令来设置所有权联接选项:-d, --dbname=DBNAME 对数据库 DBNAME备份-h, --host=主机名 数据库服务器的主机名或套接字目录-p, --port=端口号 数据库服务器的端口号-U, --username=名字 以指定的数据库用户联接-w, --no-password 永远不提示输入口令-W, --password 强制口令提示 (自动)--role=ROLENAME 在转储前运行SET ROLEpg_dump仅导出数据库结构:pg_dump -U TestRole1 -s -f TestDb1.sql TestDb1
备份某个database,备份结果以自定义压缩格式输出:pg_dump -h localhost -p 5432 -U someuser -F c -b -v -f mydb.backup mydb备份某个database,备份结果以SQL文本方式输出,输出结果中需包括CREATE DATABASE语句:pg_dump -h localhost -p 5432 -U someuser -C -F p -b -v -f mydb.backup mydb备份某个database中所有名称以“pay”开头的表,备份结果以自定义压缩个数输出:pg_dump -h localhost -p 5432 -U someuser -F c -b -v -t *.pay* -f pay.backup mydb备份某个database中hr和payroll这两个schema中的所有数据,备份结果以自定义压缩格式输出:pg_dump -h localhost -p 5432 -U someuser -F c -b -v -n hr -n payroll -f hr_payroll.backup mydb备份某个database中除了public schema中的数据以外的所有数据,备份结果以自定义压缩格式输出:pg_dump -h localhost -p 5432 -U someuser -F c -b -v -N public -f all_sch_except_pub.backup mydb
pg_dumpall
由超级用户执行备份整个集簇、数据库,包括角色和表空间
生成psql脚本,pg_dumpall 只支持文本格式
它在内部调用pg_dump
参数选项-data-only 提供没有对象定义的数据转储-globals-only 备份转储角色和表空间-clean 包括删除数据库,角色和表空间
pg_dumpall可实现仅备份角色和表空间定义:pg_dumpall -h localhost -U postgres --port=5432 -f myglobals.sql --globals-only如果仅需备份角色定义而无需备份表空间,那么可以加上--roles-only选项:pg_dumpall -h localhost -U postgres --port=5432 -f myroles.sql --roles-only
2. 逻辑恢复
文本格式的备份文件, 直接使用用户连接到对应的数据库执行备份文本;psql dbname -f filenamepsql dbname -U username < filename二进制格式的备份文件只能使用pg_restore来还原;可以指定还原的表, 编辑TOC文件, 定制还原的顺序, 表, 索引等;pg_restore [option] ... [filename]pg_restore -d dbname bakfilepg_dump --host=127.0.0.1 --port=5432 --dbname=postgres --schema=public --username=postgres --format=c --encoding=UTF8 --file= file.backup --password --blobs --inserts --column-inserts --table=pg_restore -U user -d database file. backup>a.txt 2>&1psql -d database -h IP -p 5432 -U user -f file.sql
逻辑备份恢复示例:pg_dump备份恢复示例1)创建数据库createdb testdb2)连入数据库testdbpsql testdb13)创建测试表,插入数据testdb=# create table tt(a int) tablespace tbls_t;testdb=# insert into tt(a) values(1);testdb=# insert into tt(a) values(2);4)查看数据testdb=# select * from tt;5)备份pg_dump testdb1>/dbbak/testdb.sql #简单语法,可结合选项灵活备份6)删除数据库testdbdropdb testdb7)创建新数据库(恢复之前需创建数据库)createdb testdb18)恢复数据psql testdb19)查看数据是否回复psql testdbtestdb=# select * from tt
3. PG_DUMP 扩展练习
备份选项控制备份:
#二进制格式备份文件
pg_dump -F c -f db1.dmp -C -E UTF8 -h 127.0.0.1 -U postgres db1
#文本格式备份文件
pg_dump -F p -f dbbak/p.dmp -C -E UTF8 -h 127.0.0.1 -U postgres testdb
-F c 备份为二进制格式, 压缩存储. 并且可被pg_restore用于精细还原
-F p 备份为文本, 大库不推荐.
-C include commands to create database in dump
不同格式的恢复:pg_restore dbbak/testdb.dmp|less # 可以解析二进制格式的备份文件pg_restore -l dbbak/testdb.dmp #生成二进制备份集合的TOC列表pg_restore -d testdb1 dbbak/testdb.dmp #需要先创建目标库psql -d testdb2 < dbbak/p.dmp
4.PG_DUMP扩展示例
生成toc文件进行选择性恢复:
1)根据二进制备份文件生成toc文件
pg_restore -l -f dbbak/toc1 dbbak/testdb.dmp
2)修改 toc文件,以首行加分号“;”的方式注释掉不用还原的内容
3)以toc文件列表做恢复
pg_restore -Fc -L dbbak/toc -d testdb dbbak/testdb.dmp-l --list列出归档的内容的表格。这个操作的输出能被用作-L选项的输入。注意如果把-n或-t这样的过滤开关与-l一起使用,它们将会限制列出的项。-f filename--file=filename为生成的脚本指定输出文件,或在与-l选项一起使用时为列表指定输出文件。为 stdout用 -。
使用unix管道备份恢复:
pg_dump testdb| gzip > dbbak/testdbbak.sql.gzgunzip -c dbbak/testdbbak.sql.gz | psql testdb2pg_dump testdb | psql testdb1
并行处理:
pg_dump -Fd -j4 -f dbbak/db.dir testdbpg_restore -d testdb3 -j4 dbbak/db.dir-j参数指定同时几个进程来同时执行,每个进程同时只处理一个表的数据。使用pg_dump的directory-format 对应选项 -Fd使用pg_dump的custom-format-j参数指定并发的数量(job),pg_restore恢复custom-format格式也可以使用此参数,并非只适用directory-formatfile toc.datcat toc.datcat 2866.dat.gz |gunzip一个表对应一个标号文件select oid from pg_class where relname='pitr_test';
5. COPY命令
三、物理备份与恢复

1. 冷备份恢复
备份示例:tar -jcv -f home/postgres/bak/dbbak0817.tar.bz2 $PGDATA恢复示例:tar -jxv -f home/postgres/bak/dbbak0817.tar.bz2 -C
2. 在线热备份恢复原理

运用在线备份以及即时恢复(PITR)原理,利用Postgresql 数据库的WAL(Write Ahead Logging )预写日志和基础备份( $PGDATA目录文件tar包 ),恢复到数据库崩溃前时间点,保证数据量最少丢失或者不丢失.
如果数据库崩溃,我们就可以通过热备产生的备份文件data_bak.tar包 ($PGDATA目录文件tar包)和archive_command产生的WAL及我们自己备份的WAL(pg_xlog)来进行数据库的 recovery 。
3. 在线热备份的三种实现方式
pg_basebackup
pg_basebackup 参数说明:
-h 指定连接的数据库的主机名或IP地址,这里就是主库的ip。-U 指定连接的用户名,此处是我们刚才创建的专门负责流复制的repl用户。-F 指定了输出的格式,支持p(原样输出)或者t(tar格式输出)。-x 表示备份开始后,启动另一个流复制连接从主库接收WAL日志。-P 表示允许在备份过程中实时的打印备份的进度。-R 表示会在备份结束后自动生成recovery.conf文件,这样也就避免了手动创建。-D 指定把备份写到哪个目录,这里尤其要注意一点就是做基础备份之前从库的数据目录($PGDATA)目录需要手动清空。-l 表示指定一个备份的标识
pg_basebackup实验
pg_basebackup 备份过程:
mkdir -p opt/archchown -R postgres:postgres opt/arch
vi $PGDATA/postgresql.confarchive_mode = onarchive_command = 'DATE=`date +%Y%m%d`; DIR="/opt/arch/$DATE"; (test -d $DIR || mkdir -p $DIR) && cp %p $DIR/%f'wal_level = replica
注释:
%p 表示wal文件名$PGDATA的相对路径, 如pg_wal/00000001000000190000007D
%f 表示wal文件名, 如00000001000000190000007D
2)重启数据库使参数生效,验证归档。
checkpoint; #备注1select pg_switch_wal();[root@pg01 20211124]# pwd/opt/arch/20211124[root@hgdb01 20211124]# ls000000020000000000000003 000000020000000000000004
3)创建replication权限的角色, 或者超级用户的角色。
create role repl nosuperuser replication login connection limit 32 encrypted password '111111';
4)配置pg_hba.conf,添加以下内容
------host replication repl 0.0.0.0/0 md5------
5)执行备份(因为使用流复制协议, 所以支持异地备份)
pg_ctl reload #执行加载配置的命令mkdir `date +%F` ;pg_basebackup -Ft -v -P -D home/postgres/bak/`date +%F` -h IP地址 -p 5432 -U repl
6)备份完毕,查看备份文件
[postgres@hgdb01 ~]$ cd home/postgres/bak/2021-11-24postgres@pg01-> lltotal 115M-rw-rw-r-- 1 postgres postgres 99M Nov 24 03:04 base.tar-rw------- 1 postgres postgres 17M Nov 24 03:04 pg_wal.tar[postgres@hgdb01 2021-11-24]$ tar -tvf base.tar |less #查看备份包内容backup_labelpg_start_backup,会生成 backup_label文件。pg_stop_backup,会删除backup_label文件。而如果StartupXLOG函数运行时,发现了backup_label文件,那么意味着它处正在从online backup中恢复的过程中。
pg_start_backup执行下列4个操作:
强制进入整页写入模式;
切换到当前的WAL段文件(8.4或更高版本);
执行检查点;
创建backup_label文件 —— 该文件创建于基本目录顶层中,包含有关该基本备份本身的关键信息,如检查点的检查点位置。
*第3个和第4个操作是该命令的核心。第1和第2个操作是为了更可靠地恢复数据库集簇。
备份标签backup_label文件包含以下7个项目:
检查点位置 —— 该命令所创建检查点的LSN位置。
WAL开始位置——这不是给PITR用的,流复制用的。它被命名为START WAL LOCATION,因为复制模式下的备用服务器在初始启动时只读取一次该值。
备份方法——这是用于进行此基本备份的方法,如pg_start_backup或pg_basebackup。
备份来源 —— 说明此备份是从主库还是备库拉取。
开始时间 —— 这是执行pg_start_backup时的时间戳。
备份标签 —— 这是pg_start_backup中指定的标签。
开始时间线 —— 这是备份开始的时间线,为了进行正常的检查,在版本11.0中被引入。
1)停止数据库并删除数据目录,将pg_basebackup生成的备份包分别解压到相应目录[root@pg01 2021-11-24]# tar -xvf base.tar -C opt/pg_root[root@pg01 2021-11-24]# tar -xvf pg_wal.tar -C opt/pg_root/pg_wal2)recovery.conf文件配置还原参数$cp $PGHOME/share/recovery.conf.sample $PGDATA/recovery.confvi $PGDATA/recovery.conf #备注restore_command = 'cp opt/arch/20211124/%f %p'recovery_target_timeline = 'latest'3)启动数据库并做数据查看验证是否恢复完成pg_ctl start
简单讲述表空间的软连接


pg_start_backup()和 pg_stop_backup()
物理备份恢复实验
pg_start_backup()和 pg_stop_backup() 备份过程:
1)开启归档(方法参考前面章节)
2)超级用户连接数据库,执行命令:
select pg_start_backup(now()::text);backup_labelpg_start_backup,会生成 backup_label文件。pg_stop_backup,会删除backup_label文件。而如果StartupXLOG函数运行时,发现了backup_label文件,那么意味着它处正在从online backup中恢复的过程中。------pg_start_backup-----------------0/E000028(1 row)
3)可通过函数pg_is_in_backup();查看到备份状态
select pg_is_in_backup();pg_is_in_backup-----------------t(1 row)也可以通过$PGDATA目录下生成的标签文件查看备份信息cat $PGDATA/backup_label------START WAL LOCATION: 0/E000028 (file 00000002000000000000000E)CHECKPOINT LOCATION: 0/E000060BACKUP METHOD: pg_start_backupBACKUP FROM: masterSTART TIME: 2018-01-17 11:17:18 CSTLABEL: 2018-01-17 11:17:18.151543+08
4)执行备份
使用操作系统工具比如 tar 或 cp -ra 等,或直接把数据目录复制到备份位置。过程中既不需要关闭数据库,也不需要停止数据库的任何操作。tar -jcv -f ~/bak/pgdata.tar.bz2 $PGDATA注意手动备份表空间路径,即目录的pg_tblspc软连接指向目录。tar -jcv -f ~/bak/dbbak/tbls.tar.bz2 /pgtbls/tbls01
5)再次以数据库超级用户身份连接数据库,然后发出命令:
select pg_stop_backup();这将终止备份模式并自动切换到下一个 WAL 段。
6)最后拷贝强制检查点之间的所有归档日志文件, 确保备份有效性。
四、基于时间点的恢复(PITR)

基于时间点的恢复(PITR)简介
vi $PGDATA/postgresql.confarchive_mode = onarchive_command = 'DATE=`date +%Y%m%d`; DIR="/opt/arch/$DATE"; (test -d $DIR || mkdir -p $DIR) && cp %p $DIR/%f'wal_level = replica
pg_basebackup -D /home/postgres/bak/ -Ft -P -R -Upostgres
create table t_rec (id int,time timestamp);insert into t_rec values (1,now());insert into t_rec values (2,now());insert into t_rec values (3,now());insert into t_rec values (4,now());insert into t_rec values (5,now());select pg_switch_wal();checkpoint;select * from t_rec;
基于时间点恢复
tar -xvf base.tar -C /opt/pg_roottar -xvf pg_wal.tar -C /opt/pg_root/pg_wal[root@pg01 opt]# chmod 0700 /opt/pg_root
cp /opt/pgsql/share/recovery.conf.sample /opt/pg_root/recovery.conf
restore_command = 'cp /opt/arch/20211124/%f %p'recovery_target_time = '2021-11-24 04:28:27.860105'
%p 表示wal文件名$PGDATA的相对路径, 如pg_wal/00000001000000190000007D%f 表示wal文件名, 如00000001000000190000007D
select pg_wal_replay_resume();pg_wal_replay_resume() void 如果恢复被暂停,重启之(默认仅限于超级用户,但是可以授予其他用户 EXECUTE 特权来执行该函数)。postgres=# show archive_mode ;archive_mode--------------on(1 row)postgres=# show archive_command ;archive_command-----------------------------cp %p /home/postgres/archive/%f(1 row)pg_basebackup -D /home/postgres/bak/ -Ft -P -R -Upostgrespostgres=# create table t_rec (id int,time timestamp);CREATE TABLEpostgres=# insert into t_rec values (1,now());INSERT 0 1postgres=# insert into t_rec values (2,now());
postgres=# show archive_mode ;archive_mode--------------on(1 row)postgres=# show archive_command ;archive_command-----------------------------cp %p /home/postgres/archive/%f(1 row)pg_basebackup -D /home/postgres/bak/ -Ft -P -R -Upostgrespostgres=# create table t_rec (id int,time timestamp);CREATE TABLEpostgres=# insert into t_rec values (1,now());INSERT 0 1postgres=# insert into t_rec values (2,now());
基于时间点恢复
INSERT 0 1postgres=# insert into t_rec values (3,now());INSERT 0 1postgres=# select pg_switch_wal();pg_switch_wal---------------0/1E0141B8(1 row)postgres=# insert into t_rec values (4,now());INSERT 0 1postgres=# insert into t_rec values (5,now());INSERT 0 1postgres=# select * from t_rec ;id | time----+----------------------------1 | 2020-05-29 17:28:03.3472962 | 2020-05-29 17:28:07.9510333 | 2020-05-29 17:28:14.9552854 | 2020-05-29 17:29:12.4314255 | 2020-05-29 17:29:22.629481(5 rows)
cp /home/postgres/psql/share/recovery.conf.sample/home/postgres/pgdata/recovery.conf
restore_command = 'cp /home/postgres/archive/%f %p'recovery_target_time = '2020-05-29 17:29:20.431425 +08'
select pg_wal_replay_resume();

点击下方 “阅读原文” 查看更多
↓↓↓




