发布时间:2026/7/21 16:52:33
WAL机制学习 背景在学习游戏常见场景开发遇到这个概念看目的是为了解决缓存写入数据库的过程失败后未落库的数据能够落地的方案。但是在实际工作中遇到比较少故展开学习。学习目标了解该机制原理应用场景原理WAL 的核心就是先写日志再写数据崩溃后通过回放日志来恢复。一个典型的 WAL 方案包含三个部分日志文件追加写入的文本文件或二进制文件每条记录代表一个操作。写入器负责将操作序列化为日志并刷盘。回放器启动时或崩溃后读取日志与数据库对比执行缺失的操作。关键细节以下用一些示例代码讲解下定义日志记录结构每条日志包含唯一ID、操作类型、时间戳和具体数据。importjsonimportosimportuuidimporttimefromtypingimportCallable,Dict,AnyclassWalRecord:单条WAL记录def__init__(self,op_type:str,data:Dict[str,Any]):self.record_idstr(uuid.uuid4())self.op_typeop_type# 例如 add_friend, remove_friendself.datadata# 例如 {user_id: 1, friend_id: 2}self.timestamptime.time()defto_json(self)-str:returnjson.dumps({id:self.record_id,op:self.op_type,data:self.data,ts:self.timestamp})\nstaticmethoddeffrom_json(line:str)-WalRecord:objjson.loads(line.strip())recWalRecord(obj[op],obj[data])rec.record_idobj[id]rec.timestampobj[ts]returnrecWAL 管理器负责写入、回放和清理。classWalManager:def__init__(self,file_path:str/var/log/friend_wal.log):self.file_pathfile_path self._fileNonedefopen(self):打开日志文件以追加模式self._fileopen(self.file_path,a)# a 可读可追加defclose(self):ifself._file:self._file.close()defappend(self,record:WalRecord):追加一条记录并强制刷盘linerecord.to_json()self._file.write(line)self._file.flush()# 刷新到内核缓冲区os.fsync(self._file.fileno())# 强制刷入磁盘关键defread_all(self)-list:读取所有记录用于回放records[]self._file.seek(0)# 回到文件开头forlineinself._file:ifline.strip():records.append(WalRecord.from_json(line))returnrecordsdeftruncate(self,upto_record_id:str):截断到指定记录之后清理已处理的日志# 简单实现重写文件只保留大于upto_record_id的记录all_recordsself.read_all()keep_records[rforrinall_recordsifr.record_id!upto_record_idandall_records.index(r)all_records.index([xforxinall_recordsifx.record_idupto_record_id][0])]self._file.close()withopen(self.file_path,w)asf:forrecinkeep_records:f.write(rec.to_json())self._fileopen(self.file_path,a)为什么需要 os.fsyncflush() 只是将数据从用户空间缓冲区移到内核缓冲区但内核可能还未写入磁盘。os.fsync() 强制内核将数据刷入物理磁盘确保即使系统掉电也不会丢失。这是 WAL 可靠性的核心。幂等恢复回放时不能简单地重放所有日志因为有些操作可能已经成功写入数据库例如第一次运行正常但后来服务又崩溃了。因此需要先检查数据库中是否已经存在该操作的结果。常见做法使用 INSERT IGNORE 或 ON DUPLICATE KEY UPDATE让数据库自动跳过重复。或者维护一张 processed_log 表记录已处理的日志ID回放时跳过这些ID。日志清理WAL 文件会无限增长需要定期清理。清理策略标记-截断记录一个“安全水位”表示该ID之前的日志都已处理完毕可以删除。分段管理按时间或大小切分文件只保留最近N个文件。使用数据库表代替文件利用数据库自身的清理机制.应用场景MySQL InnoDB 的 Redo LogMySQL 的 InnoDB 存储引擎内部就有 WAL 机制称为 Redo Log。每次事务提交时先写 Redo Log顺序IO再异步刷脏页到数据文件。如果数据库崩溃重启时通过 Redo Log 恢复未写入数据文件的修改。这是 WAL 最经典的工业实现。Kafka 的 Partition LogKafka 的每个分区本质上就是一个 WAL 文件。生产者写入消息时先追加到分区日志顺序写消费者从日志中读取。Kafka 的高吞吐和可靠性正依赖于这种 WAL 设计。RocksDB / LevelDB 的 WALFacebook 开发的 RocksDB用于 MySQL MyRocks 引擎、TiKV 等也有独立的 WAL 文件。每次写入先写 WAL再写 MemTable崩溃后通过 WAL 恢复。分布式系统中的 WALZooKeeper每个事务先写事务日志WAL再更新内存状态。etcd使用 BoltDB 的 WAL 机制保证一致性。TiDB​ 的 TiKV 节点使用 Raft 协议底层也是 WALRaft Log。

