基于日志或 gv$sql_audit 分析 OB 异常重试 SQL

news2024/11/15 18:02:12

本文以 SQL 异常重试场景为例,使用基于 日志文件 和 gv$sql_aduit 视图 这两种方式,找出具体的报错原因。

作者:郑增权,爱可生 DBA 团队成员,OceanBase 和 MySQL 数据库技术爱好者。

爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。

本文约 2000 字,预计阅读需要 8 分钟。

简介

我们在 OCP 云平台 Top SQL 界面看到一些异常 SQL,但并未提示具体报错原因或提示了原因但不够详细。

本文以 SQL 异常重试场景为例,使用基于 日志文件gv$sql_aduit 视图 这两种方式,找出具体的报错原因。

本文更推荐 PC 端浏览~

背景

  1. OceanBase 3.X 企业版 MySQL 模式
  2. 某客户在性能压测过程中反馈,在对某张表 UPDATE 时响应缓慢,一直无法执行成功。
  3. gv$sql_aduit 关于此 SQL 相关信息已被清理,且 Top SQL 未提示报错具体原因,只能基于日志文件进行排查。
  4. OCP 云平台查看初始状态如下:
    • UPDATE 语句重试 440 次
    • 平均响应时间为 5491.15 ms

  1. 文中后半部分对此场景进行延伸。
    • 假设 SQL 正处于异常重试状态中,且关联的 gv$sql_audit 视图信息未被清除的情况下,如何展开排查提供思路。

排查过程

1. 导出 Top SQL

列管理 按需勾选需查看的信息(如:SQL ID,重试次数)。

2. 复制 SQL 文本

3. 查找 UPDATE 语句

在对应的服务器上 grep 此 SQL 语句的打印次数:

  • 结果为 1 小时内执行了 505 次,判断针对该行数据的 UPDATE 行为可能存在异常。
  • 日志打印 SQL 次数可能与 Top SQL 不同,大致对应上即可。
  • 一般异常 SQL 会在 observer.log 中打印,正常执行完成的可能不会存在记录。
# grep -i "UPDATE evan.evan_zheng SET name = 'test0409' WHERE id = 1" observer.log.2024040916* | wc -l
505

4. 查找错误位置

SQL 语句ret= 作为条件进行检索,看是否存在相关错误码。

  • 若 SQL 文本无法精准匹配,则只复制部分关键字。
  • 可以看到 40126003 等超时相关错误码。
  • 复制一条 trace id 用于检索
# grep -i "UPDATE evan.evan_zheng SET name = 'test0409' WHERE id = 1" observer.log.2024040916* | grep "ret="

5. 查看报错信息

检索 trace_id,查看主要报错信息。

  • 写写冲突:on_wlock_retry、lock_for_write conflict
  • 错误码:6005
  • 更新某行数据失败:failed to update row (xxx)

6. 写写冲突部分日志

#  grep -i "YB420ABA40A1-000615A29EDEEA36-0-0" observer.log.2024040916* | grep "lock_for_write conflict"

点击放大

7. 确认行为

确认此 trace_id 关联的 SQL 存在重试行为。

# grep -i "YB420ABA40A1-000615A29EDEEA36-0-0" observer.log.2024040916* | grep -i "will retry"

8. 错误码含义

错误码 6005:更新操作加锁失败

错误码 6003:等待锁超时

错误码 6212:SQL 语句超时

对于语句超时的情况,首先要确定当前租户下 ob_query_timeout 变量设置,然后根据 trace_id 搜索 observer.log 日志,找到当前语句的 cur_query_start_time

如果 超时时间点cur_query_start_time = ob_query_timeout,说明是符合预期的。下面来验证一下。

  1. 查询租户变量 ob_query_timeout 为 10s。

  1. observer.log 中检索此 trace_id 的起始时间。

开始时间:

# grep -i "YB420ABA40A1-000615A29EDEEA36-0-0" observer.log.20240409* | grep -m 1 "cur_query_start_time"

超时时间:

# grep -i "YB420ABA40A1-000615A29EDEEA36-0-0" observer.log.20240409* | grep "timeout_timestamp" | tail -n 1

可以看到超时时间减去开始时间等于 10s,说明此处超时行为符合预期。

