sql >> Base de Datos >  >> RDS >> PostgreSQL

Primeros pasos con PostgreSQL 11 en Ubuntu 18.04

PostgreSQL, si bien es un RDBMS moderno y versátil, no es la bestia más fácil de configurar y poner en marcha mientras busca desarrollar una aplicación. Siga leyendo para saber cómo puede comenzar con la última versión de PostgreSQL en la versión LTS de Ubuntu.

Instalación

Ubuntu 18.04 viene con PostgreSQL 10, pero en su lugar podemos usar el repositorio APT alojado por el equipo de PostgreSQL para instalar la última versión, PostgreSQL 11.

Puede configurar el repositorio usando estos comandos:

# add the repository
sudo tee /etc/apt/sources.list.d/pgdg.list <<END
deb http://apt.postgresql.org/pub/repos/apt/ bionic-pgdg main
END

# get the signing key and import it
wget https://www.postgresql.org/media/keys/ACCC4CF8.asc
sudo apt-key add ACCC4CF8.asc

# fetch the metadata from the new repo
sudo apt-get update

Y luego instale el software en sí, usando:

sudo apt-get install postgresql-11

La instalación hace algunas cosas:

  • Instala el servidor PostgreSQL, las utilidades y un cliente de línea de comandos llamado psql .
  • Crea un usuario del sistema Linux llamado postgres . Todos los archivos de datos son propiedad de este usuario y todos los procesos se ejecutan como este usuario.
  • Crea una base de datos, también llamada postgres .
  • Crea un usuario de PostgreSQL (no el usuario del sistema Linux), también llamado postgres .

¡Puedes ver que esto comienza a ser confuso!

Clústeres de bases de datos

Su servidor PostgreSQL recién instalado consiste en un conjunto de procesos que administran lo que se conoce como un "clúster de base de datos". Puedes ver los procesos aquí:

alice@devbox:~$ ps axfww | grep postgres
 4737 ?        S      0:00 /usr/lib/postgresql/11/bin/postgres -D /var/lib/postgresql/11/main -c config_file=/etc/postgresql/11/main/postgresql.conf
 4749 ?        Ss     0:00  \_ postgres: 11/main: checkpointer
 4750 ?        Ss     0:00  \_ postgres: 11/main: background writer
 4751 ?        Ss     0:00  \_ postgres: 11/main: walwriter
 4752 ?        Ss     0:00  \_ postgres: 11/main: autovacuum launcher
 4753 ?        Ss     0:00  \_ postgres: 11/main: stats collector
 4754 ?        Ss     0:00  \_ postgres: 11/main: logical replication launcher  

El proceso principal (aquí con PID 4737) es el proceso principal que genera aún más los procesos secundarios; esto se conoce convencionalmente como el proceso "postmaster".

El uso de PostgreSQL del término "clúster" es anterior a la elegante jerga de clústeres distribuidos de hoy en día:aquí solo significa un conjunto de bases de datos administradas en una sola máquina por un solo administrador de correos. Obtenga más información sobre los clústeres aquí.

Un clúster contiene bases de datos (por ahora solo tenemos una, “postgres”) y usuarios de PostgreSQL (nuevamente, solo uno por ahora, también llamado “postgres”), entre otras cosas. Para que lo sepas, el clúster está asociado con una gran cantidad de archivos de datos, todos los cuales viven en un solo directorio, en este caso en /var/lib/postgresql/11/main . ¿Notó esta ruta en la línea de comandos del administrador de correos anterior?

Cuando su aplicación, o psql, se conecta a Postgres, tiene que hacerlo en el contexto de un usuario de PostgreSQL. Hay siempre un usuario de PostgreSQL asociado con una conexión. Pero, como ya habrá adivinado, un usuario de PostgreSQL puede corresponder o no a un usuario del sistema.

Usuarios del sistema y usuarios de PostgreSQL

Los usuarios de PostgreSQL se pueden crear mediante comandos SQL como CREATE ROLE o herramientas integradas como createdb.

