dbhelper 的 博客

欢迎来到dbhelper 的 博客>>   | 首页 资源中心 | 一般分类 | ITPUB论坛

mytun使用说明

发表人:dbhelper | 发表时间: 2008年三月05日, 16:29

mytun讨论 QQ群: 91784480

mytun 软件下载地址 http://dbhelper.itpub.net/get/26969/31248-mytun.zip

此下载于2011-12-20做过升级更新,老版本用户请即时下载(老版本使用时限为2011-9-1, 而此新版使用无时限)

Oracle数据库技术服务

qq:123614791 msn:xjwyq28@hotmail.com

电话: 131-6198-9316 王先生

一、产品安装

二、Oracle数据库备份与恢复

三、性能诊断、性能调优

四、紧急故障排除和紧急响应服务

五、数据迁移

六、电话支持服务、远程拨号诊断

七、系统健康检查(巡检服务)

八、Oracle数据库安全性、稳定性评估建议报告

九、定制数据库维护手册

十、数据库补丁包服务

十一、培训服务

写mytun这个工具的原因: 多年前,看到用户发来的statspack/awr报告时, 发现sql报告只采集现象和结果, 但并未采集问题的原因相关信息, 还需dba去现场采集很多数据才能定位问题, 即延长了排除故障的时间, 又耗费了人力和财力。 于是多年前自己就写了这个工具来方便自己用, 这样后,自己团队的工作效率大大提高。

评价地址: http://www.itpub.net/viewthread.php?tid=1333917&pid=16220636&page=1&extra=page%3D1

mytun区别于awr

oracle的awr只能看的plan变化,确没采集相关对象(表、列、index)的统计信息 ,及其变化, 所以使plan变化的本质原因并不清晰。

mytun 特色:

mytun 可采集相关对象统计信息的变化,可发现plan变化的原因。mytun是对awr的一个补充, 侧重对sql情况,执行原因的相关数据信息的收集, 为远程的问题诊断提供帮助。

-----------------------mytun生成报表内容-----------------

sql % : 某sql在各类别的排名
sql total : 某sql耗用资源量。
sql per execs : 某sql一次执行的平均消耗

sql的原始文本
sql窥视绑定变量后的sql文本
sql在不同时段的使用不同的计划(plan)
sql在v$sqlarea的情况---sql的执行情况
sql在v$sqlarea_plan_hash(一个sql可能多种计划)---sql在不同计划下的执行情况
sql在dba_hist_sql_plan ----sql的历史计划(一般是 7-30天内的)
sql在wrh$_sqlstat -----在历史时间各时段的执行情况(频次, 计划hash, 效率等)
sql在v$sql_bind_capture ------带入的绑定变量
sql在dba_hist_sqlbind -------历史时段的绑定变量
sql 涉及的对象 :
1. dba_tables --表的分析
2. dba_segments --段的大小,
3. 对象的产生, 修改时间等
4. index 统计分析信息
5. index 中包含的列
6. table的定义
7. table的当前统计分析信息, 历史统计分析信息
8. 列的当前统计分析信息, 历史统计分析信息
9. 列的柱状图信息, 历史柱状图信息。

mytun使用说明

mytun2.0简介: 是一款sql调优工具, 它可快速采集(或远程)sql优化所需的信息, 定位产生错误执行计划的原因,
为远程问题诊断提供新的途径。采集信息包括: plan, 变量值, 分析信息(表/列/索引), 柱状图,
段信息(表/分区/索引),历史执行情况等。
适用范围 : 适用于Oracle10g(10.2.0.1以上)、oracle 11g的各版本及平台。
mytun author : wang yu qiang
support: Mail: xjwyq28@sina.com.cn QQ: 123614791 Msn: xjwyq28@hotmail.com Tel: 131-6198-9316


目录

一. mytun.zip把上传至数据库服务器, 解压后会生成mytun目录和几个文件。

二. 安装软件包(第一次使用前需要安装, 以后使用就不需要了) 。
三. 使用mytun
附件1: 运行mytunrpt.sql提示过程
附件2: 运行mytunrpt.sql报告结果

四. 卸载mytun


一. mytun.zip把上传至数据库服务器, unzip解压后会生成mytun目录和几个文件。

