在我的初步回答后,我决定研究统计收集器的操作,特别是它对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.tmp
和global.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
仅影响统计收集器正在收集的信息集之一。
此外,看起来统计收集器进程无论如何都会启动并继续重写文件。这些设置似乎仅控制新数据的收集。
我的结论是,一旦文件变得臃肿,即使关闭所有统计收集选项,它也将保持不变并继续被重写。
我该如何避免这个问题?
一旦文件变得臃肿,似乎将数据库恢复到良好的工作状态的最简单方法是使用以下步骤删除文件:
停止数据库
当数据库停止时,pg_stat_tmp目录为空,并写入一个名为$PGDATA/global/pgstat.stat
的文件。我们将此文件重命名为pgstat.stat.old
。
启动数据库。它会创建一组新的pgstat文件。确认服务器正常运行后,可以删除您重命名的旧文件。
这是我们在其中一个服务器遇到此问题时使用的过程。
不用说,在手动操作Postgresql数据目录下的任何文件时要非常小心。
此后,您可能需要监视服务器,以查看文件是否再次变得臃肿。如果是,则可以考虑以下其他想法:
如上所述,如果自动清理功能没有足够积极地运行,可能会导致该文件变得膨胀。您可能希望调整自动清理设置。
禁用不需要的手册第18.9.1节中描述的任何track_xxx
选项可能有所帮助。
可以将pg_stats_tmp
目录放置在tmpfs文件系统(或Windows中可用的任何等效RAM文件系统)中。这样做应该消除这些文件的I/O问题。
参考:
pg_stat_tmp/
目录的权限,以便 postgres 可以写入该目录。(在 Unix 中,重命名只需要对目录的权限;不清楚 Windows 是否也是如此) - wildplasser