<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://petersap.nl/SybaseWiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Bobh</id>
		<title>SybaseWiki - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="http://petersap.nl/SybaseWiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Bobh"/>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php/Special:Contributions/Bobh"/>
		<updated>2026-04-04T20:46:00Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.24.2</generator>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=Sp_mon_sql2--ASE_spid_activity_monitor&amp;diff=1933</id>
		<title>Sp mon sql2--ASE spid activity monitor</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=Sp_mon_sql2--ASE_spid_activity_monitor&amp;diff=1933"/>
				<updated>2010-03-24T10:05:33Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: corrected spacing&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: This SP uses the MDA tables.&amp;lt;BR&amp;gt;&lt;br /&gt;
This sp is for getting a clear list of currently active spids with full details including login, db, blocking spid, processing time, query start time, cpu usage, logical and physical i/o, currently executing command etc.  To maximise clarity, all info is displayed on one line for each spid.  Alternate info is also available by running with the &amp;quot;x&amp;quot; switch which includes, login time, host process, originating host and other information which may be useful for tracking down the source of a problem external to ASE.&lt;br /&gt;
&lt;br /&gt;
Example output (normal usage)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     Spid   Login        DB               Hostname     blocked StartTime           Dmins  Dtime CpuTime     LogicalReads PhysicalReads Command&lt;br /&gt;
 --- ------ ------------ ---------------- ------------ ------- ------------------- ------ ----- ----------- ------------ ------------- ------------------------------&lt;br /&gt;
 ***    126 sa           PROD_DB1         prod-srv1          0 Mar 24 2010 12:13AM    570 09:30           0           42             0 SELECT&lt;br /&gt;
 ***    143 app_user1    PROD_DB1         user-hosta         0 Mar 24 2010  9:38AM      6 00:06          10            0             0 SELECT&lt;br /&gt;
 ***     32 app_user1    PROD_DB1         user-hostb       143 Mar 24 2010  9:38AM      5 00:05           0           20             0 SELECT&lt;br /&gt;
 ***     44 cron         cron_tempdb      prod-srv1          0 Mar 24 2010  9:40AM      3 00:03           0            0             0 WAITFOR&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example output (extended info)&lt;br /&gt;
 Spid   Login        DB              Hostname     blocked StartTime           Dmins  Dtime Application  OS PID  Blocked(s)  Logged in ClientIP        Command&lt;br /&gt;
 ------ ------------ --------------- ------------ ------- ------------------- ------ ----- ------------ ------- ----------- --------- --------------- ------------------------------&lt;br /&gt;
    126 sa           PROD_DB1        prod-srv1          0 Mar 24 2010 12:13AM    570 09:30 isql         6181           NULL 15:25:59  12.7.3.55       SELECT&lt;br /&gt;
    143 user1        PROD_DB1        user-hosta         0 Mar 24 2010  9:38AM      6 00:06 NULL         -              NULL 15:25:09  12.7.3.56       SELECT&lt;br /&gt;
     32 user1        PROD_DB1        user-hostb       143 Mar 24 2010  9:38AM      5 00:05 NULL         -              NULL 15:26:04  12.7.3.57       SELECT&lt;br /&gt;
     44 cron         cron_tempdb     prod-srv1          0 Mar 24 2010  9:40AM      3 00:03 isql         8639           NULL 15:26:04  12.7.3.55       WAITFOR&lt;br /&gt;
&lt;br /&gt;
Usage summary:&amp;lt;BR&amp;gt;&lt;br /&gt;
 - sp__mon_sql2            ((no params), returns standard info for all spids)&lt;br /&gt;
 - sp__mon_sql2 spid       (returns standard info for a specific spid)&lt;br /&gt;
 - sp__mon_sql2 null, &amp;quot;x&amp;quot;  (returns extended info for all spids)&lt;br /&gt;
 - sp__mon_sql2 spid, &amp;quot;x&amp;quot;  (returns extended info for a specific spid)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
create procedure sp__mon_sql2&lt;br /&gt;
(&lt;br /&gt;
@spid int = null, -- default to retrieve info for all spids&lt;br /&gt;
@extinfo char(1) = &amp;quot;u&amp;quot; -- extended info switch, default “u” (unset) is for off, “x” and “X” are for on)&lt;br /&gt;
)&lt;br /&gt;
as&lt;br /&gt;
------------------------------&lt;br /&gt;
-- Procedure: sp__mon_sql2&lt;br /&gt;
--   Created: April 2008&lt;br /&gt;
--    Author: Bob Holmes (Email: cambob@gmail.com)&lt;br /&gt;
--     Usage: sp__mon_sql2 [spid]&lt;br /&gt;
-- Version  : 1.1&lt;br /&gt;
------------------------------&lt;br /&gt;
--Modification history:&lt;br /&gt;
--bobh - if 1 is specified as the spid number then alternate info is returned (dirty hack)&lt;br /&gt;
--bobh: 14/09/2009: Dirty hack mentioned above removed.  Usage is now as follows:&lt;br /&gt;
--                  - sp__mon_sql2          ((no params), returns standard info for all spids)&lt;br /&gt;
--                  - sp__mon_sql2 spid     (returns standard info for a specific spid)&lt;br /&gt;
--                  - sp__mon_sql2 null, x  (returns extended info for all spids)&lt;br /&gt;
--                  - sp__mon_sql2 spid, x  (returns extended info for a specific spid)&lt;br /&gt;
------------------------------&lt;br /&gt;
-- INFO:&lt;br /&gt;
-- The three *'s are a grep key for a shell script to use to extract the lines needed for alerting.&lt;br /&gt;
------------------------------&lt;br /&gt;
set nocount on&lt;br /&gt;
&lt;br /&gt;
--prep - setup input variables for run mode&lt;br /&gt;
if @spid=null&lt;br /&gt;
begin&lt;br /&gt;
  select @spid=0&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--part 1 - snapshot&lt;br /&gt;
set forceplan on&lt;br /&gt;
select 	s.StartTime, &lt;br /&gt;
	convert(smallint,(datediff(mi,StartTime,getdate()))) Dmins,  &lt;br /&gt;
	p.spid, &lt;br /&gt;
	p.hostname, &lt;br /&gt;
	p.suid, &lt;br /&gt;
	p.dbid, &lt;br /&gt;
	p.cmd, &lt;br /&gt;
        p.blocked,&lt;br /&gt;
	s.CpuTime, &lt;br /&gt;
	s.LogicalReads, &lt;br /&gt;
	s.PhysicalReads,&lt;br /&gt;
	p.status, &lt;br /&gt;
	p.loggedindatetime,&lt;br /&gt;
	p.program_name, &lt;br /&gt;
	l.ClientOSPID, &lt;br /&gt;
	p.time_blocked, &lt;br /&gt;
	p.ipaddr&lt;br /&gt;
into #processmon2&lt;br /&gt;
from master..sysprocesses p, master..monProcessStatement s, master..monProcessLookup l&lt;br /&gt;
where p.spid != @@spid&lt;br /&gt;
and p.spid *= s.SPID&lt;br /&gt;
and l.SPID = p.spid&lt;br /&gt;
and suid &amp;lt;&amp;gt; 0&lt;br /&gt;
order by p.spid&lt;br /&gt;
set forceplan off&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
--&lt;br /&gt;
--case 1 - no params (0 and &amp;quot;u&amp;quot;)&lt;br /&gt;
if @spid=0 and @extinfo=&amp;quot;u&amp;quot; -- display standard information for all spids&lt;br /&gt;
begin&lt;br /&gt;
-- display header information for multiple spids&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;Process Summary (Order by Dmins, CpuTime, LogicalReads, PhysicalReads Desc )&amp;quot;&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;&amp;quot;&lt;br /&gt;
  select distinct &amp;quot;***&amp;quot;,&lt;br /&gt;
  spid Spid,&lt;br /&gt;
  convert(char(12),suser_name(suid)) Login,&lt;br /&gt;
  convert(char(16),db_name(dbid)) DB,&lt;br /&gt;
  (case hostname when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),hostname) end) Hostname,&lt;br /&gt;
  blocked,&lt;br /&gt;
  convert(varchar(19),StartTime) StartTime,&lt;br /&gt;
  Dmins,&lt;br /&gt;
  right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins/60)),2) + &amp;quot;:&amp;quot; + right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins%60)),2) Dtime,&lt;br /&gt;
  CpuTime,&lt;br /&gt;
  LogicalReads,&lt;br /&gt;
  PhysicalReads,&lt;br /&gt;
  cmd Command&lt;br /&gt;
  from #processmon2&lt;br /&gt;
  where cmd &amp;lt;&amp;gt; &amp;quot;AWAITING COMMAND&amp;quot;&lt;br /&gt;
  order by Dmins desc, CpuTime Desc, LogicalReads Desc, PhysicalReads Desc&lt;br /&gt;
end&lt;br /&gt;
--&lt;br /&gt;
--&lt;br /&gt;
--case 2 &lt;br /&gt;
else if @spid=0 and @extinfo=&amp;quot;x&amp;quot; -- extended info for all spids&lt;br /&gt;
begin&lt;br /&gt;
-- display header information for multiple spids&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;Process Summary (Order by Dmins, CpuTime, LogicalReads, PhysicalReads Desc )&amp;quot;&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;&amp;quot;&lt;br /&gt;
select &lt;br /&gt;
  spid Spid,&lt;br /&gt;
  convert(char(12),suser_name(suid)) Login,&lt;br /&gt;
  convert(char(15),db_name(dbid)) DB,&lt;br /&gt;
  (case hostname when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),hostname) end) Hostname,&lt;br /&gt;
  blocked,&lt;br /&gt;
  convert(varchar(19),StartTime) StartTime,&lt;br /&gt;
  Dmins,&lt;br /&gt;
  right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins/60)),2) + &amp;quot;:&amp;quot; + right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins%60)),2) Dtime,&lt;br /&gt;
  (case program_name when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),program_name) end) Application,&lt;br /&gt;
  (case ClientOSPID when NULL then &amp;quot;-&amp;quot; else convert(char(7),ClientOSPID) end) &amp;quot;OS PID&amp;quot;,&lt;br /&gt;
  time_blocked &amp;quot;Blocked(s)&amp;quot;,&lt;br /&gt;
  convert(char(8),loggedindatetime,108) &amp;quot;Logged in&amp;quot;,&lt;br /&gt;
  convert(char(15),ipaddr) ClientIP,&lt;br /&gt;
  cmd Command&lt;br /&gt;
  from #processmon2&lt;br /&gt;
  where cmd &amp;lt;&amp;gt; &amp;quot;AWAITING COMMAND&amp;quot;&lt;br /&gt;
  order by Dmins desc, CpuTime Desc, LogicalReads Desc, PhysicalReads Desc&lt;br /&gt;
end&lt;br /&gt;
--&lt;br /&gt;
--&lt;br /&gt;
-- case 3 &lt;br /&gt;
else if @spid &amp;lt;&amp;gt; 0 and @extinfo = &amp;quot;u&amp;quot; -- display standard info for specific spid&lt;br /&gt;
begin&lt;br /&gt;
  select distinct &amp;quot;***&amp;quot;,&lt;br /&gt;
  spid Spid,&lt;br /&gt;
  convert(char(12),suser_name(suid)) Login,&lt;br /&gt;
  convert(char(16),db_name(dbid)) DB,&lt;br /&gt;
  (case hostname when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),hostname) end) Hostname,&lt;br /&gt;
  blocked,&lt;br /&gt;
  convert(varchar(19),StartTime) StartTime,&lt;br /&gt;
  Dmins,&lt;br /&gt;
  right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins/60)),2) + &amp;quot;:&amp;quot; + right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins%60)),2) Dtime,&lt;br /&gt;
  CpuTime,&lt;br /&gt;
  LogicalReads,&lt;br /&gt;
  PhysicalReads,&lt;br /&gt;
  cmd Command&lt;br /&gt;
  from #processmon2&lt;br /&gt;
  where spid = @spid&lt;br /&gt;
  order by Dmins desc, CpuTime Desc, LogicalReads Desc, PhysicalReads Desc&lt;br /&gt;
end&lt;br /&gt;
--&lt;br /&gt;
--&lt;br /&gt;
-- case 4&lt;br /&gt;
else if @spid &amp;lt;&amp;gt; 0 and @extinfo = &amp;quot;x&amp;quot; -- display extended info for specific spid&lt;br /&gt;
begin&lt;br /&gt;
-- display header information for multiple spids&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;Process Summary (Order by Dmins, CpuTime, LogicalReads, PhysicalReads Desc )&amp;quot;&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;&amp;quot;&lt;br /&gt;
select &lt;br /&gt;
  spid Spid,&lt;br /&gt;
  convert(char(12),suser_name(suid)) Login,&lt;br /&gt;
  convert(char(15),db_name(dbid)) DB,&lt;br /&gt;
  (case hostname when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),hostname) end) Hostname,&lt;br /&gt;
  blocked,&lt;br /&gt;
  convert(varchar(19),StartTime) StartTime,&lt;br /&gt;
  Dmins,&lt;br /&gt;
  right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins/60)),2) + &amp;quot;:&amp;quot; + right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins%60)),2) Dtime,&lt;br /&gt;
  (case program_name when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),program_name) end) Application,&lt;br /&gt;
  (case ClientOSPID when NULL then &amp;quot;-&amp;quot; else convert(char(7),ClientOSPID) end) &amp;quot;OS PID&amp;quot;,&lt;br /&gt;
  time_blocked &amp;quot;Blocked(s)&amp;quot;,&lt;br /&gt;
  convert(char(8),loggedindatetime,108) &amp;quot;Logged in&amp;quot;,&lt;br /&gt;
  convert(char(15),ipaddr) ClientIP,&lt;br /&gt;
  cmd Command&lt;br /&gt;
  from #processmon2&lt;br /&gt;
  where spid = @spid&lt;br /&gt;
  order by Dmins desc, CpuTime Desc, LogicalReads Desc, PhysicalReads Desc&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:ASE]]&lt;br /&gt;
[[Category:MDA tables]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=Sp_mon_sql2--ASE_spid_activity_monitor&amp;diff=1932</id>
		<title>Sp mon sql2--ASE spid activity monitor</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=Sp_mon_sql2--ASE_spid_activity_monitor&amp;diff=1932"/>
				<updated>2010-03-24T10:04:31Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: Added examples of output (with some dummy values)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: This SP uses the MDA tables.&amp;lt;BR&amp;gt;&lt;br /&gt;
This sp is for getting a clear list of currently active spids with full details including login, db, blocking spid, processing time, query start time, cpu usage, logical and physical i/o, currently executing command etc.  To maximise clarity, all info is displayed on one line for each spid.  Alternate info is also available by running with the &amp;quot;x&amp;quot; switch which includes, login time, host process, originating host and other information which may be useful for tracking down the source of a problem external to ASE.&lt;br /&gt;
&lt;br /&gt;
Example output (normal usage)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     Spid   Login        DB               Hostname     blocked StartTime           Dmins  Dtime CpuTime     LogicalReads PhysicalReads Command&lt;br /&gt;
 --- ------ ------------ ---------------- ------------ ------- ------------------- ------ ----- ----------- ------------ ------------- ------------------------------&lt;br /&gt;
 ***    126 sa           PROD_DB1         prod-srv1          0 Mar 24 2010 12:13AM    570 09:30           0           42             0 SELECT&lt;br /&gt;
 ***    143 app_user1    PROD_DB1         user-hosta         0 Mar 24 2010  9:38AM      6 00:06          10            0             0 SELECT&lt;br /&gt;
 ***     32 app_user1    PROD_DB1         user-hostb       143 Mar 24 2010  9:38AM      5 00:05           0           20             0 SELECT&lt;br /&gt;
 ***     44 cron         cron_tempdb      prod-srv1          0 Mar 24 2010  9:40AM      3 00:03           0            0             0 WAITFOR&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example output (extended info)&lt;br /&gt;
 Spid   Login        DB              Hostname     blocked StartTime           Dmins  Dtime Application  OS PID  Blocked(s)  Logged in ClientIP        Command&lt;br /&gt;
 ------ ------------ --------------- ------------ ------- ------------------- ------ ----- ------------ ------- ----------- --------- --------------- ------------------------------&lt;br /&gt;
    126 sa           PROD_DB1        prod-srv1          0 Mar 24 2010 12:13AM    570 09:30 isql         6181           NULL 15:25:59  12.7.3.55       SELECT&lt;br /&gt;
    143 user1        PROD_DB1        user-hosta         0 Mar 24 2010  9:38AM      6 00:06 NULL         -              NULL 15:25:09  12.7.3.56       SELECT&lt;br /&gt;
     32 user1        PROD_DB1        user-hostb       143 Mar 24 2010  9:38AM      5 00:05 NULL         -              NULL 15:26:04  12.7.3.57       SELECT&lt;br /&gt;
     44 cron         cron_tempdb     prod-srv1          0 Mar 24 2010  9:40AM      3 00:03 isql         8639           NULL 15:26:04  12.7.3.55       WAITFOR&lt;br /&gt;
&lt;br /&gt;
Usage summary:&amp;lt;BR&amp;gt;&lt;br /&gt;
 - sp__mon_sql2          ((no params), returns standard info for all spids)&lt;br /&gt;
 - sp__mon_sql2 spid     (returns standard info for a specific spid)&lt;br /&gt;
 - sp__mon_sql2 null, &amp;quot;x&amp;quot;  (returns extended info for all spids)&lt;br /&gt;
 - sp__mon_sql2 spid, &amp;quot;x&amp;quot;  (returns extended info for a specific spid)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
create procedure sp__mon_sql2&lt;br /&gt;
(&lt;br /&gt;
@spid int = null, -- default to retrieve info for all spids&lt;br /&gt;
@extinfo char(1) = &amp;quot;u&amp;quot; -- extended info switch, default “u” (unset) is for off, “x” and “X” are for on)&lt;br /&gt;
)&lt;br /&gt;
as&lt;br /&gt;
------------------------------&lt;br /&gt;
-- Procedure: sp__mon_sql2&lt;br /&gt;
--   Created: April 2008&lt;br /&gt;
--    Author: Bob Holmes (Email: cambob@gmail.com)&lt;br /&gt;
--     Usage: sp__mon_sql2 [spid]&lt;br /&gt;
-- Version  : 1.1&lt;br /&gt;
------------------------------&lt;br /&gt;
--Modification history:&lt;br /&gt;
--bobh - if 1 is specified as the spid number then alternate info is returned (dirty hack)&lt;br /&gt;
--bobh: 14/09/2009: Dirty hack mentioned above removed.  Usage is now as follows:&lt;br /&gt;
--                  - sp__mon_sql2          ((no params), returns standard info for all spids)&lt;br /&gt;
--                  - sp__mon_sql2 spid     (returns standard info for a specific spid)&lt;br /&gt;
--                  - sp__mon_sql2 null, x  (returns extended info for all spids)&lt;br /&gt;
--                  - sp__mon_sql2 spid, x  (returns extended info for a specific spid)&lt;br /&gt;
------------------------------&lt;br /&gt;
-- INFO:&lt;br /&gt;
-- The three *'s are a grep key for a shell script to use to extract the lines needed for alerting.&lt;br /&gt;
------------------------------&lt;br /&gt;
set nocount on&lt;br /&gt;
&lt;br /&gt;
--prep - setup input variables for run mode&lt;br /&gt;
if @spid=null&lt;br /&gt;
begin&lt;br /&gt;
  select @spid=0&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--part 1 - snapshot&lt;br /&gt;
set forceplan on&lt;br /&gt;
select 	s.StartTime, &lt;br /&gt;
	convert(smallint,(datediff(mi,StartTime,getdate()))) Dmins,  &lt;br /&gt;
	p.spid, &lt;br /&gt;
	p.hostname, &lt;br /&gt;
	p.suid, &lt;br /&gt;
	p.dbid, &lt;br /&gt;
	p.cmd, &lt;br /&gt;
        p.blocked,&lt;br /&gt;
	s.CpuTime, &lt;br /&gt;
	s.LogicalReads, &lt;br /&gt;
	s.PhysicalReads,&lt;br /&gt;
	p.status, &lt;br /&gt;
	p.loggedindatetime,&lt;br /&gt;
	p.program_name, &lt;br /&gt;
	l.ClientOSPID, &lt;br /&gt;
	p.time_blocked, &lt;br /&gt;
	p.ipaddr&lt;br /&gt;
into #processmon2&lt;br /&gt;
from master..sysprocesses p, master..monProcessStatement s, master..monProcessLookup l&lt;br /&gt;
where p.spid != @@spid&lt;br /&gt;
and p.spid *= s.SPID&lt;br /&gt;
and l.SPID = p.spid&lt;br /&gt;
and suid &amp;lt;&amp;gt; 0&lt;br /&gt;
order by p.spid&lt;br /&gt;
set forceplan off&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
--&lt;br /&gt;
--case 1 - no params (0 and &amp;quot;u&amp;quot;)&lt;br /&gt;
if @spid=0 and @extinfo=&amp;quot;u&amp;quot; -- display standard information for all spids&lt;br /&gt;
begin&lt;br /&gt;
-- display header information for multiple spids&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;Process Summary (Order by Dmins, CpuTime, LogicalReads, PhysicalReads Desc )&amp;quot;&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;&amp;quot;&lt;br /&gt;
  select distinct &amp;quot;***&amp;quot;,&lt;br /&gt;
  spid Spid,&lt;br /&gt;
  convert(char(12),suser_name(suid)) Login,&lt;br /&gt;
  convert(char(16),db_name(dbid)) DB,&lt;br /&gt;
  (case hostname when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),hostname) end) Hostname,&lt;br /&gt;
  blocked,&lt;br /&gt;
  convert(varchar(19),StartTime) StartTime,&lt;br /&gt;
  Dmins,&lt;br /&gt;
  right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins/60)),2) + &amp;quot;:&amp;quot; + right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins%60)),2) Dtime,&lt;br /&gt;
  CpuTime,&lt;br /&gt;
  LogicalReads,&lt;br /&gt;
  PhysicalReads,&lt;br /&gt;
  cmd Command&lt;br /&gt;
  from #processmon2&lt;br /&gt;
  where cmd &amp;lt;&amp;gt; &amp;quot;AWAITING COMMAND&amp;quot;&lt;br /&gt;
  order by Dmins desc, CpuTime Desc, LogicalReads Desc, PhysicalReads Desc&lt;br /&gt;
end&lt;br /&gt;
--&lt;br /&gt;
--&lt;br /&gt;
--case 2 &lt;br /&gt;
else if @spid=0 and @extinfo=&amp;quot;x&amp;quot; -- extended info for all spids&lt;br /&gt;
begin&lt;br /&gt;
-- display header information for multiple spids&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;Process Summary (Order by Dmins, CpuTime, LogicalReads, PhysicalReads Desc )&amp;quot;&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;&amp;quot;&lt;br /&gt;
select &lt;br /&gt;
  spid Spid,&lt;br /&gt;
  convert(char(12),suser_name(suid)) Login,&lt;br /&gt;
  convert(char(15),db_name(dbid)) DB,&lt;br /&gt;
  (case hostname when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),hostname) end) Hostname,&lt;br /&gt;
  blocked,&lt;br /&gt;
  convert(varchar(19),StartTime) StartTime,&lt;br /&gt;
  Dmins,&lt;br /&gt;
  right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins/60)),2) + &amp;quot;:&amp;quot; + right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins%60)),2) Dtime,&lt;br /&gt;
  (case program_name when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),program_name) end) Application,&lt;br /&gt;
  (case ClientOSPID when NULL then &amp;quot;-&amp;quot; else convert(char(7),ClientOSPID) end) &amp;quot;OS PID&amp;quot;,&lt;br /&gt;
  time_blocked &amp;quot;Blocked(s)&amp;quot;,&lt;br /&gt;
  convert(char(8),loggedindatetime,108) &amp;quot;Logged in&amp;quot;,&lt;br /&gt;
  convert(char(15),ipaddr) ClientIP,&lt;br /&gt;
  cmd Command&lt;br /&gt;
  from #processmon2&lt;br /&gt;
  where cmd &amp;lt;&amp;gt; &amp;quot;AWAITING COMMAND&amp;quot;&lt;br /&gt;
  order by Dmins desc, CpuTime Desc, LogicalReads Desc, PhysicalReads Desc&lt;br /&gt;
end&lt;br /&gt;
--&lt;br /&gt;
--&lt;br /&gt;
-- case 3 &lt;br /&gt;
else if @spid &amp;lt;&amp;gt; 0 and @extinfo = &amp;quot;u&amp;quot; -- display standard info for specific spid&lt;br /&gt;
begin&lt;br /&gt;
  select distinct &amp;quot;***&amp;quot;,&lt;br /&gt;
  spid Spid,&lt;br /&gt;
  convert(char(12),suser_name(suid)) Login,&lt;br /&gt;
  convert(char(16),db_name(dbid)) DB,&lt;br /&gt;
  (case hostname when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),hostname) end) Hostname,&lt;br /&gt;
  blocked,&lt;br /&gt;
  convert(varchar(19),StartTime) StartTime,&lt;br /&gt;
  Dmins,&lt;br /&gt;
  right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins/60)),2) + &amp;quot;:&amp;quot; + right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins%60)),2) Dtime,&lt;br /&gt;
  CpuTime,&lt;br /&gt;
  LogicalReads,&lt;br /&gt;
  PhysicalReads,&lt;br /&gt;
  cmd Command&lt;br /&gt;
  from #processmon2&lt;br /&gt;
  where spid = @spid&lt;br /&gt;
  order by Dmins desc, CpuTime Desc, LogicalReads Desc, PhysicalReads Desc&lt;br /&gt;
end&lt;br /&gt;
--&lt;br /&gt;
--&lt;br /&gt;
-- case 4&lt;br /&gt;
else if @spid &amp;lt;&amp;gt; 0 and @extinfo = &amp;quot;x&amp;quot; -- display extended info for specific spid&lt;br /&gt;
begin&lt;br /&gt;
-- display header information for multiple spids&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;Process Summary (Order by Dmins, CpuTime, LogicalReads, PhysicalReads Desc )&amp;quot;&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;&amp;quot;&lt;br /&gt;
select &lt;br /&gt;
  spid Spid,&lt;br /&gt;
  convert(char(12),suser_name(suid)) Login,&lt;br /&gt;
  convert(char(15),db_name(dbid)) DB,&lt;br /&gt;
  (case hostname when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),hostname) end) Hostname,&lt;br /&gt;
  blocked,&lt;br /&gt;
  convert(varchar(19),StartTime) StartTime,&lt;br /&gt;
  Dmins,&lt;br /&gt;
  right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins/60)),2) + &amp;quot;:&amp;quot; + right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins%60)),2) Dtime,&lt;br /&gt;
  (case program_name when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),program_name) end) Application,&lt;br /&gt;
  (case ClientOSPID when NULL then &amp;quot;-&amp;quot; else convert(char(7),ClientOSPID) end) &amp;quot;OS PID&amp;quot;,&lt;br /&gt;
  time_blocked &amp;quot;Blocked(s)&amp;quot;,&lt;br /&gt;
  convert(char(8),loggedindatetime,108) &amp;quot;Logged in&amp;quot;,&lt;br /&gt;
  convert(char(15),ipaddr) ClientIP,&lt;br /&gt;
  cmd Command&lt;br /&gt;
  from #processmon2&lt;br /&gt;
  where spid = @spid&lt;br /&gt;
  order by Dmins desc, CpuTime Desc, LogicalReads Desc, PhysicalReads Desc&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:ASE]]&lt;br /&gt;
[[Category:MDA tables]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=Sp_mon_sql2--ASE_spid_activity_monitor&amp;diff=1931</id>
		<title>Sp mon sql2--ASE spid activity monitor</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=Sp_mon_sql2--ASE_spid_activity_monitor&amp;diff=1931"/>
				<updated>2010-03-24T09:46:27Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: Updated version of the script (dirty hack in previous version has been removed)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: This SP uses the MDA tables.&amp;lt;BR&amp;gt;&lt;br /&gt;
This sp is for getting a clear list of currently active spids with full details including login, db, blocking spid, processing time, query start time, cpu usage, logical and physical i/o, currently executing command etc.  To maximise clarity, all info is displayed on one line for each spid.  Alternate info is also available by running with the &amp;quot;x&amp;quot; switch which includes, login time, host process, originating host and other information which may be useful for tracking down the source of a problem external to ASE.&lt;br /&gt;
&lt;br /&gt;
Usage summary:&amp;lt;BR&amp;gt;&lt;br /&gt;
 - sp__mon_sql2          ((no params), returns standard info for all spids)&lt;br /&gt;
 - sp__mon_sql2 spid     (returns standard info for a specific spid)&lt;br /&gt;
 - sp__mon_sql2 null, &amp;quot;x&amp;quot;  (returns extended info for all spids)&lt;br /&gt;
 - sp__mon_sql2 spid, &amp;quot;x&amp;quot;  (returns extended info for a specific spid)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
create procedure sp__mon_sql2&lt;br /&gt;
(&lt;br /&gt;
@spid int = null, -- default to retrieve info for all spids&lt;br /&gt;
@extinfo char(1) = &amp;quot;u&amp;quot; -- extended info switch, default “u” (unset) is for off, “x” and “X” are for on)&lt;br /&gt;
)&lt;br /&gt;
as&lt;br /&gt;
------------------------------&lt;br /&gt;
-- Procedure: sp__mon_sql2&lt;br /&gt;
--   Created: April 2008&lt;br /&gt;
--    Author: Bob Holmes (Email: cambob@gmail.com)&lt;br /&gt;
--     Usage: sp__mon_sql2 [spid]&lt;br /&gt;
-- Version  : 1.1&lt;br /&gt;
------------------------------&lt;br /&gt;
--Modification history:&lt;br /&gt;
--bobh - if 1 is specified as the spid number then alternate info is returned (dirty hack)&lt;br /&gt;
--bobh: 14/09/2009: Dirty hack mentioned above removed.  Usage is now as follows:&lt;br /&gt;
--                  - sp__mon_sql2          ((no params), returns standard info for all spids)&lt;br /&gt;
--                  - sp__mon_sql2 spid     (returns standard info for a specific spid)&lt;br /&gt;
--                  - sp__mon_sql2 null, x  (returns extended info for all spids)&lt;br /&gt;
--                  - sp__mon_sql2 spid, x  (returns extended info for a specific spid)&lt;br /&gt;
------------------------------&lt;br /&gt;
-- INFO:&lt;br /&gt;
-- The three *'s are a grep key for a shell script to use to extract the lines needed for alerting.&lt;br /&gt;
------------------------------&lt;br /&gt;
set nocount on&lt;br /&gt;
&lt;br /&gt;
--prep - setup input variables for run mode&lt;br /&gt;
if @spid=null&lt;br /&gt;
begin&lt;br /&gt;
  select @spid=0&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--part 1 - snapshot&lt;br /&gt;
set forceplan on&lt;br /&gt;
select 	s.StartTime, &lt;br /&gt;
	convert(smallint,(datediff(mi,StartTime,getdate()))) Dmins,  &lt;br /&gt;
	p.spid, &lt;br /&gt;
	p.hostname, &lt;br /&gt;
	p.suid, &lt;br /&gt;
	p.dbid, &lt;br /&gt;
	p.cmd, &lt;br /&gt;
        p.blocked,&lt;br /&gt;
	s.CpuTime, &lt;br /&gt;
	s.LogicalReads, &lt;br /&gt;
	s.PhysicalReads,&lt;br /&gt;
	p.status, &lt;br /&gt;
	p.loggedindatetime,&lt;br /&gt;
	p.program_name, &lt;br /&gt;
	l.ClientOSPID, &lt;br /&gt;
	p.time_blocked, &lt;br /&gt;
	p.ipaddr&lt;br /&gt;
into #processmon2&lt;br /&gt;
from master..sysprocesses p, master..monProcessStatement s, master..monProcessLookup l&lt;br /&gt;
where p.spid != @@spid&lt;br /&gt;
and p.spid *= s.SPID&lt;br /&gt;
and l.SPID = p.spid&lt;br /&gt;
and suid &amp;lt;&amp;gt; 0&lt;br /&gt;
order by p.spid&lt;br /&gt;
set forceplan off&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
--&lt;br /&gt;
--case 1 - no params (0 and &amp;quot;u&amp;quot;)&lt;br /&gt;
if @spid=0 and @extinfo=&amp;quot;u&amp;quot; -- display standard information for all spids&lt;br /&gt;
begin&lt;br /&gt;
-- display header information for multiple spids&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;Process Summary (Order by Dmins, CpuTime, LogicalReads, PhysicalReads Desc )&amp;quot;&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;&amp;quot;&lt;br /&gt;
  select distinct &amp;quot;***&amp;quot;,&lt;br /&gt;
  spid Spid,&lt;br /&gt;
  convert(char(12),suser_name(suid)) Login,&lt;br /&gt;
  convert(char(16),db_name(dbid)) DB,&lt;br /&gt;
  (case hostname when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),hostname) end) Hostname,&lt;br /&gt;
  blocked,&lt;br /&gt;
  convert(varchar(19),StartTime) StartTime,&lt;br /&gt;
  Dmins,&lt;br /&gt;
  right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins/60)),2) + &amp;quot;:&amp;quot; + right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins%60)),2) Dtime,&lt;br /&gt;
  CpuTime,&lt;br /&gt;
  LogicalReads,&lt;br /&gt;
  PhysicalReads,&lt;br /&gt;
  cmd Command&lt;br /&gt;
  from #processmon2&lt;br /&gt;
  where cmd &amp;lt;&amp;gt; &amp;quot;AWAITING COMMAND&amp;quot;&lt;br /&gt;
  order by Dmins desc, CpuTime Desc, LogicalReads Desc, PhysicalReads Desc&lt;br /&gt;
end&lt;br /&gt;
--&lt;br /&gt;
--&lt;br /&gt;
--case 2 &lt;br /&gt;
else if @spid=0 and @extinfo=&amp;quot;x&amp;quot; -- extended info for all spids&lt;br /&gt;
begin&lt;br /&gt;
-- display header information for multiple spids&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;Process Summary (Order by Dmins, CpuTime, LogicalReads, PhysicalReads Desc )&amp;quot;&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;&amp;quot;&lt;br /&gt;
select &lt;br /&gt;
  spid Spid,&lt;br /&gt;
  convert(char(12),suser_name(suid)) Login,&lt;br /&gt;
  convert(char(15),db_name(dbid)) DB,&lt;br /&gt;
  (case hostname when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),hostname) end) Hostname,&lt;br /&gt;
  blocked,&lt;br /&gt;
  convert(varchar(19),StartTime) StartTime,&lt;br /&gt;
  Dmins,&lt;br /&gt;
  right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins/60)),2) + &amp;quot;:&amp;quot; + right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins%60)),2) Dtime,&lt;br /&gt;
  (case program_name when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),program_name) end) Application,&lt;br /&gt;
  (case ClientOSPID when NULL then &amp;quot;-&amp;quot; else convert(char(7),ClientOSPID) end) &amp;quot;OS PID&amp;quot;,&lt;br /&gt;
  time_blocked &amp;quot;Blocked(s)&amp;quot;,&lt;br /&gt;
  convert(char(8),loggedindatetime,108) &amp;quot;Logged in&amp;quot;,&lt;br /&gt;
  convert(char(15),ipaddr) ClientIP,&lt;br /&gt;
  cmd Command&lt;br /&gt;
  from #processmon2&lt;br /&gt;
  where cmd &amp;lt;&amp;gt; &amp;quot;AWAITING COMMAND&amp;quot;&lt;br /&gt;
  order by Dmins desc, CpuTime Desc, LogicalReads Desc, PhysicalReads Desc&lt;br /&gt;
end&lt;br /&gt;
--&lt;br /&gt;
--&lt;br /&gt;
-- case 3 &lt;br /&gt;
else if @spid &amp;lt;&amp;gt; 0 and @extinfo = &amp;quot;u&amp;quot; -- display standard info for specific spid&lt;br /&gt;
begin&lt;br /&gt;
  select distinct &amp;quot;***&amp;quot;,&lt;br /&gt;
  spid Spid,&lt;br /&gt;
  convert(char(12),suser_name(suid)) Login,&lt;br /&gt;
  convert(char(16),db_name(dbid)) DB,&lt;br /&gt;
  (case hostname when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),hostname) end) Hostname,&lt;br /&gt;
  blocked,&lt;br /&gt;
  convert(varchar(19),StartTime) StartTime,&lt;br /&gt;
  Dmins,&lt;br /&gt;
  right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins/60)),2) + &amp;quot;:&amp;quot; + right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins%60)),2) Dtime,&lt;br /&gt;
  CpuTime,&lt;br /&gt;
  LogicalReads,&lt;br /&gt;
  PhysicalReads,&lt;br /&gt;
  cmd Command&lt;br /&gt;
  from #processmon2&lt;br /&gt;
  where spid = @spid&lt;br /&gt;
  order by Dmins desc, CpuTime Desc, LogicalReads Desc, PhysicalReads Desc&lt;br /&gt;
end&lt;br /&gt;
--&lt;br /&gt;
--&lt;br /&gt;
-- case 4&lt;br /&gt;
else if @spid &amp;lt;&amp;gt; 0 and @extinfo = &amp;quot;x&amp;quot; -- display extended info for specific spid&lt;br /&gt;
begin&lt;br /&gt;
-- display header information for multiple spids&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;Process Summary (Order by Dmins, CpuTime, LogicalReads, PhysicalReads Desc )&amp;quot;&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;&amp;quot;&lt;br /&gt;
select &lt;br /&gt;
  spid Spid,&lt;br /&gt;
  convert(char(12),suser_name(suid)) Login,&lt;br /&gt;
  convert(char(15),db_name(dbid)) DB,&lt;br /&gt;
  (case hostname when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),hostname) end) Hostname,&lt;br /&gt;
  blocked,&lt;br /&gt;
  convert(varchar(19),StartTime) StartTime,&lt;br /&gt;
  Dmins,&lt;br /&gt;
  right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins/60)),2) + &amp;quot;:&amp;quot; + right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins%60)),2) Dtime,&lt;br /&gt;
  (case program_name when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),program_name) end) Application,&lt;br /&gt;
  (case ClientOSPID when NULL then &amp;quot;-&amp;quot; else convert(char(7),ClientOSPID) end) &amp;quot;OS PID&amp;quot;,&lt;br /&gt;
  time_blocked &amp;quot;Blocked(s)&amp;quot;,&lt;br /&gt;
  convert(char(8),loggedindatetime,108) &amp;quot;Logged in&amp;quot;,&lt;br /&gt;
  convert(char(15),ipaddr) ClientIP,&lt;br /&gt;
  cmd Command&lt;br /&gt;
  from #processmon2&lt;br /&gt;
  where spid = @spid&lt;br /&gt;
  order by Dmins desc, CpuTime Desc, LogicalReads Desc, PhysicalReads Desc&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:ASE]]&lt;br /&gt;
[[Category:MDA tables]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=Corruption_of_syslogs_(dbcc_rebuild_log)&amp;diff=1870</id>
		<title>Corruption of syslogs (dbcc rebuild log)</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=Corruption_of_syslogs_(dbcc_rebuild_log)&amp;diff=1870"/>
				<updated>2009-03-30T12:06:44Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: Corruption of syslogs moved to Corruption of syslogs (dbcc rebuild log)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A corrupt syslogs table (the transaction log of a database) can sometimes be fixed. Best approach is to load a clean database dump and it's transaction log. However, that's not always possible. For instance, when the corruption has been unnoticed for some time you need to take other steps.&lt;br /&gt;
&lt;br /&gt;
Some suggestions:&lt;br /&gt;
&lt;br /&gt;
* dump the database and reload the dump. This can solve some issues.&lt;br /&gt;
* extract all contect from the database with tools like defncopy and bcp. Then drop the database, recreate and load in the extracted information.&lt;br /&gt;
&lt;br /&gt;
A more complex situation is shown here.&lt;br /&gt;
===Solving Msg 2578 and Msg 2503===&lt;br /&gt;
Run dbcc checktable(syslogs) to check the syslogs table.&lt;br /&gt;
 use &amp;lt;database&amp;gt;&lt;br /&gt;
 go&lt;br /&gt;
 dbcc checktable(syslogs)&lt;br /&gt;
 go&lt;br /&gt;
 Checking syslogs: Logical pagesize is 2048 bytes&lt;br /&gt;
 Msg 2578, Level 16, State 1:&lt;br /&gt;
 Server 'ASE1', Line 1:&lt;br /&gt;
 The first page 67664 in sysindexes for table 'syslogs' has previous page # 67663 in its page header. The previous page # should be NULL. Please check sysindexes.&lt;br /&gt;
 Msg 2503, Level 16, State 1:&lt;br /&gt;
 Server 'ASE1', Line 1:&lt;br /&gt;
 Table Corrupt: Page linkage is not consistent; check the following pages: (current page#=67664;  page# pointing to this page=0; previous page# indicated in this page=67663)&lt;br /&gt;
 DBCC execution completed. If DBCC printed error messages, contact a user with System Administrator (SA) role.&lt;br /&gt;
You might want to run a &amp;quot;dbcc pglinkage&amp;quot; to see if you can fix the page number yourself. When that is not possible you may need to follow the rebuild_log method.&lt;br /&gt;
'''WARNING''' you must use great caution with dbcc rebuild_log. This command will increase the current database timestamp value significantly. Once the database timestamp reaches it's limit (for example if you overuse this command) you will have to rebuild the database.&lt;br /&gt;
====Bypass recovery mode for the database====&lt;br /&gt;
 use master&lt;br /&gt;
 go&lt;br /&gt;
 select status from sysdatabases where name = &amp;quot;&amp;lt;database&amp;gt;&amp;quot;&lt;br /&gt;
 go&lt;br /&gt;
Make a note of the status&lt;br /&gt;
 sp_configure &amp;quot;allow updates to system tables&amp;quot;,1&lt;br /&gt;
 go&lt;br /&gt;
 begin tran&lt;br /&gt;
 go&lt;br /&gt;
 update sysdatabases set status = -32768 where name = &amp;quot;&amp;lt;database&amp;gt;&amp;quot;&lt;br /&gt;
 go&lt;br /&gt;
 commit tran&lt;br /&gt;
 go&lt;br /&gt;
 use &amp;lt;database&amp;gt;&lt;br /&gt;
 go&lt;br /&gt;
 checkpoint&lt;br /&gt;
 go&lt;br /&gt;
 shutdown&lt;br /&gt;
 go&lt;br /&gt;
====Rebuild the transaction log====&lt;br /&gt;
Boot the ASE server. You will see a message in the errorlog that it skips recovery for the database.&lt;br /&gt;
 server  *** Bypassing recovery of database id 7&lt;br /&gt;
Run the following commands:&lt;br /&gt;
 use &amp;lt;database&amp;gt;&lt;br /&gt;
 go&lt;br /&gt;
 dbcc rebuild_log(&amp;lt;database&amp;gt;,1,1)&lt;br /&gt;
 go&lt;br /&gt;
 use master&lt;br /&gt;
 go&lt;br /&gt;
 begin tran&lt;br /&gt;
 go&lt;br /&gt;
 update sysdatabases set status = &amp;lt;original status&amp;gt; where name = &amp;quot;&amp;lt;database&amp;gt;&amp;quot;&lt;br /&gt;
 go&lt;br /&gt;
 commit tran&lt;br /&gt;
 go&lt;br /&gt;
 shutdown&lt;br /&gt;
 go&lt;br /&gt;
====Check if it worked====&lt;br /&gt;
Boot the ASE server and check if the syslogs is now OK.&lt;br /&gt;
 use &amp;lt;database&amp;gt;&lt;br /&gt;
 go&lt;br /&gt;
 dbcc checktable(syslogs)&lt;br /&gt;
 go&lt;br /&gt;
 sp_configure &amp;quot;allow updates to system tables&amp;quot;,0&lt;br /&gt;
 go&lt;br /&gt;
&lt;br /&gt;
[[Category:ASE]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=Corruption_of_syslogs&amp;diff=1871</id>
		<title>Corruption of syslogs</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=Corruption_of_syslogs&amp;diff=1871"/>
				<updated>2009-03-30T12:06:44Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: Corruption of syslogs moved to Corruption of syslogs (dbcc rebuild log): Title change for added clarity - dbcc rebuild_log vs log suicide&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#redirect [[Corruption of syslogs (dbcc rebuild log)]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=Corruption_of_Syslogs_(log_suicide)&amp;diff=1869</id>
		<title>Corruption of Syslogs (log suicide)</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=Corruption_of_Syslogs_(log_suicide)&amp;diff=1869"/>
				<updated>2009-03-30T12:03:26Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Log Suicide ==&lt;br /&gt;
----&lt;br /&gt;
'''Note: Data integrity cannot be guaranteed - this procedure is not recommended for production systems.'''&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1) update sysdatabases set status=-32768, status2=0 where name='suspect_database' &lt;br /&gt;
2) shutdown with nowait &lt;br /&gt;
3) restart dataserver &lt;br /&gt;
4) dump tran suspect_database with no_log &lt;br /&gt;
5) update sysdatabases set status=12, status2=0 where name='suspect_database' &lt;br /&gt;
6) recycle dataserver &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[Category:ASE]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=RepServer_Throughput_Script&amp;diff=1867</id>
		<title>RepServer Throughput Script</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=RepServer_Throughput_Script&amp;diff=1867"/>
				<updated>2009-02-26T11:29:41Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to know just how much data repserver is processing, then this is the tool.&amp;lt;br&amp;gt;&lt;br /&gt;
This script will tell you:&amp;lt;br&amp;gt;&lt;br /&gt;
o average throughput per queue (mb per minute)&amp;lt;br&amp;gt;&lt;br /&gt;
o average throughput combined (all queues)&amp;lt;br&amp;gt;&lt;br /&gt;
o estimated time for a replicate to catch up (Re-sync ETA)&amp;lt;br&amp;gt;&lt;br /&gt;
o current queue sizes&amp;lt;br&amp;gt;&lt;br /&gt;
There is also a maximum recorded throughput option but this appears not to work well as some of the figures have been suspicious.&amp;lt;br&amp;gt;&lt;br /&gt;
The real maximum throughput can be established by noting when the replicates start to fall behind in conjunction with the current throughput figures.&amp;lt;br&amp;gt;&lt;br /&gt;
This script can be particularly useful in helping to ascertain if you need to throw more CPU at your repserver box.&lt;br /&gt;
&lt;br /&gt;
Notes:&amp;lt;br&amp;gt;&lt;br /&gt;
1) You will need to cron this script with the insert option (rs_throughput.sh insert) and allow it to collect at least 2 samples before being able to run it interactively to obtain throughput information.  The script runs silently when run with the insert option.&amp;lt;br&amp;gt;&lt;br /&gt;
2) The script automatically determines the elapsed interval in minutes between samples so you can cron the script to your preferred interval, be it 3 minutes or 10 minutes, the mb/min figure will be calculated correctly.&amp;lt;br&amp;gt;&lt;br /&gt;
3) In addition to configuring the script to your environment, you will also need to create the rs_throughput table prior to first run.&amp;lt;br&amp;gt;&lt;br /&gt;
4) Re-sync ETA: this value is provided based on the current throughput average for the period specified.  For example, this means that running rs_throughput.sh 15 may give a different Re-Sync ETA compared to running rs_throughput.sh 20&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/ksh&lt;br /&gt;
#&lt;br /&gt;
# Script: rs_throughput.sh&lt;br /&gt;
# Author: Bob Holmes - email: cambob@gmail.com&lt;br /&gt;
# Date  : 19/09/08&lt;br /&gt;
# Version : 1.0&lt;br /&gt;
# Usage : Run &amp;quot;rs_throughput.sh help&amp;quot; for full usage information.&lt;br /&gt;
# Description : This script enables monitoring and reporting&lt;br /&gt;
#               of repserver throughput.&lt;br /&gt;
# --------------------------&lt;br /&gt;
#    ***    Variables for customisation can be found by searching for &amp;quot;!!&amp;quot; ***&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Modification history:&lt;br /&gt;
# 19/02/09 : Bob Holmes : Script modified to enable easier customisation prior&lt;br /&gt;
#                         to release on Sybase wiki. (modifications not tested)&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Comments: This script relies on the reporting..rs_throughput table for data&lt;br /&gt;
#           collection and reporting.  The definition for this table can be&lt;br /&gt;
#           found at the end of this script. &lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           setup environment                                #&lt;br /&gt;
##############################################################################&lt;br /&gt;
#&lt;br /&gt;
# save input variables&lt;br /&gt;
if ! [[ -z $1 ]]&lt;br /&gt;
then&lt;br /&gt;
  export option1=$1&lt;br /&gt;
else&lt;br /&gt;
  export option1=&amp;quot;all&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if ! [[ -z $2 ]]&lt;br /&gt;
then&lt;br /&gt;
  export option2=$2&lt;br /&gt;
else&lt;br /&gt;
  export option2=&amp;quot;15&amp;quot; # default number of minutes on which to report throughput&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# configure environment&lt;br /&gt;
HOSTNAME=`hostname`&lt;br /&gt;
. $HOME/admin/.syb_cfg.sh $HOSTNAME  # !! This line sets up the environment from&lt;br /&gt;
                                     # !! from an external shell script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           config variables                                 #&lt;br /&gt;
##############################################################################&lt;br /&gt;
# config:&lt;br /&gt;
primary_ds=&amp;quot;prim_ds&amp;quot;                   # !! string used to identify the inbound queue&lt;br /&gt;
# queues to query on:-&lt;br /&gt;
q_list=&amp;quot;prim_ds.db1 prim_ds.db2 replicate_ds.db1 replicate_ds.db2&amp;quot; # !!&lt;br /&gt;
insert_filter=&amp;quot;db1 db2&amp;quot;                # !! data will only be collected for queue names which have this keyword in&lt;br /&gt;
REP_SRV=&amp;quot;repsrv_rs&amp;quot;                    # !! the actual repserver from which to get sqm info&lt;br /&gt;
RPT_SRV=&amp;quot;reporting_ds&amp;quot;                 # !! dataserver which manages the reporting database&lt;br /&gt;
RPT_DB=&amp;quot;reporting&amp;quot;                     # !! reporting database name&lt;br /&gt;
RECIPIENTS=&amp;quot;user@domain&amp;quot;               # !! email config (separate addresses with commas)&lt;br /&gt;
ADMINDIR=&amp;quot;/opt/home/sybase/admin&amp;quot;      # !! sybase admin directory&lt;br /&gt;
RSPASS=&amp;quot;&amp;lt;command to retrieve pw&amp;gt;&amp;quot;      # !! insert equivalent command&lt;br /&gt;
ASEPASS=&amp;quot;&amp;lt;command to retrieve pw&amp;gt;&amp;quot;     # !! insert equivalent command&lt;br /&gt;
&lt;br /&gt;
# static:&lt;br /&gt;
SQMFILE=&amp;quot;$ADMINDIR/rs_sqm_tmp1.tmp&amp;quot;&lt;br /&gt;
DATE=$(date &amp;quot;+%d/%m/%y %H:%M:%S&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# config aware environment variables: # !! You may need to replace the line below with the equivalent&lt;br /&gt;
                                      # !! for your own environment. &lt;br /&gt;
RISQLCMD=&amp;quot;isql -Usa -P${RSPASS} -S${REP_SRV} -w1000&amp;quot;&lt;br /&gt;
ISQLCMD=&amp;quot;isql -Usa -P${ASEPASS} -S${RPT_SRV} -w200 -D${RPT_DB}&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                             functions                                      #&lt;br /&gt;
##############################################################################&lt;br /&gt;
&lt;br /&gt;
check_previous_instance()&lt;br /&gt;
{&lt;br /&gt;
# Note: next line greps for 8 instances as tests proved that less could cause the script to exit incorrectly&lt;br /&gt;
if [ $(ps -ef | grep rs_throughput | egrep -v &amp;quot;vi|grep&amp;quot; | grep -v &amp;quot;sh -c&amp;quot; | wc -l | awk '{print $1}') -gt 8 ]&lt;br /&gt;
then&lt;br /&gt;
  # previous instance still running - probably hanging&lt;br /&gt;
  echo Previous instance still running.&lt;br /&gt;
  exit&lt;br /&gt;
fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_checkusage()&lt;br /&gt;
{&lt;br /&gt;
if [[ -z $option1 ]]&lt;br /&gt;
then&lt;br /&gt;
  printf &amp;quot; Usage: ./rs_throughput.sh &amp;lt;all&amp;gt;|&amp;lt;q_name&amp;gt;|&amp;lt;help&amp;gt; [&amp;lt;minutes to display&amp;gt;]\n&amp;quot;&lt;br /&gt;
  exit&lt;br /&gt;
fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bcalc()&lt;br /&gt;
{&lt;br /&gt;
awk 'BEGIN{EQUATION='&amp;quot;$*&amp;quot;';printf(&amp;quot;%0.1f\n&amp;quot;,EQUATION); exit}'&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_housekeeping()&lt;br /&gt;
{&lt;br /&gt;
if [ -e $SQMFILE ]&lt;br /&gt;
then&lt;br /&gt;
  rm $SQMFILE&lt;br /&gt;
fi&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
go&lt;br /&gt;
delete from rs_throughput where sample_time &amp;lt;= dateadd(dd,-28,getdate())&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_insert_thruput_data()&lt;br /&gt;
{&lt;br /&gt;
# 1) get current segment usage/progress info&lt;br /&gt;
#connect to repserver, get sqm info - put into file&lt;br /&gt;
$RISQLCMD &amp;lt;&amp;lt; eof &amp;gt; $SQMFILE&lt;br /&gt;
admin who,sqm&lt;br /&gt;
go&lt;br /&gt;
quit&lt;br /&gt;
eof&lt;br /&gt;
&lt;br /&gt;
# 2) insert new segment data into rs_throughput table&lt;br /&gt;
#date&lt;br /&gt;
#echo &amp;quot;Queue Name, First segment, Last segment, Next segment&amp;quot;&lt;br /&gt;
cat $SQMFILE | egrep $insert_filter | sed 's/Awaiting Message/AwaitingMessage/; s/Awaiting Wakeup/AwaitingWakeup/; s/\(\.[0-9][0-9]*\)\.[0-9]/\1/' | grep -v &amp;quot;:0 ${primary_ds}&amp;quot; | awk '{print $4,$14,$15,$16}' | while read q_name first_seg last_seg next_seg&lt;br /&gt;
do&lt;br /&gt;
  q_size=$(bcalc &amp;quot;$last_seg - $first_seg&amp;quot;)&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
go&lt;br /&gt;
declare @mb_processed numeric(8,2)&lt;br /&gt;
declare @prev_sample datetime&lt;br /&gt;
declare @mins numeric(8,2)&lt;br /&gt;
declare @tput numeric(8,2)&lt;br /&gt;
if not exists (select 1 from rs_throughput where q_name = &amp;quot;${q_name}&amp;quot;)&lt;br /&gt;
insert rs_throughput values (&amp;quot;${q_name}&amp;quot;, getdate(), ${first_seg}, ${last_seg}, ${next_seg}, ${q_size}, 0, 0)&lt;br /&gt;
else&lt;br /&gt;
begin&lt;br /&gt;
-- get previous sample_time as key&lt;br /&gt;
select @prev_sample = max(sample_time) from rs_throughput where q_name = &amp;quot;${q_name}&amp;quot;&lt;br /&gt;
-- get difference in mb between current next segment and previous next segment&lt;br /&gt;
select @mb_processed = (select ${next_seg} - next from rs_throughput where sample_time = @prev_sample and q_name = &amp;quot;${q_name}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
select @prev_sample=dateadd(ss,-10,@prev_sample) -- # must substract 10 seconds to ensure the next datediff doesn't reflect 2m 58s &lt;br /&gt;
&lt;br /&gt;
as only 2mins!&lt;br /&gt;
select @mins = datediff(mi,@prev_sample,getdate())&lt;br /&gt;
if @mins &amp;gt; 0&lt;br /&gt;
begin&lt;br /&gt;
  select @tput = round((@mb_processed / @mins),2)&lt;br /&gt;
  insert rs_throughput values (&amp;quot;${q_name}&amp;quot;, getdate(), ${first_seg}, ${last_seg}, ${next_seg}, ${q_size}, @mb_processed, @tput)&lt;br /&gt;
end&lt;br /&gt;
end&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_report_thruput()&lt;br /&gt;
{&lt;br /&gt;
if [[ $option1 = [0-9]* ]]&lt;br /&gt;
then&lt;br /&gt;
  option2=$option1&lt;br /&gt;
  option1=&amp;quot;all&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if ! [[ &amp;quot;$option1&amp;quot; = &amp;quot;all&amp;quot; ]]&lt;br /&gt;
then&lt;br /&gt;
  q_list=$option1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
printf &amp;quot; -------------------------------------\n&amp;quot;&lt;br /&gt;
printf &amp;quot; Run date $DATE\n&amp;quot;&lt;br /&gt;
printf &amp;quot; -------------------------------------\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
for q_name in $q_list&lt;br /&gt;
do&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @mb_avg numeric(8,2)&lt;br /&gt;
declare @size numeric(8,2)&lt;br /&gt;
declare @eta datetime&lt;br /&gt;
select convert(char(19),sample_time) sample_time, q_name, size q_size, mb_processed, thruput &amp;quot;thruput (mb/min)&amp;quot;  from rs_throughput&lt;br /&gt;
where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name like &amp;quot;%${q_name}%&amp;quot;&lt;br /&gt;
&lt;br /&gt;
--get mb average&lt;br /&gt;
select @mb_avg = convert(numeric(8,2),avg(thruput)) from rs_throughput&lt;br /&gt;
where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name like &amp;quot;%${q_name}%&amp;quot;&lt;br /&gt;
--get current queue size&lt;br /&gt;
select @size = size from rs_throughput where q_name like &amp;quot;%${q_name}%&amp;quot; having sample_time=max(sample_time)&lt;br /&gt;
select @eta = dateadd(mi,round((@size/@mb_avg),0),getdate())&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
print &amp;quot; Average for ${q_name}: %1! mb/min,  Re-sync ETA: %2!&amp;quot;, @mb_avg, @eta&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_help_text()&lt;br /&gt;
{&lt;br /&gt;
printf &amp;quot;Usage examples:\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh (runs with default values showing all queues over 15 minutes)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh &amp;lt;q_name&amp;gt;|&amp;lt;minutes&amp;gt;\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh &amp;lt;q_name&amp;gt; &amp;lt;minutes&amp;gt;\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh size|queue (shows current queue sizes)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh max (shows highest ever throughput for queue history)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh help (shows this helptext)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh insert # this is for cron only (inserts data to $RPT_DB..rs_throughput table)\n&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_max_thruput()&lt;br /&gt;
{&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
set rowcount 0&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @q_name char(22)&lt;br /&gt;
declare @sample_time datetime&lt;br /&gt;
declare @max_thruput numeric(8,2)&lt;br /&gt;
select q_name, sample_time, thruput into #throughput from rs_throughput where 1=0&lt;br /&gt;
print &amp;quot;Maximum throughput per queue:&amp;quot;&lt;br /&gt;
-- get list of queues&lt;br /&gt;
select distinct q_name, 0 as processed into #queues from rs_throughput&lt;br /&gt;
set rowcount 1&lt;br /&gt;
select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
while @@rowcount != 0&lt;br /&gt;
begin&lt;br /&gt;
  insert #throughput select q_name, sample_time, thruput from rs_throughput&lt;br /&gt;
  where sample_time in&lt;br /&gt;
    (select sample_time from rs_throughput where q_name = @q_name having thruput = max(thruput))&lt;br /&gt;
  and q_name = @q_name&lt;br /&gt;
  update #queues set processed = 1 where q_name = @q_name&lt;br /&gt;
  select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
end&lt;br /&gt;
set rowcount 0&lt;br /&gt;
select * from #throughput order by thruput desc&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
echo&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_current_q_size()&lt;br /&gt;
{&lt;br /&gt;
$RISQLCMD &amp;lt;&amp;lt; eof &amp;gt; $SQMFILE&lt;br /&gt;
admin who,sqm&lt;br /&gt;
go&lt;br /&gt;
quit&lt;br /&gt;
eof&lt;br /&gt;
printf &amp;quot;Current Stable Queue usage:\n&amp;quot;&lt;br /&gt;
cat $SQMFILE | egrep $insert_filter | sed 's/Awaiting Message/AwaitingMessage/; s/Awaiting Wakeup/AwaitingWakeup/; s/\(\.[0-9][0-9]*\)\.[0-9]/\1/' | grep -v &amp;quot;:0 ${primary_ds}&amp;quot; | awk '{print $4,$14,$15,$16}' | while read q_name first_seg last_seg next_seg&lt;br /&gt;
do&lt;br /&gt;
  q_size=$(bcalc &amp;quot;$last_seg - $first_seg&amp;quot;)&lt;br /&gt;
  printf &amp;quot;$q_name: $q_size\n&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_combined_avg_thruput()&lt;br /&gt;
{&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set rowcount 0&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @q_name varchar(25)&lt;br /&gt;
declare @mb_avg numeric(8,2)&lt;br /&gt;
declare @mb_combined_avg numeric(8,2)&lt;br /&gt;
select @mb_combined_avg=0&lt;br /&gt;
-- get list of queues&lt;br /&gt;
&lt;br /&gt;
select distinct q_name, 0 as processed into #queues from rs_throughput&lt;br /&gt;
set rowcount 1&lt;br /&gt;
select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
while @@rowcount != 0&lt;br /&gt;
begin&lt;br /&gt;
  select @mb_avg = convert(numeric(8,2),avg(thruput)) from rs_throughput&lt;br /&gt;
  where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name = @q_name&lt;br /&gt;
  select @mb_combined_avg = @mb_combined_avg + @mb_avg&lt;br /&gt;
  update #queues set processed=1 where q_name = @q_name&lt;br /&gt;
  select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
end&lt;br /&gt;
print &amp;quot; Combined thruput average: %1! mb/min&amp;quot;, @mb_combined_avg&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                             main program                                   #&lt;br /&gt;
##############################################################################&lt;br /&gt;
&lt;br /&gt;
check_previous_instance&lt;br /&gt;
fn_checkusage&lt;br /&gt;
&lt;br /&gt;
case &amp;quot;$option1&amp;quot; in&lt;br /&gt;
        help) fn_show_help_text;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
      insert) fn_insert_thruput_data;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
         max) fn_show_max_thruput;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
       queue|size) fn_show_current_q_size;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
           *) fn_report_thruput;&lt;br /&gt;
              fn_show_combined_avg_thruput;;&lt;br /&gt;
esac&lt;br /&gt;
&lt;br /&gt;
fn_housekeeping&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
### TABLE DEFINTION FOR RAW DATA COLLECTION&lt;br /&gt;
### Use the table definition below to create the table which this script &lt;br /&gt;
### requires in order to insert queue data and furthermore query this&lt;br /&gt;
### data in order to provide throughput information.&lt;br /&gt;
#create table rs_throughput (&lt;br /&gt;
#q_name varchar(25), &lt;br /&gt;
#sample_time datetime, &lt;br /&gt;
#first numeric(8,2), &lt;br /&gt;
#last numeric(8,2), &lt;br /&gt;
#next numeric(8,2), &lt;br /&gt;
#size numeric(8,2), &lt;br /&gt;
#mb_processed numeric(8,2),&lt;br /&gt;
#thruput numeric(8,2)&lt;br /&gt;
#)&lt;br /&gt;
&lt;br /&gt;
# end program&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:RepServer]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=RepServer_Throughput_Script&amp;diff=1866</id>
		<title>RepServer Throughput Script</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=RepServer_Throughput_Script&amp;diff=1866"/>
				<updated>2009-02-26T11:25:55Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to know just how much data repserver is processing, then this is the tool.&amp;lt;br&amp;gt;&lt;br /&gt;
This script will tell you:&amp;lt;br&amp;gt;&lt;br /&gt;
o average throughput per queue (mb per minute)&amp;lt;br&amp;gt;&lt;br /&gt;
o average throughput combined (all queues)&amp;lt;br&amp;gt;&lt;br /&gt;
o estimated time for a replicate to catch up (Re-sync ETA)&amp;lt;br&amp;gt;&lt;br /&gt;
o current queue sizes&amp;lt;br&amp;gt;&lt;br /&gt;
There is also a maximum recorded throughput option but this appears not to work well as some of the figures have been suspicious.&amp;lt;br&amp;gt;&lt;br /&gt;
The real maximum throughput can be established by noting when the replicates start to fall behind in conjunction with the current throughput figures.&amp;lt;br&amp;gt;&lt;br /&gt;
This script can be particularly useful in helping to ascertain if you need to throw more CPU at your repserver box.&lt;br /&gt;
&lt;br /&gt;
Notes:&amp;lt;br&amp;gt;&lt;br /&gt;
1) You will need to cron this script with the insert option (rs_throughput.sh insert) and allow it to collect at least 2 samples before being able to run it interactively to obtain throughput information.  The script runs silently when run with the insert option.&amp;lt;br&amp;gt;&lt;br /&gt;
2) The script automatically determines the elapsed interval in minutes between samples so you can cron the script to your preferred interval, be it 3 minutes or 10 minutes, the mb/min figure will be calculated correctly.&amp;lt;br&amp;gt;&lt;br /&gt;
3) In addition to configuring the script to your environment, you will also need to create the rs_throughput table prior to first run.&amp;lt;br&amp;gt;&lt;br /&gt;
4) Re-sync ETA: this value is provided based on the current throughput average for the period specified.  For example, this means that running rs_throughput.sh 15 may give a different Re-Sync ETA compared to running rs_throughput.sh 20&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/ksh&lt;br /&gt;
#&lt;br /&gt;
# Script: rs_throughput.sh&lt;br /&gt;
# Author: Bob Holmes - email: cambob@gmail.com&lt;br /&gt;
# Date  : 19/09/08&lt;br /&gt;
# Version : 1.0&lt;br /&gt;
# Usage : Run &amp;quot;rs_throughput.sh help&amp;quot; for full usage information.&lt;br /&gt;
# Description : This script enables monitoring and reporting&lt;br /&gt;
#               of repserver throughput.&lt;br /&gt;
# --------------------------&lt;br /&gt;
#    ***    Variables for customisation can be found by searching for &amp;quot;!!&amp;quot; ***&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Modification history:&lt;br /&gt;
# 19/02/09 : Bob Holmes : Script modified to enable easier customisation prior&lt;br /&gt;
#                         to release on Sybase wiki. (modifications not tested)&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Comments: This script relies on the reporting..rs_throughput table for data&lt;br /&gt;
#           collection and reporting.  The definition for this table can be&lt;br /&gt;
#           found at the end of this script. &lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           setup environment                                #&lt;br /&gt;
##############################################################################&lt;br /&gt;
#&lt;br /&gt;
# save input variables&lt;br /&gt;
if ! [[ -z $1 ]]&lt;br /&gt;
then&lt;br /&gt;
  export option1=$1&lt;br /&gt;
else&lt;br /&gt;
  export option1=&amp;quot;all&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if ! [[ -z $2 ]]&lt;br /&gt;
then&lt;br /&gt;
  export option2=$2&lt;br /&gt;
else&lt;br /&gt;
  export option2=&amp;quot;15&amp;quot; # default number of minutes on which to report throughput&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# configure environment&lt;br /&gt;
HOSTNAME=`hostname`&lt;br /&gt;
. $HOME/admin/.syb_cfg.sh $HOSTNAME  # !! This line sets up the environment from&lt;br /&gt;
                                     # !! from an external shell script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           config variables                                 #&lt;br /&gt;
##############################################################################&lt;br /&gt;
# config:&lt;br /&gt;
primary_ds=&amp;quot;prim_ds&amp;quot;                   # !! string used to identify the inbound queue&lt;br /&gt;
# queues to query on:-&lt;br /&gt;
q_list=&amp;quot;prim_ds.db1 prim_ds.db2 replicate_ds.db1 replicate_ds.db2&amp;quot; # !!&lt;br /&gt;
insert_filter=&amp;quot;db1 db2&amp;quot;                # !! data will only be collected for queue names which have this keyword in&lt;br /&gt;
REP_SRV=&amp;quot;repsrv_rs&amp;quot;                    # !! the actual repserver from which to get sqm info&lt;br /&gt;
RPT_SRV=&amp;quot;reporting_ds&amp;quot;                 # !! dataserver which manages the reporting database&lt;br /&gt;
RPT_DB=&amp;quot;reporting&amp;quot;                     # !! reporting database name&lt;br /&gt;
RECIPIENTS=&amp;quot;user@domain&amp;quot;               # !! email config (separate addresses with commas)&lt;br /&gt;
ADMINDIR=&amp;quot;/opt/home/sybase/admin&amp;quot;      # !! sybase admin directory&lt;br /&gt;
RSPASS=&amp;quot;&amp;lt;command to retrieve pw&amp;gt;&amp;quot;      # !! insert equivalent command&lt;br /&gt;
ASEPASS=&amp;quot;&amp;lt;command to retrieve pw&amp;gt;&amp;quot;     # !! insert equivalent command&lt;br /&gt;
&lt;br /&gt;
# static:&lt;br /&gt;
SQMFILE=&amp;quot;$ADMINDIR/rs_sqm_tmp1.tmp&amp;quot;&lt;br /&gt;
DATE=$(date &amp;quot;+%d/%m/%y %H:%M:%S&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# config aware environment variables: # !! You may need to replace the line below with the equivalent&lt;br /&gt;
                                      # !! for your own environment. &lt;br /&gt;
RISQLCMD=&amp;quot;isql -Usa -P${RSPASS} -S${REP_SRV} -w1000&amp;quot;&lt;br /&gt;
ISQLCMD=&amp;quot;isql -Usa -P${ASEPASS} -S${RPT_SRV} -w200 -D${RPT_DB}&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                             functions                                      #&lt;br /&gt;
##############################################################################&lt;br /&gt;
&lt;br /&gt;
check_previous_instance()&lt;br /&gt;
{&lt;br /&gt;
# Note: next line greps for 8 instances as tests proved that less could cause the script to exit incorrectly&lt;br /&gt;
if [ $(ps -ef | grep rs_throughput | egrep -v &amp;quot;vi|grep&amp;quot; | grep -v &amp;quot;sh -c&amp;quot; | wc -l | awk '{print $1}') -gt 8 ]&lt;br /&gt;
then&lt;br /&gt;
  # previous instance still running - probably hanging&lt;br /&gt;
  echo Previous instance still running.&lt;br /&gt;
  exit&lt;br /&gt;
fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_checkusage()&lt;br /&gt;
{&lt;br /&gt;
if [[ -z $option1 ]]&lt;br /&gt;
then&lt;br /&gt;
  printf &amp;quot; Usage: ./rs_throughput.sh &amp;lt;all&amp;gt;|&amp;lt;q_name&amp;gt;|&amp;lt;help&amp;gt; [&amp;lt;minutes to display&amp;gt;]\n&amp;quot;&lt;br /&gt;
  exit&lt;br /&gt;
fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bcalc()&lt;br /&gt;
{&lt;br /&gt;
awk 'BEGIN{EQUATION='&amp;quot;$*&amp;quot;';printf(&amp;quot;%0.1f\n&amp;quot;,EQUATION); exit}'&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_housekeeping()&lt;br /&gt;
{&lt;br /&gt;
if [ -e $SQMFILE ]&lt;br /&gt;
then&lt;br /&gt;
  rm $SQMFILE&lt;br /&gt;
fi&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
go&lt;br /&gt;
delete from rs_throughput where sample_time &amp;lt;= dateadd(dd,-28,getdate())&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_insert_thruput_data()&lt;br /&gt;
{&lt;br /&gt;
# 1) get current segment usage/progress info&lt;br /&gt;
#connect to repserver, get sqm info - put into file&lt;br /&gt;
$RISQLCMD &amp;lt;&amp;lt; eof &amp;gt; $SQMFILE&lt;br /&gt;
admin who,sqm&lt;br /&gt;
go&lt;br /&gt;
quit&lt;br /&gt;
eof&lt;br /&gt;
&lt;br /&gt;
# 2) insert new segment data into rs_throughput table&lt;br /&gt;
#date&lt;br /&gt;
#echo &amp;quot;Queue Name, First segment, Last segment, Next segment&amp;quot;&lt;br /&gt;
cat $SQMFILE | egrep $insert_filter | sed 's/Awaiting Message/AwaitingMessage/; s/Awaiting Wakeup/AwaitingWakeup/; s/\(\.[0-9][0-&lt;br /&gt;
&lt;br /&gt;
9]*\)\.[0-9]/\1/' | grep -v &amp;quot;:0 ${primary_ds}&amp;quot; | awk '{print $4,$14,$15,$16}' | while read q_name first_seg last_seg next_seg&lt;br /&gt;
do&lt;br /&gt;
  q_size=$(bcalc &amp;quot;$last_seg - $first_seg&amp;quot;)&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
go&lt;br /&gt;
declare @mb_processed numeric(8,2)&lt;br /&gt;
declare @prev_sample datetime&lt;br /&gt;
declare @mins numeric(8,2)&lt;br /&gt;
declare @tput numeric(8,2)&lt;br /&gt;
if not exists (select 1 from rs_throughput where q_name = &amp;quot;${q_name}&amp;quot;)&lt;br /&gt;
insert rs_throughput values (&amp;quot;${q_name}&amp;quot;, getdate(), ${first_seg}, ${last_seg}, ${next_seg}, ${q_size}, 0, 0)&lt;br /&gt;
else&lt;br /&gt;
begin&lt;br /&gt;
-- get previous sample_time as key&lt;br /&gt;
select @prev_sample = max(sample_time) from rs_throughput where q_name = &amp;quot;${q_name}&amp;quot;&lt;br /&gt;
-- get difference in mb between current next segment and previous next segment&lt;br /&gt;
select @mb_processed = (select ${next_seg} - next from rs_throughput where sample_time = @prev_sample and q_name = &amp;quot;${q_name}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
select @prev_sample=dateadd(ss,-10,@prev_sample) -- # must substract 10 seconds to ensure the next datediff doesn't reflect 2m 58s &lt;br /&gt;
&lt;br /&gt;
as only 2mins!&lt;br /&gt;
select @mins = datediff(mi,@prev_sample,getdate())&lt;br /&gt;
if @mins &amp;gt; 0&lt;br /&gt;
begin&lt;br /&gt;
  select @tput = round((@mb_processed / @mins),2)&lt;br /&gt;
  insert rs_throughput values (&amp;quot;${q_name}&amp;quot;, getdate(), ${first_seg}, ${last_seg}, ${next_seg}, ${q_size}, @mb_processed, @tput)&lt;br /&gt;
end&lt;br /&gt;
end&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_report_thruput()&lt;br /&gt;
{&lt;br /&gt;
if [[ $option1 = [0-9]* ]]&lt;br /&gt;
then&lt;br /&gt;
  option2=$option1&lt;br /&gt;
  option1=&amp;quot;all&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if ! [[ &amp;quot;$option1&amp;quot; = &amp;quot;all&amp;quot; ]]&lt;br /&gt;
then&lt;br /&gt;
  q_list=$option1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
printf &amp;quot; -------------------------------------\n&amp;quot;&lt;br /&gt;
printf &amp;quot; Run date $DATE\n&amp;quot;&lt;br /&gt;
printf &amp;quot; -------------------------------------\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
for q_name in $q_list&lt;br /&gt;
do&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @mb_avg numeric(8,2)&lt;br /&gt;
declare @size numeric(8,2)&lt;br /&gt;
declare @eta datetime&lt;br /&gt;
select convert(char(19),sample_time) sample_time, q_name, size q_size, mb_processed, thruput &amp;quot;thruput (mb/min)&amp;quot;  from rs_throughput&lt;br /&gt;
--select convert(char(19),sample_time) sample_time, q_name, size q_size, mb_processed, thruput &amp;quot;thruput (mb/min)&amp;quot;, dateadd(mi,&lt;br /&gt;
&lt;br /&gt;
(round((size/thruput),0)),getdate()) ETA from rs_throughput&lt;br /&gt;
where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name like &amp;quot;%${q_name}%&amp;quot;&lt;br /&gt;
&lt;br /&gt;
--get mb average&lt;br /&gt;
select @mb_avg = convert(numeric(8,2),avg(thruput)) from rs_throughput&lt;br /&gt;
where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name like &amp;quot;%${q_name}%&amp;quot;&lt;br /&gt;
--get current queue size&lt;br /&gt;
select @size = size from rs_throughput where q_name like &amp;quot;%${q_name}%&amp;quot; having sample_time=max(sample_time)&lt;br /&gt;
select @eta = dateadd(mi,round((@size/@mb_avg),0),getdate())&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
print &amp;quot; Average for ${q_name}: %1! mb/min,  Re-sync ETA: %2!&amp;quot;, @mb_avg, @eta&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_help_text()&lt;br /&gt;
{&lt;br /&gt;
printf &amp;quot;Usage examples:\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh (runs with default values showing all queues over 15 minutes)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh &amp;lt;q_name&amp;gt;|&amp;lt;minutes&amp;gt;\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh &amp;lt;q_name&amp;gt; &amp;lt;minutes&amp;gt;\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh size|queue (shows current queue sizes)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh max (shows highest ever throughput for queue history)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh help (shows this helptext)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh insert # this is for cron only (inserts data to $RPT_DB..rs_throughput table)\n&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_max_thruput()&lt;br /&gt;
{&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
set rowcount 0&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @q_name char(22)&lt;br /&gt;
declare @sample_time datetime&lt;br /&gt;
declare @max_thruput numeric(8,2)&lt;br /&gt;
select q_name, sample_time, thruput into #throughput from rs_throughput where 1=0&lt;br /&gt;
print &amp;quot;Maximum throughput per queue:&amp;quot;&lt;br /&gt;
-- get list of queues&lt;br /&gt;
select distinct q_name, 0 as processed into #queues from rs_throughput&lt;br /&gt;
set rowcount 1&lt;br /&gt;
select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
while @@rowcount != 0&lt;br /&gt;
begin&lt;br /&gt;
  insert #throughput select q_name, sample_time, thruput from rs_throughput&lt;br /&gt;
  where sample_time in&lt;br /&gt;
    (select sample_time from rs_throughput where q_name = @q_name having thruput = max(thruput))&lt;br /&gt;
  and q_name = @q_name&lt;br /&gt;
  update #queues set processed = 1 where q_name = @q_name&lt;br /&gt;
  select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
end&lt;br /&gt;
set rowcount 0&lt;br /&gt;
select * from #throughput order by thruput desc&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
echo&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_current_q_size()&lt;br /&gt;
{&lt;br /&gt;
$RISQLCMD &amp;lt;&amp;lt; eof &amp;gt; $SQMFILE&lt;br /&gt;
admin who,sqm&lt;br /&gt;
go&lt;br /&gt;
quit&lt;br /&gt;
eof&lt;br /&gt;
printf &amp;quot;Current Stable Queue usage:\n&amp;quot;&lt;br /&gt;
cat $SQMFILE | egrep $insert_filter | sed 's/Awaiting Message/AwaitingMessage/; s/Awaiting Wakeup/AwaitingWakeup/; s/\(\.[0-9][0-&lt;br /&gt;
&lt;br /&gt;
9]*\)\.[0-9]/\1/' | grep -v &amp;quot;:0 ${primary_ds}&amp;quot; | awk '{print $4,$14,$15,$16}' | while read q_name first_seg last_seg next_seg&lt;br /&gt;
do&lt;br /&gt;
  q_size=$(bcalc &amp;quot;$last_seg - $first_seg&amp;quot;)&lt;br /&gt;
  printf &amp;quot;$q_name: $q_size\n&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_combined_avg_thruput()&lt;br /&gt;
{&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set rowcount 0&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @q_name varchar(25)&lt;br /&gt;
declare @mb_avg numeric(8,2)&lt;br /&gt;
declare @mb_combined_avg numeric(8,2)&lt;br /&gt;
select @mb_combined_avg=0&lt;br /&gt;
-- get list of queues&lt;br /&gt;
&lt;br /&gt;
select distinct q_name, 0 as processed into #queues from rs_throughput&lt;br /&gt;
set rowcount 1&lt;br /&gt;
select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
while @@rowcount != 0&lt;br /&gt;
begin&lt;br /&gt;
  select @mb_avg = convert(numeric(8,2),avg(thruput)) from rs_throughput&lt;br /&gt;
  where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name = @q_name&lt;br /&gt;
  select @mb_combined_avg = @mb_combined_avg + @mb_avg&lt;br /&gt;
  update #queues set processed=1 where q_name = @q_name&lt;br /&gt;
  select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
end&lt;br /&gt;
print &amp;quot; Combined thruput average: %1! mb/min&amp;quot;, @mb_combined_avg&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                             main program                                   #&lt;br /&gt;
##############################################################################&lt;br /&gt;
&lt;br /&gt;
check_previous_instance&lt;br /&gt;
fn_checkusage&lt;br /&gt;
&lt;br /&gt;
case &amp;quot;$option1&amp;quot; in&lt;br /&gt;
        help) fn_show_help_text;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
      insert) fn_insert_thruput_data;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
         max) fn_show_max_thruput;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
       queue|size) fn_show_current_q_size;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
           *) fn_report_thruput;&lt;br /&gt;
              fn_show_combined_avg_thruput;;&lt;br /&gt;
esac&lt;br /&gt;
&lt;br /&gt;
fn_housekeeping&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
### TABLE DEFINTION FOR RAW DATA COLLECTION&lt;br /&gt;
### Use the table definition below to create the table which this script &lt;br /&gt;
### requires in order to insert queue data and furthermore query this&lt;br /&gt;
### data in order to provide throughput information.&lt;br /&gt;
#create table rs_throughput (&lt;br /&gt;
#q_name varchar(25), &lt;br /&gt;
#sample_time datetime, &lt;br /&gt;
#first numeric(8,2), &lt;br /&gt;
#last numeric(8,2), &lt;br /&gt;
#next numeric(8,2), &lt;br /&gt;
#size numeric(8,2), &lt;br /&gt;
#mb_processed numeric(8,2),&lt;br /&gt;
#thruput numeric(8,2)&lt;br /&gt;
#)&lt;br /&gt;
&lt;br /&gt;
# end program&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:RepServer]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=RepServer_Throughput_Script&amp;diff=1865</id>
		<title>RepServer Throughput Script</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=RepServer_Throughput_Script&amp;diff=1865"/>
				<updated>2009-02-26T11:22:17Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to know just how much data repserver is processing, then this is the tool.&amp;lt;br&amp;gt;&lt;br /&gt;
This script will tell you:&amp;lt;br&amp;gt;&lt;br /&gt;
o average throughput per queue (mb per minute)&amp;lt;br&amp;gt;&lt;br /&gt;
o average throughput combined (all queues)&amp;lt;br&amp;gt;&lt;br /&gt;
o estimated time for a replicate to catch up (Re-sync ETA)&amp;lt;br&amp;gt;&lt;br /&gt;
o current queue sizes&amp;lt;br&amp;gt;&lt;br /&gt;
There is also a maximum recorded throughput option but this appears not to work well as some of the figures have been suspicious.&amp;lt;br&amp;gt;&lt;br /&gt;
The real maximum throughput can be established by noting when the replicates start to fall behind in conjunction with the current throughput figures.&amp;lt;br&amp;gt;&lt;br /&gt;
This script can be particularly useful in helping to ascertain if you need to throw more CPU at your repserver box.&lt;br /&gt;
&lt;br /&gt;
Notes:&amp;lt;br&amp;gt;&lt;br /&gt;
1) You will need to cron this script with the insert option (rs_throughput.sh insert) and allow it to collect at least 2 samples before being able to run it interactively to obtain throughput information.  The script runs silently when run with the insert option.&amp;lt;br&amp;gt;&lt;br /&gt;
2) The script automatically determines the elapsed interval in minutes between samples so you can cron the script to your preferred interval, be it 3 minutes or 10 minutes, the mb/min figure will be calculated correctly.&amp;lt;br&amp;gt;&lt;br /&gt;
3) In addition to configuring the script to your environment, you will also need to create the rs_throughput table prior to first run.&amp;lt;br&amp;gt;&lt;br /&gt;
4) Re-sync ETA: this value is provided based on the current throughput average for the period specified.  For example, this means that running rs_throughput.sh 15 may give a different Re-Sync ETA compared to running rs_throughput.sh 20&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/ksh&lt;br /&gt;
#&lt;br /&gt;
# Script: rs_throughput.sh&lt;br /&gt;
# Author: Bob Holmes - email: cambob@gmail.com&lt;br /&gt;
# Date  : 19/09/08&lt;br /&gt;
# Version : 1.0&lt;br /&gt;
# Usage : Run &amp;quot;rs_throughput.sh help&amp;quot; for full usage information.&lt;br /&gt;
# Description : This script enables monitoring and reporting&lt;br /&gt;
#               of repserver throughput.&lt;br /&gt;
# --------------------------&lt;br /&gt;
#    ***    Variables for customisation can be found by searching for &amp;quot;!!&amp;quot; ***&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Modification history:&lt;br /&gt;
# 19/02/09 : Bob Holmes : Script modified to enable easier customisation prior&lt;br /&gt;
#                         to release on Sybase wiki. (modifications not tested)&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Comments: This script relies on the reporting..rs_throughput table for data&lt;br /&gt;
#           collection and reporting.  The definition for this table can be&lt;br /&gt;
#           found at the end of this script. &lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           setup environment                                #&lt;br /&gt;
##############################################################################&lt;br /&gt;
#&lt;br /&gt;
# save input variables&lt;br /&gt;
if ! [[ -z $1 ]]&lt;br /&gt;
then&lt;br /&gt;
  export option1=$1&lt;br /&gt;
else&lt;br /&gt;
  export option1=&amp;quot;all&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if ! [[ -z $2 ]]&lt;br /&gt;
then&lt;br /&gt;
  export option2=$2&lt;br /&gt;
else&lt;br /&gt;
  export option2=&amp;quot;15&amp;quot; # default number of minutes on which to report throughput&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# configure environment&lt;br /&gt;
HOSTNAME=`hostname`&lt;br /&gt;
. $HOME/admin/.syb_cfg.sh $HOSTNAME  # !! This line sets up the environment from&lt;br /&gt;
                                     # !! from an external shell script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           config variables                                 #&lt;br /&gt;
##############################################################################&lt;br /&gt;
# config:&lt;br /&gt;
primary_ds=&amp;quot;prim_ds&amp;quot;                   # !! string used to identify the inbound queue&lt;br /&gt;
# queues to query on:-&lt;br /&gt;
q_list=&amp;quot;prim_ds.db1 prim_ds.db2 replicate_ds.db1 replicate_ds.db2&amp;quot; # !!&lt;br /&gt;
insert_filter=&amp;quot;db1 db2&amp;quot;                # !! data will only be collected for queue names which have this keyword in&lt;br /&gt;
REP_SRV=&amp;quot;repsrv_rs&amp;quot;                    # !! the actual repserver from which to get sqm info&lt;br /&gt;
RPT_SRV=&amp;quot;reporting_ds&amp;quot;                 # !! dataserver which manages the reporting database&lt;br /&gt;
RPT_DB=&amp;quot;reporting&amp;quot;                     # !! reporting database name&lt;br /&gt;
RECIPIENTS=&amp;quot;user@domain&amp;quot;               # !! email config (separate addresses with commas)&lt;br /&gt;
ADMINDIR=&amp;quot;/opt/home/sybase/admin&amp;quot;      # !! sybase admin directory&lt;br /&gt;
RSPASS=&amp;quot;&amp;lt;command to retrieve pw&amp;gt;&amp;quot;      # !! insert equivalent command&lt;br /&gt;
ASEPASS=&amp;quot;&amp;lt;command to retrieve pw&amp;gt;&amp;quot;     # !! insert equivalent command&lt;br /&gt;
&lt;br /&gt;
# static:&lt;br /&gt;
SQMFILE=&amp;quot;$ADMINDIR/rs_sqm_tmp1.tmp&amp;quot;&lt;br /&gt;
DATE=$(date &amp;quot;+%d/%m/%y %H:%M:%S&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# config aware environment variables: # !! You may need to replace the line below with the equivalent&lt;br /&gt;
                                      # !! for your own environment. &lt;br /&gt;
RISQLCMD=&amp;quot;isql -Usa -P${RSPASS} -S${REP_SRV} -w1000&amp;quot;&lt;br /&gt;
ISQLCMD=&amp;quot;isql -Usa -P${SYBPASS} -S${RPT_SRV} -w200 -D${RPT_DB}&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                             functions                                      #&lt;br /&gt;
##############################################################################&lt;br /&gt;
&lt;br /&gt;
check_previous_instance()&lt;br /&gt;
{&lt;br /&gt;
# Note: next line greps for 8 instances as tests proved that less could cause the script to exit incorrectly&lt;br /&gt;
if [ $(ps -ef | grep rs_throughput | egrep -v &amp;quot;vi|grep&amp;quot; | grep -v &amp;quot;sh -c&amp;quot; | wc -l | awk '{print $1}') -gt 8 ]&lt;br /&gt;
then&lt;br /&gt;
  # previous instance still running - probably hanging&lt;br /&gt;
  echo Previous instance still running.&lt;br /&gt;
  exit&lt;br /&gt;
fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_checkusage()&lt;br /&gt;
{&lt;br /&gt;
if [[ -z $option1 ]]&lt;br /&gt;
then&lt;br /&gt;
  printf &amp;quot; Usage: ./rs_throughput.sh &amp;lt;all&amp;gt;|&amp;lt;q_name&amp;gt;|&amp;lt;help&amp;gt; [&amp;lt;minutes to display&amp;gt;]\n&amp;quot;&lt;br /&gt;
  exit&lt;br /&gt;
fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bcalc()&lt;br /&gt;
{&lt;br /&gt;
awk 'BEGIN{EQUATION='&amp;quot;$*&amp;quot;';printf(&amp;quot;%0.1f\n&amp;quot;,EQUATION); exit}'&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_housekeeping()&lt;br /&gt;
{&lt;br /&gt;
if [ -e $SQMFILE ]&lt;br /&gt;
then&lt;br /&gt;
  rm $SQMFILE&lt;br /&gt;
fi&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
go&lt;br /&gt;
delete from rs_throughput where sample_time &amp;lt;= dateadd(dd,-28,getdate())&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_insert_thruput_data()&lt;br /&gt;
{&lt;br /&gt;
# 1) get current segment usage/progress info&lt;br /&gt;
#connect to repserver, get sqm info - put into file&lt;br /&gt;
$RISQLCMD &amp;lt;&amp;lt; eof &amp;gt; $SQMFILE&lt;br /&gt;
admin who,sqm&lt;br /&gt;
go&lt;br /&gt;
quit&lt;br /&gt;
eof&lt;br /&gt;
&lt;br /&gt;
# 2) insert new segment data into rs_throughput table&lt;br /&gt;
#date&lt;br /&gt;
#echo &amp;quot;Queue Name, First segment, Last segment, Next segment&amp;quot;&lt;br /&gt;
cat $SQMFILE | egrep $insert_filter | sed 's/Awaiting Message/AwaitingMessage/; s/Awaiting Wakeup/AwaitingWakeup/; s/\(\.[0-9][0-&lt;br /&gt;
&lt;br /&gt;
9]*\)\.[0-9]/\1/' | grep -v &amp;quot;:0 ${primary_ds}&amp;quot; | awk '{print $4,$14,$15,$16}' | while read q_name first_seg last_seg next_seg&lt;br /&gt;
do&lt;br /&gt;
  q_size=$(bcalc &amp;quot;$last_seg - $first_seg&amp;quot;)&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
go&lt;br /&gt;
declare @mb_processed numeric(8,2)&lt;br /&gt;
declare @prev_sample datetime&lt;br /&gt;
declare @mins numeric(8,2)&lt;br /&gt;
declare @tput numeric(8,2)&lt;br /&gt;
if not exists (select 1 from rs_throughput where q_name = &amp;quot;${q_name}&amp;quot;)&lt;br /&gt;
insert rs_throughput values (&amp;quot;${q_name}&amp;quot;, getdate(), ${first_seg}, ${last_seg}, ${next_seg}, ${q_size}, 0, 0)&lt;br /&gt;
else&lt;br /&gt;
begin&lt;br /&gt;
-- get previous sample_time as key&lt;br /&gt;
select @prev_sample = max(sample_time) from rs_throughput where q_name = &amp;quot;${q_name}&amp;quot;&lt;br /&gt;
-- get difference in mb between current next segment and previous next segment&lt;br /&gt;
select @mb_processed = (select ${next_seg} - next from rs_throughput where sample_time = @prev_sample and q_name = &amp;quot;${q_name}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
select @prev_sample=dateadd(ss,-10,@prev_sample) -- # must substract 10 seconds to ensure the next datediff doesn't reflect 2m 58s &lt;br /&gt;
&lt;br /&gt;
as only 2mins!&lt;br /&gt;
select @mins = datediff(mi,@prev_sample,getdate())&lt;br /&gt;
if @mins &amp;gt; 0&lt;br /&gt;
begin&lt;br /&gt;
  select @tput = round((@mb_processed / @mins),2)&lt;br /&gt;
  insert rs_throughput values (&amp;quot;${q_name}&amp;quot;, getdate(), ${first_seg}, ${last_seg}, ${next_seg}, ${q_size}, @mb_processed, @tput)&lt;br /&gt;
end&lt;br /&gt;
end&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_report_thruput()&lt;br /&gt;
{&lt;br /&gt;
if [[ $option1 = [0-9]* ]]&lt;br /&gt;
then&lt;br /&gt;
  option2=$option1&lt;br /&gt;
  option1=&amp;quot;all&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if ! [[ &amp;quot;$option1&amp;quot; = &amp;quot;all&amp;quot; ]]&lt;br /&gt;
then&lt;br /&gt;
  q_list=$option1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
printf &amp;quot; -------------------------------------\n&amp;quot;&lt;br /&gt;
printf &amp;quot; Run date $DATE\n&amp;quot;&lt;br /&gt;
printf &amp;quot; -------------------------------------\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
for q_name in $q_list&lt;br /&gt;
do&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @mb_avg numeric(8,2)&lt;br /&gt;
declare @size numeric(8,2)&lt;br /&gt;
declare @eta datetime&lt;br /&gt;
select convert(char(19),sample_time) sample_time, q_name, size q_size, mb_processed, thruput &amp;quot;thruput (mb/min)&amp;quot;  from rs_throughput&lt;br /&gt;
--select convert(char(19),sample_time) sample_time, q_name, size q_size, mb_processed, thruput &amp;quot;thruput (mb/min)&amp;quot;, dateadd(mi,&lt;br /&gt;
&lt;br /&gt;
(round((size/thruput),0)),getdate()) ETA from rs_throughput&lt;br /&gt;
where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name like &amp;quot;%${q_name}%&amp;quot;&lt;br /&gt;
&lt;br /&gt;
--get mb average&lt;br /&gt;
select @mb_avg = convert(numeric(8,2),avg(thruput)) from rs_throughput&lt;br /&gt;
where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name like &amp;quot;%${q_name}%&amp;quot;&lt;br /&gt;
--get current queue size&lt;br /&gt;
select @size = size from rs_throughput where q_name like &amp;quot;%${q_name}%&amp;quot; having sample_time=max(sample_time)&lt;br /&gt;
select @eta = dateadd(mi,round((@size/@mb_avg),0),getdate())&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
print &amp;quot; Average for ${q_name}: %1! mb/min,  Re-sync ETA: %2!&amp;quot;, @mb_avg, @eta&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_help_text()&lt;br /&gt;
{&lt;br /&gt;
printf &amp;quot;Usage examples:\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh (runs with default values showing all queues over 15 minutes)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh &amp;lt;q_name&amp;gt;|&amp;lt;minutes&amp;gt;\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh &amp;lt;q_name&amp;gt; &amp;lt;minutes&amp;gt;\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh size|queue (shows current queue sizes)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh max (shows highest ever throughput for queue history)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh help (shows this helptext)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh insert # this is for cron only (inserts data to $RPT_DB..rs_throughput table)\n&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_max_thruput()&lt;br /&gt;
{&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
set rowcount 0&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @q_name char(22)&lt;br /&gt;
declare @sample_time datetime&lt;br /&gt;
declare @max_thruput numeric(8,2)&lt;br /&gt;
select q_name, sample_time, thruput into #throughput from rs_throughput where 1=0&lt;br /&gt;
print &amp;quot;Maximum throughput per queue:&amp;quot;&lt;br /&gt;
-- get list of queues&lt;br /&gt;
select distinct q_name, 0 as processed into #queues from rs_throughput&lt;br /&gt;
set rowcount 1&lt;br /&gt;
select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
while @@rowcount != 0&lt;br /&gt;
begin&lt;br /&gt;
  insert #throughput select q_name, sample_time, thruput from rs_throughput&lt;br /&gt;
  where sample_time in&lt;br /&gt;
    (select sample_time from rs_throughput where q_name = @q_name having thruput = max(thruput))&lt;br /&gt;
  and q_name = @q_name&lt;br /&gt;
  update #queues set processed = 1 where q_name = @q_name&lt;br /&gt;
  select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
end&lt;br /&gt;
set rowcount 0&lt;br /&gt;
select * from #throughput order by thruput desc&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
echo&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_current_q_size()&lt;br /&gt;
{&lt;br /&gt;
$RISQLCMD &amp;lt;&amp;lt; eof &amp;gt; $SQMFILE&lt;br /&gt;
admin who,sqm&lt;br /&gt;
go&lt;br /&gt;
quit&lt;br /&gt;
eof&lt;br /&gt;
printf &amp;quot;Current Stable Queue usage:\n&amp;quot;&lt;br /&gt;
cat $SQMFILE | egrep $insert_filter | sed 's/Awaiting Message/AwaitingMessage/; s/Awaiting Wakeup/AwaitingWakeup/; s/\(\.[0-9][0-&lt;br /&gt;
&lt;br /&gt;
9]*\)\.[0-9]/\1/' | grep -v &amp;quot;:0 ${primary_ds}&amp;quot; | awk '{print $4,$14,$15,$16}' | while read q_name first_seg last_seg next_seg&lt;br /&gt;
do&lt;br /&gt;
  q_size=$(bcalc &amp;quot;$last_seg - $first_seg&amp;quot;)&lt;br /&gt;
  printf &amp;quot;$q_name: $q_size\n&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_combined_avg_thruput()&lt;br /&gt;
{&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set rowcount 0&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @q_name varchar(25)&lt;br /&gt;
declare @mb_avg numeric(8,2)&lt;br /&gt;
declare @mb_combined_avg numeric(8,2)&lt;br /&gt;
select @mb_combined_avg=0&lt;br /&gt;
-- get list of queues&lt;br /&gt;
&lt;br /&gt;
select distinct q_name, 0 as processed into #queues from rs_throughput&lt;br /&gt;
set rowcount 1&lt;br /&gt;
select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
while @@rowcount != 0&lt;br /&gt;
begin&lt;br /&gt;
  select @mb_avg = convert(numeric(8,2),avg(thruput)) from rs_throughput&lt;br /&gt;
  where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name = @q_name&lt;br /&gt;
  select @mb_combined_avg = @mb_combined_avg + @mb_avg&lt;br /&gt;
  update #queues set processed=1 where q_name = @q_name&lt;br /&gt;
  select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
end&lt;br /&gt;
print &amp;quot; Combined thruput average: %1! mb/min&amp;quot;, @mb_combined_avg&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                             main program                                   #&lt;br /&gt;
##############################################################################&lt;br /&gt;
&lt;br /&gt;
check_previous_instance&lt;br /&gt;
fn_checkusage&lt;br /&gt;
&lt;br /&gt;
case &amp;quot;$option1&amp;quot; in&lt;br /&gt;
        help) fn_show_help_text;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
      insert) fn_insert_thruput_data;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
         max) fn_show_max_thruput;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
       queue|size) fn_show_current_q_size;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
           *) fn_report_thruput;&lt;br /&gt;
              fn_show_combined_avg_thruput;;&lt;br /&gt;
esac&lt;br /&gt;
&lt;br /&gt;
fn_housekeeping&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
### TABLE DEFINTION FOR RAW DATA COLLECTION&lt;br /&gt;
### Use the table definition below to create the table which this script &lt;br /&gt;
### requires in order to insert queue data and furthermore query this&lt;br /&gt;
### data in order to provide throughput information.&lt;br /&gt;
#create table rs_throughput (&lt;br /&gt;
#q_name varchar(25), &lt;br /&gt;
#sample_time datetime, &lt;br /&gt;
#first numeric(8,2), &lt;br /&gt;
#last numeric(8,2), &lt;br /&gt;
#next numeric(8,2), &lt;br /&gt;
#size numeric(8,2), &lt;br /&gt;
#mb_processed numeric(8,2),&lt;br /&gt;
#thruput numeric(8,2)&lt;br /&gt;
#)&lt;br /&gt;
&lt;br /&gt;
# end program&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:RepServer]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=Sp_mon_sql2--ASE_spid_activity_monitor&amp;diff=1863</id>
		<title>Sp mon sql2--ASE spid activity monitor</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=Sp_mon_sql2--ASE_spid_activity_monitor&amp;diff=1863"/>
				<updated>2009-02-23T23:16:15Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: This SP uses the MDA tables.&amp;lt;BR&amp;gt;&lt;br /&gt;
This sp is for getting a clear list of currently active spids with full details including login, db, blocking spid, processing time, query start time, cpu usage, logical and physical i/o, currently executing command etc.  To maximise clarity, all info is displayed on one line for each spid.  Alternate info is also available by running with '1' (without quotes) which includes, login time, host process, originating host and other information which may be useful for tracking down the source of a problem external to ASE.  Note, unfortunately the '1' option was a quick hack - the sp needs modifying to change this to an 'x' or something similar as the sp can also be called with &amp;lt;spid&amp;gt; to investigate a spid which is not currently active.&lt;br /&gt;
&lt;br /&gt;
Usage summary:&amp;lt;BR&amp;gt;&lt;br /&gt;
sp__mon_sql2&amp;lt;BR&amp;gt;&lt;br /&gt;
sp__mon_sql2 &amp;lt;spid&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
sp__mon_sql2 1  (due to the quick hack noted above, if you want to investigate spid 1, you can't! sorry - I'll fix it in the next version. Luckily the need to investigate spid 1 is quite rare.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
create procedure sp__mon_sql2&lt;br /&gt;
(&lt;br /&gt;
@spid int = 0&lt;br /&gt;
)&lt;br /&gt;
as&lt;br /&gt;
------------------------------&lt;br /&gt;
-- Procedure: sp__mon_sql2&lt;br /&gt;
--   Created: April 2008&lt;br /&gt;
--    Author: Bob Holmes (Email: cambob@gmail.com)&lt;br /&gt;
--     Usage: sp__mon_sql2 [spid]&lt;br /&gt;
-- Last modification: bobh - if 1 is specified as the spid number then alternate info is returned (dirty hack)&lt;br /&gt;
------------------------------&lt;br /&gt;
-- INFO:&lt;br /&gt;
-- The three *'s are a grep key for a shell script to use to extract the lines needed for alerting.&lt;br /&gt;
------------------------------&lt;br /&gt;
--part 1 - snapshot&lt;br /&gt;
set forceplan on&lt;br /&gt;
select 	s.StartTime, &lt;br /&gt;
	convert(smallint,(datediff(mi,StartTime,getdate()))) Dmins,  &lt;br /&gt;
	p.spid, &lt;br /&gt;
	p.hostname, &lt;br /&gt;
	p.suid, &lt;br /&gt;
	p.dbid, &lt;br /&gt;
	p.cmd, &lt;br /&gt;
        p.blocked,&lt;br /&gt;
	s.CpuTime, &lt;br /&gt;
	s.LogicalReads, &lt;br /&gt;
	s.PhysicalReads,&lt;br /&gt;
	p.status, &lt;br /&gt;
	p.loggedindatetime,&lt;br /&gt;
	p.program_name, &lt;br /&gt;
	l.ClientOSPID, &lt;br /&gt;
	p.time_blocked, &lt;br /&gt;
	p.ipaddr&lt;br /&gt;
into #processmon2&lt;br /&gt;
from master..sysprocesses p, master..monProcessStatement s, master..monProcessLookup l&lt;br /&gt;
where p.spid != @@spid&lt;br /&gt;
and p.spid *= s.SPID&lt;br /&gt;
and l.SPID = p.spid&lt;br /&gt;
and suid &amp;lt;&amp;gt; 0&lt;br /&gt;
order by p.spid&lt;br /&gt;
set forceplan off&lt;br /&gt;
&lt;br /&gt;
--part 2 --display spid summaries&lt;br /&gt;
&lt;br /&gt;
if @spid=0&lt;br /&gt;
begin&lt;br /&gt;
-- display header information for multiple spids&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;Process Summary (Order by Dmins, CpuTime, LogicalReads, PhysicalReads Desc )&amp;quot;&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;&amp;quot;&lt;br /&gt;
  select distinct &amp;quot;***&amp;quot;,&lt;br /&gt;
  spid Spid,&lt;br /&gt;
  convert(char(12),suser_name(suid)) Login,&lt;br /&gt;
  convert(char(16),db_name(dbid)) DB,&lt;br /&gt;
  (case hostname when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),hostname) end) Hostname,&lt;br /&gt;
  blocked,&lt;br /&gt;
  convert(varchar(19),StartTime) StartTime,&lt;br /&gt;
  Dmins,&lt;br /&gt;
  right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins/60)),2) + &amp;quot;:&amp;quot; + right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins%60)),2) Dtime,&lt;br /&gt;
  CpuTime,&lt;br /&gt;
  LogicalReads,&lt;br /&gt;
  PhysicalReads,&lt;br /&gt;
  cmd Command&lt;br /&gt;
  from #processmon2&lt;br /&gt;
  where cmd &amp;lt;&amp;gt; &amp;quot;AWAITING COMMAND&amp;quot;&lt;br /&gt;
  order by Dmins desc, CpuTime Desc, LogicalReads Desc, PhysicalReads Desc&lt;br /&gt;
end&lt;br /&gt;
else if @spid=1&lt;br /&gt;
begin&lt;br /&gt;
-- display header information for multiple spids&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;Process Summary (Order by Dmins, CpuTime, LogicalReads, PhysicalReads Desc )&amp;quot;&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;&amp;quot;&lt;br /&gt;
select &lt;br /&gt;
  spid Spid,&lt;br /&gt;
  convert(char(12),suser_name(suid)) Login,&lt;br /&gt;
  convert(char(15),db_name(dbid)) DB,&lt;br /&gt;
  (case hostname when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),hostname) end) Hostname,&lt;br /&gt;
  blocked,&lt;br /&gt;
  convert(varchar(19),StartTime) StartTime,&lt;br /&gt;
  Dmins,&lt;br /&gt;
  right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins/60)),2) + &amp;quot;:&amp;quot; + right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins%60)),2) Dtime,&lt;br /&gt;
  (case program_name when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),program_name) end) Application,&lt;br /&gt;
  (case ClientOSPID when NULL then &amp;quot;-&amp;quot; else convert(char(7),ClientOSPID) end) &amp;quot;OS PID&amp;quot;,&lt;br /&gt;
  time_blocked &amp;quot;Blocked(s)&amp;quot;,&lt;br /&gt;
  convert(char(8),loggedindatetime,108) &amp;quot;Logged in&amp;quot;,&lt;br /&gt;
  convert(char(15),ipaddr) ClientIP,&lt;br /&gt;
  cmd Command&lt;br /&gt;
  from #processmon2&lt;br /&gt;
  where cmd &amp;lt;&amp;gt; &amp;quot;AWAITING COMMAND&amp;quot;&lt;br /&gt;
  order by Dmins desc, CpuTime Desc, LogicalReads Desc, PhysicalReads Desc&lt;br /&gt;
end&lt;br /&gt;
else&lt;br /&gt;
begin&lt;br /&gt;
select distinct &amp;quot;***&amp;quot;,&lt;br /&gt;
  spid Spid,&lt;br /&gt;
  convert(char(12),suser_name(suid)) Login,&lt;br /&gt;
  convert(char(16),db_name(dbid)) DB,&lt;br /&gt;
  (case hostname when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),hostname) end) Hostname,&lt;br /&gt;
  convert(varchar(19),StartTime) StartTime,&lt;br /&gt;
  Dmins,&lt;br /&gt;
  blocked,&lt;br /&gt;
  right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins/60)),2) + &amp;quot;:&amp;quot; + right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins%60)),2) Dtime,&lt;br /&gt;
  CpuTime,&lt;br /&gt;
  LogicalReads,&lt;br /&gt;
  PhysicalReads,&lt;br /&gt;
  cmd Command&lt;br /&gt;
  from #processmon2&lt;br /&gt;
  where spid = @spid&lt;br /&gt;
  order by Dmins desc, CpuTime Desc, LogicalReads Desc, PhysicalReads Desc&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:ASE]]&lt;br /&gt;
[[Category:MDA tables]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=Sp_block--check_analyse_blocked_processes&amp;diff=1862</id>
		<title>Sp block--check analyse blocked processes</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=Sp_block--check_analyse_blocked_processes&amp;diff=1862"/>
				<updated>2009-02-23T12:17:30Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: Initial version.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This sp checks for blocked processes and, if found, returns the spid info, sql text and query plan.  It requires sp__mon_sql2 and sp__capture_sql.&amp;lt;br&amp;gt;&lt;br /&gt;
It could do with some extra work to filter out the spids which are not the root blocking spids; it can produce a large amount of output if there are a high number of individual spids involved in a chain of blocks.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
create proc sp__block&lt;br /&gt;
as&lt;br /&gt;
------------------------------&lt;br /&gt;
-- Procedure: sp__block&lt;br /&gt;
--   Created: April 2008&lt;br /&gt;
--    Author: Bob Holmes&lt;br /&gt;
-- Last modification: &lt;br /&gt;
-- Dependencies: sp__mon_sql2, sp__capture_sql&lt;br /&gt;
------------------------------&lt;br /&gt;
declare @numblocks int&lt;br /&gt;
select @numblocks = count(*) from master..sysprocesses where blocked &amp;lt;&amp;gt; 0&lt;br /&gt;
-- list blocked processes&lt;br /&gt;
print &amp;quot; %1! Blocked Processes&amp;quot;, @numblocks&lt;br /&gt;
print &amp;quot; ==============================================================================================&amp;quot;&lt;br /&gt;
print &amp;quot;                                                                      duration&amp;quot;&lt;br /&gt;
select spid,&lt;br /&gt;
convert(char(12),suser_name(suid)) login,&lt;br /&gt;
convert(char(16),db_name(dbid)) db,&lt;br /&gt;
hostname,&lt;br /&gt;
blocked &amp;quot;blocked by&amp;quot;,&lt;br /&gt;
convert(varchar(9),StartTime,108) StartTime,&lt;br /&gt;
right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(time_blocked/60/60)),2)&lt;br /&gt;
  + &amp;quot;:&amp;quot;&lt;br /&gt;
  +right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),((time_blocked/60)-((time_blocked/60/60)*60))),2)&lt;br /&gt;
  + &amp;quot;:&amp;quot;&lt;br /&gt;
  + right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(time_blocked%60)),2) &amp;quot;hh:mm:ss&amp;quot;,&lt;br /&gt;
cmd Command&lt;br /&gt;
from master..sysprocesses, master..monProcessStatement&lt;br /&gt;
where blocked &amp;lt;&amp;gt; 0&lt;br /&gt;
and spid = SPID&lt;br /&gt;
&lt;br /&gt;
if @numblocks &amp;lt;&amp;gt; 0&lt;br /&gt;
begin&lt;br /&gt;
 --prep list of blocking spids&lt;br /&gt;
  select distinct blocked into #blockingspids from master..sysprocesses where blocked &amp;lt;&amp;gt; 0&lt;br /&gt;
  declare @spid int&lt;br /&gt;
 --get spid info: summary, sql, query plan&lt;br /&gt;
  select @spid = min(blocked) from #blockingspids&lt;br /&gt;
  while @spid &amp;gt;= (select min(blocked) from #blockingspids)&lt;br /&gt;
  begin&lt;br /&gt;
    print &amp;quot;&amp;quot;&lt;br /&gt;
    exec sp__mon_sql2 @spid&lt;br /&gt;
    exec sp__capture_sql @spid&lt;br /&gt;
    exec sp_showplan @spid, null, null, null&lt;br /&gt;
    print &amp;quot;Tables in use by Spid %1!&amp;quot;, @spid&lt;br /&gt;
    print &amp;quot;-----------------------------&amp;quot;&lt;br /&gt;
    select&lt;br /&gt;
    a.SPID,&lt;br /&gt;
    convert(char(12),a.Login) Login,&lt;br /&gt;
    convert(char(15),a.ClientHost),&lt;br /&gt;
    convert(char(15),a.ClientIP) ClientIP,&lt;br /&gt;
    convert(char(15),b.DBName) DBName,&lt;br /&gt;
    b.ObjectName,&lt;br /&gt;
    c.LogicalReads,&lt;br /&gt;
    c.PhysicalReads,&lt;br /&gt;
    c.PhysicalWrites,&lt;br /&gt;
    b.TableSize&lt;br /&gt;
    from master..monProcessLookup a, master..monProcessObject b, master..monProcessActivity c&lt;br /&gt;
    where a.SPID = b.SPID&lt;br /&gt;
    and b.SPID = c.SPID&lt;br /&gt;
    and a.SPID = @spid&lt;br /&gt;
    order by c.PhysicalWrites desc&lt;br /&gt;
&lt;br /&gt;
    if (@spid = (select max(blocked) from #blockingspids)) or (@spid = null)&lt;br /&gt;
      break&lt;br /&gt;
    select @spid = min(blocked) from #blockingspids where blocked &amp;gt; @spid&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
return&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[Category:ASE]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=Sp_tempdbuse--Check_usage_of_all_tempdbs&amp;diff=1861</id>
		<title>Sp tempdbuse--Check usage of all tempdbs</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=Sp_tempdbuse--Check_usage_of_all_tempdbs&amp;diff=1861"/>
				<updated>2009-02-23T12:03:39Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This sp cycles through all databases with 'tempdb' in the name and outputs usage information - size, percent used etc.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
create procedure sp__tempdbuse&lt;br /&gt;
as&lt;br /&gt;
------------------------------&lt;br /&gt;
-- Procedure: sp__tempdbuse&lt;br /&gt;
--   Created: May 2008&lt;br /&gt;
--    Author: Bob Holmes (Email: cambob@gmail.com)&lt;br /&gt;
--     Usage: sp__tempdbuse&lt;br /&gt;
------------------------------&lt;br /&gt;
set nocount on&lt;br /&gt;
&lt;br /&gt;
select name into #dblist from master..sysdatabases where name like &amp;quot;%tempdb%&amp;quot;&lt;br /&gt;
&lt;br /&gt;
declare db_cursor cursor&lt;br /&gt;
for select name from #dblist&lt;br /&gt;
&lt;br /&gt;
declare @current char(20)&lt;br /&gt;
&lt;br /&gt;
open db_cursor&lt;br /&gt;
&lt;br /&gt;
fetch db_cursor into @current&lt;br /&gt;
&lt;br /&gt;
create table #results (dbname char(20), totalspace char(10), freespace char(10), &lt;br /&gt;
&lt;br /&gt;
pctused char(3))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
while @@sqlstatus = 0&lt;br /&gt;
begin&lt;br /&gt;
  select  db_name(dbid) 'DatabaseName', segmap 'Segmap', name 'Segname',&lt;br /&gt;
          sum(size) 'Allocated',&lt;br /&gt;
          sum(curunreservedpgs(dbid,lstart,unreservedpgs)) 'Free'&lt;br /&gt;
  into    #SegAlloc&lt;br /&gt;
  from    master.dbo.sysusages , syssegments&lt;br /&gt;
  where   dbid = db_id(@current) and&lt;br /&gt;
          segmap &amp;amp; power(2,segment) = power(2,segment)&lt;br /&gt;
          and syssegments.name != 'system'&lt;br /&gt;
	  and syssegments.name != 'logsegment'&lt;br /&gt;
  group by dbid,segmap,name&lt;br /&gt;
  order by dbid,segmap,name&lt;br /&gt;
&lt;br /&gt;
  insert #results  &lt;br /&gt;
  select  DatabaseName, &lt;br /&gt;
          rtrim(convert(char(10),sum(Allocated)/512)),&lt;br /&gt;
          rtrim(convert(char(10),sum(Free)/512)),&lt;br /&gt;
          rtrim(convert(char(10),100 -(sum((Free)/512) * 100 / (sum&lt;br /&gt;
&lt;br /&gt;
(Allocated)/512))))&lt;br /&gt;
  from    #SegAlloc&lt;br /&gt;
  group by DatabaseName,Segname&lt;br /&gt;
  order by DatabaseName,Segname&lt;br /&gt;
&lt;br /&gt;
  drop table #SegAlloc&lt;br /&gt;
&lt;br /&gt;
  fetch db_cursor into @current&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
select * from #results&lt;br /&gt;
&lt;br /&gt;
close db_cursor&lt;br /&gt;
&lt;br /&gt;
deallocate cursor db_cursor&lt;br /&gt;
&lt;br /&gt;
return&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[category:ASE]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=Sp_tempdbuse--Check_usage_of_all_tempdbs&amp;diff=1860</id>
		<title>Sp tempdbuse--Check usage of all tempdbs</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=Sp_tempdbuse--Check_usage_of_all_tempdbs&amp;diff=1860"/>
				<updated>2009-02-23T12:00:54Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: Initial version.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;create procedure sp__tempdbuse&lt;br /&gt;
as&lt;br /&gt;
------------------------------&lt;br /&gt;
-- Procedure: sp__tempdbuse&lt;br /&gt;
--   Created: May 2008&lt;br /&gt;
--    Author: Bob Holmes (Email: cambob@gmail.com)&lt;br /&gt;
--     Usage: sp__tempdbuse&lt;br /&gt;
------------------------------&lt;br /&gt;
set nocount on&lt;br /&gt;
&lt;br /&gt;
select name into #dblist from master..sysdatabases where name like &amp;quot;%tempdb%&amp;quot;&lt;br /&gt;
&lt;br /&gt;
declare db_cursor cursor&lt;br /&gt;
for select name from #dblist&lt;br /&gt;
&lt;br /&gt;
declare @current char(20)&lt;br /&gt;
&lt;br /&gt;
open db_cursor&lt;br /&gt;
&lt;br /&gt;
fetch db_cursor into @current&lt;br /&gt;
&lt;br /&gt;
create table #results (dbname char(20), totalspace char(10), freespace char(10), &lt;br /&gt;
&lt;br /&gt;
pctused char(3))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
while @@sqlstatus = 0&lt;br /&gt;
begin&lt;br /&gt;
  select  db_name(dbid) 'DatabaseName', segmap 'Segmap', name 'Segname',&lt;br /&gt;
          sum(size) 'Allocated',&lt;br /&gt;
          sum(curunreservedpgs(dbid,lstart,unreservedpgs)) 'Free'&lt;br /&gt;
  into    #SegAlloc&lt;br /&gt;
  from    master.dbo.sysusages , syssegments&lt;br /&gt;
  where   dbid = db_id(@current) and&lt;br /&gt;
          segmap &amp;amp; power(2,segment) = power(2,segment)&lt;br /&gt;
          and syssegments.name != 'system'&lt;br /&gt;
	  and syssegments.name != 'logsegment'&lt;br /&gt;
  group by dbid,segmap,name&lt;br /&gt;
  order by dbid,segmap,name&lt;br /&gt;
&lt;br /&gt;
  insert #results  &lt;br /&gt;
  select  DatabaseName, &lt;br /&gt;
          rtrim(convert(char(10),sum(Allocated)/512)),&lt;br /&gt;
          rtrim(convert(char(10),sum(Free)/512)),&lt;br /&gt;
          rtrim(convert(char(10),100 -(sum((Free)/512) * 100 / (sum&lt;br /&gt;
&lt;br /&gt;
(Allocated)/512))))&lt;br /&gt;
  from    #SegAlloc&lt;br /&gt;
  group by DatabaseName,Segname&lt;br /&gt;
  order by DatabaseName,Segname&lt;br /&gt;
&lt;br /&gt;
  drop table #SegAlloc&lt;br /&gt;
&lt;br /&gt;
  fetch db_cursor into @current&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
select * from #results&lt;br /&gt;
&lt;br /&gt;
close db_cursor&lt;br /&gt;
&lt;br /&gt;
deallocate cursor db_cursor&lt;br /&gt;
&lt;br /&gt;
return&lt;br /&gt;
[[category:ASE]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=RepServer_Throughput_Script&amp;diff=1859</id>
		<title>RepServer Throughput Script</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=RepServer_Throughput_Script&amp;diff=1859"/>
				<updated>2009-02-20T11:15:17Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to know just how much data repserver is processing, then this is the tool.&amp;lt;br&amp;gt;&lt;br /&gt;
This script will tell you:&amp;lt;br&amp;gt;&lt;br /&gt;
o average throughput per queue (mb per minute)&amp;lt;br&amp;gt;&lt;br /&gt;
o average throughput combined (all queues)&amp;lt;br&amp;gt;&lt;br /&gt;
o estimated time for a replicate to catch up (Re-sync ETA)&amp;lt;br&amp;gt;&lt;br /&gt;
o current queue sizes&amp;lt;br&amp;gt;&lt;br /&gt;
There is also a maximum recorded throughput option but this appears not to work well as some of the figures have been suspicious.&amp;lt;br&amp;gt;&lt;br /&gt;
The real maximum throughput can be established by noting when the replicates start to fall behind in conjunction with the current throughput figures.&amp;lt;br&amp;gt;&lt;br /&gt;
This script can be particularly useful in helping to ascertain if you need to throw more CPU at your repserver box.&lt;br /&gt;
&lt;br /&gt;
Notes:&amp;lt;br&amp;gt;&lt;br /&gt;
1) You will need to cron this script with the insert option (rs_throughput.sh insert) and allow it to collect at least 2 samples before being able to run it interactively to obtain throughput information.  The script runs silently when run with the insert option.&amp;lt;br&amp;gt;&lt;br /&gt;
2) The script automatically determines the elapsed interval in minutes between samples so you can cron the script to your preferred interval, be it 3 minutes or 10 minutes, the mb/min figure will be calculated correctly.&amp;lt;br&amp;gt;&lt;br /&gt;
3) In addition to configuring the script to your environment, you will also need to create the rs_throughput table prior to first run.&amp;lt;br&amp;gt;&lt;br /&gt;
4) Re-sync ETA: this value is provided based on the current throughput average for the period specified.  For example, this means that running rs_throughput.sh 15 may give a different Re-Sync ETA compared to running rs_throughput.sh 20&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/ksh&lt;br /&gt;
#&lt;br /&gt;
# Script: rs_throughput.sh&lt;br /&gt;
# Author: Bob Holmes - email: cambob@gmail.com&lt;br /&gt;
# Date  : 19/09/08&lt;br /&gt;
# Version : 1.0&lt;br /&gt;
# Usage : Run &amp;quot;rs_throughput.sh help&amp;quot; for full usage information.&lt;br /&gt;
# Description : This script enables monitoring and reporting&lt;br /&gt;
#               of repserver throughput.&lt;br /&gt;
# --------------------------&lt;br /&gt;
#    ***    Variables for customisation can be found by searching for &amp;quot;!!&amp;quot; ***&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Modification history:&lt;br /&gt;
# 19/02/09 : Bob Holmes : Script modified to enable easier customisation prior&lt;br /&gt;
#                         to release on Sybase wiki. (modifications not tested)&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Comments: This script relies on the reporting..rs_throughput table for data&lt;br /&gt;
#           collection and reporting.  The definition for this table can be&lt;br /&gt;
#           found at the end of this script. &lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           setup environment                                #&lt;br /&gt;
##############################################################################&lt;br /&gt;
#&lt;br /&gt;
# save input variables&lt;br /&gt;
if ! [[ -z $1 ]]&lt;br /&gt;
then&lt;br /&gt;
  export option1=$1&lt;br /&gt;
else&lt;br /&gt;
  export option1=&amp;quot;all&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if ! [[ -z $2 ]]&lt;br /&gt;
then&lt;br /&gt;
  export option2=$2&lt;br /&gt;
else&lt;br /&gt;
  export option2=&amp;quot;15&amp;quot; # default number of minutes on which to report throughput&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# configure environment&lt;br /&gt;
HOSTNAME=`hostname`&lt;br /&gt;
. $HOME/admin/.syb_cfg.sh $HOSTNAME  # !! This line sets up the environment from&lt;br /&gt;
                                     # !! from an external shell script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           config variables                                 #&lt;br /&gt;
##############################################################################&lt;br /&gt;
# config:&lt;br /&gt;
primary_ds=&amp;quot;prim_ds&amp;quot;                   # !! string used to identify the inbound queue&lt;br /&gt;
# queues to query on:-&lt;br /&gt;
q_list=&amp;quot;prim_ds.db1 prim_ds.db2 replicate_ds.db1 replicate_ds.db2&amp;quot; # !!&lt;br /&gt;
insert_filter=&amp;quot;db1 db2&amp;quot;                # !! data will only be collected for queue names which have this keyword in&lt;br /&gt;
REP_SRV=&amp;quot;repsrv_rs&amp;quot;                    # !! the actual repserver from which to get sqm info&lt;br /&gt;
RPT_SRV=&amp;quot;reporting_ds&amp;quot;                 # !! dataserver which manages the reporting database&lt;br /&gt;
RPT_DB=&amp;quot;reporting&amp;quot;                     # !! reporting database name&lt;br /&gt;
RECIPIENTS=&amp;quot;user@domain&amp;quot;               # !! email config (separate addresses with commas)&lt;br /&gt;
ADMINDIR=&amp;quot;/opt/home/sybase/admin&amp;quot;      # !! sybase admin directory&lt;br /&gt;
&lt;br /&gt;
# static:&lt;br /&gt;
SQMFILE=&amp;quot;$ADMINDIR/rs_sqm_tmp1.tmp&amp;quot;&lt;br /&gt;
DATE=$(date &amp;quot;+%d/%m/%y %H:%M:%S&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# config aware environment variables: # !! You may need to replace the line below with the equivalent&lt;br /&gt;
                                      # !! for your own environment. &lt;br /&gt;
RISQLCMD=&amp;quot;isql -Usa -P`grep &amp;quot;$REP_SRV,&amp;quot; $HOME/admin/.servers | cut  -d , -f 4` -S$REP_SRV -w1000&amp;quot;&lt;br /&gt;
ISQLCMD=&amp;quot;isql -Usa -P${SYBPASS} -S${RPT_SRV} -w200 -D${RPT_DB}&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                             functions                                      #&lt;br /&gt;
##############################################################################&lt;br /&gt;
&lt;br /&gt;
check_previous_instance()&lt;br /&gt;
{&lt;br /&gt;
# Note: next line greps for 8 instances as tests proved that less could cause the script to exit incorrectly&lt;br /&gt;
if [ $(ps -ef | grep rs_throughput | egrep -v &amp;quot;vi|grep&amp;quot; | grep -v &amp;quot;sh -c&amp;quot; | wc -l | awk '{print $1}') -gt 8 ]&lt;br /&gt;
then&lt;br /&gt;
  # previous instance still running - probably hanging&lt;br /&gt;
  echo Previous instance still running.&lt;br /&gt;
  exit&lt;br /&gt;
fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_checkusage()&lt;br /&gt;
{&lt;br /&gt;
if [[ -z $option1 ]]&lt;br /&gt;
then&lt;br /&gt;
  printf &amp;quot; Usage: ./rs_throughput.sh &amp;lt;all&amp;gt;|&amp;lt;q_name&amp;gt;|&amp;lt;help&amp;gt; [&amp;lt;minutes to display&amp;gt;]\n&amp;quot;&lt;br /&gt;
  exit&lt;br /&gt;
fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bcalc()&lt;br /&gt;
{&lt;br /&gt;
awk 'BEGIN{EQUATION='&amp;quot;$*&amp;quot;';printf(&amp;quot;%0.1f\n&amp;quot;,EQUATION); exit}'&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_housekeeping()&lt;br /&gt;
{&lt;br /&gt;
if [ -e $SQMFILE ]&lt;br /&gt;
then&lt;br /&gt;
  rm $SQMFILE&lt;br /&gt;
fi&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
go&lt;br /&gt;
delete from rs_throughput where sample_time &amp;lt;= dateadd(dd,-28,getdate())&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_insert_thruput_data()&lt;br /&gt;
{&lt;br /&gt;
# 1) get current segment usage/progress info&lt;br /&gt;
#connect to repserver, get sqm info - put into file&lt;br /&gt;
$RISQLCMD &amp;lt;&amp;lt; eof &amp;gt; $SQMFILE&lt;br /&gt;
admin who,sqm&lt;br /&gt;
go&lt;br /&gt;
quit&lt;br /&gt;
eof&lt;br /&gt;
&lt;br /&gt;
# 2) insert new segment data into rs_throughput table&lt;br /&gt;
#date&lt;br /&gt;
#echo &amp;quot;Queue Name, First segment, Last segment, Next segment&amp;quot;&lt;br /&gt;
cat $SQMFILE | egrep $insert_filter | sed 's/Awaiting Message/AwaitingMessage/; s/Awaiting Wakeup/AwaitingWakeup/; s/\(\.[0-9][0-&lt;br /&gt;
&lt;br /&gt;
9]*\)\.[0-9]/\1/' | grep -v &amp;quot;:0 ${primary_ds}&amp;quot; | awk '{print $4,$14,$15,$16}' | while read q_name first_seg last_seg next_seg&lt;br /&gt;
do&lt;br /&gt;
  q_size=$(bcalc &amp;quot;$last_seg - $first_seg&amp;quot;)&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
go&lt;br /&gt;
declare @mb_processed numeric(8,2)&lt;br /&gt;
declare @prev_sample datetime&lt;br /&gt;
declare @mins numeric(8,2)&lt;br /&gt;
declare @tput numeric(8,2)&lt;br /&gt;
if not exists (select 1 from rs_throughput where q_name = &amp;quot;${q_name}&amp;quot;)&lt;br /&gt;
insert rs_throughput values (&amp;quot;${q_name}&amp;quot;, getdate(), ${first_seg}, ${last_seg}, ${next_seg}, ${q_size}, 0, 0)&lt;br /&gt;
else&lt;br /&gt;
begin&lt;br /&gt;
-- get previous sample_time as key&lt;br /&gt;
select @prev_sample = max(sample_time) from rs_throughput where q_name = &amp;quot;${q_name}&amp;quot;&lt;br /&gt;
-- get difference in mb between current next segment and previous next segment&lt;br /&gt;
select @mb_processed = (select ${next_seg} - next from rs_throughput where sample_time = @prev_sample and q_name = &amp;quot;${q_name}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
select @prev_sample=dateadd(ss,-10,@prev_sample) -- # must substract 10 seconds to ensure the next datediff doesn't reflect 2m 58s &lt;br /&gt;
&lt;br /&gt;
as only 2mins!&lt;br /&gt;
select @mins = datediff(mi,@prev_sample,getdate())&lt;br /&gt;
if @mins &amp;gt; 0&lt;br /&gt;
begin&lt;br /&gt;
  select @tput = round((@mb_processed / @mins),2)&lt;br /&gt;
  insert rs_throughput values (&amp;quot;${q_name}&amp;quot;, getdate(), ${first_seg}, ${last_seg}, ${next_seg}, ${q_size}, @mb_processed, @tput)&lt;br /&gt;
end&lt;br /&gt;
end&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_report_thruput()&lt;br /&gt;
{&lt;br /&gt;
if [[ $option1 = [0-9]* ]]&lt;br /&gt;
then&lt;br /&gt;
  option2=$option1&lt;br /&gt;
  option1=&amp;quot;all&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if ! [[ &amp;quot;$option1&amp;quot; = &amp;quot;all&amp;quot; ]]&lt;br /&gt;
then&lt;br /&gt;
  q_list=$option1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
printf &amp;quot; -------------------------------------\n&amp;quot;&lt;br /&gt;
printf &amp;quot; Run date $DATE\n&amp;quot;&lt;br /&gt;
printf &amp;quot; -------------------------------------\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
for q_name in $q_list&lt;br /&gt;
do&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @mb_avg numeric(8,2)&lt;br /&gt;
declare @size numeric(8,2)&lt;br /&gt;
declare @eta datetime&lt;br /&gt;
select convert(char(19),sample_time) sample_time, q_name, size q_size, mb_processed, thruput &amp;quot;thruput (mb/min)&amp;quot;  from rs_throughput&lt;br /&gt;
--select convert(char(19),sample_time) sample_time, q_name, size q_size, mb_processed, thruput &amp;quot;thruput (mb/min)&amp;quot;, dateadd(mi,&lt;br /&gt;
&lt;br /&gt;
(round((size/thruput),0)),getdate()) ETA from rs_throughput&lt;br /&gt;
where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name like &amp;quot;%${q_name}%&amp;quot;&lt;br /&gt;
&lt;br /&gt;
--get mb average&lt;br /&gt;
select @mb_avg = convert(numeric(8,2),avg(thruput)) from rs_throughput&lt;br /&gt;
where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name like &amp;quot;%${q_name}%&amp;quot;&lt;br /&gt;
--get current queue size&lt;br /&gt;
select @size = size from rs_throughput where q_name like &amp;quot;%${q_name}%&amp;quot; having sample_time=max(sample_time)&lt;br /&gt;
select @eta = dateadd(mi,round((@size/@mb_avg),0),getdate())&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
print &amp;quot; Average for ${q_name}: %1! mb/min,  Re-sync ETA: %2!&amp;quot;, @mb_avg, @eta&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_help_text()&lt;br /&gt;
{&lt;br /&gt;
printf &amp;quot;Usage examples:\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh (runs with default values showing all queues over 15 minutes)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh &amp;lt;q_name&amp;gt;|&amp;lt;minutes&amp;gt;\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh &amp;lt;q_name&amp;gt; &amp;lt;minutes&amp;gt;\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh size|queue (shows current queue sizes)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh max (shows highest ever throughput for queue history)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh help (shows this helptext)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh insert # this is for cron only (inserts data to $RPT_DB..rs_throughput table)\n&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_max_thruput()&lt;br /&gt;
{&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
set rowcount 0&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @q_name char(22)&lt;br /&gt;
declare @sample_time datetime&lt;br /&gt;
declare @max_thruput numeric(8,2)&lt;br /&gt;
select q_name, sample_time, thruput into #throughput from rs_throughput where 1=0&lt;br /&gt;
print &amp;quot;Maximum throughput per queue:&amp;quot;&lt;br /&gt;
-- get list of queues&lt;br /&gt;
select distinct q_name, 0 as processed into #queues from rs_throughput&lt;br /&gt;
set rowcount 1&lt;br /&gt;
select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
while @@rowcount != 0&lt;br /&gt;
begin&lt;br /&gt;
  insert #throughput select q_name, sample_time, thruput from rs_throughput&lt;br /&gt;
  where sample_time in&lt;br /&gt;
    (select sample_time from rs_throughput where q_name = @q_name having thruput = max(thruput))&lt;br /&gt;
  and q_name = @q_name&lt;br /&gt;
  update #queues set processed = 1 where q_name = @q_name&lt;br /&gt;
  select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
end&lt;br /&gt;
set rowcount 0&lt;br /&gt;
select * from #throughput order by thruput desc&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
echo&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_current_q_size()&lt;br /&gt;
{&lt;br /&gt;
$RISQLCMD &amp;lt;&amp;lt; eof &amp;gt; $SQMFILE&lt;br /&gt;
admin who,sqm&lt;br /&gt;
go&lt;br /&gt;
quit&lt;br /&gt;
eof&lt;br /&gt;
printf &amp;quot;Current Stable Queue usage:\n&amp;quot;&lt;br /&gt;
cat $SQMFILE | egrep $insert_filter | sed 's/Awaiting Message/AwaitingMessage/; s/Awaiting Wakeup/AwaitingWakeup/; s/\(\.[0-9][0-&lt;br /&gt;
&lt;br /&gt;
9]*\)\.[0-9]/\1/' | grep -v &amp;quot;:0 ${primary_ds}&amp;quot; | awk '{print $4,$14,$15,$16}' | while read q_name first_seg last_seg next_seg&lt;br /&gt;
do&lt;br /&gt;
  q_size=$(bcalc &amp;quot;$last_seg - $first_seg&amp;quot;)&lt;br /&gt;
  printf &amp;quot;$q_name: $q_size\n&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_combined_avg_thruput()&lt;br /&gt;
{&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set rowcount 0&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @q_name varchar(25)&lt;br /&gt;
declare @mb_avg numeric(8,2)&lt;br /&gt;
declare @mb_combined_avg numeric(8,2)&lt;br /&gt;
select @mb_combined_avg=0&lt;br /&gt;
-- get list of queues&lt;br /&gt;
&lt;br /&gt;
select distinct q_name, 0 as processed into #queues from rs_throughput&lt;br /&gt;
set rowcount 1&lt;br /&gt;
select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
while @@rowcount != 0&lt;br /&gt;
begin&lt;br /&gt;
  select @mb_avg = convert(numeric(8,2),avg(thruput)) from rs_throughput&lt;br /&gt;
  where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name = @q_name&lt;br /&gt;
  select @mb_combined_avg = @mb_combined_avg + @mb_avg&lt;br /&gt;
  update #queues set processed=1 where q_name = @q_name&lt;br /&gt;
  select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
end&lt;br /&gt;
print &amp;quot; Combined thruput average: %1! mb/min&amp;quot;, @mb_combined_avg&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                             main program                                   #&lt;br /&gt;
##############################################################################&lt;br /&gt;
&lt;br /&gt;
check_previous_instance&lt;br /&gt;
fn_checkusage&lt;br /&gt;
&lt;br /&gt;
case &amp;quot;$option1&amp;quot; in&lt;br /&gt;
        help) fn_show_help_text;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
      insert) fn_insert_thruput_data;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
         max) fn_show_max_thruput;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
       queue|size) fn_show_current_q_size;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
           *) fn_report_thruput;&lt;br /&gt;
              fn_show_combined_avg_thruput;;&lt;br /&gt;
esac&lt;br /&gt;
&lt;br /&gt;
fn_housekeeping&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
### TABLE DEFINTION FOR RAW DATA COLLECTION&lt;br /&gt;
### Use the table definition below to create the table which this script &lt;br /&gt;
### requires in order to insert queue data and furthermore query this&lt;br /&gt;
### data in order to provide throughput information.&lt;br /&gt;
#create table rs_throughput (&lt;br /&gt;
#q_name varchar(25), &lt;br /&gt;
#sample_time datetime, &lt;br /&gt;
#first numeric(8,2), &lt;br /&gt;
#last numeric(8,2), &lt;br /&gt;
#next numeric(8,2), &lt;br /&gt;
#size numeric(8,2), &lt;br /&gt;
#mb_processed numeric(8,2),&lt;br /&gt;
#thruput numeric(8,2)&lt;br /&gt;
#)&lt;br /&gt;
&lt;br /&gt;
# end program&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:RepServer]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=RepServer_Throughput_Script&amp;diff=1858</id>
		<title>RepServer Throughput Script</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=RepServer_Throughput_Script&amp;diff=1858"/>
				<updated>2009-02-20T11:14:46Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to know just how much data repserver is processing, then this is the tool.&amp;lt;br&amp;gt;&lt;br /&gt;
This script will tell you:&amp;lt;br&amp;gt;&lt;br /&gt;
o average throughput per queue (mb per minute)&amp;lt;br&amp;gt;&lt;br /&gt;
o average throughput combined (all queues)&amp;lt;br&amp;gt;&lt;br /&gt;
o estimated time for a replicate to catch up (Re-sync ETA)&amp;lt;br&amp;gt;&lt;br /&gt;
o current queue sizes&amp;lt;br&amp;gt;&lt;br /&gt;
There is also a maximum recorded throughput option but this appears not to work well as some of the figures have been suspicious.&amp;lt;br&amp;gt;&lt;br /&gt;
The real maximum throughput can be established by noting when the replicates start to fall behind in conjunction with the current throughput figures.&amp;lt;br&amp;gt;&lt;br /&gt;
This script can be particularly useful in helping to ascertain if you need to throw more CPU at your repserver box.&lt;br /&gt;
&lt;br /&gt;
Notes:&amp;lt;br&amp;gt;&lt;br /&gt;
1) You will need to cron this script with the insert option (rs_throughput.sh insert) and allow it to collect at least 2 samples before being able to run it interactively to obtain throughput information.  The script runs silently when run with the insert option.&amp;lt;br&amp;gt;&lt;br /&gt;
2) The script automatically determines the elapsed interval in minutes between samples so you can cron the script to your preferred interval, be it 3 minutes or 10 minutes, the mb/min figure will be calculated correctly.&amp;lt;br&amp;gt;&lt;br /&gt;
3) In addition to configuring the script to your environment, you will also need to create the rs_throughput table prior to first run.&lt;br /&gt;
4) Re-sync ETA: this value is provided based on the current throughput average for the period specified.  For example, this means that running rs_throughput.sh 15 may give a different Re-Sync ETA compared to running rs_throughput.sh 20&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/ksh&lt;br /&gt;
#&lt;br /&gt;
# Script: rs_throughput.sh&lt;br /&gt;
# Author: Bob Holmes - email: cambob@gmail.com&lt;br /&gt;
# Date  : 19/09/08&lt;br /&gt;
# Version : 1.0&lt;br /&gt;
# Usage : Run &amp;quot;rs_throughput.sh help&amp;quot; for full usage information.&lt;br /&gt;
# Description : This script enables monitoring and reporting&lt;br /&gt;
#               of repserver throughput.&lt;br /&gt;
# --------------------------&lt;br /&gt;
#    ***    Variables for customisation can be found by searching for &amp;quot;!!&amp;quot; ***&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Modification history:&lt;br /&gt;
# 19/02/09 : Bob Holmes : Script modified to enable easier customisation prior&lt;br /&gt;
#                         to release on Sybase wiki. (modifications not tested)&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Comments: This script relies on the reporting..rs_throughput table for data&lt;br /&gt;
#           collection and reporting.  The definition for this table can be&lt;br /&gt;
#           found at the end of this script. &lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           setup environment                                #&lt;br /&gt;
##############################################################################&lt;br /&gt;
#&lt;br /&gt;
# save input variables&lt;br /&gt;
if ! [[ -z $1 ]]&lt;br /&gt;
then&lt;br /&gt;
  export option1=$1&lt;br /&gt;
else&lt;br /&gt;
  export option1=&amp;quot;all&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if ! [[ -z $2 ]]&lt;br /&gt;
then&lt;br /&gt;
  export option2=$2&lt;br /&gt;
else&lt;br /&gt;
  export option2=&amp;quot;15&amp;quot; # default number of minutes on which to report throughput&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# configure environment&lt;br /&gt;
HOSTNAME=`hostname`&lt;br /&gt;
. $HOME/admin/.syb_cfg.sh $HOSTNAME  # !! This line sets up the environment from&lt;br /&gt;
                                     # !! from an external shell script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           config variables                                 #&lt;br /&gt;
##############################################################################&lt;br /&gt;
# config:&lt;br /&gt;
primary_ds=&amp;quot;prim_ds&amp;quot;                   # !! string used to identify the inbound queue&lt;br /&gt;
# queues to query on:-&lt;br /&gt;
q_list=&amp;quot;prim_ds.db1 prim_ds.db2 replicate_ds.db1 replicate_ds.db2&amp;quot; # !!&lt;br /&gt;
insert_filter=&amp;quot;db1 db2&amp;quot;                # !! data will only be collected for queue names which have this keyword in&lt;br /&gt;
REP_SRV=&amp;quot;repsrv_rs&amp;quot;                    # !! the actual repserver from which to get sqm info&lt;br /&gt;
RPT_SRV=&amp;quot;reporting_ds&amp;quot;                 # !! dataserver which manages the reporting database&lt;br /&gt;
RPT_DB=&amp;quot;reporting&amp;quot;                     # !! reporting database name&lt;br /&gt;
RECIPIENTS=&amp;quot;user@domain&amp;quot;               # !! email config (separate addresses with commas)&lt;br /&gt;
ADMINDIR=&amp;quot;/opt/home/sybase/admin&amp;quot;      # !! sybase admin directory&lt;br /&gt;
&lt;br /&gt;
# static:&lt;br /&gt;
SQMFILE=&amp;quot;$ADMINDIR/rs_sqm_tmp1.tmp&amp;quot;&lt;br /&gt;
DATE=$(date &amp;quot;+%d/%m/%y %H:%M:%S&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# config aware environment variables: # !! You may need to replace the line below with the equivalent&lt;br /&gt;
                                      # !! for your own environment. &lt;br /&gt;
RISQLCMD=&amp;quot;isql -Usa -P`grep &amp;quot;$REP_SRV,&amp;quot; $HOME/admin/.servers | cut  -d , -f 4` -S$REP_SRV -w1000&amp;quot;&lt;br /&gt;
ISQLCMD=&amp;quot;isql -Usa -P${SYBPASS} -S${RPT_SRV} -w200 -D${RPT_DB}&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                             functions                                      #&lt;br /&gt;
##############################################################################&lt;br /&gt;
&lt;br /&gt;
check_previous_instance()&lt;br /&gt;
{&lt;br /&gt;
# Note: next line greps for 8 instances as tests proved that less could cause the script to exit incorrectly&lt;br /&gt;
if [ $(ps -ef | grep rs_throughput | egrep -v &amp;quot;vi|grep&amp;quot; | grep -v &amp;quot;sh -c&amp;quot; | wc -l | awk '{print $1}') -gt 8 ]&lt;br /&gt;
then&lt;br /&gt;
  # previous instance still running - probably hanging&lt;br /&gt;
  echo Previous instance still running.&lt;br /&gt;
  exit&lt;br /&gt;
fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_checkusage()&lt;br /&gt;
{&lt;br /&gt;
if [[ -z $option1 ]]&lt;br /&gt;
then&lt;br /&gt;
  printf &amp;quot; Usage: ./rs_throughput.sh &amp;lt;all&amp;gt;|&amp;lt;q_name&amp;gt;|&amp;lt;help&amp;gt; [&amp;lt;minutes to display&amp;gt;]\n&amp;quot;&lt;br /&gt;
  exit&lt;br /&gt;
fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bcalc()&lt;br /&gt;
{&lt;br /&gt;
awk 'BEGIN{EQUATION='&amp;quot;$*&amp;quot;';printf(&amp;quot;%0.1f\n&amp;quot;,EQUATION); exit}'&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_housekeeping()&lt;br /&gt;
{&lt;br /&gt;
if [ -e $SQMFILE ]&lt;br /&gt;
then&lt;br /&gt;
  rm $SQMFILE&lt;br /&gt;
fi&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
go&lt;br /&gt;
delete from rs_throughput where sample_time &amp;lt;= dateadd(dd,-28,getdate())&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_insert_thruput_data()&lt;br /&gt;
{&lt;br /&gt;
# 1) get current segment usage/progress info&lt;br /&gt;
#connect to repserver, get sqm info - put into file&lt;br /&gt;
$RISQLCMD &amp;lt;&amp;lt; eof &amp;gt; $SQMFILE&lt;br /&gt;
admin who,sqm&lt;br /&gt;
go&lt;br /&gt;
quit&lt;br /&gt;
eof&lt;br /&gt;
&lt;br /&gt;
# 2) insert new segment data into rs_throughput table&lt;br /&gt;
#date&lt;br /&gt;
#echo &amp;quot;Queue Name, First segment, Last segment, Next segment&amp;quot;&lt;br /&gt;
cat $SQMFILE | egrep $insert_filter | sed 's/Awaiting Message/AwaitingMessage/; s/Awaiting Wakeup/AwaitingWakeup/; s/\(\.[0-9][0-&lt;br /&gt;
&lt;br /&gt;
9]*\)\.[0-9]/\1/' | grep -v &amp;quot;:0 ${primary_ds}&amp;quot; | awk '{print $4,$14,$15,$16}' | while read q_name first_seg last_seg next_seg&lt;br /&gt;
do&lt;br /&gt;
  q_size=$(bcalc &amp;quot;$last_seg - $first_seg&amp;quot;)&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
go&lt;br /&gt;
declare @mb_processed numeric(8,2)&lt;br /&gt;
declare @prev_sample datetime&lt;br /&gt;
declare @mins numeric(8,2)&lt;br /&gt;
declare @tput numeric(8,2)&lt;br /&gt;
if not exists (select 1 from rs_throughput where q_name = &amp;quot;${q_name}&amp;quot;)&lt;br /&gt;
insert rs_throughput values (&amp;quot;${q_name}&amp;quot;, getdate(), ${first_seg}, ${last_seg}, ${next_seg}, ${q_size}, 0, 0)&lt;br /&gt;
else&lt;br /&gt;
begin&lt;br /&gt;
-- get previous sample_time as key&lt;br /&gt;
select @prev_sample = max(sample_time) from rs_throughput where q_name = &amp;quot;${q_name}&amp;quot;&lt;br /&gt;
-- get difference in mb between current next segment and previous next segment&lt;br /&gt;
select @mb_processed = (select ${next_seg} - next from rs_throughput where sample_time = @prev_sample and q_name = &amp;quot;${q_name}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
select @prev_sample=dateadd(ss,-10,@prev_sample) -- # must substract 10 seconds to ensure the next datediff doesn't reflect 2m 58s &lt;br /&gt;
&lt;br /&gt;
as only 2mins!&lt;br /&gt;
select @mins = datediff(mi,@prev_sample,getdate())&lt;br /&gt;
if @mins &amp;gt; 0&lt;br /&gt;
begin&lt;br /&gt;
  select @tput = round((@mb_processed / @mins),2)&lt;br /&gt;
  insert rs_throughput values (&amp;quot;${q_name}&amp;quot;, getdate(), ${first_seg}, ${last_seg}, ${next_seg}, ${q_size}, @mb_processed, @tput)&lt;br /&gt;
end&lt;br /&gt;
end&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_report_thruput()&lt;br /&gt;
{&lt;br /&gt;
if [[ $option1 = [0-9]* ]]&lt;br /&gt;
then&lt;br /&gt;
  option2=$option1&lt;br /&gt;
  option1=&amp;quot;all&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if ! [[ &amp;quot;$option1&amp;quot; = &amp;quot;all&amp;quot; ]]&lt;br /&gt;
then&lt;br /&gt;
  q_list=$option1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
printf &amp;quot; -------------------------------------\n&amp;quot;&lt;br /&gt;
printf &amp;quot; Run date $DATE\n&amp;quot;&lt;br /&gt;
printf &amp;quot; -------------------------------------\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
for q_name in $q_list&lt;br /&gt;
do&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @mb_avg numeric(8,2)&lt;br /&gt;
declare @size numeric(8,2)&lt;br /&gt;
declare @eta datetime&lt;br /&gt;
select convert(char(19),sample_time) sample_time, q_name, size q_size, mb_processed, thruput &amp;quot;thruput (mb/min)&amp;quot;  from rs_throughput&lt;br /&gt;
--select convert(char(19),sample_time) sample_time, q_name, size q_size, mb_processed, thruput &amp;quot;thruput (mb/min)&amp;quot;, dateadd(mi,&lt;br /&gt;
&lt;br /&gt;
(round((size/thruput),0)),getdate()) ETA from rs_throughput&lt;br /&gt;
where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name like &amp;quot;%${q_name}%&amp;quot;&lt;br /&gt;
&lt;br /&gt;
--get mb average&lt;br /&gt;
select @mb_avg = convert(numeric(8,2),avg(thruput)) from rs_throughput&lt;br /&gt;
where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name like &amp;quot;%${q_name}%&amp;quot;&lt;br /&gt;
--get current queue size&lt;br /&gt;
select @size = size from rs_throughput where q_name like &amp;quot;%${q_name}%&amp;quot; having sample_time=max(sample_time)&lt;br /&gt;
select @eta = dateadd(mi,round((@size/@mb_avg),0),getdate())&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
print &amp;quot; Average for ${q_name}: %1! mb/min,  Re-sync ETA: %2!&amp;quot;, @mb_avg, @eta&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_help_text()&lt;br /&gt;
{&lt;br /&gt;
printf &amp;quot;Usage examples:\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh (runs with default values showing all queues over 15 minutes)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh &amp;lt;q_name&amp;gt;|&amp;lt;minutes&amp;gt;\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh &amp;lt;q_name&amp;gt; &amp;lt;minutes&amp;gt;\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh size|queue (shows current queue sizes)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh max (shows highest ever throughput for queue history)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh help (shows this helptext)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh insert # this is for cron only (inserts data to $RPT_DB..rs_throughput table)\n&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_max_thruput()&lt;br /&gt;
{&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
set rowcount 0&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @q_name char(22)&lt;br /&gt;
declare @sample_time datetime&lt;br /&gt;
declare @max_thruput numeric(8,2)&lt;br /&gt;
select q_name, sample_time, thruput into #throughput from rs_throughput where 1=0&lt;br /&gt;
print &amp;quot;Maximum throughput per queue:&amp;quot;&lt;br /&gt;
-- get list of queues&lt;br /&gt;
select distinct q_name, 0 as processed into #queues from rs_throughput&lt;br /&gt;
set rowcount 1&lt;br /&gt;
select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
while @@rowcount != 0&lt;br /&gt;
begin&lt;br /&gt;
  insert #throughput select q_name, sample_time, thruput from rs_throughput&lt;br /&gt;
  where sample_time in&lt;br /&gt;
    (select sample_time from rs_throughput where q_name = @q_name having thruput = max(thruput))&lt;br /&gt;
  and q_name = @q_name&lt;br /&gt;
  update #queues set processed = 1 where q_name = @q_name&lt;br /&gt;
  select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
end&lt;br /&gt;
set rowcount 0&lt;br /&gt;
select * from #throughput order by thruput desc&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
echo&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_current_q_size()&lt;br /&gt;
{&lt;br /&gt;
$RISQLCMD &amp;lt;&amp;lt; eof &amp;gt; $SQMFILE&lt;br /&gt;
admin who,sqm&lt;br /&gt;
go&lt;br /&gt;
quit&lt;br /&gt;
eof&lt;br /&gt;
printf &amp;quot;Current Stable Queue usage:\n&amp;quot;&lt;br /&gt;
cat $SQMFILE | egrep $insert_filter | sed 's/Awaiting Message/AwaitingMessage/; s/Awaiting Wakeup/AwaitingWakeup/; s/\(\.[0-9][0-&lt;br /&gt;
&lt;br /&gt;
9]*\)\.[0-9]/\1/' | grep -v &amp;quot;:0 ${primary_ds}&amp;quot; | awk '{print $4,$14,$15,$16}' | while read q_name first_seg last_seg next_seg&lt;br /&gt;
do&lt;br /&gt;
  q_size=$(bcalc &amp;quot;$last_seg - $first_seg&amp;quot;)&lt;br /&gt;
  printf &amp;quot;$q_name: $q_size\n&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_combined_avg_thruput()&lt;br /&gt;
{&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set rowcount 0&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @q_name varchar(25)&lt;br /&gt;
declare @mb_avg numeric(8,2)&lt;br /&gt;
declare @mb_combined_avg numeric(8,2)&lt;br /&gt;
select @mb_combined_avg=0&lt;br /&gt;
-- get list of queues&lt;br /&gt;
&lt;br /&gt;
select distinct q_name, 0 as processed into #queues from rs_throughput&lt;br /&gt;
set rowcount 1&lt;br /&gt;
select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
while @@rowcount != 0&lt;br /&gt;
begin&lt;br /&gt;
  select @mb_avg = convert(numeric(8,2),avg(thruput)) from rs_throughput&lt;br /&gt;
  where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name = @q_name&lt;br /&gt;
  select @mb_combined_avg = @mb_combined_avg + @mb_avg&lt;br /&gt;
  update #queues set processed=1 where q_name = @q_name&lt;br /&gt;
  select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
end&lt;br /&gt;
print &amp;quot; Combined thruput average: %1! mb/min&amp;quot;, @mb_combined_avg&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                             main program                                   #&lt;br /&gt;
##############################################################################&lt;br /&gt;
&lt;br /&gt;
check_previous_instance&lt;br /&gt;
fn_checkusage&lt;br /&gt;
&lt;br /&gt;
case &amp;quot;$option1&amp;quot; in&lt;br /&gt;
        help) fn_show_help_text;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
      insert) fn_insert_thruput_data;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
         max) fn_show_max_thruput;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
       queue|size) fn_show_current_q_size;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
           *) fn_report_thruput;&lt;br /&gt;
              fn_show_combined_avg_thruput;;&lt;br /&gt;
esac&lt;br /&gt;
&lt;br /&gt;
fn_housekeeping&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
### TABLE DEFINTION FOR RAW DATA COLLECTION&lt;br /&gt;
### Use the table definition below to create the table which this script &lt;br /&gt;
### requires in order to insert queue data and furthermore query this&lt;br /&gt;
### data in order to provide throughput information.&lt;br /&gt;
#create table rs_throughput (&lt;br /&gt;
#q_name varchar(25), &lt;br /&gt;
#sample_time datetime, &lt;br /&gt;
#first numeric(8,2), &lt;br /&gt;
#last numeric(8,2), &lt;br /&gt;
#next numeric(8,2), &lt;br /&gt;
#size numeric(8,2), &lt;br /&gt;
#mb_processed numeric(8,2),&lt;br /&gt;
#thruput numeric(8,2)&lt;br /&gt;
#)&lt;br /&gt;
&lt;br /&gt;
# end program&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:RepServer]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=RepServer_Throughput_Script&amp;diff=1857</id>
		<title>RepServer Throughput Script</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=RepServer_Throughput_Script&amp;diff=1857"/>
				<updated>2009-02-20T09:44:48Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to know just how much data repserver is processing, then this is the tool.&amp;lt;br&amp;gt;&lt;br /&gt;
This script will tell you:&amp;lt;br&amp;gt;&lt;br /&gt;
o average throughput per queue (mb per minute)&amp;lt;br&amp;gt;&lt;br /&gt;
o average throughput combined (all queues)&amp;lt;br&amp;gt;&lt;br /&gt;
o estimated time for a replicate to catch up&amp;lt;br&amp;gt;&lt;br /&gt;
o current queue sizes&amp;lt;br&amp;gt;&lt;br /&gt;
There is also a maximum recorded throughput option but this appears not to work well as some of the figures have been suspicious.&amp;lt;br&amp;gt;&lt;br /&gt;
The real maximum throughput can be established by noting when the replicates start to fall behind in conjunction with the current throughput figures.&amp;lt;br&amp;gt;&lt;br /&gt;
This script can be particularly useful in helping to ascertain if you need to throw more CPU at your repserver box.&lt;br /&gt;
&lt;br /&gt;
Notes:&amp;lt;br&amp;gt;&lt;br /&gt;
1) You will need to cron this script with the insert option (rs_throughput.sh insert) and allow it to collect at least 2 samples before being able to run it interactively to obtain throughput information.  The script runs silently when run with the insert option.&amp;lt;br&amp;gt;&lt;br /&gt;
2) The script automatically determines the elapsed interval in minutes between samples so you can cron the script to your preferred interval, be it 3 minutes or 10 minutes, the mb/min figure will be calculated correctly.&amp;lt;br&amp;gt;&lt;br /&gt;
3) In addition to configuring the script to your environment, you will also need to create the rs_throughput table prior to first run.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/ksh&lt;br /&gt;
#&lt;br /&gt;
# Script: rs_throughput.sh&lt;br /&gt;
# Author: Bob Holmes - email: cambob@gmail.com&lt;br /&gt;
# Date  : 19/09/08&lt;br /&gt;
# Version : 1.0&lt;br /&gt;
# Usage : Run &amp;quot;rs_throughput.sh help&amp;quot; for full usage information.&lt;br /&gt;
# Description : This script enables monitoring and reporting&lt;br /&gt;
#               of repserver throughput.&lt;br /&gt;
# --------------------------&lt;br /&gt;
#    ***    Variables for customisation can be found by searching for &amp;quot;!!&amp;quot; ***&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Modification history:&lt;br /&gt;
# 19/02/09 : Bob Holmes : Script modified to enable easier customisation prior&lt;br /&gt;
#                         to release on Sybase wiki. (modifications not tested)&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Comments: This script relies on the reporting..rs_throughput table for data&lt;br /&gt;
#           collection and reporting.  The definition for this table can be&lt;br /&gt;
#           found at the end of this script. &lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           setup environment                                #&lt;br /&gt;
##############################################################################&lt;br /&gt;
#&lt;br /&gt;
# save input variables&lt;br /&gt;
if ! [[ -z $1 ]]&lt;br /&gt;
then&lt;br /&gt;
  export option1=$1&lt;br /&gt;
else&lt;br /&gt;
  export option1=&amp;quot;all&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if ! [[ -z $2 ]]&lt;br /&gt;
then&lt;br /&gt;
  export option2=$2&lt;br /&gt;
else&lt;br /&gt;
  export option2=&amp;quot;15&amp;quot; # default number of minutes on which to report throughput&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# configure environment&lt;br /&gt;
HOSTNAME=`hostname`&lt;br /&gt;
. $HOME/admin/.syb_cfg.sh $HOSTNAME  # !! This line sets up the environment from&lt;br /&gt;
                                     # !! from an external shell script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           config variables                                 #&lt;br /&gt;
##############################################################################&lt;br /&gt;
# config:&lt;br /&gt;
primary_ds=&amp;quot;prim_ds&amp;quot;                   # !! string used to identify the inbound queue&lt;br /&gt;
# queues to query on:-&lt;br /&gt;
q_list=&amp;quot;prim_ds.db1 prim_ds.db2 replicate_ds.db1 replicate_ds.db2&amp;quot; # !!&lt;br /&gt;
insert_filter=&amp;quot;db1 db2&amp;quot;                # !! data will only be collected for queue names which have this keyword in&lt;br /&gt;
REP_SRV=&amp;quot;repsrv_rs&amp;quot;                    # !! the actual repserver from which to get sqm info&lt;br /&gt;
RPT_SRV=&amp;quot;reporting_ds&amp;quot;                 # !! dataserver which manages the reporting database&lt;br /&gt;
RPT_DB=&amp;quot;reporting&amp;quot;                     # !! reporting database name&lt;br /&gt;
RECIPIENTS=&amp;quot;user@domain&amp;quot;               # !! email config (separate addresses with commas)&lt;br /&gt;
ADMINDIR=&amp;quot;/opt/home/sybase/admin&amp;quot;      # !! sybase admin directory&lt;br /&gt;
&lt;br /&gt;
# static:&lt;br /&gt;
SQMFILE=&amp;quot;$ADMINDIR/rs_sqm_tmp1.tmp&amp;quot;&lt;br /&gt;
DATE=$(date &amp;quot;+%d/%m/%y %H:%M:%S&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# config aware environment variables: # !! You may need to replace the line below with the equivalent&lt;br /&gt;
                                      # !! for your own environment. &lt;br /&gt;
RISQLCMD=&amp;quot;isql -Usa -P`grep &amp;quot;$REP_SRV,&amp;quot; $HOME/admin/.servers | cut  -d , -f 4` -S$REP_SRV -w1000&amp;quot;&lt;br /&gt;
ISQLCMD=&amp;quot;isql -Usa -P${SYBPASS} -S${RPT_SRV} -w200 -D${RPT_DB}&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                             functions                                      #&lt;br /&gt;
##############################################################################&lt;br /&gt;
&lt;br /&gt;
check_previous_instance()&lt;br /&gt;
{&lt;br /&gt;
# Note: next line greps for 8 instances as tests proved that less could cause the script to exit incorrectly&lt;br /&gt;
if [ $(ps -ef | grep rs_throughput | egrep -v &amp;quot;vi|grep&amp;quot; | grep -v &amp;quot;sh -c&amp;quot; | wc -l | awk '{print $1}') -gt 8 ]&lt;br /&gt;
then&lt;br /&gt;
  # previous instance still running - probably hanging&lt;br /&gt;
  echo Previous instance still running.&lt;br /&gt;
  exit&lt;br /&gt;
fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_checkusage()&lt;br /&gt;
{&lt;br /&gt;
if [[ -z $option1 ]]&lt;br /&gt;
then&lt;br /&gt;
  printf &amp;quot; Usage: ./rs_throughput.sh &amp;lt;all&amp;gt;|&amp;lt;q_name&amp;gt;|&amp;lt;help&amp;gt; [&amp;lt;minutes to display&amp;gt;]\n&amp;quot;&lt;br /&gt;
  exit&lt;br /&gt;
fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bcalc()&lt;br /&gt;
{&lt;br /&gt;
awk 'BEGIN{EQUATION='&amp;quot;$*&amp;quot;';printf(&amp;quot;%0.1f\n&amp;quot;,EQUATION); exit}'&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_housekeeping()&lt;br /&gt;
{&lt;br /&gt;
if [ -e $SQMFILE ]&lt;br /&gt;
then&lt;br /&gt;
  rm $SQMFILE&lt;br /&gt;
fi&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
go&lt;br /&gt;
delete from rs_throughput where sample_time &amp;lt;= dateadd(dd,-28,getdate())&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_insert_thruput_data()&lt;br /&gt;
{&lt;br /&gt;
# 1) get current segment usage/progress info&lt;br /&gt;
#connect to repserver, get sqm info - put into file&lt;br /&gt;
$RISQLCMD &amp;lt;&amp;lt; eof &amp;gt; $SQMFILE&lt;br /&gt;
admin who,sqm&lt;br /&gt;
go&lt;br /&gt;
quit&lt;br /&gt;
eof&lt;br /&gt;
&lt;br /&gt;
# 2) insert new segment data into rs_throughput table&lt;br /&gt;
#date&lt;br /&gt;
#echo &amp;quot;Queue Name, First segment, Last segment, Next segment&amp;quot;&lt;br /&gt;
cat $SQMFILE | egrep $insert_filter | sed 's/Awaiting Message/AwaitingMessage/; s/Awaiting Wakeup/AwaitingWakeup/; s/\(\.[0-9][0-&lt;br /&gt;
&lt;br /&gt;
9]*\)\.[0-9]/\1/' | grep -v &amp;quot;:0 ${primary_ds}&amp;quot; | awk '{print $4,$14,$15,$16}' | while read q_name first_seg last_seg next_seg&lt;br /&gt;
do&lt;br /&gt;
  q_size=$(bcalc &amp;quot;$last_seg - $first_seg&amp;quot;)&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
go&lt;br /&gt;
declare @mb_processed numeric(8,2)&lt;br /&gt;
declare @prev_sample datetime&lt;br /&gt;
declare @mins numeric(8,2)&lt;br /&gt;
declare @tput numeric(8,2)&lt;br /&gt;
if not exists (select 1 from rs_throughput where q_name = &amp;quot;${q_name}&amp;quot;)&lt;br /&gt;
insert rs_throughput values (&amp;quot;${q_name}&amp;quot;, getdate(), ${first_seg}, ${last_seg}, ${next_seg}, ${q_size}, 0, 0)&lt;br /&gt;
else&lt;br /&gt;
begin&lt;br /&gt;
-- get previous sample_time as key&lt;br /&gt;
select @prev_sample = max(sample_time) from rs_throughput where q_name = &amp;quot;${q_name}&amp;quot;&lt;br /&gt;
-- get difference in mb between current next segment and previous next segment&lt;br /&gt;
select @mb_processed = (select ${next_seg} - next from rs_throughput where sample_time = @prev_sample and q_name = &amp;quot;${q_name}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
select @prev_sample=dateadd(ss,-10,@prev_sample) -- # must substract 10 seconds to ensure the next datediff doesn't reflect 2m 58s &lt;br /&gt;
&lt;br /&gt;
as only 2mins!&lt;br /&gt;
select @mins = datediff(mi,@prev_sample,getdate())&lt;br /&gt;
if @mins &amp;gt; 0&lt;br /&gt;
begin&lt;br /&gt;
  select @tput = round((@mb_processed / @mins),2)&lt;br /&gt;
  insert rs_throughput values (&amp;quot;${q_name}&amp;quot;, getdate(), ${first_seg}, ${last_seg}, ${next_seg}, ${q_size}, @mb_processed, @tput)&lt;br /&gt;
end&lt;br /&gt;
end&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_report_thruput()&lt;br /&gt;
{&lt;br /&gt;
if [[ $option1 = [0-9]* ]]&lt;br /&gt;
then&lt;br /&gt;
  option2=$option1&lt;br /&gt;
  option1=&amp;quot;all&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if ! [[ &amp;quot;$option1&amp;quot; = &amp;quot;all&amp;quot; ]]&lt;br /&gt;
then&lt;br /&gt;
  q_list=$option1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
printf &amp;quot; -------------------------------------\n&amp;quot;&lt;br /&gt;
printf &amp;quot; Run date $DATE\n&amp;quot;&lt;br /&gt;
printf &amp;quot; -------------------------------------\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
for q_name in $q_list&lt;br /&gt;
do&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @mb_avg numeric(8,2)&lt;br /&gt;
declare @size numeric(8,2)&lt;br /&gt;
declare @eta datetime&lt;br /&gt;
select convert(char(19),sample_time) sample_time, q_name, size q_size, mb_processed, thruput &amp;quot;thruput (mb/min)&amp;quot;  from rs_throughput&lt;br /&gt;
--select convert(char(19),sample_time) sample_time, q_name, size q_size, mb_processed, thruput &amp;quot;thruput (mb/min)&amp;quot;, dateadd(mi,&lt;br /&gt;
&lt;br /&gt;
(round((size/thruput),0)),getdate()) ETA from rs_throughput&lt;br /&gt;
where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name like &amp;quot;%${q_name}%&amp;quot;&lt;br /&gt;
&lt;br /&gt;
--get mb average&lt;br /&gt;
select @mb_avg = convert(numeric(8,2),avg(thruput)) from rs_throughput&lt;br /&gt;
where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name like &amp;quot;%${q_name}%&amp;quot;&lt;br /&gt;
--get current queue size&lt;br /&gt;
select @size = size from rs_throughput where q_name like &amp;quot;%${q_name}%&amp;quot; having sample_time=max(sample_time)&lt;br /&gt;
select @eta = dateadd(mi,round((@size/@mb_avg),0),getdate())&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
print &amp;quot; Average for ${q_name}: %1! mb/min,  Re-sync ETA: %2!&amp;quot;, @mb_avg, @eta&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_help_text()&lt;br /&gt;
{&lt;br /&gt;
printf &amp;quot;Usage examples:\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh (runs with default values showing all queues over 15 minutes)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh &amp;lt;q_name&amp;gt;|&amp;lt;minutes&amp;gt;\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh &amp;lt;q_name&amp;gt; &amp;lt;minutes&amp;gt;\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh size|queue (shows current queue sizes)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh max (shows highest ever throughput for queue history)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh help (shows this helptext)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh insert # this is for cron only (inserts data to $RPT_DB..rs_throughput table)\n&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_max_thruput()&lt;br /&gt;
{&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
set rowcount 0&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @q_name char(22)&lt;br /&gt;
declare @sample_time datetime&lt;br /&gt;
declare @max_thruput numeric(8,2)&lt;br /&gt;
select q_name, sample_time, thruput into #throughput from rs_throughput where 1=0&lt;br /&gt;
print &amp;quot;Maximum throughput per queue:&amp;quot;&lt;br /&gt;
-- get list of queues&lt;br /&gt;
select distinct q_name, 0 as processed into #queues from rs_throughput&lt;br /&gt;
set rowcount 1&lt;br /&gt;
select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
while @@rowcount != 0&lt;br /&gt;
begin&lt;br /&gt;
  insert #throughput select q_name, sample_time, thruput from rs_throughput&lt;br /&gt;
  where sample_time in&lt;br /&gt;
    (select sample_time from rs_throughput where q_name = @q_name having thruput = max(thruput))&lt;br /&gt;
  and q_name = @q_name&lt;br /&gt;
  update #queues set processed = 1 where q_name = @q_name&lt;br /&gt;
  select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
end&lt;br /&gt;
set rowcount 0&lt;br /&gt;
select * from #throughput order by thruput desc&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
echo&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_current_q_size()&lt;br /&gt;
{&lt;br /&gt;
$RISQLCMD &amp;lt;&amp;lt; eof &amp;gt; $SQMFILE&lt;br /&gt;
admin who,sqm&lt;br /&gt;
go&lt;br /&gt;
quit&lt;br /&gt;
eof&lt;br /&gt;
printf &amp;quot;Current Stable Queue usage:\n&amp;quot;&lt;br /&gt;
cat $SQMFILE | egrep $insert_filter | sed 's/Awaiting Message/AwaitingMessage/; s/Awaiting Wakeup/AwaitingWakeup/; s/\(\.[0-9][0-&lt;br /&gt;
&lt;br /&gt;
9]*\)\.[0-9]/\1/' | grep -v &amp;quot;:0 ${primary_ds}&amp;quot; | awk '{print $4,$14,$15,$16}' | while read q_name first_seg last_seg next_seg&lt;br /&gt;
do&lt;br /&gt;
  q_size=$(bcalc &amp;quot;$last_seg - $first_seg&amp;quot;)&lt;br /&gt;
  printf &amp;quot;$q_name: $q_size\n&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_combined_avg_thruput()&lt;br /&gt;
{&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set rowcount 0&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @q_name varchar(25)&lt;br /&gt;
declare @mb_avg numeric(8,2)&lt;br /&gt;
declare @mb_combined_avg numeric(8,2)&lt;br /&gt;
select @mb_combined_avg=0&lt;br /&gt;
-- get list of queues&lt;br /&gt;
&lt;br /&gt;
select distinct q_name, 0 as processed into #queues from rs_throughput&lt;br /&gt;
set rowcount 1&lt;br /&gt;
select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
while @@rowcount != 0&lt;br /&gt;
begin&lt;br /&gt;
  select @mb_avg = convert(numeric(8,2),avg(thruput)) from rs_throughput&lt;br /&gt;
  where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name = @q_name&lt;br /&gt;
  select @mb_combined_avg = @mb_combined_avg + @mb_avg&lt;br /&gt;
  update #queues set processed=1 where q_name = @q_name&lt;br /&gt;
  select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
end&lt;br /&gt;
print &amp;quot; Combined thruput average: %1! mb/min&amp;quot;, @mb_combined_avg&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                             main program                                   #&lt;br /&gt;
##############################################################################&lt;br /&gt;
&lt;br /&gt;
check_previous_instance&lt;br /&gt;
fn_checkusage&lt;br /&gt;
&lt;br /&gt;
case &amp;quot;$option1&amp;quot; in&lt;br /&gt;
        help) fn_show_help_text;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
      insert) fn_insert_thruput_data;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
         max) fn_show_max_thruput;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
       queue|size) fn_show_current_q_size;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
           *) fn_report_thruput;&lt;br /&gt;
              fn_show_combined_avg_thruput;;&lt;br /&gt;
esac&lt;br /&gt;
&lt;br /&gt;
fn_housekeeping&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
### TABLE DEFINTION FOR RAW DATA COLLECTION&lt;br /&gt;
### Use the table definition below to create the table which this script &lt;br /&gt;
### requires in order to insert queue data and furthermore query this&lt;br /&gt;
### data in order to provide throughput information.&lt;br /&gt;
#create table rs_throughput (&lt;br /&gt;
#q_name varchar(25), &lt;br /&gt;
#sample_time datetime, &lt;br /&gt;
#first numeric(8,2), &lt;br /&gt;
#last numeric(8,2), &lt;br /&gt;
#next numeric(8,2), &lt;br /&gt;
#size numeric(8,2), &lt;br /&gt;
#mb_processed numeric(8,2),&lt;br /&gt;
#thruput numeric(8,2)&lt;br /&gt;
#)&lt;br /&gt;
&lt;br /&gt;
# end program&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:RepServer]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=RepServer_Throughput_Script&amp;diff=1856</id>
		<title>RepServer Throughput Script</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=RepServer_Throughput_Script&amp;diff=1856"/>
				<updated>2009-02-20T09:41:31Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to know just how much data repserver is processing, then this is the tool.&amp;lt;br&amp;gt;&lt;br /&gt;
This script will tell you:&amp;lt;br&amp;gt;&lt;br /&gt;
o average throughput per queue (mb per minute)&amp;lt;br&amp;gt;&lt;br /&gt;
o average throughput combined (all queues)&amp;lt;br&amp;gt;&lt;br /&gt;
o estimated time for a replicate to catch up&amp;lt;br&amp;gt;&lt;br /&gt;
o current queue sizes&amp;lt;br&amp;gt;&lt;br /&gt;
There is also a maximum recorded throughput option but this appears not to work well as some of the figures have been suspicious.&amp;lt;br&amp;gt;&lt;br /&gt;
The real maximum throughput can be established by noting when the replicates start to fall behind in conjunction with the current throughput figures.&amp;lt;br&amp;gt;&lt;br /&gt;
This script can be particularly useful in helping to ascertain if you need to throw more CPU at your repserver box.&lt;br /&gt;
&lt;br /&gt;
Notes:&amp;lt;br&amp;gt;&lt;br /&gt;
1) You will need to cron this script with the insert option (rs_throughput.sh insert) and allow it to collect at least 2 samples before being able to run it interactively to obtain throughput information.  The script runs silently when run with the insert option.&amp;lt;br&amp;gt;&lt;br /&gt;
2) The script automatically determines the elapsed interval in minutes between samples so you can cron the script to your preferred interval, be it 3 minutes or 10 minutes, the mb/min figure will be calculated correctly.&amp;lt;br&amp;gt;&lt;br /&gt;
3) In addition to configuring the script to your environment, you will also need to create the rs_throughput table prior to first run.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/ksh&lt;br /&gt;
#&lt;br /&gt;
# Script: rs_throughput.sh&lt;br /&gt;
# Author: Bob Holmes - email: cambob@gmail.com&lt;br /&gt;
# Date  : 19/09/08&lt;br /&gt;
# Version : 1.0&lt;br /&gt;
# Usage : Run &amp;quot;rs_throughput.sh help&amp;quot; for full usage information.&lt;br /&gt;
# Description : This script enables monitoring and reporting&lt;br /&gt;
#               of repserver throughput.&lt;br /&gt;
# --------------------------&lt;br /&gt;
#    ***    Variables for customisation can be found by searching for &amp;quot;!!&amp;quot; ***&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Modification history:&lt;br /&gt;
# 19/02/09 : Bob Holmes : Script modified to enable easier customisation prior&lt;br /&gt;
#                         to release on Sybase wiki. (modifications not tested)&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Comments: This script relies on the reporting..rs_throughput table for data&lt;br /&gt;
#           collection and reporting.  The definition for this table can be&lt;br /&gt;
#           found at the end of this script. &lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           setup environment                                #&lt;br /&gt;
##############################################################################&lt;br /&gt;
#&lt;br /&gt;
# save input variables&lt;br /&gt;
if ! [[ -z $1 ]]&lt;br /&gt;
then&lt;br /&gt;
  export option1=$1&lt;br /&gt;
else&lt;br /&gt;
  export option1=&amp;quot;all&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if ! [[ -z $2 ]]&lt;br /&gt;
then&lt;br /&gt;
  export option2=$2&lt;br /&gt;
else&lt;br /&gt;
  export option2=&amp;quot;15&amp;quot; # default number of minutes on which to report throughput&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# configure environment&lt;br /&gt;
HOSTNAME=`hostname`&lt;br /&gt;
. $HOME/admin/.syb_cfg.sh $HOSTNAME  # !! This line sets up the environment from&lt;br /&gt;
                                     # !! from an external shell script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           config variables                                 #&lt;br /&gt;
##############################################################################&lt;br /&gt;
# config:&lt;br /&gt;
primary_ds=&amp;quot;prim_ds&amp;quot;                   # !! string used to identify the inbound queue&lt;br /&gt;
# queues to query on:-&lt;br /&gt;
q_list=&amp;quot;prim_ds.db1 prim_ds.db2 replicate_ds.db1 replicate_ds.db2&amp;quot; # !!&lt;br /&gt;
insert_filter=&amp;quot;db1 db2&amp;quot;                # !! data will only be collected for queue names which have this keyword in&lt;br /&gt;
REP_SRV=&amp;quot;repsrv_rs&amp;quot;                    # !! the actual repserver from which to get sqm info&lt;br /&gt;
RPT_SRV=&amp;quot;reporting_ds&amp;quot;                 # !! dataserver which manages the reporting database&lt;br /&gt;
RPT_DB=&amp;quot;reporting&amp;quot;                     # !! reporting database name&lt;br /&gt;
RECIPIENTS=&amp;quot;user@domain&amp;quot;               # !! email config (separate addresses with commas)&lt;br /&gt;
ADMINDIR=&amp;quot;/opt/home/sybase/admin&amp;quot;      # !! sybase admin directory&lt;br /&gt;
&lt;br /&gt;
# static:&lt;br /&gt;
SQMFILE=&amp;quot;$ADMINDIR/rs_sqm_tmp1.tmp&amp;quot;&lt;br /&gt;
DATE=$(date &amp;quot;+%d/%m/%y %H:%M:%S&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# config aware environment variables: # !! You may need to replace the line below with the equivalent&lt;br /&gt;
                                      # !! for your own environment. &lt;br /&gt;
RISQLCMD=&amp;quot;isql -Usa -P`grep &amp;quot;$REP_SRV,&amp;quot; $HOME/admin/.servers | cut  -d , -f 4` -S$rep_server -w1000&amp;quot;&lt;br /&gt;
ISQLCMD=&amp;quot;isql -Usa -P${SYBPASS} -S${RPT_SRV} -w200 -D${RPT_DB}&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                             functions                                      #&lt;br /&gt;
##############################################################################&lt;br /&gt;
&lt;br /&gt;
check_previous_instance()&lt;br /&gt;
{&lt;br /&gt;
# Note: next line greps for 8 instances as tests proved that less could cause the script to exit incorrectly&lt;br /&gt;
if [ $(ps -ef | grep rs_throughput | egrep -v &amp;quot;vi|grep&amp;quot; | grep -v &amp;quot;sh -c&amp;quot; | wc -l | awk '{print $1}') -gt 8 ]&lt;br /&gt;
then&lt;br /&gt;
  # previous instance still running - probably hanging&lt;br /&gt;
  echo Previous instance still running.&lt;br /&gt;
  exit&lt;br /&gt;
fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_checkusage()&lt;br /&gt;
{&lt;br /&gt;
if [[ -z $option1 ]]&lt;br /&gt;
then&lt;br /&gt;
  printf &amp;quot; Usage: ./rs_throughput.sh &amp;lt;all&amp;gt;|&amp;lt;q_name&amp;gt;|&amp;lt;help&amp;gt; [&amp;lt;minutes to display&amp;gt;]\n&amp;quot;&lt;br /&gt;
  exit&lt;br /&gt;
fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bcalc()&lt;br /&gt;
{&lt;br /&gt;
awk 'BEGIN{EQUATION='&amp;quot;$*&amp;quot;';printf(&amp;quot;%0.1f\n&amp;quot;,EQUATION); exit}'&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_housekeeping()&lt;br /&gt;
{&lt;br /&gt;
if [ -e $SQMFILE ]&lt;br /&gt;
then&lt;br /&gt;
  rm $SQMFILE&lt;br /&gt;
fi&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
go&lt;br /&gt;
delete from rs_throughput where sample_time &amp;lt;= dateadd(dd,-28,getdate())&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_insert_thruput_data()&lt;br /&gt;
{&lt;br /&gt;
# 1) get current segment usage/progress info&lt;br /&gt;
#connect to repserver, get sqm info - put into file&lt;br /&gt;
$RISQLCMD &amp;lt;&amp;lt; eof &amp;gt; $SQMFILE&lt;br /&gt;
admin who,sqm&lt;br /&gt;
go&lt;br /&gt;
quit&lt;br /&gt;
eof&lt;br /&gt;
&lt;br /&gt;
# 2) insert new segment data into rs_throughput table&lt;br /&gt;
#date&lt;br /&gt;
#echo &amp;quot;Queue Name, First segment, Last segment, Next segment&amp;quot;&lt;br /&gt;
cat $SQMFILE | egrep $insert_filter | sed 's/Awaiting Message/AwaitingMessage/; s/Awaiting Wakeup/AwaitingWakeup/; s/\(\.[0-9][0-&lt;br /&gt;
&lt;br /&gt;
9]*\)\.[0-9]/\1/' | grep -v &amp;quot;:0 ${primary_ds}&amp;quot; | awk '{print $4,$14,$15,$16}' | while read q_name first_seg last_seg next_seg&lt;br /&gt;
do&lt;br /&gt;
  q_size=$(bcalc &amp;quot;$last_seg - $first_seg&amp;quot;)&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
go&lt;br /&gt;
declare @mb_processed numeric(8,2)&lt;br /&gt;
declare @prev_sample datetime&lt;br /&gt;
declare @mins numeric(8,2)&lt;br /&gt;
declare @tput numeric(8,2)&lt;br /&gt;
if not exists (select 1 from rs_throughput where q_name = &amp;quot;${q_name}&amp;quot;)&lt;br /&gt;
insert rs_throughput values (&amp;quot;${q_name}&amp;quot;, getdate(), ${first_seg}, ${last_seg}, ${next_seg}, ${q_size}, 0, 0)&lt;br /&gt;
else&lt;br /&gt;
begin&lt;br /&gt;
-- get previous sample_time as key&lt;br /&gt;
select @prev_sample = max(sample_time) from rs_throughput where q_name = &amp;quot;${q_name}&amp;quot;&lt;br /&gt;
-- get difference in mb between current next segment and previous next segment&lt;br /&gt;
select @mb_processed = (select ${next_seg} - next from rs_throughput where sample_time = @prev_sample and q_name = &amp;quot;${q_name}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
select @prev_sample=dateadd(ss,-10,@prev_sample) -- # must substract 10 seconds to ensure the next datediff doesn't reflect 2m 58s &lt;br /&gt;
&lt;br /&gt;
as only 2mins!&lt;br /&gt;
select @mins = datediff(mi,@prev_sample,getdate())&lt;br /&gt;
if @mins &amp;gt; 0&lt;br /&gt;
begin&lt;br /&gt;
  select @tput = round((@mb_processed / @mins),2)&lt;br /&gt;
  insert rs_throughput values (&amp;quot;${q_name}&amp;quot;, getdate(), ${first_seg}, ${last_seg}, ${next_seg}, ${q_size}, @mb_processed, @tput)&lt;br /&gt;
end&lt;br /&gt;
end&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_report_thruput()&lt;br /&gt;
{&lt;br /&gt;
if [[ $option1 = [0-9]* ]]&lt;br /&gt;
then&lt;br /&gt;
  option2=$option1&lt;br /&gt;
  option1=&amp;quot;all&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if ! [[ &amp;quot;$option1&amp;quot; = &amp;quot;all&amp;quot; ]]&lt;br /&gt;
then&lt;br /&gt;
  q_list=$option1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
printf &amp;quot; -------------------------------------\n&amp;quot;&lt;br /&gt;
printf &amp;quot; Run date $DATE\n&amp;quot;&lt;br /&gt;
printf &amp;quot; -------------------------------------\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
for q_name in $q_list&lt;br /&gt;
do&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @mb_avg numeric(8,2)&lt;br /&gt;
declare @size numeric(8,2)&lt;br /&gt;
declare @eta datetime&lt;br /&gt;
select convert(char(19),sample_time) sample_time, q_name, size q_size, mb_processed, thruput &amp;quot;thruput (mb/min)&amp;quot;  from rs_throughput&lt;br /&gt;
--select convert(char(19),sample_time) sample_time, q_name, size q_size, mb_processed, thruput &amp;quot;thruput (mb/min)&amp;quot;, dateadd(mi,&lt;br /&gt;
&lt;br /&gt;
(round((size/thruput),0)),getdate()) ETA from rs_throughput&lt;br /&gt;
where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name like &amp;quot;%${q_name}%&amp;quot;&lt;br /&gt;
&lt;br /&gt;
--get mb average&lt;br /&gt;
select @mb_avg = convert(numeric(8,2),avg(thruput)) from rs_throughput&lt;br /&gt;
where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name like &amp;quot;%${q_name}%&amp;quot;&lt;br /&gt;
--get current queue size&lt;br /&gt;
select @size = size from rs_throughput where q_name like &amp;quot;%${q_name}%&amp;quot; having sample_time=max(sample_time)&lt;br /&gt;
select @eta = dateadd(mi,round((@size/@mb_avg),0),getdate())&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
print &amp;quot; Average for ${q_name}: %1! mb/min,  Re-sync ETA: %2!&amp;quot;, @mb_avg, @eta&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_help_text()&lt;br /&gt;
{&lt;br /&gt;
printf &amp;quot;Usage examples:\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh (runs with default values showing all queues over 15 minutes)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh &amp;lt;q_name&amp;gt;|&amp;lt;minutes&amp;gt;\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh &amp;lt;q_name&amp;gt; &amp;lt;minutes&amp;gt;\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh size|queue (shows current queue sizes)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh max (shows highest ever throughput for queue history)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh help (shows this helptext)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh insert # this is for cron only (inserts data to $RPT_DB..rs_throughput table)\n&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_max_thruput()&lt;br /&gt;
{&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
set rowcount 0&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @q_name char(22)&lt;br /&gt;
declare @sample_time datetime&lt;br /&gt;
declare @max_thruput numeric(8,2)&lt;br /&gt;
select q_name, sample_time, thruput into #throughput from rs_throughput where 1=0&lt;br /&gt;
print &amp;quot;Maximum throughput per queue:&amp;quot;&lt;br /&gt;
-- get list of queues&lt;br /&gt;
select distinct q_name, 0 as processed into #queues from rs_throughput&lt;br /&gt;
set rowcount 1&lt;br /&gt;
select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
while @@rowcount != 0&lt;br /&gt;
begin&lt;br /&gt;
  insert #throughput select q_name, sample_time, thruput from rs_throughput&lt;br /&gt;
  where sample_time in&lt;br /&gt;
    (select sample_time from rs_throughput where q_name = @q_name having thruput = max(thruput))&lt;br /&gt;
  and q_name = @q_name&lt;br /&gt;
  update #queues set processed = 1 where q_name = @q_name&lt;br /&gt;
  select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
end&lt;br /&gt;
set rowcount 0&lt;br /&gt;
select * from #throughput order by thruput desc&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
echo&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_current_q_size()&lt;br /&gt;
{&lt;br /&gt;
$RISQLCMD &amp;lt;&amp;lt; eof &amp;gt; $SQMFILE&lt;br /&gt;
admin who,sqm&lt;br /&gt;
go&lt;br /&gt;
quit&lt;br /&gt;
eof&lt;br /&gt;
printf &amp;quot;Current Stable Queue usage:\n&amp;quot;&lt;br /&gt;
cat $SQMFILE | egrep $insert_filter | sed 's/Awaiting Message/AwaitingMessage/; s/Awaiting Wakeup/AwaitingWakeup/; s/\(\.[0-9][0-&lt;br /&gt;
&lt;br /&gt;
9]*\)\.[0-9]/\1/' | grep -v &amp;quot;:0 ${primary_ds}&amp;quot; | awk '{print $4,$14,$15,$16}' | while read q_name first_seg last_seg next_seg&lt;br /&gt;
do&lt;br /&gt;
  q_size=$(bcalc &amp;quot;$last_seg - $first_seg&amp;quot;)&lt;br /&gt;
  printf &amp;quot;$q_name: $q_size\n&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_combined_avg_thruput()&lt;br /&gt;
{&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set rowcount 0&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @q_name varchar(25)&lt;br /&gt;
declare @mb_avg numeric(8,2)&lt;br /&gt;
declare @mb_combined_avg numeric(8,2)&lt;br /&gt;
select @mb_combined_avg=0&lt;br /&gt;
-- get list of queues&lt;br /&gt;
&lt;br /&gt;
select distinct q_name, 0 as processed into #queues from rs_throughput&lt;br /&gt;
set rowcount 1&lt;br /&gt;
select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
while @@rowcount != 0&lt;br /&gt;
begin&lt;br /&gt;
  select @mb_avg = convert(numeric(8,2),avg(thruput)) from rs_throughput&lt;br /&gt;
  where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name = @q_name&lt;br /&gt;
  select @mb_combined_avg = @mb_combined_avg + @mb_avg&lt;br /&gt;
  update #queues set processed=1 where q_name = @q_name&lt;br /&gt;
  select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
end&lt;br /&gt;
print &amp;quot; Combined thruput average: %1! mb/min&amp;quot;, @mb_combined_avg&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                             main program                                   #&lt;br /&gt;
##############################################################################&lt;br /&gt;
&lt;br /&gt;
check_previous_instance&lt;br /&gt;
fn_checkusage&lt;br /&gt;
&lt;br /&gt;
case &amp;quot;$option1&amp;quot; in&lt;br /&gt;
        help) fn_show_help_text;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
      insert) fn_insert_thruput_data;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
         max) fn_show_max_thruput;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
       queue|size) fn_show_current_q_size;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
           *) fn_report_thruput;&lt;br /&gt;
              fn_show_combined_avg_thruput;;&lt;br /&gt;
esac&lt;br /&gt;
&lt;br /&gt;
fn_housekeeping&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
### TABLE DEFINTION FOR RAW DATA COLLECTION&lt;br /&gt;
### Use the table definition below to create the table which this script &lt;br /&gt;
### requires in order to insert queue data and furthermore query this&lt;br /&gt;
### data in order to provide throughput information.&lt;br /&gt;
#create table rs_throughput (&lt;br /&gt;
#q_name varchar(25), &lt;br /&gt;
#sample_time datetime, &lt;br /&gt;
#first numeric(8,2), &lt;br /&gt;
#last numeric(8,2), &lt;br /&gt;
#next numeric(8,2), &lt;br /&gt;
#size numeric(8,2), &lt;br /&gt;
#mb_processed numeric(8,2),&lt;br /&gt;
#thruput numeric(8,2)&lt;br /&gt;
#)&lt;br /&gt;
&lt;br /&gt;
# end program&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:RepServer]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=Sp_mon_sql2--ASE_spid_activity_monitor&amp;diff=1855</id>
		<title>Sp mon sql2--ASE spid activity monitor</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=Sp_mon_sql2--ASE_spid_activity_monitor&amp;diff=1855"/>
				<updated>2009-02-20T01:03:45Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: This SP uses the MDA tables.&amp;lt;BR&amp;gt;&lt;br /&gt;
This sp is for getting a clear list of currently active spids with full details including login, db, blocking spid, processing time, query start time, cpu usage, logical and physical i/o, currently executing command etc.  To maximise clarity, all info is displayed on one line for each spid.  Alternate info is also available by running with '1' (without quotes) which includes, login time, host process, originating host and other information which may be useful for tracking down the source of a problem external to ASE.  Note, unfortunately the '1' option was a quick hack - the sp needs modifying to change this to a 'x' or something similar as the sp can also be called with &amp;lt;spid&amp;gt; to investigate a spid which is not currently active.&lt;br /&gt;
&lt;br /&gt;
Usage summary:&amp;lt;BR&amp;gt;&lt;br /&gt;
sp__mon_sql2&amp;lt;BR&amp;gt;&lt;br /&gt;
sp__mon_sql2 &amp;lt;spid&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
sp__mon_sql2 1  (due to the quick hack noted above, if you want to investigate spid 1, you can't! sorry - I'll fix it in the next version. Luckily the need to investigate spid 1 is quite rare.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
create procedure sp__mon_sql2&lt;br /&gt;
(&lt;br /&gt;
@spid int = 0&lt;br /&gt;
)&lt;br /&gt;
as&lt;br /&gt;
------------------------------&lt;br /&gt;
-- Procedure: sp__mon_sql2&lt;br /&gt;
--   Created: April 2008&lt;br /&gt;
--    Author: Bob Holmes (Email: cambob@gmail.com)&lt;br /&gt;
--     Usage: sp__mon_sql2 [spid]&lt;br /&gt;
-- Last modification: bobh - if 1 is specified as the spid number then alternate info is returned (dirty hack)&lt;br /&gt;
------------------------------&lt;br /&gt;
-- INFO:&lt;br /&gt;
-- The three *'s are a grep key for a shell script to use to extract the lines needed for alerting.&lt;br /&gt;
------------------------------&lt;br /&gt;
--part 1 - snapshot&lt;br /&gt;
set forceplan on&lt;br /&gt;
select 	s.StartTime, &lt;br /&gt;
	convert(smallint,(datediff(mi,StartTime,getdate()))) Dmins,  &lt;br /&gt;
	p.spid, &lt;br /&gt;
	p.hostname, &lt;br /&gt;
	p.suid, &lt;br /&gt;
	p.dbid, &lt;br /&gt;
	p.cmd, &lt;br /&gt;
        p.blocked,&lt;br /&gt;
	s.CpuTime, &lt;br /&gt;
	s.LogicalReads, &lt;br /&gt;
	s.PhysicalReads,&lt;br /&gt;
	p.status, &lt;br /&gt;
	p.loggedindatetime,&lt;br /&gt;
	p.program_name, &lt;br /&gt;
	l.ClientOSPID, &lt;br /&gt;
	p.time_blocked, &lt;br /&gt;
	p.ipaddr&lt;br /&gt;
into #processmon2&lt;br /&gt;
from master..sysprocesses p, master..monProcessStatement s, master..monProcessLookup l&lt;br /&gt;
where p.spid != @@spid&lt;br /&gt;
and p.spid *= s.SPID&lt;br /&gt;
and l.SPID = p.spid&lt;br /&gt;
and suid &amp;lt;&amp;gt; 0&lt;br /&gt;
order by p.spid&lt;br /&gt;
set forceplan off&lt;br /&gt;
&lt;br /&gt;
--part 2 --display spid summaries&lt;br /&gt;
&lt;br /&gt;
if @spid=0&lt;br /&gt;
begin&lt;br /&gt;
-- display header information for multiple spids&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;Process Summary (Order by Dmins, CpuTime, LogicalReads, PhysicalReads Desc )&amp;quot;&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;&amp;quot;&lt;br /&gt;
  select distinct &amp;quot;***&amp;quot;,&lt;br /&gt;
  spid Spid,&lt;br /&gt;
  convert(char(12),suser_name(suid)) Login,&lt;br /&gt;
  convert(char(16),db_name(dbid)) DB,&lt;br /&gt;
  (case hostname when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),hostname) end) Hostname,&lt;br /&gt;
  blocked,&lt;br /&gt;
  convert(varchar(19),StartTime) StartTime,&lt;br /&gt;
  Dmins,&lt;br /&gt;
  right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins/60)),2) + &amp;quot;:&amp;quot; + right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins%60)),2) Dtime,&lt;br /&gt;
  CpuTime,&lt;br /&gt;
  LogicalReads,&lt;br /&gt;
  PhysicalReads,&lt;br /&gt;
  cmd Command&lt;br /&gt;
  from #processmon2&lt;br /&gt;
  where cmd &amp;lt;&amp;gt; &amp;quot;AWAITING COMMAND&amp;quot;&lt;br /&gt;
  order by Dmins desc, CpuTime Desc, LogicalReads Desc, PhysicalReads Desc&lt;br /&gt;
end&lt;br /&gt;
else if @spid=1&lt;br /&gt;
begin&lt;br /&gt;
-- display header information for multiple spids&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;Process Summary (Order by Dmins, CpuTime, LogicalReads, PhysicalReads Desc )&amp;quot;&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;&amp;quot;&lt;br /&gt;
select &lt;br /&gt;
  spid Spid,&lt;br /&gt;
  convert(char(12),suser_name(suid)) Login,&lt;br /&gt;
  convert(char(15),db_name(dbid)) DB,&lt;br /&gt;
  (case hostname when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),hostname) end) Hostname,&lt;br /&gt;
  blocked,&lt;br /&gt;
  convert(varchar(19),StartTime) StartTime,&lt;br /&gt;
  Dmins,&lt;br /&gt;
  right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins/60)),2) + &amp;quot;:&amp;quot; + right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins%60)),2) Dtime,&lt;br /&gt;
  (case program_name when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),program_name) end) Application,&lt;br /&gt;
  (case ClientOSPID when NULL then &amp;quot;-&amp;quot; else convert(char(7),ClientOSPID) end) &amp;quot;OS PID&amp;quot;,&lt;br /&gt;
  time_blocked &amp;quot;Blocked(s)&amp;quot;,&lt;br /&gt;
  convert(char(8),loggedindatetime,108) &amp;quot;Logged in&amp;quot;,&lt;br /&gt;
  convert(char(15),ipaddr) ClientIP,&lt;br /&gt;
  cmd Command&lt;br /&gt;
  from #processmon2&lt;br /&gt;
  where cmd &amp;lt;&amp;gt; &amp;quot;AWAITING COMMAND&amp;quot;&lt;br /&gt;
  order by Dmins desc, CpuTime Desc, LogicalReads Desc, PhysicalReads Desc&lt;br /&gt;
end&lt;br /&gt;
else&lt;br /&gt;
begin&lt;br /&gt;
select distinct &amp;quot;***&amp;quot;,&lt;br /&gt;
  spid Spid,&lt;br /&gt;
  convert(char(12),suser_name(suid)) Login,&lt;br /&gt;
  convert(char(16),db_name(dbid)) DB,&lt;br /&gt;
  (case hostname when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),hostname) end) Hostname,&lt;br /&gt;
  convert(varchar(19),StartTime) StartTime,&lt;br /&gt;
  Dmins,&lt;br /&gt;
  blocked,&lt;br /&gt;
  right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins/60)),2) + &amp;quot;:&amp;quot; + right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins%60)),2) Dtime,&lt;br /&gt;
  CpuTime,&lt;br /&gt;
  LogicalReads,&lt;br /&gt;
  PhysicalReads,&lt;br /&gt;
  cmd Command&lt;br /&gt;
  from #processmon2&lt;br /&gt;
  where spid = @spid&lt;br /&gt;
  order by Dmins desc, CpuTime Desc, LogicalReads Desc, PhysicalReads Desc&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:ASE]]&lt;br /&gt;
[[Category:MDA tables]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=RepServer_Throughput_Script&amp;diff=1854</id>
		<title>RepServer Throughput Script</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=RepServer_Throughput_Script&amp;diff=1854"/>
				<updated>2009-02-20T00:27:49Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to know just how much data repserver is processing, then this is the tool.&amp;lt;br&amp;gt;&lt;br /&gt;
This script will tell you:&amp;lt;br&amp;gt;&lt;br /&gt;
o average throughput per queue (mb per minute)&amp;lt;br&amp;gt;&lt;br /&gt;
o average throughput combined (all queues)&amp;lt;br&amp;gt;&lt;br /&gt;
o estimated time for a replicate to catch up&amp;lt;br&amp;gt;&lt;br /&gt;
o current queue sizes&amp;lt;br&amp;gt;&lt;br /&gt;
There is also a maximum recorded throughput option but this appears not to work well as some of the figures have been suspicious.&amp;lt;br&amp;gt;&lt;br /&gt;
The real maximum throughput can be established by noting when the replicates start to fall behind in conjunction with the current throughput figures.&amp;lt;br&amp;gt;&lt;br /&gt;
This script can be particularly useful in helping to ascertain if you need to throw more CPU at your repserver box.&lt;br /&gt;
&lt;br /&gt;
Notes:&amp;lt;br&amp;gt;&lt;br /&gt;
1) You will need to cron this script and allow it to collect at least 2 samples before being able to run it interactively to obtain throughput information.&amp;lt;br&amp;gt;&lt;br /&gt;
2) The script automatically determines the elapsed interval in minutes between samples so you can cron the script to your preferred interval, be it 3 minutes or 10 minutes, the mb/min figure will be calculated correctly.&amp;lt;br&amp;gt;&lt;br /&gt;
3) In addition to configuring the script to your environment, you will also need to create the rs_throughput table prior to first run.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/ksh&lt;br /&gt;
#&lt;br /&gt;
# Script: rs_throughput.sh&lt;br /&gt;
# Author: Bob Holmes - email: cambob@gmail.com&lt;br /&gt;
# Date  : 19/09/08&lt;br /&gt;
# Version : 1.0&lt;br /&gt;
# Usage : Run &amp;quot;rs_throughput.sh help&amp;quot; for full usage information.&lt;br /&gt;
# Description : This script enables monitoring and reporting&lt;br /&gt;
#               of repserver throughput.&lt;br /&gt;
# --------------------------&lt;br /&gt;
#    ***    Variables for customisation can be found by searching for &amp;quot;!!&amp;quot; ***&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Modification history:&lt;br /&gt;
# 19/02/09 : Bob Holmes : Script modified to enable easier customisation prior&lt;br /&gt;
#                         to release on Sybase wiki. (modifications not tested)&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Comments: This script relies on the reporting..rs_throughput table for data&lt;br /&gt;
#           collection and reporting.  The definition for this table can be&lt;br /&gt;
#           found at the end of this script. &lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           setup environment                                #&lt;br /&gt;
##############################################################################&lt;br /&gt;
#&lt;br /&gt;
# save input variables&lt;br /&gt;
if ! [[ -z $1 ]]&lt;br /&gt;
then&lt;br /&gt;
  export option1=$1&lt;br /&gt;
else&lt;br /&gt;
  export option1=&amp;quot;all&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if ! [[ -z $2 ]]&lt;br /&gt;
then&lt;br /&gt;
  export option2=$2&lt;br /&gt;
else&lt;br /&gt;
  export option2=&amp;quot;15&amp;quot; # default number of minutes on which to report throughput&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# configure environment&lt;br /&gt;
HOSTNAME=`hostname`&lt;br /&gt;
. $HOME/admin/.syb_cfg.sh $HOSTNAME  # !! This line sets up the environment from&lt;br /&gt;
                                     # !! from an external shell script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           config variables                                 #&lt;br /&gt;
##############################################################################&lt;br /&gt;
# config:&lt;br /&gt;
primary_ds=&amp;quot;prim_ds&amp;quot;                   # !! string used to identify the inbound queue&lt;br /&gt;
# queues to query on:-&lt;br /&gt;
q_list=&amp;quot;prim_ds.db1 prim_ds.db2 replicate_ds.db1 replicate_ds.db2&amp;quot; # !!&lt;br /&gt;
insert_filter=&amp;quot;db1 db2&amp;quot;                # !! data will only be collected for queue names which have this keyword in&lt;br /&gt;
REP_SRV=&amp;quot;repsrv_rs&amp;quot;                    # !! the actual repserver from which to get sqm info&lt;br /&gt;
RPT_SRV=&amp;quot;reporting_ds&amp;quot;                 # !! dataserver which manages the reporting database&lt;br /&gt;
RPT_DB=&amp;quot;reporting&amp;quot;                     # !! reporting database name&lt;br /&gt;
RECIPIENTS=&amp;quot;user@domain&amp;quot;               # !! email config (separate addresses with commas)&lt;br /&gt;
ADMINDIR=&amp;quot;/opt/home/sybase/admin&amp;quot;      # !! sybase admin directory&lt;br /&gt;
&lt;br /&gt;
# static:&lt;br /&gt;
SQMFILE=&amp;quot;$ADMINDIR/rs_sqm_tmp1.tmp&amp;quot;&lt;br /&gt;
DATE=$(date &amp;quot;+%d/%m/%y %H:%M:%S&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# config aware environment variables: # !! You may need to replace the line below with the equivalent&lt;br /&gt;
                                      # !! for your own environment. &lt;br /&gt;
RISQLCMD=&amp;quot;isql -Usa -P`grep &amp;quot;$REP_SRV,&amp;quot; $HOME/admin/.servers | cut  -d , -f 4` -S$rep_server -w1000&amp;quot;&lt;br /&gt;
ISQLCMD=&amp;quot;isql -Usa -P${SYBPASS} -S${RPT_SRV} -w200 -D${RPT_DB}&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                             functions                                      #&lt;br /&gt;
##############################################################################&lt;br /&gt;
&lt;br /&gt;
check_previous_instance()&lt;br /&gt;
{&lt;br /&gt;
# Note: next line greps for 8 instances as tests proved that less could cause the script to exit incorrectly&lt;br /&gt;
if [ $(ps -ef | grep rs_throughput | egrep -v &amp;quot;vi|grep&amp;quot; | grep -v &amp;quot;sh -c&amp;quot; | wc -l | awk '{print $1}') -gt 8 ]&lt;br /&gt;
then&lt;br /&gt;
  # previous instance still running - probably hanging&lt;br /&gt;
  echo Previous instance still running.&lt;br /&gt;
  exit&lt;br /&gt;
fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_checkusage()&lt;br /&gt;
{&lt;br /&gt;
if [[ -z $option1 ]]&lt;br /&gt;
then&lt;br /&gt;
  printf &amp;quot; Usage: ./rs_throughput.sh &amp;lt;all&amp;gt;|&amp;lt;q_name&amp;gt;|&amp;lt;help&amp;gt; [&amp;lt;minutes to display&amp;gt;]\n&amp;quot;&lt;br /&gt;
  exit&lt;br /&gt;
fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bcalc()&lt;br /&gt;
{&lt;br /&gt;
awk 'BEGIN{EQUATION='&amp;quot;$*&amp;quot;';printf(&amp;quot;%0.1f\n&amp;quot;,EQUATION); exit}'&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_housekeeping()&lt;br /&gt;
{&lt;br /&gt;
if [ -e $SQMFILE ]&lt;br /&gt;
then&lt;br /&gt;
  rm $SQMFILE&lt;br /&gt;
fi&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
go&lt;br /&gt;
delete from rs_throughput where sample_time &amp;lt;= dateadd(dd,-28,getdate())&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_insert_thruput_data()&lt;br /&gt;
{&lt;br /&gt;
# 1) get current segment usage/progress info&lt;br /&gt;
#connect to repserver, get sqm info - put into file&lt;br /&gt;
$RISQLCMD &amp;lt;&amp;lt; eof &amp;gt; $SQMFILE&lt;br /&gt;
admin who,sqm&lt;br /&gt;
go&lt;br /&gt;
quit&lt;br /&gt;
eof&lt;br /&gt;
&lt;br /&gt;
# 2) insert new segment data into rs_throughput table&lt;br /&gt;
#date&lt;br /&gt;
#echo &amp;quot;Queue Name, First segment, Last segment, Next segment&amp;quot;&lt;br /&gt;
cat $SQMFILE | egrep $insert_filter | sed 's/Awaiting Message/AwaitingMessage/; s/Awaiting Wakeup/AwaitingWakeup/; s/\(\.[0-9][0-&lt;br /&gt;
&lt;br /&gt;
9]*\)\.[0-9]/\1/' | grep -v &amp;quot;:0 ${primary_ds}&amp;quot; | awk '{print $4,$14,$15,$16}' | while read q_name first_seg last_seg next_seg&lt;br /&gt;
do&lt;br /&gt;
  q_size=$(bcalc &amp;quot;$last_seg - $first_seg&amp;quot;)&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
go&lt;br /&gt;
declare @mb_processed numeric(8,2)&lt;br /&gt;
declare @prev_sample datetime&lt;br /&gt;
declare @mins numeric(8,2)&lt;br /&gt;
declare @tput numeric(8,2)&lt;br /&gt;
if not exists (select 1 from rs_throughput where q_name = &amp;quot;${q_name}&amp;quot;)&lt;br /&gt;
insert rs_throughput values (&amp;quot;${q_name}&amp;quot;, getdate(), ${first_seg}, ${last_seg}, ${next_seg}, ${q_size}, 0, 0)&lt;br /&gt;
else&lt;br /&gt;
begin&lt;br /&gt;
-- get previous sample_time as key&lt;br /&gt;
select @prev_sample = max(sample_time) from rs_throughput where q_name = &amp;quot;${q_name}&amp;quot;&lt;br /&gt;
-- get difference in mb between current next segment and previous next segment&lt;br /&gt;
select @mb_processed = (select ${next_seg} - next from rs_throughput where sample_time = @prev_sample and q_name = &amp;quot;${q_name}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
select @prev_sample=dateadd(ss,-10,@prev_sample) -- # must substract 10 seconds to ensure the next datediff doesn't reflect 2m 58s &lt;br /&gt;
&lt;br /&gt;
as only 2mins!&lt;br /&gt;
select @mins = datediff(mi,@prev_sample,getdate())&lt;br /&gt;
if @mins &amp;gt; 0&lt;br /&gt;
begin&lt;br /&gt;
  select @tput = round((@mb_processed / @mins),2)&lt;br /&gt;
  insert rs_throughput values (&amp;quot;${q_name}&amp;quot;, getdate(), ${first_seg}, ${last_seg}, ${next_seg}, ${q_size}, @mb_processed, @tput)&lt;br /&gt;
end&lt;br /&gt;
end&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_report_thruput()&lt;br /&gt;
{&lt;br /&gt;
if [[ $option1 = [0-9]* ]]&lt;br /&gt;
then&lt;br /&gt;
  option2=$option1&lt;br /&gt;
  option1=&amp;quot;all&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if ! [[ &amp;quot;$option1&amp;quot; = &amp;quot;all&amp;quot; ]]&lt;br /&gt;
then&lt;br /&gt;
  q_list=$option1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
printf &amp;quot; -------------------------------------\n&amp;quot;&lt;br /&gt;
printf &amp;quot; Run date $DATE\n&amp;quot;&lt;br /&gt;
printf &amp;quot; -------------------------------------\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
for q_name in $q_list&lt;br /&gt;
do&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @mb_avg numeric(8,2)&lt;br /&gt;
declare @size numeric(8,2)&lt;br /&gt;
declare @eta datetime&lt;br /&gt;
select convert(char(19),sample_time) sample_time, q_name, size q_size, mb_processed, thruput &amp;quot;thruput (mb/min)&amp;quot;  from rs_throughput&lt;br /&gt;
--select convert(char(19),sample_time) sample_time, q_name, size q_size, mb_processed, thruput &amp;quot;thruput (mb/min)&amp;quot;, dateadd(mi,&lt;br /&gt;
&lt;br /&gt;
(round((size/thruput),0)),getdate()) ETA from rs_throughput&lt;br /&gt;
where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name like &amp;quot;%${q_name}%&amp;quot;&lt;br /&gt;
&lt;br /&gt;
--get mb average&lt;br /&gt;
select @mb_avg = convert(numeric(8,2),avg(thruput)) from rs_throughput&lt;br /&gt;
where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name like &amp;quot;%${q_name}%&amp;quot;&lt;br /&gt;
--get current queue size&lt;br /&gt;
select @size = size from rs_throughput where q_name like &amp;quot;%${q_name}%&amp;quot; having sample_time=max(sample_time)&lt;br /&gt;
select @eta = dateadd(mi,round((@size/@mb_avg),0),getdate())&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
print &amp;quot; Average for ${q_name}: %1! mb/min,  Re-sync ETA: %2!&amp;quot;, @mb_avg, @eta&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_help_text()&lt;br /&gt;
{&lt;br /&gt;
printf &amp;quot;Usage examples:\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh (runs with default values showing all queues over 15 minutes)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh &amp;lt;q_name&amp;gt;|&amp;lt;minutes&amp;gt;\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh &amp;lt;q_name&amp;gt; &amp;lt;minutes&amp;gt;\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh size|queue (shows current queue sizes)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh max (shows highest ever throughput for queue history)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh help (shows this helptext)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh insert # this is for cron only (inserts data to $RPT_DB..rs_throughput table)\n&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_max_thruput()&lt;br /&gt;
{&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
set rowcount 0&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @q_name char(22)&lt;br /&gt;
declare @sample_time datetime&lt;br /&gt;
declare @max_thruput numeric(8,2)&lt;br /&gt;
select q_name, sample_time, thruput into #throughput from rs_throughput where 1=0&lt;br /&gt;
print &amp;quot;Maximum throughput per queue:&amp;quot;&lt;br /&gt;
-- get list of queues&lt;br /&gt;
select distinct q_name, 0 as processed into #queues from rs_throughput&lt;br /&gt;
set rowcount 1&lt;br /&gt;
select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
while @@rowcount != 0&lt;br /&gt;
begin&lt;br /&gt;
  insert #throughput select q_name, sample_time, thruput from rs_throughput&lt;br /&gt;
  where sample_time in&lt;br /&gt;
    (select sample_time from rs_throughput where q_name = @q_name having thruput = max(thruput))&lt;br /&gt;
  and q_name = @q_name&lt;br /&gt;
  update #queues set processed = 1 where q_name = @q_name&lt;br /&gt;
  select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
end&lt;br /&gt;
set rowcount 0&lt;br /&gt;
select * from #throughput order by thruput desc&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
echo&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_current_q_size()&lt;br /&gt;
{&lt;br /&gt;
$RISQLCMD &amp;lt;&amp;lt; eof &amp;gt; $SQMFILE&lt;br /&gt;
admin who,sqm&lt;br /&gt;
go&lt;br /&gt;
quit&lt;br /&gt;
eof&lt;br /&gt;
printf &amp;quot;Current Stable Queue usage:\n&amp;quot;&lt;br /&gt;
cat $SQMFILE | egrep $insert_filter | sed 's/Awaiting Message/AwaitingMessage/; s/Awaiting Wakeup/AwaitingWakeup/; s/\(\.[0-9][0-&lt;br /&gt;
&lt;br /&gt;
9]*\)\.[0-9]/\1/' | grep -v &amp;quot;:0 ${primary_ds}&amp;quot; | awk '{print $4,$14,$15,$16}' | while read q_name first_seg last_seg next_seg&lt;br /&gt;
do&lt;br /&gt;
  q_size=$(bcalc &amp;quot;$last_seg - $first_seg&amp;quot;)&lt;br /&gt;
  printf &amp;quot;$q_name: $q_size\n&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_combined_avg_thruput()&lt;br /&gt;
{&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set rowcount 0&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @q_name varchar(25)&lt;br /&gt;
declare @mb_avg numeric(8,2)&lt;br /&gt;
declare @mb_combined_avg numeric(8,2)&lt;br /&gt;
select @mb_combined_avg=0&lt;br /&gt;
-- get list of queues&lt;br /&gt;
&lt;br /&gt;
select distinct q_name, 0 as processed into #queues from rs_throughput&lt;br /&gt;
set rowcount 1&lt;br /&gt;
select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
while @@rowcount != 0&lt;br /&gt;
begin&lt;br /&gt;
  select @mb_avg = convert(numeric(8,2),avg(thruput)) from rs_throughput&lt;br /&gt;
  where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name = @q_name&lt;br /&gt;
  select @mb_combined_avg = @mb_combined_avg + @mb_avg&lt;br /&gt;
  update #queues set processed=1 where q_name = @q_name&lt;br /&gt;
  select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
end&lt;br /&gt;
print &amp;quot; Combined thruput average: %1! mb/min&amp;quot;, @mb_combined_avg&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                             main program                                   #&lt;br /&gt;
##############################################################################&lt;br /&gt;
&lt;br /&gt;
check_previous_instance&lt;br /&gt;
fn_checkusage&lt;br /&gt;
&lt;br /&gt;
case &amp;quot;$option1&amp;quot; in&lt;br /&gt;
        help) fn_show_help_text;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
      insert) fn_insert_thruput_data;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
         max) fn_show_max_thruput;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
       queue|size) fn_show_current_q_size;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
           *) fn_report_thruput;&lt;br /&gt;
              fn_show_combined_avg_thruput;;&lt;br /&gt;
esac&lt;br /&gt;
&lt;br /&gt;
fn_housekeeping&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
### TABLE DEFINTION FOR RAW DATA COLLECTION&lt;br /&gt;
### Use the table definition below to create the table which this script &lt;br /&gt;
### requires in order to insert queue data and furthermore query this&lt;br /&gt;
### data in order to provide throughput information.&lt;br /&gt;
#create table rs_throughput (&lt;br /&gt;
#q_name varchar(25), &lt;br /&gt;
#sample_time datetime, &lt;br /&gt;
#first numeric(8,2), &lt;br /&gt;
#last numeric(8,2), &lt;br /&gt;
#next numeric(8,2), &lt;br /&gt;
#size numeric(8,2), &lt;br /&gt;
#mb_processed numeric(8,2),&lt;br /&gt;
#thruput numeric(8,2)&lt;br /&gt;
#)&lt;br /&gt;
&lt;br /&gt;
# end program&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:RepServer]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=RepServer_Throughput_Script&amp;diff=1853</id>
		<title>RepServer Throughput Script</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=RepServer_Throughput_Script&amp;diff=1853"/>
				<updated>2009-02-20T00:26:38Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to know just how much data repserver is processing, then this is the tool.&amp;lt;br&amp;gt;&lt;br /&gt;
This script will tell you:&amp;lt;br&amp;gt;&lt;br /&gt;
o average throughput per queue (mb per minute)&amp;lt;br&amp;gt;&lt;br /&gt;
o average throughput combined (all queues)&amp;lt;br&amp;gt;&lt;br /&gt;
o estimated time for a replicate to catch up&amp;lt;br&amp;gt;&lt;br /&gt;
o current queue sizes&amp;lt;br&amp;gt;&lt;br /&gt;
There is also a maximum recorded throughput option but this appears not to work well as some of the figures have been suspicious.&amp;lt;br&amp;gt;&lt;br /&gt;
The real maximum throughput can be established by noting when the replicates start to fall behind in conjunction with the current throughput figures.&amp;lt;br&amp;gt;&lt;br /&gt;
This script can be particularly useful in helping to ascertain if you need to throw more CPU at your repserver box.&lt;br /&gt;
&lt;br /&gt;
Notes:&amp;lt;br&amp;gt;&lt;br /&gt;
1) You will need to cron this script and allow it to collect at least 2 samples before being able to run it interactively to obtain throughput information.&amp;lt;br&amp;gt;&lt;br /&gt;
2) The script automatically determines the elapsed interval in minutes between samples so you can cron the script to your preferred interval, be it 3 minutes or 10 minutes, the mb/min figure will be calculated correctly.&lt;br /&gt;
3) In addition to configuring the script to your environment, you will also need to create the rs_throughput table prior to first run.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/ksh&lt;br /&gt;
#&lt;br /&gt;
# Script: rs_throughput.sh&lt;br /&gt;
# Author: Bob Holmes - email: cambob@gmail.com&lt;br /&gt;
# Date  : 19/09/08&lt;br /&gt;
# Version : 1.0&lt;br /&gt;
# Usage : Run &amp;quot;rs_throughput.sh help&amp;quot; for full usage information.&lt;br /&gt;
# Description : This script enables monitoring and reporting&lt;br /&gt;
#               of repserver throughput.&lt;br /&gt;
# --------------------------&lt;br /&gt;
#    ***    Variables for customisation can be found by searching for &amp;quot;!!&amp;quot; ***&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Modification history:&lt;br /&gt;
# 19/02/09 : Bob Holmes : Script modified to enable easier customisation prior&lt;br /&gt;
#                         to release on Sybase wiki. (modifications not tested)&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Comments: This script relies on the reporting..rs_throughput table for data&lt;br /&gt;
#           collection and reporting.  The definition for this table can be&lt;br /&gt;
#           found at the end of this script. &lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           setup environment                                #&lt;br /&gt;
##############################################################################&lt;br /&gt;
#&lt;br /&gt;
# save input variables&lt;br /&gt;
if ! [[ -z $1 ]]&lt;br /&gt;
then&lt;br /&gt;
  export option1=$1&lt;br /&gt;
else&lt;br /&gt;
  export option1=&amp;quot;all&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if ! [[ -z $2 ]]&lt;br /&gt;
then&lt;br /&gt;
  export option2=$2&lt;br /&gt;
else&lt;br /&gt;
  export option2=&amp;quot;15&amp;quot; # default number of minutes on which to report throughput&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# configure environment&lt;br /&gt;
HOSTNAME=`hostname`&lt;br /&gt;
. $HOME/admin/.syb_cfg.sh $HOSTNAME  # !! This line sets up the environment from&lt;br /&gt;
                                     # !! from an external shell script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           config variables                                 #&lt;br /&gt;
##############################################################################&lt;br /&gt;
# config:&lt;br /&gt;
primary_ds=&amp;quot;prim_ds&amp;quot;                   # !! string used to identify the inbound queue&lt;br /&gt;
# queues to query on:-&lt;br /&gt;
q_list=&amp;quot;prim_ds.db1 prim_ds.db2 replicate_ds.db1 replicate_ds.db2&amp;quot; # !!&lt;br /&gt;
insert_filter=&amp;quot;db1 db2&amp;quot;                # !! data will only be collected for queue names which have this keyword in&lt;br /&gt;
REP_SRV=&amp;quot;repsrv_rs&amp;quot;                    # !! the actual repserver from which to get sqm info&lt;br /&gt;
RPT_SRV=&amp;quot;reporting_ds&amp;quot;                 # !! dataserver which manages the reporting database&lt;br /&gt;
RPT_DB=&amp;quot;reporting&amp;quot;                     # !! reporting database name&lt;br /&gt;
RECIPIENTS=&amp;quot;user@domain&amp;quot;               # !! email config (separate addresses with commas)&lt;br /&gt;
ADMINDIR=&amp;quot;/opt/home/sybase/admin&amp;quot;      # !! sybase admin directory&lt;br /&gt;
&lt;br /&gt;
# static:&lt;br /&gt;
SQMFILE=&amp;quot;$ADMINDIR/rs_sqm_tmp1.tmp&amp;quot;&lt;br /&gt;
DATE=$(date &amp;quot;+%d/%m/%y %H:%M:%S&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# config aware environment variables: # !! You may need to replace the line below with the equivalent&lt;br /&gt;
                                      # !! for your own environment. &lt;br /&gt;
RISQLCMD=&amp;quot;isql -Usa -P`grep &amp;quot;$REP_SRV,&amp;quot; $HOME/admin/.servers | cut  -d , -f 4` -S$rep_server -w1000&amp;quot;&lt;br /&gt;
ISQLCMD=&amp;quot;isql -Usa -P${SYBPASS} -S${RPT_SRV} -w200 -D${RPT_DB}&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                             functions                                      #&lt;br /&gt;
##############################################################################&lt;br /&gt;
&lt;br /&gt;
check_previous_instance()&lt;br /&gt;
{&lt;br /&gt;
# Note: next line greps for 8 instances as tests proved that less could cause the script to exit incorrectly&lt;br /&gt;
if [ $(ps -ef | grep rs_throughput | egrep -v &amp;quot;vi|grep&amp;quot; | grep -v &amp;quot;sh -c&amp;quot; | wc -l | awk '{print $1}') -gt 8 ]&lt;br /&gt;
then&lt;br /&gt;
  # previous instance still running - probably hanging&lt;br /&gt;
  echo Previous instance still running.&lt;br /&gt;
  exit&lt;br /&gt;
fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_checkusage()&lt;br /&gt;
{&lt;br /&gt;
if [[ -z $option1 ]]&lt;br /&gt;
then&lt;br /&gt;
  printf &amp;quot; Usage: ./rs_throughput.sh &amp;lt;all&amp;gt;|&amp;lt;q_name&amp;gt;|&amp;lt;help&amp;gt; [&amp;lt;minutes to display&amp;gt;]\n&amp;quot;&lt;br /&gt;
  exit&lt;br /&gt;
fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bcalc()&lt;br /&gt;
{&lt;br /&gt;
awk 'BEGIN{EQUATION='&amp;quot;$*&amp;quot;';printf(&amp;quot;%0.1f\n&amp;quot;,EQUATION); exit}'&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_housekeeping()&lt;br /&gt;
{&lt;br /&gt;
if [ -e $SQMFILE ]&lt;br /&gt;
then&lt;br /&gt;
  rm $SQMFILE&lt;br /&gt;
fi&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
go&lt;br /&gt;
delete from rs_throughput where sample_time &amp;lt;= dateadd(dd,-28,getdate())&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_insert_thruput_data()&lt;br /&gt;
{&lt;br /&gt;
# 1) get current segment usage/progress info&lt;br /&gt;
#connect to repserver, get sqm info - put into file&lt;br /&gt;
$RISQLCMD &amp;lt;&amp;lt; eof &amp;gt; $SQMFILE&lt;br /&gt;
admin who,sqm&lt;br /&gt;
go&lt;br /&gt;
quit&lt;br /&gt;
eof&lt;br /&gt;
&lt;br /&gt;
# 2) insert new segment data into rs_throughput table&lt;br /&gt;
#date&lt;br /&gt;
#echo &amp;quot;Queue Name, First segment, Last segment, Next segment&amp;quot;&lt;br /&gt;
cat $SQMFILE | egrep $insert_filter | sed 's/Awaiting Message/AwaitingMessage/; s/Awaiting Wakeup/AwaitingWakeup/; s/\(\.[0-9][0-&lt;br /&gt;
&lt;br /&gt;
9]*\)\.[0-9]/\1/' | grep -v &amp;quot;:0 ${primary_ds}&amp;quot; | awk '{print $4,$14,$15,$16}' | while read q_name first_seg last_seg next_seg&lt;br /&gt;
do&lt;br /&gt;
  q_size=$(bcalc &amp;quot;$last_seg - $first_seg&amp;quot;)&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
go&lt;br /&gt;
declare @mb_processed numeric(8,2)&lt;br /&gt;
declare @prev_sample datetime&lt;br /&gt;
declare @mins numeric(8,2)&lt;br /&gt;
declare @tput numeric(8,2)&lt;br /&gt;
if not exists (select 1 from rs_throughput where q_name = &amp;quot;${q_name}&amp;quot;)&lt;br /&gt;
insert rs_throughput values (&amp;quot;${q_name}&amp;quot;, getdate(), ${first_seg}, ${last_seg}, ${next_seg}, ${q_size}, 0, 0)&lt;br /&gt;
else&lt;br /&gt;
begin&lt;br /&gt;
-- get previous sample_time as key&lt;br /&gt;
select @prev_sample = max(sample_time) from rs_throughput where q_name = &amp;quot;${q_name}&amp;quot;&lt;br /&gt;
-- get difference in mb between current next segment and previous next segment&lt;br /&gt;
select @mb_processed = (select ${next_seg} - next from rs_throughput where sample_time = @prev_sample and q_name = &amp;quot;${q_name}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
select @prev_sample=dateadd(ss,-10,@prev_sample) -- # must substract 10 seconds to ensure the next datediff doesn't reflect 2m 58s &lt;br /&gt;
&lt;br /&gt;
as only 2mins!&lt;br /&gt;
select @mins = datediff(mi,@prev_sample,getdate())&lt;br /&gt;
if @mins &amp;gt; 0&lt;br /&gt;
begin&lt;br /&gt;
  select @tput = round((@mb_processed / @mins),2)&lt;br /&gt;
  insert rs_throughput values (&amp;quot;${q_name}&amp;quot;, getdate(), ${first_seg}, ${last_seg}, ${next_seg}, ${q_size}, @mb_processed, @tput)&lt;br /&gt;
end&lt;br /&gt;
end&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_report_thruput()&lt;br /&gt;
{&lt;br /&gt;
if [[ $option1 = [0-9]* ]]&lt;br /&gt;
then&lt;br /&gt;
  option2=$option1&lt;br /&gt;
  option1=&amp;quot;all&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if ! [[ &amp;quot;$option1&amp;quot; = &amp;quot;all&amp;quot; ]]&lt;br /&gt;
then&lt;br /&gt;
  q_list=$option1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
printf &amp;quot; -------------------------------------\n&amp;quot;&lt;br /&gt;
printf &amp;quot; Run date $DATE\n&amp;quot;&lt;br /&gt;
printf &amp;quot; -------------------------------------\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
for q_name in $q_list&lt;br /&gt;
do&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @mb_avg numeric(8,2)&lt;br /&gt;
declare @size numeric(8,2)&lt;br /&gt;
declare @eta datetime&lt;br /&gt;
select convert(char(19),sample_time) sample_time, q_name, size q_size, mb_processed, thruput &amp;quot;thruput (mb/min)&amp;quot;  from rs_throughput&lt;br /&gt;
--select convert(char(19),sample_time) sample_time, q_name, size q_size, mb_processed, thruput &amp;quot;thruput (mb/min)&amp;quot;, dateadd(mi,&lt;br /&gt;
&lt;br /&gt;
(round((size/thruput),0)),getdate()) ETA from rs_throughput&lt;br /&gt;
where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name like &amp;quot;%${q_name}%&amp;quot;&lt;br /&gt;
&lt;br /&gt;
--get mb average&lt;br /&gt;
select @mb_avg = convert(numeric(8,2),avg(thruput)) from rs_throughput&lt;br /&gt;
where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name like &amp;quot;%${q_name}%&amp;quot;&lt;br /&gt;
--get current queue size&lt;br /&gt;
select @size = size from rs_throughput where q_name like &amp;quot;%${q_name}%&amp;quot; having sample_time=max(sample_time)&lt;br /&gt;
select @eta = dateadd(mi,round((@size/@mb_avg),0),getdate())&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
print &amp;quot; Average for ${q_name}: %1! mb/min,  Re-sync ETA: %2!&amp;quot;, @mb_avg, @eta&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_help_text()&lt;br /&gt;
{&lt;br /&gt;
printf &amp;quot;Usage examples:\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh (runs with default values showing all queues over 15 minutes)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh &amp;lt;q_name&amp;gt;|&amp;lt;minutes&amp;gt;\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh &amp;lt;q_name&amp;gt; &amp;lt;minutes&amp;gt;\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh size|queue (shows current queue sizes)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh max (shows highest ever throughput for queue history)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh help (shows this helptext)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh insert # this is for cron only (inserts data to $RPT_DB..rs_throughput table)\n&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_max_thruput()&lt;br /&gt;
{&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
set rowcount 0&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @q_name char(22)&lt;br /&gt;
declare @sample_time datetime&lt;br /&gt;
declare @max_thruput numeric(8,2)&lt;br /&gt;
select q_name, sample_time, thruput into #throughput from rs_throughput where 1=0&lt;br /&gt;
print &amp;quot;Maximum throughput per queue:&amp;quot;&lt;br /&gt;
-- get list of queues&lt;br /&gt;
select distinct q_name, 0 as processed into #queues from rs_throughput&lt;br /&gt;
set rowcount 1&lt;br /&gt;
select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
while @@rowcount != 0&lt;br /&gt;
begin&lt;br /&gt;
  insert #throughput select q_name, sample_time, thruput from rs_throughput&lt;br /&gt;
  where sample_time in&lt;br /&gt;
    (select sample_time from rs_throughput where q_name = @q_name having thruput = max(thruput))&lt;br /&gt;
  and q_name = @q_name&lt;br /&gt;
  update #queues set processed = 1 where q_name = @q_name&lt;br /&gt;
  select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
end&lt;br /&gt;
set rowcount 0&lt;br /&gt;
select * from #throughput order by thruput desc&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
echo&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_current_q_size()&lt;br /&gt;
{&lt;br /&gt;
$RISQLCMD &amp;lt;&amp;lt; eof &amp;gt; $SQMFILE&lt;br /&gt;
admin who,sqm&lt;br /&gt;
go&lt;br /&gt;
quit&lt;br /&gt;
eof&lt;br /&gt;
printf &amp;quot;Current Stable Queue usage:\n&amp;quot;&lt;br /&gt;
cat $SQMFILE | egrep $insert_filter | sed 's/Awaiting Message/AwaitingMessage/; s/Awaiting Wakeup/AwaitingWakeup/; s/\(\.[0-9][0-&lt;br /&gt;
&lt;br /&gt;
9]*\)\.[0-9]/\1/' | grep -v &amp;quot;:0 ${primary_ds}&amp;quot; | awk '{print $4,$14,$15,$16}' | while read q_name first_seg last_seg next_seg&lt;br /&gt;
do&lt;br /&gt;
  q_size=$(bcalc &amp;quot;$last_seg - $first_seg&amp;quot;)&lt;br /&gt;
  printf &amp;quot;$q_name: $q_size\n&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_combined_avg_thruput()&lt;br /&gt;
{&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set rowcount 0&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @q_name varchar(25)&lt;br /&gt;
declare @mb_avg numeric(8,2)&lt;br /&gt;
declare @mb_combined_avg numeric(8,2)&lt;br /&gt;
select @mb_combined_avg=0&lt;br /&gt;
-- get list of queues&lt;br /&gt;
&lt;br /&gt;
select distinct q_name, 0 as processed into #queues from rs_throughput&lt;br /&gt;
set rowcount 1&lt;br /&gt;
select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
while @@rowcount != 0&lt;br /&gt;
begin&lt;br /&gt;
  select @mb_avg = convert(numeric(8,2),avg(thruput)) from rs_throughput&lt;br /&gt;
  where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name = @q_name&lt;br /&gt;
  select @mb_combined_avg = @mb_combined_avg + @mb_avg&lt;br /&gt;
  update #queues set processed=1 where q_name = @q_name&lt;br /&gt;
  select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
end&lt;br /&gt;
print &amp;quot; Combined thruput average: %1! mb/min&amp;quot;, @mb_combined_avg&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                             main program                                   #&lt;br /&gt;
##############################################################################&lt;br /&gt;
&lt;br /&gt;
check_previous_instance&lt;br /&gt;
fn_checkusage&lt;br /&gt;
&lt;br /&gt;
case &amp;quot;$option1&amp;quot; in&lt;br /&gt;
        help) fn_show_help_text;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
      insert) fn_insert_thruput_data;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
         max) fn_show_max_thruput;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
       queue|size) fn_show_current_q_size;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
           *) fn_report_thruput;&lt;br /&gt;
              fn_show_combined_avg_thruput;;&lt;br /&gt;
esac&lt;br /&gt;
&lt;br /&gt;
fn_housekeeping&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
### TABLE DEFINTION FOR RAW DATA COLLECTION&lt;br /&gt;
### Use the table definition below to create the table which this script &lt;br /&gt;
### requires in order to insert queue data and furthermore query this&lt;br /&gt;
### data in order to provide throughput information.&lt;br /&gt;
#create table rs_throughput (&lt;br /&gt;
#q_name varchar(25), &lt;br /&gt;
#sample_time datetime, &lt;br /&gt;
#first numeric(8,2), &lt;br /&gt;
#last numeric(8,2), &lt;br /&gt;
#next numeric(8,2), &lt;br /&gt;
#size numeric(8,2), &lt;br /&gt;
#mb_processed numeric(8,2),&lt;br /&gt;
#thruput numeric(8,2)&lt;br /&gt;
#)&lt;br /&gt;
&lt;br /&gt;
# end program&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:RepServer]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=RepServer_Throughput_Script&amp;diff=1852</id>
		<title>RepServer Throughput Script</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=RepServer_Throughput_Script&amp;diff=1852"/>
				<updated>2009-02-20T00:05:28Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to know just how much data repserver is processing, then this is the tool.&amp;lt;br&amp;gt;&lt;br /&gt;
This script will tell you:&amp;lt;br&amp;gt;&lt;br /&gt;
o average throughput per queue (mb per minute)&amp;lt;br&amp;gt;&lt;br /&gt;
o average throughput combined (all queues)&amp;lt;br&amp;gt;&lt;br /&gt;
o estimated time for a replicate to catch up&amp;lt;br&amp;gt;&lt;br /&gt;
o current queue sizes&amp;lt;br&amp;gt;&lt;br /&gt;
There is also a maximum recorded throughput option but this appears not to work well as some of the figures have been suspicious.&amp;lt;br&amp;gt;&lt;br /&gt;
The real maximum throughput can be established by noting when the replicates start to fall behind in conjunction with the current throughput figures.&amp;lt;br&amp;gt;&lt;br /&gt;
This script can be particularly useful in helping to ascertain if you need to throw more CPU at your repserver box.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/ksh&lt;br /&gt;
#&lt;br /&gt;
# Script: rs_throughput.sh&lt;br /&gt;
# Author: Bob Holmes - email: cambob@gmail.com&lt;br /&gt;
# Date  : 19/09/08&lt;br /&gt;
# Version : 1.0&lt;br /&gt;
# Usage : Run &amp;quot;rs_throughput.sh help&amp;quot; for full usage information.&lt;br /&gt;
# Description : This script enables monitoring and reporting&lt;br /&gt;
#               of repserver throughput.&lt;br /&gt;
# --------------------------&lt;br /&gt;
#    ***    Variables for customisation can be found by searching for &amp;quot;!!&amp;quot; ***&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Modification history:&lt;br /&gt;
# 19/02/09 : Bob Holmes : Script modified to enable easier customisation prior&lt;br /&gt;
#                         to release on Sybase wiki. (modifications not tested)&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Comments: This script relies on the reporting..rs_throughput table for data&lt;br /&gt;
#           collection and reporting.  The definition for this table can be&lt;br /&gt;
#           found at the end of this script. &lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           setup environment                                #&lt;br /&gt;
##############################################################################&lt;br /&gt;
#&lt;br /&gt;
# save input variables&lt;br /&gt;
if ! [[ -z $1 ]]&lt;br /&gt;
then&lt;br /&gt;
  export option1=$1&lt;br /&gt;
else&lt;br /&gt;
  export option1=&amp;quot;all&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if ! [[ -z $2 ]]&lt;br /&gt;
then&lt;br /&gt;
  export option2=$2&lt;br /&gt;
else&lt;br /&gt;
  export option2=&amp;quot;15&amp;quot; # default number of minutes on which to report throughput&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# configure environment&lt;br /&gt;
HOSTNAME=`hostname`&lt;br /&gt;
. $HOME/admin/.syb_cfg.sh $HOSTNAME  # !! This line sets up the environment from&lt;br /&gt;
                                     # !! from an external shell script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           config variables                                 #&lt;br /&gt;
##############################################################################&lt;br /&gt;
# config:&lt;br /&gt;
primary_ds=&amp;quot;prim_ds&amp;quot;                   # !! string used to identify the inbound queue&lt;br /&gt;
# queues to query on:-&lt;br /&gt;
q_list=&amp;quot;prim_ds.db1 prim_ds.db2 replicate_ds.db1 replicate_ds.db2&amp;quot; # !!&lt;br /&gt;
insert_filter=&amp;quot;db1 db2&amp;quot;                # !! data will only be collected for queue names which have this keyword in&lt;br /&gt;
REP_SRV=&amp;quot;repsrv_rs&amp;quot;                    # !! the actual repserver from which to get sqm info&lt;br /&gt;
RPT_SRV=&amp;quot;reporting_ds&amp;quot;                 # !! dataserver which manages the reporting database&lt;br /&gt;
RPT_DB=&amp;quot;reporting&amp;quot;                     # !! reporting database name&lt;br /&gt;
RECIPIENTS=&amp;quot;user@domain&amp;quot;               # !! email config (separate addresses with commas)&lt;br /&gt;
ADMINDIR=&amp;quot;/opt/home/sybase/admin&amp;quot;      # !! sybase admin directory&lt;br /&gt;
&lt;br /&gt;
# static:&lt;br /&gt;
SQMFILE=&amp;quot;$ADMINDIR/rs_sqm_tmp1.tmp&amp;quot;&lt;br /&gt;
DATE=$(date &amp;quot;+%d/%m/%y %H:%M:%S&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# config aware environment variables: # !! You may need to replace the line below with the equivalent&lt;br /&gt;
                                      # !! for your own environment. &lt;br /&gt;
RISQLCMD=&amp;quot;isql -Usa -P`grep &amp;quot;$REP_SRV,&amp;quot; $HOME/admin/.servers | cut  -d , -f 4` -S$rep_server -w1000&amp;quot;&lt;br /&gt;
ISQLCMD=&amp;quot;isql -Usa -P${SYBPASS} -S${RPT_SRV} -w200 -D${RPT_DB}&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                             functions                                      #&lt;br /&gt;
##############################################################################&lt;br /&gt;
&lt;br /&gt;
check_previous_instance()&lt;br /&gt;
{&lt;br /&gt;
# Note: next line greps for 8 instances as tests proved that less could cause the script to exit incorrectly&lt;br /&gt;
if [ $(ps -ef | grep rs_throughput | egrep -v &amp;quot;vi|grep&amp;quot; | grep -v &amp;quot;sh -c&amp;quot; | wc -l | awk '{print $1}') -gt 8 ]&lt;br /&gt;
then&lt;br /&gt;
  # previous instance still running - probably hanging&lt;br /&gt;
  echo Previous instance still running.&lt;br /&gt;
  exit&lt;br /&gt;
fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_checkusage()&lt;br /&gt;
{&lt;br /&gt;
if [[ -z $option1 ]]&lt;br /&gt;
then&lt;br /&gt;
  printf &amp;quot; Usage: ./rs_throughput.sh &amp;lt;all&amp;gt;|&amp;lt;q_name&amp;gt;|&amp;lt;help&amp;gt; [&amp;lt;minutes to display&amp;gt;]\n&amp;quot;&lt;br /&gt;
  exit&lt;br /&gt;
fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bcalc()&lt;br /&gt;
{&lt;br /&gt;
awk 'BEGIN{EQUATION='&amp;quot;$*&amp;quot;';printf(&amp;quot;%0.1f\n&amp;quot;,EQUATION); exit}'&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_housekeeping()&lt;br /&gt;
{&lt;br /&gt;
if [ -e $SQMFILE ]&lt;br /&gt;
then&lt;br /&gt;
  rm $SQMFILE&lt;br /&gt;
fi&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
go&lt;br /&gt;
delete from rs_throughput where sample_time &amp;lt;= dateadd(dd,-28,getdate())&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_insert_thruput_data()&lt;br /&gt;
{&lt;br /&gt;
# 1) get current segment usage/progress info&lt;br /&gt;
#connect to repserver, get sqm info - put into file&lt;br /&gt;
$RISQLCMD &amp;lt;&amp;lt; eof &amp;gt; $SQMFILE&lt;br /&gt;
admin who,sqm&lt;br /&gt;
go&lt;br /&gt;
quit&lt;br /&gt;
eof&lt;br /&gt;
&lt;br /&gt;
# 2) insert new segment data into rs_throughput table&lt;br /&gt;
#date&lt;br /&gt;
#echo &amp;quot;Queue Name, First segment, Last segment, Next segment&amp;quot;&lt;br /&gt;
cat $SQMFILE | egrep $insert_filter | sed 's/Awaiting Message/AwaitingMessage/; s/Awaiting Wakeup/AwaitingWakeup/; s/\(\.[0-9][0-&lt;br /&gt;
&lt;br /&gt;
9]*\)\.[0-9]/\1/' | grep -v &amp;quot;:0 ${primary_ds}&amp;quot; | awk '{print $4,$14,$15,$16}' | while read q_name first_seg last_seg next_seg&lt;br /&gt;
do&lt;br /&gt;
  q_size=$(bcalc &amp;quot;$last_seg - $first_seg&amp;quot;)&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
go&lt;br /&gt;
declare @mb_processed numeric(8,2)&lt;br /&gt;
declare @prev_sample datetime&lt;br /&gt;
declare @mins numeric(8,2)&lt;br /&gt;
declare @tput numeric(8,2)&lt;br /&gt;
if not exists (select 1 from rs_throughput where q_name = &amp;quot;${q_name}&amp;quot;)&lt;br /&gt;
insert rs_throughput values (&amp;quot;${q_name}&amp;quot;, getdate(), ${first_seg}, ${last_seg}, ${next_seg}, ${q_size}, 0, 0)&lt;br /&gt;
else&lt;br /&gt;
begin&lt;br /&gt;
-- get previous sample_time as key&lt;br /&gt;
select @prev_sample = max(sample_time) from rs_throughput where q_name = &amp;quot;${q_name}&amp;quot;&lt;br /&gt;
-- get difference in mb between current next segment and previous next segment&lt;br /&gt;
select @mb_processed = (select ${next_seg} - next from rs_throughput where sample_time = @prev_sample and q_name = &amp;quot;${q_name}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
select @prev_sample=dateadd(ss,-10,@prev_sample) -- # must substract 10 seconds to ensure the next datediff doesn't reflect 2m 58s &lt;br /&gt;
&lt;br /&gt;
as only 2mins!&lt;br /&gt;
select @mins = datediff(mi,@prev_sample,getdate())&lt;br /&gt;
if @mins &amp;gt; 0&lt;br /&gt;
begin&lt;br /&gt;
  select @tput = round((@mb_processed / @mins),2)&lt;br /&gt;
  insert rs_throughput values (&amp;quot;${q_name}&amp;quot;, getdate(), ${first_seg}, ${last_seg}, ${next_seg}, ${q_size}, @mb_processed, @tput)&lt;br /&gt;
end&lt;br /&gt;
end&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_report_thruput()&lt;br /&gt;
{&lt;br /&gt;
if [[ $option1 = [0-9]* ]]&lt;br /&gt;
then&lt;br /&gt;
  option2=$option1&lt;br /&gt;
  option1=&amp;quot;all&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if ! [[ &amp;quot;$option1&amp;quot; = &amp;quot;all&amp;quot; ]]&lt;br /&gt;
then&lt;br /&gt;
  q_list=$option1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
printf &amp;quot; -------------------------------------\n&amp;quot;&lt;br /&gt;
printf &amp;quot; Run date $DATE\n&amp;quot;&lt;br /&gt;
printf &amp;quot; -------------------------------------\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
for q_name in $q_list&lt;br /&gt;
do&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @mb_avg numeric(8,2)&lt;br /&gt;
declare @size numeric(8,2)&lt;br /&gt;
declare @eta datetime&lt;br /&gt;
select convert(char(19),sample_time) sample_time, q_name, size q_size, mb_processed, thruput &amp;quot;thruput (mb/min)&amp;quot;  from rs_throughput&lt;br /&gt;
--select convert(char(19),sample_time) sample_time, q_name, size q_size, mb_processed, thruput &amp;quot;thruput (mb/min)&amp;quot;, dateadd(mi,&lt;br /&gt;
&lt;br /&gt;
(round((size/thruput),0)),getdate()) ETA from rs_throughput&lt;br /&gt;
where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name like &amp;quot;%${q_name}%&amp;quot;&lt;br /&gt;
&lt;br /&gt;
--get mb average&lt;br /&gt;
select @mb_avg = convert(numeric(8,2),avg(thruput)) from rs_throughput&lt;br /&gt;
where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name like &amp;quot;%${q_name}%&amp;quot;&lt;br /&gt;
--get current queue size&lt;br /&gt;
select @size = size from rs_throughput where q_name like &amp;quot;%${q_name}%&amp;quot; having sample_time=max(sample_time)&lt;br /&gt;
select @eta = dateadd(mi,round((@size/@mb_avg),0),getdate())&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
print &amp;quot; Average for ${q_name}: %1! mb/min,  Re-sync ETA: %2!&amp;quot;, @mb_avg, @eta&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_help_text()&lt;br /&gt;
{&lt;br /&gt;
printf &amp;quot;Usage examples:\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh (runs with default values showing all queues over 15 minutes)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh &amp;lt;q_name&amp;gt;|&amp;lt;minutes&amp;gt;\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh &amp;lt;q_name&amp;gt; &amp;lt;minutes&amp;gt;\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh size|queue (shows current queue sizes)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh max (shows highest ever throughput for queue history)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh help (shows this helptext)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh insert # this is for cron only (inserts data to $RPT_DB..rs_throughput table)\n&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_max_thruput()&lt;br /&gt;
{&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
set rowcount 0&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @q_name char(22)&lt;br /&gt;
declare @sample_time datetime&lt;br /&gt;
declare @max_thruput numeric(8,2)&lt;br /&gt;
select q_name, sample_time, thruput into #throughput from rs_throughput where 1=0&lt;br /&gt;
print &amp;quot;Maximum throughput per queue:&amp;quot;&lt;br /&gt;
-- get list of queues&lt;br /&gt;
select distinct q_name, 0 as processed into #queues from rs_throughput&lt;br /&gt;
set rowcount 1&lt;br /&gt;
select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
while @@rowcount != 0&lt;br /&gt;
begin&lt;br /&gt;
  insert #throughput select q_name, sample_time, thruput from rs_throughput&lt;br /&gt;
  where sample_time in&lt;br /&gt;
    (select sample_time from rs_throughput where q_name = @q_name having thruput = max(thruput))&lt;br /&gt;
  and q_name = @q_name&lt;br /&gt;
  update #queues set processed = 1 where q_name = @q_name&lt;br /&gt;
  select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
end&lt;br /&gt;
set rowcount 0&lt;br /&gt;
select * from #throughput order by thruput desc&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
echo&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_current_q_size()&lt;br /&gt;
{&lt;br /&gt;
$RISQLCMD &amp;lt;&amp;lt; eof &amp;gt; $SQMFILE&lt;br /&gt;
admin who,sqm&lt;br /&gt;
go&lt;br /&gt;
quit&lt;br /&gt;
eof&lt;br /&gt;
printf &amp;quot;Current Stable Queue usage:\n&amp;quot;&lt;br /&gt;
cat $SQMFILE | egrep $insert_filter | sed 's/Awaiting Message/AwaitingMessage/; s/Awaiting Wakeup/AwaitingWakeup/; s/\(\.[0-9][0-&lt;br /&gt;
&lt;br /&gt;
9]*\)\.[0-9]/\1/' | grep -v &amp;quot;:0 ${primary_ds}&amp;quot; | awk '{print $4,$14,$15,$16}' | while read q_name first_seg last_seg next_seg&lt;br /&gt;
do&lt;br /&gt;
  q_size=$(bcalc &amp;quot;$last_seg - $first_seg&amp;quot;)&lt;br /&gt;
  printf &amp;quot;$q_name: $q_size\n&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_combined_avg_thruput()&lt;br /&gt;
{&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set rowcount 0&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @q_name varchar(25)&lt;br /&gt;
declare @mb_avg numeric(8,2)&lt;br /&gt;
declare @mb_combined_avg numeric(8,2)&lt;br /&gt;
select @mb_combined_avg=0&lt;br /&gt;
-- get list of queues&lt;br /&gt;
&lt;br /&gt;
select distinct q_name, 0 as processed into #queues from rs_throughput&lt;br /&gt;
set rowcount 1&lt;br /&gt;
select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
while @@rowcount != 0&lt;br /&gt;
begin&lt;br /&gt;
  select @mb_avg = convert(numeric(8,2),avg(thruput)) from rs_throughput&lt;br /&gt;
  where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name = @q_name&lt;br /&gt;
  select @mb_combined_avg = @mb_combined_avg + @mb_avg&lt;br /&gt;
  update #queues set processed=1 where q_name = @q_name&lt;br /&gt;
  select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
end&lt;br /&gt;
print &amp;quot; Combined thruput average: %1! mb/min&amp;quot;, @mb_combined_avg&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                             main program                                   #&lt;br /&gt;
##############################################################################&lt;br /&gt;
&lt;br /&gt;
check_previous_instance&lt;br /&gt;
fn_checkusage&lt;br /&gt;
&lt;br /&gt;
case &amp;quot;$option1&amp;quot; in&lt;br /&gt;
        help) fn_show_help_text;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
      insert) fn_insert_thruput_data;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
         max) fn_show_max_thruput;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
       queue|size) fn_show_current_q_size;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
           *) fn_report_thruput;&lt;br /&gt;
              fn_show_combined_avg_thruput;;&lt;br /&gt;
esac&lt;br /&gt;
&lt;br /&gt;
fn_housekeeping&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
### TABLE DEFINTION FOR RAW DATA COLLECTION&lt;br /&gt;
### Use the table definition below to create the table which this script &lt;br /&gt;
### requires in order to insert queue data and furthermore query this&lt;br /&gt;
### data in order to provide throughput information.&lt;br /&gt;
#create table rs_throughput (&lt;br /&gt;
#q_name varchar(25), &lt;br /&gt;
#sample_time datetime, &lt;br /&gt;
#first numeric(8,2), &lt;br /&gt;
#last numeric(8,2), &lt;br /&gt;
#next numeric(8,2), &lt;br /&gt;
#size numeric(8,2), &lt;br /&gt;
#mb_processed numeric(8,2),&lt;br /&gt;
#thruput numeric(8,2)&lt;br /&gt;
#)&lt;br /&gt;
&lt;br /&gt;
# end program&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:RepServer]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=RepServer_Throughput_Script&amp;diff=1851</id>
		<title>RepServer Throughput Script</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=RepServer_Throughput_Script&amp;diff=1851"/>
				<updated>2009-02-20T00:04:57Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: Initial version.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to know just how much data repserver is processing, then this is the tool.&amp;lt;br&amp;gt;&lt;br /&gt;
This script will tell you:&amp;lt;br&amp;gt;&lt;br /&gt;
o average throughput per queue (mb per minute)&amp;lt;br&amp;gt;&lt;br /&gt;
o average throughput combined (all queues)&amp;lt;br&amp;gt;&lt;br /&gt;
o estimated time for a replicate to catch up&amp;lt;br&amp;gt;&lt;br /&gt;
o current queue sizes&amp;lt;br&amp;gt;&lt;br /&gt;
There is also a maximum recorded throughput option but this appears not to work well as some of the figures have been suspicious.&amp;lt;br&amp;gt;&lt;br /&gt;
The real maximum throughput can be established by noting when the replicates start to fall behind in conjunction with the current throughput figures.&amp;lt;br&amp;gt;&lt;br /&gt;
This script can be particularly useful in helping to ascertain if you need to throw more CPU at your repserver box.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/ksh&lt;br /&gt;
#&lt;br /&gt;
# Script: rs_throughput.sh&lt;br /&gt;
# Author: Bob Holmes - email: cambob@gmail.com&lt;br /&gt;
# Date  : 19/09/08&lt;br /&gt;
# Version : 1.0&lt;br /&gt;
# Usage : Run &amp;quot;rs_throughput.sh help&amp;quot; for full usage information.&lt;br /&gt;
# Description : This script enables monitoring and reporting&lt;br /&gt;
#               of repserver throughput.&lt;br /&gt;
# --------------------------&lt;br /&gt;
#    ***    Variables for customisation can be found by searching for &amp;quot;!!&amp;quot; ***&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Modification history:&lt;br /&gt;
# 19/02/09 : Bob Holmes : Script modified to enable easier customisation prior&lt;br /&gt;
#                         to release on Sybase wiki. (modification not tested)&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Comments: This script relies on the reporting..rs_throughput table for data&lt;br /&gt;
#           collection and reporting.  The definition for this table can be&lt;br /&gt;
#           found at the end of this script. &lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           setup environment                                #&lt;br /&gt;
##############################################################################&lt;br /&gt;
#&lt;br /&gt;
# save input variables&lt;br /&gt;
if ! [[ -z $1 ]]&lt;br /&gt;
then&lt;br /&gt;
  export option1=$1&lt;br /&gt;
else&lt;br /&gt;
  export option1=&amp;quot;all&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if ! [[ -z $2 ]]&lt;br /&gt;
then&lt;br /&gt;
  export option2=$2&lt;br /&gt;
else&lt;br /&gt;
  export option2=&amp;quot;15&amp;quot; # default number of minutes on which to report throughput&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# configure environment&lt;br /&gt;
HOSTNAME=`hostname`&lt;br /&gt;
. $HOME/admin/.syb_cfg.sh $HOSTNAME  # !! This line sets up the environment from&lt;br /&gt;
                                     # !! from an external shell script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           config variables                                 #&lt;br /&gt;
##############################################################################&lt;br /&gt;
# config:&lt;br /&gt;
primary_ds=&amp;quot;prim_ds&amp;quot;                   # !! string used to identify the inbound queue&lt;br /&gt;
# queues to query on:-&lt;br /&gt;
q_list=&amp;quot;prim_ds.db1 prim_ds.db2 replicate_ds.db1 replicate_ds.db2&amp;quot; # !!&lt;br /&gt;
insert_filter=&amp;quot;db1 db2&amp;quot;                # !! data will only be collected for queue names which have this keyword in&lt;br /&gt;
REP_SRV=&amp;quot;repsrv_rs&amp;quot;                    # !! the actual repserver from which to get sqm info&lt;br /&gt;
RPT_SRV=&amp;quot;reporting_ds&amp;quot;                 # !! dataserver which manages the reporting database&lt;br /&gt;
RPT_DB=&amp;quot;reporting&amp;quot;                     # !! reporting database name&lt;br /&gt;
RECIPIENTS=&amp;quot;user@domain&amp;quot;               # !! email config (separate addresses with commas)&lt;br /&gt;
ADMINDIR=&amp;quot;/opt/home/sybase/admin&amp;quot;      # !! sybase admin directory&lt;br /&gt;
&lt;br /&gt;
# static:&lt;br /&gt;
SQMFILE=&amp;quot;$ADMINDIR/rs_sqm_tmp1.tmp&amp;quot;&lt;br /&gt;
DATE=$(date &amp;quot;+%d/%m/%y %H:%M:%S&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# config aware environment variables: # !! You may need to replace the line below with the equivalent&lt;br /&gt;
                                      # !! for your own environment. &lt;br /&gt;
RISQLCMD=&amp;quot;isql -Usa -P`grep &amp;quot;$REP_SRV,&amp;quot; $HOME/admin/.servers | cut  -d , -f 4` -S$rep_server -w1000&amp;quot;&lt;br /&gt;
ISQLCMD=&amp;quot;isql -Usa -P${SYBPASS} -S${RPT_SRV} -w200 -D${RPT_DB}&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                             functions                                      #&lt;br /&gt;
##############################################################################&lt;br /&gt;
&lt;br /&gt;
check_previous_instance()&lt;br /&gt;
{&lt;br /&gt;
# Note: next line greps for 8 instances as tests proved that less could cause the script to exit incorrectly&lt;br /&gt;
if [ $(ps -ef | grep rs_throughput | egrep -v &amp;quot;vi|grep&amp;quot; | grep -v &amp;quot;sh -c&amp;quot; | wc -l | awk '{print $1}') -gt 8 ]&lt;br /&gt;
then&lt;br /&gt;
  # previous instance still running - probably hanging&lt;br /&gt;
  echo Previous instance still running.&lt;br /&gt;
  exit&lt;br /&gt;
fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_checkusage()&lt;br /&gt;
{&lt;br /&gt;
if [[ -z $option1 ]]&lt;br /&gt;
then&lt;br /&gt;
  printf &amp;quot; Usage: ./rs_throughput.sh &amp;lt;all&amp;gt;|&amp;lt;q_name&amp;gt;|&amp;lt;help&amp;gt; [&amp;lt;minutes to display&amp;gt;]\n&amp;quot;&lt;br /&gt;
  exit&lt;br /&gt;
fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bcalc()&lt;br /&gt;
{&lt;br /&gt;
awk 'BEGIN{EQUATION='&amp;quot;$*&amp;quot;';printf(&amp;quot;%0.1f\n&amp;quot;,EQUATION); exit}'&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_housekeeping()&lt;br /&gt;
{&lt;br /&gt;
if [ -e $SQMFILE ]&lt;br /&gt;
then&lt;br /&gt;
  rm $SQMFILE&lt;br /&gt;
fi&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
go&lt;br /&gt;
delete from rs_throughput where sample_time &amp;lt;= dateadd(dd,-28,getdate())&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_insert_thruput_data()&lt;br /&gt;
{&lt;br /&gt;
# 1) get current segment usage/progress info&lt;br /&gt;
#connect to repserver, get sqm info - put into file&lt;br /&gt;
$RISQLCMD &amp;lt;&amp;lt; eof &amp;gt; $SQMFILE&lt;br /&gt;
admin who,sqm&lt;br /&gt;
go&lt;br /&gt;
quit&lt;br /&gt;
eof&lt;br /&gt;
&lt;br /&gt;
# 2) insert new segment data into rs_throughput table&lt;br /&gt;
#date&lt;br /&gt;
#echo &amp;quot;Queue Name, First segment, Last segment, Next segment&amp;quot;&lt;br /&gt;
cat $SQMFILE | egrep $insert_filter | sed 's/Awaiting Message/AwaitingMessage/; s/Awaiting Wakeup/AwaitingWakeup/; s/\(\.[0-9][0-&lt;br /&gt;
&lt;br /&gt;
9]*\)\.[0-9]/\1/' | grep -v &amp;quot;:0 ${primary_ds}&amp;quot; | awk '{print $4,$14,$15,$16}' | while read q_name first_seg last_seg next_seg&lt;br /&gt;
do&lt;br /&gt;
  q_size=$(bcalc &amp;quot;$last_seg - $first_seg&amp;quot;)&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
go&lt;br /&gt;
declare @mb_processed numeric(8,2)&lt;br /&gt;
declare @prev_sample datetime&lt;br /&gt;
declare @mins numeric(8,2)&lt;br /&gt;
declare @tput numeric(8,2)&lt;br /&gt;
if not exists (select 1 from rs_throughput where q_name = &amp;quot;${q_name}&amp;quot;)&lt;br /&gt;
insert rs_throughput values (&amp;quot;${q_name}&amp;quot;, getdate(), ${first_seg}, ${last_seg}, ${next_seg}, ${q_size}, 0, 0)&lt;br /&gt;
else&lt;br /&gt;
begin&lt;br /&gt;
-- get previous sample_time as key&lt;br /&gt;
select @prev_sample = max(sample_time) from rs_throughput where q_name = &amp;quot;${q_name}&amp;quot;&lt;br /&gt;
-- get difference in mb between current next segment and previous next segment&lt;br /&gt;
select @mb_processed = (select ${next_seg} - next from rs_throughput where sample_time = @prev_sample and q_name = &amp;quot;${q_name}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
select @prev_sample=dateadd(ss,-10,@prev_sample) -- # must substract 10 seconds to ensure the next datediff doesn't reflect 2m 58s &lt;br /&gt;
&lt;br /&gt;
as only 2mins!&lt;br /&gt;
select @mins = datediff(mi,@prev_sample,getdate())&lt;br /&gt;
if @mins &amp;gt; 0&lt;br /&gt;
begin&lt;br /&gt;
  select @tput = round((@mb_processed / @mins),2)&lt;br /&gt;
  insert rs_throughput values (&amp;quot;${q_name}&amp;quot;, getdate(), ${first_seg}, ${last_seg}, ${next_seg}, ${q_size}, @mb_processed, @tput)&lt;br /&gt;
end&lt;br /&gt;
end&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_report_thruput()&lt;br /&gt;
{&lt;br /&gt;
if [[ $option1 = [0-9]* ]]&lt;br /&gt;
then&lt;br /&gt;
  option2=$option1&lt;br /&gt;
  option1=&amp;quot;all&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if ! [[ &amp;quot;$option1&amp;quot; = &amp;quot;all&amp;quot; ]]&lt;br /&gt;
then&lt;br /&gt;
  q_list=$option1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
printf &amp;quot; -------------------------------------\n&amp;quot;&lt;br /&gt;
printf &amp;quot; Run date $DATE\n&amp;quot;&lt;br /&gt;
printf &amp;quot; -------------------------------------\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
for q_name in $q_list&lt;br /&gt;
do&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @mb_avg numeric(8,2)&lt;br /&gt;
declare @size numeric(8,2)&lt;br /&gt;
declare @eta datetime&lt;br /&gt;
select convert(char(19),sample_time) sample_time, q_name, size q_size, mb_processed, thruput &amp;quot;thruput (mb/min)&amp;quot;  from rs_throughput&lt;br /&gt;
--select convert(char(19),sample_time) sample_time, q_name, size q_size, mb_processed, thruput &amp;quot;thruput (mb/min)&amp;quot;, dateadd(mi,&lt;br /&gt;
&lt;br /&gt;
(round((size/thruput),0)),getdate()) ETA from rs_throughput&lt;br /&gt;
where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name like &amp;quot;%${q_name}%&amp;quot;&lt;br /&gt;
&lt;br /&gt;
--get mb average&lt;br /&gt;
select @mb_avg = convert(numeric(8,2),avg(thruput)) from rs_throughput&lt;br /&gt;
where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name like &amp;quot;%${q_name}%&amp;quot;&lt;br /&gt;
--get current queue size&lt;br /&gt;
select @size = size from rs_throughput where q_name like &amp;quot;%${q_name}%&amp;quot; having sample_time=max(sample_time)&lt;br /&gt;
select @eta = dateadd(mi,round((@size/@mb_avg),0),getdate())&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
print &amp;quot; Average for ${q_name}: %1! mb/min,  Re-sync ETA: %2!&amp;quot;, @mb_avg, @eta&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_help_text()&lt;br /&gt;
{&lt;br /&gt;
printf &amp;quot;Usage examples:\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh (runs with default values showing all queues over 15 minutes)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh &amp;lt;q_name&amp;gt;|&amp;lt;minutes&amp;gt;\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh &amp;lt;q_name&amp;gt; &amp;lt;minutes&amp;gt;\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh size|queue (shows current queue sizes)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh max (shows highest ever throughput for queue history)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh help (shows this helptext)\n&amp;quot;&lt;br /&gt;
printf &amp;quot;rs_throughput.sh insert # this is for cron only (inserts data to $RPT_DB..rs_throughput table)\n&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_max_thruput()&lt;br /&gt;
{&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
set rowcount 0&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @q_name char(22)&lt;br /&gt;
declare @sample_time datetime&lt;br /&gt;
declare @max_thruput numeric(8,2)&lt;br /&gt;
select q_name, sample_time, thruput into #throughput from rs_throughput where 1=0&lt;br /&gt;
print &amp;quot;Maximum throughput per queue:&amp;quot;&lt;br /&gt;
-- get list of queues&lt;br /&gt;
select distinct q_name, 0 as processed into #queues from rs_throughput&lt;br /&gt;
set rowcount 1&lt;br /&gt;
select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
while @@rowcount != 0&lt;br /&gt;
begin&lt;br /&gt;
  insert #throughput select q_name, sample_time, thruput from rs_throughput&lt;br /&gt;
  where sample_time in&lt;br /&gt;
    (select sample_time from rs_throughput where q_name = @q_name having thruput = max(thruput))&lt;br /&gt;
  and q_name = @q_name&lt;br /&gt;
  update #queues set processed = 1 where q_name = @q_name&lt;br /&gt;
  select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
end&lt;br /&gt;
set rowcount 0&lt;br /&gt;
select * from #throughput order by thruput desc&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
echo&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_current_q_size()&lt;br /&gt;
{&lt;br /&gt;
$RISQLCMD &amp;lt;&amp;lt; eof &amp;gt; $SQMFILE&lt;br /&gt;
admin who,sqm&lt;br /&gt;
go&lt;br /&gt;
quit&lt;br /&gt;
eof&lt;br /&gt;
printf &amp;quot;Current Stable Queue usage:\n&amp;quot;&lt;br /&gt;
cat $SQMFILE | egrep $insert_filter | sed 's/Awaiting Message/AwaitingMessage/; s/Awaiting Wakeup/AwaitingWakeup/; s/\(\.[0-9][0-&lt;br /&gt;
&lt;br /&gt;
9]*\)\.[0-9]/\1/' | grep -v &amp;quot;:0 ${primary_ds}&amp;quot; | awk '{print $4,$14,$15,$16}' | while read q_name first_seg last_seg next_seg&lt;br /&gt;
do&lt;br /&gt;
  q_size=$(bcalc &amp;quot;$last_seg - $first_seg&amp;quot;)&lt;br /&gt;
  printf &amp;quot;$q_name: $q_size\n&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn_show_combined_avg_thruput()&lt;br /&gt;
{&lt;br /&gt;
$ISQLCMD &amp;lt;&amp;lt;-EOF&lt;br /&gt;
set rowcount 0&lt;br /&gt;
set nocount on&lt;br /&gt;
declare @q_name varchar(25)&lt;br /&gt;
declare @mb_avg numeric(8,2)&lt;br /&gt;
declare @mb_combined_avg numeric(8,2)&lt;br /&gt;
select @mb_combined_avg=0&lt;br /&gt;
-- get list of queues&lt;br /&gt;
&lt;br /&gt;
select distinct q_name, 0 as processed into #queues from rs_throughput&lt;br /&gt;
set rowcount 1&lt;br /&gt;
select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
while @@rowcount != 0&lt;br /&gt;
begin&lt;br /&gt;
  select @mb_avg = convert(numeric(8,2),avg(thruput)) from rs_throughput&lt;br /&gt;
  where sample_time &amp;gt;= dateadd(mi,-${option2},getdate()) and q_name = @q_name&lt;br /&gt;
  select @mb_combined_avg = @mb_combined_avg + @mb_avg&lt;br /&gt;
  update #queues set processed=1 where q_name = @q_name&lt;br /&gt;
  select @q_name=q_name from #queues where processed = 0&lt;br /&gt;
end&lt;br /&gt;
print &amp;quot; Combined thruput average: %1! mb/min&amp;quot;, @mb_combined_avg&lt;br /&gt;
print &amp;quot;&amp;quot;&lt;br /&gt;
go&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                             main program                                   #&lt;br /&gt;
##############################################################################&lt;br /&gt;
&lt;br /&gt;
check_previous_instance&lt;br /&gt;
fn_checkusage&lt;br /&gt;
&lt;br /&gt;
case &amp;quot;$option1&amp;quot; in&lt;br /&gt;
        help) fn_show_help_text;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
      insert) fn_insert_thruput_data;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
         max) fn_show_max_thruput;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
       queue|size) fn_show_current_q_size;&lt;br /&gt;
              exit;;&lt;br /&gt;
&lt;br /&gt;
           *) fn_report_thruput;&lt;br /&gt;
              fn_show_combined_avg_thruput;;&lt;br /&gt;
esac&lt;br /&gt;
&lt;br /&gt;
fn_housekeeping&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
### TABLE DEFINTION FOR RAW DATA COLLECTION&lt;br /&gt;
### Use the table definition below to create the table which this script &lt;br /&gt;
### requires in order to insert queue data and furthermore query this&lt;br /&gt;
### data in order to provide throughput information.&lt;br /&gt;
#create table rs_throughput (&lt;br /&gt;
#q_name varchar(25), &lt;br /&gt;
#sample_time datetime, &lt;br /&gt;
#first numeric(8,2), &lt;br /&gt;
#last numeric(8,2), &lt;br /&gt;
#next numeric(8,2), &lt;br /&gt;
#size numeric(8,2), &lt;br /&gt;
#mb_processed numeric(8,2),&lt;br /&gt;
#thruput numeric(8,2)&lt;br /&gt;
#)&lt;br /&gt;
&lt;br /&gt;
# end program&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:RepServer]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=Sp_capture_sql--Capture_sql_of_an_active_spid&amp;diff=1845</id>
		<title>Sp capture sql--Capture sql of an active spid</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=Sp_capture_sql--Capture_sql_of_an_active_spid&amp;diff=1845"/>
				<updated>2009-02-19T18:05:15Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: Initial version.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: This SP uses the MDA tables.&amp;lt;br&amp;gt;&lt;br /&gt;
This SP is for capturing the SQL of any active spid. If a spid is not currently processing then nothing will be returned.&lt;br /&gt;
Usage: sp__capture_sql [spid]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
create procedure sp__capture_sql&lt;br /&gt;
(&lt;br /&gt;
@spid int = null&lt;br /&gt;
)&lt;br /&gt;
as&lt;br /&gt;
------------------------------&lt;br /&gt;
-- Procedure: sp__capture_sql&lt;br /&gt;
--   Created: April 2008&lt;br /&gt;
--    Author: Bob Holmes (Email: cambob@gmail.com)&lt;br /&gt;
--     Usage: sp__capture_sql [spid]&lt;br /&gt;
------------------------------&lt;br /&gt;
if @spid = null&lt;br /&gt;
begin&lt;br /&gt;
   select p.spid, suser_name(p.suid), t.SQLText&lt;br /&gt;
   from master..monProcessStatement s, master..monProcessSQLText t, master..sysprocesses p&lt;br /&gt;
   where s.SPID = t.SPID&lt;br /&gt;
   and t.SPID = p.spid&lt;br /&gt;
   and p.spid &amp;lt;&amp;gt; @@spid&lt;br /&gt;
   and suser_name(suid) &amp;lt;&amp;gt; &amp;quot;sa&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
else&lt;br /&gt;
begin&lt;br /&gt;
   select t.SQLText&lt;br /&gt;
   from master..monProcessStatement s, master..monProcessSQLText t, master..sysprocesses p&lt;br /&gt;
   where p.spid = @spid&lt;br /&gt;
   and s.SPID = t.SPID&lt;br /&gt;
   and t.SPID = p.spid&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[Category:ASE]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=Sp_mon_sql2--ASE_spid_activity_monitor&amp;diff=1844</id>
		<title>Sp mon sql2--ASE spid activity monitor</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=Sp_mon_sql2--ASE_spid_activity_monitor&amp;diff=1844"/>
				<updated>2009-02-19T17:53:39Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: This SP uses the MDA tables.&amp;lt;BR&amp;gt;&lt;br /&gt;
This sp is for getting a clear list of currently active spids with full details including login, db, blocking spid, processing time, query start time, cpu usage, logical and physical i/o, currently executing command etc.  To maximise clarity, all info is displayed on one line for each spid.  Alternate info is also available by running with '1' (without quotes) which includes, login time, host process, originating host and other information which may be useful for tracking down the source of a problem external to ASE.  Note, unfortunately the '1' option was a quick hack - the sp needs modifying to change this to a 'x' or something similar as the sp can also be called with &amp;lt;spid&amp;gt; to investigate a spid which is not currently active.&lt;br /&gt;
&lt;br /&gt;
Usage summary:&amp;lt;BR&amp;gt;&lt;br /&gt;
sp__mon_sql2&amp;lt;BR&amp;gt;&lt;br /&gt;
sp__mon_sql2 &amp;lt;spid&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
sp__mon_sql2 1  (due to the quick hack noted above, if you want to investigate spid 1, you can't! sorry - I'll fix it in the next version. Luckily the need to investigate spid 1 is quite rare.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
create procedure sp__mon_sql2&lt;br /&gt;
(&lt;br /&gt;
@spid int = 0&lt;br /&gt;
)&lt;br /&gt;
as&lt;br /&gt;
------------------------------&lt;br /&gt;
-- Procedure: sp__mon_sql2&lt;br /&gt;
--   Created: April 2008&lt;br /&gt;
--    Author: Bob Holmes (Email: cambob@gmail.com)&lt;br /&gt;
--     Usage: sp__mon_sql2 [spid]&lt;br /&gt;
-- Last modification: bobh - if 1 is specified as the spid number then alternate info is returned (dirty hack)&lt;br /&gt;
------------------------------&lt;br /&gt;
-- INFO:&lt;br /&gt;
-- The three *'s are a grep key for a shell script to use to extract the lines needed for alerting.&lt;br /&gt;
------------------------------&lt;br /&gt;
--part 1 - snapshot&lt;br /&gt;
set forceplan on&lt;br /&gt;
select 	s.StartTime, &lt;br /&gt;
	convert(smallint,(datediff(mi,StartTime,getdate()))) Dmins,  &lt;br /&gt;
	p.spid, &lt;br /&gt;
	p.hostname, &lt;br /&gt;
	p.suid, &lt;br /&gt;
	p.dbid, &lt;br /&gt;
	p.cmd, &lt;br /&gt;
        p.blocked,&lt;br /&gt;
	s.CpuTime, &lt;br /&gt;
	s.LogicalReads, &lt;br /&gt;
	s.PhysicalReads,&lt;br /&gt;
	p.status, &lt;br /&gt;
	p.loggedindatetime,&lt;br /&gt;
	p.program_name, &lt;br /&gt;
	l.ClientOSPID, &lt;br /&gt;
	p.time_blocked, &lt;br /&gt;
	p.ipaddr&lt;br /&gt;
into #processmon2&lt;br /&gt;
from master..sysprocesses p, master..monProcessStatement s, master..monProcessLookup l&lt;br /&gt;
where p.spid != @@spid&lt;br /&gt;
and p.spid *= s.SPID&lt;br /&gt;
and l.SPID = p.spid&lt;br /&gt;
and suid &amp;lt;&amp;gt; 0&lt;br /&gt;
order by p.spid&lt;br /&gt;
set forceplan off&lt;br /&gt;
&lt;br /&gt;
--part 2 --display spid summaries&lt;br /&gt;
&lt;br /&gt;
if @spid=0&lt;br /&gt;
begin&lt;br /&gt;
-- display header information for multiple spids&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;Process Summary (Order by Dmins, CpuTime, LogicalReads, PhysicalReads Desc )&amp;quot;&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;&amp;quot;&lt;br /&gt;
  select distinct &amp;quot;***&amp;quot;,&lt;br /&gt;
  spid Spid,&lt;br /&gt;
  convert(char(12),suser_name(suid)) Login,&lt;br /&gt;
  convert(char(16),db_name(dbid)) DB,&lt;br /&gt;
  (case hostname when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),hostname) end) Hostname,&lt;br /&gt;
  blocked,&lt;br /&gt;
  convert(varchar(19),StartTime) StartTime,&lt;br /&gt;
  Dmins,&lt;br /&gt;
  right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins/60)),2) + &amp;quot;:&amp;quot; + right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins%60)),2) Dtime,&lt;br /&gt;
  CpuTime,&lt;br /&gt;
  LogicalReads,&lt;br /&gt;
  PhysicalReads,&lt;br /&gt;
  cmd Command&lt;br /&gt;
  from #processmon2&lt;br /&gt;
  where cmd &amp;lt;&amp;gt; &amp;quot;AWAITING COMMAND&amp;quot;&lt;br /&gt;
  order by Dmins desc, CpuTime Desc, LogicalReads Desc, PhysicalReads Desc&lt;br /&gt;
end&lt;br /&gt;
else if @spid=1&lt;br /&gt;
begin&lt;br /&gt;
-- display header information for multiple spids&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;Process Summary (Order by Dmins, CpuTime, LogicalReads, PhysicalReads Desc )&amp;quot;&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;&amp;quot;&lt;br /&gt;
select &lt;br /&gt;
  spid Spid,&lt;br /&gt;
  convert(char(12),suser_name(suid)) Login,&lt;br /&gt;
  convert(char(15),db_name(dbid)) DB,&lt;br /&gt;
  (case hostname when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),hostname) end) Hostname,&lt;br /&gt;
  blocked,&lt;br /&gt;
  convert(varchar(19),StartTime) StartTime,&lt;br /&gt;
  Dmins,&lt;br /&gt;
  right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins/60)),2) + &amp;quot;:&amp;quot; + right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins%60)),2) Dtime,&lt;br /&gt;
  (case program_name when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),program_name) end) Application,&lt;br /&gt;
  (case ClientOSPID when NULL then &amp;quot;-&amp;quot; else convert(char(7),ClientOSPID) end) &amp;quot;OS PID&amp;quot;,&lt;br /&gt;
  time_blocked &amp;quot;Blocked(s)&amp;quot;,&lt;br /&gt;
  convert(char(8),loggedindatetime,108) &amp;quot;Logged in&amp;quot;,&lt;br /&gt;
  convert(char(15),ipaddr) ClientIP,&lt;br /&gt;
  cmd Command&lt;br /&gt;
  from #processmon2&lt;br /&gt;
  where cmd &amp;lt;&amp;gt; &amp;quot;AWAITING COMMAND&amp;quot;&lt;br /&gt;
  order by Dmins desc, CpuTime Desc, LogicalReads Desc, PhysicalReads Desc&lt;br /&gt;
end&lt;br /&gt;
else&lt;br /&gt;
begin&lt;br /&gt;
select distinct &amp;quot;***&amp;quot;,&lt;br /&gt;
  spid Spid,&lt;br /&gt;
  convert(char(12),suser_name(suid)) Login,&lt;br /&gt;
  convert(char(16),db_name(dbid)) DB,&lt;br /&gt;
  (case hostname when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),hostname) end) Hostname,&lt;br /&gt;
  convert(varchar(19),StartTime) StartTime,&lt;br /&gt;
  Dmins,&lt;br /&gt;
  blocked,&lt;br /&gt;
  right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins/60)),2) + &amp;quot;:&amp;quot; + right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins%60)),2) Dtime,&lt;br /&gt;
  CpuTime,&lt;br /&gt;
  LogicalReads,&lt;br /&gt;
  PhysicalReads,&lt;br /&gt;
  cmd Command&lt;br /&gt;
  from #processmon2&lt;br /&gt;
  where spid = @spid&lt;br /&gt;
  order by Dmins desc, CpuTime Desc, LogicalReads Desc, PhysicalReads Desc&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--select spid, convert(char(15),suser_name(suid)) user_name, &lt;br /&gt;
--convert(char(15),db_name(dbid)) dbname, status, &lt;br /&gt;
--convert(char(8),loggedindatetime,108) &amp;quot;logged in&amp;quot;,&lt;br /&gt;
--(case hostname when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else hostname end) hostname, &lt;br /&gt;
--(case program_name when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(15),program_name) end) application, &lt;br /&gt;
--(case ClientOSPID when NULL then &amp;quot;-&amp;quot; else convert(char(7),ClientOSPID) end) &amp;quot;OS Process&amp;quot;, blocked, time_blocked, ipaddr ClientIP, cmd  from --master..sysprocesses p, master..monProcessLookup l&lt;br /&gt;
--where l.SPID = p.spid&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:ASE]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=RepServer_Errorlog_checker&amp;diff=1843</id>
		<title>RepServer Errorlog checker</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=RepServer_Errorlog_checker&amp;diff=1843"/>
				<updated>2009-02-18T19:37:36Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The script below is for monitoring the repserver errorlog - it works with any version of repserver and does not need to write to the errorlog itself in order to monitor it.  However, since it doesn't write to the errorlog, it does need a $ADMINDIR/control_files/ directory which you may wish to create as a non-transient file (rserrlogmarker.dat) is maintained there.&lt;br /&gt;
Also, as per the script notes, you can easily modify this script to monitor *any* log; be sure to give rserrlogmarker.dat and the other files in the config section different names or keep them elsewhere so that there is no conflict.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/ksh&lt;br /&gt;
#&lt;br /&gt;
# Script: rs_log_checker.sh&lt;br /&gt;
# Author: Bob Holmes - email: cambob@gmail.com&lt;br /&gt;
# Date  : 08/05/2008&lt;br /&gt;
# Version: 1.1&lt;br /&gt;
# Usage : rs_log_checker.sh [v|V] (verbose mode)&lt;br /&gt;
# Description: Script for checking the repserver errorlog&lt;br /&gt;
# --------------------------&lt;br /&gt;
#    ***    Variables for customisation can be found by searching for &amp;quot;!!&amp;quot; ***&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Modification history:&lt;br /&gt;
#&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Enhancement notes:&lt;br /&gt;
# BobH: V1.0: Modified to re-create rserrlogmarker file if not found, then re-run automatically.&lt;br /&gt;
# BobH: V1.1: Updated for detecting a new log file and resetting rserrlogmarker if so.&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Comments: This script can easily be modified to monitor any log, including ASE.&lt;br /&gt;
#           The log itself is never written to so this script maintains a control&lt;br /&gt;
#           file to keep track of the last line it checked.&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           setup environment                                #&lt;br /&gt;
##############################################################################&lt;br /&gt;
HOSTNAME=`hostname`&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           config variables                                 #&lt;br /&gt;
##############################################################################&lt;br /&gt;
# config&lt;br /&gt;
RSLOGFILE=&amp;quot;/PATH_TO_ERRORLOG_HERE/servername_rs.log&amp;quot;        # !! modify for your environment&lt;br /&gt;
ADMINDIR=&amp;quot;/opt/home/sybase/admin&amp;quot;                           # !! modify for your environment&lt;br /&gt;
RSLOGMARKER=&amp;quot;$ADMINDIR/control_files/rserrlogmarker.dat&amp;quot;    # !! need $ADMINDIR/control_files/ directory&lt;br /&gt;
RECIPIENTS=&amp;quot;user@domain.dom&amp;quot;                                # !! enter email address config here &lt;br /&gt;
                                                            #   (separate with commas for multiple addresses)&lt;br /&gt;
# static&lt;br /&gt;
TEMPFILE1=&amp;quot;$ADMINDIR/rslogchecker1.tmp&amp;quot;                     # transient file&lt;br /&gt;
TEMPFILE2=&amp;quot;$ADMINDIR/rslogchecker2.tmp&amp;quot;                     # transient file&lt;br /&gt;
MAILFILE=&amp;quot;$ADMINDIR/rslogchecker.mail&amp;quot;                      # transient file&lt;br /&gt;
SCRIPT_NAME=`basename $0`&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                             main program                                   #&lt;br /&gt;
##############################################################################&lt;br /&gt;
&lt;br /&gt;
# check location of errorlog&lt;br /&gt;
if [ ! -f $RSLOGFILE ]&lt;br /&gt;
then&lt;br /&gt;
   echo RS errorlog file not found. Please check config.&lt;br /&gt;
   exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# get log marker value from file (or otherwise create it)&lt;br /&gt;
# V1.1: marker is now a line number&lt;br /&gt;
if [ ! -f $RSLOGMARKER ]&lt;br /&gt;
then&lt;br /&gt;
   MARKER=$(cat -n $RSLOGFILE | tail -1 | awk '{print $1}')&lt;br /&gt;
   echo $MARKER &amp;gt; $RSLOGMARKER&lt;br /&gt;
   #echo &amp;quot;rs log marker reset&amp;quot;&lt;br /&gt;
   $SCRIPT_NAME # must re-run after marker file reset&lt;br /&gt;
   exit&lt;br /&gt;
else&lt;br /&gt;
   MARKER=$(cat $RSLOGMARKER)&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# Compare number of lines in log file with current marker value to check&lt;br /&gt;
# if a new log has been created/repserver restarted.&lt;br /&gt;
if [ $(wc -l $RSLOGFILE | awk '{print $1}') -lt $MARKER ]&lt;br /&gt;
then&lt;br /&gt;
   # new log file created/repserver restarted&lt;br /&gt;
   printf &amp;quot;${SCRIPT_NAME}: New log file detected\n&amp;quot; &amp;gt; $TEMPFILE2&lt;br /&gt;
   RESTARTDT=$(head -1 $RSLOGFILE | awk '{print $2,$3}')&lt;br /&gt;
   printf &amp;quot;${SCRIPT_NAME}: Repserver restarted at: ${RESTARTDT}\n\n&amp;quot; &amp;gt;&amp;gt; $TEMPFILE2&lt;br /&gt;
   printf &amp;quot;Errors/Warnings from startup follow:\n&amp;quot; &amp;gt;&amp;gt; $TEMPFILE2&lt;br /&gt;
   printf &amp;quot;------------------------------------\n&amp;quot; &amp;gt;&amp;gt; $TEMPFILE2&lt;br /&gt;
   # pick out any errors/or warnings from log file:&lt;br /&gt;
   egrep &amp;quot;^E. |^W. &amp;quot; $RSLOGFILE &amp;gt;&amp;gt; $TEMPFILE2&lt;br /&gt;
   mailx -s &amp;quot;$HOSTNAME: Repserver restarted!&amp;quot; $RECIPIENTS &amp;lt; $TEMPFILE2&lt;br /&gt;
   rm $RSLOGMARKER # force reset of marker file&lt;br /&gt;
   rm $TEMPFILE2&lt;br /&gt;
   exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if [ &amp;quot;$1&amp;quot; = &amp;quot;V&amp;quot; ] || [ &amp;quot;$1&amp;quot; = &amp;quot;v&amp;quot; ] # verbose (diag) mode&lt;br /&gt;
then&lt;br /&gt;
  echo Current marker value is: $MARKER&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# increment the marker (line number) to avoid re-reading same last line&lt;br /&gt;
((MARKER=MARKER+1))&lt;br /&gt;
sed -n &amp;quot;$MARKER,$ p&amp;quot; $RSLOGFILE &amp;gt; $TEMPFILE1&lt;br /&gt;
######### next executable line checks for errors #########&lt;br /&gt;
######### add your search terms to the egrep below #######&lt;br /&gt;
EMSGS=$(egrep -c &amp;quot;^E\. |^W\. &amp;quot; $TEMPFILE1)&lt;br /&gt;
if [ $EMSGS -ne 0 ]&lt;br /&gt;
then&lt;br /&gt;
  if [ &amp;quot;$1&amp;quot; = &amp;quot;V&amp;quot; ] || [ &amp;quot;$1&amp;quot; = &amp;quot;v&amp;quot; ] # verbose (diag) mode&lt;br /&gt;
  then&lt;br /&gt;
     echo Error message found: $HOSTNAME: $EMSGS messages&lt;br /&gt;
     cat $TEMPFILE1&lt;br /&gt;
     echo END OF REPORT&lt;br /&gt;
  else&lt;br /&gt;
     cp $TEMPFILE1 $MAILFILE&lt;br /&gt;
     printf &amp;quot;-------CALLOUT SYBASE DBA - ON CALL----------------\n&amp;quot; &amp;gt;&amp;gt; $MAILFILE   # !! optional&lt;br /&gt;
     mailx -s &amp;quot;$HOSTNAME: $EMSGS errors found in repserver errorlog&amp;quot; $RECIPIENTS &amp;lt; $MAILFILE&lt;br /&gt;
  fi&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
#update marker:&lt;br /&gt;
# Note: use line count from TEMPFILE1 + (MARKER-1) to avoid re-scanning the whole errorlog;&lt;br /&gt;
# cat/cp'ing large log files can cause load issues so we don't do that!&lt;br /&gt;
LINECOUNT=$(wc -l $TEMPFILE1 | awk '{print $1}')&lt;br /&gt;
((MARKER=MARKER+LINECOUNT-1))&lt;br /&gt;
echo $MARKER &amp;gt; $RSLOGMARKER&lt;br /&gt;
if [ &amp;quot;$1&amp;quot; = &amp;quot;V&amp;quot; ] || [ &amp;quot;$1&amp;quot; = &amp;quot;v&amp;quot; ] # verbose (diag) mode&lt;br /&gt;
then&lt;br /&gt;
  echo New marker value is: $MARKER&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# housekeeping&lt;br /&gt;
if [ -e $TEMPFILE1 ]&lt;br /&gt;
then&lt;br /&gt;
  rm $TEMPFILE1&lt;br /&gt;
fi&lt;br /&gt;
if [ -e $TEMPFILE2 ]&lt;br /&gt;
then&lt;br /&gt;
  rm $TEMPFILE2&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
#end script&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:RepServer]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=RepServer_Errorlog_checker&amp;diff=1842</id>
		<title>RepServer Errorlog checker</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=RepServer_Errorlog_checker&amp;diff=1842"/>
				<updated>2009-02-18T19:35:27Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The script below is for monitoring the repserver errorlog - it works with any version of repserver and does not need to write to the errorlog itself in order to monitor it.  However, since it doesn't write to the errorlog, it does need a $ADMINDIR/control_files/ directory which you may wish to create as a non-transient file (rserrlogmarker.dat) is maintained there.&lt;br /&gt;
Also, as per the script notes, you can easily modify this script to monitor *any* log; be sure to give rserrlogmarker.dat and the other files in the config section different names or keep them elsewhere so that there is no conflict.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/ksh&lt;br /&gt;
#&lt;br /&gt;
# Script: rs_log_checker.sh&lt;br /&gt;
# Author: Bob Holmes - email: cambob@gmail.com&lt;br /&gt;
# Date  : 08/05/2008&lt;br /&gt;
# Version: 1.1&lt;br /&gt;
# Usage : rs_log_checker.sh [v|V] (verbose mode)&lt;br /&gt;
# Description: Script for checking the repserver errorlog&lt;br /&gt;
# --------------------------&lt;br /&gt;
#    ***    Variables for customisation can be found by searching for &amp;quot;!!&amp;quot; ***&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Modification history:&lt;br /&gt;
#&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Enhancement notes:&lt;br /&gt;
# BobH: V1.0: Modified to re-create rserrlogmarker file if not found, then re-run automatically.&lt;br /&gt;
# BobH: V1.1: Updated for detecting a new log file and resetting rserrlogmarker if so.&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Comments: This script can easily be modified to monitor any log, including ASE.&lt;br /&gt;
#           The log itself is never written to so this script maintains a control&lt;br /&gt;
#           file to keep track of the last line it checked.&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           setup environment                                #&lt;br /&gt;
##############################################################################&lt;br /&gt;
HOSTNAME=`hostname`&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           config variables                                 #&lt;br /&gt;
##############################################################################&lt;br /&gt;
# config&lt;br /&gt;
RSLOGFILE=&amp;quot;/PATH_TO_ERRORLOG_HERE/servername_rs.log&amp;quot;        # !! modify for your environment&lt;br /&gt;
ADMINDIR=&amp;quot;/opt/home/sybase/admin&amp;quot;                           # !! modify for your environment&lt;br /&gt;
&lt;br /&gt;
# static&lt;br /&gt;
RSLOGMARKER=&amp;quot;$ADMINDIR/control_files/rserrlogmarker.dat&amp;quot;    # !! need $ADMINDIR/control_files/ directory&lt;br /&gt;
TEMPFILE1=&amp;quot;$ADMINDIR/rslogchecker1.tmp&amp;quot;                     # transient file&lt;br /&gt;
TEMPFILE2=&amp;quot;$ADMINDIR/rslogchecker2.tmp&amp;quot;                     # transient file&lt;br /&gt;
MAILFILE=&amp;quot;$ADMINDIR/rslogchecker.mail&amp;quot;                      # transient file&lt;br /&gt;
RECIPIENTS=&amp;quot;user@domain.dom&amp;quot;                                # !! enter email address config here &lt;br /&gt;
                                                            #   (separate with commas for multiple addresses)&lt;br /&gt;
SCRIPT_NAME=`basename $0`&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                             main program                                   #&lt;br /&gt;
##############################################################################&lt;br /&gt;
&lt;br /&gt;
# check location of errorlog&lt;br /&gt;
if [ ! -f $RSLOGFILE ]&lt;br /&gt;
then&lt;br /&gt;
   echo RS errorlog file not found. Please check config.&lt;br /&gt;
   exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# get log marker value from file (or otherwise create it)&lt;br /&gt;
# V1.1: marker is now a line number&lt;br /&gt;
if [ ! -f $RSLOGMARKER ]&lt;br /&gt;
then&lt;br /&gt;
   MARKER=$(cat -n $RSLOGFILE | tail -1 | awk '{print $1}')&lt;br /&gt;
   echo $MARKER &amp;gt; $RSLOGMARKER&lt;br /&gt;
   #echo &amp;quot;rs log marker reset&amp;quot;&lt;br /&gt;
   $SCRIPT_NAME # must re-run after marker file reset&lt;br /&gt;
   exit&lt;br /&gt;
else&lt;br /&gt;
   MARKER=$(cat $RSLOGMARKER)&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# Compare number of lines in log file with current marker value to check&lt;br /&gt;
# if a new log has been created/repserver restarted.&lt;br /&gt;
if [ $(wc -l $RSLOGFILE | awk '{print $1}') -lt $MARKER ]&lt;br /&gt;
then&lt;br /&gt;
   # new log file created/repserver restarted&lt;br /&gt;
   printf &amp;quot;${SCRIPT_NAME}: New log file detected\n&amp;quot; &amp;gt; $TEMPFILE2&lt;br /&gt;
   RESTARTDT=$(head -1 $RSLOGFILE | awk '{print $2,$3}')&lt;br /&gt;
   printf &amp;quot;${SCRIPT_NAME}: Repserver restarted at: ${RESTARTDT}\n\n&amp;quot; &amp;gt;&amp;gt; $TEMPFILE2&lt;br /&gt;
   printf &amp;quot;Errors/Warnings from startup follow:\n&amp;quot; &amp;gt;&amp;gt; $TEMPFILE2&lt;br /&gt;
   printf &amp;quot;------------------------------------\n&amp;quot; &amp;gt;&amp;gt; $TEMPFILE2&lt;br /&gt;
   # pick out any errors/or warnings from log file:&lt;br /&gt;
   egrep &amp;quot;^E. |^W. &amp;quot; $RSLOGFILE &amp;gt;&amp;gt; $TEMPFILE2&lt;br /&gt;
   mailx -s &amp;quot;$HOSTNAME: Repserver restarted!&amp;quot; $RECIPIENTS &amp;lt; $TEMPFILE2&lt;br /&gt;
   rm $RSLOGMARKER # force reset of marker file&lt;br /&gt;
   rm $TEMPFILE2&lt;br /&gt;
   exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if [ &amp;quot;$1&amp;quot; = &amp;quot;V&amp;quot; ] || [ &amp;quot;$1&amp;quot; = &amp;quot;v&amp;quot; ] # verbose (diag) mode&lt;br /&gt;
then&lt;br /&gt;
  echo Current marker value is: $MARKER&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# increment the marker (line number) to avoid re-reading same last line&lt;br /&gt;
((MARKER=MARKER+1))&lt;br /&gt;
sed -n &amp;quot;$MARKER,$ p&amp;quot; $RSLOGFILE &amp;gt; $TEMPFILE1&lt;br /&gt;
######### next executable line checks for errors #########&lt;br /&gt;
######### add your search terms to the egrep below #######&lt;br /&gt;
EMSGS=$(egrep -c &amp;quot;^E\. |^W\. &amp;quot; $TEMPFILE1)&lt;br /&gt;
if [ $EMSGS -ne 0 ]&lt;br /&gt;
then&lt;br /&gt;
  if [ &amp;quot;$1&amp;quot; = &amp;quot;V&amp;quot; ] || [ &amp;quot;$1&amp;quot; = &amp;quot;v&amp;quot; ] # verbose (diag) mode&lt;br /&gt;
  then&lt;br /&gt;
     echo Error message found: $HOSTNAME: $EMSGS messages&lt;br /&gt;
     cat $TEMPFILE1&lt;br /&gt;
     echo END OF REPORT&lt;br /&gt;
  else&lt;br /&gt;
     cp $TEMPFILE1 $MAILFILE&lt;br /&gt;
     printf &amp;quot;-------CALLOUT SYBASE DBA - ON CALL----------------\n&amp;quot; &amp;gt;&amp;gt; $MAILFILE   # !! optional&lt;br /&gt;
     mailx -s &amp;quot;$HOSTNAME: $EMSGS errors found in repserver errorlog&amp;quot; $RECIPIENTS &amp;lt; $MAILFILE&lt;br /&gt;
  fi&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
#update marker:&lt;br /&gt;
# Note: use line count from TEMPFILE1 + (MARKER-1) to avoid re-scanning the whole errorlog;&lt;br /&gt;
# cat/cp'ing large log files can cause load issues so we don't do that!&lt;br /&gt;
LINECOUNT=$(wc -l $TEMPFILE1 | awk '{print $1}')&lt;br /&gt;
((MARKER=MARKER+LINECOUNT-1))&lt;br /&gt;
echo $MARKER &amp;gt; $RSLOGMARKER&lt;br /&gt;
if [ &amp;quot;$1&amp;quot; = &amp;quot;V&amp;quot; ] || [ &amp;quot;$1&amp;quot; = &amp;quot;v&amp;quot; ] # verbose (diag) mode&lt;br /&gt;
then&lt;br /&gt;
  echo New marker value is: $MARKER&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# housekeeping&lt;br /&gt;
if [ -e $TEMPFILE1 ]&lt;br /&gt;
then&lt;br /&gt;
  rm $TEMPFILE1&lt;br /&gt;
fi&lt;br /&gt;
if [ -e $TEMPFILE2 ]&lt;br /&gt;
then&lt;br /&gt;
  rm $TEMPFILE2&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
#end script&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:RepServer]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=Sp_mon_sql2--ASE_spid_activity_monitor&amp;diff=1841</id>
		<title>Sp mon sql2--ASE spid activity monitor</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=Sp_mon_sql2--ASE_spid_activity_monitor&amp;diff=1841"/>
				<updated>2009-02-18T19:04:24Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: Initial version.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: This SP uses the MDA tables.&amp;lt;BR&amp;gt;&lt;br /&gt;
This sp is for getting a clear list of currently active spids with full details including login, db, blocking spid, processing time, query start time, cpu usage, logical and physical i/o, currently executing command etc.  To maximise clarity, all info is displayed on one line for each spid.  Alternate info is also available by running with '1' (without quotes) which includes, login time, host process, originating host and other information which may be useful for tracking down the source of a problem external to ASE.  Note, unfortunately the '1' option was a quick hack - the sp needs modifying to change this to a 'x' or something similar as the sp can also be called with &amp;lt;spid&amp;gt; to investigate a spid which is not currently active.&lt;br /&gt;
&lt;br /&gt;
Usage summary:&amp;lt;BR&amp;gt;&lt;br /&gt;
sp__mon_sql2&amp;lt;BR&amp;gt;&lt;br /&gt;
sp__mon_sql2 &amp;lt;spid&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
sp__mon_sql2 1  (due to the quick hack noted above, if you want to investigate spid 1, you can't! sorry - I'll fix it in the next version. Luckily the need to investigate spid 1 is quite rare.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
create procedure sp__mon_sql2&lt;br /&gt;
(&lt;br /&gt;
@spid int = 0&lt;br /&gt;
)&lt;br /&gt;
as&lt;br /&gt;
------------------------------&lt;br /&gt;
-- Procedure: sp__mon_sql2&lt;br /&gt;
--   Created: April 2008&lt;br /&gt;
--    Author: Bob Holmes&lt;br /&gt;
-- Last modification: bobh - if 1 is specified as the spid number then alternate info is returned (dirty hack)&lt;br /&gt;
------------------------------&lt;br /&gt;
-- INFO:&lt;br /&gt;
-- The three *'s are a grep key for a shell script to use to extract the lines needed for alerting.&lt;br /&gt;
------------------------------&lt;br /&gt;
--part 1 - snapshot&lt;br /&gt;
set forceplan on&lt;br /&gt;
select 	s.StartTime, &lt;br /&gt;
	convert(smallint,(datediff(mi,StartTime,getdate()))) Dmins,  &lt;br /&gt;
	p.spid, &lt;br /&gt;
	p.hostname, &lt;br /&gt;
	p.suid, &lt;br /&gt;
	p.dbid, &lt;br /&gt;
	p.cmd, &lt;br /&gt;
        p.blocked,&lt;br /&gt;
	s.CpuTime, &lt;br /&gt;
	s.LogicalReads, &lt;br /&gt;
	s.PhysicalReads,&lt;br /&gt;
	p.status, &lt;br /&gt;
	p.loggedindatetime,&lt;br /&gt;
	p.program_name, &lt;br /&gt;
	l.ClientOSPID, &lt;br /&gt;
	p.time_blocked, &lt;br /&gt;
	p.ipaddr&lt;br /&gt;
into #processmon2&lt;br /&gt;
from master..sysprocesses p, master..monProcessStatement s, master..monProcessLookup l&lt;br /&gt;
where p.spid != @@spid&lt;br /&gt;
and p.spid *= s.SPID&lt;br /&gt;
and l.SPID = p.spid&lt;br /&gt;
and suid &amp;lt;&amp;gt; 0&lt;br /&gt;
order by p.spid&lt;br /&gt;
set forceplan off&lt;br /&gt;
&lt;br /&gt;
--part 2 --display spid summaries&lt;br /&gt;
&lt;br /&gt;
if @spid=0&lt;br /&gt;
begin&lt;br /&gt;
-- display header information for multiple spids&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;Process Summary (Order by Dmins, CpuTime, LogicalReads, PhysicalReads Desc )&amp;quot;&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;&amp;quot;&lt;br /&gt;
  select distinct &amp;quot;***&amp;quot;,&lt;br /&gt;
  spid Spid,&lt;br /&gt;
  convert(char(12),suser_name(suid)) Login,&lt;br /&gt;
  convert(char(16),db_name(dbid)) DB,&lt;br /&gt;
  (case hostname when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),hostname) end) Hostname,&lt;br /&gt;
  blocked,&lt;br /&gt;
  convert(varchar(19),StartTime) StartTime,&lt;br /&gt;
  Dmins,&lt;br /&gt;
  right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins/60)),2) + &amp;quot;:&amp;quot; + right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins%60)),2) Dtime,&lt;br /&gt;
  CpuTime,&lt;br /&gt;
  LogicalReads,&lt;br /&gt;
  PhysicalReads,&lt;br /&gt;
  cmd Command&lt;br /&gt;
  from #processmon2&lt;br /&gt;
  where cmd &amp;lt;&amp;gt; &amp;quot;AWAITING COMMAND&amp;quot;&lt;br /&gt;
  order by Dmins desc, CpuTime Desc, LogicalReads Desc, PhysicalReads Desc&lt;br /&gt;
end&lt;br /&gt;
else if @spid=1&lt;br /&gt;
begin&lt;br /&gt;
-- display header information for multiple spids&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;Process Summary (Order by Dmins, CpuTime, LogicalReads, PhysicalReads Desc )&amp;quot;&lt;br /&gt;
  print &amp;quot;******************************************************************************&amp;quot;&lt;br /&gt;
  print &amp;quot;&amp;quot;&lt;br /&gt;
select &lt;br /&gt;
  spid Spid,&lt;br /&gt;
  convert(char(12),suser_name(suid)) Login,&lt;br /&gt;
  convert(char(15),db_name(dbid)) DB,&lt;br /&gt;
  (case hostname when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),hostname) end) Hostname,&lt;br /&gt;
  blocked,&lt;br /&gt;
  convert(varchar(19),StartTime) StartTime,&lt;br /&gt;
  Dmins,&lt;br /&gt;
  right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins/60)),2) + &amp;quot;:&amp;quot; + right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins%60)),2) Dtime,&lt;br /&gt;
  (case program_name when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),program_name) end) Application,&lt;br /&gt;
  (case ClientOSPID when NULL then &amp;quot;-&amp;quot; else convert(char(7),ClientOSPID) end) &amp;quot;OS PID&amp;quot;,&lt;br /&gt;
  time_blocked &amp;quot;Blocked(s)&amp;quot;,&lt;br /&gt;
  convert(char(8),loggedindatetime,108) &amp;quot;Logged in&amp;quot;,&lt;br /&gt;
  convert(char(15),ipaddr) ClientIP,&lt;br /&gt;
  cmd Command&lt;br /&gt;
  from #processmon2&lt;br /&gt;
  where cmd &amp;lt;&amp;gt; &amp;quot;AWAITING COMMAND&amp;quot;&lt;br /&gt;
  order by Dmins desc, CpuTime Desc, LogicalReads Desc, PhysicalReads Desc&lt;br /&gt;
end&lt;br /&gt;
else&lt;br /&gt;
begin&lt;br /&gt;
select distinct &amp;quot;***&amp;quot;,&lt;br /&gt;
  spid Spid,&lt;br /&gt;
  convert(char(12),suser_name(suid)) Login,&lt;br /&gt;
  convert(char(16),db_name(dbid)) DB,&lt;br /&gt;
  (case hostname when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(12),hostname) end) Hostname,&lt;br /&gt;
  convert(varchar(19),StartTime) StartTime,&lt;br /&gt;
  Dmins,&lt;br /&gt;
  blocked,&lt;br /&gt;
  right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins/60)),2) + &amp;quot;:&amp;quot; + right( replicate(&amp;quot;0&amp;quot;, 2) + convert(varchar(2),(Dmins%60)),2) Dtime,&lt;br /&gt;
  CpuTime,&lt;br /&gt;
  LogicalReads,&lt;br /&gt;
  PhysicalReads,&lt;br /&gt;
  cmd Command&lt;br /&gt;
  from #processmon2&lt;br /&gt;
  where spid = @spid&lt;br /&gt;
  order by Dmins desc, CpuTime Desc, LogicalReads Desc, PhysicalReads Desc&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--select spid, convert(char(15),suser_name(suid)) user_name, &lt;br /&gt;
--convert(char(15),db_name(dbid)) dbname, status, &lt;br /&gt;
--convert(char(8),loggedindatetime,108) &amp;quot;logged in&amp;quot;,&lt;br /&gt;
--(case hostname when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else hostname end) hostname, &lt;br /&gt;
--(case program_name when &amp;quot;&amp;quot; then &amp;quot;-&amp;quot; else convert(char(15),program_name) end) application, &lt;br /&gt;
--(case ClientOSPID when NULL then &amp;quot;-&amp;quot; else convert(char(7),ClientOSPID) end) &amp;quot;OS Process&amp;quot;, blocked, time_blocked, ipaddr ClientIP, cmd  from --master..sysprocesses p, master..monProcessLookup l&lt;br /&gt;
--where l.SPID = p.spid&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:ASE]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=RepServer_Errorlog_checker&amp;diff=1840</id>
		<title>RepServer Errorlog checker</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=RepServer_Errorlog_checker&amp;diff=1840"/>
				<updated>2009-02-18T18:22:55Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The script below is for monitoring the repserver errorlog - it works with any version of repserver and does not need to write to the errorlog itself in order to monitor it.  However, since it doesn't write to the errorlog, it does need a $ADMINDIR/control_files/ directory which you may wish to create as a non-transient file (rserrlogmarker.dat) is maintained there.&lt;br /&gt;
Also, as per the script notes, you can easily modify this script to monitor *any* log; be sure to give rserrlogmarker.dat and the other files in the config section different names or keep them elsewhere so that there is no conflict.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/ksh&lt;br /&gt;
#&lt;br /&gt;
# Script: rs_log_checker.sh&lt;br /&gt;
# Author: Bob Holmes - email: cambob@gmail.com)&lt;br /&gt;
# Date  : 08/05/2008&lt;br /&gt;
# Version: 1.1&lt;br /&gt;
# Usage : rs_log_checker.sh [v|V] (verbose mode)&lt;br /&gt;
# Description: Script for checking the repserver errorlog&lt;br /&gt;
# --------------------------&lt;br /&gt;
#    ***    Variables for customisation can be found by searching for &amp;quot;!!&amp;quot; ***&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Modification history:&lt;br /&gt;
#&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Enhancement notes:&lt;br /&gt;
# BobH: V1.0: Modified to re-create rserrlogmarker file if not found, then re-run automatically.&lt;br /&gt;
# BobH: V1.1: Updated for detecting a new log file and resetting rserrlogmarker if so.&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Comments: This script can easily be modified to monitor any log, including ASE.&lt;br /&gt;
#           The log itself is never written to so this script maintains a control&lt;br /&gt;
#           file to keep track of the last line it checked.&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           setup environment                                #&lt;br /&gt;
##############################################################################&lt;br /&gt;
HOSTNAME=`hostname`&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           config variables                                 #&lt;br /&gt;
##############################################################################&lt;br /&gt;
# config&lt;br /&gt;
RSLOGFILE=&amp;quot;/PATH_TO_ERRORLOG_HERE/servername_rs.log&amp;quot;        # !! modify for your environment&lt;br /&gt;
ADMINDIR=&amp;quot;/opt/home/sybase/admin&amp;quot;                           # !! modify for your environment&lt;br /&gt;
&lt;br /&gt;
# static&lt;br /&gt;
RSLOGMARKER=&amp;quot;$ADMINDIR/control_files/rserrlogmarker.dat&amp;quot;    # !! need $ADMINDIR/control_files/ directory&lt;br /&gt;
TEMPFILE1=&amp;quot;$ADMINDIR/rslogchecker1.tmp&amp;quot;                     # transient file&lt;br /&gt;
TEMPFILE2=&amp;quot;$ADMINDIR/rslogchecker2.tmp&amp;quot;                     # transient file&lt;br /&gt;
MAILFILE=&amp;quot;$ADMINDIR/rslogchecker.mail&amp;quot;                      # transient file&lt;br /&gt;
RECIPIENTS=&amp;quot;user@domain.dom&amp;quot;                                # !! enter email address config here &lt;br /&gt;
                                                            #   (separate with commas for multiple addresses)&lt;br /&gt;
SCRIPT_NAME=`basename $0`&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                             main program                                   #&lt;br /&gt;
##############################################################################&lt;br /&gt;
&lt;br /&gt;
# check location of errorlog&lt;br /&gt;
if [ ! -f $RSLOGFILE ]&lt;br /&gt;
then&lt;br /&gt;
   echo RS errorlog file not found. Please check config.&lt;br /&gt;
   exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# get log marker value from file (or otherwise create it)&lt;br /&gt;
# V1.1: marker is now a line number&lt;br /&gt;
if [ ! -f $RSLOGMARKER ]&lt;br /&gt;
then&lt;br /&gt;
   MARKER=$(cat -n $RSLOGFILE | tail -1 | awk '{print $1}')&lt;br /&gt;
   echo $MARKER &amp;gt; $RSLOGMARKER&lt;br /&gt;
   #echo &amp;quot;rs log marker reset&amp;quot;&lt;br /&gt;
   $SCRIPT_NAME # must re-run after marker file reset&lt;br /&gt;
   exit&lt;br /&gt;
else&lt;br /&gt;
   MARKER=$(cat $RSLOGMARKER)&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# Compare number of lines in log file with current marker value to check&lt;br /&gt;
# if a new log has been created/repserver restarted.&lt;br /&gt;
if [ $(wc -l $RSLOGFILE | awk '{print $1}') -lt $MARKER ]&lt;br /&gt;
then&lt;br /&gt;
   # new log file created/repserver restarted&lt;br /&gt;
   printf &amp;quot;${SCRIPT_NAME}: New log file detected\n&amp;quot; &amp;gt; $TEMPFILE2&lt;br /&gt;
   RESTARTDT=$(head -1 $RSLOGFILE | awk '{print $2,$3}')&lt;br /&gt;
   printf &amp;quot;${SCRIPT_NAME}: Repserver restarted at: ${RESTARTDT}\n\n&amp;quot; &amp;gt;&amp;gt; $TEMPFILE2&lt;br /&gt;
   printf &amp;quot;Errors/Warnings from startup follow:\n&amp;quot; &amp;gt;&amp;gt; $TEMPFILE2&lt;br /&gt;
   printf &amp;quot;------------------------------------\n&amp;quot; &amp;gt;&amp;gt; $TEMPFILE2&lt;br /&gt;
   # pick out any errors/or warnings from log file:&lt;br /&gt;
   egrep &amp;quot;^E. |^W. &amp;quot; $RSLOGFILE &amp;gt;&amp;gt; $TEMPFILE2&lt;br /&gt;
   mailx -s &amp;quot;$HOSTNAME: Repserver restarted!&amp;quot; $RECIPIENTS &amp;lt; $TEMPFILE2&lt;br /&gt;
   rm $RSLOGMARKER # force reset of marker file&lt;br /&gt;
   rm $TEMPFILE2&lt;br /&gt;
   exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if [ &amp;quot;$1&amp;quot; = &amp;quot;V&amp;quot; ] || [ &amp;quot;$1&amp;quot; = &amp;quot;v&amp;quot; ] # verbose (diag) mode&lt;br /&gt;
then&lt;br /&gt;
  echo Current marker value is: $MARKER&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# increment the marker (line number) to avoid re-reading same last line&lt;br /&gt;
((MARKER=MARKER+1))&lt;br /&gt;
sed -n &amp;quot;$MARKER,$ p&amp;quot; $RSLOGFILE &amp;gt; $TEMPFILE1&lt;br /&gt;
######### next executable line checks for errors #########&lt;br /&gt;
######### add your search terms to the egrep below #######&lt;br /&gt;
EMSGS=$(egrep -c &amp;quot;^E\. |^W\. &amp;quot; $TEMPFILE1)&lt;br /&gt;
if [ $EMSGS -ne 0 ]&lt;br /&gt;
then&lt;br /&gt;
  if [ &amp;quot;$1&amp;quot; = &amp;quot;V&amp;quot; ] || [ &amp;quot;$1&amp;quot; = &amp;quot;v&amp;quot; ] # verbose (diag) mode&lt;br /&gt;
  then&lt;br /&gt;
     echo Error message found: $HOSTNAME: $EMSGS messages&lt;br /&gt;
     cat $TEMPFILE1&lt;br /&gt;
     echo END OF REPORT&lt;br /&gt;
  else&lt;br /&gt;
     cp $TEMPFILE1 $MAILFILE&lt;br /&gt;
     printf &amp;quot;-------CALLOUT SYBASE DBA - ON CALL----------------\n&amp;quot; &amp;gt;&amp;gt; $MAILFILE   # !! optional&lt;br /&gt;
     mailx -s &amp;quot;$HOSTNAME: $EMSGS errors found in repserver errorlog&amp;quot; $RECIPIENTS &amp;lt; $MAILFILE&lt;br /&gt;
  fi&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
#update marker:&lt;br /&gt;
# Note: use line count from TEMPFILE1 + (MARKER-1) to avoid re-scanning the whole errorlog;&lt;br /&gt;
# cat/cp'ing large log files can cause load issues so we don't do that!&lt;br /&gt;
LINECOUNT=$(wc -l $TEMPFILE1 | awk '{print $1}')&lt;br /&gt;
((MARKER=MARKER+LINECOUNT-1))&lt;br /&gt;
echo $MARKER &amp;gt; $RSLOGMARKER&lt;br /&gt;
if [ &amp;quot;$1&amp;quot; = &amp;quot;V&amp;quot; ] || [ &amp;quot;$1&amp;quot; = &amp;quot;v&amp;quot; ] # verbose (diag) mode&lt;br /&gt;
then&lt;br /&gt;
  echo New marker value is: $MARKER&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# housekeeping&lt;br /&gt;
if [ -e $TEMPFILE1 ]&lt;br /&gt;
then&lt;br /&gt;
  rm $TEMPFILE1&lt;br /&gt;
fi&lt;br /&gt;
if [ -e $TEMPFILE2 ]&lt;br /&gt;
then&lt;br /&gt;
  rm $TEMPFILE2&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
#end script&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:RepServer]]&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	<entry>
		<id>http://petersap.nl/SybaseWiki/index.php?title=RepServer_Errorlog_checker&amp;diff=1839</id>
		<title>RepServer Errorlog checker</title>
		<link rel="alternate" type="text/html" href="http://petersap.nl/SybaseWiki/index.php?title=RepServer_Errorlog_checker&amp;diff=1839"/>
				<updated>2009-02-18T18:17:19Z</updated>
		
		<summary type="html">&lt;p&gt;Bobh: Initial version.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The script below is for monitoring the repserver errorlog - it works with any version of repserver and does not need to write to the errorlog itself in order to monitor it.  However, since it doesn't write to the errorlog, it does need a $ADMINDIR/control_files/ directory which you may wish to create as a non-transient file (rserrlogmarker.dat) is maintained there.&lt;br /&gt;
Also, as per the script notes, you can easily modify this script to monitor *any* log; be sure to give rserrlogmarker.dat and the other files in the config section different names or keep them elsewhere so that there is no conflict.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/ksh&lt;br /&gt;
#&lt;br /&gt;
# Script: rs_log_checker.sh&lt;br /&gt;
# Author: Bob Holmes - email: cambob@gmail.com)&lt;br /&gt;
# Date  : 08/05/2008&lt;br /&gt;
# Version: 1.1&lt;br /&gt;
# Usage : rs_log_checker.sh [v|V] (verbose mode)&lt;br /&gt;
# Description: Script for checking the repserver errorlog&lt;br /&gt;
# --------------------------&lt;br /&gt;
#    ***    Variables for customisation can be found by searching for &amp;quot;!!&amp;quot; ***&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Modification history:&lt;br /&gt;
#&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Enhancement notes:&lt;br /&gt;
# BobH: V1.0: Modified to re-create rserrlogmarker file if not found, then re-run automatically.&lt;br /&gt;
# BobH: V1.1: Updated for detecting a new log file and resetting rserrlogmarker if so.&lt;br /&gt;
# --------------------------&lt;br /&gt;
# Comments: This script can easily be modified to monitor any log, including ASE.&lt;br /&gt;
#           The log itself is never written to so this script maintains a control&lt;br /&gt;
#           file to keep track of the last line it checked.&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           setup environment                                #&lt;br /&gt;
##############################################################################&lt;br /&gt;
HOSTNAME=`hostname`&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                           config variables                                 #&lt;br /&gt;
##############################################################################&lt;br /&gt;
# config&lt;br /&gt;
RSLOGFILE=&amp;quot;/PATH_TO_ERRORLOG_HERE/servername_rs.log&amp;quot;        # !! modify for your environment&lt;br /&gt;
ADMINDIR=&amp;quot;/opt/home/sybase/admin&amp;quot;                           # !! modify for your environment&lt;br /&gt;
&lt;br /&gt;
# static&lt;br /&gt;
RSLOGMARKER=&amp;quot;$ADMINDIR/control_files/rserrlogmarker.dat&amp;quot;    # !! need $ADMINDIR/control_files/ directory&lt;br /&gt;
TEMPFILE1=&amp;quot;$ADMINDIR/rslogchecker1.tmp&amp;quot;                     # transient file&lt;br /&gt;
TEMPFILE2=&amp;quot;$ADMINDIR/rslogchecker2.tmp&amp;quot;                     # transient file&lt;br /&gt;
MAILFILE=&amp;quot;$ADMINDIR/rslogchecker.mail&amp;quot;                      # transient file&lt;br /&gt;
RECIPIENTS=&amp;quot;user@domain.dom&amp;quot;                                # !! enter email address config here &lt;br /&gt;
                                                            #   (separate with commas for multiple addresses)&lt;br /&gt;
SCRIPT_NAME=`basename $0`&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#                             main program                                   #&lt;br /&gt;
##############################################################################&lt;br /&gt;
&lt;br /&gt;
# check location of errorlog&lt;br /&gt;
if [ ! -f $RSLOGFILE ]&lt;br /&gt;
then&lt;br /&gt;
   echo RS errorlog file not found. Please check config.&lt;br /&gt;
   exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# get log marker value from file (or otherwise create it)&lt;br /&gt;
# V1.1: marker is now a line number&lt;br /&gt;
if [ ! -f $RSLOGMARKER ]&lt;br /&gt;
then&lt;br /&gt;
   MARKER=$(cat -n $RSLOGFILE | tail -1 | awk '{print $1}')&lt;br /&gt;
   echo $MARKER &amp;gt; $RSLOGMARKER&lt;br /&gt;
   #echo &amp;quot;rs log marker reset&amp;quot;&lt;br /&gt;
   $SCRIPT_NAME # must re-run after marker file reset&lt;br /&gt;
   exit&lt;br /&gt;
else&lt;br /&gt;
   MARKER=$(cat $RSLOGMARKER)&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# Compare number of lines in log file with current marker value to check&lt;br /&gt;
# if a new log has been created/repserver restarted.&lt;br /&gt;
if [ $(wc -l $RSLOGFILE | awk '{print $1}') -lt $MARKER ]&lt;br /&gt;
then&lt;br /&gt;
   # new log file created/repserver restarted&lt;br /&gt;
   printf &amp;quot;${SCRIPT_NAME}: New log file detected\n&amp;quot; &amp;gt; $TEMPFILE2&lt;br /&gt;
   RESTARTDT=$(head -1 $RSLOGFILE | awk '{print $2,$3}')&lt;br /&gt;
   printf &amp;quot;${SCRIPT_NAME}: Repserver restarted at: ${RESTARTDT}\n\n&amp;quot; &amp;gt;&amp;gt; $TEMPFILE2&lt;br /&gt;
   printf &amp;quot;Errors/Warnings from startup follow:\n&amp;quot; &amp;gt;&amp;gt; $TEMPFILE2&lt;br /&gt;
   printf &amp;quot;------------------------------------\n&amp;quot; &amp;gt;&amp;gt; $TEMPFILE2&lt;br /&gt;
   # pick out any errors/or warnings from log file:&lt;br /&gt;
   egrep &amp;quot;^E. |^W. &amp;quot; $RSLOGFILE &amp;gt;&amp;gt; $TEMPFILE2&lt;br /&gt;
   mailx -s &amp;quot;$HOSTNAME: Repserver restarted!&amp;quot; $RECIPIENTS &amp;lt; $TEMPFILE2&lt;br /&gt;
   rm $RSLOGMARKER # force reset of marker file&lt;br /&gt;
   rm $TEMPFILE2&lt;br /&gt;
   exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if [ &amp;quot;$1&amp;quot; = &amp;quot;V&amp;quot; ] || [ &amp;quot;$1&amp;quot; = &amp;quot;v&amp;quot; ] # verbose (diag) mode&lt;br /&gt;
then&lt;br /&gt;
  echo Current marker value is: $MARKER&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# increment the marker (line number) to avoid re-reading same last line&lt;br /&gt;
((MARKER=MARKER+1))&lt;br /&gt;
sed -n &amp;quot;$MARKER,$ p&amp;quot; $RSLOGFILE &amp;gt; $TEMPFILE1&lt;br /&gt;
######### next executable line checks for errors #########&lt;br /&gt;
######### add your search terms to the egrep below #######&lt;br /&gt;
EMSGS=$(egrep -c &amp;quot;^E\. |^W\. &amp;quot; $TEMPFILE1)&lt;br /&gt;
if [ $EMSGS -ne 0 ]&lt;br /&gt;
then&lt;br /&gt;
  if [ &amp;quot;$1&amp;quot; = &amp;quot;V&amp;quot; ] || [ &amp;quot;$1&amp;quot; = &amp;quot;v&amp;quot; ] # verbose (diag) mode&lt;br /&gt;
  then&lt;br /&gt;
     echo Error message found: $HOSTNAME: $EMSGS messages&lt;br /&gt;
     cat $TEMPFILE1&lt;br /&gt;
     echo END OF REPORT&lt;br /&gt;
  else&lt;br /&gt;
     cp $TEMPFILE1 $MAILFILE&lt;br /&gt;
     printf &amp;quot;-------CALLOUT SYBASE DBA - ON CALL----------------\n&amp;quot; &amp;gt;&amp;gt; $MAILFILE   # !! optional&lt;br /&gt;
     mailx -s &amp;quot;$HOSTNAME: $EMSGS errors found in repserver errorlog&amp;quot; $RECIPIENTS &amp;lt; $MAILFILE&lt;br /&gt;
  fi&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
#update marker:&lt;br /&gt;
# Note: use line count from TEMPFILE1 + (MARKER-1) to avoid re-scanning the whole errorlog;&lt;br /&gt;
# cat/cp'ing large log files can cause load issues so we don't do that!&lt;br /&gt;
LINECOUNT=$(wc -l $TEMPFILE1 | awk '{print $1}')&lt;br /&gt;
((MARKER=MARKER+LINECOUNT-1))&lt;br /&gt;
echo $MARKER &amp;gt; $RSLOGMARKER&lt;br /&gt;
if [ &amp;quot;$1&amp;quot; = &amp;quot;V&amp;quot; ] || [ &amp;quot;$1&amp;quot; = &amp;quot;v&amp;quot; ] # verbose (diag) mode&lt;br /&gt;
then&lt;br /&gt;
  echo New marker value is: $MARKER&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# housekeeping&lt;br /&gt;
if [ -e $TEMPFILE1 ]&lt;br /&gt;
then&lt;br /&gt;
  rm $TEMPFILE1&lt;br /&gt;
fi&lt;br /&gt;
if [ -e $TEMPFILE2 ]&lt;br /&gt;
then&lt;br /&gt;
  rm $TEMPFILE2&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
#end script&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bobh</name></author>	</entry>

	</feed>