66.1. Disposición de archivos de base de datos #

Esta sección describe el formato de almacenamiento a nivel de archivos y directorios.

Tradicionalmente, la configuración y los archivos de datos utilizados por un clúster de bases de datos se almacenan juntos dentro del directorio de datos del clúster, comúnmente denominado PGDATA (por el nombre de la variable de entorno que se puede usar para definirlo). Una ubicación común para PGDATA es /var/lib/pgsql/data. Pueden existir múltiples clústeres, gestionados por diferentes instancias de servidor, en la misma máquina.

El directorio PGDATA contiene varios subdirectorios y archivos de control, como se muestra en Table 66.1. Además de estos elementos necesarios, los archivos de configuración del clúster postgresql.conf, pg_hba.conf y pg_ident.conf se almacenan tradicionalmente en PGDATA, aunque es posible colocarlos en otro lugar.

Table 66.1. Contenido de PGDATA

Elemento Descripción
PG_VERSIONUn archivo que contiene el número de versión principal de PostgreSQL
baseSubdirectorios que contienen subdirectorios por base de datos
current_logfilesArchivo que registra los archivos de registro en los que escribe actualmente el recolector de logs
globalSubdirectorio que contiene tablas globales del clúster, como pg_database
pg_commit_tsSubdirectorio que contiene datos de marca de tiempo de confirmación de transacciones
pg_dynshmemSubdirectorio que contiene los archivos utilizados por el subsistema de memoria compartida dinámica
pg_logicalSubdirectorio que contiene los datos de estado para la decodificación lógica
pg_multixactSubdirectorio que contiene datos de estado de multitransacciones (utilizados para bloqueos compartidos de filas)
pg_notifySubdirectorio que contiene datos de estado de LISTEN/NOTIFY
pg_replslotSubdirectorio que contiene datos de ranuras de replicación
pg_serialSubdirectorio que contiene información sobre transacciones serializables confirmadas
pg_snapshotsSubdirectorio que contiene instantáneas (snapshots) exportadas
pg_statSubdirectorio que contiene archivos permanentes para el subsistema de estadísticas
pg_stat_tmpSubdirectorio que contiene archivos temporales para el subsistema de estadísticas
pg_subtransSubdirectorio que contiene datos de estado de subtransacciones
pg_tblspcSubdirectorio que contiene enlaces simbólicos a tablespaces
pg_twophaseSubdirectorio que contiene archivos de estado para transacciones preparadas
pg_walSubdirectorio que contiene los archivos del WAL (Write Ahead Log)
pg_xactSubdirectorio que contiene datos de estado de confirmación de transacciones
postgresql.auto.confUn archivo utilizado para almacenar los parámetros de configuración establecidos por ALTER SYSTEM
postmaster.optsUn archivo que registra las opciones de línea de comandos con las que se inició el servidor por última vez
postmaster.pidUn archivo de bloqueo que registra el ID del proceso postmaster (PID) actual, la ruta del directorio de datos del clúster, la marca de tiempo de inicio del postmaster, el número de puerto, la ruta del directorio del socket de dominio Unix (puede estar vacía), la primera dirección listen_address válida (dirección IP o *, o vacía si no escucha en TCP), y el ID del segmento de memoria compartida (este archivo no está presente después de apagar el servidor)

Para cada base de datos en el clúster hay un subdirector dentro de PGDATA/base, nombrado de acuerdo con el OID de la base de datos en pg_database. Este subdirectorio es la ubicación predeterminada para los archivos de la base de datos; en particular, sus catálogos de sistema se almacenan allí.

Ten en cuenta que las siguientes secciones describen el comportamiento del método de acceso a tablas heap integrado y de los métodos de acceso a índices integrados. Debido a la naturaleza extensible de PostgreSQL, otros métodos de acceso podrían funcionar de manera diferente.

