为什么Flashback Log产生量要远少于Redo Log?

有同学提问关于闪回数据库日志为什么远少于redo log?   RVWR( Recovery Writer)每3s检查flashback generate buffer中的block before image的具体算法是如何的? 是否每一次block change都需要RVWR写出block before image 到flashback log?

 

为了实现闪回数据库,Oracle需要记录数据块的前景象before image到一种新的日志中,这种日志被命名为flashback database logs闪回日志。   闪回日志总是被循环复用,连续写出。

 

在一个实例中当一个数据块首次被修改时,前台进程会将该数据块的before image拷贝到位于shared pool中的flashback log buffer中,RVWR进程定期地将flashback log buffer中的记录刷新到磁盘上。 在DBWR进程可以写出相关脏块到磁盘之前,DBWR必须保证该buffer header相关FBA(Flashback Byte Address)的flashback log buffer已经写出到闪回日志。 这被称作 先写闪回日志 机制。

 

在常规的闪回日志维护操作中 , RVWR进程定期地插入闪回标记(flashback markers)到flashback database logs中。 闪回标记(flashback markers)的作用是在闪回数据库是告知Oracle如何flashback 到之前的某个时间点。  在闪回操作执行过程中, Oracle 会用闪回标记(flashback markers)中的信息来决定多大范围的flashback database log需要用来还原数据块景象block image; 之后Oracle 会利用前向恢复(forward recovery)的方式把数据库穿越到用户指定闪回的SCN或者时间点。

 

flashback markers for example:

 

 **** Record at fba: (lno 1 thr 1 seq 1 bno 4 bof 8184) ****
    RECORD HEADER:
      Type: 3 (Skip)  Size: 8132
    RECORD DATA (Skip):
 **** Record at fba: (lno 1 thr 1 seq 1 bno 4 bof 52) ****
    RECORD HEADER:
      Type: 7 (Begin Crash Recovery Record)  Size: 36
    RECORD DATA (Begin Crash Recovery Record):
      Previous logical record fba: (lno 1 thr 1 seq 1 bno 3 bof 316)
      Record scn: 0x0000.00000000 [0.0]
 **** Record at fba: (lno 1 thr 1 seq 1 bno 3 bof 8184) ****
    RECORD HEADER:
      Type: 3 (Skip)  Size: 7868
    RECORD DATA (Skip):
 **** Record at fba: (lno 1 thr 1 seq 1 bno 3 bof 316) ****
    RECORD HEADER:
      Type: 2 (Marker)  Size: 300
    RECORD DATA (Marker):
      Previous logical record fba: (lno 0 thr 0 seq 0 bno 0 bof 0)
      Record scn: 0x0000.00000000 [0.0]
      Marker scn: 0x0000.0060e024 [0.6348836] 06/13/2012 15:56:35
      Flag 0x0
      Flashback threads: 1, Enabled redo threads 1
      Recovery Start Checkpoint:
        scn: 0x0000.0060e024 [0.6348836]  06/13/2012 15:56:12
        thread:1 rba:(0x80.180.10)
      Flashback thread Markers:
         Thread:1 status:0 fba: (lno 1 thr 1 seq 1 bno 2 bof 8184)
      Redo Thread Checkpoint Info:
         Thread:1 rba:(0x80.180.10)
 **** Record at fba: (lno 1 thr 1 seq 1 bno 2 bof 8184) ****
    RECORD HEADER:
      Type: 3 (Skip)  Size: 8168
    RECORD DATA (Skip):
  End-Of-Thread reached

 

 

 

需要注意的是不是数据库中的每一次block change 都会触发before image被记录到闪回日志flashback log中。 如果每一次block change都记录flashback log record 那么闪回日志会要比 redo log大的多!因为毕竟flashback log 是记录整个块的before image 而 redo log只记录 change vector 。  Oracle对于闪回日志使用一种即能够保证可以讲数据库一致地穿越到某个历史时间点的状态,又不过分造成I/O损耗和生成大量闪回日志的方法:

对于hot block热块,Oracle仅在一段时间内记录一次block image到闪回日志; Oracle 内部通过闪回分界线(flashback barriers)实现这一点。在常规数据库状态下,flashback barriers被周期性的触发(一般为15分钟),对应每一个闪回分界线(flashback barriers)会有一个(flashback markers)被写出到闪回日志。

 

对于热块, 即那些频繁被change的数据库块, 闪回日志算法要求限制其写出到闪回日志的版本数。举例来说, 在15分钟内对于某个数据块仅限其写出一个版本到flashback log。虽然更多版本的before image有助于减少闪回数据库的时间,但是最小化有效闪回日志的容量是更重要的因素,比起实际闪回所用的时间来说。 为了实现这个目标,闪回日志算法引入了闪回分界线(flashback barriers), flashback barriers会被定期地触发,典型的例如15分钟一次。 对应每一个flashback barriers会有一个闪回标记(flashback markers)被插入到闪回日志中。常规情况下,对于每一个被修改的数据块在一个闪回区域(被分界线barriers分割的区域)内仅记录一个block image ,无论这个数据块在这段区域内被修改了多少次、被写出过多少次到磁盘上。

这就是为什么闪回日志flashback log要原少于redo log的产生量!

 

好了说了,这么多如果不亲身体验一下就太虚了, 我们来做以下的测试。

 

 

SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
CORE    11.2.0.3.0      Production
TNS for Linux: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production
SQL> select * from global_name;
GLOBAL_NAME
--------------------------------------------------------------------------------
www.askmaclean.com
SQL> create table flash_maclean (t1 varchar2(200)) tablespace users;
Table created.
SQL> insert into flash_maclean values('MACLEAN LOVE HANNA');
1 row created.
SQL> commit;
Commit complete.
SQL> startup force;
ORACLE instance started.
Total System Global Area  939495424 bytes
Fixed Size                  2233960 bytes
Variable Size             713034136 bytes
Database Buffers          218103808 bytes
Redo Buffers                6123520 bytes
Database mounted.
Database opened.
SQL> update flash_maclean set t1='HANNA LOVE MACLEAN';
1 row updated.
commit;
Commit complete.
SQL> alter system checkpoint;
System altered.
SQL> select dbms_rowid.rowid_block_number(rowid),dbms_rowid.rowid_relative_fno(rowid) from flash_maclean;
DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID)
------------------------------------ ------------------------------------
140431                                    4
datafile 4 block 140431 对应RDBA rdba: 0x0102248f (4/140431)
SQL> ! ps -ef|grep rvwr|grep -v grep
oracle   26695     1  0 15:56 ?        00:00:00 ora_rvwr_G11R23
SQL> oradebug setospid  26695
Oracle pid: 20, Unix process pid: 26695, image: oracle@nas.oracle.com (RVWR)
SQL> ORADEBUG DUMP FBTAIL 1;
Statement processed.
To dump the last 2000 flashback records , 以上ORADEBUG DUMP FBTAIL 1命令可以转出最近2000条的闪回记录
SQL> oradebug tracefile_name
/s01/orabase/diag/rdbms/g11r23/G11R23/trace/G11R23_rvwr_26695.trc
在 TRACE文件中可以找到对应block的 before image 
**** Record at fba: (lno 1 thr 1 seq 1 bno 55 bof 2564) ****
RECORD HEADER:
Type: 1 (Block Image)  Size: 28
RECORD DATA (Block Image):
file#: 4 rdba: 0x0102248f
Next scn: 0x0000.00000000 [0.0]
Flag: 0x0
Block Size: 8192
BLOCK IMAGE:
buffer rdba: 0x0102248f
scn: 0x0000.00609044 seq: 0x01 flg: 0x06 tail: 0x90440601
frmt: 0x02 chkval: 0xc626 type: 0x06=trans data
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x00002B1D94183C00 to 0x00002B1D94185C00
2B1D94183C00 0000A206 0102248F 00609044 06010000  [.....$..D.`.....]
2B1D94183C10 0000C626 00000001 00014AD4 0060903A  [&........J..:.`.]
2B1D94183C20 00000000 00320002 01022488 00090006  [......2..$......]
2B1D94183C30 00000CC8 00C00340 000D0542 00008000  [....@...B.......]
2B1D94183C40 006040BC 000F000A 00000920 00C002E4  [.@`..... .......]
2B1D94183C50 0017048F 00002001 00609044 00000000  [..... ..D.`.....]
2B1D94183C60 00000000 00010100 0014FFFF 1F6E1F77  [............w.n.]
2B1D94183C70 00001F6E 1F770001 00000000 00000000  [n.....w.........]
2B1D94183C80 00000000 00000000 00000000 00000000  [................]
Repeat 500 times
2B1D94185BD0 00000000 00000000 2C000000 4D120102  [...........,...M]
2B1D94185BE0 454C4341 4C204E41 2045564F 4E4E4148  [ACLEAN LOVE HANN]
2B1D94185BF0 01002C41 43414D07 4E41454C 90440601  [A,...MACLEAN..D.]
Block header dump:  0x0102248f
Object id on Block? Y
seg/obj: 0x14ad4  csc: 0x00.60903a  itc: 2  flg: E  typ: 1 - DATA
brn: 0  bdba: 0x1022488 ver: 0x01 opc: 0
inc: 0  exflg: 0
Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0006.009.00000cc8  0x00c00340.0542.0d  C---    0  scn 0x0000.006040bc
0x02   0x000a.00f.00000920  0x00c002e4.048f.17  --U-    1  fsc 0x0000.00609044
bdba: 0x0102248f
data_block_dump,data header at 0x2b1d94183c64
===============
tsiz: 0x1f98
hsiz: 0x14
pbl: 0x2b1d94183c64
76543210
flag=--------
ntab=1
nrow=1
frre=-1
fsbo=0x14
fseo=0x1f77
avsp=0x1f6e
tosp=0x1f6e
0xe:pti[0]      nrow=1  offs=0
0x12:pri[0]     offs=0x1f77
block_row_dump:
tab 0, row 0, @0x1f77
tl: 22 fb: --H-FL-- lb: 0x2  cc: 1
col  0: [18]  4d 41 43 4c 45 41 4e 20 4c 4f 56 45 20 48 41 4e 4e 41
end_of_block_dump
SQL> select dump('MACLEAN LOVE HANNA',16) from dual;
DUMP('MACLEANLOVEHANNA',16)
--------------------------------------------------------------------
Typ=96 Len=18: 4d,41,43,4c,45,41,4e,20,4c,4f,56,45,20,48,41,4e,4e,41

 

 

若我们在短期内在多个事务内反复更新同样的数据块,其在flashback log中的before image版本也不会大幅增长

 

create table flash_maclean1 (t1 int) tablespace users;
SQL>      select vs.name, ms.value
2       from v$mystat ms, v$sysstat vs
3       where vs.statistic# = ms.statistic#
4         and vs.name in ('redo size','db block changes');
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
db block changes                                                          0
redo size                                                                 0
SQL>      select name,value from v$sysstat where name like 'flashback log%';
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
flashback log writes                                                     49
flashback log write bytes                                           9306112
SQL>      begin
2       for i in 1..5000 loop
3       update flash_maclean1 set t1=t1+1;
4       commit;
5       end loop;
6       end;
7       /
PL/SQL procedure successfully completed.
SQL>     select vs.name, ms.value
2       from v$mystat ms, v$sysstat vs
3       where vs.statistic# = ms.statistic#
4         and vs.name in ('redo size','db block changes');
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
db block changes                                                      20006
redo size                                                           3071288
SQL>      select name,value from v$sysstat where name like 'flashback log%';
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
flashback log writes                                                     52
flashback log write bytes                                          10338304

 

 

