针对应用程序开发人员的PostgreSQL监控

2020-10-15 05:43:50

我是一个偶然的DBA,非常强调偶然。";我作为一名应用程序开发人员来到PostgreSQL,他非常喜欢用SQL编程,并使用数据库帮助解决我的问题。尽管如此,这些系统还是要投入生产,因此我必须学会支持它们。

PostgreSQL监控和性能优化是一个庞大的主题。事实上,我会阅读我的同事Greg Smith在Ubuntu上对PostgreSQL13进行基准测试时所写的内容,并提醒我还有很多东西需要学习!关于这个主题的几篇博客文章不可能公正地说明这一点,但我想试着分享一下我在应用程序开发人员进入运营角色时收集到的一些见解。

在上一篇文章中,我谈到了如何仅通过查看重要的统计数据(CPU、内存、磁盘和网络利用率)就可以从监视Postgres系统中学到很多东西。作为起点,这些关于资源利用率的统计数据很有帮助:它们可以指出系统的哪个部分有问题,但可能并不完全是问题所在。

这些统计信息提供了PostgreSQL数据库活动的总体情况,可以帮助您发现性能和可用性方面的问题,并且可以在坏事开始发生之前提供早期警告。

那么,这些指标告诉您什么,您如何使用它们来成功管理您的PostgreSQL数据库呢?

对于这些示例,我们使用由pgMonitor提供支持的监视堆栈,该堆栈可以与postgres操作符一起安装。

PostgreSQL的一个必需配置参数是max_connections:任何超过此数字的连接都将导致客户端连接失败。这是您需要监视数据库连接数量的第一个基本原因:过多的连接可能会导致应用程序中出现停机事件。

连接过多还会影响PostgreSQL数据库的整体性能。这在Postgres中是一个经过充分研究的问题,事实上,PostgreSQL14将在这一领域获得巨大的性能提升。

查看到数据库的连接总数可以帮助您优化应用程序的系统体系结构,并确定正确的设置来最大化吞吐量,同时限制开销。

关于连接故事还有更多的内容,这个故事涉及事务中空闲的连接。";事务中空闲的连接是指事务正在进行中(例如,在某个时刻有一个开始),但尚未提交(提交)或回滚(回滚)。如果事务中有太多空闲的连接,最终可能会导致系统的整体性能问题和潜在的维护问题。

在事务中处于空闲状态的连接可能会阻止对系统进行适当的清理,这可能会导致可怕的事务ID回绕问题。如果您看到事务中的延迟连接处于空闲状态,您应该调查原因并尽力消除它们。

事务处理速率,无论是以每秒事务处理量(TPS)还是以每分钟事务处理量(TPM)衡量,都会衡量系统的总体吞吐量。通常,此指标本身并不能告诉您太多信息:交易率可能会根据一天中的时间、一周中的某一天等而有所不同。您可以使用交易率来帮助确定是否存在负载高峰,或者将其与另一个指标(如网络吞吐量)结合起来,以确定您的性能是否受到影响。

事务率可以让您对数据库系统的整体性能有一个整体的感觉,但是需要与另一个指标结合使用,或者通过使用随时间变化的比较来实现。

行活动可以指示您正在管理的工作负载的类型,是读取繁重(SELECT)、写入繁重(INSERT/UPDATE/DELETE),还是两者之间的平衡。了解哪种类型的工作负载,并结合其他指标,您可以调整数据库以最大限度地提高应用程序的性能。

例如,了解您的工作负载类型可以帮助您调整检查点的发生时间。在检查点期间,所有脏数据(自上一个检查点以来修改过的数据)都会写入磁盘,这是一项代价高昂的操作。了解您的工作负载类型,再加上您的事务率,可以帮助您选择适当的检查点设置。

这很简单:如果PostgreSQL不能写入磁盘,您将停机。跟踪磁盘大小很重要,但了解哪些项目正在占用磁盘也很有帮助。

密切关注您的总体数据库大小是有好处的,因为这将指示您的总体数据增长率,以及何时您可能需要采取其他步骤,例如调整磁盘大小或将数据库移动到另一个实例。

此外,跟踪预写日志(WAL)在磁盘上的占用量也很好。如果您使用复制插槽,则表明复制插槽未得到确认或落后的迹象是整体WAL日志保留增加。如果由于WAL日志过多导致磁盘空间不足,您的PostgreSQL实例将会宕机。

