powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Жуткий swap от запроса
11 сообщений из 11, страница 1 из 1
Жуткий swap от запроса
    #39666903
Visermoz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день. В БД(общий размер 400 gb) с такими настройками

max_connections = 1000
shared_buffers = 1GB
effective_cache_size = 2GB
work_mem = 50MB
maintenance_work_mem = 80MB
min_wal_size = 1GB
max_wal_size = 2GB
checkpoint_completion_target = 0.9
wal_buffers = 16MB
default_statistics_target = 100
datestyle = 'iso, dmy'
max_locks_per_transaction=40000
track_activities = on
track_activity_query_size = 16384
autovacuum = on
autovacuum_max_workers = 3

(на сервере с alt linux (16 ядер, 8gb оперативной памяти, 50 gb swap))

существуют 30 схем по 300 таблиц в каждой. Некоторые таблицы(с индексами) имеют размер 20 gb.(без учета индексов по 800mb)
При формировании отчета по размерам таблиц вот таким запрсом:
Код: sql
1.
2.
3.
4.
select table_schema,table_name,pg_size_pretty(pg_total_relation_size(table_schema||'."'||table_name||'"')) 
	from information_schema.tables
		where table_schema in(select scheme from schemas_list)
order by pg_total_relation_size(table_schema||'."'||table_name||'"') desc


начинается использование swap вплоть до 50gb, там заканчивается место и сервер падает.
Причем, оперативная память в этот момент есть свободная.

Вывод free -m
Код: powershell
1.
2.
3.
4.
             total       used       free     shared    buffers     cached
Mem:          8003       7825        177          0          5       1095
-/+ buffers/cache:       6724       1278
Swap:        51199      49425       1774



