PostgreSQL恢复备份WAL(Write-Ahead Logging)主从

参考

http://www.postgres.cn/docs/11/app-pg-dumpall.html

http://www.postgres.cn/docs/11/continuous-archiving.html

http://www.postgres.cn/docs/11/recovery-target-settings.html

http://www.postgres.cn/docs/11/runtime-config-wal.html

http://m.blog.chinaunix.net/uid-20665047-id-5817656.html

http://m.blog.chinaunix.net/uid-20665047-id-5817656.html

http://www.postgres.cn/docs/11/continuous-archiving.html#BACKUP-ARCHIVING-WAL

https://blog.csdn.net/yaoqiancuo3276/article/details/80826073

http://www.postgres.cn/docs/11/runtime-config-replication.html

http://www.postgres.cn/docs/11/warm-standby.html#STREAMING-REPLICATION

https://lihaoquan.me/2018/9/29/postgresql-master-slave-ha.html

全量备份

我们要做实时恢复,就需要对数据库做增量备份,也就是记录每次数据库的操作。恢复的时候,就按照记录,一条条的把数据还原到正确的地方。但是不管怎么样,都需要有一个基准,也就是从一个初始状态开始,按照操作记录,一条条的恢复。

pg_basebackup

pg_basebackup的作用相当于是把数据库目录下的相关数据文件拷贝到一个地方。

只能用这个做全量备份或是自己拷贝所有的数据库文件,不可以使用pg_dump、pg_dumpall或者navicat的备份工具备份。因为pg_dump等只是把数据库的表备份出来。postgresql的还原需要数据库目录中的一些信息。这也是与mysql不一样的地方。

mysql是在当前数据的基础上,一条条的执行binlog中的命令。而postgresql是在数据库文件记录的当前状态下,向前同步到对应的状态。比如同步了第几条wal日志信息,还有哪些信息没同步,需要同步到第几个。如果仅仅是把数据库的表导出来,这个无法做还原,因为数据库当前状态一直是最新的状态,就算把数据改回原来的数据,对于数据库来说,只不过是更新了新的数据,并不认为是回退到了原来的某个时间点。

pg_basebackup -D /home/postgres/basebackup/

把数据全备份到指定目录

pg_dump

pg_dump dbname > dbback1

把数据库名字是dbname的数据备份到dbback1中,上面的语句并没有指定用户名和密码,是因为在postgres自己的用户下,默认配置是peer访问权限,也就是在自己用户下,不需要输入密码。

psql db_payserver < dbback1

把原来备份的数据还原。

db_dumpall

db_dumpall备份的数据更多。这个是把整个数据库备份。每个单独的数据库调用的是db_dump。但是它还额外备份了一些其他信息,其中包括

所有数据库公用的全局对象(pg_dump不保存这些对象),数据库角色和表空间都会被转储。包括适数据库用户和组、表空间以及适合所有数据库的访问权限等属性。

pg_dumpall需要多次连接到PostgreSQL服务器(每个数据库一次)。如果你使用口令认证,可能每次都会要求口令。这种情况下使用一个~/.pgpass会比较方便。

pg_dumpall > dball
psql -f dball

打开归档

与mysql的binlog类似,postgresql也会保留对数据库的操作日志,这也是时间点恢复的基础。同样需要我们配置相关参数打开。

修改配置

vim /etc/postgresql/11/main/postgresql.conf
wal_level = logical                     # minimal, replica, or logical
                                        # (change requires restart)
archive_mode = on               # enables archiving; off, on, or always
                                # (change requires restart)
archive_command = 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'           # command to use to archive a logfile segment
                                # placeholders: %p = path of file to archive
                                #               %f = file name only
                                # e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'
# e.g. 'copy "%p" d:\pg_xlog_archive\%f'

配置解释

wal_level-设置wal log需要记录哪些信息,minimal记录的信息不全,不能恢复数据。所以信息需要是replica或是更高的logical。这个等级就是记录的信息越来越多。

archive_mode-是否打开归档

archive_command-这个是当postgresql完成一个归档的时候,运行的命令。postgresql与mysql一样会记录每一次数据库操作,放到一个文件中。这个文件是有大小限制的,默认16m的时候就会换一个文档。当发生这个操作的时候,就会运行archive_command指定的命令。我们可以把当前的文档拷贝到一个地方备份起来。test的目的是不要覆盖已有的文件

wal_level是设置wal日志的模式,postgresql不管有没有设置,都会有wal日志。

postgresql产生wal日志后,会不断的删除原来的wal文档,为了可以恢复到以前更老的时间点,需要每次postgresql完成一个wal日志文件创建下一个文件的时候,把当前的文件拷贝到一个地方保存起来。归档的作用就是postgresql给我们提供的一个借口,可以自动的完成这个操作。

