最佳实践

 

找回误操作丢失的数据

更新时间 2023-09-06

PolonDB 支持找回 updatedeletedrop columnrollback 误操作造成丢失的数据。

说明

PolonDB 默认可找回最近10000个事务内的数据,可以通过配置参数修改可找回数据量。

找回 update 、delete 、rollback 操作的丢失数据

以找回 delete 的数据为示例,updaterollback 的数据找回方式一致。

  1. 准备测试数据。

    test=# truncate qc, recovery_qc;
    TRUNCATE TABLE
    
    test=# insert into qc(id) values(1), (2), (3), (4);
    INSERT 0 4
    
    test=# select * from qc;
     id | id1 
     ----+-----
      1 |    
      3 |    
      4 |    
      2 |    
    (4 rows)
    
    test=# delete from qc;
    DELETE 4
    
    test=# insert into qc values(5);
    INSERT 0 1
    
    test=# select * from qc;
     id | id1 
     ----+-----
      5 |    
    (1 row)
    
    test=# select * from recovery_qc;
     id | id1 
     ----+-----
    (0 rows)
    
  2. 开始恢复操作,需要将表的结构 id int, id1 int 填写到 pg_recoverydata

    -- recovery_qc 表中只会存储。
    test=# SELECT  run_command_on_colocated_placements
    (
      'recovery_qc',
      'qc',
      $cmd$
        insert into %s select * from pg_recoverydata('%s') as t(id int, id1 int)
      $cmd$
     )
     ;
    
  3. qc 表的数据已经被 delete 操作删除掉了,新插入的 5 依然存在。

     test=# select * from qc;
       id | id1 
       ----+-----
       5 |    
       (1 row)
    
  4. 通过 recovery_qc 表恢复 qc 表已删除的数据。

  5. qc 表的已有数据(例如表 5 )还原到recovery_qc 中。

    $ pg_recoverydata('%s', recoveryrow => false)
    
  6. pg_recoverydata('%s', recoveryrow => false) as t(id int, id1 int,recoveryrow bool ),会增加一个 recoveryrow 列用于标识已恢复数据,同样recover_qc 表也会增加 recoveryrow bool 类型的结构。

    test=# select * from recovery_qc;
     id | id1 
     ----+-----
     1 |    
     4 |    
     3 |    
     2 |    
    (4 rows)
    

找回 drop column 操作的丢失数据

  1. 清空测试数据

    test=# truncate table qc, recovery_qc;
    TRUNCATE TABLE
    test=# insert into qc(id, id1) values(1,11), (2,22), (3,33), (4,44);
    INSERT 0 4
    test=# alter table qc drop column id1;
    ALTER TABLE
    
  2. 在 drop column 后插入一个 5 的数据

    test=# insert into qc values('5');
    INSERT 0 1
    test=# select * from qc;
    id 
    ----
       1
       5
       4
       3
       2
    (5 rows)
    
  3. 恢复 id1 列的数据,recovery_qc 中应存在 id1 的列。

    test=# select * from recovery_qc;
      id | id1 
      ----+-----
      (0 rows)
    
  4. 开始恢复数据,通过系统表可知 attnum 为 2 的列被删除。

    test=# select attnum from pg_attribute, pg_class where attrelid = pg_class.oid and pg_class.relname='qc' and attname ~ 'dropped';
    attnum 
    --------
         2
    (1 row)
    
  5. 开始恢复数据, pg_recoverydata后的数据 id int, dropped_attnum_2 int 中,dropped_attnum_2 代表恢复attnum是2的数据。

     test=# SELECT run_command_on_colocated_placements(
       'recovery_qc',
       'qc',
     $cmd$
        insert into %s select * from pg_recoverydata('%s') as t(id int, dropped_attnum_2 int)
     $cmd$
     );
    
  6. 查看恢复后的数据。

    test=# select * from qc;
       id 
      ----
        1
        5
        4
        3
        2
      (5 rows)
    
  7. 恢复列的时候会将原表的所有数据都向恢复表中存储一份,例如 5 的数据。

    test=# select * from recovery_qc;
     id | id1 
     ----+-----
       1 |  11
       5 |    
       4 |  44
       3 |  33
       2 |  22
     (5 rows)
    

参考:准备数据

  1. 创建测试表

    test=# create table qc(id int, id1 int);
    CREATE TABLE
     test=# select create_distributed_table('qc', 'id');
     create_distributed_table 
     --------------------------
    
     (1 row)
    
  2. 创建误操作数据找回表,找回的数据将存储到该表中,该表不需要创建主键外键等,只需要最基础的表结构保持一致。

    test=# create table recovery_qc as select *  from qc with no data;
    CREATE TABLE AS
     test=# select create_distributed_table('recovery_qc', 'id');
     create_distributed_table 
    --------------------------
    
     (1 row)
    
  3. 确认两个表是共址表 colocationid 的数值一致。

     test=# select colocationid from pg_dist_partition where logicalrelid='qc'::regclass or logicalrelid='recovery_qc'::regclass;
      colocationid 
      --------------
               1
               1
     (2 rows)
    
这篇文档解决了您的问题吗?
0
0