相关新闻

2026/7/20 12:40:12

Obsidian界面优化:5个CSS代码片段解决你的视觉疲劳问题

Obsidian界面优化:5个CSS代码片段解决你的视觉疲劳问题 【免费下载链接】awesome-obsidian 🕶️ Awesome stuff for Obsidian 项目地址: https://gitcode.com/gh_mirrors/aw/awesome-obsidian Obsidian作为一款强大的知识管理工具,虽然…

2026/7/20 12:35:12

从代码到画布:网页设计师的灵感捕捉神器

从代码到画布:网页设计师的灵感捕捉神器 【免费下载链接】figma-html Convert any website to editable Figma designs 项目地址: https://gitcode.com/gh_mirrors/fi/figma-html 你是否曾在一个精美的网站上流连忘返,想要借鉴其设计却无从下手&a…

2026/7/21 16:51:26

企业 GEO 精细化运营:双工具递进,实现 AI 流量可持续增长

当下,豆包、DeepSeek、腾讯元宝、Kimi 等大模型已经成为用户选购、对比产品的核心决策入口。大量品牌发现,即便布局大量宣传内容,依然会在 AI 问答场景陷入 “AI 隐身” 困境:推荐榜单缺席、排名靠后、AI 认知存在偏差、负面信息无…

2026/7/21 16:51:26

2026年北京市各区智能工厂奖补政策最全汇编

一、国家层面政策根据2026年7月发布的《关于开展2026年度智能工厂梯度培育行动的通知》(工信厅联通装函〔2026〕343号),智能工厂分为基础级、先进级、卓越级、领航级四个层级进行梯度培育:1、基础级与先进级:由省级主管…

2026/7/21 16:51:26

Bilibili视频评论爬虫:基于Selenium的完整数据采集实战指南

Bilibili视频评论爬虫:基于Selenium的完整数据采集实战指南 【免费下载链接】BilibiliCommentScraper B站视频评论爬虫 Bilibili完整爬取评论数据,包括一级评论、二级评论、昵称、用户ID、发布时间、点赞数 项目地址: https://gitcode.com/gh_mirrors/…

2026/7/21 16:51:26

高新技术企业复审需要满足哪些要求?复审通过有奖励吗?

高新技术企业复审并非简单的形式审查,而是等同于“重新认定”,必须完全满足国科发〔2016〕32号文规定的八大硬性指标,且评分需高于70分。一、核心资格自检(硬性指标)复审企业必须同时满足以下条件,否则一票…

2026/7/21 16:46:25

3步掌握AI金融分析:用Finance Skills轻松计算公司真实价值

3步掌握AI金融分析:用Finance Skills轻松计算公司真实价值 【免费下载链接】finance-skills A collection of skills for AI financial analysis. 项目地址: https://gitcode.com/gh_mirrors/fi/finance-skills 想要快速判断一家公司是否值得投资&#xff1f…

2026/7/20 6:33:00

Unity与Python本地通信:基于Flask的跨语言数据交换实战

1. 项目概述:为什么我们需要一个本地通信服务器?在游戏开发、数字孪生、仿真训练等众多领域,Unity作为强大的实时3D内容创作平台,其核心逻辑通常由C#驱动。然而,当我们需要进行复杂的数据分析、机器学习推理、科学计算…

2026/7/21 0:08:52

华为OD机试 新系统真题 【酒店服务记录分析】

酒店服务记录分析(C++/Go/C/Js/Java/Py)题解 华为OD机试 新系统真题 华为OD上机考试 新系统真题 7月19号 100分题型 华为OD机试新系统真题目录点击查看: 华为OD机试新系统真题题库目录|机考题库 + 算法考点详解 题目内容 你是某连锁酒店的数据分析师,酒店每天都会用一串编…

2026/7/21 0:08:52

华为OD机试 新系统真题 【小明的顺风车】

小明的顺风车(C++/Go/C/Js/JAVA/Py)题解 华为OD机试新系统真题 华为OD上机考试新系统真题 7月19号 200分题型 华为OD机试新系统真题目录点击查看: 华为OD机试新系统真题题库目录|机考题库 + 算法考点详解 题目内容 小明自驾回家,为节省旅途成本,决定在网上挂出顺风车服务…

2026/7/20 19:08:28

3个高效策略:快速掌握Axure中文界面配置

3个高效策略:快速掌握Axure中文界面配置 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 还在为Axure RP的英文界面感…