[20191122]oracel SQL parsing function qcplgte.txt

[20191122]oracel SQL parsing function qcplgte.txt[20191122]oracel SQL parsing function qcplgte.txt–//昨天看了链接:https://nenadnoveljic.com/blog/memory-le

[20191122]oracel SQL parsing function qcplgte.txt

–//昨天看了链接:https://nenadnoveljic.com/blog/memory-leak-parsing/ =>Memory Leak During Parsing

qcplgte

qcplgte is one of the auxiliary functions in Oracle database that underpin SQL parsing. In particular, this function
divides the SQL text into several parts. In Oracle 12.2, the function receives a pointer through the second argument.
The address to the next part of the SQL string to parse is stored at the 8 bytes offset. After parsing the portion of
the SQL text, the function will update the same memory location with the pointer to the substring for the next parsing
stage.

Qcplgte是Oracle数据库中支持SQL解析的辅助功能之一。尤其是这一职能将SQL文本分为几个部分。在Oracle12.2中,函数通过第二个参
数接收指针。要解析的SQL字符串的下一部分的地址存储在8字节偏移量处。在解析了在SQL文本中,函数将用指向子字符串的指针更新相
同的内存位置,以便进行下一次解析舞台。

After having figured out the input, it is fairly easy to come up with gdb commands which will display all of the parsing
stages:

在计算出输入之后,可以很容易地找到GDB命令,这些命令将显示所有的解析阶段:

break qcplgte
set pagination off
commands 1
silent
x/s *(uint64_t *)($rsi+0x8)
continue
end

Here”s the short explanation of the commands above: According to x64 calling convention for System V the second
parameter is passed through the %rsi register. The pointer to the SQL text is stored in the memory location %rsi+8. The
OS is 64-bit, therefore casting to uint64_t when dereferencing %rsi+0x8. Finally, x/s will dereference the pointer to
the (sub)string which is stored on the memory location %rsi+0x8.

下面是对上面命令的简短解释:根据对SystemV的x64调用约定,第二个参数通过%RSI寄存器传递。指向SQL文本的指针存储在内存位置
%rsi 8中。操作系统为64位,因此当取消引用%rsi 0x8时,转换为uint 64_t。最后,x/s将取消指向存储在内存位置%rsi 0x8上的(子)字
符串的指针。

–//注:里面的翻译我直接拿金山词霸翻译的.可能不是很准确.
–//我并不感兴趣作者遇到的Memory Leak问题.而是使用跟踪qcplgte看到的输出.自己也测试看看:

1.环境:
SCOTT@book> @ ver1
PORT_STRING                    VERSION        BANNER
—————————— ————– ——————————————————————————–
x86_64/Linux 2.4.xx            11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 – 64bit Production

$ cat parse.gdb
break qcplgte
set pagination off
commands 1
silent
x/s *(uint64_t *)($rsi+0x8)
continue
end

–//分析scott.dept表.略.重启数据库.

2.建立测试环境:
–//窗口1:
SCOTT@book> @ spid

       SID    SERIAL# PROCESS                  SERVER    SPID       PID  P_SERIAL# C50
———- ———- ———————— ——— —— ——- ———- ————————————————–
       295          5 34816                    DEDICATED 34817       21          3 alter system kill session “295,5” immediate;
–//记下spid=34817

–//窗口2:
$ gdb -p 34817 -x parse.gdb
GNU gdb (GDB) Red Hat Enterprise Linux (7.0.1-45.el5)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type “show copying”
and “show warranty” for details.
This GDB was configured as “x86_64-redhat-linux-gnu”.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Attaching to process 34817

3.测试1:
–//窗口1:
SCOTT@book> select/*+this is a test*/* from dept;
–//挂起.

