Oracle Database 19cはRelease Update (RU)にバグ・フィックスだけでなく新機能を追加する場合があります。本記事で紹介するBlockchain Tableも RU 19.10 で追加された新機能です。
Blockchain Tableとは
Blockchain Tableは格納されるレコードの更新や削除を制限し、ハッシュ値によるデータの改竄をチェックする機能を持ったテーブルです。Immutable Tableをベースにしています。Blockchain Tableは通常のテーブル定義に加えて以下の設定を追加することができます。
- テーブル削除を制限する期間(Immutable Tableと同じ)
- レコード削除を制限する期間(Immutable Tableと同じ)
- レコード削除期間を変更できるか(Immutable Tableと同じ)
- ハッシュ値を計算するアルゴリズムとバージョン(Blockchain Table独自)
準備
Release Update 19.10 以降をインストールし、データベースに適用します。下記の例ではV$VERSIONビューを確認してRU 19.11が適用されていることを確認しています。
SQL> SELECT BANNER_FULL FROM V$VERSION;
BANNER_FULL
--------------------------------------------------------------------------------
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.11.0.0.0
次に初期化パラメーターcompatibleを19.10.0.0.0以上に変更する必要があります。以下の例では19.11.0.0.0に変更しています。
SQL> SHOW PARAMETER COMPATIBLE
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
compatible string 19.11.0.0.0
noncdb_compatible boolean FALSE
作成
Blockchain Tableの作成にはCREATE BLOCKCHAIN TABLE文を実行します。何もオプションを指定しない場合はエラーORA-00905が発生します。
SQL> CREATE BLOCKCHAIN TABLE block1 (c1 NUMBER, c2 VARCHAR2(10));
CREATE BLOCKCHAIN TABLE block1 (c1 NUMBER, c2 VARCHAR2(10))
*
行1でエラーが発生しました。:
ORA-00905: キーワードがありません。
最低限、テーブルの削除制限(NO DROP句)と、レコードの削除制限(NO DELETE句)、ハッシュ値計算アルゴリズム(HASING句)を指定します。HASHING USING句は現状では固定のようです。作成後は通常のテーブルと同様にINSERT文を実行できます。
SQL> CREATE BLOCKCHAIN TABLE block1 (c1 NUMBER, c2 VARCHAR2(10))
2 NO DROP UNTIL 1 DAYS IDLE
3 NO DELETE UNTIL 16 DAYS AFTER INSERT
4 HASHING USING sha2_512 VERSION v1
5 TABLESPACE blockts1;
表が作成されました。
SQL> INSERT INTO block1 VALUES (100, 'data1');
1行が作成されました。
SQL> COMMIT;
コミットが完了しました。
上記のCREATE文で作成されたテーブルは USER_TABLESビューだけでなくUSER_BLOCKCHAIN_TABLESビューに情報が格納されます。
SQL> SELECT * FROM user_blockchain_tables;
TABLE_NAME ROW_RETENTION ROW TABLE_INACTIVITY_RETENTION HASH_ALG
------------------------------ ------------- --- -------------------------- --------
BLOCK1 16 NO 1 SHA2_512
Blockchain TableにはLONG, TIMESTAMP WITH TIME ZONE等、一部のデータ型は指定できません。
SQL> CREATE BLOCKCHAIN TABLE block3 (c1 LONG, c2 TIMESTAMP WITH TIME ZONE, c3 TIMESTAMP WITH LOCAL TIME ZONE)
2 NO DROP UNTIL 1 DAYS IDLE
3 NO DELETE UNTIL 16 DAYS AFTER INSERT
4 HASHING USING sha2_512 VERSION v1
5 TABLESPACE blockts1;
CREATE BLOCKCHAIN TABLE block3 (c1 LONG, c2 TIMESTAMP WITH TIME ZONE, c3 TIMESTAMP WITH LOCAL TIME ZONE)
*
行1でエラーが発生しました。:
ORA-05816: failed to create blockchain or immutable table
ORA-05730: data type not supported for blockchain or immutable table
NO DELETE UNTIL句に指定される日数は16日以上を指定する必要があります。
SQL> CREATE BLOCKCHAIN TABLE block2 (c1 NUMBER, c2 VARCHAR2(10))
2 NO DROP UNTIL 1 DAYS IDLE
3 NO DELETE UNTIL 15 DAYS AFTER INSERT
4 HASHING USING sha2_512 VERSION v1
5 TABLESPACE blockts1;
CREATE BLOCKCHAIN TABLE block2 (c1 NUMBER, c2 VARCHAR2(10))
*
行1でエラーが発生しました。:
ORA-05741: minimum retention time too low, should be at least 16 days
テーブルの削除可能期間を示すNO DROP句は初期化パラメーターblockchain_table_max_no_dropの影響を受けるようですが検証できていません。
行の削除制限を示すNO DELETE句にLOCKEDを指定すると行の削除設定を変更できなくなります。その場合USER_BLOCKCHAIN_TABLESビューのROW_RETENTION_LOCKED列にYESが出力されます。
SQL> CREATE BLOCKCHAIN TABLE block2 (c1 NUMBER, c2 VARCHAR2(10))
2 NO DROP UNTIL 1 DAYS IDLE
3 NO DELETE LOCKED
4 HASHING USING sha2_512 VERSION v1
5 TABLESPACE blockts1;
表が作成されました。
SQL> ALTER TABLE block2 NO DELETE UNTIL 18 DAYS AFTER INSERT;
ALTER TABLE block2 NO DELETE UNTIL 18 DAYS AFTER INSERT
*
行1でエラーが発生しました。:
ORA-05731: blockchain or immutable table BLOCK2 cannot be altered
SQL> SELECT * FROM user_blockchain_tables;
TABLE_NAME ROW_RETENTION ROW TABLE_INACTIVITY_RETENTION HASH_ALG
------------------------------ ------------- --- -------------------------- --------
BLOCK1 16 NO 2 SHA2_512
BLOCK2 YES 1 SHA2_512
列定義
各レコードの作成日時や制約を実装する情報はORABCTAB_で始まる名前の隠し列として定義されています(下記の表)。しかしUSER_TAB_COLUMNSビューからは参照できません。またSQL*PlusのSET COLINVISIBLE ONを実行しても表示されませんでした。
列名 | データ型 | 説明 |
---|---|---|
ORABCTAB_INST_ID$ | NUMBER(22) | 行がインサートされたインスタンスID |
ORABCTAB_CHAIN_ID$ | NUMBER(22) | チェーンID (0~31) |
ORABCTAB_SEQ_NUM$ | NUMBER(22) | チェーンのシーケンス番号 |
ORABCTAB_CREATION_TIME$ | TIMESTAMP WITH TIME ZONE | レコード作成日時 |
ORABCTAB_USER_NUMBER$ | NUMBER(22) | 行を追加したユーザーID |
ORABCTAB_HASH$ | RAW(2000) | 行のハッシュ値 |
ORABCTAB_SIGNATURE$ | RAW(2000) | ハッシュ値から計算される行のシグネチャ |
ORABCTAB_SIGNATURE_ALG$ | NUMBER(22) | シグネチャ・アルゴリズム |
ORABCTAB_SIGNATURE_CERT$ | RAW(16) | 署名された行の署名に関連付けられた証明書のGUID |
ORABCTAB_SPARE$ | RAW(2000) | 将来のために予約 |
SQL> SET COLINVISIBLE ON
SQL> DESC block1
名前 NULL? 型
----------------------------------------- -------- ----------------------------
C1 NUMBER
C2 VARCHAR2(10)
SQL> SELECT c1, c2, ORABCTAB_SEQ_NUM$, ORABCTAB_CREATION_TIME$ FROM block1;
C1 C2 ORABCTAB_SEQ_NUM$ ORABCTAB_CREATION_TIME$
---------- ---------- ----------------- ------------------------------------
100 data1 1 21-06-30 05:50:41.930720 +00:00