Múltiples versiones de PostgreSQL en un servidor

servidor

En este artículo vamos a ver como podemos configurar un sistema linux/unix para tener múltiples instalaciones de PostgreSQL ejecutandose en un mismo servidor.

El ejemplo más común es cuando necesitamos tener acceso a diferentes versiones de PostgreSQL y queremos aprovechar los recursos disponibles en una sola máquina.

Una instalación de PostgreSQL tiene ciertos elementos en los cuales tenemos que pensar cuando vamos a tener un servidor ejecutando múltiples instancias:

  • Directorio de ejecutables/bibliotecas: Directorio donde poder encontrar los ejecutables/bibliotecas de una determinada versión de PostgreSQL
  • IP: IP utilizada por los clientes para comunicarse con la base de datos
  • Puerto: Puerto utilizado por los clientes para comunicarse con la base de datos (5432 por defecto)
  • Unix socket: Unix socket utilizado por las conexiones locales
  • Directorio de datos: Directorio de datos asociado a una instalación determinada

Lo más importante que tenemos que tener en cuenta para configurar nuestro sistema con múltiples versiones es que existen dos combinaciones de estos elementos en las que todos los elementos de la combinación tienen que ser únicos entre todas las instalaciones de PostgreSQL que comparten el mismo servidor.

  • Directorio ejecutables / directorio datos / directorio Unix socket
  • IP / Puerto

En lo que respecta al par IP/puerto podemos decir que, ó bien podemos usar una sola IP con diferentes puertos para cada instalación (opción 1), ó diferentes IPs con el mismo puerto (opción 2). A mi personalmente me gusta más la segunda opción porque de esta manera podemos usar el puerto por defecto (5432) y nos evitamos tener que definir en los clientes el puerto a utilizar.

A continuación teneis un gráfico que os muestra las dos opciones de configuración que tenemos cuando vamos a tener un servidor ejecutando múltiples instancias de PostgreSQL.

Para ilustrar como podemos configurar un sistema de este tipo, vamos a instalar un sistema con solo dos instalaciones de PostgreSQL, 8.3 y 8.4 y la opción 2 (2 IP diferentes / mismo puerto) . Los datos que vamos a utilizar para cada instalación son:

8.3

  • Directorio de ejecutables/bibliotecas: /usr/local/pgsql-8.3
  • IP: 10.1.1.10
  • Puerto: 5432
  • Directorio Unix socket: /tmp/pgsql-8.3
  • Directorio de datos: /var/pgsql-8.3/data

8.4

  • Directorio de ejecutables/bibliotecas: /usr/local/pgsql-8.4
  • IP: 10.1.1.20
  • Puerto: 5432
  • directorio Unix socket: /tmp/pgsql-8.4
  • Directorio de datos: /var/pgsql-8.4/data

En este artículo no vamos a ver como instalar multiples IP en una misma máquina ya que el procedimiento puede variar ligeramente entre distribuciones de Linux. Este paso queda como ejercicio para los usuarios que estén interesados en el tema.

Lo primero que tenemos que hacer es instalar las diferentes versiones de PostgreSQL que vamos a utilizar. En nuestro caso instalaremos desde el código fuente de PostgreSQL, información de como descargar, compilar e instalar PostgreSQL desde el código fuente, se puede encontrar en el artículo "Instalación e inicialización básica de PostgreSQL desde el código fuente".

Normalmente no se pueden instalar diferentes versiones de un programa via los sistemas de instalación/paquetes que vienen con las diferentes distribuciones, por eso instalamos desde el código fuente.

Una vez que tenemos instalado la versión 8.3 en /usr/local/pgsql-8.3 y 8.4 en /usr/local/pgsql-8.4 (debereis de usar --prefix=/usr/local/pgsql-8.3 y --prefix=/usr/local/pgsql-8.4 respectivamente en el proceso de compilación), tendremos que inicializar los dos directorios de datos que van a utilizarse con estas dos versiones.

Lo primero que hacemos es crear estos dos directorios:

[root@servidor]# mkdir -p /var/pgsql-8.3/data
[root@servidor]# mkdir -p /var/pgsql-8.4/data

[root@servidor] chown postgres /var/pgsql-8.3/data
[root@servidor] chown postgres /var/pgsql-8.4/data

A continuación los inicializamos:

[root@servidor]# su - postgres

[postgres@servidor]# /usr/local/pgsql-8.3/bin/initdb -E utf8 -U postgres 
-D /var/pgsql-8.3/data

[postgres@servidor]# /usr/local/pgsql-8.4/bin/initdb -E utf8 -U postgres 
-D /var/pgsql-8.4/data

Ahora y antes de arrancar las dos instancias de PostgreSQL deberemos de configurar que IP, puerto y unix socket tienen que utilizar. Para ello actualizaremos los ficheros postgresql.conf de las dos versiones.

Editamos el fichero /var/pgsql-8.3/data/postgresql.conf y actualizamos los siguientes parametros:

listen_addresses = '10.1.1.10'
port = 5432
unix_socket = '/tmp/pgsql-8.3
unix_socket_permissions = 0700

Y el fichero /var/pgsql-8.4/data/postgresql.conf y actualizamos los siguientes parametros:

listen_addresses = '10.1.1.20'
port = 5432
unix_socket = '/tmp/pgsql-8.4
unix_socket_permissions = 0700

Si hubiesemos decidido utilizar la misma IP con diferentes puertos tendriamos que haber definido:

Para 8.3:

listen_addresses = '10.1.1.10'
port = 5483
unix_socket = '/tmp/pgsql-8.3
unix_socket_permissions = 0700


Para 8.4:

listen_addresses = '10.1.1.10'
port = 5484
unix_socket = '/tmp/pgsql-8.4
unix_socket_permissions = 0700

Ya estamos casi listos para arrancar las dos versiones. Solo nos queda definir dos directorios diferentes si vamos a conectarnos via Unix sockets con PostgreSQL:

[root@servidor]# mkdir -p /tmp/pgsql-8.3
[root@servidor]# mkdir -p /tmp/pgsql-8.4

[root@servidor]# chown postgres /tmp/pgsql-8.3
[root@servidor]# chown postgres /tmp/pgsql-8.4

En estos momentos podemos arrancar nuestras bases de datos y empezar a utilizarlas sin problemas.

[postgres@servidor]# /usr/local/pgsql-8.3/bin/pg_ctl -D /var/pgsql-8.3/data
 -l /var/pgsql-8.3/data/postgresql.log start

[postgres@servidor]# /usr/local/pgsql-8.4/bin/pg_ctl -D /var/pgsql-8.4/data
 -l /var/pgsql-8.4/data/postgresql.log start

Si queremos parar PostgreSQL podemos utilizar los siguientes comandos:

[postgres@servidor]# /usr/local/pgsql-8.3/bin/pg_ctl -D /var/pgsql-8.3/data 
stop -m fast

[postgres@servidor]# /usr/local/pgsql-8.4/bin/pg_ctl -D /var/pgsql-8.4/data 
stop -m fast

Para empezar a utilizar las bases de datos podemos utilizar el cliente psql que viene con PostgreSQL. En nuestro caso solo tendremos que definir con que IP nos queremos conectar para utilizar una versión u otra. Por supuesto los ficheros pg_hba.conf de cada versión deben de tener los permisos correspondientes para poder conectarse a las nuevas instalaciones de PostgreSQL de nuestra máquina.

[postgres@servidor]# /usr/local/pgsql-8.3/bin/psql -h 10.0.0.10
Welcome to psql 8.3.7, the PostgreSQL interactive terminal.

Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help with psql commands
       \g or terminate with semicolon to execute query
       \q to quit

postgres=# SELECT version();
                            version
-------------------------------------------------------------
 PostgreSQL 8.3.7 on i686-pc-linux-gnu, compiled by GCC gcc 
(Ubuntu 4.3.2-1ubuntu12) 4.3.2
(1 row)

