在 PostgreSQL 中,慢查询日志是一项功能,允许您记录执行时间超过指定阈值的查询。此日志可帮助您识别和优化可能导致数据库性能问题的查询。让我们看看如何使用它。
为什么我们需要可观测性?
数据库可观测性是数据库维护和开发的关键组成部分。它有助于识别和解决问题。不过,可观测性不仅仅是监控。但是,为了构建成功的可观测性,我们需要在生产环境中的任何地方引入适当的遥测和监视。
我们开始的一件事是记录查询。我们希望捕获 SQL 语句的详细信息、有关执行时间和消耗内存的指标,以及我们使用的表的统计信息。遗憾的是,数据库系统中的许多默认设置会导致缺少对调试至关重要的信息。其中一部分是查询的详细信息,这些查询速度很慢,是问题的最可能原因。
什么是慢查询日志?
数据库在白天执行许多查询。其中一些速度非常快,而另一些可能会减慢数据库速度并导致使用数据库的其他进程出现问题。理想情况下,我们希望识别这些缓慢的查询并对其进行更多检查,以了解它们缓慢的原因。查询速度慢的原因有很多,优化查询的技术也有很多。这些技术中的大多数都侧重于使用执行计划来了解发生了什么。
执行计划说明数据库引擎在执行查询时执行的操作。这可能涉及许多操作,例如联接多个表、使用索引、对数据进行排序或将其临时保存到磁盘。这样的计划提供了所有细节,但是,这些计划可能会占用大量空间。因此,我们不会为每个查询存储它们,因为可能大多数查询都很快,不需要任何调查。
慢速查询日志是一种机制,用于捕获执行时间过长的查询的详细信息。这有助于调查,因为我们在查询运行时捕获详细信息。慢速查询日志可用于识别性能瓶颈和优化慢速查询,以提高 PostgreSQL 数据库的整体性能。
如何配置慢查询日志
要在 PostgreSQL 中启用慢查询日志,我们需要设置几个参数。让我们一一看看。
首先,您需要使用以下命令启用日志记录:
log_statement = 'all'
这将指示 PostgreSQL 记录所有语法正确的语句。其他选项包括(不记录任何内容)、(仅记录数据定义语言查询,即修改架构的查询)、(DDL 查询和修改数据的查询,但不记录类似内容)。noneddlmodVACUUM
还值得一提的是,它不会记录语法不正确的东西。我们需要用它来做到这一点。此外,可能会记录机密信息。log_statementlog_min_error_statementlog_statement
另一个参数记录所有已完成语句的持续时间:
log_duration = on
这将记录所有语句的持续时间。但是,并非所有语句都具有查询文本(因此是实际执行的语句)。为此,我们需要使用另一个参数:
log_min_duration_statement = 100ms
如果语句运行至少 100 毫秒,这将导致记录语句的持续时间。但是,这将报告语句的查询文本速度较慢。
进行这些更改后,您需要重新启动 PostgreSQL 才能使配置生效。
您可以配置其他参数。例如:
log_destination = 'csvlog'
这会导致日志记录到 CSV 文件。您可能需要使用不同的文件格式进行记录。
log_filename = 'postgresql.log.%Y-%m-%d-%H'
这将配置日志文件的名称。这样可以更轻松地以自动方式处理日志。
log_rotation_age = 60
这会导致每 60 分钟创建一个新的日志文件。
compute_query_id = 'on'
这样就可以对查询标识符进行核心计算。我们可以使用此标识符以尽最大努力查找相同的查询。这从 PostgreSQL 13 开始工作。
一旦我们记录了查询,我们就需要获取它们的执行计划。我们可以为此使用 pg_store_plans。
pg_store_plans.plan_format = 'json'
这控制在记录执行计划时要使用的格式。
pg_store_plans.max_plan_length = 1048576
这将控制要存储的计划的长度。如果计划太长,它将被截断。请务必将此值设置得足够高以存储整个执行计划。
我们还可以精确配置记录的内容:
pg_store_plans.log_buffers = true pg_store_plans.log_analyze = true pg_store_plans.log_buffers = true pg_store_plans.log_timing = true
为您提供所发生事件的足够详细信息。
临时数据库呢?
如果您的数据库存在很长时间,则配置 PostgreSQL 很简单。当您将数据库托管在云中(或通常作为托管数据库)时,或者在作为服务运行的 Docker 容器中运行数据库时,通常会出现这种情况。
但是,如果您只在很短的时间内运行 PostgreSQL,例如在自动化测试期间,那么您可能没有技术方法来重新配置它。Testcontainers 可能就是这种情况。通常,您可以在实际测试套件之前运行一些初始化代码,以初始化依赖项,例如存储模拟器或数据库服务器。Testcontainers 负责将它们作为 Docker 容器运行。但是,没有重新启动容器的直接方法。不过,在某些语言中,您可能有一个实际的 API 可以很好地处理这个问题。
临时数据库策略允许将高吞吐量、频繁更改的数据与主数据库分离,以提高效率并降低运营风险。这种方法解决了查询成本和系统压力等问题,临时数据库保存了一次性数据,从而确保了系统的稳定性和性能。
如果您在 GitHub Actions 中将 PostgreSQL 作为服务托管测试,则可能会出现类似的问题。您无法轻松控制容器并在应用配置更改后重新启动它们。
解决方案是使用自定义 Docker 映像。只需使用启用慢速查询日志的配置文件准备映像即可。然后,只需运行一次容器,配置将按预期进行。
慢速查询日志是一项功能,可用于记录执行时间超过指定阈值的查询。这可以大大简化对慢速查询的调查,因为查询的所有重要详细信息都已经可用。