PgSQL · 特性分析· Logical Decoding探索

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。

时间: 2024-12-06 12:48:00

PgSQL · 特性分析· Logical Decoding探索的相关文章

PgSQL · 特性分析 · checkpoint机制浅析

背景 上期月报PgSQL · 特性分析 · Write-Ahead Logging机制浅析中简单介绍了PostgreSQL中WAL机制,其中讲到如果是创建checkpoint会触发刷新xlog日志页到磁盘,本文主要分析下PostgreSQL中checkpoint机制. checkpoint又名检查点,一般checkpoint会将某个时间点之前的脏数据全部刷新到磁盘,以实现数据的一致性与完整性.目前各个流行的关系型数据库都具备checkpoint功能,其主要目的是为了缩短崩溃恢复时间,以Oracl

PgSQL · 特性分析 · 数据库崩溃恢复(上)

背景 为了合并I/O提高性能,PostgreSQL数据库引入了共享缓冲区,当数据库非正常关闭,比如服务器断电时,共享缓冲区即内存中的数据就会丢失,这个时候数据库操作系统重启时就需要从非正常状态中恢复过来,继续提供服务.本文将具体分析在这种情况下,PostgreSQL数据库如何从崩溃状态中恢复. 上期月报PgSQL · 特性分析 · checkpoint机制浅析中介绍了PostgreSQL中的checkpoint机制.其中提到,当PostgreSQL数据库崩溃恢复时,会以最近的checkpoint

PgSQL · 特性分析 · 数据库崩溃恢复(下)

背景 在上期月报PgSQL · 特性分析 · 数据库崩溃恢复(上),我们分析了PostgreSQL在数据库非正常退出后(包括通过recovery.conf用户主动恢复)的处理,概括起来分为以下几步: 1.如果满足以下条件之一,则进行非正常退出恢复 pg_control文件中的数据库状态不正常(非DB_SHUTDOWNED) pg_control文件中记录的最新检查点读取不到XLOG日志文件 2.用户指定recovery.conf文件主动恢复3.根据pg_control.backup_label确

PgSQL · 特性分析· JIT 在数据仓库中的应用价值

背景 近几年,分析型数据库中有项技术得到了广泛的应用.它就是 JIT(Just-in-time compilation)动态编译.还有一些相关名词 LLVM codegen 和这项技术相关.本文把这项技术做一个简单的分析,和大家分享. 一.JIT 是什么 长久以来数据仓库都是以高效的处理量数据的能力著称.随着硬件的发展,他们使用大量相关技术充分挖掘硬件的能力提高数据的吞吐量和处理效率.例如 SMP MPP mapreduce 列存储 压缩 等等.这么多年开源生态的活跃,使得我们对这类技术的实现细

PgSQL · 特性分析 · MVCC机制浅析

背景 我们在使用PostgreSQL的时候,可能会碰到表膨胀的问题(关于表膨胀可以参考之前的月报),即表的数据量并不大,但是占用的磁盘空间比较大,查询比较慢.为什么PostgreSQL有可能发生表膨胀呢?这是因为PostgreSQL引入了MVCC机制来保证事务的隔离性,实现数据库的隔离级别. 在数据库中,并发的数据库操作会面临脏读(Dirty Read).不可重复读(Nonrepeatable Read).幻读(Phantom Read)和串行化异常等问题,为了解决这些问题,在标准的SQL规范中

PgSQL · 特性分析 · 备库激活过程分析

前言 PostgreSQL standby 可以通过两种方法来激活成为主库: trigger file,配置在recovery.conf中. pg_ctl promote发送SIGUSR1信号给postmaster进程. 同时,PostgreSQL支持快速激活(fast promote)和非快速激活(fallback promote): fast promote 开启数据库读写前,不需要做检查点.而是推到开启读写之后执行一个CHECKPOINT_FORCE检查点. fallback_promot

PgSQL · 特性分析 · PostgreSQL 9.6 让多核并行起来

背景 经过多年的酝酿(从支持work process到支持动态fork共享内存,再到内核层面支持并行计算),PostgreSQL 的多核并行计算功能终于在2016年发布的9.6版本中正式上线,为PG的scale up能力再次拔高一个台阶,标志着开源数据库已经攻克了并行计算的难题. 相信有很多小伙伴已经开始测试了. 在32物理核的机器上进行了测试,重计算的场景,性能程线性提升. 目前并行计算支持全表扫描,JOIN,聚合. 一.快速安装PostgreSQL 9.6 为了让大伙能够快速用上9.6,以下

PgSQL · 特性分析· jsonb类型解析

PG 9.4版本里面,增强了对json数据的支持,受到了很大关注.9.4之前,PG已经原生支持json数据类型了,但只是用字符串的形式存储和处理.这样做天然有性能上的缺点:每次对json字符串里面的数据进行查询,一般需要全表扫描加字符串匹配,效率很低.当然也可以在存储json的字符串字段上创建GIN索引,但需要对查询中用到的json的key或value创建单独索引,造成要被动维护很多索引.所以,这种json类型,只适用于把PG单纯作为数据存储,只读入读出数据,不对数据进行限定key或value查

PgSQL · 特性分析 · 时间线解析

"时间线"(Timeline)是PG一个很有特色的概念,在备份恢复方面的文档里面时有出现.但针对这个概念的详细解释却很少,也让人不太好理解,我们在此仔细解析一下. 时间线的引入 为了理解引入时间线的背景,我们来分析一下,如果没有时间线,会有什么问题?先举个将数据库恢复到以前时间点的例子.假设在一个数据库的运行过程中,DBA在周三12:00AM删掉了一个关键的表,但是直到周五中午才发现这个问题.这个时候DBA拿出最初的数据库备份,加上存在归档目录的日志文件,将数据库恢复到周三11:00A