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

达梦数据库-学习-10-SQL 注入 HINT 规则(固定执行计划)

目录

一、环境信息

二、简述

三、参数介绍

四、存过介绍

1、SF_INJECT_HINT

(1)声明

(2)存过说明

(3)注意

(4)参数含义

(5)返回值

2、SF_ALTER_HINT

(1)声明

(2)存过说明

(3)注意

(4)参数含义

(5)返回值

3、SF_DEINJECT_HINT

(1)声明

(2)存过说明

(3)注意

(4)参数含义

(5)返回值

五、视图介绍

1、SYSINJECTHINT

六、虚机实验

1、开启参数

2、测试SQL

3、注入HINT

4、查看视图

5、验证SQL

6、设置当前会话不生效

7、查看视图

8、测试SQL

9、会话级修改参数SQLTUNE_CATEGORY

10、验证SQL

11、删除注入HINT

12、验证是否删除


一、环境信息

名称
CPU12th Gen Intel(R) Core(TM) i7-12700H
操作系统CentOS Linux release 7.9.2009 (Core)
内存2G
逻辑核数2
DM版本1          DM Database Server 64 V8
2          DB Version: 0x7000c
3          03134284194-20240703-234060-20108
4          Msg Version: 12
5          Gsu level(5) cnt: 0

二、简述

在客户现场我们经常遇到生产环境慢SQL的问题,生产环境不可改应用(把等价改写和的路子堵死了),加索引计划中不走,指定HINT后计划变优,但不可改应用,所以这个方法也被毙掉了。SQL 注入 HINT 规则的优势就来了,可以在不修改SQL的情况下,注入HINT来影响执行计划。

三、参数介绍

参数名默认值级别描述
ENABLE_INJECT_HINT0动态会
话级
是否启用 SQL 指定 HINT 的功能。

0:不启用;

1:启用;
SQLTUNE_CATEGORYDEFAULT动态会话级限制本会话中被允许使用的 SQL 配置(包括为 SQL 注入的 HINT 规则)的生效类别。

当 SQL 配置存在生效类别限制且和本会话的 SQLTUNE_CATEGORY 不一致时,该 SQL 配置在本会话不生效

四、存过介绍

1、SF_INJECT_HINT

(1)声明

VARCHAR
SF_INJECT_HINT (
sql_text text,
hint_text text,
name varchar(128),
description varchar(256),
validate boolean,
fuzzy boolean,
need_clear boolean
)

(2)存过说明

SQL 注入 HINT 规则。

(3)注意

SF_INJECT_HINT 方法创建的 HINT 规则无生效类别限制,如果需要为该 HINT 规则设置生效类别,可通过 SF_ALTER_HINT 过程修改实现。

(4)参数含义

参数名含义
sql_text待注入 HINT 规则的 SQL 语句。
hint_text待注入的 HINT 规则,必须指定为非 NULL 值。
nameHINT 规则的名称,指定为 NULL 值时系统为其命名。
description对 HINT 规则的详细描述。
validateHINT 规则是否生效。TRUE 是;FALSE 否。
fuzzy指定 SQL 的匹配规则为精准匹配或模糊匹配。

值为 TRUE 或 NULL时,为模糊匹配;

值为 FALSE 时,为精准匹配。

精准匹配时,待注入 HINT 规则的 SQL 语句
必 须 为 语 法 正 确 的 INSERT/DELETE/UPDATE/SELECT/MERGE INTO 语 句 ( 语 句 以EXPLAIN/EXPLAIN FOR 开头时,去掉 EXPLAIN/EXPLAIN FOR 后的语句必须完全正确),精准匹配要求 SQL 语句完全匹配,不支持 SQL 语句中的子查询匹配;

模糊匹配时,待注入 HINT规则的 SQL 语句应为非 NULL 值。
need_clear是否同步清空所有缓存的计划。

值为 TRUE 或 NULL 时,清空缓存的计划;

值为 FALSE 时,不清空缓存的计划,需要手动清除对应 SQL 的
计划,指定的 hint 才能生效。

(5)返回值

执行成功返回名称,执行失败报错误信息。

2、SF_ALTER_HINT

(1)声明

INT 
SF_ALTER_HINT ( 
name varchar(128),
attribute_name varchar(12),
attribute_value varchar(256),
need_clear boolean 
)

(2)存过说明

修改 HINT 规则的属性。

(3)注意

无。

(4)参数含义

参数名含义
name要修改的规则名称,必须指定为非 NULL 值。
attribute_name要修改的属性名,必须指定为非 NULL 值。

支持的可修改的属性名和属性值包括:

属性名 NAME,属性值为修改后的规则名;

属性名 DESCRIPTION,属性值为修改后的规则描述;

