Sleeping SPID บล็อกธุรกรรมอื่น ๆ


16

ฉันมีปัญหาในการติดตามการบล็อกที่เรากำลังประสบอยู่

รากปิดกั้นสถานะ SPID เป็น 'นอน' cmd คือ 'รอคำสั่ง' และเป็นsqltextSET TRANSACTION ISOLATION LEVEL READ COMMITTED

เมื่อฉันดูรายงานยอดการทำธุรกรรมตามรายการธุรกรรมที่ถูกบล็อกคำสั่งการบล็อก SQL คือ '-'

ฉันทำการติดตามบน SQL และเมื่อการบล็อคเกิดขึ้นการติดตามรูทการบล็อค SPID แต่มันไม่ได้นำฉันไปทุกที่ คำสั่งร่องรอยสุดท้ายคือเช่นเดียวกับข้างต้นsqltextSET TRANSACTION ISOLATION LEVEL READ COMMITTED

ฉันได้ตรวจสอบขั้นตอนการจัดเก็บที่เกี่ยวข้องทั้งหมดแล้วฉันสามารถค้นหาเพื่อให้แน่ใจว่าพวกเขามีงบ TRY / CATCH BEGIN TRAN / COMMIT TRAN / ROLLBACK งบ TRAN (เราใช้ขั้นตอนที่เก็บไว้สำหรับทุกสิ่งดังนั้นจึงไม่มีคำสั่งแบบสแตนด์อโลน) ปัญหานี้เพิ่งเริ่มเกิดขึ้นในช่วง 24 ชั่วโมงที่ผ่านมาและไม่มีใครอ้างว่าได้ทำการเปลี่ยนแปลงใด ๆ กับระบบ

การแก้ไข: หนึ่งในขั้นตอนการจัดเก็บที่ใช้บ่อยของเรามีข้อผิดพลาดกับการแทรก (จำนวนคอลัมน์ไม่ตรงกัน) แต่เรายังสับสนกับสิ่งที่เกิดขึ้น

เมื่อดูข้อมูลการติดตามทั้งหมดคำสั่ง EXEC สำหรับโพรซีเดอร์ที่เก็บนี้ถูกแสดงรายการในบางครั้ง แต่ไม่เคยเกิดขึ้นก่อนที่ BLOCK จะเกิดขึ้นบน SPID การบล็อก ดูเหมือนว่าเมื่อมันเริ่มบล็อกการติดตามไม่ได้บันทึกการดำเนินการของมัน (หรือคำสั่งใด ๆ ที่อยู่ในนั้น) อย่างไรก็ตามมีบางครั้งที่ร่องรอยได้บันทึกการดำเนินการและไม่มีการปิดกั้น

รายงานข้อผิดพลาดของโพรซีเดอร์ที่เก็บมาจากผู้ใช้และฉันสามารถค้นหาคำสั่ง EXEC หลายรายการในการติดตามและเรียกใช้ใน SSMS ไม่มีเวลาเมื่อฉันวิ่งพวกเขาพวกเรามีการบล็อคเกิดขึ้นหรือพวกเขาแขวน พวกเขาวิ่งตามที่คาดไว้ (catch catch fired และย้อนกลับธุรกรรมหลังจากข้อผิดพลาด) หลังจากแก้ไขการแก้ไขขั้นตอนการจัดเก็บแล้วเรายังไม่เห็นปัญหาอีก


ฉันสมมติว่าชื่อโฮสต์ของการปิดกั้น SPID ไม่ได้ช่วยอะไรเลยใช่ไหม
Jon Seigel

ไม่มันเป็นเพียง IP ของหนึ่งใน webservers ของเรา ... เรามีความคิดที่จะเปลี่ยนการเข้าสู่ระบบ SQL ทุกครั้งสำหรับการโทร SPROC แต่ละครั้งในระหว่างกระบวนการเข้าสู่ระบบ / การลงทะเบียน (ซึ่งเรารู้สึกว่าเป็นที่ที่ข้อผิดพลาดเกิดขึ้น) ช่วยเราแยก SPROC ที่จะทำให้เกิดการบล็อก
แบรด

