ความแตกต่างระหว่างระดับแถวและการล็อกระดับหน้าและผลที่ตามมา


10

เมื่อพยายามเรียกใช้แผนการบำรุงรักษาของฉันฉันได้รับข้อผิดพลาดต่อไปนี้:

การดำเนินการค้นหา "" ล้มเหลวโดยมีข้อผิดพลาดต่อไปนี้: "ดัชนี" "(พาร์ติชัน 1) บนตาราง" "ไม่สามารถจัดระเบียบใหม่ได้เนื่องจากการล็อกระดับหน้าถูกปิดใช้งาน"

ขณะนี้เราเปิดใช้งานการล็อกแถวระดับบนดัชนีนี้ ฉันสามารถเปิดใช้งานการล็อกระดับหน้าได้ แต่ไม่แน่ใจว่าผลสะท้อนกลับคืออะไร

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

คำตอบ:


14

การดำเนินการค้นหา "" ล้มเหลวโดยมีข้อผิดพลาดต่อไปนี้: "ดัชนี" "(พาร์ติชัน 1) บนตาราง" "ไม่สามารถจัดระเบียบใหม่ได้เนื่องจากการล็อกระดับหน้าถูกปิดใช้งาน"

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

ความแตกต่างระหว่างสองรูปแบบการล็อกคืออะไรและผลที่ตามมาในโลกแห่งความเป็นจริงของพวกเขา (ในการผลิต) คืออะไร?

คุณต้องเข้าใจว่าระเบียนและหน้าใดที่จะประเมินผลกระทบของการไม่อนุญาตให้ล็อคประเภทใดประเภทหนึ่ง ถ้าคุณไม่คุ้นเคยกับ SQL Server internals จัดเก็บเริ่มต้นด้วยกายวิภาคของการบันทึกและกายวิภาคของหน้า พูดง่าย ๆ :

  • แถว = บันทึก
  • แถวจะถูกเก็บไว้ในหน้า 8kb

หากคุณต้องการเปลี่ยนประเภทการล็อคที่อนุญาต:

  • ปิดใช้งานการล็อกหน้า = ล็อคแถวและตารางเท่านั้น
  • ปิดใช้งานการล็อกแถว = การล็อกหน้าและตารางเท่านั้น
  • ปิดใช้งานทั้งคู่ = ล็อคตารางเท่านั้น

มีสองสถานการณ์ที่ฉันรู้ว่าจะเป็นประโยชน์ต่อการไม่อนุญาตประเภทการล็อคได้อย่างไร ไม่ได้หมายความว่าไม่มีคนอื่นหวังว่าคนอื่นจะเข้ามามีส่วนร่วม

ตารางการค้นหาที่เข้าถึงบ่อยครั้งซึ่งมีการเปลี่ยนแปลงไม่บ่อยนัก - โดยการปิดใช้งานการล็อกทั้งระดับหน้าและแถวผู้อ่านทั้งหมดจะใช้การล็อคตารางที่ใช้ร่วมกัน นี่คือเร็วกว่า / ถูกกว่าแทนที่จะใช้ความตั้งใจร่วมกันตามปกติบนโต๊ะตามด้วยการแชร์โดยเจตนาบนหน้าเว็บและในที่สุดก็เป็นการล็อคที่ใช้ร่วมกันในแถวหรือแถวที่ระบุ

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

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

ค่าเริ่มต้นคือการเปิดใช้งานทั้งคู่และสิ่งนี้ไม่ควรเปลี่ยนแปลงโดยไม่มีสาเหตุที่ดี


9

อาจจะไม่มีอะไร ฉันแน่ใจว่า MS รู้ดีกว่าคุณหรือฉัน

ฉันทำงานกับระบบ OLTP ที่มีปริมาณมากและไม่เคยรู้สึกว่าจำเป็นต้องเปลี่ยนการตั้งค่า ควรหยุดการล็อคอีกครั้งเพราะจะเกิดขึ้นต่อไป

การอ้างอิงจากบล็อก SQL Server Storage Engine บล็อก "ล็อคการเลื่อนระดับใน SQL2005" n ซึ่งมีค่าในการอ่านอย่างสมบูรณ์อยู่ดี

โดยค่าเริ่มต้นเรามีการเปิดใช้งานทั้ง ROW และ PAGE ล็อค ... SQL Server เลือก granularity ล็อค ROW สำหรับกรณีส่วนใหญ่ แต่อาจเลือก PAGE lock ตามความเหมาะสม ดังนั้นสำหรับกรณีที่คุณระบุ ROW lock น่าจะเป็น ไม่มีวิธีปิดการล็อกหน้าในระดับฐานข้อมูลหรืออินสแตนซ์ คุณกำลังเผชิญหน้ากับการบล็อกเนื่องจากล็อคหน้าหรือไม่

ฉันคิดว่าถ้าคุณบังคับให้ rowlocks เท่านั้นคุณจะใช้ทรัพยากรที่สามารถใช้ได้อย่างมีประสิทธิภาพมากขึ้นที่อื่น หากโหลดของคุณสูงพอที่จะใช้งานได้เหตุใดจึงต้องใช้หน่วยความจำ บทความในบล็อกนี้

ฉันสงสัยว่ามีความเชื่อโชคลางอยู่เบื้องหลังเช่นนี้:


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