【GaussDB】排查应用高可用切换出现数据库整体卡顿及报错自治事务无法创建的问题

【GaussDB】排查应用高可用切换出现数据库整体卡顿及报错自治事务无法创建的问题

背景

某客户在做应用程序的高可用切换测试,在应用程序中,收到了来自数据库的报错,不能创建自治事务

ERROR: autonomous transaction failed to create autonomous session
DETAIL: wait /data/gaussdb506/tmp:7456 timeout expired

数据库是GaussDB 506.0 SPC0100.0.0集中式单机,应用软件是两个节点,同一时刻只有一个应用节点会发生业务,当主应用节点故障时,另外一个应用节点会接管业务。

测试时,先让两个应用都开启,让主应用节点正常开始业务,然后断掉主应用节点的网卡,让备应用节点接管,顿时出现数据库卡顿,新建连接要很长时间,已经建立上的连接执行任何SQL都很卡。并且大约在25秒后,日志中出现了上面提到的自治事务创建报错。

GaussDB的自治事务是服务端自行使用libpq建立了一个本地连接。

分析

该应用开始执行业务时,会根据配置的并发任务数,创建对应个数的数据库连接,本次测试时的并发数配置为200。另外根据测试人员反馈,当并发为100时,就不会出现这个问题。

检查数据库最大连接数和最大自治事务连接数,远超测试并发度:

gaussdb=# show max_connections;max_connections
-----------------3000
(1 row)gaussdb=# show max_concurrent_autonomous_transactions;max_concurrent_autonomous_transactions
----------------------------------------1000
(1 row)

该应用执行的每个业务,都会调用一个自治事务的存储过程用于记录日志,因此当业务并发数为200时,也会同时创建200个自治事务的连接,也就是说最大也才400个连接。

尝试编写简单用例进行复现,写一个shell文件,循环后台使用gsql调用自治事务的匿名块,模拟应用行为。

#!/bin/bash
rm -rf lll.log
for i in {1..200}
do
gsql -t <<'SQL_CMD' >>lll.log 2>&1 &
select 1;
declare
PRAGMA AUTONOMOUS_TRANSACTION;
begin
pg_sleep(30);
end;
/
select pg_sleep(200);
SQL_CMD
echo "Launched $i at $(date)" >> lll.log
done

由于是后台异步的,所以这个sh执行很快,top观察此时cpu和内存占用都不高,
ps -ef |grep gsql也可以观察到还有200个gsql进程。
然后另开一个gsql连接,发现连接时间比之前长了很多。
连接上之后,执行以下SQL观察,此时任意SQL执行都会非常耗时

gaussdb=#  select application_name,count(1) from pg_stat_activity where application_name in ('gsql','autonomoustransaction') and pid<>pg_backend_pid() group by application_name;application_name    | count
-----------------------+-------autonomoustransaction |    54gsql                  |   200
(2 rows)

发现gsql的主事务已经有200个了,但是自治事务却还只有54个,说明有大量的自治事务还没有创建,也就是说,并发创建自治事务的确会由于某种原因产生阻塞。
检查lll.log文件,的确也出现了创建自治事务超时的报错。

从官方文档中看有没有什么线索
《自治事务-规格约束》-https://doc.hcs.huawei.com/db/zh-cn/gaussdbqlh/25.1.30/devg-cent/gaussdb-42-0970.html

自治事务执行时,将会在后台启动自治事务session,可以通过max_concurrent_autonomous_transactions设置自治事务执行的最大并行数量,该参数取值范围为0~10000,默认值为10。
当max_concurrent_autonomous_transactions参数设置为0时,自治事务将无法执行。
自治事务新启session后,将使用默认session参数,不共享主session下对象(包括session级别变量,本地临时变量,全局临时表的数据等)。
自治事务理论上限为10000,实际上限为动态值,参考GUC参数max_concurrent_autonomous_transactions描述。
自治事务受通信缓冲区影响,返回给客户端的信息大小受限于通信缓冲区长度,超过通信缓冲区长度时报错。
自治事务的锁不受lock timeout影响,锁超时时间为2147483s,自治事务执行超过此时间会报错锁超时。
自治事务设置建立连接超时时间5s,建立连接尝试5次。建立连接期间不立即响应信号,每次建立连接前检查信号。高并发、高CPU、高内存,以及线程池扩容场景下可能存在超时报错现象。
在PACKAGE SPECIFICATION或PACKAGE BODY SPECIFICATION中声明自治事务PRAGMA AUTONOMOUS_TRANSACTION语法,可成功创建PACKAGE,但自治事务不生效。

其中有一条注意事项和当前现象有点像,超时5秒尝试5次,一共就是25秒。

于是观察故障时间点的CPU/内存/磁盘IO的情况,但是发现故障时间点,这些指标反而比平时更低,可以说服务器几乎没有干活了。那么有可能的就是"线程池扩容场景"了。

