17账本数据库

简介: 17账本数据库

一、 账本数据库概述

1. 背景信息

 

账本数据库融合了区块链思想,将用户操作记录至两种历史表中:

用户历史表

全局区块表

 

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

 

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

 

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

字段名 类型 描述   
rec_num  bigint 行级修改操作在历史表中的执行序号。
hash_ins hash16 INSERTUPDATE操作插入的数据行的hash值。
hash_del hash16 DELETEUPDATE操作删除的数据行的hash值。
pre_hash hash32 当前用户历史表的数据整体摘要。


2 hash_inshash_del场景对应关系  

-      hash_ins               hash_del    
INSERT (√) 插入行的hash


DELETE


(√) 删除行的hash值。
UPDATE (√) 新插入数据的hash (√) 删除前该行的hash值。


2. 操作步骤

(1) 创建防篡改模式。

 

例如,创建防篡改模式ledgernsp

```sql
MogDB=CREATE SCHEMA ledgernsp WITH BLOCKCHAIN;
```

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

 

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

```sql
MogDB=CREATE TABLE ledgernsp.usertable(id int, name text);
```

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

```sql
MogDB=\d+ ledgernsp.usertable;
MogDB=\d+ blockchain.ledgernsp_usertable_hist;
```

执行结果如下:

```sql
MogDB=\d+ ledgernsp.usertable;
                    Table "ledgernsp.usertable"
 Column |  Type  | Modifiers | Storage  | Stats target | Description
--------+---------+-----------+----------+--------------+-------------
 id     | integer |           | plain    |              |
 name   | text   |           | extended |              |
 hash   | hash16 |           | plain    |              |
Has OIDs: no
Distribute By: HASH(id)
Location Nodes: ALL DATANODES
Options: orientation=row, compression=no
History table name: ledgernsp_usertable_hist
MogDB=\d+ blockchain.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
```

说明:

防篡改表不支持非行存表、临时表、外表、unlog表、非行存表均无防篡改属性。

防篡改表在创建时会自动增加一个名为hash的系统列,所以防篡改表单表最大列数为1599

 

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

 

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

```sql
MogDB=INSERT INTO ledgernsp.usertable VALUES(1, 'alex'), (2, 'bob'), (3, 'peter');
INSERT 0 3
MogDB=SELECT *, hash FROM ledgernsp.usertable ORDER BY id;
 id | name  |      hash
----+-------+------------------
  1 | alex  | 1f2e543c580cb8c5
  2 | bob   | 8fcd74a8a6a4b484
  3 | peter | f51b4b1b12d0354b
(3 rows)
MogDB=UPDATE ledgernsp.usertable SET name = 'bob2' WHERE id = 2;
UPDATE 1
MogDB=SELECT *, hash FROM ledgernsp.usertable ORDER BY id;
 id | name  |      hash
----+-------+------------------
  1 | alex  | 1f2e543c580cb8c5
  2 | bob2  | 437761affbb7c605
  3 | peter | f51b4b1b12d0354b
(3 rows)
MogDB=DELETE FROM ledgernsp.usertable WHERE id = 3;
DELETE 1
MogDB=SELECT *, hash FROM ledgernsp.usertable ORDER BY id;
 id | name |       hash
----+------+------------------
  1 | alex | 1f2e543c580cb8c5
  2 | bob2 | 437761affbb7c605
(2 rows)
```

二、查看账本历史操作记录

 

1. 前提条件

 

系统中需要有审计管理员或者具有审计管理员权限的角色。

数据库正常运行,并且对防篡改数据库执行了一系列增、删、改等操作,保证在查询时段内有账本操作记录结果产生。

 

2. 背景信息

