本期介绍openGauss系数据库的几个案例:

  1. rowid使用案例
  2. GUC参数非全局设定
  3. 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"

这次的分享就到这里,后续会继续分享~

Logo

鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。

更多推荐