PostgreSQL PG15 新功能 PG_WALINSPECT

news/2024/7/9 22:24:08 标签: postgresql, 数据库

fbb4f2c43b72e42dcdeed89ec4672b02.png

开头还是介绍一下群,如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis ,Oracle ,Oceanbase 等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。加群请加微信号 liuaustin3 (共1250人左右 1 + 2 + 3 +4)新人会进入3群(即将关闭自由申请)  默认会进入4群 

每天感悟

公平很多人一辈子追求,期望,奢望,可惜了,公平只存在于公众可以看到的地方,然而实际上你生活的世界和非洲大草原上的生存的原理本质是相同的。

PostgreSQL 在PG15 版本之前如果想了解wal 日志中的信息,只能使用上期提到的工具去查看,但从PG15这个版本,查看 wal 日志的内容的方式变化了可以在数据库内部进行查看。作者名为 Bharath Rupireddy

pg_walinspect 这个模块提供了SQL 方面的函数允许你可以探究 write-ahead log 里面的内容,在一个正在运行的PostgreSQL数据库中,实际上功能和我们熟知的pg_waldump功能是类似的,但是在数据内部运行比一个外部的命令给DB人员的在一些情况下,可操作性性要更高。

CREATE EXTENSION pg_walinspect;

这里pg_walinspect函数在PG16 有增强,添加了如下的函数

function pg_get_wal_block_info() added (commit c31cf1c0, initially as pg_get_wal_fpi_info() but renamed and expanded in commit 9ecb134a)
functions pg_get_wal_records_info(), pg_get_wal_stats() and pg_get_wal_block_info() accept an LSN value higher than the current LSN (commit 5c1b6628)
functions pg_get_wal_records_info_till_end_of_wal() and pg_get_wal_stats_till_end_of_wal() removed (commit 5c1b6628)

我们通过下面的实验来快速了解pg_walinspect的工作,

postgres=# select now(),pg_current_wal_lsn();
elect now(),pg_current_wal_lsn();
             now              | pg_current_wal_lsn 
------------------------------+--------------------
 2023-08-11 08:08:16.79274-04 | 0/4552810
(1 row)

postgres=# 
postgres=# 
postgres=# create database test;
CREATE DATABASE
postgres=# create table  test (id int primary key, name varchar(200));
CREATE TABLE
postgres=# insert into test (id,name) values (1,'Austin');
INSERT 0 1
postgres=# insert into test (id,name) values (2,'Simon');
INSERT 0 1
postgres=# 
postgres=# 
postgres=# create index idx_test on test (name);
CREATE INDEX
postgres=# 
postgres=# select now(),pg_current_wal_lsn();
              now              | pg_current_wal_lsn 
-------------------------------+--------------------
 2023-08-11 08:08:16.896122-04 | 0/498AE38
(1 row)

这里我们在操作前获得事务的LSN号,同时在任务结束后,获得结束后的事务号,方便后面我们演示。

首先我们先用第一个函数 pg_get_wal_records() 通过这个函数可以查看系统中的一段日志的内容

c1617f80c7883ab97e08043169d8d721.png

postgres=# select count(*) from pg_get_wal_records_info('0/4552810', '0/498AE38');
 count 
-------
  1318
(1 row)

这一段产生1318 个记录。

9bff01b12d4f2e60a43ae7f257cdaa30.png

postgres=# select count(*) 
postgres-# from pg_get_wal_records_info('0/4552810', '0/498AE38') where record_type <> 'FPI';
-[ RECORD 1 ]
count | 394

而我们排除了FPI 的日志信息后,我们剩下的日志信息只有394 ,实际上其他的日志信息只占整体日志信息的29%,

通过这样的方法可以PG_WAL中的日志大部分信息是不是 FULL PAGE 

97307fd800e467a8dd75bbdbadec7273.png

实际上在这段f8f8cec4d4044dd15768da467169bbcf.png

实际上在这段里面日志里面我们根据resource_manager 来区分记录的类型,这里主要有 storage , database , btree ,heap , Transaction , heap2, Relmap, Standby , xlog 等,同时记录的类型,有以下集中

