ITL undo header redo commit

 事务的操作流程。
    我们可以通过下图,系统了解下事务的执行流程。

参考:  oracle_事务与undo块 - 豆腐不怕卤水的经历 - 博客园

    1.一个事务先在shared Pool解析。(以硬解析为例) 软软解析直接在PGA中 private sql area

原作者的顺序有点不对, 5 6 应该先开始,不然哪来的XID编号  ,先有undo header,再有Undo 、Data block进SGA, 这样事务表,ITL表,UBA才能确定。

   2.在buffer cache中寻找事务所需要的块。
    3.数据块读入buffer cahce。
    4.产生重做日志信息,记日志。
    5.为事务建立undo段。   
    6.事务修改数据块的详细步骤。
        6.1事务开始,必须首先在data block中分配ITL(事务槽),ITL中记录了事务ID(XID),XID由三部分内容组成:
            XIDUSN(回滚段号),XIDSLOT(回滚段槽号),XIDSQN(覆盖次数)。
        6.2分配对应的undo块,用于保存修改之前data block的数据。data block的ITL和undo block的ITL都记录着相同的UBA                      block address) 
        6.3在Undo segment header中的事务表中,记录所有回滚块上的事务信息,每个事务都会占据了一个回滚槽。
            XID指向data block。 
            UBA指向事务回滚信息的开始位置。undo块存储是一个链表结构,只要找到最先开始回滚的块,就能依次回滚整个事务。

    小结undo的内容:
    1.为事务建立undo段。

    4.建立undo块,存储数据块镜像。数据块中的UBA指向undo块。同样有xid,uba。

    2.在数据块的ITL中存储XID,UBA.


    3.在undo表头中存储相对应的数据 块的XID,UBA.

证明--下面一张根据这次事务所作的图,结合图理解

           

            undo 段表中记录着每一个事务的XID和UBA                   ---实验中用红色字体标注出XID,UBA
            data block中ITL的XID指向undo段头, UBA指向undo block
            undo 段头中的UBA指向undo block

 undo 段头

6.详细看undo段块头的信息,(篇幅很长。)    (图rollback segment header block,结合图理解)

    

 

事务隔离

ITL

ITL: Interested Transaction List,也叫事务槽,它位于BLOCK Header。格式如下:

 Itl           Xid                                 Uba                        Flag  Lck        Scn/Fsc
 0x01   0x0001.026.00000150  0x008003c0.0113.17  ----    1  fsc 0x0000.00000000
 0x02   0x0005.013.00000190  0x0080004b.013a.17  ----    1  fsc 0x0001.00000000

Xid:事务id,在回滚段事务表中有一条记录和这个事务对应,分别是undo segment number+undo segment slot+undo segment sequence,也就是回滚段编号、回滚段事务槽号、和回滚段的序号(回滚段事务槽被覆盖的次数)
Uba:回滚段地址,该事务对应的回滚段地址
Flag:事务标志位。这个标志位就记录了这个事务的操作,各个标志的含义分别是:

——- = 事务是活动的,或者在块清除前提交事务
C—- = 事务已经提交并且清除了行锁定。
-B— = this undo record contains the undo for this ITL entry
—U- = 事务已经提交(SCN已经是最大值),但是锁定还没有清除(快速清除)。
—-T = 当块清除的SCN被记录时,该事务仍然是活动的,块上如果有已经提交的事务,

Lck:影响的记录数
Scn/Fsc:快速提交(Fast Commit Fsc)的SCN或者Commit SCN。其实就是事务号。

SCN

system change number (SCN)是一个非常重要的标记,Oracle使用它来标记数据库在过去时间内的状态和轨迹。Oracle使用SCN来保存所有变化的轨迹。SCN是一个逻辑时钟来记录数据库事件。

隔离