为了验证是不是与线程池特性有关,尝试关闭线程池再执行上面的shell测试。
发现自治事务创建非常顺利,也没有出现报错。

gaussdb=#  select application_name,count(1) from pg_stat_activity where application_name in ('gsql','autonomoustransaction') and pid<>pg_backend_pid() group by application_name;application_name    | count
-----------------------+-------autonomoustransaction |   200gsql                  |   200
(2 rows)

似乎是与线程池功能有关,但是我在开启线程池后,改成400个并发,不使用自治事务,并没有出现阻塞的情况,400个gsql连接是瞬间就连接成功了。

直觉告诉我这里的设计应该有问题,从线程池里获取线程用于普通连接和用于自治事务连接,似乎走了两个不同的逻辑,自治事务连接会需要阻塞度更大的锁,但是没有源码没法分析。

大概看了一眼openGauss这里的自治事务超时,从3.1版本开始就改成了固定的10min,之前版本是没有额外的超时设置的,和libpq共用,也就是说自治事务的代码在openGauss和GaussDB已经有所区别了。不过我也测了下openGauss,在线程池模式下,的确也会出现并发创建自治事务导致数据库整体卡顿的现象,只是由于超时需要10min,所以没有出现报错,自治事务的连接数会慢慢增加。但并发度如果更高,还是可能会出现自治事务连接超过10min而报错的现象。

这个测试已经充分说明在GaussDB里,线程池开启时,并发创建自治事务会导致数据库出现整体卡顿、新连接建立缓慢、旧连接执行SQL缓慢、还有自治事务执行会出现超时报错的情况。但应用需求摆在这,如何解决这个问题呢?

回到GaussDB文档 ,“线程池扩容场景下可能存在超时报错现象” ,既然扩容就会超时报错,那么不让它扩容,一开始线程数就是够的,是不是就不会超时了?

在GaussDB中有一个这样的参数

thread_pool_attr

参数说明:用于控制线程池功能的详细属性,该参数仅在enable_thread_pool打开后生效,仅sysadmin用户可以访问。

参数类型:字符串

参数单位:无

取值范围:

该参数分为三个部分,‘thread_num, group_num, cpubind_info’,这三个部分的具体含义如下:

  • thread_num:线程池中的初始线程总数,可以动态扩充,取值范围是0~4096。其中0的含义是数据库根据系统CPU core的数量来自动配置线程池的线程数,如果参数值大于0,线程池中的线程数等于thread_num。线程池大小建议根据硬件配置进行设置,计算公式如下:thread_num = CPU核数*(3~5),thread_num最大值为4096。
  • group_num:线程池中的线程分组个数,取值范围是0~64。其中0的含义是数据库根据系统NUMA组的个数来自动配置线程池的线程分组个数,如果参数值大于0,线程池中的线程组个数等于group_num。
  • cpubind_info:线程池是否绑核的配置参数。可选择的配置方式有:1. ‘(nobind)’ ,线程不做绑核;2. ‘(allbind)’,利用当前系统所有能查询到的CPU core做线程绑核;3. ‘(nodebind: 1, 2)’,利用NUMA组1、2中的CPU core进行绑核;4. ‘(cpubind: 0-30)’,利用0-30号CPU core进行绑核;5. ‘(numabind: 0-30)’,在NUMA组内利用0-30号CPU core进行绑核。该参数不区分大小写。当开启资源多租模式时,该参数不生效。

默认值:‘4096,2,(nobind)’(196核CPU/1536G内存,128核CPU/1024G内存,104核CPU/1024G内存,96核CPU/1024G内存);‘2048,2,(nobind)’(96核CPU/768G内存,80核CPU/640G内存);‘1024,2,(nobind)’(64核CPU/512G内存,60核CPU/480G内存,32核CPU/256G内存);‘512,2,(nobind)’(16核CPU/128G内存);‘256,2,(nobind)’(8核CPU/64G内存)

设置方式:该参数属于POSTMASTER类型参数,请参考表1中对应设置方法进行设置。

设置建议:内存充足且CPU性能好的情况,当业务需要更多连接时可以增加该参数值。

设置不当的风险与影响:若thread_pool_attr设置值大于等于max_connections,会导致proc资源全部被线程池占用,出现proc资源不足的问题。默认值即推荐值,不建议修改。修改必须详细确认参数的规格限制,并考虑硬件资源是否足够,否则可能导致数据库异常。

当前环境配置的是 256,2,(nobind) ,也就是说,数据库启动的时候就会同时启动256个worker线程,可以动态扩充意味着并不是只允许256个worker同时干活,它应该会根据实际需要自动增加。但是自治事务这里似乎有些差异,结合上面查询的会话数,主事务200个,自治事务54个,接近256个了,所以理论上把256调大,改成超过400,那么并发200个连接套自治事务,就不会报错了。