postgres=# select distinct record_type from pg_get_wal_records_info('0/4552810', '0/498AE38');
-[ RECORD 1 ]---------------
record_type | INSERT
-[ RECORD 2 ]---------------
record_type | NEWROOT
-[ RECORD 3 ]---------------
record_type | CREATE_WAL_LOG
-[ RECORD 4 ]---------------
record_type | MULTI_INSERT
-[ RECORD 5 ]---------------
record_type | INPLACE
-[ RECORD 6 ]---------------
record_type | UPDATE
-[ RECORD 7 ]---------------
record_type | FPI
-[ RECORD 8 ]---------------
record_type | LOCK
-[ RECORD 9 ]---------------
record_type | CREATE
-[ RECORD 10 ]--------------
record_type | RUNNING_XACTS
-[ RECORD 11 ]--------------
record_type | COMMIT
-[ RECORD 12 ]--------------
record_type | INSERT+INIT
-[ RECORD 13 ]--------------
record_type | INSERT_LEAF
postgres=# SELECT * FROM pg_get_wal_stats('0/4552810', '0/498AE38');
-[ RECORD 1 ]----------------+----------------------
resource_manager/record_type | XLOG
count                        | 924
count_percentage             | 70.10622154779969
record_size                  | 45276
record_size_percentage       | 67.49552772808586
fpi_size                     | 4216068
fpi_size_percentage          | 97.18706086725605
combined_size                | 4261344
combined_size_percentage     | 96.73493181657214
-[ RECORD 2 ]----------------+----------------------
resource_manager/record_type | Transaction
count                        | 5
count_percentage             | 0.37936267071320184
record_size                  | 1085
record_size_percentage       | 1.6174716756112104
fpi_size                     | 0
fpi_size_percentage          | 0
combined_size                | 1085
combined_size_percentage     | 0.02463011693516899
-[ RECORD 3 ]----------------+----------------------
resource_manager/record_type | Storage
count                        | 299
count_percentage             | 22.685887708649467
record_size                  | 12558
record_size_percentage       | 18.72093023255814
fpi_size                     | 0
fpi_size_percentage          | 0
combined_size                | 12558
combined_size_percentage     | 0.2850737405270527
-[ RECORD 4 ]----------------+----------------------
resource_manager/record_type | CLOG
count                        | 0
count_percentage             | 0
record_size                  | 0
record_size_percentage       | 0
fpi_size                     | 0
fpi_size_percentage          | 0
combined_size                | 0
combined_size_percentage     | 0
-[ RECORD 5 ]----------------+----------------------
resource_manager/record_type | Database
count                        | 1
count_percentage             | 0.07587253414264036
record_size                  | 34
record_size_percentage       | 0.05068574836016696
fpi_size                     | 0
fpi_size_percentage          | 0
combined_size                | 34
combined_size_percentage     | 0.0007718193325306412
-[ RECORD 6 ]----------------+----------------------
resource_manager/record_type | Tablespace
count                        | 0
count_percentage             | 0
record_size                  | 0
record_size_percentage       | 0
fpi_size                     | 0
fpi_size_percentage          | 0
combined_size                | 0
combined_size_percentage     | 0
-[ RECORD 7 ]----------------+----------------------
resource_manager/record_type | MultiXact
count                        | 0
count_percentage             | 0
record_size                  | 0
record_size_percentage       | 0
fpi_size                     | 0
fpi_size_percentage          | 0
combined_size                | 0
combined_size_percentage     | 0
-[ RECORD 8 ]----------------+----------------------
resource_manager/record_type | RelMap
count                        | 1
count_percentage             | 0.07587253414264036
record_size                  | 553
record_size_percentage       | 0.8243887895050686
fpi_size                     | 0
Cancel request sent

通过这个功能的另一个函数 pg_get_wal_stats ,可以通过这个功能完全,了解这一段实际的日志中的日志的占比,我们可以看到FPI  , XLOG 里面FPI 占比70%。

select * from pg_get_wal_stats('0/4552810', '0/498AE38', true) order by count_percentage desc;

8c5b29ca3f0ab9add2fe0692dd7afaa5.png

最后为什么会产生那么多FPI, full page image, 主要有以下的原因, 数据库页面记录在wal日志中的原因,FPI 记录包含整个页面的内容,包括数据和元数据信息,每一个被修改的页面均会产生一个FPI记录,这些FPI记录会写到WAL 日志中,当进行事务性操作是,会对事务牵扯的需要操作的多个页面进行操作被修改的页面都需要有对应的FPI 记录,所以WAL日志中占据最大存储量的是FPI 。换言之,你的系统做的数据变动越多,牵扯的页面数量越多,则产生的FPI 会越多,最终就是你的WAL 日志会较大。

当然如果你想获得更多关于数据库操作的一些内部构造知识,可以通过下面的方式来初步获取,比如日志中一段时间,频繁操作OID,你可以把OID 放到下面的SQL中,来查看到底在这段时间,系统操作了什么。

SELECT
 relname,
 CASE 
  when relkind = 'r' then 'tab'
  when relkind = 'i' then 'idx'
  when relkind = 'S' then 'seq'
  when relkind = 't' then 'toast'
  when relkind = 'v' then 'view'
  when relkind = 'm' then 'matview'
  when relkind = 'c' then 'composite'
  when relkind = 'f' then 'F tab'
  when relkind = 'p' then 'part tab'
  when relkind = 'I' then 'part idx'
 END as object_type
   FROM
  pg_class
 WHERE
  oid IN ('oid');
