2024-05-08 postgres-调试及分析-记录

server/2024/12/3 6:59:32/

摘要:

2024-05-08 postgres-调试及分析-记录

DDL:

创建库表及插入数据:


create database d1;\c d1;create table t1( a int, b int );
create table t2( a int, b int );insert into t1(a,b) values(3,4);
insert into t1(a,b) values(5,6);insert into t2(a,b) values(3,1);
insert into t2(a,b) values(7,2);

准备查询SQL:

SELECT * FROM  t1 LEFT JOIN t2 ON t2.a = t1.a;

一. 客户端连接pg服务

参考: 2024-05-08 postgres-编译初始化及运行-记录-CSDN博客

二. 找到客户端连接的pg的后端进程的pid

命令:

ps -ef | grep postgres | grep -v grep | grep -v psql

执行结果:

[root@192 trunk]# ps -ef | grep postgres | grep -v grep | grep -v psql
kevin      41716       1  0 02:00 ?        00:00:00 /usr/local/pgsql/bin/postgres
kevin      41718   41716  0 02:00 ?        00:00:00 postgres: checkpointer 
kevin      41719   41716  0 02:00 ?        00:00:00 postgres: background writer 
kevin      41720   41716  0 02:00 ?        00:00:00 postgres: walwriter 
kevin      41721   41716  0 02:00 ?        00:00:00 postgres: autovacuum launcher 
kevin      41722   41716  0 02:00 ?        00:00:00 postgres: stats collector 
kevin      41723   41716  0 02:00 ?        00:00:00 postgres: logical replication launcher 
kevin      41772   41716  0 02:18 ?        00:00:00 postgres: kevin d1 [local] idle

客户端连接的pg后端进程pid: 

kevin      41772   41716  0 02:18 ?        00:00:00 postgres: kevin d1 [local] idle

三. gdb挂在pg后端进程并打断点

gdb挂载进程:

[root@192 trunk]# gdb -p 41772
GNU gdb (GDB) Red Hat Enterprise Linux 8.2-20.el8
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:<http://www.gnu.org/software/gdb/documentation/>.For help, type "help".
Type "apropos word" to search for commands related to "word".
Attaching to process 41772
Reading symbols from /usr/local/pgsql/bin/postgres...done.
Reading symbols from /lib64/libpthread.so.0...(no debugging symbols found)...done.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Reading symbols from /lib64/librt.so.1...(no debugging symbols found)...done.
Reading symbols from /lib64/libdl.so.2...(no debugging symbols found)...done.
Reading symbols from /lib64/libm.so.6...Reading symbols from .gnu_debugdata for /lib64/libm.so.6...(no debugging symbols found)...done.
(no debugging symbols found)...done.
Reading symbols from /lib64/libc.so.6...(no debugging symbols found)...done.
Reading symbols from /lib64/ld-linux-x86-64.so.2...done.
Reading symbols from /lib64/libnss_files.so.2...Reading symbols from .gnu_debugdata for /lib64/libnss_files.so.2...(no debugging symbols found)...done.
(no debugging symbols found)...done.
0x00007fa384b8e2cb in epoll_wait () from /lib64/libc.so.6
Missing separate debuginfos, use: yum debuginfo-install glibc-2.28-251.el8.x86_64
(gdb) 

为核心函数打断点:

例如: create_scan_plan

(gdb) 
(gdb) b create_scan_plan
Breakpoint 1 at 0x7dbe25: file createplan.c, line 558.
(gdb) c
Continuing.

四. 客户端执行查询,查看gdb的堆栈

客户端执行查询:

使用空值拒绝的外连接转内连接的规则的sql

SELECT * FROM  t1 LEFT JOIN t2 ON t2.a = t1.a WHERE t2.b < 5;

gdb中的函数调用堆栈:

(gdb) c
Continuing.Breakpoint 1, create_scan_plan (root=0x2ce5808, best_path=0x2cfb508, flags=2) at createplan.c:558
558		RelOptInfo *rel = best_path->parent;

