作者介绍:老苏,10余年DBA工作运维经验,擅长Oracle、MySQL、PG数据库运维(如安装迁移,性能优化、故障应急处理等)
公众号:老苏畅谈运维
欢迎关注本人公众号,更多精彩与您分享。
前面介绍了3种推进SCN方法
(1)event 10015 来增加 scn 的值
(2)隐含参数_minimum_giga_scn 来增加 scn 的值
(3)gdb/dbx 来直接修改内存中的值
现在来说一下oracle推进SCN方法4:使用oradebug poke 直接修改内存中的值
该方法适合版本适在12.2以下,在数据库OPEN或者MOUNT状态都可以修改,12.2以上ORACLE屏蔽了该方法。
oradebug poke修改方法如下:
oradebug setmypid
oradebug DUMPvar SGA kcsgscn --查看当前内存中的SCN (这个内存中的SCN,控制文件的当前SCN,数据文件头的start SCN --具体是什么关系,暂时待定。)
oradebug poke 【内存地址】 【长度】 【要修改的内容】
1、判断大小端问题
判断oracle所在服务器是大端还是小端方法
方法一:
[oracle@ora121:~]$ echo -n I | od -o | head -n1 | cut -f2 -d" " | cut -c6
1
[oracle@ora121:~]$ echo -n I | od -o | head -n1 | awk '{print $2}'| cut -c6
1
输出:1为小端模式,0为大端模式;
方法二:
$ lscpu | grep -i byte
Byte Order: Little Endian
输出:Byte Order: Little Endian;
注意:在低版本的Linux可能不支持lscpu命令。
方法三:如果数据库有启动,可查询相关视图
SQL> col PLATFORM_NAME for a50;
SQL> set linesize 400;
SQL> select PLATFORM_ID,PLATFORM_NAME from v$database;
PLATFORM_ID PLATFORM_NAME
----------- --------------------------------------------------
13 Linux x86 64-bit
SQL> select * from v$transportable_platform;
PLATFORM_ID PLATFORM_NAME ENDIAN_FORMAT CON_ID
----------- -------------------------------------------------- -------------- ----------
1 Solaris[tm] OE (32-bit) Big 0
2 Solaris[tm] OE (64-bit) Big 0
7 Microsoft Windows IA (32-bit) Little 0
10 Linux IA (32-bit) Little 0
6 AIX-Based Systems (64-bit) Big 0
3 HP-UX (64-bit) Big 0
5 HP Tru64 UNIX Little 0
4 HP-UX IA (64-bit) Big 0
11 Linux IA (64-bit) Little 0
15 HP Open VMS Little 0
8 Microsoft Windows IA (64-bit) Little 0
PLATFORM_ID PLATFORM_NAME ENDIAN_FORMAT CON_ID
----------- -------------------------------------------------- -------------- ----------
9 IBM zSeries Based Linux Big 0
13 Linux x86 64-bit Little 0
16 Apple Mac OS Big 0
12 Microsoft Windows x86 64-bit Little 0
17 Solaris Operating System (x86) Little 0
18 IBM Power Based Linux Big 0
19 HP IA Open VMS Little 0
20 Solaris Operating System (x86-64) Little 0
21 Apple Mac OS (x86-64) Little 0
20 rows selected.
关于db中scn存储方式的解释:
scn=scnwrap * power(2,32) + scnbase (2^32 = 4294967296)
SCN分为两部分存储,scnwrap和scnbase,每当scnbase增长到2^32之后,scnwarp加1,然后scnbase清零。
WRAP占2字节,BASE占4字节,但通常在内存里SCN_WRAP也占用4字节
(一个字节为8个bit,最小为0,最大为256,因此一个字节可以用两个16进制数(16*16)来表示,所以整个SCN显示出来应该是16个16进制数,两个16进制数表示一个字节。eg:0016CE5E 00000000)
在64-bit小字端中:前4位为scnbase,后4位为scnwrap
在64-bit大字端中:前4位为scnwrap,后4位为scnbase
由于我的系统是Linux,为小字端,所以前4个字节为base,后4个字节为wrap
2、查看当前SCN值
–首先启动到mount状态
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount;
ORACLE instance started.
Total System Global Area 3691200512 bytes
Fixed Size 2258680 bytes
Variable Size 788531464 bytes
Database Buffers 2885681152 bytes
Redo Buffers 14729216 bytes
Database mounted.
alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
col scn for 99999999999999
select checkpoint_change# scn from v$database;
SCN
---------------
2187462
select max(checkpoint_time),max(CHECKPOINT_CHANGE#) scn from v$datafile_header;
MAX(CHECKPOINT_TIME SCN
------------------- ---------------
2024-05-31 22:53:05 2187462
select max(checkpoint_time),max(CHECKPOINT_CHANGE#) scn from v$datafile;
MAX(CHECKPOINT_TIME SCN
------------------- ---------------
2024-05-31 22:53:05 2187462
--取上面最大的scn,计算新的scn号(增加100000)
select to_char(2187462+100000,'xxxxxxxxxxxxxxxx') from dual; -- 2287462
TO_CHAR(2187462+1
-----------------
22e766
3、修改SCN值
–修改
SQL> oradebug setmypid
Statement processed.
SQL> oradebug dumpvar sga kcsgscn_
kcslf kcsgscn_ [06001AE70, 06001AEA0) = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 6001AB50 00000000
--因为当前SCN和我们要更改的目标SCN都没有超过一个wrap,因此wrap位是0,更改base为 22e766 即可。
--因此我们从SCN地址06001AE70,往后推4位,为base。
--前边值是上一步第一个值,内存地址,4 代表修改字节,后边是修改后的scn号
SQL> oradebug poke 0x06001AE70 4 0x22e766
BEFORE: [06001AE70, 06001AE74) = 00000000
AFTER: [06001AE70, 06001AE74) = 0022E766
再次查看更改后的SCN:
SQL> oradebug dumpvar sga kcsgscn_
kcslf kcsgscn_ [06001AE70, 06001AEA0) = 0022E766 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 6001AB50 00000000
4、启库验证
接下来启动数据库,查看SCN,我们预计是比 2287462 大一点的:
SQL> alter database open;
Database altered.
SQL> select checkpoint_change# scn from v$database;
SCN
---------------
2287463
可以看到,SCN的值已经被修改,推进SCN成功。
链接:
史上最全,呕心沥血总结oracle推进SCN方法(一)
史上最全,呕心沥血总结oracle推进SCN方法(二)
史上最全,呕心沥血总结oracle推进SCN方法(三)