暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

SQM达梦审核获取不到执行计划的问题研究

原创 张程 2023-04-11
868

第一章 达梦日志审核问题

随着SQM版本的迭代,所支持的数据库及审核类型越来越多。在近期版本中则增加了对达梦库的审核功能。具体审核方式为审核达梦数据库的跟踪日志文件。分析文件中的慢SQL,分析违反规则、执行计划、相关对象等信息。

经过测试,SQL的违反规则和相关对象均可以顺利展示。目前发现的主要问题是大部分业务SQL的执行计划均无法获得。

image.png

查询监听日志中有大量的如下报错信息。

image.png

为了搞清楚问题原因,因此通过一条典型SQL做相应的测试。

第二章 连库分析问题原因

在确保连库采集用户授予了相应采集权限后,通过采集用户sqm登录审核目标库。

grant select on V$DM_INI to sqm;
grant select on v$version to sqm;
grant select on V$SQL_NODE_NAME to sqm;
grant select any table to sqm;
grant select any view to sqm;

image.png

尝试直接查询或EXPLAIN目标SQL解析执行计划:

image.png

会提示找不到目标表相关对象。
查询相应对象所属用户:

image.png

可以看到相应表均属于XXTEST业务用户。而当前是通过SQM用户去测试的,因此找不到用户也属于正常。

image.png

那基于本章节的测试,目前获取不到执行计划的主要原因是采集用户下没有SQL相关的表对象。下面分析解决办法。

第三章 解决方案

3.1 增加切换schema步骤

为了获得目标业务用户的所属对象,需要切换到对应用户下。因此尝试增加如下切换用户步骤:

set schema XXTEST;
alter session set current_schema=XXTEST;

切换用户测试:
image.png

经过测试,无法切换到对应业务用户。原因是对应模式不属于当前用户。即使通过SYSDBA登录,也是同样的现象。

通过查阅技术资料及与达梦原厂人员沟通,只有由自己用户创建的schema之间可以互相切换。其他用户下的schema均没有权限切换。
具体参见达梦技术文档:
https://eco.dameng.com/community/article/7663df9b6404dfd2e8c8b593183f6ec4

image.png

因此这种方案,除非是指定模式是由自己用户创建的,才可以通过上述命令切换。很显然,实际的场景是业务用户及模式已经先一步创建,之后才创建采集用户。我们希望通过采集用户

set schema schema_name;

切换到不属于自己用户下的模式,很显然是无法完成的。也就无法获得对应模式下的SQL执行计划。

3.2 给表名加上schema前缀

EXPLAIN SELECT COUNT(*) FROM XXTEST.HrmMain WHERE status IN (0, 1, 2, 3) AND loginid IS NOT NULL AND (Accounttype IS NULL OR Accounttype != 1) AND NOT EXISTS (SELECT 1 FROM XXTEST.HrmMainVirtual a, XXTEST.Hrmcustomr b WHERE HrmMain.id = a.resourceid AND a.virtualtype = -10000 AND NOT EXISTS (SELECT 1 FROM XXTEST.Hrmcustomr WHERE a.departmentid = crmmanagerdeptid));

image.png

通过表名增加模式名的办法,在采集用户sqm具有访问对应表权限的情况下,很显然是可以获得执行计划的,但这样处理的方法较为复杂,需要在SQL中用到的每张表前都增加模式名。从软件处理上较为不方便。

3.3 获取业务用户密码

通过上述两种方法,均不能很好的解决“获取不到执行计划”的问题。这里分析,只有对应用户才能直接访问用户下所属表的。因此索要业务用户密码,使用业务用户作为SQM的采集用户,是可以顺利解决获取执行计划问题的。

但又存在以下问题:
1.如果所属SQL在多个业务用户下,那单个业务用户也是无法满足需求。
2.索要业务用户密码,不符合应用安全规范。
因此这种方案,某种情况下可行,但不符合安全规范。

3.4 采集用户下建立同名同义词

通过采集用户下建立对应表的同义词。通过访问同义词来直接获得表信息。从而达到获取目标SQL执行计划的目的。

为此需要根据目标SQL所涉及到的表,编写采集脚本建立同义词:
image.png
建立同义词后,直接访问采集用户下的同义词对象,即直接访问到了对应业务用户下的表对象。
image.png

在采集用户下执行测试:

EXPLAIN SELECT COUNT(*) FROM HrmMain WHERE status IN (0, 1, 2, 3) AND loginid IS NOT NULL AND (Accounttype IS NULL OR Accounttype != 1) AND NOT EXISTS (SELECT 1 FROM HrmMainVirtual a, Hrmcustomr b WHERE HrmMain.id = a.resourceid AND a.virtualtype = -10000 AND NOT EXISTS (SELECT 1 FROM Hrmcustomr WHERE a.departmentid = crmmanagerdeptid));

image.png

相应的SQL执行计划可以顺利获得。
但此种办法也有一定限制:

如果同名表对象在多个业务用户下,那一组同名表也只能建立其中一个同义词。其他未建立同义词的表仍然是有问题。

第四章 问题总结

通过上述章节的方案测试,最终商讨后确定在采集用户下创建同义词的方式,可以用较小的代价来获得目标SQL的执行计划。

但经过实际测试:
image.png

使用采集用户SQM手动执行的业务SQL,其执行计划是正常的。
但业务用户执行的相同SQL,却仍然是获取不到执行计划。

这里分析可能是由于SQM在获取执行计划时,会提前切换到对应用户下。

alter session set current_schema=XXTEST;

但目前的情况切换时会报“模式[XXTEST]不属于当前用户”的问题。导致返回报错,从而无法继续获得采集用户下的同义词对象信息。具体是否是这里的原因,还需要产品同事进一步测试验证。从而找到修复方案。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论