Neon wal日志处理流程

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

Neon WAL 处理全链路解析:从 Compute 到 Pageserver 的深度解码与存储

摘要:本文深入剖析 Neon 数据库架构中 WAL(Write-Ahead Log)从 Compute 节点产生,经 Safekeeper 接收、解码、转发,最终被 Pageserver 摄入并存储的完整流程。重点解析 Safekeeper 的"流解码"与"深度解码"两层机制,以及 Pageserver 如何利用 InterpretedWalRecord 实现计算存储分离,避免传统 WAL Redo 的架构设计。


阶段一:Compute → Safekeeper(WAL Push)

Compute 节点 (PostgreSQL)

│ TCP连接, 发送 START_WAL_PUSH 命令

▼

1. 网络接入层

wal_service.rs:61 handle_socket() → 创建 SafekeeperPostgresHandler,启动 PG 协议主循环

handler.rs:306 process_query() → 匹配 START_WAL_PUSH → 调用 handle_start_wal_push()

2. WAL 流读取

receive_wal.rs:191 handle_start_wal_push_guts():

  • 建立 mpsc channel(msg_tx/msg_rx),将网络读取和 WAL 处理解耦
  • 启动 NetworkReader(读网络消息 → 发到 channel)
  • 启动 WalAcceptor::run()(从 channel 收消息 → 处理)

receive_wal.rs:412 read_network_loop() → 循环读取 CopyData 消息 → ProposerAcceptorMessage::parse() 反序列化 → msg_tx.send()

3. WAL 写入磁盘 + 流解码

receive_wal.rs:600 WalAcceptor::run() → 收到 AppendRequest → tli.process_msg(NoFlushAppendRequest)

timeline.rs:1106 → safekeeper.rs:937 SafeKeeper::process_msg() → safekeeper.rs:1293 handle_append_request()

wal_storage.rs:437 PhysicalStorage::write_wal() —— 这是第一个关键点:

self.write_exact(startpos, buf)?;          // ① 写入磁盘
self.decoder.feed_bytes(buf);              // ② 喂入解码器
while let Some((lsn, _rec)) = self.decoder.poll_decode()? {  // ③ 找记录边界
    self.write_record_lsn = lsn;
}

这里只做 WAL page header 校验 + 记录边界识别 + CRC 校验,不做内容解析。对应:

lib.rs:409 feed_bytes() → 追加字节到内部 buffer

lib.rs:413 poll_decode() → 版本分派到 waldecoder_handler.rs:100 poll_decode_internal():

  • 验证 page header(magic、LSN、continuation record 标志)
  • 状态机:WaitingForRecord → 读 xl_tot_len → 跨页重组 → ReassemblingRecord
  • complete_record() → CRC 校验 → 处理 XLOG_SWITCH

此时 safekeeper 得到的是原始 WAL 字节(Bytes),只确认了记录边界,未解析内容。


阶段二:Safekeeper → Pageserver(WAL 转发 + 深度解码)

Pageserver (WAL consumer)

│ TCP连接, 发送 START_REPLICATION

▼

4. Safekeeper 侧:解读 WAL 并发送

send_wal.rs:443 handle_start_replication() → send_wal.rs:559 解读模式:

// send_wal.rs:601
let reader_handle = InterpretedWalReader::spawn(
    wal_stream, start_pos, tx, shard, pg_version, ...
);
// send_wal.rs:634
let sender_handle = InterpretedWalSender::spawn(rx, pgb_writer, ...);

send_interpreted_wal.rs:254 InterpretedWalReader::spawn() → send_interpreted_wal.rs:393 run_impl():

let mut wal_decoder = WalStreamDecoder::new(start_pos, self.pg_version);
loop {
    let wal = self.wal_stream.read().await?; // 从磁盘读 WAL
    wal_decoder.feed_bytes(&wal);            // 喂入流解码器
    while let Ok(Some((lsn, recdata))) = wal_decoder.poll_decode() { // ← 你选中的行
        // 这里是深度解码!
        let records = InterpretedWalRecord::from_bytes_filtered(
            recdata, &shard_ids, next_record_lsn, self.pg_version
        )?;
        tx.send(Batch { records, ... }).await?; // 发送给 sender
    }
}

5. 深度解码:decode_wal_record()(核心!)

decoder.rs:23 InterpretedWalRecord::from_bytes_filtered():

// ① 调用 postgres_ffi 的 decode_wal_record 解析 WAL 记录内容
decode_wal_record(buf, &mut decoded, pg_version)?;