–//窗口2:
Continuing.
0x7fff2e05d9c8:  “select/*+this is a test*/* from dept”
0x7fff2e05d9ce:  “/*+this is a test*/* from dept”
0x7fff2e05d9d1:  “this is a test*/* from dept”
0x7fff2e05d9d5:  ” is a test*/* from dept”
0x7fff2e05d9e1:  “* from dept”
0x7fff2e05d9e2:  ” from dept”
0x7fff2e05d9e7:  ” dept”
0x7fff2e05d9ec:  “”
0x7fcbb40a8100:  “select/*+this is a test*/* from dept”
0x7fcbb40a8106:  “/*+this is a test*/* from dept”
0x7fcbb40a8119:  “* from dept”
0x7fcbb40a811a:  ” from dept”
0x7fcbb40a811f:  ” dept”
0x7fcbb40a8124:  “”
0x7fcbb40a8090:  “SELECT /*+THISISATEST*/ * FROM DEPT”
0x7fcbb40a8096:  ” /*+THISISATEST*/ * FROM DEPT”
0x7fcbb40a80a9:  ” FROM DEPT”
0x7fcbb40a80ae:  ” DEPT”

–//很奇怪看到3组,第1组占8行也就是调用函数qcplgte8次.好像在逐步分解.而第2次调用函数qcplgte6次.这个用语言不好表达,慢慢理解吧.
–//实际上语句越复杂,第1组看到的调用函数qcplgte次数越多.原始链接有1个例子,大家可以自行测试.
–//而第3组是全部换成大写,注解部分发生了合并,删除了空格.

–//窗口1,如果再次执行相同语句.窗口2不会有输出,因为第2次执行是软解析.
SCOTT@book> select/*+this is a test*/* from dept;

4.测试2:
–//窗口1:
SCOTT@book> select/*+this is a test*/* from scott.dept ;
    DEPTNO DNAME          LOC
———- ————– ————-
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON

–//加入shaema看看.
–//窗口2:
0x7fff2e05d9c0:  “select/*+this is a test*/* from scott.dept “
0x7fff2e05d9c6:  “/*+this is a test*/* from scott.dept “
0x7fff2e05d9c9:  “this is a test*/* from scott.dept “
0x7fff2e05d9cd:  ” is a test*/* from scott.dept “
0x7fff2e05d9d9:  “* from scott.dept “
0x7fff2e05d9da:  ” from scott.dept “
0x7fff2e05d9df:  ” scott.dept “
0x7fff2e05d9e5:  “.dept “
0x7fff2e05d9e6:  “dept “
0x7fff2e05d9ea:  ” “
0x7fcbb40a8108:  “select/*+this is a test*/* from scott.dept “
0x7fcbb40a810e:  “/*+this is a test*/* from scott.dept “
0x7fcbb40a8121:  “* from scott.dept “
0x7fcbb40a8122:  ” from scott.dept “
0x7fcbb40a8127:  ” scott.dept “
0x7fcbb40a812d:  “.dept “
0x7fcbb40a812e:  “dept “
0x7fcbb40a8132:  ” “
0x7fcbb40a8090:  “SELECT /*+THISISATEST*/ * FROM SCOTT . DEPT”
0x7fcbb40a8096:  ” /*+THISISATEST*/ * FROM SCOTT . DEPT”
0x7fcbb40a80a9:  ” FROM SCOTT . DEPT”
0x7fcbb40a80ae:  ” SCOTT . DEPT”
0x7fcbb40a80b4:  ” . DEPT”
0x7fcbb40a80b6:  ” DEPT”

–//发现一个很有趣的情况注意看第3组的输出,schema.tablename中间有空格.
–//我打开另外的窗口3执行如下:
–//窗口3:
SYS@book> select * from scott .                dept where deptno=10;
    DEPTNO DNAME          LOC
———- ————– ————-
        10 ACCOUNTING     NEW YORK

–//也就是如上写法也是能执行成功的.

4.测试3:
–//突然想起我们许多情况应用使用大量文字变量,设定cursor_sharing=force的情况.测试看看这种情况如何解析.
–//窗口1:
SCOTT@book> alter session set cursor_sharing=force ;
Session altered.

SCOTT@book> select * from dept where deptno=10;
    DEPTNO DNAME          LOC
———- ————– ————-
        10 ACCOUNTING     NEW YORK

