14.7.4 日志管理与审计分析

ProxySQL 的日志与审计由三条线构成:运行日志(进程与配置变更)、查询事件日志(SQL 事件采样)、统计/审计表(连接与错误、SQL 摘要)。运维管理需要明确日志落盘路径、日志级别、查询日志开关与采样策略,并配合 logrotate 与集中检索平台实现长周期留存与快速检索。

文章图片

日志路径与级别建议在配置文件统一规划,且运行时加载与持久化分离,修改后需要 LOAD/SAVE。示例以 /etc/proxysql.cnf 为准,包含运行日志、查询事件日志与采样策略:

# /etc/proxysql.cnf
datadir="/var/lib/proxysql"

admin_variables=
{
  admin_credentials="admin:admin"
  # 运行日志
  admin-log_filename="/var/log/proxysql/proxysql.log"
}

mysql_variables=
{
  # 查询事件日志
  mysql-eventslog_filename="/var/log/proxysql/mysql-events.log"
  mysql-eventslog_default_log=1
  mysql-eventslog_format=2   # 1=TEXT,2=JSON
  mysql-eventslog_size_limit=104857600  # 单文件上限 100MB
  # 采样:仅记录执行时间>100ms
  mysql-eventslog_sampling=1
  mysql-eventslog_sampling_random=0
  mysql-eventslog_sampling_interval=100
  mysql-eventslog_sampling_query_duration=100
}

加载并持久化配置(命令解释:LOAD 将配置加载到运行时,SAVE 将运行时写回磁盘,避免重启丢失):

-- 连接管理端口
mysql -uadmin -padmin -h127.0.0.1 -P6032

-- 加载到运行时并持久化
LOAD ADMIN VARIABLES TO RUNTIME;
LOAD MYSQL VARIABLES TO RUNTIME;
SAVE ADMIN VARIABLES TO DISK;
SAVE MYSQL VARIABLES TO DISK;

日志轮转示例(解释:按日切割、保留14天、压缩、延迟压缩减少 IO、并发送 USR1 触发重开文件):

# /etc/logrotate.d/proxysql
/var/log/proxysql/*.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    create 0640 proxysql proxysql
    postrotate
        /bin/kill -USR1 $(cat /var/lib/proxysql/proxysql.pid 2>/dev/null) 2>/dev/null || true
    endscript
}

审计分析建议以 stats_* 表为主,聚焦连接来源、错误码、SQL 摘要与路由命中。示例 SQL(解释:第一条看 Top SQL,第二条看错误码分布,第三条定位客户端来源):

-- Top SQL 摘要:按执行时间累计排序
SELECT digest_text, count_star, sum_time/1000000 AS sum_ms
FROM stats_mysql_query_digest
ORDER BY sum_time DESC
LIMIT 5;

-- 错误码分布:定位高频错误
SELECT mysql_errno, count_star
FROM stats_mysql_errors
GROUP BY mysql_errno
ORDER BY count_star DESC;

-- 连接来源:按客户端 IP 统计
SELECT client_address, count_star
FROM stats_mysql_errors
GROUP BY client_address
ORDER BY count_star DESC;

集中化日志可使用 Filebeat/Fluentd 收集。以下为 Filebeat 采集示例(解释:采集运行日志与事件日志,并打上 service 标签):

# /etc/filebeat/filebeat.yml
filebeat.inputs:
  - type: filestream
    id: proxysql-log
    paths:
      - /var/log/proxysql/proxysql.log
      - /var/log/proxysql/mysql-events.log
    fields:
      service: proxysql
    fields_under_root: true

output.elasticsearch:
  hosts: ["http://elk01:9200"]
  index: "proxysql-%{+yyyy.MM.dd}"

常见排错与定位步骤(含命令与解释):
1) 查询日志无输出:检查开关与运行时加载

SELECT variable_name, variable_value
FROM runtime_mysql_variables
WHERE variable_name LIKE 'mysql-eventslog%';

若 mysql-eventslog_default_log=0 或未 LOAD,则设置后执行 LOAD MYSQL VARIABLES TO RUNTIME。

2) 文件权限问题:ProxySQL 无法写日志

ls -l /var/log/proxysql/
sudo chown -R proxysql:proxysql /var/log/proxysql
sudo chmod 750 /var/log/proxysql

3) 日志暴增导致磁盘满:调整采样与阈值

UPDATE mysql_variables
SET variable_value='300'
WHERE variable_name='mysql-eventslog_sampling_query_duration';
LOAD MYSQL VARIABLES TO RUNTIME;
SAVE MYSQL VARIABLES TO DISK;

4) 审计表无数据:确认是否启用统计与查询是否清空

SELECT * FROM stats_mysql_global WHERE variable_name LIKE 'Query%';

运维练习(要求完成并输出结果):
1) 启用 JSON 格式查询事件日志并只记录 >200ms 的 SQL,验证文件中出现 JSON 结构。
2) 查询 stats_mysql_query_digest,输出累计耗时最高的 3 条 SQL 并分析原因。
3) 配置 logrotate 为保留 7 天并压缩,手工执行 logrotate -f /etc/logrotate.d/proxysql 验证日志切割与新文件权限。