甲骨文建筑师很久以前做出的一个设计决定可能会把甲骨文的一些最大的客户逼入绝境。补丁已经发布了,但是他们能修正多少呢?
在过去的两个月里,InfoWorld一直在研究Oracle旗舰数据库软件中的一个缺陷,该缺陷可能会对Oracle数据库客户造成严重影响,可能危及Oracle数据库系统的安全和稳定性。
通常,当一个错误导致数据库宕机时,受影响的系统可以简单地从备份中恢复。但是InfoWorld已经了解到,这种特定的Oracle问题集合可能导致数据库中断,需要花费大量时间和精力来纠正。
[订阅信息世界每日简报和在Twitter上关注InfoWorld确保你不会错过一篇文章。请参阅主编Eric Knorr给Oracle社区的邮件:给所有甲骨文客户打电话”。)
据一位不愿透露姓名的消息人士称,“这对我们来说是一个非常现实的问题。我们正在花费大量的时间和金钱来监控、规划和尽可能地解决这些问题。”
在报道这一事件的过程中,我们进行了自己的测试,从我们认为可靠的来源核实了信息,并广泛咨询了甲骨文公司。甲骨文公司对InfoWorld将安全方面的问题上报给公司给予了肯定。
在我们将我们的发现告知Oracle并进行了几次技术讨论之后,Oracle要求我们保留这个故事,直到有时间开发和测试解决这个缺陷的补丁。为了甲骨文用户的安全利益,我们同意了。这些补丁可在今天下午1点的太平洋时区,作为部分Oracle 2012年1月的关键补丁更新。
需要明确的是,该漏洞的安全方面可能使任何未打补丁的Oracle数据库客户容易受到恶意攻击。然而,另一个更基本的方面可能只对具有相互连接数据库的大型Oracle客户构成特殊风险。两者都源于数据库引擎中的一种机制,大多数Oracle dba每天很少处理这种机制。
问题的核心问题的核心是Oracle中的系统更改号(SCN)。这是一个随着每次数据库提交顺序递增的数字:插入、更新和删除。SCN还通过链接数据库交互增加。
SCN对于正常的Oracle数据库操作是至关重要的。SCN“时间戳”是在Oracle中维护数据一致性的关键,它允许数据库在每个时间点用适当的数据版本响应每个用户的查询。可以说,它的功能是数据库的时钟。和时间一样,SCN也不能减少。它必须一直向前滴答。
当Oracle数据库相互链接时,维护数据一致性要求它们与一个公共的SCN同步。这必然是任何参与的Oracle数据库实例所携带的最高SCN,因为SCN时钟不能向后运行——因此数据库链接会导致许多数据库中的SCN在正常操作期间跳转。建立连接时只需要非常基本的权限,从而导致一个数据库在另一个数据库上增加SCN。
Oracle旗舰数据库应用程序的架构师一定很清楚SCN需要是一个巨大的整数。它是:一个48位数字(281,474,976,710,656)。Oracle数据库要耗费大量的事务并导致问题——或者您可能会认为如此。
除了硬限制之外,Oracle本身还设置了一个软限制,以确保在任何给定时刻的SCN值不会过高,这将表明数据库出现故障。如果超过了软限制,数据库可能变得不稳定和/或不可用。而且,由于SCN不能减少或重置,因此不能简单地从备份中恢复数据库并重新播放日志,因为它们必须与那些事务一起携带SCN提升。我们可以类比2000年1月1日时钟敲响12点时,一个未修补的系统上的千年虫问题。
软极限来自于一个锚定在24年前的时间点的非常简单的计算:取自00:00:00 01/01/1988以来的秒数,然后将该数字乘以16,384。如果当前SCN值低于该值,则一切正常,处理将继续正常进行。简单地说,这个计算假设从1988年1月1日开始一直运行、每秒处理16,384个事务的数据库实际上不存在。
事实上,它并没有。但是如果你改变了现实,它就会改变——而且有几种方式可能会违反SCN的软限制。
备份错误最近的一个例子以bug的形式出现。Oracle数据库有一个支持热备份的特性。这允许数据库管理员运行命令以方便对活动数据库进行备份。这是一个方便的函数,可以很容易地运行:'ALTER DATABASE BEGIN BACKUP'是您需要的命令。然后可以备份活动数据库,直到发出“ALTER database END BACKUP”命令,该命令将数据库返回到正常操作模式。这使得DBA处理生产数据库的实时备份变得非常简单。
问题是,由于编码缺陷,发出“BEGIN BACKUP”命令会导致数据库实例的SCN急剧增加,因此即使在给出“END BACKUP”命令后,SCN仍在加速增加。因此,执行热备份可以非常快地将SCN值增加数百万或数十亿——而且这种上升的增长不会停止。在大多数情况下,SCN的限制是如此遥远,以至于偶尔的数量跳跃并不值得担心。管理员甚至不太可能注意到这个问题。
结合但是,当您在一个大型Oracle实现中将热备份错误与大量相互连接的数据库混合在一起时,这种组合可能会导致SCN的广泛提升。一些大型Oracle客户有数百个数据库服务器,它们运行着连接在整个基础设施中的数百个Oracle实例。每个服务器都可能承担一个核心服务和一些次要功能的任务——但就像Kevin Bacon和好莱坞的其他人一样,几乎所有服务器都通过一个、两个、四个或更多的中间服务器以某种方式连接在一起。
由于所有这些服务器都是相互连接的,因此它们的scn在某一点上变得同步。总的来说,它们可能每秒提交的提交数超过16,384次,但肯定不会超过01/01/1988,因此SCN的软限制没有问题。
但是,如果Oracle网络的某一部分上的DBA运行有缺陷的热备份例程,该怎么办呢?突然之间,他的Oracle实例上的SCN激增,比如说7亿,这个数字很快就成为整个组织中所有相互连接的Oracle实例的新的SCN。一段时间后,公司另一端的DBA发出另一个热备份命令。这一次,SCN会激增几亿,而且会随着时间的推移在所有连接的实例之间同步。
随着几个命令的发布,整个Oracle数据库基础设施的SCN在短时间内增加了数亿甚至数千亿。即使只是偶尔连接,或者每周或每月进行批处理运行的数据库实例,其SCN数量也可能激增数万亿。
在这种情况下,运行足够多的备份命令导致SCN超过软限制可能只是时间问题——此时,每个相互链接的Oracle数据库服务器都会遇到一些严重问题,拒绝来自其他服务器的连接,或者仅仅是崩溃。
在InfoWorld开始研究这个故事之前,Oracle发布了一个补丁来修复热备份代码中任意的SCN增长率错误。备份错误被列出为12371955:“在11g中开始备份ALTER数据库的SCN增长率很高。”如果您还没有安装此补丁,Oracle建议您立即安装此补丁。
的破坏者但是,通过备份错误增加SCN的风险并不是唯一需要担心的问题。也许我们发现的最重要的部分是,SCN可以由任何可以在互连的数据库上发出命令的人增加。
假设有一个低权限报告数据库系统,它有一个只读数据库链接,链接到某个地方的高权限数据库。所有人需要做的就是对低权限数据库发出一些管理命令,以提高SCN的价值,例如,1万亿;下一次高特权数据库从该机器接收到连接时,它的SCN增加到更高的级别。验证当前SCN值非常简单,因此运行命令将其推到距离软限制稍远的位置是很简单的。
使用这种技术,不良的参与者可能会导致系统范围的Oracle数据库通信失败、关闭或崩溃,而只在副服务器上执行少量命令——或者甚至编写一些代码来模拟连接实例。通过对易受攻击的应用程序进行SQL注入攻击,也可能导致同样的问题(尽管更具挑战性)。
我们发现了这种攻击方法,并将这一信息告知了Oracle,导致Oracle请求InfoWorld保存这个故事直到今天,那时可以提供一个补丁。除了我们发现的方法之外,我们还了解了另外两种通过搜索开放Web来递增SCN的类似方法,尽管这些方法需要更高的特权级别。这个补丁将我们所知道的三个方法都阻塞了,尽管可能还有其他方法。
现实SCN是一条不能跨越的移动线。直线每秒向上移动16384;只要SCN的增长率较低,一切都会好起来。
但是,当您的SCN越来越接近这条线时,会发生什么情况呢?原因是备份错误、管理员的一个简单错误或其他方法造成了虚假跳转。你如何处理这个迫在眉睫的问题?
答案是:关闭数据库服务器一段时间,使数量停止递增。
简单地说,这意味着整个公司内每一个相互关联的Oracle实例都需要被关闭,仅仅是为了离生产线更远一点。如果只有少数被关闭,当它们与其他Oracle实例连接时,就会非常迅速地跳转回高SCN。确保彻底根除此问题的唯一方法是关闭所有受影响的系统:备份服务器、副本等等。
不仅如此,当它们宕机时,管理员还需要彻底检查基础设施,以确保所有受影响的Oracle系统都能通过修复。即使错过一个实例,也必须再次执行完全关闭。
然后还有关闭多久的问题。如果你把每一个实例都关闭一个星期,那么你将离不退路大约100亿步。有多少企业会考虑关闭数据库系统这么长时间?
当它们关闭时,SCN可能被“重置”——但是只有通过转储每个数据库、删除数据库并将转储导入到一个新的数据库中。这必须同时对整个组织中运行在每个数据库服务器上的每个数据库执行。由于数据库通常在千兆字节范围内,这将需要一段时间。
同样,只有拥有许多相互连接的Oracle数据库的非常大的客户才有可能面临受到这个问题影响的重大风险。但甲骨文公司所处的环境越大,恢复工作所需要的时间就越长。通常,大型组织对停机的容忍度最低。
修复直到最近,除了备份错误修复,甲骨文的唯一的反应SCN高程问题——只要我们已经能够确定,已经发布一个补丁,扩展了SCN计算32768次01/01/1988以来的秒数,软限制的速度翻倍增加。Oracle甚至让它可以修改,这样管理员可以进一步增加乘数。
如果这个补丁应用于一个Oracle实例,它肯定会在达到SCN限制之前增加相互链接的数据库的运行时间。但是,它也引入了新的变量。
部分问题是你不能一次给每个系统都打补丁。此外,如果你有一个修补系统软限制——基于乘法器的升高,说,65536年的视交叉上核系统可以高于SCN发动系统上使用原16384乘数,导致应用补丁的系统拒绝连接或遇到另一个问题,因为它没有软限制检查。还有一个问题是,运行较旧版本Oracle的服务器可能没有可用的补丁。
此外,如果这个补丁是下一个Oracle版本的默认包含,管理员可能会突然发现他们现有的服务器无法与使用新的、更高SCN计算方法的新服务器或升级服务器通信,而新服务器的SCN应该足够高。如果SCN值恰好对齐,则有可能一个经过修补的系统连接并将未经过修补的系统的SCN设置为刚好低于软限制,从而导致未经过修补的系统通过其自己的处理达到限制。