MatrixOne WAL设计解析

PostgreSQL源码分析——WAL日志(一) WAL日志对数据库故障恢复,物理备份,事务处理等至关重要,这里我们分析一下WAL日志的相关内容。如果没有WAL日志文件,那么数据库需要在每次更新页面后,刷盘持久化才能提交,频繁的进行刷盘,并且是随机写,而且是整页的写,代价很大。对此,设计了WAL,每次只将对数据页的修改抽象成WAL日志记录,顺序写入WAL日志文件中,这就将随机写变为了顺序写入,并且文件的大小也有所减少,因为绝大部分情况不用整页写入了,减少了刷盘的代价。 阅读详情

作者:蒋昕萌  MO研发工程师

WAL(Write Ahead Log)是一项与数据库原子性和持久性相关的技术,在事务提交时把随机写转换成顺序读写。事务的更改随机地发生在各页上,这些页很分散,随机写的开销大于顺序写,会降低提交的性能。WAL只记录事务的更改操作,类似于在哪个block中增加了哪行。提交事务时新的WAL entry顺序地写在WAL文件末尾。提交之后再异步地更新那些脏页,销毁对应的WAL entry,释放空间。MatrixOne的WAL是物理日志,记录每行更新发生的位置,每次回放出来,数据不仅在逻辑上相同,底层的组织结构也是一样的。


Part 1 Commit Pipeline

Commit Pipeline是处理事务提交的组件。提交之前要更新memtable,持久化WAL entry,执行这些任务的耗时决定了提交的性能。持久化WAL entry涉及到IO,比较耗时。MatrixOne中采用commit pipeline,异步持久化WAL entry,不阻塞内存中的更新。

事务提交的流程是:

  1. 把更改更新到memtable中,事务进入commit pipeline之前,先并发更新memtable,事务之间互相不阻塞。这时这些更改的状态为未提交,不对任何事务不可见;
  2. 进入commit pipeline检查冲突;
  3. 持久化WAL entry,从内存收集WAL entry写到后端。持久化WAL entry是异步的,队列里只把WAL entry传给后端就立刻返回,不用等待写入成功,这样不会阻塞后续其他事务。后端同时处理一批entry,通过Group Commit进一步加速持久化。
  4. 更新memtable中的状态使事务可见,事务按照进队列的顺序依次更新状态,这样事务可见的顺序和队列里写WAL entry的顺序是一致的。

Part 2 Checkpoint

Checkpoint将脏数据写入Storage,销毁旧的log entry,释放空间。MatrixOne中,checkpoint是一个后台发起的任务,它的流程是:

  • 选定一个合适的时间戳作为checkpoint,然后扫描时间戳之前的修改。图上的t0是上个checkpoint,t1是当前选定的checkpoint。[t0,t1]之间发生的更改需要转存。
  • 转存DML修改。DML更改存在memtable中的各个block中。Logtail Mgr是一个内存模块,记录着每个事务改动了哪些block。在Logtail Mgr上扫描[t0,t1]之间的事务,发起后台事务把这些block转存到Storage上,在元数据中记录地址。这样,所有t1前提交的DML更改都能通过元数据中的地址查到。为了及时做checkpoint,不让WAL无限增长,哪怕区间中block只改动了一行,也需要转存。

  • 扫描Catalog转存DDL和元数据更改。Catalog是一棵树,记录了所有的DDL和元数据信息,树上的每个节点都会记录更改发生的时间戳。扫描时收集所有落在[t0,t1]之间的更改。

  • 销毁旧的WAL entry。Logtail Mgr中存了每个事务对应的LSN。根据时间戳,找到t1前最后一个事务,然后通知Log Backend清理这个事务的LSN之前的所有日志。

Part 3 Log Backend

MatrixOne的WAL能写在各种Log Backend中。最初的Log Backend基于本地文件系统。为了分布式特性,我们自研了高可靠低延迟Log Service作为新的Log Backend。我们为适配不同的log backend,抽象出一个虚拟的backend, 通过一些很轻量的driver开发,对接不同的backend。