问题总结

当执行 SQL UPDATE evan.evan_zheng SET name = 'test0409' WHERE id = 1; 更新操作加锁失败,达到当前租户 ob_query_timeout 变量设置的值(10s)触发 6212 报错(语句超时)回滚语句。

可能造成此问题的原因:

  1. 业务使用了较大的超时时间,且存在一个会话中的未知长事务持有锁,阻塞了其他事务的执行。
  2. 开发人员并发更新同一行数据,并发处理逻辑存在错误。

优化措施

  1. 合理设置超时变量时间。
  2. 合理设置程序代码并发控制逻辑。
  3. 关注长事务告警。

延伸场景

如果 SQL 正在持续重试中,且 gv$sql_audit 视图信息未被清除,可参考如下步骤进行排查。

1. OCP 云平台,复制 SQL ID

2. 基于 SQL ID 查看主要的错误代码

可以看到 40126003 等超时相关错误码。

select
  /*+ PARALLEL(8)*/
  trace_id,
  sid,
  tenant_name,
  svr_ip,
  svr_port,
  retry_cnt,
  ret_code,
  query_sql,
  usec_to_time(request_time) as start_time
from
  gv$sql_audit
where
  sql_id = 'D884EA797E73F466819BAE2AE4AC1FE1'
  and retry_cnt > 1
group by
  ret_code
order by
  retry_cnt desc;

3. 查看 session_id

select
  /*+ PARALLEL(8)*/
  trace_id,
  sid,
  tenant_name,
  svr_ip,
  svr_port,
  retry_cnt,
  ret_code,
  query_sql,
  usec_to_time(request_time) as start_time
from
  gv$sql_audit
where
  sql_id = 'D884EA797E73F466819BAE2AE4AC1FE1'
group by
  sid
order by
  request_time desc;

4. 查询 table_id

select
  database_name,
  table_id,
  table_name,
  tenant_id,
  tenant_name
from
  oceanbase.gv$table
where
  tenant_id = 1001
  and database_name = 'evan'
  and table_name = 'evan_zheng';

5. 查询锁持有者事务信息

使用 sys 租户执行。

select * from __all_virtual_trans_lock_stat where table_id = '1100611139453778'\G

6. 查询锁等待者事务信息

使用 sys 租户执行。

可以看到此处 session_idgv$sql_audit 查询出来的是一致的(即,异常重试的 SQL 的会话)。

select * from __all_virtual_lock_wait_stat where table_id = '1100611139453778'\G

7. 查询锁持有者 session 的 SQL

select
  trace_id,
  usec_to_time(request_time),
  query_sql
from
  gv$sql_audit
where
  TENANT_ID = 1001
  AND USER_NAME = 'root'
  AND SID = '3221616444'
order by
  request_time desc;

8. 查看锁等待者 session 的 SQL

select
  trace_id,
  usec_to_time(request_time),
  query_sql
from
  gv$sql_audit
where
  TENANT_ID = 1001
  AND USER_NAME = 'root'
  AND SID = ' 3221618060'
order by
  request_time desc;

可以看到锁持有者的会话和锁等待者的会话都针对表 evan_zhengid=1 的字段进行更新,由于锁持有者开启了手动提交且未进行提交导致锁等待者持续重试 UPDATE 操作。

9. KILL 锁持有者会话

解决方法:经确认风险后,kill 锁持有者会话。

进一步分析可参考前方步骤,结合 observer.log 等信息进行分析。

其他错误码

通过如下几个错误码可以判断 SQL 超时原因(语句超时/事务超时/事务空闲超时):

  • 系统变量 ob_query_timeout 该变量控制着语句执行时间的上限,语句执行时间超过此值会给应用返回语句超时的错误,错误码为 6212,并回滚语句,通常该值默认为 10s。
  • 系统变量 ob_trx_timeout 该变量控制着事务超时时间,事务执行时间超过此值会给应用返回事务超时的错误,错误码为 6210,此时需要应用发起 ROLLBACK 语句回滚该事务。
  • 系统变量 ob_trx_idle_timeout 该变量表示 session上一个事务处于的 IDLE 状态的最长时间,即长时间没有 DML 语句或结束该事务。超过该时间值后,事务会自动回滚。再执行 DML 语句会给应用返回错误码 6224,应用需要发起 ROLLBACK 语句清理 session 状态。

