本期介绍openGauss系数据库的几个案例:
- rowid使用案例
- GUC参数非全局设定
- hash分区键限制
astore引擎下的rowid使用问题
Oracle迁移经常会遇到rowid兼容性问题:可能是不支持rowid,也可能是rowid类型或行为有差异。
rowid的常用场景:
- 确保无主键表排序结果稳定性
- 删除表中的重复记录
- 方便DML操作定位行
很多openGauss发行版都支持了rowid功能,最近在项目中遇到一个问题,业务使用JDBC驱动pbe方式执行如下语句:
delete from tab1 where rowid=? ;
执行计划走了Seq Scan,没走预期的Tid Scan
prepare stmt(varchar) as select * from tab1 where rowid=$1;
postgres=# explain execute stmt('nMYAAA==5sAAAA==gAA=');
QUERY PLAN
--------------------------------------------------------------
Seq Scan on tab1 (cost=0.00..230557.40 rows=50000 width=36)
Filter: (rowid = ($1)::rowid)
(2 rows)
如果直接使用静态值,则能走Tid Scan
postgres=# explain delete from tab1 where rowid ='nMYAAA==5sAAAA==gAA=';
QUERY PLAN
----------------------------------------------------------
Delete on tab1 (cost=0.00..4.02 rows=1 width=6)
-> Tid Scan on tab1 (cost=0.00..4.02 rows=1 width=6)
TID Cond: (ctid = '(49382,128)'::tid)
Filter: (tableoid = 50844)
(4 rows)
在服务端打开rowidexpr_tidscan选项后达到预期:
postgres=# explain execute stmt('nMYAAA==5sAAAA==gAA=');
QUERY PLAN
---------------------------------------------------------
Tid Scan on tab1 (cost=0.01..4.02 rows=50000 width=36)
TID Cond: (rowid = ($1)::rowid)
(2 rows)
JDBC使用pbe方式如果没开那个选项,PBE方式会走全表扫。
GUC参数非全局设定
哪些GUC参数能使用set进行局部配置,而非cluster全局范围生效呢?
可以使用SET在user、database进行设置,有三种设置形态:
alter user set ... alter database set ... alter user in database set ...
但数据库里并非所有的参数都能使用set在session范围进行设置,否则可能会遇到
- xxx cannot be changed now
- xxx cannot be set after connection start
这类错误提示,而当前数据库内核哪些参数可以设置,我们可以使用如下代码提前了解:
DO LANGUAGE plpgsql $do$
declare
v_rec record;
v_sql varchar;
begin
for v_rec in select * from pg_settings where context not in('internal','postmaster') loop
begin
v_sql = 'alter database postgres set '||v_rec.name||'='||quote_literal(v_rec.setting)||';';
execute v_sql;
raise notice '%',v_rec.name;
exception
when others then
--raise notice 'state=%,error=%',SQLSTATE,SQLERRM;
end;
end loop;
end;
$do$;
分布式场景hash分区键问题
openGauss系分布式扩缩容时遇到一个问题,分析定位与分区表hash分区键类型有关。
- 分区表使用普通的create table方式,hash分区支持分区键支持浮点数类型或时间类型
- 分区表使用create table including方式,hash分区分区键只支持整型
测试语句如下:
- 普通的create table方式可以成功
create table test1 (
id integer not null,
wid decimal(4,4)
) DISTRIBUTE BY HASH(id)
PARTITION BY HASH(wid)(
PARTITION p1,
PARTITION p2,
PARTITION p3
);
create table test2 (
id integer not null,
since timestamp
) DISTRIBUTE BY HASH(id)
PARTITION BY HASH(since)(
PARTITION p1,
PARTITION p2,
PARTITION p3
);
test1表的hash分区键为浮点类型,test2表的hash分区键为时间类型。
- create table including方式失败
CREATE TABLE tmp1(LIKE test1 INCLUDING DISTRIBUTION INCLUDING PARTITION);
CREATE TABLE tmp2(LIKE test2 INCLUDING DISTRIBUTION INCLUDING PARTITION);
复制test1表分区键类型为浮点型时,tmp1表创建失败,报错:
ERROR: numeric field overflow
复制test2表分区键类型为时间类型时,tmp2表创建失败,报错:
ERROR: invalid input syntax for type timestamp: "2"
本文结束~
往期回顾
- 数据库微观案例第53期
- 数据库微观案例第52期
- 数据库微观案例第51期
- 数据库微观案例第50期
- 数据库微观案例第49期
- 数据库微观案例第48期
- 数据库微观案例第47期
- 数据库微观案例第46期
- 数据库微观案例第45期
- 数据库微观案例第44期
- 数据库微观案例第43期
- 数据库微观案例第42期
- 数据库微观案例第41期 |NULL值案例
- 数据库微观案例第40期
- PostgreSQL智慧碎片|微观案例 |宏观收获
- PostgreSQL小案例集|4月刊
与我联系
- 微信公众号:象楚之行
- 墨天轮:https://www.modb.pro/u/15675
- 微信:skypkmoon
勤耕细作,用心积微;静待花开,量变质成。
最后修改时间:2024-12-27 15:45:06
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




