当前位置: 首页
数据库
PostgreSQL与MySQL数据库日志机制深度对比

PostgreSQL与MySQL数据库日志机制深度对比

热心网友 时间:2026-07-18
转载

PostgreSQL仅使用一套WAL日志,就同时实现了MySQL的redo、binlog和undo的全部功能,而MySQL因插件式架构需要三套日志并依赖两阶段提交保证一致性。其多版本并发控制通过追加写实现,无需单独的undo日志,但需要定期执行VACUUM操作清理死元组,防止表膨胀。

一、结论先行

PostgreSQL 没有 redo log、binlog、undo log。

PostgreSQL及MySQL数据库日志机制深度对比

只有 WAL 一套日志,承担了 MySQL 三套日志的全部职责。

二、MySQL 为什么需要三套日志

MySQL 的架构一开始就分了两层,后果就是日志也得跟着裂成两层:

MySQL 架构
┌─────────────────────────────────────┐
│           Server 层                  │
│   binlog(引擎无关,Server 自己记)   │
├─────────────────────────────────────┤
│         InnoDB 引擎层                │
│   redo log(InnoDB 自己记)          │
│   undo log(InnoDB 自己记)          │
└─────────────────────────────────────┘
  • binlog:Server 层的逻辑日志,记录"执行了什么操作"
  • redo log:InnoDB 的物理日志,记录"数据页哪里改了"
  • undo log:InnoDB 的回滚日志,记录"改之前是什么"

说白了,这是历史包袱。MySQL 最初走的是插件式引擎架构,Server 层根本不知道引擎内部在干什么,只能各记各的账。

三、三套日志各自的职责

3.1 redo log —— 崩溃恢复

写入时序:
  事务提交
    ↓
  写 redo log(WAL,顺序写,快)
    ↓
  内存数据页标记为 dirty
    ↓
  checkpoint 时才把 dirty page 刷盘

崩溃恢复:
  重启 → 读 redo log → replay 未刷盘的变更 → 数据一致

对应到 PostgreSQL:WAL 承担了完全相同的职责

3.2 binlog —— 主从复制 / 数据归档 / CDC

binlog 有三种格式:
  STATEMENT:记录 SQL 语句(不精确,有歧义)
  ROW:      记录行的前后变化(精确,CDC 必用)
  MIXED:    混合模式

主从复制流程:
  主库 binlog → IO Thread → 从库 relay log → SQL Thread → 从库执行

对应到 PostgreSQL:WAL logical decoding 承担了相同职责

3.3 undo log —— 事务回滚 + MVCC

UPDATE user SET name='Alice' WHERE id=1

InnoDB 做法:
  1. 把旧值 name='Bob' 写入 undo log
  2. 数据页改为 name='Alice'(原地更新)
  3. 事务回滚时:从 undo log 读旧值,恢复回去

MVCC 读旧版本:
  另一个事务需要读 name='Bob'(旧快照)
  → 从 undo log 回溯旧版本

对应到 PostgreSQL:不需要 undo log,见下节

四、PostgreSQL 为什么不需要 undo log

这是 PG 和 MySQL MVCC 实现思路的根本差异

MySQL:原地更新(Update in Place)

数据页:
  ┌──────────────────┐
  │  id=1, name=Alice │  ← 只存最新版本
  └──────────────────┘

undo log:
  ┌──────────────────┐
  │  id=1, name=Bob   │  ← 旧版本存这里
  └──────────────────┘

读旧快照 → 去 undo log 里找

PostgreSQL:追加写(Append-Only Heap)

数据页:
  ┌──────────────────────────────────────────────┐
  │  Tuple1: id=1, name=Bob  [xmax=200, dead]    │  ← 旧版本,打标记
  │  Tuple2: id=1, name=Alice [xmin=200, alive]  │  ← 新版本
  └──────────────────────────────────────────────┘

UPDATE = INSERT 一条新 tuple + 把旧 tuple 标记为 dead

读旧快照 → 直接读同一数据页里的 dead tuple(根据 xmin/xmax 判断可见性)

代价:需要 VACUUM 清理

dead tuple 不会自动消失,需要 VACUUM 定期清理:
  VACUUM table_name;  -- 或者 autovacuum 后台自动运行

如果 VACUUM 跑不过来(写入太快)→ 表膨胀(Table Bloat)
这是 PG 的独有问题,MySQL 没有

五、MySQL 的两阶段提交

既然 redo log 和 binlog 是两套独立的日志,MySQL 就必须用两阶段提交来保证一致性:

事务提交流程:
  1. InnoDB 写 redo log(prepare 阶段)
  2. Server 写 binlog
  3. InnoDB 提交 redo log(commit 阶段)

如果第 2 步崩溃:
  重启后发现 redo log prepare 但 binlog 没有 → 回滚

