Recientemente, he actualizado un servidor PostgreSQL 8.2.11 a 8.4 para aprovechar las características de vacío automático y estar en línea con otros 30 servidores PGSQL. Esto fue realizado por un grupo de TI independiente que administra el hardware, por lo que no tenemos muchas opciones en otras actualizaciones (no veremos 9+ por un tiempo). El servidor existe en un entorno muy cerrado (red aislada, privilegios de root limitados) y se ejecuta en RHEL5.5 (i686). Después de la actualización, la base de datos ha crecido constantemente hasta alcanzar los 5-6 GB por día. Normalmente, la base de datos, en su conjunto, es de ~ 20 GB; Actualmente, es ~ 89GB. Tenemos un par de otros servidores que ejecutan bases de datos equivalentes y en realidad sincronizan los registros entre sí a través de una aplicación de terceros (uno que no tengo acceso al funcionamiento interno). Las otras bases de datos son ~ 20GB como deberían ser.
Al ejecutar el siguiente SQL, es bastante obvio que hay un problema con una tabla en particular y, más específicamente, con su tabla TOAST.
SELECT nspname || '.' || relname AS "relation",
pg_size_pretty(pg_relation_size(C.oid)) AS "size"
FROM pg_class C
LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
WHERE nspname NOT IN ('pg_catalog', 'information_schema')
ORDER BY pg_relation_size(C.oid) DESC
LIMIT 20;
Que produce:
relación | Talla ------------------------------------ + --------- pg_toast.pg_toast_16874 | 89 GB fews00.warmstates | 1095 MB ... (20 filas)
Esta tabla TOAST es para una tabla llamada "series de tiempo" que guarda grandes registros de datos blobbados. Uno SUM(LENGTH(blob)/1024./1024.)
de todos los registros en series de tiempo produce ~ 16 GB para esa columna. No debería haber ninguna razón para que la tabla TOAST de esta tabla sea tan grande como es.
He realizado un VACUUM FULL VERBOSE ANALYZE timeseries
, y el vacío se ejecuta hasta su finalización sin errores.
INFO: aspirar "pg_toast.pg_toast_16874"
INFO: "pg_toast_16874": se encontraron 22483 versiones removibles, 10475318 no removibles en 10448587 páginas
DETALLE: 0 versiones muertas aún no se pueden eliminar.
Las versiones de fila no extraíbles varían de 37 a 2036 bytes de longitud.
Hubo 20121422 punteros de elementos no utilizados.
El espacio libre total (incluidas las versiones de fila extraíbles) es de 0 bytes. 4944885 páginas están o estarán vacías, incluido 0 al final de la tabla. 4944885 páginas que contienen 0 bytes libres son posibles destinos de movimiento.
CPU 75.31s / 29.59u sec transcurrido 877.79 sec.
INFORMACIÓN: el índice "pg_toast_16874_index" ahora contiene 10475318 versiones de fila en 179931 páginas
DETALLE: Se eliminaron 23884 versiones de fila de índice.
Se han eliminado 101623 páginas de índice, 101623 son actualmente reutilizables.
CPU 1.35s / 2.46u sec transcurrido 21.07 sec.
REINDEXed la tabla que liberó un poco de espacio (~ 1GB). No puedo agrupar la tabla ya que no hay suficiente espacio en el disco para el proceso, y estoy esperando reconstruir la tabla por completo, ya que me gustaría descubrir por qué es mucho más grande que las bases de datos equivalentes que tenemos.
Ejecuté una consulta desde el wiki de PostgreSQL aquí: "Mostrar hinchazón de la base de datos" , y esto es lo que obtengo:
current_database | Schemaname | nombre de tabla | tbloat | desechos desperdiciados | iname | ibloat | wastedibytes ----------------- + ------------ + ------------------- ------------- + -------- + ------------- + ------------- -------------------- + -------- + -------------- ptrdb04 | fews00 | series de tiempo | 1.0 | 0 | idx_timeseries_synchlevel | 0,0 | 0 0 ptrdb04 | fews00 | series de tiempo | 1.0 | 0 | idx_timeseries_localavail | 0,0 | 0 0 ptrdb04 | fews00 | series de tiempo | 1.0 | 0 | idx_timeseries_expirytime | 0,0 | 0 0 ptrdb04 | fews00 | series de tiempo | 1.0 | 0 | idx_timeseries_expiry_null | 0,0 | 0 0 ptrdb04 | fews00 | series de tiempo | 1.0 | 0 | uniq_localintid | 0,0 | 0 0 ptrdb04 | fews00 | series de tiempo | 1.0 | 0 | pk_timeseries | 0,1 | 0 0 ptrdb04 | fews00 | idx_timeseries_expiry_null | 0.6 | 0 | ? El | 0,0 | 0 0
Parece que la base de datos no considera este espacio como "vacío" en absoluto, ¡pero no veo de dónde viene todo el espacio en disco!
Sospecho que este servidor de base de datos está decidiendo usar 4-5 veces más espacio en disco para guardar los mismos registros extraídos de los otros servidores de datos. Mi pregunta es esta: ¿hay alguna forma de verificar el tamaño del disco físico de una fila? Me gustaría comparar el tamaño de una fila en esta base de datos con otra base de datos "saludable".
¡Gracias por cualquier ayuda que usted nos pueda proporcionar!
ACTUALIZACIÓN 1
Terminé reconstruyendo la tabla a partir de un esquema volcado debido a su tamaño (no podía dejarlo solo para otro día). Después de sincronizar los datos, a través del proceso de sincronización del software, la tabla TOAST fue de ~ 35 GB; sin embargo, solo pude dar cuenta de ~ 9 GB de esa columna de blob, que debería ser la más larga en términos de valores. No estoy seguro de dónde provienen los otros 26 GB. CLUSTERADO, VACÍO LLENO y REINDEXADO en vano. Los archivos postgresql.conf entre los servidores de datos locales y remotos son exactamente iguales. ¿Hay alguna razón por la que esta base de datos podría estar intentando almacenar cada registro con un espacio más grande en el disco?
ACTUALIZACIÓN 2 - Fijo
Finalmente decidí reconstruir completamente la base de datos desde cero, incluso llegando a reinstalar los paquetes PostgreSQL84 en el sistema. La ruta de la base de datos se reinicializó y los espacios de tablas se limpiaron. El proceso de sincronización de software de terceros repobló las tablas, ¡y el tamaño final resultó ser ~ 12GB ! Desafortunadamente, esto, de ninguna manera, ayuda a resolver cuál fue la fuente exacta del problema aquí. Lo veré durante un día o dos y veré si hay diferencias importantes con la forma en que la base de datos revitalizada maneja la tabla TOAST y publicaré esos resultados aquí.
Tamaño de relación
ptrdb04=> SELECT nspname || '.' || relname AS "relation",
ptrdb04-> pg_size_pretty(pg_relation_size(C.oid)) AS "size"
ptrdb04-> FROM pg_class C
ptrdb04-> LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
ptrdb04-> WHERE nspname NOT IN ('pg_catalog', 'information_schema')
ptrdb04-> ORDER BY pg_relation_size(C.oid) DESC
ptrdb04-> LIMIT 2;
relación | tamaño
------------------------- + ---------
pg_toast . pg_toast_17269 | 18 GB
Fews00 . estados cálidos | 1224 MB
( 2 filas )
VACUUM VERBOSE ANALYZE timeseries;
INFORMACIÓN: "series de tiempo": se encontraron 12699 versiones removibles, 681961 filas no removibles en 58130 de 68382 páginas DETALLE: 0 versiones de fila muerta no se pueden eliminar todavía. Hubo 105847 punteros de elementos no utilizados. 0 páginas están completamente vacías. CPU 0.83s / 2.08u sec transcurrido 33.36 sec. INFORMACIÓN: aspirar "pg_toast.pg_toast_17269" INFORMACIÓN: índice escaneado "pg_toast_17269_index" para eliminar las versiones de fila 2055849 DETALLE: CPU 0.37s / 2.92u sec transcurrido 13.29 sec. INFORMACIÓN: "pg_toast_17269": se eliminaron 2055849 versiones de fila en 518543 páginas DETALLE: CPU 8.60s / 3.21u sec transcurrido 358.42 sec. INFORMACIÓN: el índice "pg_toast_17269_index" ahora contiene 7346902 versiones de fila en 36786 páginas DETALLE: se eliminaron las versiones de la fila del índice 2055849. Se han eliminado 10410 páginas de índice, 5124 son actualmente reutilizables. CPU 0.00s / 0.00u sec transcurrido 0.01 sec. INFORMACIÓN: "pg_toast_17269": se encontraron 1286128 extraíbles, 2993389 versiones de filas no extraíbles en 1257871 de 2328079 páginas DETALLE: 0 versiones de fila muerta no se pueden eliminar todavía. Hubo 18847 punteros de elementos no utilizados. 0 páginas están completamente vacías. CPU 26.56s / 13.04u sec transcurrido 714.97 sec. INFORMACIÓN: analizando "fews00.timeseries" INFORMACIÓN: "series de tiempo": escaneadas 30000 de 68382 páginas, que contienen 360192 filas activas y 0 filas muertas; 30000 filas en la muestra, 821022 filas totales estimadas
La única diferencia notable después de la reconstrucción (que no sea el uso del disco) es
INFORMACIÓN: "pg_toast_17269": se encontraron 1286128 extraíbles, 2993389 versiones de filas no extraíblescomo @CraigRinger mencionó en un comentario. El recuento de filas no extraíbles es mucho menor que antes.
Nueva pregunta: ¿Pueden otras tablas afectar el tamaño de otra tabla? (a través de claves externas y similares) La reconstrucción de la tabla no hizo nada, pero reconstruir toda la base de datos probó solucionar el problema.