在以上的测试中可以看到 对于hot block,在产生20006 个block changes的情况下 产生了 3000k 的redo log 和 大约1000k的 flashback log 。

Oracle数据库使用闪回和 LogMiner

闪回和 LogMiner 的新增功能和增强功能

Oracle Database 11g 中易于使用:

  • 闪回数据归档功能可自动跟踪和安全存储在某个记录的生存期(而非应用程序逻辑)内对该记录进行的所有事务处理更改。
  • 闪回事务处理和相关事务处理或作业回退提高了处理还原逻辑错误的灵活性
  • 采用与闪回事务处理集成在一起的基于浏览器的 Enterprise Manager (EM) LogMiner 界面

组织经常需要跟踪和存储在某个记录的生存期内对该记录进行的所有事务处理更改。现在不必再将此智能功能内置到应用程序中。闪回数据归档功能以安全的方式满足了长期保留需求(超过还原保留期)。

使用 Oracle Database 11g 您可以闪回所选事务处理和所有相关事务处理。此恢复操作使用还原数据创建并执行相应的校正事务处理,使受影响的数据还原到其原始状态。闪回事务处理或“作业回退”只使用一个命令即可在保持数据库联机的同时,轻松并快速地回退某一特定事务处理或一组事务处理及其相关事务处理,从而提高了逻辑恢复期间的可用性。

在早期版本中,管理员需要为 LogMiner 安装并使用单独的 Java 控制台。使用 Enterprise Manager 界面,管理员可以使用一个与闪回事务处理集成在一起的界面,因此少了一个安装任务。

