PgSQL · 特性分析· Logical Decoding探索

简介: Logical Decoding是9.4里面的一个主要功能,是向最终实现逻辑复制迈出的一大步。简言之,它的功能是从PG的WAL日志中,读取数据库更新信息,然后“翻译”(Decode)成逻辑的形式,可发送到远程从库做数据同步。这个功能还可以用于,DBA在数据库宕机,并发生主从切换后,检查原主库有哪些.

Logical Decoding是9.4里面的一个主要功能,是向最终实现逻辑复制迈出的一大步。简言之,它的功能是从PG的WAL日志中,读取数据库更新信息,然后“翻译”(Decode)成逻辑的形式,可发送到远程从库做数据同步。这个功能还可以用于,DBA在数据库宕机,并发生主从切换后,检查原主库有哪些更新宕机前未同步到从库,并手动同步来弥补丢失的(已提交)的更新。这里我们探索一下它的使用和实现原理。

使用

1)首先需要将 wal_level这个配置参数设置为logical,并保证max_replication_slots至少为1。

2)创建Logical Replication Slot。Logical Decoding利用了Logical Replication Slot来获取和Decode日志。关于Physical Replication Slot我们在上期中有详细介绍,而Logical Replication Slot与Physical Replication Slot的数据结构类似。创建一个Logical Replication Slot的命令如下:

 
 

注意,创建Logical Replication Slot,需要指定一个输出插件(Output Plugin)。这个插件要提供一些回调函数,用于格式化输出日志。就是说,内核中的Logical Decoding先读取WAL日志,将其Decode成一种半成品式的格式(已包含所有有效信息,比如被更新的表名,更新类型,更新前后的数据记录即Tuple),然后交由输出插件最终呈现给用户。这里我们使用了系统自带的一个插件,即test_decoding。上面的输出中,创建命令返回的xlog_position的值是当前系统中,最后被写入磁盘的日志记录的LSN。此LSN之后的日志,都可以通过Logical Decoding进行解析了。

3)解析日志。

 

pg_logical_slot_peek_changes返回数据中的第二行记录了我们所做的INSERT操作(只有在事务提交后,才能看到这些修改)。而我们通过pg_xlogdump可以看到原来的WAL日志记录为:

 

也就是说,Logical Decoding把这条日志,反解析成一个“table public.test: INSERT: col[integer]:2”字符串。其实如果对输出插件稍作修改,可以直接解析成可执行的SQL语句:“INSERT INTO public.test (col) VALUES(2)“

那么这是如何做到的呢?下面我们看看其中原理。

原理

追踪一下pg_logical_slot_peek_changes的调用链,不难看到Decoding的整个过程。在pg_logical_slot_get_changes_guts中,从restart_lsn(即上次的最后读取后,剩下的事务中最先开始的事务对应的LSN)开始,先用XLogReadRecord函数(注意,会先从cache里面读取日志,如果cache里面没有,则会到磁盘中的日志段里面读取)获取一个日志记录,存入结构体XLogRecord,紧接着用LogicalDecodingProcessRecord做Decode。如此循环,直到读完日志或到达指定点。

LogicalDecodingProcessRecord是解析日志的关键。它在内存中维护一个哈希表(LogicalDecodingContext->reorder->by_txn),存放正在处理的事务信息。在处理每个日志记录时,如果遇到一个BEGIN操作,就在哈希表中插入相应事务。而只有在遇到COMMIT操作的时候,才会把整个事务的所有语句解析出来(调用ReorderBufferCommit)。这个过程中,它要为每个事务维护一个快照(Snapshot)。每次有事务做COMMIT都要更新一下这个快照。这样,等到事务COMMIT时,它的快照是最新的,可以用来访问系统表,得到如relation node id与relation名字之间的对应关系等信息,从而完成Decode。需要说明的是,LogicalDecodingProcessRecord在维护快照时做了优化:因为Decode过程只需要访问系统表,所以快照中只保留了那些更新了系统表的事务。

另外,Replication Slot的xmin信息会影响系统的Vacuum,使其保留仍然需要的数据版本。而SnapBuildProcessRunningXacts会不断更新Replication Slot中的xmin信息,避免使Vacuum停滞。

输出Decode后日志的过程,都在DecodeCommit调用的ReorderBufferCommit函数中。在ReorderBufferCommit中,调用了输出插件的apply_change等回调函数,会将日志信息打印成我们最终看到的字符串,这样就完成了Decode。


目录
相关文章
|
Python
Ubuntu22.04编译安装OpenVINO
Ubuntu22.04编译安装OpenVINO
1777 1
Ubuntu22.04编译安装OpenVINO
|
XML 前端开发 安全
Spring Mvc 拦截器详解
Spring Mvc 拦截器详解
481 0
|
Linux
百度搜索:蓝易云【Linux 修改系统时间的两种方式?】
这些是在Linux系统中修改系统时间的两种常见方式。根据您的需求和权限,选择适合您的方法进行操作。
1115 0
百度搜索:蓝易云【Linux 修改系统时间的两种方式?】
|
存储 人工智能 运维
阿里云联合信通院发布《面向LLM应用的可观测性能力要求》
随着大模型技术的广泛应用,大语言模型(LLM)在对话系统、检索增强生成(RAG)、智能体(Agent)等场景中展现出无限的想象力与创造力。同时,基于 LLM 以及 AI 生态技术栈构建的应用以及业务场景也如雨后春笋般不断涌现。然而,LLM 应用在生产落地过程中面临着模型不确定性大、架构链路复杂、用户体验难以评估等诸多痛点。如何构建 LLM 应用的全链路可观测性体系以及如何评估可观测性能力是否完善,业界缺乏统一且完整细致的标准。
|
8月前
|
存储 NoSQL 安全
如何保存并分析Linux内核转储(coredump)文件
在Linux中,生成coredump需配置系统参数并满足程序条件。通过ulimit或limits.conf设置核心文件大小,修改core_pattern定义存储路径与命名格式,确保程序无信号屏蔽、权限限制,并留足磁盘空间,最后用gdb分析崩溃堆栈,便于调试定位问题。
|
12月前
|
JSON 安全 API
亚马逊支付API:支持国际卡种,开拓跨境用户
亚马逊通过集成支持Visa、Mastercard等国际卡种的支付API,提升跨境交易便捷性。本文详解API调用、卡种识别、实时汇率转换与安全机制,结合代码示例与合规要点,助力开发者高效实现全球化支付,拓展国际市场。
|
存储 缓存 关系型数据库
MariaDB 和 GreatSQL 性能差异背后的真相
【10月更文挑战第22天】本文介绍了 MariaDB 和 GreatSQL 两款数据库系统的背景、性能差异因素及实际应用场景。MariaDB 是 MySQL 的分支,具有良好的社区支持和丰富的插件生态系统;GreatSQL 是国产的 MySQL 兼容数据库,专注于企业级应用场景。文章详细对比了两者的存储引擎优化、查询优化器差异、缓存机制和并发处理能力,并分析了它们在 OLTP 和 OLAP 场景中的性能表现。
873 3
|
JavaScript API
【Vue 3】effectScope 究竟为何物?其运作机制如何?又能为我们化解哪些难题?
【Vue 3】effectScope 究竟为何物?其运作机制如何?又能为我们化解哪些难题?
|
SQL 存储 监控
|
人工智能 测试技术
ChatExcel--自动处理表格
ChatExcel--自动处理表格
1015 1
ChatExcel--自动处理表格