1

我有一个在 Windows 上使用 PostgreSQL 8.3 的 C++ 应用程序。我们使用 libpq 接口。

我们有一个多线程应用程序,其中每个线程打开一个连接并在没有 PQFinish 的情况下继续使用。

我们注意到,对于每个查询(尤其是 SELECT 语句),postgres.exe 的内存消耗都会增加。它高达 1.3 GB。最终,postgres.exe 崩溃并强制我们的程序创建一个新连接。

有没有人遇到过这个问题?

编辑:shared_buffer 当前在我们的 conf 中设置为 128MB。文件。

EDIT2:我们现在采用的解决方法是为每个事务调用 PQfinish。但是,这会稍微减慢我们的处理速度,因为每次建立连接都很慢。

4

3 回答 3

4

在 PostgreSQL 中,每个连接都有一个专用的后端。该后端不仅保存连接和会话状态,而且还是一个执行引擎。后端闲置起来并不是特别便宜,即使在空闲时它们也会消耗内存和同步开销。

对于任何给定的工作负载,任何给定的 Pg 服务器都有一个最佳数量的活跃​​工作后端,其中添加更多工作后端会减慢而不是加快速度。您想找到那个点,并将后端的数量限制在该级别附近。不幸的是,这没有什么灵丹妙药,它主要涉及基准测试——在你的硬件和你的工作负载上。

如果您需要更多的连接,则应使用代理或池系统,允许您将“连接状态”与“执行引擎”分开。两个流行的选择是PgBouncerPgPool-II。您可以维护从您的应用程序到代理/池程序的轻量级连接,并让它安排工作负载以保持数据库服务器以最佳负载工作。如果有太多查询进来,一些查询会在执行之前等待,而不是竞争资源并减慢服务器上的所有查询。

请参阅postgresql 维基

请注意,如果您的工作负载以读取为主,特别是如果它具有不经常更改的项目,您可以确定可靠的缓存失效方案,您还可以潜在地使用 memcached 或 Redis 来减少数据库工作负载。这需要更改应用程序。PostgreSQL 将帮助您进行合理的LISTEN缓存NOTIFY失效。

许多数据库引擎在核心数据库引擎的设计中内置了执行引擎和连接状态的一些分离。Sybase ASE 确实如此,我认为Oracle 也是如此,但我不太确定后者。不幸的是,由于 PostgreSQL 的每个连接一个进程的模型,它在后端之间传递工作并不容易,这使得 PostgreSQL 更难在本地执行此操作,因此大多数人使用代理或池。

我强烈建议您阅读PostgreSQL High Performance我与 Greg Smith 或出版商*没有任何关系/从属关系,我只是认为这很棒,如果您担心数据库的性能,这将非常有用。


* ...好吧,我写这篇文章的时候没有。我现在在同一家公司工作。

于 2012-04-18T11:37:35.863 回答
1

内存使用不一定是问题。PostgreSQL 使用共享内存进行一些缓存,并且在实际使用之前,该内存不计入进程内存使用的大小。您使用该进程的次数越多,共享缓冲区的较大部分将在其地址空间中处于活动状态。

如果shared_buffers的值很大,就会发生这种情况。如果它太大,进程可能会耗尽地址空间并崩溃,是的。

于 2009-08-01T15:37:41.577 回答
0

问题可能是您没有关闭事务,在 PostgreSQL 中,即使您只在没有 DML 的情况下进行选择,它也会在需要回滚的事务中运行。通过在事务结束时添加回滚将减少您的内存问题

于 2013-04-09T14:48:34.867 回答