Cuando cualquier aplicación intenta conectarse a Postgres, debe proporcionar un nombre de usuario de PostgreSQL. Veamos qué sucede cuando inicia un cliente de PostgreSQL como psql:

alice@devbox:~$ psql
psql: FATAL:  role "alice" does not exist

Aquí, "alicia" es el nombre de usuario de su sistema Linux. psql toma este nombre y lo usa como el nombre de usuario de Postgres. Un rol (los roles son un nombre genérico de tipo para "usuario" o "grupo", por cierto) con ese nombre no existe, que es de lo que se queja Postgres.

Sabemos que hay un rol con el nombre "postgres", así que intentémoslo. Podemos usar el parámetro “-U” de psql para especificar el nombre de usuario:

alice@devbox:~$ psql -U postgres
psql: FATAL:  Peer authentication failed for user "postgres"

Bien, nos estamos acercando:el rol/usuario "postgres" existe, pero la "autenticación entre pares" ha fallado. ¿Qué es esta "autenticación de pares"?

Autenticación de pares y contraseña

Los clientes de PostgreSQL como psql o su aplicación pueden conectarse al servidor de PostgreSQL a través de uno de estos mecanismos IPC:

  • Sockets de dominio Unix
  • Conectores TCP

A diferencia de los sockets TCP, los sockets de dominio Unix ofrecen la posibilidad de validar la identificación de usuario del sistema de la conexión del cliente. El servidor de Postgres puede examinar una conexión entrante a través de un socket de dominio Unix y determinar el ID de usuario del sistema del cliente y luego decidir si otorgarle acceso o no.

De manera predeterminada, su servidor solo escucha conexiones a través de sockets de dominio Unix y no TCP/IP.

Veamos qué sucede si intentamos iniciar psql como usuario del sistema postgres:

alice@devbox:~$ sudo -u postgres psql
psql (11.0 (Ubuntu 11.0-1.pgdg18.04+2))
Type "help" for help.

postgres=#

¡Eso funciono! (Utilice "\q", "\quit" o ^D para salir de psql, por cierto.)

En la autenticación de pares, si la conexión del cliente se realiza mediante un socket de dominio Unix y el proceso del cliente tiene el mismo nombre de usuario del sistema que el usuario de PostgreSQL con el que intenta conectarse, entonces la autenticación se considera exitosa.

A los usuarios de PostgreSQL también se les puede asignar opcionalmente una contraseña, y puede pedirle a PostgreSQL que valide las conexiones entrantes usando la contraseña. ¿Pero cómo? Esa es la siguiente pieza del rompecabezas.

pg_hba.conf

Ahora es el momento de abrir el (in)famoso archivo de configuración pg_hba.conf, ubicado en /etc/postgresql/11/main/pg_hba.conf :

sudo vim /etc/postgresql/11/main/pg_hba.conf

HBA significa autenticación basada en host. Básicamente, este archivo se usa para controlar cómo se autentican los usuarios de PostgreSQL. Este archivo es probablemente la parte menos intuitiva de la curva de aprendizaje de PostgreSQL. La documentación de referencia está aquí, debe leerla más tarde.

La primera línea (sin comentarios) aquí es:

local all postgres peer

que le dice a Postgres que acepte conexiones "locales" (dominio UNIX) a "todas" las bases de datos, autenticándose como usuario "postgres" usando la autenticación "peer". Esta es la razón por la cual conectarse como el usuario del sistema "postgres" funciona de forma inmediata.

El orden de las líneas en este archivo es importante, la primera línea que coincida gana. Veamos otra línea:

host all all 127.0.0.1/32 md5

Esta línea permite que "todos" los usuarios inicien sesión usando TCP/IP ("host") desde el host local ("127.0.0.1/32") a "todas" las bases de datos, si tienen éxito en la autenticación de contraseña usando el método "md5".

Hay más métodos de autenticación de contraseña (md5, scram-sha-256, gss, ldap, …) de los que podemos cubrir, así que volvamos a ejemplos más simples.