$ unzip mytun.zip
Archive: mytun.zip
creating: mytun/
inflating: mytun/awrinpnm.sql
inflating: mytun/awrinput.sql
inflating: mytun/awrrpti.sql
inflating: mytun/checkmytun.sql
inflating: mytun/mytun.sql
inflating: mytun/mytunrpt.sql
inflating: mytun/p_mytun1.plb
inflating: mytun/p_mytun2.plb
inflating: mytun/running_sql.sql

二. 安装软件包(第一次使用时需要安装, 以后使用就不需要了)

方法1
$cd mytun
$sqlplus "/ as sysdba"

SQL> @p_mytun1.plb
Package created.

SQL> @p_mytun2.plb
Package body created.

方法2
sqlplus "/ as sysdba" @p_mytun1.plb
sqlplus "/ as sysdba" @p_mytun2.plb

三.使用mytun


使用mytun的方式有3种:
方式1: 采集历史时段的数据库性能sql报告
sqlplus "/ as sysdba"
SQL> @mytunrpt.sql;《下面的附件1显示在运行mytunrpt.sql提示过程》
注意: 如果没有 执行(二. 安装软件包 ), 运行mytunrpt.sql时会提醒安装。
note: please first install p_mytun1.plb in another session, method: sqlplus "sys/change_on_install as sysdba" @p_mytun1.plb
note: please second install p_mytun2.plb in another session, method: sqlplus "sys/change_on_install as sysdba" @p_mytun2.plb

方式2: 采集正在运行的sql报告
sqlplus "/ as sysdba"
SQL> @running_sql.sql;


方式3:根据一个SQL的sql_id直接查询。 会生成一个clob的报告。

3.1 在工具(PL/SQL Developer等工具)中, 查询会生成一个clob的报告。
select mytun.mysql( (select dbid from v$database),
(select instance_number from v$instance),
'056j4snsvphk5' , --sql_id
100)
from dual;

100: 每个查询子集返回的行数, 建议值100

3.2 在工具(sqlplus 环境中)中, 把结果输出到文件中。
sqlplus "/ as sysdba"
set long 999999999
set heading off
set pages 40000
set feedback off
set echo off
SET LONGCHUNKSIZE 500
set linesize 500
SET LOBOFFSET 1
spool /xxx/xxx/a.txt;
select mytun.mysql( (select dbid from v$database),
(select instance_number from v$instance),
'056j4snsvphk5' , --sql_id
100)
from dual;
spool off;

四. 卸载mytun

$ sqlplus "/ as sysdba"

SQL> drop package mytun;

Package dropped.


一次隐藏较隐蔽的SQL优化问题----不要轻易的忽视count(列)

发表人:dbhelper | 发表时间: 2006年十二月24日, 17:14

xjwyq28@hotmail.com 原创 qq: 123614791


1. 场景说明:


stockpile ----IC卡的供求信息
xh-- 型号-----字符型

xh 列是 可为null的


index SP_XH, 是函数index, 定义如下create index SP_XH on stockpile (upper(xh));

注意:

( xh 列是 可为null的,会多读一次表

如果xh上带not null 的约束,只读index 不读表 )

高频度查询SQL
select /*+ INDEX(s SP_XH) */ count(s.xh)
from stockpile s
where upper(s.xh) like 'TL431%'

COUNT(S.XH)
-----------
186875


2. 问题出现:


读完index SP_XH 统计出数量后, 为何有多读一次STOCKPILE, 幸好它对性能的恶化程度还不算非常厉害,


select /*+ INDEX(s SP_XH) */ count(s.xh)
from stockpile s
where upper(s.xh) like 'TL431%'

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: FIRST_ROWS (Cost=272 Card=1Bytes=14)
1 0 SORT (AGGREGATE)
2 1 TABLE ACCESS (BY INDEX ROWID) OF 'STOCKPILE' (Cost=272 Card=284 Bytes=3976)
3 2 INDEX (RANGE SCAN) OF 'SP_XH' (NON-UNIQUE) (Cost=3 Card=284)

3. 分析解决:

a. 这个sql如果用count(*), 只读 index SP_XH { upper(s.xh) } , 不读表 。

