Oracle redolog文件头信息解读

梁铭图 2019-07-18 21:07:00
 

​作者介绍

梁铭图,新炬网络首席架构师,十多年数据库运维、数据库设计、数据治理以及系统规划建设经验,拥有Oracle OCM、Togaf企业架构师(鉴定级)、IBM CATE等认证,曾获dbaplus年度MVP以及华为云MVP等荣誉,并参与数据资产管理国家标准的编写工作。在数据库运维管理和架构设计、运维体系规划、数据资产管理方面有深入研究。

 

Oracle 的Online redo log 是为确保已经提交的事务不会丢失而建立的一个机制。因为这种健全的机制,才能让我们在数据库crash时,恢复数据,保证数据不丢失。一般而言,数据库随着数据库操作会不断将操作条目写入redo log,并且通过归档的方式备份操作日志加以备份。

 

日常运维中使用redo log的常用场景主要包括:

 

  • 数据库crash后的恢复。

  • 数据库从备份介质中的恢复。

  • 数据实时同步工具(OGG、DSG)从中挖掘数据变化信息。

  • ADG向远端同步。

  • ……

 

从手中的资料可查Oracle 日志文件的格式如下:

 

redo logfile的结构

 

 

block 0: file header

block 1: redo header

block 2: redo record 1

block 3: redo record 2

...

...

block N: redo record n

 

本文主要分析一下Redo log里面文件头里的信息。

 

一、准备工作

 

使用dbfsize(oracle自带工具)可以查看redo logfile信息。

 

 

SQL> col member for a40

SQL> select member from v$logfile;

MEMBER

----------------------------------------

/u01/app/oradata/test/redo03.log

/u01/app/oradata/test/redo02.log

/u01/app/oradata/test/redo01.log

 

SQL> exit

Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production

With the Partitioning, OLAP, Data Mining and Real Application Testing options

 

$ dbfsize /u01/app/oradata/test/redo01.log

Database file: /u01/app/oradata/test/redo01.log

Database file type: file system

Database file size: 102400 512 byte blocks

<=====含义是redo块的大小是512字节,一共有102400个块

 

 

SQL> col member for a40

SQL> select a.member, b.bytes from v$logfile a, v$log b where a.group#=b.group#;

MEMBER   BYTES

---------------------------------------- ----------

/u01/app/oradata/QXY/redo03.log   52428800

/u01/app/oradata/QXY/redo02.log   52428800

/u01/app/oradata/QXY/redo01.log   52428800

 

跟数据库查询的结果是一致的。

 

二、解读redo logfile的文件头

 

解析redo logfile header block(redo文件的第一个块):

 

 

$ dd if=/u01/app/oradata/test/redo01.log bs=512 count=1 | od -x

1+0 records in

1+0 records out

512 bytes (512 B) copied, 3.0992e-05 s, 16.5 MB/s

0000000 2200 0000 0000 ffc0 0000 0000 0000 0000     <======第一行

0000020 c867 0000 0200 0000 9000 0001 7c7d 7a7b              二

0000040 81a0 0000 0000 0000 0000 0000 0000 0000              三

0000060 0000 0000 0000 0000 0000 0000 0000 0000              四

*

0001000

 

其中可读取的信息为:

 

 

第一行的 2200     ----表示file type,0x22代表redo logfile

第二行的 0200     ----表示redo block 大小,转换成十进制为512

第二行的 9000 0001 -----大小端转换后是00019000,转换成十进制为102400

第二行的 7c7d 7a7b -----代表逻辑号

 

可以看到通过dd+od的方式读取的redo logfile的第一块的内容和dbfsize看到的数据一致,redo logfile 文件头主要描述该该文件是什么类型的文件,每个块大小是多少,一共有多少个块等。

 

解读redo logfile的redo header(第二个块):

 

 

$ dd if=/u01/app/oradata/test/redo01.log skip=1 bs=512 count=1 | od -x  <=====skip=1,也就是跳过redo logfile的文件头块(第一个块)

