Oracle 區塊鏈表創建過程詳解
大傢好!我是隻談技術不剪發的 Tony 老師。
Oracle 21c 增加瞭一個非常強大的新功能:原生的區塊鏈表(Blockchain Table)。Oracle 區塊鏈表是一個具有防篡改功能的表,隻能插入數據,同時提供瞭表級和行級的保留期限。區塊鏈表中的所有行構成瞭一個數據鏈,每一行存儲瞭當前數據和前一個哈希值的哈希值。
Oracle 區塊鏈技術可以有效防范數據庫欺詐,利用區塊鏈的防篡改特性,用戶可以為金融交易、監管鏈、法定保全、托管服務、審計日志以及許多其他使用場景下的集中式總賬提供安全保護。
本文給大傢一下如何創建和使用 Oracle 區塊鏈表,以及相關的註意事項。如果覺得文章有用,歡迎評論📝、點贊👍、推薦🎁
📝Oracle 區塊鏈表功能也可以在 Oracle 19.10 版本中使用,不過需要應用 patch 32431413 補丁,並且將 COMPATIBLE 參數設置為 19.10。從 Oracle 19.11 版本開始不再需要應用補丁。
創建區塊鏈表
我們可以使用 CREATE BLOCKCHAIN TABLE 命令創建區塊鏈表,同時可以指定三個選項。
其中,NO DROP 子句決定瞭什麼時候允許刪除區塊鏈表,如果表中沒有任何數據的話可以被刪除。與初始版本的區塊鏈表不同,從 Oracle 19.11 和 Oracle 21.3 開始 NO DROP 子句也可以阻止通過 DROP USER … CASCADE 命令刪除區塊鏈表。
NO DROP [ UNTIL number DAYS IDLE ]
- NO DROP,不允許刪除表。創建測試表時小心使用該選項。
- NO DROP UNTIL number DAYS IDLE,不允許刪除表,直到指定天數之內都沒有插入新的數據行。測試時可以設置為 0 或者 1 天。
NO DELETE 子句決定瞭數據的保留期限,存在時間超過這個期限的數據才允許刪除。
NO DELETE { [ LOCKED ] | (UNTIL number DAYS AFTER INSERT [ LOCKED ]) }
- NO DELETE,數據永久保留。雖然沒有指定 LOCKED 關鍵字,但並不意味著可以使用 ALTER TABLE 命令修改保留期限,因為保留期限隻能增加,不能減少。
- NO DELETE LOCKED,數據永久保留,和 NO DELETE 一樣。
- NO DELETE UNTIL number DAYS AFTER INSERT,數據至少存在指定天數之後才能被刪除,可以使用 ALTER TABLE 命令增加保留期限。保留期限最少 16 天。
- NO DELETE UNTIL number DAYS AFTER INSERT LOCKED,數據至少存在指定天數之後才能被刪除,不能使用 ALTER TABLE 命令增加保留期限。保留期限最少 16 天。
HASHING 子句用於指定區塊鏈哈希算法和數據格式,當前版本隻能使用固定值,將來可能允許其他的設置。
HASHING USING sha2_512 VERSION v1
以下是一個創建區塊鏈表的完整示例:
--drop table bct_t1 purge; create blockchain table bct_t1 ( id number, fruit varchar2(20), quantity number, created_date date, constraint bct_t1_pk primary key (id) ) no drop until 0 days idle no delete until 16 days after insert hashing using "SHA2_512" version "v1";
📝在學習區塊鏈表時,註意不要設置太長的保留期限,否則需要等待很長時間之後才能刪除測試表。
查詢 USER_TAB_COLS 視圖可以看到數據庫為我們增加瞭一些不可見的字段。
set linesize 120 pagesize 50 column column_name format a30 column data_type format a27 column hidden_column format a13 select internal_column_id, column_name, data_type, data_length, hidden_column FROM user_tab_cols WHERE table_name = 'BCT_T1' ORDER BY internal_column_id; INTERNAL_COLUMN_ID COLUMN_NAME DATA_TYPE DATA_LENGTH HIDDEN_COLUMN ------------------ ------------------------------ --------------------------- ----------- ------------- 1 ID NUMBER 22 NO 2 FRUIT VARCHAR2 25 NO 3 QUANTITY NUMBER 22 NO 4 CREATED_DATE DATE 7 NO 5 ORABCTAB_INST_ID$ NUMBER 22 YES 6 ORABCTAB_CHAIN_ID$ NUMBER 22 YES 7 ORABCTAB_SEQ_NUM$ NUMBER 22 YES 8 ORABCTAB_CREATION_TIME$ TIMESTAMP(6) WITH TIME ZONE 13 YES 9 ORABCTAB_USER_NUMBER$ NUMBER 22 YES 10 ORABCTAB_HASH$ RAW 2000 YES 11 ORABCTAB_SIGNATURE$ RAW 2000 YES 12 ORABCTAB_SIGNATURE_ALG$ NUMBER 22 YES 13 ORABCTAB_SIGNATURE_CERT$ RAW 16 YES 14 ORABCTAB_SPARE$ RAW 2000 YES 14 rows selected.
{CDB|DBA|ALL|USER}_BLOCKCHAIN_TABLES 視圖包括瞭區塊鏈表的相關信息,它們是基於 SYS.BLOCKCHAIN_TABLE$ 系統表的視圖。
column row_retention format a13 column row_retention_locked format a20 column table_inactivity_retention format a26 column hash_algorithm format a14 SELECT row_retention, row_retention_locked, table_inactivity_retention, hash_algorithm FROM user_blockchain_tables WHERE table_name = 'BCT_T1'; ROW_RETENTION ROW_RETENTION_LOCKED TABLE_INACTIVITY_RETENTION HASH_ALGORITHM ------------- -------------------- -------------------------- -------------- 16 NO 0 SHA2_512
修改區塊鏈表
官方文檔告訴我們隻要不是減少保留期限,就可以使用 ALTER TABLE 命令修改 NO DROP 子句。不過目前如果我們將 NO DROP UNTIL 0 DAYS IDLE 修改為更長的期限,數據庫將會返回錯誤。
alter table bct_t1 no drop until 100 days idle; Error report - ORA-05732: retention value cannot be lowered
以上語法沒有問題,可能是系統的一個 bug。如果創建表時使用的是 NO DROP UNTIL 1 DAYS IDLE 獲取其他期限就沒有問題。
無論當前的保留期限是多少,如果將 NO DROP 修改為永久保留的話都會返回 ORA-00600 錯誤:
alter table bct_t1 no drop; Error starting at line : 1 in command - alter table bct_t1 no drop Error report - ORA-00600: internal error code, arguments: [atbbctable_1], [0], [], [], [], [], [], [], [], [], [], []
這可能是一個問題,因為大多數人可能想從保留期限為 0 天開始嘗試,然後再增加保留期限。從保留期限為 1 天開始可能會導致一定的風險,因為想要刪除測試表的唯一辦法就是刪除整個模式。
如果沒有指定 LOCKED 選項,我們可以使用 ALTER TABLE 命令修改 NO DELETE 子句,當然隻能增加保留期限。我們的測試表目前的數據保留期限為 16 天,下面我們將它修改為 32 天:
-- 增加到 32 天 alter table bct_t1 no delete until 32 days after insert; Table BCT_T1 altered. -- 減少到 16 天時返回錯誤 alter table bct_t1 no delete until 16 days after insert; Error report - ORA-05732: retention value cannot be lowered
當前版本中,如果嘗試將數據保留期限修改為 NO DELETE(增加保留期限)將會導致 ORA-00600 錯誤,應該也是一個 bug。
alter table bct_t1 no delete; Error report - ORA-00600: internal error code, arguments: [atbbctable_1], [0], [], [], [], [], [], [], [], [], [], []
阻止 DML 和 DDL 語句
區塊鏈表隻支持數據的插入,所有導致數據修改或刪除的 DML 和 DDL 語句都會返回錯誤。例如:
-- INSERT insert into bct_t1 (id, fruit, quantity, created_date ) values (1, 'apple', 20, sysdate); 1 row inserted. SQL> commit; Commit complete. -- UPDATE update bct_t1 set quantity = 10 where id = 1; Error report - SQL Error: ORA-05715: operation not allowed on the blockchain table -- DELETE delete from bct_t1 where id = 1; Error report - SQL Error: ORA-05715: operation not allowed on the blockchain table
導致數據變化的 DDL 語句同樣會返回錯誤,以下是一個 TRUNCATE 語句示例:
truncate table bct_t1; Error report - ORA-05715: operation not allowed on the blockchain table
我們可以擴展已有字段的長度,但是不能增加字段或者刪除已有字段:
-- 修改字段長度 alter table bct_t1 modify (fruit varchar2(25)); Table BCT_T1 altered. -- 增加字段 alter table bct_t1 add (additional_info varchar2(50)); Error report - ORA-05715: operation not allowed on the blockchain table -- 刪除字段 alter table bct_t1 drop column quantity; Error report - ORA-05715: operation not allowed on the blockchain table
DBMS_BLOCKCHAIN_TABLE
系統程序包DBMS_BLOCKCHAIN_TABLE 可以用於維護區塊鏈表。
其中,存儲過程 DELETE_EXPIRED_ROWS 可以用於刪除超過保留期限的數據行,這些數據無法使用正常的 DELETE 語句進行刪除。
set serveroutput on declare l_rows number; begin dbms_blockchain_table.delete_expired_rows( schema_name => 'admin', table_name => 'bct_t1', before_timestamp => null, number_of_rows_deleted => l_rows); dbms_output.put_line('Rows Deleted=' || l_rows); end; / Rows Deleted=0 PL/SQL procedure successfully completed.
另外,我們也可以增加一個日期限制,隻有超過保留期限並且滿足日期要求的數據行才會被刪除。
set serveroutput on declare l_rows number; begin dbms_blockchain_table.delete_expired_rows( schema_name => 'testuser1', table_name => 'it_t1', before_timestamp => systimestamp - 60, number_of_rows_deleted => l_rows); dbms_output.put_line('Rows Deleted=' || l_rows); end; / Rows Deleted=0 PL/SQL procedure successfully completed.
存儲過程 VERIFY_ROWS 可以用於檢查數據行擁有一致性哈希值,以及用戶簽名(如果使用瞭的話)。
set serveroutput on declare l_rows number; l_verified number; begin select count(*) into l_rows from admin.bct_t1; dbms_blockchain_table.verify_rows( schema_name => 'admin', table_name => 'bct_t1', number_of_rows_verified => l_verified); dbms_output.put_line('Rows=' || l_rows || ' Verified Rows=' || l_verified); end; / Rows=1 Verified Rows=1 PL/SQL procedure successfully completed.
註意事項
在使用區塊鏈表之前需要考慮以下問題:
- 目前區塊鏈表的功能還存在一些問題,某些功能並不完全像官方文檔描述。
- 區塊鏈表比普通表的性能差一些,因為它需要執行更多的操作,例如計算哈希值。
- 區塊鏈表可以像其他表一樣支持索引和分區。
- 區塊鏈表的導入導出還存在一些限制。
- 區塊鏈表的使用限制。
- Oracle 推薦將每個區塊鏈的當前哈希算法和相應的序列號存儲在數據庫之外,這樣就可以將存儲的值和表中的數據進行比較,提供額外的安全保護。
- 在 data guard 配置中,Oracle 推薦使用最大保護模式或者最大高可用性模式同步區塊鏈表。
- DBMS_USER_CERTS 程序包中的 ADD_CERTIFICATE 存儲過程可以用於增加用戶證書,然後使用 DBMS_BLOCKCHAIN_TABLE 程序包中的 SIGN_ROW 存儲過程將其應用到已有的數據行。
以上就是Oracle 一個集中式的區塊鏈平臺的詳細內容,更多關於Oracle區塊鏈平臺的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- Oracle觸發器和程序包的基本介紹
- MySQL基礎快速入門知識總結(附思維導圖)
- Oracle Logminer快速使用詳解
- 在Oracle表中進行關鍵詞搜索的過程
- ORACLE中dbms_output.put_line輸出問題的解決過程