达梦数据库-学习-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、验证是否删除


一、环境信息

|------|------------------------------------------------------------------------------------------------------------------------------|
| 名称 | 值 |
| CPU | 12th 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_HINT | 0 | 动态会 话级 | 是否启用 SQL 指定 HINT 的功能。 0:不启用; 1:启用; |
| SQLTUNE_CATEGORY | DEFAULT | 动态会话级 | 限制本会话中被允许使用的 SQL 配置(包括为 SQL 注入的 HINT 规则)的生效类别。 当 SQL 配置存在生效类别限制且和本会话的 SQLTUNE_CATEGORY 不一致时,该 SQL 配置在本会话不生效 |

四、存过介绍

1、SF_INJECT_HINT

(1)声明

sql 复制代码
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 值。 |
| name | HINT 规则的名称,指定为 NULL 值时系统为其命名。 |
| description | 对 HINT 规则的详细描述。 |
| validate | HINT 规则是否生效。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)声明

sql 复制代码
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)声明

sql 复制代码
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 复制代码
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 否,精确匹配 |
| INFO2 | HINT 规则的生效类别。可使用 BINTOCHAR函数将该字段转换为 VARCHAR 类型显示 |
| INFO3 | 保留字段 |

六、虚机实验

1、开启参数

sql 复制代码
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 复制代码
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 复制代码
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 复制代码
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 复制代码
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、设置当前会话不生效

sql 复制代码
CALL 
SF_ALTER_HINT ( 
'INJECT_HINT_ad9ccfdb7ec1745f',
'CATEGORY',
'SUN',
TRUE 
);

7、查看视图

sql 复制代码
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 复制代码
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 复制代码
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 复制代码
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 复制代码
SQL> CALL 
SF_DEINJECT_HINT ( 
'INJECT_HINT_ad9ccfdb7ec1745f',
TRUE 
);2   3   4   5   
DMSQL 过程已成功完成
已用时间: 5.053(毫秒). 执行号:2014.

12、验证是否删除

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.812(毫秒). 执行号:0.

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

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

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

相关推荐
磊灬泽4 小时前
【日常错误】鼠标无反应
linux·windows
知白守黑2674 小时前
Ansible角色
运维·服务器·ansible
Jwest20214 小时前
工业显示器在地铁电力监控与运维中的应用
运维·计算机外设
知识分享小能手5 小时前
React学习教程,从入门到精通, React 属性(Props)语法知识点与案例详解(14)
前端·javascript·vue.js·学习·react.js·vue·react
luckys.one5 小时前
第9篇:Freqtrade量化交易之config.json 基础入门与初始化
javascript·数据库·python·mysql·算法·json·区块链
言之。6 小时前
Django中的软删除
数据库·django·sqlite
茯苓gao7 小时前
STM32G4 速度环开环,电流环闭环 IF模式建模
笔记·stm32·单片机·嵌入式硬件·学习
是誰萆微了承諾7 小时前
【golang学习笔记 gin 】1.2 redis 的使用
笔记·学习·golang
阿里嘎多哈基米7 小时前
SQL 层面行转列
数据库·sql·状态模式·mapper·行转列
抠脚学代码8 小时前
Ubuntu Qt x64平台搭建 arm64 编译套件
数据库·qt·ubuntu