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

循序渐进丨MogDB 数据库新特性之SQL PATCH绑定执行计划

1

SQL PATCH

熟悉 Oracle 的DBA都知道,生产系统出现性能问题时,往往是SQL走错了执行计划,紧急情况下,无法及时修改应用代码,DBA可以采用多种方式针对于某类SQL进行执行计划绑定,比如SQL Profile、SPM、SQL Plan Base等等。

MogDB 数据库5.0版本引入了SQL PATCH的特性,SQL PATCH能够在避免直接修改用户业务语句的前提下对查询执行的方式做一定调整。在发现查询语句的执行计划、执行方式未达预期的场景下,可以通过创建查询补丁的方式,使用Hint对查询计划进行调优或对特定的语句进行报错短路处理。

SQL PATCH主要设计给DBA、运维人员及其他需要对SQL进行调优的角色使用,用户通过其他运维视图或定位手段识别到业务语句存在计划不优导致的性能问题时,可以通过创建SQL PATCH对业务语句进行基于Hint的调优。目前支持行数、扫描方式、连接方式、连接顺序、PBE custom/generic计划选择、语句级参数设置、参数化路径的Hint。

特性约束

    • 仅支持针对Unique SQL ID打PATCH,如果存在Unique SQL ID冲突,用于Hint调优的SQL PATCH可能影响性能,但不影响语义正确性。

    • 仅支持不改变SQL语义的Hint作为PATCH,不支持SQL改写。

    • 不支持逻辑备份、恢复。

    • 不支持创建时校验PATCH合法性,如果PATCH的Hint存在语法或语义错误,不影响查询正确执行。

    • 仅初始用户、运维管理员、监控管理员、系统管理员用户有权限执行;库之间不共享,创建SQL PATCH时需要连接目标库。

    • 配置集中式备机可读时,需要指定主机执行SQL PATCH创建/修改/删除函数调用,备机执行报错。

    • SQL PATCH同步给备机存在一定延迟,待备机回放相关日志后PATCH生效。

    • 不支持对存储过程中的SQL语句生效,当前机制不会对存储过程内语句生成Unique SQL ID。

    • 用于规避的Abort Patch不建议在数据库中长期使用,只应该作为临时规避方法;遇到内核问题所导致的特定语句触发数据库服务不可用问题,需要尽快修改业务或升级内核版本解决问题;并且升级后由于Unique SQL ID生成方法可能变化,可能导致规避方法失效。

    • 当前,除DML语句之外,其他SQL语句(如CREATE TABLE等)的Unique SQL ID是对语句文本直接哈希生成的,所以对于此类语句,SQL PATCH对大小写、空格、换行等敏感,即不同的文本的语句,即使语义相对,仍然需要对应不同的SQL PATCH;对于DML,则同一个SQL PATCH可以对不同入参的语句生效,并且忽略大小写和空格。

依赖关系

需要开启enable_resource_track参数并且设置instr_unique_sql_count大于0。对于不同的语句,如果生成的Unique SQL ID冲突,会导致SQL PATCH错误地命中预期外的其他语句。其中用于调优的Hint PATCH副作用相对较小,Abort Patch需要谨慎使用。

2

实际案例

1、创建表

创建表t1和t2;

 
create table t1(name char(10),id int);
create table t2(name char(10),id int);

2、构造数据

 
INSERT INTO t1 (name, id)
SELECT 'data_'|| generate_series(1, 1000), generate_series(1, 1000);INSERT INTO t2 (name, id)
SELECT 'data_'|| generate_series(1, 1000), generate_series(1, 1000);CREATE INDEX idx_t1 ON t1 (id);
CREATE INDEX idx_t2 ON t2 (id);

3、获取unique_query_id

