当前位置: 首页 > article >正文

PgSQL技术内幕 • statement_timeout做的那些事

PgSQL技术内幕 • statement_timeout做的那些事

statement_timeout是Postgres种的一个配置参数,用于指定SQL语句执行的超时时间,当超时时就取消该SQL的执行,并返回错误信息。这个参数通常用于控制运行时间较长的查询,避免影响数据库性能和响应时间。一旦一条SQL查询花费几分钟甚至更长时间才能执行完时,若没有限制,这种查询可能占用数据库资源,导致其他请求阻塞。

statement_timeout默认值是0,表示不限制SQL查询执行时间,单位为毫秒。那么,这个参数是如何做到控制SQL的执行时间的呢?

1、statement_timeout超时的起使时间点在哪?

b95fad77c6b464a6900733cd2eb6cd63.png

配置项在代码中对应的变量为StatementTimeout。

b2aeac9fe0c945b4f5783c1752b3b31d.png

事务开启时,StartTransactionCommand之后的时间点作为超时时间计时开始,即上图中蓝色框内的now值。超时时间点:now + statement_timeout的值作为fin_time记录到计时器中。

2、超时机制

上节,我们知道开始事务的时间点作为超时的起使计时点,通过schedule_alarm设置定时器。那么这个定时器通过什么来触发?

1)我们接着看下schedule_alarm函数,其中enable_alarm函数将alarm_enabled置为true,后续会用到,然后通过settimer函数设置一个定时器,也就是超时后会向进程发送一个SIGALRM信号:

5af331eee982d154636267d8314e1a60.png

2)SIGALRM信号接收到后,做什么动作呢?接着观察SIGALRM信号注册函数句柄:

94a0e18acabf7a5fca339e08172bbf1c.png

PostgresMain作为PG服务进程的入口函数,在InitializeTimeouts函数初始化all_timeouts[]数组时,注册SIGALRM信号句柄函数,即handle_sig_alarm。

在1)中设置了alarm_enabled为true,handle_sig_alarm进入超时处理流程,即处理active_timeouts[]数组每个超时事件(拿一个删除一个,所以总是取active_timeouts[0]):标记indicator=true,并调用超时句柄,针对statement_timeout,在InitPostgres->RegisterTimeout函数设置了句柄为StatementTimeoutHandler。

StatementTimeoutHandler通过kill向进程发送SIGINT信号。

3)PostgresMain也注册了SIGINT信号处理函数:StatementCancelHandler:

0698ce3454a25f155110c8f5d3130868.png

主要设置了两个变量:InterruptPending和QueryCancelPending都为true。

4)进入中断处理函数ProcessInterrupts后,根据QueryCancelPending为true,进入取消SQL执行的逻辑:通过ereport::ERROR 跳出当前流程到异常结束:

91b6b7e456cdec9096cf1b44d43798bb.png

3、ProcessInterrupts何时被执行

很显然,statement_timeout是通过一系列软中断来完成的。当发生中断的时候,CPU会停下当前处理流程,进入内核态进行中断信号处理,中断信号处理完,返回用户态时处理注册的中断处理函数,然后返回中断处理前软件流程接着工作。所以ProcessInterrupts什么时候被执行呢?

CHECK_FOR_INTERRUPTS->ProcessInterrupts:InterruptPending在函数StatementCancelHandler中就置为了true,所以CHECK_FOR_INTERRUPTS宏会调用到ProcessInterrupts。而PG关键流程中有很多地方都会调用CHECK_FOR_INTERRUPTS来检测中断的发生并处理。

032b095f01266e5ff76c0d6ad5a4398b.png

一旦PG流程陷入某些底层函数出不来,导致statement_timeout超时,就会因为不能继续执行后续流程进入CHECK_FOR_INTERRUPTS做真正取消SQL的操作。也就是说这种情况下,statement_timeout是管不住的!


http://www.kler.cn/a/153269.html

相关文章:

  • Spring Boot 统⼀数据返回格式
  • 前端面试高频考点—事件循环Event loop
  • 『heqingchun-Ubuntu系统+x86架构+配置编译安装使用yolov5-6.0+带有TensorRT硬件加速+封装动态库+C++部署+Qt』
  • 登录/注册波形库账号(英国Pico汽车论坛账号)
  • 2023-12-01 AIGC-自动生成ppt的AI工具
  • C#多线程开发之----List Task有返回值
  • RPG项目01_场景及人物动画管理器
  • 【零基础入门Docker】Dockerfile中的USER指令以及dockerfile命令详解
  • C++ 传递指针给函数
  • 从PDF和图像中提取文本,以供大型语言模型使用
  • java开发之个微群聊自动添加好友
  • scrapy爬虫中间件和下载中间件的使用
  • git基本概念
  • 【概率统计】如何理解概率密度函数及核密度估计
  • Doris 数据导入一:Broker Load 方式
  • 树莓派3B+ PCB叠层设计
  • 连锁零售企业如何提高异地组网的稳定性?
  • PVE系列-LVM安装MacOS的各个版本
  • github / gitlab s申城 配置密钥 ssh key
  • 【SparkSQL】SparkSQL函数定义(重点:定义UDF函数、使用窗口函数)