18.3. Inicio del servidor de la base de datos #

18.3.1. Fallos en el inicio del servidor
18.3.2. Problemas de conexión del cliente

Antes de que alguien pueda acceder a la base de datos, debes iniciar la base de datos servidor. El programa del servidor de bases de datos se llama postgres.

Si estás usando una versión preempaquetada de PostgreSQL, casi ciertamente incluye provisiones para ejecutar el servidor como una tarea en segundo plano de acuerdo con las convenciones de tu sistema operativo. Usar la infraestructura del paquete para iniciar el servidor será mucho menos trabajo que averiguar cómo hacer esto tú mismo. Consulta la documentación del paquete para detalles.

La forma sencilla de iniciar el servidor manualmente es simplemente invocar postgres directamente, especificando la ubicación del directorio de datos con la opción -D, por ejemplo:

$ postgres -D /usr/local/pgsql/data

el cual dejará el servidor corriendo en primer plano. Esto debe hacerse mientras inicias sesión en la cuenta de usuario de PostgreSQL. Sin -D, el servidor intentará usar el directorio de datos nombrado por la variable de entorno PGDATA. Si esa variable no es proporcionada tampoco, fallará.

Normalmente es mejor iniciar postgres en segundo plano. Para esto, usa la sintaxis de shell de Unix habitual:

$ postgres -D /usr/local/pgsql/data >logfile 2>&1 &

Es importante almacenar la salida stdout y stderr del servidor en algún lugar, como se muestra arriba. Ayudará para propósitos de auditoría y para diagnosticar problemas. (Ver Section 24.3 para una discusión más exhaustiva sobre el manejo de archivos de registro.)

El programa postgres también toma un número de otras opciones de línea de comandos. Para más información, ver la página de referencia postgres y Chapter 19 abajo.

Esta sintaxis de shell puede volverse tediosa rápidamente. Por lo tanto el programa contenedor pg_ctl es proporcionado para simplificar algunas tareas. Por ejemplo:

pg_ctl start -l logfile

iniciará el servidor en segundo plano y pondrá la salida en el archivo de registro nombrado. La opción -D tiene el mismo significado aquí que para postgres. pg_ctl también es capaz de detener el servidor.

Normalmente, querrás iniciar el servidor de bases de datos cuando el ordenador arranca. Los scripts de inicio automático son específicos del sistema operativo. Hay unos pocos scripts de ejemplo distribuidos con PostgreSQL en el directorio contrib/start-scripts. Instalar uno requerirá privilegios de root.

Diferentes sistemas tienen diferentes convenciones para iniciar demonios en tiempo de arranque. Muchos sistemas tienen un archivo /etc/rc.local o /etc/rc.d/rc.local. Otros usan directorios init.d o rc.d. Hagas lo que hagas, el servidor debe ser ejecutado por la cuenta de usuario de PostgreSQL y no por root o cualquier otro usuario. Por lo tanto tú probablemente deberías formar tus comandos usando su postgres -c '...'. Por ejemplo:

su postgres -c 'pg_ctl start -D /usr/local/pgsql/data -l serverlog'

Aquí hay algunas sugerencias más específicas del sistema operativo. (En cada caso asegúrate de usar el directorio de instalación y nombre de usuario adecuados donde mostramos valores genéricos.)

Mientras el servidor se está ejecutando, su PID se almacena en el archivo postmaster.pid en el directorio de datos. Esto se usa para evitar que múltiples instancias del servidor se ejecuten en el mismo directorio de datos y también se puede usar para apagar el servidor.

18.3.1. Fallos en el inicio del servidor #

Hay varias razones comunes por las que el servidor podría fallar al iniciar. Revisa el archivo de registro del servidor, o inícialo a mano (sin redireccionar la salida estándar o el error estándar) y mira qué mensajes de error aparecen. A continuación explicamos algunos de los mensajes de error más comunes con más detalle.