当发出一条sql语句时,ORACLE会记录下这个时刻(SCN),然后在buffer cache中查找需要的BLOCK,或者从磁盘上读。当别的会话修改了数据,或者正在修改数据,就会在相应的block上记录ITL,此时ORACLE发现ITL中记录的SCN(Scn/Fsc)大于SELECT时刻的SCN,或者ITL没有SCN(正在修改,未提交);那么ORACLE就会根据ITL(ITL中xid flag标记 scn号)中的Uba找到UNDO信息获得该block的前镜像,然后在buffer cache 中构造出CR(consistent read)块,此时ORALCE 也会检查构造出来的BLOCK中ITL记录的SCN(Scn/Fsc),如果SCN(Scn/Fsc)还大于select时刻的SCN,那么一直重复构造前镜像,然后ORACLE找到前镜像BLOCK中的ITL的SCN是否小于select的SCN,同时检查这个事物有没有提交或者回滚,如果没有,那么继续构造前镜像,直到找到需要的BLOCK(找的过程中虽然事务表中有事务信息,但是没有去查,都是利用自身的UBA去取回BLOCK及ITL表改变的矢量变化。这就是块中保留事务UBA的作用。  XID中的事务行覆盖次数用不上,用覆盖次数的例子就是:延迟块清理时发现覆盖次数大于itl中覆盖次数,代表itl中的事务已经结束没有清理而已),如果在构造前镜像的过程中所需的UNDO信息被覆盖了(只有可能是报错的这个事务本身运行时间过长,人家未commit前开始事务,做完了了这边才又开始查找并CR这个数据块。),就会报快照过旧的错误。

一致性.png

SCN号在block上都有, 数据文件头 控制文件也有

一个事务开始以后,在一个数据块上得到一个事务槽,那么在这个事务提交以前,这个事务槽会一直占用,直到这个事务提交释放这个事务槽

只有在已经提交以后,这个itl事务槽中的scn才会有数值。

一个事务在一个数据块上占用一个事务槽

