数据库的路上

Postgresql 源码研究之基础备份工具pg_basebackup

pg_basebackup介绍

pg_basebackup 是 PostgreSQL 内置的 物理备份工具,用于创建数据库集群的 一致基础备份。它支持 在线热备份(备份时数据库可正常读写),是实现高可用性(如流复制)和灾难恢复的核心工具之一

main函数介绍

根据代码分析,main()函数在pg_basebackup.c中主要完成了以下逻辑步骤:

  1. 初始化处理

    • 解析命令行参数
    • 设置信号处理
    • 初始化全局变量和数据结构
  2. 连接数据库

    • 建立与PostgreSQL服务器的连接

      conn = GetConnection();
      
    • 验证服务器版本兼容性

  3. 备份准备

    • 创建或清理目标目录

      verify_dir_is_empty_or_create(basedir, &made_new_pgdata, &found_existing_pgdata);
      
    • 处理表空间映射

    • 设置WAL日志目录

  4. 执行备份

    • 根据参数选择备份格式(plain/tar)
    • 启动后台WAL流接收进程
    • 通过流复制协议接收基础备份数据

    关键函数调

    BaseBackup() - 核心备份逻辑

    StartLogStreamer()` - 启动WAL流接收

    cleanup_directories_atexit()` - 退出时清理

全量备份

不指定增量备份情况下,默认是全量备份.

主要步骤

client 端 BaseBackup();

▶ 通过libpq 发送"BASE_BACKUP" 命令给server

image-20250429161709054

▶ 对于采用流复制备份单独启动一个进程接收wal日志(数据库在备份期间还存在并发写入的情况) StartLogStreamer(xlogstart..)

  • 会使用临时物理复制槽位,保证wal在备份期间不丢失
zhou=# select slot_name from pg_replication_slots ;
    slot_name      
---------------------
pg_basebackup_19476
(1 row)

▶ 循环接收服务端发送过来的备份数据直到结束 ReceiveArchiveStream(conn, client_compress);

server端 :
收到backup请求

image-20250429174951006

server端的backend 进程.显示的是walsender和pg_basebackup

 286171 ?        ts     0:00  \_ postgres: walsender postgres 127.0.0.1(46855) sending backup "pg_basebackup base backup"
执行具体备份的函数perform_base_backup()
  1. InitializeBackupManifest() 初始化备份清单

  2. do_pg_backup_start() 底层备份起始准备函数

    • 强制结束当前WAL段文件并开始一个新文件: RequestXLogSwitch(false);
    • 执行检查点RequestCheckpoint(CHECKPOINT_FORCE | CHECKPOINT_WAIT |(fast ? CHECKPOINT_IMMEDIATE : 0));
  3. bbsink_begin_backup(sink, &state, SINK_BUFFER_LENGTH); 标记开始备份

  4. 依次备份每一个表空间

    • bbsink_begin_archive(sink, “base.tar”); 准备打包信息,打包的话方便发送

    • backup_label = build_backup_content(backup_state, false);生成备份标签文件(backup_label)

    • sendFileWithContent(sink, BACKUP_LABEL_FILE backup_label, -1, &manifest); backup_label 内容写入 tar 流中

    • 把目录内文件发送到客户端 sendDir(sink, “.”, 1, false, state.tablespaces, sendtblspclinks, &manifest, InvalidOid, ib);

      遇到子目录会再次递归调用自己

  5. 最后发送控制文件 sendFile(sink, XLOG_CONTROL_FILE..)

结束备份 do_pg_backup_stop()

  • wal日志中插入结束备份标志
  • 切换wal日志
  • 写入备份历史文件

增量备份(Postgresql17 新特性)

通过incremental_manifest 变量控制逻辑进入到增量备份

image-20250429143732351

前提条件

设置参数summarize_wal = on
备份时指定 -i 参数
pg_basebackup -h 127.0.0.1 -p 5432 -D /Users/zhou/soft/pgsql/backup/base2 -i base1/backup_manifest
```​