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。因为:

  1. LVM环境会自动建立/u02和/u03目录。因此后续脚本在建立目录时并未指定mkdir -p选项
  2. 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

Oracle LiveLabs实验:DB Security - Oracle Label Security (OLS)

Oracle LiveLabs实验:Oracle Label Security (OLS)