Уровень 3.0
Предусловие: пройдены предыдущие практические задания: «Архитектура», «Транзакции».
Практика. Базы данных
Подготовительный этап
-
Остановите сервер:
[student@ServerName ~]$ sudo systemctl stop postgresql[student@ServerName ~]$ sudo systemctl status postgresql● postgresql.service - Runners PostgreSQL serviceLoaded: loaded (/etc/systemd/system/postgresql.service; disabled; vendor preset: disabled)Active: inactive (dead) -
В сеансе
postgresпереименуйте каталог данных кластера и создайте пустой новый каталог со старым именем — оно задано переменной окруженияPGDATA:[student@ServerName ~]$ sudo su - postgres[postgres@ServerName ~]$ cd $PGDATA[postgres@ServerName data]$ cd ..[postgres@ServerName 06]$ pwd/pgdata/06[postgres@ServerName 06]$ lsdata[postgres@ServerName 06]$ mv -v data{,.bak}renamed 'data' -> 'data.bak'[postgres@ServerName 06]$ lsdata.bak[postgres@ServerName 06]$ mkdir $PGDATA[postgres@ServerName 06]$ lsdata data.bak
Основной этап
-
Проверьте настройки системной локали:
[postgres@ServerName 06]$ localeLANG=en_US.UTF-8LC_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=en_US.UTF-8 -
Выведите список настроек, в соответствии с которыми
initdbбудет создавать кластер баз данных:[postgres@ServerName 06]$ initdb -sThe files belonging to this database system will be owned by user "postgres".This user must also own the server process.VERSION=15.5PGDATA=/pgdata/06/datashare_path=/usr/pangolin-{major.minor}/sharePGPATH=/usr/pangolin-{major.minor}/binPOSTGRES_SUPERUSERNAME=postgresPOSTGRES_BKI=/usr/pangolin-{major.minor}/share/postgres.bkiPOSTGRESQL_CONF_SAMPLE=/usr/pangolin-{major.minor}/share/postgresql.conf.samplePG_HBA_SAMPLE=/usr/pangolin-{major.minor}/share/pg_hba.conf.samplePG_IDENT_SAMPLE=/usr/pangolin-{major.minor}/share/pg_ident.conf.samplePG_QUOTA_SAMPLE=/usr/pangolin-{major.minor}/share/pg_quota.conf.sampleОпция
-s(simulate) показывает настройки, с которыми будет создан кластер, без фактического создания. -
Создайте кластер данных командой
initdbс настройками по умолчанию. Не указывайте опцию-kили--data-checksums. Требуется создать кластер данных без защиты данных контрольными суммами:[postgres@ServerName 06]$ initdbThe 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 ... okcreating subdirectories ... okselecting dynamic shared memory implementation ... posixselecting default max_connections ..."/usr/pangolin-{major.minor}/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>&1100selecting default shared_buffers ... 128MBselecting default time zone ... Europe/Moscowcreating configuration files ... okrunning bootstrap script ... WARNING: 01000: Force disable "enable_vault_certificates_cache" vault credentials does not existsLOCATION: check_enable_certificates_cache, security.c:112WARNING: 01000: Force disable "enable_vault_params_cache", vault credentials does not existsLOCATION: check_enable_params_cache, security.c:1012025-05-24 13:59:42.897 MSK [5218] WARNING: /usr/pangolin-{major.minor}/bin/postgres: Could not init KMS connection. Error: -52 (failed to lock file)okperforming post-bootstrap initialization ... WARNING: 01000: Force disable "enable_vault_certificates_cache" vault credentials does not existsLOCATION: check_enable_certificates_cache, security.c:112WARNING: 01000: Force disable "enable_vault_params_cache", vault credentials does not existsLOCATION: check_enable_params_cache, security.c:1012025-05-24 13:59:43.137 MSK [5220] WARNING: postgres: Could not init KMS connection. Error: -52 (failed to lock file)oksyncing data to disk ... okinitdb: warning: enabling "trust" authentication for local connectionsinitdb: 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 -
Проверьте, что сервер может стартовать с вновь созданным кластером данных:
[postgres@ServerName 06]$ exitlogout[student@ServerName ~]$ sudo systemctl start postgresql[student@ServerName ~]$ sudo systemctl status postgresql● postgresql.service - Runners PostgreSQL serviceLoaded: loaded (/etc/systemd/system/postgresql.service; disabled; vendor preset: disabled)Active: active (running) since Sat 2025-05-24 14:02:11 MSK; 6s agoProcess: 5280 ExecStartPre=/bin/mkdir -p /var/run/postgresql (code=exited, status=0/SUCCESS)Process: 5281 ExecStartPre=/bin/chown -R postgres:postgres /var/run/postgresql (code=exited, status=0/SUCCESS)Main PID: 5282 (postgres)Tasks: 10 (limit: 2362)Memory: 28.9MCGroup: /system.slice/postgresql.service├─5282 /usr/pangolin-{major.minor}/bin/postgres -D /pgdata/06/data├─5284 postgres: checkpointer├─5285 postgres: background writer├─5287 postgres: idle sessions terminator├─5288 postgres: walwriter├─5289 postgres: autovacuum launcher├─5290 postgres: autounite launcher├─5291 postgres: integrity check launcher├─5292 postgres: license checker└─5293 postgres: logical replication launcher[student@ServerName ~]$ ps f -C postgresPID TTY STAT TIME COMMAND5282 ? Ss 0:00 /usr/pangolin-{major.minor}/bin/postgres -D /pgdata/06/data5284 ? Ss 0:00 \_ postgres: checkpointer5285 ? Ss 0:00 \_ postgres: background writer5287 ? Ss 0:00 \_ postgres: idle sessions terminator5288 ? Ss 0:00 \_ postgres: walwriter5289 ? Ss 0:00 \_ postgres: autovacuum launcher5290 ? Ss 0:00 \_ postgres: autounite launcher5291 ? Ss 0:00 \_ postgres: integrity check launcher5292 ? Ss 0:00 \_ postgres: license checker5293 ? Ss 0:00 \_ postgres: logical replication launcher -
Остановите сервер. Теперь необходимо убедиться в том, что контрольные суммы не включены:
[student@ServerName ~]$ sudo systemctl stop postgresql[student@ServerName ~]$ sudo su - postgres[postgres@ServerName ~]$ pg_checksums -D $PGDATA -cpg_checksums: error: data checksums are not enabled in clusterКоманда
pg_checksumsс опцией-cпроверяет, включены ли контрольные суммы. -
Включите контрольные суммы и снова проверьте. Сервер должен быть остановлен:
[postgres@ServerName ~]$ pgrep -l postgrespgrep -l postgresищет процессы с именемpostgresи выводит их PID и имя. Пустой вывод подтверждает, что сервер остановлен.[postgres@ServerName ~]$ pg_checksums -D $PGDATA -eChecksum operation completedFiles scanned: 1011Blocks scanned: 3435Files written: 827Blocks written: 3435pg_checksums: syncing data directorypg_checksums: updating control fileChecksums enabled in clusterКонтрольные суммы включены.
Начальная настройка экземпляра
-
В сеансе
postgresперейдите в каталогPGDATAи внесите изменения в конфигурационный файлpostgresql.conf, предварительно сохранив его копию:[postgres@ServerName ~]$ cd $PGDATA[postgres@ServerName data]$ cp -v postgresql.conf{,.orig}'postgresql.conf' -> 'postgresql.conf.origНастройка для прослушивания всех интерфейсов:
[postgres@ServerName data]$ vi postgresql.conflisten_addresses = '*'Разрешенные дополнительные методы аутентификации:
[postgres@ServerName data]$ vi postgresql.confenabled_extra_auth_methods = 'scram-sha-256, peer, cert'Разрешение запоминать историю выполненных команд в psql:
[postgres@ServerName data]$ vi postgresql.confpsql.save_history = 'on' -
Сохраните резервную копию файла настроек аутентификации
pg_hba.conf:[postgres@ServerName 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@ServerName data]$ sed -i 's/\(^local.*\)trust/\1 peer/' pg_hba.confЗамена
trustметодомscram-sha-256для сетевых подключенийhost:[postgres@ServerName data]$ sed -i 's/\(^host.*\)trust/\1 scram-sha-256/' pg_hba.confЗамена IPv4-адреса
127.0.0.1/32разрешением подключаться с любых сетевых интерфейсов данного хоста:[postgres@ServerName data]$ sed -i 's/127\.0\.0\.1\/32/samehost /' pg_hba.confРезультат (показаны последние 13 строк файла):
[postgres@ServerName data]$ tail -13 pg_hba.conf# TYPE DATABASE USER ADDRESS METHOD# "local" is for Unix domain socket connections onlylocal all all peer# IPv4 local connections:host all all samehost 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 peerhost replication all samehost scram-sha-256host replication all ::1/128 scram-sha-256Суть таких настроек – при локальных подключениях будет разрешен вход без пароля зарегистрированным в ОС пользователям, имена которых совпадают с именами ролей в PostgreSQL, например,
postgres. Подключения через сеть потребуют ввода паролей (пока не установлены). -
Запускайте сервер из-под учетной записи
student, так какpostgresне имеет доступ кsudo(и ни в коем случае не должен иметь доступ кsudo):[postgres@ServerName 06]$ exitlogout[student@ServerName ~]$ sudo systemctl start postgresql[student@ServerName ~]$ ps f -C postgresPID TTY STAT TIME COMMAND5363 ? Ss 0:00 /usr/pangolin-{major.minor}/bin/postgres -D /pgdata/06/data5368 ? Ss 0:00 \_ postgres: checkpointer5369 ? Ss 0:00 \_ postgres: background writer5371 ? Ss 0:00 \_ postgres: idle sessions terminator5372 ? Ss 0:00 \_ postgres: walwriter5373 ? Ss 0:00 \_ postgres: autovacuum launcher5374 ? Ss 0:00 \_ postgres: autounite launcher5375 ? Ss 0:00 \_ postgres: integrity check launcher5376 ? Ss 0:00 \_ postgres: license checker5377 ? Ss 0:00 \_ postgres: logical replication launcher
Базы данных
-
Из сеанса пользователя ОС
postgresподключитесь к экземпляру:[student@ServerName ~]$ sudo su - postgres[postgres@ServerName ~]$ psqlpsql (15.5)Type "help" for help.postgres@postgres=# \conninfoYou are connected to database "postgres" as user "postgres" via socket in "/tmp" at port "5432". -
Получите список баз данных:
postgres@postgres=# \lList of databasesName | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges-----------+----------+----------+-------------+-------------+------------+-----------------+-----------------------postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc |template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =c/postgres +| | | | | | | postgres=CTc/postgrestemplate1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =c/postgres +| | | | | | | postgres=CTc/postgres(3 rows) -
Получите список ролей:
postgres@postgres=# \duList of rolesRole name | Attributes | Member of-----------+------------------------------------------------------------+-----------postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {} -
Задайте суперпользователю
postgresпароль для обеспечения возможности входить в сеанс с помощью парольной аутентификации, которая потребуется при сетевом подключении:postgres@postgres=# ALTER ROLE postgres PASSWORD 'postgres';ALTER ROLE -
Зарегистрируйте роль
studentс правом входа в сеанс и паролемstudent:postgres@postgres=# CREATE USER student PASSWORD 'student';CREATE ROLEpostgres@postgres=# \duList of rolesRole name | Attributes | Member of-----------+------------------------------------------------------------+-----------postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}student | | {} -
Создайте БД
student, принадлежащую ролиstudent:postgres@postgres=# CREATE DATABASE student OWNER student;CREATE DATABASEpostgres@postgres=# \l studentList of databasesName | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges---------+---------+----------+-------------+-------------+------------+-----------------+-------------------student | student | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc |(1 row) -
Создайте БД
koi8_dbс кодировкойKOI8R, отличающейся от кодировки кластераen_US.UTF-8. Для этого необходимо воспользоваться шаблономtemplate0:postgres@postgres=# CREATE DATABASE koi8_db TEMPLATE=template0 ENCODING='KOI8R' LOCALE='ru_RU.koi8r';CREATE DATABASEpostgres@postgres=# \x \l *_db \xExpanded display is on.List of databases-[ RECORD 1 ]-----+------------Name | koi8_dbOwner | postgresEncoding | KOI8RCollate | ru_RU.koi8rCtype | ru_RU.koi8rICU Locale |Locale Provider | libcAccess privileges |Expanded display is off.
Настройка шаблона template1
-
Подключитесь к БД
template1— шаблону для создания БД по умолчанию:postgres@postgres=# \c template1You are now connected to database "template1" as user "postgres". -
Создайте схему
profдля размещения объектов расширения:postgres@template1=# CREATE SCHEMA prof;CREATE SCHEMA -
Подключите расширение
pg_profileс опцией каскадной установки зависимостей:postgres@template1=# CREATE EXTENSION pg_profile CASCADE SCHEMA prof;NOTICE: installing required extension "dblink"CREATE EXTENSION -
Проверьте, что расширение установлено:
postgres@template1=# \dxList of installed extensionsName | Version | Schema | Description------------+---------+------------+--------------------------------------------------------------dblink | 1.2.1 | prof | connect to other PostgreSQL databases from within a databasepg_profile | 4.7.a | prof | PostgreSQL load profile repository and report builderplpgsql | 1.1 | pg_catalog | PL/pgSQL procedural language(3 rows) -
Подключитесь к БД
postgresи создайте БДprof_db, используя шаблон по умолчанию:postgres@template1=# \c postgresYou are now connected to database "postgres" as user "postgres".postgres@postgres=# CREATE DATABASE prof_db;CREATE DATABASEpostgres@postgres=# \x \l pro* \xExpanded display is on.List of databases-[ RECORD 1 ]-----+------------Name | prof_dbOwner | postgresEncoding | UTF8Collate | en_US.UTF-8Ctype | en_US.UTF-8ICU Locale |Locale Provider | libcAccess privileges |Expanded display is off. -
Подключитесь к БД
prof_dbи проверьте наличие расширения:postgres@postgres=# \c prof_dbYou are now connected to database "prof_db" as user "postgres".postgres@prof_db=# \dxList of installed extensionsName | Version | Schema | Description------------+---------+------------+--------------------------------------------------------------dblink | 1.2.1 | prof | connect to other PostgreSQL databases from within a databasepg_profile | 4.7.a | prof | PostgreSQL load profile repository and report builderplpgsql | 1.1 | pg_catalog | PL/pgSQL procedural language(3 rows)postgres@prof_db=# \dx+ pg_profileObjects in extension "pg_profile"Object description----------------------------------------------------------------------------------------------...view prof.v_sample_settingsview prof.v_sample_stat_indexesview prof.v_sample_stat_tablesview prof.v_sample_stat_tablespacesview prof.v_sample_stat_user_functionsview prof.v_sample_timings(258 rows) -
Подключитесь к шаблону
template1и удалите расширение вместе с зависимыми объектами:postgres@prof_db=# \c template1You are now connected to database "template1" as user "postgres".postgres@template1=# DROP EXTENSION pg_profile CASCADE;DROP EXTENSIONpostgres@template1=# \dnList of schemasName | Owner--------+-------------------prof | postgrespublic | pg_database_owner(2 rows)postgres@template1=# DROP SCHEMA prof CASCADE;NOTICE: drop cascades to extension dblinkDROP SCHEMApostgres@template1=# \dxList of installed extensionsName | Version | Schema | Description------------+---------+------------+-------------------------------------------plpgsql | 1.1 | pg_catalog | PL/pgSQL procedural language(1 row)postgres@template1=# exit[postgres@ServerName ~]$ exitlogout
Схемы
-
Подключитесь к БД
studentпользователемstudent:[student@ServerName ~]$ psqlpsql (15.5)Type "help" for help.student@student=> \conninfoYou are connected to database "student" as user "student" via socket in "/tmp" at port "5432". -
Получите список схем в БД:
student@student=> \dnList of schemasName | 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 TABLEstudent@student=> INSERT INTO stab(msg) SELECT 'A' FROM generate_series(1,100000);INSERT 0 100000 -
Проверьте, в какой схеме была создана таблица:
student@student=> \dList of relationsSchema | Name | Type | Owner--------+-------------+----------+---------public | stab | table | studentpublic | stab_id_seq | sequence | student(2 rows)Схема
public. -
Создайте схему
student:student@student=> CREATE SCHEMA student;CREATE SCHEMAstudent@student=> \dnList of schemasName | Owner---------+-------------------public | pg_database_ownerstudent | student(2 rows) -
Создайте еще одну таблицу
stabбез полей:student@student=> CREATE TABLE stab();CREATE TABLEstudent@student=> \dList of relationsSchema | Name | Type | Owner---------+-------------+----------+---------public | stab_id_seq | sequence | studentstudent | stab | table | student(2 rows)student@student=> SELECT count(*) FROM stab;count-------0(1 row)Таблица пустая.
-
Определите, где находится первая таблица
stab:student@student=> \dt *.stabList of relationsSchema | Name | Type | Owner---------+------+-------+---------public | stab | table | studentstudent | stab | table | student(2 rows) -
Проверьте настройку пути поиска в схемах, определите реальный путь поиска и имя схемы, в которой будут создаваться новые объекты:
student@student=> \dconfig search_pathList of configuration parametersParameter | 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 *.stabList of relationsSchema | Name | Type | Owner-----------+------+-------+---------pg_temp_5 | stab | table | studentpublic | stab | table | studentstudent | 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=> \cYou are now connected to database "student" as user "student".student@student=> \dt *.stabList of relationsSchema | Name | Type | Owner---------+------+-------+---------public | stab | table | studentstudent | stab | table | student(2 rows)student@student=> SELECT current_schemas(true);current_schemas-----------------------------{pg_catalog,student,public}(1 row)
На этом лабораторную работу можно считать завершенной.
Самопроверка
Вопрос 1
Кластер Pangolin DB инициализирован следующей командой shell:
initdb --locale="en_US.UTF-8"
С использованием каких SQL-команд НЕ может быть создана база данных с локалью "ru_RU.UTF-8"?
Вопрос 2
В кластере Pangolin DB имеются следующие базы данных:
postgrestemplate0template1
C использованием psql выполнено подключение к базе данных template1. В сеансе psql выполнены следующие команды:
template1=# \dx
Список установленных расширений
Имя | Версия | Схема | Описание
--------------------+--------+------------+------------------------------------------------------------------------
pg_stat_statements | 1.10 | public | track planning and execution statistics of all SQL statements executed
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
(2 строки)
template1=# \c postgres
Вы подключены к базе данных "postgres" как пользователь "postgres".
postgres=# \dx
Список установленных расширений
Имя | Версия | Схема | Описание
----------------+--------+------------+-------------------------------------------------------
pg_buffercache | 1.3 | public | examine the shared buffer cache
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
(4 строки)
postgres=# CREATE DATABASE ext_db;
CREATE DATABASE
postgres=# \c ext_db
Вы подключены к базе данных "ext_db" как пользователь "postgres".
ext_db=# CREATE EXTENSION dblink;
CREATE EXTENSION
ext_db=# \dx
Какие из приведенных расширений будут выданы последней командой?
Вопрос 3
В базе данных dev_db имеется три схемы: pg_catalog, public и developer, а также пользователь developer, обладающий необходимыми привилегиями для обращения к объектам в указанных схемах.
C использованием psql выполнено подключение к базе данных dev_db пользователем developer и выполнены следующие команды:
dev_db=> CREATE TEMP TABLE tmp_table AS SELECT 1;
SELECT 1
dev_db=> SHOW search_path;
search_path
-----------------
"$user", public
(1 строка)
dev_db=> SELECT * FROM any_table;
В какой последовательности будут просматриваться схемы при поиске в них таблицы any_table при выполнении последнего запроса?