参考资料

  1. 《OceanBase 数据库日志解读示例》https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000207691
  2. 《OceanBase 数据库事务问题排查指南》https://www.oceanbase.com/knowledge-base/oceanbase-database-20000000026
  3. 《OceanBase 数据库中的行锁问题排查指南》https://www.oceanbase.com/knowledge-base/oceanbase-database-20000000016
  4. 《事务控制概述》https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000642694

更多技术文章,请访问:https://opensource.actionsky.com/

关于 SQLE

SQLE 是一款全方位的 SQL 质量管理平台,覆盖开发至生产环境的 SQL 审核和管理。支持主流的开源、商业、国产数据库,为开发和运维提供流程自动化能力,提升上线效率,提高数据质量。

SQLE 获取

类型地址
版本库https://github.com/actiontech/sqle
文档https://actiontech.github.io/sqle-docs/
发布信息https://github.com/actiontech/sqle/releases
数据审核插件开发文档https://actiontech.github.io/sqle-docs/docs/dev-manual/plugins/howtouse

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

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

相关文章

1941springboot VUE 服务机构评估管理系统开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 springboot VUE服务机构评估管理系统是一套完善的完整信息管理类型系统,结合springboot框架和VUE完成本系统,对理解JSP java编程开发语言有帮助系统采用springboot框架(MVC模式开发),系统具有完整的源代…

深入解读HTTP状态码:分类、含义、应用场景与故障排查指南

HTTP状态码作为超文本传输协议(HTTP)响应的重要组成部分,为客户端与服务器之间的交互提供了清晰的状态反馈。本文将全面展开对HTTP状态码的深入解读,涵盖其分类、具体含义、典型应用场景以及在故障排查中的实用价值,旨在帮助开发者与运维人员更好地理解和应对各类HTTP响应…

冯喜运:5.24黄金今日能否回调?日内国际黄金美原油操作策略

【黄金消息面分析】:在过去的半个世纪里,美国国债作为买入持有的投资手段,轻松超越了黄金。然而,如今债券作为终极避险资产的地位正面临着前所未有的挑战。传统上,投资者将美国国债视为一种超安全的投资,因…

[emailprotected](7)父子通信,传递元素内容

目录 1,children 属性2,多个属性 普通对象等,可以通过变量直接传递,那类似 vue 中的 slot 插槽,如何传递元素内容? 1,children 属性 实际上,写在自定义组件标签的内部代码&#xf…

express.js--连接数据库,并且增删改查(四)