Driver需要适配出这些接口:

  • Append,提交事务时异步地写入log entry:
Append(entry) (Lsn, error)
  • Read,重启时批量读取log entry:
 Read(Lsn, maxSize) (entry, Lsn, error)
  • Truncate接口会销毁LSN前的所有log entry,释放空间:
  Truncate(lsn Lsn) error

Part 4 Group Commit

Group Commit可以加速持久化log entry。持久化log entry涉及到IO,非常耗时,经常是提交的瓶颈。为了降低延迟,批量向Log Backend中写入log entry。比如,在文件系统中fsync耗时很久。如果每条entry都fsync,会耗费大量时间。基于文件系统的Log Backend中,多个entry写完后统一只做一次fsync,这些entry刷盘的时间成本之和近似一条entry刷盘的时间。

Log Service中支持并发写入,各条entry刷盘的时间可以重叠,这也能缩短写entry的总时间,提高了提交的并发。

Part 5 处理Log Backend的乱序LSN

为了加速,向Log Backend并发写入entry,写入成功的顺序和发出请求的顺序不一致,导致Log Backend中产生的LSN和上层传给Driver的逻辑LSN不一致。Truncate和重启的时候要处理这些乱序LSN。为了保证Log Backend中的LSN基本有序,乱序的跨度不要太大,维持了一个逻辑LSN的窗口,如果有很早的log entry正在写入还未成功,会停止向Log Backend写入新的entry。例如,如果窗口的长度是7,图中的LSN为13的entry还未返回,就会阻塞住LSN大于等于20的entry。

Log Backend中通过truncate操作销毁日志,销毁指定LSN之前的所有entry。这个LSN之前的entry所对应的逻辑LSN都要小于逻辑truncate点。比如图中逻辑truncate到7,这条entry对应Log Backend中的11,但是Log Backend中5,6,7,10对应的逻辑LSN都大于7,不能被truncate。Log Backend只能truncate 4。

重启时,会跳过开始和末尾那些不连续的entry。比如图上的Log Backend写到14时,整个机器断电了,重启时会根据上次的truncate信息过滤掉开头8,9,11。等读完所有的entry发现6,14的逻辑 LSN和其他的entry不连续,就丢弃末尾的6和14。

Part 6 MatrixOne中WAL的具体格式

每个写事务对应一条log entry,由LSN,Transaction Context和多个Command组成。

+---------------------------------------------------------+
|                  Transaction Entry                      |
+-----+---------------------+-----------+-----------+-   -+
| LSN | Transaction Context | Command-1 | Command-2 | ... |
+-----+---------------------+-----------+-----------+-   -+

6.1 LSN

每条log entry对应一个LSN。LSN连续递增,在做checkpoint时用来删除entry。

6.2 Transaction Context

Transaction Context里记录了事务的信息。

+---------------------------+
|   Transaction Context     |
+---------+----------+------+
| StartTS | CommitTS | Memo |
+---------+----------+------+
  1. StartTS和CommitTS分别是事务开始和结束的时间戳。
  2. Memo记录事务更改了哪些地方的数据。重启的时候,会把这些信息恢复到Logtail Mgr里,做checkpoint要用到这些信息

6.3 Transaction Commands

事务中每种写操作对应一个或多个command。log entry会记录事务中所有的command。

OperatorCommand
DDLUpdate Catalog
InsertUpdate Catalog
_Append
DeleteDelete
Compact&MergeUpdate Catalog

>>>Operators

MatrixOne中DN负责提交事务,向Log Backend中写log entry,做checkpoint。DN支持建库,删库,建表,删表,更新表结构,插入,删除,同时后台会自动触发排序。更新操作被拆分成插入和删除。

1. DDL 

DDL包括建库,删库,建表,删表,更新表结构。DN在Catalog里记录了表和库的信息。内存里的Catalog是一棵树,每个结点是一条catalog entry。catalog entry有4类,database,table,segment和block,其中segment和block是元数据,在插入数据和后台排序的时候会变更。每条database entry对应一个库,每条table entry对应一张表。每个DDL操作对应一条database/table entry,在entry里记录成Update Catalog Command。

