清除掉shared pool中某条sql语句方法

联系:手机/微信(+86 17813235971) QQ(107644445)

标题:清除掉shared pool中某条sql语句方法

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

在论坛中看到一个帖子,如何清除掉shared pool中某条sql语句,如果是在10g以前的版本,那估计会比较麻烦,为了删除一条sql语句记录,需要清空整个shared pool,在10g中提供了新的dbms_shared_pool包可以实现该功能(如果该包没有安装,可以通过?/rdbms/admin/dbmspool.sql安装),下面我通过在11g中试验证明该问题
1.数据库版本信息

SQL> select * from v$version;
BANNER
----------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
PL/SQL Release 11.2.0.1.0 - Production
CORE    11.2.0.1.0      Production
TNS for 32-bit Windows: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production

2.模拟一条sql语句

SQL> create table xff as
  2  select * from dba_tables
  3  where rownum<10;
表已创建。
SQL> select count(*) from xff;
  COUNT(*)
----------
         9
SQL> col sql_text for a30
SQL> SELECT ADDRESS,HASH_VALUE,SQL_TEXT FROM V$SQLAREA
  2  WHERE SQL_TEXT LIKE 'select % xff';
ADDRESS  HASH_VALUE SQL_TEXT
-------- ---------- ------------------------------
1EFB91B8 3642190903 select count(*) from xff

3.打破神话一:权限操作
对表进行权限操作,可以清除该表在shared pool中关于该表记录

SQL> grant select on xff to chf;
授权成功。
SQL> col sql_text for a30
SQL> SELECT ADDRESS,HASH_VALUE,SQL_TEXT FROM V$SQLAREA
  2  WHERE SQL_TEXT LIKE 'select % xff';
ADDRESS  HASH_VALUE SQL_TEXT
-------- ---------- ------------------------------
1EFB91B8 3642190903 select count(*) from xff
SQL> revoke select on xff from chf;
撤销成功。
SQL> col sql_text for a30
SQL> SELECT ADDRESS,HASH_VALUE,SQL_TEXT FROM V$SQLAREA
  2  WHERE SQL_TEXT LIKE 'select % xff';
ADDRESS  HASH_VALUE SQL_TEXT
-------- ---------- ------------------------------
1EFB91B8 3642190903 select count(*) from xff

证明grant和revoke操作没有清除shared pool中关于该表的sql语句

4.打破神话二:ddl操作
对表进行ddl操作,可以清除该表在shared pool中关于该表记录

SQL> alter table xff add  owner1 varchar2(100);
表已更改。
SQL> SELECT ADDRESS,HASH_VALUE,SQL_TEXT FROM V$SQLAREA
  2  WHERE SQL_TEXT LIKE 'select % xff';
ADDRESS  HASH_VALUE SQL_TEXT
-------- ---------- ------------------------------
1EFB91B8 3642190903 select count(*) from xff

事实证明ddl操作不能达到预期效果,没有清除掉这条sql语句

5.刷新shared pool

SQL> alter system flush shared_pool
  2  ;
系统已更改。
SQL> SELECT ADDRESS,HASH_VALUE,SQL_TEXT FROM V$SQLAREA
  2  WHERE SQL_TEXT LIKE 'select % xff';
未选定行

把整个shared pool都刷新了,自然其中的一条sql语句也没有了,在10g前只能通过这种方法实现

6.使用dbms_shared_pool.purge

SQL> select count(*) from xff;
  COUNT(*)
----------
         9
SQL> SELECT ADDRESS,HASH_VALUE,SQL_TEXT FROM V$SQLAREA
  2  WHERE SQL_TEXT LIKE 'select % xff';
ADDRESS  HASH_VALUE SQL_TEXT
-------- ---------- ------------------------------
1EFB91B8 3642190903 select count(*) from xff
SQL> exec dbms_shared_pool.purge('1EFB91B8, 3642190903','C');
PL/SQL 过程已成功完成。
SQL> SELECT ADDRESS,HASH_VALUE,SQL_TEXT FROM V$SQLAREA
  2  WHERE SQL_TEXT LIKE 'select % xff';
未选定行

试验证明在shared pool中清除了一条sql记录

7.关于dbms_shared_pool.purge参数说明

purge(name varchar2, flag char DEFAULT 'P', heaps number DEFAULT 1);
--    name
--      The name of the object to keep.  There are two kinds of objects:
--      PL/SQL objects, triggers, sequences, types and Java objects,
--      which are specified by name, and
--      SQL cursor objects which are specified by a two-part number
--      (indicating a location in the shared pool).  For example:
--        dbms_shared_pool.keep('scott.hispackage')
--      will keep package HISPACKAGE, owned by SCOTT.  The names for
--      PL/SQL objects follows SQL rules for naming objects (i.e.,
--      delimited identifiers, multi-byte names, etc. are allowed).
--      A cursor can be keeped by
--        dbms_shared_pool.keep('0034CDFF, 20348871', 'C')
--      The complete hexadecimal address must be in the first 8 characters.
--      The value for this identifier is the concatenation of the
--      'address' and 'hash_value' columns from the v$sqlarea view.  This
--      is displayed by the 'sizes' call above.
--      Currently 'TABLE' and 'VIEW' objects may not be keeped.
--
--    flag
--      This is an optional parameter.  If the parameter is not specified,
--        the package assumes that the first parameter is the name of a
--        package/procedure/function and will resolve the name.  Otherwise,
--        the parameter is a character string indicating what kind of object
--        to keep the name identifies.  The string is case insensitive.
--        The possible values and the kinds of objects they indicate are
--        given in the following table:
--          Value        Kind of Object to keep
--          -----      ----------------------
--	      P          package/procedure/function
--	      Q          sequence
--	      R          trigger
--	      T          type
--            JS         java source
--            JC         java class
--	      JR         java resource
--	      JD         java shared data
--	      C          cursor
--      If and only if the first argument is a cursor address and hash-value,
--        the flag parameter should be set to 'C' (or 'c').
--
--    heaps
--      heaps to purge. e.g if heap 0 and heap 6 are to be purged.
--      1<<0 | 1<<6 => hex 0x41 => decimal 65. so specify heaps=>65.
--      Default is 1 i.e heap 0 which means the whole object will be purged.

StatSpack报告中redo size为负数

联系:手机/微信(+86 17813235971) QQ(107644445)

标题:StatSpack报告中redo size为负数

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

在一份statspack报告中发现redo size 为负数

DB Name         DB Id    Instance     Inst Num Release     Cluster Host
------------ ----------- ------------ -------- ----------- ------- ------------
CRM           3413823439 crm2                2 9.2.0.8.0   YES     zwq_crm2
              Snap Id     Snap Time      Sessions Curs/Sess Comment
            --------- ------------------ -------- --------- -------------------
Begin Snap:     47654 05-Feb-12 11:00:04    2,301      20.0
  End Snap:     47655 05-Feb-12 12:00:02    2,298      20.3
   Elapsed:               59.97 (mins)
