VastbaseG100

基于openGauss内核开发的企业级关系型数据库。

Menu

账本数据库概述

特性描述

账本数据库采用账本Schema对普通表和防篡改用户表进行隔离。用户在账本Schema中创建的行存表具有防篡改属性,即为防篡改用户表。用户向防篡改用户表中插入数据时,系统会自动生成少量行级校验信息。在用户执行DML时,系统会在全局区块表(GS_GLOBAL_CHAIN)中记录用户的操作、在用户表相应的历史表中记录数据的更改等信息,操作记录、数据变化记录和用户表中的数据三者严格保持一致。账本数据库提供高性能校验接口,能够供用户方便的校验数据的一致性,如果一致性校验失败,则说明数据可能发生篡改,需要及时联系审计管理员回溯操作记录历史。

背景信息

账本数据库融合了区块链思想,将用户操作记录至两种历史表中:用户历史表和全局区块表。当用户创建防篡改用户表时,系统将自动为该表添加一个hash列来保存每行数据的hash摘要信息,同时在blockchain模式下会创建一张用户历史表来记录对应用户表中每条数据的变更行为;而用户对防篡改用户表的一次修改行为将记录至全局区块表中。由于历史表具有只可追加不可修改的特点,因此历史表记录串联起来便形成了用户对防篡改用户表的修改历史。

用户历史表命名和结构如下:

表 1 用户历史表blockchain.__hist所包含的字段

字段名

类型

描述

rec_num

bigint

行级修改操作在历史表中的执行序号。

hash_ins

hash16

INSERT或UPDATE操作插入的数据行的hash值。

hash_del

hash16

DELETE或UPDATE操作删除的数据行的hash值。

pre_hash

hash32

当前用户历史表的数据整体摘要。

表 2 hash_ins与hash_del场景对应关系

-

hash_ins

hash_del

INSERT

(√) 插入行的hash值

DELETE

(√) 删除行的hash值。

UPDATE

(√) 新插入数据的hash值

(√) 删除前该行的hash值。

注意事项

  • 防篡改模式下的行存表具有防篡改属性,而临时表、UNLOGGED表、列存表、时序表等均不具有防篡改属性。
  • 不允许修改防篡改用户表的结构,不允许truncate防篡改相关表,不允许将防篡改用户表切换到普通的Schema中,不允许将非防篡改表切换到防篡改Schema中。
  • 防篡改表如果为分区表,则不支持exchange partition、drop partition、truncate partition等操作。
  • 不支持使用函数、TRIGGER修改防篡改用户表数据。
  • 防篡改用户表创建时不能有名为“hash”的列。
  • 普通用户调用篡改校验接口只能校验自己有权查询的表。
  • 只允许审计管理员和初始用户查询全局区块表和BLOCKCHAIN模式中的表,普通用户无权访问,所有用户均无权修改。
  • 根据用户历史表命名规则,若待创建表的Schema或表名以_结尾或开头,可能会出现对应历史表名与已有表名冲突的情况,需要重新命名。
  • 账本数据库目前针对用户行级数据的hash摘要仅用来保证数据的一致性,当前能力暂时无法阻止攻击用户直接对数据文件的篡改。
  • 防篡改模式下不支持二级分区表。
  • 防篡改用户表不支持自定义类型。
  • 防篡改表不支持非行存表、临时表、外表、unlog表,非行存表均无防篡改属性。
  • 防篡改表在创建时会自动增加一个名为hash的系统列,所以防篡改表单表最大列数为1599。

操作步骤

1、创建防篡改模式。

​ 例如,创建防篡改模式ledgernsp。

CREATE SCHEMA ledgernsp WITH BLOCKCHAIN;

2、在防篡改模式下创建防篡改用户表。

​ 例如,创建防篡改用户表ledgernsp.usertable。

CREATE TABLE ledgernsp.usertable(id int, name text);

​ 查看防篡改用户表结构及其对应的用户历史表结构。

\d+ ledgernsp.usertable;
\d+ blockchain.ledgernsp_usertable_hist;

​ 执行结果如下:

                     Table "ledgernsp.usertable"
 Column |  Type   | Modifiers | Storage  | Stats target | Description
--------+---------+-----------+----------+--------------+-------------
 id     | integer |           | plain    |              |
 name   | text    |           | extended |              |
 hash   | hash16  |           | plain    |              |
Has OIDs: no
Options: orientation=row, compression=no
History table name: ledgernsp_usertable_hist

             Table "blockchain.ledgernsp_usertable_hist"
  Column  |  Type  | Modifiers | Storage | Stats target | Description
----------+--------+-----------+---------+--------------+-------------
 rec_num  | bigint |           | plain   |              |
 hash_ins | hash16 |           | plain   |              |
 hash_del | hash16 |           | plain   |              |
 pre_hash | hash32 |           | plain   |              |
Indexes:
    "gs_hist_16388_index" PRIMARY KEY, btree (rec_num int4_ops) TABLESPACE pg_default
Has OIDs: no
Options: internal_mask=263

  • dbe_perf和snapshot两个模式不能ALTER为blockchain属性,如:ALTER SCHEMA dbe_perf WITH BLOCKCHAIN;
  • 系统模式不能 ALTER 为blockchain属性,如:ALTER SCHEMA pg_catalog WITH BLOCKCHAIN。
  • 包含表的SCHEMA不能通过ALTER SCHEMA语句修改属性为blockchain。

3、修改防篡改用户表数据。

例如,对防篡改用户表执行INSERT/UPDATE/DELETE。

INSERT INTO ledgernsp.usertable VALUES(1, 'alex'), (2, 'bob'), (3, 'peter');
SELECT *, hash FROM ledgernsp.usertable ORDER BY id;
UPDATE ledgernsp.usertable SET name = 'bob2' WHERE id = 2;
SELECT *, hash FROM ledgernsp.usertable ORDER BY id;
DELETE FROM ledgernsp.usertable WHERE id = 3;
SELECT *, hash FROM ledgernsp.usertable ORDER BY id;

返回结果为如下:

INSERT 0 3

 id | name  |       hash
----+-------+------------------
  1 | alex  | 1f2e543c580cb8c5
  2 | bob   | 8fcd74a8a6a4b484
  3 | peter | f51b4b1b12d0354b
(3 rows)

UPDATE 1

 id | name  |       hash
----+-------+------------------
  1 | alex  | 1f2e543c580cb8c5
  2 | bob2  | 437761affbb7c605
  3 | peter | f51b4b1b12d0354b
(3 rows)

DELETE 1

 id | name |       hash
----+------+------------------
  1 | alex | 1f2e543c580cb8c5
  2 | bob2 | 437761affbb7c605
(2 rows)