查找消耗资源的查询

来自 PostgreSQL Wiki
跳转到导航跳转到搜索

定位 Apache 进程正在执行的查询。

最近我正在为一位客户解决一系列性能问题。我尽力调整配置,但不幸的是,即使机器和配置再好,编写错误的查询也会导致糟糕的性能...

最大的问题是,这是一个由多个供应商组件拼凑而成的 Frankenstein 式 Web 应用程序(就像弗兰肯斯坦的怪物),最糟糕的是,查询是动态生成的,这使得维护工作变得很头疼... 想象一下,在这种环境中,你要找出哪个页面正在执行哪个查询(如果有任何简单的解决方案,请告诉我)。

到目前为止,我所做到的只是确定某个特定 Apache 进程执行的语句,通过这些语句,我能够追踪到服务器在某些时刻挂起的原因(准确地确定哪个页面发送了查询是另一个故事)。

希望这些内容对你们也有帮助。

准备 PostgreSQL 日志以监控 Apache 进程。

首先,我们需要修改 postgresql.conf 文件中的几个参数。

log_line_prefix = '%r'

我们可以保留参数以前的值,只需要添加 %r。这将记录客户端机器的 IP 地址和端口。

log_statement = alllog_min_duration_statement = 合理的值

为了避免日志被不必要的信息填满,如果使用 log_statement,可以使用 'mod',如果使用 log_min_duration_statement,可以使用一个合理的值。

选择我们要监控的 Apache 进程。

要选择我们要监控的 Apache 进程,可以使用以下命令(在应用程序服务器上)

ps aux | grep httpd | awk '{print $2, $6}' | sort -­n -­k 2

此命令将显示一个按顺序排列的 Apache 进程列表,其中第一列是进程的 PID,第二列是进程消耗的内存量(列表按此列从小到大排序)。

我们将选择一个持续占用大量内存的进程。

将 Apache 进程与数据库连接绑定。

选择一个进程后,执行以下命令(仍在应用程序服务器上)

lsof -­i TCP@$ip_servidor_bbdd | grep $pid_escogido | awk '{print $8}'

这将生成类似于以下内容的输出(ip_cliente:puerto_cliente­->ip_servidor_bdd:puerto_sevidor_bdd)

webserver.servidorweb.com:55774­>postgresql.servidorpgsql.com:postgres

使用这些数据,我们可以在 PostgreSQL 日志中查找从该客户端 IP 和端口执行的 SQL 语句。

grep $ip_cliente $archivo_log | grep $puerto_cliente

注意:在日志文件中搜索时,应该使用客户端机器的 IP 地址,而不是网络中的名称。