深入剖析Oracle SCN机制
ccwgpt 2024-11-25 10:24 106 浏览 0 评论
1. SCN介绍
SCN即系统改变号(System Change Number),是在某个时间点定义数据库已提交版本的时间戳标记。 Oracle为每个已提交的事务分配一个唯一的SCN。 SCN的值是对数据库进行更改的逻辑时间点。 Oracle使用此编号记录对数据库所做的更改。
SCN是一个6字节(48bit)的数字,其值为281,474,976,710,656(2^48),分为2个部分:SCN_BASE和SCN_WRAP。 SCN_BASE是一个4字节(32bit)的数字,而SCN_WRAP是一个2字节(16bit)的数字。每当SCN_BASE达到其最大值(2^32 = 4294967296)时,SCN_WRAP增加1,SCN_BASE将被重置为0,一直持续到SCN_WRAP达到其最大值,即2^16 = 65536。
SCN =(SCN_WRAP * 4294967296)+ SCN_BASE
SCN随着每个事务的完成而增加。提交不会写入数据文件,也不更新控制文件。
当发生checkpoint时,控制文件更新,SCN被写入到控制文件。
当前的SCN可以通过以下查询获得:
select dbms_flashback.get_system_change_number scn from dual;
select current_scn from v$database;
2. SCN的作用
在数据恢复、Data Guard、Streams复制、RAC节点间的同步等各个功能中都起着非常重要作用。
3. 四种重要的SCN
在理解这几种SCN之前,我们先看下oracle事务中的数据变化是如何写入数据文件的:
1、事务开始;
2、在buffer cache中找到需要的数据块,如果没找到,从数据文件中载入buffer cache中;
3、事务修改buffer cache的数据块,该数据被标识为“脏数据”,并被写入log buffer中;
4、事务提交,LGWR进程将log buffer中的“脏数据”的日志条目写入redo log file中;
5、当发生checkpoint,CKPT进程更新所有数据文件的文件头中的信息,DBWn进程则负责将Buffer Cache中的脏数据写入到数据文件中。
经过上述5个步骤,事务中的数据变化最终被写入到数据文件中。但是,一旦在上述中间环节时,数据库意外宕机了,在重新启动时如何知道哪些数据已经写入数据文件、哪些没有写呢(同样,在DG、streams中也存在类似疑问:redo log中哪些是上一次同步已经复制过的数据、哪些没有)?SCN机制就能比较完善的解决上述问题。 SCN是一个数字,确切的说是一个只会增加、不会减少的数字。正是它这种只会增加的特性确保了 Oracle知道哪些应该被恢复、哪些应该被复制。总共有4中SCN:系统检查点(System Checkpoint)SCN、数据文件检查点(Datafile Checkpoint)SCN、结束SCN(Stop SCN)、开始SCN(Start SCN)。
(1) System Checkpoint SCN
当checkpoint完成后,ORACLE将System Checkpoint SCN号存放在控制文件中。我们可以通过下面SQL语句查询:
select checkpoint_change# from v$database;
(2) Datafile Checkpoint SCN
当checkpoint完成后,ORACLE将Datafile Checkpoint SCN存放在控制文件中。我们可以通过下面SQL语句查询所有数据文件的Datafile Checkpoinnt SCN。
select name,checkpoint_change# from v$datafile;
(3) Start SCN
ORACLE将Start SCN存放在数据文件头中。这个SCN用于检查数据库启动过程是否需要做media recovery。我们可以通过以下SQL语句查询:
select name,checkpoint_change# from v$datafile_header;
(4) Stop SCN
ORACLE将Stop SCN存放在控制文件中。这个SCN号用于检查数据库启动过程是否需要做instance recovery。我们可以通过以下SQL语句查询:
select name,last_change# from v$datafile;
在数据库正常运行的情况下,对可读写的online数据文件,该SCN号为NULL。
过程详解:
1.其中3种SCN存在于控制文件中,Start SCN则存在于数据文件的文件头中。在控制文件中,System Checkpoint SCN是针对整个数据库全局的,因而只存在一个,而DatafileCheckpoint SCN和Stop SCN是针对每个数据文件的,因而一个数据文件就对应在控制文件中存在一份Datafile Checkpoint SCN和Stop SCN。
2.在数据库正常运行期间,Stop SCN是一个无穷大的数字或者说是NULL。
3.在一个事务提交后(上述第四个步骤),会在 redo log 中存在一条 redo 记录,同时,系统为其提供一个最新的 SCN,记录在该条记录中。如果该条记录是在 redo log 被清空(日志满做切换时或发生 checkpoint 时,所有变化日志已经被写入数据文件中),则其 SCN 被记录为 redo log 的 low SCN。以后在日志再次被清空前写入的 redo 记录中 SCN 则成为Next SCN。当日志切换或发生 checkpoint(上述第五个步骤)时,从 Low SCN 到 Next SCN之间的所有 redo 记录的数据就被 DBWn 进程写入数据文件中,而 CKPT 进程则将所有数据文件(无论 redo log 中的数据是否影响到该数据文件)的文件头上记录的 Start SCN(通过视图 v$datafile_header 的字段 checkpoint_change#可以查询)更新为 Next SCN,同时 将 控 制 文 件 中 的 System Checkpoint SCN ( 通 过 视 图 v$database 的 字 段checkpoint_change#可以查询)、每个数据文件对应的 Datafile Checkpoint(通过视图v$datafile 的字段 checkpoint_change#可以查询)也更新为 Next SCN。但是,如果该数据文件所在的表空间被设置为 read-only 时,数据文件的 Start SCN 和控制文件中 Datafile Checkpoint SCN 都不会被更新。
4.那系统是如何产生一个最新的SCN的?实际上,这个数字是由当时的timestamp转换过来的。每当需要产生一个最新的SCN到redo记录时,系统获取当时的timestamp,将其转换为数字作为SCN。
提问1:为什么ORACLE在控制文件中记录System checkpoint SCN 号的同时,还需要为每个数据文件记录Datafile Checkpoint SCN?
SCN与数据库启动:
在数据库启动过程中,当System Checkpoint SCN、Datafile Checkpoint SCN和Start SCN都相同时,数据库可以正常启动,不需要做media recovery.三者当中有一个不同时,则需要做media recovery.如果在启动的过程中,End SCN为NULL,则需要做instance recovery.ORACLE 在启动过程中首先检查是否需要media recovery,然后再检查是否需要instance recovery.
SCN与数据库关闭:
如果数据库的正常关闭的话,将会触发一个checkpoint,同时将数据文件的END SCN设置为相应数据文件的Start SCN。当数据库启动时,发现它们是一致的,则不需要做instance recovery。在数据库正常启动后,ORACLE会将END SCN设置为NULL.如果数据库异常关闭的话,则END SCN将为NULL.
4. 可能遇到的SCN问题
首选我们看几个跟SCN有关的概念:
(1) Reasonable SCN Limit(RSL)
RSL = (当前时间 - 1988年1月1日)*24*3600*SCN每秒最大可能增长速率
也就是从1988年1月1日开始,加入SCN按最大速率增长,当天理论上的最大值。
最大增长速率:在11.2.0.2之前是16384,在11.2.0.2及之后版本是32768
在11.2.0.2版本之后由_max_reasonable_scn_rate参数控制
SQL> select x.ksppinm name, y.ksppstvl value, x.ksppdesc description 2 from sys.x$ksppi x, sys.x$ksppcv y 3 where x.inst_id = userenv('Instance') 4 and y.inst_id = userenv('Instance') 5 and x.indx = y.indx 6 and x.ksppinm = '_max_reasonable_scn_rate'; NAME VALUE DESCRIPTION ----------------------------------- -------- ---------------------------------------- _max_reasonable_scn_rate 32768 Max reasonable SCN rate
该参数不建议修改。
(2) SCN Headroom
Headroom(天) = (Reasonable SCN Limit -Current SCN)/ SCN每秒最大可能增长速率/3600/24
也就是如果SCN按最大速率增长,达到当前理论最大值需要的天数。这个值可以用来判断SCN增长速率是否过快。
那么,SCN Headroom如果获取呢?参考MOS: Bug 13498243 - "scnhealthcheck.sql" script (文档 ID 13498243.8),打上该BUG的patch之后,将在$ORACLE_HOME/rdbms/admin中增加scnhealthcheck.sql文件,该文件就是用来检查SCN是否正常。
另外还有一篇MOS文档,专门对该脚本的输出做了解释。即Installing, Executing and Interpreting output from the "scnhealthcheck.sql" script (文档 ID 1393363.1)。
执行该脚本,结果如下:
SQL> @scnhealthcheck.sql -------------------------------------------------------------- ScnHealthCheck -------------------------------------------------------------- Current Date: 2017/11/13 14:46:21 Current SCN: 13396148604155 Version: 11.2.0.3.0 -------------------------------------------------------------- Result: A - SCN Headroom is good Apply the latest recommended patches based on your maintenance schedule For further information review MOS document id 1393363.1 --------------------------------------------------------------
这个结果我们仍然无法得到该数据库的具体SCN Headroom,下面这个SQL是从scnhealthcheck.sql中找到的,可以直接查到SCN Headroom的值(indicator字段)。
SQL> select version, 2 date_time, 3 dbms_flashback.get_system_change_number current_scn, 4 indicator 5 from (select version, 6 to_char(SYSDATE, 'YYYY/MM/DD HH24:MI:SS') DATE_TIME, 7 ((((((to_number(to_char(sysdate, 'YYYY')) - 1988) * 12 * 31 * 24 * 60 * 60) + 8 ((to_number(to_char(sysdate, 'MM')) - 1) * 31 * 24 * 60 * 60) + 9 (((to_number(to_char(sysdate, 'DD')) - 1)) * 24 * 60 * 60) + 10 (to_number(to_char(sysdate, 'HH24')) * 60 * 60) + 11 (to_number(to_char(sysdate, 'MI')) * 60) + 12 (to_number(to_char(sysdate, 'SS')))) * (16 * 1024)) - 13 dbms_flashback.get_system_change_number) / 14 (16 * 1024 * 60 * 60 * 24)) indicator 15 from v$instance); VERSION DATE_TIME CURRENT_SCN INDICATOR ----------------- ------------------- ----------- ---------- 11.2.0.3.0 2017/11/13 14:46:55 1.3396E+13 1647.23587 提问2: 针对上面的查询结果,是不是意味着过1647天之后,SCN就将达到最大值?
(3) SCN headroom过小的问题
如果SCN正常增长,达到最大值大约可以用500年,SCN headroom的值也会随着时间的推移慢慢变大,但是可能由于BUG、用特殊手段人为调整、dblink传播导致SCN增长出现异常。但如果出现SCN headroom过来,alert log会出现警告:Warning: The SCN headroom for this database is only NN days!
原因定位:
1. 通过下面这篇文档里提供的脚本,该脚本类似于创建AWR,可以按snap_id对dba_hist_sysstat里的某个stat_name做统计,我们这里的Stat_name选择calls to kcmgas。
How to Extract the Historical Values of a Statistic from the AWR Repository (文档 ID 948272.1)
2. 通过查询V$ARCHIVED_LOG单位时间内scn变化
3. 通过上面两个方式得出的结果分析,如果是非持续突发增长,认为很可能是通过dblink引起;
4. 同时比较awr报告中calls to kcmgas和“user commits”,如果user commits也是高速增长,很可能是自身引起;
kcmgas是Oracle分配scn的函数,在一个空库上做测试,可以看出每分配一次scn,calls to kcmgas的统计增加1,所以calls to kcmgas的量可以作为scn的增长量来分析。
SQL> select name,value from v$sysstat where name='calls to kcmgas'; NAME VALUE ----------------------------------- --------- calls to kcmgas 56506 SQL> select current_scn from v$database; CURRENT_SCN ----------- 431781 SQL> select name,value from v$sysstat where name='calls to kcmgas'; NAME VALUE ----------------------------------- --------- calls to kcmgas 56507
(4) ORA-19706: Invalid SCN错误
1376995.1]里的介绍,在2012年1月CPU或PSU里增加_external_scn_rejection_threshold_hours参数,11.2.0.2及以后的版本,默认为1天即24小时,其他版本默认为31天即744小时,相当于把拒绝外部SCN连接的阈值调大了,因而更加容易引发ORA-19706错误(该错误最常见的就是拒绝dblink连接的时候,如A库跟B库通过dblink连接,A的SCN有通过人为调整增大许多,连接B库的时候,Oracle会判断该SCN传播过来之后,如果会导致SCN headroom小于_external_scn_rejection_threshold_hours设置的阈值,则拒绝连接)。该参数对数据库自身产生的SCN递增没有影响。Bug 13554409 - Fix for bug 13554409 [ID 13554409.8]的里对该问题也有介绍
Oracle 10.2.0.5
Oracle 11.1.0.7
Oracle 11.2.0.2
Oracle 11.2.0.3
针对上述版本的数据库,oracle建议给数据库安装2012年4月发布的PSU,并在安装该PSU的基础上,安装补丁13916709。如果是集群架构,同时给集群软件最新安装PSU。参数_external_scn_rejection_threshold_hours在2012年4月(包含2012年4月)以后发布的PSU/CPU中,11.2.0.2及以后的版本,是1天即24小时,其他版本是31天即744小时。
其他版本:先升级到高版本,再按照上面的方法处理。
综上:如果发现SCN有异常,需要及时通过上述方法来打上最新的PSU,同时尽量少用DBLINK,从系统设计角度来讲也是不推荐这种系统间强耦合的设计。
5. 问题解答
提问1:为什么ORACLE在控制文件中记录System checkpoint SCN 号的同时,还需要为每个数据文件记录Datafile Checkpoint SCN?
答:如果有表空间read only,那么该表空间的所有datafile的start SCN和stop SCN将被冻结,这个时候就跟System Checkpoint SCN不一致,但在库open的时候是不需要做media recovery的,如果没有Datafile Checkpoint SCN就无法判断这些datafile是否是最新的。
提问2:针对上面的查询结果,是不是意味着过1647天之后,SCN就将达到最大值?
答:不会,因为1647天之后,Current SCN会变大,Reasonable SCN Limit同样也会变大,正常情况下,SCN Headroon只会变大不会变小。
相关推荐
- 十分钟让你学会LNMP架构负载均衡(impala负载均衡)
-
业务架构、应用架构、数据架构和技术架构一、几个基本概念1、pv值pv值(pageviews):页面的浏览量概念:一个网站的所有页面,在一天内,被浏览的总次数。(大型网站通常是上千万的级别)2、u...
- AGV仓储机器人调度系统架构(agv物流机器人)
-
系统架构层次划分采用分层模块化设计,分为以下五层:1.1用户接口层功能:提供人机交互界面(Web/桌面端),支持任务下发、实时监控、数据可视化和报警管理。模块:任务管理面板:接收订单(如拣货、...
- 远程热部署在美团的落地实践(远程热点是什么意思)
-
Sonic是美团内部研发设计的一款用于热部署的IDEA插件,本文其实现原理及落地的一些技术细节。在阅读本文之前,建议大家先熟悉一下Spring源码、SpringMVC源码、SpringBoot...
- springboot搭建xxl-job(分布式任务调度系统)
-
一、部署xxl-job服务端下载xxl-job源码:https://gitee.com/xuxueli0323/xxl-job二、导入项目、创建xxl_job数据库、修改配置文件为自己的数据库三、启动...
- 大模型:使用vLLM和Ray分布式部署推理应用
-
一、vLLM:面向大模型的高效推理框架1.核心特点专为推理优化:专注于大模型(如GPT-3、LLaMA)的高吞吐量、低延迟推理。关键技术:PagedAttention:类似操作系统内存分页管理,将K...
- 国产开源之光【分布式工作流调度系统】:DolphinScheduler
-
DolphinScheduler是一个开源的分布式工作流调度系统,旨在帮助用户以可靠、高效和可扩展的方式管理和调度大规模的数据处理工作流。它支持以图形化方式定义和管理工作流,提供了丰富的调度功能和监控...
- 简单可靠高效的分布式任务队列系统
-
#记录我的2024#大家好,又见面了,我是GitHub精选君!背景介绍在系统访问量逐渐增大,高并发、分布式系统成为了企业技术架构升级的必由之路。在这样的背景下,异步任务队列扮演着至关重要的角色,...
- 虚拟服务器之间如何分布式运行?(虚拟服务器部署)
-
在云计算和虚拟化技术快速发展的今天,传统“单机单任务”的服务器架构早已难以满足现代业务对高并发、高可用、弹性伸缩和容错容灾的严苛要求。分布式系统应运而生,并成为支撑各类互联网平台、企业信息系统和A...
- 一文掌握 XXL-Job 的 6 大核心组件
-
XXL-Job是一个分布式任务调度平台,其核心组件主要包括以下部分,各组件相互协作实现高效的任务调度与管理:1.调度注册中心(RegistryCenter)作用:负责管理调度器(Schedule...
- 京东大佬问我,SpringBoot中如何做延迟队列?单机与分布式如何做?
-
京东大佬问我,SpringBoot中如何做延迟队列?单机如何做?分布式如何做呢?并给出案例与代码分析。嗯,用户问的是在SpringBoot中如何实现延迟队列,单机和分布式环境下分别怎么做。这个问题其实...
- 企业级项目组件选型(一)分布式任务调度平台
-
官网地址:https://www.xuxueli.com/xxl-job/能力介绍架构图安全性为提升系统安全性,调度中心和执行器进行安全性校验,双方AccessToken匹配才允许通讯;调度中心和执...
- python多进程的分布式任务调度应用场景及示例
-
多进程的分布式任务调度可以应用于以下场景:分布式爬虫:importmultiprocessingimportrequestsdefcrawl(url):response=re...
- SpringBoot整合ElasticJob实现分布式任务调度
-
介绍ElasticJob是面向互联网生态和海量任务的分布式调度解决方案,由两个相互独立的子项目ElasticJob-Lite和ElasticJob-Cloud组成。它通过弹性调度、资源管控、...
- 分布式可视化 DAG 任务调度系统 Taier 的整体流程分析
-
Taier作为袋鼠云的开源项目之一,是一个分布式可视化的DAG任务调度系统。旨在降低ETL开发成本,提高大数据平台稳定性,让大数据开发人员可以在Taier直接进行业务逻辑的开发,而不用关...
- SpringBoot任务调度:@Scheduled与TaskExecutor全面解析
-
一、任务调度基础概念1.1什么是任务调度任务调度是指按照预定的时间计划或特定条件自动执行任务的过程。在现代应用开发中,任务调度扮演着至关重要的角色,它使得开发者能够自动化处理周期性任务、定时任务和异...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- MVC框架 (46)
- spring框架 (46)
- 框架图 (58)
- flask框架 (53)
- quartz框架 (51)
- abp框架 (47)
- jpa框架 (47)
- laravel框架 (46)
- springmvc框架 (49)
- 分布式事务框架 (65)
- scrapy框架 (56)
- shiro框架 (61)
- 定时任务框架 (56)
- java日志框架 (61)
- JAVA集合框架 (47)
- grpc框架 (55)
- ppt框架 (48)
- 内联框架 (52)
- winform框架 (46)
- gui框架 (44)
- cad怎么画框架 (58)
- ps怎么画框架 (47)
- ssm框架实现登录注册 (49)
- oracle字符串长度 (48)
- oracle提交事务 (47)