Некоторое время читал и смотрел на временные таблицы в PostgreSQL. Решил сохранить найденную информацию и эксперименты, которые делал.
Я не буду рассказывать что такое временные таблицы в PostgreSQL, но порекомендую прочитать следующие полезные статьи для понимания темы:
- Документация. CREATE TEMP TABLE
- Документация. Параметр temp_tablespaces
- Документация. Отличия от SQL стандарта
- Документация. Зачистка файлов временных таблиц после падения сервера
- Документация. pg_my_temp_schema()
- Иван Фролков. 2016. Временные таблицы в Postgresql — проблемы и методы решения
- Хабр. Типы таблиц в PostgreSQL: logged, unlogged и temporary tables
- Хабр. PostgreSQL и временные таблицы
- dev.to. Postgres Temporary Tables: A Guide to Data Manipulation
- CyberTec. Про memory context, который используется в local buffers
- Исходный код. Реализация Local Buffer SourceCode
Также прочитал про функцию pg_my_temp_schema() в документации по ссылке выше. Решил посмотреть как она реализована, путь моего поиска тоже сохраню:
Это была общая информация, а теперь несколько экспериментов для 16-й версии сервера. В итоге, оформил в репозитарии на github. Даже readme можно почитать 🙂
Перечень экспериментов:
- Временная таблица on commit {reserver|delete|drop}
- Временная таблица и путь поиска
- Временное табличное пространство по умолчанию и нет
- Временная таблица, представление и функция
- Временная схема и суперпользователь
- Временная схема и обычная роль
- Auto {analyze|vacuum} временной и обычной таблицы
- Параллельная обработка временных таблиц
- Параметр temp_buffers
- Временные таблица, индекс, TOAST и их расположение на диске
- Параметр remove_temp_files_after_crash (тут возможно баг?)
К каждому эксперименту прикладываю еще и два скрипта команд, который можно будет выполнить на вашей системе и самостоятельно посмотреть результат. Старался написать так, чтобы все скрипты (кроме последнего) выполнились единой командой без каких-либо подстановок параметров. Нужно скачать код эксперимента, сохранить в файл и выполнить этот файл командами вида:
psql -f TEMP_TABLE_1.sql
Или уже находясь в psql’e:
\i TEMP_TABLE_1.sql
1. Временная таблица on commit {reserver|delete|drop}
1. Временная таблица on commit {reserver|delete|drop}. Код эксперимента
1. Временная таблица on commit {reserver|delete|drop}. ECHO-комментарии
-- 1. Временная таблица on commit {reserver|delete|drop}
-- ON COMMIT PRESERVE ROWS — строки в таблице сохраняются до конца сессии
-- ON COMMIT DROP — таблица удаляется после завершения транзакции
-- ON COMMIT DELETE ROWS — все строки таблицы будут удалены после фиксации транзакции
-- Создаем три временные таблицы с разным поведением
CREATE TEMP TABLE t_temp1_1 (id integer) ON COMMIT PRESERVE ROWS;
CREATE TABLE
CREATE TEMP TABLE t_temp1_2 (id integer) ON COMMIT DELETE ROWS;
CREATE TABLE
CREATE TEMP TABLE t_temp1_3 (id integer) ON COMMIT DROP;
CREATE TABLE
-- Добавляем в них строки
INSERT INTO t_temp1_1 SELECT * FROM generate_series(1,1_000);
INSERT 0 1000
INSERT INTO t_temp1_2 SELECT * FROM generate_series(1,1_000);
INSERT 0 1000
INSERT INTO t_temp1_3 SELECT * FROM generate_series(1,1_000);
psql:1.sql:23: ERROR: relation "t_temp1_3" does not exist
LINE 1: INSERT INTO t_temp1_3 SELECT * FROM generate_series(1,1_000)...
-- Смотрим что в таблицах
SELECT count(*) FROM t_temp1_1;
count
-------
1000
(1 row)
SELECT count(*) FROM t_temp1_2;
count
-------
0
(1 row)
SELECT count(*) FROM t_temp1_3;
psql:1.sql:32: ERROR: relation "t_temp1_3" does not exist
LINE 1: SELECT count(*) FROM t_temp1_3;
-- Доступно только две временные таблицы
SELECT schemaname, tablename FROM pg_tables WHERE tablename like t_temp1%;
schemaname | tablename
------------+-----------
pg_temp_3 | t_temp1_1
pg_temp_3 | t_temp1_2
(2 rows)
-- Удаляем их
DROP TABLE t_temp1_1;
DROP TABLE
DROP TABLE t_temp1_2;
DROP TABLE
-- Начинаем новую транзакцию
BEGIN;
BEGIN
-- Создаем три временные таблицы с разным поведением
CREATE TEMP TABLE t_temp1_1 (id integer) ON COMMIT PRESERVE ROWS;
CREATE TABLE
CREATE TEMP TABLE t_temp1_2 (id integer) ON COMMIT DELETE ROWS;
CREATE TABLE
CREATE TEMP TABLE t_temp1_3 (id integer) ON COMMIT DROP;
CREATE TABLE
-- Добавляем в них строки
INSERT INTO t_temp1_1 SELECT * FROM generate_series(1,1_000);
INSERT 0 1000
INSERT INTO t_temp1_2 SELECT * FROM generate_series(1,1_000);
INSERT 0 1000
INSERT INTO t_temp1_3 SELECT * FROM generate_series(1,1_000);
INSERT 0 1000
-- В транзакции видны все три временные таблицы
SELECT schemaname, tablename FROM pg_tables WHERE tablename like t_temp1%;
schemaname | tablename
------------+-----------
pg_temp_3 | t_temp1_1
pg_temp_3 | t_temp1_2
pg_temp_3 | t_temp1_3
(3 rows)
-- Смотрим что в них
SELECT count(*) FROM t_temp1_1;
count
-------
1000
(1 row)
SELECT count(*) FROM t_temp1_2;
count
-------
1000
(1 row)
SELECT count(*) FROM t_temp1_3;
count
-------
1000
(1 row)
COMMIT;
COMMIT
-- После завершения транзакции снова доступно две таблицы
SELECT schemaname, tablename FROM pg_tables WHERE tablename like t_temp1%;
schemaname | tablename
------------+-----------
pg_temp_3 | t_temp1_1
pg_temp_3 | t_temp1_2
(2 rows)
-- И в одной из них все строки удалены
SELECT count(*) FROM t_temp1_1;
count
-------
1000
(1 row)
SELECT count(*) FROM t_temp1_2;
count
-------
0
(1 row)
SELECT count(*) FROM t_temp1_3;
psql:1.sql:89: ERROR: relation "t_temp1_3" does not exist
LINE 1: SELECT count(*) FROM t_temp1_3;
2. Временная таблица и путь поиска
2. Временная таблица и путь поиска. Код эксперимента
2. Временная таблица и путь поиска. ECHO-комментарии
-- 2. Временная таблица и путь поиска
-- Проверим временную схему сеанса, пути поиска
SELECT pg_my_temp_schema()::regnamespace;
pg_my_temp_schema
-------------------
-
(1 row)
SHOW search_path;
search_path
-----------------
"$user", public
(1 row)
SELECT current_schemas(true);
current_schemas
---------------------
{pg_catalog,public}
(1 row)
-- Создадим обычную таблицу, добавим туда строки
CREATE TABLE temp2 (id integer);
CREATE TABLE
INSERT INTO temp2 VALUES (1),(2),(3);
INSERT 0 3
SELECT * FROM temp2;
id
----
1
2
3
(3 rows)
-- Создадим временную таблицу с аналогичным названием
CREATE TEMP TABLE temp2 (id integer);
CREATE TABLE
-- Снова проверим временную схему сеанса и пути поиска
SELECT pg_my_temp_schema()::regnamespace;
pg_my_temp_schema
-------------------
pg_temp_3
(1 row)
SHOW search_path;
search_path
-----------------
"$user", public
(1 row)
SELECT current_schemas(true);
current_schemas
-------------------------------
{pg_temp_3,pg_catalog,public}
(1 row)
-- Выполним эксперимент
SELECT * FROM temp2;
id
----
(0 rows)
SELECT * FROM public.temp2;
id
----
1
2
3
(3 rows)
SELECT * FROM pg_temp.temp2;
id
----
(0 rows)
DROP TABLE temp2;
DROP TABLE
SELECT * FROM temp2;
id
----
1
2
3
(3 rows)
-- Удалим лишние объекты
DROP TABLE public.temp2;
DROP TABLE
3. Табличное пространство по умолчанию для временных объектов
3. Временное табличное пространство по умолчанию и нет. Код эксперимента
3. Временное табличное пространство по умолчанию и нет. ECHO-комментарии
-- Табличное пространство по умолчанию для временных объектов -- («По умолчанию значение этой переменной — пустая строка. -- С таким значением все временные объекты создаются в табличном -- пространстве по умолчанию, установленном для текущей базы данных») SHOW temp_tablespaces; temp_tablespaces ------------------ (1 row) -- Табличное пространство по умолчанию SHOW default_tablespace; default_tablespace -------------------- (1 row) -- Табличное пространство по умолчанию для текущей БД SELECT db.datname, ts.spcname FROM pg_tablespace ts JOIN pg_database db ON db.dattablespace = ts.oid WHERE db.datname = (SELECT * FROM current_database()); datname | spcname ---------+------------ pavel | pg_default (1 row) -- Изменим табличное пространство по умолчанию SET temp_tablespaces = pg_global; SET -- Снова создадим временную таблицу CREATE TEMP TABLE t_temp3(id integer); psql:3.sql:35: ERROR: only shared relations can be placed in pg_global tablespace -- Создадим обычную таблицу CREATE TABLE t_temp3(id integer); CREATE TABLE -- Удалим лишнее DROP TABLE t_temp_3; DROP TABLE
4. Временная таблица, представление и функция
4. Временная таблица, представление и функция. Код эксперимента
4. Временная таблица, представление и функция. ECHO-комментарии
-- 4. Временная таблица, представление и функция
-- Создадим временную таблицу
CREATE TEMP TABLE t_temp4 (id integer);
CREATE TABLE
-- Создадим представление на основе временной таблицы
CREATE VIEW v_t_temp4 AS SELECT * FROM t_temp4;
psql:4.sql:13: NOTICE: view "v_t_temp4" will be a temporary view
CREATE VIEW
-- Посмотрим где представление хранится на диске
SELECT pg_relation_filepath(v_t_temp4);
pg_relation_filepath
----------------------
(1 row)
-- Создадим обычную таблицу
CREATE TABLE temp4 (id integer);
CREATE TABLE
-- Создадим представление на основе обычной таблицы
CREATE VIEW v_temp4 AS SELECT * FROM temp4;
CREATE VIEW
-- И посмотрим где это представление хранится на диске
SELECT pg_relation_filepath(v_temp4);
pg_relation_filepath
----------------------
(1 row)
-- Создадим функцию
CREATE FUNCTION f_t_func()
RETURNS integer
AS $$
SELECT count(*) FROM v_t_temp4;
$$ LANGUAGE sql;
CREATE FUNCTION
SELECT f_t_func();
f_t_func
----------
0
(1 row)
CREATE MATERIALIZED VIEW mv AS SELECT * FROM t_temp4 ;
psql:4.sql:57: ERROR: materialized views must not use temporary tables or views
-- Удалим таблицу
DROP TABLE t_temp4;
psql:4.sql:63: ERROR: cannot drop table t_temp4 because other objects depend on it
DETAIL: view v_t_temp4 depends on table t_temp4
HINT: Use DROP ... CASCADE to drop the dependent objects too.
-- Удалим таблицу и каскадно все объекты, связанные с ней
DROP TABLE t_temp4 CASCADE;
psql:4.sql:69: NOTICE: drop cascades to view v_t_temp4
DROP TABLE
-- Удалим лишние объекты
DROP TABLE temp4 CASCADE;
psql:4.sql:75: NOTICE: drop cascades to view v_temp4
DROP TABLE
DROP FUNCTION f_t_func;
DROP FUNCTION
5. Временная схема и суперпользователь
5. Временная схема и суперпользователь. Код эксперимента
5. Временная схема и суперпользователь. ECHO-комментарии
-- 5. Временная схема и суперпользователь
-- Создаем таблицу, смотрим схему
SELECT current_schemas(true);
current_schemas
---------------------
{pg_catalog,public}
(1 row)
CREATE TEMP TABLE t_temp5 (id integer);
CREATE TABLE
SELECT current_schemas(true);
current_schemas
-------------------------------
{pg_temp_3,pg_catalog,public}
(1 row)
SELECT n.nspname FROM pg_catalog.pg_namespace n ORDER BY 1;
nspname
--------------------
information_schema
pg_catalog
pg_temp_3
pg_temp_4
pg_toast
pg_toast_temp_3
pg_toast_temp_4
public
(8 rows)
-- Добавим строки, проверим временную схему и строки из таблицы
INSERT INTO t_temp5 VALUES (1),(2),(3);
INSERT 0 3
SELECT pg_my_temp_schema()::regnamespace;
pg_my_temp_schema
-------------------
pg_temp_3
(1 row)
BEGIN;
BEGIN
-- Анонимный блок нужен чтобы сформировать полное имя: схема.таблица
DO $$
DECLARE
_query text;
_cursor CONSTANT refcursor := _cursor;
BEGIN
_query := SELECT * FROM || (SELECT n.nspname || . || c.relname relname FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace LEFT JOIN pg_catalog.pg_am am ON am.oid = c.relam WHERE c.relname = ('t_temp5'));
OPEN _cursor FOR EXECUTE _query;
END
$$;
DO
FETCH ALL FROM _cursor;
id
----
1
2
3
(3 rows)
COMMIT;
COMMIT
-- Попробуем удалить временную схему (аналог DROP SCHEMA name)
DO $$ BEGIN EXECUTE DROP SCHEMA || pg_my_temp_schema()::regnamespace; END $$;
psql:5.sql:55: ERROR: cannot drop schema pg_temp_3 because other objects depend on it
DETAIL: table t_temp5 depends on schema pg_temp_3
HINT: Use DROP ... CASCADE to drop the dependent objects too.
CONTEXT: SQL statement "DROP SCHEMA IF EXISTS pg_temp_3"
PL/pgSQL function inline_code_block line 1 at EXECUTE
-- Повторим с CASCADE (схема удалилась успешно)
DO $$ BEGIN EXECUTE DROP SCHEMA || pg_my_temp_schema()::regnamespace || CASCADE; END $$;
psql:5.sql:57: NOTICE: drop cascades to table t_temp5
DO
SELECT current_schemas(true);
current_schemas
---------------------
{pg_catalog,public}
(1 row)
-- Создадим еще одну временную таблицу
CREATE TEMP TABLE t_temp5_2 (id integer);
CREATE TABLE
SELECT n.nspname FROM pg_catalog.pg_namespace n ORDER BY 1;
nspname
--------------------
information_schema
pg_catalog
pg_temp_4
pg_toast
pg_toast_temp_3
pg_toast_temp_4
public
(7 rows)
SELECT current_schemas(true);
current_schemas
---------------------
{pg_catalog,public}
(1 row)
SHOW search_path;
search_path
-----------------
"$user", public
(1 row)
INSERT INTO t_temp5_2 VALUES (1), (2), (3);
INSERT 0 3
-- OID временной схемы есть, но записи в pg_namespace для него нет
SELECT pg_my_temp_schema()::regnamespace;
pg_my_temp_schema
-------------------
482607
(1 row)
SELECT nspname FROM pg_namespace WHERE oid = pg_my_temp_schema();
nspname
---------
(0 rows)
SELECT * FROM pg_temp.t_temp5_2;
id
----
1
2
3
(3 rows)
SELECT * FROM pg_temp_3.t_temp5_2;
psql:5.sql:85: ERROR: relation "pg_temp_3.t_temp5_2" does not exist
LINE 1: SELECT * FROM pg_temp_3.t_temp5_2;
^
SELECT current_schemas(true);
current_schemas
---------------------
{pg_catalog,public}
(1 row)
SELECT * FROM pg_catalog.pg_namespace;
oid | nspname | nspowner | nspacl
--------+--------------------+----------+---------------------------------------------------------------
99 | pg_toast | 10 |
11 | pg_catalog | 10 | {postgres=UC/postgres,=U/postgres}
2200 | public | 6171 | {pg_database_owner=UC/pg_database_owner,=U/pg_database_owner}
13250 | information_schema | 10 | {postgres=UC/postgres,=U/postgres}
432342 | pg_temp_4 | 10 |
432516 | pg_toast_temp_3 | 10 |
432571 | pg_toast_temp_4 | 10 |
(7 rows)
-- Проверим что пишут в системном каталоге
SELECT c.oid, c.relname FROM pg_catalog.pg_class c WHERE c.relname = 't_temp5_2';
oid | relname
--------+-----------
482611 | t_temp5_2
(1 row)
SELECT oid, relnamespace FROM pg_class WHERE oid = (SELECT c.oid FROM pg_catalog.pg_class c WHERE c.relname = 't_temp5');
oid | relnamespace
-----+--------------
(0 rows)
SELECT * FROM pg_namespace WHERE oid = (SELECT relnamespace FROM pg_class WHERE oid = (SELECT c.oid FROM pg_catalog.pg_class c WHERE c.relname = 't_temp5'));
oid | nspname | nspowner | nspacl
-----+---------+----------+--------
(0 rows)
6. Временная схема и обычная роль
6. Временная схема и обычная роль. Код эксперимента
6. Временная схема и обычная роль. ECHO-комментарии
-- 6. Временная схема и обычная роль
-- pavel — это роль суперпользователя
CREATE ROLE check_tmp LOGIN;
CREATE ROLE
SHOW hba_file;
hba_file
-------------------------------------
/etc/postgresql/16/main/pg_hba.conf
(1 row)
SELECT * FROM pg_hba_file_rules;
rule_number | file_name | line_number | type | database | user_name | address | netmask | auth_method | options | error
-------------+-------------------------------------+-------------+-------+---------------+-------------+----------+-----------------------------------------+---------------+---------+-------
1 | /etc/postgresql/16/main/pg_hba.conf | 1 | local | {all} | {check_tmp} | | | trust | |
14 | /etc/postgresql/16/main/pg_hba.conf | 123 | local | {all} | {postgres} | | | peer | |
15 | /etc/postgresql/16/main/pg_hba.conf | 128 | local | {all} | {all} | | | peer | |
16 | /etc/postgresql/16/main/pg_hba.conf | 129 | local | {pavel} | {pavel} | | | trust | |
17 | /etc/postgresql/16/main/pg_hba.conf | 131 | host | {all} | {all} | 127.0.0..| 255.255.255.255 | scram-sha-256 | |
| | | | | |.1 | | | |
18 | /etc/postgresql/16/main/pg_hba.conf | 133 | host | {all} | {all} | ::1 | ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff | scram-sha-256 | |
19 | /etc/postgresql/16/main/pg_hba.conf | 136 | local | {replication} | {all} | | | peer | |
20 | /etc/postgresql/16/main/pg_hba.conf | 137 | host | {replication} | {all} | 127.0.0..| 255.255.255.255 | scram-sha-256 | |
| | | | | |.1 | | | |
21 | /etc/postgresql/16/main/pg_hba.conf | 138 | host | {replication} | {all} | ::1 | ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff | scram-sha-256 | |
(21 rows)
SELECT pg_reload_conf();
pg_reload_conf
----------------
t
(1 row)
\c - check_tmp
You are now connected to database "pavel" as user "check_tmp".
\conninfo
You are connected to database "pavel" as user "check_tmp" via socket in "/var/run/postgresql" at port "5432".
-- Проверка — все команды из пятого эксперимента
-- Обратить внимание на результат команды удаления схемы
-- ERROR: must be owner of schema pg_temp_3
-- И на последнюю команду — для схемы pg_temp_3 есть название
-- Создаем таблицу, смотрим схему
SELECT current_schemas(true);
current_schemas
---------------------
{pg_catalog,public}
(1 row)
CREATE TEMP TABLE t_temp6 (id integer);
CREATE TABLE
SELECT current_schemas(true);
current_schemas
-------------------------------
{pg_temp_3,pg_catalog,public}
(1 row)
SELECT n.nspname FROM pg_catalog.pg_namespace n ORDER BY 1;
nspname
--------------------
information_schema
pg_catalog
pg_temp_3
pg_temp_4
pg_toast
pg_toast_temp_3
pg_toast_temp_4
public
(8 rows)
-- Добавим строки, проверим временную схему и строки из таблицы
INSERT INTO t_temp6 VALUES (1),(2),(3);
INSERT 0 3
SELECT pg_my_temp_schema()::regnamespace;
pg_my_temp_schema
-------------------
pg_temp_3
(1 row)
BEGIN;
BEGIN
-- Анонимный блок нужен чтобы сформировать полное имя: схема.таблица
DO $$
DECLARE
_query text;
_cursor CONSTANT refcursor := _cursor;
BEGIN
_query := SELECT * FROM || (SELECT n.nspname || . || c.relname relname FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace LEFT JOIN pg_catalog.pg_am am ON am.oid = c.relam WHERE c.relname = ('t_temp6'));
OPEN _cursor FOR EXECUTE _query;
END
$$;
DO
FETCH ALL FROM _cursor;
id
----
1
2
3
(3 rows)
COMMIT;
COMMIT
-- Попробуем удалить временную схему (аналог DROP SCHEMA name)
DO $$ BEGIN EXECUTE DROP SCHEMA || pg_my_temp_schema()::regnamespace; END $$;
psql:6.sql:84: ERROR: must be owner of schema pg_temp_3
CONTEXT: SQL statement "DROP SCHEMA pg_temp_3"
PL/pgSQL function inline_code_block line 1 at EXECUTE
-- Повторим с CASCADE
DO $$ BEGIN EXECUTE DROP SCHEMA || pg_my_temp_schema()::regnamespace || CASCADE; END $$;
psql:6.sql:90: ERROR: must be owner of schema pg_temp_3
CONTEXT: SQL statement "DROP SCHEMA pg_temp_3 CASCADE"
PL/pgSQL function inline_code_block line 1 at EXECUTE
SELECT current_schemas(true);
current_schemas
-------------------------------
{pg_temp_3,pg_catalog,public}
(1 row)
-- Создадим еще одну временную таблицу
CREATE TEMP TABLE t_temp6_2 (id integer);
CREATE TABLE
SELECT n.nspname FROM pg_catalog.pg_namespace n ORDER BY 1;
nspname
--------------------
information_schema
pg_catalog
pg_temp_3
pg_temp_4
pg_toast
pg_toast_temp_3
pg_toast_temp_4
public
(8 rows)
SELECT current_schemas(true);
current_schemas
-------------------------------
{pg_temp_3,pg_catalog,public}
(1 row)
SHOW search_path;
search_path
-----------------
"$user", public
(1 row)
INSERT INTO t_temp6_2 VALUES (1), (2), (3);
INSERT 0 3
-- Временная схема не определяется
SELECT pg_my_temp_schema()::regnamespace;
pg_my_temp_schema
-------------------
pg_temp_3
(1 row)
SELECT nspname FROM pg_namespace WHERE oid = pg_my_temp_schema();
nspname
-----------
pg_temp_3
(1 row)
SELECT * FROM pg_temp.t_temp6_2;
id
----
1
2
3
(3 rows)
SELECT * FROM pg_temp_3.t_temp6_2;
id
----
1
2
3
(3 rows)
SELECT current_schemas(true);
current_schemas
-------------------------------
{pg_temp_3,pg_catalog,public}
(1 row)
SELECT * FROM pg_catalog.pg_namespace;
oid | nspname | nspowner | nspacl
--------+--------------------+----------+---------------------------------------------------------------
99 | pg_toast | 10 |
11 | pg_catalog | 10 | {postgres=UC/postgres,=U/postgres}
2200 | public | 6171 | {pg_database_owner=UC/pg_database_owner,=U/pg_database_owner}
13250 | information_schema | 10 | {postgres=UC/postgres,=U/postgres}
432342 | pg_temp_4 | 10 |
432516 | pg_toast_temp_3 | 10 |
432571 | pg_toast_temp_4 | 10 |
482748 | pg_temp_3 | 10 |
(8 rows)
-- Проверим что пишут в системном каталоге
SELECT c.oid, c.relname FROM pg_catalog.pg_class c WHERE c.relname = 't_temp6_2';
oid | relname
--------+-----------
482794 | t_temp6_2
(1 row)
SELECT oid, relnamespace FROM pg_class WHERE oid = (SELECT c.oid FROM pg_catalog.pg_class c WHERE c.relname = 't_temp6');
oid | relnamespace
--------+--------------
482791 | 482748
(1 row)
SELECT * FROM pg_namespace WHERE oid = (SELECT relnamespace FROM pg_class WHERE oid = (SELECT c.oid FROM pg_catalog.pg_class c WHERE c.relname = 't_temp6'));
oid | nspname | nspowner | nspacl
--------+-----------+----------+--------
482748 | pg_temp_3 | 10 |
(1 row)
-- Удаляем лишнее
DROP TABLE t_temp6;
DROP TABLE
DROP TABLE t_temp6_2;
DROP TABLE
\c - pavel
You are now connected to database "pavel" as user "pavel".
DROP ROLE check_tmp;
DROP ROLE
7. Auto {analyze|vacuum} временной и обычной таблицы
7. Auto {analyze|vacuum} временной и обычной таблицы. Код эксперимента
7. Auto {analyze|vacuum} временной и обычной таблицы. ECHO-комментарии
-- 7. Auto {analyze|vacuum} временной и обычной таблицы
-- Добавлю настройки ускорения авто -вакуума и -анализа
ALTER SYSTEM SET autovacuum_naptime = 1;
ALTER SYSTEM
ALTER SYSTEM SET autovacuum_vacuum_scale_factor = 0.01;
ALTER SYSTEM
ALTER SYSTEM SET autovacuum_vacuum_threshold = 0;
ALTER SYSTEM
ALTER SYSTEM SET autovacuum_analyze_scale_factor = 0.02;
ALTER SYSTEM
ALTER SYSTEM SET autovacuum_analyze_threshold = 0;
ALTER SYSTEM
-- Перечитаю конфигурацию
SELECT pg_reload_conf();
pg_reload_conf
----------------
t
(1 row)
-- Создадим две таблицы (обычную и временную)
-- И заполним их данными
CREATE TEMP TABLE t_temp7 (id integer);
CREATE TABLE
INSERT INTO t_temp7 SELECT * FROM generate_series(1,1_000_000);
INSERT 0 1000000
CREATE TABLE temp7 (id integer);
CREATE TABLE
INSERT INTO temp7 SELECT * FROM generate_series(1,1_000_000);
INSERT 0 1000000
-- Сделаем небольшую паузу
SELECT pg_sleep(2);
pg_sleep
----------
(1 row)
-- Проверим собранную статистику по таблицам
SELECT pg_sleep(2);
pg_sleep
----------
(1 row)
SELECT reltuples, relpages FROM pg_class WHERE relname = 't_temp7';
reltuples | relpages
-----------+----------
-1 | 0
(1 row)
SELECT reltuples, relpages FROM pg_class WHERE relname = 'temp7';
reltuples | relpages
-----------+----------
1e+06 | 4425
(1 row)
SELECT count(*) FROM t_temp7;
count
---------
1000000
(1 row)
SELECT count(*) FROM temp7;
count
---------
1000000
(1 row)
SELECT null_frac, avg_width, n_distinct, correlation
FROM pg_stats s
WHERE s.tablename = 't_temp7' AND s.attname = 'id';
null_frac | avg_width | n_distinct | correlation
-----------+-----------+------------+-------------
(0 rows)
SELECT null_frac, avg_width, n_distinct, correlation
FROM pg_stats s
WHERE s.tablename = 'temp7' AND s.attname = 'id';
null_frac | avg_width | n_distinct | correlation
-----------+-----------+------------+-------------
0 | 4 | -1 | 1
(1 row)
-- Показания отличаются
-- Для временной таблицы автоанализ не срабатывает
-- Соберём статистику по временной таблице руками
ANALYZE t_temp7;
ANALYZE
SELECT reltuples, relpages FROM pg_class WHERE relname = 't_temp7';
reltuples | relpages
-----------+----------
1e+06 | 4425
(1 row)
SELECT reltuples, relpages FROM pg_class WHERE relname = 'temp7';
reltuples | relpages
-----------+----------
1e+06 | 4425
(1 row)
SELECT null_frac, avg_width, n_distinct, correlation
FROM pg_stats s
WHERE s.tablename = 't_temp7' AND s.attname = 'id';
null_frac | avg_width | n_distinct | correlation
-----------+-----------+------------+-------------
0 | 4 | -1 | 1
(1 row)
SELECT null_frac, avg_width, n_distinct, correlation
FROM pg_stats s
WHERE s.tablename = 'temp7' AND s.attname = 'id';
null_frac | avg_width | n_distinct | correlation
-----------+-----------+------------+-------------
0 | 4 | -1 | 1
(1 row)
-- Проверим размер полученных таблиц
SELECT pg_size_pretty(pg_table_size('t_temp7'));
pg_size_pretty
----------------
35 MB
(1 row)
SELECT pg_size_pretty(pg_table_size('temp7'));
pg_size_pretty
----------------
35 MB
(1 row)
-- Обновим все строки в таблицах и снова проверим размер
UPDATE t_temp7 SET id = id + 1;
UPDATE 1000000
UPDATE temp7 SET id = id + 1;
UPDATE 1000000
SELECT pg_size_pretty(pg_table_size('t_temp7'));
pg_size_pretty
----------------
69 MB
(1 row)
SELECT pg_size_pretty(pg_table_size('temp7'));
pg_size_pretty
----------------
69 MB
(1 row)
-- Удалим все строки из таблиц
DELETE FROM t_temp7;
DELETE 1000000
DELETE FROM temp7;
DELETE 1000000
-- Сделаем небольшую задержку
SELECT pg_sleep(3);
pg_sleep
----------
(1 row)
-- Автовакуум не очищает временную таблицу
SELECT pg_size_pretty(pg_table_size('t_temp7'));
pg_size_pretty
----------------
69 MB
(1 row)
SELECT pg_size_pretty(pg_table_size('temp7'));
pg_size_pretty
----------------
16 kB
(1 row)
-- Сделаем очистку руками
VACUUM t_temp7;
VACUUM
SELECT pg_sleep(3);
pg_sleep
----------
(1 row)
SELECT pg_size_pretty(pg_table_size('t_temp7'));
pg_size_pretty
----------------
16 kB
(1 row)
SELECT pg_size_pretty(pg_table_size('temp7'));
pg_size_pretty
----------------
16 kB
(1 row)
-- Удалим лишнее
DROP TABLE temp7;
DROP TABLE
-- И настройки тоже
ALTER SYSTEM RESET autovacuum_naptime;
ALTER SYSTEM
ALTER SYSTEM RESET autovacuum_vacuum_scale_factor;
ALTER SYSTEM
ALTER SYSTEM RESET autovacuum_vacuum_threshold;
ALTER SYSTEM
ALTER SYSTEM RESET autovacuum_analyze_scale_factor;
ALTER SYSTEM
ALTER SYSTEM RESET autovacuum_analyze_threshold;
ALTER SYSTEM
-- Перечитаю конфигурацию
SELECT pg_reload_conf();
pg_reload_conf
----------------
t
(1 row)
8. Параллельная обработка временных таблиц
8. Параллельная обработка временных таблиц. Код эксперимента
8. Параллельная обработка временных таблиц. ECHO-комментарии
-- 8. Параллельная обработка временных таблиц
-- Создадим две таблицы, одну временную, другую обычную
CREATE TEMP TABLE t_temp8 (id integer);
CREATE TABLE
CREATE TABLE temp8 (id integer);
CREATE TABLE
-- Добавим туда по миллиону строк
INSERT INTO t_temp8 SELECT * FROM generate_series(1,1_000_000);
INSERT 0 1000000
INSERT INTO temp8 SELECT * FROM generate_series(1,1_000_000);
INSERT 0 1000000
-- Руками сделаем анализ
ANALYZE t_temp8;
ANALYZE
ANALYZE temp8;
ANALYZE
-- Посмотрим план запросов
EXPLAIN ANALYZE SELECT * FROM t_temp8;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------
Seq Scan on t_temp8 (cost=0.00..14425.00 rows=1000000 width=4) (actual time=0.029..1249.628 rows=1000000 loops=1)
Planning Time: 0.045 ms
Execution Time: 2440.071 ms
(3 rows)
EXPLAIN ANALYZE SELECT * FROM temp8;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------
Seq Scan on temp8 (cost=0.00..14425.00 rows=1000000 width=4) (actual time=0.011..1237.203 rows=1000000 loops=1)
Planning Time: 0.069 ms
Execution Time: 2431.272 ms
(3 rows)
-- Установим пар-р, с помощью которого можно посмотреть параллельный план
SHOW debug_parallel_query;
debug_parallel_query
----------------------
off
(1 row)
SET debug_parallel_query = on;
SET
-- И снова посмотрим план запросов — обычная таблица распараллеливается
EXPLAIN ANALYZE SELECT * FROM t_temp8;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------
Seq Scan on t_temp8 (cost=0.00..14425.00 rows=1000000 width=4) (actual time=0.011..1245.712 rows=1000000 loops=1)
Planning Time: 0.034 ms
Execution Time: 2435.330 ms
(3 rows)
EXPLAIN ANALYZE SELECT * FROM temp8;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------
Gather (cost=1000.00..115425.00 rows=1000000 width=4) (actual time=4.182..1309.885 rows=1000000 loops=1)
Workers Planned: 1
Workers Launched: 1
Single Copy: true
-> Seq Scan on temp8 (cost=0.00..14425.00 rows=1000000 width=4) (actual time=0.013..1297.671 rows=1000000 loops=1)
Planning Time: 0.032 ms
Execution Time: 2594.434 ms
(7 rows)
-- Удаляем лишнее
DROP TABLE temp8;
DROP TABLE
9. Параметр temp_buffers
9. Параметр temp_buffers. Код эксперимента
9. Параметр temp_buffers. ECHO-комментарии
-- 9. Параметр temp_buffers
-- Подготовка — создадим роль check_tmp, настроим доступ pg_hba
-- Проверим значение пар-ра temp_buffers
SHOW temp_buffers;
temp_buffers
--------------
8MB
(1 row)
-- Увеличим его
SET temp_buffers = 16MB;
SET
-- Создадим временную таблицу и снова увеличим значение пар-ра
CREATE TEMP TABLE t_temp9 (id integer);
CREATE TABLE
SET temp_buffers = 32MB;
SET
-- Вроде бы обращаемся к временной таблице - но пар-р снова можно изменить
SELECT * FROM t_temp9;
id
----
(0 rows)
SET temp_buffers = 16MB;
SET
-- Но после изменения данных во временной таблице уже нельзя менять значение пар-ра
INSERT INTO t_temp9 VALUES (1);
INSERT 0 1
SET temp_buffers = 32MB;
psql:9.sql:36: ERROR: invalid value for parameter "temp_buffers": 4096
DETAIL: "temp_buffers" cannot be changed after any temporary tables have been accessed in the session.
-- В плане чтение из локального кеша отображается как LOCAL READ/HIT
EXPLAIN (ANALYZE, BUFFERS) SELECT count(*) FROM t_temp9;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------
Aggregate (cost=41.88..41.88 rows=1 width=8) (actual time=0.016..0.023 rows=1 loops=1)
Buffers: local hit=1
-> Seq Scan on t_temp9 (cost=0.00..35.50 rows=2550 width=0) (actual time=0.006..0.009 rows=1 loops=1)
Buffers: local hit=1
Planning:
Buffers: shared hit=3
Planning Time: 0.046 ms
Execution Time: 0.130 ms
(8 rows)
\c
You are now connected to database "pavel" as user "pavel".
SET temp_buffers = 1024 kB;
SET
CREATE TEMP TABLE t_temp9 (id integer);
CREATE TABLE
CREATE TABLE temp9 (id integer);
CREATE TABLE
INSERT INTO t_temp9 SELECT * FROM generate_series(1,1_000_000);
INSERT 0 1000000
INSERT INTO temp9 SELECT * FROM generate_series(1,1_000_000);
INSERT 0 1000000
SELECT count(*) FROM temp9;
count
---------
1000000
(1 row)
-- local read
EXPLAIN (ANALYZE, BUFFERS) SELECT count(*) FROM t_temp9;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------
Aggregate (cost=18529.69..18529.70 rows=1 width=8) (actual time=2452.049..2452.055 rows=1 loops=1)
Buffers: local read=4425 dirtied=4425 written=4423
-> Seq Scan on t_temp9 (cost=0.00..15708.75 rows=1128375 width=0) (actual time=0.027..1232.810 rows=1000000 loops=1)
Buffers: local read=4425 dirtied=4425 written=4423
Planning:
Buffers: shared hit=4
Planning Time: 0.048 ms
Execution Time: 2452.079 ms
(8 rows)
-- Удаляем лишнее
DROP TABLE temp9;
DROP TABLE
10. Временные таблица, индекс, TOAST и их расположение на диске
10. Временные таблица, индекс, TOAST и их расположение на диске. Код эксперимента
10. Временные таблица, индекс, TOAST и их расположение на диске. ECHO-комментарии
-- 10. Временные таблица, индекс, TOAST и их расположение на диске
-- ТАБЛИЦА t_temp10
CREATE TEMP TABLE t_temp10(val text);
CREATE TABLE
-- Индекс на таблицу t_temp10
CREATE INDEX i_t_temp10 ON t_temp10 (val);
CREATE INDEX
-- НАЗВАНИЕ временной схемы
SELECT pg_my_temp_schema()::regnamespace;
pg_my_temp_schema
-------------------
pg_temp_3
(1 row)
-- НАЗВАНИЕ временной TOAST схемы
SELECT n.nspname FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
LEFT JOIN pg_catalog.pg_am am ON am.oid = c.relam WHERE c.relname = (
SELECT relname FROM pg_class WHERE OID = (
SELECT reltoastrelid FROM pg_class WHERE relname='t_temp10'));
nspname
-----------------
pg_toast_temp_3
(1 row)
-- Однако, план запроса с опцией VERBOSE показывает без цифр
EXPLAIN (ANALYZE, VERBOSE) select * from t_temp10;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------
Seq Scan on pg_temp.t_temp10 (cost=0.00..23.60 rows=1360 width=32) (actual time=0.002..0.004 rows=0 loops=1)
Output: val
Planning Time: 0.084 ms
Execution Time: 0.012 ms
(4 rows)
-- OID таблицы t_temp10
SELECT c.oid, c.relname
FROM pg_catalog.pg_class c
WHERE c.relname = 't_temp10';
oid | relname
--------+----------
490781 | t_temp10
(1 row)
-- OID индекса i_t_temp10
SELECT c.oid, c.relname
FROM pg_catalog.pg_class c
WHERE c.relname = 'i_t_temp10';
oid | relname
--------+------------
490786 | i_t_temp10
(1 row)
-- OID TOAST-таблицы на t_temp10
SELECT relfilenode, relname FROM pg_class WHERE OID = (
SELECT reltoastrelid FROM pg_class WHERE relname='t_temp10');
relfilenode | relname
-------------+-----------------
490784 | pg_toast_490781
(1 row)
-- OID TOAST-таблицы на t_temp10 с именем временной схемы
SELECT c.oid, n.nspname || . || c.relname relname
FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
LEFT JOIN pg_catalog.pg_am am ON am.oid = c.relam WHERE c.relname = (SELECT relname FROM pg_class WHERE OID = (
SELECT reltoastrelid FROM pg_class WHERE relname='t_temp10'));
oid | relname
--------+---------------------------------
490784 | pg_toast_temp_3.pg_toast_490781
(1 row)
-- Индекс на TOAST-таблицу
SELECT relname || '_index' FROM pg_class WHERE OID = (SELECT reltoastrelid FROM pg_class WHERE relname='t_temp10');
?column?
-----------------------
pg_toast_490781_index
(1 row)
-- Индекс на TOAST-таблицу на t_temp10 с именем временной схемы
SELECT c.oid, n.nspname || . || c.relname relname
FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
LEFT JOIN pg_catalog.pg_am am ON am.oid = c.relam
WHERE c.relname = (SELECT relname || '_index' FROM pg_class WHERE OID = (SELECT reltoastrelid FROM pg_class WHERE relname='t_temp10'));
oid | relname
--------+---------------------------------------
490785 | pg_toast_temp_3.pg_toast_490781_index
(1 row)
-- Текущая БД
SELECT * FROM current_database();
current_database
------------------
pavel
(1 row)
-- OID текущей БД
SELECT oid, datname FROM pg_catalog.pg_database WHERE datname = (SELECT * FROM current_database());
oid | datname
-------+---------
16391 | pavel
(1 row)
-- Адрес t_temp10 на диске
SELECT pg_relation_filepath('t_temp10') temp10_table;
temp10_table
----------------------
base/16391/t3_490781
(1 row)
-- Адрес i_t_temp10 на диске
SELECT pg_relation_filepath('i_t_temp10') temp10_index;
temp10_index
----------------------
base/16391/t3_490786
(1 row)
-- Адрес TOAST-таблицы на диске
SELECT pg_relation_filepath((SELECT n.nspname || . || c.relname relname
FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
LEFT JOIN pg_catalog.pg_am am ON am.oid = c.relam
WHERE c.relname = (SELECT relname FROM pg_class WHERE OID = (SELECT reltoastrelid FROM pg_class WHERE relname='t_temp10')))) TOAST_table;
toast_table
----------------------
base/16391/t3_490784
(1 row)
-- Адрес индекса на TOAST-таблицу на диске
SELECT pg_relation_filepath((SELECT n.nspname || . || c.relname relname
FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
LEFT JOIN pg_catalog.pg_am am ON am.oid = c.relam
WHERE c.relname = (SELECT relname || '_index' FROM pg_class WHERE OID = (SELECT reltoastrelid FROM pg_class WHERE relname='t_temp10')))) TOAST_temp10_index;
toast_temp10_index
----------------------
base/16391/t3_490785
(1 row)
SHOW data_directory;
data_directory
-----------------------------
/var/lib/postgresql/16/main
(1 row)
-- Проверим на диске
sudo ls -al /var/lib/postgresql/16/main/base/16391/ | grep t3
-rw------- 1 postgres postgres 0 ноя 20 16:20 t3_490781
-rw------- 1 postgres postgres 0 ноя 20 16:20 t3_490784
-rw------- 1 postgres postgres 8192 ноя 20 16:20 t3_490785
-rw------- 1 postgres postgres 8192 ноя 20 16:20 t3_490786
11. Параметр remove_temp_files_after_crash (тут возможно баг?)
11. Параметр remove_temp_files_after_crash (тут возможно баг?). Код эксперимента 1
11. Параметр remove_temp_files_after_crash (тут возможно баг?). Код эксперимента 2
11. Параметр remove_temp_files_after_crash (тут возможно баг?). Код эксперимента 3
11. Параметр remove_temp_files_after_crash (тут возможно баг?). ECHO-комментарии 1
11. Параметр remove_temp_files_after_crash (тут возможно баг?). ECHO-комментарии 2
11. Параметр remove_temp_files_after_crash (тут возможно баг?). ECHO-комментарии 3
psql:
-- 11. Параметр remove_temp_files_after_crash
-- 11_1
-- А здесь единым скриптом не получилось
-- Команды, начинающиеся с доллара — выполняются в ОС
SHOW remove_temp_files_after_crash;
remove_temp_files_after_crash
-------------------------------
off
(1 row)
-- Включаем параметр remove_temp_files_after_crash в сессии нельзя
SET remove_temp_files_after_crash = on;
psql:11_1.sql:9: ERROR: parameter "remove_temp_files_after_crash" cannot be changed now
ALTER SYSTEM SET remove_temp_files_after_crash = on;
ALTER SYSTEM
-- Далее перезапускаем экземпляр
-- 11.2
-- Проверяем параметр
SHOW remove_temp_files_after_crash;
remove_temp_files_after_crash
-------------------------------
on
(1 row)
CREATE TEMP TABLE t_temp11 (id integer);
CREATE TABLE
INSERT INTO t_temp11 VALUES (1),(2),(3);
INSERT 0 3
SELECT pg_relation_filepath(t_temp11);
pg_relation_filepath
----------------------
base/16391/t3_498992
(1 row)
SHOW data_directory;
data_directory
-----------------------------
/var/lib/postgresql/16/main
(1 row)
-- ID обслуживающего процесса
SELECT pg_backend_pid();
pg_backend_pid
----------------
77078
(1 row)
bash:
$ sudo ls -al /var/lib/postgresql/16/main/base/16391/ | grep t3 -rw------- 1 postgres postgres 8192 ноя 20 17:37 t3_498992 $ sudo kill -9 77078 $ sudo ls -al /var/lib/postgresql/16/main/base/16391/ | grep t3 # пусто — таких файлов нет
psql:
-- 11_3
-- Сессия оборвана
SELECT 1;
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.
-- Но сразу восстанавливается
SELECT 1;
?column?
----------
1
(1 row)
SHOW remove_temp_files_after_crash;
remove_temp_files_after_crash
-------------------------------
on
(1 row)
-- Отключаем параметр remove_temp_files_after_crash в сессии нельзя
SET remove_temp_files_after_crash = off;
psql:11_3.sql:15: ERROR: parameter "remove_temp_files_after_crash" cannot be changed now
ALTER SYSTEM SET remove_temp_files_after_crash = off;
ALTER SYSTEM
-- Далее перезапускаем экземпляр
bash:
$ sudo systemctl restart postgresql@16-main.service
psql:
-- 11.2
-- Проверяем параметр
SHOW remove_temp_files_after_crash;
remove_temp_files_after_crash
-------------------------------
off
(1 row)
CREATE TEMP TABLE t_temp11 (id integer);
CREATE TABLE
INSERT INTO t_temp11 VALUES (1),(2),(3);
INSERT 0 3
SELECT pg_relation_filepath(t_temp11);
pg_relation_filepath
----------------------
base/16391/t3_507187
(1 row)
SHOW data_directory;
data_directory
-----------------------------
/var/lib/postgresql/16/main
(1 row)
-- ID обслуживающего процесса
SELECT pg_backend_pid();
pg_backend_pid
----------------
78040
(1 row)
bash:
$ sudo ls -al /var/lib/postgresql/16/main/base/16391/ | grep t3 -rw------- 1 postgres postgres 8192 ноя 20 17:37 t3_507187 $ sudo kill -9 78040 $ sudo ls -al /var/lib/postgresql/16/main/base/16391/ | grep t3 -rw------- 1 postgres postgres 8192 ноя 20 17:37 t3_507187 sudo hexdump /var/lib/postgresql/16/main/base/16391/t3_507187 0000000 0000 0000 0000 0000 0000 0000 0000 0000 * 0002000
psql:
-- Однако! Если опять подключиться к серверу
SELECT 1;
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.
SELECT 1;
?column?
----------
1
(1 row)
-- Файлы временных таблиц будут удалены!
bash:
$ sudo ls -al /var/lib/postgresql/16/main/base/16391/ | grep t3 # пусто — файлов больше нет
psql:
-- И еще раз однако!
-- 11.2
-- Проверяем параметр
SHOW remove_temp_files_after_crash;
remove_temp_files_after_crash
-------------------------------
off
(1 row)
CREATE TEMP TABLE t_temp11 (id integer);
CREATE TABLE
INSERT INTO t_temp11 VALUES (1),(2),(3);
INSERT 0 3
SELECT pg_relation_filepath(t_temp11);
pg_relation_filepath
----------------------
base/16391/t3_515379
(1 row)
SHOW data_directory;
data_directory
-----------------------------
/var/lib/postgresql/16/main
(1 row)
-- ID обслуживающего процесса
SELECT pg_backend_pid();
pg_backend_pid
----------------
78839
(1 row)
bash (вот тут?):
$ sudo head -n 1 /var/lib/postgresql/16/main/postmaster.pid 78014 $ sudo ls -al /var/lib/postgresql/16/main/base/16391/ | grep t3 -rw------- 1 postgres postgres 8192 ноя 20 17:37 t3_507187 $ sudo kill -9 78014 $ sudo ls -al /var/lib/postgresql/16/main/base/16391/ | grep t3 # иии пусто — файлов нет! Почему? Я подозреваю что это баг
Leave a Reply