LOG:  could not bind IPv4 address "127.0.0.1": Address already in use
HINT:  Is another postmaster already running on port 5432? If not, wait a few seconds and retry.
FATAL:  could not create any TCP/IP sockets

Esto usualmente significa justo lo que sugiere: intentaste iniciar otro servidor en el mismo puerto donde ya se está ejecutando uno. Sin embargo, si el mensaje de error del kernel no es Address already in use o alguna variante de eso, podría haber un problema diferente. Por ejemplo, intentar iniciar un servidor en un número de puerto reservado podría generar algo como:

$ postgres -p 666
LOG:  could not bind IPv4 address "127.0.0.1": Permission denied
HINT:  Is another postmaster already running on port 666? If not, wait a few seconds and retry.
FATAL:  could not create any TCP/IP sockets

Un mensaje como:

FATAL:  could not create shared memory segment: Invalid argument
DETAIL:  Failed system call was shmget(key=5440001, size=4011376640, 03600).

probablemente significa que el límite de tu kernel para el tamaño de la memoria compartida es menor que el área de trabajo que PostgreSQL está intentando crear (4011376640 bytes en este ejemplo). Esto solo es probable que pase si has establecido shared_memory_type a sysv. En ese caso, puedes intentar iniciar el servidor con un número de buffers menor al normal (shared_buffers), o reconfigurar tu kernel para incrementar el tamaño de memoria compartida permitido. También podrías ver este mensaje al intentar iniciar múltiples servidores en la misma máquina, si el espacio total solicitado supera el límite del kernel.

Un error como:

FATAL:  could not create semaphores: No space left on device
DETAIL:  Failed system call was semget(5440126, 17, 03600).

no significa que te has quedado sin espacio en disco. Significa que el límite de tu kernel para el número de semáforos de System V es menor que el número que PostgreSQL quiere crear. Como en el caso anterior, podrías resolver temporalmente el problema iniciando el servidor con un número menor de conexiones permitidas (max_connections), pero eventualmente querrás incrementar el límite del kernel.

Se dan detalles sobre la configuración de las facilidades de IPC de System V en Section 18.4.1.

18.3.2. Problemas de conexión del cliente #

Aunque las condiciones de error posibles en el lado del cliente son bastante variadas y dependen de la aplicación, algunas de ellas podrían estar directamente relacionadas con cómo se inició el servidor. Las condiciones distintas de las que se muestran a continuación deberían estar documentadas con la respectiva aplicación cliente.

psql: error: connection to server at "server.joe.com" (123.123.123.123), port 5432 failed: Connection refused
        Is the server running on that host and accepting TCP/IP connections?

Este es el fallo genérico de no he podido encontrar un servidor con el que hablar. Se ve como el anterior cuando se intenta la comunicación por TCP/IP. Un error común es olvidar configurar listen_addresses para que el servidor acepte conexiones TCP remotas.

Alternativamente, podrías obtener esto cuando intentas la comunicación por sockets de dominio Unix con un servidor local:

psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such file or directory
        Is the server running locally and accepting connections on that socket?

Si el servidor de verdad se está ejecutando, comprueba que la idea del cliente sobre la ruta del socket (aquí /tmp) coincida con la configuración de unix_socket_directories del servidor.

Un mensaje de fallo de conexión siempre muestra la dirección del servidor o el nombre de la ruta del socket, lo cual es útil para verificar que el cliente está intentando conectarse al lugar correcto. Si de hecho no hay ningún servidor escuchando allí, el mensaje de error del kernel típicamente será Connection refused o No such file or directory, como se ilustra. (Es importante darse cuenta de que Connection refused en este contexto no significa que el servidor recibió tu solicitud de conexión y la rechazó. Ese caso producirá un mensaje diferente, como se muestra en Section 20.16). Otros mensajes de error como Connection timed out podrían indicar problemas más fundamentales, como la falta de conectividad de red, o un cortafuegos (firewall) bloqueando la conexión.