вывод
Код: powershell
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
 for file in /proc/*/status ; do awk '/VmSwap|Name/{printf $2 " " $3}END{ print ""}' $file; done | sort -k 2 -n -r | less
postgres 49703700 kB
postgres 4147268 kB
postgres 258116 kB
postgres 248840 kB
postgres 201168 kB
postgres 181504 kB
postgres 161044 kB
postgres 152284 kB
postgres 138784 kB
postgres 97260 kB
postgres 68716 kB
...



Пробовал разные настройки shared_buffers(до 4 gb) и effective_cache_size (до 6gb), но результат такой же.
Примерно похожая ситуация возникает и при снятии копии БД утилитой pg_dump.
Подскажите пожалуйста, можно ли понять почему так происходит и как уменьшить использование swap. Запрос с размерами таблиц приведен для примера-больше всего хочется понять почему подобное происходит вообще и как правильно нужно настраивать.
Или с этим ничего не сделать и нужно для такой БД более мощный сервер использовать.
...
Рейтинг: 0 / 0
Жуткий swap от запроса
    #39666955
gav21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Visermoz,

покажите план вашего запроса
explain <ваш запрос>
...
Рейтинг: 0 / 0
Жуткий swap от запроса
    #39666994
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Visermoz,

А покажите что показывает select count(*) from pg_tables; на этой базе.
Если не отработает то
select count(*) from pg_class where relkind='r';

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
Жуткий swap от запроса
    #39667042
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VisermozПробовал разные настройки shared_buffers(до 4 gb) и effective_cache_size (до 6gb), но результат такой же.
Примерно похожая ситуация возникает и при снятии копии БД утилитой pg_dump.
Подскажите пожалуйста, можно ли понять почему так происходит и как уменьшить использование swap. Запрос с размерами таблиц приведен для примера-больше всего хочется понять почему подобное происходит вообще и как правильно нужно настраивать.
Или с этим ничего не сделать и нужно для такой БД более мощный сервер использовать.

Вероятнее всего ответ будет что надо больше памяти на сервере под такую базу.
Кстати а что дает select count(*) from pg_class; на этой базе?

Проблема в кешировании структуры всех таблиц (к которым обратились) и индексов в памяти backend, в вашем случае это приводит к кешированию структуры вообще всей базы а она судя по вашему описанию очень развесистая у вас.

Проблема называется relcache bloat:
Пример проблемы тут вот
https://www.postgresql.org/message-id/flat/20171129100649.1473.73990@wrigleys.postgresql.org

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
Жуткий swap от запроса
    #39667055
Visermoz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
gav21,


Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
explain
select table_schema,table_name,pg_size_pretty(pg_total_relation_size(table_schema||'."'||table_name||'"')) 
	from information_schema.tables
		where table_schema in(select scheme from schemas_list)
order by pg_total_relation_size(table_schema||'."'||table_name||'"') desc


Result  (cost=25820.68..26970.40 rows=20904 width=104)
  ->  Sort  (cost=25820.68..25872.94 rows=20904 width=200)
        Sort Key: (pg_total_relation_size(((((((nc.nspname)::information_schema.sql_identifier)::text || '."'::text) || ((c.relname)::information_schema.sql_identifier)::text) || '"'::text))::regclass)) DESC
        ->  Hash Left Join  (cost=11834.70..24320.66 rows=20904 width=200)
              Hash Cond: (c.reloftype = t.oid)
              ->  Hash Join  (cost=25.72..11753.92 rows=20904 width=132)
                    Hash Cond: (c.relnamespace = nc.oid)
                    ->  Seq Scan on pg_class c  (cost=0.00..11284.28 rows=62758 width=72)
                          Filter: ((relkind = ANY ('{r,v,f}'::"char"[])) AND (pg_has_role(relowner, 'USAGE'::text) OR has_table_privilege(oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER'::text) OR has_any_column_privilege(oid, 'SELECT, INSERT, UPDATE, REFERENCES'::text)))
                    ->  Hash  (cost=22.92..22.92 rows=224 width=68)
                          ->  Hash Semi Join  (cost=1.52..22.92 rows=224 width=68)
                                Hash Cond: (((nc.nspname)::information_schema.sql_identifier)::text = (schemas_list.scheme)::text)
                                ->  Seq Scan on pg_namespace nc  (cost=0.00..17.43 rows=449 width=68)
                                      Filter: (NOT pg_is_other_temp_schema(oid))
                                ->  Hash  (cost=1.23..1.23 rows=23 width=9)
                                      ->  Seq Scan on schemas_list  (cost=0.00..1.23 rows=23 width=9)
              ->  Hash  (cost=9560.51..9560.51 rows=179877 width=4)
                    ->  Hash Join  (cost=24.16..9560.51 rows=179877 width=4)
                          Hash Cond: (t.typnamespace = nt.oid)
                          ->  Seq Scan on pg_type t  (cost=0.00..7267.77 rows=179877 width=8)
                          ->  Hash  (cost=15.74..15.74 rows=674 width=4)
                                ->  Seq Scan on pg_namespace nt  (cost=0.00..15.74 rows=674 width=4)



Согласен, лучше было бы не на вьюшку делать,а напрямую к системному словарю- тогда план получается приятнее
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
explain
select n.nspname,c.relname,pg_size_pretty(pg_total_relation_size(n.nspname||'."'||c.relname||'"')) 
from pg_class c 
	join pg_namespace n on n.oid=c.relnamespace and nspname in(select scheme from schemas_list)
where c.relkind='r'
order by pg_total_relation_size(n.nspname||'."'||c.relname||'"') desc

Result  (cost=6652.28..6667.83 rows=311 width=168)
  Output: n.nspname, c.relname, pg_size_pretty((pg_total_relation_size((((((n.nspname)::text || '."'::text) || (c.relname)::text) || '"'::text))::regclass))), (pg_total_relation_size((((((n.nspname)::text || '."'::text) || (c.relname)::text) || '"'::text))::regclass))
  ->  Sort  (cost=6652.28..6653.05 rows=311 width=136)
        Output: n.nspname, c.relname, (pg_total_relation_size((((((n.nspname)::text || '."'::text) || (c.relname)::text) || '"'::text))::regclass))
        Sort Key: (pg_total_relation_size((((((n.nspname)::text || '."'::text) || (c.relname)::text) || '"'::text))::regclass)) DESC
        ->  Hash Join  (cost=19.68..6639.40 rows=311 width=136)
              Output: n.nspname, c.relname, pg_total_relation_size((((((n.nspname)::text || '."'::text) || (c.relname)::text) || '"'::text))::regclass)
              Hash Cond: (c.relnamespace = n.oid)
              ->  Seq Scan on pg_catalog.pg_class c  (cost=0.00..6576.94 rows=9128 width=68)
                    Output: c.relname, c.relnamespace, c.reltype, c.reloftype, c.relowner, c.relam, c.relfilenode, c.reltablespace, c.relpages, c.reltuples, c.relallvisible, c.reltoastrelid, c.relhasindex, c.relisshared, c.relpersistence, c.relkind, c.relnatts, c.relchecks, c.relhasoids, c.relhaspkey, c.relhasrules, c.relhastriggers, c.relhassubclass, c.relrowsecurity, c.relforcerowsecurity, c.relispopulated, c.relreplident, c.relfrozenxid, c.relminmxid, c.relacl, c.reloptions
                    Filter: (c.relkind = 'r'::"char")
              ->  Hash  (cost=19.39..19.39 rows=23 width=68)
                    Output: n.nspname, n.oid
                    ->  Hash Semi Join  (cost=1.52..19.39 rows=23 width=68)
                          Output: n.nspname, n.oid
                          Hash Cond: (n.nspname = (schemas_list.scheme)::name)
                          ->  Seq Scan on pg_catalog.pg_namespace n  (cost=0.00..15.74 rows=674 width=68)
                                Output: n.nspname, n.oid
                          ->  Hash  (cost=1.23..1.23 rows=23 width=9)
                                Output: schemas_list.scheme
                                ->  Seq Scan on schemas_list  (cost=0.00..1.23 rows=23 width=9)
                                      Output: schemas_list.scheme
...
Рейтинг: 0 / 0
Жуткий swap от запроса
    #39667056
Visermoz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguk,

Запросы выполнились быстро
Код: plsql
1.
2.
3.
4.
5.
select count(*) from pg_tables;
9166

select count(*) from pg_class where relkind='r';
9166
...
Рейтинг: 0 / 0
Жуткий swap от запроса
    #39667058
Visermoz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Интересно, что запрос
Код: sql
1.
2.
3.
4.
5.
select n.nspname,c.relname,pg_size_pretty(pg_total_relation_size(n.nspname||'."'||c.relname||'"')) 
from pg_class c 
	join pg_namespace n on n.oid=c.relnamespace and nspname in(select scheme from schemas_list)
where c.relkind='r'
order by pg_total_relation_size(n.nspname||'."'||c.relname||'"') desc


выполнился за 3 секунды без всякой нагрузки на БД и swap!
...
Рейтинг: 0 / 0
Жуткий swap от запроса
    #39667066
Visermoz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
gav21 , Maxim Boguk ,
спасибо вам за советы и помощь. С этим запросом, после переписывания с представления information_schema.tables на таблицы системного словаря всё стало работать как нужно.

Вероятно, при использовании pg_dump происходит как раз relcache bloat. В базе помимо большого количества таблиц в каждой схеме существуют по ~ 3000 представлений.
Этот вопрос обсуждали в http://www.sql.ru/forum/1278360/pg-dump-zanimaet-vsu-operativnuu-pamyat-i-ves-swap, но пришлось снимать не все схемы в один файл, а в несколько файлов. Там тоже было большое использование swap, но при выполнении pg_get_viewdef при сохранении структуры БД утилитой pg_dump.
...
Рейтинг: 0 / 0
Жуткий swap от запроса
    #39667104
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Visermozgav21 , Maxim Boguk ,
спасибо вам за советы и помощь. С этим запросом, после переписывания с представления information_schema.tables на таблицы системного словаря всё стало работать как нужно.

Вероятно, при использовании pg_dump происходит как раз relcache bloat. В базе помимо большого количества таблиц в каждой схеме существуют по ~ 3000 представлений.
Этот вопрос обсуждали в http://www.sql.ru/forum/1278360/pg-dump-zanimaet-vsu-operativnuu-pamyat-i-ves-swap, но пришлось снимать не все схемы в один файл, а в несколько файлов. Там тоже было большое использование swap, но при выполнении pg_get_viewdef при сохранении структуры БД утилитой pg_dump.

Я даже могу обьяснить почему у вас ООМ при использовании information_schema.tables
Если вы посмотрите на определение \d+ information_schema.tables
Вы там увидите:
WHERE (c.relkind = ANY (ARRAY['r'::"char", 'v'::"char", 'f'::"char"]))

'v'::"char" - это как раз эти самые views которые вам и дают ООМ.
А при прямой работе с pg_class - вы их не цепляете и поэтому запрос работает.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
Жуткий swap от запроса
    #39667135
Visermoz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguk,
да, точно. Большое спасибо за пояснение.

Подскажите пожалуйста по ответу Tom Lane:
"but why wouldn't it get reclaimed at the end of each tuple cycle?". К сожалению, я не понял термин "Цикл кортежей". Имеется ввиду просто выборка и то что память освободится когда получение данных завершится?

Еще он пишет, что "pg_dump вытягивает описание вьюшек последовательно, одну за другой, а не целым запросом", но для самого серверного процесса ведь большой разницы нет- что так, что так relcache будет заполняться и освободится только когда процесс завершится?
Поэтому для такой базы решением будет увеличение памяти(или swap) или снятие копии без представлений?
...
Рейтинг: 0 / 0
Жуткий swap от запроса
    #39667171
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VisermozMaxim Boguk,
да, точно. Большое спасибо за пояснение.

Подскажите пожалуйста по ответу Tom Lane:
"but why wouldn't it get reclaimed at the end of each tuple cycle?". К сожалению, я не понял термин "Цикл кортежей". Имеется ввиду просто выборка и то что память освободится когда получение данных завершится?

Еще он пишет, что "pg_dump вытягивает описание вьюшек последовательно, одну за другой, а не целым запросом", но для самого серверного процесса ведь большой разницы нет- что так, что так relcache будет заполняться и освободится только когда процесс завершится?
Поэтому для такой базы решением будет увеличение памяти(или swap) или снятие копии без представлений?

Да или без views или памяти сильно больше выдать (8Gb даже на ноуте сейчас это очень мало).

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Жуткий swap от запроса
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]