// ② 按 shard 过滤并提取元数据 + 页面数据
MetadataRecord::from_decoded_filtered(&decoded, pg_version)? // 元数据(事务/DDL等)
SerializedValueBatch::from_decoded_filtered(&decoded, ...)   // 页面KV数据

walrecord.rs:246 decode_wal_record() —— 深度解析:

  • 解析 XLogRecord header(rmid, info, xid)
  • 遍历 block headers:提取 RelFileNode、forknum、blkno、full-page image、压缩信息
  • 处理 XLR_BLOCK_ID_ORIGIN、XLR_BLOCK_ID_TOPLEVEL_XID 等特殊标志

decoder.rs:77 MetadataRecord::from_decoded_filtered() → 按 xl_rmid 分发:

rmgr ID处理函数产物
RM_XACT_IDdecode_xact_record()XACT commit/abort 信息
RM_HEAP_IDdecode_heapam_record()VM bit 清除
RM_DBASE_IDdecode_dbase_record()DB create/drop
RM_SMGR_IDdecode_smgr_record()SMGR create/truncate
RM_CLOG_IDdecode_clog_record()CLOG zero/truncate
RM_LOGICALMSG_IDdecode_logical_message_record()LogicalMessage(Put/Failpoint)

6. 网络发送给 Pageserver

send_interpreted_wal.rs:650 InterpretedWalSender::run() → 从 channel 收 Batch → 序列化为 InterpretedWalRecords wire format → 通过 PG 协议发送


阶段三:Pageserver 接收 + 存储

Safekeeper 发送 InterpretedWalRecords (wire format)

│ TCP

▼

7. Pageserver 接收 WAL

walreceiver_connection.rs:116 handle_walreceiver_connection():

  • 连接 safekeeper(物理复制协议)
  • IDENTIFY_SYSTEM 获取 WAL 位点
  • START_REPLICATION PHYSICAL <startpoint> 开始流复制
  • 创建 WalIngest 实例

walreceiver_connection.rs:337 接收循环:

ReplicationMessage::RawInterpretedWalRecords(raw) => {
    let batch = InterpretedWalRecords::from_wire(raw.data(), format, compression)?;
    for record in batch.records {
        walingest.ingest_record(interpreted, &mut modification, &ctx)?;
    }
    modification.commit(&ctx).await?;
}

8. WAL 摄入引擎

walingest.rs:233 WalIngest::ingest_record() —— 中央分发:

ingest_record()
├── MetadataRecord 分发
│   ├── Xact(commit/abort) → ingest_xact_record() → 写 CLOG、删关系
│   ├── Dbase(create) → ingest_xlog_dbase_create() → 复制源库关系
│   ├── Dbase(drop) → ingest_xlog_dbase_drop() → 删除库关系
│   ├── Smgr(create) → ingest_xlog_smgr_create() → 创建关系元数据
│   ├── Smgr(truncate) → ingest_xlog_smgr_truncate()
│   ├── Clog(truncate) → ingest_clog_truncate()
│   ├── Heap(ClearVM) → ingest_clear_vm_bits() → WAL record 写入
│   ├── LogicalMessage(put) → ingest_logical_message_put()
│   └── ...
│
├── modification.ingest_batch(interpreted.batch) → 页面数据累积
│   └── [pgdatadir_mapping.rs:1929] → pending_data_batch 累积 KV
│
└── modification.put_checkpoint() → 更新 checkpoint (nextXid等)

9. 提交到存储层

pgdatadir_mapping.rs:2867 DatadirModification::commit():

let mut writer = self.tline.writer().await; // 获取 TimelineWriter
writer.put_batch(batch, ctx)?;             // 写入 InMemoryLayer
writer.finish_write(pending_lsn)?;         // 推进 last_record_lsn

timeline.rs:7862 → inmemory_layer.rs:571 InMemoryLayer::put_batch():

  • file.write_raw(raw) → 追加序列化字节到文件
  • index.write() → 更新内存 BTree 索引(key → LSN/offset/length)

完整调用栈总览

┌─────────────────────────────────────────────────────────────────────────┐
│ Compute 节点                                                           │
│ PostgreSQL WAL writer → TCP → START_WAL_PUSH                           │
└────────────────────────────┬────────────────────────────────────────────┘
                             ▼