实测也的确如此,所以我们调整了安装的初始化参数配置,直接把thread_pool_attr改成了4096,2,(nobind) ,这样启动的时候就会有四千多个空闲的worker线程,在目前应用场景下绝对是够用的。

由于这个主事务加自治事务会话数需要低于启动时的线程池个数的表现,在openGauss中似乎并不存在,因此再看openGauss的源码分析,意义也不大了。

不过,这也意味着,在当前GaussDB数据库版本中,由于默认是开启了线程池的,所以如果业务代码经常使用自治事务,无论机器硬件配置有多高,最大支持的并发业务数其实只有2048个了,超过就可能导致数据库整体变慢,甚至还会出现报错。

结论

在GaussDB中,如果频繁使用自治事务,当thread_pool_attr的第一个值小于应用的并发连接数乘2时,数据库可能会出现严重的卡顿以及报错的现象,因此在硬件资源足够的情况下,建议把thread_pool_attr的第一个值配置成实际上最大客户端连接数的两倍。

  • 本文作者: DarkAthena
  • 本文链接: https://www.darkathena.top/archives/gaussdb-autonomoustransaction-create-timeout-hang
  • 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处

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

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

相关文章

shell脚本第五阶段---shell函数与正则表达式

学习目标掌握case语句的基本语法结构掌握函数的定义以及调用掌握常用的正则表达式元字符含义一、case语句case语句为多选择语句。可以用case语句匹配一个值与一个模式&#xff0c;如果匹配成功&#xff0c;执行相匹配的命令。case var in 定义变量&#xff1b;var代表变量名…

164.在 Vue3 中使用 OpenLayers 加载 Esri 地图(多种形式)

适配&#xff1a;Vue 3 Vite TypeScript&#xff08;也兼容 JS&#xff09; 地图引擎&#xff1a;OpenLayers v10 目标&#xff1a;一次性学会 多种 Esri 底图加载方式、注记叠加、动态切换、令牌&#xff08;Token&#xff09;鉴权、常见坑位排查。一、效果预览二、为什么选…

深入了解Flink核心:Slot资源管理机制

TaskExecutor、Task 和 Slot 简单来说&#xff0c;它们的关系可以比作&#xff1a;TaskExecutor&#xff1a;一个工厂&#xff0c;拥有固定的生产资源。TaskSlot&#xff1a;工厂里的一个工位。每个工位都预先分配了一份独立的资源&#xff08;主要是内存&#xff09;。Task&am…

java web 练习demo。生成简单验证码前端是jsp

目录结构 demo\ ├── WEB-INF\ │ └── weblogic.xml # WebLogic服务器配置文件 ├── demo.iml # IntelliJ IDEA项目配置文件 ├── lib\ # Java EE核心依赖库 │ ├── javax.annotation.jar │ ├── javax.ejb.jar │ ├── javax.…

拥抱智能高效翻译 ——8 款视频翻译工具深度测评

前阵子帮知识博主做跨境视频翻译&#xff0c;踩了不少坑&#xff1a;把 “内卷” 直译成 “involution” 让海外观众困惑&#xff0c;多语种版本赶工 3 天只出 2 种&#xff0c;还得手动核对 “碳中和”“非遗” 这类特色词的译法&#xff1b;用传统工具译完&#xff0c;视频要…

[知识点记录]SQLite 数据库和MySQL 数据库有什么区别?

核心区别&#xff1a;一个“内嵌”&#xff0c;一个“独立”SQLite (你的个人笔记本)本质&#xff1a; 它是“无服务器”的&#xff0c;或者叫“内嵌式”数据库。它不需要一个独立的程序一直在后台运行。你的应用程序&#xff08;比如Strapi&#xff09;直接就能读写它的数据库…

【Spark Core】(二)RDD编程入门

目录1 程序入口&#xff1a;SparkContext对象2 RDD的创建2.1 本地创建2.2 读取文件创建3 RDD算子4 常用Transform算子4.1 map算子4.2 flatMap算子4.3 reduceBykey算子4.4 mapValues算子<实例> WordCount4.5 groupBy算子4.6 filter算子4.7 distinct算子4.8 union算子4.9 j…

java IDEA run/Debug异常:“jdk1.8injava.exe“ CreateProcess error=206, 文件名或扩展名太长

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家、CSDN平台优质创作者&#xff0c;高级开发工程师&#xff0c;数学专业&#xff0c;10年以上C/C, C#,Java等多种编程语言开发经验&#xff0c;拥有高级工程师证书&#xff1b;擅长C/C、C#等开发语言&#xff0c;熟悉Java常用开发…

Java 函数编程之【过滤器filter()合并】【predicate(断言)】与【谓词逻辑】