Cache Sizes (end)
~~~~~~~~~~~~~~~~~
               Buffer Cache:    36,448M      Std Block Size:          8K
           Shared Pool Size:    10,240M          Log Buffer:     20,480K
Load Profile
~~~~~~~~~~~~                            Per Second       Per Transaction
                                   ---------------       ---------------
  负数=====>      Redo size:           -359,121.01             -7,828.69
              Logical reads:            349,787.58              7,625.22
              Block changes:              5,656.13                123.30
             Physical reads:             12,521.51                272.96
            Physical writes:                427.44                  9.32
                 User calls:             22,223.63                484.47
                     Parses:              4,673.27                101.88
                Hard parses:                 46.78                  1.02
                      Sorts:              4,027.70                 87.80
                     Logons:                 10.57                  0.23
                   Executes:             10,480.35                228.47
               Transactions:                 45.87

一时之间感觉很奇怪,在运行的数据库redo size不可能为负数(只要数据库在运行redo size都应该大于0).查询MOS[ID 308414.1]发现原来是一个bug引起(Bug:1713403 NEGATIVE VALUE IN V$SESSTAT FOR STATISTIC REDO SIZE),sp中的redo size其本质还是来源于V$SESSTAT.

Applies to:
Oracle Server - Enterprise Edition - Version: 8.1.7.4 to 9.2.0.8
This problem can occur on any platform.
Symptoms
Redo Size is displayed as a Negative number in a Statspack report.
For example:
Load Profile
~~~~~~~~~~~~ Per Second Per Transaction
             --------------- ---------------
Redo size:        -17,931.33      -55,277.73
Logical reads:     31,095.80       95,860.43
...
Cause
Bug:1713403 NEGATIVE VALUE IN V$SESSTAT FOR STATISTIC REDO SIZE
Overflow of 'redo size' statistic. This is fixed in Oracle10g and above.
Patches do not exist for earlier releases.
Solution
Use 'redo blocks written' instead to measure the amount of redo.
Ignore negative 'redo size'.

Easy Connect Naming Method与EZCONNECT关系

联系:手机/微信(+86 17813235971) QQ(107644445)

标题:Easy Connect Naming Method与EZCONNECT关系

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

Easy Connect Naming Method这个东西是Oracle 10g推出的东东,我想不用我解释它的好,dba和开发人员都喜欢它,以前一直都用它,从没有关注到它和sqlnet.ora中的NAMES.DIRECTORY_PATH的关系,昨天一朋友和我说到了EZCONNECT,今天查询了一些资料和做了一些实验,使得自己对NAMES.DIRECTORY_PATH和EZCONNECT有了新的认识,也怪自己一致忽略了这个知识点。

1.NAMES.DIRECTORY_PATH= (TNSNAMES)

[oracle@node1 samples]$ more $ORACLE_HOME/network/admin/sqlnet.ora
#NAMES.DIRECTORY_PATH= (EZCONNECT)
NAMES.DIRECTORY_PATH= (TNSNAMES)
[oracle@node1 samples]$ sqlplus hr/xifenfei@127.0.0.1/ecp
SQL*Plus: Release 10.2.0.5.0 - Production on Wed Feb 8 23:12:12 2012
Copyright (c) 1982, 2010, Oracle.  All Rights Reserved.
ERROR:
ORA-12154: TNS:could not resolve the connect identifier specified
Enter user-name:
ERROR:
ORA-01017: invalid username/password; logon denied
Enter user-name:
ERROR:
ORA-01017: invalid username/password; logon denied
SP2-0157: unable to CONNECT to ORACLE after 3 attempts, exiting SQL*Plus

证明sqlnet.ora中的NAMES.DIRECTORY_PATH设置为TNSNAMES时,Easy Connect Naming Method不能工作。

2.NAMES.DIRECTORY_PATH= (EZCONNECT)

[oracle@node1 samples]$ more $ORACLE_HOME/network/admin/sqlnet.ora
NAMES.DIRECTORY_PATH= (EZCONNECT)
#NAMES.DIRECTORY_PATH= (TNSNAMES)
[oracle@node1 samples]$ sqlplus hr/xifenfei@127.0.0.1/ecp
SQL*Plus: Release 10.2.0.5.0 - Production on Wed Feb 8 23:13:21 2012
Copyright (c) 1982, 2010, Oracle.  All Rights Reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL>

登录成功,其实这里生效是因为设置了NAMES.DIRECTORY_PATH为EZCONNECT的功效,从EZCONNECT的上面也可以看出是

3.NAMES.DIRECTORY_PATH为默认值

[oracle@node1 samples]$ more $ORACLE_HOME/network/admin/sqlnet.ora
#NAMES.DIRECTORY_PATH= (EZCONNECT)
#NAMES.DIRECTORY_PATH= (TNSNAMES)
[oracle@node1 samples]$ sqlplus hr/xifenfei@127.0.0.1/ecp
SQL*Plus: Release 10.2.0.5.0 - Production on Wed Feb 8 23:13:49 2012
Copyright (c) 1982, 2010, Oracle.  All Rights Reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL>

当NAMES.DIRECTORY_PATH为默认值时,使用Easy Connect Naming Method也可以登录成功(正是因为这个原因,导致我忽略了EZCONNECT的存在).

4.sqlnet.ora中关于NAMES.DIRECTORY_PATH说明

#names.directory_path
#
#Syntax:  <adapter-name>
#Default: TNSNAMES,ONAMES,HOSTNAME
#
# Sets the (ordered) list of naming adaptors to use in resolving a name.
# The default is as shown for 3.0.2 of sqlnet onwards. The default was
# (TNSNAMES, ONAMES) before that. The value can be presented without
# parentheses if only a single entry is being specified. The parameter is
# recognized from version 2.3.2 of sqlnet onward. Acceptable values include:
#  TNSNAMES -- tnsnames.ora lookup
#  ONAMES   -- Oracle Names
#  HOSTNAME -- use the hostname (or an alias of the hostname)
#  NIS      -- NIS (also known as "yp")
#  CDS      -- OSF DCE's Cell Directory Service
#  NDS      -- Novell's Netware Directory Service

5.关于NAMES.DIRECTORY_PATH参数的补充说明

tnsnames:local naming naming method
Set to resolve a net service name through the tnsnames.ora file on the client.
hostname:host naming method
Set to resolve a host name alias through an existing names resolution service or a centrally-maintained set of /etc/hosts files.
onames:Oracle Names method
Set to resolve database objects through a Oracle Names server.
ldap:directory naming naming method
Set to resolve a database service name, net service name, or net service alias through a directory server.
cds:Cell Directory Services (CDS) external naming method
Set to resolve an Oracle database name in a Distributed Computing Environment (DCE) environment.
nis:Network Information Service (NIS) external naming method
Set to resolve service information through an existing NIS.
Ezconnect:The easy connect naming method eliminates the need for service name lookup in the tnsnames.ora files for TCP/IP environments; in fact, no naming or directory system is required if you use this method.

PL/SQL Developer编译过程引起ora-600[15419]

联系:手机/微信(+86 17813235971) QQ(107644445)

标题:PL/SQL Developer编译过程引起ora-600[15419]

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