1
TRY / CATCH จะไม่พบข้อผิดพลาดในการรวบรวมและการแทรกคอลัมน์ที่ไม่ตรงกันจะเป็นข้อผิดพลาดในการรวบรวม สิ่งนี้จะไม่ทำให้เกิดเหตุการณ์ของตัวสร้างโปรไฟล์ XX: ที่เสร็จสมบูรณ์จำนวนมาก
Remus Rusanu

1
มันไม่ใช่ข้อผิดพลาดในการคอมไพล์ในกรณีนี้เพราะนักพัฒนาอัจฉริยะใช้ INSERT INTO [ตาราง] SELECT * จาก [Othertable] และมันไม่ได้ติดอยู่ในกลุ่มเดียวกัน ฉันใช้ SPROC ในการพัฒนา 1,000 ครั้งจาก ColdFusion ใน 3 เซสชันพร้อมกันและไม่เคยเปิดธุรกรรมเช่นเดียวกับในการผลิต
แบรด

คำตอบ:


10

จากความคิดเห็นฉันเดาว่าคุณมีการหมดเวลาคำสั่งฝั่งไคลเอ็นต์ที่ยกเลิกการสืบค้น SQL สิ่งนี้ไม่ย้อนกลับธุรกรรมเนื่องจากการเชื่อมต่อเปิดอยู่บน SQL Server เนื่องจากการเชื่อมต่อร่วมกัน

ดังนั้นคุณต้องใช้ SET XACT_ABORT ON หรือเพิ่มรหัสย้อนกลับลูกค้าบางส่วน

ดูการหมดเวลาธุรกรรมเซิร์ฟเวอร์ SQLสำหรับรายละเอียดเลือดทั้งหมด


SPROCs ทั้งหมดของเรามีบล็อค TRY / CATCH และคำสั่ง BEGIN TRAN / COMMIT TRAN / ROLLBACK TRAN, ROLLBACK อยู่ใน CATCH XACT_ABORT จะยังคงมีผลหรือไม่
แบรด

@Brad: ใช่ ดูลิงค์ของฉัน บล็อก catch ไม่ถูกโจมตีใน CommandTimeout
gbn

gbn: ขอบคุณ ฉันยังสับสนอยู่ การเชื่อมต่อของเราถูกตั้งค่าเป็นไม่หมดเวลา (0) ดังนั้นคุณกำลังบอกว่าถ้าเราใช้การเชื่อมต่ออีกครั้งและการเชื่อมต่อรัน SPROC ด้วยข้อผิดพลาด (ที่มีบล็อค TRY / CATCH และ TRAN) ก็ไม่สามารถเรียกใช้ ROLLBACK ในบล็อก CATCH ได้ดังนั้นจึงล็อคตารางและรักษาธุรกรรมไว้ เปิด? นั่นไม่สมเหตุสมผลสำหรับฉัน
แบรด

@Brad: SPROC ที่มีข้อผิดพลาดจะกด CATCH block ฉันไม่ได้พูดอย่างอื่นหรือแตกต่าง แต่ลิงค์ของฉันระบุว่าจะเกิดอะไรขึ้นถ้าคุณมี CommandTimeout ซึ่งแตกต่างจาก ConnectionTimeout ลูกค้าแจ้งว่า "ยกเลิก" และ SQL Server หยุดการประมวลผล Ergo, บล็อกที่จับได้หรือย้อนกลับหรือกระทำไม่เคยตี
GBN

ฉันไม่คิดว่าเรามี CommandTimeout ที่ระบุ ขั้นตอนการจัดเก็บทั้งหมดของเรากำลังทดสอบโดยใช้ sqlstress และจะต้องดำเนินการไม่เกิน 1,000 มิลลิวินาทีที่ผู้ใช้ 10 คนทำซ้ำ 10 ครั้ง (อย่างน้อยที่สุด) ฉันยังสับสนอยู่มากเกี่ยวกับสิ่งที่เกิดขึ้น แต่ฉันกำลังอัปเดตคำถามด้วยสิ่งที่เราพบว่าเป็นปัญหา
แบรด

9

