功能描述
在openGauss中如果实现数据复制呢?
- 可以通过数据迁移工具定期向目标数据库进行数据库的同步,说的定期,这就意味着这种方式不能满足数据实时复制的需求。
- 在openGauss中为我们提供了
逻辑解码
功能,工作原理就是反解xlog,从而生成逻辑日志,在目标数据库中通过对逻辑进行解析来实现数据的实时复制能力。由于目标数据库对逻辑日志进行解析生成的SQL语句,都是标准SQL,因此逻辑复制大大降低了对目标数据库的形态限制,故支持异构数据库、同构异形数据库对数据的同步,同时也是支持在目标数据库对数据同步期间的可读可写操作,降低了数据同步到时延。
通过上面的图,我们可以清楚的看到逻辑复制是由两部分组成:
- 逻辑解码
- 数据复制
逻辑解码部分会产生逻辑日志,逻辑日志是以事务为单位进行组织的。我们可以在自己的业务对逻辑日志进行组成SQL语句,从而实现数据复制到目的,数据库中间件即为此原理。
思考一下
我们如何自己实现一个openGauss数据同步到中间件呢?如果你有想法来评论区交流交流吧!
要是实现逻辑复制,逻辑解码是必须可少的,因为逻辑解码提供了事务解码的基础能力,在openGauss中要实现逻辑解码很是简单,我们可以通过SQL函数接口就能做到,是不是简单到超乎你的想象,这种方式使用起来不需要额外的工具,简单易用好上手,也能非常方便的对接外部工具。
因为逻辑日志的基本单位是事务,所以只有当事务提交后才会有输出,并且这个过程是用户自行驱动的;在openGauss高斯中为了阻塞xlog的回收,使用了逻辑复制槽,这样中的目的是:
- 防止事务开始时的xlog被系统回收;
- 防止所需要的事务信息被VACUUM回收。
什么是VACUUM?
在页面级别、表级别和数据库级别的整体清理,这个机制称之为VACUUM操作。
上面说到了一个概念“逻辑复制槽”,那么这个是什么呢?
说白了逻辑复制槽就是一个更改流,相关的更改能在其他数据库中以它们的原数据库中产生的顺序被重放,逻辑复制槽由每个逻辑日志的获取者维护一个。
注意事项
这部分内容来自官方
- 不支持DDL语句解码,在执行特定的DDL语句(例如普通表truncate或分区表exchange)时,可能造成解码数据丢失。
- 不支持列存、数据页复制的解码。
- 不支持级联备机进行逻辑解码。
- 当执行DDL语句(如alter table)后,该DDL语句前尚未解码的物理日志可能会丢失。
- 单条元组大小不超过1GB,考虑解码结果可能大于插入数据,因此建议单条元组大小不超过500MB。
- openGauss支持解码的数据类型为:INTEGER、BIGINT、SMALLINT、TINYINT、SERIAL、SMALLSERIAL、BIGSERIAL、FLOAT、DOUBLE PRECISION、DATE、TIME[WITHOUT TIME ZONE]、TIMESTAMP[WITHOUT TIME ZONE]、CHAR(n)、VARCHAR(n)、TEXT。
- 如果需要ssl连接需要保证前置设置GUC参数ssl=on。
- 逻辑复制槽名称必须小于64个字符,且只包含小写字母、数字或者下划线中的一种或几种。
- 当前逻辑复制不支持MOT特性。
- 当逻辑复制槽所在数据库被删除后,这些复制槽变为不可用状态,需要用户手动删除。
- 仅支持utf-8字符集。
- 对多库的解码需要分别在库内创建流复制槽并开始解码,每个库的解码都需要单独扫一遍日志。
- 不支持强起,强起后需要重新全量导出数据。
- 备机解码时,switchover和failover时可能出现解码数据变多,需用户手动过滤。Qurem协议下,switchover和failover选择升主的备机,需要与当前主机日志同步。
- 不允许主备,多个备机同时使用同一个复制槽解码,否则会产生数据不一致。
- 只支持主机创建删除复制槽。
- 数据库故障重启或逻辑复制进程重启后,解码数据存在重复,用户需自己过滤。
- 计算机内核故障后,解码存在乱码,需手动或自动过滤。
- 当前备机逻辑解码,不支持开启极致RTO。
- 请确保在创建逻辑复制槽过程中长事务未启动,启动长事务会阻塞逻辑复制槽的创建。
- 不支持interval partition表复制。
- 不支持全局临时表。
- 在事务中执行DDL语句后,该DDL语句与之后的语句不会被解码。
- 如需进行备机解码,需在对应主机上设置guc参数enable_slot_log = on。
- 禁止在使用逻辑复制槽时在其他节点对该复制槽进行操作,删除复制槽进行的操作需在该复制槽停止解码后执行。
- 在开启逻辑复制的场景下,如需创建包含系统列的主键索引,必须将该表的REPLICA IDENTITY属性设置为FULL或是使用USING INDEX指定不包含系统列的、唯一的、非局部的、不可延迟的、仅包括标记为NOT NULL的列的索引。
好了,到这次讲了这么多,那么我们该如何使用呢?
不着急,让眼睛休息一下,我们继续往下看…
使用SQL函数接口进行逻辑解码
修改配置
wal_level=logica
max_replication_slots=8
操作步骤
- 以
omm
用户登录openGauss数据库的主节点 - 采用
gsql
命令登录
gsql -d postgres -p 9999 -r
上面的9999
端口修改你的实际端口号
- 创建逻辑复制槽
openGauss=# SELECT * FROM pg_create_logical_replication_slot('test-slot', 'mppdb_decoding');
slotname | xlog_position
----------+---------------
test-slot | 0/601C150
(1 row)
test-slot
就是槽名称,当前你可以根据你自己的规则命令,我这里仅仅是做演示。
- 创建数据表并插入数据
-- 创建test表
CREATE TABLE test(a int PRIMARY KEY, b int);
-- 插入数据
INSERT INTO test VALUES(1024,512);
- 读取
test-slot
槽解码结果
SELECT * FROM pg_logical_slot_peek_changes('slot1', NULL, 4096);
location | xid | data
-----------+-------+------------------------------------------------------------------
--------------------------------------------------------------------------------------
------------------------------------
0/601C188 | 1010023 | BEGIN 1010023
0/601ED60 | 1010023 | COMMIT 1010023 CSN 1010022
0/601ED60 | 1010024 | BEGIN 1010024
0/601ED60 | 1010024 | {"table_name":"public.test","op_type":"INSERT","columns_name":["a","b"],"columns_type":["integer",
"integer"],"columns_val":["1024","512"],"old_keys_name":[],"old_keys_type":[],"old_keys_val":[]}
0/601EED8 | 1010024 | COMMIT 1010024 CSN 1010023
(5 rows)
- 通过下面的方式删除复制槽
test-slot
SELECT * FROM pg_drop_replication_slot('test-slot');
pg_drop_replication_slot
--------------------------
(1 row)
标签:slot,逻辑,数据库,复制,SQL,test,openGauss,解码
From: https://blog.csdn.net/u010490822/article/details/141196347