空谷に吼える

ブロックチェーン/DLTまわりのなにかしらを書いていく所存

Oracle Database 23cの新機能のFlashback Data Archive(Flashback Time Travel)×Blockchain Tableを試す

Flashback Data Archiveの履歴表をBlockchain Tableにできるようになったらしい

Oracle Databaseの23cが(プラットフォームごとに順次)リリースされています。で、23cの新機能には"フラッシュバック・データ・アーカイブ履歴表をブロックチェーン表にできるようになりました。"というのがあります*1

わたしがFlashback Data Archiveを使ったことがないせいかもしれないですが、これだけ読んでもいまいちどういうことなのか想像がつかない……のでもうちょっと詳しい記載がないか探してみると、23c新機能ガイドに以下の説明があります。

ブロックチェーン表ログ履歴 フラッシュバック・データ・アーカイブの履歴表がブロックチェーン表になりました。この機能を使用すると、1つ以上の通常のユーザー表に対する変更を、フラッシュバック・データ・アーカイブの一部としてOracleデータベースによって保守されるブロックチェーン表で追跡できます。通常の表内の各変更は、ブロックチェーン表によって管理される暗号化ハッシュ・チェーン内の個別の行として、ブロックチェーン・ログ履歴表に追加されます。フラッシュバック・データ・アーカイブブロックチェーン・ログ履歴表のデータとチェーンの整合性を検証するには、組込みの検証プロシージャ(DBMS_BLOCKCHAIN_TABLE.verify_rows)を使用するか、外部の検証を使用します。これには、https://github.com/oracle/blockchain-table-samplesに用意されているサンプルが示す継続的な検証プロセスが含まれています。

この機能を使用すると、暗号的にセキュアで検証可能な方法で、通常のユーザー表に対する変更を記録できます。

読み解くと、「もともとFlashback Data Archiveで(Blockchain Tableではない)通常のテーブルの変更履歴を履歴表として保存しておけるが、その履歴表をBlockchain Tableにすることができるようになったよ」ということですね。Blockchain Tableの機能強化のコーナーに書いてはあるんですが、どちらかというとFlashback Data Archiveの機能強化ですね。

  • Flashback Data Archiveを設定しておくことにより保存される履歴をBlockchain Tableに記録することで、改ざん(削除、改変)ができないようにする
  • Blockchain Tableに備わっている検証プロシージャ(verify_rows)を用いることで、履歴に改ざんがないことの検証もできる

といった点が追加のメリットということになるかと思います。

試してみた

ということで実際どういう差があるのか試してみました。Flashback Data Archiveを使うのが始めてだったので作成部分は以下の記事をそのまま参考にしています。

ORACLE-BASE - Blockchain Table Enhancements in Oracle Database 23c

まずユーザーに必要(そう)な権限を付与し、Flashback Archiveオブジェクトを作成します。

-- AS SYSDBA
grant db_developer_role to BCTTEST;
alter user BCTTEST quota unlimited on users;
create flashback archive default fda_1year tablespace users quota 10g retention 1 year;
grant flashback archive on fda_1year to BCTTEST;
grant flashback archive administer to BCTTEST;
grant execute on dbms_flashback_archive to BCTTEST;
grant create any context to BCTTEST;

そんでFlashback Data Archive設定をしつつテーブルを作成します。 今回の機能追加により、BLOCKCHAIN FLASHBACK ARCHIVE とBLOCKCHAIN句を追加して指定することでBlockchain Tableが利用されるようになります。

-- AS BCTTEST
drop table if exists t1 purge;

create table t1 (
  id           number,
  description  varchar2(50),
  constraint t1_pk primary key (id)
)
blockchain flashback archive fda_1year;

Flashback Data Archiveを設定すると、自動的にSYS_FBA_DDL_COLMAP_nnnnn, SYS_FBA_HIST_nnnnn, SYS_FBA_TCRV_nnnnnの3つのテーブルが作成されます。 このうちSYS_FBA_HIST_nnnnnの形式のテーブルが履歴の保持に使われるもので、これがBlockchain Tableになっています(他ふたつは通常のテーブルのままです)。 DDLは以下になっていました。CREATE BLOCKCHAIN TABLEの部分に注目。

