本文主要介绍两种并行逻辑备份的方式:
一种是手动设置多个连接使用相同的快照,并且每个连接同时备份不同的数据库对象,然后使用copy等命令进行数据拷贝,一种是使用pg_dump的-j选项。对于一般情况,使用pg_dump的-j选项就可以了,但是对于低于PG9.3的版本,以及一些基于PG低版本且没有pg_dump的-j选项的国产数据库的话,可能需要多个连接使用同一快照的方式进行并行备份。
通常情况下,如果使用多个连接并行的备份数据库中的相同的表,在数据库还在同时修改数据库的状态下是无法获得一个完全一致的数据的。
对于这个情况,其实可以利用PG的快照机制去实现多个连接的并行逻辑备份,来获取到同一时刻的这些表的数据。因为当一个session或者说一个连接在做dml操作的时候,需要获取一个事务,而事务的可见性由事务中的快照决定。所以如果所有的连接,他们的事务使用的快照是一样的,那么他们在和这个事务里,查询到的相同对象的数据,是完全一致的。
一、利用快照进行并行备份
1、保存唯一快照
PostgreSQL 9.2 开始,支持pg_export_snapshot这个函数,他会保存当前快照,并返回标识快照的文本字符串,即唯一标识,便于其他事务也使用相同的快照查看数据。
postgres=# select pg_export_snapshot();
pg_export_snapshot
---------------------
00000003-000A77D7-1
(1 row)
除此之外,这样导出一致的快照需要在REPEATABLE READ和更高的隔离级别中,这些级别的事务在其整个生命周期中使用相同的快照。而例如默认的READ COMMITTED级别的事务,一个事务可以导出多个快照,因此并不适用于这个场景。
因此在做这种多个连接并行逻辑备份的时候,我们需要更改我们当前连接的隔离级别。
postgres=# BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN
postgres=*# select pg_export_snapshot();
pg_export_snapshot
---------------------
00000003-000A77D8-1
(1 row)
2、指定快照版本开启事务
从 PostgreSQL 9.2 开始,也支持开启一个事务到一个指定的的快照版本。
例如另开一个连接,使用如下语句
[xmaster@mogdb-kernel-0005 ~]$ psql
psql (14.1)
Type "help" for help.
postgres=# BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN
postgres=*# SET TRANSACTION SNAPSHOT '00000003-000A77D8-1';
SET
所以对于手动做多个逻辑备份去备份同一时刻不同的表的时候,可以设置其使用同一个快照版本。
使用如上的方式,在做备份的时候可以开启一个只读事务,然后保存一个快照,接着打开多个连接,并且指定snapshotid,让其都使用这一个快照。这样他们所获取的数据源都是完全一致的。所以多个连接在使用copy等命令进行并行备份不同的对象的时候,其数据也都是同一时刻的。
二、pg_dump并行逻辑备份(directory 模式备份)
pg_dump工具的 -j, --jobs=NUM 选项可以使用并行功能。需要注意的是备份的并行粒度是以表为单位,且需要以 directory 模式备份数据,也就是备份数据到一个目录中,目录中每个表的数据都用一个或多个文件存放。所以,当你没有使用directory 模式备份数据的时候就会遇到如下的提示。
[xmaster@mogdb-kernel-0005 ~]$ pg_dump -d postgres -j 2 > 1.sql
pg_dump: error: parallel backup only supported by the directory format
正确的使用directory 模式备份数据并开启并行的方式是
[xmaster@mogdb-kernel-0005 ~]$ pg_dump -d postgres -F d -j 3 -f ./test_dump_parallel2
[xmaster@mogdb-kernel-0005 ~]$ cd test_dump_parallel
[xmaster@mogdb-kernel-0005 test_dump_parallel2]$ ls
2915.dat.gz 2917.dat.gz 2919.dat.gz 2921.dat.gz 2923.dat.gz 2925.dat.gz 2928.dat.gz test_dump_parallel2
2916.dat.gz 2918.dat.gz 2920.dat.gz 2922.dat.gz 2924.dat.gz 2927.dat.gz 2929.dat.gz toc.dat
需要注意的是,这种逻辑备份的方式仅限于directory 模式备份的数据,如果是用pg_dump备份成其他格式的,或者说pg_dump是9.3以下,甚至说使用的是基于PG的国产数据库,不支持pg_dump -j 并行选项的,可能还是采用第一种方式。
三、pg_restore并行恢复
pg_restore 也支持-j,–jobs=NUM 并行恢复选项。
[xmaster@mogdb-kernel-0005 ~]$ psql -c "create database pg2;"
CREATE DATABASE
[xmaster@mogdb-kernel-0005 ~]$ pg_restore -d pg2 test_dump_parallel -j 4