Oracle 21c 的区块链表,是最受关注的特性,但是还有一个小特性,很少有人提及,那就是 Immutable tables - 不可变表。
区块链表是在 21c 中引入的,然后向后移植到 19.10,不可变表同时被引入到 Oracle 21.3 和 19.11 中,因此它可以被认为是 19c 和 21c 的新特性。
参数设置
要想使用到这个特性,需要将数据库的 compatible 参数设置 19.11.0 之上(请预先评估这个参数的影响)。
否则会收到如下报错:
ERROR at line 1:
ORA-00406: COMPATIBLE parameter needs to be 19.11.0.0.0 or greater
ORA-00722: Feature "Immutable table" compatible string 19.0.0
例如:
# Oracle Database 19c
alter system set compatible='19.11.0' scope=spfile;
# Oracle Database 21c
alter system set compatible='21.0.0' scope=spfile;
shutdown immediate;
startup;
主要特性
不可变表继承了 Blockchain Table 的相似语法,但是去掉了内部行记录的链接,提高了性能。
关于不可变表的主要好处如下:
不可变表是只读表,可防止内部人员未经授权的数据修改和人为错误导致的意外数据修改。
可以防范受感染或恶意员工进行的未经授权的修改。
可以向不可变表添加新行,但不能修改现有行。
必须为不可变表和不可变表中的行指定保留期。在指定的行保留期之后,行将过时。只能从不可变表中删除过时的行。
不可变表包含系统生成的隐藏列。列与区块链表的列相同。插入一行时,会为 ORABCTAB_CREATION_TIME$ 和 ORABCTAB_USER_NUMBER$ 列设置一个非 NULL 值。其余系统生成的隐藏列的值设置为 NULL。
使用不可变表不需要更改现有应用程序。
范例
以下是创建 Immutable Table 的范例:
CREATE IMMUTABLE TABLE mogdb (id NUMBER, duser VARCHAR2(40), value NUMBER)
NO DROP UNTIL 40 DAYS IDLE
NO DELETE UNTIL 100 DAYS AFTER INSERT;
以下是在墨天轮 Oracle 21c Express 版本的实训环境中所做的测试:
bash-4.4$ sqlplus / as sysdba
SQL*Plus: Release 21.0.0.0.0 - Production on Tue Nov 9 12:43:31 2021
Version 21.3.0.0.0
Copyright (c) 1982, 2021, Oracle. All rights reserved.
Connected to:
Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
SQL> show pdbs;
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 XEPDB1 READ WRITE NO
SQL> alter session set container=XEPDB1;
Session altered.
SQL> CREATE IMMUTABLE TABLE mogdb (id NUMBER, duser VARCHAR2(40), value NUMBER)
NO DROP UNTIL 40 DAYS IDLE
NO DELETE UNTIL 100 DAYS AFTER INSERT;
Table created.
SQL> insert into mogdb values(1,'zCloud',100);
1 row created.
SQL> insert into mogdb values(2,'openGauss',200);
1 row created.
SQL> commit;
Commit complete.
SQL> select * from mogdb;
ID DUSER VALUE
---------- ---------------------------------------- ----------
1 zCloud 100
2 openGauss 200
SQL> update mogdb set value=300;
update mogdb set value=300
*
ERROR at line 1:
ORA-05715: operation not allowed on the blockchain or immutable table
数据维护
只有当数据超过保留期限,才能从不可变表中删除行。
以下示例以 SYS 身份连接时,删除不可变表 trade_ledger 中保留窗口之外的所有行。删除的行数存储在输出参数 num_rows 中。
DECLARE
num_rows NUMBER;
BEGIN
DBMS_IMMUTABLE_TABLE.DELETE_EXPIRED_ROWS(‘EXAMPLES’,‘TRADE_LEDGER’, NULL, num_rows);
DBMS_OUTPUT.PUT_LINE('Number_of_rows_deleted = ’ || num_rows);
END;
/
以下示例以 SYS 身份连接时,删除在当前系统日期之前 30 天创建的过时行。删除的行数存储在输出参数 num_rows 中。
DECLARE
num_rows NUMBER;
BEGIN
DBMS_IMMUTABLE_TABLE.DELETE_EXPIRED_ROWS(‘EXAMPLES’,‘TRADE_LEDGER’, SYSDATE-30, num_rows);
DBMS_OUTPUT.PUT_LINE(‘Number_of_rows_deleted=’ || num_rows);
END;
/
当尝试修改不可变表的数据时,你会收到类似如下的错误提示:
SQL Error: ORA-05715: operation not allowed on the blockchain or immutable table
如果不可变表为空或在其保留期定义的一段时间内未修改,则可以删除不可变表。
例如:
DROP TABLE examples.trade_ledger;