文章目录

相比与Oracle来说,PostgreSQL的备份还是简单许多了,基本上只需要简单做数据文件的copy就可以完成。

所有操作都用postgres用户完成,所有用到的目录都对postgres用户赋予了权限,否则可能会有权限问题。先建立archive归档目录,用于备份WAL Log(相当于Oracle的Redo Log)。

1
2
3
4
5
6
7
8
[postgres@anzhy ~]$ echo $POSTGRESQLHOME
/home/postgres/postgres
[postgres@anzhy ~]$ echo $PGDATA
/home/postgres/postgres/data
[postgres@anzhy ~]$ mkdir -p archive
[postgres@anzhy ~]$ cd archive/
[postgres@anzhy archive]$ pwd
/home/postgres/archive

然后配置PostgreSQL开启归档日志,并将归档的文件放到刚才归档目录/home/postgres/archive中。配置文件在$PGDATA\postgresql.conf中,修改以下几行,

1
2
3
wal_level = hot_standby
archive_mode = on
archive_command = 'DATE=`date +%Y%m%d`; DIR="/home/postgres/archive/$DATE"; (test -d $DIR || mkdir -p $DIR) && cp $PGDATA/%p $DIR/%f'

archive_mode = on是打开归档模式;archive_command是归档WAL日志的命令,其实就是新建一个文件夹加复制命令的组合,其中,%p表示xlog文件名,用的是$PGDATA的相对路径, 如pg_xlog/00000001000000190000007D,%f表示xlog文件名, 如00000001000000190000007D;wal_level = hot_standby是在负载均衡的情况下,让standby备机可以做只读访问,如果没有hot_standby的话,那备机只能在master主机失效的情况下才允许客户端连接。这个功能还算是比较新的,Oracle在11g版本中引入,叫archive datagard,PostgreSQL在9.0版本引入,叫hot standby。关于hot standby的说法参考了这里12

配置完成后,保存退出,重启数据库,并用psql登陆执行sql。

1
2
3
4
5
6
7
8
9
10
11
12
13
[postgres@anzhy ~]$ psql test
psql (9.3.4)
Type "help" for help.
test=# checkpoint;
CHECKPOINT
test=# select pg_switch_xlog();
pg_switch_xlog
----------------
0/60000150
(1 row)
test=#

pg_switch_xlog是系统函数,强制切换到一个新的事务日志文件。上述步骤可以多次执行,生成多个归档日志文件,如下

如果要做备份,可以用以下命令,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[postgres@anzhy ~]$ psql -c "select pg_start_backup('hot_backup');"
pg_start_backup
-----------------
0/65000028
(1 row)
[postgres@anzhy ~]$ DATE=`date +%Y%m%d`
[postgres@anzhy ~]$ tar -cf /home/postgres/archive/$DATE.backup.tar $PGDATA
tar: Removing leading `/' from member names
[postgres@anzhy ~]$ psql -c "select pg_stop_backup();"
NOTICE: pg_stop_backup complete, all required WAL segments have been archived
pg_stop_backup
----------------
0/650000F0
(1 row)
[postgres@anzhy ~]$ tar -rf /home/postgres/archive/$DATE.backup.tar /home/postgres/archive/$DATE/
tar: Removing leading `/' from member names
[postgres@anzhy ~]$

pg_start_backuppg_stop_backup分别是开始和结束在线备份的函数,备份的文件在/home/postgres/archive/$DATE.backup.tar。也可以将上述操作写成脚本backup_postgres.sh,如下

1
2
3
4
5
6
7
8
9
10
#!/bin/bash
psql -c "select pg_start_backup('hot_backup');"
DATE=`date +%Y%m%d`
ARCHIVE_DIR=/home/postgres/archive
tar -cf $ARCHIVE_DIR/$DATE.backup.tar $PGDATA
psql -c "select pg_stop_backup();"
tar -rf $ARCHIVE_DIR/$DATE.backup.tar $ARCHIVE_DIR/$DATE/

如果要做还原的话,只要把备份的文件/home/postgres/archive/$DATE.backup.tar解压到指定目录就好了。这个操作也可以写成脚本restore_postgres.sh,如下,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
BAK_FILE=$1
CUR_DIR=`pwd`
ARCHIVE_DIR=/home/postgres/archive
tar xf $BAK_FILE
cd home/postgres/postgres/data
cp -r * $PGDATA
cd $CUR_DIR
cd home/postgres/archive
cp -r * $ARCHIVE_DIR
cd $CUR_DIR
rm -r home

restore_postgres.sh XXXX.tar来恢复数据,XXXX.tar是之前备份脚本产生的文件。注意,备份数据库的时候可以热备,但是恢复的时候需要shutdown数据库来操作。以上脚本是针对之前的备份脚本特别写的,如果目录有变化的话,需要修改相关内容,而且写法也不是很严谨,没有对文件或目录是否存在做判断。不难看出,这个方法可以将备份文件copy到多个系统上,一次性还原出多个一样的数据库。此外,PostgreSQL的程序本身,只要操作系统相同,也是可以用复制来安装的,只要新增一些环境变量即可,便于日常使用(其实,不新增这些环境变量程序也是可用的,就是每次敲命令的时候可能要敲很长)。我的环境变量如下,加在.bashrc中,

1
2
3
4
export POSTGRESQLHOME=/home/postgres/postgres
export PGDATA=$POSTGRESQLHOME/data
export LD_LIBRARY_PATH=$POSTGRESQLHOME/lib:$LD_LIBRARY_PATH
export PATH=$POSTGRESQLHOME/bin:/usr/local/pgadmin3/bin:/home/program/bin:$PATH

因此,只需要将上述几个脚本略加修改合并,就可以完成一个自动化在多机上部署相同数据库的脚本。

本文展示了联机热备的方法,如果只备份data目录下的文件,那么这种备份方法称为文件系统复制,PostgreSQL还有一种备份方法SQL dump,主要使用了PostgreSQL自带的pg_dump命令,本文不再介绍,想了解的朋友可以参考34。如果想做单表备份,也可以使用PostgreSQL提供的copy命令,可以参考5,其作用应该类似与Oracle的sqlldr。

文章目录

欢迎来到Valleylord的博客!

本博的文章尽量原创。