数据库版本

SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.8.0 - 64bit Production
PL/SQL Release 9.2.0.8.0 - Production
CORE    9.2.0.8.0       Production
TNS for IBM/AIX RISC System/6000: Version 9.2.0.8.0 - Production
NLSRTL Version 9.2.0.8.0 - Production

alert中发现错误

Sun Feb  5 16:32:33 2012
Errors in file /oracle9/app/admin/crm/udump/crm2_ora_2434040.trc:
ORA-00600: internal error code, arguments: [15419], [severe error during PL/SQL execution], [], [], [], [], [], []
ORA-06544: PL/SQL: internal error, arguments: [2603], [], [], [], [], [], [], []
ORA-06553: PLS-707: unsupported construct or internal error [2603]
Sun Feb  5 16:32:33 2012
Trace dumping is performing id=[cdmp_20120205163233]
Sun Feb  5 16:32:45 2012
Errors in file /oracle9/app/admin/crm/udump/crm2_ora_2732864.trc:
ORA-00600: internal error code, arguments: [15419], [severe error during PL/SQL execution], [], [], [], [], [], []
ORA-06544: PL/SQL: internal error, arguments: [2603], [], [], [], [], [], [], []
ORA-06553: PLS-707: unsupported construct or internal error [2603]

trace文件内容

----- Call Stack Trace -----
calling              call     entry                argument values in hex
location             type     point                (? means dubious value)
-------------------- -------- -------------------- ----------------------------
ksedmp+0148          bl       ksedst               1029746FC ?
ksfdmp+0018          bl       01FD4014
kgeriv+0118          bl       _ptrgl
kgesiv+0080          bl       kgeriv               FFFFFFFFFFF3AF0 ?
                                                   700000D072A1238 ?
                                                   FFFFFFFFFFF3A80 ?
                                                   3592393502A3F478 ?
                                                   100112038 ?
ksesic1+005c         bl       kgesiv               000000000 ? 700000000003BC8 ?
                                                   2FFFFFEFFFF40C8 ?
                                                   7000002E147A6E0 ? 110002A20 ?
kkxexe+0308          bl       ksesic1              3C3B00003C3B ? 000000001 ?
                                                   000000024 ? 102A1143C ?
                                                   000000009 ? 110362830 ?
                                                   000000002 ? 000007FFF ?
opiexe+274c          bl       kkxexe               1103B5B50 ?
opiodr+08cc          bl       _ptrgl
rpidrus+008c         bl       opiodr               4103A2A20 ? 300000000 ?
                                                   FFFFFFFFFFF6A70 ? 50000F618 ?
skgmstack+00d0       bl       _ptrgl
rpidru+0090          bl       skgmstack            0FFFF5F30 ? 1101FAF78 ?
                                                   110006448 ? FFFFFFFFFFF6AD8 ?
                                                   700000C7CF68900 ?
rpiswu2+0358         bl       _ptrgl
rpidrv+07fc          bl       rpiswu2              700000C386E8718 ? 500000000 ?
                                                   1103B7908 ? FFFFFFFFFFF6E40 ?
                                                   000000000 ? 2E00000000 ?
                                                   1101E9CA8 ? 000000000 ?
rpiexe+0034          bl       rpidrv               5FFFF6A68 ? 400000A20 ?
                                                   FFFFFFFFFFF6A70 ? 00000002E ?
psdevnCallback+00d4  bl       rpiexe               FFFFFFFFFFF71D0 ?
rpiswu2+0358         bl       _ptrgl
psdevn+0068          bl       rpiswu2              700000C386E8718 ?
                                                   10803D00008 ? 000000000 ?
                                                   102A1BA98 ? 1103B7210 ?
                                                   2E00000008 ? 108000003D0 ?
                                                   000000000 ?
pbedeevn+0350        bl       _ptrgl
pbeevnd+0198         bcl      pevm_CHSNULL+01c0    FFFFFFFFFFF7370 ? 000000000 ?
                                                   100AE4A10 ? 000000000 ?
                                                   11035F738 ? 11035FB76 ?
pfrrun+0ce4          bl       pbeevnd              1103B7210 ? 1103B7278 ?
                                                   700000CE62919A6 ?
peicnt+01b8          bl       pfrrun               1103B7210 ?
kkxexe+01f8          bl       peicnt               FFFFFFFFFFF8F80 ? 1103B7210 ?
opiexe+274c          bl       kkxexe               1103B7908 ?
opiall0+102c         bl       opiexe               4FFFFFFB0 ? FFFFFFFFFFFBBB0 ?
                                                   FFFFFFFFFFFA0A0 ?
kpoal8+0a78          bl       opiall0              5EFFFFBED4 ? 22FFFFBC18 ?
                                                   FFFFFFFFFFFA5B8 ? 000000000 ?
                                                   FFFFFFFFFFFA508 ? 1102A6498 ?
                                                   5B00000070 ? 24000000007FFF ?
opiodr+08cc          bl       _ptrgl
ttcpip+0cc4          bl       _ptrgl
opitsk+0d60          bl       ttcpip               11000CF90 ? 000000000 ?
                                                   000000000 ? 000000000 ?
                                                   000000000 ? 000000000 ?
                                                   000000000 ? 000000000 ?
opiino+0758          bl       opitsk               000000000 ? 000000000 ?
opiodr+08cc          bl       _ptrgl
opidrv+032c          bl       opiodr               3C00000018 ? 4101FAF78 ?
                                                   FFFFFFFFFFFF7B0 ? 0A000F350 ?
sou2o+0028           bl       opidrv               3C0C000000 ? 4A00E8B50 ?
                                                   FFFFFFFFFFFF7B0 ?
main+0138            bl       01FD3A28
__start+0098         bl       main                 000000000 ? 000000000 ?
--------------------- Binary Stack Dump ---------------------
………………
SO: 700000c386e8718, type: 4, owner: 700000c3c7779a0, flag: INIT/-/-/0x00
    (session) trans: 0, creator: 700000c3c7779a0, flag: (41) USR/- BSY/-/-/-/-/-
              DID: 0002-02FA-00A04E87, short-term DID: 0000-0000-00000000
              txn branch: 0
              oct: 47, prv: 0, sql: 700000d85e7a0d8, psql: 7000002615ef140, user: 46/DBMARK
    O/S info: user: yuyangah, term: LENOVO-C18854BA, ospid: 5624:5632, machine: WORKGROUP\LENOVO-C18854BA
              program: plsqldev.exe
    application name: PL/SQL Developer, hash value=1190136663
    action name: 测试窗口 - procedure PRC_MARK_UP, hash value=3097949562
    last wait for 'pipe get' blocking sess=0x0 seq=42 wait_time=122
                handle address=700000cd07bddb8, buffer length=1000, timeout=e10
temporary object counter: 0

通过这里可以看出,WORKGROUP\LENOVO-C18854BA机上的yuyangah用户在使用PL/SQL Developer操作PRC_MARK_UP过程的时候,产生了该错误。查询mos[ID 436359.1]发现有相关记录
解决方法:
1.在编译包/过程/函数时,不要选中在pl/sql dev中的Tools > Preferences > Debugger >Add debug information when compiling

