暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

Oracle SCN浅析

原创 董宏伟 云和恩墨 2023-05-21
707

SCN的概念

SCN(System Change Number)是一个戳(印记),它定义了某个时间点上数据库的已提交版本。Oracle为每个提交的事务分配一个唯一的SCN。SCN的值是对数据库进行更改的逻辑时间点。Oracle使用这个数字来记录数据库所做的更改。

SCN是一个6字节(48位)的数字,其最大值为281,474,976,710,656(281),并表示为两个部分——SCN_BASE和SCN_WRAP。SCN_BASE是一个4字节(32位)的数字,而SCN_WRAP是一个2字节(16位)的数字。每当SCN_BASE达到其最大值(2 power 32 = 4294967296)时,SCN_WRAP将增加1,SCN_BASE将重置为0。这个过程一直持续到SCN_WRAP达到最大值,即2 power 16 = 65536。

SCN = (scn_wrap * 4294967296) + scn_base

从12.2开始,兼容性设置为12.2,SCN是一个8字节的数字,SCN的最大值可达2^63。

每完成一笔交易,SCN会递增。提交操作不会写入任何数据文件,也不会更新控制文件。
当控制文件更新时,SCN会被写入控制文件中——这通常是由于一些情况发生导致的,其中之一就是“正式检查点结束”。
SCN会持续地被写入重做日志中——当你提交时,它们会被发送到重做流中,在语义上,它们会在检查点完成之后而不是检查点启动之后被记录。

当前SCN可以通过以下任一查询获得:

select dbms_flashback.get_system_change_number scn from dual;
select current_scn from v$database;

SCN天花板

考虑到SCN存在上限,任何给定的Oracle数据库都不能耗尽可用的scn。Oracle数据库使用基于时间的配给系统来确保不会发生这种情况。

在任何时间点,Oracle数据库都会根据自1988年以来经过的秒数乘以16,384 (16K/sec),计算一个数据库可以使用的scn数量的“不超过”限制。这就是数据库当前的最大SCN限制(软限制)。这样做可以确保Oracle数据库将随着时间的推移配给scn,允许使用12.2.0.1或更低版本的任何Oracle数据库进行超过500年的数据处理。从12.2.0.1开始,将兼容性设置为12.2,即使scn以96K/秒的速度消耗,Oracle数据库也将允许近300万年的数据处理。

当前系统使用的SCN与“不超过”上限之间的差值被称为SCN Headroom。几乎所有的Oracle数据库,这个Headroom在每秒钟都在不断地增加。

scn天花板检查sql:

SELECT VERSION,
TO_CHAR(CURRENT_SCN),
DATE_TIME,
TO_CHAR(ROUND(HEADROOM, 2))
FROM (SELECT VERSION,
DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER CURRENT_SCN,
TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') DATE_TIME,
case
when replace(version, '.', '') < 112020 then
((((((TO_NUMBER(TO_CHAR(SYSDATE, 'YYYY')) - 1988) * 12 * 31 * 24 * 60 * 60) +
((TO_NUMBER(TO_CHAR(SYSDATE, 'MM')) - 1) * 31 * 24 * 60 * 60) +
(((TO_NUMBER(TO_CHAR(SYSDATE, 'DD')) - 1)) * 24 * 60 * 60) +
(TO_NUMBER(TO_CHAR(SYSDATE, 'HH24')) * 60 * 60) +
(TO_NUMBER(TO_CHAR(SYSDATE, 'MI')) * 60) +
(TO_NUMBER(TO_CHAR(SYSDATE, 'SS')))) * (16 * 1024)) -
DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER) /
(16 * 1024 * 60 * 60 * 24))
when replace(version, '.', '') < 12201 then
((((((TO_NUMBER(TO_CHAR(SYSDATE, 'YYYY')) - 1988) * 12 * 31 * 24 * 60 * 60) +
((TO_NUMBER(TO_CHAR(SYSDATE, 'MM')) - 1) * 31 * 24 * 60 * 60) +
(((TO_NUMBER(TO_CHAR(SYSDATE, 'DD')) - 1)) * 24 * 60 * 60) +
(TO_NUMBER(TO_CHAR(SYSDATE, 'HH24')) * 60 * 60) +
(TO_NUMBER(TO_CHAR(SYSDATE, 'MI')) * 60) +
(TO_NUMBER(TO_CHAR(SYSDATE, 'SS')))) * (32 * 1024)) -
DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER) /
(32 * 1024 * 60 * 60 * 24))
else
((((((TO_NUMBER(TO_CHAR(SYSDATE, 'YYYY')) - 1988) * 12 * 31 * 24 * 60 * 60) +
((TO_NUMBER(TO_CHAR(SYSDATE, 'MM')) - 1) * 31 * 24 * 60 * 60) +
(((TO_NUMBER(TO_CHAR(SYSDATE, 'DD')) - 1)) * 24 * 60 * 60) +
(TO_NUMBER(TO_CHAR(SYSDATE, 'HH24')) * 60 * 60) +
(TO_NUMBER(TO_CHAR(SYSDATE, 'MI')) * 60) +
(TO_NUMBER(TO_CHAR(SYSDATE, 'SS')))) * (96 * 1024)) -
DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER) /
(96 * 1024 * 60 * 60 * 24))
end HEADROOM
FROM V$INSTANCE);

_external_scn_rejection_threshold_hours参数:允许外部SCN和SCN Headroom之间的差距。

检查点的概念

检查点是将修改过的、缓存的数据库块刷新到磁盘的行为。通常,当对一个块进行更改时,对该块的修改会对块的内存副本进行更改。当提交block时,它不会被写到数据文件中,而是被写到REDO LOG中,所以我们可以在实例失败的情况下“重演”事务。最终,系统会将你修改过的块写入磁盘上的数据文件中进行检查点操作。

检查点号是将所有脏缓冲区写入磁盘的SCN编号。在对象/表空间/数据文件/数据库级别可以有一个检查点。

一个成功的检查点确保所有到检查点SCN的数据库更改都记录在数据文件中。因此,只有在检查点之后所做的更改需要在实例恢复期间应用。

检查点的目标是将脏缓冲区安全地从SGA转移到磁盘上。

使检查点发生的事件:

  • 当DBWR将Oracle SGA中的所有脏缓冲区写入数据文件时。
  • 当重做日志切换发生时。
  • 当达到LOG_CHECKPOINT_TIMEOUT参数设置的时间时。
  • 通过发出命令’alter system switch logfile’或’alter system checkpoint’。

检查点进程在执行检查点时更新控制文件。请记住,检查点操作将所有已更改(脏)的块写入磁盘。通过在控制文件中记录这一事实,Oracle知道在实例失败的情况下需要应用哪些重做记录。为了从实例故障中恢复,Oracle需要应用控制文件中记录的最后一个检查点之后生成的所有redo。

DBWR把脏块从缓存写到磁盘上——这不会在你提交的时候发生——提交的时候会涉及到LGWR。

当日志缓冲区占满1MB、填充到1/3、每隔3秒或每次提交时(以哪个先到的为准)时,这些都将触发redo写入。

日志切换导致检查点。检查点不会引起日志切换。
当检查点完成时,保护已经检查点数据的重做日志将不再需要进行实例恢复。


订阅号:DongDB手记
墨天轮:https://www.modb.pro/u/231198
image.png

最后修改时间:2023-05-21 21:54:24
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论