Información blog

Linux, tutoriales, noticias, sistemas, redes y seguridad informática, entre otras cosas.

miércoles, 24 de febrero de 2016

Postgresql, una alternativa a mysql en Linux

Hoy quiero venir con algo ligeramente distinto a lo que suelo traeros; generalmente suelo centrarme en temas más referentes a shells, redes o seguridad, pero hoy quiero veniros con un post orientado a la bases de datos. Hace ya tiempo hice referencia al montaje de un servidor LAMP y a la securización de éste; LAMP estaría compuesto por: Linux, Apache, Mysql y PHP; servicios muy famosos usados en todo el mundo. La cuestión está en que el mundo no está compuesto únicamente por estas herramientas y siempre hay otras alternativas como Nginx para un servidor web por ejemplo... Es por ello que hoy quiero traeros una alternativa a Mysql: postgresql.

postgresql_portada

Para empezar creo que es necesario hacer una pequeña explicación sobre las diferencias entre una base de datos y otra, pues aunque ambas son de código abierto, existen bastantes diferencias entre ellas. La primera y más fundamental es el tipo de licencia sobre la que están distribuidas: Mysql está distribuida bajo una licencia copyleft, es decir que puede ser distribuida libremente siempre y cuando se preserven los mismos derechos que los de la versión original... En otras palabras que requiere que el código del programa que trabaje con mysql sea liberado; cosa que por ejemplo para algunas empresas puede ser complicado e incluso contraproducente... Eso no significa que la licencia sea buena o mala sino que es una licencia que se encuentra en sintonía con la filosofía del software libre. Postgresql en cambio tiene una licencia más abierta y flexible que puede adaptarse a más entornos sin tener que preservar tantos derechos como Mysql (para bien o para mal).

Obviamente también existen diferencias técnicas: Mysql trabaja muy bien con php y es realmente eficiente a la hora de realizar consultas sql sencillas... En cambio cuando se quiere trabajar con un gran volumen de tablas y se quiere apostar más por la integridad de la base de datos en vez de por la eficiencia de las consultas sql, se suele optar por postgresql. Ambas son grandes opciones, cada una con sus virtudes y defectos, y si bien a nivel técnico ambas van mejorando a pasos agigantados, la filosofía de cada una sigue siendo completamente diferente la una de la otra.

Ahora que ya tenemos cierta idea de lo que nos aporta postgresql, pasemos al uso de éste. Como toda base de datos basada en Linux, postgresql no se halla instalado en Linux, pero al estar incluido en los repositorios oficiales no tendremos problemas instalándolo, con lo que la instalación sería tan sencilla como escribir:

apt-get install postgresql

Tras un rato tendríamos la base de datos instalada, pero habrían dos problemas: El primero es que nadie puede conectarse a la base datos a excepción del propio equipo en el que se ha instalado el software, cosa muy poco práctica, especialmente para gestionar la base de datos remotamente. La otra pega es que por defecto la base de datos está diseñada para soportar "solo" 100 conexiones simultáneas; a partir de allí la base de datos se ralentizaría e incluso se podría llegar a detener dicha base de datos debido a la sobrecarga de conexiones. Es por ello que es recomendable poner postgresql "a punto" antes de empezar a usarlo. Para dicha puesta a punto es necesario dirigirse a la carpeta de configuración de postgresql, la cual es: /etc/postgresql/(versión)/main/; al habernos descargado para este caso en concreto la versión 9.4, nos moveremos a dicha carpeta mediante el comando cd de la siguiente forma:

cd /etc/postgresql/9.4/main/

Este directorio está compuesto por 6 ficheros, de los cuales dos, nos interesan especialmente: pg_hba.conf y postgresql.conf. El primero es el encargado de gestionar qué ips pueden conectarse a la base de datos; si le echamos un vistazo veremos que solamente tiene tres lineas útiles (el resto son comentarios):

  1. local   all             all                                     peer
  2. host    all             all             127.0.0.1/32            md5
  3. host    all             all             ::1/128                 md5

La primera línea se encarga de abrir puertos en el servidor y no requiere que la modifiquemos ni la borremos; las otras dos son las líneas que especifican qué ips pueden conectarse. Por temas de gestión es recomendable no borrar esas líneas, pero sí que es recomendable añadir algunas líneas nuevas para evitar problemas. En mi caso en concreto he añadido una línea para que todos los de la red local puedan acceder a la base de datos; para ello primero habría que conocer la estructura con la que trabajan dichas líneas:

host base_de_datos usuario ip/mascara método_de_autenticación

En caso de querer hacer referencia a "todos", es decir a todas las bases de datos o que todos los usuarios asociados con postgresql puedan acceder, habría que escribir all. Mi línea en concreto sería la siguiente:

host    all             all             192.168.1.0/255.255.255.0                 md5

Ahora que la base de datos es más "accesible", habría que optimizarla para que pueda soportar más conexiones a la vez... Para ello lo primero que tenemos que saber es saber con cuanta memoria RAM trabajamos para hacer nuestros calculos; no es lo mismo trabajar con un equipo de 8 GB de RAM que con uno de 16... Para conocer la cantidad total de memoria RAM que dispone nuestro equipo podemos hacer uso del comando free -m.

Supongamos que contamos con 8 GB de ram. Ahora nos dirigiríamos al fichero postgresql.conf y editaríamos los siguientes parámetros:

  • listen_addresses: La base de datos está diseñada para "escuchar" únicamente en localhost, aquí habría que poner la ip de la interfaz de red que queremos que reciba las conexiones del resto de lugares.
  • max_connections: Aquí pondríamos el número máximo de conexiones. Cada conexión requiere consumir cierta ram del equipo, con lo que es importante no "pasarnos", si bien realizar un calculo preciso es complicado; se pueden buscar herramientas online que juegan sobre seguro o se pueden ir probando diferentes cantidades hasta dar con la adecuada.
  • shared_bufers: Este valor indica cuanta ram está reservada para el arranque de postgres; aquí no es necesario poner un valor extremadamente alto, si bien el valor por defecto (24 MB) , se puede quedar corto, pues puede que no sea capaz de arrancar. El valor ideal es poner el 10% de la memoria RAM total en este parámetro (he ahí el motivo por el que es conveniente saber de cuanta RAM total disponemos).
  • work_mem: También conocido como memoria de trabajo, especifica la memoria reservada para tareas como la ordenación de tablas o la ejecución de consultas. Generalmente en servidores "normales" se suele asignar un 2% de la memoria RAM total, pero en caso de quedarse corta se pueden asignar hasta 4.
  • effective cache size: Indica cuanta memoria máxima cachear para postgres; al ser un valor que influye en la caché, se pude asignar tranquilamente la mitad de la RAM total.

Con estos valores, y suponiendo que tenemos un equipo con la ip 192.168.1.5 con un capacidad de 8 GB de RAM, tendríamos el siguiente resultado:

  1. listen_addresses = 'localhost, 192.168.1.5'
  2. max_connections200
  3. shared_buffers = 800MB
  4. work_mem=160MB
  5. effective cache size=4GB

Si tuviesemos "miedo" a forzar demasiado los parámetros y quisiesemos un método automatizado que, si bien no le saca todo el partido a la base de datos, es más seguro, podemos recurrir a webs tales como http://pgtune.leopard.in.ua/ que te "tunean" la base de datos para dejartela a medida; eso sí, ellos mismos admiten que sus parámetros son recomendaciones.  Para aplicar los cambios habría que reiniciar el servicio mediante el comando:

/etc/init.d/postgresql restart

Con las versiones más nuevas, este proceso es suficiente para optimizar nuestra base de datos, pero las versiones previas a la 9.4, tienen un problema con la gestión de la memoria y no dejarán que postgres arranque... Si vamos al fichero /var/log/syslog, veremos un error parecido al siguiente:

CETFATAL: could not create shared memory segment: Argumento inválido
CETDETAIL: Failed system call was shmget(key=5432001, size=4294967296, 03600).
CETHINT: This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter. You can either reduce the request size or reconfigure the kernel with larger SHMMAX. To reduce the request size (currently 3495149568 bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.

Esto significa que la memoria que queremos usar excede la capacidad que soporta nuestro kernel, impidiendo que arranque postgres. Afortunadamente esto se puede solucionar mediante la ayuda de sysctl; mediante dicho comando modificaremos dos valores: shmmax y shmall; shmmax tendrá que tener el mismo valor que el indicado en el valor size del fichero /var/log/syslog, mientras que el valor shmall tendría que ser dicho valor dividido entre 4096 (4KB); con lo que editaríamos ambos valores de la siguiente forma en el fichero /etc/sysct.conf:

  1. kernel.shmmax=4294967296
  2. kernel.shmall=1048576

Para aplicar los cambios tendríamos que escribir el siguiente comando en la consola:

sysctl -p

Gracias a dicho cambio, ahora seríamos capaces de iniciar postgresql sin impedimentos, pudiendo disfrutar de una base de datos a pleno rendimiento, eso sí; manejar postgresql desde la consola puede ser muy dificultoso, con lo que es recomendable usar herramientas gráficas tales como pgadmin (la oficial de postgresql) para facilitarnos la vida. Dicha herramienta es muy útil pues podemos usarla tanto en entornos Windows como Linux.

Espero que os haya resultado útil.

Saludos.

1 comentario :