Cómo reclamar el espacio ocupado por un índice que se construyó parcialmente y fue terminado por un corte de energía

9

Estoy ejecutando postgres (postgis) 9.4.2 en una mac (10.10.4).

Tengo un par de mesas grandes (varias TB).

Durante la creación de un índice en uno de ellos que dura aproximadamente una semana, vi caer el espacio disponible en HD, ya que esperarías cerca del punto en que el índice se terminaría cuando un corte de energía durara más que la unidad de batería y el sistema bajó Tenía buffers desactivados y fillfactor=100durante la compilación ya que es una fuente de datos estática. Al reiniciar, el espacio disponible que queda en la unidad es exactamente donde estaba casi al final de la compilación del índice. El análisis de vacío no libera el espacio.

Intenté dejar caer la mesa y volver a ingerir, y eso no dejó caer el espacio. Ahora estoy en un lugar donde no tengo suficiente espacio para construir el índice.

¿Los archivos generados durante la creación del índice están atrapados en algún limbo donde el sistema no puede eliminarlos debido a la forma en que la máquina se cayó durante el corte de energía?

Cuando miro los tamaños de tabla + índices en la base de datos (que son los únicos datos en esa unidad) suman aproximadamente 6 TB . La unidad es de 8 TB , y quedan menos de 500 GB en la unidad, por lo que parece que hay aproximadamente 1.5 TB perdidos en algún lugar, que es aproximadamente del tamaño que habría sido el índice.

¿Algunas ideas?

dkitchel
fuente
¿El índice todavía aparece con una consulta como esta? SELECT r.relname, r.relkind, n.nspname FROM pg_class r INNER JOIN pg_namespace n ON r.relnamespace = n.oid WHERE relkind = 'i';
Kassandry
No, no aparece en los resultados de esa consulta.
dkitchel
1
¿Tienes algo en la lista que SELECT indexrelid::regclass, indrelid::regclass FROM pg_catalog.pg_index WHERE NOT indisvalid;te da?
dezso
No, eso sale vacío.
dkitchel

Respuestas:

5

Normalmente, esperaríamos que cuando se reiniciara postgres, el proceso de recuperación de fallos hubiera eliminado archivos relacionados con un índice retrotraído del directorio de datos.

Supongamos que no funcionó, o al menos que debe verificarse manualmente.

La lista de archivos que deberían estar en el datadir se puede establecer con una consulta como esta:

select pg_relation_filenode(oid)
   from pg_class
  where relkind in ('i','r','t','S','m')
    and reltablespace=0
  order by 1;

reltablespace=0es para el espacio de tabla predeterminado. Si el índice problemático se creó en un espacio de tabla no predeterminado, se 0debe reemplazar por su OID en pg_tablespace.

i, r, t, S, m en relkindcorresponden respectivamente a índices, tablas, espacio de tostado, secuencias, vistas materializadas. Todos estos objetos tienen sus datos en archivos cuyos nombres coinciden pg_relation_filenode(oid).

En el disco, los archivos de datos están debajo de $PGDATA/base/oid/dónde oidestá oidla base de datos obtenida por select oid,datname from pg_database. Si no estamos hablando del espacio de tabla predeterminado, basese reemplaza por en su PG_version_somelabellugar.

Liste y ordene los archivos que coincidan con los relfilenodes en ese directorio:

ls | grep -E '^[0-9]+$' | sort -n > /tmp/list-of-relations.txt

(que en realidad solo mantiene el primer segmento para relaciones que son mayores a 1 Gb. Si hay segmentos persistentes que no están unidos a nada, deben considerarse por separado)

y diferencie ese archivo con el resultado de la consulta anterior.

Si hay archivos de datos persistentes que no corresponden a ningún objeto que el db conozca, deberían aparecer en esa diferencia.

Daniel Vérité
fuente
¡Increíble! Encontré 1 archivo en el datadir que no se mostraba en la lista de selección. ¿Puedo eliminar ese archivo de manera segura?
dkitchel
En realidad, corresponde a unos 800 archivos con iteraciones después del punto, todos como 499807.484, etc. ¿Puedo eliminar esos archivos de forma segura?
dkitchel
@dkitchel: eso sería segmentos de 1Gb cada uno para el gran índice. Tal vez verifique que sus marcas de tiempo coincidan con cuando se estaba ejecutando el índice de creación. En cuanto a eliminarlos, bueno, espero que mi razonamiento anterior sea correcto, pero son sus datos, ¡así que finalmente es su decisión!
Daniel Vérité
Sí, las marcas de tiempo son consistentes con el momento en que se estaba creando el índice, y la suma de los tamaños de archivo aproximadamente corresponde con el tamaño del índice. Tu razonamiento parece sólido. Lo intentaré con mucha confianza. Gracias una tonelada.
dkitchel
Simplemente haga un seguimiento para que otros que se encuentren en la misma situación puedan usar la solución de @DanielVerite con confianza. Su solución realmente funcionó perfectamente para mí.
dkitchel