CodeGym /课程 /SQL SELF /PostgreSQL 怎么存数据:数据库结构和事务日志(WAL)

PostgreSQL 怎么存数据:数据库结构和事务日志(WAL)

SQL SELF
第 43 级, 课程 4
可用

你平时用数据库的时候,好像一切都挺简单:加一行、改个记录、删个客户。但其实这背后有一套很复杂、很精妙的机制。那些数据到底存哪儿了?为啥 PostgreSQL 就算服务器突然断电也不会丢数据?

想搞明白这些,你得知道两件事:数据(表、索引、服务信息)到底物理上放哪儿,以及数据保护机制是怎么搞的——也就是事务日志,WAL(Write-Ahead Logging)。

整个 PostgreSQL 数据库其实就是一堆文件,放在一个专门的目录里——data_directory。一般都在这儿:

/var/lib/postgresql/17/main

这个文件夹就是数据库的心脏:表、索引、元信息、配置全都在这儿。WAL 日志也在这里——它是第一个接收所有变更的机制。数据还没真正写进表文件前,都会先写进 WAL。就像草稿本,数据库把每一步都记下来,这样哪怕出事了,也能恢复到最后一次操作。

靠这种方式,PostgreSQL 就算在最不靠谱的环境下也能保证数据安全和稳定。

表

每个表其实就是一个独立的文件或者一组文件。这些文件都在 base/ 子目录下。结构大概这样:

$PGDATA/base/
├── 16384/
│   ├── 12345   ← 表
│   ├── 12346   ← 索引
│   └── ...
  • 16384 —— 这是数据库的内部 ID(OID)。
  • 12345 —— 这是具体表的 ID。

如果表很大,PostgreSQL 会把它按 1GB 分成多个段:

12345
12345.1
12345.2
...

这些文件里可不是像 CSV 那样的“行”,而是 8KB 的“二进制页面”格式。

WAL: Write-Ahead Logging —— 不只是个“日志”

现在说说 PostgreSQL 里最重要、但经常被误解的部分之一——WAL,也就是Write-Ahead Logging。别看名字里有 log,WAL 可不是普通的文本日志文件,不像错误日志或者查询日志那样。它是保证数据一致性和恢复的核心机制,直接操作底层文件系统的变更。

WAL 不是事件报告,而是所有即将发生的数据变更的预写记录。而且这记录是在真正改表文件之前写进去的。所以才叫 write-ahead ——“提前写”。

比如你往表里插一行,PostgreSQL 会:

  1. 不会立刻改表文件 —— 这样又慢又不安全。
  2. 先写进 WAL,说明要加这一行。
  3. 等到合适的时候(比如后台进程),才真的把数据写进表文件。

这就像你在银行开支票:先签个支票(WAL),银行之后才会更新账户(表)。要是出点啥事——支票还在手上,操作还能重来。

WAL 的格式和结构

  • WAL 文件是二进制格式的。
  • 每个文件都是严格有序的操作流,描述了数据页、索引结构、提交等的内部变更。
  • 一个 WAL 文件大小是固定的——默认 16MB。

注意:WAL 里没有“SQL 命令”或者“表的行”这种东西。它只存PostgreSQL 引擎用来重放变更的指令,一页一页地还原。

崩溃时会发生什么?

如果 PostgreSQL 服务器突然挂了——比如断电——也不用慌。下次启动时,数据库不会慌张,而是先从磁盘加载最后一次保存的“稳定”数据版本。然后它会拿出事务日志(WAL),把里面还没写进主文件的所有变更都“补上”。这样数据库就能恢复到完全一致的状态,仿佛啥事都没发生。

WAL 的额外功能

Point-In-Time Recovery (PITR)。 只要保存 WAL 文件,就能把数据库恢复到任意时间点,只要在两个完整备份之间。

流式复制。 PostgreSQL 可以实时把 WAL 记录发到另一个服务器。这就能搞热备份——和主库同步的数据库副本。

增量恢复。 配合完整备份,WAL 能只恢复变更的部分,不用全库重拷贝。

做二进制备份:pg_basebackup

如果你用过 pg_dump,就知道它很适合做逻辑备份(把数据库结构和数据导成 SQL 语句)。但要是你想做物理备份呢?比如把数据库所有文件完整镜像一份?这时候就要用 pg_basebackup 了。

pg_basebackup 是个能做 PostgreSQL 物理拷贝的工具。它对大数据库特别有用,能高效管理恢复流程。最大优点就是速度快。

pg_basebackup 的基本命令用法

用 pg_basebackup,先得搞懂它的命令格式。在终端里执行,基本长这样:

pg_basebackup -D /backup_directory -F tar -z -P

来拆解一下:

  • -D /backup_directory —— 指定备份文件要存哪儿。
  • -F tar —— 数据格式。tar 选项会生成 .tar 格式的归档文件。你也可以用 plain,那就是数据库文件夹结构。
  • -z —— 压缩备份,省磁盘空间。谁不喜欢备份小点呢!
  • -P —— 实时显示进度。看着进度条,心里更踏实:知道进程没卡死。

用法示例:

pg_basebackup -D /backups/university_backup -F tar -z -P

执行完后,在 /backups/university_backup 目录下就有了 .tar 格式的备份。

用 pg_basebackup 的好处

高效: 增量备份不会重复拷贝没变的数据,省时又省空间。

简单易用: pg_basebackup 自动处理所有细节,包括 WAL 文件。

靠谱: 跟 PostgreSQL 引擎深度集成,pg_basebackup 能做出完整可恢复的数据库副本。

使用示例

下面来点实操。这里有几个 pg_basebackup 的真实用法例子:怎么做基础备份、怎么加压缩、怎么开启 WAL 日志归档(这样就能恢复到任意时间点)。这些命令新手老手都能用。

做基础备份

pg_basebackup -D /backups/full_backup -F tar -z -P

结果:一个完整的数据库 .tar 归档备份。

设置压缩和格式

做个高压缩级别的备份:

pg_basebackup -D /backups/full_backup -F tar -z -Z 9 -P

这里 -Z 9 是压缩级别(最高 9)。

WAL 归档

如果你配置了 WAL 归档,数据库就能恢复到任意时间点。设置 WAL 备份的命令:

pg_basebackup -D /backups/incremental_backup -F tar -z -P --wal-method=archive
2
任务
SQL SELF, 第 43 级, 课程 4
已锁定
使用 WAL 创建 PostgreSQL 物理备份
使用 WAL 创建 PostgreSQL 物理备份
1
调查/小测验
备份简介第 43 级,课程 4
不可用
备份简介
备份简介
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION