Oracle 11g新特性之SecureFiles
SecureFiles:新 LOB
瞭解如何使用新一代 LOB:SecureFiles。SecureFiles 集外部檔案和資料庫 LOB 方法的優點於一身,可以儲存非結構化資料,允許加密、壓縮、重複消除等等。
資料庫駐留 BLOBS 或 OS 檔案
您在 Oracle 資料庫中儲存什麼?通常,您會以關係格式儲存資料以便於對映到某些定義模式的型別,或者以客戶姓名、帳戶餘額、狀態程式碼等定義的資料型別儲存資料。但是,以非結構化或半結構化格式儲存資訊的需求也日益增加。例如,照片、字處理文件、電子表格、XML 檔案等等。這些型別的資料如何儲存?
通常有兩種方法:這些資料作為 LOB 欄位(BLOB 用於儲存二進位制資料,CLOB 用於儲存字元資料)儲存在資料庫中,或者通過引用儲存在資料庫中的檔案儲存在 OS 檔案中。
每種方法都各具優缺點。OS 檔案可以由 OS 和日誌檔案系統快取以加速崩潰後的恢復。由於可進行壓縮,因此 OS 檔案佔用的空間通常也比資料庫中的資料要少。
還有一些工具可以智慧地識別檔案模式並消除重複從而提高儲存效率;但是 OS 檔案位於資料庫外部,因此資料庫屬性不適用於它們。這些檔案不進行備份、細粒度安全性不適用於它們,此類檔案不是事務的一部分 — 因此 Oracle 資料庫固有的讀取一致性等該概念不適用於它們。
如果能集兩種方法的優點於一身會怎樣?Oracle 資料庫 11g 中的 SecureFiles 為您提供了答案。SecureFiles 是資料庫中一個全新的基礎架構,可提供最佳的資料庫駐留 LOB 和 OS 檔案效能。讓我們看一看這種方案的實現方式。(順便說明的是,傳統 LOB 仍然以 BasicFiles 格式提供。)
實際示例
通過一個簡單的示例來介紹 SecureFiles 概念或許是一種最佳方式。假設您要開發一個合同管理系統,在該系統中您希望將所有合同的副本都放在一個表中。掃描的文件通常是 PDF 檔案而非文字。某些可能是 MS Word 文件或者甚至是掃描的照片。這是 BLOB 的最佳使用案例,因為列必需能夠支援二進位制資料。
通常,在 Oracle 資料庫 11g 推出之前,您可能會按照以下方式定義表:
create table contracts_basic ( contract_id number(12), contract_name varchar2(80), file_size number, orig_file blob ) tablespace users lob (orig_file) ( tablespace users enable storage in row chunk 4096 pctversion 20 nocache nologging ); \
實際的檔案以二進位制格式儲存在 ORIG_FILE 列中。各種引數指明在操作期間 LOB 不應快取並記入日誌,應按錶行儲存,塊大小應為 4KB 並儲存在表空間 USERS 中。由於您沒有明確指定,因此 LOB 在 Oracle 資料庫 11g 中以常規格式 (BasicFiles) 儲存。
如果您將 LOB 儲存為 SecureFile,只需在建立表時放入一個子句 store as securefile,如下所示:
create table contracts_sec ( contract_id number(12), contract_name varchar2(80), file_size number, orig_file blob ) tablespace users lob (orig_file) store as securefile ( tablespace users enable storage in row chunk 4096 pctversion 20 nocache nologging ) /
要建立 SecureFile LOB,您需要滿足兩個條件,而這兩個條件都是預設設定,因此您可能已經滿足。
- 初始化引數 db_securefile 應設為 permitted(預設設定)。我會在後面部分說明該引數的作用。
- 在其中建立 securefile 的表空間應啟用自動段空間管理 (ASSM)。在 Oracle 資料庫 11g 中,表空間建立的預設模式為 ASSM,因此該表空間可能已經這樣設定。如果沒有,則需要在一個新的 ASSM 表空間上建立 SecureFile。
表建立完成後,您可以載入資料,方式與 11g 之前的常規 LOB (BasicFile) 相同。不需要更改應用程式,也不需要記住某些特殊的語法。
下面是一個載入該表的小程式。
declare l_size number; l_file_ptr bfile; l_blob blob; begin l_file_ptr := bfilename('SECFILE', 'contract.pdf'); dbms_lob.fileopen(l_file_ptr); l_size := dbms_lob.getlength(l_file_ptr); for ctr in 1 .. 100 loop insert into contracts_sec ( contract_id, contract_name, file_size, orig_file ) values ( ctr, 'Contract '||ctr, null, empty_blob() ) returning orig_file into l_blob; dbms_lob.loadfromfile(l_blob, l_file_ptr, l_size); end loop; commit; dbms_lob.close(l_file_ptr); end; /
該程式將 contract.pdf 檔案分 100 次載入表的 100 個行中。您應該已經為儲存 contract.pdf 檔案的 OS 目錄定義了一個名為 SECFILE 的目錄物件。下面的示例指明 contract.pdf 檔案在 /opt/oracle 中的位置。
SQL> create directory secfile for ’/opt/oracle’;
將 LOB 儲存為 SecureFile 後,您就可以獲得很多能優化操作的特性。下面就是其中一些很有用的特性。
重複消除
重複消除可能是 SecureFiles 中最受歡迎的特性,它由於 OS 檔案在某些高階檔案系統中相對於資料庫駐留 BLOB 的優勢而倍受推崇。假設一個表有五個記錄,每個記錄各有一個 BLOB。其中三個 BLOB 是完全相同的。如果能夠只儲存該 BLOB 一次而在其他兩個記錄上只儲存對該副本的引用將極大地減少空間消耗。這在 OS 在檔案中是可行的,但在 Oracle 資料庫 10g LOB 中則無法實現。但是如果使用 SecureFiles,只需通過一個稱為重複消除的屬性即可輕鬆搞定。可以在表建立時指定該屬性,也可以在以後將其修改為:
SQL> alter table contracts_sec 2 modify lob(orig_file) 3 (deduplicate) 4 / Table altered.
使用重複消除後,資料庫計算每行中各列的雜湊值並進行相互比較。如果有匹配的雜湊值,則儲存該雜湊值而不是實際的 BLOB。新記錄插入時會計算其雜湊值,如果其雜湊值與其他雜湊值匹配,則插入雜湊值;否則儲存實際的值。
下面,我們來看看進行重複消除過程後的空間節省情況。可以通過程式包 DBMS_SPACE 檢查 LOB 段中的空間消耗。下面是一個顯示空間消耗的程式:
declare l_segment_name varchar2(30); l_segment_size_blocks number; l_segment_size_bytes number; l_used_blocks number; l_used_bytes number; l_expired_blocks number; l_expired_bytes number; l_unexpired_blocks number; l_unexpired_bytes number; begin select segment_name into l_segment_name from dba_lobs where table_name = 'CONTRACTS_SEC'; dbms_output.put_line('Segment Name=' || l_segment_name); dbms_space.space_usage( segment_owner => 'ARUP', segment_name => l_segment_name, segment_type => 'LOB', partition_name => NULL, segment_size_blocks => l_segment_size_blocks, segment_size_bytes => l_segment_size_bytes, used_blocks => l_used_blocks, used_bytes => l_used_bytes, expired_blocks => l_expired_blocks, expired_bytes => l_expired_bytes, unexpired_blocks => l_unexpired_blocks, unexpired_bytes => l_unexpired_bytes ); dbms_output.put_line('segment_size_blocks => '|| l_segment_size_blocks); dbms_output.put_line('segment_size_bytes => '|| l_segment_size_bytes); dbms_output.put_line('used_blocks => '|| l_used_blocks); dbms_output.put_line('used_bytes => '|| l_used_bytes); dbms_output.put_line('expired_blocks => '|| l_expired_blocks); dbms_output.put_line('expired_bytes => '|| l_expired_bytes); dbms_output.put_line('unexpired_blocks => '|| l_unexpired_blocks); dbms_output.put_line('unexpired_bytes => '|| l_unexpired_bytes); end; /
該指令碼顯示 LOB 的各種與空間有關的統計資訊。進行重複消除過程之前,輸出如下:
Segment Name=SYS_LOB0000070763C00004$$ segment_size_blocks => 1072 segment_size_bytes => 8781824 used_blocks => 601 used_bytes => 4923392 expired_blocks => 448 expired_bytes => 3670016 unexpired_blocks => 0 unexpired_bytes => 0
使用重複消除後:
Segment Name=SYS_LOB0000070763C00004$$ segment_size_blocks => 1456 segment_size_bytes => 11927552 used_blocks => 7 used_bytes => 57344 expired_blocks => 127 expired_bytes => 1040384 unexpired_blocks => 1296 unexpired_bytes => 10616832
僅以上輸出中的一個度量標準就足以說明問題:used_bytes。它顯示了 LOB 列儲存的位元組數。使用重複消除之前,需要佔用 4,923,392 位元組或 5MB,但使用重複消除後,該值縮減為 57,344 位元組或大約 57KB,差不多是原始值的 1%。這是因為重複消除過程發現了 100 個具相同值的行(回憶一下,我們將同一個值放到了所有行的 LOB 列中)。重複消除過程只保留了一行而使其他行成為指標。
您也可以反向進行該重複消除過程:
SQL> alter table contracts_sec 2 modify lob(orig_file) 3 (keep_duplicates) 4 / Table altered.
之後,如果您再檢查空間:
Segment Name=SYS_LOB0000070763C00004$$ segment_size_blocks => 1456 segment_size_bytes => 11927552 used_blocks => 601 used_bytes => 4923392 expired_blocks => 0 expired_bytes => 0 unexpired_blocks => 829 unexpired_bytes => 6791168
您將發現 USED_BYTES 增加,變為大約 5MB 的原始值。
壓縮
SecureFiles 的另一個特性是壓縮。可以使用以下 SQL 壓縮儲存在 LOB 中的值:
SQL> alter table contracts_sec 2 modify lob(orig_file) 3 (compress high) 4 / Table altered.
現在,如果您執行空間查詢 PL/SQL 塊:
Segment Name=SYS_LOB0000070763C00004$$ segment_size_blocks => 1456 segment_size_bytes => 11927552 used_blocks => 201 used_bytes => 1646592 expired_blocks => 0 expired_bytes => 0 unexpired_blocks => 1229 unexpired_bytes => 10067968
您將發現 used_bytes 這一度量標準由 5MB 降至現在的 1,646,592 或大約 1.5 MB。
壓縮與重複消除不同。壓縮在每行的 LOB 列內部發生 — 每個 LOB 列單獨壓縮。在重複消除過程中,所有行都受到檢查,列中的重複值將進行刪除並替換為指標。如果您有兩個完全不同的行,重複消除不會減少佔用空間;但是壓縮可以優化 LOB 值的空間。除了對錶執行重複消除過程,您還可以對錶進行壓縮。
由於壓縮佔用 CPU 迴圈,因此如果資料壓縮量不大,可能並不值得進行壓縮。例如,如果您有大量已經壓縮過的 JPEG 照片,則進一步的壓縮不會節省任何空間。但是,如果您有一個作為 CLOB 儲存的 XML 文件,則壓縮可以節省大量空間。SecureFiles 壓縮自動檢測資料是否可壓縮並僅在壓縮可以節省空間時佔用 CPU 迴圈。
Oracle Text 索引可以在壓縮過的 SecureFiles LOB 上安裝。較之檔案系統中的壓縮檔案,這是在 Oracle 資料庫中儲存非結構化資料的主要好處。
此外,請注意,LOB 壓縮與表壓縮無關。壓縮表 CONTRACTS_SEC 並不會壓縮 LOB。LOB 壓縮僅在您執行上述 SQL 時才會發生。
加密
您可以對 SecureFiles 使用透明資料庫加密,就像您將對任何列所做的一樣。下面說明如何使用 AES 128 位加密對列 orig_file LOB 進行加密。
alter table contracts_sec modify lob(orig_file) (encrypt using 'AES128') /
啟用加密之前,您需要設定加密錢夾。(加密錢夾的完整描述可以在此 Oracle Magazine 文章中找到。)下面是總結的幾個步驟:
- 在 sqlnet.ora 中設定引數(如果尚未設定)以指定錢夾的位置:
ENCRYPTION_WALLET_LOCATION= (SOURCE= (METHOD=FILE) (METHOD_DATA= (DIRECTORY= /opt/oracle/orawall) ) )
目錄 /opt/oracle/orawall 應該已經存在;如果不存在,則應該建立該目錄。 - 建立錢夾:
alter system set encryption key authenticated by "mypass"
這將建立口令為 mypass 的錢夾並將其開啟。 - 上述步驟只需執行一次。錢夾建立並開啟後,只要資料庫在執行它就會一直開啟(除非人為關閉)。如果資料庫重啟,您需要通過以下語句開啟錢夾:
alter system set encryption wallet open identified by "mypass"
當 SecureFile LOB 列得到加密後,該表所有行的列值都會得到加密。加密後,您不能在表中使用常規匯出或匯入;您需要使用資料泵。
您可以檢視檢視 dba_encrypted_columns 瞭解哪些列已得到加密以及加密的方式。
SQL> select table_name, column_name, encryption_alg 2 from dba_encrypted_columns 3 / TABLE_NAME COLUMN_NAME ENCRYPTION_ALG ------------------------------ ------------------ ----------------------------- CONTRACTS_SEC ORIG_FILE AES 128 bits key
快取
較之資料庫駐留物件,在 OS 檔案中儲存非結構化資料的優勢之一是快取工具。檔案可以在作業系統的檔案緩衝區中進行快取。資料庫駐留物件還可以在資料庫緩衝區快取中進行快取。但是,在某些情況下,快取可能竟會損害效能。LOB 通常都很大(該術語大物件就是因此得名),如果它們進入緩衝區快取,大多數其他的資料塊將需要被推送出快取以為要進來的 LOB 騰出空間。該 LOB 可能以後永遠都不會使用,但是它進入緩衝區緩衝卻會導致某些必需的資料塊流出。因此,在大多數情況下,您可能希望對 LOB 禁用快取。
在針對 CONTRACTS_SEC 的示例指令碼中,您使用了 nocache 子句來禁用快取。要為 LOB 啟用快取,您可以對該表進行以下更改:
alter table contracts_sec modify lob(orig_file) (cache) /
這將啟用 LOB 快取。注意該快取只引用 LOB。表的其餘部分放入緩衝區快取,並遵循任何其他表的邏輯(無論該表上的 LOB 快取如何設定)。
快取的優點是非常依賴於應用程式。在處理縮圖的應用程式中,使用快取可能會提高效能。但是,對於大型文件或影像,最好關閉快取。您可以通過 securefiles 進行控制。
日誌記錄
日誌記錄子句決定 LOB 中的資料更改如何記錄到重做日誌流中。與任何其他資料一樣,預設設定為完全日誌記錄,但是由於 LOB 中的資料通常都很大,在某些情況下,您可能希望不進行日誌記錄。上述示例中的 NOLOGING 子句就可以實現該目的。
SecureFiles 為該子句提供了另一個值 filesystem_like_logging,如下所示:
create table contracts_sec_fs ( contract_id number(12), contract_name varchar2(80), file_size number, orig_file blob ) tablespace users lob (orig_file) store as securefile ( tablespace users enable storage in row chunk 4096 pctversion 20 nocache filesystem_like_logging )
注意以黑體顯示的行,它將 LOB 後設資料記錄到重做日誌中,而不是記錄整個 LOB。這類似於檔案系統。檔案後設資料記錄到檔案系統日誌中。同樣,SecureFiles 上的該子句會加速崩潰後的恢復。
管理
資料字典檢視 DBA_LOBS 顯示了資料庫中 LOB 的屬性(包括 SecureFiles)。下面是該檢視的列:
列名 | 說明 |
OWNER |
表的所有者 |
TABLE_NAME |
表的名稱 |
COLUMN_NAME |
LOB 列的名稱 |
SEGMENT_NAME |
LOB 作為單獨的段儲存,由使用者命名,預設為 SYS_LOB… |
TABLESPACE_NAME |
表空間的名稱 |
INDEX_NAME |
LOB 索引的名稱 |
CHUNK |
LOB 的塊大小 |
PCTVERSION |
在 SecureFiles 中忽略 |
RETENTION |
如果 SecureFile LOB 進行了更新,以前的影像與任何其他資料庫塊一樣儲存在還原段中;但是與資料庫塊不同的是,您可以指定以前的影像儲存多長時間(保留期)。 |
FREEPOOLS |
對 SecureFiles 忽略 |
CACHE |
SecureFile LOB 是否在緩衝池中緩衝(是/否),本文已說明 |
LOGGING |
是否記錄對 SecureFile LOB 進行的更改(是/否),本文已說明 |
ENCRYPT |
SecureFile LOB 是否已加密(是/否),本文已說明 |
COMPRESSION |
SecureFile LOB 是否已壓縮(是/否),本文已說明 |
DEDUPLICATION |
Securefile LOB 是否已進行重複消除(是/否),本文已說明 |
IN_ROW |
LOB 是否按錶行儲存 |
FORMAT |
LOB 是否與平臺的位元組順序有關 |
PARTITIONED |
LOB 是否在分割槽表上 |
SECUREFILE |
LOB 是 SECUREFILE(是或否)還是 BASICFILE |
在分割槽表上,LOB 資訊儲存在檢視 DBA_LOB_PARTITIONS 中。
LOB 到 SecureFiles 的移植
既然已經瞭解 SecureFiles 是多麼有用,您可能希望對現有的表進行轉換。最簡單的方法是建立一個新表,載入舊錶中的資料,然後重新命名該表。(當然,這要求這些表在操作期間不可用。)另一種方法是使用 dbms_redefinition 程式包線上重新定義表,不影響可用性。
我們通過一個示例來了解該過程。假設您希望移植原始表 CONTRACTS_BASIC 以儲存為 SecureFiles。要實現該目的,執行以下步驟。
- 確保您具有一個主鍵。如果沒有,建立一個。
alter table contracts_basic add constraint pk_contacts primary key (contract_id) /
- 構建新表。
create table contracts_new ( contract_id number(12), contract_name varchar2(80), file_size number, orig_file BLOB ) lob (orig_file) store as securefile (nocache nologging) /
- 將列對映到新表。
declare l_col_mapping varchar2(1000); begin l_col_mapping := 'contract_id contract_id , '|| 'contract_name contract_name , '|| 'file_size file_size, '|| 'orig_file orig_file'; dbms_redefinition.start_redef_table ('ARUP', 'CONTRACTS_BASIC', 'CONTRACTS_NEW', l_col_mapping); end; /
- 開始重新定義過程。
declare l_error_count pls_integer := 0; begin dbms_redefinition.copy_table_dependents ( 'ARUP', 'CONTRACTS_BASIC', 'CONTRACTS_NEW', 1, TRUE, TRUE, TRUE, FALSE, l_error_count ); dbms_output.put_line('Errors Occurred := ' || to_char(l_error_count)); end; /
這會將 CONTRACTS_BASIC 中的所有行復制到 CONTRACTS_NEW 中,因此,根據表的行數,該操作可能需要較長時間。 - 完成重新定義過程。
begin dbms_redefinition.finish_redef_table ('ARUP', 'CONTRACTS_BASIC', 'CONTRACTS_NEW'); end; /
- 確認表已得到轉換。
select securefile from dba_lobs where table_name = 'CONTRACTS_BASIC' / SEC --- YES
列顯示 YES,表明列已轉換為 SecureFiles。 - 刪除臨時表 CONTRACTS_NEW。
SQL> drop table contracts_new; Table dropped.
您可以嘗試在開始就啟用並行 DML 以加快複製過程。下面說明如何在會話中啟用並行 DML:
alter session force parallel dml;
初始化引數
初始化引數 db_securefile 決定 SecureFiles 在資料庫中的使用。下面是該引數的各種值及其效果:
值 |
效果 |
PERMITTED |
預設值。該值指明可以在資料庫中建立 SecureFile LOB。 |
ALWAYS |
既然您已經知道了 SecureFiles 是多麼有用,您可能希望確保所有 LOB 建立後就應該僅為 SecureFiles 而非預設的 BasicFiles(即使使用者沒有指定 securefile)。該引數值確保所有 LOB 預設情況下建立為 SecureFiles。記住,SecureFiles 需要 ASSM 表空間(在 11g 中為預設設定),因此如果您嘗試在非 ASSM 表空間中建立 LOB,將出現錯誤。 |
NEVER |
與 always 值相反。由於某種原因,您不喜歡 SecureFiles 並且不希望允許它在資料庫中建立。即使使用 SecureFile 子句,該引數值仍然會將 LOB 建立為 BasicFile。當使用了 SecureFile 子句而 LOB 仍然建立為預設的 BasicFile 時,使用者不會收到錯誤訊息。 |
IGNORE |
忽略 securefile 子句以及所有儲存子句。 |
結論
SecureFiles 不僅是新一代 LOB,它們還為 LOB 帶來了更多的價值,尤其是以前只能在檔案系統領域中獲得的特性。SecureFiles 可以進行加密以確保安全性,可以進行重複消除和壓縮以提高儲存效率,可以進行快取(或不進行快取)以加快訪問(或節省緩衝池空間),可以按多個級別記錄以減少崩潰後的平均恢復時間。引入 SecureFiles 後,您可以在資料庫中儲存更多的非結構化文件,而不會導致過多的開銷,也不會失去 OS 檔案系統提供的任何重要功能。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/1384/viewspace-217978/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle 11g 新特性 -- SecureFiles 說明Oracle
- Oracle 11g 新特性之DRCPOracle
- 【ORACLE新特性】11G 分割槽新特性Oracle
- Oracle 11g 新特性Oracle
- oracle 11g 的新特性Oracle
- oracle 11g新特性之密碼大小寫敏感Oracle密碼
- Oracle 20c 新特性:Online SecureFiles Defragmentation 線上的 LOB 碎片整理OracleFragment
- Oracle 11g 新特性簡介Oracle
- Oracle 11g新特性:Result CacheOracle
- Oracle 11g 新特性(轉載)Oracle
- Oracle 11g新特性之收集多列統計資訊Oracle
- Oracle 11g新特性之使用者重新命名Oracle
- 【DataGuard】Oracle 11g DataGuard 新特性之 Snapshot Standby DatabaseOracleDatabase
- Oracle 11g新特性之快取與連線池Oracle快取
- oracle DG 11g新特性彙總Oracle
- ORACLE 11G新特性之列新增操作Oracle
- oracle 11g 新特性 表壓縮Oracle
- [引用分割槽表]Oracle 11g新特性之引用分割槽表Oracle
- Oracle 11g 新特性 -- SQL Plan Management 示例OracleSQL
- 天天學習ORACLE(三)-11G新特性Oracle
- oracle 11g 新特性 磁碟組檢查Oracle
- Oracle 11G 新特性 Automatic block repairOracleBloCAI
- 11g分割槽新特性之interval partition
- oracle 11g 新特性之動態繫結變數窺視(二)Oracle變數
- oracle 11g 新特性之動態繫結變數窺視(一)Oracle變數
- Oracle 11g DG新特性--Automatic block repairOracleBloCAI
- Oracle 11g 新特性 – HM(Hang Manager)簡介Oracle
- ORACLE 11g新特性-統計值掛起Oracle
- oracle 11g 新特性 data recover AdvisorOracle
- oracle 11g 新特性 Flashback Data Archive 說明OracleHive
- Oracle 11g的新特性分割槽:System PartitionOracle
- 11g新特性之結果集快取快取
- 11g新特性--Oracle 11g 閃回資料歸檔Oracle
- Using Oracle SecureFiles LOBsOracle
- Oracle 12c新特性之Sequence的Session特性OracleSession
- Oracle11g新特性之editionOracle
- 新特性:/dev/shm對Oracle 11g的影響devOracle
- 【11g新特性】Oracle 加密表空間-可下載Oracle加密