首页 > 数据库 > 数据库开发技术 > MogDB 5.0 增加的8大PG兼容性
欢迎关注公众号, 持续发布PostgreSQL、openGauas/MogDB等PG系数据库干货文章。
MogDB 5.0版本支持alter sequence方式修改序列属性:

openGauss继承于pgxc,分布式的pgxc禁用了游标的SCROLL属性,MogDB 5.0版本在A模式或PG模式,可以对游标指定SCROLL属性,使其可用于倒序方式检索数据行(即反向检索)。

MogDB 5.0版本使用gs_dump -j和gs_restore -j可支持表间任务并行导入导出,参考语法如下:
gs_dump -f /tmp/backupdir -Fd -j 4 postgres
gs_restore -d res_db -Fd -j 4 /tmp/backupdir
单表并行化,例如单个大表(非分区表)导出,可先使用pg_export_snapshot()函数获取事务快照ID,再利用多个客户端在RR事务隔离级别相同的事务快照下进行并行化加速导出。
默认logged属性的表有WAL写保护,不会有数据丢失的风险。不过unlogged属性的表不记录WAL性能更高,不同场景用户可以灵活选择,进行切换使用。
MogDB 5.0版本在PG/A兼容模式下支持在线切换表的logged/unlogged属性,并且同时兼容两种用法:
一、PG风格用法:
CREATE TABLE tab1 (...);
ALTER TABLE tab1 SET UNLOGGED ;
ALTER TABLE tab1 SET LOGGED ;
二、Oracle风格用法:
CREATE TABLE tab1 (...);
ALTER TABLE tab1 LOGGING ;
ALTER TABLE tab1 NOLOGGING ;
WITH语句也是Common table expressions (CTEs),可以把大的复杂查询分解为简小的片段,从而更易阅读和理解,同时使用WITH语句可以“物化”缓存多次重复的计算,降低冗余子查询及函数的副作用。
在PG 12之前WITH语句默认是保持物化的行为,但物化行为也可能会引起执行变慢。PG 12对WITH语句提供了MATERIALIZED/NOT MATERIALIZED的选项,同时默认行为改变为保持不物化。
MogDB 5.0版本保持兼容PG 12的这一行为,并对一些复杂场景,例如子查询内部被引用时,仍可保持不物化行为,使其可以被提升到上层查询,生成更优查询计划,以提升执行性能。
测试示例如下:

upsert相当于insert + update的组合,当数据行insert操作发生主键或唯一约束重复时,可触发update操作或者忽略不报错。
MogDB支持Oracle语法风格的upsert,参考如下:
insert into ... ON DUPLICATE KEY update columnN=excluded.columnN;
MogDB 5.0版本对upsert语法增加了兼容PG风格的形式:
insert into ... ON CONFLICT(XXX) do update set columnN=excluded.columnN;
PG风格的upsert使用场景更加丰富。
示例一:
create table test_upsert (id int primary key,code varchar unique,info varchar);
insert into test_upsert (id,code,info)
values (1,'code1','info');
上面插入一条主键id为1的数据后,再次插入id为1的数据时可使用upsert语句正常执行
insert into test_upsert (id,code,info)
values (1,'code1','info extra1')
on conflict(id)
do update set info=excluded.info,id=excluded.id;
insert into test_upsert (id,code,info)
values (1,'code1','info extra2')
on conflict(id)
do update set info=excluded.info,code=excluded.code;
upsert语句允许在update子句里更新主键id字段亦或唯一约束code字段。
示例二:
create table test_upsert2 (
id int primary key,
code1 varchar not null,
code2 varchar not null,
info varchar,
unique(code1,code2)
);
insert into test_upsert2 (id,code1,code2,info) values (1,'openGauss','MogDB','info');
test_upsert2表里使用了多字段唯一索引,下面upsert语句可以指定冲突的条件是unique(code1,code2),而非主键id,同时在update子句也可对主键id或组合唯一索引的部分字段code1进行操作
insert into test_upsert2 (id,code1,code2,info)
values (1,'openGauss','MogDB','db extra1')
on conflict(code1,code2)
do update set info=excluded.info,
id=excluded.id,
code1=excluded.code1;
逻辑复制场景使用双向订阅发布会存在循环复制的问题,因为数据库内核可能无法区分数据变化是由用户的SQL语句或replication流复制引起。
PG 16解决了这个问题,在创建订阅时可设置发布端不发布replication复制源,从而避免陷入复制循环。参考语法如下:
B端:
create subscription... publication... with(origin='none');
A端:
create subscription... publication... with(origin='none',copy_data=false);
MogDB 5.0版本也支持双向发布,参考实验如下:
从A端发布数据到B端,A端先创建表结构及发布
create table public.tab1(id int primary key,info varchar);
create publication mypub_in_1610 for table public.tab1;
B端创建表结构及订阅
create table public.tab1(id int primary key,info varchar);
create subscription mysub_in_1620
connection 'host=127.0.0.1 port=1611 user=repuser password=XXX dbname=postgres' publication mypub_in_1610 ;
注意上面的端口需要使用“加1端口”1611(1610+1),使用1610主端口会出现如下错误:
WARNING: apply worker could not connect to the remote server
ERROR: Failed to connect to publisher.
再反向从B端发布数据到A端:
B端创建发布
create publication mypub_in_1620 for table public.tab1;
A端创建订阅
create subscription mysub_in_1610
connection 'host=127.0.0.1 port=1621 user=repuser password=XXX dbname=postgres' publication mypub_in_1620 ;
同样需要注意端口需要使用“加1端口”1621(1620+1)。
配置完双向订阅与发布后,再进行数据操作。
MogDB 5.0版本也提供了MogDB JDBC驱动,下载地址如下:
https://www.mogdb.io/downloads/jdbc/all
相比原生驱动,也增加了一些兼容及增强特性,简单列举几点:
增加statement级别SQL读写分离路由功能
支持cleanupSavepoints参数,与savepoint参数搭配防止内存溢出
支持连接串使用options设置guc参数
增大绑定变量上限,由32767到65535
大家需要详细了解哪个特性,欢迎留言评论,文章如有描述错误也请大家指正。
原文作者:象楚之行;如有侵权,请联系管理员删除。