b. 如果用 count(s.xh) , s.xh的数据只有在表中有 , 对应的index SP_XH { upper(s.xh) } 没有, 为排除s.xh空值影响, 所以读完index还要读表。

注解: <列> 与 某 function(列) 之间, ORACLE不能够 根据 其中一个判断另一个是否为NULL, 例如 function 是NVL(列, '1'), DECODE(列, NULL, '1', '2',NULL) 或是自定义函数, 根据函数处理后的列值-----> 不能判断 最初的<列> 是否为NULL。


c. 如改写成 count( upper(s.xh)) 一样可以只读index不读表。

select /*+ INDEX(s SP_XH) */ count( upper(s.xh))
from stockpile s
where upper(s.xh) like 'TL431%'


4. 回顾:

a. 函数index 中 存贮的是: 函数处理列后的值 和 行rowid。

b. 当xh 列是 可为null的,count(列) 出现, 走的又是 列的函数index, count(列)会多读一次表。

c. 当xh列上带not null 的约束, 只读index不读表。

d. count(列)出现时, 要看一下这对业务来说是否真的有必要, 如果只是程序员的一个书写习惯,不要轻易的忽视它。

xjwyq28@hotmail.com 原创 qq: 123614791


其中一个mview失败,一个命令来剔除失败mview的所需的log

发表人:dbhelper | 发表时间: 2006年十二月22日, 15:03

xjwyq28@hotmail.com 原创
场景:
1. 分布式数据库通过mview同步, 一个主表被多个mview来刷取数据。
2. 当其中一个含 mview的数据库失败,其上的那个mview停止刷新。
2. 坏了一个 mview , 主表的mlog$xxxx表的数据因为有一个没刷, 而不删除,主表的mlog$xxxx表不断变大。
3. mlog$xxxx 不断变大 , 影响其它正常的mview的刷新非常速度, 且iowait严重。


解决:

1. 在建主表库上使用DBMS_MVIEW.PURGE_LOG() 可以 删除mlog$中log (最近最少刷新的mview所需log), 那个失败的mview一般情况下就是

最近最少刷新(least recently refreshed) 的(根据实际情况定) 。

2. DBMS_MVIEW.PURGE_LOG() 后, mlog$xxxx表 的 仍热很大, 因为HWM(高水位线) 过高, 可用alter table xxxx move来降低。


回顾: mview 刷新的原理: 不再陈述。


使用方法如下:
=====================================PURGE_LOG Procedure=================================
This procedure purges rows from the materialized view log.

Syntax
DBMS_MVIEW.PURGE_LOG (
master IN VARCHAR2,
num IN BINARY_INTEGER := 1,
flag IN VARCHAR2 := 'NOP');

Parameters
Table 54-8 PURGE_LOG Procedure Parameters
Parameter Description
master
Name of the master table or master materialized view.

num
Number of least recently refreshed materialized views whose rows you want to remove from materialized view log. For

example, the following statement deletes rows needed to refresh the two least recently refreshed materialized views:

DBMS_MVIEW.PURGE_LOG('master_table', 2);

To delete all rows in the materialized view log, indicate a high number of materialized views to disregard, as in this

example:

DBMS_MVIEW.PURGE_LOG('master_table',9999);

This statement completely purges the materialized view log that corresponds to master_table if fewer than 9999 materialized

views are based on master_table. A simple materialized view whose rows have been purged from the materialized view log must

be completely refreshed the next time it is refreshed.

flag
Specify delete to guarantee that rows are deleted from the materialized view log for at least one materialized view. This

parameter can override the setting for the parameter num. For example, the following statement deletes rows from the

materialized view log that has dependency rows in the least recently refreshed materialized view:

DBMS_MVIEW.PURGE_LOG('master_table',1,'delete');

xjwyq28@hotmail.com 原创


oracle数据类型隐式转换----- 应急方案

发表人:dbhelper | 发表时间: 2006年十二月22日, 00:29

原创 xjwyq28@hotmail.com qq : 123614791
场景:
1. 数据列类型 和 输入值 类型 不一致
2. 已有列的常规index不能被使用,访问都是 TABLE ACCESS (FULL)。
3. 程序代码不能立刻修正。


