数据库微观案例第53期

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

  • SQLLDR像素级模仿
  • 全表查询结果集溢出
  • timestamp类型B模式带时区
  • update并发更新死锁推演图

SQLLDR像素级模仿

openGauss提供了gs_loader命令行工具,用于将外部数据文件快速加载到数据库表中‌。商业发行版MogDB对gs_loader进一步增强,几乎达到SQLLDR像素级模仿的用法。

image.png

参考链接:DarkAthena https://www.modb.pro/db/1847308456702861312

gs_loader使用示例如下:

1.使用管理员用户创建新的用户

CREATE USER load_user WITH PASSWORD '************';

2.将public schema权限赋给新的用户

GRANT ALL ON SCHEMA public TO load_user;

3.创建新用户并授权

新用户授权gs_copy_summary执行结果汇总表和pgxc_copy_error_log错误表

gs_copy_summary表记录COPY执行结果汇总,包括成功行数,出错行数,忽略行数,空行数。

SELECT copy_summary_create() WHERE NOT EXISTS(SELECT * FROM pg_tables WHERE schemaname='public' AND tablename='gs_copy_summary');

GRANT INSERT,SELECT ON  public.gs_copy_summary To load_user;
SELECT copy_error_log_create() WHERE NOT EXISTS(SELECT * FROM pg_tables WHERE schemaname='public' AND tablename='pgxc_copy_error_log');

GRANT INSERT,SELECT,DELETE ON  public.pgxc_copy_error_log To load_user;

4.切换到普通用户load_user,并创建业务表

\c - load_user

创建业务表loader_tbl

CREATE TABLE  loader_tbl
(
    ID   NUMBER,
    NAME VARCHAR2(20),
    CON  VARCHAR2(20),
    DT   DATE
);

5.创建gs_loader所需的控制文件loader.ctl

在gs_loader客户端机器上创建控制文件loader.ctl

LOAD DATA
truncate into table loader_tbl
fields terminated by ','
trailing nullcols
(
    id integer external,
    name char(32),
    con ":id || '-' || :name",
    dt date
)

6.模拟数据文件data.csv

在gs_loader客户端机器上创建数据文件data.csv

1,OK,,2007-07-8
2,OK,,2008-07-8
3,OK,,2009-07-8
4,OK,,2007-07-8
43,DISCARD,,2007-07-8
,,,
32,DISCARD,,2007-07-8
a,ERROR int,,2007-07-8
8,ERROR date,,2007-37-8
,,,,
 ,
8,ERROR fields,,2007-37-8
,,,
5,OK,,2021-07-30

7.执行gs_loader导入

gs_loader control=loader.ctl data=data.csv log=loader.log bad=loader.bad discard=loader.discard create=false clean=true errors=5 host=127.0.0.1  port=5090 db=postgres passwd=**** user=admin

执行结果:

gs_loader: version 0.1

 6 Rows successfully loaded. 

log file is: 
 loader.log

查看错误记录

 cat loader.bad 

 a,ERROR int,,2007-07-8
 8,ERROR date,,2007-37-8
  ,
 8,ERROR fields,,2007-37-8

全表查询结果集溢出

业务查询这个大表时,字段有50多个,记录有三千多万

select * from tab;

执行时提示如下错误:

Error: Integer overflow when select execution.

其原因是表的行列结果集超过了4字节Int的最大值,从openGauss 5.0开始,内核加了这个硬限制。

src/bin/psql/print.cpp

    if (res >= (int64)PG_INT32_MAX) {
        fprintf(stderr, _("Error: Integer overflow when select execution.\n"));
        exit(EXIT_FAILURE);
    }

B模式timestamp类型带时区信息

在PG系里,timestamp类型不带时区信息,timestamptz带时区信息

postgres=# create table t(a timestamp,b timestamptz);
CREATE TABLE
postgres=# \d t
                 Table "public.t"
 Column |            Type             | Modifiers 
--------+-----------------------------+-----------
 a      | timestamp without time zone | 
 b      | timestamp with time zone    | 

但openGauss系B模式下timestamp类型解析为带时区信息的timestamp(0) with time zone

db_mysql=# create table t1(a timestamp);
CREATE TABLE
db_mysql=# \d t1
                Table "public.t1"
 Column |            Type             | Modifiers 
--------+-----------------------------+-----------
 a      | timestamp(0) with time zone | 

从MySQL迁移过来的业务如果不希望带时区信息时,应该明确使用timestamp without time zone类型,而不要使用timestamp别名类型。

update并发更新死锁推演图

客户端并发更新同一张表的多行数据时,数据库会自动检测到死锁,出错信息参考如下:

ERROR:  deadlock detected
DETAIL:  Process 3001767 waits for ShareLock on transaction 103443111; blocked by process 2983755.
Process 2983755 waits for ShareLock on transaction 103443178; blocked by process 3001767.
HINT:  See server log for query details.
CONTEXT:  while rechecking updated tuple (10,163) in relation "test"

表结构和测试语句如下:

create table test(id int,create_timestamp timestamp);
insert into test select n,now() from generate_series(1,10) n;

打开两个客户端会话执行下面的匿名块即可复现出死锁问题。

do
$do$
BEGIN
   FOR i IN 1..100000 LOOP
      UPDATE test
      SET create_timestamp = clock_timestamp()
      WHERE id>=2;
      COMMIT;
   END LOOP;
END;
$do$ language plpgsql;

内核同事传成大佬(walminer作者:https://gitee.com/movead/XLogMiner)整理出如下的推演图,分享如下:

image.png

image.png

image.png

image.png

根因:在事务隔离级别RC下,事务更新行时,如果此行被其他事务更新,需要重新读取新的版本再重试一次,而范围更新的场景下,tuple新版本大概率会在其它页面上,更容易形成ABBA锁的条件,出现死锁。

本文结束~

往期回顾

与我联系

  • 微信公众号:象楚之行
  • 墨天轮:https://www.modb.pro/u/15675
  • 微信:skypkmoon

勤耕细作,用心积微;静待花开,量变质成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值