love Oracle

提供专业Oracle服务 mail: oracledb2#139.com

Windows 平台通过操作系统文件创建ASM磁盘组

Posted by admin on 四月 19th, 2012

今天在metalink上看到一篇文章,在Windows平台使用操作系统文件替代真实的裸设备来创建ASM磁盘组。用这种方式,可以很方便的在Windows环境下,搭建ASM环境。当然,这种非常规的方式仅供学习,不建议在真实的生产环境上使用。

  • dd for windows

dd for windows 是一个开源的工具,提供Windows下的类似Linux/UNIX下dd的功能。asm的磁盘文件通过这个工具来创建,可以通过下面的网站下载:

http://www.chrysocome.net/dd

  • 创建虚拟裸设备文件

# dd if=/dev/zero of=e:\dd\asmdisk1 bs=1k count=100000

 

100000+0 records in
100000+0 records out

 

# dd if=/dev/zero of=e:\dd\asmdisk2 bs=1k count=100000

 

100000+0 records in
100000+0 records out

  • 设置asm参数

为了asm能够识别到虚拟裸设备文件,需要设置一个隐含参数。

E:\dd>sqlplus '/as sysdba'

 

SQL*Plus: Release 10.2.0.1.0 – Production on 星期三 4月 18 16:39:19 2012

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

 

SQL> alter system set "_asm_allow_only_raw_disks"=false scope=spfile;

 

System altered.

 

SQL> alter system set asm_diskstring='e:\dd\*' scope=both;

 

System altered.

  • 采用虚拟设备文件创建asm磁盘组

SQL> create diskgroup data external redundancy disk 'e:\dd\asmdisk1',
  2  'e:\dd\asmdisk2';
 
Diskgroup created.

 

SQL> create tablespace test datafile '+data' size 10m;

 

Tablespace created.

 

SQL> select * from v$dbfile;

 

     FILE# NAME
———- ————————————————————
……
         5 +DATA/bill/datafile/test.256.780945535

Tags:
Posted in 操作系统 | No Comments »

about_asm_concept

Posted by admin on 四月 18th, 2012

分享一篇官方ASM文档,对于初学ASM的同学很有帮助。

 

Applies to:

Oracle Server – Enterprise Edition – Version: 10.1.0.2 to 11.2.0.2 – Release: 10.1 to 11.2
Information in this document applies to any platform.
 

Purpose

This note provides a quick overview of Oracle Automatic Storage Management (ASM) concepts and operations. This document can help clarify some key concepts that are not well understood by users – without requiring lengthy research.

Scope and Application

This note is intended for architects, DBAs, and system administrators at an intermediate level of Oracle database knowledge.
 

ASM Concepts Quick Overview

The following points describe key concepts of ASM; for more information refer to the resources at the end of this note.

 

  • ASM exists to manage file storage for the RDBMS
    • ASM does NOT perform I/O on behalf of the RDBMS
    • I/O is performed by the RDBMS processes as it does with other storage types
    • Thus, ASM is not an intermediary for I/O (would be a bottleneck)
    • I/O can occur synchronously or asynchronously depending on the value of the DISK_ASYNCH_IO parameter
    • Disks are RAW devices to ASM
    • Files that can be stored in ASM: typical database data files, control files, redologs, archivelogs, flashback logs, spfiles,
      RMAN backups and incremental tracking bitmaps, datapump dumpsets.
    • In 11gR2, ASM has been extended to allow storing any kind of file using Oracle ACFS capability (it appears as another filesystem to clients). Note that database files are not supported within ACFS

 

  • ASM Basics
    • The smallest unit of storage written to disk is called an "allocation unit" (AU) and is usually 1MB (4MB recommended for Exadata)
    • Very simply, ASM is organized around storing files
    • Files are divided into pieces called "extents"
    • Extent sizes are typically equal to 1 AU, except in 11g where it will use variable extent sizes that can be 1, 8, or 64 AUs
    • File extent locations are maintained by ASM using file extent maps.
    • ASM maintains file metadata in headers on the disks rather than in a data dictionary
    • The file extent maps are cached in the RDBMS shared pool; these are consulted when an RDBMS process does I/O
    • ASM is very crash resilient since it uses instance / crash recovery similar to a normal RDBMS (similar to using undo and redo logging)

       

  • Storage is organized into "diskgroups" (DGs)
    • A DG has a name like "DATA" in ASM which is visible to the RDBMS as a file begining with "+DATA"; when tablespaces are created, they refer to a DG for storage such as "+DATA/…/…"
    • Beneath a diskgroup are one or more failure groups (FGs)
    • FGs are defined over a set of "disks"
    • "Disks" can be based on raw physical volumes, a disk partition, a LUN presenting a disk array, or even an LVM or NAS device
    • FGs should have disks defined that have a common failure component, otherwise ASM redundancy will not be effective

       

  • High availability
    • ASM can perform mirroring to recover from device failures
    • You have a choice of EXTERNAL, NORMAL, OR HIGH redundancy mirroring
      EXTERNAL means allow the underlying physical disk array do the mirroring
      NORMAL
      means ASM will create one additional copy of an extent for redundancy
      HIGH means ASM will create two additional copies of an extent for redundancy
    • Mirroring is implemented via "failure groups" and extent partnering; ASM can tolerate the complete loss of all disks in a failure group when NORMAL or HIGH redundancy is implemented

     

  • FG mirroring implementation
    • Mirroring is not implemented like RAID 1 arrays (where a disk is partnered with another disk)
    • Mirroring occurs at the file extent level and these extents are distributed among several disks known as "partners"
    • Partner disks will reside in one or more separate failure groups (otherwise mirror copies would be vulnerable)
    • ASM automatically choses partners and limits the number of them to less than 10 (varies by RDBMS version) in order to contain the overall impact of multiple disk failures
    • If a disk fails, then ASM updates its extent mapping such that reads will now occur on the surviving partners
      • This is one example when ASM and the RDBMS communicate with each other
      • The failed disk is offlined
    • In 11g, while the disk is offline, any changes to files are tracked so that those changes can be reapplied if the disk is brought online within a period of time (3.6 hours by default value of DISK_REPAIR_TIME). This could happen in cases of a bad controller or similar problem rather than the failure of the disk itself
      • The tracking occurs via a bitmap of changed file extents; the bitmaps tell ASM which extents need to be copied back to the repaired disk from the partner
         
      • This is called "fast mirror resync"
         
    • In 10g, the disk is offlined and dropped – there is no repair time grace period before dropping.
       
    • If the disk cannot be onlined, it must be dropped. A new disk will be installed and ASM will copy the data back via a "rebalancing" operation. This happens automatically in the background

       

  • Rebalancing
    • "Rebalancing" is the process of moving file extents onto or off of disks for the purpose of evenly distributing the I/O load of the diskgroup
    • It occurs asynchronously in the background and can be monitored
    • In a clustered environment, rebalancing for a disk group is done within a single ASM instance only and cannot be distributed across multiple cluster node to speed it up
    • ASM will automatically rebalance data on disks when disks are added or removed
    • The speed and effort placed on rebalancing can be controlled via a POWER LIMIT setting
    • POWER LIMIT controls the number of background processes involved in the rebalancing effort and is limited to 11. Level 0 means no rebalancing will occur
    • I/O performance is impacted during rebalancing, but the amount of impact varies on which disks are being rebalanced and how much they are part of the I/O workload. The default power limit was chosen so as not to impact application performance

       

  • Performance
    • ASM will maximize the available bandwidth of disks by striping file extents across all disks in a DG
    • Two stripe widths are available: coarse which has a stripe size of 1 AU, and fine with stripe size of 128K
    • Fine striping still uses normally-sized file extents, but the striping occurs in small pieces across these extents in a round-robin fashion
    • ASM does not read from alternating mirror copies since disks contain primary and mirror extents and I/O is already balanced
    • By default the RDBMS will read from a primary extent; in 11.1 this can be changed via the PREFERRED_READ_FAILURE_GROUP parameter setting for cases where reading extents from a local node results in lower latency. Note: This is a special case applicable to "stretch clusters" and not applicable in the general usage of ASM

       

  • Miscellaneous
    • ASM can work for RAC and non-RAC databases
    • One ASM instance on a node will service any number of instances on that node
    • If using ASM for RAC, ASM must also be clustered to allow instances to update each other when file mapping changes occur
    • In 11.2 onwards, ASM is installed in a grid home along with the clusterware as opposed to an RDBMS home in prior versions.
       