2.检查的版本pl/sql dev是否和数据库兼容,建议使用新版本

使用dblink导致scn发现改变

联系:手机/微信(+86 17813235971) QQ(107644445)

标题:使用dblink导致scn发现改变

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

1.dblink目标端

[oracle@node1 ~]$ sqlplus / as sysdba
SQL*Plus: Release 11.2.0.3.0 Production on Sat Jan 21 15:25:59 2012
Copyright (c) 1982, 2011, Oracle.  All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP, Data Mining,
Oracle Database Vault and Real Application Testing options
SQL> select dbms_flashback.GET_SYSTEM_CHANGE_NUMBER scn from dual;
       SCN
----------
  17454270
SQL> select file#,CHECKPOINT_CHANGE# scn from v$datafile;
     FILE#        SCN
---------- ----------
         1   17454265
         2   17454265
         3   17454265
         4   17454265
         5   17454265
         6   17454265
         7   17454265
         8   17454265
         9   17454265
        10   17454265
        11   17454265
     FILE#        SCN
---------- ----------
        13   17454265
        14   17454265
13 rows selected.

通过这里可以知道,该数据库目前的scn是小于18000000。

2.dblink操作

[oracle@node1 admin]$ sqlplus / as sysdba
SQL*Plus: Release 10.2.0.5.0 - Production on Sat Jan 21 15:49:39 2012
Copyright (c) 1982, 2010, Oracle.  All Rights Reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> select dbms_flashback.GET_SYSTEM_CHANGE_NUMBER scn from dual;
       SCN
----------
  20359364
SQL> select dbms_flashback.GET_SYSTEM_CHANGE_NUMBER scn from dual@chf;
       SCN
----------
  20359367

通过这步操作发现目标端的scn发生改变,和原端库scn一致(因为先后关系,有小出入)

3.再次查看dblink目标端

SQL>  alter system checkpoint;
System altered.
SQL> select file#,CHECKPOINT_CHANGE# scn from v$datafile;
     FILE#        SCN
---------- ----------
         1   20359409
         2   20359409
         3   20359409
         4   20359409
         5   20359409
         6   20359409
         7   20359409
         8   20359409
         9   20359409
        10   20359409
        11   20359409
     FILE#        SCN
---------- ----------
        13   20359409
        14   20359409
13 rows selected.

通过checkpoint之后,发现目标库的scn已经发现改变(向前推荐),从而证明使用dblink,确实使得scn小的库和scn大的库一致。

跳过obj$坏块方法

联系:手机/微信(+86 17813235971) QQ(107644445)

标题:跳过obj$坏块方法

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

1.确定obj$坏块存在

SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
CORE    11.2.0.3.0      Production
TNS for Linux: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production
SQL> select /*+full(obj$)*/ count(*) from obj$;
select /*+full(obj$)*/ count(*) from obj$
                                     *
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 1, block # 95369)
ORA-01110: data file 1: '/opt/oracle/oradata/chf/system01.dbf'

2.使用dbms_repair跳过坏块

SQL> exec dbms_repair.skip_corrupt_blocks('SYS','OBJ$');
BEGIN dbms_repair.skip_corrupt_blocks('SYS','OBJ$'); END;
*
ERROR at line 1:
ORA-00701: object necessary for warmstarting database cannot be altered
ORA-06512: at "SYS.DBMS_REPAIR", line 419
ORA-06512: at line 1
--ORA-00701原因
SQL> set pages 100
SQL> SELECT * FROM BOOTSTRAP$ WHERE SQL_TEXT LIKE '%OBJ$%';
     LINE#       OBJ#
---------- ----------
SQL_TEXT
--------------------------------------------------------------------------------
        18      90724