如果是insert,默认每个表的ini_trans  itl是2,尽量保持这个数据块的事务数不超过2(这是buffer busy wait的解决方案,降低pctused,减少ini_trans

采用在多个数据块中插入的情况。这样将insert分布到多个数据块中,防止了itl的争用。

这时buffer busy wait的解决方案,降低pctused,减少ini_trans

三个会话同时修改一个数据块。

事务槽自己增加到了3个。

因为max_trans是255,因此发生ITL争用的几率也很小。

因此基于上面的两种情况来说,ITL发生争用的几率很小。

Cleanout有2种:

1:fast commit cleanout  (提交清除)

2:delayed block cleanout(延迟清除).

提交清除是如何工作的?

Oracle会记录已修改的块列表,这些列表可以有20个块,Oracle根据需要分配多个这样的列表,

但是如果这些修改的块加起来超过buffer_cache的10%,oracle就停止分配这样的列表,因此

当提交时就只会清理最多10%buffer_cache的数据块,其余的部分就延迟清除,这样也是为了

提高commit的效率。U

还有一种情况,就是当事务还未commit时,修改的数据块已经写入硬盘,当发生commit时

oracle并不会把block重新读入做cleanout,而是把cleanout留到下一次对此块的访问是完成。 

注意:对于Oracle来说,对于一个事务,可以是快速提交、也可以是延迟提交。目的都是为了提高提交的速度。

提交以后,oracle需要对ITL事务槽、每一行的锁定标记进行清除。

如果是快速提交,那么在提交的时候,会将事务表和每一个数据块的ITL槽进行清除。但是锁定标记可能没有清除,等下次用到的时候再进行清除。

如果是延迟提交,那么在提交的时候,只是将事务表进行清除,并没有对ITL事务槽进行清除,每一行的锁定标记也没有清除。

块清除的过程并不包括每个行的锁定标记的清除,主要指的是ITL的清除。

 

1、事务是否已经提交、事务对应的SCN,这些信息都是以回滚段事务表中的为主,事务槽中的不准确

2、事务槽中的事务id和uba地址是准确的

3、事务槽1中的事务id和回滚段中的事务id肯定不是一样的,不同回滚段中的事务id也一定不一样。

4、每一个回滚段块中都有一个事务id,记录哪个事务正在使用这个块。

5、回滚事务表可能被覆盖,回滚段也可能被覆盖

对于前者,我们需要增加回滚段

对于后者,我们需要增大回滚段

回滚段也是循环使用的,只有活动的回滚段不会被覆盖

行级锁

锁分共享锁和排他锁,查询使用共享锁,修改使用排他锁,所以事务对修改的数据需要加排他锁,例如行级锁。行级锁实现通过对数据记录设置itl的序号,来说明数据记录已经被这个itl设置。

----------------
Start dump data blocks tsn: 0 file#: 1 minblk 61186 maxblk 61186
buffer tsn: 0 rdba: 0x0040ef02 (1/61186)
scn: 0x0000.000d206f seq: 0x01 flg: 0x02 tail: 0x206f0601
frmt: 0x02 chkval: 0x0000 type: 0x06=trans data
----------------
 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0001.026.00000150  0x008003c0.0113.17  ----    1  fsc 0x0000.00000000
0x02   0x0005.013.00000190  0x0080004b.013a.17  --U-    1  fsc 0x0001.000d206f

-----------------
block_row_dump:
tab 0, row 0, @0x1f6e
tl: 13 fb: --H-FL-- lb: 0x0  cc: 2
col  0: [ 2]  c1 02
col  1: [ 6]  6f 72 61 63 6c 65
tab 0, row 1, @0x1f55
tl: 12 fb: --H-FL-- lb: 0x2  cc: 2     --对应itl 0x02
col  0: [ 2]  c1 03
col  1: [ 5]  6d 79 73 71 6c
tab 0, row 2, @0x1f61
tl: 13 fb: --H-FL-- lb: 0x1  cc: 2
col  0: [ 2]  c1 04
col  1: [ 6]  6f 72 61 63 6c 65
end_of_block_dump

ITL Cleanout和Delayed block cleanout 和快速提交

在事务提交(commit)前,会在数据块的头部记录下这个Cleanout SCN(Csc)号、Undo Block Address(Uba)和Transaction ID(Xid);并且在在对应Interested Transaction List(Itl)中设置锁标志,记录这个事务在这数据块中产生的锁的数目;同时在对应修改的数据记录上打上行级锁标志,并映射到对应的Itl去。当提交时,并不会一一清除掉所有锁标志,而是给对应的Itl打上相应标志,告诉后面访问该数据块的事务,相应的事务已经提交。这就叫做快速提交(Fast Commit)。

ITL Cleanout

一个新的事务过来时,它首先会选择一个itl槽,首先oracle采用C---状态的事务,如果没有C---状态的事务,oracle就会发生一次itl cleanout,检查所有的ITL相关的事务,如果确认事务已经提交了,就将之修改为C---状态了。

Delayed block cleanout

1.如果一个transaction修改的block超过db cache的10%.
2.当一个事务未提交时,其修改过的block就已经写到硬盘上去了。此时事务提交了,并不会修改数据块上的状态。
仅仅为修改状态来重写数据块代价比较高,所以采用延迟修改。
可以看出块有可能在修改过程中,事务还没有commit的时候被写进磁盘。
已经提交的事务可以不用修改itl,从事务表中可以找到相应事务的状态,所以最终不会对结果造成任何影响,ITL Cleanout的时候也是这样查询真实的事务状态。

事务表条目有限,ITL Delayed block cleanout 丢失了事务表中的信息怎么办?

 TRN TBL::
 
  index  state cflags  wrap#    uel         scn            dba            parent-xid    nub     stmt_num    cmt
  ------------------------------------------------------------------------------------------------
   0x00    9    0x00  0x5b1a5  0x001c  0x0000.07ecd2be  0x0080030b  0x0000.000.00000000  0x00000002   0x00000000  1398758386
   0x01    9    0x00  0x5b170  0x0011  0x0000.07ecd32d  0x00800326  0x0000.000.00000000  0x00000001   0x00000000  1398758405
   0x02    9    0x00  0x5b1a0  0x000c  0x0000.07ecd2d7  0x0080030b  0x0000.000.00000000  0x00000001   0x00000000  1398758403
   0x03    9    0x00  0x5b1a8  0x0000  0x0000.07ecd2b7  0x0080030a  0x0000.000.00000000  0x00000001   0x00000000  1398758386
   0x04    9    0x00  0x5b1ad  0x000d  0x0000.07ecd2e4  0x0080030c  0x0000.000.00000000  0x00000002   0x00000000  1398758404
   0x05    9    0x00  0x5b1a3  0x0021  0x0000.07ecd25d  0x0080030a  0x0000.000.00000000  0x00000001   0x00000000  1398758346
   0x06   10    0x80  0x5b1ab  0x0002  0x0000.07ecd29c  0x00800326  0x0000.000.00000000  0x00000001   0x00000000  0
   0x07    9    0x00  0x5b1a3  0x0012  0x0000.07ecd2ee  0x00000000  0x0000.000.00000000  0x00000000   0x00000000  1398758404

0x06的State 10表示这个回滚段对应的事务是active状态。如果发现事务表中的条目被覆盖了,例如itl记载的序列为100,现在为120,则认为事务已经提交,没有提交的事务为active,oracle是不会覆盖的。

undo, redo

Undo日志记录某数据被修改前的值,可以用来在事务失败时进行rollback;Redo日志记录某数据块被修改后的值,可以用来恢复未写入data file的已成功事务更新的数据。但是数据库崩溃了之后从日志的什么位置进行恢复?就引出了检查点的概念。

redo日志应首先持久化在磁盘上,然后事务的操作结果才写入db buffer,(此时,内存中的数据和data file对应的数据不同,我们认为内存中的数据是脏数据),db buffer再选择合适的时机将数据持久化到data file中。这种顺序可以保证在需要故障恢复时恢复最后的修改操作。先持久化日志的策略叫做Write Ahead Log,即预写日志。

WAL写日志 -> 修改db buffer -> 写入data file。
redo是对应的数据文件,undo是数据文件的一部分,所以undo的修改是需要进redo日志的,这个策略解决很大问题

检查点

WAL导致写数据文件是"异步"的,写日志文件是"同步"的。

这就可能导致数据库实例崩溃时,内存中的DB_Buffer 中的修改过的数据,可能没有写入到数据块中。数据库在重新打开时,需要进行恢复,来恢复DB Buffer 中的数据状态,并确保已经提交的数据被写入到数据块中。检查点是这个过程中的重要机制,通过它来确定,恢复时哪些重做日志应该被扫描并应用于恢复。

要了解这个检查点,首先要知道checkpoint queue概念,检查点发生后,触发DBWn,CKPT获取发生检查点时对应的SCN,通知DBWn要写到这个SCN为止, DBWR写dirty buffer 是根据 buffer 在被首次 modify的时候的时间的顺序写出,也就是 buffer被modify 的时候会进入一个queue (checkpoint queue),DBWr 就根据queue从其中批量地写到数据文件。 由于这里有一个顺序的关系,所以 dbwr的写的进度就是可衡量的,写到哪个buffer的时候该buffer的首次变化时候的scn就是当前所有数据文件block的最新scn,但是由于无法适时的将dbwr的进度记录下来,所以oracle 选择了一些策略。 其中就包括ckpt进程的检查点和心跳。

恢复

当数据库突然崩溃,而还没有来得及将buffer cache里的脏数据块刷新到数据文件里,同时在实例崩溃时正在运行着的事务被突然中断,则事务为中间状态,也就是既没有提交也没有回滚。这时数据文件里的内容不能体现实例崩溃时的状态。这样关闭的数据库是不一致的。
下次启动实例时,Oracle会由SMON进程自动进行实例恢复。实例启动时,SMON进程会去检查控制文件中所记录的、每个在线的、可读写的数据文件的END SCN号。

roll forward (前滚)

SMON进程进行实例恢复时,会从控制文件中获得检查点位置。于是,SMON进程到联机日志文件中,找到该检查点位置,然后从该检查点位置开始往下,应用所有的重做条目,从而在buffer cache里又恢复了实例崩溃那个时间点的状态。这个过程叫做前滚,前滚完毕以后,buffer cache里既有崩溃时已经提交还没有写入数据文件的脏数据块,也还有事务被突然终止,而导致的既没有提交又没有回滚的事务所弄脏的数据块。

rollback(回滚)

前滚一旦完毕,SMON进程立即打开数据库。但是,这时的数据库中还含有那些中间状态的、既没有提交又没有回滚的脏块,这种脏块是不能存在于数据库中的,因为它们并没有被提交,必须被回滚。打开数据库以后,SMON进程会在后台进行回滚。

必须先前滚,在回滚

回滚段实际上也是以回滚表空间的形式存在的,既然是表空间,那么肯定就有对应的数据文件,同时在buffer cache 中就会存在映像块,这一点和其他表空间的数据文件相同。

当发生DML操作时,既要生成REDO(针对DML操作本身的REDO Entry)也要生成UNDO(用于回滚该DML操作,记录在UNDO表空间中),但是既然UNDO信息也是使用回滚表空间来存放的,那么该DML操作对应的UNDO信息(在BUFFER CACHE生成对应中的UNDO BLOCK)就会首先生成其对应的REDO信息(UNDO BLOCK's REDO Entry)并写入Log Buffer中。

这样做的原因是因为Buffer Cache中的有关UNDO表空间的块也可能因为数据库故障而丢失,为了保障在下一次启动时能够顺利进行回滚,首先就必须使用REDO日志来恢复UNDO段(实际上是先回复Buffer Cache中的脏数据块,然后由Checkpoint写入UNDO段中),在数据库OPEN以后再使用UNDO信息来进行回滚,达到一致性的目的。

生成完UNDO BLOCK's REDO Entry后才轮到该DML语句对应的REDO Entry,最后再修改Buffer Cache中的Block,该Block同时变为脏数据块。

实际上,简单点说REDO的作用就是记录所有的数据库更改,包括UNDO表空间在内。

事务

  1. 首先当一个开始时,需要在回滚段事务表上分配一个事务表(事务槽)。
  2. 在数据块头部获取一个ITL事务槽,该事务槽指向回滚段头的事务槽。
  3. 在修改数据之前,需要记录前镜像信息,这个信息以UNDO RECORD的形式存储在回滚段中,回滚段头事务槽指向该记录。
  4. 锁定修改行,修改行锁定位(1b-lock-byte)指向ITL事务槽。
  5. 记录redo日志。
  6. 修改数据。
  7. 提交日志,日志号为提交时的scn。

问题

UNDO日志没有持久化到磁盘,rollback怎么办?

生成UNDO日志时,UNDO信息是使用回滚表空间来存放的,相当于修改数据,会生成相应的REDO日志。所以恢复时需要先前滚后回滚,前滚可以恢复回滚表空间。

UNDO REDO datafile

redo--> undo-->datafile
insert一条记录时,表跟undo的信息都会放进 redo 中,在commit 或之前, redo 的信息会放进硬盘上。 故障时, redo 便可恢复那些已经commit 了的数据。

AWL, 任何修改操作需要先写日志成功, 但是orcale在提交时才将日志写磁盘,详情将下节。commit,提交仅仅是生成事务号,提交当前的scn,记录下提交标志,将REDO日志刷到磁盘。

一次事务严格要执行多少次刷盘 【猜测】

首先生成UNDO日志,相应的要生成REDO日志,如果有多条UNDO日志,最后只调用一次刷盘就行,因为此时还没修改数据。

一种策略:
1.批量写入UNDO的REDO日志。
2.刷盘
3.写UNDO日志
4.批量写入数据修改的REDO日志。
5.批量修改DBbuffer。
6.提交。
7.刷盘。
提交事务的时候,生成事务号,写提交标志,这个时候REDO需要刷盘,成功刷盘意味着事务成功提交。
一次事务基本需要2次刷盘。

另外一种:【mysql一次事务一次刷盘配置是这种】
用户只在提交事务时强制sync一次。为了避免数据修改一部分down机,undo数据的redo还没写盘问题。采取的解决还是日志先行策略,Btree中的数据写入磁盘前,数据块对应的redo要先写到磁盘中。
总之,发起事务方强制在提交事务时sync一次,数据库机制保证在数据块写磁盘时,强制相应redo先入盘。一般的情况是数据修改在内存中,undo的redo日志以及数据块的redo日志都在内存中,当数据库要将数据块写盘时,会先将对应的redo日志写盘,undo的redo日志在数据块的redo日志之前,所以不会有什么问题。

回滚段与事务

一、认识UNDO

ORACLE的逻辑存储结构如下图所示,表空间--->段--->区--->块

UNDO表空间和普通的数据表空间不同,ORACLE自动生成UNDO表空间,自动生成UNDO段,自动分配UNDO区,自动使用UNDO段,只要保证UNDO表空间的大小就可以,UNDO段自动维护。

9i之前,ORACLE自动生成UNDO表空间,自动分配UNDO段,手工分配UNDO区,如果UNDO段用完之后没有及时分配UNDO区,事务会挂起,大的DML操作经常因为UNDO段不够而失败。

注:系统中会同时存在两个回滚段:系统表空间回滚段和UNDO表空间回滚段

二、UNDO的作用

2.1、回滚

ORACLE开始一个事务的时候,开始使用UNDO表空间。

一个事务开始时,ORACLE会拷贝一份修改前的数据放到UNDO表空间的UNDO段里,事务修改的块越多,必然使用的UNDO段就越多,当一个事务未完成就意外终止,ORACLE会自动回滚该事务,就是把修改前的数据再拷贝回来。(拷贝的就是记录,前镜像,一条一条,不是一个block块

2.2、提供读一致性

A会话开始一个事务,把1改成2,未提交;B会话上来只能看到1,看不到2。

为什么会这样呢?B怎么会看到1而不是2呢?

原因:B通过构造CR块达到一致性读的目的。因为1在被修改成2之前就被拷贝到UNDO段里,B上来发现A会话没有提交,就在buffer cache里额外申请一个数据块,把回滚段里的数据1的镜像拷贝写到buffer cache供B会话读取。

2.3、实例恢复

ORACLE用redo log做实例恢复,前滚时里面有未提交的事务,这部分事务需要回滚(rollback)

图解一个事务的操作流程

4.1 事务表、事务槽、回滚块的概念

UNDO表空间的UNDO段的第一个数据块(段头块)里存在一张事务表,这张事务表有47行,意味着每一个UNDO段头块可以有47个事务,一行一个,写上事务id(xid)。一个UNDO段最多可以同时有47个活动事务,意味着47个活动事务共用一个回滚段。

ORACLE尽量让一个事务占一个回滚段,实在没办法才让多个事务占一个回滚段,ORACLE还会尽量均匀将事务分配在各个回滚段上。

当一个事务开始时候,ORACLE给每一个事务分配一个事务ID(XID),事务在回滚段表空间里寻找回滚段,首先在undo段头块的事务表里的某一个空行里写上自己的信息,同时,该事务还需要在被修改的数据块头的事务槽(1-255)里,找个空的事务槽写上自己的信息。

就是说事务表在UNDO段头块里,事务槽在被修改的数据块里,事务ID用来标识每一个不同的事务。

4.2 图解一个事务过程

1.事务开始,ORACLE会为每一个事务分配一个事务ID(XID),在undo表空间里的undo段的段头块里的事务表里找一行写上该事务ID,同时分配一个undo block 1,并将undo block 1的地址(UBA)写到事务表里,与事务表中的XID对应。XID既是一个事务编号也是一个地址,XID由块号、行号、被覆盖次数组成,三者共同标识唯一一个事务,通过XID可以找到事务表。

2.该事务若是要修改一个数据块,首先在该数据块头部的事务槽里找一行写上XID,XID与回滚段段头块里的XID对应。

3.若是修改目标数据块里的某五行数据,这五行数据就被写到了第一次分配的undo block 1。

4.当然,一个事务可以修改不止一个数据块,如果有第二个数据块被修改,同样的,也要在第二个即将被修改的数据块头部的事务槽里找一行写上XID,与回滚段段头块中的事务表里的XID对应。

5.在修改第二个数据块时,第一次分配的undo块如果已经被写满了,则要重新分配一个undo block 2,并将第二个被修改的数据块中的相应的行写到undo block 2中去。

下面这个和事务rollback没关系

(数据block iTL中指针指向undo block 2的地址,这样,构建一致性读不需要再undo header读事务表了。 虽然重复记录了这个数据,但作用不相同的。尤其是构造commit很久,事务表被覆盖掉的情况下,从datablock旧镜像中ITL表中直接再次取到UBA,循坏的构造出满足scn号的块)

6.事务表里的UBA指向最新的undo block 2。

undo block 1和undo block 2是存在先后顺序的,并且新老undo块串联起来,新的undo块指向上一个老的undo块。因为写undo块的时候是从undo block 1写到undo block 2再写到undo block 3,当需要做rollback的时候,需要先回滚undo block3 ,再回滚undo block 2,最后才是undo block 1。

参考:
【1】http://www.dbaxiaoyu.com/archives/1987
【2】Oracle Redo Log 机制 小结_David Dai -- Focus on Oracle-CSDN博客_oracle的redo
【3】Oracle Block浅析2:ITL(Interested Transaction List) - PoleStar - 博客园
【4】理解数据库中的undo日志、redo日志、检查点_kobejayandy的专栏-CSDN博客_数据库redo日志
【5】RedoLog Checkpoint 和 SCN关系_David Dai -- Focus on Oracle-CSDN博客
【6】oracle四个重要的后台进程(DBWR / LGWR / ARCH / CKPT)_王慧-tyger的博客-CSDN博客_lgwr进程
【7】oracle证明题:未提交的事务也可能被DBWn写进数据文件_记录创业路上的一些想法-CSDN博客
【8】Oracle redo undo commit rollback剖析_朝着梦想 渐行前进-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值