今天,我发现存储我的数据库的硬盘驱动器已满。这是以前发生的,通常原因很明显。通常会有一个错误的查询,这会导致大量的溢出到tempdb,直到磁盘装满为止。这次不太清楚发生了什么,因为tempdb不是驱动器满载的原因,而是数据库本身。
事实:
- 通常的数据库大小约为55 GB,后来增加到605 GB。
- 日志文件大小正常,数据文件很大。
- 数据文件具有85%的可用空间(我将其解释为“空气”:已使用但已释放的空间。SQLServer分配后将保留所有空间)。
- Tempdb大小正常。
我发现了可能的原因;有一个查询选择了太多行的查询(错误的联接会导致选择110亿行,预计会有几十万行)。这是一个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'.
但是目标表确实存在。但是,实际查询不是在显式事务中执行的,这可以解释目标表的存在吗?
我在这里勾勒出的假设是否正确?这是否可能发生过?