ORACLE事务和实例的恢复过程讲解


这篇文章主要介绍“ORACLE事务和实例的恢复过程讲解”,在日常操作中,相信很多人在ORACLE事务和实例的恢复过程讲解问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”ORACLE事务和实例的恢复过程讲解”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!从oracle 的一个事务说起:例如当我们发起一个update 语句更改某一行数据,例如更改zabbix.cwdtest 的 table_name=’ICOL$’ 为’aaxx’。该行记录在14号文件,1835491块1.首先会经过在share pool中的sql语句的解析过程,这一过程只要是针对sql语法,执行计划这些进行处理,这一部分不细讲。2.接着,到了sql执行后,数据库从物理文件读出数据行相应的数据库到 buffer cache中(假设此时内存不存在相应的数据块同时不讨论锁的过程),这一过程也涉及到数据块写到dirty list,并写脏块,为新读取的数据块寻找空闲空间的过程3.同时会分配回滚段并在undo段再保留一份修改前的数据块映像。以下通过DUMP UNDO 相关 信息来查看。看到index是0x09的事务槽的state为10代表事务正在活动,而其他槽是9代表事务不活动,scn 表示务事启动、提交、回滚的SCN,事务槽0x09的scn是 0x0009.01e25a30,转换之后是38686317104。dba 表示uba:第一部分的undo块地址,这个DBA是(rollback)回滚的起始点,也就是说是记录事务修改的最后一条记录所在UNDO块的地址。事物表中0x19槽的dba为0x0a400495即41号文件的1173号块块号这与(与v$transaction视图中一致)。我们在看一下这个前镜像到底是什么?转储数据块这里scn表示 最近写入磁盘的SCN号,此时数据块中的scn是0x0009.01e25beb,转化之后是38686317547。对于DBWR,每次刷新脏块后,会去维护这个block的SCN号,代表这个block的数据版本。接着往下看,有本UNDO块中有51条记录:我们找到第51行记录的对象号是130736,这个正是我们本次事务更改的表。这里字段值是 49 43 4f 4c 24,通过转换是ICOL$,这正是update前的值。SQL>selectutl_raw.cast_to_varchar2(replace(‘49434f4c24’,”))fromdual;UTL_RAW.CAST_TO_VARCHAR2(REPLACE(‘49434F4C24’,”))————————–免费云主机域名———————————————————–ICOL$而bdba: 0x039c01e3 是该记录对应的数据块地址,该行记录正是在14号文件,1835491块SQL>selectto_number(‘039c01e3′,’xxxxxxxxxxx’)fromdual;TO_NUMBER(‘039C01E3′,’XXXXXXXXXXX’)———————————–60555747SQL>selectdbms_utility.data_block_address_file(60555747)file#,dbms_utility.data_block_address_block(60555747)blockfromdual;FILE#BLOCK————————–141835491整个与UNDO相关的有几个SCN,我们重新整理下:undo header 中的SCN:表示务事启动、提交、回滚的SCN,事务槽0x09的scn是 0x0009.01e25a30,转换之后是38686317104。undo block中scn:表示 最近写入磁盘的SCN号,此时数据块中的scn是0x0009.01e25beb,转化之后是38686317547undo block修改记录行的SCN:ctl max scn: 0x0009.01e25b73 转化之后是38686317427prv tx scn: 0x0009.01e25b75 ,转化之后是38686317429txn start scn: scn: 0x0000.00000000 ,这里是0 。而此时redo记录的信息如下:alter system dump logfile ‘/opt/app/oracle/oradata/tlvdb/redo1.log’;4..为事务修改数据块,并在执行更改完成后,针对此数据块的修改也生成redo信息。这里是将该语句所影响的并被读入db buffer中的这些行数据的rowid及要更新的原值和新值及scn等信息从PGA逐条的写入redo log buffer中,以下分别UPDATE 前后执行alter system dump datafile 14 block 1835491;来dump 出数据块。执行UPDATE之前:tab0,row0,@0x1e87tl:249fb:–H-FL–lb:0x0cc:55col0:[3]535953col1:[5]49434f4c24
这里scn: 0x0009.01e25a2b 转换之后是38686317099执行UPDATE 之后:tl:248fb:–H-FL–lb:0x2cc:55col0:[3]535953col1:[4]61617878
这里scn: 0x0009.01e25beb 转换之后是38686317547这里说明,当事务中修改了数据块,不管事务有无提交,数据脏块会随着 dbw进程的机制写入数据文件中。而在 REDO日志中会记录操作的记录,并记录本次undo操作的信息,即修改前的信息:REDORECORD-Thread:1RBA:0x000412.00335b66.0010LEN:0x01a0VLD:0x0dSCN:0x0009.01e25bebSUBSCN:107/22/201917:53:43(LWNRBA:0x000412.00335b66.0010LEN:0001NST:0001SCN:0x0009.01e25beb)CHANGE#1TYP:0CLS:1AFN:14DBA:0x039c01e3OBJ:130736SCN:0x0009.01e25a2bSEQ:2OP:11.5ENC:0RBL:0KTBRedoop:0x01ver:0x01compatbit:4(post-11)padding:1op:Fxid:0x000b.009.0001ba87uba:0x0a400495.639a.51KDOOpcode:URProwdependenciesDisabledxtype:XAflags:0x00000000bdba:0x039c01e3hdba:0x039c01e2itli:2ispac:0maxfr:4858tabn:0slot:0(0x0)flag:0x2clock:2ckix:0ncol:55nnew:1size:-1col1:[4]61617878CHANGE#2TYP:0CLS:37AFN:3DBA:0x00c00170OBJ:4294967295SCN:0x0009.01e25bb3SEQ:1OP:5.2ENC:0RBL:0ktudhredo:slt:0x0009sqn:0x0001ba87flg:0x0012siz:140fbi:0uba:0x0a400495.639a.51pxid:0x0000.000.00000000CHANGE#3TYP:0CLS:38AFN:41DBA:0x0a400495OBJ:4294967295SCN:0x0009.01e25bb2SEQ:1OP:5.1ENC:0RBL:0ktudbredo:siz:140spc:646flg:0x0012seq:0x639arec:0x51xid:0x000b.009.0001ba87ktublredo:slt:9rci:0opc:11.1[objn:130736objd:130736tsn:7]Undotype:RegularundoBegintransLastbuffersplit:NoTempObject:NoTablespaceUndo:No0x00000000prevctluba:0x0a400495.639a.50prevctlmaxcmtscn:0x0009.01e25b73prevtxcmtscn:0x0009.01e25b75txnstartscn:0x0000.00000000logonuser:0prevbrb:171967629prevbcl:0BuExtidx:0flg2:0KDOundorecord:KTBRedoop:0x03ver:0x01compatbit:4(post-11)padding:1op:ZKDOOpcode:URProwdependenciesDisabledxtype:XAflags:0x00000000bdba:0x039c01e3hdba:0x039c01e2itli:2ispac:0maxfr:4858tabn:0slot:0(0x0)flag:0x2clock:0ckix:0ncol:55nnew:1size:1col1:[5]49434f4c24《〈〈更改前镜像数据5.执行commit命令,声明redo log buffer 中的redo处于commit状态,然后修改事务表相应slot,声明事务已提交,最后通知lgwr进程将redo log buffer中的数据写入redo log file。待lgwr进程通知已经写入完成后,向用户发出commit完成的信息。在事务的过程中涉及到三个进程,CKPT,DBWn,LGWR进程 :CKPT:检查点进程(Checkpoint Process)只是更新数据文件的文件首部,以辅助建立检查点的进程ckpt 触发条件:什么时候发生normal checkpoint下面这些操作将会触发checkpoint事件:日志切换,通过ALTER SYSTEM SWITCH LOGFILE。DBA发出checkpoint命令,通过ALTER SYSTEM checkpoint。对数据文件进行热备时,针对该数据文件的checkpoint也会进行,ALTER TABLESPACE TS_NAME BEGIN BACKUP/END BACKUP。当运行ALTER TABLESPACE/DATAFILE READ ONLY的时候。SHUTDOWN命令发出时。因为每次完全的checkpoint都需要把buffer cache所有的脏块都写入到数据文件中,这样就是产生一个很大的IO消耗,频繁的完全checkpoint操作很对系统的性能有很大的影响,为此Oracle引入的增量checkpoint的概念,buffer cache中的脏块将会按照BCQ队列的顺序持续不断的被写入到磁盘当中,同时CKPT进程将会每3秒中检查DBWn的写入进度并将相应的RBA信息记录到控制文件中。有了增量checkpoint之后在进行实例恢复的时候就不需要再从崩溃前的那个完全checkpoint开始应用重做日志了,只需要从控制文件中记录的RBA开始进行恢复操作,这样能节省恢复的时间。发生增量checkpoint的先决条件恢复需求设定 (FAST_START_IO_TARGET/FAST_START_MTTR_TARGET)LOG_checkpoint_INTERVAL参数值LOG_checkpoint_TIMEOUT参数值最小的日志文件大小buffer cache中的脏块的数量DBWn:数据库块写入器(Database Block Writer)负责将脏块写入磁盘的后台进程。触发DBWR进程的条件有:1.DBWR超时,大约3秒2.系统中没有多余的空缓冲区来存放数据3.CKPT 进程触发DBWR4.free buffer waits 40% 触发 dbwr吧lruw脏块写入磁盘5.关机会触发dbwr写6.alter system checkpoint 触发dbwr写7.redo 日志切换 触发dbwr写8. 表空间 offline /online 触发dbwr写LGWR:日志写入器(Log Writer)负责将SGA中重做日志缓冲区的内容刷新输出到磁盘。 触发LGWn工作的时点有几个: 1. 用户提交 ,用户提交时必须写LOGFILE. 2. 有1/3重做日志缓冲区未被写入磁盘 3. 有大于1M的重做日志缓冲区未被写入磁盘 4. 3秒超时 5. DBWR 需要写入的数据的SCN大于LGWR记录的SCN,DBWR 触发LGWR写入。这三个进程都是为了更好地完成一件事:安全高效地实现内存数据块写入数据文件,就是将内存中修改的数据反映到硬盘的数据文件上。 我在事务未提交时做一个刷新buffer cache,此时发现数据块已经被刷新到磁盘文件中,通过以上三个进程的触发条件也可以看出刷新数据块与事务是否提交关系不大。首先,日志文件的写入是很频繁的。LGWn会不断将日志信息从Log Buffer中写入Online Redo Log;其次,在日志文件上,可以有三个类型的事务事件。1、事务结束,已经被commit,之后打过checkpoint检查点。2、事务结束,已经被commit,之后没有打入checkpint检查点。3、事务未结束,没有commit。那么当我有一个事务一直未提交,此时发生断电,数据库直接crash,在重启后ORACLE是如何保证数据一致性呢?启动数据库时,如果发现有datafile header的START SCN 不等于储存于CONTROLFILE的DATAFILE SCN,表示需要进行介质恢复。启动数据库时,如果发现STOP SCN = NULL,表示需要进行crash recovery。oracle 的实例恢复过程实例恢复主要经历三个阶段: cache recovery、open database、transaction recovery1.首先oracle对比控制文件中检查点scn与数据文件头部scn,发现不一致但我开启一个事务,并不作提交时,首先来看控制文件中记录的 SCN情况:最近一次完全检查点checkpoint change scn:DATABASEENTRY***************************************************************************。。。。ControlfileCreationTimestamp08/21/201711:01:49Incmpltrecoveryscn:0x0000.00000000Resetlogsscn:0x0000.000e2006ResetlogsTimestamp08/21/201711:01:51Priorresetlogsscn:0x0000.00000001PriorresetlogsTimestamp08/24/201311:37:30RedoVersion:compatible=0xb200400#Datafiles=53,#Onlinefiles=53Databasecheckpoint:Thread=1scn:0x0009.01e35ecdThreads:#Enabled=1,#Open=1,Head=1,Tail=1这里是 Database checkpoint: Thread=1 scn: 0x0009.01e35ecd,转换之后是38686383821。而增量检查点SCNCHECKPOINTPROGRESSRECORDS***************************************************************************(size=8180,compatsize=8180,sectionmax=11,sectionin-use=0,last-recid=0,old-recno=0,last-recno=0)(extent=1,blkno=2,numrecs=11)THREAD#1-status:0x2flags:0x0dirty:15lowcacherba:(0x413.18481.0)〉〉〉起点ondiskrba:(0x413.1849b.0)〉〉〉终点ondiskscn:0x0009.01e374ef07/24/201910:23:54resetlogsscn:0x0000.000e200608/21/201711:01:51heartbeat:996528373mountid:1186014334low cache rba就是CKPT记录的DBWR写脏块的进度是最近一次完全checkpoint scn 的位置, on disk rba就是LGWR的写进度,是 lgwr 写日志文件的最末位置的地址low cache rba 以前的更新的脏块已经写入数据文件,不需要重做, on disk rba以后的日志还没写入到online logfile.所以不需要恢复.而此时有15个脏块。on disk scn表示当前系统最新的rba对应的scn,由CKPT进程每3秒跟新一次。如果数据库异常宕机,那么CRASH RECOVER时服务器至少要应用到该SCN为止。这里的增量检查点SCN是38686389487,这个scn会比全量检查点后的SCN大。控制文件中记录的数据文件 SCN:DATAFILE#14:name#18:/opt/app/oracle/oradata/xxxx/xxxcreationsize=2097152blocksize=8192status=0xehead=18tail=18dup=1tablespace7,index=7krfil=14prev_file=13unrecoverablescn:0x0000.0000000001/01/198800:00:00Checkpointcnt:1061scn:0x0009.01e35ecd07/24/201907:30:51Stopscn:0xffff.ffffffff09/27/201809:20:13CreationCheckpointedatscn:0x0000.000f421208/21/201712:03:57thread:1rba:(0x8.3f45.10)这里记录的数据文件的scn
也同样是38686383821,而Stop scn是无穷大,表示当前数据库是正常打开状态,或者异常关闭状态。再看数据文件头中SCN:oradebugdumpfile_hdrs1DATAFILE#14:name#18:/opt/app/oracle/oradata/xxxx/xxxcreationsize=2097152blocksize=8192status=0xehead=18tail=18dup=1tablespace7,index=7krfil=14prev_file=13unrecoverablescn:0x0000.0000000001/01/198800:00:00Checkpointcnt:1061scn:0x0009.01e35ecd07/24/201907:30:51这里记录的数据文件头SCN
与控制文件中记录的一致。以上这种情况当发现控制文件中数据文件的SCN与数据文件头中记录 的SCN一致,即不会发生介质恢复。当启动时发现Stop scn是无穷大,则表示数据库是异常关闭了,需要进行crash recovery,即回滚。而其中增量检查点的作用就是记录了该从哪个地方回滚到那个地方。此时,我们 模式 数据库crash ,然后重启:alterdatabaseopenBeginningcrashrecoveryof1threadsparallelrecoverystartedwith32processesStartedredoscanCompletedredoscanread16KBredo,14datablocksneedrecoveryStartedredoapplicationatThread1:logseq1043,block185196RecoveryofOnlineRedoLog:Thread1Group2Seq1043Readingmem0Mem#0:/opt/app/oracle/oradata/tlvdb/redo2.logCompletedredoapplicationof0.01MBCompletedcrashrecoveryatThread1:logseq1043,block185228,scn38686432573《〈〈〈〈〈〈〈〈14datablocksread,14datablockswritten,16redok-bytesreadWedJul2423:44:502019Thread1advancedtologsequence1044(threadopen)Thread1openedatlogsequence1044Currentlog#3seq#1044mem#0:/opt/app/oracle/oradata/tlvdb/redo3.logSuccessfulopenofredothread1MTTRadvisoryisdisabledbecauseFAST_START_MTTR_TARGETisnotsetWedJul2423:44:502019SMON:enablingcacherecovery[39962]SuccessfullyonlinedUndoTablespace2.Undoinitializationfinishedserial:0start:193329648end:193329738diff:90(0seconds)Verifyingfileheadercompatibilityfor11gtablespaceencryption..Verifying11gfileheadercompatibilityfortablespaceencryptioncompletedSMON:enablingtxrecoveryDatabaseCharactersetisZHS16GBK2.从最后检查点之后到日志文件尾部将被重新应用到数据文件,同时产生undo信息(回滚),此阶段也称为cache recovery当数据库中有已经COMMIT但没有写入磁盘的数据块,当数据库CRASH后重启,会从控制文件中最近一次完全检查点位置到最后一次增量检查点位置,例如上面从38686383821到38686389487。然后到redo日志文件中找到该检查点位置,然后从该检查点位置开始往下到增量检查点位置,应用所有的redo,而其寻找redo条目是从low cache rba到on disk rba,从而在buffer cache里又恢复了实例崩溃那个时间点的状态。这个过程叫做前滚,前滚完毕以后,buffer cache里既有崩溃时已经提交还没有写入数据文件的脏数据块,也还有事务被突然终止,而导致的既没有提交又没有回滚的事务所弄脏的数据块。可以把这个过程的redo给dump出来:SQL>ALTERSYSTEMDUMPLOGFILE’/opt/app/oracle/oradata/tlvdb/redo1.log’SCNMIN38686383821SCNMAX38686389487;Systemaltered.Opcodes*.*RBAs:0x000000.00000000.0000thru0xffffffff.ffffffff.ffffSCNs:scn:0x0009.01e35ecd(38686383821)thruscn:0x0009.01e374ef(38686389487)Times:creationthrueternityFILEHEADER:。。。。ControlSeq=459718=0x703c6,Filesize=4194304=0x400000FileNumber=1,Blksiz=512,FileType=2LOGdescrip:”Thread0001,Seq#0000001042,SCN0x000901d8f38d-0x000901e35ecd”thread:1nab:0x384d91seq:0x00000412hws:0x3eot:0dis:0resetlogscount:0x38c7849fscn:0x0000.000e2006(925702)prevresetlogscount:0x3121c97ascn:0x0000.00000001(1)Lowscn:0x0009.01d8f38d(38685701005)07/08/201909:24:12Nextscn:0x0009.01e35ecd(38686383821)07/24/201907:30:51Enabledscn:0x0000.000e2006(925702)08/21/201711:01:51Threadclosedscn:0x0009.01d8f38d(38685701005)07/08/201909:24:12Diskcksum:0x56caCalccksum:0x56caTerminalrecoverystopscn:0x0000.00000000Terminalrecovery01/01/198800:00:00Mostrecentredoscn:0x0000.00000000LargestLWN:2395blocks3.数据文件中包含已提交或未提交的数据,尽管存在未提交的数据,此时数据库已经被打开,允许用户连接,此时针对未提交的事务被进行回滚前滚一旦完毕,SMON进程立即打开数据库。但是,这时的数据库中还含有那些中间状态的、既没有提交又没有回滚的脏块,这种脏块是不能存在于数据库中的,因为它们并没有被提交,必须被回滚。打开数据库以后,SMON进程会在后台进行回滚,此时会从Undo空间中寻找到旧版本SCN的数据块信息,来进行SGA中Buffer Cache数据块恢复。几个疑问:一,当log buffer 中的数据还没来得及写入redo file,此时数据库crash掉,那这部分丢失redo怎么办?Oracle 采取在事务提交的时候将和这个事务相关的REDO LOG 数据,包括COMMIT 记录,都必须从LOG BUFFER 中写入REDO LOG 文件,此时事务提交成功的信号才能发送给用户进程。这样便可以确保当已经提交的事务中的部分BUFFER CACHE 还没有被写入数据文件时发生了实例故障,在重启后做实例恢复的时候,也可以通过REDO LOG 的信息,将不一致的数据前滚。如果某事务未提交,此时产生的REDO仍在LOG BUFFER中,当数据库突然CRASH,log buffer数据也丢失了,我们可以确认这部分数据是没有提交的,将会被回滚,但是,redo信息没有写入磁盘,不存在了。也没办法通过redo 构造数据块,怎么办?其实这里是理解错了,未写入redo_file,也未写入db_file,那么发生数据库失败恢复时,数据库将直接丢弃该DML操作,反正该操作尚未commit,丢掉了也没关系,并且因为未写入数据文件,没必要进行构造UNDO回滚。二、UNDO有没有写缓存情况,如果有UNDO丢失怎么办?undo 有undo buffer ,从以上可以看出,redo 日志会记录了事务的 redo 和undo信息。所以不用担心三、实例恢复过程主要使用的四个SCN:Control file三个地方为:1、System checkpoint SCNselect checkpoint_change# from v$database;这里应该有完整检查点的SCN,完整检查点的SCN会更新数据文件及数据文件头的SCN, 增量检查点SCN只在控制文件中更新。2、Datafile checkpoint SCNset linesize 400col name for a50select name, checkpoint_change# from v$datafile where file#=14;3、 Stop SCNselect name,last_change# from v$datafile where file#=14;正常datafile在read-write mode运作下,last_change#一定是null还有一个SCN在datafile header内4、 Start SCNselect name,checkpoint_change# from v$datafile_header where file#=14;到此,关于“ORACLE事务和实例的恢复过程讲解”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注百云网站,小编会继续努力为大家带来更多实用的文章!

相关推荐: redis通过命令行批量删除key的方法

这篇文章给大家分享的是有关redis通过命令行批量删除key的方法的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。可用的方法有:1、使用cliFLUSH免费云主机域名DB 清除一个数据库,FLUSHALL清除整个redis数据。2、使…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

(0)
打赏 微信扫一扫 微信扫一扫
上一篇 01/05 22:04
下一篇 01/05 22:31