posgresql 备份

开启归档




mkdir -p /usr/local/postgres/data/archive


# - Archiving -
wal_level = archive 
#wal_level = hot_standby
archive_mode = on
archive_command = 'cp -i %p /usr/local/postgres/archive/%f'
#archive_command = 'test ! -f /usr/local/postgres/archive/%f && cp %p /usr/local/postgres/archive/%f'


pg_ctl stop/start




方法一:手动切换 WAL 日志
select pg_switch_xlog();


方法二:WAL 日志写满后触发归档
WAL 日志被写满后会触发归档,文档在说明配置参数 archive_command 时的第一句说就说明了这点, 
WAL 日志文件默认为 16MB,这个值可以在编译 PostgreSQL 时通过参数 "--with-wal-segsize" 更改,编
译后不能修改。
方法三:设置 archive_timeout
 另外可以设置archive 超时参数 archive_timeout ,假如设置 archive_timeout=60 ,那么每 60 s ,
会触发一次 WAL 日志切换,同时触发日志归档,这里有个隐含的假设: 当前 WAL 日志中仍有未归档的 WAL 
日志内容




热备份:
方法1:利用pg_basebackup命令进行热备份和恢复
前提要开启归档
vi postgresql.conf
max_wal_senders = 2 
这个参数是在主机上设置的,是从机连接到主机的并发连接数之总和,所以这个参数是个正整型。默认值是0,也即默认没有流复制功能。该并发连接数从进程上看,就是各个wal sender进程数之和,可以通过ps -ef|grep senders来查看,所以该值不能超过系统的最大连接数


max_wal_senders是为了让一个master端,带多个slave端用的,基本上每一对master--slave用一个链接。
但是,还需要注意,pg_basebackup也会用到一个。


开启流复制访问
vi  pg_hba.conf
host  replication  postgres    127.0.0.1/32      trust

pg_basebackup -D /usr/local/postgres/backup -h 127.0.0.1 -U postgres -Ft -z -P 

cp /usr/local/postgres/share/recovery.conf.sample  /usr/local/postgres/data/recovery.conf
vi recovery.conf
restore_command = 'cp /usr/local/postgres/archive/%f %p' 


恢复:
cd  /usr/local/postgres/backup
tar zxvf 24584.tar.gz
tar zxvf 24587.tar.gz
tar zxvf base.tar.gz


mv /usr/local/postgres/data /usr/local/postgres/data/bak
mkdir -p /usr/local/postgres/data
chown -R postgres:root /usr/local/postgres/data
chmod 700 /usr/local/postgres/data
cd  /usr/local/postgres/backup
cp -r * /usr/local/postgres/data
pg_ctl start




热备份库方法2:
PostgreSQL热备份的过程一般为:


数据库中执行:pg_start_backup() ;
然后使用操作系统的tar或 cp命令拷贝 PostgreSQL数据文件。
数据库中执行:pg_stop_backup()  ;
有人可能会问为什么我们开始用操作系统备份数据库前需要执行pg_start_backup()?


实际上pg_start_backup()主要做了以下两个工作:


置写日志标志为:XLogCtl->Insert.forcePageWrites = true,也就是把这个标志设置为true后,数据库会把变化的整个数据块都记录到数据库中,而不仅仅是块中记录的变化。
强制发生一次checkpoint点。


准备备份目录:
mkdir -p /usr/local/postgres/backup/`date +%Y%m%d`


启动备份
psql postgres -c "select pg_start_backup('hot_backup');"
 
使用tar命令备份数据库文件,不包含pg_xlog目录
要保证你的备份转储包括所有数据库集群目录里的文件(比如 /usr/local/pgsql/data)
tar --exclude $PGDATA/pg_xlog -cvjpf /usr/local/postgres/backup/`date +%Y%m%d`/pgbackup.tar.bz2 $PGDATA
完成备份
psql postgres -c "select pg_stop_backup();"


