事务正确性Skill transaction-correctness

这个技能涉及Turso数据库中的WAL(预写日志)机制、检查点、并发规则和恢复过程,用于确保事务的原子性、一致性、隔离性和持久性(ACID属性)。关键词包括:WAL、检查点、并发控制、事务恢复、Turso数据库、数据库事务、预写日志、检查点策略。

后端开发 0 次安装 0 次浏览 更新于 3/25/2026

name: transaction-correctness description: Turso数据库中WAL机制、检查点、并发规则和恢复如何工作

事务正确性指南

Turso仅使用WAL(预写日志)模式。

文件:.db, .db-wal(无.db-shm - Turso使用内存中的WAL索引)

WAL机制

写入路径

  1. 写入者将帧(页面数据)追加到WAL文件(顺序I/O)
  2. COMMIT = 头部中db_size非零的帧(标记事务结束)
  3. 原始数据库在检查点之前保持不变

读取路径

  1. 读取者获取读取标记(mxFrame = 最后一个有效提交帧)
  2. 对于每个页面:检查WAL直到mxFrame,回退到主数据库
  3. 读取者在其读取标记处看到一致的快照

检查点

将WAL内容传输回主数据库。

WAL增长 → 触发检查点(默认:1000页) → 页面复制到数据库 → WAL重用

检查点类型:

  • PASSIVE:非阻塞,停止在活动读取者需要的页面
  • FULL:等待读取者,检查点所有内容
  • RESTART:类似于FULL,同时重置WAL到开头
  • TRUNCATE:类似于RESTART,同时将WAL文件截断为零长度

WAL索引

SQLite使用共享内存文件(-shm)作为WAL索引。Turso不使用 - 它使用内存数据结构(frame_cache哈希映射,原子读取标记),因为不支持多进程访问。

并发规则

  • 一次一个写入者
  • 读取者不阻塞写入者,写入者不阻塞读取者
  • 检查点必须停止在活动读取者需要的页面

恢复

崩溃时:

  1. 第一个连接获取独占锁
  2. 从WAL重放有效提交
  3. 释放锁,恢复正常操作

Turso实现

关键文件:

连接私有 vs 共享

每个连接(私有):

  • Pager - 页面缓存,脏页面,保存点,提交状态
  • WalFile - 连接的快照视图:
    • max_frame / min_frame - 此连接快照的帧范围
    • max_frame_read_lock_index - 此连接持有的读取锁槽
    • last_checksum - 滚动校验和状态

跨连接共享:

  • WalFileShared - 全局WAL状态:
    • frame_cache - 页面到帧索引(替代.shm文件)
    • max_frame / nbackfills - 全局WAL进度
    • read_locks[5] - 读取标记槽(带有嵌入帧值的TursoRwLock)
    • write_lock - 独占写入者锁
    • checkpoint_lock - 检查点序列化
    • file - WAL文件句柄
  • DatabaseStorage - 主.db文件
  • BufferPool - 共享内存分配

正确性不变式

  1. 持久性:COMMIT记录必须在返回成功前fsync
  2. 原子性:部分事务对读取者不可见
  3. 隔离性:每个读取者看到一致的快照
  4. 无丢失更新:检查点不能覆盖未提交的更改

参考