CREATE TABLE OBJ$("OBJ#" NUMBER NOT NULL,"DATAOBJ#" NUMBER,"OWNER#" NUMBER NOT N
ULL,"NAME" VARCHAR2(30) NOT NULL,"NAMESPACE" NUMBER NOT NULL,"SUBNAME" VARCHAR2(
30),"TYPE#" NUMBER NOT NULL,"CTIME" DATE NOT NULL,"MTIME" DATE NOT NULL,"STIME"
DATE NOT NULL,"STATUS" NUMBER NOT NULL,"REMOTEOWNER" VARCHAR2(30),"LINKNAME" VAR
CHAR2(128),"FLAGS" NUMBER,"OID$" RAW(16),"SPARE1" NUMBER,"SPARE2" NUMBER,"SPARE3
" NUMBER,"SPARE4" VARCHAR2(1000),"SPARE5" VARCHAR2(1000),"SPARE6" DATE) PCTFREE
10 PCTUSED 40 INITRANS 1 MAXTRANS 255 STORAGE (  INITIAL 16384 NEXT 106496 MINEX
TENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 90724 EXTENTS (FILE 1 BLOCK 94
505))
--obj$是BOOTSTRAP$中对象,不能被修改
--这里打破一个传奇:一般人都说BOOTSTRAP$中对象都是object_id是非常小靠前。
--但是我这个从10g升级过来的库,obj$的object_id为90724

3.使用event跳过坏块

pfile中添加
event="10231 trace name context forever, level 10"
SQL> startup pfile='/tmp/pfile_new' force
ORACLE instance started.
Total System Global Area  622149632 bytes
Fixed Size                  2230912 bytes
Variable Size             398460288 bytes
Database Buffers          213909504 bytes
Redo Buffers                7548928 bytes
Database mounted.
Database opened.
SQL> select /*+full(obj$)*/ count(*) from obj$;
  COUNT(*)
----------
     74503

诡异dblink问题解决–dblink insert操作数据类型发生改变

联系:手机/微信(+86 17813235971) QQ(107644445)

标题:诡异dblink问题解决–dblink insert操作数据类型发生改变

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

1.展示列属性

[oracle@saas-xunzhi-db1 ~]$ sqlplus testga/testga
SQL*Plus: Release 10.2.0.1.0 - Production on Thu Jan 12 16:26:56 2012
Copyright (c) 1982, 2005, Oracle.  All rights reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bit Production
With the Partitioning, OLAP and Data Mining options
SQL> desc t_xifenfei;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 PROCESS_INSTANCE_ID                       NOT NULL NUMBER(10)
 STATUS_NEW                                         NUMBER
 PACKAGE_NAME                                       VARCHAR2(50)
SQL> desc wf_proc_inst@oldmoa
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                        NOT NULL NUMBER(10)
 NAME                                               VARCHAR2(500)
 PROC_ID                                   NOT NULL NUMBER(10)
 PARE_INST_ID                              NOT NULL NUMBER(10)
 PARE_ACTI_ID                              NOT NULL NUMBER(10)
 INST_CREATOR                                       VARCHAR2(40)
 CREAT_DATE                                         DATE
 STATUS                                             CHAR(1)
 ATT1                                               NUMBER(10)
 ATT2                                               VARCHAR2(255)
 SEQVALUE                                           VARCHAR2(50)

从这里可以看出,原表的status列是char,而目标表的STATUS_NEW列是number类型

2.通过dblink查询列值

SQL> select t.inst_id as ID,
  2         case w.status
  3           when '0' then
  4            4
  5           when '2' then
  6            3
  7           else
  8            1
  9         end as  status_new,
 10         p.name as PACKAGE_NAME
 11    from wf_proc_inst@oldmoa i
 12    left join wf_proc_info_inst@oldmoa t on t.inst_id = i.id
 13    left join wf_proc_type@oldmoa p on t.type_id = p.id
 14    left join wf_proc_inst@oldmoa w on t.inst_id = w.id
 15   where t.inst_id = i.id
 16     and t.proc_id <> 53
 17     and t.is_ok = 1
 18     AND t.inst_id <= 4837
 19     AND t.inst_id>=4735;
        ID STATUS_NEW PACKAGE_NAME
---------- ---------- --------------------------
      4755          3 呈批处理
      4836          3 公文处理

从这里可以看出来,case工作正常,传入的char类型,通过case转换为number类型

3.使用dblink插入数据并查询

SQL> INSERT INTO t_xifenfei
  2  select t.inst_id as ID,
  3         case w.status
  4           when '0' then
  5            4
  6           when '2' then
  7            3
  8           else
  9            1
 10         end as  status_new,
 11         p.name as PACKAGE_NAME
 12    from wf_proc_inst@oldmoa i
 13    left join wf_proc_info_inst@oldmoa t on t.inst_id = i.id
 14    left join wf_proc_type@oldmoa p on t.type_id = p.id
 15    left join wf_proc_inst@oldmoa w on t.inst_id = w.id
 16   where t.inst_id = i.id
 17     and t.proc_id <> 53
 18     and t.is_ok = 1
 19     AND t.inst_id <= 4837
 20     AND t.inst_id>=4735;
2 rows created.
SQL> commit;
Commit complete.
SQL> col package_name for a10
SQL> select * from t_xifenfei;
PROCESS_INSTANCE_ID STATUS_NEW PACKAGE_NA
------------------- ---------- ----------
               4755          1 呈批处理
               4836          1 公文处理

这里出现异常,怀疑case中传入的值,都走到else那边了,怀疑是在使用dblink 的时候,char的类型发生的改变,转为了number,导致case匹配失败,所以走到else。

4.在dblink端创建视图,插入数据

SQL> CREATE VIEW GZZJ.v_xifenfei
  2  AS
  3  select t.inst_id as ID,
  4         case to_char(w.status)
  5           when '0' then
  6            4
  7           when '2' then
  8            3
  9           else
 10            1
 11         end as  status_new,
 12         p.name as PACKAGE_NAME
 13    from GZZJ.wf_proc_inst i
 14    left join GZZJ.wf_proc_info_inst t on t.inst_id = i.id
 15    left join GZZJ.wf_proc_type p on t.type_id = p.id
 16    left join GZZJ.wf_proc_inst w on t.inst_id = w.id
 17   where t.inst_id = i.id
 18     and t.proc_id <> 53
 19     and t.is_ok = 1
 20     AND t.inst_id <= 4837
 21     AND t.inst_id>=4735;
View created.
SQL> insert into t_xifenfei
  2  select * from v_xifenfei@oldmoa;
2 rows created.
SQL> commit;
Commit complete.
SQL> select * from t_xifenfei;
PROCESS_INSTANCE_ID STATUS_NEW PACKAGE_NA
------------------- ---------- ----------
               4755          3 呈批处理
               4836          3 公文处理

通过远程视图,接触数据类型发生改变异常(怀疑是dblink 在insert时候,char数据类型变成了number,但是未得到官方或者权威的确认)

CAST本质探讨

联系:手机/微信(+86 17813235971) QQ(107644445)

标题:CAST本质探讨

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

1.试验前提

SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
CORE    11.2.0.3.0      Production
TNS for Linux: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production
SQL> select FORCE_LOGGING,SUPPLEMENTAL_LOG_DATA_PK,SUPPLEMENTAL_LOG_DATA_UI,
   2 SUPPLEMENTAL_LOG_DATA_MIN from v$database;
FOR SUP SUP SUPPLEME
--- --- --- --------
NO  NO  NO  NO
SQL> conn / as sysdba
Connected.
SQL> archive log list;
Database log mode              Archive Mode
Automatic archival             Enabled
Archive destination            /opt/oracle/oradata/archivelog/chf
Oldest online log sequence     1879
Next log sequence to archive   1881
Current log sequence           1881
SQL> select count(*) from t_xifenfei_move;
  COUNT(*)
----------
   7432085
SQL> select bytes/1024/1024 from user_segments where segment_name='T_XIFENFEI_MOVE';
BYTES/1024/1024
---------------
            832

从上面信息可以看到数据库处于归档模式,强制日志和辅助日志为开启,试验测试表t_xifenfei_move有7432085条记录,占用硬盘空间832M

2.常规CAST

SQL>  alter system flush buffer_cache;
System altered.
SQL> alter system flush shared_pool;
System altered.
SQL> SET TIMING ON
SQL> select a.name, b.value
  2  from v$statname a, v$mystat b
  3  where a.statistic# = b.statistic#
  4  and lower(a.name) in
  5  ('redo size','undo change vector size');
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                            100028
undo change vector size                                               16172
Elapsed: 00:00:00.06
SQL> create table chf.t_xifenfei_move_CAST tablespace users
  2  as
  3  select * from chf.t_xifenfei_move;
Table created.
Elapsed: 00:01:58.10
SQL> select a.name, b.value
  2  from v$statname a, v$mystat b
  3  where a.statistic# = b.statistic#
  4  and lower(a.name) in
  5  ('redo size','undo change vector size');
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                         873150548
undo change vector size                                              131384
Elapsed: 00:00:00.01
SQL> select 873150548-100028 "redo size" from dual;
 redo size
----------
 873050520
SQL> select 131384-16172 "undo size" from dual;
 undo size
----------
    115212

通过这个可以得出结论,产生redo为873050520,undo为115212

3.普通INSERT

SQL>  alter system flush buffer_cache;
System altered.
Elapsed: 00:00:00.06
SQL> alter system flush shared_pool;
System altered.
Elapsed: 00:00:00.01
SQL> select a.name, b.value
  2  from v$statname a, v$mystat b
  3  where a.statistic# = b.statistic#
  4  and lower(a.name) in
  5  ('redo size','undo change vector size');
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                               732
undo change vector size                                                 136
Elapsed: 00:00:00.18
SQL> CREATE TABLE t_xifenfei_move_INSERT
  2  AS
  3  SELECT * FROM T_XIFENFEI_MOVE WHERE 1=0;
Table created.
Elapsed: 00:00:00.32
SQL> select a.name, b.value
  2  from v$statname a, v$mystat b
  3  where a.statistic# = b.statistic#
  4  and lower(a.name) in
  5  ('redo size','undo change vector size');
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                             22712
undo change vector size                                                6512
Elapsed: 00:00:00.02
SQL> INSERT INTO t_xifenfei_move_INSERT
  2  SELECT * FROM T_XIFENFEI_MOVE;
7432085 rows created.
Elapsed: 00:01:59.47
SQL> select a.name, b.value
  2  from v$statname a, v$mystat b
  3  where a.statistic# = b.statistic#
  4  and lower(a.name) in
  5  ('redo size','undo change vector size');
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                         862261580
undo change vector size                                            27980508
--redo
SQL> select 22712-732 "create redo size" from dual;
create redo size
----------------
           21980
SQL> select 862261580-22712 "insert redo size" from dual;
insert redo size
----------------
       862238868
--undo
SQL> select 6512-136 "create undo size" from dual;
create undo size
----------------
            6376
SQL> select 27980508-6512 "insert undo size" from dual;
insert undo size
----------------
        27973996

通过这个可以得出CREATE TABLE 过程中产生redo:21980,undo:6376,而INSERT 过程中产生的redo:862238868,undo:27973996,整个过程总的产生redo:862260848(862238868+21980),undo:27980372(27973996+6376)

4.INSERT+APPEND

SQL>  alter system flush buffer_cache;
System altered.
Elapsed: 00:00:25.19
SQL> alter system flush shared_pool;
System altered.
Elapsed: 00:00:00.04
SQL> select a.name, b.value
  2  from v$statname a, v$mystat b
  3  where a.statistic# = b.statistic#
  4  and lower(a.name) in
  5  ('redo size','undo change vector size');
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                               732
undo change vector size                                                 136
Elapsed: 00:00:00.05
SQL> create table chf.t_xifenfei_move_INSERT_A tablespace users
  2  as
  3  select * from chf.t_xifenfei_move where 1=0;
Table created.
Elapsed: 00:00:00.18
SQL> select a.name, b.value
  2  from v$statname a, v$mystat b
  3  where a.statistic# = b.statistic#
  4  and lower(a.name) in
  5  ('redo size','undo change vector size');
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                             21892
undo change vector size                                                6308
Elapsed: 00:00:00.00
SQL> INSERT /*+ append */INTO t_xifenfei_move_INSERT_A
  2  SELECT * FROM T_XIFENFEI_MOVE;
7432085 rows created.
Elapsed: 00:02:26.37
SQL> select a.name, b.value
  2  from v$statname a, v$mystat b
  3  where a.statistic# = b.statistic#
  4  and lower(a.name) in
  5  ('redo size','undo change vector size');
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                         872792032
undo change vector size                                               87764
--redo
SQL> select 21892-732 "create redo size" from dual;
create redo size
----------------
           21160
SQL> select 872792032-21892 "insert redo size" from dual;
insert redo size
----------------
       872770140
--undo
SQL> select 6308-136 "create undo size" from dual;
create undo size
----------------
            6172
SQL> select 87764-6308 "insert undo size" from dual;
insert undo size
----------------
           81456

这个过程可以得到结论,create 表的过程产生的redo:21160,undo:6172;insert 表的过程redo:872770140,undo:81456;整个过程产生的redo:872791300(21160+872770140),undo:87628(6172+81456)

5.INSERT+NOLOGGING

SQL>  alter system flush buffer_cache;
System altered.
Elapsed: 00:00:02.21
SQL> alter system flush shared_pool;
System altered.
Elapsed: 00:00:00.06
SQL> select a.name, b.value
  2  from v$statname a, v$mystat b
  3  where a.statistic# = b.statistic#
  4  and lower(a.name) in
  5  ('redo size','undo change vector size');
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                               780
undo change vector size                                                 136
Elapsed: 00:00:00.06
SQL> create table chf.t_xifenfei_move_INSERT_N tablespace users
  2  as
  3  select * from chf.t_xifenfei_move where 1=0;
Table created.
Elapsed: 00:00:00.22
SQL> select a.name, b.value
  2  from v$statname a, v$mystat b
  3  where a.statistic# = b.statistic#
  4  and lower(a.name) in
  5  ('redo size','undo change vector size');
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                             22056
undo change vector size                                                6308
Elapsed: 00:00:00.00
SQL> INSERT /*+ NOLOGGING */INTO t_xifenfei_move_INSERT_N
  2  SELECT * FROM T_XIFENFEI_MOVE;
7432085 rows created.
Elapsed: 00:02:30.33
SQL> select a.name, b.value
  2  from v$statname a, v$mystat b
  3  where a.statistic# = b.statistic#
  4  and lower(a.name) in
  5  ('redo size','undo change vector size');
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                         862123984
undo change vector size                                            27982876
--redo
SQL> select 22056-780 "create redo size" from dual;
create redo size
----------------
           21276
SQL> select 862123984-22056 "insert redo size" from dual;
insert redo size
----------------
       862101928
--undo
SQL> select 6308-136 "create undo size" from dual;
create undo size
----------------
            6172
SQL> select 27982876-6308 "insert undo size" from dual;
insert undo size
----------------
        27976568

这个试验过程得出,create table得到redo:21276,undo:6172,insert table 得到redo:862101928,undo:27976568,整个过程redo:862123204,undo:27982740(27976568+6172)

6.INSERT+NOLOGGING(TABLE)

SQL>  alter system flush buffer_cache;
System altered.
Elapsed: 00:00:23.68
SQL> alter system flush shared_pool;
System altered.
Elapsed: 00:00:00.04
SQL> select a.name, b.value
  2  from v$statname a, v$mystat b
  3  where a.statistic# = b.statistic#
  4  and lower(a.name) in
  5  ('redo size','undo change vector size');
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                               800
undo change vector size                                                 136
Elapsed: 00:00:00.18
SQL> create table chf.t_xifenfei_move_INSERT_N_new nologging tablespace users
  2  as
  3  select * from chf.t_xifenfei_move where 1=0;
Table created.
Elapsed: 00:00:00.71
SQL> select a.name, b.value
  2  from v$statname a, v$mystat b
  3  where a.statistic# = b.statistic#
  4  and lower(a.name) in
  5  ('redo size','undo change vector size');
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                             23296
undo change vector size                                                6756
Elapsed: 00:00:00.00
SQL> INSERT INTO t_xifenfei_move_INSERT_N_new
  2  SELECT * FROM T_XIFENFEI_MOVE;
7432085 rows created.
Elapsed: 00:02:37.51
SQL> select a.name, b.value
  2  from v$statname a, v$mystat b
  3  where a.statistic# = b.statistic#
  4  and lower(a.name) in
  5  ('redo size','undo change vector size');
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                         862031304
undo change vector size                                            27982776
SQL> select 23296-800 "create redo size" from dual;
create redo size
----------------
           22496
SQL> select 862031304-23296 "insert redo size" from dual;
insert redo size
----------------
       862008008
SQL> select 6756-136 "create undo size" from dual;
create undo size
----------------
            6620
SQL> select 27982776-6756 "insert undo size" from dual;
insert undo size
----------------
        27976020

通过该试验得出,create table 产生redo:22496,undo:6620;insert into 产生redo:862008008,undo:27976020;整个过程产生redo:862030504(22496+862008008),undo:27982640(6620+27976020)

7.APPEND+NOLOGGING(TABLE)

SQL> alter system flush buffer_cache;
System altered.
Elapsed: 00:00:23.59
SQL> alter system flush shared_pool;
System altered.
Elapsed: 00:00:00.05
SQL> select a.name, b.value
  2  from v$statname a, v$mystat b
  3  where a.statistic# = b.statistic#
  4  and lower(a.name) in
  5  ('redo size','undo change vector size');
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                               780
undo change vector size                                                 136
Elapsed: 00:00:00.04
SQL> create table chf.t_xifenfei_move_INSERT_NA nologging tablespace users
  2  as
  3  select * from chf.t_xifenfei_move where 1=0;
Table created.
Elapsed: 00:00:00.42
SQL> select a.name, b.value
  2  from v$statname a, v$mystat b
  3  where a.statistic# = b.statistic#
  4  and lower(a.name) in
  5  ('redo size','undo change vector size');
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                             22000
undo change vector size                                                6308
Elapsed: 00:00:00.00
SQL> INSERT /*+APPEND */ INTO t_xifenfei_move_INSERT_NA
  2  SELECT * FROM T_XIFENFEI_MOVE;
7432085 rows created.
Elapsed: 00:01:08.92
SQL> select a.name, b.value
  2  from v$statname a, v$mystat b
  3  where a.statistic# = b.statistic#
  4  and lower(a.name) in
  5  ('redo size','undo change vector size');
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                            602352
undo change vector size                                               82756
--redo
SQL> select 22000-780 "create redo size" from dual;
create redo size
----------------
           21220
SQL> select 602352-22000 "insert redo size" from dual;
insert redo size
----------------
          580352
--undo
SQL> select 6308-136 "create undo size" from dual;
create undo size
----------------
            6172
SQL> select 82756-6308 "insert undo size" from dual;
insert undo size
----------------
           76448

在这个试验中,create table产生redo:21220,undo:6172,insert into产生redo:580352,undo:76448;整个过程产生的redo:601572(
21220+580352),undo:82620(6172+76448)

8.CAST+NOLOGGING(TABLE)

SQL>  alter system flush buffer_cache;
System altered.
Elapsed: 00:00:03.35
SQL> alter system flush shared_pool;
System altered.
Elapsed: 00:00:00.04
SQL>
SQL> select a.name, b.value
  2  from v$statname a, v$mystat b
  3  where a.statistic# = b.statistic#
  4  and lower(a.name) in
  5  ('redo size','undo change vector size');
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                               732
undo change vector size                                                 136
Elapsed: 00:00:00.05
SQL> create table chf.t_xifenfei_move_cast_N nologging tablespace users
  2  as
  3  select * from chf.t_xifenfei_move;
Table created.
Elapsed: 00:00:56.41
SQL> select a.name, b.value
  2  from v$statname a, v$mystat b
  3  where a.statistic# = b.statistic#
  4  and lower(a.name) in
  5  ('redo size','undo change vector size');
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                            769848
undo change vector size                                              124944
SQL> select 769848-732 "redo size" from dual;
 redo size
----------
    769116
SQL> select 124944-136 "undo  size" from dual;
undo  size
----------
    124808

这个试验产生的redo:769116,undo:124808

9.通过试验得出结论
1)sql hint中的nologgging无效
2)普通的cast(不含hint),其本质是append,无nologgging
3)nologgging(表级别)可以使得cast效率较高
4)nologgging(表级别)+append(hint)可以使得insert效率较高

