ฉันจะเพิ่มคอลัมน์ rowversion ลงในตารางขนาดใหญ่โดยมีเวลาหยุดทำงานน้อยที่สุดได้อย่างไร


21

ใช้ SQL Server 2008 และใหม่กว่าฉันต้องการเพิ่มคอลัมน์ rowversion ในตารางขนาดใหญ่อย่างไรก็ตามเมื่อฉันเพียงแค่

ALTER TABLE [Tablename]
ADD Rowversion [Rowversion] NOT NULL

จากนั้นตารางจะไม่พร้อมใช้งานสำหรับการอัปเดตนานเกินไป

ฉันสามารถใช้กลยุทธ์ใดในการลดเวลาหยุดทำงานนี้ ฉันจะพิจารณาอะไร แน่นอนง่ายกว่าดีกว่า แต่ฉันจะพิจารณากลยุทธ์ใด ๆ

ความคิดของฉันคือเป็นทางเลือกสุดท้ายฉันสามารถรักษาตารางการแสดงละครที่ปรับปรุงใหม่โดยทริกเกอร์แล้ว sp_rename ตาราง staging ลงในตารางเดิม แต่ฉันหวังว่าจะได้อะไรที่ง่ายกว่า / ง่ายกว่านี้

คำตอบ:


26

ลองสร้างตารางใหม่ที่มีสคีมาเหมือนกันบวกกับคอลัมน์ rowversion และเพิ่มมุมมองบนทั้งสองตารางที่รวมกันทั้งหมด ให้ผู้คนใช้มุมมองและเขียนทริกเกอร์แทนตารางและมุมมองพื้นฐาน

ควรแทรกส่วนแทรกลงในตารางใหม่การอัพเดตควรย้ายข้อมูลไปยังตารางใหม่และการลบควรถูกนำไปใช้กับทั้งสองตาราง

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

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

เมื่อต้องการหลีกเลี่ยงทริกเกอร์ที่เริ่มต้นเมื่อข้อมูลกำลังถูกโยกย้ายในแบตช์ให้ดูที่จำนวนแถวในตารางที่ถูกลบ / แทรกในทริกเกอร์และข้ามกิจกรรมหากพวกเขาอยู่ใกล้กับจำนวนแถวในแบทช์ของคุณ


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


7

หากคุณมีเวลาวางแผนล่วงหน้ามีวิธีแก้ปัญหาที่ง่ายกว่ามาก ... (ปกติ)

การล็อคแบบยาวนั้นเกิดจากการแยกหน้าในเลเยอร์การจัดเก็บ ดังนั้นบังคับพวกเขาในตารางของคุณเอง

  1. VARBINARY(8)เพิ่มคอลัมน์ชั่วคราวโมฆะสามารถกับประเภทข้อมูล
  2. ค้นหาเวลาเผื่อที่มีอยู่ในฐานข้อมูลเพื่ออัปเดตแบทช์ของระเบียนที่มีอยู่ด้วยค่าที่ถูกต้องสำหรับฟิลด์ ( 0x0000000027F95A5Bตัวอย่าง)
  3. การอัปเดตจะบังคับให้แยกหน้าที่จำเป็นและจัดสรรพื้นที่เพิ่มเติมให้กับตาราง
  4. เมื่อคุณจมลงให้วางคอลัมน์ชั่วคราว (ไม่ได้สัมผัสที่เก็บข้อมูลที่จัดสรร) และเพิ่มคอลัมน์ rowversion
  5. ไม่มีการแบ่งหน้าและการล็อกที่ต้องการนานพอที่จะเติมค่า

ฉันใช้มันสำเร็จแล้วในการเพิ่มคอลัมน์ rowversion ลงในตารางแถว 150M ในเวลาไม่ถึง 10 นาที

Caveat ... หากคุณมีตารางที่มีเขตข้อมูล varchar ขนาดใหญ่ (โดยเฉพาะvarchar(max)) SQL Server ตัดสินใจที่จะสร้างตารางใหม่แทนที่จะใช้พื้นที่ว่างที่มีอยู่ใหม่ ยังคงพยายามหาทางรอบ ๆ ที่


น่าสนใจฉันเดาว่าไม่ได้ระบุว่า "ยาวเกินไป" ในคำถามของฉัน หาก> 30 นาทียาวเกินไปสำหรับสถานการณ์ของคุณและยอมรับได้ 10 นาทีโซลูชันนี้จะใช้งานได้ สถานการณ์ของฉันเกี่ยวข้องกับการพยายามที่จะประสบความสำเร็จในการหยุดทำงานเป็นศูนย์หรือเฉพาะเจาะจง <10 วินาทีซึ่งคำตอบของเบรนต์ทำได้
Michael J Swart

1

หากTIMESTAMPคุณกำลังเพิ่มคือNULLABLE:

  1. เพิ่มVARBINARY(8)คอลัมน์
  2. เติมด้วยข้อมูล

หลังจากที่มีประชากรในกลับไปที่คำสั่ง SQL กลับคอลัมน์คุณเพียงแค่เพิ่มและมีประชากรและเพิ่มคอลัมน์DROPVARBINARY(8)TIMESTAMP NULL


หากTIMESTAMPคุณกำลังเพิ่มคือNOT NULLABLE:

  1. เพิ่มBINARY(8)คอลัมน์
  2. เติมด้วยข้อมูล

หลังจากที่มีประชากรในกลับไปที่คำสั่ง SQL กลับคอลัมน์คุณเพียงแค่เพิ่มและมีประชากรและคอลัมน์DROPBINARY(8)ADD THE TIMESTAMP NOT NULL

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