1+0 records in

1+0 records out

512 bytes (512 B) copied, 3.5083e-05 s, 14.6 MB/s

0000000 2201 0000 0001 0000 0001 0000 8000 6f2c

0000020 0000 0000 0000 0b20 f07a fc4a 5851 0059

0000040 0000 0000 448a 0000 9000 0001 0200 0000

0000060 0001 0002 80c2 ff13 0000 0000 0000 0000

0000100 0000 0000 0000 0000 0000 0000 0000 0000

0000120 0000 0000 0000 0000 0000 0000 6854 6572

0000140 6461 3020 3030 2c31 5320 7165 2023 3030

0000160 3030 3030 3030 3130 202c 4353 204e 7830

0000200 3030 3030 3130 6637 3639 3331 302d 3078

0000220 3030 3030 3731 6666 3463 0063 4804 0000

0000240 ea1c 3ad1 9613 017f 0000 0000 0006 0000

0000260 0001 0000 9613 017f 0000 0000 ea1c 3ad1

0000300 fc4c 017f 0000 0000 4967 3ad3 0000 0208

0000320 9613 017f 0000 0000 ea1c 3ad1 fc4a 017f

0000340 0000 0000 28da 3ad2 0000 0000 0000 0080

0000360 0000 0000 0000 0000 0000 0000 0002 0000

0000400 0000 0000 0000 0000 0000 0000 0000 0000

0000420 0000 0000 0000 0000 0000 0000 9392 017f

0000440 0000 0000 e8f9 3ad1 0000 0000 0000 0000

0000460 0000 0000 0000 0000 0000 0000 0000 0000

*

0000700 5b73 a77c 06b1 482f 5802 3aaa a734 35fa

0000720 5e8c 05f2 25fe 9da5 996b 149e 5f26 1e03

0000740 0005 0000 0000 0000 0000 0000 0000 0000

0000760 0000 0000 0000 0000 0000 0000 0000 0000

0001000

 

offset 0~1  :2201    ----表示redo logfile block,redo block的第一个块都是这个值

offset 4~5  :0001    ----表示redo log block nuber号

offset 8~9  :0001    ----表示redo log sequence 号

offset 12~13:8000    ----表示offset值

 

上面部分内容结合在一起,就是redo的RBA信息。

 

 

RBA = logseq+log block number +offset = 0x000001.00000001.0008

 

offset 14~15: 6f2c   ----表示checksum

offset 20~23:0000 0b20   ----表示db version , 对应redo dump里面的 Compatibility Vsn = 186646528=0xb200000

offset 24~27: f07a fc4a   ----表示DB ID值,大小端转换后为fc4af07a,转换10进制为4232769658

offset 28~33: 5851 0059 0000  ----代表DB Name

offset 36~37 :448a   ----表示control seq的值,转换成10进制为17546

offset 40~43 :9000 0001  ----表示file size,单位是redo block个数,转换成10进制为102400

offset 44~45 :0200      ----表示redo block size的大小,转换成10进制为512

offset 48~49 :0001     ----表示file number号,代表当前是redo的第一个文件

offset 50~51 :0002     ----表示file type的值,redo文件都是0002.

offset 52~55 :80c2 ff13  ---表示Activation ID的值,转换成10进制

offset 92~103:6854 6572 6461 3020 3030 2c31 -----代表"Thread 0001,"字符串

offset 104~121: 5320 7165 2023 3030 3030 3030 3030 3130 202c   -----代表log seq号 "Seq# 0000000001,"

offset 122~153: 4353 204e 7830 3030 3030 3130 6637 3639 3331 302d 3078 3030 3030 3731 6666 3463  ----代表SCN的范围

offset 154~159: 0063 4804 0000    ---表示thread nab的值

offset 160~163:ea1c 3ad1         ---表示resetlogs count的值

offset 164~167:9613 017f         ---表示resetlogs的scn值

