Oracle Livelabs实验: 区块链表
Posted dingdingfish
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle Livelabs实验: 区块链表相关的知识,希望对你有一定的参考价值。
本实验基于Oracle Livalabs中的Database 21c - Blockchain Workshop实验指南。耗时约1小时。
概念
区块链表是仅允许插入操作的仅附加表。 根据时间禁止或限制删除行。 区块链表中的行通过特殊的排序和链接算法进行防篡改。 用户可以验证行没有被篡改。 作为行元数据一部分的哈希值用于链接和验证行。
区块链表使您能够实施集中式分类帐模型,其中区块链网络中的所有参与者都可以访问相同的防篡改分类帐。
中心化账本模型减少了建立去中心化账本网络的管理开销,与去中心化账本相比,延迟相对较低,提高了开发人员的生产力,缩短了上市时间,并为组织节省了大量资金。 数据库用户可以继续使用他们用于其他数据库应用程序开发的相同工具和实践。
实验过程
此实验需要OCI环境,并建立一个VM DBCS。
VM DBCS的shape使用VM Standard2.1即可,尽管原文建议的是VM Standard2.4。
但一定注意,必须使用LVM而不是ASM。因为:
- LVM环境会自动建立/u02和/u03目录。因此后续脚本在建立目录时并未指定
mkdir -p
选项 - dbca建库使用的数据库模板在使用ASM时会删除,而在LVM时会保留。目的是为了在一个租户下只运行创建一个CDB。
原文中也强调了这一点:
Note: This is very important to choose Logical Volume Manager
如果在ASM环境下使用dbca,会报错如下:
[FATAL] [DBT-10508] Invalid template file specified (/u01/app/oracle/product/21.0.0.0/dbhome_1/assistants/dbca/templates/General_Purpose.dbc).
CAUSE: Either the given template path is not valid file path or could not locate the given template in the local file system.
ACTION: Verify the existance of the template file.
建立目录结构:
sudo mkdir /u02/app/oracle/oradata/CDB21
sudo chown oracle:oinstall /u02/app/oracle/oradata/CDB21
sudo chmod 755 /u02/app/oracle/oradata/CDB21
sudo mkdir /u02/app/oracle/oradata/pdb21
sudo chown oracle:oinstall /u02/app/oracle/oradata/pdb21
sudo chmod 755 /u02/app/oracle/oradata/pdb21
sudo mkdir /u02/app/oracle/oradata/PDB21
sudo chown oracle:oinstall /u02/app/oracle/oradata/PDB21
sudo chmod 755 /u02/app/oracle/oradata/PDB21
sudo mkdir /u02/app/oracle/oradata/toys_root
sudo chown oracle:oinstall /u02/app/oracle/oradata/toys_root
sudo chmod 755 /u02/app/oracle/oradata/toys_root
sudo mkdir /u03/app/oracle/fast_recovery_area
sudo chown oracle:oinstall /u03/app/oracle/fast_recovery_area
sudo chmod 755 /u03/app/oracle/fast_recovery_area
获取脚本:
sudo su - oracle
cd /home/oracle
wget https://objectstorage.us-ashburn-1.oraclecloud.com/p/OKr2yAGkytLaadBqjdMiQKkiUjwgoyvyYaB0YVT2AA4G2sZWr3GG_QZRhv_4gYKS/n/c4u04/b/data-management-library-files/o/Cloud_21c_Labs.zip
unzip Cloud_21c_Labs.zip
运行脚本,修改所有脚本中的口令:
$ chmod 777 /home/oracle/labs/update_pass.sh
$ /home/oracle/labs/update_pass.sh
Enter the password you set during the DBSystem creation: WElcome123##
创建数据库(在创建数据库前,建议将默认的CDB shutdown,以释放内存):
cd /home/oracle/labs/M104784GC10
./create_CDB21.sh
确保你的tnsnames.ora中包含以下条目,其中CDB21是自动生成的,余下2个需要手工添加:
$ cat /u01/app/oracle/homes/OraDB21Home1/network/admin/tnsnames.ora
CDB21 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = blkc.sub07281614200.training.oraclevcn.com)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = CDB21)
)
)
PDB21 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = blkc.sub07281614200.training.oraclevcn.com)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = PDB21)
)
)
PDB21_2 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = blkc.sub07281614200.training.oraclevcn.com)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = PDB21_2)
)
)
确认数据库已启动并可以登录:
ps -ef|grep smon
ORAENV_ASK=NO
export ORACLE_SID=CDB21
. oraenv
sqlplus sys/WElcome123##@cdb21 AS SYSDBA
sqlplus sys/WElcome123##@pdb21 AS SYSDBA
确认PDB已建立:
SQL> show pdbs
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
4 PDB21 READ WRITE NO
创建HR Schema和auditor用户:
cd /home/oracle/labs/M104781GC10
./setup_user.sh
创建:
$ sqlplus auditor/WElcome123##@PDB21
-- 以下4个子句都是必须的
CREATE BLOCKCHAIN TABLE ledger_emp (employee_id NUMBER, salary NUMBER)
NO DROP UNTIL 31 DAYS IDLE
NO DELETE LOCKED
HASHING USING "SHA2_512" VERSION "v1";
SELECT row_retention, row_retention_locked,
table_inactivity_retention, hash_algorithm
FROM user_blockchain_tables
WHERE table_name='LEDGER_EMP';
ROW_RETENTION ROW TABLE_INACTIVITY_RETENTION HASH_ALG
------------- --- -------------------------- --------
365000 YES 31 SHA2_512
ALL_BLOCKCHAIN_TABLES的帮助参见这里。
ROW_RETENTION表示:一行插入表后必须保留且不能删除的最小天数
ROW_RETENTION_LOCKED指示区块链表的行保留期是否锁定。 可能的值:
- YES:行保留期已锁定。 您不能更改行保留期
- NO:行保留期未锁定。 您可以使用 SQL 语句 ALTER TABLE … NO DELETE UNTIL n DAYS AFTER INSERT 将行保留期更改为高于当前值的值
TABLE_INACTIVITY_RETENTION表示区块链表必须处于非活动状态才能删除的天数,即最近一次插入行后必须经过的天数才能删除该表。无论该列值如何,都可以随时删除没有行的表。
表的描述中不会出现隐藏列:
SQL> DESC ledger_emp
Name Null? Type
----------------------------------------- -------- ----------------------------
EMPLOYEE_ID NUMBER
SALARY NUMBER
显示隐藏列:
COL "Data Length" FORMAT 9999
COL "Column Name" FORMAT A24
COL "Data Type" FORMAT A28
SELECT internal_column_id "Col ID", SUBSTR(column_name,1,30) "Column Name",
SUBSTR(data_type,1,30) "Data Type", data_length "Data Length"
FROM user_tab_cols
WHERE table_name = 'LEDGER_EMP' ORDER BY internal_column_id;
Col ID Column Name Data Type Data Length
---------- ------------------------ ---------------------------- -----------
1 EMPLOYEE_ID NUMBER 22
2 SALARY NUMBER 22
3 ORABCTAB_INST_ID$ NUMBER 22
4 ORABCTAB_CHAIN_ID$ NUMBER 22
5 ORABCTAB_SEQ_NUM$ NUMBER 22
6 ORABCTAB_CREATION_TIME$ TIMESTAMP(6) WITH TIME ZONE 13
7 ORABCTAB_USER_NUMBER$ NUMBER 22
8 ORABCTAB_HASH$ RAW 2000
9 ORABCTAB_SIGNATURE$ RAW 2000
10 ORABCTAB_SIGNATURE_ALG$ NUMBER 22
11 ORABCTAB_SIGNATURE_CERT$ RAW 16
12 ORABCTAB_SPARE$ RAW 2000
12 rows selected.
目前为止,此表还没有任何数据。
插入一行:
INSERT INTO ledger_emp VALUES (106,12000);
commit;
显示此行其余的内部列:
COL "Chain date" FORMAT A17
COL "Chain ID" FORMAT 99999999
COL "Seq Num" FORMAT 99999999
COL "User Num" FORMAT 9999999
COL "Chain HASH" FORMAT 99999999999999
SELECT ORABCTAB_CHAIN_ID$ "Chain ID", ORABCTAB_SEQ_NUM$ "Seq Num",
to_char(ORABCTAB_CREATION_TIME$,'dd-Mon-YYYY hh-mi') "Chain date",
ORABCTAB_USER_NUMBER$ "User Num", ORABCTAB_HASH$ "Chain HASH"
FROM ledger_emp;
Chain ID Seq Num Chain date User Num
--------- --------- ----------------- --------
Chain HASH
--------------------------------------------------------------------------------
23 1 26-Dec-2021 12-06 112
FE6E2F3783A183B314D8798FE0BC2C2396D2998AD3413547B658B7A16B112924E78A0817D15A17DD
7CC79DAA48B22416FD01D2F80269091AE8C9840545AE2343
以hr用户插入一行,然后以auditor用户查看内部列:
GRANT insert ON ledger_emp TO hr;
CONNECT hr/WElcome123##@PDB21
INSERT INTO auditor.ledger_emp VALUES (106,24000);
commit;
CONNECT auditor/WElcome123##@PDB21
SELECT ORABCTAB_CHAIN_ID$ "Chain ID", ORABCTAB_SEQ_NUM$ "Seq Num",
to_char(ORABCTAB_CREATION_TIME$,'dd-Mon-YYYY hh-mi') "Chain date",
ORABCTAB_USER_NUMBER$ "User Num", ORABCTAB_HASH$ "Chain HASH",
employee_id, salary
FROM ledger_emp;
Chain ID Seq Num Chain date User Num
--------- --------- ----------------- --------
Chain HASH
--------------------------------------------------------------------------------
EMPLOYEE_ID SALARY
----------- ----------
23 1 26-Dec-2021 12-06 112
FE6E2F3783A183B314D8798FE0BC2C2396D2998AD3413547B658B7A16B112924E78A0817D15A17DD
7CC79DAA48B22416FD01D2F80269091AE8C9840545AE2343
106 12000
23 2 26-Dec-2021 12-11 111
B12760350B7B533050754616B800040ACE673A5B572D233D9F22B4CC8090290E0B5884450B1C4078
1880CE927A41DF2CCBC87886896EA94D890078F67434F6AB
106 24000
观察User Num不同。 此值与 V$SESSION.USER# 列的值相同。
您不能使用 DML DELETE 命令删除区块链表中的行。 您必须使用 DBMS_BLOCKCHAIN_TABLE 包。:
DELETE FROM ledger_emp WHERE ORABCTAB_USER_NUMBER$ = 111;
ORA-05715: operation not allowed on the blockchain or immutable table
以下的过程执行成功,但是没有删除任何行。因为这些行还没有过保留期:
SET SERVEROUTPUT ON
DECLARE
NUMBER_ROWS NUMBER;
BEGIN
DBMS_BLOCKCHAIN_TABLE.DELETE_EXPIRED_ROWS('AUDITOR','LEDGER_EMP', null, NUMBER_ROWS);
DBMS_OUTPUT.PUT_LINE('Number of rows deleted=' || NUMBER_ROWS);
END;
/
清空表也不允许:
SQL> TRUNCATE TABLE ledger_emp;
TRUNCATE TABLE ledger_emp
*
ERROR at line 1:
ORA-05715: operation not allowed on the blockchain or immutable table
修改保留期也不允许。因为之前使用 NO DELETE LOCKED 属性创建了表。 LOCKED 子句指示您以后永远不能修改行保留期:
SQL> ALTER TABLE ledger_emp NO DELETE UNTIL 15 DAYS AFTER INSERT;
ALTER TABLE ledger_emp NO DELETE UNTIL 15 DAYS AFTER INSERT
*
ERROR at line 1:
ORA-05741: minimum retention time too low, should be at least 16 days
删除表失败,因为还未过31天的非活动期:
SQL> DROP TABLE ledger_emp;
DROP TABLE ledger_emp
*
ERROR at line 1:
ORA-05723: drop blockchain or immutable table LEDGER_EMP not allowed
非活动期改为更长是允许的,但改短不可以:
SQL> ALTER TABLE ledger_emp NO DROP UNTIL 1 DAYS IDLE;
ALTER TABLE ledger_emp NO DROP UNTIL 1 DAYS IDLE
*
ERROR at line 1:
ORA-05732: retention value cannot be lowered
SQL> ALTER TABLE ledger_emp NO DROP UNTIL 40 DAYS IDLE;
Table altered.
您只能增加非活动期的值。 这禁止了删除出于安全目的需要保留的任何历史信息的可能性。
执行以下两SQL,第一个失败,因保留期至少为16天:
CREATE BLOCKCHAIN TABLE auditor.ledger_test (id NUMBER, label VARCHAR2(2))
NO DROP UNTIL 1 DAYS IDLE
NO DELETE UNTIL 5 DAYS AFTER INSERT
HASHING USING "SHA2_512" VERSION "v1";
ERROR at line 1:
ORA-05741: minimum retention time too low, should be at least 16 days
CREATE BLOCKCHAIN TABLE auditor.ledger_test (id NUMBER, label VARCHAR2(2))
NO DROP UNTIL 16 DAYS IDLE
NO DELETE UNTIL 16 DAYS AFTER INSERT
HASHING USING "SHA2_512" VERSION "v1";
Table created.
以hr用户插入数据,然后以auditor用户查看数据:
GRANT insert ON auditor.ledger_test TO hr;
CONNECT hr/WElcome123##@PDB21
INSERT INTO auditor.ledger_test VALUES (1,'A1');
COMMIT;
CONNECT auditor/WElcome123##@PDB21
SELECT * FROM auditor.ledger_test;
ID LA
---------- --
1 A1
SET SERVEROUTPUT ON
DECLARE
row_count NUMBER;
verify_rows NUMBER;
instance_id NUMBER;
BEGIN
FOR instance_id IN 1 .. 2 LOOP
SELECT COUNT(*) INTO row_count FROM auditor.ledger_test WHERE ORABCTAB_INST_ID$=instance_id;
DBMS_BLOCKCHAIN_TABLE.VERIFY_ROWS('AUDITOR','LEDGER_TEST', NULL, NULL, instance_id, NULL, verify_rows);
DBMS_OUTPUT.PUT_LINE('Number of rows verified in instance Id '|| instance_id || ' = '|| row_count);
END LOOP;
END;
/
Number of rows verified in instance Id 1 = 1
Number of rows verified in instance Id 2 = 0
PL/SQL procedure successfully completed.
以上是关于Oracle Livelabs实验: 区块链表的主要内容,如果未能解决你的问题,请参考以下文章
Oracle LiveLabs实验: Oracle多租户基础
Oracle LiveLabs实验: Oracle多租户基础
Oracle LiveLabs实验:Oracle RAC Fundamentals
Oracle LiveLabs实验:Install Oracle Database 21c