测试
$ psql postgres
create table abc(id integer);
insert into abc values(1);
select pg_switch_xlog();     




 


恢复:
pg_ctl stop -m fast

kill -s SIGQUIT Postmaster进程号 


删除data目录
mv data/ databak/




解压之前的备份文件压缩包
tar -jxvf /usr/local/postgres/backup/`date +%Y%m%d`/pgbackup.tar.bz2
mv /usr/local/postgres/backup/20150825/usr/local/postgres/data/  /usr/local/postgres/data
cd /usr/local/postgres/data


把崩溃时后的online wal log 也准备好
cp -r databak/pg_xlog/ data/
cd data/pg_xlog/archive_status
rm -f *
将online wal log因为日志名相同,则
DETAIL:  The failed archive command was: test ! -f /usr/local/postgres/archive/000000010000000000000010 && cp pg_xlog/000000010000000000000010 /usr/local/postgres/archive/000000010000000000000010
LOG:  archive command failed with exit code 1





mkdir pg_xlog
chmod 0700 pg_xlog/
chown postgres:postgres pg_xlog/
cd pg_xlog/
mkdir archive_status
chmod 0700 archive_status/
chown postgres:postgres archive_status/




配置恢复配置文件
cd  /usr/local/postgres/data
touch recovery.conf
echo "restore_command='cp -i /usr/local/postgres/archive/%f %p'" >>recovery.conf
echo "recovery_target_time = '2013-08-07 13:45:00+08'"  >>recovery.conf        --基于时间点恢复
chown postgre:postgre recovery.conf
chmod 0750 recovery.conf


启动
pg_ctl start
 


所有这些操作的关键是设置一个恢复命令文件,这个文件描述你希望如何恢复以及恢复应该走到哪里。你可以使用 recovery.conf.sample(通常安装在安装目录的 share/ 子目录里)作为原型。你必须在 recovery.conf 里面声明的一个东西是 restore_command ,它告诉系统如何拿回归档的 WAL 文件段。类似 archive_command ,这个是一个脚本命令字符串。它可以包含 %f ,这个变量会被需要的日志文件名替换,以及 %p ,它会被要拷贝去的日志文件的绝对路径代替。如果需要在命令里替换真正的 % 字符,那么就双写(%%)。最简单的有用命令是类似下面的东西


restore_command = 'cp /mnt/server/archivedir/%f %p'
这个命令将把以前归档的 WAL 段从 /mnt/server/archivedir 目录拷贝过来
在归档中找不到的 WAL 段将被认为在 pg_xlog/ 里;这样就允许使用最近没有归档的段。但是在归档中的段将比 pg_xlog/ 中的优先。在检索归档文件的时候,系统将不会覆盖现有的 pg_xlog/ 内容。




pg_xlog目录不断增大,想要清理一下,释放磁盘空间,怎么办?


pg_xlog目录的用途:包含 WAL(预写日志)文件的子目录
归档过程:archive进程使用linux命令cp,mv等来处理WAL和归档。
1.如果日志发生切换,archive 使用命令cp 000000001000000A /archive_backup来把旧WAL日志进行归档。
2.在archive_status目录中使用命令mv 000000001000000A 000000001000000A.done,来表明已经归档完成。
3.在pg_xlog中使用rm -f 000000001000000A
  在pg_xlog/archive_status目录用使用rm -f 000000001000000A.done来完成清理旧WAL日志。


因此当没有启动归档时,pg_xlog目录可能会不断增大,占用很大的磁盘空间,想要释放空间,那么可以模拟postgresql归档的过程,甚至可以直接删除pg_xlog下的日志文件.


cd pg_xlog
find ./ -mtime +10 -exec rm -f {} \; #删除10天以前的所有日志。