select * from pg_get_wal_stats('0/4552810', '0/498AE38', true) order by count_percentage desc;
postgres-# 
oid                  relfilenode          relhassubclass       relkind              reloftype            relpersistence       reltoastrelid
relacl               relforcerowsecurity  relhastriggers       relminmxid           reloptions           relreplident         reltuples
relallvisible        relfrozenxid         relispartition       relname              relowner             relrewrite           reltype
relam                relhasindex          relispopulated       relnamespace         relpages             relrowsecurity       
relchecks            relhasrules          relisshared          relnatts             relpartbound         reltablespace        
postgres-# oid IN ('1663','16394','2619','1247');
-[ RECORD 1 ]-------------
relname     | pg_statistic
object_type | tab
-[ RECORD 2 ]-------------
relname     | pg_type
object_type | tab
postgres-# 
oid                  relfilenode          relhassubclass       relkind              reloftype            relpersistence       reltoastrelid
relacl               relforcerowsecurity  relhastriggers       relminmxid           reloptions           relreplident         reltuples
relallvisible        relfrozenxid         relispartition       relname              relowner             relrewrite           reltype
relam                relhasindex          relispopulated       relnamespace         relpages             relrowsecurity       
relchecks            relhasrules          relisshared          relnatts             relpartbound         reltablespace        
postgres-# oid IN ('1663','16394','2619','1247');
-[ RECORD 1 ]-------------
relname     | pg_statistic
object_type | tab
-[ RECORD 2 ]-------------
relname     | pg_type
object_type | tab

52d1c11f7f13f24c6b32fdc04951201f.png


http://www.niftyadmin.cn/n/5010203.html

相关文章

一见“氢”心-康士柏氢能产业链蓄力待发

9月6日&#xff0c;“欧洲CE、IECQ 合规规范与推进氢能产业链发展会议”在广东康士柏丹灶产业园顺利举行。来自20余家氢能企业、政府部门等近50名代表参会。 本次会议邀请了全球权威认证机构德国德凯DEKRA培训讲师现场培训讲解&#xff0c;分别以欧盟新立法架构(CE合规&#x…

Java 和 PHP GC 的差异和差异出现的原因

JAVA 的 GC 处理 判断草死掉的两种方式&#xff1a;引用计数和可达性分析 可达性分析对 JAVA 比较好用的原因是 JAVA遵守这面向对象的严格要求&#xff0c;每个变量都被对象包裹&#xff0c;所以每个变量都能通过对象来进行遍历找到&#xff0c;最终判断他们的是否被引用&…

nginx服务和uwsgi服务如何设置开机自启动

上次学到了在云服务器下如何部署Django项目&#xff0c;用到了nginx服务和uwsgi服务&#xff0c;需要手工启动这2个服务的命令。 现在考虑如何设置开机自启动&#xff0c;为什么要这样考虑&#xff1f;因为服务器万一出问题&#xff0c;意外重启了&#xff0c;那我们部署的Dja…

python爬虫,多线程与生产者消费者模式

使用队列完成生产者消费者模式使用类创建多线程提高爬虫速度 https://sc.chinaz.com/tupian/index.html https://sc.chinaz.com/tupian/index_2.html https://sc.chinaz.com/tupian/index_3.html from threading import Thread from queue import Queue import requests from b…

vue插槽slot

插槽有三种&#xff1a; 目录 1.普通插槽 2.具名插槽 3.作用域插槽 1.普通插槽 sub.vue 子组件 --- 子组件写slot标签&#xff0c;父组件的Sub标签内填写的内容会显示在slot的位置&#xff0c;父组件如果不写内容就会展示默认内容。 <template><div class"…

【LeetCode - 每日一题】1123. 最深叶节点的最近公共祖先(23.09.06)

1123. 最深叶节点的最近公共祖先 题意 返回最深节点的最近公共祖先&#xff1b;每个节点的 val 互不相同&#xff1b;节点最多 1000 个&#xff1b; 解法1 bfs 回溯 和经典的 LCA 不同的是&#xff0c;这里的对象是 若干个叶节点&#xff08;1个或多个&#xff0c;最深的&…

vue3+ts+vite项目引入echarts,vue3项目echarts组件封装

概述 技术栈&#xff1a;Vue3 Ts Vite Echarts 简介&#xff1a; 图文详解&#xff0c;教你如何在Vue3项目中引入Echarts&#xff0c;封装Echarts组件&#xff0c;并实现常用Echarts图例 文章目录 概述一、先看效果1.1 静态效果1.2 动态效果 二、话不多数&#xff0c;引入 …

锯齿波-RC充放电路

锯齿波电路根据应用的不同又叫扫描电路、时基断电路&#xff0c;在一些仪器仪表等电子设备中经常用到的一种单元电路。锯齿波信号的明显的特征是电压或是电流先随时间呈线性增长&#xff0c;再迅速下降&#xff0c;然后再线性上升&#xff0c;再迅速下降&#xff0c;如此循环。…