offset 172~173: 0006              ---表示hws的值

offset 176~177:0001              ---表示eot的值

offset 180~183:9613 017f         ---low scn的值

offset 188~191:ea1c 3ad1         ---表示resetlogs的值

offset 192~195:fc4c 017f         ---next scn的值

offset 207~210:9613 017f         ---Enabled scn的值

offset 219~222:fc4a 017f         ---Thread closed scn的值

 

下面是redo dump的信息来进一步说明。

 

 

SQL> alter system dump logfile '/u01/app/oradata/test/redo01.log';

System altered.

<=====redo 文件头信息

 

 

DUMP OF REDO FROM FILE '/u01/app/oradata/test/redo01.log'

 Opcodes *.*

 RBAs: 0x000000.00000000.0000 thru 0xffffffff.ffffffff.ffff

 SCNs: scn: 0x0000.00000000 thru scn: 0xffff.ffffffff

 Times: creation thru eternity

 FILE HEADER: 

        Compatibility Vsn = 186646528=0xb200000   <=====对应offset 20~23

        Db ID=4232769658=0xfc4af07a, Db Name='QXY'<=====分别对应offset 24~33

FILE HEADER:

        Compatibility Vsn = 186646528=0xb200000

        Db ID=4232769658=0xfc4af07a, Db Name='test'

        Activation ID=4279468226=0xff1380c2

        Control Seq=17546=0x448a, File size=102400=0x19000   <======对应offset 36~43

        File Number=1, Blksiz=512, File Type=2 LOG           <======对应offset 44~51

 descrip:"Thread 0001, Seq# 0000000001, SCN 0x0000017f9613-0x0000017ffc4c"  <======对应offset 92~153

 thread: 1 nab: 0x4804 seq: 0x00000001 hws: 0x6 eot: 0 dis: 0       <======对应offset 154~177

 resetlogs count: 0x3ad1ea1c scn: 0x0000.017f9613 (25138707)        

 prev resetlogs count: 0x3ad1e8f9 scn: 0x0000.017f9392 (25138066)

 Low  scn: 0x0000.017f9613 (25138707) 09/14/2018 16:58:04      <===对应offset 180~183

 Next scn: 0x0000.017ffc4c (25164876) 09/15/2018 17:56:55      <===对应offset 192~195

 Enabled scn: 0x0000.017f9613 (25138707) 09/14/2018 16:58:04   <===对应offset 207~210

 Thread closed scn: 0x0000.017ffc4a (25164874) 09/14/2018 21:25:46  <====对应offset219~222

 Disk cksum: 0x6f2c Calc cksum: 0x6f2c

 Terminal recovery stop scn: 0x0000.00000000

 Terminal recovery  01/01/1988 00:00:00

 Most recent redo scn: 0x0000.00000000

 

模拟redo header损坏。

 

替换之前DBID的值如下:

 

 

$ dd if=/u01/app/oradata/QXY/redo01.log skip=1 bs=512 count=1 | od -x

1+0 records in

1+0 records out

512 bytes (512 B) copied, 3.4274e-05 s, 14.9 MB/s

0000000 2201 0000 0001 0000 0001 0000 8000 6f79

0000020 0000 0000 0000 0b20 f07a fc4a 5851 0059   <=====f07a fc4a

0000040 0000 0000 44de 0000 9000 0001 0200 0000

0000060 0001 0002 80c2 ff13 0000 0000 0000 0000

0000100 0000 0000 0000 0000 0000 0000 0000 0000

 

用4个A执行替换:

 

 

[oracle@qxy QXY]$ echo AAAA |dd of=/u01/app/oradata/QXY/redo01.log seek=536 bs=1 count=4 conv=notrunc

4+0 records in

4+0 records out

4 bytes (4 B) copied, 4.9324e-05 s, 81.1 kB/s

 

其中seek=536代表跳过536个字节,其中536=512+24,其中512为第一个块redo file header 然后加上第二个块的偏移量24,正好为DBID所在的位置。

 