执行SQL并获取unique_query_id、执行计划:

 
set track_stmt_stat_level = 'L1,L1'; --track_stmt_stat_level解释:
该参数分为两部分:
--形式为'full sql stat level, slow sql stat level'。
--级别(L2 > L1 > L0),L1在L0的基础上记录了执行计划,L2在L1的基础上记录了锁的详细信息select * from t1 a, t2 b where a.id = b.id;name    |  id  |    name    |  id  
------------+------+------------+------data_1     |    1 | data_1     |    1data_2     |    2 | data_2     |    2data_3     |    3 | data_3     |    3data_4     |    4 | data_4     |    4data_5     |    5 | data_5     |    5data_6     |    6 | data_6     |    6data_7     |    7 | data_7     |    7。。。。
(1000 row)

4、获取查看执行计划

走的全表扫描hash jion执行计划:

 
explain select * from t1 a, t2 b where a.id = b.id;QUERY PLAN  
--------------------------------------------------------------------------Aggregate  (cost=60.75..60.76 rows=1 width=8)->  Hash Join  (cost=28.50..58.25 rows=1000 width=0)Hash Cond: (a.id = b.id)->  Seq Scan on t1 a  (cost=0.00..16.00 rows=1000 width=4)->  Hash  (cost=16.00..16.00 rows=1000 width=4)->  Seq Scan on t2 b  (cost=0.00..16.00 rows=1000 width=4)

5、查询unique_query_id

 
select unique_query_id,query,start_time from dbe_perf.statement_history  where query like '%from t1 a%';unique_query_id |                       query                        |          start_time           
-----------------+----------------------------------------------------+-------------------------------3366573496 | select * from t1 a, t2 b where a.id = b.id;        | 2024-01-19 10:08:56.994391+08也可以通过statement_history查询执行计划
select start_time,query_plan  from dbe_perf.statement_history  where unique_query_id = 3366573496;start_time           |                                query_plan                                
-------------------------------+--------------------------------------------------------------------------2024-01-19 10:08:56.994391+08 | Datanode Name: dn_6001_6002                                        +| Hash Join  (cost=28.50..58.25 rows=1000 width=30)                  +|   Hash Cond: (a.id = b.id)                                         +|   ->  Seq Scan on t1 a  (cost=0.00..16.00 rows=1000 width=15)      +|   ->  Hash  (cost=16.00..16.00 rows=1000 width=15)                 +|         ->  Seq Scan on t2 b  (cost=0.00..16.00 rows=1000 width=15)+|                                                                    +

6、SQL PATCH绑定执行计划

 
call dbe_sql_util.create_hint_sql_patch('enmo patch',3366573496,'indexscan(a)');create_hint_sql_patch 
-----------------------t
(1 row)--参数说明:
enmo patch --SQL PATCH name
3366573496 --unique_query_id
indexscan(a) --Hint文本

7、验证SQL PATCH

 

执行并检查新的执行计划是否生效:

select * from t1 a, t2 b where a.id = b.id;name    |  id  |    name    |  id  
------------+------+------------+------data_1     |    1 | data_1     |    1data_2     |    2 | data_2     |    2data_3     |    3 | data_3     |    3data_4     |    4 | data_4     |    4data_5     |    5 | data_5     |    5data_6     |    6 | data_6     |    6data_7     |    7 | data_7     |    7。。。。explain select * from t1 a, t2 b where a.id = b.id;
NOTICE:  Plan influenced by SQL hint patchQUERY PLAN                                  
------------------------------------------------------------------------------Hash Join  (cost=28.50..86.50 rows=1000 width=30)Hash Cond: (a.id = b.id)->  Index Scan using idx_t1 on t1 a  (cost=0.00..44.25 rows=1000 width=15) --这里走了索引,表示SQL patch生效->  Hash  (cost=16.00..16.00 rows=1000 width=15)->  Seq Scan on t2 b  (cost=0.00..16.00 rows=1000 width=15)
(5 rows)

查看statement_history的执行计划:

select query_plan,to_char(start_time,'yyyymmdd-hh24:mi:ss') starttime
from dbe_perf.statement_history 
where unique_query_id = 3366573496
order by start_time;Datanode Name: dn_6001_6002                                                 +| 20240119-10:09:54Hash Join  (cost=28.50..86.50 rows=1000 width=30)                           +| Hash Cond: (a.id = b.id)                                                  +| ->  Index Scan using idx_t1 on t1 a  (cost=0.00..44.25 rows=1000 width=15)+| ->  Hash  (cost=16.00..16.00 rows=1000 width=15)                          +| ->  Seq Scan on t2 b  (cost=0.00..16.00 rows=1000 width=15)         +| +| |

查看数据库内已定义的SQL Patch:

select patch_name,unique_sql_id,enable,hint_string from gs_sql_patch;patch_name | unique_sql_id | enable | hint_string  
------------+---------------+--------+--------------enmo patch |    3366573496 | t      | indexscan(a)show_sql_patch查看SQL PATCH内容
MogDB=# select  DBE_SQL_UTIL.show_sql_patch('enmo patch');show_sql_patch            
-------------------------------------(3366573496,t,f,"indexscan(a)")
(1 row)

8、Abort Patch

使用Abort PATCH对特定语句进行提前报错规避:

 
MogDB=# select * from dbe_sql_util.drop_sql_patch('enmo patch'); -- 删去enmo patchdrop_sql_patch
----------------t
(1 row)
MogDB=# select * from dbe_sql_util.create_abort_sql_patch('patch2', 3366573496); -- 对该语句的Unique SQL ID创建Abort Patchcreate_abort_sql_patch
------------------------t
(1 row)MogDB=# select * from t1 a, t2 b where a.id = b.id; -- 再次执行语句会提前报错
ERROR:  Statement 3366573496 canceled by abort patch patch2

9、关闭特定SQL Patch

 
disable enmo patch
call dbe_sql_util.disable_sql_patch('enmo patch');

执行SQL并检查执行计划是否恢复原始状态:

MogDB=# select  query_plan,to_char(start_time,'yyyymmdd-hh24:mi:ss') starttime
MogDB-#  from dbe_perf.statement_history 
MogDB-#  where  unique_query_id = 3366573496
MogDB-#  order by start_time;query_plan                                |     starttime     
--------------------------------------------------------------------------+-------------------Datanode Name: dn_6001_6002                                             +| 20240119-13:24:52Nested Loop  (cost=0.00..340.00 rows=1000 width=30)                     +| ->  Seq Scan on t1 a  (cost=0.00..16.00 rows=1000 width=15)           +| ->  Index Scan using idx_t2 on t2 b  (cost=0.00..0.31 rows=1 width=15)+| Index Cond: (id = a.id)                                         +| +| | Datanode Name: dn_6001_6002                                             +| 20240119-13:31:49Hash Join  (cost=28.50..58.25 rows=1000 width=30)                       +| Hash Cond: (a.id = b.id)                                              +| ->  Seq Scan on t1 a  (cost=0.00..16.00 rows=1000 width=15)           +| ->  Hash  (cost=16.00..16.00 rows=1000 width=15)                      +| ->  Seq Scan on t2 b  (cost=0.00..16.00 rows=1000 width=15)     +| +|

最新的执行计划已经还原成hash jion。

MogDB 数据库官方文档参考:

    • SQL PATCH特性描述:https://docs.mogdb.io/zh/mogdb/v5.0/sql-patch#特性描述

    • track_stmt_stat_level:https://docs.mogdb.io/zh/mogdb/v5.0/query#track_stmt_stat_level

关于作者

许玉晨,云和恩墨 MogDB 技术支持工程师,有12年左右的金融、保险、政府、地税、运营商等业务关键型系统的运维经验,曾担任公司异常恢复东区接口人,负责紧急异常恢复工作,目前负责国产化MogDB数据库的推广工作。

8d11367cc484ec24d340be1b5b3eacae.gif

数据驱动,成就未来,云和恩墨,不负所托!


云和恩墨创立于2011年,以“数据驱动,成就未来”为使命,是智能的数据技术提供商。我们致力于将数据技术带给每个行业、每个组织、每个人,构建数据驱动的智能未来。