属性名 STATUS,属性值为 ENABLED/DISABLED;

属性名 CATEGORY,属性值为修改后的 HINT 的生效类别(由于 SF_INJECT_HINT 方法仅能注入无类别限制的
HINT,若需要注入带生效类别的 HINT,则还需要再调用一次 SF_ALTER_HINT 更改其生效类别)。
attribute_value设置的属性值,必须指定为非 NULL 值。
need_clear是否同步清空所有缓存的计划。

值为 TRUE 或 NULL 时,清空缓存的计划;

值为 FALSE 时,不清空缓存的计划,需要手动清除对应 SQL 的计划,否则 SQL 仍使用老计划。

(5)返回值

执行成功返回 0 ,执行失败返回错误码。

3、SF_DEINJECT_HINT

(1)声明

INT 
SF_DEINJECT_HINT ( 
name varchar(128),
need_clear boolean 
)

(2)存过说明

删除 SQL 中已注入的 HINT 规则。

(3)注意

无。

(4)参数含义

参数名含义
name要删除的规则名称,必须指定为非 NULL 值。
need_clear是否同步清空所有缓存的计划。

值为 TRUE 或 NULL 时,清空缓存的计划;

值为 FALSE 时,不清空缓存的计划,需要手动清除对应 SQL 的计划,否则 SQL 仍使用老计划。

(5)返回值

执行成功返回 0 ,执行失败返回错误码。

五、视图介绍

1、SYSINJECTHINT

SQL> DESC SYSINJECTHINT;

行号     NAME        TYPE$           NULLABLE
---------- ----------- --------------- --------
1          NAME        VARCHAR(128)    N
2          DESCRIPTION VARCHAR(256)    Y
3          VALIDATE    VARCHAR(5)      Y
4          SQL_TEXT    TEXT            N
5          HINT_TEXT   TEXT            N
6          CREATOR     VARCHAR(128)    Y
7          CRTDATE     DATETIME(6)     Y
8          INFO1       INTEGER         Y
9          INFO2       VARBINARY(128)  Y
10         INFO3       VARBINARY(1024) Y

10 rows got

已用时间: 13.896(毫秒). 执行号:1018.
字段名描述
NAME规则名称
DESCRIPTION规则的详细描述
VALIDATE规则是否生效,取值 TRUE/FALSE
SQL_TEXT规则中的 SQL 语句
HINT_TEXT为 SQL 语句注入的 HINT 规则内容
CREATOR规则创建人
CRTDATE规则创建时间
INFO1是否为模糊匹配。1 是;0 否,精确匹配
INFO2HINT 规则的生效类别。可使用 BINTOCHAR函数将该字段转换为 VARCHAR 类型显示
INFO3保留字段

六、虚机实验

1、开启参数

SQL> CALL SP_SET_PARA_VALUE(1,'ENABLE_INJECT_HINT',1);
DMSQL 过程已成功完成
已用时间: 12.612(毫秒). 执行号:2003.

SQL> SELECT * FROM V$DM_INI WHERE PARA_NAME = 'ENABLE_INJECT_HINT';

行号     PARA_NAME          PARA_VALUE MIN_VALUE MAX_VALUE DEFAULT_VALUE MPP_CHK SESS_VALUE FILE_VALUE DESCRIPTION        PARA_TYPE SYNC_FLAG
---------- ------------------ ---------- --------- --------- ------------- ------- ---------- ---------- ------------------ --------- ---------
           SYNC_LEVEL
           ----------
1          ENABLE_INJECT_HINT 1          0         1         0             N       1          1          enable inject hint SESSION   ALL_SYNC
           CAN_SYNC


已用时间: 7.387(毫秒). 执行号:2004.

2、测试SQL

SQL> EXPLAIN SELECT * FROM ZXJ.TEST T1 JOIN ZXJ.TEST T2 ON T1.A = T2.A;

1   #NSET2: [4, 29405, 8] 
2     #PRJT2: [4, 29405, 8]; exp_num(2), is_atom(FALSE) 
3       #HASH2 INNER JOIN: [4, 29405, 8];  KEY_NUM(1); KEY(T1.A=T2.A) KEY_NULL_EQU(0)
4         #CSCN2: [1, 10000, 4]; INDEX33555476(TEST as T1); btr_scan(1)
5         #CSCN2: [1, 10000, 4]; INDEX33555476(TEST as T2); btr_scan(1)

已用时间: 0.829(毫秒). 执行号:0.

我们可以才看出,在没有干预的情况下,优化器选的是哈希内连接。

3、注入HINT