[postgres@servidor]# /usr/local/pgsql-8.4/bin/psql -h 10.0.0.20
psql (8.4.0)
Type "help" for help.

postgres=# SELECT version();
                            version
-------------------------------------------------------------
 PostgreSQL 8.4.0 on i686-pc-linux-gnu, compiled by GCC gcc 
 (Ubuntu 4.3.2-1ubuntu12) 4.3.2, 32-bit
(1 row)

Bueno, esto es todo en este artículo. Más información sobre el tema en:

http://www.postgresql-es.org/node/218
http://www.postgresql-es.org/node/219

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

error al instalar postgres 8.4

Hola, estoy intentando instalar el postgres 8.4 ya tengo instalado 8.3 y me da este erroral momento de compilarlo ./configure --prefix=/usr/local/pgsql-8.4

configure: error: readline library not found
If you have readline already installed, see config.log for details on the
failure. It is possible the compiler isn't looking in the proper directory.
Use --without-readline to disable readline support.

instale la libreria readline para ver si ese era el problema y nada... espero me puedan ayudar.

Imagen de rafaelma

Re: error al instalar postgres 8.4

¿Estas seguro que has instalado libreadline y libreadline-dev? Si te da este fallo es porque no tienes instalado todo lo necesario.

Mas información en http://www.postgresql-es.org/node/218#comment-276

--
Rafael Martinez
PostgreSQL-es.org

varias versiones....

Hola Tengo instalado postgres 8.3 pero no esta instalado en los directorios que dice el manual el postgres.conf esta en etc/postgres/8.3/main/postgres.conf

quiero saber si puedo dejar como esta el postgres 8.3 y probar el manual instalando postgres 8.1 y postgres8.4, es decir si es posible tener la 3 versiones? o como podria configurar de nuevo mi postgres 8.3 en los directorios que indica el manual.

Imagen de rafaelma

Re:varias versiones....

Probablemente hayas instalado PostgreSQL con los paquetes que vienen con tu distribución (¿qué distribución utilizas?), algunos de estos paquetes instalan las diferentes partes en otros sitios que en los estandares, como en este caso.

No deberias de tener ningún problema en instalar otras versiones como indicamos aqui y seguir usando 8.3 como la tienes ahora. Siempre y cuando sigas las reglas explicadas en el artículo de tener todo separado para las diferentes versiones.

La versión 8.3 que has instalado via los paquetes de tu distribución se podria en teoria cambiar, pero no te lo aconsejo. Probablemete tendrias que alterar el script de arranque (en /etc/init.d), y el fichero de configuración (en /etc/postgres/8.3/main), y tienes que saber que cambiar.

--
Rafael Martinez
PostgreSQL-es.org

Gracias por tu ayuda ahora

Gracias por tu ayuda ahora tengo otra duda al momento de configurar el postgres.conf la dirección IP que voy a utilizar como selecciono la IP puede ser cualquiera? o de acuerdo a que parámetros la tengo que seleccionar?

Imagen de rafaelma

Dirección IP en postgresql.conf

La direccion IP (ó hostname) que defines en postgresql.conf con el parámetro 'listen_addresses' tiene que ser una IP (ó nombre de maquina) que esté instalada en el ordenador que va a ejecutar postgresql. si lo que defines aqui no esta instalado en el ordenador, no te va a funcionar.

Por defecto listen_addresses tiene el valor 'localhost' (ó lo que es lo mismo 127.0.0.1). Si quieres que postgresql este accesible por todas las IPs instaladas en tu máquina puedes usar listen_addresses = '*'. Si defines más de una IP en listen_addresses las tienes que separar con comas.

--
Rafael Martinez
PostgreSQL-es.org

error al iniciar el servicio

Hola gracias por responder ya entendi lo de las IP. como dice en manual instale otra IP en mi maquina:

8.1

* Directorio de ejecutables/bibliotecas: /usr/local/pgsql-8.1
* IP: 172.16.1.15
* Puerto: 5432
* Directorio Unix socket: /tmp/pgsql-8.1
* Directorio de datos: /var/pgsql-8.1/data
*

