Oracle SCN对于数据库运行、维护而言是至关重要的因素。在启动从mount到open过程中,主要是各种文件的SCN进行比较的行为。通常情况下,我们是不需要介入到Oracle SCN的取值和设置,甚至错误的干预可能会引起严重运行事故。

在之前的文章中,笔者介绍过使用隐含参数和跟踪事件来推动Oracle SCN前进的方法。但是,在11.2.0.2之后的版本中,Oracle关闭了这个通道,这种方法不在有效。在高版本情况下,我们是可以通过oradebug工具对SCN进行修改。

注意:这种方法比较危险,请不要在投产环境下进行测试。

1、实验环境说明

笔者使用Oracle 11g进行测试,版本为11.2.0.4。对应操作系统是Linux 6.5 64bit版本。

SQL> select * from v$version;

BANNER

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

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

PL/SQL Release 11.2.0.4.0 - Production

CORE11.2.0.4.0Production

TNS for Linux: Version 11.2.0.4.0 - Production

NLSRTL Version 11.2.0.4.0 – Production

我们先聊聊Oracle的SCN。在数据库内部,SCN是一个单向递增的数字编号,控制文件、数据文件、在线Redo日志、归档日志和备份集合中,都包括这个数字编号。在内部文件中,SCN是通过Base和Wrap两个部分进行保存。Base是SCN编号的基础位,是通过32位二进制位进行保存。一旦超过这32位长度,系统会自动在Wrap进位。也就是说,Wrap表示的超过4G个数的进位次数。

使用Oracle oradebug修改SCN,可以在两个场景下进行,就是Oracle启动Open状态和Mount状态。下面分别进行说明。

2、Open状态下SCN修改

在Open状态,系统的SCN是在不断的向前推动,即使对外没有事务操作,系统内部SCN编号也在不断的前进。我们先将数据库进入open状态。

SQL> alter database open;

Database altered.

SQL> select CHECKPOINT_CHANGE#, current_scn from v$database;

CHECKPOINT_CHANGE# CURRENT_SCN

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

17539821754355

SQL> select dbms_flashback.get_system_change_number from dual;

GET_SYSTEM_CHANGE_NUMBER

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

1754364

此时,从系统中提取出的SCN编号约为1754364,显然没有超过wrap的进位4G,变化为16进制如下:

SQL> select to_char(1754364, 'XXXXXXXX') from dual;

TO_CHAR(1754364,'XXXXXXXX')

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

1AC4FC

使用oradebug查看内存中SCN对应的变量。

SQL> oradebug setmypid

Statement processed.

SQL> oradebug dumpvar sga kcsgscn_

kcslf kcsgscn_ [06001AE70, 06001AEA0) = 001AC52A 00000000 00000000 00000000 00000065 00000000 00000000 00000000 00000000 00000000 6001AB50 00000000

其中,0x001AC52A近似SCN的Base部分。注意:Linux系统是Little位的操作系统,Base在前,Wrap在后。

SQL> select to_number('1AC52A','xxxxxx') from dual;

TO_NUMBER('1AC52A','XXXXXX')

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

1754410

下面计划将Base修改为1800000,查看16进制取值。

SQL> select to_char(1800000, 'XXXXXXXX') from dual;

TO_CHAR(1800000,'XXXXXXXX')

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

1B7740

使用poke命令将计算好的值写入进去。

SQL> oradebug poke 0x06001AE70 4 0x001B7740

BEFORE: [06001AE70, 06001AE74) = 001AC66F

AFTER:[06001AE70, 06001AE74) = 001B7740

SQL> oradebug DUMPvar SGA kcsgscn_

kcslf kcsgscn_ [06001AE70, 06001AEA0) =001B7745 00000000 00000000 00000000 00000164 00000000 00000000 00000000 00000000 00000000 6001AB50 00000000

SQL>

poke命令中,第一位参数是对应写入的内存位数,第二位参数是写入长度,第三位参数是写入取值。默认写入取值是10进制,我们在这里指定写入16进制。

每一个取值段,用8个16进制对应,对应到数字位数是4位。此时查看Oracle情况。

SQL> select CHECKPOINT_CHANGE#, current_scn from v$database;

CHECKPOINT_CHANGE# CURRENT_SCN

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

17539821800400

SQL> select dbms_flashback.get_system_change_number from dual;

GET_SYSTEM_CHANGE_NUMBER

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

1800402

SQL> select file#, checkpoint_change# from v$datafile;

FILE# CHECKPOINT_CHANGE#

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

11753982

21753982

31753982

41753982

51753982

61753982

71753982

7 rows selected

SQL> select file#, checkpoint_change# from v$datafile_header;

FILE# CHECKPOINT_CHANGE#

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

11753982

21753982

31753982

41753982

51753982

61753982

71753982

7 rows selected

