postgresql流复制同异步分析

news/2024/7/9 20:21:13 标签: postgresql, 数据库

postgresql_0">postgresql流复制同异步分析

postgresql流复制主要是四个进程的交互。

  • postgres(backend进程)(主节点)

    接受客户端的请求,并通过共享内存等待walsender唤醒。

  • walsender(主节点)

    向walreceiver发送日志,通过tcp通信,采用流复制协议与walreceiver交互。

  • walreceiver(备节点)

    向walsender请求日志,并回复wal日志接收,写入,数据apply信息,通过tcp通信,采用流复制协议与walsender通信。

  • startup(备节点)

    进行日志回放,将wal日志redo成数据,通过共享内存和信号与walreceiver通信。

参数

流复制同异步由如下两个参数控制:

  • synchronous_commit

    用于指定同异步模式。

  • synchronous_standby_names

    用于指定同步时需要多少备节点确认。

synchronous_commit

配置解析

{"synchronous_commit", PGC_USERSET, WAL_SETTINGS,
            gettext_noop("Sets the current transaction's synchronization level."),
            NULL
        },
        &synchronous_commit,
        SYNCHRONOUS_COMMIT_ON, synchronous_commit_options,
        NULL, assign_synchronous_commit, NULL
static const struct config_enum_entry synchronous_commit_options[] = {
    {"local", SYNCHRONOUS_COMMIT_LOCAL_FLUSH, false},
    {"remote_write", SYNCHRONOUS_COMMIT_REMOTE_WRITE, false},
    {"remote_apply", SYNCHRONOUS_COMMIT_REMOTE_APPLY, false},
    {"on", SYNCHRONOUS_COMMIT_ON, false},
    {"off", SYNCHRONOUS_COMMIT_OFF, false},
    {"true", SYNCHRONOUS_COMMIT_ON, true},
    {"false", SYNCHRONOUS_COMMIT_OFF, true},
    {"yes", SYNCHRONOUS_COMMIT_ON, true},
    {"no", SYNCHRONOUS_COMMIT_OFF, true},
    {"1", SYNCHRONOUS_COMMIT_ON, true},
    {"0", SYNCHRONOUS_COMMIT_OFF, true},
    {NULL, 0, false}
};

配置不同的值代表不同的同步模式。

synchronous_standby_names

配置解析

{
        {"synchronous_standby_names", PGC_SIGHUP, REPLICATION_PRIMARY,
            gettext_noop("Number of synchronous standbys and list of names of potential synchronous ones."),
            NULL,
            GUC_LIST_INPUT
        },
        &SyncRepStandbyNames,
        "",
        check_synchronous_standby_names, assign_synchronous_standby_names, NULL
    },
SyncRepConfig = (SyncRepConfigData *) extra;

在check_synchronous_standby_names中解析后最终将其赋值给了SyncRepConfig。

synchronous_standby_names可以配置为某个具体的备节点名,也可以配置成any 1(*)的形式。

synchronous_standby_names = 'standby001'

或者

synchronous_standby_names='ANY 1 (*)'

walsender进程处理同步

walsender收到walreceiver回复的r报文
唤醒满足条件的backend进程
计算备库的回复确认是否满足要求,同时会计算writePtr,flushPtr,applyPtr
获取候选者个数
SYNC_REP_PRIORITY优先级模式计算ptr,最旧的
非优先级模式计算ptr,第n个
ProcessStandbyMessage
ProcessStandbyReplyMessage
SyncRepReleaseWaiters
SyncRepGetSyncRecPtr
SyncRepGetCandidateStandbys
SyncRepGetOldestSyncRecPtr
SyncRepGetNthLatestSyncRecPtr

收到walreceiver的确认报文,walsender需要判断回复的standby个数是否满足配置的要求。SyncRepGetSyncRecPtr中会计算已经回复的standby个数并和配置的值进行比较,若满足则会返回true,否则返回false。