如果第 3 步崩溃:
  重启后发现 binlog 有但 redo log 未 commit → 提交

保证 redo log 和 binlog 始终一致

PostgreSQL 没有这个问题,因为只有一套 WAL,天然一致。

六、完整对比表

职责 MySQL PostgreSQL
崩溃恢复 redo log(InnoDB 层) WAL
主从复制 binlog(Server 层) WAL Streaming Replication
CDC / 变更捕获 binlog(ROW 格式) WAL Logical Decoding
事务回滚 undo log WAL(未提交事务直接丢弃)
MVCC 旧版本 undo log 数据页内的 dead tuple
日志套数 3 套 1 套
架构复杂度 高(两阶段提交协调)

七、各自的优缺点

PostgreSQL WAL 优点

✅ 架构简洁,一套日志全包
✅ 无两阶段提交开销
✅ WAL 顺序写性能极好
✅ Logical Decoding 开箱即用,CDC 友好

PostgreSQL WAL 缺点 / 注意事项

⚠️ dead tuple 堆积需要 VACUUM,写入密集场景需要调优
⚠️ wal_level=logical 会增加 WAL 体积(记录更多信息)
⚠️ Replication Slot 如果消费方停止,WAL 文件不删除 → 磁盘风险

MySQL 日志优点

✅ undo log 独立,旧版本存储与数据文件分离,表不膨胀
✅ binlog 格式成熟,生态丰富(Canal、Maxwell 等 CDC 工具)

MySQL 日志缺点

⚠️ 三套日志,维护复杂
⚠️ 两阶段提交有额外开销
⚠️ binlog 和 redo log 可能不一致(极端崩溃场景)
⚠️ undo log 过大会影响读性能(长事务问题)

八、小结

MySQL:历史包袱导致三套日志
  redo log  ← 崩溃恢复
  binlog    ← 复制/CDC
  undo log  ← 回滚/MVCC

PostgreSQL:设计简洁,一套 WAL 全包
  WAL              ← 崩溃恢复 + 复制 + CDC
  heap dead tuple  ← MVCC 旧版本(替代 undo log)

代价不同:
  MySQL  → 两阶段提交协调开销 + undo log 长事务问题
  PG     → dead tuple 堆积需要 VACUUM 调优

总结

来源:https://www.jb51.net/database/367316sxe.htm

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
SQL数据库视图简化开发人员编码的实用方法

SQL数据库视图简化开发人员编码的实用方法

视图适合封装固定逻辑(如固定时间窗口、静态状态过滤)和固定JOIN关系,不宜用于需动态传入参数(如用户ID、日期范围)的查询。视图性能取决于底层索引,而非视图本身。ALTERVIEW仅更新元数据,会短暂阻塞新查询启动,应避开高峰期操作。

时间:2026-07-18 22:24
MySQL decimal使用常见问题及解决方法

MySQL decimal使用常见问题及解决方法

MySQL中的DECIMAL类型用于精确数值计算,通过DECIMAL(M,D)定义精度与标度。常见问题包括精度设置不当导致溢出、计算时精度溢出、插入格式错误等。优化建议:合理设置M和D,可用BIGINT存储分单位,关键列建索引,保持版本更新。

时间:2026-07-18 22:22
MySQL大字段TEXT建立索引导致的性能下降解决方案

MySQL大字段TEXT建立索引导致的性能下降解决方案

TEXT字段无法直接建立常规B+树索引,前缀索引不支持左模糊查询,全文索引受词长、中文分词和更新延迟限制。高效替代方案是使用MD5摘要索引和垂直拆分,将TEXT字段分离到独立表,主表采用DYNAMIC行格式,避免溢出页IO问题。

时间:2026-07-18 22:22
金仓数据库迁移避坑指南:从未被质疑的左连接隐患

金仓数据库迁移避坑指南:从未被质疑的左连接隐患

迁移至金仓KES时,LEFTJOIN若在WHERE中过滤右表非空列,将会触发外连接消除,导致数据结果减少。正确做法是将过滤条件置于ON子句中。金仓KES与主流数据库行为一致,务必通过EXPLAIN仔细检查执行计划,以确保连接语义正确。

时间:2026-07-18 22:22
PostgreSQL与MySQL数据库日志机制深度对比

PostgreSQL与MySQL数据库日志机制深度对比

PostgreSQL仅使用一套WAL日志,就同时实现了MySQL的redo、binlog和undo的全部功能,而MySQL因插件式架构需要三套日志并依赖两阶段提交保证一致性。其多版本并发控制通过追加写实现,无需单独的undo日志,但需要定期执行VACUUM操作清理死元组,防止表膨胀。

时间:2026-07-18 22:22
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 热门数据榜