MOVE和CAST比较(续)

联系:手机/微信(+86 17813235971) QQ(107644445)

标题:MOVE和CAST比较(续)

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

本篇文章是MOVE和CAST比较的续篇,主要是对于第一篇中没有涉及到的redo和undo的情况加以叙述
1.查询move产生redo和undo量

SQL> alter system flush buffer_cache;
System altered.
SQL> alter system flush shared_pool;
System altered.
SQL> select a.name, b.value
  2  from v$statname a, v$mystat b
  3  where a.statistic# = b.statistic#
  4  and lower(a.name) in
  5  ('redo size','undo change vector size');
NAME                                          VALUE
---------------------------------------- ----------
redo size                                       844
undo change vector size                         136
SQL> ALTER TABLE CHF.T_XIFENFEI_MOVE MOVE TABLESPACE TEST_OCP;
Table altered.
SQL> select a.name, b.value
  2  from v$statname a, v$mystat b
  3  where a.statistic# = b.statistic#
  4  and lower(a.name) in
  5  ('redo size','undo change vector size');
NAME                                          VALUE
---------------------------------------- ----------
redo size                                 873074928
undo change vector size                      110748
--产生redo
SQL> select 873074928-844 "redo size" from dual;
 redo size
----------
 873074084
--产生undo
SQL> select 110748-136 "undo size" from dual;
 undo size