Tags:
Posted in 操作系统, 概念解析 | No Comments »

组合列统计信息收集

Posted by admin on 四月 2nd, 2012

上一篇帖子,我们提到通过正确的收集列的统计信息来避免Oracle在计算时得出错误的结果。但我们实例中的SQL非常简单(只有一个条件),实际生产环境中的语句要复杂的多。类似下面的这条SQL语句的查询也非常多见,来看看这种情况下优化器的计算。

SQL > select /*+ gather_plan_statistics */ count(*) from t1 where c+d>1;

 

  COUNT(*)
———-
     93978

 

SQL > select * from table(dbms_xplan.display_cursor(null, null, 'allstats last'));

 

PLAN_TABLE_OUTPUT
————————————————————————————-
SQL_ID  6frrqz2cqtknp, child number 1
————————————-
select /*+ gather_plan_statistics */        count(*)       from t1
where c+d>:"SYS_B_0"

Plan hash value: 3724264953

————————————————————————————-
| Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
————————————————————————————-
|   1 |  SORT AGGREGATE    |      |      1 |      1 |      1 |00:00:00.04 |     364 |
|*  2 |   TABLE ACCESS FULL| T1   |      1 |   5000 |  93978 |00:00:01.69 |     364 |
————————————————————————————-

Predicate Information (identified by operation id):
—————————————————

   2 – filter("C"+"D">:SYS_B_0)

19 rows selected.

从执行计划的输出结果中可以看出,优化器的评估结果再次出现了20倍左右的误差。造成这种误差的原因是,虽然有C和D列的统计信息,但是并不存在C+D的统计信息。

Oracle 10g解决方案

可以通过设置初始化参数dynamic_sampling=4,在SQL语句执行过程中动态收集,从而得出正确的评估值。

关于dynamic_sampling参数的收集级别,可以查看 http://docs.oracle.com/cd/B19306_01/server.102/b14211/stats.htm#i43032

SQL> alter session set optimizer_dynamic_sampling=4;

 

Session altered.

 

SQL> select /*+ gather_plan_statistics */ count(*) from t1 where c+d>1;

 

  COUNT(*)
———-
     93978

 

SQL> select * from table(dbms_xplan.display_cursor(null, null, 'allstats last'));

 

PLAN_TABLE_OUTPUT
————————————————————————————–
SQL_ID  6frrqz2cqtknp, child number 0
————————————-
select /*+ gather_plan_statistics */        count(*)       from t1
where c+d>:"SYS_B_0"

Plan hash value: 3724264953

————————————————————————————-
| Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
————————————————————————————-
|   1 |  SORT AGGREGATE    |      |      1 |      1 |      1 |00:00:00.05 |     364 |
|*  2 |   TABLE ACCESS FULL| T1   |      1 |  93837 |  93978 |00:00:02.82 |     364 |
————————————————————————————-

Predicate Information (identified by operation id):
—————————————————

   2 – filter("C"+"D">:SYS_B_0)

Note
—–
   – dynamic sampling used for this statement

 

23 rows selected.

Oracle 11g解决方案

11g中引入了著名的“Extended Statistics”,解决多列组合查询或者谓词中存在表达式时,优化器如何准确评估的问题。

和extended statistics相关视图:

  • user_stat_extensions

基于上面的查询语句,创建C+D列的扩展统计。

SQL> select dbms_stats.create_extended_stats(user, 't1', '(c+d)') from dual;

 

dbms_stats.create_extended_stats(user,'t1','(c+d)')
——————————————————————————–
sys_sturfyc68xoinde_ih320edb2h

 

SQL> select * from USER_STAT_EXTENSIONS;

 

TABLE_NAME   EXTENSION_NAME                EXTENSION   CREATO DRO
————– —————————— ———— —— —-
T1          SYS_STURFYC68XOINDE_IH320EDB2H ("C"+"D")   USER   YES

 

SQL> select /*+ gather_plan_statistics */ count(*) from t1 where c+d>1;

 

  COUNT(*)
———-
     93978

 

SQL> select * from table(dbms_xplan.display_cursor(null, null, 'allstats last'));

 

PLAN_TABLE_OUTPUT
——————————————————————————————————————————————————————————————————–
SQL_ID 1dp0vu169g6xt, child number 1
————————————-
select /*+ gather_plan_statistics */ count(*) from t1 where c+d>1

Plan hash value: 3724264953

