Oracle 数据库 10g 审计以一种非常详细的级别捕获用户行为,它可以消除手动的、基于触发器的审计。假定用户 Joe 具有更新那张表的权限,并按如下所示的方式更新了表中的一行数据。
update SCOTT.EMP set salary = 12000 where empno = 123456; |
您如何在数据库中跟踪这种行为呢?在 Oracle 9i 数据库及其较低版本中,审计只能捕获“谁”执行此操作,而不能捕获执行了“什么”内容。例如,它让您知道 Joe 更新了 SCOTT 所有的表 EMP,但它不会显示他更新了该表中员工号为 123456 的薪水列。它不会显示更改前的薪水列的值—要捕获如此详细的更改,您将不得不编写您自己的触发器来捕获更改前的值,或使用 Log Miner 将它们从存档日志中检索出来。
这两种方法都能让您跟踪更改的内容并记录更改前的值,但其成本非常高。使用触发器编写审计数据可能会对性能产生主要的影响;鉴于此,在某些情况下(如在第三方应用中)禁止使用用户定义的触发器。Log Miner 不会影响性能,但它是依赖于存档日志的可用性来跟踪更改的。
细粒度审计 (FGA),是在 Oracle 9i 中引入的,能够记录 SCN 号和行级的更改以重建旧的数据,但是它们只能用于 select 语句,而不能用于 DML,如 update、insert 和 delete 语句。因此,对于 Oracle 数据库 10g 之前的版本,使用触发器虽然对于以行级跟踪用户初始的更改是没有吸引力的选择,但它也是唯一可靠的方法。
随着 Oracle 10g 的到来,由于审计能力的两个重大的改变,这些限制也随之而去。由于两种审计类型涉及到—标准审计(在所有版本中均可用)和细粒度审计(在 Oracle 9i 及其以上版本中可用)—我们将分别对它们进行处理,然后看看它们是如何相互补充以提供一个单一的、强大的跟踪功能。
新特性
首先,FGA 现在除了支持 select 语句外,还支持 DMA 语句。这些更改都记录在同一个位置,即表 FGA_LOG$ 中,并通过 DBA_FGA_AUDIT_TRAIL 视图显示出来。除了 DML 外,您现在可以选择只有在访问了所有或者甚至很少的相关的列后,才可以触发一个线索。(有关 FGA 在 Oracle 10g 中是如何工作的详细信息,请参阅该主题的我的技术文章的内容。)
标准审计,是由 SQL 命令 AUDIT 执行的,可用于为特定的对象快速、容易地设置跟踪。例如,如果您想跟踪对 Scott 所拥有的表 EMP 的所有更新,您可以发出如下命令:
audit UPDATE on SCOTT.EMP by access; |
任何用户每一次更新表 SCOTT.EMP 时,该命令都会把所有的更新记录到审计跟踪表 AUD$ 中,可以通过 DBA_AUDIT_TRAIL 视图来查看。
这个功能对于 Oracle 10g 之前的版本也是可用的。但是,在那些版本中,写到跟踪中的信息仅限于少数相关的项,如:发出该语句的用户、时间、终端标识号等等;它缺少某些重要的信息,如绑定变量的值。在 Oracle 10g 中,除了以前的版本中所收集到的内容之外,审计操作还捕获了许多这些重要的信息片断。用于审计的原始表 AUD$,包含若干个用于记录它们的新列,相应地,DBA_AUDIT_TRAIL 视图也包含这些列。让我们详细地研究一下。
EXTENDED_TIMESTAMP。 该列以 TIMESTAMP (6) 格式记录了审计记录的时间戳,它是用格林尼治标准时间(也称为全球统一时间)来记录时间的,其小数点后的秒数到 9 为止,并且带有时区信息。以这种格式存储的时间的一个例子如下所示。2004-3-13 18.10.13.123456000 -5:0日期表示为 2004 年 3 月 13 日,是美国的东部标准时间,它比全球统一时间晚 5 小时(用 -5.0 来表示)。这种以扩展格式显示的时间有助于把审计跟踪精确定位到一个更窄的时间间隔中,从而增强了它们的用途,特别是在数据库横跨多个时区时更是如此。
GLOBAL_UID 和 PROXY_SESSIONID。 当使用某种身份管理组件如 Oracle Internet Directory 进行身份验证时,用户对数据库的访问权限稍有不同。例如,当将他们访问数据库时,可能将他们视为企业用户。审计这些用户不会在 DBA_AUDIT_TRAIL 视图的 USERNAME 列中记录他们的企业用户标识号,以使该信息无用。在 Oracle 数据库 10g 中,全局(或企业)用户唯一的标识号记录在 GLOBAL_UID 列中,并且没有作进一步的处理或设置。该列可用于查询目录服务器,以查找有关该企业用户的完整的详细信息。
有时企业用户也许是通过一个代理用户连接到数据库,特别是在多层应用中。可以通过命令为用户提供代理身份验证:
alter user scott grant connect to appuser; |
该命令将允许用户 SCOTT 以 APPUSER 的身份,作为代理用户连接到数据库。在那种情况下,COMMENT_TEXT 列将通过存储值 PROXY 来记录事实;但是对于 Oracle 9i 而言,代理用户的会话标识号将不会进行记录。在 Oracle 10g 中,PROXY_SESSIONID 列记录了它,用于精确标识代理会话。
INSTANCE_NUMBER。 在 Oracle 真正应用集群 (RAC) 环境中,它可能有助于知道在进行更改时用户连接的是哪一个特定的例程。在 Oracle 10g 中,该列记录了例程号,它是由该例程的初始化参数文件指定的。
OS_PROCESS。 在 Oracle 9i 及其较低的版本中,只会在审计跟踪中记录 SID 值;而不会记录操作系统进程标识号。但是,服务器进程的操作系统进程标识号随后可能是必要的,例如,用于交叉引用一个线索文件。在 Oracle 10g 中,该值也记录在该列中。
TRANSACTIONID。 在此就产生了最关键的信息价格。假定用户发出下面的命令:
update CLASS set size = 10 where class_id = 123; commit; |
该命令获取一个事务项,并且生成一个审计记录。但是,您怎样知道该审计记录真正记录的是什么内容呢?如果记录是一个事务,该事务标识号就会存储在该列中。您可以使用它把审计跟踪与 FLASHBACK_TRANSACTION_QUERY 视图联接起来。下面是该视图中的列的一个小示例:
select start_scn, start_timestamp, commit_scn, commit_timestamp, undo_change#, row_id, undo_sql from flashback_transaction_query where xid = '<the transaction id>'; |
除了记录对该事务所做的通常的统计外,如 undo change#、rowid 等等,Oracle 10g 还可以在 UNDO_SQL 列中记录撤消对事务所作更改 SQL 命令,以及在 ROW_ID 列显示的受影响行的 rowid。
系统更改号。 最终,它记录更改前的值。您怎样执行该操作呢?按 Oracle 9i 中的 FGA 所指出的那样,更改前的值可以通过闪回查询来获取。但是您需要知道该更改的系统更改号 (SCN),它可以在审计跟踪的该列中捕获到。您可以发出下面的命令:
select size from class as of SCN 123456 where where class_id = 123; |
这将显示用户所看到的内容或更改前的值。
扩展的 DB 审计
记住我们最初的兴趣:为了捕获用户发出的 SQL 语句,以及在标准审计中无法捕获的绑定变量。在 Oracle 数据库 10g 中进入增强型审计,其中这些任务变得如同更改一个简单的初始化参数一样微不足道。只需把下列代码行放入参数文件中。
audit_trail = db_extended |
如果使用该参数,该参数将在各列中记录 SQL 文本和绑定变量值。该值在早期的版本中不可用。
触发器何时是必要的
避免误检。 审计跟踪是通过来自于原始事务的自治事务生成的。因此,即使原始事务回滚,它们也会提交。
有一个简单例子演示了这一点。假定我们已在表 CLASS 上为 UPDATE 设置了审计。用户发出一条语句以将数据值从 20 更新为 10,然后将其回滚,如下所示:
update class set size = 10 where class_id = 123; rollback |
现在该列的 SIZE 值将变成 20,而不是 10,好像用户从未做过任何事情。但是,即使回滚,审计跟踪也将捕获该更改。在某些情况下这可能不是人们所想要的,尤其是用户执行了许多回滚时。在这种情况下,您也许不得不使用触发器仅捕获已提交的更改。如果表 CLASS 上有一个触发器用于将记录插入到用户定义的审计线索中,在回滚的基础上审计线索也被回滚。
捕获之前更改的值。 Oracle 提供的审计跟踪不会显示更改前后的值。例如,上述的更改将创建一个审计记录,它显示了语句和更改的 SCN 号,但没有显示更改前的值 (20)。可以使用闪回查询通过 SCN 号获取该值,但是它依赖于在撤消段中可用的信息。如果该信息无法在由 undo_retention 时间段指定的期限内捕获到,就永远不能检索出先前的值来。使用触发器保证了无需依赖于 undo_retention 时间段即可捕获到该值,并且有时很有用。在这两种环境下,您可以决定继续使用触发器以细粒度的级别来记录审计跟踪。
统一的审计跟踪
由于 FGA 和标准审计捕获的是相同类型的信息,当把它们结合起来使用时可以提供许多重要的信息。Oracle 数据库 10g 把这些跟踪合并到一个称为 DBA_COMMON_AUDIT_TRAIL 的通用跟踪中,它是 DBA_AUDIT_TRAIL 视图和 DBA_FGA_AUDIT_TRAIL 视图的一个 UNION ALL 视图。但是,在这两种审计类型之间有一些重大的区别。
结论
在 Oracle 10g 中,审计已经从一个单纯的“操作记录者”成长为一个“事实记录机制”,它能以一个非常详细的级别来捕获用户的行为,这可以消除您对手动的、基于触发器的审计的需要。它还结合了标准审计和 FGA 的跟踪,这使其更易于跟踪数据库访问,而不用考虑它是如何生成的。