----------
    110612

2.查询cast产生redo和undo 大小

SQL> alter system flush buffer_cache;
System altered.
SQL> alter system flush shared_pool;
System altered.
SQL> select a.name, b.value
  2  from v$statname a, v$mystat b
  3  where a.statistic# = b.statistic#
and lower(a.name) in
  4    5  ('redo size','undo change vector size');
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                               776
undo change vector size                                                 136
SQL> create table chf.t_xifenfei_move_new tablespace users
  2  as
  3  select * from chf.t_xifenfei_move;
Table created.
SQL> select a.name, b.value
  2  from v$statname a, v$mystat b
  3  where a.statistic# = b.statistic#
  4  and lower(a.name) in
  5  ('redo size','undo change vector size');
NAME                                                                  VALUE
---------------------------------------------------------------- ----------
redo size                                                         873017580
undo change vector size                                              115340
--产生redo
SQL> select 873017580-776 "redo size" from dual;
 redo size
----------
 873016804
--产生undo
SQL> select 115340-136 "undo size" from dual;
 undo size
----------
    115204

3.两次实验比较

--redo(分母使用cast操作产生redo)
SQL> select 873074084-873016804 "redo" from dual;
      redo
----------
     57280
SQL> select 57280/873074084 from dual;
57280/873074084
---------------
     .000065607
--undo(分母使用cast操作产生undo)
SQL> select 110612-115204 undo from dual;
         undo
-------------
        -4592
SQL> select 4592/115204 from dual;
4592/115204
-----------
 .039859727

通过这两个的比较可以知道move操作产生的redo多了万分之七不到,undo少了百分之四,这些也是在实验允许的误差范围内,再说move操作还包括了cast的一些后续步骤在其中,所以通过这个验证和上一篇试验(MOVE和CAST比较),基本上可以大胆操作move操作的本质就是全表扫描+append插入数据,操作过程中产生的redo大小几乎和表本身大小(872415232)相等,这个证明,move和cast都是以logging模式运行(数据库本身是非force logging模式)

MOVE和CAST比较

联系:手机/微信(+86 17813235971) QQ(107644445)

标题:MOVE和CAST比较

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

1.创建模拟表

SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
CORE    11.2.0.3.0      Production
TNS for Linux: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production
SQL> create table chf.t_xifenfei_move
  2  as
  3  select * from dba_objects;