云和恩墨在数据承载(分布式存储、数据持续保护)、管理(数据库基础软件、数据库云管平台、数据技术服务)、加工(应用开发质量管控、数据模型管控、数字化转型咨询)和应用(数据服务化管理平台、数据智能分析处理、隐私计算)等领域为各个组织提供可信赖的产品、服务和解决方案,围绕用户需求,持续为客户创造价值,激发数据潜能,为成就未来敏捷高效的数字世界而不懈努力。

cb4ee4c75b07a8aa336d301e56042a5c.gif

相关文章:

循序渐进丨MogDB 数据库新特性之SQL PATCH绑定执行计划

1 SQL PATCH 熟悉 Oracle 的DBA都知道,生产系统出现性能问题时,往往是SQL走错了执行计划,紧急情况下,无法及时修改应用代码,DBA可以采用多种方式针对于某类SQL进行执行计划绑定,比如SQL Profile、SPM、SQL …...

【论文阅读随笔】RoPE/旋转编码:ROFORMER: ENHANCED TRANSFORMER WITH ROTARY POSITION EMBEDDING

文章目录 1.目的:通过绝对位置编码的方式实现相对位置编码2.理解RoPE,在我看来有几个需要注意的点:3.本文相关复数概念:3.1.复数乘法的几何意义3.2.复数内积 VS. 复数乘法 4.REF: 1.目的:通过绝对位置编码的…...

数据挖掘

一.数据仓库概述: 1.1数据仓库概述 1.1.1数据仓库定义 数据仓库是一个用于支持管理决策的、面向主题、集成、相对稳定且反映历史变化的数据集合。 1.1.2数据仓库四大特征 集成性(Integration): 数据仓库集成了来自多个不同来源…...

java SSM旅游景点与公交线路查询系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM旅游景点与公交线路查询系统是一套完善的web设计系统(系统采用SSM框架进行设计开发,springspringMVCmybatis),对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系…...

解决Git报错:fatal: detected dubious ownership in repository at

在通过 Git Bash 提交项目代码时输入 git add . 命令后,报错:fatal: detected dubious ownership in repository at 这是因为该项目的所有者与现在的用户不一致 比如说: 该项目的所有者是 Administrator,而当前用户是 YuYang, 那…...

网络协议常见问题

网络协议常见问题 OSI(Open Systems Interconnection)模型OSI 封装 TCP/IP协议栈IP数据报的报头TCP头格式UDP头格式TCP (3-way shake)三次握手建立连接:为什么三次握手才可以初始化 Socket、序列号和窗口大小并建立 TCP 连接。每次建立TCP连接…...

人工智能的迷惑行为

目录 前言1 人工智能的“幽默”瞬间1.1 语义误解1.2 逻辑错误 2 技术原理探究2.1 算法设计缺陷2.2 数据处理不当 3 社会影响分析3.1 信任度下降3.2 技术担忧 结语 前言 随着人工智能技术的迅猛发展,各类AI大模型如ChatGPT、文心一言、通义千问等纷纷登场&#xff0…...

XR技术:短剧制作的全新纪元

在数字技术的浪潮中,XR(扩展现实)技术以其独特的魅力,正在为短剧制作带来革命性的突破。这种融合了虚拟现实、增强现实和混合现实等先进技术的创新工具,正逐渐改变着短剧制作的传统模式,引领着短剧艺术走向…...

安卓 OpenGL ES 学习笔记

文章目录 OpenGL 学习笔记OpenGL 是什么?OpenGL ES是什么?怎么用?hello world如何实现动画效果 参考文章 OpenGL 学习笔记 OpenGL 是什么? OpenGL(Open Graphics Library)是一个跨平台的图形编程接口&…...

git分布式管理-头歌实验冲突处理、忽略文件

一、解决冲突 任务描述 在团队协作开发过程中,可能你和团队中的其他成员,都修改了某个文件的某一部分内容,且其他成员已将该修改推送到了远程仓库。这样当你需要合并他的代码的时候,可能就会在内容上出现冲突,这个时候…...