注意事项

windows下创建的目录,用来拷贝保存wal日志。权限需要增加network service用户组,不然会报错没有权限,无法拷贝数据。

重启服务或是系统

//windows
在Computer Management->Services选择postgres对应的服务项,右键,选择重启

//Debian
service postgresql restart

我们可以调用pg_switch_wal命令来刷新强制产生一次归档,看看数据是否拷贝到我们命令设置的地方。

数据还原测试

通过pg_basebackup全量本分数据库

这就相当于做了一个还原点,从现在这个点往后的数据都可以还原

确定打开了wal日志,并设定为replica或logical

确定打开了归档

修改数据

第一条数据改为111

第二条数据改为222

第三条数据改为333

查看当前wal日志

SELECT pg_walfile_name(pg_current_wal_lsn())

查看当前wal详细信息

/usr/lib/postgresql/11/bin/pg_controldata /var/lib/postgresql/11/main

手动归档当前wal日志

select pg_switch_wal();

手动把当前的wal刷新一下,切换到另一个新的日志。这样就可以分析当前的日志了。因为分析正在使用的wal日志有可能会报错。

运行这个命令或是数据库在重启(也就是关闭的时候)或是在系统重启(也就是数据库关闭的时候),都会切换日志,运行归档命令。

这个也可以不做,因为恢复数据的时候需要停止数据库,这是也会归档wal日志。

停止数据库

//Windows
在Computer Management->Services中选择postgresql对应的服务,右键选择stop

//Debian
service postgresql stop

把数据库的data目录拷贝到一个地方,防止恢复失败的时候导致更多数据丢失

C:Program FilesPostgreSQL11data
/var/lib/postgresql/11/main

上面是windows和linux下默认安装的data目录

清空原来的data目录下的数据

把上面pg_basebackup备份的数据拷贝到data目录

就相当于从备份那个点开始还原

分析日志

pg_waldump是用来分析wal日志的命令

pg_waldump 000000040000000000000010

这个命令就是导出日志的详细信息。这个命令有可能不在系统的环境中,直接执行会报找不到命令的错误,可以通过find找到对应的位置。

postgresql的wal日志有一个很大的问题,就是不知道执行的是什么sql语句。这个与mysql的binlog比起来就麻烦了很多。虽然有一些方法可以导出来,但是太麻烦了。希望postgresql以后可以提供直接在日志中显示sql语句的功能。

上面就是wal日志的详细信息,我们可以看到COMMIT信息,还有对应的日期。COMMIT信息上面描述了这次操作的类型,比如HOT_UPDATE,就是运行了update命令,更新了数据。

我们看到中间有running xid 1205; online等信息,xid 1205就是这次运行的事务id。也就是我们修改数据库,默认数据库也会开启事务,与我们自己写的事务一样,为了保证这次修改要么成功,要么没修改,不存在中间状态。

我们还原的时候可以根据这个事务id还原,就可以保证精确度。

上面修改了三次,我们看到这里有三个事务id,1205、1206、1207。所以如果还原到第二条修改,那就是1206.

拷贝wal日志到data目录下的pg_wal

拷贝recovery.conf.sample到data目录下,并且修改名字为recovery.conf

这里面有注释,可以根据注释修改,我这里只打开了两个

restore_command = ''

recovery_target_xid = '1206'

第一个是必须要开的,就是把原来的归档,wal日志,拷贝到pg_wal目录,如果提前自己拷贝进来,直接是空就好了。

第二个是按照xid的模式还原到1206个xid

启动数据库

我们看到数据还原到第二条修改,第三条修改还是原来的值

//Windows
在Computer Management->Services选择postgresql服务,右键,选择start

//Debian
service postgresql start

主从异步流复制

注意事项

  • 通过pg_basebackup备份过来的文件权限太多,需要设置成只能postgres自己才能访问操作,过多的权限会导致数据库无法启动
  • 从widows备份过来的文件和linux下的编码格式不匹配,无法正常启动,会报如下错误

psql: FATAL:  database locale is incompatible with operating system
DETAIL:  The database was initialized with LC_COLLATE "Chinese (Simplified)_People's Republic of China.936",  which is not recognized by setlocale().
HINT:  Recreate the database with another locale or install the missing locale.

  • 如果不使用主服务器的备份,则无法启动主从

 最终测试下来失败,如果有知道如何主从复制,主服务器是windows,从服务器是linux,请告知。

原文地址:https://www.cnblogs.com/studywithallofyou/p/12403160.html