|
|
493445 |
|
Sybase Replication Server |
|
repserver |
|
|
|
|
|
|
|
|
15.5 |
|
06 Jan 2010 |
Fixed |
|
15.5 |
|
29 Dec 2009 |
Fixed |
|
|
|
|
|
Change RSSD to prevent locking on high volume RSs and cases where monitoring (RMA) is done. |
|
Workaround Description |
|
Here is script done by customer to eliminate the full table scans:
if exists(select name
from sysobjects
where name = 'rma_queue'
and type = 'P')
begin
drop proc rma_queue
end
go
create procedure rma_queue
(@servername varchar(30)
)
as
set nocount on
create table #subs (rawid binary(8), intid int)
/*
** If this a byte-swap machine, swap the order of the last
** four bytes of the subid
*/
if (convert(int, 0x00000100) = 65536)
insert #subs
select rawid = subid,
intid = substring(subid, 8, 1) +
substring(subid, 7, 1) +
substring(subid, 6, 1) +
substring(subid, 5, 1)
from rs_subscriptions
else
insert #subs
select rawid = subid, intid = substring(subid, 5, 4)
from rs_subscriptions
create table #queues
( name varchar(255),
q_number int,
q_type int,
q_state int,
size int,
saved int,
detect_loss int,
ignore_loss int,
first_seg int,
q_objid binary(8),
q_objid_temp binary(8),
xnl_large_msg varchar(9) NULL )
insert #queues
select distinct dsname + '.' + dbname + '(Inbound)',
number, 1, q.state, 0, 0, 0, 0, 0, 0, 0, ''
from rs_queues q, rs_databases d
where number = d.dbid and type=1
insert #queues
select distinct
isnull(convert(varchar(61), name), dsname+'.'+dbname)+'(Outbound)',
number, 0, q.state, 0, 0, 0, 0, 0, 0, 0, ''
from rs_queues q, rs_databases, rs_sites
where number *= dbid
and number *= id
and type=0
insert #queues
select distinct d.dsname+'.'+d.dbname+'(Materialization-'+sub.subname+')',
number, q.type, q.state, 0, 0, 0, 0, 0, 0, 0, ''
from rs_queues q, rs_subscriptions sub, rs_databases d, #subs
where d.dbid=number
and sub.dbid=d.dbid
and #subs.rawid = sub.subid
and #subs.intid = q.type
and materializing=1
insert #queues
select distinct d.dsname+'.'+d.dbname+'(Dematerialization-'+sub.subname+')',
number, q.type, q.state, 0, 0, 0, 0, 0, 0, 0, ''
from rs_queues q, rs_subscriptions sub, rs_databases d, #subs
where d.dbid=number
and sub.dbid=d.dbid
and #subs.rawid = sub.subid
and #subs.intid = q.type
and dematerializing=1
/*
3/10/2008 - Mark Parsons
RMS is causing deadlocks with RepServer while both
processes are trying to access rs_segments. Also,
there is no usable index on rs_segments for the
queries in this stored proc.
Changing rs_segments to datarows locking, and adding
an index on rs_segments(q_number, q_type [,used_flag]),
may help eliminate the deadlocks. But these steps should
be tested/verified/implemented by Sybase as a long-term
solution.
In the meantime we'll put in a kludge to get us around
the majority of deadlock possibilities.
Let's pull a copy of rs_segments into a #temp table
to help minimize chances of deadlocking with the RepServer.
Also, go ahead and add an index to help with follow-on queries.
*/
-- minimize time required to pull data from rs_segments by
-- creating #segments separately
select q_number,
q_type,
logical_seg,
used_flag
into #segments
from rs_segments
where 1=0
insert #segments
select q_number,
q_type,
logical_seg,
used_flag
from rs_segments
create clustered index idx1
on #segments
(q_number, q_type)
with allow_dup_row
update #queues
set size = (select count(*)
from #segments
where #queues.q_number = #segments.q_number
and #queues.q_type = #segments.q_type
and used_flag > 0)
update #queues
set saved = (select count(*)
from #segments
where #queues.q_number = #segments.q_number
and #queues.q_type = #segments.q_type
and used_flag > 1)
update #queues
set detect_loss = detect_loss + (select count(*)
from rs_oqid
where #queues.q_number = rs_oqid.q_number
and #queues.q_type = rs_oqid.q_type
and valid = 1),
ignore_loss = ignore_loss + (select count(*)
from rs_oqid
where #queues.q_number = rs_oqid.q_number
and #queues.q_type = rs_oqid.q_type
and valid = 2)
update #queues
set detect_loss = detect_loss + (select count(*)
from rs_exceptslast
where #queues.q_number = error_db
and status = 1),
ignore_loss = ignore_loss + (select count(*)
from rs_exceptslast
where #queues.q_number = error_db
and status = 2)
update #queues
set first_seg = (select isnull(min(logical_seg),0)
from #segments
where #queues.q_number = #segments.q_number
and #queues.q_type = #segments.q_type)
/* Build the queue objid number to search for wide message flag in rs_config */
update #queues
set q_objid = convert ( binary(4), q_number )
+ convert ( binary(4), q_type )
/* Store a copy of the queue objid in case the bytes need to be reversed */
update #queues
set q_objid_temp = convert ( binary(4), q_number )
+ convert ( binary(4), q_type )
/* If this a byte-swap machine, reverse the objid */
if (convert(int, 0x00000100) = 65536)
update #queues
set q_objid = substring ( q_objid_temp, 8, 1 ) +
substring ( q_objid_temp, 7, 1 ) +
substring ( q_objid_temp, 6, 1 ) +
substring ( q_objid_temp, 5, 1 ) +
substring ( q_objid_temp, 4, 1 ) +
substring ( q_objid_temp, 3, 1 ) +
substring ( q_objid_temp, 2, 1 ) +
substring ( q_objid_temp, 1, 1 )
update #queues
set xnl_large_msg = (select charvalue
from rs_config
where rs_config.objid = #queues.q_objid
and rs_config.optionname =
'sqm_xact_with_large_msg' )
update #queues
set xnl_large_msg = 'shutdown' where xnl_large_msg = NULL
select @servername, name, q_number, q_type, size, saved,
convert(char(40), getdate(), 109),
detect_loss, ignore_loss, first_seg, "DOWN", xnl_large_msg
from #queues
where q_number != 0 and q_state != 1
union all
select @servername, name, q_number, q_type, size, saved,
convert(char(40), getdate(), 109),
detect_loss, ignore_loss, first_seg, "UP", xnl_large_msg
from #queues
where q_number != 0 and q_state = 1
/* Cleanup */
truncate table #queues
truncate table #subs
truncate table #segments
drop table #queues
drop table #subs
drop table #segments
go
grant execute on rma_queue to rs_systabgroup |
|
|
|