┌─ Safekeeper ───────────────────────────────────────────────────────────┐
│ wal_service.rs:61 handle_socket() TCP accept                           │
│ handler.rs:306 process_query() PG协议分发                               │
│ receive_wal.rs:263 read_first_message() 读首条消息                      │
│ receive_wal.rs:412 read_network_loop() CopyData循环读取                 │
│ receive_wal.rs:600 WalAcceptor::run() 消息处理循环                      │
│ safekeeper.rs:1293 handle_append_request() WAL追加处理                  │
│ wal_storage.rs:437 write_wal() ─────────────────────┐                  │
│   ├── write_exact() 写入磁盘                        │                  │
│   ├── feed_bytes() 喂入WalStreamDecoder             │ ← 阶段一         │
│   └── poll_decode() 找记录边界+CRC校验 ← 你选中的行 │ (写入)           │
│       (waldecoder_handler.rs:100)                   │                  │
│                                                     │                  │
│ ─────────────── safekeeper 两条路径的分界线 ──────────── │                  │
│                                                     │                  │
│ send_wal.rs:443 handle_start_replication()          │                  │
│ send_interpreted_wal:254 InterpretedWalReader::spawn()│                  │
│ send_interpreted_wal:393 run_impl() ─────────────────────┐ │                  │
│   ├── feed_bytes() 喂入WalStreamDecoder             │ │                  │
│   ├── poll_decode() 找记录边界 ← 又是你选中的行     │ │ ← 阶段二         │
│   ├── from_bytes_filtered() ★ 深度解码入口          │ │ (转发)           │
│   │   ├── decode_wal_record() 解析WAL内容(walrecord:246)│ │                  │
│   │   ├── MetadataRecord解码 (decoder.rs:77)        │ │                  │
│   │   └── SerializedValueBatch 页面数据序列化       │ │                  │
│   └── tx.send(Batch) 发送给InterpretedWalSender     │ │                  │
│                                                     │                  │
│ send_interpreted_wal:650 InterpretedWalSender::run()│                  │
│   └── BeMessage::InterpretedWalRecords 序列化+网络发送│                  │
└────────────────────────────┬────────────────────────────────────────────┘
                             │ TCP (InterpretedWalRecords wire format)
                             ▼
┌─ Pageserver ───────────────────────────────────────────────────────────┐
│ walreceiver_connection:116 handle_walreceiver_connection() 连接+握手   │
│ walreceiver_connection:346 from_wire() 反序列化                        │
│ walreceiver_connection:446 ingest_record() ───────────────┐           │
│                                                           │           │
│ walingest.rs:233 WalIngest::ingest_record() 中央分发      │           │
│   ├── ingest_xact_record() → CLOG写入 + 关系删除          │           │
│   ├── ingest_xlog_dbase_create() → 复制数据库关系         │ ← 阶段三   │
│   ├── ingest_xlog_smgr_create() → 创建关系元数据          │ (存储)     │
│   ├── ingest_clear_vm_bits() → VM页面WAL记录              │
MATLAB 2022b 用户专属:保姆级IPOPT求解器安装配置全流程(含OPTI工具箱) 本文为MATLAB 2022b用户提供IPOPT求解器的详细安装与配置指南,涵盖OPTI工具箱的适配安装、环境变量设置及常见问题解决方案。通过实战案例演示非线性优化问题的求解过程,帮助用户高效部署这一强大的优化工具,提升工程计算效率。 阅读详情

相关推荐

[南大ICS]PA1 - 开天辟地的篇章: 最简单的计算机

task PA1.1: 实现单步执行, 打印寄存器状态, 扫描内存 task PA1.2: 实现算术表达式求值 task PA1.3: 实现所有要求, 提交完整的实验报告

qq_42474104的博客 1570

Neon wal日志处理流程2

本文深入解析 Neon 数据库中 WAL 的解码与传输机制,涵盖 safekeeper 的两种协议模式、解码层次、存储链路以及 logical_message 的特殊处理流程。通过对比传统 PostgreSQL 与 Neon 的架构差异,揭示计算存储分离下的 WAL 处理优化。

foolishlee的博客 266

图信号处理中的多尺度分析:图小波变换与图傅里叶变换的对比与应用

本文深入探讨了图信号处理中的多尺度分析方法,重点对比了图小波变换(GWT)与图傅里叶变换(GFT)的技术特点与应用场景。通过分析图的拓扑结构,GWT展现出强大的局部洞察力,适用于异常检测和社区发现;而GFT则擅长全局频率分析,适合趋势分析和信号去噪。文章结合实战案例,为读者提供了方法选型指南和前沿进展,帮助开发者在生物信息学、社交网络分析等领域高效应用这些技术。