(gdb) bt
#0  create_scan_plan (root=0x2ce5808, best_path=0x2cfb508, flags=2) at createplan.c:558
#1  0x00000000007dbaa4 in create_plan_recurse (root=0x2ce5808, best_path=0x2cfb508, flags=2) at createplan.c:410
#2  0x00000000007e2777 in create_mergejoin_plan (root=0x2ce5808, best_path=0x2cfbee8) at createplan.c:4376
#3  0x00000000007dc862 in create_join_plan (root=0x2ce5808, best_path=0x2cfbee8) at createplan.c:1067
#4  0x00000000007dbac0 in create_plan_recurse (root=0x2ce5808, best_path=0x2cfbee8, flags=1) at createplan.c:415
#5  0x00000000007db9ba in create_plan (root=0x2ce5808, best_path=0x2cfbee8) at createplan.c:346
#6  0x00000000007ecfbf in standard_planner (parse=0x2c16948, query_string=0x2c15718 "SELECT * FROM  t1 LEFT JOIN t2 ON t2.a = t1.a;", cursorOptions=2048, boundParams=0x0)at planner.c:407
#7  0x00000000007ecd2a in planner (parse=0x2c16948, query_string=0x2c15718 "SELECT * FROM  t1 LEFT JOIN t2 ON t2.a = t1.a;", cursorOptions=2048, boundParams=0x0) at planner.c:271
#8  0x000000000090572b in pg_plan_query (querytree=0x2c16948, query_string=0x2c15718 "SELECT * FROM  t1 LEFT JOIN t2 ON t2.a = t1.a;", cursorOptions=2048, boundParams=0x0)at postgres.c:847
#9  0x0000000000905869 in pg_plan_queries (querytrees=0x2ce5728, query_string=0x2c15718 "SELECT * FROM  t1 LEFT JOIN t2 ON t2.a = t1.a;", cursorOptions=2048, boundParams=0x0)at postgres.c:939
#10 0x0000000000905bc0 in exec_simple_query (query_string=0x2c15718 "SELECT * FROM  t1 LEFT JOIN t2 ON t2.a = t1.a;") at postgres.c:1133
#11 0x000000000090a0ef in PostgresMain (argc=1, argv=0x7fff70e94eb0, dbname=0x2c42428 "d1", username=0x2c10a58 "kevin") at postgres.c:4496
#12 0x0000000000857a54 in BackendRun (port=0x2c39e30) at postmaster.c:4530
#13 0x00000000008573c1 in BackendStartup (port=0x2c39e30) at postmaster.c:4252
#14 0x0000000000853b10 in ServerLoop () at postmaster.c:1745
#15 0x00000000008533c9 in PostmasterMain (argc=1, argv=0x2c0ea10) at postmaster.c:1417
#16 0x0000000000760270 in main (argc=1, argv=0x2c0ea10) at main.c:209

查询优化后, 查询执行的调用堆栈:

#0  ExecScanFetch (node=0x14328d8, accessMtd=0x730efe <SeqNext>, recheckMtd=0x730fa8 <SeqRecheck>) at execScan.c:39
#1  0x00000000006f86b3 in ExecScan (node=0x14328d8, accessMtd=0x730efe <SeqNext>, recheckMtd=0x730fa8 <SeqRecheck>) at execScan.c:199
#2  0x0000000000730ff3 in ExecSeqScan (pstate=0x14328d8) at nodeSeqscan.c:112
#3  0x00000000006f4ca9 in ExecProcNodeFirst (node=0x14328d8) at execProcnode.c:463
#4  0x0000000000732343 in ExecProcNode (node=0x14328d8) at ../../../src/include/executor/executor.h:257
#5  0x000000000073248a in ExecSort (pstate=0x14326c8) at nodeSort.c:108
#6  0x00000000006f4ca9 in ExecProcNodeFirst (node=0x14326c8) at execProcnode.c:463
#7  0x0000000000726e97 in ExecProcNode (node=0x14326c8) at ../../../src/include/executor/executor.h:257
#8  0x0000000000727af0 in ExecMergeJoin (pstate=0x14322b8) at nodeMergejoin.c:656
#9  0x00000000006f4ca9 in ExecProcNodeFirst (node=0x14322b8) at execProcnode.c:463
#10 0x00000000006ea204 in ExecProcNode (node=0x14322b8) at ../../../src/include/executor/executor.h:257
#11 0x00000000006ec6bb in ExecutePlan (estate=0x1432078, planstate=0x14322b8, use_parallel_mode=false, operation=CMD_SELECT, sendTuples=true, numberTuples=0, direction=ForwardScanDirection, dest=0x1423f98, execute_once=true) at execMain.c:1551
#12 0x00000000006ea76a in standard_ExecutorRun (queryDesc=0x136dfc8, direction=ForwardScanDirection, count=0, execute_once=true) at execMain.c:361
#13 0x00000000006ea602 in ExecutorRun (queryDesc=0x136dfc8, direction=ForwardScanDirection, count=0, execute_once=true) at execMain.c:305
#14 0x000000000090c03e in PortalRunSelect (portal=0x13ad5d8, forward=true, count=0, dest=0x1423f98) at pquery.c:921
#15 0x000000000090bd2d in PortalRun (portal=0x13ad5d8, count=9223372036854775807, isTopLevel=true, run_once=true, dest=0x1423f98, altdest=0x1423f98, qc=0x7ffff3ea58b0)at pquery.c:765
#16 0x0000000000905d39 in exec_simple_query (query_string=0x134a598 "SELECT * FROM  t1 LEFT JOIN t2 ON t2.a = t1.a WHERE t2.b < 5;") at postgres.c:1214
#17 0x000000000090a0ef in PostgresMain (argc=1, argv=0x7ffff3ea5b40, dbname=0x13775d8 "d1", username=0x1345a48 "kevin") at postgres.c:4496
#18 0x0000000000857a54 in BackendRun (port=0x136f010) at postmaster.c:4530
#19 0x00000000008573c1 in BackendStartup (port=0x136f010) at postmaster.c:4252
#20 0x0000000000853b10 in ServerLoop () at postmaster.c:1745
#21 0x00000000008533c9 in PostmasterMain (argc=1, argv=0x1343a00) at postmaster.c:1417
#22 0x0000000000760270 in main (argc=1, argv=0x1343a00) at main.c:209

五. 查询计划分析

PostgreSQL: Documentation: 16: 14.1. Using EXPLAIN

explain参数:

explain [ ( option [,...] ) ] statement
explain [ analyze ] [ verbose ] statementoption选项有:
analyze [ boolean ]                     //会实际执行SQL,并返回SQL实际执行的相关统计信息
verbose [ boolean ]                     //显示执行计划的附加信息
costs [ boolean ]                       //默认开启,显示每个计划节点的启动成本、总成本,预计返回行数,预估返回结果集每行平均宽度
buffers [ boolean ]                     //显示缓冲区使用信息
format [ text | xml | json | yaml ]     //执行计划执行输出格式

例子:

d1=# EXPLAIN ANALYZE VERBOSE      
d1-# SELECT * FROM  t1 LEFT JOIN t2 ON t2.a = t1.a WHERE t2.b < 5;
***(Single step mode: verify command)*******************************************
explain analyze verbose    
SELECT * FROM  t1 LEFT JOIN t2 ON t2.a = t1.a WHERE t2.b < 5;
***(press return to proceed or enter x and return to cancel)********************QUERY PLAN                                                     
-------------------------------------------------------------------------------------------------------------------Merge Join  (cost=232.74..364.14 rows=8509 width=16) (actual time=0.027..0.030 rows=1 loops=1)Output: t1.a, t1.b, t2.a, t2.bMerge Cond: (t2.a = t1.a)->  Sort  (cost=74.23..76.11 rows=753 width=8) (actual time=0.018..0.018 rows=2 loops=1)Output: t2.a, t2.bSort Key: t2.aSort Method: quicksort  Memory: 25kB->  Seq Scan on public.t2  (cost=0.00..38.25 rows=753 width=8) (actual time=0.009..0.011 rows=2 loops=1)Output: t2.a, t2.bFilter: (t2.b < 5)->  Sort  (cost=158.51..164.16 rows=2260 width=8) (actual time=0.005..0.006 rows=2 loops=1)Output: t1.a, t1.bSort Key: t1.aSort Method: quicksort  Memory: 25kB->  Seq Scan on public.t1  (cost=0.00..32.60 rows=2260 width=8) (actual time=0.002..0.003 rows=2 loops=1)Output: t1.a, t1.bPlanning Time: 0.177 msExecution Time: 0.064 ms
(18 rows)