——————————————————————————————————
| Id  | Operation                 | Name | Starts | E-Rows | A-Rows |  A-Time   | Buffers | Reads  |
——————————————————————————————————
|   0 | SELECT STATEMENT          |      |  1   |       |    1   |00:00:00.79 | 361     |  243 |
|   1 |  SORT AGGREGATE           |      |  1   |     1 |    1   |00:00:00.79 | 361     |  243 |
|*  2 |   TABLE ACCESS STORAGE FULL| T1    |  1   |  93978 |  93978 |00:00:00.09 | 361     |  243 |
——————————————————————————————————

Predicate Information (identified by operation id):
—————————————————

   2 – filter("C"+"D">1)

Note
—–
   – cardinality feedback used for this statement

23 rows selected.

这个评估结果和实际返回结果是完全一致的。

Tags: ,
Posted in 概念解析 | 1 Comment »

关于dbms_stats.method_opt

Posted by admin on 四月 2nd, 2012

Oracle推荐使用dbms_stats包收集统计信息,在收集列统计信息或者直方图时,需要使用到method_opt参数。该参数主要功能有:

  • 控制哪些列的统计信息会被收集;
  • 控制哪些列的直方图会被收集;

和列统计信息相关的视图:

  • user_tab_col_statistics
  • user_part_col_statistics
  • user_subpart_col_statistics

在使用method_opt收集列统计信息的时候,经常会看到类似的语句:

method_opt=>'for all indexed columns size auto'

相信大家都知道这个语句的意义 — dbms_stats仅仅收集创建了索引的列的统计信息,并且基于索引列的数据分布来决定是否创建直方图,以及用于存放直方图的buckets数量。这种方式在某些场景,可能会造成一些问题。看看下面的例子:

SQL> create table t1 (id number, a number, b number, c number, d number);

 

Table created.

 

SQL> exec dbms_random.initialize(1);

 

PL/SQL procedure successfully completed.

 

SQL> begin
        for i in 1..100000 loop
        insert into t1 values (i, round(dbms_random.value(1,2)), round(dbms_random.value(1,5)), -
          round(dbms_random.value(1,10)), round(dbms_random.value(1,100)));
        end loop;
        commit;
    end;
/

 

PL/SQL procedure successfully completed.

 

SQL> exec dbms_stats.gather_table_stats(user,'t1',estimate_percent=>30,cascade=>true);

 

PL/SQL procedure successfully completed.

视图user_tab_col_statistics中记录了和列统计相关的一些关键信息,比如NDV,直方图,buckets等。

SQL> select
       column_name, num_distinct, histogram, num_buckets,
       to_char(last_analyzed,'yyyy-dd-mm hh24:mi:ss') last_analyzed
     from user_tab_col_statistics
     where table_name='T1'
/

 

COLUMN_NAME                    NUM_DISTINCT HISTOGRAM       NUM_BUCKETS LAST_ANALYZED
—————————— ———— ————— ———– ———————–
ID                                   100467 NONE                      1 2012-02-04 09:03:48
A                                         2 NONE                      1 2012-02-04 09:03:48
B                                         5 NONE                      1 2012-02-04 09:03:48
C                                        10 NONE                      1 2012-02-04 09:03:48
D                                       100 NONE                      1 2012-02-04 09:03:48

接下来在列id上创建一个索引,看看收集的统计信息。

SQL> create unique index pk_t1 on t1(id);

 

Index created.

 

SQL> begin
  dbms_stats.delete_table_stats(user,'T1');

  dbms_stats.gather_table_stats(
    ownname => user,
    tabname => 'T1',
    estimate_percent => 30,
    method_opt => 'for all indexed columns',
    cascade => true);
end;
/

 

PL/SQL procedure successfully completed.

 

SQL> select
       column_name, num_distinct, histogram, num_buckets,
       to_char(last_analyzed,'yyyy-dd-mm hh24:mi:ss') last_analyzed
     from user_tab_col_statistics
     where table_name='T1'
/

 

COLUMN_NAME                    NUM_DISTINCT HISTOGRAM       NUM_BUCKETS LAST_ANALYZED
—————————— ———— ————— ———– ———————-
ID                                   100153 HEIGHT BALANCED          75 2012-02-04 09:05:23

 

SQL> begin
  dbms_stats.delete_table_stats(user,'T1');

  dbms_stats.gather_table_stats(
    ownname => user,
    tabname => 'T1',
    estimate_percent => 100,
    method_opt => 'for all indexed columns size auto',
    cascade => true);
end;
/

 

PL/SQL procedure successfully completed.

 

SQL>
SQL> select
       column_name, num_distinct, histogram, num_buckets,
       to_char(last_analyzed,'yyyy-dd-mm hh24:mi:ss') last_analyzed
     from user_tab_col_statistics
     where table_name='T1'
/

 

COLUMN_NAME                    NUM_DISTINCT HISTOGRAM       NUM_BUCKETS LAST_ANALYZED
—————————— ———— ————— ———– ——————–
ID                                   100000 NONE                      1 2012-02-04 09:12:47

对比几次查询的输出可以看到,指定“all indexed columns”时只收集了列id的信息,而其他列的信息并没有收集。在没有指定size auto时,默认的buckets数量为75,指定则会根据数据分布情况创建。

到现在为止还看不出这种现象对系统有什么影响,再看看下面的例子。

SQL> select /*+ gather_plan_statistics */
       count(*)
     from t1
     where a=1
/

 

  COUNT(*)
———-
     49726

 

SQL> select * from table(dbms_xplan.display_cursor(null, null, 'allstats last'));

 

PLAN_TABLE_OUTPUT
————————————————————————————-
SQL_ID  b4ka9hw10bdvn, child number 0
————————————-
select /*+ gather_plan_statistics */        count(*)      from t1      where
a=:"SYS_B_0"

Plan hash value: 3724264953

————————————————————————————-
| Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
————————————————————————————-
|   1 |  SORT AGGREGATE    |      |      1 |      1 |      1 |00:00:00.03 |     364 |

PLAN_TABLE_OUTPUT
————————————————————————————-
|*  2 |   TABLE ACCESS FULL| T1   |      1 |   1001 |  49726 |00:00:02.39 |     364 |
————————————————————————————-

Predicate Information (identified by operation id):
—————————————————

   2 – filter("A"=:SYS_B_0)

19 rows selected.

从执行计划中可以看出,优化器估计的行数是1001,而实际上返回了49726行。评估误差大约50倍,为什么会产生这么大的差距呢?根据cardinality计算公式:

cardinality = (num_rows of t1) * 1/NDV = 100000 * 1/2 = 50000

