达梦数据库の闪回技术

1.8 达梦の闪回技术

1.8.1 概述

闪回功能依赖于ROLL回滚段的管理,回滚段中存储着事务过程中涉及增删改的历史前镜像(旧值)。
闪回技术可以在一定程度上满足UNDO_RETENTION参数(事务提交后回滚页保持时间,单位秒,取值0~86400)条件情况下恢复用户误操作的导致的数据丢失。
闪回技术是为了用户可以迅速处理用户误操作引起的数据逻辑损坏的情况而产生的。
达梦数据库默认情况下,闪回功能是关闭的。如果要开启闪回功能,将参数ENABLE_FLASHBACK设置值为1打开,并配合参数UNDO_RETENTION指定事务中操作过的回滚段保留时间长度,即此闪回保留时间决定了闪回数据的有效时间长度。
开启闪回功能后,达梦数据库会在内存中记录下每个事务的起始时间和提交时间。通过用户指定的时刻或查询到该时刻的事务号,结合当前记录和回滚段中的 UNDO 记录,就可以还原出特定事务号的记录(指定时刻的数据记录状态)。

达梦8数据库目前只支持闪回查询,闪回版本查询,闪回事务查询功能。

闪回技术的优势:

  1. 自我维护过程中的修复:当一些重要的记录被意外删除,用户可以向后移动到一个时间点,查看丢失的行并把它们重新插入现在的表内恢复。
  2. 用于分析数据变化:可以对同一张表的不同闪回时刻进行链接查询,以此查看变化的数据。

闪回技术的限制:

  1. 闪回查询功能完全依赖于回滚段管理,对于DROP等误操作不能恢复。
  2. 闪回查询只支持普通表(包括加密表与压缩表)、临时表和堆表,不支持水平分区表、列存储表、外部表与视图。

1.8.2 打开闪回功能

SQL> select * from v$parameter where name in ('ENABLE_FLASHBACK','UNDO_RETENTION');

行号     ID          NAME             TYPE VALUE     SYS_VALUE FILE_VALUE
---------- ----------- ---------------- ---- --------- --------- ----------
           DESCRIPTION                                                                             
           ----------------------------------------------------------------------------------------
1          423         ENABLE_FLASHBACK SYS  0         0         0
           Whether to enable flashback function

2          424         UNDO_RETENTION   SYS  90.000000 90.000000 90.000000
           Maximum retention time in seconds for undo pages since relative transaction is committed          

ENABLE_FLASHBACK和 UNDO_RETENTION两个参数都属于系统级参数,我们可以动态修改它们。

打开闪回功能如下步骤:

方法一:  alter system set 'ENABLE_FLASHBACK'=1 deferred both;  //对内存和ini参数文件都生效,并且是全局的。继承Oracle语法。
方法二:  sp_set_para_value(1,'ENABLE_FLASHBACK', 1); 
方法三:  sf_set_system_para_value('ENABLE_FLASHBACK',1,0,1); //强推,不用死心眼管参数类型(整型、浮点型、字符型)

/* 拓展:
sf_set_session_para_value('会话级参数名',整型值); //只能针对session会话级别参数,表示仅对当前会话生效。
等价于 alter session set '会话级参数名'=1 ;
*/

# 设置回滚段保留时间为15分钟
sp_set_para_double_value(1,'UNDO_RETENTION',900);

1.8.3 闪回查询

闪回查询只需要在FROM子句后添加一个WHEN的闪回查询的子句。它的意思:查询指定时刻前或某个事务号之前的数据记录状态。
语法格式:
在这里插入图片描述
示例1:在有效时间内闪回表以前的值,恢复误操作。

SQL> create table score (name varchar(20),num int);
操作已执行
已用时间: 6.198(毫秒). 执行号:311.
SQL> insert into score values('语文',90);
影响行数 1
已用时间: 1.228(毫秒). 执行号:312.
SQL> insert into score values(' 数学',100);
影响行数 1
已用时间: 1.016(毫秒). 执行号:313.
SQL> insert into score values('英语',99);
影响行数 1
已用时间: 1.067(毫秒). 执行号:314.
SQL>  insert into score values('体育',50);
影响行数 1
已用时间: 1.713(毫秒). 执行号:315.
SQL> commit;
操作已执行
已用时间: 1.298(毫秒). 执行号:316.
SQL> select * from score;
行号     NAME    NUM        
---------- ------- -----------
1          语文  90
2           数学 100
3          英语  99
4          体育  50