Table created.
SQL> select count(*) from chf.t_xifenfei_move;
  COUNT(*)
----------
     73585
SQL> create table chf.t_xifenfei_move
  2  as
  3  select * from dba_objects;
Table created.
SQL> select count(*) from chf.t_xifenfei_move;
  COUNT(*)
----------
     73585
SQL> DECLARE
  2     i NUMBER;
  3      BEGIN
  4        FOR i IN 1..100 LOOP
  5          INSERT INTO chf.t_xifenfei_move
  6          select * from dba_objects;
  7          END LOOP;
  8          COMMIT;
  9      END;
 10      /
PL/SQL procedure successfully completed.
SQL> exec dbms_stats.gather_table_stats('CHF','T_XIFENFEI_MOVE');
PL/SQL procedure successfully completed.
SQL> select bytes from dba_segments where segment_name='T_XIFENFEI_MOVE';
     BYTES
----------
 872415232

2.测试move
2.1)执行move操作,记录时间

SQL> alter system flush buffer_cache;
System altered.
SQL> SET TIMING ON;
SQL> alter session set events
  2  '10046 trace name context forever,level 1';
Session altered.
Elapsed: 00:00:00.00
SQL> ALTER TABLE CHF.T_XIFENFEI_MOVE MOVE TABLESPACE USERS;
Table altered.
Elapsed: 00:02:11.77
SQL> alter session set events
  2  '10046 trace name context off';
Session altered.
Elapsed: 00:00:00.04
SQL> select d.value||'/'||lower(rtrim(i.instance,chr(0)))||'_ora_'||p.spid||'.trc' trace_file_name from
  2  (select p.spid from v$mystat m, v$session s,v$process p where m.statistic# = 1 and s.sid = m.sid and p.addr = s.paddr ) p,
  3  (select t.instance from v$thread t,v$parameter v where v.name = 'thread' and(v.value = 0 or t.thread# = to_number(v.value))) i,
  4  (select value from v$parameter where name = 'user_dump_dest') d;
TRACE_FILE_NAME
--------------------------------------------------------------------------------
/opt/oracle/diag/rdbms/chf/chf/trace/chf_ora_4765.trc

从这里可以看出,move操作执行了00:02:11.77

2.2)查看trace内容

[oracle@node1 ~]$ tkprof  /opt/oracle/diag/rdbms/chf/chf/trace/chf_ora_4765.trc /tmp/xifenfei_move.txt
TKPROF: Release 11.2.0.3.0 - Development on Tue Jan 10 10:57:59 2012
Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.
********************************************************************************
SQL ID: c1yk5pv0v1wg1 Plan Hash: 2931676921
ALTER TABLE CHF.T_XIFENFEI_MOVE MOVE TABLESPACE USERS
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.05          7          8          0           0
Execute      1     11.29     131.23     105584     106275     115654     7432085
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2     11.30     131.29     105591     106283     115654     7432085
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS
Number of plan statistics captured: 1
Rows (1st) Rows (avg) Rows (max)  Row Source Operation
---------- ---------- ----------  ---------------------------------------------------
         0          0          0  LOAD AS SELECT  (cr=117799 pr=105602 pw=105585 time=131351005 us)
   7432085    7432085    7432085   TABLE ACCESS FULL T_XIFENFEI_MOVE (cr=105591 pr=105586 pw=0 time=4735560 us cost=23453 size=720912245 card=7432085)
********************************************************************************

从这里可以看出执行move,其实本质是全表扫描表,然后append方式插入数据,而不是真的数据块拷贝

3.测试CAST
3.1).CAST插入数据过程

SQL> alter system flush buffer_cache;
System altered.
SQL> SET TIMING ON;
SQL> alter session set events
2 ‘10046 trace name context forever,level 1’;
Session altered.
Elapsed: 00:00:00.01
SQL> create table chf.t_xifenfei_move_new tablespace test_ocp
2 as
3 select * from chf.t_xifenfei_move;
Table created.
Elapsed: 00:01:59.22
SQL> alter session set events
2 ‘10046 trace name context off’;
Session altered.
Elapsed: 00:00:00.00
SQL> select d.value||’/’||lower(rtrim(i.instance,chr(0)))||’_ora_’||p.spid||’.trc’ trace_file_name from
2 (select p.spid from v$mystat m, v$session s,v$process p where m.statistic# = 1 and s.sid = m.sid and p.addr = s.paddr ) p,
3 (select t.instance from v$thread t,v$parameter v where v.name = ‘thread’ and(v.value = 0 or t.thread# = to_number(v.value))) i,
4 (select value from v$parameter where name = ‘user_dump_dest’) d;
TRACE_FILE_NAME
——————————————————————————–
/opt/oracle/diag/rdbms/chf/chf/trace/chf_ora_5121.trc

从这里看出cast操作用时:00:01:59.22,比move稍微少,但是cast要实现move完全的功能,还需要表重命名,表授权,编译无效对象等。

3.2)查看trace内容

[oracle@node1 ~]$ tkprof  /opt/oracle/diag/rdbms/chf/chf/trace/chf_ora_5121.trc /tmp/xifenfei_create.txt
TKPROF: Release 11.2.0.3.0 - Development on Tue Jan 10 11:08:19 2012
Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.
********************************************************************************
create table chf.t_xifenfei_move_new tablespace test_ocp
as
select * from chf.t_xifenfei_move
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.02          1          4          0           0
Execute      1      9.85     118.37     105587     106097     112387     7432085
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      9.85     118.40     105588     106101     112387     7432085
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS
Number of plan statistics captured: 1
Rows (1st) Rows (avg) Rows (max)  Row Source Operation
---------- ---------- ----------  ---------------------------------------------------
         0          0          0  LOAD AS SELECT  (cr=106631 pr=105592 pw=105585 time=118338607 us)
   7432085    7432085    7432085   TABLE ACCESS FULL T_XIFENFEI_MOVE (cr=105591 pr=105586 pw=0 time=2935008 us cost=23453 size=720912245 card=7432085)
********************************************************************************

通过这个可以看出,CAST其实本质也是全表扫描,然后append方式插入数据

4.比较move和cast
4.1)通过比较执行时间,cast稍微少,但是还有后续操作需要时间
4.2)通过比较执行计划,两者是一样的
4.3)move操作在整个过程中都会锁表,而cast不会锁住原表(select+where可以减少停业务时间)
4.4)move操作会一次性处理好权限,plsql/view等有效,而cast在rename之后,相关对象可能需要重新编译,重新授权等操作
4.5)cast操作index需要新建(create),而move操作index需要重建(rebuild)
4.6)cast完成后,需要对表重命名,删除原表操作操作,而这个操作move不用

5.选择使用谁
5.1)如果停业务时间够长,建议使用move操作
5.2)如果停业务时间不能太长,可以使用cast+where实现
5.3)如果数据库版本>=10g,且表空间使用local管理,那么可以考虑在不停业务的情况下使用shrink实现类此功能

至于MOVE和CAST在执行过程中,关于产生的redo和undo的比较,请见下篇:MOVE和CAST比较(续)