这些增强功能提供了基于任务的直观方法(通过 EM 图形化用户界面),或者降低了应用程序的复杂性,因此增强了易用性并节省了时间(https://www.askmaclean.com/archives/oracle数据库使用闪回和-logminer.html ‎)。

 

闪回数据归档概览:Oracle Total Recall

以非常安全、高效且透明的方式跟踪对所有 Oracle 数据的
历史记录更改

  • 安全

无法修改历史记录数据

根据规范进行保留

基于保留策略自动清除

  • 高效

采用特殊的内核优化,最小化捕获历史记录数据的性能开销

以压缩形式存储在表空间中,最小化存储要求

对应用程序是完全透明的

易于设置

 

闪回数据归档是一个新的数据库对象,是存储历史记录信息的逻辑容器。它存储在一个或多个表空间中,跟踪一个或多个表的历史记录。您需要为每个闪回数据归档指定保留持续时间。可在闪回数据归档中按保留要求分组历史记录表数据。多个表可以共享相同的保留和清除策略。

使用“Oracle Total Recall”选项,Oracle Database 11g 得到了显著增强,它可以跟踪历史记录,同时保持性能受到的影响最小,并且可以使用压缩形式存储历史记录数据。此效率是使用您自己的触发器所无法达到的,这些触发器还需要花费时间和精力进行设置和维护。

系统不允许执行使历史记录失效或阻止历史记录捕获的操作,例如删除或截断表(https://www.askmaclean.com/archives/oracle数据库使用闪回和-logminer.html ‎)。

 

闪回数据归档比较 

闪回数据归档 闪回数据库
主要优点 访问任何时间点的数据而不会更改当前数据 使整个数据库实际回退到某个
时间点
操作 联机操作,启用跟踪,使用最少的资源 脱机操作,需要预配置和资源
粒度 数据库
访问时间点 每个表任意数目 每个数据库一个

 

闪回数据归档技术与闪回数据库的比较:

  • 使用闪回数据归档可以访问任意时间点的数据,而不会实际更改当前数据。这与闪回数据库相反,闪回数据库会使数据库实际返回到某个时间点。
  • 必须启用跟踪才能访问历史记录,而闪回数据库需要预配置。闪回数据库属于脱机操作,需要资源。闪回数据归档属于联机操作(历史记录访问与当前访问无缝共存)。由于使用了新的后台进程,所以它对现有的进程几乎没有影响。
  • 闪回数据归档在表级别启用,而闪回数据库只能在数据库级别运行。
  • 使用闪回数据归档,可以返回到一个表的不同行或多个不同表的多个不同时间点,而使用闪回数据库则只能返回到特定调用的一个时间点。

 

闪回数据归档:概览

 

闪回数据归档是一种历史记录数据存储。Oracle Database 11g 通过新的闪回数据归档后台进程 FBDA 自动跟踪和归档启用了闪回数据归档的表中的数据。使用此功能可满足超过还原保留期的长期保留要求。闪回数据归档可确保闪回查询能够获得对数据库对象版本的 SQL 级别访问权限,而不会出现快照太旧的错误。

闪回数据归档由一个或多个表空间(或其中的几部分)组成。您可以拥有多个闪回数据归档。每个闪回数据归档都具有特定的保留持续时间。您应根据保留持续时间的要求创建不同的闪回数据归档,例如,为必须保留一年的所有记录创建一个闪回数据归档,为必须保留两年的所有记录创建另一个闪回数据归档等。

FBDA 将异步收集原始数据并将其写入闪回数据归档。它并不包括原始索引,因为检索历史记录信息的模式与检索当前信息的模式可能大不相同。

注:您可能需要针对历史记录查询持续时间创建适合的索引。

 

闪回数据归档:体系结构

 

 

闪回数据归档后台进程 (FBDA) 随数据库启动。

  1. FBDA 首先对缓冲区高速缓存中的还原数据执行操作。
  2. 如果还原数据已不在缓冲区高速缓存中,FBDA 也可以从还原段读取所需值。
  3. FBDA 将合并启用了闪回归档的表中的修改行,并将其写入相应的历史记录表,这些表将组成闪回数据归档。

您可以通过查询 *_FLASHBACK_ARCHIVE_TABLES 视图查找历史记录表的内部分配名称。历史记录表是压缩的数据,并已在内部进行了分区。

数据库将在保留期到期后的第一天自动清除所有历史记录信息(删除数据,而不破坏闪回数据归档)。例如,如果保留期为 10 天,则会在每 10 天后的第一天删除最旧的信息,在归档中仅保留 10 天的信息。这是实现数字粉碎的一种方法。

 

准备数据库

要满足长期保留要求,请使用闪回数据归档。首先执行下列步骤:

  • 对于归档管理员:

为数据归档创建一个或多个表空间并授予对表空间的 QUOTA 权限。

授予创建和维护闪回归档所需的 FLASHBACK ARCHIVE ADMINISTER 系统权限。

  • 对于归档用户:

授予 FLASHBACK ARCHIVE 对象权限(用于对给定闪回归档中的特定表启用历史记录跟踪)。

授予查询特定对象所需的 FLASHBACK SELECT 权限。

 

要启用闪回数据归档,请务必执行下列任务:

为数据归档创建一个或多个表空间,并对“归档管理员”授予访问权限和适合的限额。

同时,为归档管理员授予 FLASHBACK ARCHIVE ADMINISTER 系统权限,允许其执行下列语句:

  • CREATE FLASHBACK ARCHIVE
  • ALTER FLASHBACK ARCHIVE
  • DROP FLASHBACK ARCHIVE

要允许特定用户使用特定闪回数据归档,请为归档用户授予对该闪回数据归档的 FLASHBACK ARCHIVE 对象权限。这样,归档用户可以使用特定闪回数据归档对表启用闪回归档。

以归档管理员身份执行以下示例:

GRANT FLASHBACK ARCHIVE ON FLA1 TO HR;

 

用户很有可能会使用其它闪回功能。要允许在查询期间访问特定对象,请授予对查询涉及的所有对象的 FLASHBACK 和 SELECT 权限。

如果用户需要访问 DBMS_FLASHBACK 程序包,则需要为他们授予对此程序包的 SELECT 权限。这样,用户就可以使用 DBMS_FLASHBACK.ENABLE 和 DBMS_FLASHBACK.DISABLE 过程来启用或禁用闪回数据归档。

 

准备数据库

 

 

  • 配置还原:

创建还原表空间(默认设置为:可自动扩展的表空间)

启用自动还原管理(11g 的默认设置)

了解还原的自动优化:

固定大小的表空间:可获得最佳保留期的自动优化

可自动扩展的还原表空间:可获得运行时间最长的查询的自动优化

建议对闪回使用以下设置:固定大小的还原表空间

 

Oracle Database 11g 使用下列默认数据库初始化参数:

  • UNDO_MANAGEMENT=’AUTO’
  • UNDO_TABLESPACE=’UNDOTBS1′
  • UNDO_RETENTION=900

换句话说,默认情况下启用自动还原管理。如果需要,请按《Oracle 数据库管理员指南》中的说明启用自动还原管理。

可自动扩展的还原表空间基于数据库安装而创建。

  • 对于固定大小的还原表空间,Oracle DB 会自动优化系统,以便为还原表空间提供可能的最佳还原保留期。
  • 对于可自动扩展的还原表空间(默认),Oracle DB 会保留还原数据,其保留时间至少满足运行时间最长的查询所需的保留期,以及 UNDO_RETENTION 参数指定的还原保留期阈值。

使用固定大小的还原表空间,自动优化还原保留期通常会产生较好的结果。如果由于此原因或其它原因而希望将还原表空间更改为固定大小,还原指导可帮助您确定要分配的正确固定大小。

 

如果不能确定空间要求或者无法访问还原指导,请执行以下步骤:

  1. 以可自动扩展的还原表空间开始。
  2. 在一个业务循环(例如,1 天或 2 天或更长时间)中观察它。
  3. 使用 V$UNDO_STAT 视图收集还原块信息,计算空间要求,并使用它们创建大小适合的固定还原表空间(《Oracle 数据库管理员指南》中提供了计算公式)。
  4. 查询 V$UNDOSTAT.TUNED_UNDORETENTION 以确定对于当前还原表空间还原数据的保留持续时间。设置 UNDO_RETENTION 参数并不能保证未到期的还原数据不会被覆盖。如果系统需要较多的空间,Oracle DB 可以用最新生成的还原数据覆盖未到期的还原数据。

-为还原表空间指定 RETENTION GUARANTEE 子句,以确保不会丢弃未到期的还原数据(https://www.askmaclean.com/archives/oracle数据库使用闪回和-logminer.html ‎)。

-为了满足超过还原保留期的长期保留要求,可创建闪回数据归档。

 

闪回数据归档:工作流

1.创建闪回数据归档。

2.指定默认闪回数据归档(可选)。

3.启用闪回数据归档。

4.查看闪回数据归档数据。

 

 

第一步是创建闪回数据归档。闪回数据归档由一个或多个表空间组成。您可以拥有多个闪回数据归档。

第二步是为系统指定默认的闪回数据归档,该步骤是可选的。闪回数据归档配置有保留时间。将在此保留时间内保留在闪回数据归档中归档的数据。

在第三步中,可以对表先启用闪回归档(然后再禁用它)。对表启用闪回归档时,系统不允许对该表执行某些 DDL 语句。默认情况下,不对任何表启用闪回归档。

在第四步中,当查询的数据超过了可能的还原保留期时,会以透明方式重新编写该查询以使用闪回数据归档中的历史记录表。

使用闪回数据归档

 

访问历史记录数据的基本工作流:

  1. 创建闪回数据归档:

 

CREATE FLASHBACK ARCHIVE fla1

  TABLESPACE tbs1 QUOTA 10G RETENTION 5 YEAR;

 

  1. FLA1 归档中的表启用历史记录跟踪:

 

ALTER TABLE inventory FLASHBACK ARCHIVE fla1;

  1. 查看历史记录数据:

SELECT product_number, product_name, count

  FROM inventory   AS OF TIMESTAMP TO_TIMESTAMP

  (‘2007-01-01 00:00:00’, ‘YYYY-MM-DD HH24:MI:SS’);

 

使用 CREATE FLASHBACK ARCHIVE 语句创建闪回数据归档。

  • 可以为系统指定默认的闪回数据归档(可选)。如果省略此选项,则以后仍可以将此闪回数据归档指定为默认选项。
  • 需要提供闪回数据归档的名称。
  • 需要提供闪回数据归档的第一个表空间的名称。
  • 可以确定表空间中闪回数据归档可以使用的最大空间量。默认设置是不受限制。如果第一个表空间中的空间限额不是无限制的,则必须指定该值,否则会引发 ORA-55621。
  • 需要提供保留时间(表的闪回数据归档数据的保留天数)。

创建并使用闪回数据归档的基本工作流只包含三个步骤:

  1. 归档管理员创建名为 fla1 的闪回数据归档,这最多占用 10 GB 的 tbs1 表空间,其中的数据会保留五年。
  2. 在第二步中,归档用户启用闪回数据归档。如果自动还原管理处于禁用状态,则在试图修改表时会出现错误 ORA-55614。
  3. 第三步使用 AS OF 查询显示所访问的历史记录数据。

 

配置默认闪回数据归档

使用默认闪回归档:

  1. 创建默认闪回数据归档:

 

CREATE FLASHBACK ARCHIVE DEFAULT fla2

  TABLESPACE tbs1 QUOTA 10G RETENTION 2 YEAR;

  1. 对表启用历史记录跟踪:

ALTER TABLE stock_data FLASHBACK ARCHIVE;

   注:因为使用了默认的闪回数据归档,所以不需要提供闪回数据归档名称。

  1. 禁用历史记录跟踪:

ALTER TABLE stock_data NO FLASHBACK ARCHIVE;

 

在 FLASHBACK ARCHIVE 子句中,可以指定将在其中存储表的历史记录数据的闪回数据归档。默认情况下,系统没有闪回数据归档。在前面的示例中,为系统指定了默认闪回数据归档。

可使用以下两种方式之一创建默认闪回归档:

  • 在 ALTER FLASHBACK ARCHIVE 语句的 SET DEFAULT 子句中,指定现有闪回数据归档的名称。
  • 创建闪回数据归档时,CREATE FLASHBACK ARCHIVE 语句中包含 DEFAULT。

可使用 ALTER TABLE 命令对表启用和禁用闪回归档。可通过指定闪回数据归档名称将内部归档表分配给特定闪回数据归档。如果省略了名称,将使用默认闪回数据归档。指定 NO FLASHBACK ARCHIVE 可禁用表归档。

 

 

填充闪回数据归档空间

闪回数据归档填满后,会发生什么?

  • 空间使用率达到 90%
  • 引发错误:

ORA-55623 “Flashback Archive \”%s\” is blocking and tracking on all tables is suspended”

ORA-55617 “Flashback Archive \”%s\” runs out of space and tracking on \”%s\” is suspended”

  • 生成预警日志条目
  • 挂起跟踪

用尽闪回数据归档中的空间后,FBDA 及所有生成跟踪还原的前台进程会引发 ORA-55617 或 ORA-55623 错误。会增加一个预警日志条目,表明“闪回归档 fla1 已满,归档已挂起。\n”默认情况下,分配空间的使用率达到 90% 后即会发生此错误。
示例:

  • 55623, 00000, “Flashback Archive \”%s\” is blocking and tracking on all tables is suspended”
    // *Cause: Flashback archive tablespace has run out of space.
    // *Action: Add tablespace or increase tablespace quota for the flashback archive.
    //
  • 55617, 00000, “Flashback Archive \”%s\” runs out of space and tracking on \”%s\” is suspended“
    // *Cause: Flashback archive tablespace quota is running out.
    // *Action: Add tablespace or increase tablespace quota for the flashback archive.

注:此后,由于 FBDA 无法归档这些操作,新的事务处理会受到阻止。跟踪数据中不会因丢失的操作而出现间断。提高限额或扩展分配的表空间会导致 FBDA 先处理未归档的事务处理,然后再处理正在进行的事务处理或新的事务处理。

 

维护闪回数据归档

  1. 增加空间:

 

ALTER FLASHBACK ARCHIVE fla1

  ADD TABLESPACE tbs3 QUOTA 5G;       

  1. 更改保留时间:

ALTER FLASHBACK ARCHIVE fla1 MODIFY RETENTION 2 YEAR;

 

  1. 清除数据:

 

ALTER FLASHBACK ARCHIVE fla1 PURGE BEFORE TIMESTAMP(SYSTIMESTAMP – INTERVAL ‘1’ day);

 

  1. 删除闪回数据归档:

DROP FLASHBACK ARCHIVE fla1;

 

  1. 示例 1 为闪回数据归档 FLA1 最多增加 5 GB 的 TBS3 表空间(归档管理员不能超过由 DBA 授予的表空间限额)。
  2. 示例 2 将闪回数据归档 FLA1 的保留时间更改为两年。
  3. 示例 3 从闪回数据归档 FLA1 中清除了一天前的所有历史记录数据。通常会在保留时间到期后的第一天执行自动清除。也可以覆盖此设置以进行临时清除。
  4. 示例 4 删除闪回数据归档 FLA1 和历史记录数据,但不删除其表空间。使用 ALTER FLASHBACK ARCHIVE 命令,可以:

-更改闪回数据归档的保留时间

-清除部分或全部数据

-增加、修改和删除表空间

注:删除闪回数据归档的全部表空间会引发错误。

 

闪回数据归档:示例

  1. 强制执行数字粉碎:

CREATE FLASHBACK ARCHIVE tax7_archive  TABLESPACE tbs1 RETENTION 7 YEAR;       

  1. 访问历史记录数据:

 

SELECT symbol, stock_price FROM stock_data
 AS OF TIMESTAMP TO_TIMESTAMP (‘2006-12-31 23:59:00’,
  ‘YYYY-MM-DD HH24:MI:SS’)      

 

  1. 恢复数据:

INSERT INTO employees   SELECT * FROM employees AS OF TIMESTAMP  TO_TIMESTAMP(‘2007-06-12 11:30:00′,’YYYY-MM-DD HH24:MI:SS’)
WHERE name = ‘JOE’;       

 

出于某些目的,组织需要存储历史记录数据。闪回数据归档功能可通过“as of”查询提供对历史记录数据的无缝访问。可将闪回数据归档功能用于兼容性报告、审计报表、数据分析和决策支持。

  • 假设您希望建立自己的数据库,以便在 7 年后的第一天自动删除 TAX7_ARCHIVE 中的信息。要实现此目的,只需指定示例 1 中所示的命令。
  • 要在 2006 年 12 月 31 日营业时间结束时检索股票行情,请使用示例 2 中所示的查询。
  • 如果发现错误删除了 JOE 的雇员记录,但该记录在 2007 年 6 月 12 日 11:30 时仍然存在,可以如示例 3 中所示重新将其插入。

 

闪回数据归档:DDL 限制

对启用了闪回数据归档功能的表使用下述任一 DDL 语句都会导致错误 ORA-55610:

  • 执行以下任一操作的 ALTER TABLE 语句:

删除、重命名或修改列

执行分区或子分区操作

LONG 列转换为 LOB

包括 UPGRADE TABLE 子句(不管有无 INCLUDING DATA 子句)

  • DROP TABLE 语句
  • TRUNCATE TABLE 语句

出于安全性和合法兼容性方面的考虑,上述限制可确保闪回数据归档中的数据不会失效。

 

查看闪回数据归档

查看结果:

视图名称 说明
*_FLASHBACK_ARCHIVE 显示有关闪回数据归档的信息
*_FLASHBACK_ARCHIVE_TS 显示闪回数据归档的表空间
*_FLASHBACK_ARCHIVE_TABLES 显示有关启用了闪回归档的表的信息

 

可使用动态数据字典视图查看跟踪表和闪回数据归档元数据。要访问 USER_FLASHBACK 视图,需要拥有表的所有权。对于其它视图,则需要拥有 SYSDBA 权限。

示例:

  • 查询闪回数据归档的创建时间:

SELECT FLASHBACK_ARCHIVE_NAME, CREATE_TIME, STATUS

FROM   DBA_FLASHBACK_ARCHIVE;

  • 列出闪回数据归档使用的表空间:

SELECT *

FROM   DBA_FLASHBACK_ARCHIVE_TS;

  • 列出特定表的归档表名称:

SELECT ARCHIVE_TABLE_NAME

FROM   USER_FLASHBACK_ARCHIVE_TABLES

WHERE  TABLE_NAME = ‘EMPLOYEES’;

无法从动态性能 (V$) 视图中检索过去的数据。对此类视图中的查询总是返回当前数据。不过,您可以在静态数据字典视图(如 *_TABLES)中对过去的数据执行查询。

 

 

标准和使用提示

  • 查询过去的数据前执行 COMMIT ROLLBACK
  • 使用当前的会话设置
  • 使用 DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER 函数获取 SCN
  • 使用以下公式计算过去的某个时间:

  (SYSTIMESTAMP – INTERVAL ’10’ MINUTE)

  • 在要求一定精度(时间戳的粒度为三秒)的情况下使用系统更改号 (SCN)。

 

  • 为了确保数据库的一致性,应始终在查询过去的数据前执行 COMMIT 或 ROLLBACK
    操作。
  • 请记住,所有闪回处理都使用当前的会话设置(如国家语言和字符集),而不使用查询时生效的设置。
  • 要获得稍后与闪回功能一起使用的 SCN,可以使用 DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER 函数。
  • 要计算或检索查询中使用的过去某个时间,请使用函数返回值作为时间戳或 SCN 参数。例如,将 SYSTIMESTAMP 函数的值加上或减去一个 INTERVAL 值。
  • 要查询某个精确时间的过去数据,请使用 SCN。如果使用时间戳,查询的实际时间可以比指定的时间最多早 3 秒。Oracle DB 在内部使用 SCN 并将其映射到粒度为 3 秒的时间戳。

 

闪回事务处理回退

 

  • 用于回退特定事务处理及其所有相关事务处理的逻辑恢复选项

使用还原、重做日志以及补充事件记录功能

创建并执行校正事务处理

以提交或回退操作来结束更改

  • 比费力的手动方法更快、更容易

 

闪回事务处理回退是一个逻辑恢复选项,用于回退特定事务处理及相关事务处理,同时保持数据库联机。相关事务处理通过连续编写 (WAW) 关系或主键约束关系相关联,在前者中事务处理对目标事务处理更改的同一数据进行修改,而在后者中事务处理重新插入由目标事务处理删除的同一主键值。闪回事务处理利用为还原块生成的还原和重做来创建并执行校正事务处理,以将受影响的数据还原到其原始状态。

 

闪回事务处理

 

  • 建立闪回事务处理的先决条件
  • 逐步完成可能的工作流
  • 使用闪回事务处理向导
  • 查询有相关性及没有相关性的事务处理
  • 选择回退选项和闪回事务处理
  • 检查结果

可从 Enterprise Manager 或 PL/SQL 程序包中使用闪回事务处理功能。

DBMS_FLASHBACK.TRANSACTION_BACKOUT

 

先决条件

 

要使用此功能,必须启用补充事件记录功能并建立正确的权限。例如,HR 方案中的 HR 用户决定对 REGIONS 表使用闪回事务处理。SYSDBA 可确保数据库处于归档日志模式,并在 SQL*Plus 中执行以下设置步骤:

alter database add supplemental log data;

alter database add supplemental log data (primary key) columns;

grant execute on dbms_flashback to hr;

grant select any transaction to hr;

HR 用户需要拥有表(和上一示例中的情况相同)或拥有 SELECT、UPDATE、DELETE 和 INSERT 权限,这样才能执行校正还原 SQL 代码。

 

 

闪回事务处理

  • 可使用 Enterprise Manager 或命令行闪回事务处理。
  • EM 使用闪回事务处理向导,该向导使用 NOCASCADE
    选项调用 DBMS_FLASHBACK.TRANSACTION_BACKOUT 过程。
  • 如果 PL/SQL 调用成功完成,即意味着事务处理不具有
    任何相关性,并且已成功回退单个事务处理。

安全权限

要闪回或回退事务处理,也就是创建校正事务处理,您必须对所有受影响的表具有 SELECT、FLASHBACK 和 DML 权限。

使用条件

  • 相冲突的 DDL 不支持事务处理回退。
  • 事务处理回退从 LogMiner 中继承数据类型支持。要查看支持的数据类型,请参阅 Oracle Database 11g 文档。

建议

  • 发现需要回退事务处理时,尽快启动回退操作的效果会比较好。重做日志太大和事务处理率过高会降低事务处理回退操作的速度。
  • 为回退操作提供事务处理名称有利于稍后的审计工作。如果没有提供事务处理名称,会自动生成一个名称。

 

可能的工作流

  • 查看表中的数据
  • 发现逻辑问题
  • 使用闪回事务处理

执行查询

选择事务处理

闪回事务处理(如果没有冲突)

选择其它回退选项(如果存在冲突)

  • 查看闪回事务处理结果

假定有如下所示的几个事务处理:

connect hr/hr

INSERT INTO hr.regions VALUES (5,’Pole’);

COMMIT;

UPDATE hr.regions SET region_name=’Poles’ WHERE region_id = 5;

UPDATE hr.regions SET region_name=’North and South Poles’ WHERE region_id = 5;

COMMIT;

INSERT INTO hr.countries VALUES (‘TT’,’Test Country’,5);

COMMIT;

connect sys/<password> as sysdba

ALTER SYSTEM ARCHIVE LOG CURRENT;

 

最后步骤(不使用 EM)

选择回退选项后,会在 DBA_FLASHBACK_TXN_STATE DBA_FLASHBACK_TXN_REPORT 表中生成相关性报告。

  • 检查显示了已回退的所有事务处理的相关性报表。
  • 提交更改使其成为永久更改。
  • 回退以放弃更改。

DBA_FLASHBACK_TXN_STATE 视图包含事务处理的当前状态:在系统中是处于活动状态还是已被有效回退。系统将使用校正事务处理以原子方式维护此表。对于每个校正事务处理,可能存在多个行,其中每行都会提供校正事务处理已校正的事务处理间的相关性关系。

DBA_FLASHBACK_TXN_REPORT 视图可提供关于数据库中已提交的所有校正事务处理的详细信息。此视图中的每一行都与一个校正事务处理相关联。

有关这些表的详细说明,请参阅《Oracle 数据库参考》。

 

查看闪回事务处理元数据

 

视图名称 说明
*_FLASHBACK_TXN_REPORT 显示相关的 XML 信息
*_FLASHBACK_TXN_STATE 显示已回退的事务处理的事务处理标识符

 

 

 

SQL> SELECT * FROM DBA_FLASHBACK_TXN_STATE;
COMPENSATING_XID XID              BACKOUT_MODE DEPENDENT_XID      USER#
---------------- ---------------- ------------ --------------- --------
0500150069050000 03000000A9050000            4                        0 
0500150069050000 05001E0063050000            4 03000000A9050000       0      
可使用数据字典视图查看关于闪回事务处理回退的信息。 
DBA_ FLASHBACK_TXN_REPORT 的示例内容: 
COMPENSATING_XID
----------------
COMPENSATING_TXN_NAME
-----------------------------------------------------------------------------COMMIT_TI
---------
XID_REPORT
-----------------------------------------------------------------------------
USER#
----------
0500150069050000
 
26-JUN-07

 

 

Script:收集Flashback Database Log诊断信息

以下脚本可以用于收集10g以后的闪回数据库日志Flashback Database Log的诊断信息:

WITH flashback_database_log AS
(SELECT ROUND((SYSDATE - oldest_flashback_time) * 24 * 60, 2) oldest_log_minutes,
retention_target retention_target_minutes,
flashback_size / 1048576 flashback_size_mb,
estimated_flashback_size / 1048576 estimated_flashback_size_mb
FROM v$flashback_database_log),
flashback_database_logfile AS
(SELECT COUNT(*) logs,
SUM(BYTES / 1048576) size_mb,
MIN(first_time) oldest_log,
MAX(first_time) latest_log
FROM v$flashback_database_logfile),
flashback_usage AS
(SELECT file_type,
ROUND(mb_used, 2) mb_used,
ROUND(mb_reclaimable, 2) mb_reclaimable,
DECODE(total_mb, 0, 0, ROUND(mb_used * 100 / total_mb, 2)) percent_space_used,
DECODE(total_mb, 0, 0, ROUND(mb_reclaimable * 100 / total_mb, 2)) percent_space_reclaimable,
number_of_files,
total_mb db_recovery_file_dest_mb,
flashback_retention_target,
oldest_record,
ROUND((sysdate - oldest_record) * 24 * 60, 2) oldest_record_age_sec
FROM (SELECT SUM(DECODE(NAME,
'db_recovery_file_dest_size',
VALUE / 1048576,
0)) total_mb,
SUM(DECODE(NAME, 'db_flashback_retention_target', VALUE, 0)) flashback_retention_target
FROM v$parameter
WHERE NAME IN ('db_recovery_file_dest_size',
'db_flashback_retention_target')),
(SELECT 'FLASHBACKLOG' file_type,
NVL(SUM(BYTES) / 1048576, 0) mb_used,
sum(CASE
WHEN last_time <= (sysdate - (tgt.value / 1440)) THEN
bytes / 1048576
ELSE
0
END) mb_reclaimable,
COUNT(*) number_of_files,
MIN(first_time) oldest_record
FROM (select bytes,
lead(first_time) over(order by first_time asc) last_time,
first_time
from v$flashback_database_logfile) fla_log,
(SELECT value value
FROM v$parameter
WHERE name = 'db_flashback_retention_target') tgt
UNION
SELECT 'BACKUPPIECE' file_type,
NVL(SUM(BYTES / 1048576), 0) mb,
SUM(CASE
WHEN dl.rectype = 13 THEN
(BYTES / 1048576)
ELSE
0
END) reclaimable_mb,
COUNT(*) no_of_files,
MIN(start_time) oldest_record
FROM v$backup_piece bp, x$kccagf dl
WHERE is_recovery_dest_file = 'YES'
AND deleted = 'NO'
AND bp.recid = dl.recid(+)
AND dl.rectype(+) = 13
UNION
SELECT 'ARCHIVELOG' file_type,
NVL(SUM(blocks * block_size) / 1048576, 0) mb,
SUM(CASE
WHEN dl.rectype = 11 THEN
(LOG.blocks * LOG.block_size / 1048576)
ELSE
0
END) reclaimable_mb,
COUNT(*) no_of_files,
MIN(first_time) oldest_record
FROM v$archived_log log, x$kccagf dl
WHERE deleted = 'NO'
AND is_recovery_dest_file = 'YES'
AND dl.recid(+) = log.recid
AND dl.rectype(+) = 11
UNION
SELECT 'ONLINELOG' file_type,
SUM(BYTES / 1048576) mb,
0 reclaimable,
COUNT(*) no_of_files,
MIN(first_time) oldest_record
FROM v$logfile lf,
(SELECT group#, BYTES, first_time
FROM v$standby_log
UNION
SELECT group#, BYTES, first_time FROM v$log) l
WHERE l.group# = lf.group#
AND lf.is_recovery_dest_file = 'YES'
UNION
SELECT 'IMAGECOPY',
NVL(SUM(blocks * (block_size / 1048576)), 0) mb,
0 reclaimable_mb,
COUNT(*) no_of_files,
MIN(creation_time) oldest_record
FROM v$datafile_copy
WHERE deleted = 'NO'
AND is_recovery_dest_file = 'YES'
UNION
SELECT 'CONTROLFILE',
NVL(SUM(block_size * file_size_blks) / 1048576, 0) mb,
0 reclaimable,
COUNT(*) no_of_files,
NULL oldest_record
FROM v$controlfile
WHERE is_recovery_dest_file = 'YES'))
SELECT order_, NAME, VALUE
FROM(
SELECT 0 order_, NAME, VALUE
FROM v$parameter
WHERE NAME LIKE 'db_recovery_file%'
UNION
SELECT 3, 'oldest flashback log (minutes)', TO_CHAR(ROUND(oldest_log_minutes, 2))
FROM flashback_database_log
UNION
SELECT 1, 'retention target (minutes)', TO_CHAR(ROUND(retention_target_minutes, 2))
FROM flashback_database_log
UNION
SELECT 2, 'estimated size for flashback logs (MB)', TO_CHAR(ROUND(estimated_flashback_size_mb, 2))
FROM flashback_database_log
UNION
SELECT 2, 'Current flashback log count', TO_CHAR(logs)
FROM flashback_database_logfile
UNION
SELECT 3, 'Most recent flashback log (minutes)', TO_CHAR(ROUND((SYSDATE - latest_log) * 24 * 60, 2))
FROM flashback_database_logfile
UNION
SELECT 4, 'Total size of all files in MB', TO_CHAR(ROUND(SUM(mb_used), 2))
FROM flashback_usage
UNION
SELECT 5, 'Total size of reclaimable files in MB', TO_CHAR(ROUND(SUM(mb_reclaimable), 2))
FROM flashback_usage
UNION
SELECT 6, 'unused space in MB', TO_CHAR(ROUND(MIN(db_recovery_file_dest_mb) - SUM(mb_used)))
FROM flashback_usage)
ORDER BY order_, NAME
/

Sample Output:

ORDER_ NAME                                                                             VALUE
---------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
0 db_recovery_file_dest                                                            +SYSTEMDG
0 db_recovery_file_dest_size                                                       5218762752
1 retention target (minutes)                                                       1440
2 Current flashback log count                                                      33
2 estimated size for flashback logs (MB)                                           142.15
3 Most recent flashback log (minutes)                                              164.03
3 oldest flashback log (minutes)                                                   5846.35
4 Total size of all files in MB                                                    1963.11
5 Total size of reclaimable files in MB                                            534.47
6 unused space in MB                                                               3014

11g r2中对闪回数据归档的增强

11g r1中引入了闪回数据归档新特性,其工作原理是为针对启用了归档方式的表,FBDA进程将创建对应于该表的内部历史表。历史表将拥有原始表的所有列加上某些时间戳列以便跟踪事务处理的变化,具体如下:

SQL> desc SYS_FBA_HIST_75718;
Name                                      Null?    Type
----------------------------------------- -------- ----------------------------
RID                                                VARCHAR2(4000)
STARTSCN                                           NUMBER
ENDSCN                                             NUMBER
XID                                                RAW(8)
OPERATION                                          VARCHAR2(1)
T1                                                 NUMBER(38)
T2                                                 VARCHAR2(20)
/* 注意其中T1,T2为原始表上的应用数据列 */

[Read more…]

沪ICP备14014813号

沪公网安备 31010802001379号