【问题标题】:Postgres slave server log replay detailsPostgres 从服务器日志重播详细信息
【发布时间】:2015-10-15 13:56:22
【问题描述】:

Postgres 通过 WAL(Write Ahead Log) 文件支持主从复制。

在主服务器上,名为WALSender的后端进程将发送日志文件(记录)到从服务器,在从服务器上,名为WALReceiver的后端进程将接收日志文件(记录),并阻止数据而不是 SQL 查询存储在 WAL 文件中。 (我说的对吗??)

那么在基于文件的复制和流式复​​制这两种情况下,从服务器如何应用日志更新呢?我的意思是详细地说是哪个进程处理这个以及它是如何做到的?

提前致谢。

【问题讨论】:

  • 这更适合数据库管理员站点。

标签: postgresql master-slave wal


【解决方案1】:

你的描述是一个合理的总结,是的。大致分为三个层次:

  • 高级 SQL 查询,例如“UPDATE mytable SET a=nextval('some_sequence'), b=current_timestamp WHERE id=$1”

  • 逻辑行更改,例如“在主键值 id=42 的表 abc 中,元组已更新为新值(a=11,b=12314234321)”。这些不是以这种形式记录在磁盘上的,而是执行器内部产生的一个中间阶段,然后变成:

  • 将块级更改写入 xlog 然后写入堆,例如“与存储在表空间 1 中的 dboid 9191 中的 relfilenode 12312.1 相关,块 41231 字节偏移量 0x0012 更改为 0xde 0xad 0xbe 0xef 0x01”

(所有数字完全组成)

基于 WAL 的复制发生在最低级别,记录数据库中文件的块更改。好的,所以它不是那么简单,但这对于理解复制来说是可行的。

在独立的 master 上,SQL 被执行,产生记录到 WAL 和 shared_buffers 的行更改。然后重放 WAL 以将更改应用到数据库堆。 (同样,由于 bgwriter 的脏写回等原因,这并不是那么简单,但现在可以使用)。

使用基于 WAL 的复制,主服务器保留 WAL - 将其发送到副本或存档。副本,而不是生成自己的 WAL 然后重放它,只需从其他地方的 master 重放 WAL,使用它来更新数据库堆和它们的 shared_buffers

那么从服务器如何在基于文件的复制的两种情况下应用日志更新

副本运行restore_command 以在到达上一个存档的末尾时请求下一个 WAL 存档。然后恢复过程开始读取 WAL 存档,逐记录处理它。

查看restore_command 在源代码中是如何使用的,看看它是如何被调用的。

还有流式复制?

replica 的 walreceiver 连接到上游的 walsender 并接收 wal 记录。这些被写入一个文件,然后恢复过程会读取该文件。

recovery 部分在这两种情况下是相同的,不同之处在于 WAL 是如何从上游接收的。在 master 上进行崩溃恢复时,恢复也大致相同。这也只是重播 WAL。

我的意思是详细地说是哪个进程处理这个以及它是如何做到的?

最好的参考是源代码 - 特别是 cmets 和 README 文件。

我强烈建议您使用pg_xlogdump 来查看 WAL 实际包含的内容。然后阅读相关 WAL 记录的文档以了解每种记录类型的作用。

也从阅读src/backend/access/transam/READMEsrc/backend/access/transam/xlog.c 开始。

我不会重复相关 README 中已经包含的内容,它们比我的描述更可能是正确的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-01
    • 2017-07-16
    • 2016-01-02
    • 2013-12-24
    • 2020-08-03
    • 2014-11-17
    • 1970-01-01
    相关资源
    最近更新 更多