weixin_30369041的博客 406

Neon safekeeper解析wal日志

文件中只有 Value::Image= 文件中可以有 Value::Image 或 Value::WalRecord底层解析:walrecord.rs 负责将原始 WAL 字节转换为结构化的 DecodedWALRecord语义理解:decoder.rs 进一步将解码后的记录转换为具有 Neon 存储语义的 InterpretedWalRecord数据分层:区分 Value 类型(Image/WalRecord)和 Layer 类型(Image Layer/Delta Layer)流程优化。

foolishlee的博客 240

同花顺自动化交易避坑指南:pywinauto实战中验证码识别与界面弹窗处理

本文深入探讨同花顺自动化交易中的关键稳定性问题,重点解决验证码识别与弹窗处理两大难题。通过优化Tesseract OCR、整合打码平台API以及设计pywinauto弹窗监控体系,提供了一套完整的自动化交易解决方案,帮助交易者有效规避资金账户和持仓信息操作中的常见陷阱。

weixin_33734785的博客 488

CANoe: Panel的上位机控制方法

本文介绍了不同于IG的报文控制方法,实现了Panel面板的控制模式。

Jonsnow3zz的博客 1407

Neon性能挑战:极限压力测试与优化成果

在现代云原生数据库领域,性能始终是核心挑战。Neon作为业界领先的Serverless PostgreSQL解决方案,通过创新的存储计算分离架构,重新定义了数据库性能的边界。本文将深入探讨Neon在面对极限压力测试时的表现,并详细分析其优化成果。 ## 架构优势:性能提升的基石 ### 存储计算分离架构 ```mermaid flowchart TD A[Compute Nodes...

gitblog_00771的博客 656

【IxNetwork】史上最全IxNetwork测试仪使用精讲(一),图文教程超赞超详细!!!

IXIA使用的是Server-client模式,Server端在测试仪表的主机上,在开机后会随着主机内的操作系统的启动而自动启动,一般情况下不需要人为的手工启动。因此在通常不需要为主机配置专用的显示器和键盘。client端包括两个测试软件: Ixia Explorer和ScriptMate。这两个软件一般安装在测试用计算机上,在仪表自带的主机中也有这两个软件。根据测试项目的不同来选择使用不同的软件。Ixia Explorer主要提供数据流的测试,针对设备的功能进行测试;

风云说通信 2056

Spring Boot 数据源与 MyBatis(-Plus) 自定义配置详解

本文详解 Spring Boot 中单数据源环境下 HikariCP 与 MyBatis-Plus 的自定义配置。通过手动声明 SqlSessionFactory,实现下划线转驼峰、日志输出、一级缓存策略等精细化控制。结合 HikariCP 核心参数调优(如最大连接数、连接生命周期),确保高性能与稳定性。适用于仅需访问单一数据库的场景,避免多数据源复杂性,兼顾性能与可维护性。

BADAO_LIUMANG_QIZHI的博客 206

道威棱镜的设计参考

道威棱镜的设计参考

weixin_72050316的博客 381

VSCode + QMT 量化交易完整解决方案!

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。

**My Coding Family** 1327

Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)

Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)

要努力去发光,而不是被照亮~ 143

为何wait和notify方法必须加锁?

为何wait和notify方法必须加锁? 是为了避免Lost Wake Up问题,即丢失唤醒问题。 所谓Lost Wake Up,指的是:线程A调用wait()方法进入阻塞状态,接下来没有其他线程去唤醒线程A,或者其他线程唤醒的时机不对(早于线程A的wait()),导致线程A永远阻塞下去。 下面以一个生产者和消费者的案例来说明上述问题。 假如我们有两个线程,一个消费者线程,一个生产者线程。生产者线程的任务可以简化成将count加一,而后唤醒消费者;消费者则是将count减一,而后在减到0的时候陷入睡眠,.

打酱油的葫芦娃 9155

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

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

m0_62221377的博客 462

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

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

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

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

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

数据库主键选型指南:BIGINT vs VARCHAR

主键选型关乎数据库性能与架构演进。BIGINT(如雪花算法)在顺序写入、二级索引开销和分布式生成上优势显著,适合高并发核心链路;而传统 VARCHAR UUIDv4 因随机性导致频繁页分裂、存储膨胀,性能堪忧。UUIDv7 通过时间戳有序性实现高效追加写入,结合 BINARY(16) 存储可兼顾性能与安全,成为现代微服务新选择。关键在于:主键应稳定、无业务含义,优先选用趋势递增的紧凑类型,并根据场景合理采用双主键模式或 ULID 等替代方案。

