postgresql源码学习(50)—— 小白学习Dtrace追踪源码函数调用

news2025/7/20 9:26:25

       不知不觉第50篇了,昨天在文章里(https://mp.weixin.qq.com/s/AzBGzYhGxYjSf7Sptj55lQ)学到一个追踪源码执行情况的利器 —— Dtrace,本篇记录下实验和笔记。

一、 解决痛点

      学习以来一直有一个疑惑,如何将pg中执行的SQL语句和源码对应起来?回顾下之前学到的gdb调试方法,看看适用场景,以及不足。

常用调试方法

  • 已知函数名:gdb调试。包括很常用的一些语句例如checkpoint,对应函数名网上都能搜到
  • 慢查询卡在某个特定函数:可以gdb跟踪进程然后查看调用栈
  • 有报错信息:根据报错文本在源码中搜索

       但是,如果是业务任意执行的一条语句、出现了某些怪异的现象(例如原文是加长字段长度后其统计信息被删除),如何能知道它究竟调用了pg中的哪些函数?而哪些函数是不符合我们预期的?Dtrace就能解决这个问题。

二、 准备工作

       DTrace叫动态追踪(Dynamic Tracing),本身是源于Solaris系统的,无法在Linux中运行 。因为非常好用,有了Linux移植版,名SystemTap。SystemTap 也定义了一种类似的脚本语言,方便用户根据需要自由扩展。更多简介可以参考:https://blog.csdn.net/Hehuyi_In/article/details/108910781

1. 安装SystemTap

我Oracle Linux 7的虚拟机自带了这个工具,如果没有,可以安装以下包

yum -y install systemtap systemtap-runtime

执行hello world测试命令

stap -e 'probe begin{printf("Hello, World"); exit();}'

上面那些提示对测试没什么影响,可以不管它。

       如果不能输出Hello, World,则需要根据提示装一些kernel相关的包,注意必须跟操作系统的版本是一致的,不能直接yum安装最新版。

2. 使用--enable-dtrace选项编译安装pg

postgresql源码学习(一)—— 源码编译安装与gdb调试入门_Hehuyi_In的博客-CSDN博客_postgresql 源码调试

三、 开始测试

准备完终于可以开始测了,就以原文的例子,看看加长字段长度会调用什么函数。

1. Systemtap脚本准备

vi function.c

      脚本内容,process中的路径自行替换,function中的*代表输出所有函数(因为不知道具体有哪些,可以利用通配符缩小范围,例如*Start*)

probe process("/data/postgres/base/14.0/bin/postgres").function("*") {
        printf("%s: %s\n", execname(), ppfunc());
}

2. 创建测试表

create table t(id int,info varchar(10));
insert into t select n,left(md5(random()::text),10) from generate_series(1,1000) as n;
analyze t;

3. 执行Systemtap脚本

stap function.c > mylog.txt

       红色的提示可以忽略,实际已经装了这个包,并不影响使用,WARNING的信息虽然多,但也不影响使用。

4. 执行加长字段语句

alter table t alter COLUMN info type varchar(20);

这里发现需要另开一个会话才能抓到,直接在原先会话执行一直是些空闲等待的函数

5. 观察输出结果

再开一个窗口,mylog.txt中有输出后退出脚本,否则会记录很多无用信息。

按原文搜一下statistic相关函数,发现有了

cat mylog.txt | sort | uniq | grep -i statistic

再看看日志中的内容

四、 源码学习

定位到函数后,就回到了熟悉的内容,gdb也好vscode也好,可以根据函数名调试和搜索它了。

       RemoveStatistics函数用于为单表或单列删除pg_statistic系统表中对应的记录。如果attnum为零(未指定列),删除该表的所有记录;如果指定了列,则删除该列的记录。

/*
 * RemoveStatistics --- remove entries in pg_statistic for a rel or column
 *
 * If attnum is zero, remove all entries for rel; else remove only the one(s)
 * for that column.
 */
void
RemoveStatistics(Oid relid, AttrNumber attnum)
{
    Relation    pgstatistic;
    SysScanDesc scan;
    ScanKeyData key[2];
    int         nkeys;
    HeapTuple   tuple;

    pgstatistic = table_open(StatisticRelationId, RowExclusiveLock);

    ScanKeyInit(&key[0],
                Anum_pg_statistic_starelid,
                BTEqualStrategyNumber, F_OIDEQ,
                ObjectIdGetDatum(relid));

    if (attnum == 0)
        nkeys = 1;
    else
    {
        ScanKeyInit(&key[1],
                    Anum_pg_statistic_staattnum,
                    BTEqualStrategyNumber, F_INT2EQ,
                    Int16GetDatum(attnum));
        nkeys = 2;
    }

    scan = systable_beginscan(pgstatistic, StatisticRelidAttnumInhIndexId, true,
                              NULL, nkeys, key);

    /* we must loop even when attnum != 0, in case of inherited stats */
    while (HeapTupleIsValid(tuple = systable_getnext(scan)))
        CatalogTupleDelete(pgstatistic, &tuple->t_self);

    systable_endscan(scan);

    table_close(pgstatistic, RowExclusiveLock);
}

另外看了下会调用该函数的文件

点开看了看,大概有以下函数(操作)会删除统计信息:

  • heap_drop_with_catalog - removes specified relation from catalogs,删表
  • RemoveAttributeById - This is the guts of ALTER TABLE DROP COLUMN,删列
  • index_drop - 删索引
  • ATExecAlterColumnType - ALTER COLUMN .. SET DATA TYPE,改字段类型,注释为
   /*
     * Drop any pg_statistic entry for the column, since it's now wrong type
     */
    RemoveStatistics(RelationGetRelid(rel), attnum);

 这方法感觉有点傻,应该有更方便能看到函数调用信息的工具?不过暂时没搜到,留待以后吧~

参考

PostgreSQL修改列类型又掉坑了!

使用动态追踪Dtrace分析问题

https://gist.github.com/alexandrnikitin/7fd095371e8c105f6cb9ab7f87664547

PostgreSQL数据库统计信息——统计信息系统表_肥叔菌的博客-CSDN博客_postgresql 表统计信息

《Linux性能优化实战》笔记(24)—— 动态追踪 DTrace_Hehuyi_In的博客-CSDN博客_dtrace linux

postgresql源码学习(一)—— 源码编译安装与gdb调试入门_Hehuyi_In的博客-CSDN博客_postgresql 源码调试

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/37771.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Boot 3.0 正式发布,这份升级指南必须收藏

Spring Boot 3.0 现已正式发布,它包含了 12 个月以来 151 个开发者的 5700 多次代码提交。这是自 4.5 年前发布 2.0 以来,Spring Boot 的第一次重大修订。它也是第一个支持 Spring Framework 6.0 和 GraalVM 的 Spring Boot GA 版本,同时也是…

Nginx环境搭建及前端部署教程(Windows版)

1、Nginx简介 Nginx (engine x) 是一个轻量级、高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。几乎可以做到 7 * 24 小时不间断运行,即使运行几个月也不需要重新启动,还能在不间断服务的情况下对软件版本进行热更新。性…

2022年,数字化转型升级,越来越重要

所谓数字化营销,指的是使用数字传播渠道推广产品和服务,从而以一种及时、相关、定制化和节省成本的方式与消费者进行沟通。 进入2022年,数字化转型升级,变得越来越重要。 01政策推动数字化发展 国家“十四五”期间将加快推进企业…

arthas进阶版排查问题之idea插件工具操作

arthas前面的文章讲了怎么去使用命令排查线上问题,线上出了问题就需要我们去排查问题和处理程序异常,但是线上一般出问题不太好解决,总有一些奇怪的问题,当然很多场景是测试测试不到的,我们不能百分百保证线上不出问题…

Unreal地形高级材质之根据斜率分配材质

目的:根据地形的斜率来混合地形材质,制作地形时,当地形有高度抬升时,被拉伸部位的贴图会出现拉伸,或者想要在拉伸区域使用其他类型种类的贴图时。如果使用笔刷对地形进行更改是耗费时间的,所以想要整体一次…

数据结构中的树和二叉树(0基础讲解+代码)

树和二叉树树的定义树的一些基本概念树的代码链接方式二叉树完全二叉树和满二叉树二叉树的性质链式二叉树前序遍历后序遍历中序遍历层序遍历二叉树的深度二叉树第k层的结点个数二叉树的叶子节点个数总结前言:前面我们所学习的数据结构比如链表,顺序表&am…

【博客542】k8s使用EndpointSlices扩展大规模service后端服务数量

k8s使用EndpointSlices扩展大规模service后端服务数量 EndpointSlices 端点切片(EndpointSlices) 提供了一种简单的方法来跟踪 Kubernetes 集群中的网络端点(network endpoints)。 它们为 Endpoints 提供了一种可扩缩和可拓展的替…

长时间序列模型DLinear(代码解析)

前言 今年时间序列SOTA,DLinear模型,论文下载链接,也可以看我写的论文解析当然最好是读原文。Dlinear,NLinear模型Github项目地址,下载项目文件这里提供我写过注释的项目文件,下载地址 参数设定模块(run_…

图神经网络之预训练大模型结合:ERNIESage在链接预测任务应用

1.ERNIESage运行实例介绍(1.8x版本) 本项目原链接:https://aistudio.baidu.com/aistudio/projectdetail/5097085?contributionType1 本项目主要是为了直接提供一个可以运行ERNIESage模型的环境, https://github.com/PaddlePaddle/PGL/blob/develop/e…

笔记redis

redis特点: 1.这些数据类型都支持 push/pop. add/remove 及取交集并集和差集及更丰富的操作 2.Redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件中进行持久化 3.单线路IO多路复用 4.redis操作是原子性操作 redis 单线程模型: Redis 内…

chrome插件开发(manifest_version版本V3 + Ant Design Vue)

1.什么是 Chrome 插件 谷歌浏览器插件是一种小型的定制浏览器体验的程序,通过插件可以自定义浏览器的一些行为来适合个人的需求,例如上面的查看服务器状态插件。 在应用商店中下载下来的插件基本上都是以.crx 为文件后缀,该文件其实就是一个…

Word2Vec

Word2Vec 在自然语言发展的早期阶段,词的表示经历了不断地发展和改进,直到后来有一种word vector的思想被提出以及后续的实现,才极大地促进了NLP的发展。 word vector的核心思想: 为每个单词构建一个密集向量,选择后…

傻白入门芯片设计,先进封装技术(五)

集成电路芯片与封装之间是不可分割的整体。没有一个芯片可以不用封装就能正常工作,封装对芯片来说是必不可少的,随着IC生产技术的进步,封装技术也不断更新换代,每一代IC都与新一代的IC封装技术紧密相连。 一、什么是封装&#xf…

什么蓝牙耳机颜值高音质好?颜值高音质好的蓝牙耳机推荐

朋友让我推荐蓝牙耳机的时候,总是喜欢问哪款蓝牙耳机的性能更强,想要直接入手那款性能更强的蓝牙耳机,以此节省对比的时间。但是用户自行进行对比的步骤,显然是不能省的,所以今天我给四款蓝牙耳机做了横向对比&#xf…

C语言tips-NULL指针和void指针

0.写在最前 最近因为工作需要开始重新学c语言,越学越发现c语言深不可测,当初用python轻轻松松处理的一些数据,但是c语言写起来却异常的复杂,这个板块就记录一下我的c语言复习之路 1. void指针 1.1 解释 void 用在函数定义中可以表…

身份安全风险分析

摘要 从勒索软件到 APT,身份风险是重要的攻击向量。 管理 Active Directory 的复杂性,导致所有组织都存在1/6的可利用的特权身份风险。 这些身份风险包括使用过时密码的本地管理员、具有不必要权限的错误配置用户、在终端上暴露的缓存凭据等。 当攻击者…

让学前端不再害怕英语单词(四)

|| 欢迎关注csdn前端领域博主: 前端小王hs || email: 337674757qq.com || 前端交流群: 598778642前三章直通车↓↓↓ 让学前端不再害怕英语单词(一) 让学前端不再害怕英语单词(二) 让学前端不再害怕英语单词&#xff0…

单目标应用:最有价值球员算法(Most Valuable Player Algorithm,MVPA)求解旅行商问题TSP

一、最有价值球员算法 最有价值球员算法(Most Valuable Player Algorithm,MVPA)由Bouchekara 等人于2017年提出,该算法受到体育比赛的启发,球员们为了赢得冠军而组成队伍进行队伍竞争,他们也为了赢得最有价…

使用VMware安装系统Window、Linux操作系统

使用VMware安装系统Window、Linux操作系统 下载镜像文件打开VMware 下载镜像文件地址或链接: Windows全家桶镜像文件下载网站:msdn.itellyou.cnWindows 10 种子文件 ed2k://|file|cn_windows_10_business_editions_version_1803_updated_aug_2019_x64_dv…

Js逆向教程-14反调试

Js逆向教程-14反调试 一、检测是否在调试 键盘监听(F12)检测浏览器的高度插值检测开发者人员工具变量是否为true利用console.log调用次数利用代码运行的时间差利用toString检测非浏览器 二、显性 2.1 debugger: function xx() {debugger;…