PostgreSQL, макар да е модерна и гъвкава RDBMS, не е най-лесният от зверове за настройка и работа, докато търсите да разработите приложение. Прочетете, за да научите как можете да започнете с най-новата версия на PostgreSQL на LTS версията на Ubuntu.
Инсталиране
Ubuntu 18.04 идва с PostgreSQL 10, но вместо това можем да използваме хранилището на APT, хоствано от екипа на PostgreSQL, за да инсталираме най-новата версия, PostgreSQL 11.
Можете да настроите хранилището с помощта на тези команди:
# 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
След това инсталирайте самия софтуер, като използвате:
sudo apt-get install postgresql-11
Инсталацията прави няколко неща:
- Той инсталира сървъра PostgreSQL, помощните програми и клиент от командния ред, нареченpsql .
- Той създава потребител на системата на Linux, наречен postgres . Всички файлове с данни са собственост на този потребител и всички процеси се изпълняват като този потребител.
- Създава една база данни, наричана още postgres .
- Той създава един потребител на PostgreSQL (не потребителят на системата Linux), наричан ощеpostgres .
Виждате, че това започва да става объркващо!
Клъстери от бази данни
Вашият новоинсталиран PostgreSQL сървър се състои от набор от процеси, които управляват това, което е известно като „клъстер от база данни“. Можете да видите процесите тук:
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
Основният процес (тук с PID 4737) е основният процес, който допълнително поражда дъщерните процеси – това условно се нарича процес „postmaster“.
Използването на термина „клъстер“ от PostgreSQL предшества съвременния модерен жаргон за разпределен клъстер – тук това просто означава набор от бази данни, управлявани на една машина от един администратор на пощата. Прочетете повече за клъстерите тук.
Клъстерът съдържа бази данни (засега имаме само една, „postgres“) и потребители на PostgreSQL (отново, само един засега, наричан още „postgres“) наред с други неща. Само за да знаете, клъстерът е свързан с цял куп файлове с данни, всички от които живеят в една единствена директория – в този случай под/var/lib/postgresql/11/main . Забелязахте ли този път в командния ред на пощенския администратор по-горе?
Когато вашето приложение, или psql, се свърже с Postgres, то трябва да направи това в контекста на потребител на PostgreSQL. Има винаги потребител на PostgreSQL, свързан с aconnection. Но, както може би се досещате досега, потребител на PostgreSQL може или не може да съответства на потребител на системата.
Системни потребители и потребители на PostgreSQL
Потребителите на PostgreSQL могат да бъдат създадени с помощта на SQL команди като CREATE ROLE или пакетни инструменти като createdb.
Когато някое приложение се опита да се свърже с Postgres, то трябва да предостави потребителско име на aPostgreSQL. Нека видим какво се случва, когато стартирате PostgreSQLclient като psql:
alice@devbox:~$ psql
psql: FATAL: role "alice" does not exist
Тук „alice“ е потребителското име на вашата Linux система. psql приема това име и го използва като потребителско име на Postgres. Роля (ролите са родово име за сортиране за „потребител“ или „група“, BTW) с това име не съществува, от което Postgres се оплаква.
Знаем, че има роля с името „postgres“, така че нека опитаме това. Можем да използваме параметъра “-U” на psql за определяне на потребителското име:
alice@devbox:~$ psql -U postgres
psql: FATAL: Peer authentication failed for user "postgres"
Добре, приближаваме се – ролята/потребител „postgres“ съществува, но „peerauthentication“ е неуспешна. Какво е това „peer authentication“?
Удостоверяване на партньор и парола
PostgreSQL клиенти като psql или вашето приложение могат да се свържат със сървъра на PostgreSQL през един от тези IPC механизми:
- Сокети на Unix домейн
- TCP сокети
За разлика от TCP сокетите, Unix домейните сокети предлагат възможност за валидиране на системния потребителски идентификатор на клиентската връзка. Сървърът на Postgres може да проучи входяща връзка през сокет на Unix домейн и да определи системния потребителски идентификатор на клиента и след това да реши дали да му предостави достъп или не.
По подразбиране вашият сървър слуша само връзки през unix домейн сокети, а не TCP/IP.
Нека видим какво ще се случи, ако се опитаме да стартираме psql като системен потребител postgres:
alice@devbox:~$ sudo -u postgres psql
psql (11.0 (Ubuntu 11.0-1.pgdg18.04+2))
Type "help" for help.
postgres=#
Това проработи! (Използвайте “\q”, “\quit” или ^D
за да излезете от psql, BTW.)
При равнопоставено удостоверяване, ако клиентската връзка се осъществява с помощта на Unix domainsocket и клиентският процес има същото системно потребителско име като PostgreSQLuser, с който се опитва да се свърже, тогава удостоверяването се счита за успешно.
Потребителите на PostgreSQL също могат да получат по избор парола и можете да поискате от PostgreSQL да потвърди входящите връзки с помощта на паролата. Но как? Това е следващото парче от пъзела.
pg_hba.conf
Сега е време да отворите (не)известния конфигурационен файл pg_hba.conf, намиращ се в/etc/postgresql/11/main/pg_hba.conf
:
sudo vim /etc/postgresql/11/main/pg_hba.conf
HBA означава удостоверяване, базирано на хост. По принцип този файл се използва за контрол на това как потребителите на PostgreSQL се удостоверяват. Този файл вероятно е най-неинтуитивната част от кривата на обучение на PostgreSQL. Референтната документация е тук, трябва да я прочетете по-късно.
Първият (без коментар) ред тук е:
local all postgres peer
който казва на Postgres да приема „локални“ (unix домейн) връзки към „всички“ бази данни, удостоверявайки се като потребител „postgres“, използвайки „peer“ удостоверяване. Ето защо свързването като системен потребител „postgres“ работи извън кутията.
Редът на редовете в този файл е важен, първият съвпадащ ред печели. Нека видим друг ред:
host all all 127.0.0.1/32 md5
Този ред позволява на „всички“ потребители да влязат с помощта на TCP/IP („хост“) от локалния хост („127.0.0.1/32“) до „всички“ бази данни, ако успеят да удостоверят автентификацията с парола с помощта на метода „md5“.
Има повече методи за удостоверяване на парола (md5, scram-sha-256, gss,ldap, ...), отколкото можем да покрием, така че нека просто се върнем към по-прости примери.
Но първо трябва да се уверим, че PostgreSQL приема и TCP/IP връзки. За това трябва да редактираме основния конфигурационен файл.
postgresql.conf
Файлът /etc/postgresql/11/main/postgresql.conf е основният конфигурационен файл за вашия PostgreSQL клъстер. Този файл съдържа много на настройките и разбирането какво означават всички те изобщо не е лесна задача. Засега нека видим първата настройка:
#listen_addresses = 'localhost'
Този ред е коментиран по подразбиране, нека го декоментираме, за да се чете:
listen_addresses = 'localhost'
Това ще позволи на PostgreSQL да слуша за входящи TCP/IP връзки на localhost, порт 5432 (по подразбиране). Запазете промените (ще трябва да сте „root“, за да направите това) и рестартирайте Postgres сървъра, за да влязат в сила промените:
sudo systemctl restart postgresql
(Обърнете внимание, че някои за повечето промени в настройките просто трябва да „презаредите“, а не да „рестартирате“, но това изисква „рестартиране“).
Сега можем да видим как Postgres слуша на порт 5432, свързан към 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
Сега нека настроим нов потребител и база данни за използване от приложение.
Настройка на приложението
Нека се свържем като суперпотребител „postgres“, за да направим промените:
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=#
Вече създадохме база данни, наречена myapp
и потребител, наречен myapp_user
,с парола s3cr3t
. Базата данни е празна и ще бъде собственост на потребителя myapp_user
, което означава, че чрез свързване като myapp_user
клиентът ще може да изпълнява повечето DDL/DML команди.
Нека се свържем с базата данни на приложението като този потребител на приложението сега:
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=>
Проработи! Вече сте свързани с „myapp“ (вижте подканата), като използвате SSL през aTCP/IP връзка до 127.0.0.1. Имайте предвид, че ние посочихме името на базата данни и в командния ред за psql. По исторически причини, ако това е пропуснато, името на базата данни също се приема, че е същото като името на системния потребител („alice“ тук), което не е това, което искаме. Потребителското име на PostgreSQL също е посочено (“-U myapp_user”).
Ако трябва да се свържете от други машини, ще трябва да редактирате pg_hba.conf
за добавяне на редове така:
# 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
и презаредете PostgreSQL („sudo systemctl презареди postgresql“), за да влязат в сила промените.
С това вече можете да използвате низове за връзка с база данни като тези във вашите приложения:
# URL format
postgresql://myapp_user:[email protected]/myapp
# connection string format
host=127.0.0.1 user=myapp_user dbname=myapp password=s3cr3t
Готови!
Това трябва да ви осигури настройка със специална база данни и потребител за вашето приложение. Вашата рамка за разработка на приложения (като Django, Drupal и др.) трябва да може да създава обекти (като таблици, изгледи) и да управлява данните в тази база данни.