[20170526]GLOBAL_NAME为NULL的修复2.txt
--//昨天看了www.oratea.com/2017/05/22/%e4%bf%ae%e6%94%b9props%e7%9a%84global_db_name%e4%b8%ba%e7%a9%ba%e5%90%8e%e7%9a%84%e6%81%a2%e5%a4%8d%e8%bf%87%e7%a8%8b/
--//提到修改update props$ set value$ = null where name = 'GLOBAL_DB_NAME';会导致下次开机无法正常系统,lz采用gdb设置断点break kokiasg,来修复这个问题.
--//我记得第一次这样做是熊军.
--//我以前也写过类似的文章:
http://blog.itpub.net/267265/viewspace-746031/
http://blog.itpub.net/267265/viewspace-746032/
http://blog.itpub.net/267265/viewspace-746080/
--//当时为了学习bbed,而且才开始学,采用bbed修复思路很乱.现在再重复测试看看.
1.环境:
SCOTT@book> @ &r/ver1
PORT_STRING VERSION BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx 11.2.0.4.0 Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
SCOTT@book> select value$ from sys.props$ where name = 'GLOBAL_DB_NAME';
VALUE$
------------------------------
BOOK
SCOTT@book> select rowid,ora_rowscn, a.* from sys.props$ a where name = 'GLOBAL_DB_NAME';
ROWID ORA_ROWSCN NAME VALUE$ COMMENT$
------------------ ------------ -------------------- ------- --------------------
AAAABiAABAAAAMhAAf 991533 GLOBAL_DB_NAME BOOK Global database name
SCOTT@book> @ &r/rowid AAAABiAABAAAAMhAAf
OBJECT FILE BLOCK ROW ROWID_DBA DBA TEXT
------------ ------------ ------------ ------------ -------------------- -------------------- ----------------------------------------
98 1 801 31 0x400321 1,801 alter system dump datafile 1 block 801 ;
--//注:出现问题这些信息的位置基本固定,可以从另外的机器获得.
2.问题再现:
SYS@book> update sys.props$ set value$ = null where name = 'GLOBAL_DB_NAME';
1 row updated.
SYS@book> commit ;
Commit complete.
SYS@book> shutdown abort ;
ORACLE instance shut down.
SYS@book> startup
ORACLE instance started.
Total System Global Area 634732544 bytes
Fixed Size 2255792 bytes
Variable Size 197133392 bytes
Database Buffers 427819008 bytes
Redo Buffers 7524352 bytes
Database mounted.
ORA-01092: ORACLE instance terminated. Disconnection forced
ORA-00600: internal error code, arguments: [18062], [], [], [], [], [], [], [], [], [], [], []
Process ID: 42648
Session ID: 232 Serial number: 3
--//不知道从转储内容如何看,估计采用10046跟踪也许好定位一些.
$ grep select /u01/app/oracle/diag/rdbms/book/book/incident/incdir_1356848/book_ora_42648_i1356848.trc | head
ObjectName: Name=select value$ from props$ where name = 'GLOBAL_DB_NAME'
ObjectName: Name=select value$ from sys.props$ where name = :1
ObjectName: Name=select u.name, o.name, a.interface_version#, o.obj# from association$ a, user$ u, obj$ o where a.obj# = :1 and a.property = :2 and a.statstype# = o.obj# and u.user# = o.owner#
3.bbed修复:
BBED> x /rccc dba 1,801 *kdbr[31]
rowdata[0] @5957
----------
flag@5957: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@5958: 0x02
cols@5959: 3
col 0[14] @5960: GLOBAL_DB_NAME
col 1[0] @5975: *NULL*
col 2[20] @5976: Global database name
BBED> find /c GLOBAL_DB_NAME top
File: /mnt/ramdisk/book/system01.dbf (1)
Block: 801 Offsets: 5961 to 6024 Dba:0x00400321
------------------------------------------------------------------------------------------------------------------------------------------------
474c4f42 414c5f44 425f4e41 4d45ff14 476c6f62 616c2064 61746162 61736520 6e616d65 2c00030e 474c4f42 414c5f44 425f4e41 4d450442 4f4f4b14 476c6f62
<64 bytes per line>
BBED> set offset 5971
OFFSET 5971
--//注意偏移不要加的太大,避免错过.
BBED> find /c GLOBAL_DB_NAME
File: /mnt/ramdisk/book/system01.dbf (1)
Block: 801 Offsets: 6001 to 6064 Dba:0x00400321
------------------------------------------------------------------------------------------------------------------------------------------------
474c4f42 414c5f44 425f4e41 4d450442 4f4f4b14 476c6f62 616c2064 61746162 61736520 6e616d65 2c00030a 44425449 4d455a4f 4e450530 303a3030 0c444220
<64 bytes per line>
--//注:数据一般从底部插入,第1个找到的位置就是当前数据,而第2个找到的位置就是修改前的记录. 这样原来的位置 6001-4=5997
BBED> x /rccc dba 1,801 offset 5997
rowdata[40] @5997
-----------
flag@5997: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@5998: 0x00
cols@5999: 3
col 0[14] @6000: GLOBAL_DB_NAME
col 1[4] @6015: BOOK
col 2[20] @6020: Global database name
--//如果你继续查询还可以发现如下,说明原来最原始的名字是SEEDDATA,估计是oracle安装的种子数据库.
BBED> x /rccc dba 1,801 offset 6457
rowdata[500] @6457
------------
flag@6457: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@6458: 0x00
cols@6459: 3
col 0[14] @6460: GLOBAL_DB_NAME
col 1[8] @6475: SEEDDATA
col 2[20] @6484: Global database name
=======================
BBED> p kdbr[31]
sb2 kdbr[31] @172 5865
BBED> p kdbh
struct kdbh, 14 bytes @92
ub1 kdbhflag @92 0x00 (NONE)
sb1 kdbhntab @93 1
sb2 kdbhnrow @94 37
sb2 kdbhfrre @96 6
sb2 kdbhfsbo @98 92
sb2 kdbhfseo @100 5865
sb2 kdbhavsp @102 6042
sb2 kdbhtosp @104 6046
--//kdbr记录的行偏移从kdbh偏移算起,相差92. 5957-5865=92
--//这样仅仅修改5997-92=5905就ok了.
BBED> assign kdbr[31]=5905
sb2 kdbr[0] @172 5905
BBED> x /rccc dba 1,801 *kdbr[31]
rowdata[40] @5997
-----------
flag@5997: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@5998: 0x00
cols@5999: 3
col 0[14] @6000: GLOBAL_DB_NAME
col 1[4] @6015: BOOK
col 2[20] @6020: Global database name
BBED> sum apply dba 1,801
Check value for File 1, Block 801:
current = 0xa776, required = 0xa776
BBED> verify dba 1,801
DBVERIFY - Verification starting
FILE = /mnt/ramdisk/book/system01.dbf
BLOCK = 801
Block Checking: DBA = 4195105, Block Type = KTB-managed data block
data header at 0x7fc309ad825c
kdbchk: xaction header lock count mismatch
trans=2 ilk=1 nlo=0
Block 801 failed with check code 6108
--//lock@5998: 0x00 要修改为0x02. 参考前面(lock@5958: 0x02).
BBED> modify /x 0x02 offset 5998
File: /mnt/ramdisk/book/system01.dbf (1)
Block: 801 Offsets: 5998 to 6013 Dba:0x00400321
------------------------------------------------------------------------------------------------------------------------------------------------
02030e47 4c4f4241 4c5f4442 5f4e414d
<64 bytes per line>
BBED> x /rccc dba 1,801 *kdbr[31]
rowdata[40] @5997
-----------
flag@5997: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@5998: 0x02
cols@5999: 3
col 0[14] @6000: GLOBAL_DB_NAME
col 1[4] @6015: BOOK
col 2[20] @6020: Global database name
BBED> sum apply dba 1,801
Check value for File 1, Block 801:
current = 0xa774, required = 0xa774
BBED> verify dba 1,801
DBVERIFY - Verification starting
FILE = /mnt/ramdisk/book/system01.dbf
BLOCK = 801
Block Checking: DBA = 4195105, Block Type = KTB-managed data block
data header at 0x1548c5c
kdbchk: the amount of space used is not equal to block size
used=2054 fsc=4 avsp=6042 dtl=8096
Block 801 failed with check code 6110
--//实际上到这里基本结束,以下可以不修复.
--//A.设置ktbbh.ktbbhitl[1]._ktbitfsc=0
BBED> p ktbbh.ktbbhitl[1]
struct ktbbhitl[1], 24 bytes @68
struct ktbitxid, 8 bytes @68
ub2 kxidusn @68 0x0014
ub2 kxidslt @70 0x000c
ub4 kxidsqn @72 0x000005ec
struct ktbituba, 8 bytes @76
ub4 kubadba @76 0x01c0028f
ub2 kubaseq @80 0x014e
ub1 kubarec @82 0x19
ub2 ktbitflg @84 0x0001 (NONE)
union _ktbitun, 2 bytes @86
sb2 _ktbitfsc @86 4
ub2 _ktbitwrp @86 0x0004
ub4 ktbitbas @88 0x00000000
--//首先设置ktbbh.ktbbhitl[1]._ktbitun._ktbitfsc=0
BBED> assign ktbbh.ktbbhitl[1]._ktbitun._ktbitfsc=0
sb2 _ktbitfsc @86 0
BBED> sum apply dba 1,801
Check value for File 1, Block 801:
current = 0xa770, required = 0xa770
BBED> verify dba 1,801
DBVERIFY - Verification starting
FILE = /mnt/ramdisk/book/system01.dbf
BLOCK = 801
Block Checking: DBA = 4195105, Block Type = KTB-managed data block
data header at 0x1548c5c
kdbchk: space available on commit is incorrect
tosp=6046 fsc=0 stb=0 avsp=6042
Block 801 failed with check code 6111
--//B.设置assign kdbh.kdbhtosp=6042
BBED> assign kdbh.kdbhtosp=6042
sb2 kdbhtosp @104 6042
BBED> sum apply dba 1,801
Check value for File 1, Block 801:
current = 0xa774, required = 0xa774
BBED> verify dba 1,801
DBVERIFY - Verification starting
FILE = /mnt/ramdisk/book/system01.dbf
BLOCK = 801
--//OK,现在修复完成.
4.启动看看:
SYS@book> startup open read only
ORACLE instance started.
Total System Global Area 634732544 bytes
Fixed Size 2255792 bytes
Variable Size 197133392 bytes
Database Buffers 427819008 bytes
Redo Buffers 7524352 bytes
Database mounted.
ORA-16005: database requires recovery
SYS@book> recover database ;
Media recovery complete.
SYS@book> alter database open read only;
alter database open read only
*
ERROR at line 1:
ORA-16005: database requires recovery
--//经过shutdown abort的数据库,不能第1次open read only打开.
SYS@book> @ &r/chscn
FILE# NAME STATUS FUZ 数据库记录的scn 控制文件记录的开始scn 控制文件记录的结束scn 数据文件头记录的scn TABLESPACE_NAME
----- -------------------------------- ------- --- --------------- --------------------- --------------------- ------------------- --------------------
1 /mnt/ramdisk/book/system01.dbf ONLINE NO 13278617901 13278638196 13278638196 13278638196 SYSTEM
2 /mnt/ramdisk/book/sysaux01.dbf ONLINE NO 13278617901 13278638196 13278638196 13278638196 SYSAUX
3 /mnt/ramdisk/book/undotbs01.dbf ONLINE NO 13278617901 13278638196 13278638196 13278638196 UNDOTBS1
4 /mnt/ramdisk/book/users01.dbf ONLINE NO 13278617901 13278638196 13278638196 13278638196 USERS
5 /mnt/ramdisk/book/example01.dbf ONLINE NO 13278617901 13278638196 13278638196 13278638196 EXAMPLE
6 /mnt/ramdisk/book/tea01.dbf ONLINE NO 13278617901 13278638196 13278638196 13278638196 TEA
7 /mnt/ramdisk/book/undotbs02.dbf ONLINE NO 13278617901 13278638196 13278638196 13278638196 UNDOTBS2
7 rows selected.
--//估计这种情况是控制文件里面记录的scn还是13278617901,如果是13278638196估计可以.
SYS@book> alter database open ;
Database altered.
SYS@book> column VALUE$ format a30
SYS@book> select rowid,ora_rowscn, a.* from sys.props$ a where name = 'GLOBAL_DB_NAME';
ROWID ORA_ROWSCN NAME VALUE$ COMMENT$
------------------ ------------ -------------- ------ --------------------
AAAABiAABAAAAMhAAf 13278597868 GLOBAL_DB_NAME BOOK Global database name
--//实际上如果备份,使用bbed的copy命令更简单一些.