PostgreSQL 没有 redo log、binlog、undo log。
只有 WAL 一套日志,承担了 MySQL 三套日志的全部职责。
MySQL 的架构分为两层,导致日志也分裂成两层:
MySQL 架构┌─────────────────────────────────────┐│ Server 层 ││ binlog(引擎无关,Server 自己记) │├─────────────────────────────────────┤│ InnoDB 引擎层 ││ redo log(InnoDB 自己记) ││ undo log(InnoDB 自己记) │└─────────────────────────────────────┘
这是历史包袱:MySQL 最初是插件式引擎架构,Server 层不知道引擎内部,只能各记各的。
写入时序: 事务提交 ↓ 写 redo log(WAL,顺序写,快) ↓ 内存数据页标记为 dirty ↓ checkpoint 时才把 dirty page 刷盘崩溃恢复: 重启 → 读 redo log → replay 未刷盘的变更 → 数据一致
对应 PostgreSQL:WAL 承担了完全相同的职责
binlog 有三种格式: STATEMENT:记录 SQL 语句(不精确,有歧义) ROW: 记录行的前后变化(精确,CDC 必用) MIXED: 混合模式主从复制流程: 主库 binlog → IO Thread → 从库 relay log → SQL Thread → 从库执行
对应 PostgreSQL:WAL logical decoding 承担了相同职责
UPDATE user SET name='Alice' WHERE id=1InnoDB 做法: 1. 把旧值 name='Bob' 写入 undo log 2. 数据页改为 name='Alice'(原地更新) 3. 事务回滚时:从 undo log 读旧值,恢复回去 MVCC 读旧版本: 另一个事务需要读 name='Bob'(旧快照) → 从 undo log 回溯旧版本
对应 PostgreSQL:不需要 undo log,见下节
这是 PG 和 MySQL MVCC 实现思路的根本差异。
数据页: ┌──────────────────┐ │ id=1, name=Alice │ ← 只存最新版本 └──────────────────┘undo log: ┌──────────────────┐ │ id=1, name=Bob │ ← 旧版本存这里 └──────────────────┘读旧快照 → 去 undo log 里找
数据页: ┌──────────────────────────────────────────────┐ │ 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 判断可见性)
dead tuple 不会自动消失,需要 VACUUM 定期清理: VACUUM table_name; -- 或者 autovacuum 后台自动运行如果 VACUUM 跑不过来(写入太快)→ 表膨胀(Table Bloat)这是 PG 的独有问题,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 套 |
| 架构复杂度 | 高(两阶段提交协调) | 低 |
✅ 架构简洁,一套日志全包✅ 无两阶段提交开销✅ WAL 顺序写性能极好✅ Logical Decoding 开箱即用,CDC 友好
⚠️ dead tuple 堆积需要 VACUUM,写入密集场景需要调优⚠️ wal_level=logical 会增加 WAL 体积(记录更多信息)⚠️ Replication Slot 如果消费方停止,WAL 文件不删除 → 磁盘风险
✅ undo log 独立,旧版本存储与数据文件分离,表不膨胀✅ binlog 格式成熟,生态丰富(Canal、Maxwell 等 CDC 工具)
⚠️ 三套日志,维护复杂⚠️ 两阶段提交有额外开销⚠️ binlog 和 redo log 可能不一致(极端崩溃场景)⚠️ undo log 过大会影响读性能(长事务问题)
MySQL:历史包袱导致三套日志 redo log ← 崩溃恢复 binlog ← 复制/CDC undo log ← 回滚/MVCCPostgreSQL:设计简洁,一套 WAL 全包 WAL ← 崩溃恢复 + 复制 + CDC heap dead tuple ← MVCC 旧版本(替代 undo log) 代价不同: MySQL → 两阶段提交协调开销 + undo log 长事务问题 PG → dead tuple 堆积需要 VACUUM 调优
樱花动漫APP下载-樱花动漫官方正版APP最新下载入口
premiere画中画大小位置调节方法 - premiere如何调节画中画大小和位置
丁香修剪技巧有哪些-如何用丁香修剪技巧打造优美树形
在Win2008 R2中如何删除DHCP管理工具-Win2008 R2怎样删除DHCP管理工具
如何通过支付宝阿宝自动匹配生活服务入口-怎样借助支付宝阿宝自动匹配生活服务入口
edius素材添加单门推效果的操作方法-edius素材如何添加单门推效果