got_recptr = SyncRepGetSyncRecPtr(&writePtr, &flushPtr, &applyPtr, &am_sync);
    if (!got_recptr || !am_sync)	{ // 若确认的standby个数不足或者不是sync模式直接返回
		LWLockRelease(SyncRepLock);
		announce_next_takeover = !am_sync;
		return;
	}

若确认的standby个数不足或者不是sync模式直接返回;

若确认的standby个数满足,且是sync模式,则需要唤醒对应模式的backend进程。

    if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
	{
		walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
		numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
	}
	if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
	{
		walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
		numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
	}
	if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
	{
		walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
		numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
	}

此时唤醒对应的后端进程后,后端进程将回复客户端。


http://www.niftyadmin.cn/n/332348.html

相关文章

点亮未来明灯,引领绿色革命

随着全球气候变化日趋严重&#xff0c;能源转型成为解决气候问题和提高全球能源安全合理性的必要措施之一。可持续能源技术因其对环境的友好性和可再生性而成为了当前热点话题。可持续能源技术已经成为人们日益关注的焦点。这项技术可以帮助我们减少对化石燃料的依赖&#xff0…

ThreadLocal 的原理讲述 + 基于ThreadLocal实现MVC中的M层的事务控制

ThreadLocal 的原理讲述 基于ThreadLocal实现MVC中的M层的事务控制 文章目录 ThreadLocal 的原理讲述 基于ThreadLocal实现MVC中的M层的事务控制每博一文案1. ThreadLocal 给概述2. 抛砖引玉——>ThreadLocal3. ThreadLocal 的模拟编写4. ThreadLocal 源码原理分析5. Thre…

C语言——史上最全通讯录讲解(附源码)

C语言——史上最全通讯录讲解&#xff08;附源码&#xff09; 一、开始界面的打印二、对六大板块进行定义操作三、对联系人进行初始化四、对通讯录进行初始化4.1动态版本4.2静态版本 五、通讯录六大功能的具体实现5.1判断是否需要扩容Checkcapcity5.2添加联系人ADDcontact5.3删…

C++ ---- 类和对象(下)

目录 初始化列表 初始化列表的语法 初始化列表的特性 explicit关键字 构造函数的隐式转换 explicit的作用 static修饰成员变量和成员函数 static修饰成员变量 static修饰成员函数 友元 友元函数 友元类 内部类 匿名对象 拷贝对象时的一些编译器优化 初始化列表 …

用两分钟教会你在领英Linkedin实现一天几个询盘

如果有兄弟还只会在展会、邮箱这些传统渠道开发客户的话&#xff0c;今天这篇文章你就要好好读一下了。最近几年&#xff0c;是社交媒体营销比较火爆的时候&#xff0c;很多跨境人都开始了社交化主动式去开发客户。而领英作为目前全球用户总计超过8亿&#xff0c;覆盖了200多个…

Android Studio 基础 之 使用 okhttp 长连接,流式获取数据的方法简单整理了

Android Studio 基础 之 使用 okhttp 长连接&#xff0c;流式获取数据的方法简单整理了 目录 Android Studio 基础 之 使用 okhttp 长连接&#xff0c;流式获取数据的方法简单整理了 一、简单介绍 二、实现原理 三、注意事项 四、效果预览 五、实现关键 六、关键代码 七…

生产流程图怎么制作?思路提供

生产流程图是一种图表&#xff0c;用来展示生产流程中的各个环节及其顺序。这种图表可以帮助企业管理者更好地了解生产过程中的各个环节&#xff0c;从而更好地进行管理和优化。生产流程图通常包括各个生产环节的名称、所需时间、参与人员、设备和工具等信息。 在制作生产流程图…

什么是GHZ?炫云到底是怎么收费的?

作为一家云渲染“老牌”服务商&#xff0c;炫云的行业资历无疑是悠久的。在广大用户的支持与认可下&#xff0c;炫云砥砺前行迎来蓬勃发展。注册用户体量的剧增&#xff0c;为炫云带来了更多新面孔。在客服汇总的新用户常见问题里&#xff0c;有关“GHZ”与“收费”的字眼出现频…