0%

PostgreSQL PIRT恢复

PostgreSQL的PIRT恢复

基于备份集的恢复比较简单,直接使用备份进行恢复,但是在实际环境中我们可能会遇到数据误删除需要指定恢复到某一时间点

实验步骤

总体步骤如下:

  • 基于数据库做基础备份
  • 插入新数据
  • 删除表中部分数据
  • 基于备份做指定时间点的恢复
  • 验证数据是否恢复

基础备份

  • 使用pg_basebackup
    1
    2
    3
    4
    5
    6
    pg_basebackup  -X s -P -F t -U postgres -D /backup/

    [postgres@pg39 backup]$ ls -ltr
    total 40104
    -rw-rw-r-- 1 postgres postgres 24284160 May 6 01:47 base.tar
    -rw------- 1 postgres postgres 16779264 May 6 01:47 pg_wal.tar
    备份完成后会看到生成两个tar文件,其中pg_wal是由于备份时添加了-X s参数的原因

插入新数据

  • 向dhytest表中插入新数据并记录时间
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    [postgres@pg39 backup]$ psql
    psql (10.3)
    Type "help" for help.

    postgres=# insert into dhytest values (10);
    INSERT 0 1
    postgres=# insert into dhytest values (20);
    INSERT 0 1
    postgres=# insert into dhytest values (30);
    INSERT 0 1
    postgres=# insert into dhytest values (40);
    INSERT 0 1
    postgres=# insert into dhytest values (50);
    INSERT 0 1
    postgres=# select now();
    now
    -------------------------------
    2018-05-06 01:51:52.664137+08

删除数据

  • 删除数据并记录时间点,用于指定时间点恢复时使用
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    postgres=# delete from dhytest where id = 40;
    DELETE 1
    postgres=# select now();
    now
    -------------------------------
    2018-05-06 01:52:31.409248+08
    (1 row)

    [postgres@pg39 backup]$ psql
    psql (10.3)
    Type "help" for help.

    //切换几个wal日志
    postgres=# select pg_switch_wal();
    pg_switch_wal
    ---------------
    0/18000730
    (1 row)

    postgres=# select pg_switch_wal();
    pg_switch_wal
    ---------------
    0/19000078
    (1 row)

基于备份做指定时间点的恢复

  • 解压备份文件
    1
    2
    3
    tar xvf base.tar
    mv pg_wal.tar pg_wal/
    tar xvf pg_wal.tar
  • 创建recovery.conf文件
    1
    2
    recovery_target_time = ' 2018-05-06 01:51:52.664137'
    restore_command = 'cp /pgdata/pg_wal/%f %p' //这里没有做wal的归档,所以直接指向了wal 的目录,如果设置了wal归档则执行归档目录即可

验证数据是否恢复

  • 启动数据库后我们查看数据全部恢复完成
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    [postgres@pg39 backup]$ pg_ctl start -D /backup/
    waiting for server to start....2018-05-06 02:01:35.282 CST [4404] LOG: listening on IPv4 address "0.0.0.0", port 5432
    2018-05-06 02:01:35.282 CST [4404] LOG: listening on IPv6 address "::", port 5432
    2018-05-06 02:01:35.285 CST [4404] LOG: listening on Unix socket "/tmp/.s.PGSQL.5432"
    2018-05-06 02:01:35.292 CST [4404] LOG: redirecting log output to logging collector process
    2018-05-06 02:01:35.292 CST [4404] HINT: Future log output will appear in directory "log".
    done
    server started
    [postgres@pg39 backup]$ psql
    psql (10.3)
    Type "help" for help.

    postgres=# select * from dhytest;
    id
    ----
    10
    20
    30
    40
    50
    (5 rows)

    恢复大致原理

    基于时间点恢复主要过程就是利用全备+WAL日志,将数据库推至一个指定的状态。在恢复时我们需要注意WAL日志是否完整,如果归档目录下WAL日志不能恢复到指定时间点需要拷贝最新的WAL日志到归档目录下,才能继续恢复。