http://www.ppmy.cn/server/41762.html

相关文章

从零开始学习MySQL

# 第一步&#xff1a;下载MySQL安装包 访问MySQL官方网站的[下载页面](https://dev.mysql.com/downloads/mysql/)&#xff0c;根据你的操作系统&#xff08;Windows、macOS、Linux等&#xff09;选择合适的MySQL Community Server版本进行下载。对于Windows用户&#xff0c;可以…

Python-VBA函数之旅-vars函数

目录 一、vars函数的常见应用场景 二、vars函数使用注意事项 三、如何用好vars函数&#xff1f; 1、vars函数&#xff1a; 1-1、Python&#xff1a; 1-2、VBA&#xff1a; 2、推荐阅读&#xff1a; 个人主页&#xff1a;https://myelsa1024.blog.csdn.net/ 一、vars函数…

【软考】设计模式之桥接模式

目录 1. 说明2. 应用场景3. 结构图4. 构成5. 适用性6. 优点7. 缺点8. java示例 1. 说明 1.将抽象部分与其实现部分分离&#xff0c;使它们都可以独立地变化。2.桥接模式&#xff08;Bridge Pattern&#xff09;属于对象结构型模式&#xff0c;又称为柄体&#xff08;Handle an…

spring 循环依赖

单例bean循环依赖: 先创建ABean 1.0. 记录正在创建ABean singletonCurrentlyInCreation<ABean> 1.1.实例化ABean–>得到一个对象–>存入singletonFactories 1.2. 填充BBean属性–>去单例池找BBean–>没有就创建 1.3. 进行其他依赖注入 1.4. 初始化前&#…

Java毕业设计 基于SpringBoot vue新能源充电系统

Java毕业设计 基于SpringBoot vue新能源充电系统 SpringBoot 新能源充电系统 功能介绍 首页 图片轮播 充电桩 充电桩类型 充电桩详情 充电桩预约 新能源公告 公告详情 登录注册 个人中心 余额充值 修改密码 充电桩报修 充电桩预约订单 客服 后台管理 登录 个人中心 修改密码…

单片机的讲解

由于我是一个初中生没有太多时间写文章所以抱歉啊各位csdn用户 编写单片机代码教程需要考虑到读者的基础水平和学习目标。以下是一个简单的单片机&#xff08;比如基于AVR系列的Arduino&#xff09;代码教程的大纲&#xff1a; ### 第1节&#xff1a;入门 - **介绍单片机编程…

【概况】——物联网

物联网产品架构&#xff1f; 对于物联网&#xff0c;一般可分为四层&#xff0c;感知层、网络层、平台层、应用层。 1&#xff09;感知层 通过传感技术&#xff0c;采集物理世界的数据。 包含RFID&#xff08;射频识别技术&#xff09;&#xff0c;如高速公路的我们车上的E…

数学建模(科普)

数学建模&#xff0c;就是根据实际问题来建立数学模型&#xff0c;对数学模型来进行求解&#xff0c;然后根据结果去解决实际问题。 当需要从定量的角度分析和研究一个实际问题时&#xff0c;人们就要在深入调查研究、了解对象信息、作出简化假设、分析内在规律等工作的基础上…