2. Insert 

新插入的数据记录在Append Command中。DN中的数据记录在block中,多个block组成一个segment。如果DN中没有足够的block或segment记录新插入的数据,就会新建一个。这些变化记录在Update Catalog Command中。大事务中,由CN直接把数据写入S3,DN只提交元数据。这样,Append Command中的数据不会很大。

3. Delete 

DN记录Delete发生的行号。读取时,先读所有插入过的数据,然后再减去这些行。事务中,同一个block上所有的删除合并起来,对应一个Delete Command。

4. Compact & Merge 

DN后台发起事务,把内存里的数据转存到s3上。把S3上的数据按主键排序,方便读的时候过滤。compact发生在一个block上,compact之后block内的数据是有序的。merge发生在segment里,会涉及多个block,merge之后整个segment内有序。compact/merge前后的数据不变,只改变元数据,删除旧的block/segment,创建新的block/segment。每次删除/创建对应一条Update Catalog Command。

>>>Commands

1. Update Catalog 

Catalog从上到下每层分别是database,table,segment和block。一条Updata Catalog Command对应一条Catalog Entry。每次ddl或者跟新元数据对应一条Update Catalog Command。Update Catalog Command包含Dest和EntryNode。

+-------------------+
|   Update Catalog  |
+-------+-----------+
| Dest | EntryNode |
+-------+-----------+
  • Dest - Dest是这条Command作用的位置,记录了对应结点和他的祖先结点的id。重启的时候会通过Dest,在Catalog上定位到操作的位置。
TypeDest
Update Databasedatabase id
Update Tabledatabase id、table id
Update Segmentdatabase id、table id、segment id
Update Blockdatabase id、table id、segment id、block id
  • EntryNode
    • 每个EntryNode都记录了entry的创建时间和删除时间。如果entry没被删除,删除时间为0。如果当前事务正在创建或者删除,对应的时间为UncommitTS。
+-------------------+
|    Entry Node     |
+---------+---------+
| Create@ | Delete@ |
+---------+---------+
  • 对于segment和block,Entry Node还记录了metaLoc,deltaLoc,分别是数据和删除记录在S3上的地址。
+----------------------------------------+
 |               Entry Node               |
 +---------+---------+---------+----------+
 | Create@ | Delete@ | metaLoc | deltaLoc |
 +---------+---------+---------+----------+
  • 对于table,Entry Node还记录了表结构schema。
+----------------------------+
 |         Entry Node         |
 +---------+---------+--------+
 | Create@ | Delete@ | schema |
 +---------+---------+--------+

2. Append 

Append Command中记录了插入的数据和和这些数据的位置。

+-------------------------------------------+
|             Append Command                |
+--------------+--------------+-   -+-------+
| AppendInfo-1 | AppendInfo-2 | ... | Batch |
+--------------+--------------+-   -+-------+
  • Batch是插入的数据。
  • AppendInfo 一个Append Data Command中的数据可能跨多个block。每个block对应一个Append Info,记录了数据在Command的Batch中的位置pointer to data,还有数据在block中的位置destination。
+------------------------------------------------------------------------------+
|                              AppendInfo                                      |
+-----------------+------------------------------------------------------------+
| pointer to data |                     destination                            |
+--------+--------+-------+----------+------------+----------+--------+--------+
| offset | length | db id | table id | segment id | block id | offset | length |
+--------+--------+-------+----------+------------+----------+--------+--------+

3. Delete Command 

每个Delete Command只包含一个block中的删除。

+---------------------------+
|      Delete Command       |
+-------------+-------------+
| Destination | Delete Mask |
+-------------+-------------+
  • Destination记录Delete发生在哪个Block上。
  • Delete Mask记录删除掉的行号。

WAL在存储系统中应用得十分广泛。WAL把随机写转换成顺序写,是一种更高效的模式。WAL内部还有很多执行细节,我们会不断调整,不断优化。


MatrixOne社区介绍