再次查询:

 

[oracle@qxy QXY]$ dd if=/u01/app/oradata/QXY/redo01.log skip=1 bs=512 count=1 | od -x

1+0 records in

1+0 records out

512 bytes (512 B) copied, 4.0794e-05 s, 12.6 MB/s

0000000 2201 0000 0001 0000 0001 0000 8000 6f79

0000020 0000 0000 0000 0b20 4141 4141 5851 0059  <====这里从原来的f07a fc4a 变成了4141 4141(即AAAA)

0000040 0000 0000 44de 0000 9000 0001 0200 0000

0000060 0001 0002 80c2 ff13 0000 0000 0000 0000

 

重新启动数据库,数据库报错如下:

 

 

SQL> startup 

ORACLE instance started.

 

Total System Global Area  776646656 bytes

Fixed Size                  2232392 bytes

Variable Size             603983800 bytes

Database Buffers          163577856 bytes

Redo Buffers                6852608 bytes

Database mounted.

ORA-00366: log 1 of thread 1, checksum error in the file header

ORA-00312: online log 1 thread 1: '/u01/app/oradata/QXY/redo01.log'

 

Alert日志错误如下:

 

starting up 1 shared server(s) ...

ORACLE_BASE from environment = /u01/app

Sat Sep 15 23:41:57 2018

ALTER DATABASE   MOUNT

Successful mount of redo thread 1, with mount id 4279599365

Database mounted in Exclusive Mode

Lost write protection disabled

Completed: ALTER DATABASE   MOUNT

Sat Sep 15 23:42:01 2018

ALTER DATABASE OPEN

Beginning crash recovery of 1 threads

 parallel recovery started with 2 processes

Started redo scan

Errors in file /u01/app/diag/rdbms/qxy/QXY/trace/QXY_ora_4176.trc:

ORA-00366: log 1 of thread 1, checksum error in the file header

ORA-00312: online log 1 thread 1: '/u01/app/oradata/QXY/redo01.log'

Aborting crash recovery due to error 366

Errors in file /u01/app/diag/rdbms/qxy/QXY/trace/QXY_ora_4176.trc:

ORA-00366: log 1 of thread 1, checksum error in the file header

ORA-00312: online log 1 thread 1: '/u01/app/oradata/QXY/redo01.log'

Errors in file /u01/app/diag/rdbms/qxy/QXY/trace/QXY_ora_4176.trc:

ORA-00366: log 1 of thread 1, checksum error in the file header

ORA-00312: online log 1 thread 1: '/u01/app/oradata/QXY/redo01.log'

ORA-366 signalled during: ALTER DATABASE OPEN...

Sat Sep 15 23:42:01 2018

Errors in file /u01/app/diag/rdbms/qxy/QXY/trace/QXY_m000_4182.trc:

ORA-00366: log 1 of thread 1, checksum error in the file header

ORA-00312: online log 1 thread 1: '/u01/app/oradata/QXY/redo01.log'

Checker run found 2 new persistent data failures

 

查看trace的信息:

 

 

more /u01/app/diag/rdbms/qxy/test/trace/test_ora_4176.trc

Trace file /u01/app/diag/rdbms/test/test/trace/test_ora_4176.trc

Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production

With the Partitioning, OLAP, Data Mining and Real Application Testing options

ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1

System name:    Linux

Node name:      test

Release:        2.6.32-431.el6.x86_64

Version:        #1 SMP Sun Nov 10 22:19:54 EST 2013

Machine:        x86_64

VM name:        VMWare Version: 6

Instance name: test

Redo thread mounted by this instance: 1

Oracle process number: 19

Unix process pid: 4176, image: oracle@test (TNS V1-V3)

 

 

*** 2018-09-15 23:42:01.720

*** SESSION ID:(125.5) 2018-09-15 23:42:01.720

*** CLIENT ID:() 2018-09-15 23:42:01.720