ใช้ Most_recent_sql_handle ใน sys.dm_exec_connections เพื่อดูคำสั่งสุดท้ายที่ถูกดำเนินการ

SELECT  t.text,
        QUOTENAME(OBJECT_SCHEMA_NAME(t.objectid, t.dbid)) + '.'
        + QUOTENAME(OBJECT_NAME(t.objectid, t.dbid)) proc_name,
        c.connect_time,
        s.last_request_start_time,
        s.last_request_end_time,
        s.status
FROM    sys.dm_exec_connections c
JOIN    sys.dm_exec_sessions s
        ON c.session_id = s.session_id
CROSS APPLY sys.dm_exec_sql_text(c.most_recent_sql_handle) t
WHERE   c.session_id = 72;--your blocking spid

ตรวจสอบด้วยว่ามีการทำธุรกรรมแบบเปิดสำหรับ spid นั้นหรือไม่

SELECT  st.transaction_id,
        at.name,
        at.transaction_begin_time,
        at.transaction_state,
        at.transaction_status
FROM    sys.dm_tran_session_transactions st
JOIN    sys.dm_tran_active_transactions at
        ON st.transaction_id = at.transaction_id
WHERE   st.session_id = 72;--your blocking spid

คุณสามารถใช้DBCC INPUTBUFFER(spid)เพื่อดู SQL ที่ดำเนินการล่าสุด
Mike Fal

ฉันได้ใช้สิ่งเหล่านี้ทั้งหมดและคำสั่งสุดท้ายคือสิ่งที่ฉันใส่ไว้ในโพสต์ต้นฉบับของฉัน: SET TRANSACTION ISOLATION LEVEL ระดับที่อ่านได้กระทำ ฉันยังรัน DBCC OPENTRAN และจะเห็นว่ามีธุรกรรมเปิดสำหรับการบล็อก PID
แบรด

การเลือกครั้งแรกของฉันจะให้ชื่อขั้นตอนแก่คุณเช่นกันหากข้อความนั้นเป็นส่วนหนึ่งของขั้นตอน
เซบาสเตียนมีน

ฉันรับรองว่าคุณใช้คำสั่ง adhoc จากเว็บเซิร์ฟเวอร์ของเราและเมื่อฉันเรียกใช้แบบสอบถามครั้งแรกแม้ว่าไม่มีส่วนคำสั่ง WHERE ฉันจะได้รับชื่อ SPROC เพียงไม่กี่ครั้งใน SQL ช่วงที่เหลือคอลัมน์นั้นเป็น NULL
แบรด

ฉันสังเกตเห็นว่าฉันมีเซสชันจำนวนมากที่บอกว่า 'SET TRANSACTION ISOLATION LEAD READ COMMITTED' และทั้งหมดนั้นมาจาก ColdFusion (สคริปต์หลักที่ใช้บนเว็บเซิร์ฟเวอร์ของเรา) บางที ColdFusion เมื่อไม่ได้ใช้งานจะมีคำสั่งให้เปิดการเชื่อมต่อ (เนื่องจากเป็นการตั้งค่าให้เปิดการเชื่อมต่อไว้)
แบรด

4

คุณเคยลองใช้sp_whoisactiveของ Adam Machanic หรือไม่? มีตัวเลือกในการรับคำสั่ง outer เพื่อดูว่าจริง ๆ อยู่ใน proc อาจเป็นแอปพลิเคชันที่ถือเปิดธุรกรรมแทนการกระทำ ลองดูที่DBCC OPENTRANเช่นกัน


ขอบคุณสำหรับ DBCC OPENTRAN มันบอกฉันว่าการปิดกั้น PID มีธุรกรรมเปิด แต่ไม่มีรายละเอียดเพิ่มเติม sp_whoisactive ส่งกลับข้อมูลเดียวกันในกระบวนการที่ถูกบล็อกเนื่องจากฉันสามารถทำได้ด้วยตัวเอง ยังไม่มีรายละเอียดว่าเกิดอะไรขึ้นนอกจาก 'SET TRANSACTION ISOLATION LEAD READ COMMITTED'
Brad
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.