在本系列的前兩個部分中
我向您介紹了細粒度審計 (FGA) 的概念
它用來在 Oracle
i Database 和更高版本中跟蹤選定的語句
我還說明了如何在復雜的環境中(比如說在一個 Web 應用程序內部)通過應用程序上下文和客戶端標識符來使用這個特性
這兩篇文章為您提供了足夠的信息
使您可以為幾乎所有類型的數據庫系統(無論它有多復雜)構建一個 FGA 設置程序
在這個第三部分
同時也是最後一部分中
我將說明 Oracle Database
g 為表帶來的 FGA 增強
Oraclei Database 中的 FGA 讓我們簡要地重述一下 FGA 的好處
關於完整的討論
請參考本系列的第
部分和第
部分
正規審計(通過 AUDIT 語句)記錄使用的語句 — 如 SELECT 或 INSERT — 以及誰發出它
從哪一個終端
什麼時候等等
然而
信息最重要的部分 — 哪條特定記錄被修改了
以及數據本身的變化 — 沒有捕獲到
相反
許多用戶編寫觸發器來捕獲變化前後的數據值
並把它們記錄在用戶自定義的表中
但因為觸發器只可能在 DML 語句(如 insert
update 和 delete)上使用
所以訪問的一個主要的方面 — SELECT 語句 — 不能通過這種途徑來審計
因此 FGA 的價值在於
它只捕獲 SELECT 語句
與觸發器和 Log Miner 工具一起
FGA 提供了一種機制來審計各種類型的值修改和不涉及到修改的數據訪問
FGA 不僅填補了審計 SELECT 語句的空白
而且還提供了其它的一些引人注目的額外好處
這些好處使得數據庫管理員的工作變得更加輕松
例如
FGA 允許一個用戶自定義的過程在指定的審計條件出現的時候執行
因此您可以認為它是 SELECT 語句上的一個觸發器 — 這是一個在其它方式下沒有提供的功能
這個技巧可能非常有用 — 例如
任何時候當有人選擇了收入超過
百萬美元的員工的工資記錄時
發送一封郵件給一個安全審計員
以在用戶自定義的表中生成審計記錄
這些表可以不受限制地進行處理(這與 SYS 擁有的 FGA_LOG$ 表不同)
利用審計線索識別數據訪問類型
以找出最可能的索引機制等等
由於這些及其它的原因
FGA 成為數據庫管理員工具箱中最重要的工具之一
不過
在 Oracle
i Database 中
它缺少一個重要的特性
在 SELECT 語句之外的語句上使用
所有類型的 DML 在 Oracle Database
g 中
FGA 已變得很完善 — 它可以審計所有類型的 DML 語句
而不只是 SELECT
讓我們看一個例子
在本系列的第
部分中
我介紹了一個名稱為 ACCOUNTS 的表
在那個表上定義的 FGA 策略為
begin
dbms_fga
add_policy (
object_schema =>
BANK
object_name =>
ACCOUNTS
policy_name =>
ACCOUNTS_ACCESS
audit_column =>
BALANCE
audit_condition =>
BALANCE >=
);
end;
在 Oracle
i Database 下
這個策略只能審計 SELECT 語句
然而
在 Oracle Database
g 中
您可以擴展它
使它包含 INSERT
UPDATE 和 DELETE
您可以通過指定一個新的參數來實現這個目的
statement_types =>
INSERT
UPDATE
DELETE
SELECT
這個參數將在所有包括的語句類型上啟用審計
您甚至可能考慮為每種語句類型創建單獨的策略
這將允許您隨意地啟用和禁用策略 — 尤其是
控制審計線索的創建
以管理它們占用的空間
不過
statement_type 參數默認情況下只審計 SELECT 語句
在策略中添加新的參數之後
發出以下語句
update accounts set balance =
where balance >=
;
這將使一條記錄插入到 FGA_LOG$ 表中
注意這條記錄是由一個自動事務插入的
即使您回滾 update 語句
這條記錄也將存在
您可以從另一個會話來檢查線索是否存在
select lsqltext from fga_log$;
LSQLTEXT
update accounts set balance =
where balance >=
該行還包括其它所有的相關詳細信息(如表名稱
策略名稱和事務 ID)
與觸發器方法相比較 那麼 FGA 能做什麼原來的基於觸發器的方法不能做的事情?
在 Oracle Database
g 之前
DML 語句審計是在一個觸發器中進行的
類似於以下方式(注意
這不是真實的代碼
只是一個代表性的示例)
CREATE TRIGGER XXXXX
ON Table
AFTER INSERT OR UPDATE OR DELETE
FOR EACH ROW
BEGIN
INSERT INTO AUDIT_LOG
Old Value
New Value
Time
END
觸發器捕獲舊的值和新的值
並填充 AUDIT_LOG 表
如果需要
還可以將它變為自動事務
最大的問題是觸發器是對每行觸發的
而不是每條語句一次
例如
以下語句
update accounts set balance =
where balance >=
;
對全部
條記錄觸發
在審計表中插入
行
這種方法可能嚴重地損害 update 語句的性能
甚至可能因審計線索中的空間問題而導致失敗
使用語句觸發器也無濟於事
因為它不能捕獲個別記錄的任何新的或舊的值
比較而言
在 FGA 方法中
只創建一條記錄
並且插入只在每條語句上執行一次
而不是每行一次 — 即使有的話
對性能的影響也很小
在 FGA 中
您可以指定相關的列來限定審計線索僅在這些列被訪問時才創建
在觸發器中
通過使用觸發器定義的 WHERE
這種功能也可以實現
不過
其中存在一個非常重要的差異 — 在觸發器中
只有當列被修改時(而不是被訪問時)才檢查它們
在 FGA 中
無論何時列被訪問(無論它們被修改與否)
審計就開始
這個特性使得 FGA 比觸發器具有更多的功能
另一個優點是 FGA 工具的適用性
有時
在一個視圖上定義的 INSTEAD OF 觸發器在基表上更新視圖
另一個 INSTEAD OF 觸發器不能捕獲由其它的觸發器所作的修改
因此這些修改不能被記錄
然而
FGA 是建立在視圖或表的基礎上的
它能夠捕獲變化
而不論變化來自哪裡 — 用戶語句或觸發器
那麼
是否存在觸發器比 FGA 更好的情況呢?可能有兩種情況
記住
FGA 通過一個自動事務來插入審計線索
這種事務在它自己的上下文中提交
當 DML 語句失敗或被回滾時
插入的線索記錄不被回滾
如果用戶更新了一些東西但沒有提交
則不執行修改
但不管怎樣
將創建審計線索
這可能導致在審計線索中產生幾個虛假的實際項目 — 一種不希望出現的潛在情況
隨後使用通過閃回查詢捕獲的 SCN 號碼對表進行分析將可能揭露這個問題
但這個過程可能非常復雜
但如果這種風險是不可接受的
那麼基於觸發器的方法將優於 FGA 成為首選
FGA 記錄用戶發出的 SQL 語句和 SCN 號碼
但不記錄在修改之前和之後的值
必須使用一個單獨的工具來從表中通過閃回查詢取出這些值
因為閃回查詢依賴於 UNDO 段中包含的信息(這些信息是有限的)
因此這個工具可能不會從過去很久的時間點上取出舊的值
基於觸發器的方法在源數據上捕獲變化
因此保證舊的值和新的值都有記錄
在變化期間 FGA 的行為 數據始終在變化
因此它有可能變得適用於審計條件 — 雖然之前它不適用於審計條件
反之亦然
這個問題帶來了一些關於 FGA 在不同情況下的行為的有趣問題
考慮我們的例子
其中在 UPDATE 上已經定義了 FGA 策略
條件為 BALANCE >=
審計列是 BALANCE
第
種情況
之前
BALANCE =
用戶發出
update accounts set balance =
where ACCOUNT_NO =
舊的和新的 balance 都小於
審計條件不滿足
因此這條語句將不會被審計
第
種情況
之前
BALANCE =
用戶發出
update accounts set balance =
where ACCOUNT_NO =
新的 balance 大於
審計條件滿足
因此這條語句將 會被審計
第
種情況
之前
BALANCE =
用戶發出
update accounts set balance =
where ACCOUNT_NO =
新的 balance 小於
但舊的 balance 大於
因此審計條件滿足
這條語句將被審計
第
種情況
用戶插入一行
其中有 BALANCE <
insert into accounts values (
X
);
因為 balance
不滿足審計條件
所以這條語句不被審計
如果 balance 列大於或等於
它將被審計
第
種情況
用戶插入一行
其中 balance 的值為空
insert into accounts (account_no
status) values (
X
);
因為 balance 為空
該列沒有任何默認值
所以審計條件不滿足(比較 NULL >=
結果為 FALSE)
這條語句不會被審計
重要注意事項
假設該列有一個大於
的默認值時
這條語句仍然不會被審計
即使插入行的 balance 列值大於
所有相關的列? 考慮在表 ACCOUNTS 上定義的一個策略
如下
begin
dbms_fga
add_policy (
object_schema =>
ANANDA
obje
From:http://tw.wingwit.com/Article/program/Oracle/201311/16901.html