Cada tabla e índice se almacena en un archivo independiente. Para las relaciones ordinarias, estos archivos se nombran según el número de filenode de la tabla o índice, el cual se puede encontrar en pg_class.relfilenode. Pero para las relaciones temporales, el nombre del archivo tiene la forma tBBB_FFF, donde BBB es el número de proceso del backend que creó el archivo, y FFF es el número de filenode. En cualquier caso, además del archivo principal (también conocido como bifurcación principal - main fork), cada tabla e índice tiene un mapa de espacio libre (ver Section 66.3), el cual almacena información sobre el espacio libre disponible en la relación. El mapa de espacio libre se almacena en un archivo nombrado con el número de filenode más el sufijo _fsm. Las tablas también tienen un mapa de visibilidad, almacenado en una bifurcación con el sufijo _vm, para rastrear qué páginas se sabe que no tienen tuplas muertas. El mapa de visibilidad se describe con más detalle en Section 66.4. Las tablas e índices no registrados (unlogged) tienen una tercera bifurcación, conocida como la bifurcación de inicialización, que se almacena en una bifurcación con el sufijo _init (ver Section 66.5).

Caution

Ten en cuenta que aunque el filenode de una tabla a menudo coincide con su OID, esto no es necesariamente así; algunas operaciones, como TRUNCATE, REINDEX, CLUSTER y algunas formas de ALTER TABLE, pueden cambiar el filenode conservando el OID. Evita asumir que el filenode y el OID de la tabla son iguales. Además, para ciertos catálogos de sistema, incluido pg_class en sí, pg_class.relfilenode contiene cero. El número de filenode real de estos catálogos se almacena en una estructura de datos de nivel inferior y se puede obtener utilizando la función pg_relation_filenode().

Cuando una tabla o índice supera 1 GB, se divide en segmentos de tamaño de gigabyte. El nombre del archivo del primer segmento es el mismo que el del filenode; los segmentos subsiguientes se llaman filenode.1, filenode.2, etc. Esta disposición evita problemas en plataformas que tienen limitaciones en el tamaño de los archivos. (En realidad, 1 GB es solo el tamaño de segmento predeterminado. El tamaño del segmento se puede ajustar utilizando la opción de configuración --with-segsize al compilar PostgreSQL). En principio, las bifurcaciones del mapa de espacio libre y del mapa de visibilidad también podrían requerir múltiples segmentos, aunque es poco probable que esto suceda en la práctica.

Una tabla que tiene columnas con entradas potencialmente grandes tendrá una tabla TOAST asociada, que se utiliza para el almacenamiento fuera de línea de valores de campo que son demasiado grandes para mantenerse en las filas de la tabla propiamente dichas. pg_class.reltoastrelid enlaza desde una tabla a su tabla TOAST, si la hay. Consulta Section 66.2 para obtener más información.

El contenido de las tablas y los índices se analiza con más detalle en Section 66.6.

Los tablespaces hacen que el escenario sea más complicado. Cada tablespace definido por el usuario tiene un enlace simbólico dentro del directorio PGDATA/pg_tblspc, el cual apunta al directorio físico del tablespace (es decir, la ubicación especificada en el comando CREATE TABLESPACE del tablespace). Este enlace simbólico se nombra según el OID del tablespace. Dentro del directorio físico del tablespace hay un subdirectorio con un nombre que depende de la versión del servidor PostgreSQL, como PG_9.0_201008051. (La razón para usar este subdirectorio es para que las sucesivas versiones de la base de datos puedan usar la misma ubicación de CREATE TABLESPACE sin conflictos). Dentro del subdirectorio específico de la versión, hay un subdirectorio para cada base de datos que tiene elementos en el tablespace, nombrado con el OID de la base de datos. Las tablas y los índices se almacenan dentro de ese directorio, utilizando el esquema de nomenclatura de filenode. Al tablespace pg_default no se accede a través de pg_tblspc, sino que corresponde a PGDATA/base. De manera similar, al tablespace pg_global no se accede a través de pg_tblspc, sino que corresponde a PGDATA/global.

La función pg_relation_filepath() muestra la ruta completa (relativa a PGDATA) de cualquier relación. A menudo es útil como un sustituto para recordar muchas de las reglas anteriores. Pero ten en cuenta que esta función solo proporciona el nombre del primer segmento de la bifurcación principal de la relación; es posible que necesites añadir un número de segmento y/o _fsm, _vm o _init para encontrar todos los archivos asociados con la relación.

Los archivos temporales (para operaciones como la clasificación de más datos de los que caben en la memoria) se crean dentro de PGDATA/base/pgsql_tmp, o dentro de un subdirectorio pgsql_tmp de un directorio de tablespace si se especifica un tablespace distinto de pg_default para ellos. El nombre de un archivo temporal tiene la forma pgsql_tmpPPP.NNN, donde PPP es el PID del backend propietario y NNN distingue los diferentes archivos temporales de ese backend.