यहाँ परिदृश्य है।
मुझे 'लाइवफिड' नामक एक प्रक्रिया मिली है जो तार से स्ट्रीमिंग की कीमतें पढ़ती है, आवेषण कतार में आती है, और 'अस्थायी अपलोड पर अस्थायी अपलोड' का उपयोग करती है और फिर एमडीसी तालिका में डालें/अपडेट करें। (बल्क यूपीएसर्ट)
मुझे एक और प्रक्रिया मिली है जो तब इस डेटा को पढ़ती है, अन्य डेटा की गणना करती है, और उसके बाद समान बल्क यूपीएसर्ट संग्रहित प्रो का उपयोग करके परिणाम को उसी तालिका में वापस सहेजती है।
तीसरा, ऐसे कई उपयोगकर्ता हैं जो सी # गुई एमडीसी तालिका को मतदान करते हैं और इससे अपडेट पढ़ते हैं।
अब, जब डेटा तेजी से बदल रहा है, तो चीजें बहुत आसानी से चल रही हैं, लेकिन फिर, बाजार के घंटों के बाद, हमने हाल ही में डेटाबेस से बाहर आने वाले डेडलॉक अपवादों की बढ़ती संख्या को देखना शुरू कर दिया है, आजकल हम 10 देखते हैं -20 एक दिन। यहां ध्यान देने योग्य अपमानजनक बात यह है कि ये तब होते हैं जब मान नहीं बदल रहे होते हैं। ,
मैं चल रहा है किसी SQL Profiler ट्रेस मिल गया है गतिरोध को पकड़ने, और यहाँ है -
CREATE TABLE [dbo].[MarketDataCurrent](
[MDID] [int] NOT NULL,
[LastUpdate] [datetime] NOT NULL,
[Value] [float] NOT NULL,
[Source] [varchar](20) NULL,
CONSTRAINT [PK_MarketDataCurrent] PRIMARY KEY CLUSTERED
(
[MDID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
:
टेबल डेफ:
यहाँ सभी प्रासंगिक जानकारी है सभी ग्राफ क्या दिखते हैं।
प्रक्रिया 258, निम्नलिखित 'BulkUpsert' संग्रहीत proc कहा जाता है, बार-बार, जबकि 73 अगले एक बुला रहा है:
ALTER proc [dbo].[MarketDataCurrent_BulkUpload]
@updateTime datetime,
@source varchar(10)
as
begin transaction
update c with (rowlock) set LastUpdate = getdate(), Value = t.Value, Source = @source
from MarketDataCurrent c INNER JOIN #MDTUP t ON c.MDID = t.mdid
where c.lastUpdate < @updateTime
and c.mdid not in (select mdid from MarketData where LiveFeedTicker is not null and PriceSource like 'LiveFeed.%')
and c.value <> t.value
insert into MarketDataCurrent
with (rowlock)
select MDID, getdate(), Value, @source from #MDTUP
where mdid not in (select mdid from MarketDataCurrent with (nolock))
and mdid not in (select mdid from MarketData where LiveFeedTicker is not null and PriceSource like 'LiveFeed.%')
commit
और अन्य एक:
ALTER PROCEDURE [dbo].[MarketDataCurrent_LiveFeedUpload]
AS
begin transaction
-- Update existing mdid
UPDATE c WITH (ROWLOCK) SET LastUpdate = t.LastUpdate, Value = t.Value, Source = t.Source
FROM MarketDataCurrent c INNER JOIN #TEMPTABLE2 t ON c.MDID = t.mdid;
-- Insert new MDID
INSERT INTO MarketDataCurrent with (ROWLOCK) SELECT * FROM #TEMPTABLE2
WHERE MDID NOT IN (SELECT MDID FROM MarketDataCurrent with (NOLOCK))
-- Clean up the temp table
DELETE #TEMPTABLE2
commit
स्पष्टीकरण के लिए, उन Temp टेबल्स को उसी कनेक्शन पर सी # कोड द्वारा बनाया जा रहा है और सी # एसक्यूएलकल्क कॉपी क्लास का उपयोग करके पॉप्युलेट किया गया है।
मेरे लिए ऐसा लगता है कि यह तालिका के पीके पर डेडलॉकिंग है, इसलिए मैंने उस पीके को हटाने और इसके बजाय एक अनोखा प्रतिबंध पर स्विच करने की कोशिश की लेकिन इससे 10 गुना डेडलॉक्स की संख्या में वृद्धि हुई।
मैं पूरी तरह से खो गया हूं कि इस स्थिति के बारे में क्या करना है और किसी भी सुझाव के लिए खुला हूं।
सहायता !!
XDL के लिए अनुरोध के जवाब में, यहाँ यह है:
<deadlock-list>
<deadlock victim="processc19978">
<process-list>
<process id="processaf0b68" taskpriority="0" logused="0" waitresource="KEY: 6:72057594090487808 (d900ed5a6cc6)" waittime="718" ownerId="1102128174" transactionname="user_transaction" lasttranstarted="2010-06-11T16:30:44.750" XDES="0xffffffff817f9a40" lockMode="U" schedulerid="3" kpid="8228" status="suspended" spid="73" sbid="0" ecid="0" priority="0" transcount="2" lastbatchstarted="2010-06-11T16:30:44.750" lastbatchcompleted="2010-06-11T16:30:44.750" clientapp=".Net SqlClient Data Provider" hostname="RISKAPPS_VM" hostpid="3836" loginname="RiskOpt" isolationlevel="read committed (2)" xactid="1102128174" currentdb="6" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="MKP_RISKDB.dbo.MarketDataCurrent_BulkUpload" line="28" stmtstart="1062" stmtend="1720" sqlhandle="0x03000600a28e5e4ef4fd8e00849d00000100000000000000">
UPDATE c WITH (ROWLOCK) SET LastUpdate = getdate(), Value = t.Value, Source = @source
FROM MarketDataCurrent c INNER JOIN #MDTUP t ON c.MDID = t.mdid
WHERE c.lastUpdate < @updateTime
and c.mdid not in (select mdid from MarketData where BloombergTicker is not null and PriceSource like 'Blbg.%')
and c.value <> t.value </frame>
<frame procname="adhoc" line="1" stmtstart="88" sqlhandle="0x01000600c1653d0598706ca7000000000000000000000000">
exec MarketDataCurrent_BulkUpload @clearBefore, @source </frame>
<frame procname="unknown" line="1" sqlhandle="0x000000000000000000000000000000000000000000000000">
unknown </frame>
</executionStack>
<inputbuf>
(@clearBefore datetime,@source nvarchar(10))exec MarketDataCurrent_BulkUpload @clearBefore, @source </inputbuf>
</process>
<process id="processc19978" taskpriority="0" logused="0" waitresource="KEY: 6:72057594090487808 (74008e31572b)" waittime="718" ownerId="1102128228" transactionname="user_transaction" lasttranstarted="2010-06-11T16:30:44.780" XDES="0x380be9d8" lockMode="U" schedulerid="5" kpid="8464" status="suspended" spid="248" sbid="0" ecid="0" priority="0" transcount="2" lastbatchstarted="2010-06-11T16:30:44.780" lastbatchcompleted="2010-06-11T16:30:44.780" clientapp=".Net SqlClient Data Provider" hostname="RISKBBG_VM" hostpid="4480" loginname="RiskOpt" isolationlevel="read committed (2)" xactid="1102128228" currentdb="6" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="MKP_RISKDB.dbo.MarketDataCurrentBlbgRtUpload" line="14" stmtstart="840" stmtend="1220" sqlhandle="0x03000600005f9d24c8878f00849d00000100000000000000">
UPDATE c WITH (ROWLOCK) SET LastUpdate = t.LastUpdate, Value = t.Value, Source = t.Source
FROM MarketDataCurrent c INNER JOIN #TEMPTABLE2 t ON c.MDID = t.mdid;
-- Insert new MDID </frame>
<frame procname="adhoc" line="1" sqlhandle="0x010006004a58132228bf8d73000000000000000000000000">
MarketDataCurrentBlbgRtUpload </frame>
</executionStack>
<inputbuf>
MarketDataCurrentBlbgRtUpload </inputbuf>
</process>
</process-list>
<resource-list>
<keylock hobtid="72057594090487808" dbid="6" objectname="MKP_RISKDB.dbo.MarketDataCurrent" indexname="PK_MarketDataCurrent" id="lock5ba77b00" mode="U" associatedObjectId="72057594090487808">
<owner-list>
<owner id="processc19978" mode="U"/>
</owner-list>
<waiter-list>
<waiter id="processaf0b68" mode="U" requestType="wait"/>
</waiter-list>
</keylock>
<keylock hobtid="72057594090487808" dbid="6" objectname="MKP_RISKDB.dbo.MarketDataCurrent" indexname="PK_MarketDataCurrent" id="lock65dca340" mode="U" associatedObjectId="72057594090487808">
<owner-list>
<owner id="processaf0b68" mode="U"/>
</owner-list>
<waiter-list>
<waiter id="processc19978" mode="U" requestType="wait"/>
</waiter-list>
</keylock>
</resource-list>
</deadlock>
</deadlock-list>
क्या होगा यदि आप स्पष्ट चप्पू-आंकड़ा और nolock विनिर्देशक निकालना चाहते हैं? क्या टेबल के बजाए आपके प्रश्नों के विचारों में उल्लिखित डेटा स्रोत हैं, और यदि ऐसा है तो कृपया दृश्य स्रोत पोस्ट करें? धन्यवाद। –
डेटा स्रोतों में से कोई भी विचार नहीं है। असल में, स्पष्टीकरण रोलॉक और नोलॉक्स जोड़ने से डेडलॉक्स की संख्या कम हो गई। – skimania
वास्तविक डेडलॉक एक्सडीएल बेहतर पोस्ट करें, छवि नहीं। छवियां धोखा दे सकती हैं ... http://rusanu.com/2010/05/12/the-puzzle-of-u-locks-in-deadlock-graphs/ –