解决 : 产生to_number(列)的 函数index, 却能够被应用, 避免一场数据库的灾难。

---------------- oracle数据隐式转换---- 应急方案-to_number(列) 函数index-----------------------------------------------

1. 列为数值型。
where ml_id= '36837053' 可以使用 index
where ml_id = 36837053 可以使用 index

2. 列为字符型varchar2 。
var_col='36837053' 可以使用 index

where var_col= 36837053 ; 不能用上其列index

(重要:产生to_number(列)的index 却可以被应用===》 在不能立刻改程序代码的情况下, 应急方案。 )


---------------------------------------- 明细测试如下-------------------------------------------------
create table TMP
(
ML_ID NUMBER(38) not null,
L_TYPE VARCHAR2(20),
OP_NAME VARCHAR2(20),
OP_ID VARCHAR2(1000),
OP_SQL VARCHAR2(1000),
PROVIDERID NUMBER(12) not null,
OPERATOR VARCHAR2(40),
OP_DATE TIMESTAMP(6),
LOG_TYPE CHAR(1),
VAR_COL VARCHAR2(40)
)


1. 当列为数值型。


select ml_id from TMP where ml_id='36837053'

select ml_id from TMP where ml_id = 36837053

create index TMP_ml_id on b_log_his200611_2(ml_id) tablespace newhcindex;


select ml_id from TMP where ml_id='36837053'
/

ML_ID
----------
36837053

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=FIRST_ROWS (Cost=1 Card=1 Bytes=6)
1 0 INDEX (RANGE SCAN) OF 'TMP_ML_ID' (INDEX) (Cost=1 Card=1 Bytes=6)

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
4 consistent gets
0 physical reads


select ml_id from TMP where ml_id = 36837053

ML_ID
----------
36837053

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=FIRST_ROWS (Cost=1 Card=1 Bytes=6 )
1 0 INDEX (RANGE SCAN) OF 'TMP_ML_ID' (INDEX) (Cost=1 Card=1 Bytes=6)


Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
4 consistent gets


2. 当列为字符型。
create table tmp as select * from b_log_his200611_2

alter table tmp add var_col varchar2(40);

update tmp set var_col = ml_id;

select ml_id, var_col from tmp

select ml_id from tmp where var_col='36837053'

create index tmp_var_col on tmp(var_col) tablespace newhcindex;


select ml_id from tmp where var_col='36837053'
/

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=FIRST_ROWS (Cost=1 Card=10 Bytes=350)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TMP' (TABLE) (Cost=1 Card=10 Bytes=350)
2 1 INDEX (RANGE SCAN) OF 'TMP_VAR_COL' (INDEX) (Cost=1 Card=7946)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
5 consistent gets


SQL> select ml_id from tmp where var_col= 36837053 ;
ML_ID
----------
36837053
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=FIRST_ROWS (Cost=3 Card=10 Bytes=350)
1 0 TABLE ACCESS (FULL) OF 'TMP' (TABLE) (Cost=3 Card=10 Bytes =350)
Statistics
----------------------------------------------------------
165 recursive calls
0 db block gets
9628 consistent gets
0 physical reads

select /*+ RULE INDEX(A tmp_var_col) */ A.ml_id from tmp A where A.var_col= 36837053
/
SQL> /
ML_ID
----------
36837053
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: RULE
1 0 TABLE ACCESS (FULL) OF 'TMP' (TABLE)

Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
9597 consistent gets


create index tmp_var_col_tonumber on tmp(to_number(var_col)) tablespace newhcindex;

select ml_id from tmp where var_col= 36837053
/
ML_ID
----------
36837053
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=FIRST_ROWS (Cost=1 Card=10 Bytes=350)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TMP' (TABLE) (Cost=1 Card=10 Bytes=350)
2 1 INDEX (RANGE SCAN) OF 'TMP_VAR_COL_TONUMBER' (INDEX) (Cost=1 Card=7946)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
5 consistent gets
0 physical reads

原创 xjwyq28@hotmail.com qq : 123614791


Valid XHTML 1.0 Strict and CSS. Powered by pLog
Design by Blog.lvwo.com