–//窗口2:
0x7fff9d820208:  “select * from dept where deptno=10”
0x7fff9d82020e:  ” * from dept where deptno=10″
0x7fff9d820210:  ” from dept where deptno=10″
0x7fff9d820215:  ” dept where deptno=10″
0x7fff9d82021a:  ” where deptno=10″
0x7fff9d820220:  ” deptno=10″
0x7fff9d820227:  “=10”
0x7fff9d820228:  “10”
0x7fff9d82022a:  “”
0x7dc4a338:      “select * from dept where deptno=:”SYS_B_0″”
0x7dc4a33e:      ” * from dept where deptno=:”SYS_B_0″”
0x7dc4a340:      ” from dept where deptno=:”SYS_B_0″”
0x7dc4a345:      ” dept where deptno=:”SYS_B_0″”
0x7dc4a34a:      ” where deptno=:”SYS_B_0″”
0x7dc4a350:      ” deptno=:”SYS_B_0″”
0x7dc4a357:      “=:”SYS_B_0″”
0x7dc4a351:      “deptno=:”SYS_B_0″”
0x7dc4a357:      “=:”SYS_B_0″”
0x7dc4a358:      “:”SYS_B_0″”
0x7dc4a359:      “”SYS_B_0″”
0x7dc4a362:      “”
0x7f0cb4e28108:  “select * from dept where deptno=:”SYS_B_0″”
0x7f0cb4e2810e:  ” * from dept where deptno=:”SYS_B_0″”
0x7f0cb4e28110:  ” from dept where deptno=:”SYS_B_0″”
0x7f0cb4e28115:  ” dept where deptno=:”SYS_B_0″”
0x7f0cb4e2811a:  ” where deptno=:”SYS_B_0″”
0x7f0cb4e28120:  ” deptno=:”SYS_B_0″”
0x7f0cb4e28127:  “=:”SYS_B_0″”
0x7f0cb4e28128:  “:”SYS_B_0″”
0x7f0cb4e28129:  “”SYS_B_0″”
0x7f0cb4e28132:  “”
0x7f0cb4e28090:  “SELECT * FROM DEPT WHERE DEPTNO = :”SYS_B_0″”
0x7f0cb4e28096:  ” * FROM DEPT WHERE DEPTNO = :”SYS_B_0″”
0x7f0cb4e28098:  ” FROM DEPT WHERE DEPTNO = :”SYS_B_0″”
0x7f0cb4e2809d:  ” DEPT WHERE DEPTNO = :”SYS_B_0″”
0x7f0cb4e280a2:  ” WHERE DEPTNO = :”SYS_B_0″”
0x7f0cb4e280a8:  ” DEPTNO = :”SYS_B_0″”
0x7f0cb4e280af:  ” = :”SYS_B_0″”
0x7f0cb4e280b1:  ” :”SYS_B_0″”
0x7f0cb4e280b3:  “”SYS_B_0″”
0x7de1bdd6:      “DEPTNO”
0x7de1bddc:      “”
0x7db9aad6:      “DNAME”
0x7db9aadb:      “”
0x7db9a9fe:      “LOC”
0x7db9aa01:      “”

–//看到4组,仔细观察可以发现前面2组与第一次测试一样.我觉得真正分析的是第3次.
–//还很奇怪的是这样的情况还看到表dept中3个字段的分析调用.

–//窗口3:
SCOTT@book> show parameter cursor_sharing
NAME           TYPE   VALUE
————– —— ——
cursor_sharing string EXACT

SCOTT@book>  select * from dept where deptno=30;
    DEPTNO DNAME          LOC
———- ————– ————-
        30 SALES          CHICAGO

–//切换会窗口1,执行相同语句:
SCOTT@book> select * from dept where deptno=30;
    DEPTNO DNAME          LOC
———- ————– ————-
        30 SALES          CHICAGO

–//窗口2看到的输出:
0x7fff9d820208:  “select * from dept where deptno=30”
0x7fff9d82020e:  ” * from dept where deptno=30″
0x7fff9d820210:  ” from dept where deptno=30″
0x7fff9d820215:  ” dept where deptno=30″
0x7fff9d82021a:  ” where deptno=30″
0x7fff9d820220:  ” deptno=30″
0x7fff9d820227:  “=30”
0x7fff9d820228:  “30”
0x7fff9d82022a:  “”
0x7de1bdd6:      “DEPTNO”
0x7de1bddc:      “”
0x7db9aad6:      “DNAME”
0x7db9aadb:      “”
0x7db9a9fe:      “LOC”
0x7db9aa01:      “”