从上面看,内存和控制文件中新的取值已经写入进去了。但是各个文件的头块和检查点还没有反应过来。此时可以使用checkpoint强制写入。

SQL> alter system checkpoint;

System altered.

SQL> select file#, checkpoint_change# from v$datafile;

FILE# CHECKPOINT_CHANGE#

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

11800422

21800422

31800422

41800422

51800422

61800422

71800422

7 rows selected

SQL> select file#, checkpoint_change# from v$datafile_header;

FILE# CHECKPOINT_CHANGE#

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

11800422

21800422

31800422

41800422

51800422

61800422

71800422

7 rows selected

SQL> select CHECKPOINT_CHANGE#, current_scn from v$database;

CHECKPOINT_CHANGE# CURRENT_SCN

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

18004221800433

此时,关闭重启系统也不会有问题。篇幅原因,不进行具体展示。那么,很多时候SCN错误是会影响到开启数据库的,我们可能都不能进入open状态。从mount状态下我们怎么修改SCN编号。

3、Mount状态修改SCN编号

我们测试进入mount状态。

SQL> startup mount

ORACLE instance started.

Total System Global Area 3540881408 bytes

Fixed Size2258320 bytes

Variable Size855640688 bytes

Database Buffers2667577344 bytes

Redo Buffers15405056 bytes

Database mounted.

此时,oradebug命令导出内存取值。

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

注意:在mount状态下,内存中的SCN取值都是0,包括base和wrap两部分。我们这次修改wrap从0到1。这个过程中,我们需要写入base和wrap两个部分,如果我们只写入了wrap部分,base部分保持0,那么系统运行的时候,会从base为0开始。

此时,需要查看一下当前文件里面SCN是多少。

SQL> select file#, checkpoint_change# from v$datafile;

FILE# CHECKPOINT_CHANGE#

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

11800920

21800920

31800920

41800920

51800920

61800920

71800920

7 rows selected

SQL> select file#, checkpoint_change# from v$datafile_header;

FILE# CHECKPOINT_CHANGE#

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

11800920

21800920

31800920

41800920

51800920

61800920

71800920

7 rows selected

SQL> select CHECKPOINT_CHANGE#, current_scn from v$database;

CHECKPOINT_CHANGE# CURRENT_SCN

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

18009200

计算1800920对应到16进制取值为:0x001B7AD8。下面分别写入base和wrap取值。

SQL> oradebug DUMPvar SGA kcsgscn_

kcslf kcsgscn_[06001AE70, 06001AEA0) = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 6001AB50 00000000

SQL> oradebug poke 0x06001AE70 4 0x001B7AD8

BEFORE: [06001AE70, 06001AE74) = 00000000

AFTER:[06001AE70, 06001AE74) = 001B7AD8

SQL> oradebug poke 0x06001AE74 4 0x00000001

BEFORE: [06001AE74, 06001AE78) = 00000000

AFTER:[06001AE74, 06001AE78) = 00000001

SQL> oradebug DUMPvar SGA kcsgscn_

kcslf kcsgscn_ [06001AE70, 06001AEA0) = 001B7AD8 00000001 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 6001AB50 00000000

启动数据库。

SQL> alter database open;

Database altered.

SQL> select CHECKPOINT_CHANGE#, current_scn from v$database;

CHECKPOINT_CHANGE# CURRENT_SCN

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

42967682174296768485

SQL> select file#, checkpoint_change# from v$datafile_header;

FILE# CHECKPOINT_CHANGE#

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

14296768217

24296768217

34296768217

44296768217

54296768217

64296768217

74296768217

7 rows selected

SQL> select file#, checkpoint_change# from v$datafile;

FILE# CHECKPOINT_CHANGE#

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

14296768217

24296768217

34296768217

44296768217

54296768217

64296768217

74296768217

7 rows selected

显然在open的时候,写入的checkpoint在所有文件中。写入的wrap头也比较清晰。

SQL> select 4296768217/(4*1024*1024*1024) from dual;

4296768217/(4*1024*1024*1024)

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

1.0004193095956

SQL> oradebug DUMPvar SGA kcsgscn_

kcslf kcsgscn_ [06001AE70, 06001AEA0) = 001B7C1D 00000001 00000000 00000000 00000047 00000000 00000000 00000000 00000000 00000000 6001AB50 00000000

4、结论

使用oradebug直接修改内存SCN,是我们在故障修复时候非常快捷的方法。不过,快捷建立在对内部机制清晰理解的前提之下。所以,无论何种场景进行修复,有备份、可恢复是我们工作的基本前提。