MatrixOne是一款面向未来的超融合异构云原生数据库管理系统。通过全新设计和研发的统一分布式数据库引擎,能够同时灵活支持OLTP、OLAP、 Streaming等不同工作负载的数据管理和应用,用户可以在公有云、自建数据中心和边缘节点上无缝部署和运行。

MatrixOrigin 官网:新一代超融合异构开源数据库-矩阵起源(深圳)信息科技有限公司 MatrixOne

Github 仓库:GitHub - matrixorigin/matrixone: Hyperconverged cloud-edge native database

【0249】WAL Modes(WAL模式,synchronous_commit)深入分析 当服务器正常运行时,WAL文件不断被写入磁盘。但是,这些写入是顺序的:几乎没有随机访问,因此即使是hdd也可以处理这个任务。由于这种类型的加载与典型的数据文件访问非常不同,因此有必要为WAL文件设置一个单独的物理存储,并用一个指向已挂载文件系统中的目录的符号链接替换目录。有几种情况下,WAL文件必须同时写入和读取。第一个是明显的崩溃恢复案例;第二种是流复制。walsender进程直接从文件中读取WAL条目。 阅读详情

相关推荐

SpringBoot+Vue+MySQL 高校学科竞赛平台 完整可运行版(源码+文档)

本项目基于SpringBoot+Vue+MySQL构建高校学科竞赛管理平台,覆盖学生、教师、领队教师、管理员四大角色,实现竞赛发布、报名、刷题、评分、公示等全流程闭环管理。系统架构清晰,技术主流,配套完整源码、数据库脚本、万字论文、开题报告、答辩PPT及部署文档,支持一键运行,适用于毕业设计、课程设计及院系二次开发,真正实现“开箱即用”。

招风的黑耳优快云 295

预写日志——WAL

预写日志——WAL

style_boy的博客 1620

Python实现微信PC端聊天记录自动化监听与智能回复

本文详细介绍了如何使用Python实现微信PC端聊天记录的自动化监听与智能回复。通过win32api和uiautomation库,模拟人工操作,实时监控聊天窗口并抓取新消息。文章重点讲解了核心代码逻辑、环境搭建步骤,并提供了实现关键词触发自动回复的完整方案,旨在提高工作效率与信息管理自动化水平。

weixin_29092031的博客 349

HBase预写日志WAL机制

预写日志(Write-ahead log,WAL) 最重要的作用是灾难恢复,一旦服务器崩溃,通过重放log,我们可以恢复崩溃之前的数据。如果写入WAL失败,整个操作也将认为失败。 从上图看: 1 客户端对数据执行一个修改操作,如put(),delete(),incr()等。 2 每一个修改被封装到一个KeyValue对象实例,并通过RPC调用发送出来。 3 上述调用成批地发送给含有匹配regio...

Fys的博客 5330

WPF 解决listview值更改时页面没有刷新

WPF 解决listview值更改时页面没有刷新。

weixin_52475977的博客 1386

手把手教你用GD32F407VET6的EXMC驱动外部SRAM,搞定大内存需求

本文详细介绍了如何使用GD32F407VET6的EXMC外设驱动外部SRAM,解决嵌入式开发中的大内存需求问题。通过硬件连接方案、EXMC时序配置与初始化步骤,以及软件集成与内存管理技巧,帮助开发者快速实现内存扩展。特别适合需要处理图形显示缓冲、音频处理等大内存场景的GD32F407开发者。

weixin_30752699的博客 347

SQLite分析之WAL机制

对SQLite的WAL机制的分析

岩之痕 1万+

STM32(HAL库)驱动st7789LCD屏幕(7引脚240*240)

屏幕厂家提供的都是标准库,网上找了找没看到好用的HAL库屏幕驱动,因此本文对HAL库驱动TFT屏幕进行详细讲解。

weixin_44597885的博客 6065

MatrixOne Git4Data 技术详解(三):MatrixOne 架构及 Git4Data 原理解析,快照、Diff、Merge 凭什么这么快

