Hoy descubrí que el disco duro que almacena mis bases de datos estaba lleno. Esto ha sucedido antes, generalmente la causa es bastante evidente. Por lo general, hay una mala consulta, lo que provoca que se produzcan grandes derrames en tempdb que crece hasta que el disco está lleno. Esta vez fue un poco menos evidente lo que sucedió, ya que tempdb no fue la causa del disco completo, sino la base de datos en sí.
Los hechos:
- El tamaño habitual de la base de datos es de aproximadamente 55 GB, creció a 605 GB.
- El archivo de registro tiene un tamaño normal, el archivo de datos es enorme.
- El archivo de datos tiene un 85% de espacio disponible (interpreto esto como 'aire': espacio que se utilizó, pero se ha liberado. SQL Server reserva todo el espacio una vez asignado).
- El tamaño de tempdb es normal.
He encontrado la causa probable; hay una consulta que selecciona demasiadas filas (la unión incorrecta provoca la selección de 11 mil millones de filas donde se esperan un par de cientos de miles). Esta es una SELECT INTO
consulta, que me hizo preguntarme si el siguiente escenario podría haber sucedido:
- SELECT INTO se ejecuta
- Se crea la tabla de destino
- Los datos se insertan a medida que se seleccionan
- El disco se llena, haciendo que la inserción falle
- SELECT INTO es abortado y revertido
- La reversión libera espacio (los datos ya insertados se eliminan), pero SQL Server no libera el espacio liberado.
En esta situación, sin embargo, no hubiera esperado que la tabla creada por el SELECT INTO
todavía existiera, debería ser descartada por la reversión. Probé esto:
BEGIN TRANSACTION
SELECT T.x
INTO TMP.test
FROM (VALUES(1))T(x)
ROLLBACK
SELECT *
FROM TMP.test
Esto resulta en:
(1 row affected)
Msg 208, Level 16, State 1, Line 8
Invalid object name 'TMP.test'.
Sin embargo, la tabla de destino existe. Sin embargo, la consulta real no se ejecutó en una transacción explícita, ¿eso puede explicar la existencia de la tabla de destino?
¿Son correctas las suposiciones que bosquejé aquí? ¿Es probable que esto haya sucedido?
fuente