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

目录
相关文章
|
7月前
|
SQL NoSQL 关系型数据库
数据库解决方案
【5月更文挑战第12天】数据库解决方案。
99 4
|
7月前
|
网络安全 数据库 数据安全/隐私保护
数据库被盗
数据库被盗
|
存储 安全 数据库
商品存入数据库怎么保证数据库的数据安全
商品存入数据库怎么保证数据库的数据安全
98 0
|
存储 SQL 算法
关于账本数据库:你想知道的这里都有
关于账本数据库:你想知道的这里都有
关于账本数据库:你想知道的这里都有
|
存储 安全 区块链
区块链101:区块链和数据库的区别是什么?
区块链101:区块链和数据库的区别是什么?
|
安全 Java 关系型数据库
集中式整合之使用数据库数据实现认证|学习笔记
快速学习集中式整合之使用数据库数据实现认证
集中式整合之使用数据库数据实现认证|学习笔记
|
存储 程序员 数据库
【数据库技术基础】数据库与数据库系统
【数据库技术基础】数据库与数据库系统
146 0
|
消息中间件 缓存 NoSQL
Redis缓存与数据库一致性解决方案(下)
Redis缓存与数据库一致性解决方案
349 0
Redis缓存与数据库一致性解决方案(下)
|
缓存 NoSQL 数据库
Redis缓存与数据库一致性解决方案(上)
Redis缓存与数据库一致性解决方案
538 0
Redis缓存与数据库一致性解决方案(上)
|
存储 SQL NoSQL
分布式系统 in 2010s :存储之数据库篇
回看这几年,分布式系统领域出现了很多新东西,特别是云和 AI 的崛起,让这个过去其实不太 sexy 的领域一下到了风口浪尖,在这期间诞生了很多新技术、新思想,让这个古老的领域重新焕发生机。站在 2010s 的尾巴上,我想跟大家一起聊聊分布式系统令人振奋的进化路程,以及谈一些对 2020s 的大胆猜想。 无论哪个时代,存储都是一个重要的话题,今天先聊聊数据库。在过去的几年,数据库技术上出现了几个很明显的趋势。 存储和计算进一步分离 我印象中最早的存储-计算分离的尝试是 Snowflake,Snowflake 团队在 2016 年发表的论文《The Snowflake Elastic Data
182 0