只有拥有AUDITADMIN属性的用户才可以查看账本历史操作记录。有关数据库用户及创建用户的办法请参见[管理用户及权限](https://docs.mogdb.io/zh/mogdb/v3.0/2-managing-users-and-their-permissions)

 

查询全局区块表命令是直接查询gs_global_chain表,操作为:

```sql
SELECT * FROM gs_global_chain;
```

该表有11个字段,每个字段的含义见章节[GS_GLOBAL_CHAIN](https://docs.mogdb.io/zh/mogdb/v3.0/GS_GLOBAL_CHAIN)

 

查询用户历史表的命令是直接查询BLOCKCHAIN模式下的用户历史表,操作为:

 

例如用户表所在的模式为ledgernsp,表名为usertable,则对应的用户历史表名为blockchain.ledgernsp_usertable_hist

```sql
SELECT * FROM blockchain.ledgernsp_usertable_hist;
```

用户历史表有4个字段,每个字段的含义见[1](https://docs.mogdb.io/zh/mogdb/v3.0/5-setting-a-ledger-databasetable1)

 

 说明: 用户历史表的表名一般为blockchain.hist形式。当防篡改用户表模式名或者表名过长导致前述方式生成的表名超出表名长度限制,则会采用blockchain.hist的方式命名。


3. 操作步骤

以操作系统用户omm登录数据库主节点。

使用如下命令连接数据库。

```sql
gsql -d postgres -p 8000
```

postgres为需要连接的数据库名称,8000为端口号。  

4. 查询全局区块表记录。

```sql
MogDB=SELECT * FROM gs_global_chain;
 blocknum |  dbname | username |          starttime           | relid |  relnsp  |  relname  |    relhash      |            globalhash            |
              txcommand
----------+----------+----------+-------------------------------+-------+-----------+-----------+------------------+----------------------------------+------------------
------------------------------------------------------------
       0 | postgres | omm      | 2021-04-14 07:00:46.32757+08  | 16393 | ledgernsp | usertable | a41714001181a294 | 6b5624e039e8aee36bff3e8295c75b40 | insert into ledge
rnsp.usertable values(1, 'alex'), (2, 'bob'), (3, 'peter');
       1 | postgres | omm      | 2021-04-14 07:01:19.767799+08 | 16393 | ledgernsp | usertable | b3a9ed0755131181 | 328b48c4370faed930937869783c23e0 | update ledgernsp.
usertable set name = 'bob2' where id = 2;
       2 | postgres | omm      | 2021-04-14 07:01:29.896148+08 | 16393 | ledgernsp | usertable | 0ae4b4e4ed2fcab5 | aa8f0a236357cac4e5bc1648a739f2ef | delete from ledge
rnsp.usertable where id = 3;
```

该结果表明,用户omm连续执行了三条DML命令,包括INSERTUPDATEDELETE操作。

 

5. 查询历史表记录。

```sql
MogDB=SELECT * FROM blockchain.ledgernsp_usertable_hist;
 rec_num |     hash_ins     |    hash_del     |             pre_hash
---------+------------------+------------------+----------------------------------
      0 | 1f2e543c580cb8c5 |                  | e1b664970d925d09caa295abd38d9b35
      1 | 8fcd74a8a6a4b484 |                  | dad3ed8939a141bf3682043891776b67
      2 | f51b4b1b12d0354b |                  | 53eb887fc7c4302402343c8914e43c69
      3 | 437761affbb7c605 | 8fcd74a8a6a4b484 | c2868c5b49550801d0dbbbaa77a83a10
      4 |                  | f51b4b1b12d0354b | 9c512619f6ffef38c098477933499fe3
(5 rows)
```

查询结果显示,用户ommledgernsp.usertable表插入了3条数据,更新了1条数据,随后删除了1行数据,最后剩余2行数据,hash值分别为1f2e543c580cb8c5437761affbb7c605

 

6. 查询用户表数据及hash校验列。

```sql
MogDB=SELECT *, hash FROM ledgernsp.usertable;
 id | name |       hash
----+------+------------------
 1 | alex | 1f2e543c580cb8c5
 2 | bob2 | 437761affbb7c605
(2 rows)
```

查询结果显示,用户表中剩余2条数据,与步骤4中的记录一致。

 

三、校验账本数据一致性

1. 前提条件

数据库正常运行,并且对防篡改数据库执行了一系列增、删、改等操作,保证在查询时段内有账本操作记录结果产生。

 

2. 背景信息

账本数据库校验功能目前提供两种校验接口,分别为:]ledger_hist_check(text, text)](https://docs.mogdb.io/zh/mogdb/v3.0/20.1-ledger-database-functions)[ledger_gchain_check(text, text)](https://docs.mogdb.io/zh/mogdb/v3.0/20.1-ledger-database-functions)。普通用户调用校验接口,仅能校验自己有权限访问的表。

 

校验防篡改用户表和用户历史表的接口为pg_catalog.ledger_hist_check,操作为:

```sql
SELECT pg_catalog.ledger_hist_check(schema_name text,table_name text);
```

如果校验通过,函数返回t,反之则返回f


校验防篡改用户表、用户历史表和全局区块表三者是否一致的接口为pg_catalog.ledger_gchain_check,操作为:

```sql
SELECT pg_catalog.ledger_gchain_check(schema_name text, table_name text);
```

如果校验通过,函数返回t,反之则返回f

 

3. 操作步骤

 

校验防篡改用户表ledgernsp.usertable与其对应的历史表是否一致。

```sql
MogDB=SELECT pg_catalog.ledger_hist_check('ledgernsp', 'usertable');
 ledger_hist_check
-------------------
t
(1 row)
```

该结果表明防篡改用户表和用户历史表中记录的结果能够一一对应,保持一致。

 

查询防篡改用户表ledgernsp.usertable与其对应的历史表以及全局区块表中关于该表的记录是否一致。

```sql
MogDB=  SELECT pg_catalog.ledger_gchain_check('ledgernsp', 'usertable');
 ledger_gchain_check
---------------------
t
(1 row)
```

查询结果显示,上述三表中关于ledgernsp.usertable的记录保持一致,未发生篡改行为。

 

四、归档账本数据库

1. 前提条件

系统中需要有审计管理员或者具有审计管理员权限的角色。

数据库正常运行,并且对防篡改数据库执行了一系列增、删、改等操作,保证在查询时段内有账本操作记录结果产生。

数据库已经正确配置审计文件的存储路径audit_directory

2. 背景信息

账本数据库归档功能目前提供两种校验接口,分别为:[ledger_hist_archive(text, text)](https://docs.mogdb.io/zh/mogdb/v3.0/20.1-ledger-database-functions)[ledger_gchain_archive(void)](https://docs.mogdb.io/zh/mogdb/v3.0/20.1-ledger-database-functions)。账本数据库接口仅审计管理员可以调用。

 

归档用户历史表的接口为pg_catalog.ledger_hist_archive,操作为:

```sql
SELECT pg_catalog.ledger_hist_archive(schema_name text,table_name text);
```

如果归档成功,函数返回t,反之则返回f

 

归档全局区块表的接口为pg_catalog.ledger_gchain_archive,操作为:

```sql
SELECT pg_catalog.ledger_gchain_archive();
```

如果归档成功,函数返回t,反之则返回f

 

3. 操作步骤

对指定用户历史表进行归档操作。

```sql
MogDB=SELECT pg_catalog.ledger_hist_archive('ledgernsp', 'usertable')
 ledger_hist_archive
---------------------
t
(1 row)
```

用户历史表将归档为一条数据:

```sql
MogDB=SELECT * FROM blockchain.ledgernsp_usertable_hist;
 rec_num |     hash_ins     |    hash_del     |             pre_hash
---------+------------------+------------------+----------------------------------
       3 | e78e75b00d396899 | 8fcd74a8a6a4b484 | fd61cb772033da297d10c4e658e898d7
(1 row)
```

该结果表明当前节点用户历史表导出成功。

 

执行全局区块表导出操作。

```sql
MogDB=SELECT pg_catalog.ledger_gchain_archive();
 ledger_gchain_archive
-----------------------
t
(1 row)
```

全局历史表将以用户表为单位归档为N(用户表数量)条数据:

```sql
MogDB=SELECT * FROM gs_global_chain;
 blocknum |  dbname | username |          starttime           | relid |  relnsp  |  relname  |    relhash      |            globalhash            | txcommand
----------+----------+----------+-------------------------------+-------+-----------+-----------+------------------+----------------------------------+-----------
        1 | postgres | libc     | 2021-05-10 19:59:38.619472+08 | 16388 | ledgernsp | usertable | 57c101076694b415 | be82f98ee68b2bc4e375f69209345406 | Archived.
(1 row)
```

该结果表明,当前节点全局区块表导出成功。

 

五、修复账本数据库

1. 前提条件

系统中需要有审计管理员或者具有审计管理员权限的角色。

数据库正常运行,并且对防篡改数据库执行了一系列增、删、改等操作,保证在查询时段内有账本操作记录结果产生。

2. 背景信息

当在异常情况或表被损坏时需要使用[账本数据库](https://docs.mogdb.io/zh/mogdb/v3.0/5-setting-a-ledger-database)的函数章节中的ledger_gchain_repair(text, text)ledger_hist_repair(text, text)接口对全局区块表或用户历史表进行修复,修复后调用全局区块表或用户历史表校验接口结果为true

 

修复用户历史表的接口为pg_catalog.ledger_hist_repair,操作为:

```sql
SELECT pg_catalog.ledger_hist_repair(schema_name text,table_name text);
```

如果修复成功,函数返回修复过程中用户历史表hash的增量。

 

归档全局区块表的接口为pg_catalog.ledger_gchain_repair,操作为:

```sql
SELECT pg_catalog.ledger_gchain_repair(schema_name text,table_name text);
```

如果修复成功,函数返回修复过程中全局区块表hash的增量。

 

3. 操作步骤

执行历史表修复操作。

```sql
MogDB=SELECT pg_catalog.ledger_hist_repair('ledgernsp', 'usertable');
 ledger_hist_repair
--------------------
84e8bfc3b974e9cf
(1 row)
```

该结果表明当前节点用户历史表修复成功,修复造成的用户历史表hash增量为84e8bfc3b974e9cf

 

执行全局区块表修复操作。

```sql
MogDB=SELECT pg_catalog.ledger_gchain_repair('ledgernsp', 'usertable');
 ledger_gchain_repair
----------------------
a41714001181a294
(1 row)
```

该结果表明,全局区块表修复成功,且插入一条修复数据,其hash值为a41714001181a294

目录
相关文章
|
8月前
|
SQL NoSQL 关系型数据库
常用数据库
【5月更文挑战第21天】常用数据库
104 3
|
8月前
|
数据库
数据库(二)
数据查询教程包括单表查询操作,如Select语句用于选取属性,可指定列名、使用别名、计算表达式,并通过Distinct去除重复元组。条件查询(Where子句)支持比较运算,如Between、In、Like(支持模糊匹配)及空值判断。连接查询用于合并多表数据,如内连接、外连接和笛卡尔积。例如,通过连接emp和dept表,可获取员工姓名及其所在部门名称。
52 3
|
关系型数据库 Linux BI
数据库的一些知识
数据库的一些知识
55 0
|
8月前
|
数据库
数据库视频(五)
数据库视频(五)
36 0
|
8月前
|
数据库
数据库视频(四)
数据库视频(四)
49 0
|
8月前
|
存储 数据库 数据安全/隐私保护
数据库特点
数据库特点
98 9
|
8月前
|
关系型数据库 MySQL 数据库
数据库(三)
数据完整性是数据库管理中的关键概念,确保数据的准确和一致。主要包括: 1. 实体完整性:通过主键(唯一且非空)来标识表中的每条记录,如创建`test2`表时设置`n1`为主键。 2. 创建表`test3`时,`n1`和`n2`组合成为主键,确保多字段的唯一性。 3. 唯一约束:用于保证列值的唯一性,如在`test1`中添加对`n2`的唯一约束,或创建`test4`时`n1`和`n2`的组合值唯一。 4. 引用完整性:通过外键约束实现,如`emp`表的`dept_id`引用`dept`表的`id`,确保数据间的关联合法性。外键可以有级联操作,如`on delete cascade`和`o
34 0
|
8月前
|
Go 数据库
数据库的实现
数据库的实现
|
SQL 关系型数据库 MySQL
盘点数据库中的一些坑(一)
​ 首先我们来看一下sql中的null值问题,null值是编程界一个臭名昭著的问题,当然对于数据管理的数据库来说也是没有办法避免的,下面我们根据几个案例列举一些null值的坑来说明为什么不建议使用null值
140 0
盘点数据库中的一些坑(一)
|
存储 SQL 安全
一、如何快速掌握数据库
一、如何快速掌握数据库
128 0

热门文章

最新文章