小李同学的博客 306

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

但行好事,莫问前程

qq_42996461的博客 220

自动化运维选型:四条技术路线的能力边界,以及它们为什么不能互相替代

自动化运维怎么选型?拆解配置管理、基础设施即代码、作业调度与场景化编排四条技术路线边界,分析账本归属与时间语义差异,给出四种架构组合与判断点,帮企业看清为何不能互相替代。

trainsignalcn的专栏 340

C++算法(七)

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

2503_94479566的博客 374

不用再为文本搜索单独维护一套系统!全文检索深度解析

为了给商品、客服工单或者企业知识库增加一个搜索框,企业往往需要在业务数据库之外,再部署一套Elasticsearch。数据库保存商品、订单和用户等真实业务数据,搜索引擎保存另一份文本索引;两套系统之间,还需要通过CDC、消息队列或者同步程序持续传输数据。一个看似简单的搜索需求,最后可能变成两套集群、两份数据和一条必须保持稳定的数据链路。由此产生的问题并不少:数据库已经完成更新,搜索结果却可能尚未同步;业务查询同时涉及文本、库存、权限和订单状态时,应用需要在两个系统之间来回组合结果;

TiDB 社区干货传送门 281

IDEA 简介:从零认识 IntelliJ IDEA

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

ztI10的博客 160

市场调查与统计分析专业大学期间考证怎么安排?

市场调查与统计分析专业的考证规划,适合从一份完整的调查报告倒推:能不能设计问卷、判断样本是否合理、清洗数据,再把分析结果转化为业务建议?围绕这条能力链安排证书,比单纯按“热门程度”报名更有针对性。结合2026年的学习安排,并为2027年的实习、升学和求职预留时间,大学期间可以重点考虑六类证书:全国计算机等级考试证书、大学英语四级或六级成绩报告单、CDA数据分析师、初级统计专业技术资格证书、微软办公软件国际认证中的Excel相关证书,以及软考数据库系统工程师资格证书。

cc572502653的博客 165

Oracle 19c 在线重定义后旧表空间清理及 ASM 存储资源回收 SOP

Oracle 19c 在线重定义后旧表空间清理与 ASM 存储资源回收 SOP

「YYL DBA手记」 数据库 · 架构 · 运维 · 实战 yyldba.blog.youkuaiyun.com 501

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

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

dbasenewbie的博客 274

MySQL报Too many open files?句柄耗尽的排查与参数配置

文章讲清 max_connections 与 open_files_limit 两个额度、句柄被谁占走、分区表为什么最容易踩,给出从 error log 到 /proc/pid/limits 的定位顺序与句柄预算算法。

「一个在数据库赛道上边学边分享的学妹」——聚焦国产数据库/信创方向、分享学习笔记、踩坑经验和行业观察。 319

从事件风暴到因果收敛:Mopheus多智能体协同事件触发架构与防循环实践

在构建生产级多智能体协同引擎的过程中,我们总结了三条核心工程准则:1.不可变因果链优于事后关系反查在高度并发且异步的多智能体网络中,因果关系的追溯绝不能依赖事后查库反查关联;将只增的因果祖先链显式封装在事件载荷与任务上下文中,以O(1)的内存检查实现确定性极高的闭环防范。2.生产端纯粹广播与消费端前置极速过滤是高吞吐的基石遵循严格的Pub/Sub模式,让核心业务实体与下游智能体编排解耦;通过调度层内存条件字典求值(conditions),在纳秒级内过滤掉99%的无关事件,保障零业务侵入与极高的系统吞吐。

weixin_54551388的博客 242

Spring事务和事务传播机制

3. 可重复读(REPEATABLE READ): 事务不会读到其他事务对已有数据的修改, 即使其他事务已提交. 也就可以确保同⼀事务多次查询的结果⼀致, 但是其他事务新插⼊的数据, 是可以感知到的. 这也就引发了幻读问题. 可重复读, 是 MySQL 的默认事务隔离级别.p1事务可以认为是⽗事务, 嵌套事务是⼦事务. ⽗事务出现异常, ⼦事务也会回滚, ⼦事务出现异常, 如果不进⾏处理, 也会导致⽗事务回滚.

txxzjmzlh的博客 207
上一篇: Neon safekeeper解析wal日志
下一篇: Neon wal日志处理流程2
foolishlee
博客等级 码龄19年 13粉丝 57原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值