[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资源为前提的.

[20191122]oracel SQL parsing function qcplgte.txt的更多相关文章

  1. [20191125]oracel SQL parsing function qcplgte 2.txt

    [20191125]oracel SQL parsing function qcplgte 2.txt --//参考前面的测试:http://blog.itpub.net/267265/viewspa ...

  2. [20190328]简单探究sql语句相关mutexes.txt

    [20190328]简单探究sql语句相关mutexes.txt --//摘要:http://www.askmaclean.com/archives/understanding-oracle-mute ...

  3. [20191101]通过zsh计算sql语句的sql_id.txt

    [20191101]通过zsh计算sql语句的sql_id.txt 1.简单介绍以及测试使用zsh遇到的问题:--//前段时间写的,链接http://blog.itpub.net/267265/vie ...

  4. [20191011]通过bash计算sql语句的sql_id.txt

    [20191011]通过bash计算sql语句的sql_id.txt --//当我知道如何通过bash计算sql语句的full_hash_value ,就很想通过bash编程计算sql_id.当时受限 ...

  5. SQL LOADER 的用法 TXT文件导入非常之快

    前提,需要本地安装ORACLE 客户端 控制文件 cms.ctl load dataCHARACTERSET UTF8infile 'oracle.txt'APPEND INTO TABLE JR f ...

  6. sql连着function使用

    create function fun002(@thename varchar()) returns int as begin declare @count int select @count=cou ...

  7. oracel SQL多表查询优化

    SQL优化 1.执行路径:ORACLE的这个功能大大地提高了SQL的执行性能并节省了内存的使用:我们发现,单表数据的统计比多表统计的速度完全是两个概念.单表统计可能只要0.02秒,但是2张表联合统计就 ...

  8. oracel sql分组求和过滤条件

  9. 在数据库中生成txt文件到网络驱动器中(计算机直接创建的网络驱动器在sql server中没有被找到)

    环境:sql server 2008 一.创建网络驱动器映射 语法:exec master..xp_cmdshell 'net use Z: \\ip地址\网络路径 密码 /user:用户名' 例如: ...

随机推荐

  1. 如何在ASP.NET Core 中快速构建PDF文档

    比如我们需要ASP.NET Core 中需要通过PDF来进行某些简单的报表开发,随着这并不难,但还是会手忙脚乱的去搜索一些资料,那么恭喜您,这篇帖子会帮助到您,我们就不会再去浪费一些宝贵的时间. 在本 ...

  2. C#语言和SQL Server数据库技术_前四章错题

      1.在C#中,如果让某个方法只能被它所在的程序集内的其他方法访问,可使用(C)修饰这个方法. (选择一项) A:private B:protected C:internal D:以上都不对 2.下 ...

  3. 编译安装nginx时配置开机自启

    详细编译安装nginx请参考[Nginx目录结构与配置文件详解]以及[Nginx安装部署],在这里就进行简单安装 安装Nginx 环境介绍 操作系统: [root@localhost ~]# cat ...

  4. 机器学习预测时label错位对未来数据做预测

    前言 这篇文章时承继上一篇机器学习经典模型使用归一化的影响.这次又有了新的任务,通过将label错位来对未来数据做预测. 实验过程 使用不同的归一化方法,不同得模型将测试集label错位,计算出MSE ...

  5. 关于C 语言的字符串常量拼接

    问题记录: C语言中,字符串是否可以通过连续的常量创建直接编辑拼接在一起? 比如下述语句赋值: const char *path = “this is string one”   “this is s ...

  6. 【Babel】293- 初学 Babel 工作原理

    戳蓝字「前端技术优选」关注我们哦! 前言 babel Babel 对于前端开发者来说应该是很熟悉了,日常开发中基本上是离不开它的. 已经9102了,我们已经能够熟练地使用 es2015+ 的语法.但是 ...

  7. C#中关于值类型和引用类型的区别

    小声哔哔 一直以来对于值类型与引用类型之间的区别都不是特别清晰,直到踩了坑.... 正好最新闲暇,便想着梳理梳理这一两年来遇到的奇葩问题和解决方案,顺便就把它给拎出来记一下,免得以后再摔跤 值类型与引 ...

  8. jenkins+gitlab+webhook实现自动发布

    实验环境   Jenkins:192.168.1.15 Gitlab:192.168.1.14   一.Jenkins配置   1:安装gitlab hook plugin插件 2:新建一个job 3 ...

  9. struct socket结构体详解

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://weiguozhihui.blog.51cto.com/3060615/15852 ...

  10. Kubernetes服务发现入门:如何高效管理服务?

    愈发复杂的应用程序正在依靠微服务来保持可扩展性和提升效率.Kubernetes为微服务提供了完美的环境,并能够让其与Kubernetes的工具组件和功能兼容.当应用程序的每个部分放置在一个容器中,整个 ...