架构设计 #

一、整体架构 #

1.1 分层架构 #

text
┌─────────────────────────────────────────────────────────────┐
│                        应用层                                │
│         PostgreSQL Client / ORM / Application               │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                        SQL层                                 │
│    SQL解析 → 优化器 → 执行器 → 分布式执行                    │
│                    (无状态,可水平扩展)                      │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                       事务层                                 │
│              事务协调 / 并发控制 / 时间戳                    │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                       分布式层                               │
│              Range / Raft / 副本管理                        │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                       存储层                                 │
│              Pebble (LSM-Tree) / MVCC                       │
└─────────────────────────────────────────────────────────────┘

1.2 架构特点 #

特点 说明
无共享架构 每个节点独立,无单点故障
对等节点 所有节点功能相同
水平扩展 添加节点即可扩展
自动均衡 数据自动分布和均衡

二、SQL层 #

2.1 SQL处理流程 #

text
SQL 处理流程
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   SQL 语句                                                  │
│       │                                                     │
│       ▼                                                     │
│   ┌─────────────┐                                          │
│   │  SQL 解析   │  词法分析 → 语法分析 → AST               │
│   └─────────────┘                                          │
│       │                                                     │
│       ▼                                                     │
│   ┌─────────────┐                                          │
│   │  语义分析   │  类型检查 → 权限检查                     │
│   └─────────────┘                                          │
│       │                                                     │
│       ▼                                                     │
│   ┌─────────────┐                                          │
│   │  查询优化   │  逻辑优化 → 物理优化                     │
│   └─────────────┘                                          │
│       │                                                     │
│       ▼                                                     │
│   ┌─────────────┐                                          │
│   │  执行计划   │  生成执行计划树                          │
│   └─────────────┘                                          │
│       │                                                     │
│       ▼                                                     │
│   ┌─────────────┐                                          │
│   │  分布式执行 │  数据分发 → 并行执行                     │
│   └─────────────┘                                          │
│       │                                                     │
│       ▼                                                     │
│   查询结果                                                  │
│                                                             │
└─────────────────────────────────────────────────────────────┘

2.2 查询优化器 #

sql
-- 查看执行计划
EXPLAIN SELECT * FROM users WHERE id = 1;

-- 查看详细执行计划
EXPLAIN ANALYZE SELECT * FROM users WHERE id = 1;

-- 执行计划示例
--                                               │
--        • index join                          │
--        │                                     │
--        └── • scan                            │
--            missing stats                     │
--            table: users@primary              │
--            spans: FULL SCAN                  │

2.3 PostgreSQL兼容性 #

sql
-- 支持的PostgreSQL特性

-- 数据类型
SELECT 
    'hello'::VARCHAR,
    123::INTEGER,
    3.14::DECIMAL(10,2),
    '{"key": "value"}'::JSONB;

-- 数组类型
SELECT ARRAY[1, 2, 3];
SELECT '{1, 2, 3}'::INTEGER[];

-- 窗口函数
SELECT 
    id,
    amount,
    ROW_NUMBER() OVER (ORDER BY amount DESC) AS rank,
    SUM(amount) OVER (PARTITION BY user_id) AS total
FROM orders;

-- CTE (Common Table Expression)
WITH user_orders AS (
    SELECT user_id, COUNT(*) AS order_count
    FROM orders
    GROUP BY user_id
)
SELECT * FROM user_orders WHERE order_count > 10;

-- JSON操作
SELECT 
    data->>'name' AS name,
    data->'age' AS age
FROM users
WHERE data->>'status' = 'active';

三、存储层 #

3.1 Pebble存储引擎 #

text
Pebble 存储引擎 (LSM-Tree)
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   写入流程:                                                 │
│                                                             │
│   写入请求                                                  │
│       │                                                     │
│       ▼                                                     │
│   ┌─────────────┐                                          │
│   │ Write Ahead │  预写日志 (WAL)                          │
│   │    Log      │  保证持久性                              │
│   └─────────────┘                                          │
│       │                                                     │
│       ▼                                                     │
│   ┌─────────────┐                                          │
│   │ MemTable    │  内存表 (有序)                           │
│   │  (Active)   │  新数据写入                              │
│   └─────────────┘                                          │
│       │                                                     │
│       │ MemTable 满了                                       │
│       ▼                                                     │
│   ┌─────────────┐                                          │
│   │ MemTable    │  不可变内存表                            │
│   │ (Immutable) │  等待刷盘                                │
│   └─────────────┘                                          │
│       │                                                     │
│       ▼                                                     │
│   ┌─────────────┐                                          │
│   │   SSTable   │  磁盘文件 (Sorted String Table)          │
│   │   (L0-L6)   │  分层存储                                │
│   └─────────────┘                                          │
│                                                             │
│   读取流程:                                                 │
│   MemTable → Immutable MemTable → L0 → L1 → ... → L6       │
│                                                             │
└─────────────────────────────────────────────────────────────┘