已用时间: 1.636(毫秒). 执行号:317.

SQL> select sysdate ;

行号     SYSDATE                                                                                             
---------- ----------------------------------------------------------------------------------------------------
1          2021-03-22 16:11:54

已用时间: 1.973(毫秒). 执行号:321.
SQL> set time on
16:12:03 SQL> select * from score;

行号     NAME    NUM        
---------- ------- -----------
1          语文  90
2           数学 100
3          英语  99
4          体育  50
已用时间: 0.854(毫秒). 执行号:322.

//更新体育的分数
16:12:17 SQL> update score set num=100 where name='体育';
影响行数 1

已用时间: 0.799(毫秒). 执行号:323.
16:12:39 SQL> commit;
操作已执行
已用时间: 4.336(毫秒). 执行号:324.
16:12:42 SQL> select * from score;
行号     NAME    NUM        
---------- ------- -----------
1          语文  90
2           数学 100
3          英语  99
4          体育  100

已用时间: 1.906(毫秒). 执行号:325.
16:12:47 SQL> 

//继续修改语文
16:12:47 SQL>  update score set num=100 where name='语文';
影响行数 1

已用时间: 2.269(毫秒). 执行号:326.
16:14:12 SQL> commit;
操作已执行
已用时间: 2.056(毫秒). 执行号:327.
16:14:16 SQL> select * from score;
行号     NAME    NUM        
---------- ------- -----------
1          语文  100
2           数学 100
3          英语  99
4          体育  100

已用时间: 0.968(毫秒). 执行号:328.


//此时闪回查询体育指定时刻未被修改的记录状态
16:17:49 SQL> select * from score when timestamp '2021-03-22 16:10:00';
行号     NAME    NUM        
---------- ------- -----------
1          语文  90
2           数学 100
3          英语  99
4          体育  50

已用时间: 4.780(毫秒). 执行号:332.

//将原表值复制到一张新表
6:18:30 SQL> create table score_bak as select * from score when timestamp '2021-03-22 16:10:00';    
操作已执行
已用时间: 10.313(毫秒). 执行号:333.
16:19:43 SQL> select * from score_bak;

行号     NAME    NUM        
---------- ------- -----------
1          语文  90
2           数学 100
3          英语  99
4          体育  50

已用时间: 5.184(毫秒). 执行号:334.
16:19:56 SQL> 

//收集原表中所有约束和索引等信息,在新表中复原(此实验省略该过程)
16:21:36 SQL> alter table score rename to score_new;
操作已执行
已用时间: 15.061(毫秒). 执行号:335.
16:21:56 SQL> alter table score_bak rename to score;
操作已执行
已用时间: 16.360(毫秒). 执行号:336.
16:22:09 SQL> select * from score;
行号     NAME    NUM        
---------- ------- -----------
1          语文  90
2           数学 100
3          英语  99
4          体育  50

已用时间: 4.496(毫秒). 执行号:337.
16:22:12 SQL> 

1.8.4 闪回版本查询

方便观察表中的数据记录在一段时间内的变化过程(每一次事务提交更新表中的记录称作一个版本)。
语法格式:
在这里插入图片描述
示例1:闪回版本查询指定时间段内的数据记录变化。

SQL> select sysdate from dual;

行号     SYSDATE                                                                                             
---------- --------------------------
1          2021-03-30 10:09:49
已用时间: 2.965(毫秒). 执行号:6.

SQL> select  * from score;

行号     NAME    NUM        
---------- ------- -----------
1          语文  90
2           数学 100
3          英语  99
4          体育  50
已用时间: 5.219(毫秒). 执行号:7.

SQL> update score set num=80 where name='体育';
影响行数 1
已用时间: 4.623(毫秒). 执行号:8.

SQL> commit;
操作已执行
已用时间: 6.157(毫秒). 执行号:9.