8.4

* Directorio de ejecutables/bibliotecas: /usr/local/pgsql-8.4
* IP: 172.16.1.16
* Puerto: 5432
* directorio Unix socket: /tmp/pgsql-8.4
* Directorio de datos: /var/pgsql-8.4/data
*
Tengo varias preguntas:

1) al configurar el postgres.conf como queda la parte de:
#data_directory = 'ConfigDir'
#hba_file = 'ConfigDir/pg_hba.conf'
#ident_file = 'ConfigDir/pg_ident.conf'

# If external_pid_file is not explicitly set, no extra pid file is written.
#external_pid_file = '(none)'

2)luego de configurar postgres.conf cuando mando a iniciar el servicio 8.4

postgres@servidor-desktop:/$ /usr/local/pgsql-8.4/bin/pg_ctl -D /var/pgsql-8.4/data/ -l /var/pgsql-8.4/data/postgresql.log start
server starting

y con el servicio 8.1 me da el siguiente error

postgres@servicio-desktop:/$ /usr/local/pgsql-8.1/bin/pg_ctl -D /var/pgsql-8.1/data/ -l /var/pgsql-8.1/data/postgresql.log start
pg_ctl: another postmaster may be running; trying to start postmaster anyway
pg_ctl: could not start postmaster
Examine the log output.

no se que puede ser???

Imagen de rafaelma

Re: error al iniciar el servicio

al configurar el postgres.conf como queda la parte de:
#data_directory = 'ConfigDir' ....

Esto no lo tienes que cambiar. ConfigDir tiene automaticamente el valor definido en el parametro -D de pg_ctl

pg_ctl: another postmaster may be running; trying to start postmaster anyway
pg_ctl: could not start postmaster

¿Estas seguro que las IP definidas en el fichero postgresql.conf son diferentes? Este error ocurre cuando la IP:puerto que se intenta usar ya estan en uso.

--
Rafael Martinez
PostgreSQL-es.org

No puedo empezar a usar la base de datos.

Ya casi lo logro jeje Gracias rafael ya me inician los dos:

postgres@servidor-desktop:/var/pgsql-8.4/data$ /usr/local/pgsql-8.4/bin/pg_ctl 
-D /var/pgsql-8.4/data/ 
-l /var/pgsql-8.4/data/postgresql.log start
server starting
postgres@servidor-desktop:/var/pgsql-8.4/data$ /usr/local/pgsql-8.1/bin/pg_ctl
-D /var/pgsql-8.1/data/ 
-l /var/pgsql-8.1/data/postgresql.log start
postmaster starting

ahora cuando voy a empezar a usar la base de datos con el siguiente comando

postgres@servidro-desktop:/$ /usr/local/pgsql-8.4/bin/psql -h 172.16.1.15
psql: could not connect to server: Conexión rechazada
	Is the server running on host "172.16.1.15" and accepting
	TCP/IP connections on port 5432?
postgres@servidor-desktop:/$ /usr/local/pgsql-8.4/bin/psql -h 172.16.1.16
psql: could not connect to server: No hay ruta hacia el host
	Is the server running on host "172.16.1.16" and accepting
	TCP/IP connections on port 5432?

me : arroja esto verifique que en los archivos postgresq.conf tengasn las IP distintas. mi maquina la configure para que tuviera 2 IP.

Imagen de rafaelma

Re: No puedo empezar a usar la base de datos.

psql: could not connect to server: Conexión rechazada
......

psql: could not connect to server: No hay ruta hacia el host
Is the server running on host "172.16.1.16" and accepting
TCP/IP connections on port 5432?

Estos errores lo dicen claro, tienes un problema en la configuración de red de tu ordenador y el cliente psql no puede acceder a las IPs que intentas usar.

¿Usas firewall? ¿Qué resultados te dan los comandos 'netstat -lpn |grep tcp', '/sbin/ifconfig' y '/sbin/route -n'?

--
Rafael Martinez
PostgreSQL-es.org