ดูเหมือนว่าคิวรีลบขนาดใหญ่จะหยุดชะงัก


10

เราเรียกใช้คิวรีการลบในฐานข้อมูลที่มีแถว 1.8 พันล้าน การลบนี้จะลบแถว 1.2 พันล้าน

ในการเข้าใจย้อนหลังเราจะแยกแบบสอบถามนี้เป็น 100m ต่อครั้ง แต่เราอยู่ในตำแหน่งที่มีการเรียกใช้งานเป็นเวลา 24 ชั่วโมงและไฟล์บันทึกอยู่ที่ 2Tb ซึ่งดูเหมือนจะเป็นขนาดสูงสุดที่อนุญาตสำหรับไฟล์บันทึก

ฐานข้อมูลอยู่ในโหมดการกู้คืนแบบง่าย

มีการบันทึกแบบสอบถามนี้หรือไม่? หรือเราต้องรีสตาร์ทเซิร์ฟเวอร์ SQL และดูว่าเกิดอะไรขึ้น ฐานข้อมูลจะใช้ไม่ได้หรือไม่ มีอะไรที่เราสามารถทำได้เพื่อกำจัดสิ่งนี้ให้หมดจดที่สุด


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

1
@ Graeme จากประสบการณ์ของเรากับฐานข้อมูลหลายพันล้านระเบียน (เรากำลังเรียกใช้งานอยู่สองสามรายการ) บางครั้งมันเร็วกว่าที่จะบันทึกระเบียนที่เหลือจากตารางเหยื่อตัดทอนลบเปลี่ยนชื่อบันทึกที่บันทึกไว้กลับไปเป็นชื่อเดิม .
Anton Krouglov

1
เมื่อคุณเคลียร์สปินนี้แล้วฉันจะแนะนำแบตช์ที่มีขนาดเล็กกว่า 100 ม. ฉันมักจะทำ 100k ถึง 1m นอกจากนี้ใช้คีย์หลักของคุณเป็น WHERE clause ของคุณเพื่อเลือกระเบียนสำหรับการลบหากเป็นไปได้
BradC

ตัดเป็นเพื่อนของคุณเมื่อลบข้อมูลจำนวนมากและพยายามหลีกเลี่ยงปัญหาบันทึก
Jeff.Clark

คำตอบ:


14

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

แม้ว่าฉันจะชอบฆ่า spid ด้วยตนเองอยู่เสมอ (ใช้sp_who2หรือsp_WhoIsActiveค้นหา spid จากนั้นทำ a kill 59หรืออะไรก็ตาม) นอกจากนี้คุณยังไม่สามารถตรวจสอบสถานะการย้อนกลับจนกว่าคุณจะทำ KILL ชัดเจนดูหัวข้อที่เกี่ยวข้องนี้

เนื่องจากนี่เป็นการลบและไม่ใช่การอัปเดตหรือการแทรกคุณอาจโชคดีมากและพบว่ามันย้อนกลับไปทันที หากไม่เป็นเช่นนั้นอาจใช้เวลานาน (หรือนานกว่า) ในการย้อนกลับไปที่จุดนี้

หากต้องการดูสถานะการย้อนกลับให้ใช้

kill 59 with statusonly

น่าเสียดายที่ฉันพบว่าสิ่งนี้มักจะไม่แสดงผลใด ๆ ที่มีประโยชน์เพียงแค่ "เสร็จ 0%" ในกรณีนี้คุณจะต้องใช้sp_who2และดู IO และ CPU เพื่อดูว่ายังทำอะไรอยู่หรือไม่

เกี่ยวกับการรีบูตนี่เป็นความเสี่ยงที่ร้ายแรง หาก spid กำลังย้อนกลับอย่างแข็งขัน (CPU และ IO กำลังเปลี่ยนแปลง) การรีสตาร์ท SQL จะทำให้ออฟไลน์ฐานข้อมูลทั้งหมดเท่านั้นจนกว่าการย้อนกลับจะเสร็จสิ้นสมบูรณ์ (ชั่วโมงและชั่วโมง) แต่ถ้า CPU และ IO ไม่เคลื่อนไหวดังนั้นในความเป็นจริงมันอาจชัดเจนทันที ไม่ว่าจะด้วยวิธีใดมันเป็นความเสี่ยง

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

ถ้าคุณไม่สามารถปล่อย DB (หรือถ้าคุณรีสตาร์ตอินสแตนซ์แล้วและ errorlog sql กำลังทำนายเวลาการกู้คืน 24 ชั่วโมง) จากนั้นปิดบริการ SQL ลบไฟล์ MDF และ LDF จากดิสก์เริ่มต้น SQL, ปล่อย ฐานข้อมูล (ghost) และกู้คืนจากการสำรองข้อมูล

