362 lines
7.4 KiB
Markdown
362 lines
7.4 KiB
Markdown
|
|
# Trustlog 数据库建表脚本
|
|||
|
|
|
|||
|
|
本目录包含 go-trustlog 数据库持久化模块的建表 SQL 脚本。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📁 文件列表
|
|||
|
|
|
|||
|
|
| 文件 | 数据库 | 说明 |
|
|||
|
|
|------|--------|------|
|
|||
|
|
| `postgresql.sql` | PostgreSQL 12+ | PostgreSQL 数据库建表脚本 |
|
|||
|
|
| `mysql.sql` | MySQL 8.0+ / MariaDB 10+ | MySQL 数据库建表脚本 |
|
|||
|
|
| `sqlite.sql` | SQLite 3+ | SQLite 数据库建表脚本 |
|
|||
|
|
| `test_data.sql` | 通用 | 测试数据插入脚本 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📊 表结构说明
|
|||
|
|
|
|||
|
|
### 1. operation 表
|
|||
|
|
|
|||
|
|
操作记录表,用于存储所有的操作记录。
|
|||
|
|
|
|||
|
|
**关键字段**:
|
|||
|
|
- `op_id` - 操作ID(主键)
|
|||
|
|
- `client_ip` - **客户端IP(可空,仅落库,不存证)**
|
|||
|
|
- `server_ip` - **服务端IP(可空,仅落库,不存证)**
|
|||
|
|
- `trustlog_status` - **存证状态(NOT_TRUSTLOGGED / TRUSTLOGGED)**
|
|||
|
|
- `timestamp` - 操作时间戳
|
|||
|
|
|
|||
|
|
**索引**:
|
|||
|
|
- `idx_operation_timestamp` - 时间戳索引
|
|||
|
|
- `idx_operation_status` - 存证状态索引
|
|||
|
|
- `idx_operation_doid` - DOID 索引
|
|||
|
|
|
|||
|
|
### 2. trustlog_cursor 表
|
|||
|
|
|
|||
|
|
游标表,用于跟踪处理进度,支持断点续传。
|
|||
|
|
|
|||
|
|
**关键字段**:
|
|||
|
|
- `id` - 游标ID(固定为1)
|
|||
|
|
- `last_processed_id` - 最后处理的操作ID
|
|||
|
|
- `last_processed_at` - 最后处理时间
|
|||
|
|
|
|||
|
|
**特性**:
|
|||
|
|
- 自动初始化一条记录(id=1)
|
|||
|
|
- 用于实现最终一致性
|
|||
|
|
|
|||
|
|
### 3. trustlog_retry 表
|
|||
|
|
|
|||
|
|
重试表,用于管理失败的存证操作。
|
|||
|
|
|
|||
|
|
**关键字段**:
|
|||
|
|
- `op_id` - 操作ID(主键)
|
|||
|
|
- `retry_count` - 重试次数
|
|||
|
|
- `retry_status` - 重试状态(PENDING / RETRYING / DEAD_LETTER)
|
|||
|
|
- `next_retry_at` - 下次重试时间(指数退避)
|
|||
|
|
- `error_message` - 错误信息
|
|||
|
|
|
|||
|
|
**索引**:
|
|||
|
|
- `idx_retry_status` - 重试状态索引
|
|||
|
|
- `idx_retry_next_retry_at` - 下次重试时间索引
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🚀 使用方法
|
|||
|
|
|
|||
|
|
### PostgreSQL
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 方式1: 使用 psql 命令
|
|||
|
|
psql -U username -d database_name -f postgresql.sql
|
|||
|
|
|
|||
|
|
# 方式2: 使用管道
|
|||
|
|
psql -U username -d database_name < postgresql.sql
|
|||
|
|
|
|||
|
|
# 方式3: 在 psql 中执行
|
|||
|
|
psql -U username -d database_name
|
|||
|
|
\i postgresql.sql
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### MySQL
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 方式1: 使用 mysql 命令
|
|||
|
|
mysql -u username -p database_name < mysql.sql
|
|||
|
|
|
|||
|
|
# 方式2: 在 mysql 中执行
|
|||
|
|
mysql -u username -p
|
|||
|
|
USE database_name;
|
|||
|
|
SOURCE mysql.sql;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### SQLite
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 方式1: 使用 sqlite3 命令
|
|||
|
|
sqlite3 trustlog.db < sqlite.sql
|
|||
|
|
|
|||
|
|
# 方式2: 在 sqlite3 中执行
|
|||
|
|
sqlite3 trustlog.db
|
|||
|
|
.read sqlite.sql
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔍 验证安装
|
|||
|
|
|
|||
|
|
每个 SQL 脚本末尾都包含验证查询,执行后可以检查:
|
|||
|
|
|
|||
|
|
### PostgreSQL
|
|||
|
|
```sql
|
|||
|
|
-- 查询所有表
|
|||
|
|
SELECT tablename FROM pg_tables WHERE schemaname = 'public'
|
|||
|
|
AND tablename IN ('operation', 'trustlog_cursor', 'trustlog_retry');
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### MySQL
|
|||
|
|
```sql
|
|||
|
|
-- 查询所有表
|
|||
|
|
SHOW TABLES LIKE 'operation%';
|
|||
|
|
SHOW TABLES LIKE 'trustlog_%';
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### SQLite
|
|||
|
|
```sql
|
|||
|
|
-- 查询所有表
|
|||
|
|
SELECT name FROM sqlite_master
|
|||
|
|
WHERE type='table'
|
|||
|
|
AND name IN ('operation', 'trustlog_cursor', 'trustlog_retry');
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📝 字段说明
|
|||
|
|
|
|||
|
|
### operation 表新增字段
|
|||
|
|
|
|||
|
|
#### client_ip 和 server_ip
|
|||
|
|
|
|||
|
|
**特性**:
|
|||
|
|
- 类型: VARCHAR(32) / TEXT (根据数据库而定)
|
|||
|
|
- 可空: YES
|
|||
|
|
- 默认值: NULL
|
|||
|
|
|
|||
|
|
**用途**:
|
|||
|
|
- 记录客户端和服务端的 IP 地址
|
|||
|
|
- **仅用于数据库持久化**
|
|||
|
|
- **不参与存证哈希计算**
|
|||
|
|
- **不会被序列化到 CBOR 格式**
|
|||
|
|
|
|||
|
|
**示例**:
|
|||
|
|
```sql
|
|||
|
|
-- 插入 NULL 值(默认)
|
|||
|
|
INSERT INTO operation (..., client_ip, server_ip, ...)
|
|||
|
|
VALUES (..., NULL, NULL, ...);
|
|||
|
|
|
|||
|
|
-- 插入 IP 值
|
|||
|
|
INSERT INTO operation (..., client_ip, server_ip, ...)
|
|||
|
|
VALUES (..., '192.168.1.100', '10.0.0.50', ...);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### trustlog_status
|
|||
|
|
|
|||
|
|
**特性**:
|
|||
|
|
- 类型: VARCHAR(32) / TEXT
|
|||
|
|
- 可空: YES
|
|||
|
|
- 可选值:
|
|||
|
|
- `NOT_TRUSTLOGGED` - 未存证
|
|||
|
|
- `TRUSTLOGGED` - 已存证
|
|||
|
|
|
|||
|
|
**用途**:
|
|||
|
|
- 标记操作记录的存证状态
|
|||
|
|
- 用于查询未存证的记录
|
|||
|
|
- 支持最终一致性机制
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔄 常用查询
|
|||
|
|
|
|||
|
|
### 1. 查询未存证的操作
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
SELECT * FROM operation
|
|||
|
|
WHERE trustlog_status = 'NOT_TRUSTLOGGED'
|
|||
|
|
ORDER BY timestamp ASC
|
|||
|
|
LIMIT 100;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 查询待重试的操作
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
SELECT * FROM trustlog_retry
|
|||
|
|
WHERE retry_status IN ('PENDING', 'RETRYING')
|
|||
|
|
AND next_retry_at <= NOW()
|
|||
|
|
ORDER BY next_retry_at ASC
|
|||
|
|
LIMIT 100;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 查询死信记录
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
SELECT
|
|||
|
|
o.op_id,
|
|||
|
|
o.doid,
|
|||
|
|
r.retry_count,
|
|||
|
|
r.error_message,
|
|||
|
|
r.created_at
|
|||
|
|
FROM operation o
|
|||
|
|
JOIN trustlog_retry r ON o.op_id = r.op_id
|
|||
|
|
WHERE r.retry_status = 'DEAD_LETTER'
|
|||
|
|
ORDER BY r.created_at DESC;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4. 按 IP 查询操作
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
-- 查询特定客户端IP的操作
|
|||
|
|
SELECT * FROM operation
|
|||
|
|
WHERE client_ip = '192.168.1.100'
|
|||
|
|
ORDER BY timestamp DESC;
|
|||
|
|
|
|||
|
|
-- 查询未设置IP的操作
|
|||
|
|
SELECT * FROM operation
|
|||
|
|
WHERE client_ip IS NULL
|
|||
|
|
ORDER BY timestamp DESC;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5. 统计存证状态
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
SELECT
|
|||
|
|
trustlog_status,
|
|||
|
|
COUNT(*) as count
|
|||
|
|
FROM operation
|
|||
|
|
GROUP BY trustlog_status;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🗑️ 清理脚本
|
|||
|
|
|
|||
|
|
### 删除所有表
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
-- PostgreSQL / MySQL
|
|||
|
|
DROP TABLE IF EXISTS trustlog_retry;
|
|||
|
|
DROP TABLE IF EXISTS trustlog_cursor;
|
|||
|
|
DROP TABLE IF EXISTS operation;
|
|||
|
|
|
|||
|
|
-- SQLite
|
|||
|
|
DROP TABLE IF EXISTS trustlog_retry;
|
|||
|
|
DROP TABLE IF EXISTS trustlog_cursor;
|
|||
|
|
DROP TABLE IF EXISTS operation;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 清空数据(保留结构)
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
-- 清空重试表
|
|||
|
|
DELETE FROM trustlog_retry;
|
|||
|
|
|
|||
|
|
-- 清空操作表
|
|||
|
|
DELETE FROM operation;
|
|||
|
|
|
|||
|
|
-- 重置游标表
|
|||
|
|
UPDATE trustlog_cursor SET
|
|||
|
|
last_processed_id = NULL,
|
|||
|
|
last_processed_at = NULL,
|
|||
|
|
updated_at = CURRENT_TIMESTAMP
|
|||
|
|
WHERE id = 1;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## ⚠️ 注意事项
|
|||
|
|
|
|||
|
|
### 1. 字符集和排序规则(MySQL)
|
|||
|
|
- 使用 `utf8mb4` 字符集
|
|||
|
|
- 使用 `utf8mb4_unicode_ci` 排序规则
|
|||
|
|
- 支持完整的 Unicode 字符
|
|||
|
|
|
|||
|
|
### 2. 索引长度(MySQL)
|
|||
|
|
- `doid` 字段使用前缀索引 `doid(255)`
|
|||
|
|
- 避免索引长度超过限制
|
|||
|
|
|
|||
|
|
### 3. 自增主键
|
|||
|
|
- PostgreSQL: `SERIAL`
|
|||
|
|
- MySQL: `AUTO_INCREMENT`
|
|||
|
|
- SQLite: `AUTOINCREMENT`
|
|||
|
|
|
|||
|
|
### 4. 时间类型
|
|||
|
|
- PostgreSQL: `TIMESTAMP`
|
|||
|
|
- MySQL: `DATETIME`
|
|||
|
|
- SQLite: `DATETIME` (存储为文本)
|
|||
|
|
|
|||
|
|
### 5. IP 字段长度
|
|||
|
|
- 当前长度: 32 字符
|
|||
|
|
- IPv4: 最长 15 字符 (`255.255.255.255`)
|
|||
|
|
- IPv4 with port: 最长 21 字符 (`255.255.255.255:65535`)
|
|||
|
|
- **IPv6: 最长 39 字符** - 如需支持完整 IPv6,建议扩展到 64 字符
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔧 扩展建议
|
|||
|
|
|
|||
|
|
### 1. 如果需要支持完整 IPv6
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
-- 修改 client_ip 和 server_ip 字段长度
|
|||
|
|
ALTER TABLE operation MODIFY COLUMN client_ip VARCHAR(64);
|
|||
|
|
ALTER TABLE operation MODIFY COLUMN server_ip VARCHAR(64);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 如果需要分区表(PostgreSQL)
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
-- 按时间分区
|
|||
|
|
CREATE TABLE operation_partitioned (
|
|||
|
|
-- ... 字段定义 ...
|
|||
|
|
) PARTITION BY RANGE (timestamp);
|
|||
|
|
|
|||
|
|
CREATE TABLE operation_2024_01 PARTITION OF operation_partitioned
|
|||
|
|
FOR VALUES FROM ('2024-01-01') TO ('2024-02-01');
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 如果需要添加审计字段
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
-- 添加创建人和更新人
|
|||
|
|
ALTER TABLE operation ADD COLUMN created_by VARCHAR(64);
|
|||
|
|
ALTER TABLE operation ADD COLUMN updated_by VARCHAR(64);
|
|||
|
|
ALTER TABLE operation ADD COLUMN updated_at TIMESTAMP;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📚 相关文档
|
|||
|
|
|
|||
|
|
- [PERSISTENCE_QUICKSTART.md](../../PERSISTENCE_QUICKSTART.md) - 快速入门
|
|||
|
|
- [README.md](../README.md) - 详细技术文档
|
|||
|
|
- [IP_FIELDS_USAGE.md](../IP_FIELDS_USAGE.md) - IP 字段使用说明
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## ✅ 检查清单
|
|||
|
|
|
|||
|
|
安装完成后,请检查:
|
|||
|
|
|
|||
|
|
- [ ] 所有3个表都已创建
|
|||
|
|
- [ ] 所有索引都已创建
|
|||
|
|
- [ ] trustlog_cursor 表有初始记录(id=1)
|
|||
|
|
- [ ] operation 表可以插入 NULL 的 IP 值
|
|||
|
|
- [ ] operation 表可以插入非 NULL 的 IP 值
|
|||
|
|
- [ ] 查询验证脚本能正常执行
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**最后更新**: 2025-12-23
|
|||
|
|
**版本**: v1.0.0
|
|||
|
|
|