LATCH_EX รอทรัพยากร METADATA_SEQUENCE_GENERATOR


11

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

กระบวนการฐานข้อมูลสำหรับการประมวลผลแต่ละกลุ่มรวบรวมข้อมูลลงในตาราง #Temporary ในตอนท้ายของแต่ละชิ้นประมวลผลข้อมูลจะถูกเขียนไปยังตารางถาวรใน tempdb ในที่สุดเมื่อสิ้นสุดกระบวนการหนึ่งเธรดที่ฝั่งไคลเอ็นต์ร้องขอข้อมูลทั้งหมดจากตาราง tempdb ถาวร

ยิ่งผู้ใช้ที่เรียกใช้รายงานนี้ยิ่งได้รับช้า ฉันวิเคราะห์กิจกรรมในฐานข้อมูล ณ จุดหนึ่งฉันเห็นคำขอ 35 รายการที่ถูกบล็อกทั้งหมดถูกบล็อก ณ จุดหนึ่งในกระบวนการ SPIDs ทั้งหมดเหล่านี้ได้ในคำสั่งของ 50 มิลลิวินาทีรอประเภททรัพยากรLATCH_EX METADATA_SEQUENCE_GENERATOR (00000010E13CA1A8)SPID หนึ่งมีทรัพยากรนี้และอื่น ๆ ทั้งหมดกำลังบล็อก ฉันไม่พบสิ่งใดเกี่ยวกับทรัพยากรการรอนี้ในการค้นหาเว็บ

ตารางใน tempdb ที่เราใช้อยู่มีIDENTITY(1,1)คอลัมน์ SPID เหล่านี้กำลังรอคอลัมน์ประจำตัวหรือไม่ เราสามารถใช้วิธีการใดในการลดหรือกำจัดการบล็อก

เซิร์ฟเวอร์เป็นส่วนหนึ่งของคลัสเตอร์ เซิร์ฟเวอร์กำลังเรียกใช้ SQL Server 2012 Standard Edition SP1 64 บิตใน Windows 2008 R2 Enterprise 64 บิต เซิร์ฟเวอร์มีตัวประมวลผล 64 GB และ 48 แต่ฐานข้อมูลสามารถใช้ 16 เท่านั้นเนื่องจากเป็นรุ่นมาตรฐาน

(โปรดทราบว่าฉันไม่ได้ตื่นเต้นกับการออกแบบการใช้ตารางถาวรใน tempdb เพื่อเก็บข้อมูลทั้งหมดนี้การเปลี่ยนแปลงที่เป็นความท้าทายด้านเทคนิคและการเมืองที่น่าสนใจ แต่ฉันเปิดรับข้อเสนอแนะ)

UPDATE 4/23/2013

เราได้เปิดเคสการสนับสนุนกับ Microsoft ฉันจะเก็บคำถามนี้ไว้เมื่อเราเรียนรู้เพิ่มเติม

UPDATE 5/10/2556

วิศวกรฝ่ายสนับสนุนของ SQL Server ยอมรับว่าการรอเกิดจากคอลัมน์ตัวตน การลบตัวตนจะช่วยลดการรอคอย เราไม่สามารถซ้ำปัญหาใน SQL 2008 R2; มันเกิดขึ้นเฉพาะใน SQL 2012


กระบวนการเป็นหลักคัดลอกข้อมูลจากตาราง #Temporary ไปยังตารางถาวรหรือมีตรรกะการแปลงเพิ่มเติมที่เกิดขึ้นในขั้นตอนนั้นหรือไม่
Jon Seigel

ในขั้นตอนที่มันกำลังรอมันกำลังคัดลอกบันทึกสินค้าคงคลังของร้านค้าเดียวลงในตารางถาวรโดยไม่มีการแปลง เราสามารถทำงานภายในตารางถาวรตลอดเวลา แต่ฉันคิดว่าโปรแกรมเมอร์เลือกใช้ #Temporary table เป็นพื้นที่พักเพื่อป้องกันการอัพเดทข้อมูลเป็นประจำจากการแปลงเป็นล็อค PAGE
พอลวิลเลียมส์

คำตอบ:


4

สมมติว่าคุณสามารถแยกปัญหาการสร้างค่าเอกลักษณ์ (ลองลบคอลัมน์นั้นเป็นการทดสอบ) สิ่งที่ฉันอยากจะแนะนำคือ:

  1. ลบIDENTITYคุณสมบัติออกจากคอลัมน์ในตารางสุดท้าย
  2. สร้างค่าเอกลักษณ์ในแต่ละตาราง #Temporary
  3. เมื่อโหลดตารางสุดท้ายให้รวมตัวระบุตัวเลขสำหรับร้านค้าเฉพาะกับค่าเอกลักษณ์จากขั้นตอนที่ 2

ดังนั้นถ้าคุณมีรหัสร้านค้า 3 และ 4 คุณจะต้องจบด้วยค่ารหัสสุดท้ายดังนี้:

3000000001
3000000002
3000000003
...
4000000001
4000000002
...

หรืออะไรทำนองนั้น คุณได้รับความคิด

สิ่งนี้จะขจัดความจำเป็นในการซีเรียลIDENTITYไลซ์เซชั่นในขณะที่รักษาเอกลักษณ์ในผลลัพธ์สุดท้าย

อีกทางหนึ่งขึ้นอยู่กับวิธีการทำงานของกระบวนการแทรกค่า id ที่คำนวณขั้นสุดท้ายลงในตาราง #Temporary จากนั้นคุณสามารถสร้างมุมมองที่UNION ALLรวมเข้าด้วยกันโดยไม่จำเป็นต้องคัดลอกข้อมูลเลย


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

