固定执行计划-使用SPM(Sql Plan Management)固定执行计划

测试目的: 使用SPM(Sql Plan Management)固定执行计划和hint中指定no index,谁的优先级高?
.
固定执行计划-使用SQL Tuning Advisor
固定执行计划-手工指定PLAN OUTLINE
固定执行计划-手工指定索引名称的方式
固定执行计划-使用coe_xfr_sql_profile固定执行计划
固定执行计划-使用SPM(Sql Plan Management)固定执行计划
.

在Oracle 11g前,我们可以借助存储大纲(Stored Outline)和SQL Profile来帮助我们固定某个SQL语句的执行计划。
11g中,Oracle 提供了SPM(Sql Plan Management)。
通过这个特性,可以考虑让Oracle自动去判断某个SQL的新的执行计划是否更加合理(成本更低),只有在新的执行计划比原来的执行计划更好才会被使用,从而保护了执行计划的稳定性和SQL语句的执行效率。
可以考虑手工捕获和自动捕获两种方式,这里我们采用手工捕获(11.2的缺省设置是非自动捕获)。
首先查看当前为禁止自动捕获的状态:

SYS@lunardb>show parameter optimizer_capture_sql_plan_baselines

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
optimizer_capture_sql_plan_baselines boolean     FALSE
SYS@lunardb>

当前SPM中没有内容:

LUNAR@lunardb>select signature,sql_handle,plan_name,origin,enabled,accepted,autopurge from dba_sql_plan_baselines;

no rows selected

Elapsed: 00:00:00.00
LUNAR@lunardb>

手工加载一个SQL到SPM中:

LUNAR@lunardb>declare
  2    l_plans_loaded  PLS_INTEGER;
  3  begin
  4    l_plans_loaded := DBMS_SPM.load_plans_from_cursor_cache(sql_id => '&sql_id');
  5    DBMS_OUTPUT.put_line('Plans Loaded: ' || l_plans_loaded);
  6  END;
  7  /
Enter value for sql_id: bjgduva68mbqm
old   4:   l_plans_loaded := DBMS_SPM.load_plans_from_cursor_cache(sql_id => '&sql_id');
new   4:   l_plans_loaded := DBMS_SPM.load_plans_from_cursor_cache(sql_id => 'bjgduva68mbqm');
Plans Loaded: 1

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.21
LUNAR@lunardb>
LUNAR@lunardb>select signature,sql_handle,plan_name,origin,enabled,accepted,autopurge from dba_sql_plan_baselines;

       SIGNATURE SQL_HANDLE                     PLAN_NAME                      ORIGIN         ENA ACC AUT
---------------- ------------------------------ ------------------------------ -------------- --- --- ---
6.5941520220E+17 SQL_0926b6a1f69f6f5c           SQL_PLAN_0k9pqn7v9yvuw02b73393 MANUAL-LOAD    YES YES YES

Elapsed: 00:00:00.01
LUNAR@lunardb>

由于上一个测试,我们已经有了正确的执行计划,即:

LUNAR@lunardb>select * from table(dbms_xplan.display_cursor(sql_id=>'bjgduva68mbqm')) where plan_table_output  like ('Plan hash value%');

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 3241900148

Elapsed: 00:00:00.02
LUNAR@lunardb>
LUNAR@lunardb>select SQL_HANDLE, PLAN_NAME, ENABLED, ACCEPTED, SQL_TEXT 
  2  from DBA_SQL_PLAN_BASELINES 
  3  where ACCEPTED = 'YES'
  4  order by LAST_MODIFIED;

SQL_HANDLE                     PLAN_NAME                      ENA ACC SQL_TEXT
------------------------------ ------------------------------ --- --- --------------------------------------------------------------------------------
SQL_0926b6a1f69f6f5c           SQL_PLAN_0k9pqn7v9yvuw02b73393 YES YES select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1

Elapsed: 00:00:00.01
LUNAR@lunardb>

下面,我们装载指定的执行计划:

LUNAR@lunardb>variable cnt number ;
LUNAR@lunardb>exec :cnt :=dbms_spm.LOAD_PLANS_FROM_CURSOR_CACHE (SQL_ID => '&SQL_ID',PLAN_HASH_VALUE => &plan_hash_value, SQL_HANDLE => '&SQL_HANDLE' ) ; 
Enter value for sql_id: bjgduva68mbqm
Enter value for plan_hash_value: 1172089107
Enter value for sql_handle: SQL_0926b6a1f69f6f5c

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.02
LUNAR@lunardb>select signature,sql_handle,plan_name,origin,enabled,accepted,autopurge 
  2  from dba_sql_plan_baselines where CREATED>sysdate-1/48 order by created;

             SIGNATURE SQL_HANDLE                     PLAN_NAME                      ORIGIN         ENA ACC AUT
---------------------- ------------------------------ ------------------------------ -------------- --- --- ---
    659415202199990108 SQL_0926b6a1f69f6f5c           SQL_PLAN_0k9pqn7v9yvuw02b73393 MANUAL-LOAD    YES YES YES

Elapsed: 00:00:00.00
LUNAR@lunardb>

确认该执行计划的OUTLINE:

LUNAR@lunardb>SELECT extractValue(value(h),'.') AS hint
  2  FROM sys.sqlobj$data od, sys.sqlobj$ so,
  3  table(xmlsequence(extract(xmltype(od.comp_data),'/outline_data/hint'))) h
  4  WHERE so.name = 'SQL_PLAN_0k9pqn7v9yvuw02b73393'
  5  AND so.signature = od.signature
  6  AND so.category = od.category
  7  AND so.obj_type = od.obj_type
  8  AND so.plan_id = od.plan_id;

HINT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('11.2.0.4')
DB_VERSION('11.2.0.4')
ALL_ROWS
OUTLINE_LEAF(@"SEL$1")
INDEX(@"SEL$1" "LUNARTEST1"@"SEL$1" ("LUNARTEST1"."N"))

6 rows selected.

Elapsed: 00:00:00.08
LUNAR@lunardb>

这里看到是我们需要的走索引的outline,详细的OUTLINE信息如下:

LUNAR@lunardb>SELECT extractValue(value(h),'.') AS hint
  2  FROM sys.sqlobj$data od, sys.sqlobj$ so,
  3  table(xmlsequence(extract(xmltype(od.comp_data),'/outline_data/hint'))) h
  4  WHERE so.signature = '659415202199990108'
  5  AND so.signature = od.signature
  6  AND so.category = od.category
  7  AND so.obj_type = od.obj_type
  8  AND so.plan_id = od.plan_id;

HINT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('11.2.0.4')
DB_VERSION('11.2.0.4')
ALL_ROWS
OUTLINE_LEAF(@"SEL$1")
INDEX(@"SEL$1" "LUNARTEST1"@"SEL$1" ("LUNARTEST1"."N"))
END_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('11.2.0.4')
DB_VERSION('11.2.0.4')
ALL_ROWS
OUTLINE_LEAF(@"SEL$1")
INDEX(@"SEL$1" "LUNARTEST1"@"SEL$1" ("LUNARTEST1"."N"))

14 rows selected.

Elapsed: 00:00:00.10
LUNAR@lunardb>    

现在我们删除profile以前用coe绑定的sql profile:

LUNAR@lunardb>SELECT * FROM DBA_SQL_PROFILES;

NAME                           CATEGORY                                    SIGNATURE SQL_TEXT
------------------------------ ------------------------------ ---------------------- --------------------------------------------------------------------------------
CREATED                                                                     LAST_MODIFIED
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
DESCRIPTION
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
TYPE    STATUS   FOR          TASK_ID TASK_EXEC_NAME                      TASK_OBJ_ID      TASK_FND_ID      TASK_REC_ID
------- -------- --- ---------------- ------------------------------ ---------------- ---------------- ----------------
coe_bjgduva68mbqm_3241900148   DEFAULT                            659415202199990108 select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1
12-JAN-16 11.24.18.000000 AM                                                12-JAN-16 11.40.52.000000 AM
coe bjgduva68mbqm 3241900148 659415202199990108 9900816299026594015
MANUAL  ENABLED  NO


Elapsed: 00:00:00.01
LUNAR@lunardb>
LUNAR@lunardb>exec dbms_sqltune.drop_sql_profile('coe_bjgduva68mbqm_3241900148'); 

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.01
LUNAR@lunardb>SELECT * FROM DBA_SQL_PROFILES;

no rows selected

Elapsed: 00:00:00.00
LUNAR@lunardb>

再次验证SPM的执行计划:

LUNAR@lunardb>select * from table(dbms_xplan.DISPLAY_SQL_PLAN_BASELINE('&sql_handle','&PLAN_NAME'));
Enter value for sql_handle: SQL_0926b6a1f69f6f5c
Enter value for plan_name: SQL_PLAN_0k9pqn7v9yvuw02b73393
old   1: select * from table(dbms_xplan.DISPLAY_SQL_PLAN_BASELINE('&sql_handle','&PLAN_NAME'))
new   1: select * from table(dbms_xplan.DISPLAY_SQL_PLAN_BASELINE('SQL_0926b6a1f69f6f5c','SQL_PLAN_0k9pqn7v9yvuw02b73393'))

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

--------------------------------------------------------------------------------
SQL handle: SQL_0926b6a1f69f6f5c
SQL text: select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1
          where n=1
--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
Plan name: SQL_PLAN_0k9pqn7v9yvuw02b73393         Plan id: 45560723
Enabled: YES     Fixed: NO      Accepted: YES     Origin: MANUAL-LOAD
--------------------------------------------------------------------------------

Plan hash value: 3241900148

-------------------------------------------------------------------------------------
| Id  | Operation        | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |                  |     1 |     4 |     1   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| IDX_LUNARTEST1_N |     1 |     4 |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------

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

   1 - access("N"=1)

25 rows selected.

Elapsed: 00:00:00.16
LUNAR@lunardb>

执行SQL,发现SPM可以固定执行计划,使用了我们期待的:

LUNAR@lunardb>set autotrace traceo exp stat
LUNAR@lunardb>select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1;

Elapsed: 00:00:00.13

Execution Plan
----------------------------------------------------------
Plan hash value: 3241900148

-------------------------------------------------------------------------------------
| Id  | Operation        | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |                  |     1 |     4 |     1   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| IDX_LUNARTEST1_N |     1 |     4 |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------

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

   1 - access("N"=1)

Note
-----
   - SQL plan baseline "SQL_PLAN_0k9pqn7v9yvuw02b73393" used for this statement


Statistics
----------------------------------------------------------
         59  recursive calls
         52  db block gets
         36  consistent gets
          1  physical reads
      15312  redo size
        519  bytes sent via SQL*Net to client
        523  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

LUNAR@lunardb>

这里看到已经使用了SPM中的SQL Profile:SQL_PLAN_0k9pqn7v9yvuw02b73393
总结:
这里已经使用了我们的SPM(SQL_PLAN_0k9pqn7v9yvuw02b73393)固定了执行计划,sql使用了索引
说明SPM绑定执行计划的方式比hint的优先级高

发表在 Performence Tuning | 标签为 , | 留下评论

固定执行计划-使用coe_xfr_sql_profile(BASELINE)固定执行计划

测试目的: 使用coe_xfr_sql_profile的方式固定执行计划和hint中指定no index,谁的优先级高?
在SQLT工具中包含了几个轻巧方便的coe脚本,用来固定执行计划,其中coe_xfr_sql_profile是我常用的。
.
固定执行计划-使用SQL Tuning Advisor
固定执行计划-手工指定PLAN OUTLINE
固定执行计划-手工指定索引名称的方式
固定执行计划-使用coe_xfr_sql_profile固定执行计划
固定执行计划-使用SPM(Sql Plan Management)固定执行计划
.
查看当前的SQL Profile:

LUNAR@lunardb>select * from dba_sql_profiles;

NAME                           CATEGORY                              SIGNATURE SQL_TEXT
------------------------------ ------------------------------ ---------------- --------------------------------------------------------------------------------
CREATED                                                                     LAST_MODIFIED
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
DESCRIPTION
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
TYPE    STATUS   FOR          TASK_ID TASK_EXEC_NAME                      TASK_OBJ_ID      TASK_FND_ID      TASK_REC_ID
------- -------- --- ---------------- ------------------------------ ---------------- ---------------- ----------------
Lunar_bjgduva68mbqm_profile    DEFAULT                        9.9008162990E+18 select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1
12-JAN-16 10.53.46.000000 AM                                                12-JAN-16 10.53.46.000000 AM

MANUAL  ENABLED  YES


Elapsed: 00:00:00.00
LUNAR@lunardb>
LUNAR@lunardb>exec dbms_sqltune.drop_sql_profile('Lunar_bjgduva68mbqm_profile');  

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.14
LUNAR@lunardb>select * from dba_sql_profiles;

no rows selected

Elapsed: 00:00:00.01
LUNAR@lunardb>

使用coe_xfr_sql_profile脚本自动识别和指定执行计划:

LUNAR@lunardb>@coe_xfr_sql_profile.sql bjgduva68mbqm

Parameter 1:
SQL_ID (required)



 PLAN_HASH_VALUE      AVG_ET_SECS
---------------- ----------------
      1172089107             .003

Parameter 2:
PLAN_HASH_VALUE (required)

Enter value for 2: 1172089107

Values passed to coe_xfr_sql_profile:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SQL_ID         : "bjgduva68mbqm"
PLAN_HASH_VALUE: "1172089107"

SQL>BEGIN
  2    IF :sql_text IS NULL THEN
  3      RAISE_APPLICATION_ERROR(-20100, 'SQL_TEXT for SQL_ID &&sql_id. was not found in memory (gv$sqltext_with_newlines) or AWR (dba_hist_sqltext).');
  4    END IF;
  5  END;
  6  /
SQL>SET TERM OFF;
SQL>BEGIN
  2    IF :other_xml IS NULL THEN
  3      RAISE_APPLICATION_ERROR(-20101, 'PLAN for SQL_ID &&sql_id. and PHV &&plan_hash_value. was not found in memory (gv$sql_plan) or AWR (dba_hist_sql_plan).');
  4    END IF;
  5  END;
  6  /
SQL>SET TERM OFF;

Execute coe_xfr_sql_profile_bjgduva68mbqm_1172089107.sql
on TARGET system in order to create a custom SQL Profile
with plan 1172089107 linked to adjusted sql_text.