【实战项目】网络编程:在Linux环境下基于opencv和socket的人脸识别系统--C++实现

🌞前言 这里我们会实现一个项目:在linux操作系统下基于OpenCV和Socket的人脸识别系统。 目录 🌞前言 🌞一、项目介绍 🌞二、项目分工 🌞三、项目难题 🌞四、实现细节 🌼4.1 关…...

零售EDI:劳氏 Lowe‘s EDI项目案例

通过 EDI,企业与Lowes之间可以直接交换各种商业文档,如订单、发票、收据等,从而实现信息的实时交换,提高了供应链的效率和准确性。在现代供应链管理中,EDI 已经成为了不可或缺的重要工具。 作为一家拥有多条业务线的企…...

为什么不用 index 做 key?

“在 Vue 中,我们在使用 v-for 渲染列表的时候,为什么要绑定一个 key?能不能用 index 做 key?” 在聊这个问题之前我们还得需要知道 Vue 是如何操作 DOM 结构的。 虚拟DOM 我们知道,Vue 不可以直接操作 DOM 结构&am…...

Linux虚拟机安装Redis

官网下载压缩包:官网链接,然后将对应的tar.gz压缩包放入虚拟机下的/opt目录下。由于redis是C语言开发的,因此需要安装gcc编译器来编译代码,我们下载的压缩包里面是源代码,需要编译。通过yum install gcc指令下载C语言的…...

网络安全: Kali Linux 进行 SSH 渗透与防御

目录 一、实验 1.环境 2.nmap扫描目标主机 3.Kali Linux 进行 SSH 渗透 3.Kali Linux 进行 SSH 防御 二、问题 1.SSH有哪些安全配置 一、实验 1.环境 (1)主机 表1 主机 系统版本IP备注Kali Linux2022.4 192.168.204.154(动态&…...

近年来文本检测相关工作梳理

引言 场景文本检测任务,一直以来是OCR整个任务中最为重要的一环。虽然有一些相关工作是端对端OCR工作的,但是从工业界来看,相关落地应用较为困难。因此,两阶段的OCR方案一直是优先考虑的。 在两阶段中(文本检测文本识…...

文件系统事件监听

文件系统事件和网络IO事件一样,也可以通过epoll或者IOCP 事件管理器统一调度,当所监控的文件或文件夹发生了增删改的事件时,就会触发事件回调,进行事件处理。很常见的应用,如配置文件立即生效功能,就可以通…...

探秘HTTPS:如何通过SSL/TLS保证网络通信安全

目录 引言 详解HTTPS加密实现机制 SSL/TLS工作原理 结论 引言 随着网络安全威胁的日益增加,HTTPS通过SSL(Secure Sockets Layer)和TLS(Transport Layer Security)协议提供的加密技术变得至关重要。这些技术保证了用…...

Java算法之动态规划

Java算法之动态规划 前言 ​ 最近这一段时间一直在刷算法题,基本上一有时间就会做一两道,这两天做了几道动态规划的问题,动态规划之前一直是我比较头疼的一个问题,感觉好复杂,一遇到这样的问题就想跳过,昨…...

C++从零开始的打怪升级之路(day47)

这是关于一个普通双非本科大一学生的C的学习记录贴 在此前,我学了一点点C语言还有简单的数据结构,如果有小伙伴想和我一起学习的,可以私信我交流分享学习资料 那么开启正题 今天分享的是关于set和map的知识点 1.关联式容器 在前面&#…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子&#xff08…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

大话软工笔记—需求分析概述

需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

Java面试专项一-准备篇

一、企业简历筛选规则 一般企业的简历筛选流程&#xff1a;首先由HR先筛选一部分简历后&#xff0c;在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如&#xff1a;Boss直聘&#xff08;招聘方平台&#xff09; 直接按照条件进行筛选 例如&#xff1a…...