PHP项目如何配置数据库慢查询日志?

wen PHP项目 68

本文目录导读:

PHP项目如何配置数据库慢查询日志?

  1. 核心概念
  2. 配置步骤
  3. 验证配置是否生效
  4. 慢查询日志分析工具
  5. PHP 项目中的辅助排查
  6. 注意事项

在 PHP 项目中配置数据库慢查询日志,主要涉及数据库层面(MySQL/MariaDB) 的配置,而不是 PHP 代码本身,PHP 通常通过 PDO 或 MySQLi 等扩展连接数据库,慢查询的检测和记录是由数据库服务器完成的。

以下是在 MySQL/MariaDB 中配置慢查询日志的详细步骤,以及在 PHP 项目中的一些辅助排查思路。


核心概念

  • 慢查询日志(Slow Query Log):记录执行时间超过指定阈值的 SQL 语句。
  • long_query_time:阈值,单位是秒,建议设置为 12(生产环境推荐 1 秒或更低)。
  • slow_query_log:是否开启日志,ONOFF
  • slow_query_log_file:日志文件路径。

配置步骤

方法 1:修改 MySQL 配置文件(持久化,推荐)

适用于 Linux 系统(/etc/my.cnf/etc/mysql/my.cnf/etc/mysql/mysql.conf.d/mysqld.cnf)或 Windows(my.ini)。

  1. 编辑配置文件(以 Linux 为例):

    sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
  2. [mysqld] 段落中添加或修改:

    [mysqld]
    # 开启慢查询日志
    slow_query_log = 1
    # 设置阈值(秒),2 秒
    long_query_time = 2
    # 日志文件路径(确保 MySQL 用户有写入权限)
    slow_query_log_file = /var/log/mysql/mysql-slow.log
    # 可选:记录未使用索引的查询(用于分析索引设计问题)
    log_queries_not_using_indexes = 1
    # 可选:记录管理语句(如 ALTER TABLE 等)
    log_slow_admin_statements = 1
  3. 保存文件并重启 MySQL 服务:

    sudo systemctl restart mysql   # 或:service mysql restart

方法 2:动态修改(无需重启,临时生效)

通过 MySQL 客户端直接设置,重启后会失效。

-- 开启慢查询日志
SET GLOBAL slow_query_log = 'ON';
-- 设置阈值(秒)
SET GLOBAL long_query_time = 2;   -- 对于已连接会话,需要重新连接才生效
-- 查看当前配置
SHOW VARIABLES LIKE 'slow_query_log%';
SHOW VARIABLES LIKE 'long_query_time%';

验证配置是否生效

  1. 检查变量

    SHOW VARIABLES LIKE 'slow_query%';
    SHOW VARIABLES LIKE 'long_query_time';
  2. 手动触发一个慢查询SELECT SLEEP(3)):

    SELECT SLEEP(3);  -- 3 秒,大于阈值 2 秒
  3. 查看日志文件

    sudo tail -f /var/log/mysql/mysql-slow.log

    应该能看到类似以下记录:

    Time: 2024-05-27T10:30:00.123456Z
    User@Host: root[root] @ localhost []
    Query_time: 3.000512  Lock_time: 0.000000 Rows_sent: 1  Rows_examined: 0
    SET timestamp=1716815400;
    SELECT SLEEP(3);

慢查询日志分析工具

配置好日志后,需要定期分析,而不是只查看原始文件。

mysqldumpslow(MySQL 自带)

# 统计总耗时排序前10的慢查询
sudo mysqldumpslow -s t -t 10 /var/log/mysql/mysql-slow.log
# 统计平均耗时排序
sudo mysqldumpslow -s at -t 10 /var/log/mysql/mysql-slow.log

pt-query-digest(Percona Toolkit,强烈推荐)

这是一个强大的开源工具,能分析查询模式、频率和总体影响。

# 安装
sudo apt install percona-toolkit
# 分析慢查询日志
sudo pt-query-digest /var/log/mysql/mysql-slow.log

PHP 项目中的辅助排查

虽然慢查询主要靠数据库自身记录,但 PHP 侧可以配合以下方法定位问题:

日志记录绑定参数

PHP 使用 PDO 预编译语句(Prepared Statement),慢查询日志中可能只显示 INSERT INTO ... VALUES (?, ?, ?) 而非实际值,不利于排查具体参数。

解决方法:开启 PHP 的 General Query Log(谨慎,仅用于开发或低负载环境)。

// 在 PHP 配置中(或在运行时动态设置)
ini_set('mysql.trace_mode', 1);  // 仅用于 MySQL 扩展
// 或使用 PDO 的 setAttribute 设置模拟模式
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);

更好的做法:在 PHP 业务代码中自行记录慢操作。

在 PHP 中主动记录超时查询

封装数据库查询方法,检测耗时。

<?php
function queryWithTimeLog($sql, $params = []) {
    $start = microtime(true);
    $stmt = $pdo->prepare($sql);
    $stmt->execute($params);
    $time = (microtime(true) - $start);
    if ($time > 1.0) { // 阈值 1 秒
        error_log("Slow query ({$time}s): {$sql} | Params: " . json_encode($params), 3, '/tmp/php-slow.log');
    }
    return $stmt;
}

注意事项

  1. 日志文件权限:确保 MySQL 运行用户(通常是 mysql)对日志目录有写入权限。
  2. 磁盘 I/O 影响:慢查询日志会写入磁盘,高并发环境下可能增加 I/O 压力,生产环境中不建议log_queries_not_using_indexes 始终开启,因为即使很短的查询也会被记录,导致日志迅速膨胀,建议仅在排查阶段临时开启。
  3. 不要记录所有查询:不要开启 general_log(通用查询日志),除非是调试目的,因为它会记录所有 SQL,性能影响非常大。
  4. 定期清理:设置日志轮转(logrotate)或手动清理,避免占用过多磁盘空间。
# 日志轮转配置(位于 /etc/logrotate.d/)
/var/log/mysql/mysql-slow.log {
    daily
    rotate 7
    missingok
    compress
    delaycompress
    notifempty
    create 640 mysql adm
}

  • 核心:在数据库端配置 slow_query_loglong_query_time
  • 工具:用 pt-query-digestmysqldumpslow 分析日志。
  • PHP 端:结合自身代码记录耗时长的查询参数,辅助定位。

生产环境推荐配置示例

slow_query_log = 1
long_query_time = 2
slow_query_log_file = /var/log/mysql/slow.log
log_slow_admin_statements = 1
# log_queries_not_using_indexes = 0   # 默认关闭,避免日志过多

这样配置后,超过 2 秒的查询会自动记录到 /var/log/mysql/slow.log,你再配合分析工具定期查看即可。

抱歉,评论功能暂时关闭!