SQL>  update score set num=76  where name='体育';
影响行数 1
已用时间: 5.067(毫秒). 执行号:10.
SQL> commit;
操作已执行
已用时间: 6.644(毫秒). 执行号:11.
SQL> select  * from score;

行号     NAME    NUM        
---------- ------- -----------
1          语文  90
2           数学 100
3          英语  99
4          体育  76
已用时间: 1.498(毫秒). 执行号:12.


# 闪回版本查询
SQL> select versions_starttime,versions_endtime,name,num from score versions between timestamp '2021-03-30 10:09:49' and sysdate;
行号     VERSIONS_STARTTIME              VERSIONS_ENDTIME         NAME    NUM        
---------- --------------------------- ----------------------------------- ------- -----------
1          NULL                           NULL                     语文  90
2          NULL                           NULL                     数学 100
3          NULL                           NULL                     英语  99
4          2021-03-30 10:11:23            NULL                     体育  76
5          2021-03-30 10:10:43            2021-03-30 10:11:23      体育  80
6          NULL                           2021-03-30 10:10:43      体育  50

6 rows got

已用时间: 1.666(毫秒). 执行号:17.

//以上可以清晰看到体育成绩在不同的时间点内的变化过程:50->80->76


1.8.5 闪回事务查询

闪回事务查询以视图V$FLASHBACK_TRX_INFO查询在事务级对数据库所做的更改。
可以根据视图信息确定如何还原指定事务或指定时间段内的修改。
视图v$flashback_trx_info说明:
在这里插入图片描述

示例1:更新数表,观察记录的变化过程,定位到想要的事务号的时间点,并撤回记录的值。

SQL> select * from score;

行号     NAME    NUM        
---------- ------- -----------
1          语文  90
2           数学 100
3          英语  99
4          体育  76

已用时间: 3.609(毫秒). 执行号:304.
SQL> update score set num=99 where trim(name)='数学';
影响行数 1

已用时间: 5.438(毫秒). 执行号:305.
SQL> commit;
操作已执行
已用时间: 5.881(毫秒). 执行号:306.
SQL> update score set num=60 where trim(name)='数学';
影响行数 1

已用时间: 4.112(毫秒). 执行号:307.
SQL> commit;
操作已执行
已用时间: 5.817(毫秒). 执行号:308.
SQL>  update score set num=80 where trim(name)='数学';
影响行数 1

已用时间: 4.716(毫秒). 执行号:309.
SQL> commit;
操作已执行
已用时间: 4.960(毫秒). 执行号:310.
SQL> select * from v$flashback_trx_info;

行号     START_TRXID          START_TIMESTAMP                                                                                     
---------- -------------------- ----------------------------------------------------------------------------------------------------
           COMMIT_TRXID         COMMIT_TIMESTAMP                                                                                     LOGIN_USER
           -------------------- ---------------------------------------------------------------------------------------------------- ----------
           UNDO_CHANGE# OPERATION TABLE_NAME TABLE_OWNER ROW_ID               UNDO_SQL                                     
           ------------ --------- ---------- ----------- -------------------- ---------------------------------------------
1          38653                2021-03-30 10:43:42.000000
           38654                2021-03-30 10:44:17.301000                                                                           SYSDBA
           4            U         SCORE      SYSDBA      2                    UPDATE SYSDBA.SCORE SET NUM=100 WHERE ROWID=2


行号     START_TRXID          START_TIMESTAMP                                                                                     
---------- -------------------- ----------------------------------------------------------------------------------------------------
           COMMIT_TRXID         COMMIT_TIMESTAMP                                                                                     LOGIN_USER
           -------------------- ---------------------------------------------------------------------------------------------------- ----------
           UNDO_CHANGE# OPERATION TABLE_NAME TABLE_OWNER ROW_ID               UNDO_SQL                                     
           ------------ --------- ---------- ----------- -------------------- ---------------------------------------------
2          38653                2021-03-30 10:43:42.000000
           38654                2021-03-30 10:44:17.301000                                                                           SYSDBA
           6            C         NULL       NULL        NULL                 NULL