@ พอล: โปรดแจ้งให้เราทราบ; ฉันแค่อยากรู้อยากเห็น เช่นเดียวกับคุณฉันไม่สามารถค้นพบอะไรบนเว็บเกี่ยวกับสลักนี้ แต่ก็มีเหตุผลที่แน่นอนว่ามันเป็นตัวตน / ลำดับซีเรียล ไม่ว่าจะเป็นคอขวดหรือไม่ก็ยากที่จะพูดแม้ว่าจะมีเธรดมากกว่า 30 รายการที่แข่งขันกันเพื่อหาค่า คุณสามารถลองคัดลอกจาก #Temporary แต่ละตารางเป็นอนุกรม (แทนที่จะขนาน) เพื่อดูว่ามีประโยชน์หรือไม่
Jon Seigel

2
วิศวกร SQL Server ตกลงว่าน่าจะเป็นIDENTITYคอลัมน์ เราลบออกจากดัชนีคลัสเตอร์แบบกว้างที่มีอยู่แล้วและลบคอลัมน์ทั้งหมด มันไม่จำเป็น หลังจากนั้น LATCH_EX เหล่านี้ก็หายไป เราไม่สามารถทำซ้ำการรอใน SQL 2008 R2 ได้ ปัญหาเกิดขึ้นเฉพาะใน SQL Server 2012
พอลวิลเลียมส์

@Paul: ขอบคุณสำหรับการติดตาม น่าสนใจมาก. ฉันเดาว่ารหัสที่สร้างIDENTITYค่าจะถูกเขียนใหม่เพื่อใช้สิ่งที่สร้างลำดับใหม่ที่ใหม่ในปี 2012 ใน <2012 คุณอาจเห็นประเภทสลักที่แตกต่างกันแม้ว่าจะไม่มีปัญหาเพอร์เฟคก็ตามดูเหมือนว่า การถดถอยในรหัส ไม่ว่าในกรณีใดการลบIDENTITYคอลัมน์เป็นสิ่งที่ปลอดภัยที่สุด
Jon Seigel

แทนที่จะเป็นตัวตนคุณสามารถลองใช้ 'ลำดับ' (ซึ่งเป็นของใหม่ใน SQL 2012)
Bogdan Maxim

7

(อัปเดตเมื่อกุมภาพันธ์ 2019)

นี่เป็นโพสต์เก่าที่กล่าวว่าในที่สุดฉันก็สามารถโน้มน้าวใจ Microsoft ได้ว่าข้อเท็จจริงที่เกิดขึ้นนี้เป็นข้อบกพร่องอย่างแน่นอน

อัปเดต: MS ยืนยันข้อบกพร่องและกำหนดข้อผิดพลาด # 12628722

ฉันได้เห็นโพสต์นี้เมื่อเดือนพฤศจิกายน 2018 เมื่อเราเริ่มประสบปัญหามากหลังจากเราอัพเกรดจาก Sql Server 2005 เป็น Sql Server 2017 ตาราง 3.3 ล้านแถวที่ใช้เวลา 10 วินาทีในการแทรกจำนวนมากเริ่มใช้เวลา 10 วินาที นาทีในตารางที่มีIdentityคอลัมน์

ปรากฎว่ามีสองประเด็นที่อยู่เบื้องหลัง:

  1. Microsoft เปลี่ยนพฤติกรรมใน Sql Server 2014 เพื่อบังคับให้แทรกจำนวนมากให้ทำงานแบบขนาน - ในรุ่นก่อนหน้าแทรกจำนวนมากได้รับแผนแบบอนุกรม
  2. เมื่อทำงานแบบขนานบนกล่อง 32 แกนของเราเครื่องยนต์ใช้เวลามากขึ้นกับแกนล็อคซึ่งกันและกันมากกว่าการใช้งานจริง

เอาฉัน 4 สัปดาห์ แต่หลังจากวันหยุดฉันได้รับของขวัญล่าช้าจากซานต้า - ยืนยันว่าปัญหานั้นเป็นข้อบกพร่องแน่นอน

มีวิธีแก้ปัญหาที่เป็นไปได้สองสามอย่างที่เราพบจนกระทั่งสิ่งนี้ได้รับการแก้ไข:

  1. ใช้Option (MaxDop 1)ในแบบสอบถามเพื่อเปลี่ยนการแทรกจำนวนมากกลับไปเป็นแผนอนุกรม
  2. ปิดบังคอลัมน์ Identity โดยการคัดเลือก (เช่นSelect Cast(MyIdentityColumn As Integer) As MyIdentityColumn)
    • สิ่งนี้ป้องกันไม่ให้มีการคัดลอกคุณสมบัติของข้อมูลประจำตัวเมื่อใช้ SELECT...INTO
  3. ลบคอลัมน์ข้อมูลประจำตัวตามที่อธิบายไว้ข้างต้น
  4. เปลี่ยนโหมดความเข้ากันได้ของฐานข้อมูลเป็น Sql Server 2012 หรือต่ำกว่าเพื่อสร้างแผนที่ต่อเนื่องกันอีกครั้ง

อัปเดต: โปรแกรมแก้ไข MS จะนำไปใช้จะคืนค่าส่วนแทรกเหล่านี้กลับไปใช้ Serialized แผน สิ่งนี้มีการวางแผนสำหรับSQL Server 2017 CU14 (ไม่มีข่าวเกี่ยวกับ SQL Server รุ่นอื่น - ขอโทษ!) เมื่อดำเนินการติดตามสถานะ9492 DBCC TraceOnจะต้องมีการเปิดใช้งานทั้งในระดับเซิร์ฟเวอร์หรือผ่านทาง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.