COE_XFR_SQL_PROFILE completed.
SQL>
SQL>@coe_xfr_sql_profile_bjgduva68mbqm_1172089107.sql
SQL>REM
SQL>REM $Header: 215187.1 coe_xfr_sql_profile_bjgduva68mbqm_1172089107.sql 11.4.4.4 2016/01/12 carlos.sierra $
SQL>REM
SQL>REM Copyright (c) 2000-2012, Oracle Corporation. All rights reserved.
SQL>REM
SQL>REM AUTHOR
SQL>REM   carlos.sierra@oracle.com
SQL>REM
SQL>REM SCRIPT
SQL>REM   coe_xfr_sql_profile_bjgduva68mbqm_1172089107.sql
SQL>REM
SQL>REM DESCRIPTION
SQL>REM   This script is generated by coe_xfr_sql_profile.sql
SQL>REM   It contains the SQL*Plus commands to create a custom
SQL>REM   SQL Profile for SQL_ID bjgduva68mbqm based on plan hash
SQL>REM   value 1172089107.
SQL>REM   The custom SQL Profile to be created by this script
SQL>REM   will affect plans for SQL commands with signature
SQL>REM   matching the one for SQL Text below.
SQL>REM   Review SQL Text and adjust accordingly.
SQL>REM
SQL>REM PARAMETERS
SQL>REM   None.
SQL>REM
SQL>REM EXAMPLE
SQL>REM   SQL> START coe_xfr_sql_profile_bjgduva68mbqm_1172089107.sql;
SQL>REM
SQL>REM NOTES
SQL>REM   1. Should be run as SYSTEM or SYSDBA.
SQL>REM   2. User must have CREATE ANY SQL PROFILE privilege.
SQL>REM   3. SOURCE and TARGET systems can be the same or similar.
SQL>REM   4. To drop this custom SQL Profile after it has been created:
SQL>REM  EXEC DBMS_SQLTUNE.DROP_SQL_PROFILE('coe_bjgduva68mbqm_1172089107');
SQL>REM   5. Be aware that using DBMS_SQLTUNE requires a license
SQL>REM  for the Oracle Tuning Pack.
SQL>REM   6. If you modified a SQL putting Hints in order to produce a desired
SQL>REM  Plan, you can remove the artifical Hints from SQL Text pieces below.
SQL>REM  By doing so you can create a custom SQL Profile for the original
SQL>REM  SQL but with the Plan captured from the modified SQL (with Hints).
SQL>REM
SQL>WHENEVER SQLERROR EXIT SQL.SQLCODE;
SQL>REM
SQL>VAR signature NUMBER;
SQL>VAR signaturef NUMBER;
SQL>REM
SQL>DECLARE
  2  sql_txt CLOB;
  3  h       SYS.SQLPROF_ATTR;
  4  PROCEDURE wa (p_line IN VARCHAR2) IS
  5  BEGIN
  6  DBMS_LOB.WRITEAPPEND(sql_txt, LENGTH(p_line), p_line);
  7  END wa;
  8  BEGIN
  9  DBMS_LOB.CREATETEMPORARY(sql_txt, TRUE);
 10  DBMS_LOB.OPEN(sql_txt, DBMS_LOB.LOB_READWRITE);
 11  -- SQL Text pieces below do not have to be of same length.
 12  -- So if you edit SQL Text (i.e. removing temporary Hints),
 13  -- there is no need to edit or re-align unmodified pieces.
 14  wa(q'[select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunar]');
 15  wa(q'[test1 where n=1]');
 16  DBMS_LOB.CLOSE(sql_txt);
 17  h := SYS.SQLPROF_ATTR(
 18  q'[BEGIN_OUTLINE_DATA]',
 19  q'[IGNORE_OPTIM_EMBEDDED_HINTS]',
 20  q'[OPTIMIZER_FEATURES_ENABLE('11.2.0.4')]',
 21  q'[DB_VERSION('11.2.0.4')]',
 22  q'[ALL_ROWS]',
 23  q'[OUTLINE_LEAF(@"SEL$1")]',
 24  q'[FULL(@"SEL$1" "LUNARTEST1"@"SEL$1")]',
 25  q'[END_OUTLINE_DATA]');
 26  :signature := DBMS_SQLTUNE.SQLTEXT_TO_SIGNATURE(sql_txt);
 27  :signaturef := DBMS_SQLTUNE.SQLTEXT_TO_SIGNATURE(sql_txt, TRUE);
 28  DBMS_SQLTUNE.IMPORT_SQL_PROFILE (
 29  sql_text    => sql_txt,
 30  profile     => h,
 31  name        => 'coe_bjgduva68mbqm_1172089107',
 32  description => 'coe bjgduva68mbqm 1172089107 '||:signature||' '||:signaturef||'',
 33  category    => 'DEFAULT',
 34  validate    => TRUE,
 35  replace     => TRUE,
 36  force_match => FALSE /* TRUE:FORCE (match even when different literals in SQL). FALSE:EXACT (similar to CURSOR_SHARING) */ );
 37  DBMS_LOB.FREETEMPORARY(sql_txt);
 38  END;
 39  /

PL/SQL procedure successfully completed.

SQL>WHENEVER SQLERROR CONTINUE
SQL>SET ECHO OFF;

            SIGNATURE
---------------------
   659415202199990108


           SIGNATUREF
---------------------
  9900816299026594015


... manual custom SQL Profile has been created


COE_XFR_SQL_PROFILE_bjgduva68mbqm_1172089107 completed
SQL>