文章摘要: MatrixOne数据库通过云原生存算分离架构,实现毫秒级数据版本控制。核心原理为:1) 数据以不可变对象存储,仅目录元数据可变;2) 快照通过记录时间戳保护对象版本,克隆仅复制元数据引用,均无需数据拷贝;3) Diff操作仅扫描增量变更对象而非全表;4) 合并采用三方对比机制,自动处理非冲突修改。这种设计使得对1亿行数据创建快照仅需5ms,克隆25ms,比对1000行差异23ms,版本控制成本与数据量解耦,成为存储引擎的自然特性而非额外开销。

MatrixOrigin的博客 775

Data+AI━━数仓建模的智能进化之路!

Data+AI━━数仓建模的智能进化之路!

ith321的博客 1746

复现CVE-2014-085(Apache ZooKeeper 未授权访问漏洞)

默认安装配置完的zookeeper允许未授权访问,管理员未配置访问控制列表(ACL)。导致攻击者可以在默认开放的2181端口下通过执行envi命令获得大量敏感信息(系统名称、java环境)导致任意用户可以在网络不受限的情况下进行未授权访问读取数据。

记录并分享学习安全的知识点.. 2178

MatrixOne架构设计原理:存储计算事务分离的终极实现

MatrixOne作为一款AI原生的HTAP数据库,创新性地实现了存储、计算与事务处理的彻底分离架构,为智能应用提供了高效的数据与内存支撑。本文将深入解析这一架构设计的核心原理,揭示其如何通过组件解耦实现极致的性能与扩展性。 ## 核心组件:四大服务构建分离式架构 MatrixOne采用存算分离架构,由四个核心服务组成有机整体,每个组件专注于特定职责,实现了高度的模块化与可扩展性: | 组件

gitblog_00453的博客 705

第三节:Vben Admin 最新 v5.0 (vben5) + Python Flask 快速入门 - 对接后端登录接口(上)

这里是Vben Admin V5版本实战体验,上一节我们前端已正常运行,但是没有实现登录。本节的重点是对接后端接口。上一节地址:第一节:Vben Admin 最新 v5.0初体验第二节:Vben Admin 登录逻辑梳理和对接后端准备后端我们采用Python的Flask项目,Flask-SQLAlchemy管理数据库模型,Flask-Migrate进行模型迁移。参考版本如下:Flask3.0.23.1.1到这里,登录接口完成,下一步要实现获取用户信息和权限的接口功能。

cuiwin的专栏 1864

技术解读|MatrixOne高效 CDC:基于快照的分布式数据库优化方案

CDC ,即变更数据捕获,是一种用于监控数据库变更(插入、更新、删除及模式变更)并将这些变更以可消费格式传递给其他系统的技术。它是连接数据库与下游应用(如缓存、数据仓库或搜索引擎)的桥梁,广泛应用于实时同步、分析和灾备等场景。传统 CDC 依赖于解析数据库事务日志(如 MySQL 的 binlog 或 PostgreSQL 的 WAL )。解析延迟:大日志文件的解析耗时较长,导致变更捕获延迟。资源开销:日志解析需要大量CPU和内存,影响数据库性能。HTAP适配性差。

MatrixOrigin的博客 1103

Xilinx系FPGA学习笔记(三)Vivado的仿真及ILA使用

接着学习vivado的使用方法。

贾saisai的博客 2547

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

MatrixOne HSTAP引擎深度剖析:如何实现OLTP与OLAP的极致性能

MatrixOne是一款AI原生的HTAP数据库,它创新性地融合了Git-for-Data功能与内置向量搜索,为智能代理和应用提供强大的数据与内存支持。本文将深入剖析MatrixOne的HSTAP引擎架构,揭示其如何突破传统数据库的性能瓶颈,实现OLTP与OLAP工作负载的高效协同。 ## 核心架构:存算分离的分布式设计 ⚙️ MatrixOne采用先进的存算分离架构,通过四个核心服务组件构建

gitblog_00725的博客 662

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Rocksdb 写流程,读流程,WAL文件,MANIFEST文件,ColumnFamily,Memtable,SST文件原理详解