3.2 MVCC实现 #

sql
-- MVCC (多版本并发控制)

-- 每行数据有多个版本
-- Key: (table_id, index_id, primary_key)
-- Value: (timestamp, value)

-- 时间旅行查询
SELECT * FROM users 
AS OF SYSTEM TIME '-10s';

-- 查看历史数据
SELECT * FROM users 
AS OF SYSTEM TIME '2024-01-01 00:00:00';

-- 垃圾回收
-- CockroachDB 自动清理旧版本数据
-- 默认保留 25 小时

3.3 数据编码 #

text
数据编码格式
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   Key 编码:                                                 │
│   ┌─────────────────────────────────────────────────────┐   │
│   │ /Table/<table_id>/<index_id>/<primary_key>         │   │
│   │                                                      │   │
│   │ 示例:                                                │   │
│   │ /Table/53/1/1  (表53, 主键索引, 主键值1)            │   │
│   │ /Table/53/2/'user@example.com' (二级索引)           │   │
│   └─────────────────────────────────────────────────────┘   │
│                                                             │
│   Value 编码:                                               │
│   ┌─────────────────────────────────────────────────────┐   │
│   │ <timestamp> + <value>                               │   │
│   │                                                      │   │
│   │ timestamp: 事务时间戳                               │   │
│   │ value: 行数据 (编码后的列值)                        │   │
│   └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

四、分布式层 #

4.1 Range分片 #

text
Range 数据分片
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   数据按 Range 分片:                                        │
│                                                             │
│   整个数据空间                                              │
│   ┌─────────────────────────────────────────────────────┐   │
│   │ Range 1 │ Range 2 │ Range 3 │ Range 4 │ Range 5    │   │
│   │ [a-f)   │ [f-m)   │ [m-r)   │ [r-w)   │ [w-z]      │   │
│   └─────────────────────────────────────────────────────┘   │
│                                                             │
│   Range 特点:                                               │
│   ├── 默认大小: 512MB                                      │
│   ├── 自动分裂: 超过阈值自动分裂                          │
│   ├── 自动合并: 数据减少自动合并                          │
│   └── 自动均衡: 自动迁移到不同节点                        │
│                                                             │
│   Range 分布:                                               │
│                                                             │
│   Node 1          Node 2          Node 3                   │
│   ┌─────────┐    ┌─────────┐    ┌─────────┐               │
│   │ Range 1 │    │ Range 2 │    │ Range 3 │               │
│   │ Range 4 │    │ Range 5 │    │ Range 6 │               │
│   │ Range 7 │    │ Range 8 │    │ Range 9 │               │
│   └─────────┘    └─────────┘    └─────────┘               │
│                                                             │
└─────────────────────────────────────────────────────────────┘

4.2 Raft共识 #

text
Raft 共识协议
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   每个 Range 是一个 Raft Group:                             │
│                                                             │
│   ┌─────────────────────────────────────────────────────┐   │
│   │                  Range 1                             │   │
│   │                                                      │   │
│   │   ┌──────────┐                                      │   │
│   │   │ Leader   │  Node 1                              │   │
│   │   │ (Raft)   │  处理读写请求                        │   │
│   │   └──────────┘                                      │   │
│   │        │                                             │   │
│   │        ├─────────────────┐                          │   │
│   │        ▼                 ▼                          │   │
│   │   ┌──────────┐    ┌──────────┐                      │   │
│   │   │Follower  │    │Follower  │                      │   │
│   │   │ Node 2   │    │ Node 3   │                      │   │
│   │   └──────────┘    └──────────┘                      │   │
│   │                                                      │   │
│   │   写入流程:                                          │   │
│   │   1. 客户端发送写入到 Leader                        │   │
│   │   2. Leader 追加日志                                 │   │
│   │   3. 复制到 Followers                               │   │
│   │   4. 多数确认后提交                                 │   │
│   │   5. 返回客户端成功                                 │   │
│   │                                                      │   │
│   └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

4.3 副本管理 #

sql
-- 查看Range分布
SELECT 
    range_id,
    start_key,
    end_key,
    replicas
FROM crdb_internal.ranges;

-- 配置副本数
ALTER DATABASE defaultdb CONFIGURE ZONE USING 
    num_replicas = 5;

-- 配置放置策略
ALTER DATABASE mydb CONFIGURE ZONE USING 
    constraints = '[+region=us-east]';

五、事务层 #

5.1 事务模型 #