*** SERVICE NAME:() 2018-09-15 23:42:01.720

*** MODULE NAME:(sqlplus@test (TNS V1-V3)) 2018-09-15 23:42:01.720

*** ACTION NAME:() 2018-09-15 23:42:01.720

 

 

Successfully allocated 2 recovery slaves

Using 67 overflow buffers per recovery slave

Thread 1 checkpoint: logseq 4, block 83, scn 25197573

    on-disk rba: logseq 4, block 179, scn 25197821

  start recovery at logseq 4, block 179, scn 25197821

DDE rules only execution for: ORA 312

----- START Event Driven Actions Dump ----

---- END Event Driven Actions Dump ----

----- START DDE Actions Dump -----

Executing SYNC actions

----- START DDE Action: 'DB_STRUCTURE_INTEGRITY_CHECK' (Async) -----

Successfully dispatched

----- END DDE Action: 'DB_STRUCTURE_INTEGRITY_CHECK' (SUCCESS, 1 csec) -----

Executing ASYNC actions

----- END DDE Actions Dump (total 1 csec) -----

ORA-00366: log 1 of thread 1, checksum error in the file header

ORA-00312: online log 1 thread 1: '/u01/app/oradata/test/redo01.log'

ORA-00366: log 1 of thread 1, checksum error in the file header

ORA-00312: online log 1 thread 1: '/u01/app/oradata/test/redo01.log'

ORA-00366: log 1 of thread 1, checksum error in the file header

ORA-00312: online log 1 thread 1: '/u01/app/oradata/test/redo01.log'

 

这说明Oracle数据库启动时检验数据库redo文件头时出错,导致数据库实例恢复不成功。

 

要让数据库启动起来,还需要使用dd重新修改redo01.log文件的DBID的值。

 

 

$ dd if=redo02.log skip=536 bs=1 count=4 of=/u01/app/oradata/test/redo01.log seek=536 bs=1 count=4 conv=notrunc

4+0 records in

4+0 records out

4 bytes (4 B) copied, 0.000988096 s, 4.0 kB/s

 

检查一下修改后的值如下:

 

 

$ dd if=/u01/app/oradata/QXY/redo01.log skip=1 bs=512 count=1 | od -x

1+0 records in

1+0 records out

512 bytes (512 B) copied, 6.2949e-05 s, 8.1 MB/s

0000000 2201 0000 0001 0000 0004 0000 8000 6403

0000020 0000 0000 0000 0b20 f07a fc4a 5851 0059   <=====由原来的41414141变为f07a fc4a

0000040 0000 0000 44f3 0000 9000 0001 0200 0000

0000060 0001 0002 80c2 ff13 0000 0000 0000 0000

0000100 0000 0000 0000 0000 0000 0000 0000 0000

 

重新启动数据库:

 

 

SQL> startup

ORACLE instance started.

 

Total System Global Area  776646656 bytes

Fixed Size                  2232392 bytes

Variable Size             603983800 bytes

Database Buffers          163577856 bytes

Redo Buffers                6852608 bytes

Database mounted.

Database opened.                      <=====数据库正常启动

SQL> 

 

三、小结

 

如果能够对redo header比较了解的话,就可以使用特殊手段来修复一些redo lheader损坏的情况,特别是当current的redo header出现问题,这个时候更有必要修复。如果认真对比redo01.log和redo02.log的redo header会发现两个文件的数据基本都是一致的,只有个别地方是每个redo file特有的。所以当一个redo logfile header损坏的情况下,可以参考他正常redo header的内容来修复损坏的redo header。


最新评论
访客 2023年08月20日

230721

访客 2023年08月16日

1、导入Mongo Monitor监控工具表结构(mongo_monitor…

访客 2023年08月04日

上面提到: 在问题描述的架构图中我们可以看到,Click…

访客 2023年07月19日

PMM不香吗?

访客 2023年06月20日

如今看都很棒

活动预告