因为删除了SQL Profile,对应的执行计划也会被删除,因此当前只有一个全表扫描的执行计划(上次测试留下的),以前的执行计划都不在了。
上面的执行过程中已经告诉我们,这个执行计划会使用全表扫描(q'[FULL(@”SEL$1″ “LUNARTEST1″@”SEL$1”)]’):

16  DBMS_LOB.CLOSE(sql_txt);
 17  h := SYS.SQLPROF_ATTR(
 18  q'[BEGIN_OUTLINE_DATA]',
 19  q'[IGNORE_OPTIM_EMBEDDED_HINTS]',
 20  q'[OPTIMIZER_FEATURES_ENABLE('11.2.0.4')]',
 21  q'[DB_VERSION('11.2.0.4')]',
 22  q'[ALL_ROWS]',
 23  q'[OUTLINE_LEAF(@"SEL$1")]',
 24  q'[FULL(@"SEL$1" "LUNARTEST1"@"SEL$1")]',
 25  q'[END_OUTLINE_DATA]');

我们查看一下这个SQL Profile的主要内容:

SYS@lunardb>conn lunar/lunar
Connected.
LUNAR@lunardb>select * from dba_sql_profiles;

NAME                           CATEGORY                              SIGNATURE SQL_TEXT
------------------------------ ------------------------------ ---------------- --------------------------------------------------------------------------------
CREATED                                                                     LAST_MODIFIED
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
DESCRIPTION
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
TYPE    STATUS   FOR          TASK_ID TASK_EXEC_NAME                      TASK_OBJ_ID      TASK_FND_ID      TASK_REC_ID
------- -------- --- ---------------- ------------------------------ ---------------- ---------------- ----------------
coe_bjgduva68mbqm_1172089107   DEFAULT                        6.5941520220E+17 select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1
12-JAN-16 11.24.18.000000 AM                                                12-JAN-16 11.24.18.000000 AM
coe bjgduva68mbqm 1172089107 659415202199990108 9900816299026594015
MANUAL  ENABLED  NO

Elapsed: 00:00:00.01
LUNAR@lunardb>
LUNAR@lunardb>SELECT extractValue(value(h),'.') AS hint
  2  FROM sys.sqlobj$data od, sys.sqlobj$ so,
  3  table(xmlsequence(extract(xmltype(od.comp_data),'/outline_data/hint'))) h
  4  WHERE so.name = 'coe_bjgduva68mbqm_1172089107'
  5  AND so.signature = od.signature
  6  AND so.category = od.category
  7  AND so.obj_type = od.obj_type
  8  AND so.plan_id = od.plan_id;

HINT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('11.2.0.4')
DB_VERSION('11.2.0.4')
ALL_ROWS
OUTLINE_LEAF(@"SEL$1")
FULL(@"SEL$1" "LUNARTEST1"@"SEL$1")
END_OUTLINE_DATA

8 rows selected.

Elapsed: 00:00:00.02
LUNAR@lunardb>

现在我们产生一个正确的执行计划,让该sql执行时使用到索引:

LUNAR@lunardb>select * from lunartest1 where n=1;

Elapsed: 00:00:00.00

Execution Plan
----------------------------------------------------------
Plan hash value: 3241900148

-------------------------------------------------------------------------------------
| Id  | Operation        | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |                  |     1 |     4 |     1   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| IDX_LUNARTEST1_N |     1 |     4 |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------

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

   1 - access("N"=1)


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          3  consistent gets
          0  physical reads
          0  redo size
        519  bytes sent via SQL*Net to client
        524  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

LUNAR@lunardb>

找出sqlid

SYS@lunardb>select sql_id,sql_text from v$sql where sql_text like '%select * from lunartest1 where n=1%';

SQL_ID
-------------
SQL_TEXT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4b2bfyz3qnrxu
EXPLAIN PLAN SET STATEMENT_ID='PLUS80018' FOR select * from lunartest1 where n=1

fjmxgdhw858hz
select * from lunartest1 where n=1

8ka8pzvvkqwwg
select sql_id,sql_text from v$sql where sql_text like '%select * from lunartest1 where n=1%'


Elapsed: 00:00:00.02
SYS@lunardb>

找出正确的outline:

SYS@lunardb>select * from table(dbms_xplan.display_cursor('fjmxgdhw858hz',null,'outline'));

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  fjmxgdhw858hz, child number 0
-------------------------------------
select * from lunartest1 where n=1

Plan hash value: 3241900148

-------------------------------------------------------------------------------------
| Id  | Operation        | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |                  |       |       |     1 (100)|          |
|*  1 |  INDEX RANGE SCAN| IDX_LUNARTEST1_N |     1 |     4 |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------

Outline Data
-------------

  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('11.2.0.4')
      DB_VERSION('11.2.0.4')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$1")
      INDEX(@"SEL$1" "LUNARTEST1"@"SEL$1" ("LUNARTEST1"."N"))
      END_OUTLINE_DATA
  */

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

   1 - access("N"=1)


32 rows selected.

Elapsed: 00:00:00.02
SYS@lunardb>

这里我们看到已经使用了索引。
使用coe_xfr_sql_profile固定执行计划:

LUNAR@lunardb>@coe_xfr_sql_profile.sql bjgduva68mbqm

Parameter 1:
SQL_ID (required)



 PLAN_HASH_VALUE      AVG_ET_SECS
---------------- ----------------
      1172089107             .003

Parameter 2:
PLAN_HASH_VALUE (required)

Enter value for 2: 3241900148

Values passed to coe_xfr_sql_profile:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SQL_ID         : "bjgduva68mbqm"
PLAN_HASH_VALUE: "3241900148"

SQL>BEGIN
  2    IF :sql_text IS NULL THEN
  3      RAISE_APPLICATION_ERROR(-20100, 'SQL_TEXT for SQL_ID &&sql_id. was not found in memory (gv$sqltext_with_newlines) or AWR (dba_hist_sqltext).');
  4    END IF;
  5  END;
  6  /
SQL>SET TERM OFF;
SQL>BEGIN
  2    IF :other_xml IS NULL THEN
  3      RAISE_APPLICATION_ERROR(-20101, 'PLAN for SQL_ID &&sql_id. and PHV &&plan_hash_value. was not found in memory (gv$sql_plan) or AWR (dba_hist_sql_plan).');
  4    END IF;
  5  END;
  6  /
SQL>SET TERM OFF;

Execute coe_xfr_sql_profile_bjgduva68mbqm_3241900148.sql
on TARGET system in order to create a custom SQL Profile
with plan 3241900148 linked to adjusted sql_text.


COE_XFR_SQL_PROFILE completed.
SQL>

现在,测试一下,使用SYS用户绑定是否会影响其他用户使用执行计划:

SYS@lunardb>@coe_xfr_sql_profile_bjgduva68mbqm_3241900148.sql
SYS@lunardb>REM
SYS@lunardb>REM $Header: 215187.1 coe_xfr_sql_profile_bjgduva68mbqm_3241900148.sql 11.4.4.4 2016/01/12 carlos.sierra $
SYS@lunardb>REM
SYS@lunardb>REM Copyright (c) 2000-2012, Oracle Corporation. All rights reserved.
SYS@lunardb>REM
SYS@lunardb>REM AUTHOR
SYS@lunardb>REM   carlos.sierra@oracle.com
SYS@lunardb>REM
SYS@lunardb>REM SCRIPT
SYS@lunardb>REM   coe_xfr_sql_profile_bjgduva68mbqm_3241900148.sql
SYS@lunardb>REM
SYS@lunardb>REM DESCRIPTION
SYS@lunardb>REM   This script is generated by coe_xfr_sql_profile.sql
SYS@lunardb>REM   It contains the SQL*Plus commands to create a custom
SYS@lunardb>REM   SQL Profile for SQL_ID bjgduva68mbqm based on plan hash
SYS@lunardb>REM   value 3241900148.
SYS@lunardb>REM   The custom SQL Profile to be created by this script
SYS@lunardb>REM   will affect plans for SQL commands with signature
SYS@lunardb>REM   matching the one for SQL Text below.
SYS@lunardb>REM   Review SQL Text and adjust accordingly.
SYS@lunardb>REM
SYS@lunardb>REM PARAMETERS
SYS@lunardb>REM   None.
SYS@lunardb>REM
SYS@lunardb>REM EXAMPLE
SYS@lunardb>REM   SQL> START coe_xfr_sql_profile_bjgduva68mbqm_3241900148.sql;
SYS@lunardb>REM
SYS@lunardb>REM NOTES
SYS@lunardb>REM   1. Should be run as SYSTEM or SYSDBA.
SYS@lunardb>REM   2. User must have CREATE ANY SQL PROFILE privilege.
SYS@lunardb>REM   3. SOURCE and TARGET systems can be the same or similar.
SYS@lunardb>REM   4. To drop this custom SQL Profile after it has been created:
SYS@lunardb>REM  EXEC DBMS_SQLTUNE.DROP_SQL_PROFILE('coe_bjgduva68mbqm_3241900148');
SYS@lunardb>REM   5. Be aware that using DBMS_SQLTUNE requires a license
SYS@lunardb>REM  for the Oracle Tuning Pack.
SYS@lunardb>REM   6. If you modified a SQL putting Hints in order to produce a desired
SYS@lunardb>REM  Plan, you can remove the artifical Hints from SQL Text pieces below.
SYS@lunardb>REM  By doing so you can create a custom SQL Profile for the original
SYS@lunardb>REM  SQL but with the Plan captured from the modified SQL (with Hints).
SYS@lunardb>REM
SYS@lunardb>WHENEVER SQLERROR EXIT SQL.SQLCODE;
SYS@lunardb>REM
SYS@lunardb>VAR signature NUMBER;
SYS@lunardb>VAR signaturef NUMBER;
SYS@lunardb>REM
SYS@lunardb>DECLARE
  2  sql_txt CLOB;
  3  h       SYS.SQLPROF_ATTR;
  4  PROCEDURE wa (p_line IN VARCHAR2) IS
  5  BEGIN
  6  DBMS_LOB.WRITEAPPEND(sql_txt, LENGTH(p_line), p_line);
  7  END wa;
  8  BEGIN
  9  DBMS_LOB.CREATETEMPORARY(sql_txt, TRUE);
 10  DBMS_LOB.OPEN(sql_txt, DBMS_LOB.LOB_READWRITE);
 11  -- SQL Text pieces below do not have to be of same length.
 12  -- So if you edit SQL Text (i.e. removing temporary Hints),
 13  -- there is no need to edit or re-align unmodified pieces.
 14  wa(q'[select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunar]');
 15  wa(q'[test1 where n=1]');
 16  DBMS_LOB.CLOSE(sql_txt);
 17  h := SYS.SQLPROF_ATTR(
 18  q'[BEGIN_OUTLINE_DATA]',
 19  q'[IGNORE_OPTIM_EMBEDDED_HINTS]',
 20  q'[OPTIMIZER_FEATURES_ENABLE('11.2.0.4')]',
 21  q'[DB_VERSION('11.2.0.4')]',
 22  q'[ALL_ROWS]',
 23  q'[OUTLINE_LEAF(@"SEL$1")]',
 24  q'[INDEX(@"SEL$1" "LUNARTEST1"@"SEL$1" ("LUNARTEST1"."N"))]',
 25  q'[END_OUTLINE_DATA]');
 26  :signature := DBMS_SQLTUNE.SQLTEXT_TO_SIGNATURE(sql_txt);
 27  :signaturef := DBMS_SQLTUNE.SQLTEXT_TO_SIGNATURE(sql_txt, TRUE);
 28  DBMS_SQLTUNE.IMPORT_SQL_PROFILE (
 29  sql_text    => sql_txt,
 30  profile     => h,
 31  name        => 'coe_bjgduva68mbqm_3241900148',
 32  description => 'coe bjgduva68mbqm 3241900148 '||:signature||' '||:signaturef||'',
 33  category    => 'DEFAULT',
 34  validate    => TRUE,
 35  replace     => TRUE,
 36  force_match => FALSE /* TRUE:FORCE (match even when different literals in SQL). FALSE:EXACT (similar to CURSOR_SHARING) */ );
 37  DBMS_LOB.FREETEMPORARY(sql_txt);
 38  END;
 39  /

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.11
SYS@lunardb>WHENEVER SQLERROR CONTINUE
SYS@lunardb>SET ECHO OFF;

            SIGNATURE
---------------------
   659415202199990108


           SIGNATUREF
---------------------
  9900816299026594015


... manual custom SQL Profile has been created


COE_XFR_SQL_PROFILE_bjgduva68mbqm_3241900148 completed
SYS@lunardb>
SYS@lunardb>select * from dba_sql_profiles;

NAME                           CATEGORY                              SIGNATURE SQL_TEXT
------------------------------ ------------------------------ ---------------- --------------------------------------------------------------------------------
CREATED                                                                     LAST_MODIFIED
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
DESCRIPTION
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
TYPE    STATUS   FOR          TASK_ID TASK_EXEC_NAME                      TASK_OBJ_ID      TASK_FND_ID      TASK_REC_ID
------- -------- --- ---------------- ------------------------------ ---------------- ---------------- ----------------
coe_bjgduva68mbqm_3241900148   DEFAULT                        6.5941520220E+17 select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1
12-JAN-16 11.24.18.000000 AM                                                12-JAN-16 11.40.52.000000 AM
coe bjgduva68mbqm 3241900148 659415202199990108 9900816299026594015
MANUAL  ENABLED  NO


Elapsed: 00:00:00.00
SYS@lunardb>

再次执行查询:

LUNAR@lunardb>select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1;

Elapsed: 00:00:00.01

Execution Plan
----------------------------------------------------------
Plan hash value: 3241900148

-------------------------------------------------------------------------------------
| Id  | Operation        | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |                  |     1 |     4 |     1   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| IDX_LUNARTEST1_N |     1 |     4 |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------

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

   1 - access("N"=1)

Note
-----
   - SQL profile "coe_bjgduva68mbqm_3241900148" used for this statement


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          3  consistent gets
          0  physical reads
          0  redo size
        519  bytes sent via SQL*Net to client
        524  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

LUNAR@lunardb>

这里我们看到该SQL还是忽略了hint而使用了索引。
结论:
1,使用SYS用户绑定执行计划不会影响其他用户使用该SQL Profile及执行效果
2,这里已经使用了我们的SQL PROFILE(coe_bjgduva68mbqm_3241900148),sql使用了索引,说明coe_xfr_sql_profile绑定执行计划的方式比hint的优先级高

发表在 Performence Tuning | 标签为 | 留下评论

固定执行计划-手工指定索引名称的方式

测试目的:手工指定索引的方式绑定的执行计划和hint中指定no index,谁的优先级高?
.
固定执行计划-使用SQL Tuning Advisor
固定执行计划-手工指定PLAN OUTLINE
固定执行计划-手工指定索引名称的方式
固定执行计划-使用coe_xfr_sql_profile固定执行计划
固定执行计划-使用SPM(Sql Plan Management)固定执行计划
.
由于上一个测试中,已经绑定了SQL Profile。
这里我们需要先删除该SQL Profile,再手工指定索引的方式绑定执行计划试试看。
确认下SQL PROFILE的内容:

LUNAR@lunardb>select * from dba_sql_profiles;

NAME                           CATEGORY                              SIGNATURE
------------------------------ ------------------------------ ----------------
SQL_TEXT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CREATED                                                                     LAST_MODIFIED
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
DESCRIPTION
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
TYPE    STATUS   FOR          TASK_ID TASK_EXEC_NAME                      TASK_OBJ_ID      TASK_FND_ID      TASK_REC_ID
------- -------- --- ---------------- ------------------------------ ---------------- ---------------- ----------------
Lunar_Manaual_sqlprofile       DEFAULT                        9.9008162990E+18
select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1
12-JAN-16 10.44.30.000000 AM                                                12-JAN-16 10.44.30.000000 AM

MANUAL  ENABLED  YES

Elapsed: 00:00:00.01
LUNAR@lunardb>

删除这个sql profile

LUNAR@lunardb>exec dbms_sqltune.drop_sql_profile('Lunar_Manaual_sqlprofile');  

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.04
LUNAR@lunardb>select * from dba_sql_profiles;

no rows selected

Elapsed: 00:00:00.00
LUNAR@lunardb>

通过sqlprof_attr来实现手工指定索引的方式绑定执行计划,执行计划起名为“Lunar_bjgduva68mbqm_profile”:

LUNAR@lunardb>declare  
  2    v_hints sys.sqlprof_attr;  
  3  begin  
  4    v_hints:=sys.sqlprof_attr('INDEX(IDX_LUNARTEST1_N)');  
  5    dbms_sqltune.import_sql_profile('select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1',  
  6                v_hints,'Lunar_bjgduva68mbqm_profile',force_match=>true);  
  7  end;  
  8  / 

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.01
LUNAR@lunardb>
LUNAR@lunardb>select * from dba_sql_profiles;

NAME                           CATEGORY                              SIGNATURE
------------------------------ ------------------------------ ----------------
SQL_TEXT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CREATED                                                                     LAST_MODIFIED
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
DESCRIPTION
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
TYPE    STATUS   FOR          TASK_ID TASK_EXEC_NAME                      TASK_OBJ_ID      TASK_FND_ID      TASK_REC_ID
------- -------- --- ---------------- ------------------------------ ---------------- ---------------- ----------------
Lunar_bjgduva68mbqm_profile    DEFAULT                        9.9008162990E+18
select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1
12-JAN-16 10.53.46.000000 AM                                                12-JAN-16 10.53.46.000000 AM

MANUAL  ENABLED  YES


Elapsed: 00:00:00.00
LUNAR@lunardb>

查看这个Lunar_bjgduva68mbqm_profile的一些参数,确认是我们指定的索引:

LUNAR@lunardb>SELECT extractValue(value(h),'.') AS hint
  2  FROM sys.sqlobj$data od, sys.sqlobj$ so,
  3  table(xmlsequence(extract(xmltype(od.comp_data),'/outline_data/hint'))) h
  4  WHERE so.name = 'Lunar_bjgduva68mbqm_profile'
  5  AND so.signature = od.signature
  6  AND so.category = od.category
  7  AND so.obj_type = od.obj_type
  8  AND so.plan_id = od.plan_id;

HINT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
INDEX(IDX_LUNARTEST1_N)

Elapsed: 00:00:00.02
LUNAR@lunardb>

再次执行SQL,看看这个Lunar_bjgduva68mbqm_profile是否生效:

LUNAR@lunardb>select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1;

Elapsed: 00:00:00.00

Execution Plan
----------------------------------------------------------
Plan hash value: 1172089107

--------------------------------------------------------------------------------
| Id  | Operation         | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |            |     1 |     4 |     7   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| LUNARTEST1 |     1 |     4 |     7   (0)| 00:00:01 |
--------------------------------------------------------------------------------

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

   1 - filter("N"=1)

Note
-----
   - SQL profile "Lunar_bjgduva68mbqm_profile" used for this statement


Statistics
----------------------------------------------------------
          7  recursive calls
          0  db block gets
         28  consistent gets
          1  physical reads
          0  redo size
        519  bytes sent via SQL*Net to client
        524  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

LUNAR@lunardb>

结论:
这里看到已经使用了Lunar_bjgduva68mbqm_profile,但是SQL并没有按照Lunar_bjgduva68mbqm_profile中指定的索引名称使用索引。
这里已经使用了我们的SQL PROFILE,但是仍然走全表扫描
说明hint覆盖了手工指定索引的方式绑定的执行计划,说明手工指定索引名称的方式比hint的优先级低。

发表在 Performence Tuning | 标签为 | 留下评论

固定执行计划-手工指定PLAN OUTLINE

测试目的: hint和手工指定OUTLINE参数的方式来帮顶执行计划,谁的优先级高?
.
固定执行计划-使用SQL Tuning Advisor
固定执行计划-手工指定PLAN OUTLINE
固定执行计划-手工指定索引名称的方式
固定执行计划-使用coe_xfr_sql_profile固定执行计划
固定执行计划-使用SPM(Sql Plan Management)固定执行计划
.
由于上一个测试中,已经绑定了sql使用SQL Tuning Advisor中的执行计划,从而使SQL走索引了(覆盖了hint)。这里我们需要先删除该SQL Profile,再手工绑定试试。
确认下SQL PROFILE的内容:

LUNAR@lunardb>SELECT * FROM DBA_SQL_PROFILES;

NAME                           CATEGORY                              SIGNATURE
------------------------------ ------------------------------ ----------------
SQL_TEXT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CREATED                                                                     LAST_MODIFIED
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
DESCRIPTION
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
TYPE    STATUS   FOR          TASK_ID TASK_EXEC_NAME                      TASK_OBJ_ID      TASK_FND_ID      TASK_REC_ID
------- -------- --- ---------------- ------------------------------ ---------------- ---------------- ----------------
SYS_SQLPROF_015236655fb80000   DEFAULT                        6.5941520220E+17
select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1
12-JAN-16 10.12.39.000000 AM                                                12-JAN-16 10.12.39.000000 AM

MANUAL  ENABLED  NO               158 EXEC_146                                      1                1                1


Elapsed: 00:00:00.02
LUNAR@lunardb>
LUNAR@lunardb>SELECT extractValue(value(h),'.') AS hint
  2  FROM sys.sqlobj$data od, sys.sqlobj$ so,
  3  table(xmlsequence(extract(xmltype(od.comp_data),'/outline_data/hint'))) h
  4  WHERE so.name = 'SYS_SQLPROF_015236655fb80000'
  5  AND so.signature = od.signature
  6  AND so.category = od.category
  7  AND so.obj_type = od.obj_type
  8  AND so.plan_id = od.plan_id;

HINT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
COLUMN_STATS("LUNAR"."LUNARTEST1", "N", scale, length=3 distinct=10000 nulls=0 min=1 max=10000)
TABLE_STATS("LUNAR"."LUNARTEST1", scale, blocks=20 rows=10000)
OPTIMIZER_FEATURES_ENABLE(default)
IGNORE_OPTIM_EMBEDDED_HINTS

Elapsed: 00:00:00.05
LUNAR@lunardb>

这里我们看到该SQP Profile中提供了详细的表和列的统计信息
并且有“IGNORE_OPTIM_EMBEDDED_HINTS”,也就是忽略嵌入到SQL中的hint
确认一下,当前SQL语句使用了该SQL Profile:

LUNAR@lunardb>select * from table(dbms_xplan.display_cursor('bjgduva68mbqm',null,'outline'));

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  bjgduva68mbqm, child number 0
-------------------------------------
select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1
where n=1

Plan hash value: 3241900148

-------------------------------------------------------------------------------------
| Id  | Operation        | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |                  |       |       |     1 (100)|          |
|*  1 |  INDEX RANGE SCAN| IDX_LUNARTEST1_N |     1 |     3 |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------

Outline Data
-------------

  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('11.2.0.4')
      DB_VERSION('11.2.0.4')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$1")
      INDEX(@"SEL$1" "LUNARTEST1"@"SEL$1" ("LUNARTEST1"."N"))
      END_OUTLINE_DATA
  */

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

   1 - access("N"=1)

Note
-----
   - SQL profile SYS_SQLPROF_015236655fb80000 used for this statement


37 rows selected.

Elapsed: 00:00:00.23
LUNAR@lunardb>

这里我们看到,当前执行确实使用了SQL profile SYS_SQLPROF_015236655fb80000,因此hint no_index失效了
(优先级低于SYS_SQLPROF_015236655fb80000,具体参见固定执行计划-使用SQL Tuning Advisor
查看SYS_SQLPROF_015236655fb80000的OUTLINE信息:

LUNAR@lunardb>select '''' || extractvalue(value(d), '/hint') || ''',' as outline_hints
  2  from xmltable('/*/outline_data/hint' passing (
  3                                     select xmltype(other_xml) as xmlval
  4                                     from v$sql_plan 
  5                                     where sql_id = 'bjgduva68mbqm' and plan_hash_value = '3241900148' and other_xml is not null
  6                                     )
  7             ) d;

OUTLINE_HINTS
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
'IGNORE_OPTIM_EMBEDDED_HINTS',
'OPTIMIZER_FEATURES_ENABLE('11.2.0.4')',
'DB_VERSION('11.2.0.4')',
'ALL_ROWS',
'OUTLINE_LEAF(@"SEL$1")',
'INDEX(@"SEL$1" "LUNARTEST1"@"SEL$1" ("LUNARTEST1"."N"))',

6 rows selected.

Elapsed: 00:00:00.06
LUNAR@lunardb>

这里我们看到该SQP Profile中提供了详细的表和列的统计信息
并且有“IGNORE_OPTIM_EMBEDDED_HINTS”,也就是忽略嵌入到SQL中的hint
现在,我们删除这个SQL Profile,稍后使用上面的OUTLINE手工绑定执行计划:

LUNAR@lunardb>begin
  2     DBMS_SQLTUNE.DROP_SQL_PROFILE(name => 'SYS_SQLPROF_015236655fb80000');
  3  end;
  4  /

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.02
LUNAR@lunardb>SELECT * FROM DBA_SQL_PROFILES;

no rows selected

Elapsed: 00:00:00.00
LUNAR@lunardb>

此时,应该正常按照hint走了全表扫描:

LUNAR@lunardb>set autotrace traceonly exp stat
LUNAR@lunardb>select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1;

Elapsed: 00:00:00.03

Execution Plan
----------------------------------------------------------
Plan hash value: 1172089107

--------------------------------------------------------------------------------
| Id  | Operation         | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |            |     1 |     4 |     7   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| LUNARTEST1 |     1 |     4 |     7   (0)| 00:00:01 |
--------------------------------------------------------------------------------

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

   1 - filter("N"=1)


Statistics
----------------------------------------------------------
        114  recursive calls
          0  db block gets
        137  consistent gets
          0  physical reads
          0  redo size
        519  bytes sent via SQL*Net to client
        524  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
         15  sorts (memory)
          0  sorts (disk)
          1  rows processed

LUNAR@lunardb>

手工指定sqlprofile参数的方式绑定执行计划:

LUNAR@lunardb>declare
  2     v_hints sys.sqlprof_attr;
  3     sql_txt clob;
  4  begin 
  5     v_hints:=sys.sqlprof_attr(
  6           'BEGIN_OUTLINE_DATA',
  7           'IGNORE_OPTIM_EMBEDDED_HINTS',
  8           'OPTIMIZER_FEATURES_ENABLE(''11.2.0.4'')',
  9           'DB_VERSION(''11.2.0.4'')',
 10           'ALL_ROWS',
 11           'OUTLINE_LEAF(@"SEL$1")',
 12           'INDEX(@"SEL$1" "LUNARTEST1"@"SEL$1" ("LUNARTEST1"."N"))',
 13           'END_OUTLINE_DATA'
 14     );
 15  
 16     select sql_fulltext into sql_txt from v$sql where sql_id='&sqlid';
 17     dbms_sqltune.import_sql_profile(sql_text => sql_txt,
 18             profile => v_hints,name => 'Lunar_Manaual_sqlprofile',
 19             replace => TRUE,force_match => TRUE);
 20  end;
 21  /
Enter value for sqlid: bjgduva68mbqm
old  16:        select sql_fulltext into sql_txt from v$sql where sql_id='&sqlid';
new  16:        select sql_fulltext into sql_txt from v$sql where sql_id='bjgduva68mbqm';

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.53
LUNAR@lunardb>
LUNAR@lunardb>SELECT * FROM DBA_SQL_PROFILES;

NAME                           CATEGORY                              SIGNATURE
------------------------------ ------------------------------ ----------------
SQL_TEXT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CREATED                                                                     LAST_MODIFIED
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
DESCRIPTION
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
TYPE    STATUS   FOR          TASK_ID TASK_EXEC_NAME                      TASK_OBJ_ID      TASK_FND_ID      TASK_REC_ID
------- -------- --- ---------------- ------------------------------ ---------------- ---------------- ----------------
Lunar_Manaual_sqlprofile       DEFAULT                        9.9008162990E+18
select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1
12-JAN-16 10.44.30.000000 AM                                                12-JAN-16 10.44.30.000000 AM

MANUAL  ENABLED  YES


Elapsed: 00:00:00.02
LUNAR@lunardb>

再次查询,看看Lunar_Manaual_sqlprofile是否生效:

LUNAR@lunardb>select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1;

Elapsed: 00:00:00.02

Execution Plan
----------------------------------------------------------
Plan hash value: 3241900148

-------------------------------------------------------------------------------------
| Id  | Operation        | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |                  |     1 |     4 |     1   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| IDX_LUNARTEST1_N |     1 |     4 |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------

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

   1 - access("N"=1)

Note
-----
   - SQL profile "Lunar_Manaual_sqlprofile" used for this statement


Statistics
----------------------------------------------------------
         34  recursive calls
          0  db block gets
         13  consistent gets
          1  physical reads
          0  redo size
        519  bytes sent via SQL*Net to client
        524  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          1  rows processed

LUNAR@lunardb>

这里我们看到Lunar_Manaual_sqlprofile已经生效,且sql语句虽然带有no_index的hint,但是仍然可以按照SQL Profile指定的大纲使用索引
总结:
这里虽然有hint指定了no index,但是sql语句仍然按照Lunar_Manaual_sqlprofile指定的profile使用了index的
说明,使用手工指定outline参数的方式绑定的执行计划优先级高于hint

发表在 Performence Tuning | 标签为 | 留下评论

固定执行计划-使用SQL Tuning Advisor

测试目的,当有hint时,并且hint跟需要绑定的执行计划有冲突,谁的优先级高。
.
固定执行计划-使用SQL Tuning Advisor
固定执行计划-手工指定PLAN OUTLINE
固定执行计划-手工指定索引名称的方式
固定执行计划-使用coe_xfr_sql_profile固定执行计划
固定执行计划-使用SPM(Sql Plan Management)固定执行计划
.
这里是第一个测试,使用SQL Tuning Advisor来测试:
创建测试用例:

LUNAR@lunardb>create table lunartest1 (n number );

Table created.

Elapsed: 00:00:00.08
LUNAR@lunardb>begin
  2         for i in 1 .. 10000 loop
  3             insert into lunartest1 values(i);
  4             commit;
  5         end loop;
  6        end;
  7  /

PL/SQL procedure successfully completed.

Elapsed: 00:00:02.05
LUNAR@lunardb>create index idx_lunartest1_n on lunartest1(n);

Index created.

Elapsed: 00:00:00.04

执行查询,我们看到sql按照hint的方式没有使用索引,而是全表扫描,这是我们预期的结果:

LUNAR@lunardb>set autotrace on
LUNAR@lunardb>select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1;

               N
----------------
               1

Elapsed: 00:00:00.00

Execution Plan
----------------------------------------------------------
Plan hash value: 1172089107

--------------------------------------------------------------------------------
| Id  | Operation         | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |            |     1 |    13 |     7   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| LUNARTEST1 |     1 |    13 |     7   (0)| 00:00:01 |
--------------------------------------------------------------------------------

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

   1 - filter("N"=1)

Note
-----
   - dynamic sampling used for this statement (level=2)


Statistics
----------------------------------------------------------
          5  recursive calls
          0  db block gets
         49  consistent gets
          0  physical reads
          0  redo size
        519  bytes sent via SQL*Net to client
        524  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

LUNAR@lunardb>

下面我们运行SQL Tuning Advisor来生成建议报告:

LUNAR@lunardb>DECLARE
  2   my_task_name VARCHAR2(50);
  3  BEGIN
  4    my_task_name := DBMS_SQLTUNE.CREATE_TUNING_TASK(
  5           SQL_ID      => 'bjgduva68mbqm',
  6           scope       => 'COMPREHENSIVE',
  7           time_limit  => 60,
  8           task_name   => 'Lunar_tunning_bjgduva68mbqm', 
  9           description => 'Task to tune a query on bjgduva68mbqm by Lunar');
 10    dbms_sqltune.execute_tuning_task(my_task_name);  
 11    dbms_output.put_line(my_task_name);  
 12  END;
 13  / 
Lunar_tunning_bjgduva68mbqm

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.20
LUNAR@lunardb>

查看生成的报告内容:

LUNAR@lunardb>SELECT dbms_sqltune.report_tuning_task('&task_name') FROM dual;  
Enter value for task_name: Lunar_tunning_bjgduva68mbqm
old   1: SELECT dbms_sqltune.report_tuning_task('&task_name') FROM dual
new   1: SELECT dbms_sqltune.report_tuning_task('Lunar_tunning_bjgduva68mbqm') FROM dual

DBMS_SQLTUNE.REPORT_TUNING_TASK('LUNAR_TUNNING_BJGDUVA68MBQM')
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
GENERAL INFORMATION SECTION
-------------------------------------------------------------------------------
Tuning Task Name   : Lunar_tunning_bjgduva68mbqm
Tuning Task Owner  : LUNAR
Workload Type      : Single SQL Statement
Scope              : COMPREHENSIVE
Time Limit(seconds): 60
Completion Status  : COMPLETED
Started at         : 01/12/2016 10:09:54
Completed at       : 01/12/2016 10:09:54

-------------------------------------------------------------------------------
Schema Name: LUNAR
SQL ID     : bjgduva68mbqm
SQL Text   : select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from
             lunartest1 where n=1

-------------------------------------------------------------------------------
FINDINGS SECTION (2 findings)
-------------------------------------------------------------------------------

1- Statistics Finding
---------------------
  Table "LUNAR"."LUNARTEST1" was not analyzed.

  Recommendation
  --------------
  - Consider collecting optimizer statistics for this table.
    execute dbms_stats.gather_table_stats(ownname => 'LUNAR', tabname =>
            'LUNARTEST1', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
            method_opt => 'FOR ALL COLUMNS SIZE AUTO');

  Rationale
  ---------
    The optimizer requires up-to-date statistics for the table in order to
    select a good execution plan.

2- SQL Profile Finding (see explain plans section below)
--------------------------------------------------------
  A potentially better execution plan was found for this statement.

  Recommendation (estimated benefit: 91.31%)
  ------------------------------------------
  - Consider accepting the recommended SQL profile.
    execute dbms_sqltune.accept_sql_profile(task_name =>
            'Lunar_tunning_bjgduva68mbqm', task_owner => 'LUNAR', replace =>
            TRUE);

  Validation results
  ------------------
  The SQL profile was tested by executing both its plan and the original plan
  and measuring their respective execution statistics. A plan may have been
  only partially executed if the other could be run to completion in less time.

                           Original Plan  With SQL Profile  % Improved
                           -------------  ----------------  ----------
  Completion Status:            COMPLETE          COMPLETE
  Elapsed Time (s):             .000196            .00002      89.79 %
  CPU Time (s):                   .0002                 0        100 %
  User I/O Time (s):                  0                 0
  Buffer Gets:                       23                 2       91.3 %
  Physical Read Requests:             0                 0
  Physical Write Requests:            0                 0
  Physical Read Bytes:                0                 0
  Physical Write Bytes:               0                 0
  Rows Processed:                     1                 1
  Fetches:                            1                 1
  Executions:                         1                 1

  Notes
  -----
  1. Statistics for the original plan were averaged over 10 executions.
  2. Statistics for the SQL profile plan were averaged over 10 executions.

-------------------------------------------------------------------------------
EXPLAIN PLANS SECTION
-------------------------------------------------------------------------------

1- Original With Adjusted Cost
------------------------------
Plan hash value: 1172089107

--------------------------------------------------------------------------------
| Id  | Operation         | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |            |     1 |     3 |     7   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| LUNARTEST1 |     1 |     3 |     7   (0)| 00:00:01 |
--------------------------------------------------------------------------------

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

   1 - filter("N"=1)

2- Using SQL Profile
--------------------
Plan hash value: 3241900148

-------------------------------------------------------------------------------------
| Id  | Operation        | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |                  |     1 |     3 |     1   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| IDX_LUNARTEST1_N |     1 |     3 |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------

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

   1 - access("N"=1)

-------------------------------------------------------------------------------


Elapsed: 00:00:00.06
LUNAR@lunardb>

这里我们看到SQL Tuning Advisor提示了两个建议:
1,收集统计信息:

    execute dbms_stats.gather_table_stats(ownname => 'LUNAR', tabname =>
            'LUNARTEST1', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
            method_opt => 'FOR ALL COLUMNS SIZE AUTO');
1
.
2,提供了一个执行计划建议:
1
    execute dbms_sqltune.accept_sql_profile(task_name =>
            'Lunar_tunning_bjgduva68mbqm', task_owner => 'LUNAR', replace =>
            TRUE);

并且给出了这个执行计划和原始执行计划的对比,可以看到 执行效率提高了89%以上,逻辑读从23降低为2,减少了91.3%。
.
下面我们按照建议执行。
首先收集统计信息:

LUNAR@lunardb>execute dbms_stats.gather_table_stats(ownname => 'LUNAR', tabname =>'LUNARTEST1', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt => 'FOR ALL COLUMNS SIZE AUTO');

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.12
LUNAR@lunardb>

然后我们接受建议中的执行计划:

LUNAR@lunardb>execute dbms_sqltune.accept_sql_profile(task_name => 'Lunar_tunning_bjgduva68mbqm', task_owner => 'LUNAR', replace =>TRUE);

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.33
LUNAR@lunardb>

现在,再次查询看看效果:

LUNAR@lunardb>select /*+ no_index(lunartest1 idx_lunartest1_n) */ * from lunartest1 where n=1;

Elapsed: 00:00:00.08

Execution Plan
----------------------------------------------------------
Plan hash value: 3241900148

-------------------------------------------------------------------------------------
| Id  | Operation        | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |                  |     1 |     3 |     1   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| IDX_LUNARTEST1_N |     1 |     3 |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------

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

   1 - access("N"=1)

Note
-----
   - SQL profile "SYS_SQLPROF_015236655fb80000" used for this statement


Statistics
----------------------------------------------------------
         37  recursive calls
          0  db block gets
         14  consistent gets
          1  physical reads
          0  redo size
        519  bytes sent via SQL*Net to client
        524  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          1  rows processed

这里我们看到,这个执行计划中已经使用了索引,并且逻辑读从49降低为14,
但是这里还有物理读,因此,我们再次执行看看:

LUNAR@lunardb>/

Elapsed: 00:00:00.01

Execution Plan
----------------------------------------------------------
Plan hash value: 3241900148

-------------------------------------------------------------------------------------
| Id  | Operation        | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |                  |     1 |     3 |     1   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| IDX_LUNARTEST1_N |     1 |     3 |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------

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

   1 - access("N"=1)

Note
-----
   - SQL profile "SYS_SQLPROF_015236655fb80000" used for this statement


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          3  consistent gets
          0  physical reads
          0  redo size
        519  bytes sent via SQL*Net to client
        524  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

LUNAR@lunardb>

逻辑读从14降低为3,这个执行计划已经是我们需要的。
现在我们查看一下这个SQL Profile的OUTLINE:

LUNAR@lunardb>SELECT extractValue(value(h),'.') AS hint
  2  FROM sys.sqlobj$data od, sys.sqlobj$ so,
  3  table(xmlsequence(extract(xmltype(od.comp_data),'/outline_data/hint'))) h
  4  WHERE so.name = 'SYS_SQLPROF_015236655fb80000'
  5  AND so.signature = od.signature
  6  AND so.category = od.category
  7  AND so.obj_type = od.obj_type
  8  AND so.plan_id = od.plan_id;

HINT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
COLUMN_STATS("LUNAR"."LUNARTEST1", "N", scale, length=3 distinct=10000 nulls=0 min=1 max=10000)
TABLE_STATS("LUNAR"."LUNARTEST1", scale, blocks=20 rows=10000)
OPTIMIZER_FEATURES_ENABLE(default)
IGNORE_OPTIM_EMBEDDED_HINTS

Elapsed: 00:00:00.05
LUNAR@lunardb>

这里我们看到该SQP Profile中提供了详细的表和列的统计信息
并且有“IGNORE_OPTIM_EMBEDDED_HINTS”,也就是忽略嵌入到SQL中的hint
结论:
虽然这个SQL的hint中指定了no index,即不使用索引,但是sql语句仍然按照SYS_SQLPROF_015236655fb80000指定的profile使用了index。
说明dbms_sqltune.accept_sql_profile方式绑定的执行计划优先级高于hint指定是否使用索引的方式。
不过不代表所有hint的优先级都低,还需要测试更多其他hint……

发表在 Performence Tuning | 标签为 | 留下评论

Leap Second(润秒)跟Oracle相关产品的提示

今天好多朋友都在讨论Leap Second(润秒)的问题(不少集成商和客户都收到Oracle的通告了):
Oracle官方的解释也很清晰:


1


2


Oracle所有产品线关于润秒的说明:
Information Center: Leap Second Information for All Products – Database – Exadata – Middleware – Exalogic – Linux – Sun – Fusion – EBS – JDE – Siebel – Peoplesoft (Doc ID 2019397.2)
.
MySQL也会有相应的影响,比如 NOW() 函数会返回2次的xx:59:59,具体请参考oracle官方的推荐。
.
其他:
1,Tuxedo没这个问题:

No, there is no Tuxedo issue with “Leap Second” because Tuxedo uses the UNIX epoch.
.
2,Exalytics有:
Exalytics is affected with Leap second issue till Patchset 3. Leap second Issue is fixed in kernel 2.6.32-300.29.1.
.
3,一些Oracle的带库(其他带库,使用到相关NTP功能的都应该以此类推的考虑,具体需要问各自厂商)
All other tape products not using NTP, like SL8500, SL3000, 9×40, T10K and VSM4/5 are not exposed.
The NTP protocol can be used to sync time with most tape product software, using the Solaris or Linux OS.
.
4,其他Oracle相关应用和可能的表现:
比如某个进程100% CPU,例如EM 具体参见:
Enterprise Manager Management Agent or OMS CPU Use Is Excessive near Leap Second Additions on Linux (Doc ID 1472651.1)
Leap second hang – CPU can be seen at 100% Note 1472421.1
.
5,没使用NTP 的不涉及这个问题(但是在不同环境如果不使用NTP可能有其他问题,比如exadata上,NTP不当问题可能导致cell重启)。注意受影响的NTP版本:ntp-4.2.6-*,该问题在ntp-4.2.6-p5-3.el6_6 fixed了。
还有 ntp-4.2.2/4.2.4 这两种ntp版本没有问题。

.
6,推荐的解决方法:修改/etc/sysconfig/ntpd中的下面:
OPTIONS=”-u ntp:ntp -p /var/run/ntpd.pid -x”
注意其中的 -x
这个设置实际上是Oracle自从10g后,RAC配置中的标准配置,在文档中有明确的NTP配置说明(使用-x)。
.
7,下面的Oracle RDBMS 版本fixed了oracle润秒的问题:


3


MOS的原文如下(该文是以日本 +9区为例的,中国是正8区,因此时间是明早7:59:60):

What is the "leap second"?

The "leap second" is a world wide time adjustment by inserting or deleting one whole second to keep UTC (Universal Time, Coordinated) close to the mean solar time. Such adjustment would be made at 23:59:59 on Jun 30 or at 23:59:59 on Dec 31(UTC).

Note that the clock is adjusted in UTC. Thus in Japan(UTC+9), it would be adjusted at 08:59:59 on Jul/Jan 1st.

If it is inserted, the real clock will be adjusted as follows:

23:59:57 -> 23:59:58 -> 23:59:59 -> 23:59:60 -> 00:00:00 -> 00:00:01
A leap second would be deleted by omitting second 23:59:59 on one of these days, although this has never happened:

23:59:57 -> 23:59:58 -> 00:00:00 -> 00:00:01
Note that the clock is adjusted in UTC. Thus in Japan(UTC+9), it would be adjusted at 8:59:59AM on Jul/Jan 1st.

What might be a problem with leap second?

At the time inserting/deleting a second, OS clock(ex. obtained by gettimeofday()) could show "abnormal" time, like 23:59:60. This would not be a problem for Linux kernel, as it does not refer to the OS clock, but jiffies(kernel internal counter) instead. However, many applications could not handle the "abnormal" time and it would be a cause of a hang up of the applications, or OS reboot kicked by them. Please contact your application vendor and confirm if there are any issues with leap second.

It depends on kernel, ntp configuration and OS environment what time would be returned from OS at the leap second. For example, inserting a second would bring 23:60:00 like:

Case A:

2012/06/30 23:59:59.759058705
2012/06/30 23:59:59.862213189
2012/06/30 23:59:59.965647209
2012/06/30 23:59:60.068161514 <- shows 23:59:60.### 
2012/06/30 23:59:60.175351284
2012/06/30 23:59:60.278096054
2012/06/30 23:59:60.381168210
2012/06/30 23:59:60.483526254
2012/06/30 23:59:60.591406966
2012/06/30 23:59:60.694055754
2012/06/30 23:59:60.797548683
2012/06/30 23:59:60.900835003
2012/07/01 00:00:00.005271538
2012/07/01 00:00:00.107279748
2012/07/01 00:00:00.219733676

or backward time, twice 23:59:59 like:

Case B:

2012/06/30 23:59:59.759058705
2012/06/30 23:59:59.862213189
2012/06/30 23:59:59.965647209
2012/06/30 23:59:59.068161514 <- time backward 1sec
2012/06/30 23:59:59.175351284
2012/06/30 23:59:59.278096054
2012/06/30 23:59:59.381168210
2012/06/30 23:59:59.483526254
2012/06/30 23:59:59.591406966
2012/06/30 23:59:59.694055754
2012/06/30 23:59:59.797548683
2012/06/30 23:59:59.900835003
2012/07/01 00:00:00.005271538
2012/07/01 00:00:00.107279748
2012/07/01 00:00:00.219733676

or same time for 1 sec at 23:59:59 like:

Case C:

2012/06/30 23:59:59.759058705
2012/06/30 23:59:59.862213189
2012/06/30 23:59:59.965647209
2012/06/30 23:59:59.965647209 <- same time for 1sec
2012/06/30 23:59:59.965647209
2012/06/30 23:59:59.965647209
2012/06/30 23:59:59.965647209
2012/06/30 23:59:59.965647209
2012/06/30 23:59:59.965647209
2012/06/30 23:59:59.965647209
2012/06/30 23:59:59.965647209
2012/06/30 23:59:59.965647209
2012/07/01 00:00:00.005271538
2012/07/01 00:00:00.107279748
2012/07/01 00:00:00.219733676

On the other hand, deleting a second would bring below:

Case D:

2012/06/30 23:59:58.759058705
2012/06/30 23:59:58.862213189
2012/06/30 23:59:58.965647209
2012/07/01 00:00:00.005271538 <- no 23:59:59.###
2012/07/01 00:00:00.107279748
2012/07/01 00:00:00.219733676

And, there is another Case E, where the kernel does not care about the leap second, and just continues to count up its clock independently from UTC. In this case, OS clock would drift one second, and will be adjusted by ntp if configured.

How about Linux without ntp?

If your Linux box does not refer to ntp (ntpd service does not run), the OS clock would be affected by /etc/localtime file, which is originated in /usr/share/zoneinfo/ or /usr/share/zoneinfo/right/. By default, the Linux (including Oracle Linux) installer generates /etc/localtime from /usr/share/zoneinfo/, which does not take regard any of leap seconds. Thus it would be Case E above.

If the latest "tzdata" package is installed which includes the leap second reflection date, and also /etc/localtime file was overwritten with a zoneinfo file from /usr/share/zoneinfo/right/, the OS clock would be Case A when the leap second is inserted and Case D when the leap second is deleted. However, most users do not need to consider this case, since /etc/localtime is from /usr/share/zoneinfo/ by default.

How about Linux with ntp?

At first, ntp should be started with "-x" option to avoid rapid clock adjustment, which is described in OPTIONS= line in /etc/sysconfig/ntpd file:

OPTIONS="-u ntp:ntp -p /var/run/ntpd.pid -x"

The following is in the case of "-x" option is being specified. Otherwise, OS clock could be adjusted very rapidly regardless of leap second:

If your Linux system uses ntp (the ntpd service runs), it is more complicated and version-dependent. There are several cases:

ntp >= 4.2.2p1-9(OL5U3 or later) runs
ntp < 4.2.2p1-9 runs and on physical(baremetal) server
ntp < 4.2.2p1-9 runs and on Oracle VM(Xen) Dom0, or DomU(PVM with kernel-ovs/kernel-xen)
ntp < 4.2.2p1-9 runs and on Oracle VM DomU(HVM)
The reason there are many cases depends on three conditions:

whether ntpd receives leap indicator(=01 or 10) from its parent ntp server
whether ntpd notify the leap second to kernel
how the kernel handle the leap second
"leap indicator" is a flag which is delivered from a parent ntp server, which indicates the next leap second is forthcoming. This can be confirmed by ntpq command:

# ntpq -c rv
assID=0 status=06c4 leap_none, sync_ntp, 12 events, event_peer/strat_chg,version="ntpd 4.2.2p1@1.1570-o Wed Nov 16 20:15:02 UTC 2011 (1)", processor="x86_64", system="Linux/2.6.32-300.4.1.el5uek", leap=01, stratum=5, precision=-20, rootdelay=358.828, rootdispersion=80.082, peer=35040, refid=10.137.32.190, reftime=d365b71e.438957d3  Tue, May 22 2012 15:56:30.263, poll=10, clock=d365c2f0.21f062cc  Tue, May 22 2012 16:46:56.132, state=4, offset=0.921, frequency=-63.452, jitter=0.066, noise=0.328, stability=0.010, tai=0

where leap=01 means ntpd will insert a sec, leap=10 means will delete a sec, leap=00 means do nothing, leap=11 means it has not synced yet. This is from a parent ntp server, thus you can not control whether this indicator is set or not. In the case leap=00 means "do nothing", OS clock would be Case E.

In fact, ntp >= 4.2.2p1-9 (with -x option) does not inform Linux kernel the status of leap indicator even if leap=01 or leap=10 is issued from its parent ntp server, due to the fix below:

* Thu Sep 04 2008 Miroslav Lichvar <mlichvar@redhat.com> 4.2.2p1-9.el5
- disable kernel discipline when -x option is used (#431729)

With this fix in place, Case E applies.

If ntp < 4.2.2p1-9, ntpd informs the Linux kernel of the leap status via a system call "adjtimex(tx.modes=ADJ_STATUS, tx_status = STA_INS/STA_DEL)". In this case, the result of OS clock adjustment depends on the Linux kernel.

If Linux kernel runs on a physical(baremetal) server, it handles the leap second insertion as Case B (could be backward) and deletion as Case D
If Linux kernel is kernel-ovs or kernel-xen in a PVM, it handles leap second insertion as Case C (can never be backward) and deletion as Case D
If it is not a Linux, or on HVM, it would depend on the OS
We can check whether OS receives leap=01/10 from ntpd by running ntptime. In this example output inserting a sec (in the case of leap=01):

# ntptime
ntp_gettime() returns code 0 (OK)
  time d39a117d.015a0000  Sun, Jul  1 2012  8:59:57.005, (.005280),
  maximum error 16384000 us, estimated error 16384000 us
ntp_adjtime() returns code 0 (OK)
  modes 0x0 (),
  offset 0.000 us, frequency 0.000 ppm, interval 1 s,
  maximum error 16384000 us, estimated error 16384000 us,
  status 0x10 (INS),
  time constant 2, precision 1.000 us, tolerance 512 ppm,


发表在 Database | 标签为 , | 留下评论

使用DUL和ODU抽取Exadata上的oracle数据库(抽取磁盘上的数据文件)

之前研究过dul和odu,发现不能识别磁盘,当时犯了一个错误,因为普通环境(非exadata环境),都是在主机上运行扫描磁盘的工作,因此我之前也在exadata的主机上扫描磁盘,发现不行,具体参见:
在Exadata上,为什么 DUL 和 ODU不能读取ASM数据库的数据,但是Kfed却可以?
今天在exadata的存储节点(cell节点)上配置了一下,发现dul和odu都可以直接扫描磁盘,以后有exadata上oracle数据库损坏时,请联系我,O(∩_∩)O哈哈
具体测试如下:

[root@dm01cel01 lunar]# ./dul

Data UnLoader: 10.2.0.6.5 - Internal Only - on Tue Jun 23 20:30:37 2015
with 64-bit io functions

Copyright (c) 1994 2015 Bernard van Duijnen All rights reserved.

 Strictly Oracle Internal Use Only


DUL: Warning: Could not open parameter file <init.dul>
DUL: Warning: Compatible is set to 10 Values can be 6|7|8|9|10
DUL: Warning: no parameter file means no logfile

DUL: Warning: block 0 is not a disk header block
DUL: Warning: ASM Block type 32 not handled yet
...................
DUL>扫描磁盘

............
DUL: Error: INCSEQ mismatch[8388877!=427426078]
DUL: Error: While processing unknown file unknown block
offset 33605120 possible block of size 512
DUL: Error: INCSEQ mismatch[8388892!=23134477]
DUL: Error: While processing unknown file unknown block
DUL: Error: block trailer mismatch found 0X0080011C expect 0X0A611C80
DUL: Error: checksum should be unused: 0x0a64
DUL: Error: While processing unknown file unknown block
DUL: Error: block trailer mismatch found 0X0080011B expect 0X02540C80

............

DUL: Error: block trailer mismatch found 0X00800888 expect 0X021B0D80
DUL: Error: checksum should be unused: 0x0229
DUL: Error: While processing unknown file unknown block
DUL: Error: INCSEQ mismatch[8390800!=961087622]
DUL: Error: While processing unknown file unknown block
Found file   2 block 88576 type 32 offs 46137344 delta 69398953984
extent of 512 blocks
Found file   1 block 102400 type 6 offs 50331648 delta 35148267520
extent of 473 blocks
Found file   2 block 98816 type 32 offs 54525952 delta 69474451456
extent of 512 blocks
Found file   2 block 107008 type 32 offs 58720256 delta 69537366016
extent of 512 blocks
Found file   2 block 111104 type 32 offs 62914560 delta 69566726144
extent of 512 blocks
Found file   2 block 125440 type 32 offs 67108864 delta 69679972352
extent of 512 blocks
Found file 352 block  7168 type 6 offs 71303168 delta 12094615322624
extent of 512 blocks
Found file 352 block 25600 type 6 offs 75497472 delta 12094762123264
extent of 512 blocks
Found file 352 block 44032 type 32 offs 79691776 delta 12094908923904
extent of 512 blocks
Found file 352 block 46592 type 6 offs 83886080 delta 12094925701120
extent of 512 blocks
Found file 352 block 58880 type 6 offs 88080384 delta 12095022170112
extent of 512 blocks
Found file 352 block 62464 type 32 offs 92274688 delta 12095047335936
extent of 512 blocks
Found file 352 block 66048 type 6 offs 96468992 delta 12095072501760
extent of 512 blocks
Found file 352 block 78848 type 32 offs 100663296 delta 12095173165056
extent of 512 blocks
Found file 352 block 80896 type 6 offs 104857600 delta 12095185747968
extent of 512 blocks
Found file 352 block 87552 type 6 offs 109051904 delta 12095236079616
extent of 512 blocks
Found file 352 block 89600 type 6 offs 113246208 delta 12095248662528
extent of 512 blocks
Found file 352 block 98304 type 6 offs 117440512 delta 12095315771392
extent of 512 blocks
Found file 352 block 99328 type 6 offs 121634816 delta 12095319965696

Found file 381 block 2410496 type 6 offs 54836330496 delta 13055970770944
extent of 512 blocks
Found file 381 block 2422272 type 32 offs 54840524800 delta 13056063045632
^C
[root@dm01cel01 lunar]# 

这里我使用control+C终止了,因为磁盘太大了,扫描时间太久,上面的信息已经可以证明,至少可以扫描
至于normal external等其他问题,以后再说。

扫描文件具体如下:

[root@dm01cel01 lunar]# ll
total 3172
-rw-r--r-- 1 root      root      71 Jun 23 20:30 control.dul
-rwxrwxr-x 1 celladmin 1000 1101896 May  5 00:14 dul
-rw-r--r-- 1 root      root  487424 Jun 23 20:36 IDX_DATA1.dat
[root@dm01cel01 lunar]# head IDX_DATA1.dat
D /dev/sdc
B 46137344 8477184 1 6687
T 46145536 8477185 7 6687
T 46202880 8477192 8 6643
T 46268416 8477200 8 6649
T 46333952 8477208 8 6651
T 46399488 8477216 8 6657
T 46465024 8477224 8 6653
T 46530560 8477232 8 6655
T 46596096 8477240 8 6687
[root@dm01cel01 lunar]#

这里 IDX_DATA1.dat 就是dul扫描出来的一些信息,之后使用命令抽成文件就依据这些。

再看看ODU:

[root@dm01cel01 odu]# ./odu

Oracle Data Unloader trial version 4.1.3

Copyright (c) 2008,2009,2010,2011 XiongJun. All rights reserved.

Web: http://www.oracleodu.com
Email: magic007cn@gmail.com

loading default config.......

byte_order little
block_size  8192
block_buffers 1024
error at line 3.
db_timezone -7
Invalid db timezone:-7
client_timezone 8
Invalid client timezone:8
asmfile_extract_path   /tmp/lunar
.......

scan disk start: 2015-06-23 21:19:25
scanning disk...
writing file error No space left on device
writing file error No space left on device
writing file error No space left on device
writing file error No space left on device
writing file error No space left on device
writing file error No space left on device
writing file error No space left on device
writing file error No space left on device
writing file error No space left on device
writing file error No space left on device
writing file error No space left on device

..........

writing file error No space left on device
writing file error No space left on device

这里报错是因为cell上磁盘空间很小,稍微一折腾就满了(存放ODU抽取文件的是根,100%了):

[root@dm01cel01 odu]# ll
total 18280
-rw-r--r-- 1 root root        16109568 Jun 23 21:20 asmblocks.odu
-rwxrwxrwx 1 root root             353 Jun 23 21:15 asmdisk.txt
-rwxrwxrwx 1 root root             560 Jun 23 21:10 config.txt
-rwxrwxrwx 1 root root             118 Mar 22  2011 control.txt
drwxr-xr-x 2  501 cellmonitor     4096 May 15  2009 data
-rwxrwxrwx 1 root root         2588361 Feb  2  2012 odu
-rw-r--r-- 1 root root               0 Jun 23 20:45 odu_trace.txt
[root@dm01cel01 odu]# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/md5        9.9G  9.9G     0 100% /
tmpfs            48G  4.0K   48G   1% /dev/shm
/dev/md7        3.0G  1.7G  1.2G  58% /opt/oracle
/dev/md4        114M   25M   84M  23% /boot
/dev/md11       5.0G  199M  4.5G   5% /var/log/oracle
[root@dm01cel01 odu]#

先别急删除,进去看看数据;

[root@dm01cel01 odu]# cd data
/tmp/lunar/odu/data
[root@dm01cel01 data]# ll
total 0
[root@dm01cel01 data]# cd ..
[root@dm01cel01 odu]# ll
total 18280
-rw-r--r-- 1 root root        16109568 Jun 23 21:20 asmblocks.odu
-rwxrwxrwx 1 root root             353 Jun 23 21:15 asmdisk.txt
-rwxrwxrwx 1 root root             560 Jun 23 21:10 config.txt
-rwxrwxrwx 1 root root             118 Mar 22  2011 control.txt
drwxr-xr-x 2  501 cellmonitor     4096 May 15  2009 data
-rwxrwxrwx 1 root root         2588361 Feb  2  2012 odu
-rw-r--r-- 1 root root               0 Jun 23 20:45 odu_trace.txt
[root@dm01cel01 odu]# 
[root@dm01cel01 odu]# more asmblocks.odu 
########################################################################################
##  data_obj#,block_type, scn_base,scn_wrap,group_no,disk_no,au_no,au_block_no,rdba#####
#########################################################################################
105140,6,2084721470,1468,1,20,13,1,8478721
105140,6,2084721466,1468,1,20,13,2,8478722
105140,6,2084761650,1468,1,20,13,3,8478723
105140,6,2084721466,1468,1,20,13,4,8478724
105140,6,2084721466,1468,1,20,13,5,8478725
105140,6,2084721466,1468,1,20,13,6,8478726
105140,6,2084721466,1468,1,20,13,7,8478727
105052,6,2084729409,1468,1,20,13,9,8478729
105052,6,2084754575,1468,1,20,13,10,8478730
105052,6,2084729334,1468,1,20,13,11,8478731
105052,6,2084729334,1468,1,20,13,12,8478732
105052,6,2084729334,1468,1,20,13,13,8478733
105052,6,2084729409,1468,1,20,13,14,8478734
105052,6,2084739193,1468,1,20,13,15,8478735
105108,6,2084768994,1468,1,20,13,17,8478737
105108,6,2084768948,1468,1,20,13,18,8478738
105108,6,2084729462,1468,1,20,13,19,8478739
105108,6,2084753947,1468,1,20,13,20,8478740
105108,6,2084738498,1468,1,20,13,21,8478741
105108,6,2084760977,1468,1,20,13,22,8478742
105108,6,2084760977,1468,1,20,13,23,8478743
105096,6,2084746973,1468,1,20,13,25,8478745
105096,6,2084728789,1468,1,20,13,26,8478746
105096,6,2084738658,1468,1,20,13,27,8478747
105096,6,2084728789,1468,1,20,13,28,8478748
105096,6,2084746205,1468,1,20,13,29,8478749
105096,6,2084746264,1468,1,20,13,30,8478750
105096,6,2084761170,1468,1,20,13,31,8478751
105048,6,2084738715,1468,1,20,13,33,8478753
105048,6,2084761180,1468,1,20,13,34,8478754
105048,6,2084761188,1468,1,20,13,35,8478755
105048,6,2084738679,1468,1,20,13,36,8478756
105048,6,2084754128,1468,1,20,13,37,8478757
105048,6,2084738715,1468,1,20,13,38,8478758
105048,6,2084738715,1468,1,20,13,39,8478759
6580,6,2084212809,1468,1,20,13,40,8478760
6580,6,2084649441,1468,1,20,13,41,8478761
[root@dm01cel01 odu]#
。。。
[root@dm01cel01 odu]# cd ..
[root@dm01cel01 lunar]# ll
total 2743224
-rw-r--r-- 1 root      root        847249408 Jun 23 21:19 1.dbf
-rw-r--r-- 1 root      root        901775360 Jun 23 21:19 2.dbf
-rw-r--r-- 1 root      root      33260830720 Jun 23 21:19 352.dbf
-rw-r--r-- 1 root      root      19101519872 Jun 23 21:20 353.dbf
-rw-r--r-- 1 root      root               71 Jun 23 20:30 control.dul
-rwxrwxr-x 1 celladmin      1000     1101896 May  5 00:14 dul
-rw-r--r-- 1 root      root           487424 Jun 23 20:36 IDX_DATA1.dat
drwxr-xr-x 3       501 cellusers        4096 Jun 23 21:15 odu
[root@dm01cel01 lunar]# 

可以看到,odu也抽出了数据, 并且,可以看到,已经抽取了几个dbf的数据文件。

发表在 ASM, backup&recovery, DUL ODU, Exadata | 标签为 , , , | 留下评论

ASM NORMAL REDUNDANCY情况下,谁完成了数据的镜像IO?

前几天,一些朋友讨论ASM中,如果是NORMAL redundancy磁盘组,数据的镜像是由oracle rdbms进程完成,还是由ASM的进程完成镜像的工作。
我们知道,ASM NORMAL REDUNDANCY磁盘组类似于RAID 10的操作,也就是镜像+条带划。
.
在传统架构中,oracle只负责写入一份数据,数据保护(镜像)是由存储或者RAID卡来完成的,那么在ASM中是否也是DB完成一次写入,ASM进行同步呢?
根据下面的测试,结论是:
DB的进程完成数据库中所有应用数据的IO操作,包括镜像数据的IO。而ASM进程只负责元数据(metadata extent)的维护和IO。
.
具体测试如下:
首先,我们创建一个normal redundancy的磁盘组,用来放数据库的redo,比如 +REDODG:

SQL>select GROUP_NUMBER,NAME,SECTOR_SIZE,BLOCK_SIZE,ALLOCATION_UNIT_SIZE,TYPE FROM V$ASM_DISKGROUP where name='REDODG';

GROUP_NUMBER NAME                           SECTOR_SIZE BLOCK_SIZE ALLOCATION_UNIT_SIZE TYPE
------------ ------------------------------ ----------- ---------- -------------------- ------
           6 REDODG                                 512       4096              1048576 NORMAL

SQL>
SQL>col path for a50  
SQL>col library for a15    
SQL>select GROUP_NUMBER,DISK_NUMBER,REDUNDANCY,LIBRARY,NAME,PATH from v$asm_disk WHERE GROUP_NUMBER=6;

GROUP_NUMBER DISK_NUMBER REDUNDA LIBRARY         NAME                           PATH
------------ ----------- ------- --------------- ------------------------------ --------------------------------------------------
           6           1 UNKNOWN System          REDODG_0001                    /dev/mapper/redolun2
           6           0 UNKNOWN System          REDODG_0000                    /dev/mapper/redolun1

SQL>

这个两个磁盘的failure group的信息如下:

SQL>SELECT GROUP_NUMBER,DISK_NUMBER,STATE,REDUNDANCY,LIBRARY,NAME,FAILGROUP,PATH,REPAIR_TIMER FROM V$ASM_DISK WHERE GROUP_NUMBER=6;

GROUP_NUMBER DISK_NUMBER STATE    REDUNDA LIBRARY         NAME                           FAILGROUP
------------ ----------- -------- ------- --------------- ------------------------------ ------------------------------
PATH                                               REPAIR_TIMER
-------------------------------------------------- ------------
           6           1 NORMAL   UNKNOWN System          V5DATA_0001                    V5DATA_0001
/dev/mapper/v5lun2                                            0

           6           0 NORMAL   UNKNOWN System          V5DATA_0000                    V5DATA_0000
/dev/mapper/v5lun1                                            0


SQL>

[oracle@lunardb1 ~]$ ll /dev/mapper/redolun*
brw-rw---- 1 oracle oinstall 253, 8 Jun 16 10:39 /dev/mapper/redolun1
brw-rw---- 1 oracle oinstall 253, 9 Jun 16 10:39 /dev/mapper/redolun2
[oracle@lunardb1 ~]$ 

然后,我们使用REDODG创建了9组redo log group(这套10204的RAC的redo都放在上面了):

[oracle@lunardb1 ~]$ ss

SQL*Plus: Release 10.2.0.4.0 - Production on Tue Jun 16 10:37:49 2015

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.


Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
With the Partitioning, Real Application Clusters, Data Mining and Real Application Testing options

sys@LUNAR>select * from v$log;

    GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARC STATUS           FIRST_CHANGE# FIRST_TIM
---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ---------
         1          1       4623   52428800          1 YES INACTIVE             902491454 16-JUN-15
         2          1       4621   52428800          1 YES INACTIVE             901886291 16-JUN-15
         3          2       1621   52428800          1 YES INACTIVE             900432674 16-JUN-15
         4          2       1624   52428800          1 NO  CURRENT              902514208 16-JUN-15
         5          1       4624 1073741824          1 YES INACTIVE             902511227 16-JUN-15
         6          1       4625 1073741824          1 NO  CURRENT              903006387 16-JUN-15
         7          1       4622 1073741824          1 YES INACTIVE             901890974 16-JUN-15
         8          2       1622 1073741824          1 YES INACTIVE             901661757 16-JUN-15
         9          2       1623 1073741824          1 YES INACTIVE             901886509 16-JUN-15

9 rows selected.

sys@LUNAR>col member for a70
sys@LUNAR>select * from v$logfile;

    GROUP# STATUS  TYPE    MEMBER                                                                 IS_
---------- ------- ------- ---------------------------------------------------------------------- ---
         2         ONLINE  +REDODG/lunar/onlinelog/group_2.269.855587247                           NO
         1         ONLINE  +REDODG/lunar/onlinelog/group_1.270.855587247                           NO
         3         ONLINE  +REDODG/lunar/onlinelog/group_3.264.855587433                           NO
         4         ONLINE  +REDODG/lunar/onlinelog/group_4.263.855587433                           NO
         5         ONLINE  +REDODG/lunar/onlinelog/group_5.341.855591573                           NO
         6         ONLINE  +REDODG/lunar/onlinelog/group_6.303.855591671                           NO
         7         ONLINE  +REDODG/lunar/onlinelog/group_7.403.855591683                           NO
         8         ONLINE  +REDODG/lunar/onlinelog/redo08.log                                      NO
         9         ONLINE  +REDODG/lunar/onlinelog/redo09.log                                      NO

9 rows selected.

这个数据库实例的LGWR进程号为 11159:

[oracle@lunardb1 ~]$ ps -ef|grep lgwr|grep lunar
oracle   11159     1  0 Mar03 ?        08:01:25 ora_lgwr_lunar1
[oracle@lunardb1 ~]$ 


sys@lunar>select spid from v$process where PROGRAM like '%LGWR%';

SPID
------------
11159

sys@lunar>

现在我们使用strace跟踪一下这个进程在数据库切换日志时的动作,如果lgwr进程只写了一个设备,比如/dev/mapper/redolun1或者/dev/mapper/redolun2,那么可以再跟踪一下ASMB进程。
.
如果LGWR进程写了两个设备,即/dev/mapper/redolun2和/dev/mapper/redolun1都写入了相应的IO,那么我们可以认为,数据库的LGWR自己完成了primary extent和mirror extent的全部操作。
这也是Oracle 文档中一直说明的一点“ASM负责ASM实例的metadata的IO,而DB完成应用实际数据的IO”。
具体跟踪文件如下:

首先我们看到oracle将相同的内容
[oracle@lunardb1 ~]$ tail -f /tmp/lgwr_lunar1_strace-1.log
。。。。。。。。。。。。。。。。。。。。。。。
11159      0.000078 times(NULL)         = 1336555656
11159      0.000043 pread(16, "\1\"\0\0\1\0\0\0\26\22\0\0\0\200\245K\0\0\0\0\0\3 \n-\250\371\232lunar"..., 512, 105444803072) = 512
11159      0.007057 times(NULL)         = 1336555657
11159      0.000081 times(NULL)         = 1336555657
11159      0.000045 pread(16, "\25\302\0\0f\0\0\0\342\334\6\0\377\377\1\4\375-\0\0\3\0\2\0\0\0\0\0\0\0+"..., 16384, 586383360) = 16384
11159      0.000222 times(NULL)         = 1336555657
11159      0.000077 times(NULL)         = 1336555657
11159      0.000059 pwrite(17, "\1\"\0\0\1\0\0\0\27\22\0\0\0\200\246\335\0\0\0\0\0\3 \n-\250\371\232lunar"..., 512, 1400898048) = 512
11159      0.005443 times(NULL)         = 1336555658
11159      0.000063 times(NULL)         = 1336555658
11159      0.000049 pwrite(16, "\1\"\0\0\1\0\0\0\27\22\0\0\0\200\246\335\0\0\0\0\0\3 \n-\250\371\232lunar"..., 512, 1400898048) = 512
11159      0.004075 times(NULL)         = 1336555658
11159      0.000098 times(NULL)         = 1336555658
11159      0.000120 pread(16, "\1\"\0\0\1\0\0\0\26\22\0\0\0\200\245K\0\0\0\0\0\3 \n-\250\371\232lunar"..., 512, 105444803072) = 512
11159      0.000148 times(NULL)         = 1336555658
11159      0.000068 times(NULL)         = 1336555658
11159      0.000044 pwrite(16, "\1\"\0\0\1\0\0\0\26\22\0\0\0\200\255\364\0\0\0\0\0\3 \n-\250\371\232lunar"..., 512, 105444803072) = 512
11159      0.000472 times(NULL)         = 1336555658
11159      0.000060 times(NULL)         = 1336555658
11159      0.000052 pwrite(17, "\1\"\0\0\1\0\0\0\26\22\0\0\0\200\255\364\0\0\0\0\0\3 \n-\250\371\232lunar"..., 512, 105444803072) = 512
11159      0.000399 times(NULL)         = 1336555658
11159      0.000075 times(NULL)         = 1336555658
。。。。。。。。。。。。。。。。。。。。。。。。。。。

上面的跟踪文件可以很清晰的看到,LGWR进程连续写了2分相同的数据到fd为16和17的设备上。
那么16和17是什么呢:

[oracle@lunardb1 fd]$ cd /proc/11159/fd
[oracle@lunardb1 fd]$ ls -lrt
total 0
lr-x------ 1 oracle oinstall 64 Jun 13 17:04 0 -> /dev/null
lrwx------ 1 oracle oinstall 64 Jun 13 17:04 9 -> /u01/oracle/app/product/10.2/db_1/dbs/lkinstlunar1 (deleted)
l-wx------ 1 oracle oinstall 64 Jun 13 17:04 8 -> /u01/oracle/app/admin/lunar/bdump/alert_lunar1.log
lrwx------ 1 oracle oinstall 64 Jun 13 17:04 7 -> /u01/oracle/app/product/10.2/db_1/dbs/hc_lunar1.dat
l-wx------ 1 oracle oinstall 64 Jun 13 17:04 6 -> /u01/oracle/app/admin/lunar/bdump/alert_lunar1.log
l-wx------ 1 oracle oinstall 64 Jun 13 17:04 5 -> /u01/oracle/app/admin/lunar/udump/lunar1_ora_11099.trc
lr-x------ 1 oracle oinstall 64 Jun 13 17:04 4 -> /dev/null
lr-x------ 1 oracle oinstall 64 Jun 13 17:04 3 -> /dev/null
l-wx------ 1 oracle oinstall 64 Jun 13 17:04 2 -> /u01/oracle/app/admin/lunar/bdump/lunar1_lgwr_11159.trc
lr-x------ 1 oracle oinstall 64 Jun 13 17:04 18 -> /u01/oracle/app/product/10.2/db_1/rdbms/mesg/oraus.msb
lrwx------ 1 oracle oinstall 64 Jun 13 17:04 17 -> /dev/mapper/redolun2
lrwx------ 1 oracle oinstall 64 Jun 13 17:04 16 -> /dev/mapper/redolun1
lrwx------ 1 oracle oinstall 64 Jun 13 17:04 15 -> socket:[32662]
lrwx------ 1 oracle oinstall 64 Jun 13 17:04 14 -> /u01/oracle/app/product/10.2/db_1/dbs/hc_lunar1.dat
lr-x------ 1 oracle oinstall 64 Jun 13 17:04 13 -> /u01/oracle/app/product/10.2/db_1/rdbms/mesg/oraus.msb
lr-x------ 1 oracle oinstall 64 Jun 13 17:04 12 -> /dev/zero
lr-x------ 1 oracle oinstall 64 Jun 13 17:04 11 -> /dev/zero
lrwx------ 1 oracle oinstall 64 Jun 13 17:04 10 -> socket:[32659]
lr-x------ 1 oracle oinstall 64 Jun 13 17:04 1 -> /dev/null
[oracle@lunardb1 fd]$ 
[oracle@lunardb1 fd]$ ll 17
lrwx------ 1 oracle oinstall 64 Jun 13 17:04 17 -> /dev/mapper/redolun2
[oracle@lunardb1 fd]$ ll 16
lrwx------ 1 oracle oinstall 64 Jun 13 17:04 16 -> /dev/mapper/redolun1
[oracle@lunardb1 fd]$ 

这里看到,16和17就是redodg所使用的两个磁盘。也就是说,LGWR自己完成了primary extent和mirror extent的IO操作。
至此已经很清楚了,那么可以我们可以推断,DBWR等数据库操作也是有DB自己的进程完成了,而ASM只负责元数据的IO操作和维护。
具体的测试,有兴趣的可以自己跟踪。
上面的跟踪信息还可以看到,实际上oracle使用AIO的方式(使用io_submit,io_getevents等),定期同步控制文件的信息,仍然是写16和17两个设备。
并且通知ARCH进程进行归档操作,并在完成后,写入alert.log的过程:

。。。。。。。。。。。。。。。。。。。
11159      0.000050 io_submit(46982646722560, 2, {{0x2abafffaa3c8, 0, 1, 0, 16}, {0x2abafffaa6d8, 0, 1, 0, 17}}) = 2
11159      0.000127 io_getevents(46982646722560, 1, 1024, {{0x2abafffaa3c8, 0x2abafffaa3c8, 16384, 0}}, {600, 0}) = 1
11159      0.000545 times(NULL)         = 1336555658
11159      0.000053 io_getevents(46982646722560, 1, 1023, {{0x2abafffaa6d8, 0x2abafffaa6d8, 16384, 0}}, {600, 0}) = 1
11159      0.000048 times(NULL)         = 1336555658
11159      0.000075 times(NULL)         = 1336555658
11159      0.000068 pread(17, "\25\302\0\0\t\3\0\0\376\326\6\0\377\377\1\4\311N\0\0\4\2\2\0\337\7\0\0\0\0\0\0"..., 16384, 591937536) = 16384
11159      0.000230 times(NULL)         = 1336555658
11159      0.000086 times(NULL)         = 1336555658
11159      0.000045 pread(17, "\25\302\0\0\253\1\0\0\t\251\n\0\377\377\1\0041\330\0\0\270\35\2264\1\0\0\0\363\27\0\0"..., 16384, 588038144) = 16384
11159      0.005841 times(NULL)         = 1336555659
11159      0.000094 times(NULL)         = 1336555659
11159      0.000046 pread(17, "\25\302\0\0.\0\0\0)\251\n\0\377\377\1\4\356\231\0\0\0\220\1\0\24\22\0\0\2\0\0\0"..., 16384, 587300864) = 16384
11159      0.000195 times(NULL)         = 1336555659
11159      0.000076 times(NULL)         = 1336555659
11159      0.000099 io_submit(46982646722560, 2, {{0x2abafffaa3c8, 0, 1, 0, 16}, {0x2abafffaa6d8, 0, 1, 0, 17}}) = 2
11159      0.000164 io_getevents(46982646722560, 1, 1024, {{0x2abafffaa6d8, 0x2abafffaa6d8, 16384, 0}, {0x2abafffaa3c8, 0x2abafffaa3c8, 16384, 0}}, {600, 0}) = 2
11159      0.000329 times(NULL)         = 1336555659
11159      0.000050 times(NULL)         = 1336555659
11159      0.000065 times(NULL)         = 1336555659
11159      0.000045 pread(17, "\25\302\0\0,\0\0\0\27\251\n\0\377\377\1\4\310Z\0\0\17\0\0\0-\246\3465\0\0\375>"..., 16384, 587268096) = 16384
11159      0.000221 times(NULL)         = 1336555659
11159      0.000098 times(NULL)         = 1336555659
11159      0.000054 io_submit(46982646722560, 2, {{0x2abafffaa3c8, 0, 1, 0, 16}, {0x2abafffaa6d8, 0, 1, 0, 17}}) = 2
11159      0.000121 io_getevents(46982646722560, 1, 1024, {{0x2abafffaa6d8, 0x2abafffaa6d8, 16384, 0}}, {600, 0}) = 1
11159      0.000379 times(NULL)         = 1336555659
11159      0.000048 io_getevents(46982646722560, 1, 1023, {{0x2abafffaa3c8, 0x2abafffaa3c8, 16384, 0}}, {600, 0}) = 1
11159      0.000047 times(NULL)         = 1336555659
11159      0.000077 times(NULL)         = 1336555659
11159      0.000053 io_submit(46982646722560, 2, {{0x2abafffaa3c8, 0, 1, 0, 16}, {0x2abafffaa6d8, 0, 1, 0, 17}}) = 2
11159      0.000108 io_getevents(46982646722560, 1, 1024, {{0x2abafffaa6d8, 0x2abafffaa6d8, 16384, 0}, {0x2abafffaa3c8, 0x2abafffaa3c8, 16384, 0}}, {600, 0}) = 2
11159      0.000425 times(NULL)         = 1336555659
11159      0.000038 times(NULL)         = 1336555659
11159      0.000073 times(NULL)         = 1336555659
11159      0.000050 io_submit(46982646722560, 2, {{0x2abafffaa3c8, 0, 1, 0, 16}, {0x2abafffaa6d8, 0, 1, 0, 17}}) = 2
11159      0.000114 io_getevents(46982646722560, 1, 1024, {{0x2abafffaa3c8, 0x2abafffaa3c8, 16384, 0}}, {600, 0}) = 1
11159      0.000421 times(NULL)         = 1336555659
11159      0.000041 io_getevents(46982646722560, 1, 1023, {{0x2abafffaa6d8, 0x2abafffaa6d8, 16384, 0}}, {600, 0}) = 1
11159      0.000047 times(NULL)         = 1336555659
11159      0.000076 times(NULL)         = 1336555659
11159      0.000054 io_submit(46982646722560, 2, {{0x2abafffaa6d8, 0, 1, 0, 16}, {0x2abafffaa3c8, 0, 1, 0, 17}}) = 2
11159      0.000128 io_getevents(46982646722560, 1, 1024, {{0x2abafffaa6d8, 0x2abafffaa6d8, 16384, 0}, {0x2abafffaa3c8, 0x2abafffaa3c8, 16384, 0}}, {600, 0}) = 2
11159      0.000318 times(NULL)         = 1336555659
11159      0.000038 times(NULL)         = 1336555659
11159      0.000060 times(NULL)         = 1336555659
11159      0.000044 pread(16, "\25\302\0\0\1\0\0\0\0\0\0\0\0\0\1\4\16\243\0\0\0\0\0\0\0\3 \n-\250\371\232"..., 16384, 581976064) = 16384
11159      0.000244 times(NULL)         = 1336555660
11159      0.000067 times(NULL)         = 1336555660
11159      0.000117 times(NULL)         = 1336555660
11159      0.000044 times(NULL)         = 1336555660
11159      0.000037 times(NULL)         = 1336555660
11159      0.000343 times(NULL)         = 1336555660
11159      0.000065 semctl(720901, 51, SETVAL, 0x7fff00000001) = 0
11159      0.000081 times(NULL)         = 1336555660
11159      0.000053 pread(16, "\25\302\0\0f\0\0\0\342\334\6\0\377\377\1\4\375-\0\0\3\0\2\0\0\0\0\0\0\0+V"..., 16384, 586383360) = 16384
11159      0.000234 times(NULL)         = 1336555660
11159      0.000062 times(NULL)         = 1336555660
11159      0.000081 semctl(720901, 18, SETVAL, 0x2abb00000001) = 0
11159      0.000062 semctl(720901, 19, SETVAL, 0x2abb00000001) = 0
11159      0.000123 semctl(720901, 20, SETVAL, 0x2abb00000001) = 0
11159      0.000251 open("/proc/11356/stat", O_RDONLY) = 19
11159      0.000113 read(19, "11356 (oracle) S 1 11356 11356 0"..., 999) = 249
11159      0.000118 close(19)           = 0
11159      0.000120 semctl(720901, 36, SETVAL, 0x2abb00000001) = 0
11159      0.000239 close(8)            = 0
11159      0.000044 open("/u01/oracle/app/admin/lunar/bdump/alert_lunar1.log", O_WRONLY|O_CREAT|O_APPEND, 0660) = 8
11159      0.000069 writev(8, [{"Tue Jun 16 14:47:51 2015\n", 25}, {"Thread 1 advanced to log sequenc"..., 52}, {"\n", 1}], 3) = 78
11159      0.000075 times(NULL)         = 1336555660
11159      0.000043 times(NULL)         = 1336555660
11159      0.000053 close(8)            = 0
11159      0.000053 open("/u01/oracle/app/admin/lunar/bdump/alert_lunar1.log", O_WRONLY|O_CREAT|O_APPEND, 0660) = 8
11159      0.000057 writev(8, [{"  Current log# 2 seq# 4631 mem# "..., 79}, {"\n", 1}], 2) = 80
11159      0.000061 times(NULL)         = 1336555660
11159      0.000043 times(NULL)         = 1336555660
11159      0.000043 semtimedop(720901, 0x7fff585eeef0, 1, {1, 960000000}) = 0
11159      0.105071 times(NULL)         = 1336555670
11159      0.000058 times(NULL)         = 1336555670
11159      0.000102 times(NULL)         = 1336555670
。。。。。。。。。。。。。。。。。。。。。。。。。。。
[oracle@lunardb1 ~]$ 

至此,已经完全可以得出结论,ASM的冗余操作分为两部分:
1,数据库中实际应用数据的冗余,primary extent和mirror extent都由数据库自己完成
2,ASM的元数据的镜像操作由ASM进程自己完成。

发表在 ASM | 标签为 , | 留下评论

收集ASM信息的脚本

当ASM中某些磁盘状态异常,比如应该是“MEMBER”的,却是“CANDIDATE”或者其他等各种盘头异常,或者ASM实例异常,可以使用下面脚本收集ASM信息(来源于MOS)

#/bin/sh
################################################################################################
###  The next script generates additional ASM metadata information thru the ASMCMD interface ###
################################################################################################

test $# -eq '1' || { echo " exec sh check_asm_lunar.sh arg1 "; exit;}
ASMVERSION=$1

case $ASMVERSION in
  10g|10.2)
    SYSROLE="sysdba"

  ;;
  11g|11.2)
    SYSROLE="sysasm"
  ;;
  *)
    echo "Unkown ASM VERSION"
