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

PostgreSQL问答-第20221126期

原创 多米爸比 2022-11-26
728

本期的几个问答如下:

  • 备份被卡住的原因
  • 为什么pg_is_in_backup()函数消失了
  • 通俗理解backend_xid和backend_xmin
  • 多行查询优雅的使用COPY
  • 非UTF-8编码的数据库生成随机汉字示例
  • pg_surgery插件的用途

Q1. 使用pg_basebackup工具或者调用pg_start_backup函数时,好像被卡住,这是什么原因?

问题描述

使用pg_basebackup工具进行基础备份或者调用pg_start_backup备份开始函数后,好像立刻被阻塞住了。或者是说为什么基础备份需要执行的checkpoint较慢,而手工在数据库发起checkpoint能很快执行完成。

问题解答

因为基础备份需要伴随一次checkpoint操作,默认的spread模式会等待定期的checkpoint调度完成,这可能会需要较长的时间(受checkpoint_completion_target以及max_wal_size配置的影响),好处是减少checkpoint带来的大量刷脏,从而减少抖动。
坏处是checkpoint操作被拉长。当我们想要快速完成备份,则可以使用fast模式立即执行checkpoint,全速刷脏。好处是快,坏处是如果脏页特别多,可能会有大量IO影响其他会话性能。

pg_basebackup可以使用"–checkpoint=fast",pg_start_backup函数可以使用fast=true来快速完成尽快完成checkpoint操作。

还有一个相关问题是当我们打开了归档archive_mode=on,但归档命令没有配置正确,例如archive_command配置为空,则调用备份结束函数会一直提示如下告警信息:

NOTICE:  base backup done, waiting for required WAL segments to be archived
WARNING:  still waiting for all required WAL segments to be archived (60 seconds elapsed)
HINT:  Check that your archive_command is executing properly.  You can safely cancel this backup, but the database backup will not be usable without all the WAL segments.
...

将archive_command配置正确或关闭归档即可,下面是归档配置正确后正常的输出。

image.png

不过即使archive_mode设置为on,归档命令没有配置正确,我们也可以在备份结束函数里设置wait_for_archive为false来完成备份,测试截图如下:

image.png

Q2. repmgr执行switchover时为什么提示pg_is_in_backup()函数不存在?

问题描述

使用repmgr 5.3.1对PG 15执行switchover时提示pg_is_in_backup()函数不存在,错误截图如下:

image.png

问题解答

从PG 15开始,与排他性备份模式相关的pg_is_in_backup()函数已经被废弃删除了。我们查看repmgr对PG的版本支持情况可以看到repmgr 5.3.3开始支持PG 15。

image.png

Q3. pg_stat_activity视图backend_xid和backend_xmin有啥区别?

问题描述

pg_stat_activity视图的backend_xid和backend_xmin官方文档的解释看不明白,如何用大白话解释。

问题解答

从名称的差异来体会:

  • backend_xid表示是当前获取到的事务ID,只有查询语句实际对数据库有修改操作时事务管理器才分配生成。
  • backend_xmin与事务快照相关,借助事务快照,PG可以确定元组可见性,生产环境应主要关注backend_xmin。

事务快照形式:

xmin:xmax:xip_list

  • xmin: “visible since”,活动事务的最旧事务ID。
  • xmax: “visible until”,活动事务的最新事务ID。
  • xip_list: 所有活动事务ID列表。

Q4. 多行查询如何在COPY中优雅的使用

问题描述

使用元命令\copy处理较长的复杂查询语句生成的结果集时,要么我们借助临时表,要么我们需要对多行语句进行编辑,调整到一行,这件事非常头疼的!

问题解答

其实我们还有这种方式:

postgres=# copy (
               select *
               from foo
               where id<300
           ) to stdout with csv header \g foo.csv
COPY 5
  • 虽然\copy不支持多行查询,但copy支持。
  • copy结果除了输出到文件也可输出到标准输出stdout
  • 使用\g将标准输出的内容写入到本地文件

结合这三点,可以优雅的处理多行查询。

Q5. 非UTF-8编码的数据库如何生成随机汉字?

问题描述

在UTF-8编码的数据库里可以使用chr函数基于unicode码来随机生成汉字:

postgres=# select chr(int4(random()*20901)+19968);
 chr 
-----
 盾
(1 row)

而非UTF-8编码的数据库则不能使用chr函数。

问题解答

例如在euc_cn编码的环境下我可以根据GBK的区位码规则封装如下函数来生成随机汉字:

create or replace function chr_euc_cn()
returns text
as $function$
declare
    hight_pos text;
    low_pos text;	
begin
    hight_pos = to_hex((176+random()*71)::int4);
    low_pos = to_hex((161+random()*93)::int4);
    return convert_from(decode(hight_pos||low_pos, 'hex'), 'euc_cn');
end;
$function$ language plpgsql;

测试结果如下:

db_chinese=# select chr_euc_cn();
 chr_euc_cn 
------------
 茏
(1 row)

db_chinese=# select chr_euc_cn();
 chr_euc_cn 
------------
 括
(1 row)

Q6. PG 14的pg_surgery插件有什么用途?

有客户想了解PG 14有什么新增的扩展插件,有什么用途。查看了一下官方文档及资料,先总结了一张最新的各版本新增插件图。

image.png

关注到pg_surgery可以与pg_dirtyread很好的搭配起来恢复delete的数据。

下面是参考示例:

image.png

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

评论