这个计算结果,和实际的返回行数基本是一致的。但是由于这里没有收集列A的统计信息,优化器给出了一个猜测值 — 1%,100000 * 1% = 1000。10053事件记录更能清楚的反应这个现象。

SINGLE TABLE ACCESS PATH
  —————————————–
  BEGIN Single Table Cardinality Estimation
  —————————————–
  Column (#2): A(NUMBER)  NO STATISTICS (using defaults)
    AvgLen: 13.00 NDV: 3125 Nulls: 0 Density: 3.2000e-04
  Table: T1  Alias: T1    
    Card: Original: 100000  Rounded: 1000  Computed: 1000.00  Non Adjusted: 1000.00
  —————————————–

随着查询谓词的增多,这种计算的误差会越来越大,在实际生产中就会由于缺少列的统计信息导致优化器选择错误的执行计划。因此“for all indexed columns”应该慎用!

Tags: ,
Posted in 概念解析 | 2 Comments »

通过NFS进行数据泵导出导入

Posted by admin on 十二月 14th, 2011

expdp/impdp是Oracle10g中新增的导出导入工具,比exp/imp提供了更好的性能和更强大的作业控制。但是expdp/impdp的数据只能放在服务器端,客户端执行的时候我们可以通过挂NFS盘的方式,将客户端的磁盘映射到服务器端。设置步骤简单记录如下:

环境:

NFS SERVER: Red Hat AS 5.4
NFS CLIENT: AIX 5.3

NFS服务端(Oracle客户端)设置

# vi /etc/exports

/home/share    *(rw)

# service portmap start
# service nfs start

NFS客户端(Oracle服务器端)设置

# nfso -o nfs_use_reserved_ports=1

如果设置不正确可能会出现下面的错误:

# mount 192.168.0.76:/home/share /home/share
       mount: 1831-008 giving up on:
       192.168.0.76:/home/share
       vmount: Operation not permitted.

NFS客户端挂载磁盘

mount -o rw,bg,hard,nointr,rsize=32768,wsize=32768,proto=tcp,vers=3,timeo=600 192.168.0.76:/home/share /home/share

或者设置 /etc/filesystems 文件

/dds/expganso:
        dev             = /dds/expganso
        vfs             = nfs
        mount           = true
        type            = nfs_mount
        nodename        = ddsser
        options         = rw,bg,hard,nointr,rsize=32768,wsize=32768,proto=tcp,vers=3,timeo=600
        account         = false

设置event 10298事件

alter system set events '10298 trace name context forever,level 32';

执行导出导入操作

expdp test/test@test directory=testnfs dumpfile=second.dmp tables=second nologfile=y

impdp test/test directory=testnfs dumpfile=second.dmp full=y REMAP_SCHEMA=test:testnfs nologfile=y

Tags:
Posted in 备份恢复 | 1 Comment »

Linux 平台安装 Oracle Timesten

Posted by admin on 十二月 13th, 2011

修改相应的内核参数

kernel.sem = 250 32000 100 128
kernel.shmmax=2147483648
kernel.shmall=4194304
kernel.sem = 250 32000 100 128
net.ipv4.tcp_rmem=4096 4194304 4194304
net.ipv4.tcp_wmem=98304 4194304 4194304
net.core.rmem_default=262144
net.core.wmem_default=262144
net.core.rmem_max=4194304
net.core.wmem_max=4194304
net.ipv4.tcp_window_scaling=1
net.ipv4.ip_local_port_range="1024 65000"

创建用户组

groupadd timesten
usermod -G timesten,oinstall,dba oracle

创建timesten注册文件

mkdir /etc/TimesTen
touch /etc/TimesTen/instance_info
groupadd ttadmin
chgrp -R ttadmin /etc/TimesTen
chmod 770 /etc/TimesTen/
chmod 660 /etc/TimesTen/*

安装timesten

[oracle@ora10gr2 linux86]$ ./setup.sh

NOTE: Each TimesTen installation is identified by a unique instance name.
      The instance name must be a non-null alphanumeric string, not longer
      than 255 characters.

Please choose an instance name for this installation? [ tt1121 ]
Instance name will be 'tt1121'.
Is this correct? [ yes ]

Of the three components:

  [1] Client/Server and Data Manager
  [2] Data Manager Only
  [3] Client Only

Which would you like to install? [ 1 ]

Of the following options :

  [1] /home/oracle
  [2] /home/oracle
  [3] Specify a location
  [q] Quit the installation

Where would you like to install the tt1121 instance of TimesTen? [ 1 ] 3
Please specify a directory to install TimesTen? [ /home/oracle ] /u01/app/oracle/timesten
Where would you like to create the daemon home directory? [ /u01/app/oracle/timesten/TimesTen/tt1121/info ]
The directory /u01/app/oracle/timesten/TimesTen/tt1121/info does not exist.
Do you want to create it? [ yes ]

The daemon logs will be located in /u01/app/oracle/timesten/TimesTen/tt1121/info
Would you like to specify a different location for the daemon logs? [ no ]
Installing into /u01/app/oracle/timesten/TimesTen/tt1121 …
Creating /u01/app/oracle/timesten/TimesTen/tt1121 …
Uncompressing …

NOTE: If you are configuring TimesTen for use with Oracle Clusterware, the
      daemon port number must be the same across all TimesTen installations
      managed within the same Oracle Clusterware cluster.

NOTE: All installations that replicate to each other must use the same daemon
      port number that is set at installation time. The daemon port number can
      be verified by running 'ttVersion'.

The default port number is 53384.

Do you want to use the default port number for the TimesTen daemon? [ yes ]
The daemon will run on the default port number (53384).

NOTE: For security, we recommend that you restrict access to the
      TimesTen installation to members of a single OS group. Only members of
      that OS group will be allowed to perform direct mode connections to
      TimesTen, and only members of that OS group will be allowed to perform
      operations that access TimesTen data stores, TimesTen files and shared
      memory. The OS group defaults to the primary group of the instance
      administrator. You can default to this group, choose another OS group
      or you can make this instance world-accessible. If you choose to make
      this instance world-accessible, all database files and shared memory
      are readable and writable by all users.

Restrict access to the the TimesTen installation to the group 'oinstall'? [ yes ]

NOTE: Enabling PL/SQL will increase the size of some TimesTen libraries.

Would you like to enable PL/SQL for this instance? [ yes ]
      TNS_ADMIN was not set in your environment but there is a tnsnames.ora
      file in /u01/app/oracle/product/10.2.0/db_1/network/admin.
Would you like to use this TNS_ADMIN setting for the In-Memory Database Cache? [ yes ]

TNS_ADMIN will be set to /u01/app/oracle/product/10.2.0/db_1/network/admin
You can change TNS_ADMIN later by running <install_dir>/bin/ttmodinstall.

NOTE: It appears that you are running version 3.4 or higher of the g++
      compiler. TimesTen ships with multiple sets of client libraries and server
      binaries : one built for compatibility with g++ 3.4.6 and one with
      g++ 4.1.0. The installer has created links to the 3.4.6 library in the
      <install_dir>/lib directory and to the 3.4.6 server binary in the
      <install_dir>/bin directory. If you want to use a different compiler,
      please modify the links to point to the desired library and server binary.

Installing server components …
What is the TCP/IP port number that you want the TimesTen Server to listen on? [ 53385 ]
Do you want to install QuickStart and the TimesTen Documentation? [ no ]
Would you like to install the documentation (without QuickStart)? [ yes ]
Where would you like to create the doc directory (s=skip)? [ /u01/app/oracle/timesten/TimesTen/tt1121/doc ]
The TimesTen documentation has been installed in /u01/app/oracle/timesten/TimesTen/tt1121/doc.
Installing client components …

Would you like to use TimesTen Replication with Oracle Clusterware? [ no ]

NOTE: The TimesTen daemon startup/shutdown scripts have not been installed.

Run the 'setuproot' script :
        cd /u01/app/oracle/timesten/TimesTen/tt1121/bin
        ./setuproot -install
This will move the TimesTen startup script into its appropriate location.

The startup script is currently located here :
  '/u01/app/oracle/timesten/TimesTen/tt1121/startup/tt_tt1121'.

The 11.2.1.8 Release Notes are located here :
  '/u01/app/oracle/timesten/TimesTen/tt1121/README.html'

Starting the daemon …
TimesTen Daemon startup OK.
End of TimesTen installation.

Tags:
Posted in 概念解析 | No Comments »

Oracle Goldengate ORA-21780故障处理

Posted by admin on 十一月 14th, 2011

Oracle Goldengate升级到11.1.1.1.1后,解决了前期频繁出现的一些错误,但是又出现了新的错误。

2011-11-11 16:54:03  WARNING OGG-00455  Oracle GoldenGate Capture for Oracle, ext2.prm:  Problem in resolving [xxx.tab_xxx]: ORA-21780: Maximum number of object durations exceeded., try to fix this issue in order to avoid possible fatal error.
2011-11-11 16:54:03  ERROR   OGG-00521  Oracle GoldenGate Capture for Oracle, ext2.prm:  Object was resolved, however in the same resolution call both DDL history and database metadata resolution failed, cannot recover, SCN [2777663572], object id [56041].
2011-11-11 16:54:05  ERROR   OGG-01668  Oracle GoldenGate Capture for Oracle, ext2.prm:  PROCESS ABENDING.

造成错误的原因是OGG 11.1.1.1.1中引入的一个自动开启特性 — logretention,这个特性触发了bug 12732996。

LOGRETENTION主要功能是防止rman删除ogg恢复所需要用到的归档日志,可以通过禁用这个特性来解决上面的这个问题。

ggsci> stop ext2
ggsci> dblogin userid xx password xx
ggsci> unregister extract ext2 logretention
ggsci> edit params ext2

TRANLOGOPTIONS LOGRETENTION DISABLED   — add

ggsci> start ext2
 

Tags:
Posted in 备份恢复, 故障诊断 | No Comments »

svmon -S中inuse的求和脚本及其结果比svmon -G小的原因

Posted by admin on 十一月 1st, 2011

很多客户可能认为svmon -S中inuse的求和结果和svmon -G中的inuse一样,但是实际是不一样的。下面的脚本可以用来统计svmon -S中的inuse的相加结果:

==============================================
#!/usr/bin/ksh
svmon -S | cut -c54-62 | awk '/^[-sLm]/ {if ($1 ~ /L/)
{COUNT1 =($2*4096+COUNT1)}
else if ($1 ~ /m/)
{COUNT2 =($2*16+COUNT2)}
else {COUNT3 =$2+COUNT3}}
END {printf "The result is as following with 4k as unit size\n16M page count=%d\n64k page count=%d\n4k page count=%d\nTatal page count=%d\n", COUNT1,COUNT2,COUNT3,'COUNT1+COUNT2+COUNT3'}'
========================================================

那么,产生这种差别的原因是什么呢?解释如下:
svmon -S用来显示系统中所有内存段(segment)的内存使用信息。AIX上仅存在三种内存段,它们是work,client和persistent。因此,统计svmon -S中inuse的和就是将被使用的上述三种内存段进行求和。但是,这种统计并没有将系统上所有的被使用的内存页面统计进来。系统里存在着一些尚未被VMM管理的内存页面,这些页面已经被使用,但是不属于上述三种内存段,因此在svmon -S中体现不出来。而svmon -G则包含了这些未被管理的页面。

这些未被VMM管理的内存主要是被硬件使用,用来对物理内存做一些设置。在AIX 5L中,可以通过在kdb执行vmstat来查看未被管理的内存,输出如下:

VMM Memory Limits:

Total available memory (4K frames) : 00100000 4.0GB
Total unmanaged mem (wlm_hw_pages): 0000D639 214.3MB

4K number of frames : 000F29C7 3.8GB
4K frames pinned : 00009FEE 160.0MB
4K system pinnable frames remaining: 000B817E 2.9GB
4K user pinnable frames remaining : 000BC0BC 3.0GB

Free paging space (in 4K blocks) : 0001FD00 509.0MB
Paging space SIGDANGER level : 00001000 16.0MB
Paging space SIGKILL level : 00000400 4.0MB
 

其中“unmanaged mem”就代表这类未被VMM管理的内存页面。

本文转自:http://www-900.ibm.com/cn/support/viewdoc/detail?DocId=2811998D15000

Tags:
Posted in 操作系统 | No Comments »

ogg replicat 进程 abend 处理

Posted by admin on 十一月 1st, 2011

Oracle Goldengate实际使用过程中经常会出现abend的现象,有时ggserr.log提示的信息又让我们摸不着头脑。

2011-11-01 09:14:28  WARNING OGG-01431  Oracle GoldenGate Delivery for Oracle, rep1.prm:  Aborted grouped transaction on 'XXX.XXX_BONUS_LOG', Mapping error.
2011-11-01 09:14:28  WARNING OGG-01003  Oracle GoldenGate Delivery for Oracle, rep1.prm:  Repositioning to rba 4662627 in seqno 2114.
2011-11-01 09:14:28  WARNING OGG-01151  Oracle GoldenGate Delivery for Oracle, rep1.prm:  Error mapping from XXX.XXX_BONUS_LOG to XXX.XXX_BONUS_LOG.
2011-11-01 09:14:28  WARNING OGG-01003  Oracle GoldenGate Delivery for Oracle, rep1.prm:  Repositioning to rba 4662627 in seqno 2114.
2011-11-01 09:14:28  ERROR   OGG-01296  Oracle GoldenGate Delivery for Oracle, rep1.prm:  Error mapping from XXX.XXX_BONUS_LOG to XXX.XXX_BONUS_LOG.
2011-11-01 09:14:28  ERROR   OGG-01668  Oracle GoldenGate Delivery for Oracle, rep1.prm:  PROCESS ABENDING.

上面的这个错误,如果用logdump去查看,你会发现日志seqno 2114 rba 4662627位置根本就不是XXX.XXX_BONUS_LOG。原因很简单,Goldengate加载的时候默认遵循源端的事务一致性,在这个例子中,seqno 2114 rba 4662627只是事务的起点,而出错的位置在ggserr.log中没有办法定位。这时候就需要用到一些特殊的参数来帮助我们来定位具体的问题原因。

  • SHOWSYNTAX 

         Use the SHOWSYNTAX parameter to start an interactive session where you can view each Replicat SQL statement before it is applied. By viewing the syntax of SQL statements that failed, you might be able to diagnose the cause of the problem.

  • NODYNSQL

         With DYNSQL, the default, Replicat uses dynamic SQL to compile a statement once, and then execute it many times with different bind variables.

  • NOBINARYCHARS

         NOBINARYCHARS is an undocumented parameter that causes Oracle GoldenGate to treat binary data as a null-terminated string.

通过这三个参数的结合,在report文件中记录详细的SQL语句,和具体的出错位置,结合logdump和具体的SQL语句,相信很快能够定位出问题的原因。

2011-11-01 09:15:56  WARNING OGG-01431  Aborted grouped transaction on 'XXX.XXX_BONUS_LOG', Mapping error.
2011-11-01 09:15:56  WARNING OGG-01003  Repositioning to rba 4662954 in seqno 2114.
2011-11-01 09:15:56  WARNING OGG-01151  Error mapping from XXX.XXX_BONUS_LOG to XXX.XXX_BONUS_LOG.
2011-11-01 09:15:56  WARNING OGG-01003  Repositioning to rba 4662954 in seqno 2114.

Source Context :
  SourceModule            : [er.main]
  SourceID                : [/scratch/angorant/view_storage/angorant_ogg_12978807_x64/oggcore/OpenSys/src/app/er/rep.c]
  SourceFunction          : [take_rep_err_action]
  SourceLine              : [16134]
  ThreadBacktrace         : [8] elements
                          : [/u01/app/oracle/ggs/replicat(CMessageContext::AddThreadContext()+0x26) [0x5ef8b6]]
                          : [/u01/app/oracle/ggs/replicat(CMessageFactory::CreateMessage(CSourceContext*, unsigned int, ...)+0x7b2) [0x5e6382]]
                          : [/u01/app/oracle/ggs/replicat(_MSG_ERR_MAP_TO_TANDEM_FAILED(CSourceContext*, DBString<777> const&, DBString<777> const&, CMessageFactory::MessageDisposition)+0x9b) [0x5c4bcb]]
                          : [/u01/app/oracle/ggs/replicat [0x81ac2f]]
                          : [/u01/app/oracle/ggs/replicat [0x8f73e2]]
                          : [/u01/app/oracle/ggs/replicat(main+0x84b) [0x50764b]]
                          : [/lib64/tls/libc.so.6(__libc_start_main+0xdb) [0x30f3c1c40b]]
                          : [/u01/app/oracle/ggs/replicat(__gxx_personality_v0+0x1da) [0x4e3c2a]]

2011-11-01 09:15:56  ERROR   OGG-01296  Error mapping from XXX.XXX_BONUS_LOG to XXX.XXX_BONUS_LOG.

可以看到,出错的位置是rba 4662954,具体的trail文件信息如下:

Logdump 195 >n
___________________________________________________________________
Hdr-Ind    :     E  (x45)     Partition  :     .  (x04) 
UndoFlag   :     .  (x00)     BeforeAfter:     B  (x42) 
RecLength  :   227  (x00e3)   IO Time    : 2011/10/31 11:18:19.230.994  
IOType     :     3  (x03)     OrigNode   :   255  (xff)
TransInd   :     .  (x01)     FormatType :     R  (x52)
SyskeyLen  :     0  (x00)     Incomplete :     .  (x00)
AuditRBA   :       4602       AuditPos   : 200518188
Continued  :     N  (x00)     RecCount   :     1  (x01)

2011/10/31 11:18:19.230.994 Delete               Len   227 RBA 4662954
Name: XXX.XXX_BONUS_LOG
Before Image:                                             Partition 4   G  m  
 0000 0015 0000 3230 3131 2d31 302d 3331 3a31 303a | ……2011-10-31:10: 
 3537 3a34 3500 0100 0a00 0000 0000 0000 1ca2 1100 | 57:45…………… 
 0200 0a00 0000 0000 0000 0000 1b00 0300 0a00 00ff | ……………….. 
 ffff ffff fffc e000 0400 0a00 0000 0000 0000 0000 | ……………….. 
 0000 0500 0700 0000 034e 4554 0006 000a 0000 0000 | ………NET…….. 
 0102 aea6 3a3b 0007 0004 ffff 0000 0008 0014 0000 | ….:;………….. 
 0010 3331 3131 3938 302d bbfd b7d6 bbbb b9ba 0009 | ..3111980-………. 
Column     0 (x0000), Len    21 (x0015) 
 0000 3230 3131 2d31 302d 3331 3a31 303a 3537 3a34 | ..2011-10-31:10:57:45

通过logdump发现这是处于事务中间的一个删除语句出错了,检查发现这张表的该记录确实不存在,因此导致Error mapping错误的发生。但由于这是事务中间的一条记录,我们不能直接跳到故障语句之后,这里还需要借助另外两个参数的帮助。

  • GROUPTRANSOPS

         Controls the number of records that are sent to the trail in one batch.

  • MAXTRANSOPS

         Divides large source transactions into smaller ones on the target system.

通过这两个参数,可以把源端大的事务拆分成小的事务。为了方便起见,我们设置这两个参数为1。

edit params rep1

grouptransops 1
maxtransops 1

再重启rep1进程,rep1进程在出错位置停下来后,手工跳过有问题的语句。

alter rep1, extseqno 2114, extrba 4663281
start rep1

至此,这个问题得到了解决。当然根治这个问题最好的办法还是全同步数据不一致的表,但在一个比较大的生产环境中重新全同步表还是比较麻烦的,在出错语句不是太多的情况下,这也不失为一种解决办法。而我们这个案例刚好是delete操作,因此可以简单的跳过,如果是update或insert则还需要进一步分析。

Tags:
Posted in 备份恢复, 故障诊断 | No Comments »

Oracle执行计划显示

Posted by admin on 十月 27th, 2011

生成和显示SQL语句的执行计划,是大多数DBA、SQL开发人员以及性能优化专家经常做的工作,因为执行计划能够提供SQL语句性能相关的信息。执行计划解释了SQL语句执行的详细过程,这个过程记录了一系列的数据库操作以及每个操作涉及到的数据行数和生成的数据行数。优化器使用查询转换和物理优化技术决定数据库操作顺序和过程实现。

执行计划通常以扁平的表格形式呈现,是一个事实树形结构。下面是一个基于SH模式中SALES、PRODUCTS表生成的查询:

SQL> select prod_category, avg(amount_sold)
 2   from sales s, products p
 3   where p.prod_id = s.prod_id
 4   group by prod_category;

执行计划以表格的形式呈现:

——————————————
 Id   Operation              Name
——————————————
   0  SELECT STATEMENT
   1   HASH GROUP BY
   2    HASH JOIN
   3     TABLE ACCESS FULL   PRODUCTS
   4     PARTITION RANGE ALL
   5      TABLE ACCESS FULL  SALES
——————————————

通过事实树来解读执行计划:

   GROUP BY
      |
     JOIN
 _____|_______
 |            |
ACCESS     ACCESS
(PRODUCTS) (SALES)

计划树的执行顺序是从下到上,上述的例子中,首先执行的是表的访问操作,也就是树的叶子部分。通过执行计划,我们可以看出访问操作是全表扫描,表扫描返回的数据行用来做连接操作,这里连接操作的类型是hash连接。最后对连接操作返回的数据行进行group-by,这里分组同样使用的是hash。

值得一提的是,查询优化器最终选择的执行计划是从众多的可选择执行计划中选取的代价最低的一个。这里的代价可以理解为性能的衡量指标,代价越低性能越好。查询优化器使用的代价模型是通过评估IO、CPU及网络等方面的数据计算出来的。

Oracle数据库中可以通过两种方式查看SQL语句的执行计划:

EXPLIAN PLAN 命令 — 这种方式没有实际执行SQL语句而仅仅把执行计划显示出来;
V$SQL_PALN — 从Oracle 9i开始引入了这个V$视图,通过该视图可以查询游标缓存中存在的SQL语句的执行计划。

在某些特定的场景下,使用EXPLAIN PLAN得到的执行计划可能和V$SQL_PLAN不同。比如,当SQL语句包含绑定变量时,EXPLAIN PLAN得到的执行计划会忽略绑定变量值,而V$SQL_PLAN中记录的执行计划则考虑了绑定变量值。

Oracle 9i引入了dbms_xplan包,随后的版本中该包的功能不断的增强,使得查看执行计划变得更加便利。这个包里提供了几个PL/SQL函数,用于从不同的数据源获取执行计划:

1. EXPLAIN PLAN command
2. V$SQL_PLAN
3. Automatic Workload Repository (AWR)
4. SQL Tuning Set (STS)
5. SQL Plan Baseline (SPM)

下面通过一些具体的例子展示如果使用dbms_xplan包提供的函数,产生和显示SQL语句的执行计划。

例1:使用EXPLAIN PLAN command和dbms_xplan.display函数

SQL> EXPLAIN PLAN FOR
 2   select prod_category, avg(amount_sold)
 3   from sales s, products p
 4   where p.prod_id = s.prod_id
 5   group by prod_category;

Explained.

SQL> select plan_table_output
 2   from table(dbms_xplan.display('plan_table', null, 'basic'));

——————————————
 Id   Operation              Name
——————————————
   0  SELECT STATEMENT
   1   HASH GROUP BY
   2    HASH JOIN
   3     TABLE ACCESS FULL   PRODUCTS
   4     PARTITION RANGE ALL
   5      TABLE ACCESS FULL  SALES
——————————————

dbms_xplan.display使用的参数有:

plan table name (默认 'PLAN_TABLE')
statement_id (默认 null),
format (默认 'TYPICAL')

更详细的信息可以查看$ORACLE_HOME/rdbms/admin/dbmsxpln.sql。

例2:生成和显示会话中最后执行的SQL语句的执行计划

SQL> select prod_category, avg(amount_sold)
 2   from sales s, products p
 3   where p.prod_id = s.prod_id
 4   group by prod_category;

no rows selected

SQL> select plan_table_output
 2   from table(dbms_xplan.display_cursor(null, null, 'basic'));

——————————————
 Id   Operation              Name
——————————————
   0  SELECT STATEMENT
   1   HASH GROUP BY
   2    HASH JOIN
   3     TABLE ACCESS FULL   PRODUCTS
   4     PARTITION RANGE ALL
   5      TABLE ACCESS FULL  SALES
——————————————

dbms_xplan.display_cursor使用的参数有:

SQL ID (默认 null, null意味着当前会话中最后执行的SQL语句)
child number (默认 0),
format (默认 'TYPICAL')

例3:显示任何其他语句的执行计划

直接提供SQL_ID:

SQL> select plan_table_output from
 2   table(dbms_xplan.display_cursor('fnrtqw9c233tt',null,'basic'));

间接查询获取SQL_ID:

SQL> select plan_table_output
 2   from v$sql s,
 3   table(dbms_xplan.display_cursor(s.sql_id,
 4                                  s.child_number, 'basic')) t
 5   where s.sql_text like 'select PROD_CATEGORY%';

例4:根据SQL Plan Baseline显示执行计划。SQL Plan Baseline是Oracle 11g中引入的新概念,用于支持SQL Plan Management (SPM)特性。

SQL> alter session set optimizer_capture_sql_plan_baselines=true;

Session altered.

SQL> select prod_category, avg(amount_sold)
 2   from sales s, products p
 3   where p.prod_id = s.prod_id
 4   group by prod_category;

no rows selected

假如上述语句执行超过一次,将会产生一个该语句的SQL Plan Baseline,可以通过下面的查询进行确认:

SQL> select SQL_HANDLE, PLAN_NAME, ACCEPTED
 2   from dba_sql_plan_baselines
 3   where sql_text like 'select prod_category%';

SQL_HANDLE                     PLAN_NAME                      ACC
—————————— —————————— —
SYS_SQL_1899bb9331ed7772       SYS_SQL_PLAN_31ed7772f2c7a4c2  YES

上面创建的SQL Plan Baseline可以通过下面的方式显示:

直接提供SQL_HANDLE:

SQL> select t.* from
 2   table(dbms_xplan.display_sql_plan_baseline('SYS_SQL_1899bb9331ed7772',
 3                                              format => 'basic')) t;

间接查询获取SQL_HANDLE:

SQL> select t.*
 2       from (select distinct sql_handle
 3             from dba_sql_plan_baselines
 4             where sql_text like 'select prod_category%') pb,
 5       table(dbms_xplan.display_sql_plan_baseline(pb.sql_handle,
 6                                                  null,'basic')) t;

这两条语句的输出结果如下:

—————————————————————————-
SQL handle: SYS_SQL_1899bb9331ed7772
SQL text: select prod_category, avg(amount_sold) from sales s, products p
          where p.prod_id = s.prod_id group by prod_category
—————————————————————————-
Plan name: SYS_SQL_PLAN_31ed7772f2c7a4c2
Enabled: YES     Fixed: NO      Accepted: YES     Origin: AUTO-CAPTURE
—————————————————————————-

Plan hash value: 4073170114
———————————————————
 Id   Operation                 Name              
———————————————————
   0  SELECT STATEMENT                            
   1   HASH GROUP BY                              
   2    HASH JOIN                                 
   3     VIEW                   index$_join$_002  
   4      HASH JOIN                               
   5       INDEX FAST FULL SCAN PRODUCTS_PK       
   6       INDEX FAST FULL SCAN PRODUCTS_PROD_CAT_IX
   7     PARTITION RANGE ALL                      
   8      TABLE ACCESS FULL     SALES             
———————————————————

格式化

格式化参数可以进行高度定制,可以根据实际需要输出适当的信息。高级别的选项有:

Basic 输出的执行计划包括操作、选项和对象名(表、索引、物化视图等)
Typical 输出的执行计划包括Basic内容,加上和优化器相关的内部信息,如代价、大小、基数等,具体包括执行计划中的每个操作,优化器计算出来的每个操作的代价,每个操作返回的数据行数等,同时还会包括操作中所使用的评估谓词。Oracle CBO中存在两种谓词:ACCESS和FILTER。ACCESS表示根据查询条件,使用索引提取相关的数据块。FILTER表示数据块提取之后的评估。
All 输出的执行计划包括Typical内容,加上每个操作生成的表达式列表、提示别名、查询块的名称。

低级选项允许包括或者排除诸如谓词、代价之类的细节,举例如下:

SQL> select plan_table_output
 2   from table(dbms_xplan.display('plan_table',null,'basic +predicate +cost'));

——————————————————-
 Id   Operation              Name      Cost (%CPU)
——————————————————-
   0  SELECT STATEMENT                    17  (18)
   1   HASH GROUP BY                      17  (18)
*  2    HASH JOIN                         15   (7)
   3     TABLE ACCESS FULL   PRODUCTS      9   (0)
   4     PARTITION RANGE ALL               5   (0)
   5      TABLE ACCESS FULL  SALES         5   (0)
——————————————————-

Predicate Information (identified by operation id):
—————————————————
2 – access("P"."PROD_ID"="S"."PROD_ID")

select plan_table_output from
table(dbms_xplan.display('plan_table',null,'typical -cost -bytes'));

—————————————————————————-
 Id   Operation              Name      Rows  Time      Pstart Pstop
—————————————————————————-
   0  SELECT STATEMENT                    4  00:00:01            
   1   HASH GROUP BY                      4  00:00:01            
*  2    HASH JOIN                       960  00:00:01            
   3     TABLE ACCESS FULL   PRODUCTS   766  00:00:01            
   4     PARTITION RANGE ALL            960  00:00:01      1     16
   5      TABLE ACCESS FULL  SALES      960  00:00:01      1     16
—————————————————————————-

Predicate Information (identified by operation id):
—————————————————
2 – access("P"."PROD_ID"="S"."PROD_ID")

注解部分

dbms_xplan包生成执行计划时会将注释显示在NOTE部分,比如查询优化过程中使用了动态抽样或者星形转换应用在查询中。比如SALES表没有统计信息,优化器在分析代价时将会使用动态抽样,执行计划将会把这一过程记录在NOTE部分。

SQL> select plan_table_output
 2   from table(dbms_xplan.display('plan_table',null,'basic +note'));

——————————————
 Id   Operation              Name  
——————————————
   0  SELECT STATEMENT             
   1   HASH GROUP BY               
   2    HASH JOIN                  
   3     TABLE ACCESS FULL   PRODUCTS
   4     PARTITION RANGE ALL       
   5      TABLE ACCESS FULL  SALES 
——————————————

Note
—–
- dynamic sampling used for this statement

绑定窥视

在生成执行计划时,优化器会考虑绑定变量的实际值,这一过程就是所谓的绑定变量窥视。就像我们前面提到的那样,V$SQL_PLAN中记录的执行计划考虑了绑定变量值而EXPLAIN PLAN命令生成的执行计划并没有考虑这一点。从Oracle10gR2开始,dbms_xplan包可以显示用于生成特定计划或者游标的绑定变量值,只需要在display_cursor()函数时加上'+peeked_binds'参数即可。

下面的例子展示了一点:

SQL> variable pcat varchar2(50)
SQL> exec :pcat := 'Women'

SQL> select PROD_CATEGORY, avg(amount_sold)
 2   from sales s, products p
 3   where p.PROD_ID = s.PROD_ID
 4   and prod_category != :pcat
 5   group by PROD_CATEGORY;

SQL> select plan_table_output
 2   from table(dbms_xplan.display_cursor(null,null,'basic +PEEKED_BINDS'));

——————————————
 Id   Operation              Name  
——————————————
   0  SELECT STATEMENT             
   1   HASH GROUP BY               
   2    HASH JOIN                  
   3     TABLE ACCESS FULL   PRODUCTS
   4     PARTITION RANGE ALL       
   5      TABLE ACCESS FULL  SALES 
——————————————

Peeked Binds (identified by position):
————————————–

1 – :P CAT (VARCHAR2(30), CSID=2): 'Women'

Tags:
Posted in 概念解析 | No Comments »