使用数据库需要在电脑安装mysql,然后使用navicat 我没有下载mysql,我使用的是小皮里面的数据库,需要破解版的navicat可以私信我 安装mysql npm i mysql 数据库的基本信息,我是直接写到配置文件里面的 config/index.js module.exports {…

css扇形菜单动画效果

菜单组件 IntelligentAnalysis.vue 中间圆形区域可以换个图片 <template><div class"intel-analysis"><div class"info" :class"{ close-animation: !showMenu }"><div class"middle"></div><div cl…

win11安装MySQL

目录[-] 1. 1. 下载2. 2. 安装 参考文档&#xff1a;MySQL :: MySQL 8.4 Reference Manual 1. 下载 mysql官网下载msi安装程序&#xff1a;MySQL :: Begin Your Download 2. 安装 运行下载的mis程序,逐步安装。 安装模式&#xff1a; complete; 进入配置&#xff1a; data di…

声明式管理方法

一.方法 1.适合于对资源的修改操作 2.声明式资源管理方法依赖于资源配置清单文件对资源进行管理 资源配置清单文件有两种格式&#xff1a;yaml&#xff08;人性化&#xff0c;易读&#xff09;&#xff0c;json&#xff08;易于api接口解析&#xff09; 3.对资源的管理&#x…

第06章 数据加载、存储与文件格式

以下内容参考自https://github.com/iamseancheney/python_for_data_analysis_2nd_chinese_version/blob/master/%E7%AC%AC05%E7%AB%A0%20pandas%E5%85%A5%E9%97%A8.md 《利用Python进行数据分析第2版》 用以学习和记录。 输入输出通常可以划分为几个大类&#xff1a;读取文本文…

代码随想录--哈希表--有效的字母异位词

题目 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 示例 1: 输入: s “anagram”, t “nagaram” 输出: true 示例 2: 输入: s “rat”, t “car” 输出: false 说明: 你可以假设字符串只包含小写字母。 思路 先看暴力的解法&am…

Github 2024-05-23 开源项目日报 Top10

根据Github Trendings的统计,今日(2024-05-23统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目3TypeScript项目2非开发语言项目1Java项目1Shell项目1Jupyter Notebook项目1JavaScript项目1Java设计模式:提高开发效率的正规化实践…

适合企业的通配符https证书

通配符https证书&#xff0c;也被称为泛域名https证书&#xff0c;是一种可以保护主域名及其所有子域名的数字证书产品。通配符https证书由证书颁发机构(CA)签发&#xff0c;为http明文传输协议加上安全套接层&#xff0c;加密客户端与服务器之间传输的信息&#xff0c;为网站访…

Java方法的递归

Java方法的递归 前言一、递归的概念示例代码示例 二、递归执行过程分析代码示例执行过程图 三、递归练习代码示例按顺序打印一个数字的每一位(例如 1234 打印出 1 2 3 4)递归求 1 2 3 ... 10写一个递归方法&#xff0c;输入一个非负整数&#xff0c;返回组成它的数字之和. …

stm32学习-光敏传感器控制蜂鸣器

接线 GPIO配置 初始化GPIO 1.使用RCC开启GPIO时钟 void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); 作用&#xff1a;外设时钟控制(根据外设连接的总线选择要开启的时钟&#xff09; RCC_AHBPeriph/RCC_APB2Periph/RCC_APB1Periph&#x…

基于EifficientNet的视网膜病变识别

分析一下代码 model.py ①下面这个方法的作用是&#xff1a;将传入的ch&#xff08;channel&#xff09;的个数调整到离它最近的8的整数倍&#xff0c;这样做的目的是对硬件更加友好。 def _make_divisible(ch, divisor8, min_chNone):if min_ch is None:min_ch divisornew…

学习Uni-app开发小程序Day23

今天学习了将上一章的所有核算的js&#xff0c;抽离出去&#xff0c;让在其他地方可以直接调用&#xff0c;然后和适配抖音的办法&#xff0c;封装网络请求&#xff1b; 抽离公共方法 如何将公共方法抽离&#xff1f; 1、在根目录创建一个目录&#xff0c;一般起名是:utils 2…

谷歌快速收录怎么做?

快速收录顾名思义&#xff0c;就是让新的的网页内容能够迅速被谷歌搜索引擎抓取、索引和显示在搜索结果中&#xff0c;这对于做seo来说非常重要&#xff0c;因为它有助于新发布的内容尽快出现在谷歌的搜索结果中&#xff0c;从而增加网站的流量 想做谷歌快速收录谷歌推荐了几种…

告别硬编码:Spring条件注解优雅应对多类场景

一、背景 在当今的软件开发中&#xff0c;服务接口通常需要对应多个实现类&#xff0c;以满足不同的需求和场景。举例来说&#xff0c;假设我们是一家2B公司&#xff0c;公司的产品具备对象存储服务的能力。然而&#xff0c;在不同的合作机构部署时&#xff0c;发现每家公司底…

每天五分钟深度学习框架PyTorch:创建具有特殊值的tensor张量

本文重点 tensor张量是一个多维数组,本节课程我们将学习一些pytorch中已经封装好的方法,使用这些方法我们可以快速创建出具有特殊意义的tensor张量。 创建一个值为空的张量 import torch import numpy as np a=torch.empty(1) print(a) print(a.dim()) print(s.shape) 如图…

python3如何查看是32位还是64位

在安装一些python的软件包时&#xff0c;经常安装错误&#xff0c;可能是跟python的位数有关系。 下面告诉大家如何查看python的位数。 第一种方法&#xff1a;通过在cmd中输入“python”即可。 第二种方法&#xff1a;通过platform包查看&#xff0c;首先导入platform包&…