sybase 的 mda表使用
sybase 的 mda表使用
Adaptive Server 12.5.0.3包含一组新的系统性能监测系统表,利用这些系统表中的信息对分析ASE服务器的性能非常方便.也就是我们常说的mda table.
mda 表的使用不需要license。mda 表在master数据库中,都以mon打头命名,它的内容都在内存中,是只读的。
mda表的安装和使用:
ase缺省不安装mda表,需要使用$SYBASE/ASE-12_5/scripts目录(对于 NT 为 %SYBASE%\ASE-12_5\scripts)中的 installmontables 脚本创建它们。安装之前需要执行
sp_addserver loopback, null, @@servername
来创建一个名为“loopback”的服务器
安装完成后,如果要使用mda表,必须有mon_role权限,执行
grant role mon_role to loginname
配置enable monitoring参数使可以使用mda表
sp_configure "enable monitoring",1
可以使用
sp_configure Monitoring
查看mda表使用可以调整的参数。
这些参数大多都是需要根据使用mda表进行调整的,有的参数是静态的,需要重启ase,注意
mda 表的简单说明
monTables
提供对所有监控表的说明
monTableParameters
提供对每个监控表的所有可选参数的说明。
monTableColumns
说明每个监控表的所有列
monState
提供有关 Adaptive Server 的总体状态的信息
monEngine
提供有关 Adaptive Server 引擎的统计信息
monDataCache
返回与 Adaptive Server 数据高速缓存有关的统计信息。
monProcedureCache
返回与 Adaptive Server 过程高速缓存有关的统计信息。
monOpenDatabases
提供与当前使用的数据库有关的状态信息和统计信息
monSysWorkerThread
返回与工作线程有关的服务器范围的统计信息。
monNetworkIO
返回网络 I/O 统计信息。
monErrorLog
从 Adaptive Server 错误日志返回最新的错误消息。
monLocks
为每个对象返回任何进程持有的以及请求的所有锁的列表。
monDeadLock
提供有关在 Adaptive Server 中已经出现的最新死锁的信息。
monWaitClassInfo
为所有等待类提供文本说明
monWaitEventInfo
为强制进程在 Adaptive Server 内等待的每种可能情况提供文本说明。
monCachedObject
返回当前在高速缓存中具有页的所有对象和索引的统计信息。
monCachePool
提供为所有高速缓存分配的所有池的统计信息。
monOpenObjectActivity
提供所有打开对象的统计信息。
monIOQueue
提供设备 I/O 统计信息,细分为每个设备上常规数据库和临时数据库的数据和日志 I/O
monDeviceIO
返回与设备有关的统计信息。
monSysWaits
提供一个服务器范围的视图,指出进程等待事件的位置。
monProcess
提供有关当前正在执行的或等待的进程的详细统计信息。
monProcessLookup
提供一些信息,这些信息使应用程序、用户、客户机等可以跟踪进程。
monProcessActivity
提供有关进程活动的详细统计信息。
monProcessNetIO
提供每个进程的网络 I/O 活动信息。
monProcessObject
提供有关进程已经访问的对象的统计信息。
monProcessWaits
提供一个服务器范围的视图,指出进程等待事件的位置。
monProcessStatement
提供当前正在执行的语句的信息。
monProcessSQLText
提供当前正在执行的 SQL 文本
monSysPlanText
提供最新生成的文本计划。
monSysStatement
提供有关最近执行的语句的统计信息。
monCachedProcedures
提供当前存储在过程高速缓存中的所有过程的统计信息。
monSysSQLText
提供已经执行的最新 SQL 文本或当前正在执行的 SQL 文本。
monProcessProcedures
返回进程正在执行的所有过程的列表。
一个简单例子
看哪个进程占用cpu最多,它在干什么
select ps.SPID, ps.CpuTime,pst.LineNumber, pst.SQLText
from master..monProcessSQLText pst,
master..monProcessStatement ps
where ps.SPID = pst.SPID
and ps.CpuTime = (select max(CpuTime) from master..monProcessStatement)
order by SPID, LineNumber
关于mda一个很好的存储过程,sypron的
/*
* SP_MDA.SQL
*
* Description
* ===========
* This file contains various stored procedures related to the so-called
* "MDA tables". These tables provide low-level monitoring information. They
* were introduced in ASE 12.5.0.3.
*
* This script installs the following procedures:
* sp_mda_help - for searching through MDA table/columns names
* sp_mda_io - monitors logical I/O by T-SQL statements
* sp_mda_wait - displays wait event info
*
* For usage information, specify '?' as the first parameter
* to these procedures.
*
*
* Installation
* ============
* Execute this script using "isql", using a login having 'sa_role'.
* The stored procedures will be created in the sybsystemprocs database.
*
*
* Notes
* =====
* - The MDA tables are a new feature, and a lot is still to be
* discovered about them. Check back at [url=][/url] for
* new additions.
*
*
* Revision History
* ================
* Version 1.0 Jun-2003 First version
* Version 1.1 Aug-2004 Added sp_mda_wait; various improvements
* Version 1.2 Jan-2005 Adapted for case-insensitive sort order
*
*
* Copyright Note & Disclaimer :
* =============================
* This software is provided "as is"; there is no warranty of any kind.
* While this software is believed to work accurately, it may not work
* correctly and/or reliably in a production environment. In no event shall
* Rob Verschoor and/or Sypron B.V. be liable for any damages resulting
* from the use of this software.
* You are allowed to use this software free of charge for your own
* professional, non-commercial purposes.
* You are not allowed to sell or bundle this software or use it for any
* other commercial purpose without prior written permission from
* Rob Verschoor/Sypron B.V.
* You may (re)distribute only unaltered copies of this software, which
* must include this copyright note, as well as the copyright note in
* the header of each stored procedure.
*
* Note: All trademarks are acknowledged.
*
* Please send any comments, bugs, suggestions etc. to the below email
* address.
*
* Copyright (c) 2003-2005 Rob Verschoor/Sypron B.V.
* P.O.Box 10695
* 2501 HR Den Haag
* The Netherlands
*
* Email: [email=sypron@sypron.nl]sypron@sypron.nl[/email]
* WWW : [url=][/url]
*----------------------------------------------------------------------------
*/
set nocount on
go
set flushmessage on
go
-- check we have sa_role
if charindex("sa_role", show_role()) = 0
begin
print ""
print ""
print " This script requires 'sa_role'."
print " Aborting..."
print " "
print " "
print ""
set background on -- terminate this script now
end
go
-- We need to be in 12.5.0.3+
-- First test for 12.0 to avoid a syntax error on license_enabled()
if isnull(object_id("master.dbo.sysqueryplans"),99) >= 99
begin
print ""
print ""
print " This script requires ASE 12.5.0.3 or later."
print " Aborting..."
print " "
print " "
print ""
set background on -- terminate this script now
end
go
-- We need to be in 12.5.0.3+
if license_enabled('ASE_XRAY') = NULL
begin
print ""
print ""
print " This script requires ASE 12.5.0.3 or later."
print " Aborting..."
print " "
print " "
print ""
select syb_quit() -- terminate this script now
end
go
-- Check whether the user has already installed the MDA tables
if object_id('master..monTables') = NULL
begin
print ""
print ""
print " This script requires the MDA tables to be installed."
print " Among other things, this involves executing the 'installmontables'"
print " script."
print " See the ASE documentation, or [url=][/url], for more "
print " information."
print " "
print " Aborting..."
print " "
print " "
print ""
select syb_quit() -- terminate this script now
end
go
use sybsystemprocs
go
print ""
print " Installing 'sp_mda_help' ..."
go
if object_id('sp_mda_help') <> NULL
drop proc sp_mda_help
go
create proc sp_mda_help
/* Copyright (c) 2003-2005 Rob Verschoor/Sypron B.V. */
@tab varchar(30) = NULL,
@col varchar(30) = NULL
as
begin
declare @n int, @match varchar(40), @TabID int
if @tab = '?'
or (@tab = NULL and @col = NULL)
begin
print " "
print " Usage: sp_mda_help { table_name_pattern | column_name_pattern }"
print ""
print " This procedure displays information about MDA tables and/or columns"
print " "
print " Arguments:"
print " table_name_pattern - pattern matching MDA table names"
print " tcolumn_name_pattern - pattern matching MDA column names"
print ""
print "Examples:"
print " Find all tables with cache information:"
print " sp_mda_help 'cache' "
print ""
print " Find all columns related to SQL text or statements:"
print " sp_mda_help null, 'sql' "
print ""
print " Copyright (c) 2003-2005 Rob Verschoor/Sypron B.V."
print " Visit [url=][/url]"
print " "
return 0
end
if @tab = NULL select @tab = "%"
if @col = NULL select @col = "%"
if @tab != "%"
begin
select @match = upper(@tab)
select @n = count(*)
from master..monTables
where upper(TableName) like @match
if @n = 0
begin
select @match = "%"+upper(@tab)+"%"
select @n = count(*)
from master..monTables
where upper(TableName) like @match
end
if @n = 1
begin
select @TabID = TableID
from master..monTables
where upper(TableName) like @match
select TableName, Description
from master..monTables
where upper(TableName) like @match
select ColumnName + " " + substring(TypeName,1,9) + " " + Description
from master..monTableColumns
where TableID = @TabID
select ParameterName + " " + substring(TypeName,1,9) + " " + Description
from master..monTableParameters
where TableID = @TabID
end
if @n > 1
begin
select TableName = TableName + " " + Description
from master..monTables
where upper(TableName) like "%"+upper(@tab)+"%"
order by TableName
end
end
if @col != "%"
begin
select TableName, ColumnName, substring(TypeName,1,9) TypeName
from master..monTableColumns
where upper(ColumnName) like "%"+upper(@col)+"%"
order by 1,2
end
end
go
grant execute on sp_mda_help to public -- mon_role is needed anyway
go
dump tran sybsystemprocs with truncate_only
go
----------------------------------------------------------------------------
if object_id('sp_mda_io') <> NULL
drop proc sp_mda_io
go
print ""
print " Installing 'sp_mda_io' ..."
go
create procedure sp_mda_io
/* Copyright (c) 2003-2005 Rob Verschoor/Sypron B.V. */
@p_cmd varchar(16384) = NULL,
@debug int = 0
as
begin
declare @cmd varchar(1000)
declare @tabname varchar(60), @kpid_this int, @init int
set nocount on
select @init = 0
if @p_cmd = '?'
begin
print " "
print " Usage: sp_mda_io '' [, debug ] "
print ""
print " This procedure displays information about logical/physical I/Os used by T-SQL statements"
print " "
print " Arguments:"
print " '' - a T-SQL command batch "
print " debug - when set to 1, print debugging info for this procedure"
print ""
print " Copyright (c) 2003-2005 Rob Verschoor/Sypron B.V."
print " Visit [url=][/url]"
print " "
return 0
end
--
-- Determine name for temp table.
-- We cannot use a #temp table since this cannot be created from
-- within exec-immediate (well, it can, but it'd be dropped
-- immediately again when exiting the exec-imm scope)
--
select @tabname = db_name(@@tempdbid) + ".guest.tab_mda_io_" +
convert(varchar,@@spid)
-- We need the kpid to verify the table is this session
select @kpid_this = kpid
from master.dbo.sysprocesses
where spid = @@spid
-- debug
if @debug != 0
begin
print "Tabname= %1! ; kpid= %2!", @tabname, @kpid_this
end
if object_id(@tabname) = NULL
begin
select @init = 1
exec("select kpid = 0, dt = getdate(), " +
"LogicalReads = 0, PhysicalReads = 0, PhysicalWrites = 0 into " +
@tabname
)
end
select @cmd =
"declare @kpid_mda int declare @lio int, @pio int, @pwr int, @init int, @secs int select @init = 0" +
"select @kpid_mda = kpid from " + @tabname + " " +
"if @kpid_mda != " + convert(varchar,@kpid_this) + " " +
"begin select @init = 1 print 'Initialised I/O monitoring for this session' end " +
"update " + @tabname + " " +
"set kpid = " + convert(varchar,@kpid_this) + " " +
" , dt = getdate() " +
" , LogicalReads = m.LogicalReads " +
" , PhysicalReads = m.PhysicalReads " +
" , PhysicalWrites = m.PhysicalWrites " +
" , @secs = ceiling(datediff(ms, t.dt, getdate())/1000.0)" +
" , @lio = m.LogicalReads - t.LogicalReads" +
" , @pio = m.PhysicalReads - t.PhysicalReads " +
" , @pwr = m.PhysicalWrites - t.PhysicalWrites " +
"from " + @tabname + " t, master.dbo.monProcessActivity m where SPID=@@spid " +
"if @init = 0 begin print '' print '[spid=%1!] #secs=%2! #Log.Reads= %3! #Phys.Reads= %4! #Phys.Writes= %5!', @@spid, @secs, @lio, @pio, @pwr end"
if @debug != 0
begin
print "cmd=[%1!]", @cmd
end
exec(@cmd)
if @p_cmd = NULL
begin
return (0)
end
exec(@p_cmd)
exec(@cmd)
return (0)
end
go
grant execute on sp_mda_io to public -- mon_role is needed anyway
go
dump tran sybsystemprocs with truncate_only
go
----------------------------------------------------------------------------
if object_id ('sp_mda_wait') != NULL
drop procedure sp_mda_wait
go
print ""
print " Installing 'sp_mda_wait' ..."
go
create procedure sp_mda_wait
/* Copyright (c) 2005 Rob Verschoor/Sypron B.V. */
@p1 varchar(20) = NULL,
@interval char(8) = "00:00:10",
@top_n int = 20,
@debug int = 0 -- if <> 0, prints raw sampling data
as
begin
declare @dt1 datetime, @dt2 datetime
declare @c varchar(100), @suid int, @kpid int, @kpid2 int
declare @v varchar(30), @groupwait int, @delta_secs int
declare @tot_spids int, @sys_spids int, @user_spids int
declare @spid int
set nocount on
select @p1 = lower(ltrim(rtrim(@p1)))
if isnull(@p1, '?') = '?'
or
((@p1 not in ('all', 'server')) and (@p1 not like "[0-9]%"))
begin
print ""
print " Usage: sp_mda_wait { 'server' | '' | 'all' } [, 'hh:mm:ss' [, top_N ]]"
print " Displays wait event details over a certain interval (default = 10 seconds)."
print " top_N applies only to the 'server' and '' parameters and shows only the"
print " top N (default = 20) wait events. "
print " "
print " Notes:"
print " sp_mda_wait 'server' - displays cumulative wait event info for the entire ASE server"
print ""
print " sp_mda_wait '' - displays wait event info for the specified spid"
print ""
print " sp_mda_wait 'all' - displays wait event info for all spids, including session details"
print " such as currently executing SQL"
print ""
print ""
print " Copyright (c) 2005 Rob Verschoor/Sypron B.V."
print " Visit [url=][/url]"
return 0
end
if @p1 like "[0-9]%"
begin
select @spid = convert(int, @p1)
select @suid = suid, @kpid = kpid
from master.dbo.sysprocesses
where spid = @spid
if @@rowcount = 0
begin
print "Spid %1! not found", @spid
return -1
end
end
-- prepare #temp tables
select WaitTime, Waits, WaitEventID, SPID = 0, KPID = 0
into #t
from master.dbo.monSysWaits
where 1 = 0
select WaitTime, Waits, WaitEventID, SPID = 0, KPID = 0
into #t2
from master.dbo.monSysWaits
where 0 = 1
-- take snapshot
if @p1 = 'server'
begin
-- get wait cumulative event details for the entire server
insert #t
select WaitTime, Waits, WaitEventID, 0, 0
from master.dbo.monSysWaits
end
else
begin
-- get wait event detail per process
insert #t
select WaitTime, Waits, WaitEventID, SPID, KPID
from master.dbo.monProcessWaits
end
if @debug != 0 select * from #t
-- wait ...
select @dt1 = getdate()
waitfor delay @interval
select @dt2 = getdate()
-- ready waiting, take snapshot again
if @p1 = 'server'
begin
insert #t2
select WaitTime, Waits, WaitEventID, 0, 0
from master.dbo.monSysWaits
end
else
begin
if @spid > 0
begin
select @kpid2 = kpid
from master.dbo.sysprocesses
where spid = @spid
if @kpid2 != @kpid
begin
print "Spid %1! has changed during the waiting interval. Sorry...", @spid
return -1
end
end
-- get wait event details per process
insert #t2
select WaitTime, Waits, WaitEventID, SPID, KPID
from master.dbo.monProcessWaits
-- get some details about each process
select *
into #sp
from master..sysprocesses
-- get details about the SQL currently being executed
select * into #st from master.dbo.monProcessStatement
select * into #sq from master.dbo.monSysSQLText
end
if @debug != 0 select * from #t2
-- Calculate the wait event time deltas
-- Note: we're only including wait events that existed both at the start
-- and the end of the wait interval.
--
select #t.SPID, #t.KPID,
WaitTime = #t2.WaitTime - #t.WaitTime,
Waits = #t2.Waits - #t.Waits,
WaitEventID = #t.WaitEventID,
sortid = identity(9)
into #t3
from #t, #t2
where #t.WaitEventID = #t2.WaitEventID
and #t.SPID = #t2.SPID
and #t.KPID = #t2.KPID
order by SPID, (#t2.WaitTime - #t.WaitTime) desc, (#t2.Waits - #t.Waits) desc
-- if taken from monProcessWaits, convert the milliseconds to seconds
if @p1 != 'server'
begin
update #t3
set WaitTime = (WaitTime + 500) / 1000
end
if @debug != 0 select * from #t3
-- report results
select @delta_secs = floor((datediff(ms, @dt1, @dt2)+100)/1000.0)
--select convert(varchar,@dt1,109) dt1, convert(varchar,@dt2,109) dt2
print ""
select @v = "(" + substring(substring(@@version,28,50), 1, charindex("/", substring(@@version,38,20))+9) + ")"
select @c = "ASE server: " + @@servername + " " + @v
print @c
select @c = "Sampling period: " + str_replace(convert(varchar,@dt1,106),' ','-') + " " + convert(varchar,@dt1,108) + " - " + convert(varchar,@dt2,108) + " (" + convert(varchar,@delta_secs) + " seconds)"
print @c
if @p1 = 'server'
begin
select @c = "Wait event times for: entire ASE server"
end
else
begin
if @p1 = 'all'
begin
select @c = "Wait event times for: all spids"
end
else
begin
select @c = "Wait event times for: spid " + convert(varchar, @spid) + " (" + suser_name(@suid) + ")"
end
end
print @c
if @p1 != 'server'
begin
print "Spid of current session: %1!", @@spid
end
print ""
if @p1 != 'all'
begin
-- report wait event info for a single spid or for overall ASE server
if @spid > 0
begin
delete #t3
where SPID != @spid
end
-- report detailed wait events
set rowcount @top_n
select
WaitSecs = sw.WaitTime,
--str((sw.WaitTime*100.0/@delta_secs),3) " %",
NrWaits = sw.Waits,
WaitEvent = wei.Description
, sw.WaitEventID
--, wei.WaitClassID
from #t3 sw,
master.dbo.monWaitEventInfo wei,
master.dbo.monWaitClassInfo wci
where sw.WaitEventID = wei.WaitEventID
and wci.WaitClassID = wei.WaitClassID
and (sw.Waits > 0 or sw.WaitTime > 0)
order by sw.WaitTime desc, sw.Waits desc
set rowcount 0
end
else
begin
-- report detailed wait events for all spids
-- set rowcount @top_n
select
sortcol = convert(numeric(30), (SPID * 100000) + 10 + sw.sortid),
SPID = -1,
SPIDstr = space(5),
Info = right(space(10) + convert(varchar,sw.WaitTime),10) + ' / ' + right(space(5) + convert(varchar, sw.Waits),5) + ': ' + wei.Description + ' (' + convert(varchar(3),wei.WaitEventID) + ')'
into #t4
from #t3 sw,
master.dbo.monWaitEventInfo wei,
master.dbo.monWaitClassInfo wci
where sw.WaitEventID = wei.WaitEventID
and wci.WaitClassID = wei.WaitClassID
and (sw.Waits > 0 or sw.WaitTime > 0)
insert #t4
select distinct (#t3.SPID * 100000),
#t3.SPID,
SPIDstr = right(space(5) + convert(varchar, #t3.SPID),5),
ltrim(suser_name(suid) + ' ' + cmd) + ' ' + status + ' ' + hostname + ' ' + ipaddr + ' ' + program_name
from #t3, #sp
where #t3.SPID = #sp.spid
and #t3.KPID = #sp.kpid
if @debug != 0 select * from #t4
insert #t4
select distinct (SPID * 100000) + 99, -1, ' ', ' '
from #t4
where SPID >= 0
insert #t4
select (#sq.SPID * 100000) + 1, -1, ' ',
'Proc: ' + db_name(DBID) + '..' + object_name(ProcedureID,DBID) + ' Line# in proc: ' + convert(varchar,#st.LineNumber)
from #st, #sq
where #st.SPID = #sq.SPID
and #st.KPID = #sq.KPID
and #st.BatchID = #sq.BatchID
and object_name(ProcedureID,DBID) != NULL
order by #sq.SPID
insert #t4
select (#sq.SPID * 100000) + 1, -1, ' ',
'Line# in batch: ' + convert(varchar,#st.LineNumber)
from #st, #sq
where #st.SPID = #sq.SPID
and #st.KPID = #sq.KPID
and #st.BatchID = #sq.BatchID
and object_name(ProcedureID,DBID) = NULL
order by #sq.SPID
insert #t4
select sortcol = (#sq.SPID * 100000) + 2, SPID= -1, SPIDstr = ' ',
sql = str_replace(,str_replace('SQL batch: ' + rtrim(#sq.SQLText) + "ZZZXXXYYY", char(10) + "ZZZXXXYYY", ' '), "ZZZXXXYYY", ' ')
from #st, #sq
where #st.SPID = #sq.SPID
and #st.KPID = #sq.KPID
and #st.BatchID = #sq.BatchID
order by #sq.SPID
print " spid login command status hostname clientIPaddress program_name"
print " procedure and/or SQL being executed"
print " waittime(sec)/#waits: wait event description (event ID)"
-- return the formatted results for each process
select SPIDstr " ", Info " " from #t4
order by sortcol
-- set rowcount 0
end
-- disable the wait time per event class for now...
select @groupwait = 0
if @groupwait = 1
begin
-- report wait events by group
select
WaitSecs = sum(sw.WaitTime), NrWaits = sum(sw.Waits),
NrWaitEventTypes = count(distinct wei.WaitEventID),
WaitClass = wci.Description, wci.WaitClassID
from #t3 sw,
master.dbo.monWaitClassInfo wci,
master.dbo.monWaitEventInfo wei
where sw.WaitEventID = wei.WaitEventID
and wci.WaitClassID = wei.WaitClassID
and sw.Waits > 0
group by wci.WaitClassID, wci.Description
order by 1 desc, 2 desc
end
-- report #spids
select @tot_spids = count(*) from master..sysprocesses
select @sys_spids = count(*) from master..sysprocesses where suid = 0
select @user_spids = @tot_spids - @sys_spids
print " "
print " Total #spids in ASE server: %1! (system: %2!; user: %3!)", @tot_spids, @sys_spids, @user_spids
end
go
grant execute on sp_mda_wait to public -- mon_role is needed anyway
go
dump tran sybsystemprocs with truncate_only
go
----------------------------------------------------------------------------
print ""
print " For on-line help information, run these procedures with '?' as "
print " the first parameter."
print " Ready."
print ""
print " Copyright (c) 2003-2005 Rob Verschoor/Sypron B.V."
go
--
-- end
--
写的很简单,算是一个入门,具体可以参考sybase的手册。不对地方请指正。
可以转载,请注明作者 echoaix