1 linux 32位
[oracle@lx01 ~]$ uname -a
Linux lx01 2.6.18-194.el5 #1 SMP Tue Mar 16 21:52:43 EDT 2010 i686 i686 i386 GNU/Linux
SYS@fyl>select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
SYS@fyl>select to_char(current_scn,'XXXXXXXXXXXX') from v$database;
TO_CHAR(CURRE
-------------
10000765F
SYS@fyl>select to_number('10000765F','XXXXXXXXXXXX') from dual;
TO_NUMBER('10000765F','XXXXXXXXXXXX')
-------------------------------------
4294997599
SYS@fyl>oradebug setmypid
Statement processed.
SYS@fyl>oradebug dumpvar sga kcsgscn_
kcslf kcsgscn_ [2000D260, 2000D280) = 00000001 00007651 000009EB 00000000 00000000 00000000 00000000 2000D06C
SYS@fyl>
SYS@fyl>oradebug poke 0x2000D260 4 0x000000002
BEFORE: [2000D260, 2000D264) = 00000001
AFTER: [2000D260, 2000D264) = 00000002
SYS@fyl>oradebug dumpvar sga kcsgscn_
kcslf kcsgscn_ [2000D260, 2000D280) = 00000002 00007677 00000A0C 00000000 00000000 00000000 00000000 2000D06C
SYS@fyl>select to_char(current_scn,'XXXXXXXXXXXX') from v$database;
TO_CHAR(CURRE
-------------
20000767C
SYS@fyl>select current_scn from v$database;
CURRENT_SCN
-----------
8589964953
我这里把SCN wrap推高了一位,即把SCN提高了2的32次方=2*2*1024*1024*1024=4294967296
修改后相差
SYS@fyl>select 8589964953-4294997599 from dual;
8589964953-4294997599
---------------------
4294967354
修改SCN base数值
SYS@fyl>select to_char(checkpoint_change#,'XXXXXXXXXXXXXXXX') from v$database;
TO_CHAR(CHECKPOIN
-----------------
41000538C
SYS@fyl>oradebug setmypid
Statement processed.
SYS@fyl>oradebug dumpvar sga kcsgscn_
kcslf kcsgscn_ [2000D260, 2000D280) = 00000004 10005429 00000049 00000000 00000000 00000000 00000000 2000D06C
SYS@fyl>oradebug poke 0x2000D264 4 0x10010000
BEFORE: [2000D264, 2000D268) = 10005453
AFTER: [2000D264, 2000D268) = 10010000
SYS@fyl>oradebug dumpvar sga kcsgscn_
kcslf kcsgscn_ [2000D260, 2000D280) = 00000004 10010004 00000074 00000000 00000000 00000000 00000000 2000D06C
SYS@fyl>select to_char(checkpoint_change#,'XXXXXXXXXXXXXXXX') from v$database;
TO_CHAR(CHECKPOIN
-----------------
41001000F
大小端可以参考oracle视图
SYS@fyl>select PLATFORM_ID,PLATFORM_NAME from v$database;
PLATFORM_ID PLATFORM_NAME
----------- -----------------------------------------------------------------------------------------------------
10 Linux IA (32-bit)
SYS@fyl>select * from v$transportable_platform;
PLATFORM_ID PLATFORM_NAME ENDIAN_FORMAT
----------- ----------------------------------------------------------------------------------------------------- --------------
1 Solaris[tm] OE (32-bit) Big
2 Solaris[tm] OE (64-bit) Big
7 Microsoft Windows IA (32-bit) Little
10 Linux IA (32-bit) Little
6 AIX-Based Systems (64-bit) Big
3 HP-UX (64-bit) Big
5 HP Tru64 UNIX Little
4 HP-UX IA (64-bit) Big
11 Linux IA (64-bit) Little
15 HP Open VMS Little
8 Microsoft Windows IA (64-bit) Little
9 IBM zSeries Based Linux Big
13 Linux x86 64-bit Little
16 Apple Mac OS Big
12 Microsoft Windows x86 64-bit Little
17 Solaris Operating System (x86) Little
18 IBM Power Based Linux Big
19 HP IA Open VMS Little
20 Solaris Operating System (x86-64) Little
21 Apple Mac OS (x86-64) Little
20 rows selected.
其他测试
SQL> oradebug dumpvar sga kcsgscn_
kcslf kcsgscn_ [380016528, 380016558) = 00000000 0002FB37 00000000 00000000 0000D5E9 00000000 00000000 00000000 00000000 00000000 00000003 80016208
SQL> select to_char(checkpoint_change#,'XXXXXXXX') from v$database;
TO_CHAR(C
---------
3C264
SQL> select checkpoint_change# from v$database;
CHECKPOINT_CHANGE#
------------------
246372
1)设置SCN BASE值
SQL> oradebug poke 0x380016528 8 0x3C264 8表示修改8个字节的值
BEFORE: [380016528, 380016530) = 00000000 00000000 (mount数据库时kcsgscn_=0)
AFTER: [380016528, 380016530) = 00000000 0003C264 -->更改成功
SQL> oradebug dumpvar sga kcsgscn_
kcslf kcsgscn_ [380016528, 380016558) = 00000000 0003C264 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000003 80016208
SQL> oradebug poke 0x380016528 4 0x00000001 --> 4表示修改前4个字节SCN_WRAP,改成1
BEFORE: [380016528, 38001652C) = 00000000
AFTER: [380016528, 38001652C) = 00000001
SQL> oradebug dumpvar sga kcsgscn_
kcslf kcsgscn_ [380016528, 380016558) = 00000001 0003C264 --> 最终SCN_WRAP和SCN_BASE都修改成功
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000003 80016208
SQL> alter database open;
SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
4295213826
SQL> select to_char(dbms_flashback.get_system_change_number,'XXXXXXXXXXXXXXXX') from dual;
TO_CHAR(DBMS_FLAS
-----------------
10003C30B --> SCN WRAP跳了一位
实际上用poke 地址 8 0x000000010003C264直接修改也可以
SQL> oradebug dumpvar sga kcsgscn_
kcslf kcsgscn_ [380016528, 380016558) = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000003 80016208
SQL> select to_char(checkpoint_change#,'XXXXXXXXXXXXXXXX') from v$database;
TO_CHAR(CHECKPOIN
-----------------
10003C482
SQL> oradebug poke 0x380016528 8 0x10003C482
BEFORE: [380016528, 380016530) = 00000000 00000000
AFTER: [380016528, 380016530) = 00000001 0003C482
本测试说明大端序64位系统,语法
oradebug poke 地址 8 SCN号
测试环境2:
SQL> select to_char(current_scn,'XXXXXXXX') from v$database;
TO_CHAR(CURRENT_SCN,'XXXXXX
---------------------------
B49D9
SQL> oradebug dumpvar sga kcsgscn_
kcslf kcsgscn_ [060017008, 060017038) = 000B49DD 00000000 00000000 00000000 000169BF 00000000 00000000 00000000 00000000 00000000 60016CE8 00000000
前4字节是SCN BASE:000B49DD
5~8字节是SCN WRAP:00000000
SQL> oradebug poke 0x060017008 8 0x000B56C400000001 -->值设为SCN_BASE SCN_WRAP
BEFORE: [060017008, 060017010) = 00000000 00000000
AFTER: [060017008, 060017010) = 00000001 000B56C4
SQL> oradebug dumpvar sga kcsgscn_
kcslf kcsgscn_ [060017008, 060017038) = 00000001 000B56C4 -->修改的值不对,前4字节成了SCN_WRAP,后4字节是SCN_BASE
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 60016CE8 00000000
SQL> oradebug poke 0x060017008 8 0x00000001000B56C4 -->重新修改,不考虑大小端,直接写SCN号
BEFORE: [060017008, 060017010) = 00000001 000B56C4
AFTER: [060017008, 060017010) = 000B56C4 00000001
SQL> oradebug dumpvar sga kcsgscn_
kcslf kcsgscn_ [060017008, 060017038) = 000B56C4 00000001 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 60016CE8 00000000
SQL> alter database open;
Database altered.
SQL> select to_char(current_scn,'XXXXXXXXXXXXXXXX') from v$database;
TO_CHAR(CURRENT_SCN,'XXXXXXXXXXXXXXXX')
---------------------------------------------------
1000B579F -->SCN_WRAP跳了1位
测试说明小端序64位系统,修改SCN的方法也是
oradebug poke 地址 8 SCN号
测试环境3:
SQL> oradebug setmypid
已处理的语句
SQL> oradebug dumpvar sga kcsgscn_
kcslf kcsgscn_ [59852C8, 59852E8) = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 059850C0
SQL> select to_char(checkpoint_change#,'XXXXXXXXXXXXXXXX') from v$database;
TO_CHAR(CHECKPOIN
-----------------
3378B
SQL> oradebug poke 0x59852C8 8 0x000000010003378B --> 32位系统寻址只能是4字节,不能填8
ORA-00082: 8 的内存大小不在有效集合 [1], [2], [4] 之内SQL>
SQL> oradebug poke 0x59852C8 4 0x01 -->修改SCN_WRAP值
BEFORE: [59852C8, 59852CC) = 00000000
AFTER: [59852C8, 59852CC) = 00000001
SQL> oradebug dumpvar sga kcsgscn_
kcslf kcsgscn_ [59852C8, 59852E8) = 00000001 00000000 00000000 00000000 00000000 00000000 00000000 059850C0
SQL> oradebug poke 0x59852CC 4 0x0003378B --->修改SCN_WRAP值,需要把内存地址+4字节
BEFORE: [59852CC, 59852D0) = 00000000
AFTER: [59852CC, 59852D0) = 0003378B
SQL> oradebug dumpvar sga kcsgscn_
kcslf kcsgscn_ [59852C8, 59852E8) = 00000001 0003378B 00000000 00000000 00000000 00000000 00000000 059850C0
SQL> alter database open;
数据库已更改。
SQL> select to_char(current_scn,'XXXXXXXXXXXXXXXX') from v$database;
TO_CHAR(CURRENT_S
-----------------
10003381A --> SCN_WRAP跳了1位。
测试表明对于32位系统,需要分别改SCN_WRAP和SCN_BASE来修改内存中的SCN
参考:
http://www.laoxiong.net/scn-ora-19706-_external_scn_rejection_threshold_hours-parameter.html
http://www.askmaclean.com/archives/how-to-increase-system-change-number-by-manual.html
http://www.dbsnake.net/how_to_dirty_adjust_scn.html