PostgreSQL, samtidigt som det är ett modernt och mångsidigt RDBMS, är inte det lättaste av beasts att installera och komma igång medan du letar efter att utveckla en applikation. Läs vidare för att lära dig mer om hur du kan komma igång med den senaste versionen av PostgreSQL på LTS-versionen av Ubuntu.
Installation
Ubuntu 18.04 kommer med PostgreSQL 10, men vi kan istället använda APT-förrådet som PostgreSQL-teamet är värd för att installera den senaste versionen, PostgreSQL 11.
Du kan ställa in förvaret med dessa kommandon:
# 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
Och installera sedan själva programvaran med:
sudo apt-get install postgresql-11
Installationen gör några saker:
- Den installerar PostgreSQL-servern, verktyg och en kommandoradsklient som heterpsql .
- Den skapar en Linux-systemanvändare som heter postgres . Alla datafiler ägs av denna användare, och alla processer körs som denna användare.
- Det skapar en databas, även kallad postgres .
- Det skapar en PostgreSQL-användare (inte Linux-systemanvändaren), även kalladpostgres .
Du kan se att det här börjar bli förvirrande!
Databaskluster
Din nyinstallerade PostgreSQL-server består av en uppsättning processer som hanterar vad som kallas ett "databaskluster". Du kan se processerna här:
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
Huvudprocessen (här med PID 4737) är huvudprocessen som ytterligare skapar de underordnade processerna – detta kallas konventionellt för "postmaster"-processen.
PostgreSQL:s användning av termen "kluster" går före dagens tjusiga distribuerade kluster-jargong - här betyder det bara en uppsättning databaser som hanteras på en enda maskin av en enda postmaster. Läs mer om kluster här.
Ett kluster innehåller databaser (för nu har vi bara en, "postgres") och PostgreSQL-användare (återigen, bara en för nu, även kallad "postgres") bland annat. Bara så att du vet är klustret associerat med en hel massa datafiler, som alla finns under en enda katalog – i det här fallet under/var/lib/postgresql/11/main . Lade du märke till den här sökvägen i postmaster-kommandoraden ovan?
När din app, eller psql, ansluter till Postgres, måste den göra det i en PostgreSQL-användares sammanhang. Det finns alltid en PostgreSQL-användare kopplad till en anslutning. Men som du kanske har gissat vid det här laget, kanske en PostgreSQL-användare kanske inte motsvarar en systemanvändare.
Systemanvändare och PostgreSQL-användare
PostgreSQL-användare kan skapas med SQL-kommandon som CREATE ROLEeller medföljande verktyg som createb.
När någon applikation försöker ansluta till Postgres, måste den ange aPostgreSQL-användarnamn. Låt oss se vad som händer när du startar en PostgreSQLclient som psql:
alice@devbox:~$ psql
psql: FATAL: role "alice" does not exist
Här är "alice" ditt användarnamn för Linux-systemet. psql tar detta namn och använder det som Postgres användarnamn. En roll (roller är ett slags generiskt namn för "användare" eller "grupp", BTW) med det namnet existerar inte, vilket är vad Postgres klagar över.
Vi vet att det finns en roll med namnet "postgres", så låt oss prova det. Vi kan använda parametern "-U" för psql för att ange användarnamnet:
alice@devbox:~$ psql -U postgres
psql: FATAL: Peer authentication failed for user "postgres"
OK, vi närmar oss – rollen/användaren "postgres" finns, men "peerauthentication" har misslyckats. Vad är denna "peer-autentisering"?
Peer- och lösenordsautentisering
PostgreSQL-klienter som psql eller din app kan ansluta till PostgreSQL-servern över en av dessa IPC-mekanismer:
- Unix-domänsockets
- TCP-uttag
Till skillnad från TCP-sockets erbjuder Unix-domänsockets möjligheten att validera klientanslutningens systemanvändar-ID. Postgres-servern kan undersöka en inkommande anslutning över en Unix-domänsocket och bestämma klientens systemanvändar-ID och sedan bestämma om den ska beviljas åtkomst eller inte.
Som standard lyssnar din server bara efter anslutningar över unix-domänsockets och inte TCP/IP.
Låt oss se vad som händer om vi försöker starta psql som systemanvändare postgres:
alice@devbox:~$ sudo -u postgres psql
psql (11.0 (Ubuntu 11.0-1.pgdg18.04+2))
Type "help" for help.
postgres=#
Det fungerade! (Använd “\q”, “\quit” eller ^D
för att avsluta psql, förresten.)
Vid peer-autentisering, om klientanslutningen görs med en Unix-domänsocket och klientprocessen har samma systemanvändarnamn som den PostgreSQLuser som den försöker ansluta som, anses autentiseringen vara framgångsrik.
PostgreSQL-användare kan också valfritt tilldelas ett lösenord, och du kan be PostgreSQL att validera inkommande anslutningar med lösenordet. Men hur? Det är nästa pusselbit.
pg_hba.conf
Det är nu dags att öppna den (o)berömda pg_hba.conf-konfigurationsfilen, som finns på /etc/postgresql/11/main/pg_hba.conf
:
sudo vim /etc/postgresql/11/main/pg_hba.conf
HBA står för värdbaserad autentisering. I grund och botten används den här filen för att kontrollera hur PostgreSQL-användare autentiseras. Den här filen är förmodligen den mest icke-intuitiva delen av PostgreSQL-inlärningskurvan. Referensdokumentationen finns här, du bör läsa den senare.
Den första (icke-kommentar) raden här är:
local all postgres peer
som säger till Postgres att acceptera "lokala" (unix-domän) anslutningar till "alla" databaser, autentisera som användaren "postgres" med "peer"-autentisering. Det är därför anslutning som systemanvändare "postgres" fungerar direkt.
Ordningen på raderna i den här filen är viktig, den första matchande raden vinner. Låt oss se en annan rad:
host all all 127.0.0.1/32 md5
Den här raden tillåter "alla" användare att logga in med TCP/IP ("värd") från localhost ("127.0.0.1/32") till "alla" databaser, om de lyckas med lösenordsautentisering med "md5"-metoden.
Det finns fler lösenordsautentiseringsmetoder (md5, scram-sha-256, gss,ldap, …) än vi kan täcka, så låt oss bara gå tillbaka till enklare exempel.
Men först måste vi se till att PostgreSQL också accepterar TCP/IP-anslutningar. För det måste vi redigera huvudkonfigurationsfilen.
postgresql.conf
Filen /etc/postgresql/11/main/postgresql.conf är huvudkonfigurationsfilen för ditt PostgreSQL-kluster. Den här filen innehåller ett parti inställningar och att förstå vad alla dessa betyder är ingen lätt uppgift alls. För nu, låt oss se den allra första inställningen:
#listen_addresses = 'localhost'
Den här raden är kommenterad som standard, låt oss avkommentera den för att få den att läsa:
listen_addresses = 'localhost'
Detta låter PostgreSQL lyssna efter inkommande TCP/IP-anslutningar på localhost,port 5432 (standard). Spara ändringarna (du måste vara "root" för att göra detta) och starta om Postgres-servern för att ändringarna ska träda i kraft:
sudo systemctl restart postgresql
(Observera att vissa för de flesta inställningsändringar måste du bara "ladda om", inte "starta om", men detta kräver en "omstart").
Nu kan vi se Postgres lyssna på port 5432, bundet till 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
Låt oss nu konfigurera en ny användare och databas för användning av en app.
Appinställning
Låt oss ansluta som superanvändare "postgres" för att göra ändringarna:
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=#
Vi har nu skapat en databas som heter myapp
och en användare som heter myapp_user
, med lösenordet s3cr3t
. Databasen är tom och kommer att ägas av användarenmyapp_user
, vilket innebär att genom att ansluta som myapp_user
klienten kommer att kunna köra nästan alla DDL/DML-kommandon.
Låt oss ansluta till appdatabasen som denna appanvändare nu:
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=>
Det fungerade! Du är nu ansluten till "myapp" (se prompten), med SSL över en TCP/IP-anslutning till 127.0.0.1. Observera att vi angav databasnamnet också på kommandoraden för psql. Av historiska skäl, om detta utelämnas, antas även databasnamnet vara detsamma som systemets användarnamn ("alice" här), vilket inte är vad vi vill ha. PostgreSQL-användarnamnet anges också ("-U myapp_user").
Om du behöver ansluta från andra maskiner måste du redigera pg_hba.conf
för att lägga till rader så här:
# 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
och ladda om PostgreSQL ("sudo systemctl reload postgresql") för att ändringar ska träda i kraft.
Med detta på plats kan du nu använda databasanslutningssträngar som dessa i dina appar:
# URL format
postgresql://myapp_user:[email protected]/myapp
# connection string format
host=127.0.0.1 user=myapp_user dbname=myapp password=s3cr3t
Klar!
Detta bör ge dig en dedikerad databas och användare för din app. Ditt ramverk för apputveckling (som Django, Drupal etc.) bör kunna skapa objekt (som tabeller, vyer) och hantera data i denna databas.