Гость
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Жуткий swap от запроса / 11 сообщений из 11, страница 1 из 1
28.06.2018, 08:19
    #39666903
Visermoz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Жуткий swap от запроса
Добрый день. В БД(общий размер 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
28.06.2018, 09:58
    #39666955
gav21
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Жуткий swap от запроса
Visermoz,

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

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

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
28.06.2018, 11:42
    #39667042
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Жуткий swap от запроса
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
28.06.2018, 12:05
    #39667055
Visermoz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Жуткий swap от запроса
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
28.06.2018, 12:05
    #39667056
Visermoz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Жуткий swap от запроса
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
28.06.2018, 12:09
    #39667058
Visermoz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Жуткий swap от запроса
Интересно, что запрос
Код: 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
28.06.2018, 12:16
    #39667066
Visermoz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Жуткий swap от запроса
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
28.06.2018, 12:58
    #39667104
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Жуткий swap от запроса
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
28.06.2018, 13:23
    #39667135
Visermoz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Жуткий swap от запроса
Maxim Boguk,
да, точно. Большое спасибо за пояснение.

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

Еще он пишет, что "pg_dump вытягивает описание вьюшек последовательно, одну за другой, а не целым запросом", но для самого серверного процесса ведь большой разницы нет- что так, что так relcache будет заполняться и освободится только когда процесс завершится?
Поэтому для такой базы решением будет увеличение памяти(или swap) или снятие копии без представлений?
...
Рейтинг: 0 / 0
28.06.2018, 14:14
    #39667171
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Жуткий swap от запроса
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
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Жуткий swap от запроса / 11 сообщений из 11, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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