备份脚本:
[postgres@server11 ~]$ more /opt/postgres/pgbak.sh
#!/bin/bash
export PG_BACKUP=/opt/postgres/backup
export PG_BASE=/opt/postgres
export PG_HOME=/opt/postgres/product/9.4.1
export PGDATA=$PG_BASE/data
export PG_LOGFILE=$PG_BASE/trace/pg_log.log
export LD_LIBRARY_PATH=$PG_HOME/lib
export LC_MESSAGES=en_US
export MANPATH=$MANPATH:$PG_HOME/share/man
export PATH=$PATH:$PG_HOME:$PG_HOME/bin:$HOME
BAKDIR=${PG_BACKUP}/`date +%Y%m%d`_pgbak
if [ -f '/tmp/backup_in_process' ];
then
    echo "Another pgback is running now!please wait..........." >>${PG_BACKUP}/baklog/baklog/`date +%Y%m%d`_bak.log 2>&1
    exit 1
fi
touch /tmp/backup_in_process
mkdir -p ${BAKDIR}
echo "Begin backing up pg database......................." >>${PG_BACKUP}/baklog/`date +%Y%m%d`_bak.log 2>&1
psql -c "select pg_start_backup('hotbak');" -h localhost -p 5432 >>${PG_BACKUP}/baklog/`date +%Y%m%d`_bak.log 2>&1
tar -zcf ${BAKDIR}/`date +%Y%m%d`_hotbak.tar.gz $PGDATA 
psql -c "select pg_stop_backup();" -h localhost -p 5432 >>${PG_BACKUP}/baklog/`date +%Y%m%d`_bak.log 2>&1
#mv   ${PG_BASE}/archive/* ${PG_BACKUP}/xlog/
rm /tmp/backup_in_process
if [ $? -eq 0 ];
then
    echo "Pg database has been backuped successfully" >>${PG_BACKUP}/baklog/`date +%Y%m%d`_bak.log 2>&1
    exit 0
else
    echo "Pg backup has been terminated unexpectly, please check ${PG_BACKUP}/baklog/`date +%Y%m%d`_bak.log for details" 
>>${PG_BACKUP}/baklog/`date +%Y%m%d`_bak.log 2>&1
    exit 1
fi


逻辑导出
创建备份账号:
vi pg_hba.conf
host    all     backupadmin        192.168.0.0/16            md5


创建备份账号
create user backupadmin with password 'backupadmin';
grant all privileges on database ywhjdb to backupadmin;
grant all privileges on database test2 to backupadmin;
grant all privileges on database webdb to backupadmin;
grant all privileges on database postgres to backupadmin;
psql -U backupadmin -W -h 192.168.168.142 -p 1921 


创建超级用户:
create user root with superuser password '123456';


>psql -U backupadmin  -h 192.168.168.142 -p 1921  -d ywhjdb
>psql -U root  -h 192.168.168.142 -p 1921  -d ywhjdb




DETAIL:  The database subdirectory "pg_tblspc






pg_dump -h 192.168.168.142 -U root ywhjdb >/tmp/ywhjdb.sql


恢复到另一个数据库
create database ywhjdb2;
pg_restore -h 192.168.168.142 -U root -d ywhjdb2 /tmp/ywhjdb.sql
备份出来的为脚本(纯文本)文件,不能直接使用pg_restore进行恢复,用下面的方式来恢复
psql -h 192.168.168.142 -U root -d ywhjdb2 </tmp/ywhjdb.sql




仅备份数据库结构
pg_dump -h 192.168.168.142 -U root -s -f /tmp/ywhjdb_ddl.sql ywhjdb




 pg_dumpall 可以导出所有数据库,类似 pg_dump,但用得非常少,原因可能是多方面的,
例如以下:


1 pg_dumpall 导出所有数据库到一个脚本文件,维护不方便;
2 pg_dumpall 依次导出所有库,总耗时比并行 pg_dump 各个库要多;
3 pg_dumpall 仅支持导出文件格式,还原时不能使用 pg_restore 有效使用并行等参数。




