วันนี้ฉันค้นพบฮาร์ดไดรฟ์ที่เก็บฐานข้อมูลของฉันเต็ม สิ่งนี้เคยเกิดขึ้นมาก่อนโดยปกติสาเหตุจะชัดเจนมาก มักจะมีแบบสอบถามที่ไม่ดีซึ่งทำให้เกิดการรั่วไหลขนาดใหญ่เพื่อ tempdb ซึ่งเติบโตขึ้นจนดิสก์เต็ม คราวนี้มันเห็นได้ชัดน้อยลงว่าเกิดอะไรขึ้นเนื่องจาก tempdb ไม่ได้เป็นสาเหตุของไดรฟ์เต็มรูปแบบมันเป็นฐานข้อมูลของตัวเอง
ข้อเท็จจริง:
- ขนาดฐานข้อมูลปกติประมาณ 55 GB เพิ่มขึ้นเป็น 605 GB
- ไฟล์บันทึกมีขนาดปกติและมีขนาดใหญ่มาก
- Datafile มีพื้นที่ว่าง 85% (ฉันตีความว่าเป็น 'อากาศ': พื้นที่ที่ใช้ แต่ได้รับการปล่อยให้ว่างแล้ว SQL Server จะสำรองพื้นที่ทั้งหมดเมื่อจัดสรรแล้ว)
- ขนาด Tempdb เป็นปกติ
ฉันได้พบสาเหตุที่น่าจะเป็น; มีหนึ่งแบบสอบถามที่เลือกแถวมากเกินไป (การรวมที่ไม่ดีทำให้เกิดการเลือก 11 พันล้านแถวซึ่งคาดว่าสองแสนคน) นี่คือSELECT INTO
แบบสอบถามซึ่งทำให้ฉันสงสัยว่าสถานการณ์ต่อไปนี้อาจเกิดขึ้น:
- SELECT INTO ถูกใช้งาน
- สร้างตารางเป้าหมายแล้ว
- ข้อมูลถูกแทรกขณะที่ถูกเลือก
- ดิสก์เต็มทำให้การแทรกล้มเหลว
- SELECT INTO ถูกยกเลิกและย้อนกลับ
- การย้อนกลับเพิ่มพื้นที่ว่าง (ข้อมูลที่แทรกไว้แล้วจะถูกลบ) แต่ SQL Server จะไม่ปล่อยพื้นที่ว่าง
ในสถานการณ์นี้ แต่ฉันจะไม่คาดหวังว่าตารางที่สร้างขึ้นโดยSELECT INTO
ยังคงมีอยู่มันควรจะถูกทิ้งโดยการย้อนกลับ ฉันทดสอบสิ่งนี้:
BEGIN TRANSACTION
SELECT T.x
INTO TMP.test
FROM (VALUES(1))T(x)
ROLLBACK
SELECT *
FROM TMP.test
ผลลัพธ์นี้ใน:
(1 row affected)
Msg 208, Level 16, State 1, Line 8
Invalid object name 'TMP.test'.
แต่ตารางเป้าหมายนั้นมีอยู่จริง แบบสอบถามที่เกิดขึ้นจริงไม่ได้ถูกดำเนินการในธุรกรรมที่ชัดเจน แต่นั่นสามารถอธิบายการมีอยู่ของตารางเป้าหมายได้หรือไม่
สมมติฐานที่ฉันร่างที่นี่ถูกต้อง? นี่เป็นสถานการณ์ที่น่าจะเกิดขึ้นหรือไม่