Rocksdb写流程 过程基本如下流程图: 涉及到的几个核心文件: WAL 保存当前rocksdb的memtable中的文件信息,当memtable --》 immutable memtable中的数据刷到L0之后即之前的会被删除 — 即于DB目录下的 00012.log MANIFEST 保存当前db的状态信息(类似于快照),主要是SST文件的各个版本信息(当sst文件被改动,即会生成对应的versionEdit,并触发sync写manifest文件),用于异常断电后恢复— 即 MANIFEST-

天行健,地势坤 1万+

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Docker Compose:搭建本地多服务开发环境

从一个 Java API、PostgreSQL 和 Redis 开始,配置服务名、端口、环境变量、健康检查、数据卷和依赖关系。理解 Compose 文件如何被解析、项目如何隔离,以及哪些数据不能依赖“重建容器”保留,能够把个人开发环境整理成团队可复用的启动入口。

m0_62221377的博客 476

AI全栈实战 | 3.9-01 爬虫入门:requests 加 BeautifulSoup 三分钟跑通,但 90% 的人栽在这 4 个“礼貌“问题上

⚠️:本文内容仅用于。请遵守目标站点的服务条款与相关法律法规,不得对目标服务造成负担,不得采集、传播个人隐私数据。技术是中性的,边界在你手里。爬虫的入门技术(requests 发请求 + BeautifulSoup 解析)三分钟就能学会。真正区分"会用爬虫"和"会做爬虫的人"的,是这篇我们跑通"请求→解析→存储"的最小闭环,然后重点把"合规与礼貌"这根弦给你绷上。

源码获取 | 运行部署 | 定制二开修改,如果回复不及时请耐心等待,请见谅。 432

【基于 WebSocket 的多用户网页五子棋】—— 数据管理模块

但行好事,莫问前程

qq_42996461的博客 250

C++算法(七)

C++ stack算法题和一些客观题

2503_94479566的博客 378

OpenClaw 深度调查:把 AI 助手做成你自己的控制平面

对 openclaw/openclaw 的完整技术尽调:Gateway 架构、Agent 运行时、工具与沙箱、30 个消息通道、181 个插件、安全信任边界、工程代价与采用建议。17 章 / 10 张图,全部数字标注口径,数据截至 2026-10-31。

厚积薄发 294

IDEA 简介:从零认识 IntelliJ IDEA

IDEA 全称,是由 JetBrains 公司开发的一款主流 Java 集成开发环境(IDE)。它集代码编辑、编译、调试、测试、版本控制、构建管理等功能于一体,被大量 Java 开发者视为日常开发的首选工具。所谓 IDE(Integrated Development Environment,集成开发环境),就是把写代码所需的各类工具整合到同一个界面中。相比只用文本编辑器加命令行编译,IDE 能显著减少重复操作,让开发者把精力集中在业务逻辑上。

ztI10的博客 176

TransactionInactiveError:await 之后事务已经不活跃了

TransactionInactiveError 出现于 IndexedDB 事务已结束(非 active 状态)时调用 put、get 等操作。常见于 await 后或 setTimeout 中执行请求,因任务已完成,事务已提交或进入 finished 状态。请求必须在创建事务的同一任务中挂起,否则无效。解决方法:在 onsuccess 回调内同步发起后续操作,或提前将所有请求挂入事务。避免在异步上下文中使用事务操作,确保请求在事务活跃期内完成。

qq_40822000的博客 159

云计算课程小组PPT汇报任务书

36人分为6组,每组6人;形式:生活案例调研 + 理论解读;汇报时长7‑9min;PPT建议10‑14页。

Michelle8023的博客 207

大表 ALTER TABLE 怎么做?NineData OnlineDDL 配置与执行实践

介绍NineData OnlineDDL大表变更实践,涵盖执行策略、切表控制、拷贝批次与可视化进度追踪。

dbasenewbie的博客 295
上一篇: 数据库内核之Binder
下一篇: 对话矩阵起源王龙:想要做数据库领域的 iPhone
MatrixOrigin
博客等级 码龄5年 708粉丝 230原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值