暂无图片
暂无图片
2
暂无图片
暂无图片
暂无图片

数据库微观案例第44期

原创 彭冲 2024-07-02
401

本期内容如下:

  • 函数的自增序号
  • 版本兼容性案例
  • 备库catchup快速追主

一、函数的自增序号

FROM子句后的函数使用with ordinality后缀修饰时,函数的每行输出将追加一列类型为bigint的自增序号。

例如常见unnest函数将数组展开为表:

postgres=# SELECT * FROM unnest(array(values('one'), ('two'))) WITH ORDINALITY AS t(f1,f2); f1 | f2 -----+---- one | 1 two | 2 (2 rows)
复制

不使用with ordinality,需要额外生成行号语句会复杂些

SELECT unnest(array(values('one'), ('two'))) AS f1, generate_series(1, array_length(array(values('one'), ('two')), 1)) AS f2;
复制

批量生成测试数据的generate_series函数也很合适使用with ordinality

postgres=# SELECT f2,f1 FROM generate_series(2_00, 1_00,-50) WITH ORDINALITY AS t(f1,f2); f2 | f1 ----+----- 1 | 200 2 | 150 3 | 100 (3 rows)
复制

另外,对于xml和json类型的函数也能使用for ordinality

SELECT * FROM json_table( '[{"a":10,"b":20},{"a":30,"b":40}]'::jsonb, '$[*]' COLUMNS ( id FOR ORDINALITY, column_a int4 path '$.a', column_b int4 path '$.b', a int4, b int4, c text ) );
复制

二、两个有趣的版本兼容性案例

  • 版本9.6到10使用insert语句与generate_series函数生成数据不一致问题
INSERT INTO test VALUES ( generate_series(1, 10) ,generate_series(1, 3) );
复制

上面的插入语句里两个generate_series函数返回行数不一致,且一个行数不是另外一个的倍数时,在9.6和10分别有不一样的行为,测试截图如下:

image.png

第一条语句,即便返回行数不一致,只要其中一个是另一个的倍数,版本行为是一致的,插入的数据条数是第一个函数返回的行数10,第二个函数返回的行数2,能整除,值不断重复生成如下:

image.png

这是9.6版本的行为,而10版本插入的行数虽然是一致,但第二个函数只产生2行数据不会重复,其他数据库行的第二列值为NULL。

第二条语句,两个函数返回行数不一致,且10不能整除3,低版本9.6产生笛卡尔积,10版本以上,第二个函数同样不会重复生成数据:

image.png

大家可以实测一下

  • 版本11到12浮点数精度显示不一致问题

之前第37期案例分享过这个问题,表结构如下:

create table t1(a varchar);
复制

Java使用double类型插入数据主要代码如下:

String sql = "insert into t1 values(?)"; PreparedStatement ps = connection.prepareStatement(sql); ps.setObject(1, new Double(48)); ps.execute(); ps.setObject(1, new Double(48.1)); ps.execute(); ps.setObject(1, new Double(48.9)); ps.execute();
复制

JDBC驱动层发送到服务端时会隐含设置extra_float_digits = 3,此时版本11和12入库的结果会有差异。

image.png

从12版本开始,浮点数输出显示的精度做了优化,extra_float_digits参数描述也说明了这一点,使用shortest-precise模式。

三、主备节点间的catchup功能

微信群友提到备份工具pg_probackup的catchup的功能,之前没注意到,后来了解到是2.5.2版本新增的功能,主要有两个场景:

  • 快速添加新的standby节点
  • 让落后的standby快速追赶主库

例如使用catchup命令快速搭建standby节点:

$ pg_probackup catchup --backup-mode=full \ --source-pgdata=/home/postgres/data_master \ --destination-pgdata=/home/postgres/data_standby3000 \ --pguser=backup --pgdatabase=postgres --pgport=2000 \ --remote-host=192.168.20.100 \ --remote-port=22 \ --remote-user=postgres \ --stream --threads=4
复制

使用catchup命令增量追赶主库

$ pg_probackup catchup --backup-mode=delta \ --source-pgdata=/home/postgres/data_master \ --destination-pgdata=/home/postgres/data_standby3000 \ --pguser=backup --pgdatabase=postgres --pgport=2000 \ --remote-host=192.168.20.100 \ --remote-port=22 \ --remote-user=postgres \ --exclude-path=postgresql.conf \ --stream --threads=4
复制

同时保留postgresql.conf配置文件,不同步。

其他配置文件不需要同步也可以继续添加,例如:

--exclude-path=postgresql.auto.conf \
--exclude-path=pg_hba.conf \
--exclude-path=pg_ident.conf \
复制

注意增量追赶主库,需要先停standby节点的服务,才能操作。

推荐阅读

与我联系

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

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

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论