微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java – postgresql中的大量活/死元组/真空无法正常工作

有一张桌子,有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,其中shard_id = 1;

更新查询 – 更新此选定分片ID的其他一些列
>大约20个线程并行执行此操作,一个线程仅在一行上工作.
> app在java中编写,我们正在使用hibernate来执行数据库操作.
> Postgresql版本是9.3.24

一个有趣的观察:
  – 当我停止我的Java应用程序,然后完全真空,它工作正常(行数和实时元组变得相等).因此,如果我们从Java应用程序中连续选择和更新,则会出现问题. –

问题/发行

这些活元组有时会去死元组,并且经过一段时间再次生存.

由于上述行为,从表中选择花费时间和增加服务器上的负载,因为有很多活/死的..

解决方法:

我知道有三件事让VACUUM无法完成任务:

>长时间运行的交易.
>未准备好的准备交易.
>陈旧的复制插槽.

有关详情,请参见my blog post.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