text
分布式事务模型
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   事务执行流程:                                             │
│                                                             │
│   BEGIN TRANSACTION                                         │
│       │                                                     │
│       ▼                                                     │
│   ┌─────────────────┐                                      │
│   │ 获取时间戳      │  HLC (混合逻辑时钟)                  │
│   │ (Transaction ID)│                                      │
│   └─────────────────┘                                      │
│       │                                                     │
│       ▼                                                     │
│   ┌─────────────────┐                                      │
│   │ 读取数据        │  MVCC 快照读取                       │
│   │ (Snapshot Read) │                                      │
│   └─────────────────┘                                      │
│       │                                                     │
│       ▼                                                     │
│   ┌─────────────────┐                                      │
│   │ 写入数据        │  写入临时缓冲区                      │
│   │ (Write Buffer)  │                                      │
│   └─────────────────┘                                      │
│       │                                                     │
│       ▼                                                     │
│   ┌─────────────────┐                                      │
│   │ 两阶段提交      │  1. Prepare (锁定)                   │
│   │ (2PC)           │  2. Commit (提交)                    │
│   └─────────────────┘                                      │
│       │                                                     │
│       ▼                                                     │
│   COMMIT TRANSACTION                                        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

5.2 隔离级别 #

sql
-- 支持的隔离级别

-- READ COMMITTED (默认)
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

-- SERIALIZABLE
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

-- 示例
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT * FROM accounts WHERE id = 1;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
COMMIT;

-- 查看当前隔离级别
SHOW TRANSACTION ISOLATION LEVEL;

5.3 并发控制 #

text
并发控制机制
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   乐观并发控制:                                             │
│                                                             │
│   1. 读取阶段                                               │
│      ├── 读取数据到本地                                    │
│      └── 记录读取的时间戳                                  │
│                                                             │
│   2. 验证阶段                                               │
│      ├── 检查是否有冲突                                    │
│      └── 冲突则重试                                        │
│                                                             │
│   3. 写入阶段                                               │
│      ├── 提交事务                                          │
│      └── 写入新版本数据                                    │
│                                                             │
│   冲突检测:                                                 │
│   ├── 写写冲突: 两个事务写同一行                           │
│   ├── 读写冲突: 读后写                                     │
│   └── 写读冲突: 写后读                                     │
│                                                             │
│   重试机制:                                                 │
│   ├── 自动重试 (可序列化事务)                              │
│   └── 客户端重试 (其他事务)                                │
│                                                             │
└─────────────────────────────────────────────────────────────┘

六、数据流 #

6.1 写入流程 #

text
写入数据流程
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   INSERT INTO users (id, name) VALUES (1, 'Alice');         │
│                                                             │
│   1. SQL层解析和优化                                       │
│      │                                                      │
│      ▼                                                      │
│   2. 确定目标Range                                         │
│      │                                                      │
│      ▼                                                      │
│   3. 发送到Range Leader                                    │
│      │                                                      │
│      ▼                                                      │
│   4. Leader处理写入                                        │
│      ├── 获取事务时间戳                                    │
│      ├── 写入WAL                                           │
│      └── 写入MemTable                                      │
│      │                                                      │
│      ▼                                                      │
│   5. Raft复制到Followers                                   │
│      │                                                      │
│      ▼                                                      │
│   6. 多数确认后提交                                        │
│      │                                                      │
│      ▼                                                      │
│   7. 返回客户端成功                                        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

6.2 读取流程 #

text
读取数据流程
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   SELECT * FROM users WHERE id = 1;                         │
│                                                             │
│   1. SQL层解析和优化                                       │
│      │                                                      │
│      ▼                                                      │
│   2. 确定目标Range                                         │
│      │                                                      │
│      ▼                                                      │
│   3. 发送到Range Leader (或Follower)                       │
│      │                                                      │
│      ▼                                                      │
│   4. 读取数据                                              │
│      ├── 确定时间戳                                        │
│      ├── 查找MemTable                                      │
│      └── 查找SSTable                                       │
│      │                                                      │
│      ▼                                                      │
│   5. 返回结果                                              │
│                                                             │
│   一致性读取:                                               │
│   ├── 强一致读: 从Leader读取                               │
│   └── 过期读: 从Follower读取 (AS OF SYSTEM TIME)           │
│                                                             │
└─────────────────────────────────────────────────────────────┘

七、总结 #

架构要点:

层次 职责 关键技术
SQL层 SQL处理 解析、优化、执行
事务层 事务管理 MVCC、2PC
分布式层 数据分布 Range、Raft
存储层 数据存储 Pebble、LSM-Tree

下一步,让我们学习CockroachDB的数据类型!

最后更新:2026-03-27