Java函数式编程之【过滤器filter合并】【predicate&#xff08;断言&#xff09;】与【谓词逻辑】一、合并多个过滤器filter &#xff08;Lambda版本&#xff09;二、合并多个过滤器filter &#xff08;谓词逻辑&#xff08;Predicate&#xff09;版本&#xff09;&#xff08;…

CentOS10安装RabbitMQ

1.下载资源 &#xff08;1&#xff09;下载erlang-rpm 注意&#xff1a;按照图片中的下载&#xff0c;用绿色三角形指向的是重点关注的。 网址&#xff1a; erlang-rpmhttps://github.com/rabbitmq/erlang-rpm/releases &#xff08;2&#xff09;下载rabbitmq-server 注…

JVM——八股文

1. JDK, JRE和JVM的关系JDK JRE Java开发工具JRE JVM Java核心类库JDK供Java程序开发人员开发软件&#xff0c;JRE供客户使用&#xff0c;只需要JVM运行环境即可。JVM运行的是class字节码&#xff0c;不仅能运行Java代码&#xff0c;还能运行其他语言&#xff0c;只要语言能…

骑行把带定期换,维乐 Skin Wrap 把带焕新骑行

在公路骑行的装备体系里&#xff0c;把带是最易被忽视却至关重要的“消耗品”。它是骑手手部与车身的直接连接&#xff0c;每一次转向、变速、刹车&#xff0c;都需通过把带传递力量与操控意图&#xff1b;同时&#xff0c;它还承担着吸汗、减震、保护车把的作用。可长期使用后…

LeetCode100-73矩阵置零

本文基于各个大佬的文章 上点关注下点赞&#xff0c;明天一定更灿烂&#xff01; 前言 Python基础好像会了又好像没会&#xff0c;所有我直接开始刷leetcode一边抄样例代码一边学习吧。本系列文章用来记录学习中的思考&#xff0c;写给自己看的&#xff0c;也欢迎大家在评论区指…

宁波市第八届网络安全大赛 -- Crypto -- WriteUp

宁波市第八届网络安全大赛 – Crypto – WriteUp Three-prime RSA task import gmpy2 from Crypto.Util.number import *from secret import flagp getPrime(512) q getPrime(512) r getPrime(512) n p * q * r random_num getPrime(28) D ((p q r) * random_num) % n …

大语言模型 (LLM) 与多模态大模型 (MLM)

文章目录概述&#xff1a;从“模型”到“大”模型1、大语言模型 (Large Language Model, LLM)1.1 定义与概述关键特征&#xff1a;1.2 核心技术与架构Transformer架构自注意力机制 (Self-Attention)1.3 训练过程1.4 工作原理2. 多模态大模型 (Multimodal Large Model, MLM)2.1 …

HTML应用指南:利用GET请求获取全国招商银行网点位置信息

招商银行&#xff08;China Merchants Bank, CMB&#xff09;作为中国领先的股份制商业银行&#xff0c;始终坚持“以客户为中心”的服务理念&#xff0c;致力于为个人客户、企业客户及机构客户提供专业、高效、便捷的综合金融服务。依托“轻型银行”战略与“金融科技银行”建设…

JVM性能监控工具的使用

了解JVM性能监控工具并能熟练使用&#xff0c;是Java开发者进阶的必备技能。下面本文将为你介绍一些主流的JVM性能监控工具及其使用方法&#xff0c;并通过一些场景案例来分析如何应用这些工具解决实际问题。 &#x1f6e0;️ JVM性能监控与调优工具指南 ✨ 工具概览 以下是几款…

【工作】一些找工作需要了解避雷的知识

面试前 1.公司的具体情况 公司全称&#xff0c;办公地点&#xff0c;涉及岗位 要求hr做个简单的公司介绍 2.岗位职责/业务方向 工作内容、公司业务 3.薪资待遇&#xff0c;构成&#xff0c;底薪&#xff0c;五险一金 问一下工资范围 底薪 &#xff08;有责&#xff0c;无…

五、练习2:Git分支操作

练习2&#xff1a;Git分支操作 练习目标 掌握Git分支的创建、切换、合并等操作&#xff0c;理解分支在开发中的作用。 练习步骤 步骤1&#xff1a;准备基础仓库 # 创建练习目录 mkdir branch-practice cd branch-practice# 初始化仓库 git init# 创建初始文件 echo "# 分支…

【笔记】算法设计:异或空间线性基

Content1.什么是异或&#xff08;定义和性质&#xff09;2.异或空间线性基的构造方法3.异或空间线性基的应用4.算法设计例举5.小结说明算法设计应用之前&#xff0c;首先明确异或空间线性基&#xff1a;一种数据结构。用于处理异或关系&#xff08;运算&#xff09;下的向量空间…