SQL> CALL 
SF_INJECT_HINT (
'SELECT * FROM ZXJ.TEST T1 JOIN ZXJ.TEST T2 ON T1.A = T2.A;',
'USE_NL(T1,T2)',
NULL,
'',
TRUE,
FALSE,
TRUE
);2   3   4   5   6   7   8   9   10  
DMSQL 过程已成功完成
已用时间: 19.472(毫秒). 执行号:2006.

4、查看视图

SQL> SELECT * FROM SYSINJECTHINT;

行号     NAME                         DESCRIPTION VALIDATE SQL_TEXT                                                   HINT_TEXT     CREATOR
---------- ---------------------------- ----------- -------- ---------------------------------------------------------- ------------- -------
           CRTDATE                    INFO1       INFO2      INFO3     
           -------------------------- ----------- ---------- ----------
1          INJECT_HINT_ad9ccfdb7ec1745f             TRUE     SELECT * FROM ZXJ.TEST T1 JOIN ZXJ.TEST T2 ON T1.A = T2.A; USE_NL(T1,T2) SYSDBA
           2025-02-14 17:28:19.701426 0           NULL       NULL


已用时间: 3.337(毫秒). 执行号:2007.

5、验证SQL

SQL> EXPLAIN SELECT * FROM ZXJ.TEST T1 JOIN ZXJ.TEST T2 ON T1.A = T2.A;

1   #NSET2: [17551877, 29405, 8] 
2     #PRJT2: [17551877, 29405, 8]; exp_num(2), is_atom(FALSE) 
3       #SLCT2: [17551877, 29405, 8]; T1.A = T2.A
4         #NEST LOOP INNER JOIN2: [17551877, 29405, 8] 
5           #CSCN2: [1, 10000, 4]; INDEX33555476(TEST as T1); btr_scan(1)
6           #CSCN2: [1, 10000, 4]; INDEX33555476(TEST as T2); btr_scan(1)

已用时间: 0.809(毫秒). 执行号:0.

我们可以发现计划中两表的连接方式变为了嵌套循环连接,说明我们的SQL注入HINT配置成功。

6、设置当前会话不生效

CALL 
SF_ALTER_HINT ( 
'INJECT_HINT_ad9ccfdb7ec1745f',
'CATEGORY',
'SUN',
TRUE 
);

7、查看视图

SQL> SELECT NAME,DESCRIPTION,"VALIDATE",SQL_TEXT,HINT_TEXT,CREATOR,CRTDATE,INFO1,BINTOCHAR(INFO2) FROM SYSINJECTHINT;

行号     NAME                         DESCRIPTION VALIDATE SQL_TEXT                                                   HINT_TEXT     CREATOR
---------- ---------------------------- ----------- -------- ---------------------------------------------------------- ------------- -------
           CRTDATE                    INFO1       BINTOCHAR(INFO2)
           -------------------------- ----------- ----------------
1          INJECT_HINT_ad9ccfdb7ec1745f             TRUE     SELECT * FROM ZXJ.TEST T1 JOIN ZXJ.TEST T2 ON T1.A = T2.A; USE_NL(T1,T2) SYSDBA
           2025-02-14 17:28:19.701426 0           SUN


已用时间: 6.296(毫秒). 执行号:2010.

8、测试SQL

SQL> EXPLAIN SELECT * FROM ZXJ.TEST T1 JOIN ZXJ.TEST T2 ON T1.A = T2.A;

1   #NSET2: [4, 29405, 8] 
2     #PRJT2: [4, 29405, 8]; exp_num(2), is_atom(FALSE) 
3       #HASH2 INNER JOIN: [4, 29405, 8];  KEY_NUM(1); KEY(T1.A=T2.A) KEY_NULL_EQU(0)
4         #CSCN2: [1, 10000, 4]; INDEX33555476(TEST as T1); btr_scan(1)
5         #CSCN2: [1, 10000, 4]; INDEX33555476(TEST as T2); btr_scan(1)

已用时间: 0.868(毫秒). 执行号:0.

SQL> SELECT * FROM V$DM_INI WHERE PARA_NAME = 'SQLTUNE_CATEGORY';

行号     PARA_NAME        PARA_VALUE MIN_VALUE MAX_VALUE DEFAULT_VALUE MPP_CHK SESS_VALUE FILE_VALUE
---------- ---------------- ---------- --------- --------- ------------- ------- ---------- ----------
           DESCRIPTION                                                  PARA_TYPE SYNC_FLAG SYNC_LEVEL
           ------------------------------------------------------------ --------- --------- ----------
1          SQLTUNE_CATEGORY DEFAULT    NULL      NULL      NULL          N       DEFAULT    DEFAULT
           The category of SQL profiles that take effect in the session SESSION   ALL_SYNC  CAN_SYNC


已用时间: 8.464(毫秒). 执行号:2011.