เห็นได้ชัดว่าคุณพยายามที่จะถ้าเป็นฐานข้อมูลการประมวลผลส่วนหลังที่ผู้ใช้ไม่ได้โต้ตอบ


3
คำแนะนำที่ดีเกี่ยวกับตัวเลือกการคืนค่า น่ากลัวเหมือนนรก แต่ก็ยังมีคำแนะนำที่ดี
Max Vernon

2
ใช่เรามี DBA รีสตาร์ทอินสแตนซ์ในสภาพนี้ซึ่งบังคับให้เราตัดสินใจระหว่างตัวเลือกที่แย่มากสองตัวเลือก: ลงเป็นเวลา 18-24 ชั่วโมงหรือสูญเสียข้อมูลโดยย้อนกลับไปก่อนที่จะเริ่มการสืบค้น ธุรกิจเลือกที่จะย้อนกลับ
BradC

1
เรามีการสำรองข้อมูลเต็มรูปแบบจากวันที่ 4 มีนาคมซึ่งเราจะกู้คืนเป็นทางเลือกสุดท้ายหากการรีบูตใช้งานไม่ได้ โชคดีที่มันเป็นฐานข้อมูลคงที่เพียงพอซึ่งเราแค่ต้องการลดทอนลง ขอบคุณสำหรับคำติชมมีประโยชน์มาก
Graeme

4
@Graeme - FYI - แทนที่จะพยายามลบ 1.2 พันล้านแถวสร้างสำเนาของโครงสร้างตารางคัดลอกแถวที่คุณต้องการเก็บไว้ในตารางใหม่จากนั้นปล่อยตารางเก่า หากคุณเพิ่มคำถามใหม่ที่ถามว่าจะทำอย่างไรฉันสามารถแสดงให้คุณเห็นวิธีที่ลื่นไหลซึ่งเร็วกว่าการลบ 1.2 พันล้านแถว
Max Vernon

คำตอบของฉันถือว่าฐานข้อมูลอยู่ในโหมดการกู้คืน SIMPLE ถ้ามันอยู่ในโหมดเต็มคุณจะต้องจัดการการสำรองข้อมูลทรานขนาดใหญ่เช่นกัน
BradC

8

ห้ามรีสตาร์ทเซิร์ฟเวอร์ SQL วิธีนี้จะช่วยยืดอายุความเจ็บปวดของคุณเนื่องจากการกู้คืนจะเกิดขึ้นซึ่งจะย้อนกลับหรือทำซ้ำธุรกรรมใด ๆ ที่ไม่เสร็จสมบูรณ์รวมถึงการลบของคุณ

การฆ่าเซสชันที่ใช้การลบจะส่งผลให้เกิดการย้อนกลับซึ่งจะใช้เวลานานกว่าจะเสร็จสมบูรณ์

คุณต้องการดูแบบสอบถามต่อไปนี้เพื่อดูสถานะของการดำเนินการ:

SELECT des.session_id 
    , des.host_name
    , des.login_name
    , der.command
    , der.estimated_completion_time
    , der.blocking_session_id
    , der.last_wait_type
    , der.percent_complete
    , der.start_time
    , der.status
    , der.wait_resource
    , der.wait_type
    , der.wait_time
FROM sys.dm_exec_sessions des
    INNER JOIN sys.dm_exec_requests der ON des.session_id = der.session_id
WHERE des.session_id <> @@SPID
    AND des.is_user_process = 1
ORDER BY des.session_id;

percent_completeคอลัมน์และผู้ที่พึ่งพาได้เช่นestimated_completion_timeมีประชากรเพียงสำหรับการดำเนินการดังต่อไปนี้:

ALTER INDEX REORGANIZE
AUTO_SHRINK option with ALTER DATABASE
BACKUP DATABASE
DBCC CHECKDB
DBCC CHECKFILEGROUP
DBCC CHECKTABLE
DBCC INDEXDEFRAG
DBCC SHRINKDATABASE
DBCC SHRINKFILE
RECOVERY
RESTORE DATABASE
ROLLBACK
TDE ENCRYPTION

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

หากblocking_session_idคอลัมน์มีตัวเลขแสดงว่าเซสชันอื่นกำลังบล็อกการดำเนินการลบ หากเซสชันนั้นบล็อกการดำเนินการลบตั้งแต่เริ่มต้นคุณอาจสามารถยกเลิกการดำเนินการได้โดยไม่ต้องย้อนกลับใด ๆ


ข้อความค้นหาที่ดี แต่ดูเหมือนว่าไม่น่าเป็นไปได้ที่บันทึกจะโตขึ้นมากหากการลบถูกบล็อก
BradC

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