Oracle10g的DBA_TAB_STATISTICS视图的STATTYPE_LOCKED列没有正确的显示结果。
10g中DBA_TAB_STATISTICS的STATTYPE_LOCKED列对分区锁定显示为空:https://yangtingkun.net/?p=1023
上文提到了DBA_TAB_STATISTICS中的STATTYPE_LOCKED列在10g中对于分区锁定统计信息显示为空,那么在10g中有没有办法获取到正确的结果呢:
SQL> SELECT TABLE_NAME, partition_name, last_analyzed, stattype_locked 2 FROM dba_tab_statistics 3 WHERE owner = USER 4 AND TABLE_NAME = 'T_PART'; TABLE_NAME PARTITION_NAME LAST_ANAL STATT ------------------------------ ------------------------------ --------- ----- T_PART 16-JUL-12 T_PART P1 T_PART P2 16-JUL-12 T_PART PMAX 16-JUL-12 SQL> EXEC dbms_stats.gather_table_stats(USER, 'T_PART', partname => 'P1') BEGIN dbms_stats.gather_table_stats(USER, 'T_PART', partname => 'P1'); END; * ERROR at line 1: ORA-20005: object statistics are locked (stattype = ALL) ORA-06512: at "SYS.DBMS_STATS", line 15027 ORA-06512: at "SYS.DBMS_STATS", line 15049 ORA-06512: at line 1 |
显然虽然Oracle在DBA_TAB_STATISTICS视图中没有正确的显示分区的锁定状态,但是Oracle在内部确实记录了分区的锁定状态,既然Oracle记录了这个信息,就有办法将这个信息显示出来。
既然11g能够显示该列的值,最简单的方法莫过于对比10g和11g中DBA_TAB_STATISTICS视图的区别,10g视图的结果:
SQL> SELECT text FROM dba_views WHERE view_name = 'DBA_TAB_STATISTICS'; TEXT -------------------------------------------------------------------------------- SELECT /* TABLES */ u.name, o.name, NULL, NULL, NULL, NULL, 'TABLE', t.rowcnt, . . . decode(bitand(t.trigflag, 67108864) + bitand(t.trigflag, 134217728), 0, NULL, 67108864, 'DATA', 134217728, 'CACHE', 'ALL'), . . . FROM sys.user$ u, sys.obj$ o, sys.tab$ t, sys.tab_stats$ ts, sys.mon_mods_all$ m WHERE . . . UNION ALL SELECT /* PARTITIONS, NOT IOT */ u.name, o.name, o.subname, tp.part#, NULL, NULL, 'PARTITION', . . . decode(bitand(tab.trigflag, 67108864) + bitand(tab.trigflag, 134217728), 0, NULL, 67108864, 'DATA', 134217728, 'CACHE', 'ALL'), . . . FROM sys.user$ u, sys.obj$ o, sys.tabpartv$ tp, sys.tab_stats$ ts, sys.tab$ tab, sys.mon_mods_all$ m WHERE . . . UNION ALL SELECT /* IOT Partitions */ u.name, o.name, o.subname, tp.part#, NULL, NULL, 'PARTITION', . . . decode(bitand(tab.trigflag, 67108864) + bitand(tab.trigflag, 134217728), 0, NULL, 67108864, 'DATA', 134217728, 'CACHE', 'ALL'), . . . FROM sys.user$ u, sys.obj$ o, sys.tabpartv$ tp, sys.tab$ tab, sys.mon_mods_all$ m WHERE . . . UNION ALL SELECT /* COMPOSITE PARTITIONS */ u.name, o.name, o.subname, tcp.part#, NULL, NULL, 'PARTITION', . . . decode(bitand(tab.trigflag, 67108864) + bitand(tab.trigflag, 134217728), 0, NULL, 67108864, 'DATA', 134217728, 'CACHE', 'ALL'), . . . FROM sys.user$ u, sys.obj$ o, sys.tabcompartv$ tcp, sys.tab_stats$ ts, sys.tab$ tab, sys.mon_mods_all$ m WHERE . . . UNION ALL SELECT /* SUBPARTITIONS */ u.name, po.name, po.subname, tcp.part#, so.subname, tsp.subpart#, . . . decode(bitand(tab.trigflag, 67108864) + bitand(tab.trigflag, 134217728), 0, NULL, 67108864, 'DATA', 134217728, 'CACHE', 'ALL'), . . . FROM sys.user$ u, sys.obj$ po, sys.obj$ so, sys.tabcompartv$ tcp, sys.tabsubpartv$ tsp, sys.tab_stats$ ts, sys.tab$ tab, sys.mon_mods_all$ m WHERE . . . UNION ALL SELECT /* FIXED TABLES */ 'SYS', t.kqftanam, NULL, NULL, NULL, NULL, 'FIXED TABLE', . . . |
对比一下11g的查询结果:
SQL> SELECT text FROM dba_views WHERE view_name = 'DBA_TAB_STATISTICS'; TEXT -------------------------------------------------------------------------------- SELECT /* TABLES */ u.name, o.name, NULL, NULL, NULL, NULL, 'TABLE', t.rowcnt, . . . decode(bitand(t.trigflag, 67108864) + bitand(t.trigflag, 134217728), 0, NULL, 67108864, 'DATA', 134217728, 'CACHE', 'ALL'), . . . FROM sys.user$ u, sys.obj$ o, sys.tab$ t, sys.tab_stats$ ts, sys.mon_mods_all$ m WHERE . . . UNION ALL SELECT /* PARTITIONS, NOT IOT */ u.name, o.name, o.subname, tp.part#, NULL, NULL, 'PARTITION', . . . decode( /* * Following decode returns 1 if DATA stats locked for partition * or at table level */ decode(bitand(tab.trigflag, 67108864) + bitand(tp.flags, 32), 0, 0, 1) + /* * Following decode returns 2 if CACHE stats locked for partition * or at table level */ decode(bitand(tab.trigflag, 134217728) + bitand(tp.flags, 64), 0, 0, 2), /* if 0 => not locked, 3 => data and cache stats locked */ 0, NULL, 1, 'DATA', 2, 'CACHE', 'ALL'), . . . FROM sys.user$ u, sys.obj$ o, sys.tabpartv$ tp, sys.tab_stats$ ts, sys.tab$ tab, sys.mon_mods_all$ m . . . UNION ALL SELECT /* IOT Partitions */ u.name, o.name, o.subname, tp.part#, NULL, NULL, 'PARTITION', . . . decode( /* * Following decode returns 1 if DATA stats locked for partition * or at table level */ decode(bitand(tab.trigflag, 67108864) + bitand(tp.flags, 32), 0, 0, 1) + /* * Following decode returns 2 if CACHE stats locked for partition * or at table level */ decode(bitand(tab.trigflag, 134217728) + bitand(tp.flags, 64), 0, 0, 2), /* if 0 => not locked, 3 => data and cache stats locked */ 0, NULL, 1, 'DATA', 2, 'CACHE', 'ALL'), . . . FROM sys.user$ u, sys.obj$ o, sys.tabpartv$ tp, sys.tab$ tab, sys.mon_mods_all$ m WHERE . . . UNION ALL SELECT /* COMPOSITE PARTITIONS */ u.name, o.name, o.subname, tcp.part#, NULL, NULL, 'PARTITION', . . . decode( /* * Following decode returns 1 if DATA stats locked for partition * or at table level */ decode(bitand(tab.trigflag, 67108864) + bitand(tcp.flags, 32), 0, 0, 1) + /* * Following decode returns 2 if CACHE stats locked for partition * or at table level */ decode(bitand(tab.trigflag, 134217728) + bitand(tcp.flags, 64), 0, 0, 2), /* if 0 => not locked, 3 => data and cache stats locked */ 0, NULL, 1, 'DATA', 2, 'CACHE', 'ALL'), . . . FROM sys.user$ u, sys.obj$ o, sys.tabcompartv$ tcp, sys.tab_stats$ ts, sys.tab$ tab, sys.mon_mods_all$ m WHERE . . . UNION ALL SELECT /* SUBPARTITIONS */ u.name, po.name, po.subname, tcp.part#, so.subname, tsp.subpart#, . . . decode( /* * Following decode returns 1 if DATA stats locked for partition * or at table level. * Note that dbms_stats does n't allow locking subpartition stats. * If the composite partition is locked, all subpartitions are * considered locked. Hence decode checks for tcp entry. */ decode(bitand(tab.trigflag, 67108864) + bitand(tcp.flags, 32), 0, 0, 1) + /* * Following decode returns 2 if CACHE stats locked for partition * or at table level */ decode(bitand(tab.trigflag, 134217728) + bitand(tcp.flags, 64), 0, 0, 2), /* if 0 => not locked, 3 => data and cache stats locked */ 0, NULL, 1, 'DATA', 2, 'CACHE', 'ALL'), . . . FROM sys.user$ u, sys.obj$ po, sys.obj$ so, sys.tabcompartv$ tcp, sys.tabsubpartv$ tsp, sys.tab_stats$ ts, sys.tab$ tab, sys.mon_mods_all$ m WHERE . . . UNION ALL SELECT /* FIXED TABLES */ . . . |
显然在11g中Oracle对于分区锁定的显示采用了新的算法,那么可以仿照11g中建立一个视图,来解决10g中分区显示存在错误的问题:
SQL> CREATE OR REPLACE VIEW DBA_TAB_STATISTICS_LOCK 2 (OWNER, TABLE_NAME, PARTITION_NAME, 3 SUBPARTITION_NAME, OBJECT_TYPE, STATTYPE_LOCKED) 4 AS 5 SELECT u.name, o.name, NULL, NULL, 'TABLE', 6 decode(bitand(t.trigflag, 67108864) + bitand(t.trigflag, 134217728), 7 0, NULL, 67108864, 'DATA', 134217728, 'CACHE', 'ALL') 8 FROM sys.user$ u, sys.obj$ o, sys.tab$ t 9 WHERE o.owner# = u.user# 10 AND o.obj# = t.obj# 11 AND bitand(t.property, 1) = 0 12 AND o.subname IS NULL 13 AND o.namespace = 1 AND o.remoteowner IS NULL AND o.linkname IS NULL 14 AND bitand(o.flags, 128) = 0 15 UNION ALL 16 SELECT u.name, o.name, o.subname, NULL, 'PARTITION', 17 decode( 18 decode(bitand(tab.trigflag, 67108864) + bitand(tp.flags, 32), 0, 0, 1) + 19 decode(bitand(tab.trigflag, 134217728) + bitand(tp.flags, 64), 0, 0, 2), 20 0, NULL, 1, 'DATA', 2, 'CACHE', 'ALL') 21 FROM sys.user$ u, sys.obj$ o, sys.tabpartv$ tp, sys.tab$ tab 22 WHERE o.owner# = u.user# 23 AND o.obj# = tp.obj# 24 AND tp.bo# = tab.obj# 25 AND bitand(tab.property, 64) = 0 26 AND o.namespace = 1 AND o.remoteowner IS NULL AND o.linkname IS NULL 27 AND bitand(o.flags, 128) = 0 28 UNION ALL 29 SELECT u.name, o.name, o.subname, NULL, 'PARTITION', 30 decode( 31 decode(bitand(tab.trigflag, 67108864) + bitand(tp.flags, 32), 0, 0, 1) + 32 decode(bitand(tab.trigflag, 134217728) + bitand(tp.flags, 64), 0, 0, 2), 33 0, NULL, 1, 'DATA', 2, 'CACHE', 'ALL') 34 FROM sys.user$ u, sys.obj$ o, sys.tabpartv$ tp, sys.tab$ tab 35 WHERE o.owner# = u.user# 36 AND o.obj# = tp.obj# 37 AND tp.bo# = tab.obj# 38 AND bitand(tab.property, 64) = 64 39 AND o.namespace = 1 AND o.remoteowner IS NULL AND o.linkname IS NULL 40 AND bitand(o.flags, 128) = 0 41 UNION ALL 42 SELECT u.name, o.name, o.subname, NULL, 'PARTITION', 43 decode( 44 decode(bitand(tab.trigflag, 67108864) + bitand(tcp.flags, 32), 0, 0, 1) + 45 decode(bitand(tab.trigflag, 134217728) + bitand(tcp.flags, 64), 0, 0, 2), 46 0, NULL, 1, 'DATA', 2, 'CACHE', 'ALL') 47 FROM sys.user$ u, sys.obj$ o, sys.tabcompartv$ tcp, sys.tab$ tab 48 WHERE o.owner# = u.user# 49 AND o.obj# = tcp.obj# 50 AND tcp.bo# = tab.obj# 51 AND o.namespace = 1 AND o.remoteowner IS NULL AND o.linkname IS NULL 52 AND bitand(o.flags, 128) = 0 53 UNION ALL 54 SELECT u.name, po.name, po.subname, so.subname, 'SUBPARTITION', 55 decode( 56 decode(bitand(tab.trigflag, 67108864) + bitand(tcp.flags, 32), 0, 0, 1) + 57 decode(bitand(tab.trigflag, 134217728) + bitand(tcp.flags, 64), 0, 0, 2), 58 0, NULL, 1, 'DATA', 2, 'CACHE', 'ALL') 59 FROM sys.user$ u, sys.obj$ po, sys.obj$ so, sys.tabcompartv$ tcp, sys.tabsubpartv$ tsp, sys.tab$ tab 60 WHERE so.obj# = tsp.obj# 61 AND po.obj# = tcp.obj# 62 AND tcp.obj# = tsp.pobj# 63 AND tcp.bo# = tab.obj# 64 AND u.user# = po.owner# 65 AND bitand(tab.property, 64) = 0 66 AND po.namespace = 1 AND po.remoteowner IS NULL AND po.linkname IS NULL 67 AND bitand(po.flags, 128) = 0 68 ; VIEW created. SQL> SELECT TABLE_NAME, partition_name, object_type, stattype_locked 2 FROM dba_tab_statistics_lock 3 WHERE owner = 'TEST' 4 AND TABLE_NAME = 'T_PART'; TABLE_NAME PARTITION_NAME OBJECT_TYPE STATT ------------------------------ ------------------------------ ------------ ----- T_PART TABLE T_PART P1 PARTITION ALL T_PART P2 PARTITION T_PART PMAX PARTITION |
使用新创建的这个视图,就可以解决锁定分区的统计信息显示问题。