跟踪整个系统以及PostgreSQL系统的每个单独组件的磁盘使用量同样重要。

我希望在我职业生涯的早期更多地了解缓存命中率,因为这是能够正确调整PostgreSQL实例大小和调优的一个很好的指标。缓存命中率是对您的工作数据集有多少驻留在内存中的度量。如果您请求不在内存中的数据,PostgreSQL将不得不去从磁盘获取数据,这是一项成本高得多的操作。那么,您的目标是尝试使缓存命中率尽可能接近100%。

那么,您的工作数据集是什么?简单地说,您的工作数据集就是您的应用程序在给定时间段内访问的数据。例如,假设我有一个简单的日程安排应用程序,它只查看今天或将来的约会。因此,我的工作数据集的最大大小将是从现在到将来的所有计划项目。我的实际工作数据集可能更小:应用程序更有可能访问离今天更近的约会,而不是更远的约会,所以我们可以将窗口缩小到这一范围。

您如何帮助提高缓存命中率?最简单的答案是增加内存,再结合调优PostgreSQL SHARED_BUFFERS设置。但是,更长远的答案是它很复杂,需要了解您的数据工作负载,以便结合PostgreSQL配置来优化您的物理资源(尽管Shared_Buffers在这方面扮演着重要角色)。在这方面,您需要了解您的数据工作负载,以便优化您的物理资源和PostgreSQL配置(尽管Shared_Buffers在其中扮演着重要的角色)。此外,重新启动后,PostgreSQL将需要一些时间将工作数据集拉入内存,不过您可以使用pg_preware来抵消部分负担。

监控缓存命中率可以帮助您从根本上调整PostgreSQL数据库,了解您需要哪些硬件资源,并帮助您更好地了解您自己的应用程序的访问模式。

通常,当我必须查看锁时,这是因为我的应用程序日志会突然充满两种类型的PostgreSQL错误中的一种:";无法获取锁";或";死锁。";然后我会去调查PG_LOCKS表,并尝试查找任何似乎异常的行为。

锁定是PostgreSQL的自然组成部分,因为它是多版本并发控制(MVCC)的基本部分之一,因此拥有锁是非常正常的。密钥位是上面的:确保您可以避免由于锁定而导致的错误。我会遇到的最常见的锁定错误是";无法获取锁定,通常是因为我的系统在这一点上已经过饱和。我通常会因为错误的代码而触发死锁(我承认:我确实编写了一些非常复杂的链式触发器,这通常会起作用)。

锁定问题可能很难诊断,更不用说修复了,因为它们通常涉及同时尝试执行类似操作的多个会话。重要的是要密切关注系统的整体锁定行为,以防止锁争用导致应用程序出错。

PostgreSQL9.0的发布及其对流复制的支持让我兴奋不已!在将其部署到临时环境后,我无意中给自己上了一堂关于复制延迟(以及Wal回收)的课。

简而言之,复制延迟是复制副本或数据库副本更新到主副本所需的时间。通常,您希望此值较小:如果存在导致主服务器不可用的情况,则希望切换到数据丢失尽可能少的副本服务器。

(如果您对数据丢失很敏感,可以考虑同步复制,不过这也需要权衡)。

副本服务器可能远远落后于主服务器的原因有很多:网络饱和、副本服务器上的计算能力、副本服务器已离开且未重新连接等。拥有健康的Postgres群集的一部分是确保您的副本服务器不会远远落后于主服务器!

如果我不对备份说一句话,那我就是玩忽职守了。在我所做的几乎每一次演示中,我都试图插入一句话,说明使用pgBackRest这样的备份管理工具定期备份数据库的重要性。如果您的系统在您订阅的期限内未成功完成备份,您绝对应该修复该问题。备份不仅在发生灾难时至关重要,还可用于帮助高效地引导其他群集。

您可以使用许多不同的监控指标来帮助确保您的PostgreSQL系统保持健康。对我来说,我倾向于从查看系统的CPU、内存、磁盘和网络利用率开始,以便在开始进一步故障排除之前提供一个起点。随着我参加了更多的Postgres活动,并了解到更多关于在系统和数据库管理方面比我经验丰富的人如何描述他们所寻找的内容的信息,我扩展了我的工具包,以跟踪和分析我在上面讨论的许多指标。

如果您正在Kubernetes上运行PostgreSQL,或者甚至正在考虑这样做,我鼓励您在您的环境中设置Postgres监控,试一试,看看您可以在故障排除中开发哪些模式!