Практикум
Подготовка
-
Остановите сервер:
[student@p620 ~]$ sudo systemctl stop postgresql
[student@p620 ~]$ sudo systemctl status postgresql ○ postgresql.service - Runners PostgreSQL service
Loaded: loaded (/etc/systemd/system/postgresql.service; enabled; vendor preset: disabled)
Active: inactive (dead) since Sat 2024-11-09 15:49:30 MSK; 7s ago
Process: 28517 ExecStartPre=/bin/mkdir -p /var/run/postgresql (code=exited, status=0/SUCCESS)
Process: 28519 ExecStartPre=/bin/chown -R postgres:postgres /var/run/postgresql (code=exited,
status=0/SUCCESS)
Process: 28520 ExecStart=/bin/bash -i -c /usr/pangolin-6.2.0/bin/postgres -D /pgdata/06/data
(code=exited, status=0/SUCCESS)
Main PID: 28520 -
В сеансе
postgres
переименуйте каталог данных кластера и создайте пустой новый каталог со старым именем - оно задано переменной окруженияPGDATA
:[postgres@p620 ~]$ cd $PGDATA
[postgres@p620 data]$ cd ..
[postgres@p620 06]$ pwd /pgdata/06
[postgres@p620 06]$ ls data
[postgres@p620 06]$ mv -v data{,.bak} renamed 'data' -> 'data.bak'
[postgres@p620 06]$ ls data.bak
[postgres@p620 06]$ mkdir $PGDATA
[postgres@p620 06]$ ls data data.bak
Кластер баз данных
-
Проверьте настройки системной локали:
[postgres@p620 06]$ locale LANG=en_US.UTF-8 LC_CTYPE="en_US.UTF-8" LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL= -
Выведите список настроек, в соответствии с которыми
initdb
будет создавать кластер баз данных:[postgres@p620 06]$ initdb -s
The files belonging to this database system will be owned by user "postgres". This user must also own the server process.
VERSION=15.5
PGDATA=/pgdata/06/data
share_path=/usr/pangolin-6.2.0/share
PGPATH=/usr/pangolin-6.2.0/bin
POSTGRES_SUPERUSERNAME=postgres
POSTGRES_BKI=/usr/pangolin-6.2.0/share/postgres.bki
POSTGRESQL_CONF_SAMPLE=/usr/pangolin-6.2.0/share/postgresql.conf.sample
PG_HBA_SAMPLE=/usr/pangolin-6.2.0/share/pg_hba.conf.sample
PG_IDENT_SAMPLE=/usr/pangolin-6.2.0/share/pg_ident.conf.sample
PG_QUOTA_SAMPLE=/usr/pangolin-6.2.0/share/pg_quota.conf.sample -
Создайте кластер данных командой
initdb
с настройками по умолчанию. Не указывайте опцию-k
или--data-checksums
. Требуется создать кластер данных без защиты данных контрольными суммами:[postgres@p620 06]$ initdb
The files belonging to this database system will be owned by user "postgres". This user must also own the server process.
The database cluster will be initialized with locale "en_US.UTF-8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".
Data page checksums are disabled.
fixing permissions on existing directory /pgdata/06/data ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default max_connections ...
"/usr/pangolin-6.2.0/bin/postgres" --check -F -c log_checkpoints=false -c is_initdb=true -c
max_connections=100 -c shared_buffers=1000 -c dynamic_shared_memory_type=posix < "/dev/null" >
"/dev/null" 2>&1
100
selecting default shared_buffers ... 128MB
selecting default time zone ... Europe/Moscow
creating configuration files ... ok
running bootstrap script ... 2024-11-09 16:15:06.155 MSK [31377] WARNING:
/usr/pangolin-6.2.0/bin/postgres: Could not init KMS connection. Error: -52 (failed to lock file)
ok
performing post-bootstrap initialization ... 2024-11-09 16:15:06.375 MSK [31379] WARNING: postgres:
Could not init KMS connection. Error: -52 (failed to lock file)
ok
syncing data to disk ... ok
initdb: warning: enabling "trust" authentication for local connections
initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and
--auth-host, the next time you run initdb.
Success. You can now start the database server using:
pg_ctl -D /pgdata/06/data -l logfile start -
Проверьте, что сервер может стартовать с вновь созданным кластером данных:
[student@p620 ~]$ sudo systemctl start postgresql
[student@p620 ~]$ sudo systemctl status postgresql ● postgresql.service - Runners PostgreSQL service
Loaded: loaded (/etc/systemd/system/postgresql.service; enabled; vendor preset: disabled)
Active: active (running) since Sat 2024-11-09 19:25:10 MSK; 6s ago
Process: 31726 ExecStartPre=/bin/mkdir -p /var/run/postgresql (code=exited, status=0/SUCCESS)
Process: 31727 ExecStartPre=/bin/chown -R postgres:postgres /var/run/postgresql (code=exited,
status=0/SUCCESS)
Main PID: 31728 (postgres)
Tasks: 10 (limit: 4652)
Memory: 28.6M
CPU: 164ms
CGroup: /system.slice/postgresql.service
├─ 31728 /usr/pangolin-6.2.0/bin/postgres -D /pgdata/06/data
├─ 31752 "postgres: checkpointer " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""
"" "" "" "" "" "" "" "" "" "" ""
├─ 31753 "postgres: background writer " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""
"" "" "" "" "" "" ""
├─ 31755 "postgres: idle sessions terminator " "" "" "" "" "" "" "" "" "" "" "" "" ""
"" "" ""
├─ 31756 "postgres: walwriter " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""
"" "" "" "" "" "" "" "" "" "" "" "" ""
├─ 31757 "postgres: license checker " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""
"" "" "" "" "" "" "" "" ""
├─ 31758 "postgres: autovacuum launcher " "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""
"" "" "" "" "" ""
├─ 31759 "postgres: autounite launcher " "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""
"" "" "" "" "" "" ""
"" "" ""
├─ 31760 "postgres: integrity check launcher " "" "" "" "" "" "" "" "" "" "" "" "" ""
└─ 31761 "postgres: logical replication launcher " "" "" "" "" "" "" "" "" "" "" "" ""
Nov 09 19:25:10 p620.class.edu bash[31728]: 2024-11-09 19:25:10.421 MSK [31728] LOG: listening on
IPv6 address "::1", port 5432
Nov 09 19:25:10 p620.class.edu bash[31728]: 2024-11-09 19:25:10.422 MSK [31728] LOG: listening on
IPv4 address "127.0.0.1", port 5432
Nov 09 19:25:10 p620.class.edu bash[31728]: 2024-11-09 19:25:10.430 MSK [31728] LOG: listening on
Unix socket "/tmp/.s.PGSQL.5432"
Nov 09 19:25:10 p620.class.edu bash[31754]: 2024-11-09 19:25:10.449 MSK [31754] LOG: database
system was shut down at 2024-11-09 16:15:06 MSK
Nov 09 19:25:10 p620.class.edu bash[31755]: 2024-11-09 19:25:10.454 MSK [31755] LOG: idle
terminator started
Nov 09 19:25:10 p620.class.edu bash[31757]: 2024-11-09 19:25:10.490 MSK [31757] LOG: License
checker started
Nov 09 19:25:10 p620.class.edu bash[31728]: 2024-11-09 19:25:10.498 MSK [31728] LOG: database
system is ready to accept connections
Nov 09 19:25:10 p620.class.edu bash[31760]: 2024-11-09 19:25:10.499 MSK [31728] LOG: Start
integrity check launcher
Nov 09 19:25:10 p620.class.edu bash[31760]: 2024-11-09 19:25:10.502 MSK [31760] LOG: Start of
integrity check
Nov 09 19:25:10 p620.class.edu systemd[1]: Started Runners PostgreSQL service.
[student@p620 ~]$ ps f -C postgres
PID TTY
31728 ?
31752 ?
31753 ?
31755 ?
31756 ?
31757 ?
31758 ?
31759 ?
31760 ?
31761 ?
STAT TIME COMMAND
Ss 0:00 /usr/pangolin-6.2.0/bin/postgres -D /pgdata/06/data
Ss 0:00 \_ postgres: checkpointer
Ss 0:00 \_ postgres: background writer
Ss 0:00 \_ postgres: idle sessions terminator
Ss 0:00 \_ postgres: walwriter
Ss 0:00 \_ postgres: license checker
Ss 0:00 \_ postgres: autovacuum launcher
Ss 0:00 \_ postgres: autounite launcher
Ss 0:00 \_ postgres: integrity check launcher
Ss 0:00 \_ postgres: logical replication launcher -
Остановите сервер. Теперь необходимо убедиться в том, что контрольные суммы не включены:
[student@p620 ~]$ sudo systemctl stop postgresql
[student@p620 ~]$ sudo -iu postgres
[postgres@p620 ~]$ pg_checksums -D $PGDATA -c
pg_checksums: error: data checksums are not enabled in clusterКоманда
pg_checksums
с опцией-c
проверяет, включены ли контрольные суммы. -
Включите контрольные суммы и снова проверьте. Сервер должен быть остановлен:
[postgres@p620 ~]$ pgrep -l postgres
[postgres@p620 ~]$ pg_checksums -D $PGDATA -e Checksum operation completed
Files scanned: 1011
Blocks scanned: 3476
Files written: 827
Blocks written: 3476
pg_checksums: syncing data directory
pg_checksums: updating control file
Checksums enabled in clusterКонтрольные суммы включены.
Начальная настройка экземпляра
-
В сеансе
postgres
перейдите в каталогPGDATA
и внесите изменения в конфигурационный файлpostgresql.conf
, предварительно сохранив его копию:[postgres@p620 ~]$ cd $PGDATA
[postgres@p620 data]$ cp -v postgresql.conf{,.orig} 'postgresql.conf' -> 'postgresql.conf.origНастройка для прослушивания всех интерфейсов:
[postgres@p620 data]$ tee -a postgresql.conf <<< "listen_addresses = '*'" listen_addresses = '*'
Разрешенные дополнительные методы аутентификации:
[postgres@p620 data]$ tee -a postgresql.conf <<< "enabled_extra_auth_methods = 'scram-sha-256, peer, cert'"
enabled_extra_auth_methods = 'scram-sha-256, peer, cert'Разрешение запоминать историю выполненных команд в psql:
[postgres@p620 data]$ tee -a postgresql.conf <<< "psql.save_history = 'on'"
-
Сохраните резервную копию файла настроек аутентификации
pg_hba.conf
:[postgres@p620 data]$ cp -v pg_hba.conf{,.orig} 'pg_hba.conf' -> 'pg_hba.conf.orig'
-
Настройка разрешений аутентификации в
pg_hba.conf
. Метод аутентификацииtrust
необходимо заменить. Поставьте метод peer для метода подключенияlocal
иscram-sha-256
для метода аутентификацииhost
. Ниже приводятся автоматические команды, редактирующие файлpg_hba.conf
с помощью потокового редактораsed
. Если это вызывает затруднения, воспользуйтесь привычным текстовым редактором и просто скопируйте в него результат редактирования, который будет показан ниже. Заменаtrust
методом peer для локальных подключений через Unix-сокет:[postgres@p620 data]$ sed -i 's/\(^local.*\)trust/\1 peer/' pg_hba.conf
Замена trust методом
scram-sha-256
для сетевых подключенийhost
:[postgres@p620 data]$ sed -i 's/\(^host.*\)trust/\1 scram-sha-256/' pg_hba.conf
Замена IPv4 адреса
127.0.0.1/32
разрешением подключаться с любых сетевых интерфейсов данного хоста:[postgres@p620 data]$ sed -i 's/127\.0\.0\.1\/32/samehost /' pg_hba.conf
Результат (показаны последние 13 строк файла):
[postgres@p620 data]$ tail -13 pg_hba.conf
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all peer
# IPv4 local connections:
host all all 127.0.0.1/32 scram-sha-256
# IPv6 local connections:
host all all ::1/128 scram-sha-256
# Allow replication connections from localhost, by a user with the
# replication privilege.
local replication all peer
host replication all 127.0.0.1/32 scram-sha-256
host replication all ::1/128 scram-sha-256Суть таких настроек: при локальных подключениях будет разрешен вход без пароля зарегистрированным в ОС пользователям, имена которых совпадают с именами ролей в PostgreSQL. Пример:
postgres
. Подключения через сеть потребуют ввода паролей (пока не установлены). -
Запускайте сервер из-под учетной записи
student
, так какpostgres
не имеет доступ к sudo (и ни в коем случае не должен иметь доступ кsudo
):[student@p620 ~]$ sudo systemctl start postgresql
127.0.0.1/32
::1/128
scram-sha-256
peer
scram-sha-256
scram-sha-256
127.0.0.1/32
::1/128
[student@p620 ~]$ ps f -C postgres
PID TTY
31973 ?
31997 ?
31998 ?
32000 ?
32001 ?
32002 ?
32003 ?
32004 ?
32005 ?
32006 ?
STAT TIME COMMAND
Ss 0:00 /usr/pangolin-6.2.0/bin/postgres -D /pgdata/06/data
Ss 0:00 \_ postgres: checkpointer
Ss 0:00 \_ postgres: background writer
Ss 0:00 \_ postgres: idle sessions terminator
Ss 0:00 \_ postgres: walwriter
Ss 0:00 \_ postgres: license checker
Ss 0:00 \_ postgres: autovacuum launcher
Ss 0:00 \_ postgres: autounite launcher
Ss 0:00 \_ postgres: integrity check launcher
Ss 0:00 \_ postgres: logical replication launcher
Базы данных
-
Из сеанса пользователя ОС
postgres
подключитесь к экземпляру:[postgres@p620 data]$ cd
[postgres@p620 ~]$ psql psql (15.5)
Type "help" for help.
postgres=# \conninfo
You are connected to database "postgres" as user "postgres" via socket in "/tmp" at port "5432". -
Получите список баз данных:
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider |
-----------+----------+----------+-------------+-------------+------------+-----------------+
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc |
| | | | | | | |
| template1| postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc |
| | | | | | | |
(3 rows) -
Получите список ролей:
postgres=# \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {} -
Задайте суперпользователю
postgres
пароль для обеспечения возможности входить в сеанс с помощью парольной аутентификации, которая потребуется при сетевом подключении:postgres=# ALTER ROLE postgres PASSWORD 'postgres'; ALTER ROLE
-
Зарегистрируйте роль
student
с правом входа в сеанс и паролемstudent
:postgres=# CREATE USER student PASSWORD 'student';
postgres=# \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
student | | {} -
Создайте БД
student
, принадлежащую ролиstudent
:postgres=# CREATE DATABASE student OWNER student; CREATE DATABASE
postgres=# \l student
List of databases
Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access pr
---------+---------+----------+-------------+-------------+------------+-----------------+----------
student | student | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc |
(1 row) -
Создайте БД
koi8_db
с кодировкойKOI8R
, отличающейся от кодировки кластераen_US.UTF-8
. Для этого необходимо воспользоваться шаблономtemplate0
:postgres=# CREATE DATABASE koi8_db TEMPLATE=template0 ENCODING='KOI8R' LOCALE='ru_RU.koi8r';
CREATE DATABASE
postgres=# \x \l *_db \x
Expanded display is on.
List of databases
-[ RECORD 1 ]-----+------------
Name | koi8_db
Owner | postgres
Encoding | KOI8R
Collate | ru_RU.koi8r
Ctype | ru_RU.koi8r
ICU Locale |
Locale Provider | libc
Access privileges |
Expanded display is off.
Настройка шаблона template1
-
Подключитесь к БД
template1
- шаблону для создания БД по умолчанию:postgres=# \c template1
You are now connected to database "template1" as user "postgres". -
Создайте схему
py_json
для размещения объектов расширения:template1=# CREATE SCHEMA py_json; CREATE SCHEMA
-
Подключите расширение
jsonb_plpython3u
с опцией каскадной установки зависимостей:template1=# CREATE EXTENSION jsonb_plpython3u CASCADE SCHEMA py_json; NOTICE: installing required extension "plpython3u"
CREATE EXTENSION -
Проверьте, что расширение установлено:
template1=# \dx
List of installed extensions
Name | Version | Schema | Description
------------------+---------+------------+-------------------------------------------
jsonb_plpython3u | 1.0 | py_json | transform between jsonb and plpython3u
plpgsql | 1.1 | pg_catalog | PL/pgSQL procedural language
plpython3u | 1.0 | pg_catalog | PL/Python3U untrusted procedural language
(3 rows) -
Подключитесь к БД
postgres
и создайте БДpy_json_db
, используя шаблон по умолчанию:template1=# \c postgres
You are now connected to database "postgres" as user "postgres".
postgres=# CREATE DATABASE py_json_db;
CREATE DATABASE
postgres=# \x \l py* \x
Expanded display is on.
List of databases
-[ RECORD 1 ]-----+------------
Name | py_json_db
Owner | postgres
Encoding | UTF8
Collate | en_US.UTF-8
Ctype | en_US.UTF-8
ICU Locale |
Locale Provider | libc
Access privileges |
Expanded display is off -
Подключитесь к БД
py_json_db
и проверьте наличие расширения:py_json_db=# \dx
List of installed extensions
Name | Version | Schema | Description
-----------------+----------+------------+--------------------------------------------
jsonb_plpython3u | 1.0 | py_json | transform between jsonb and plpython3u
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
plpython3u | 1.0 | pg_catalog | PL/Python3U untrusted procedural language
(3 rows)
py_json_db=# \dx+ jsonb_plpython3u
Objects in extension "jsonb_plpython3u"
Object description
-----------------------------------------------
function py_json.jsonb_to_plpython3(internal)
function py_json.plpython3_to_jsonb(internal)
transform for jsonb language plpython3u
(3 rows) -
Подключитесь к шаблону
template1
и удалите расширение вместе с зависимыми объектами:py_json_db=# \c template1
You are now connected to database "template1" as user "postgres".
template1=# DROP EXTENSION jsonb_plpython3u CASCADE;
DROP EXTENSION
template1=# \dn
List of schemas
Name | Owner
---------+-------------------
public | pg_database_owner
py_json | postgres
(2 rows)
template1=# DROP SCHEMA py_json ;
DROP SCHEMA
template1=# \dx
List of installed extensions
Name | Version | Schema | Description
------------+---------+------------+-------------------------------------------
plpgsql | 1.1 | pg_catalog | PL/pgSQL procedural language
plpython3u | 1.0 | pg_catalog | PL/Python3U untrusted procedural language
(2 rows)
template1=# \c postgres
You are now connected to database "postgres" as user "postgres".
Схемы
-
Подключитесь к БД student пользователем
student
:[student@p620 ~]$ psql
psql (15.5)
Type "help" for help.
student@student=> \conninfo
You are connected to database "student" as user "student" via socket in "/tmp" at port "5432".
student@student=> -
Получите список схем в БД:
student@student=> \dn List of schemas Name | Owner
--------+-------------------
public | pg_database_owner
(1 row) -
Создайте таблицу
stab
и заполните ее случайными данными:student@student=> CREATE TABLE stab (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY, nmr real DEFAULT random(),
dte timestamp DEFAULT now(),
msg text );
CREATE TABLE
student@student=> INSERT INTO stab(msg) SELECT 'A' FROM generate_series(1,100000); INSERT 0 100000 -
Проверьте, в какой схеме была создана таблица:
student@student=> \d
List of relations
Schema | Name | Type | Owner
--------+-------------+----------+---------
public | stab | table | student
public | stab_id_seq | sequence | student
(2 rows)Схема
public
. -
Создайте схему
student
:student@student=> CREATE SCHEMA student; CREATE SCHEMA
student@student=> \dn List of schemas Name | Owner
---------+-------------------
public | pg_database_owner
student | student
(2 rows) -
Создайте еще одну таблицу
stab
без полей:student@student=> CREATE TABLE stab(); CREATE TABLE
student@student=> \d
List of relations
Schema | Name | Type | Owner
---------+-------------+----------+---------
public | stab_id_seq | sequence | student
student | stab | table | student
(2 rows)
student@student=> SELECT count(*) FROM stab; count
------- 0
(1 row)Таблица пустая.
-
Определите, где находится первая таблица
stab
:student@student=> \dt *.stab List of relations
Schema | Name | Type | Owner
---------+------+-------+---------
public | stab | table | student
student | stab | table | student
(2 rows) -
Проверьте настройку пути поиска в схемах, определите реальный путь поиска и имя схемы, в которой будут создаваться новые объекты:
student@student=> \dconfig search_path
List of configuration parameters
Parameter | Value
-------------+-----------------
search_path | "$user", public
(1 row)
student@student=> SELECT current_schemas(true);
current_schemas
-----------------------------
{pg_catalog,student,public}
(1 row)
student@student=> SELECT current_schema();
current_schema
----------------
student
(1 row)Параметр
search_path
, задающий последовательность схем для поиска в них объектов, настроен по умолчанию:"$user"
,public
. Сначала производится поиск объектов в одноименной схеме с именем пользователя, если такая схема существует. Далее вpublic
.Реальный путь:
pg_catalog,student,public
. Схемаpg_catalog
объектов системного каталога просматривается первой.Схема, в которой будут создаваться новые объекты:
student
. -
Создайте временную таблицу
stab
с произвольной структурой:student@student=> CREATE TEMP TABLE stab(n numeric); CREATE TABLE
-
Получите список всех таблиц с именем
stab
:
student@student=> \dt *.stab List of relations
Schema | Name | Type | Owner
-----------+------+-------+---------
pg_temp_5 | stab | table | student
public | stab | table | student
student | stab | table | student
(3 rows)
-
Снова проверьте реальный путь поиска:
student@student=> SELECT current_schemas(true); \
current_schemas
---------------------------------------
{pg_temp_5,pg_catalog,student,public}
(1 row) -
Рестартуйте сессию, проверьте, какие таблицы stab остались и какой теперь реальный путь поиска:
student@student=> \c
You are now connected to database "student" as user "student".
student@student=> \dt *.stab
List of relations
Schema | Name | Type | Owner
---------+------+-------+---------
public | stab | table | student
student | stab | table | student
(2 rows)
student@student=> SELECT current_schemas(true); current_schemas
-----------------------------
{pg_catalog,student,public}
(1 row)