一 导出所有 role 和 tablespace 
--1.1 导出 role 和 tablespace 
 [pg92@redhatB tf]$ pg_dumpall -g > pg92_globle.sql




 二 仅导出 role
 [pg92@redhatB tf]$ pg_dumpall -r > pg92_roles.sql




三 仅导出 tablespace
 [pg92@redhatB tf]$ pg_dumpall -t > pg92_tablespace.sql
备注: 这里的 -t 是指导出所有表空间,和 pg_dump 的 -t 不一样。



-----------------------------------备份恢复测试-----------------------------

----------------------
备份恢复测试:OK
启动备份
psql -U postgres -h 127.0.0.1
select pg_start_backup('hot_backup');
tar --exclude $PGDATA/pg_xlog -cvjpf /backup/pgbackup.tar.bz2 $PGDATA
select pg_stop_backup();


create table abc(id integer);
insert into abc values(1);
\q


停止数据库,拷贝日志
pg_ctl stop
cp $PGDATA/pg_xlog/*00* /usr/local/postgres/archive/
把/data/pg_xlog/下的WAL日志文件复制到预设的归档目录下,保证产生的WAL日志都已归档






删除"发生错误"的data目录
cd /usr/local/postgres
rm -rf data


解压之前的备份文件压缩包
tar -xvf /backup/pgbackup.tar.bz2
mv /usr/local/postgres/usr/local/postgres/data /usr/local/postgres


恢复data目录,重新创建pg_xlog目录及其子目录archive_status
cd /usr/local/postgres/data
mkdir pg_xlog
chmod 0700 pg_xlog/
chown postgres:postgres pg_xlog/
cd pg_xlog/
mkdir archive_status
chmod 0700 archive_status/
chown postgres:postgres archive_status/
mv /usr/local/postgres/archive/*00* /usr/local/postgres/data/pg_xlog


配置恢复配置文件
cd /usr/local/postgres/data
touch recovery.conf
echo "restore_command='cp -i /usr/local/postgres/archive/%f %p'" >>recovery.conf
chown postgres:postgres recovery.conf
chmod 0750 recovery.conf
pg_ctl start




psql -h 127.0.0.1 -p 1921 -U postgres 
select * from abc;




--------------------
备份测试2:OK
备份
create table tb(a int);
insert into tb(a) values(1);
select pg_start_backup('base_backup');
tar jcvf /backup/baseline.tar.bz2 /usr/local/postgres/data/
select pg_stop_backup();


测试数据:
 insert into tb(a) values(2);
 select pg_switch_xlog();
 insert into tb(a) values(3);
 select pg_switch_xlog();
 insert into tb(a) values(4);
 select pg_switch_xlog();


 把/data/pg_xlog/下的WAL日志文件复制到预设的归档目录下,保证产生的WAL日志都已归档。
 cp /usr/local/postgres/data/pg_xlog/*00* /usr/local/postgres/archive/


数据删除:
pg_ctl stop -m fast
cd /usr/local/postgres
rm -rf data


恢复数据:
tar -xvf /backup/baseline.tar.bz2
mv /usr/local/postgres/usr/local/postgres/data /usr/local/postgres
cd /usr/local/postgres/data/pg_xlog
rm -rf /usr/local/postgres/data/pg_xlog/
mkdir -p /usr/local/postgres/data/pg_xlog/
mkdir -p /usr/local/postgres/data/pg_xlog/archive_status






cd /usr/local/postgres/data
touch recovery.conf
echo "restore_command='cp -i /usr/local/postgres/archive/%f %p'" >>recovery.conf
chown postgres:postgres recovery.conf
chmod 0750 recovery.conf
pg_ctl start




psql -U postgres -h 127.0.0.1
postgres=# select * from tb;
 a 
---
 1
 2
 3
 4
(4 rows)




--------------------


请使用浏览器的分享功能分享到微信等