【发布时间】:2019-01-21 11:59:09
【问题描述】:
有一个表,有 200 行。但显示的实时元组数量不止于此(大约 60K)。
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
我们的 App 是如何查询这个表的。
-
我们的应用程序一般会选择一些行,并根据一些业务计算,更新行。
选择查询 -- 根据某个 id 选择
select * from subscriber_offset_manager where shard_id=1 ;
更新查询 -- 更新此选定分片 ID 的其他列
大约 20 个线程并行执行此操作,一个线程仅在一行上工作。
- app 是用 java 编写的,我们使用 hibernate 来进行数据库操作。
- Postgresql 版本为 9.3.24
另一个有趣的观察结果: - 当我停止我的 java 应用程序然后完全真空时,它工作正常(行数和活动元组变得相等)。因此,如果我们从 java app 中不断选择和更新,就会出现问题。 -
问题/问题
这些活的元组有时会变成死元组,然后又会活过来。
由于上述行为,从表中进行选择会花费时间并增加服务器上的负载,因为那里有很多 live/deadtuples ..
【问题讨论】:
-
听起来好像有什么严重的错误。 Postgres 9.3 哪一点发布?最新的 9.3.23?
SHOW track_counts能得到什么? -
Postgres 版本是 9.3.24 。再观察一下 - 当我停止我的 java 应用程序然后进行全真空时,它工作正常。所以如果我们不断选择和更新就会有问题。
-
您可能会显示用于选择/更新行的查询。
-
添加了问题:选择查询-基于某些ID选择*来自订阅者偏移量管理器其中shard_id = 1;更新查询 -- 更新此选定分片 ID 的其他列
标签: java postgresql performance hibernate postgresql-9.3