[20150804]提升scn2.txt
--有时候修复数据库,要避免一些ora-00600错误,要提升数据库的scn。自己花了1点时间google许多资料,做1个总结:
--安全起见,我做了一个冷备份。便于重复测试。
--拿比较常见的ORA-600 [2662]错误:
ORA-600 [2662] "Block SCN is ahead of Current SCN",说明当前数据库的数据块的SCN早于当前的SCN,主要是和存储在UGA变量中的
dependent SCN进行比较,如果当前的SCN小于它,数据库就会产生这个ORA-600 [2662]的错误了。这个错误一共有五个参数,分别代表不同的含义
ORA-600 [2662] [a] [b] {c} [d] [e]
Arg [a] Current SCN WRAP
Arg [b] Current SCN BASE
Arg {c} dependent SCN WRAP
Arg [d] dependent SCN BASE
Arg [e] Where present this is the DBA where the dependent SCN came from.
--已经写了1篇:
http://blog.itpub.net/267265/viewspace-1710054/
--大概总结:
1.一般常用的方法:
一种是在open的状态下:用alter session set events 'IMMEDIATE trace name adjust_scn level n';
一种是在mount状态下:用alter session set events '10015 trace name adjust_scn level n';
--说明以下level的计算,实际上level的单位是1g = 1024*1024*1024 =2^30.
--而1 wrap = 2^32 ,这样1wrap 必须乘以4,相当于 4 level。
--另外我的测试在10.2.0.4的情况下:以上两者方法都没有成功,不知道哪里出错了。
--这样ORA-600 [2662] "Block SCN is ahead of Current SCN"的错误,根据提示计算level的公式如下:
Arg {c}* 4得出一个数值,假设为V_Wrap
如果Arg [d]=0,则V_Wrap值为需要的level
Arg [d] < 1073741824(2^30*1),V_Wrap+1为需要的level
Arg [d] < 2147483648(2^30*2),V_Wrap+2为需要的level
Arg [d] < 3221225472(2^30*3),V_Wrap+3为需要的level
2.修改隐含参数_minimum_giga_scn:
--很简单按照上面计算出来的level。修改参数加入:
*._minimum_giga_scn=level
3.通过oradebug手工修改SCN:
SYS@test> oradebug setmypid
Statement processed.
SYS@test> oradebug DUMPvar SGA kcsgscn_
SYS@test> oradebug poke 0x0600122B0 4 0x50000097
....
当然还有其它方法,换一个思路,提供控制文件里面的scn看看:
1.建立测试环境:
SYS@test> @ver1
PORT_STRING VERSION BANNER
------------------------------ -------------- ----------------------------------------------------------------
x86_64/Linux 2.4.xx 10.2.0.4.0 Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
SYS@test> SELECT file#, CHECKPOINT_CHANGE#, UNRECOVERABLE_CHANGE# ,LAST_CHANGE#, OFFLINE_CHANGE#, ONLINE_CHANGE#,status FROM v$datafile;
FILE# CHECKPOINT_CHANGE# UNRECOVERABLE_CHANGE# LAST_CHANGE# OFFLINE_CHANGE# ONLINE_CHANGE# STATUS
------------ ------------------ --------------------- ------------ --------------- -------------- -------
1 12701762346 0 0 0 SYSTEM
2 12701762346 0 0 0 ONLINE
3 12701762346 0 0 0 ONLINE
4 12701762346 0 0 0 ONLINE
5 12701762346 0 0 0 ONLINE
6 12701762346 0 0 0 ONLINE
6 rows selected.
SYS@test> SELECT file#, CHECKPOINT_CHANGE#, CREATION_CHANGE# , RESETLOGS_CHANGE#,status, CHECKPOINT_COUNT,fuzzy FROM v$datafile_header;
FILE# CHECKPOINT_CHANGE# CREATION_CHANGE# RESETLOGS_CHANGE# STATUS CHECKPOINT_COUNT FUZ
------------ ------------------ ---------------- ----------------- ------- ---------------- ---
1 12701762346 5 12691748925 ONLINE 868465477 YES
2 12701762346 600647 12691748925 ONLINE 868465477 YES
3 12701762346 6678 12691748925 ONLINE 868465477 YES
4 12701762346 10685 12691748925 ONLINE 868465481 YES
5 12701762346 625439 12691748925 ONLINE 868465477 YES
6 12701762346 12695496030 12691748925 ONLINE 73 YES
6 rows selected.
SYS@test> SELECT 'controlfile' "SCN location", 'SYSTEM checkpoint' NAME, checkpoint_change#,open_mode,current_scn FROM v$database;
SCN locatio NAME CHECKPOINT_CHANGE# OPEN_MODE CURRENT_SCN
----------- -------------------- ------------------ ---------- ------------
controlfile SYSTEM checkpoint 12701762346 READ WRITE 12701774633
2.从上面看修改多处不是很合理,仅仅修改v$database视图看到的checkpoint_change#应该就ok了:
SYS@test> shutdown immediate ;
Database closed.
Database dismounted.
ORACLE instance shut down.
SYS@test> startup mount
ORACLE instance started.
Total System Global Area 473956352 bytes
Fixed Size 2084776 bytes
Variable Size 268435544 bytes
Database Buffers 192937984 bytes
Redo Buffers 10498048 bytes
Database mounted.
SYS@test> SELECT 'controlfile' "SCN location", 'SYSTEM checkpoint' NAME, checkpoint_change#,open_mode,current_scn FROM v$database;
SCN locatio NAME CHECKPOINT_CHANGE# OPEN_MODE CURRENT_SCN
----------- -------------------------------------------------- ------------------ ---------- ------------
controlfile SYSTEM checkpoint 12701775154 MOUNTED 0
select 12701775154,trunc(12701775154/power(2,32)) scn_wrap,mod(12701775154,power(2,32)) scn_base from dual
12701775154 SCN_WRAP SCN_BASE
------------ ------------ ------------
12701775154 2 4111840562
SYS@test> @10to16 4111840562
10 to 16 HEX REVERSE16
-------------- ------------------
00000f515b532 0x32b515f5
SYS@test> show parameter control_files
NAME TYPE VALUE
-------------- ------- --------------------------------------------------------------------------------------------------------------
control_files string /mnt/ramdisk/test/control01.ctl, /mnt/ramdisk/test/control02.ctl, /mnt/ramdisk/test/control03.ctl
3.使用bvi修改:
00043FF8 00 00 00 00 01 15 46 E5 15 C2 00 00 11 00 00 00 47 E5 C3 33 FF FF 01 04 E6 EE 00 00 00 00 00 00 00 00 00 00 E0 5F 79 34 ......F.........G..3................._y4
00044020 54 45 53 54 00 00 00 00 00 00 00 00 79 01 40 00 01 40 40 50 00 00 00 00 00 00 00 00 3D B8 7C F4 02 00 00 00 1B 5F 79 34 TEST........y.@..@@P........=.|......_y4
00044048 C0 CC 2A 00 00 00 00 00 F7 13 C5 33 00 00 00 00 00 03 20 0A 06 00 00 00 06 00 00 00 01 00 00 00 32 B5 15 F5 02 00 00 00 ..*........3...... .............2.......
~~~~~~~~~~~~~~~~~~
00044070 01 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........................................
--注意使用查询16进制,输入\32 b5 15 f5.(而不是vim使用的/).我仅仅把F5=>FF
SYS@test> @16to10 2ff15b532
16 to 10 DEC
------------
12869547314
--这样修改后结果应该是 12869547314.另外注意3个控制文件要一起修改,我采用覆盖方式。注意要关闭数据库修改控制文件。
--另外还要注意修改检查和。参考http://www.ludatou.com/1682.html,采用清0的方式。
--按照连接的介绍还要修改0x44010的E6EE
$ cp control01.ctl control02.ctl
$ cp control01.ctl control03.ctl
--我的测试不行,也许11g可以,10g不行。问题在那里呢?也许10g发现检查和不对,会从数据文件读取填充SCN。
3.重新测试:
SYS@test> startup mount
ORACLE instance started.
Total System Global Area 473956352 bytes
Fixed Size 2084776 bytes
Variable Size 268435544 bytes
Database Buffers 192937984 bytes
Redo Buffers 10498048 bytes
Database mounted.
SYS@test> SELECT 'controlfile' "SCN location", 'SYSTEM checkpoint' NAME, checkpoint_change#,open_mode,current_scn FROM v$database;
SCN locatio NAME CHECKPOINT_CHANGE# OPEN_MODE CURRENT_SCN
----------- -------------------------------------------------- ------------------ ---------- ------------
controlfile SYSTEM checkpoint 12701802922 MOUNTED 0
select 12701802922,trunc(12701802922/power(2,32)) scn_wrap,mod(12701802922,power(2,32)) scn_base from dual
12701802922 SCN_WRAP SCN_BASE
------------ ------------ ------------
12701802922 2 4111868330
SYS@test> @10to16 4111868330
10 to 16 HEX REVERSE16
-------------- ------------------
00000f51621aa 0xaa2116f5
SYS@test> shutdown immediate ;
ORA-01109: database not open
Database dismounted.
ORACLE instance shut down.
--使用bvi修改:
00044000 15 C2 00 00 11 00 00 00 7D E5 C3 33 FF FF 01 04 6A 64 00 00 00 00 00 00 00 00 00 00 E0 5F 79 34 54 45 53 54 00 00 00 00 00 00 00 00 79 01 40 00 01 40 40 50 00 00 00 00 00 00 00 00 3D B8 7C F4 ........}..3....jd..........._y4TEST........y.@..@@P........=.|.
00044040 02 00 00 00 1B 5F 79 34 C0 CC 2A 00 00 00 00 00 F7 13 C5 33 00 00 00 00 00 03 20 0A 06 00 00 00 06 00 00 00 01 00 00 00 AA 21 16 F5 02 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 ....._y4..*........3...... .............."......................
~~~~~~~~~~~
00044080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................................................................
000440C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 00 01 00 ................................................................"
\aa 21 16 f5
--修改为ab 22 17 f6
--说明:oracle检查和的算法很简单的,虽然我不知道,但是每个ascii加1(4个),检查和就不会变。这样就可以骗过oracle的检查代码。
SYS@test> SELECT 'controlfile' "SCN location", 'SYSTEM checkpoint' NAME, checkpoint_change#,open_mode,current_scn FROM v$database;
SCN locatio NAME CHECKPOINT_CHANGE# OPEN_MODE CURRENT_SCN
----------- -------------------------------------------------- ------------------ ---------- ------------
controlfile SYSTEM checkpoint 12718645931 MOUNTED 0
--OK这次正确!
SYS@test> @16to10 2f61722ab
16 to 10 DEC
------------
12718645931
--提升了12718645931 -12701802922=16843009.
SYS@test> alter database open ;
Database altered.
SYS@test> SELECT 'controlfile' "SCN location", 'SYSTEM checkpoint' NAME, checkpoint_change#,open_mode,current_scn FROM v$database;
SCN locatio NAME CHECKPOINT_CHANGE# OPEN_MODE CURRENT_SCN
----------- -------------------------------------------------- ------------------ ---------- ------------
controlfile SYSTEM checkpoint 12718645932 READ WRITE 12718646077
--OK,没有任何问题,注意不要在生产系统做这样的测试以及试验!!!