Существует таблица, которая имеет 200 строк. Но количество живых кортежей, показывающих там больше, чем (около 60 тыс.).
select count(*) from subscriber_offset_manager;
count
-------
200
(1 row)
SELECT schemaname,relname,n_live_tup,n_dead_tup FROM pg_stat_user_tables where relname='subscriber_offset_manager' ORDER BY n_dead_tup
;
schemaname | relname | n_live_tup | n_dead_tup
------------+---------------------------+------------+------------
public | subscriber_offset_manager | 61453 | 5
(1 row)
Но, как видно из pg_stat_activity и pg_locks, мы не можем отслеживать любое открытое соединение.
SELECT query, state,locktype,mode
FROM pg_locks
JOIN pg_stat_activity
USING (pid)
WHERE relation::regclass = 'subscriber_offset_manager'::regclass
;
query | state | locktype | mode
-------+-------+----------+------
(0 rows)
Я также попробовал полный вакуум на этой таблице, Ниже приведены результаты:
- Все строки, которые не удаляются
- несколько раз все живые кортежи становятся мертвыми кортежами.
Вот вывод.
vacuum FULL VERBOSE ANALYZE subscriber_offset_manager;
INFO: vacuuming "public.subscriber_offset_manager"
INFO: "subscriber_offset_manager": found 0 removable, 67920 nonremovable row versions in 714 pages
DETAIL: 67720 dead row versions cannot be removed yet.
CPU 0.01s/0.06u sec elapsed 0.13 sec.
INFO: analyzing "public.subscriber_offset_manager"
INFO: "subscriber_offset_manager": scanned 710 of 710 pages, containing 200 live rows and 67720 dead rows; 200 rows in sample, 200 estimated total rows
VACUUM
SELECT schemaname,relname,n_live_tup,n_dead_tup FROM pg_stat_user_tables where relname='subscriber_offset_manager' ORDER BY n_dead_tup
;
schemaname | relname | n_live_tup | n_dead_tup
------------+---------------------------+------------+------------
public | subscriber_offset_manager | 200 | 67749
и через 10 сек
SELECT schemaname,relname,n_live_tup,n_dead_tup FROM pg_stat_user_tables where relname='subscriber_offset_manager' ORDER BY n_dead_tup
;
schemaname | relname | n_live_tup | n_dead_tup
------------+---------------------------+------------+------------
public | subscriber_offset_manager | 68325 | 132
Как наш запрос приложения к этой таблице.
-
Наше приложение обычно выбирает некоторые строки и основывается на некоторых бизнес-расчетах, обновляет строку.
select query - выберите на основе некоторого id
выберите * from subscriber_offset_manager, где shard_id = 1;
update query - обновить другой столбец для этого выбранного идентификатора осколков
-
около 20 потоков выполняют это параллельно, а один поток работает только с одной строкой.
- приложение написано в java, и мы используем hibernate для выполнения операций db.
- Версия Postgresql - 9.3.24
Еще одно интересное замечание: когда я останавливаю свое приложение java, а затем выполняю полный вакуум, он отлично работает (количество строк и живых кортежей становится равным). Таким образом, есть что-то неправильно, если мы постоянно выбираем и обновляем приложение java. -
Проблема/Выпуск
Эти живые кортежи несколько раз переходят к мертвым кортежам и через некоторое время снова оживают.
Из-за вышеуказанного поведения выберите из таблицы время и увеличив нагрузку на сервер, так как там есть много живых/мертвых точек.