–//你可以看出因为别的会话在cursor_sharing=EXACT执行1次select * from dept where deptno=30;.
–//这样在cursor_sharing=force的会话执行select * from dept where deptno=30;仅仅分析1组.

–//窗口1:
SCOTT@book> select * from dept where deptno=40;
    DEPTNO DNAME          LOC
———- ————– ————-
        40 OPERATIONS     BOSTON

–//窗口2看到的输出:
0x7fff9d820208:  “select * from dept where deptno=40”
0x7fff9d82020e:  ” * from dept where deptno=40″
0x7fff9d820210:  ” from dept where deptno=40″
0x7fff9d820215:  ” dept where deptno=40″
0x7fff9d82021a:  ” where deptno=40″
0x7fff9d820220:  ” deptno=40″
0x7fff9d820227:  “=40”
0x7fff9d820228:  “40”
0x7fff9d82022a:  “”
0x7de1bdd6:      “DEPTNO”
0x7de1bddc:      “”
0x7db9aad6:      “DNAME”
0x7db9aadb:      “”
0x7db9a9fe:      “LOC”
0x7db9aa01:      “”
–//可以看到跟前面一样的情况.
–//可以看出cursor_sharing=force的情况下,只要存在文字变量,要调用qcplgte 1组,以消耗一定cpu资源为前提的.

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/10834.html

(0)
上一篇 2022-12-21 08:30
下一篇 2022-12-21

相关推荐

  • mysql 查询本月、本周、今日、昨日数据「终于解决」

    mysql 查询本月、本周、今日、昨日数据「终于解决」created_at 类型为 timestamp — SELECT COUNT(1) FROM lara_orders WHERE MONTHNAME(created_at)=MONTHNAME(…

    2023-03-28
    162
  • GaussDB for DWS:内存自适应控制技术总结

    GaussDB for DWS:内存自适应控制技术总结1.技术背景 在SQL语句复杂、处理数据量大的AP场景下,单个查询对内存的需求越来越大,多个语句的并发很容易将系统的内存吃满,造成内存不足的问题。为了应对这种问题,GaussDB for DWS引入…

    2023-03-20
    152
  • Windows/Linux/Mac系统下的MySQL安装(全网最全步骤)「终于解决」

    Windows/Linux/Mac系统下的MySQL安装(全网最全步骤)「终于解决」详解各系统(Windows/Linux/Mac)下的MySQL安装步骤与流程

    2023-04-26
    152
  • Python中break的使用方法

    Python中break的使用方法在Python中,break是一种控制流语句,用于中断循环语句的执行。当程序执行到break语句时,循环语句会立即停止执行,程序开始执行循环语句后的第一条语句。通过使用break,我们可以在满足一定条件的情况下,中断循环,提高程序执行的效率。

    2024-03-01
    98
  • 数据库授予权限语句_sql用户权限设置

    数据库授予权限语句_sql用户权限设置1.使用root账号登陆到MySQL服务器: 2.切换到mysql数据库实例: 3.查看用户表: 4.创建一个只允许从本机登录的用户“yang”,密码为“yangpass”: 5.删除一个名为“yan

    2023-02-03
    152
  • MySQL相关基础知识[通俗易懂]

    MySQL相关基础知识[通俗易懂]恢复内容开始 [TOC] MySQL相关知识 Mysql链接 mysql u用户名 p密码 创建数据库 create databse 数据库名; 删除数据库 drop database 数据库名; 选

    2023-02-18
    150
  • Python升级版本新特性介绍

    Python升级版本新特性介绍Python作为一门高级编程语言,备受程序员们的喜爱,其简洁、易学、高效的特点在广泛的应用场景中得到了体现。Python的版本更新也一直没有停止。本文将为大家介绍Python升级版本的新特性,包括Python 3.8、Python 3.9和Python 3.10等版本中的新功能、新语法、新模块等,希望对各位开发者有所启发。

    2024-09-16
    29
  • Python 进制转换实用指南

    Python 进制转换实用指南计算机科学中,进制转换是一项非常基础和重要的技能,也是许多高级算法和编程语言中必不可少的部分。Python 作为一种高级编程语言,提供了很多内置函数和标准库,可以很方便地进行进制转换。在本文中,我们将以 Python 为例,介绍常见的进制转换技巧。

    2024-08-01
    29

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注