行号     START_TRXID          START_TIMESTAMP                                                                                     
---------- -------------------- ----------------------------------------------------------------------------------------------------
           COMMIT_TRXID         COMMIT_TIMESTAMP                                                                                     LOGIN_USER
           -------------------- ---------------------------------------------------------------------------------------------------- ----------
           UNDO_CHANGE# OPERATION TABLE_NAME TABLE_OWNER ROW_ID               UNDO_SQL                                     
           ------------ --------- ---------- ----------- -------------------- ---------------------------------------------
3          38654                2021-03-30 10:44:31.000000
           38655                2021-03-30 10:44:34.709000                                                                           SYSDBA
           3            U         SCORE      SYSDBA      2                    UPDATE SYSDBA.SCORE SET NUM=99 WHERE ROWID=2


行号     START_TRXID          START_TIMESTAMP                                                                                     
---------- -------------------- ----------------------------------------------------------------------------------------------------
           COMMIT_TRXID         COMMIT_TIMESTAMP                                                                                     LOGIN_USER
           -------------------- ---------------------------------------------------------------------------------------------------- ----------
           UNDO_CHANGE# OPERATION TABLE_NAME TABLE_OWNER ROW_ID               UNDO_SQL                                     
           ------------ --------- ---------- ----------- -------------------- ---------------------------------------------
4          38654                2021-03-30 10:44:31.000000
           38655                2021-03-30 10:44:34.709000                                                                           SYSDBA
           5            C         NULL       NULL        NULL                 NULL


行号     START_TRXID          START_TIMESTAMP                                                                                     
---------- -------------------- ----------------------------------------------------------------------------------------------------
           COMMIT_TRXID         COMMIT_TIMESTAMP                                                                                     LOGIN_USER
           -------------------- ---------------------------------------------------------------------------------------------------- ----------
           UNDO_CHANGE# OPERATION TABLE_NAME TABLE_OWNER ROW_ID               UNDO_SQL                                     
           ------------ --------- ---------- ----------- -------------------- ---------------------------------------------
5          38655                2021-03-30 10:44:49.000000
           38656                2021-03-30 10:44:50.733000                                                                           SYSDBA
           3            U         SCORE      SYSDBA      2                    UPDATE SYSDBA.SCORE SET NUM=60 WHERE ROWID=2


行号     START_TRXID          START_TIMESTAMP                                                                                     
---------- -------------------- ----------------------------------------------------------------------------------------------------
           COMMIT_TRXID         COMMIT_TIMESTAMP                                                                                     LOGIN_USER
           -------------------- ---------------------------------------------------------------------------------------------------- ----------
           UNDO_CHANGE# OPERATION TABLE_NAME TABLE_OWNER ROW_ID               UNDO_SQL                                     
           ------------ --------- ---------- ----------- -------------------- ---------------------------------------------
6          38655                2021-03-30 10:44:49.000000
           38656                2021-03-30 10:44:50.733000                                                                           SYSDBA
           5            C         NULL       NULL        NULL                 NULL


6 rows got

已用时间: 4.079(毫秒). 执行号:311.
SQL> 


//比如:撤回到事务38655的时候
//这里仅是闪回表查询
SQL> select * from score when trxid 38655;
行号     NAME    NUM        
---------- ------- -----------
1          语文  90
2           数学 60
3          英语  99
4          体育  76

已用时间: 6.260(毫秒). 执行号:312.

//以下利用undo_sql进行撤回
SQL> UPDATE SYSDBA.SCORE SET NUM=99 WHERE ROWID=2;      
影响行数 1

已用时间: 3.209(毫秒). 执行号:313.
SQL> commit;
操作已执行
已用时间: 3.949(毫秒). 执行号:314.
SQL> select * from score;

行号     NAME    NUM        
---------- ------- -----------
1          语文  90
2           数学 99
3          英语  99
4          体育  76

已用时间: 0.585(毫秒). 执行号:315.
SQL> 

事务版本变化过程视图:
在这里插入图片描述


1.8.6 个人总结

1.当不确定想要闪回到的时间点或事务号,可通过闪回版本查询定位到具体时间点或提交事务号。
2.为方便在原表上进行撤销某个事务的DML操作,可结合闪回版本查询和闪回事务查询视图undo_sql进行回撤语句。
3.关于闪回技术的应用,一定在undo_retention参数值的范围内有效,超过该时间长度,旧事务的值会被覆盖。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值