-- SYS_FBA_HIST_80571
  CREATE BLOCKCHAIN TABLE "BCTTEST"."SYS_FBA_HIST_80571" 
   (    "RID" VARCHAR2(4000 BYTE), 
    "STARTSCN" NUMBER, 
    "ENDSCN" NUMBER, 
    "XID" RAW(8), 
    "OPERATION" VARCHAR2(1 BYTE), 
    "ID" NUMBER, 
    "DESCRIPTION" VARCHAR2(50 BYTE)
   )  NO DROP UNTIL 0 DAYS IDLE NO DELETE UNTIL 16 DAYS AFTER INSERT 
 HASHING USING "SHA2_512"  CONFIGURE 32 SYSTEM CHAINS PER INSTANCE VERSION "V2"
 PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 
  STORAGE(
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS" 
  PARTITION BY RANGE ("ENDSCN") 
 (PARTITION "HIGH_PART"  VALUES LESS THAN (MAXVALUE) SEGMENT CREATION DEFERRED 
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 
 NOCOMPRESS LOGGING 
  STORAGE(
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS" ) ;

  CREATE INDEX "BCTTEST"."SYS_FBA_HIST_IDX1_80571" ON "BCTTEST"."SYS_FBA_HIST_80571" ("ENDSCN", "STARTSCN", "RID") 
  PCTFREE 10 INITRANS 2 MAXTRANS 165 
  STORAGE(
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS"  LOCAL
 (PARTITION "HIGH_PART" NOCOMPRESS 
  PCTFREE 10 INITRANS 2 MAXTRANS 165 LOGGING 
  STORAGE(
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS" ) 
  PARALLEL ;

なお、DROP不可の保護期間(NO DROP UNTIL n DAYS IDLE)は0=いつでもDROP可能に、古い行が破棄可能になるまでの期間(NO DELETE UNTIL n DAYS AFTER INSERT)は16日になっていますね。通常、Blockchain Tableはこれらのnを増やす=制約を厳しくする方向にはALTER TABLEで更新できるんですが、このFlashback Data Archiveのテーブルに関しては試してみたところ以下のようなエラーになってALTER TABLEできませんでした。どうもそもそもFlashback Data Archiveのテーブルは制約されてるっぽい?頑張れば何らかの方法で回避できるのかもしれないですが、データベースちからが足りずわかりません。

ORA-55622: DML、ALTERおよびCREATE UNIQUE INDEX操作は表"BCTTEST"."SYS_FBA_HIST_80571"では許可されていません
55622. 00000 -  "DML, ALTER and CREATE UNIQUE INDEX operations are not allowed on table \"%s\".\"%s\""
*Cause:    An attempt was made to write to or alter or create unique index
           on a Flashback Archive internal table.
*Action:   No action required. Only Oracle is allowed to perform such
           operations on Flashback Archive internal tables.

Flashback Data Archiveとしてはふつうに使えるので以下のようにAS OFで過去断面をクエリするなどを試してみましょう。 ちなみに、更新を行った際にSYS_FBA_HISTに過去断面のデータが書き込まれるんですが、即時ではなく時間差がありました(もともとそういう仕様な模様)。

-- AS BCTTEST
insert into t1 values (1, 'aaaa') ;
insert into t1 values (2, 'bbbb') ;
update t1 set description = 'xxx' where id = 1;
commit;
select * from t1 AS OF TIMESTAMP(SYSTIMESTAMP - INTERVAL '1' MINUTE);
update t1 set description = 'yyy' where id = 2;
commit;
select * from t1 AS OF TIMESTAMP(SYSTIMESTAMP - INTERVAL '1' MINUTE);
select * from SYS_FBA_HIST_80571;

HISTテーブルに対してハッシュチェーンの検証も、以下のように通常のBlockchain Tableと同様に行えました。これによりFlashback Data Archiveを用いることで記録される履歴が改ざんされていないことを確認できます。

set serveroutput on
declare
  l_rows      number;
  l_verified  number;
begin
  select count(*)
  into   l_rows
  from   SYS_FBA_HIST_80571;

  dbms_blockchain_table.verify_rows(
    schema_name             => 'BCTTEST',
    table_name              => 'SYS_FBA_HIST_80571',
    number_of_rows_verified => l_verified);

  dbms_output.put_line('Rows=' || l_rows || '  Verified Rows=' || l_verified);
end;

結果↓

Rows=3  Verified Rows=3
PL/SQLプロシージャが正常に完了しました。

想定ユースケースは?

基本的な用途や機能としては基本的にFlashback Data Archive(あるいはFlashback Time Travel)と変わらず、Blockchain Tableになったことで改ざん不能であり、かつ改ざんしていないことを検証できるようになっています。ある情報(データ)の更新履歴を確実に、かつ監査で改ざんしていないことを確認しやすく保存したい、というような場合に便利に使えそうです。

↓でサンプルユースケースとして扱っているような、ドキュメントのバージョン履歴を保持したい、みたいなところにはハマるかも? gakumura.hatenablog.com

*1:なお、フラッシュバック・データ・アーカイブ/Flashback Data Archiveは19c以降ではフラッシュバック・タイム・トラベル/Flashback Time Travelとも呼称されています。さらに昔はOracle Total Recallという名称でした。この記事ではFlashback Data Archiveで統一します。