我们在JBoss中运行一个使用PostgreSQL 8.0.9作为数据库的Java EE Web应用程序。
应用程序中的一个页面在加载时运行一个大而复杂的查询。如果用户在请求的页面返回到客户端之前请求此页面并关闭其浏览器窗口,则会出现问题。问题是关闭窗口会产生一个新的PostgreSQL线程/进程(可通过top查看),并且新的线程/进程在顶部输出中需要很长时间才能从SELECT切换到空闲状态。如果大约5个或更多用户在一个小窗口中执行此操作(在大型复杂查询页面返回到客户端之前关闭浏览器窗口),则生成的线程/进程正在增长,而不是切换到空闲状态(保留在SELECT中)并消耗很多CPU,造成重大性能问题。值得一提的是,如果关闭浏览器窗口的用户注销,关联的线程/进程将切换到空闲状态,CPU使用率会降低。同样重要的是,如果重新启动JBoss,适用的线程/进程将切换到空闲状态(因为所有用户都将通过重新启动注销)。
挂起线程/进程的问题似乎已由数据库备份和RESTORE解决。现在生成的新线程/进程在很短的时间内从SELECT切换到空闲,并且CPU不会受到它们的负担。此外,自RESTORE以来,大型复杂查询的性能似乎有了显着提高。
我们每24小时在数据库上运行VACUUM。由于存在数据损坏风险,我们不会在数据库上运行REINDEX。我们确实倾向于在iostat输出上有相当高的等待数,特别是在上述性能问题情况下。
数据库在转储和恢复时会发生什么(例如REINDEX等)?其中哪一项似乎是我们解决方案的关键?
是否有一个设置来管理在将具有大量复杂查询的页面返回给客户端之前关闭浏览器窗口时生成的线程/进程数?是否有设置来管理从SELECT到空闲的线程/进程的转换?是否可以在应用程序级别管理其中任何一个?
答案 0 :(得分:2)
版本8.0已经是EOL,版本8.0.9也没有在很长一段时间内修补:8.0.26是最后一次。您缺少许多补丁,至少应更新到最新的8.0版本,但也要开始迁移到仍受支持的版本。从版本8.2和8.3开始,性能变得更好。
问题:为什么您认为REINDEX会破坏您的数据?数据的腐败会使这个陈述变得毫无用处...... REINDEX不是你每天都会做的事,但有时你需要它。