由于本会话的参数SQLTUNE_CATEGORY的值DEFAULT与设置的值SUN不一致,所以此SQL注入HINT不生效。

9、会话级修改参数SQLTUNE_CATEGORY

SQL> CALL SF_SET_SESSION_PARA_VALUE('SQLTUNE_CATEGORY','SUN');
DMSQL 过程已成功完成
已用时间: 2.563(毫秒). 执行号:2012.

SQL> SELECT * FROM V$DM_INI WHERE PARA_NAME = 'SQLTUNE_CATEGORY';

行号     PARA_NAME        PARA_VALUE MIN_VALUE MAX_VALUE DEFAULT_VALUE MPP_CHK SESS_VALUE FILE_VALUE
---------- ---------------- ---------- --------- --------- ------------- ------- ---------- ----------
           DESCRIPTION                                                  PARA_TYPE SYNC_FLAG SYNC_LEVEL
           ------------------------------------------------------------ --------- --------- ----------
1          SQLTUNE_CATEGORY DEFAULT    NULL      NULL      NULL          N       SUN        DEFAULT
           The category of SQL profiles that take effect in the session SESSION   ALL_SYNC  CAN_SYNC


已用时间: 7.108(毫秒). 执行号:2013.

这次参数SQLTUNE_CATEGORY的会话值SUN与设置的值SUN不一致了。

10、验证SQL

SQL> EXPLAIN SELECT * FROM ZXJ.TEST T1 JOIN ZXJ.TEST T2 ON T1.A = T2.A;

1   #NSET2: [17551877, 29405, 8] 
2     #PRJT2: [17551877, 29405, 8]; exp_num(2), is_atom(FALSE) 
3       #SLCT2: [17551877, 29405, 8]; T1.A = T2.A
4         #NEST LOOP INNER JOIN2: [17551877, 29405, 8] 
5           #CSCN2: [1, 10000, 4]; INDEX33555476(TEST as T1); btr_scan(1)
6           #CSCN2: [1, 10000, 4]; INDEX33555476(TEST as T2); btr_scan(1)

已用时间: 0.789(毫秒). 执行号:0.

又变回来了。

11、删除注入HINT

SQL> CALL 
SF_DEINJECT_HINT ( 
'INJECT_HINT_ad9ccfdb7ec1745f',
TRUE 
);2   3   4   5   
DMSQL 过程已成功完成
已用时间: 5.053(毫秒). 执行号:2014.

12、验证是否删除

SQL> EXPLAIN SELECT * FROM ZXJ.TEST T1 JOIN ZXJ.TEST T2 ON T1.A = T2.A;

1   #NSET2: [4, 29405, 8] 
2     #PRJT2: [4, 29405, 8]; exp_num(2), is_atom(FALSE) 
3       #HASH2 INNER JOIN: [4, 29405, 8];  KEY_NUM(1); KEY(T1.A=T2.A) KEY_NULL_EQU(0)
4         #CSCN2: [1, 10000, 4]; INDEX33555476(TEST as T1); btr_scan(1)
5         #CSCN2: [1, 10000, 4]; INDEX33555476(TEST as T2); btr_scan(1)

已用时间: 0.812(毫秒). 执行号:0.

SQL> SELECT NAME,DESCRIPTION,"VALIDATE",SQL_TEXT,HINT_TEXT,CREATOR,CRTDATE,INFO1,BINTOCHAR(INFO2) FROM SYSINJECTHINT;
未选定行

已用时间: 1.033(毫秒). 执行号:2015.

我们可以看出计划变回最先的了,系统视图中也看不到了。


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

相关文章:

  • Redis Sentinel (哨兵模式)深度解析:构建高可用分布式缓存系统的核心机制
  • AI+Mermaid 制作流程图
  • 聚类中的相似矩阵和拉普拉斯矩阵
  • 计算机操作系统
  • Redis-缓存穿透击穿雪崩
  • 常见的交换机端口类型
  • k8s面经
  • 如何将错误边界与React的Suspense结合使用?
  • 随机快速排序
  • 我与DeepSeek读《大型网站技术架构》(12)-网购秒杀系统架构设计案例分析
  • JVM学习-类文件结构 类加载
  • FX-std::vector
  • Postgresql中null值和空字符串举例详解例子解析
  • SpringBoot 实现接口数据脱敏
  • 办公常用自动化工具
  • 【C++】STL全面简介与string类的使用(万字解析)
  • 【2025】基于springboot+vue的汽车销售试驾平台(源码、万字文档、图文修改、调试答疑)
  • 前:vue 后:django 部署:supervisor+nginx 流程及部分问题简记
  • python编写的一个打砖块小游戏
  • 基于AI智能算法的无人机城市综合治理