手动修改oracle scn号,使用Oradebug修改Oracle SCN相关推荐

  1. oracle加分号报错,在Oracle SQL中,何时需要使用分号和斜杠?

    我知道这是一个老生常谈,但我只是偶然发现,我觉得这一点还没有得到完全解释. 在SQL*Plus中,/和一个;因为他们的工作方式不同. 这个;结束SQL语句,而/执行当前"缓冲区"中 ...

  2. html 端口修改,tomcat端口号在哪里修改?

    在默认情况下,tomcat的端口是8080,使用了两个tomcat,那么就需要修改其中的一个的端口号才能使得两个同时工作.那么,如何修改tomcat的端口号呢?下面本篇文章给大家介绍一下. 首先到安装 ...

  3. 修改Redis端口号以及解决修改完端口号但是没有生效的问题

    Redis默认端口号是6379,如果不把端口号修改的话,可能会受到攻击.当然,如果改的端口号太简单的话也会受到攻击. 找到Redis的安装路径,用编辑器(我用的是Notepad++)打开redis.w ...

  4. Oracle订单号就是授权号码,oracle多单号的说明

    在ORACLE中,单引号有两个作用,一是字符串是由单引号引用,二是转义.单引号的使用是就近配对,即就近原则.而在单引号充当转义角色时相对不好理解 1.从第二个单引号开始被视为转义符,如果第二个单引号后 ...

  5. oracle bug号,《一次Oracle bug的故障排查过程思考》的问题重现解决

    在<一次Oracle bug的故障排查过程思考>这个问题排查过程当中,当时和同事们一块儿猜想.实验.论证,昨天有幸,通过了精心设计,在生产环境中,进行了问题重现,以及解决的部分验证.sql ...

  6. oracle查询号段是否重复,ORACLE SQL: 查询连续号码段并合并的方法

    有一个表phonearea,结构如下: province   prefix 2014       00000001 2014       00000002 2014       00000003 20 ...

  7. oracle数据库修改写入状态,【学习笔记】Oracle oradebug 使用oradebug修改数据库SCN方法案例...

    天萃荷净 使用oradebug修改数据库scn,使用oradebug修改数据库scn的案例. 这里也做了两个测试,发现该功能确实很巧妙,通过修改内存中的scn值,然后写入控制文件和数据文件,实现修改s ...

  8. 修改tomcat端口号的方法:

    修改tomcat端口号的方法: 修改Server.xml文件,把8080端口改成80就可以了. 8080是Tomcat服务器的默认的端口号.我们可以通过修改Tomcat服务器的conf目录下的主配置文 ...

  9. oracle数据库scn是什么,深入了解ORACLE数据库的SCN

    1. 深入了解oracle数据库的SCN 1.1. SCN的概念 SCN是顺序递增的一个数字,在Oracle 中用来标识数据库的每一次改动,及其先后顺序.SCN的最大值是0xffff.ffffffff ...

最新文章

  1. Elasticsearch高并发写入优化的开源协同经历
  2. 机器翻译Seq2Seq模型的启发-人工神经网络系统-诞生
  3. 二调建设用地地类代码_二调土地地类代码表
  4. LFS安装ifconfig命令
  5. 控件setVisible为false会导致控件被移除
  6. LVM逻辑卷,RAID磁盘阵列
  7. CRM管理系统、教育后台、赠品管理、优惠管理、预约管理、试听课、教师、学生、客户、学员、商品管理、科目、优惠券、完课回访、客户管理系统、收费、退费、回访、账号权限、订单流水、审批、转账、rp原型
  8. 物流行业企业报表开发指南
  9. gnuplot在windows下的安装和使用
  10. 【CentOS 7架构16】,限制user_agent#171226
  11. 被吐槽得最惨的10大专业,计算机专业亮了
  12. Linux实战教学笔记29:MySQL数据库企业级应用实践
  13. 【嵌入式】NBIoT(BC26)低功耗模式与控制
  14. ei加声调怎么加_微商怎么加好友找客源实操篇
  15. 由于应用程序配置不正确,应用程序未能启动。重新安装应用程序可能会纠正这个问题
  16. 公关世界杂志公关世界杂志社公关世界编辑部2022年第14期目录
  17. (转)DOTA新版地图6.78发布:大幅改动 增两位新英雄
  18. python中csv文件是什么_Python中的csv文件
  19. 进击的Android之manifests
  20. 新人必看的机器人制作过程

热门文章

  1. print('曾经有一份真挚的爱情放在我面前,那个人的名字是' + goddess),Python旅程开始的地方!
  2. 斯坦福大学教授,推荐Python入门必看的三本书,非常适合零基础
  3. 电脑网页的准考证如何存u盘
  4. python/itertools-contextlib-urllib-XML-HTMLParser
  5. 零基础入门UI设计,如何提升审美能力呢?
  6. Linux下oracle创建表空间及用户
  7. 入门学习建模需要了解并掌握哪些软件?工业建模、游戏建模工具介绍
  8. 谈一谈交通大脑——智慧城市背后的王牌!
  9. java kt_我的KT库之-----认识KT
  10. 基于vue3 element plus form 表单的二次封装