Pero primero, debemos asegurarnos de que PostgreSQL también acepte conexiones TCP/IP. Para eso, debemos editar el archivo de configuración principal.

postgresql.conf

El archivo /etc/postgresql/11/main/postgresql.conf es el archivo de configuración principal para su clúster de PostgreSQL. Este archivo contiene mucho de ajustes, y comprender lo que significan todos ellos no es tarea fácil en absoluto. Por ahora, veamos la primera configuración:

#listen_addresses = 'localhost'

Esta línea está comentada de forma predeterminada, vamos a descomentarla para que se lea:

listen_addresses = 'localhost'

Esto permitirá que PostgreSQL escuche las conexiones TCP/IP entrantes en localhost, puerto 5432 (el valor predeterminado). Guarde los cambios (tendrá que ser "root" para hacerlo) y reinicie el servidor de Postgres para que los cambios surtan efecto:

sudo systemctl restart postgresql

(Tenga en cuenta que para la mayoría de los cambios de configuración solo tiene que "recargar", no "reiniciar", pero esto requiere un "reinicio").

Ahora podemos ver a Postgres escuchando en el puerto 5432, vinculado a 127.0.0.1:

alice@devbox:~$ sudo netstat -tnlp | grep 5432
tcp        0      0 127.0.0.1:5432          0.0.0.0:*               LISTEN      8408/postgres

Ahora configuremos un nuevo usuario y base de datos para que los use una aplicación.

Configuración de la aplicación

Conectémonos como superusuario “postgres” para realizar los cambios:

alice@devbox:~$ sudo -u postgres psql
psql (11.0 (Ubuntu 11.0-1.pgdg18.04+2))
Type "help" for help.

postgres=# create user myapp_user password 's3cr3t';
CREATE ROLE
postgres=# create database myapp owner myapp_user;
CREATE DATABASE
postgres=#

Ahora hemos creado una base de datos llamada myapp y un usuario llamado myapp_user ,con la contraseña s3cr3t . La base de datos está vacía y será propiedad del usuario myapp_user , lo que significa que al conectarse como myapp_user el cliente podrá ejecutar la mayoría de los comandos DDL/DML.

Conectémonos a la base de datos de la aplicación como este usuario de la aplicación ahora:

alice@devbox:~$ psql -h 127.0.0.1 -d myapp -U myapp_user
Password for user myapp_user:
psql (11.0 (Ubuntu 11.0-1.pgdg18.04+2))
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

myapp=>

¡Funcionó! Ahora está conectado a "myapp" (vea el aviso), usando SSL sobre una conexión TCP/IP a 127.0.0.1. Tenga en cuenta que también especificamos el nombre de la base de datos en la línea de comandos para psql. Por razones históricas, si esto se omite, también se asume que el nombre de la base de datos es el mismo que el nombre de usuario del sistema ("alice" aquí), que no es lo que queremos. También se especifica el nombre de usuario de PostgreSQL ("-U myapp_user").

Si necesita conectarse desde otras máquinas, deberá editar pg_hba.conf para agregar líneas así:

# existing entry, allows connections from localhost
host all   all        127.0.0.1/32 md5

# new entry to allow connections from 10.1.2.0/24 subnet,
# only to myapp database for myapp_user
host myapp myapp_user 10.1.2.0/24  md5

y vuelva a cargar PostgreSQL ("sudo systemctl reload postgresql") para que los cambios surtan efecto.

Con esto en su lugar, ahora puede usar cadenas de conexión de base de datos como estas en sus aplicaciones:

# URL format
postgresql://myapp_user:[email protected]/myapp

# connection string format
host=127.0.0.1 user=myapp_user dbname=myapp password=s3cr3t

¡Listo!

Esto debería permitirle configurar una base de datos dedicada y un usuario para su aplicación. El marco de desarrollo de su aplicación (como Django, Drupal, etc.) debería ser capaz de crear objetos (como tablas, vistas) y administrar los datos en esta base de datos.