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.