在Oracle 9中伪造存储概要

时间:2017-07-17 18:18

在前面的文章中,我讨论到存储概要,并且描述了一种通过滥用系统来生成你所需要存储概要的方法.我同时也指出,在Oracle 9中使用这种方法存在一些风险,因为存储在数据库中的细节信息已经变得非常复杂.在接下来的文章中,我将介绍一种合法的操作存储概要的方法,这种方法可以应用在Oracle 8与Oracle 9中.这篇文章的细节都是基于实验得出的,实验环境是Oracle 8.1.7.0与Oracle 9.2.0.1的默认安装环境.

回顾

当你知道如何通过给一段DML语句添加提示就可以让它运行的快很多,但是你却没有访问源代码并将提示放到适当位置的途径, 你会怎么做?

在上一篇文章中,我展示了你可以如何用存储概要(也被称为执行计划稳定性)来驱使数据库引擎为你做这种工作.

一个存储概要由两个组件组成(宽泛地讲)-一个你希望控制的SQL语句,一组每当Oracle发现这条SQL被优化都将在它上面应用的提示.这两个组件都被保存在一个被称为outln的数据库schema中.

我们可以使用一组如图-1中类似的查询语句来检查保存在其中的SQL语句,以及附着在这条SQL语句上的提示.

1 select  name, used, sql_text

2 from    user_outlines

3 where   category = 'DEFAULT'

4 ;

5

6 select  stage, node, hint

7 from    user_outline_hints

8 where   name = '{one of the names}'

9 ;

Figure 1 Examining stored outlines.

在前面的文章中,我介绍了这样一种想法来欺骗系统, 使用合法的方法创建一个存储概要, 接着,使用一个文本相似的但已经添加过提示的语句来创建一个存储概要,最后,使用一组SQL语句来交换这两个存储概要的实际结果来修复存储概要.

当时,我曾提到这种方法对Oracle 8来讲或许是安全的,但是由于在新版本中引入的变化, 在Oracle 9中可能会导致问题.

这篇文章将对这些变化进行考查, 介绍一种合法的方法来得到你想要的一组存储到outln中的提示,用来解决你的那些问题语句.

相关变化

如果你登录到outln schema(在Oracle 9中它默认是锁住的)查看可用的表清单,你将发现Oracle 9比Oracle 8多出来一张表. 这些表为:

ol$ SQL语句

ol$hints 提示表

ol$nodes 查询块

第三张表是一张新表,被用来将提示列表与这条SQL语句(一份内部重写的版本)的多个不同查询块.你还将发现,提示列表(ol$hints)也被加强了,其中还包括文本长度与偏移量的细节信息.

图2为这三张表的详细描述,用星号标注了Oracle 9中出现的新字段.

01 ol$

02

03 OL_NAME          VARCHAR2(30)

04 SQL_TEXT         LONG

05 TEXTLEN          NUMBER

06 SIGNATURE        RAW(16)

07 HASH_VALUE       NUMBER

08 HASH_VALUE2      NUMBER           ***

09 CATEGORY         VARCHAR2(30)

10 VERSION          VARCHAR2(64)

11 CREATOR          VARCHAR2(30)

12 TIMESTAMP        DATE

13 FLAGS            NUMBER

14 HINTCOUNT        NUMBER

15 SPARE1           NUMBER           ***

16 SPARE2           VARCHAR2(1000)   ***

17

18 Ol$hints

19

20 OL_NAME          VARCHAR2(30)

21 HINT#            NUMBER

22 CATEGORY         VARCHAR2(30)

23 HINT_TYPE        NUMBER

24 HINT_TEXT        VARCHAR2(512)

25 STAGE#           NUMBER

26 NODE#            NUMBER

27 TABLE_NAME       VARCHAR2(30)

28 TABLE_TIN        NUMBER

29 TABLE_POS        NUMBER

30 REF_ID           NUMBER           ***

31 USER_TABLE_NAME  VARCHAR2(64)     ***

32 COST             FLOAT(126)       ***

33 CARDINALITY      FLOAT(126)       ***

34 BYTES            FLOAT(126)       ***

35 HINT_TEXTOFF     NUMBER           ***

36 HINT_TEXTLEN     NUMBER           ***

37 JOIN_PRED        VARCHAR2(2000)   ***

38 SPARE1           NUMBER           ***

39 SPARE2           NUMBER           ***

40

41 ol$nodes  (completely new in 9)

42

43 OL_NAME          VARCHAR2(30)

44 CATEGORY         VARCHAR2(30)

45 NODE_ID          NUMBER

46 PARENT_ID        NUMBER

47 NODE_TYPE        NUMBER

48 NODE_TEXTLEN     NUMBER

49 NODE_TEXTOFF     NUMBER

Figure 2 The outln tables.