All checks were successful
Build MkDocs / build-and-deploy (push) Successful in 20s
456 lines
21 KiB
Markdown
456 lines
21 KiB
Markdown
### Полезные ссылки
|
||
|
||
[Cheat sheet](https://gist.github.com/Kartones/dd3ff5ec5ea238d4c546)
|
||
|
||
### Команды
|
||
|
||
- `sudo -u postgres psql postgres` - подключиться к базе данных `postgres` от имени пользователя Linux `postgres`
|
||
!!! tip ""
|
||
`sudo -u postgres psql`
|
||
|
||
Если не указано имя базы данных при подключении, `psql` попытается подключиться к базе данных с именем, совпадающим с именем пользователя. В данном случае это будет база данных postgres
|
||
- `sudo -u postgres psql -d имя_базы_данных -f путь_к_скрипту.sql` - выполнить SQL-скрипт на базе
|
||
- `sudo -u postgres psql -d имя_базы_данных -c "SQL-запрос"` - выполнить SQL-скрипт на базе
|
||
|
||
!!! tip "Команды `psql` начинаются с `\`"
|
||
|
||
- `\l` - просмотр списка БД
|
||
- `\du` - посмотреть какие роли назначены пользователю
|
||
- `\q` - выход из psql
|
||
- `\e` - открывает текстовый редактор для написания SQL-запроса
|
||
- `\c <database_name> <user_name>` - подключение к БД или из bash `psql -U username -d <database_name>`
|
||
- `\dt` - просмотр списка таблиц
|
||
- `\d <table_name>` - показывает столбцы, типы данных и индексы
|
||
- `\dn` - список схем
|
||
- `\dt <schema_name>` - список таблиц в схеме
|
||
- `psql -U postgres -d my_database -f /etc/script.sql` - выполнить скрипт
|
||
|
||
---
|
||
|
||
- `CREATE TABLE имя_таблицы (id SERIAL PRIMARY KEY, колонка1 тип, колонка2 тип, ...);` - создание таблицы
|
||
- `CREATE USER имя_пользователя WITH PASSWORD 'пароль';`
|
||
- `CREATE ROLE имя_роли;`
|
||
??? info "В чём разница USER и ROLE?"
|
||
Пользователь (USER) — это роль, которая по умолчанию ИМЕЕТ право на подключение к базе данных
|
||
Роль (ROLE) — это более общее понятие. Она может быть как пользователем, так и группой. Роль по умолчанию НЕ ИМЕЕТ права на подключение к базе данных (если не указан атрибут LOGIN)
|
||
|
||
Роли (и пользователи) могут иметь дополнительные атрибуты, которые определяют их поведение. Вот основные атрибуты:
|
||
|
||
- `LOGIN` - Позволяет роли подключаться к базе данных (по умолчанию для USER)
|
||
- `SUPERUSER` - Дает роли права суперпользователя
|
||
- `CREATEDB` - Позволяет роли создавать базы данных
|
||
- `CREATEROLE` - Позволяет роли создавать другие роли
|
||
- `INHERIT` - Позволяет роли наследовать права от других ролей (по умолчанию TRUE)
|
||
- `REPLICATION`- Позволяет роли использоваться для репликации
|
||
- `PASSWORD` - Устанавливает пароль для роли
|
||
|
||
```sql
|
||
CREATE ROLE admin WITH LOGIN PASSWORD 'password' CREATEDB CREATEROLE
|
||
```
|
||
|
||
Пользователя (USER) можно добавить в роль (ROLE). Когда пользователь добавляется в роль, он автоматически наследует все права, связанные с этой ролью.
|
||
|
||
```sql
|
||
-- Создаем роль
|
||
CREATE ROLE read_only;
|
||
-- Создаем пользователя
|
||
CREATE USER myuser WITH PASSWORD 'password';
|
||
-- Добавляем пользователя в роль
|
||
GRANT read_only TO myuser;
|
||
```
|
||
```sql
|
||
-- удалить пользователя из роли
|
||
REVOKE имя_роли FROM имя_пользователя;
|
||
```
|
||
- `GRANT ALL PRIVILEGES ON DATABASE имя_базы TO имя_пользователя;`
|
||
- `DROP USER имя_пользователя;`
|
||
- `DROP ROLE имя_роли;`
|
||
- `ALTER TABLE` — это команда в SQL, которая используется для изменения структуры уже существующей таблицы в базе данных.
|
||
```sql
|
||
ALTER TABLE имя_таблицы ADD имя_столбца тип_данных;
|
||
```
|
||
```sql
|
||
ALTER TABLE имя_таблицы DROP COLUMN имя_столбца;
|
||
```
|
||
```sql
|
||
ALTER TABLE имя_таблицы ALTER COLUMN имя_столбца SET DATA TYPE новый_тип;
|
||
```
|
||
```sql { .code-wrap }
|
||
ALTER TABLE имя_таблицы ADD CONSTRAINT имя_ограничения тип_ограничения (столбец);
|
||
```
|
||
```sql
|
||
ALTER TABLE employees ADD CONSTRAINT age_check CHECK (age >= 18);
|
||
```
|
||
```sql
|
||
ALTER DATABASE "<old_name>" RENAME TO "<new_name>";
|
||
```
|
||
```sql
|
||
-- какие роли назначены пользователю
|
||
SELECT rolname, memberof
|
||
FROM pg_roles
|
||
WHERE rolname = 'myuser';
|
||
```
|
||
---
|
||
|
||
```sql
|
||
-- отключить все подключения к бд
|
||
SELECT pg_terminate_backend( pid )
|
||
FROM pg_stat_activity
|
||
WHERE pid <> pg_backend_pid( ) AND datname = '<database_name>';
|
||
```
|
||
```sql
|
||
-- убить подключение по pid
|
||
SELECT pg_terminate_backend(pid)
|
||
FROM pg_stat_activity
|
||
WHERE pid = <process_id>;
|
||
```
|
||
|
||
#### Статистика
|
||
|
||
- `SELECT * FROM pg_stat_activity;` - просмотр текущий подключений
|
||
- `SELECT * FROM pg_locks;` - просмотр блокировок
|
||
|
||
```sql
|
||
-- просмотр текущих подключений подробно
|
||
SELECT
|
||
pid, -- Идентификатор процесса
|
||
state, -- Состояние процесса
|
||
now() - query_start AS query_runtime, -- Время выполнения текущего запроса
|
||
now() - xact_start AS transaction_runtime, -- Время выполнения транзакции
|
||
application_name,
|
||
query, -- Текущий запрос
|
||
usename, -- Пользователь
|
||
datname, -- База данных
|
||
xact_start -- Время начала транзакции
|
||
FROM pg_stat_activity
|
||
WHERE state IN ('active', 'idle in transaction') and datname = current_database()
|
||
ORDER BY transaction_runtime DESC;
|
||
```
|
||
```sql
|
||
-- смотрим базы и их размер
|
||
SELECT pg_database.datname,
|
||
pg_size_pretty(pg_database_size(pg_database.datname)) AS size
|
||
FROM pg_database
|
||
ORDER BY pg_database_size(pg_database.datname) DESC;
|
||
```
|
||
```sql
|
||
-- общий размер конкретной БД
|
||
select pg_size_pretty(pg_database_size('название базы'));
|
||
```
|
||
```sql
|
||
-- общий размер индекса в БД
|
||
SELECT
|
||
pg_size_pretty(SUM(pg_relation_size(indexrelid))) AS total_index_size
|
||
FROM
|
||
pg_stat_all_indexes;
|
||
```
|
||
```sql
|
||
-- размер таблиц в БД
|
||
SELECT
|
||
schemaname AS table_schema,
|
||
relname AS table_name,
|
||
pg_size_pretty(pg_total_relation_size(relid)) AS total_size,
|
||
pg_size_pretty(pg_table_size(relid)) AS data_size,
|
||
pg_size_pretty(pg_indexes_size(relid)) AS index_size
|
||
FROM
|
||
pg_catalog.pg_statio_user_tables
|
||
ORDER BY
|
||
pg_total_relation_size(relid) DESC,
|
||
pg_table_size(relid) DESC;
|
||
```
|
||
```sql
|
||
-- размер индексов в БД
|
||
SELECT
|
||
pg_size_pretty(SUM(pg_relation_size(indexrelid))) AS total_index_size
|
||
FROM
|
||
pg_index
|
||
JOIN
|
||
pg_class ON pg_index.indexrelid = pg_class.oid
|
||
WHERE
|
||
pg_class.relkind = 'i';
|
||
```
|
||
```sql
|
||
-- общий размер индексов в таблице
|
||
SELECT
|
||
pg_size_pretty(SUM(pg_relation_size(indexrelid))) AS total_index_size
|
||
FROM
|
||
pg_stat_all_indexes
|
||
WHERE
|
||
relname = 'название таблицы';
|
||
```
|
||
```sql
|
||
-- имя индексов в таблице и скрипт которым создан индекс
|
||
SELECT
|
||
indexname,
|
||
indexdef
|
||
FROM
|
||
pg_indexes
|
||
WHERE
|
||
tablename = 'table_name';
|
||
```
|
||
```sql
|
||
-- блокировки в БД
|
||
SELECT
|
||
blocked_locks.pid AS blocked_pid,
|
||
blocked_activity.usename AS blocked_user,
|
||
blocking_locks.pid AS blocking_pid,
|
||
blocking_activity.usename AS blocking_user,
|
||
blocking_activity.state AS blocking_state,
|
||
blocked_activity.query AS blocked_statement,
|
||
blocking_activity.query AS current_statement_in_blocking_process,
|
||
blocked_locks.locktype AS blocked_locktype,
|
||
blocking_locks.locktype AS blocking_locktype
|
||
FROM pg_catalog.pg_locks blocked_locks
|
||
JOIN pg_catalog.pg_stat_activity blocked_activity
|
||
ON blocked_activity.pid = blocked_locks.pid
|
||
JOIN pg_catalog.pg_locks blocking_locks
|
||
ON blocking_locks.locktype = blocked_locks.locktype
|
||
AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE
|
||
AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
|
||
AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page
|
||
AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
|
||
AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
|
||
AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
|
||
AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
|
||
AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
|
||
AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
|
||
AND blocking_locks.pid != blocked_locks.pid
|
||
JOIN pg_catalog.pg_stat_activity blocking_activity
|
||
ON blocking_activity.pid = blocking_locks.pid
|
||
WHERE NOT blocked_locks.GRANTED;
|
||
```
|
||
```sql
|
||
select * from pgstats where tablename = '<table_name>' and attname = '<att_name>'
|
||
```
|
||
```sql
|
||
-- использование памяти и ресурсов в БД
|
||
SELECT *
|
||
FROM pg_stat_database;
|
||
```
|
||
??? info "Расшифровка атрибутов `pg_stat_database`"
|
||
- `datid` — Идентификатор базы данных (OID).
|
||
- `datname` — Имя базы данных.
|
||
- `numbackends` — Количество активных соединений (клиентов) с этой базой.
|
||
- `xact_commit` — Общее количество успешно завершённых транзакций.
|
||
- `xact_rollback` — Общее количество откатов транзакций.
|
||
- `blks_read` — Количество блоков, считанных с диска.
|
||
- `blks_hit` — Количество блоков, найденных в кеше (попадания в shared_buffers).
|
||
- `tup_returned` — Количество строк, возвращённых клиенту.
|
||
- `tup_fetched` — Количество строк, извлечённых (например, SELECT).
|
||
- `tup_inserted` — Количество вставленных строк (INSERT).
|
||
- `tup_updated` — Количество обновлённых строк (UPDATE).
|
||
- `tup_deleted` — Количество удалённых строк (DELETE).
|
||
- `conflicts` — Количество конфликтов (например, из-за репликации).
|
||
- `temp_files` — Количество временных файлов, созданных сервером.
|
||
- `temp_bytes` — Количество данных, записанных во временные файлы (в байтах).
|
||
- `deadlocks` — Количество взаимоблокировок.
|
||
- `blk_read_time` — Общее время чтения блоков с диска (в миллисекундах).
|
||
- `blk_write_time` — Общее время записи блоков на диск (в миллисекундах).
|
||
|
||
### Бэкапирование
|
||
|
||
По умолчанию pg_dump создает логический бэкап в формате plain (обычный SQL-скрипт)
|
||
|
||
В PostgreSQL есть два типа дампов:
|
||
|
||
- `Физические (pg_basebackup)` — побайтовая копия файлов БД.
|
||
- `Логические (pg_dump, pg_dumpall)` — SQL-скрипты или архивные файлы.
|
||
|
||
!!! info ""
|
||
`pg_dumpall` создает резервную копию всех баз данных, роли (пользователи и группы), права доступа (GRANT/REVOKE), настройки tablespace, глобальные параметры (например, настройки аутентификации). Умеет отдавать только дамп в формате .sql
|
||
|
||
`pg_dump` не экспортирует роли, права доступа, tablespaces, параметры кластера (например, `pg_hba.conf`)
|
||
|
||
1. plain (Текстовый SQL-скрипт)
|
||
|
||
Описание:
|
||
|
||
В этом формате по дефолту снимает `pg_dump`. Формат plain представляет собой обычный SQL-скрипт, содержащий скрипты `CREATE TABLE`, `INSERT INTO`, `ALTER TABLE` и другие скрипты для создания и наполнения бд .
|
||
|
||
Дамп в формате `plain`:
|
||
```bash
|
||
pg_dump -U postgres -d mydatabase -Fp -f backup.sql
|
||
```
|
||
Пример содержимого файла дампа:
|
||
|
||
```sql
|
||
CREATE TABLE users (
|
||
id SERIAL PRIMARY KEY,
|
||
name TEXT
|
||
);
|
||
INSERT INTO users (id, name) VALUES (1, 'Alice');
|
||
```
|
||
|
||
- Можно редактировать в текстовом редакторе.
|
||
|
||
- Можно восстановить частично, скопировав нужные команды.
|
||
|
||
- Относительно долгое восстановление, так как все данные вставляются скриптами.
|
||
|
||
Как восстановить:
|
||
```bash
|
||
psql -U postgres -d mydatabase -f backup.sql
|
||
```
|
||
|
||
2. custom (Сжатый бинарный формат)
|
||
|
||
Описание:
|
||
|
||
Формат custom является бинарным, поддерживает сжатие и позволяет восстанавливать отдельные объекты базы данных, такие как таблицы и схемы.
|
||
|
||
Как создать дамп в формате `custom`:
|
||
```bash
|
||
pg_dump -U postgres -d mydatabase -Fc -Z 9 -f backup.dump
|
||
```
|
||
Параметры:
|
||
|
||
- `Fc` - указывает на использование формата custom.
|
||
- `Z 9` - применяет максимальное сжатие дампа.
|
||
- `-a` или `--data-only`: Дамп только данных, без схемы
|
||
- `-s` или `--schema-only`: Дамп только схемы, без данных
|
||
- `-O` или `--no-owner`: Исключает команды SET OWNER из дампа
|
||
- `-x` или `--no-privileges`: Исключает команды GRANT/REVOKE из дампа.
|
||
|
||
- Поддерживает выборочное снятие отдельных объектов.
|
||
- Поддерживает параллельное снятие с `-j`.
|
||
|
||
Посмотреть содержимое дампа без восстановления:
|
||
```bash
|
||
pg_restore -l backup.dump
|
||
```
|
||
|
||
Как восстановить базу данных:
|
||
```bash
|
||
pg_restore -U postgres -d mydatabase -f backup.dump
|
||
```
|
||
|
||
3. directory (Каталог с дампом)
|
||
|
||
Описание:
|
||
|
||
Формат `directory` сохраняет резервную копию в виде каталога, содержащего отдельные файлы для каждой таблицы и других объектов базы данных. Этот формат позволяет параллельно снимать бэкап.
|
||
|
||
Дамп в формате `directory`:
|
||
|
||
```bash
|
||
pg_dump -U postgres -d mydatabase -Fd -j4 -f backup_dir/
|
||
```
|
||
|
||
Параметры:
|
||
|
||
- `Fd` — указывает на формат directory.
|
||
- `j4` — использует 4 параллельных потока для ускорения процесса.
|
||
|
||
- Можно восстанавливать отдельные таблицы и объекты.
|
||
|
||
Восстановление
|
||
```bash
|
||
pg_restore -U postgres -d mydatabase -j 4 backup_dir/
|
||
```
|
||
|
||
4. tar (Архив tar)
|
||
Описание:
|
||
|
||
Формат tar создает архив tar, содержащий все необходимые файлы для восстановления базы данных. Он удобен для хранения и передачи, но восстановление в данном формате выполняется медленнее по сравнению с `directory` или `custom`.
|
||
|
||
Дамп в формате `tar`:
|
||
```bash
|
||
pg_dump -U postgres -d mydatabase -F t -f backup.tar
|
||
```
|
||
Параметры:
|
||
|
||
- Ft — указывает на формат tar.
|
||
- Медленное восстановление, так как данные сначала извлекаются из архива.
|
||
|
||
Восстановление бд:
|
||
```bash
|
||
pg_restore -U postgres -d mydatabase -Ft backup.tar
|
||
```
|
||
|
||
!!! info ""
|
||
Все форматы дампов кроме `.sql` восстанавливаются через `pg_restore`
|
||
|
||
|
||
#### Пример организации бэкапирования
|
||
|
||
Скрипт `backup.sh` для снятия бэкапа, удаления бэкапов
|
||
```bash
|
||
#!/bin/bash
|
||
|
||
if [ "$#" -ne 3 ]; then
|
||
echo "Необходимо передать три аргумента."
|
||
echo "Пример: $0 <имя_стенда> <имя_базы_данных> <время_жизни_бэкапа_в_днях>"
|
||
exit 1
|
||
fi
|
||
|
||
PG_PASSWORD="postgres"
|
||
PG_PORT="5432"
|
||
STAND_NAME="$1"
|
||
DB_NAME="$2"
|
||
BACKUP_TTL="$3"
|
||
BACKUP_DIR="/opt/backups/${STAND_NAME}"
|
||
BACKUP_FILE="${STAND_NAME}_$(date +%Y%m%d).dump"
|
||
LOG_DIR="${BACKUP_DIR}/logs"
|
||
LOG_FILE="${LOG_DIR}/backup_${STAND_NAME}.log"
|
||
|
||
mkdir -p "${BACKUP_DIR}"
|
||
mkdir -p "${LOG_DIR}"
|
||
|
||
echo "$(date +%Y%m%d_%H%M%S) Начало резервного копирования базы данных ${DB_NAME}" >> ${LOG_FILE}
|
||
|
||
PGPASSWORD=${PG_PASSWORD} pg_dump -p ${PG_PORT} -h localhost -U postgres -d ${DB_NAME} -Fc -Z 9 -f "${BACKUP_DIR}/${BACKUP_FILE}" 2>> ${LOG_FILE}
|
||
|
||
if [ $? -eq 0 ]; then
|
||
echo "$(date +%Y%m%d_%H%M%S) Резервное копирование успешно завершено: ${BACKUP_DIR}/${BACKUP_FILE}" >> ${LOG_FILE}
|
||
|
||
find ${BACKUP_DIR} -type f -name "*.dump" -mtime +${BACKUP_TTL} -exec rm {} \;
|
||
|
||
if [ $? -eq 0 ]; then
|
||
echo "$(date +%Y%m%d_%H%M%S) Бэкапы старше ${BACKUP_TTL} дней удалены." >> ${LOG_FILE}
|
||
else
|
||
echo "$(date +%Y%m%d_%H%M%S) Ошибка при удалении бэкапов." >> ${LOG_FILE}
|
||
fi
|
||
|
||
else
|
||
echo "$(date +%Y%m%d_%H%M%S) Ошибка при резервном копировании базы данных ${DB_NAME}" >> ${LOG_FILE}
|
||
fi
|
||
```
|
||
|
||
Добавить в `cron`
|
||
|
||
```bash
|
||
# Для снятия бэкапа: <путь к скрипту> <имя каталога для бэкапа> <имя базы данных стенда> <кол-во хранимых бэкапов>
|
||
00 23 * * * /opt/backups/backup.sh stand1 database1 3
|
||
59 23 * * * /opt/backups/backup.sh stand2 database2 3
|
||
```
|
||
|
||
### Разное
|
||
|
||
- `ps -ef | grep -v grep | grep postgres` - определяет есть ли процесс постгрес на машине
|
||
- `which psql` - есть ли в локальном окружении psql
|
||
- `sudo docker inspect <имя_контейнера> | grep postgres` - есть ли постгрес в контейнере
|
||
---
|
||
- `psql -U postgres -c "SHOW server_version;"` - версия пг или `psql -V` или `/usr/bin/psql -V`
|
||
- `psql -U postgres -c "SHOW port;"` - порт на котором работает пг
|
||
- `psql -U postgres -c "SHOW wal_directory;"` - каталог WAL
|
||
|
||
|
||
#### Где что лежит??
|
||
|
||
1. Каталог данных
|
||
- `/var/lib/postgresql/<версия>/main/` - Debian/Ubuntu
|
||
- `/var/lib/pgsql/<версия>/data/` - CentOS/Fedora
|
||
- `psql -U postgres -c "SHOW data_directory;"`
|
||
2. Конфигурационные файлы (могут находится в каталоге данных)
|
||
- `/etc/postgresql/<версия>/main/`
|
||
- `psql -U postgres -c "SHOW config_file;"` - путь к конфигу
|
||
- `psql -U postgres -c "SHOW hba_file;"` - путь к настройкам аутентификации
|
||
3. Каталог логов
|
||
- `/var/log/postgresql/`
|
||
- `psql -U postgres -c "SHOW log_directory;"`
|
||
---
|
||
|
||
- `SHOW shared_preload_libraries;` - список библиотек, которые были загружены при старте PostgreSQL с помощью параметра `shared_preload_libraries` в `postgresql.conf`
|
||
- `pg_config --pkglibdir` - показывает путь к каталогу, где находятся библиотеки пг (shared libraries).
|
||
|