PostgreSQL统计问题 - 无法重命名临时统计文件

16

我在Windows上运行PotgreSQL 9.4,经常遇到以下错误:

2015-06-15 09:35:36 EDT LOG could not rename temporary statistics file "pg_stat_tmp/global.tmp" to "pg_stat_tmp/global.stat": Permission denied 

我还注意到全局变量global.stat和global.tmp不断进行200-800k的写入操作。我发现其他用户也遇到了同样的问题,但没有解决方案。 这是一个大型数据库服务器,有300GB的数据和6000个数据库。

我尝试设置,

track_activities=off

在配置文件中,但似乎没有任何影响。

对于这个错误需要什么帮助,或者如何减少写入?


特别寻找为什么在track_activities=off状态下仍然以每秒800k的速度写入统计数据。 - James
这是一个已知的 bug。手动解决方案是更改 pg_stat_tmp/ 目录的权限,以便 postgres 可以写入该目录。(在 Unix 中,重命名只需要对目录的权限;不清楚 Windows 是否也是如此) - wildplasser
我已经更改了目录的权限以允许所有操作,但我认为这不是权限问题。Postgres可以写入该目录,该目录中有100多个文件,最近都被写入过。我猜测这可能是某种文件并发问题? - James
文件路径使用斜杠相对路径,但在Windows中应该使用反斜杠。也许它试图移动文件并失败了,因为存在不可能的Windows文件名“pg_stat_tmp/global.stat”?如果将stats_temp_directory更改为完整路径,会发生什么? - Vao Tsun
3个回答

26
在我的初步回答后,我决定研究统计收集器的操作,特别是它对pg_stat_tmp文件的处理。结果,我进行了大量重写。
全局.stat / global.tmp文件用于什么?
Postgresql包含收集有关其操作的统计信息和状态信息的功能。该功能在手册的第27.2节中描述。
此信息由stats collector进程汇总。通过global.stat文件提供给其他postgresql进程。第一次运行访问此数据的查询时,在事务内连接到的后端将读取global.stat文件并缓存结果,使用它直到事务结束。
为了使该文件保持最新,统计收集器进程周期性地使用更新后的信息重新编写它。通常每秒执行几次。过程如下:
1.创建一个新文件global.tmp 2.向此文件写入数据
3.将global.tmp重命名为global.stat,覆盖以前的global.stat
"

全局变量global.tmpglobal.stats文件被写入由stats_temp_directory配置参数配置的目录中。通常情况下,这个参数被设置为$PGDATA/pg_stat_tmp

在关闭时,统计文件被写入到文件$PGDATA/global/pgstat.stat中,并且上面tmp目录中的文件被删除。当数据库再次启动时,该文件会被读取并删除。

为什么统计收集器处理器会创建如此多的I/O负载?

通常情况下,写入到global.stats的数据量相对较小,并且写入它不会产生太多的I/O流量。然而,在某些情况下,它似乎会变得非常臃肿。当发生这种情况时,生成的负载量可能会变得过多,因为整个文件每秒钟被重写一次以上。

我曾经有过一次经验,其中它增长了10倍或更多,与其他类似的服务器相比。这台机器确实有异常数量的数据库(至少对于我们的应用程序来说是这样-30-40个数据库-但没有像您所说的那样多达6000个)。拥有大量数据库可能会加剧这种情况。

"
以下一些参考资料讨论了创建/删除大量表格会导致文件膨胀的模式,可能是因为自动清理没有足够积极地清除相关的文件膨胀。您可能需要考虑您的自动清理设置。
为什么我在Windows上会收到“权限被拒绝”的错误?
在检查了postgresql源代码后,我认为存在访问global.stats文件的竞争条件,这种情况可能随时发生,但由于文件大小而加剧。
Windows的默认操作模式是,在另一个进程打开文件时,不允许重命名或删除该文件。这与Linux(或Unix)不同,在Linux(或Unix)中,当其他进程正在访问文件时,可以重命名或删除文件。
在上述序列中,如果其中一个后端进程正在读取文件,同时状态收集器正在重写它,则后端进程可能仍然在尝试重命名时保持文件处于打开状态。这导致了您看到的“权限被拒绝”错误。
当文件变得非常大时,读取文件所需的时间变得更加显著,因此,在后端仍然打开文件的情况下,状态收集器进程尝试重命名的概率增加。
然而,由于文件经常被重写,这些错误的影响相对较小。它只意味着此特定更新失败,导致后端得到略微过时的统计数据。下一个更新可能会成功。
请注意,Windows确实提供了一种文件打开模式,允许在另一个进程打开文件时删除或重命名文件,但据我所知,Postgresql没有使用这种模式。我找不到任何有关此问题的错误报告 - 似乎应该报告。
总之,这些错误是主要问题的副作用,即global.stat文件过大。
我已关闭track_activities,但文件仍在被写入 - 为什么?
据我所见,track_activities仅影响统计收集器正在收集的信息集之一。
此外,看起来统计收集器进程无论如何都会启动并继续重写文件。这些设置似乎仅控制新数据的收集。
我的结论是,一旦文件变得臃肿,即使关闭所有统计收集选项,它也将保持不变并继续被重写。

我该如何避免这个问题?

一旦文件变得臃肿,似乎将数据库恢复到良好的工作状态的最简单方法是使用以下步骤删除文件:

  1. 停止数据库

  2. 当数据库停止时,pg_stat_tmp目录为空,并写入一个名为$PGDATA/global/pgstat.stat的文件。我们将此文件重命名为pgstat.stat.old

  3. 启动数据库。它会创建一组新的pgstat文件。确认服务器正常运行后,可以删除您重命名的旧文件。

这是我们在其中一个服务器遇到此问题时使用的过程。

不用说,在手动操作Postgresql数据目录下的任何文件时要非常小心。

此后,您可能需要监视服务器,以查看文件是否再次变得臃肿。如果是,则可以考虑以下其他想法:

  • 如上所述,如果自动清理功能没有足够积极地运行,可能会导致该文件变得膨胀。您可能希望调整自动清理设置。

  • 禁用不需要的手册第18.9.1节中描述的任何track_xxx选项可能有所帮助。

  • 可以将pg_stats_tmp目录放置在tmpfs文件系统(或Windows中可用的任何等效RAM文件系统)中。这样做应该消除这些文件的I/O问题。

参考:


感谢您详细的回复。很遗憾目前还没有解决这个问题的方法。 - James
2
长话短说:转到Linux并感到快乐。 - Christian
Linux或许可以解决错误问题,但磁盘性能问题呢? - James
@James,你尝试过回答中描述的解决方法吗?我认为如果你重置那个文件(通过停止/删除文件/重新启动),那么磁盘I/O问题应该会减轻。 - harmic
即使停止服务器并手动清理文件可以解决此问题,但这个问题几天后会再次出现。看起来像是一个重大的性能错误。这是一个繁忙的服务器,并且非常受磁盘限制,也许我会尝试使用不同的数据库,除非Postgres有解决此问题的方法。 - James
显示剩余2条评论

2

这不是防病毒软件的问题,该计算机上没有安装防病毒软件。 - James

1
几天前我遇到了这个问题。我重新启动了机器,但错误没有消失。
不知道为什么,但执行vacuum analyze verbose就解决了问题,错误也停止出现了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接