#    exit;
  ;;
esac


################################################################################################
###  The next script generates additional ASM metadata information thru the ASMCMD interface ###
################################################################################################
mkdir /tmp/lunar
cd /tmp/lunar
rm -rf /tmp/lunar/*

echo "ASMCMD commands to gather complementary metadata information:"    > /tmp/asmcmd_script.out  2> /tmp/asmcmd_script.out
echo "=================================="       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "                                  "       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
asmcmd -p ls -ls        >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "=================================="       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "                                  "       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
asmcmd -p lsattr        >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "=================================="       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "                                  "       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
asmcmd -p lsct  >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "=================================="       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "                                  "       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
asmcmd -p lsdg  >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "=================================="       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "                                  "       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
asmcmd -p lsdsk >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "=================================="       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "                                  "       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
asmcmd -p lsof  >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "=================================="       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "                                  "       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
asmcmd -p lsod  >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "=================================="       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "                                  "       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
asmcmd -p iostat        >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "=================================="       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "                                  "       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
asmcmd -p dsget >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "=================================="       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "                                  "       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
asmcmd -p lsop  >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "=================================="       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "                                  "       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
asmcmd -p spget >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "=================================="       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "                                  "       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
asmcmd -p  lstmpl       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "=================================="       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "                                  "       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
asmcmd -p   lsusr       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "=================================="       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "                                  "       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
asmcmd -p  lsgrp        >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "=================================="       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "                                  "       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
asmcmd -p   lspwusr     >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "=================================="       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "                                  "       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
asmcmd -p   volinfo -a  >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "=================================="       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
echo "                                  "       >> /tmp/asmcmd_script.out               2>> /tmp/asmcmd_script.out
##############################################################################################################

sqlplus -S /nolog<<EOF
conn / as $SYSROLE

spool /tmp/asm_Generic_ASM_metadata.html
-- ASM Versions 10.1, 10.2, 11.1  & 11.2
SET MARKUP HTML ON
set echo on

set pagesize 200

alter session set nls_date_format='YYYY-MM-DD HH24:MI:SS';

select 'THIS ASM REPORT WAS GENERATED AT: ==)> ' , sysdate " "  from dual;


select 'HOSTNAME ASSOCIATED WITH THIS ASM INSTANCE: ==)> ' , MACHINE " " from v\$session where program like '%SMON%';

select * from v\$asm_diskgroup;

SELECT * FROM  v\$ASM_DISK ORDER BY GROUP_NUMBER,DISK_NUMBER;  

SELECT SUBSTR(d.name,1,16) AS asmdisk, d.mount_status, d.state,
     dg.name AS diskgroup FROM v\$ASM_DISKGROUP dg, v\$ASM_DISK d
     WHERE dg.group_number = d.group_number;


SELECT * FROM v\$ASM_CLIENT;

 SELECT dg.name AS diskgroup, SUBSTR(c.instance_name,1,12) AS instance,
    SUBSTR(c.db_name,1,12) AS dbname, SUBSTR(c.SOFTWARE_VERSION,1,12) AS software,
    SUBSTR(c.COMPATIBLE_VERSION,1,12) AS compatible
    FROM v\$ASM_DISKGROUP dg, v\$ASM_CLIENT c  
    WHERE dg.group_number = c.group_number;

select * from v\$ASM_ATTRIBUTE;

select * from v\$asm_operation;
select * from gv\$asm_operation;


select * from v\$version;


select * from   v\$ASM_ACFSSNAPSHOTS;
select * from   v\$ASM_ACFSVOLUMES;
select * from   v\$ASM_FILESYSTEM;
select * from   v\$ASM_VOLUME;
select * from   v\$ASM_VOLUME_STAT;

select * from   v\$ASM_USER;
select * from   v\$ASM_USERGROUP;
select * from   v\$ASM_USERGROUP_MEMBER;

select * from   v\$ASM_DISK_IOSTAT;
select * from   v\$ASM_DISK_STAT;
select * from   v\$ASM_DISKGROUP_STAT;

select * from   v\$ASM_TEMPLATE;

show parameter asm
show parameter cluster
show parameter instance_type
show parameter instance_name
show parameter spfile

show sga

!echo "select '" > /tmp/gpnptool.sql 2> /dev/null
! $ORACLE_HOME/bin/gpnptool get >> /tmp/gpnptool.sql 2>> /dev/null
!echo "'  from dual;" >> /tmp/gpnptool.sql 2>> /dev/null

set echo off

@@/tmp/gpnptool.sql


spool off


spool /tmp/asm_alias_files.html
-- ASM Versions 10.1, 10.2, 11.1  & 11.2
SET MARKUP HTML ON
set echo on

set pagesize 200

alter session set nls_date_format='YYYY-MON-DD HH24:MI:SS';

select 'THIS ASM REPORT WAS GENERATED AT: ==)> ' , sysdate " "  from dual;


select 'HOSTNAME ASSOCIATED WITH THIS ASM INSTANCE: ==)> ' , MACHINE " " from v\$session where program like '%SMON%';

select * from v\$asm_alias;

select * from v\$asm_file;

show parameter asm
show parameter cluster
show parameter instance_type
show parameter instance_name
show parameter spfile

show sga

spool off



spool /tmp/asm_full_path_alias_directory.html
-- ASM Versions 10.1, 10.2, 11.1  & 11.2
SET MARKUP HTML ON
set echo on

set pagesize 200

alter session set nls_date_format='YYYY-MON-DD HH24:MI:SS';

select 'THIS ASM REPORT WAS GENERATED AT: ==)> ' , sysdate " "  from dual;


select 'HOSTNAME ASSOCIATED WITH THIS ASM INSTANCE: ==)> ' , MACHINE " " from v\$session where program like '%SMON%';

SELECT CONCAT('+'||GNAME, SYS_CONNECT_BY_PATH(ANAME, '/'))
 FULL_PATH, SYSTEM_CREATED, ALIAS_DIRECTORY, FILE_TYPE
 FROM ( SELECT B.NAME GNAME, A.PARENT_INDEX PINDEX,
 A.NAME ANAME, A.REFERENCE_INDEX RINDEX,
 A.SYSTEM_CREATED, A.ALIAS_DIRECTORY,
 C.TYPE FILE_TYPE
 FROM v\$ASM_ALIAS A, v\$ASM_DISKGROUP B, v\$ASM_FILE C
 WHERE A.GROUP_NUMBER = B.GROUP_NUMBER
 AND A.GROUP_NUMBER = C.GROUP_NUMBER(+)
 AND A.FILE_NUMBER = C.FILE_NUMBER(+)
 AND A.FILE_INCARNATION = C.INCARNATION(+)
 )
 START WITH (MOD(PINDEX, POWER(2, 24))) = 0
 CONNECT BY PRIOR RINDEX = PINDEX;



spool off

exit

EOF

mv /tmp/asmcmd_script.out /tmp/lunar/
mv /tmp/asm_full_path_alias_directory.html /tmp/lunar/
mv /tmp/gpnptool.sql /tmp/lunar/
mv /tmp/asm_alias_files.html /tmp/lunar/
mv /tmp/asm_Generic_ASM_metadata.html /tmp/lunar/
cd /tmp
tar cvf asm_lunar.tar /tmp/lunar/*

发表在 ASM, Scripts | 标签为 , | 留下评论

使用dd备份和恢复ASM中的数据文件头

今天看了飞总微博上的备份ASM中数据文件头(http://www.xifenfei.com/5888.html),觉得有意思
佩服飞总专业的钻研精神,那么多X$的internal视图……O(∩_∩)O哈哈~
这里用大家随处可见的(除了extent分布的x$kffxp需要百度和google外),其余都是文档中有详细记载的常用ASM视图来实现同样功能:

下面的用于从ASM中备份数据文件头:
[grid@lunarnew1 ~]$ ss

SQL*Plus: Release 11.2.0.4.0 Production on Sat May 16 20:03:11 2015

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


Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Automatic Storage Management option

SQL> set linesize 200
SQL> set pages 9999
SQL> col "backup(dd) fileheader from asm" for a200
SQL> SELECT 'dd if='||d.path||' of=&backup_path/'||e.GROUP_KFFXP||'_'||e.DISK_KFFXP||'_'
  2  ||a.file_number||'.asm'||' count=1 conv=notrunc bs='||G.ALLOCATION_UNIT_SIZE||' skip='||e.AU_KFFXP "backup(dd) fileheader from asm"
  3  FROM x$kffxp e, v$asm_file f, v$asm_alias a, v$asm_disk d, V$ASM_DISKGROUP G
  4  WHERE e.number_kffxp=a.file_number
  5  and e.GROUP_KFFXP=a.GROUP_NUMBER
  6  and f.group_number=a.group_number 
  7  and f.file_number=a.file_number 
  8  and e.DISK_KFFXP=d.DISK_NUMBER
  9  and e.GROUP_KFFXP=d.GROUP_NUMBER
 10  and a.SYSTEM_CREATED='Y'
 11  and f.type='DATAFILE'
 12  and e.XNUM_KFFXP=0
 13  AND D.GROUP_NUMBER=G.GROUP_NUMBER
 14  ;
Enter value for backup_path: /tmp
old   1: SELECT 'dd if='||d.path||' of=&backup_path/'||e.GROUP_KFFXP||'_'||e.DISK_KFFXP||'_'
new   1: SELECT 'dd if='||d.path||' of=/tmp/'||e.GROUP_KFFXP||'_'||e.DISK_KFFXP||'_'

backup(dd) fileheader from asm
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
dd if=/dev/asm-disk1 of=/tmp/1_0_258.asm count=1 conv=notrunc bs=1048576 skip=45
dd if=/dev/asm-disk1 of=/tmp/1_0_260.asm count=1 conv=notrunc bs=1048576 skip=700
dd if=/dev/asm-disk1 of=/tmp/1_0_261.asm count=1 conv=notrunc bs=1048576 skip=749
dd if=/dev/asm-disk1 of=/tmp/1_0_263.asm count=1 conv=notrunc bs=1048576 skip=1101
dd if=/dev/asm-disk2 of=/tmp/1_1_262.asm count=1 conv=notrunc bs=1048576 skip=978
dd if=/dev/asm-disk2 of=/tmp/1_1_259.asm count=1 conv=notrunc bs=1048576 skip=103

6 rows selected.

SQL> 
下面的用于使用bbed修改文件头后放回到ASM中:
SQL> set linesize 200
SQL> set pages 9999
SQL> col"Restore(dd) fileheader to asm" for a200
SQL> SELECT 'dd of='||d.path||' if=&backup_path/'||e.GROUP_KFFXP||'_'||e.DISK_KFFXP||'_'
  2  ||a.file_number||'.asm'||' count=1 conv=notrunc bs='||G.ALLOCATION_UNIT_SIZE||' seek='||e.AU_KFFXP "Restore(dd) fileheader to asm"
  3  FROM x$kffxp e, v$asm_file f, v$asm_alias a, v$asm_disk d, V$ASM_DISKGROUP G
  4  WHERE e.number_kffxp=a.file_number
  5  and e.GROUP_KFFXP=a.GROUP_NUMBER
  6  and f.group_number=a.group_number 
  7  and f.file_number=a.file_number 
  8  and e.DISK_KFFXP=d.DISK_NUMBER
  9  and e.GROUP_KFFXP=d.GROUP_NUMBER
 10  and a.SYSTEM_CREATED='Y'
 11  and f.type='DATAFILE'
 12  and e.XNUM_KFFXP=0
 13  AND D.GROUP_NUMBER=G.GROUP_NUMBER
 14  ;
Enter value for backup_path: /tmp
old   1: SELECT 'dd of='||d.path||' if=&backup_path/'||e.GROUP_KFFXP||'_'||e.DISK_KFFXP||'_'
new   1: SELECT 'dd of='||d.path||' if=/tmp/'||e.GROUP_KFFXP||'_'||e.DISK_KFFXP||'_'

Restore(dd) fileheader to asm
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
dd of=/dev/asm-disk1 if=/tmp/1_0_258.asm count=1 conv=notrunc bs=1048576 seek=45
dd of=/dev/asm-disk1 if=/tmp/1_0_260.asm count=1 conv=notrunc bs=1048576 seek=700
dd of=/dev/asm-disk1 if=/tmp/1_0_261.asm count=1 conv=notrunc bs=1048576 seek=749
dd of=/dev/asm-disk1 if=/tmp/1_0_263.asm count=1 conv=notrunc bs=1048576 seek=1101
dd of=/dev/asm-disk2 if=/tmp/1_1_262.asm count=1 conv=notrunc bs=1048576 seek=978
dd of=/dev/asm-disk2 if=/tmp/1_1_259.asm count=1 conv=notrunc bs=1048576 seek=103

6 rows selected.

SQL> 
发表在 ASM | 标签为 , | 一条评论