# slow_log_rotation **Repository Path**: dbother/slow_log_rotation ## Basic Information - **Project Name**: slow_log_rotation - **Description**: 针对 MySQL TABLE模式的日志轮转 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-03-10 - **Last Updated**: 2026-03-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # MySQL 慢日志轮转代理 (MySQL Slow Log Rotation Agent) 一个用于自动管理 MySQL 慢日志轮转的代理程序,支持多实例管理和灵活的轮转策略。 ## 📋 目录 - [功能特性](#功能特性) - [适用场景](#适用场景) - [系统架构](#系统架构) - [工作流程](#工作流程) - [前置要求](#前置要求) - [快速开始](#快速开始) - [部署方式](#部署方式) - [配置说明](#配置说明) - [轮转逻辑详解](#轮转逻辑详解) - [常见问题](#常见问题) - [性能影响](#性能影响) ## 功能特性 - ✅ **支持多 MySQL 实例管理** - 同时管理多个 MySQL 实例的慢日志轮转 - ✅ **灵活的轮转策略** - 可配置的轮转周期(按天) - ✅ **自动化轮转流程** - 无需人工干预,自动执行轮转 - ✅ **安全的密码管理** - 支持密码加密存储(AES-256-GCM) - ✅ **健壮的错误处理** - 完善的错误恢复机制,失败自动重试 - ✅ **详细的操作日志** - 完整记录所有操作,便于问题排查 - ✅ **启动时权限验证** - 自动检查 MySQL 用户权限 - ✅ **多种部署方式** - 支持 systemd 和 Docker 部署 - ✅ **配置热更新** - 修改配置后重启即可生效 ## 适用场景 ### ✅ 适合使用的情况 - MySQL 慢日志写入到 `mysql.slow_log` 表 - 需要定期清理慢日志数据,避免表过大影响查询性能 - 需要保留历史慢日志数据用于分析 - 有多个 MySQL 实例需要统一管理 - 希望自动化运维,减少人工干预 ### ❌ 不适合使用的情况 - MySQL 慢日志只写入文件(不写入表) - 需要按表大小或行数轮转(本工具只支持按时间) - 需要保留 slow_log 表中的所有数据(本工具会轮转替换) - 需要实时的慢日志分析(轮转期间可能有短暂中断) ## 系统架构 ### 组件说明 ``` ┌─────────────────────────────────────────────────────────┐ │ slow_log_rotation │ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ Config │ │ Rotation │ │ Encryption │ │ │ │ Manager │ │ Manager │ │ Module │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │ │ │ │ │ └─────────┼──────────────────┼──────────────────┼──────────┘ │ │ │ ▼ ▼ ▼ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ config │ │ MySQL │ │ Encrypted│ │ .yaml │ │ Instances│ │ Passwords│ └──────────┘ └──────────┘ └──────────┘ ``` **核心模块:** - **Config Manager** - 配置文件加载、解析、加密/解密 - **Rotation Manager** - 轮转任务调度、执行、监控 - **Encryption Module** - 密码加密/解密(AES-256-GCM) ## 工作流程 ### 整体流程 ``` ┌─────────────┐ │ 程序启动 │ └──────┬──────┘ │ ▼ ┌─────────────────────┐ │ 加载配置文件 │ │ - 解密密码 │ │ - 验证配置格式 │ └──────┬──────────────┘ │ ▼ ┌─────────────────────┐ │ 验证 MySQL 连接 │ │ - 检查连接 │ │ - 验证权限 │ │ - 检查 log_output │ └──────┬──────────────┘ │ ▼ ┌─────────────────────────────┐ │ 为每个实例启动独立调度器 │ │ - 等待到 check_time │ │ - 检查是否需要轮转 │ │ - 执行轮转操作 │ │ - 更新 last_rotation 时间 │ └─────────────────────────────┘ ``` ### 轮转流程 ``` ┌─────────────────┐ │ 等待到 check_time│ └────────┬────────┘ │ ▼ ┌────────────────────┐ │ 判断是否需要轮转 │ │ - last_rotation │ │ - rotation_days │ └────────┬───────────┘ │ ┌────┴────┐ │ │ 否 是 │ │ │ ▼ │ ┌──────────────┐ │ │ 删除旧表 │ │ │ slow_log_old │ │ └──────┬───────┘ │ │ │ ▼ │ ┌──────────────┐ │ │ 创建新表 │ │ │ slow_log_new │ │ └──────┬───────┘ │ │ │ ▼ │ ┌──────────────┐ │ │ 重命名表 │ │ │ slow_log │ │ │ → _old │ │ │ slow_log_new│ │ │ → slow_log│ │ └──────┬───────┘ │ │ │ ▼ │ ┌──────────────┐ │ │ 更新配置 │ │ │ last_rotation│ │ └──────┬───────┘ │ │ └─────────┴──────────────┐ │ ▼ ┌────────────────┐ │ 等待下一次检查 │ │ (24小时后) │ └────────────────┘ ``` ## 前置要求 ### MySQL 配置要求 **必须将慢日志写入到表中:** ```sql -- 检查当前配置 mysql> SHOW VARIABLES LIKE 'log_output'; +---------------+------------+ | Variable_name | Value | +---------------+------------+ | log_output | FILE,TABLE | -- ✅ 正确 | log_output | TABLE | -- ✅ 正确 | log_output | FILE | -- ❌ 不支持 +---------------+------------+ -- 临时设置(重启失效) SET GLOBAL log_output = 'TABLE'; -- 或 SET GLOBAL log_output = 'FILE,TABLE'; -- 永久设置(修改 my.cnf) [mysqld] log_output = TABLE ``` ### 权限要求 #### MySQL 用户权限 程序需要连接到 MySQL 并执行慢日志轮转操作。以下是所需的最小权限: **创建专用用户:** ```sql -- 创建慢日志轮转专用用户 CREATE USER 'slow_log_rotation'@'%' IDENTIFIED BY 'your_strong_password'; ``` **最小化权限:** ```sql GRANT INSERT, CREATE, DROP, ALTER ON `mysql`.`slow_log_new` TO `slow_log_rotation`@`%`; GRANT INSERT, CREATE, DROP, ALTER ON `mysql`.`slow_log_old` TO `slow_log_rotation`@`%`; GRANT SELECT, INSERT, CREATE, DROP, ALTER ON `mysql`.`slow_log` TO `slow_log_rotation`@`%`; 或者给大一点的权限 GRANT SELECT,INSERT, CREATE, DROP, ALTER ON `mysql`.* TO `slow_log_rotation`@`%`; 或 GRANT ALL ON `mysql`.* TO `slow_log_rotation`@`%`; ``` #### 系统权限 **程序运行时需要:** - ✅ 配置文件读写权限:`/usr/local/slow_log_rotation/config/config.yaml` - ✅ 网络连接权限:连接 MySQL 服务器(默认 3306 端口) - ✅ 日志写入权限:systemd journal 或日志文件 **配置文件权限(推荐):** ```bash # 配置文件包含敏感信息,应设置为仅所有者可读写 sudo chmod 600 /usr/local/slow_log_rotation/config/config.yaml sudo chown root:root /usr/local/slow_log_rotation/config/config.yaml ``` #### systemd 服务权限 服务文件中已配置以下安全限制: ```ini NoNewPrivileges=true # 禁止获取新权限 PrivateTmp=true # 使用私有 /tmp 目录 User=root # 以 root 用户运行(可改为专用用户) ``` ### 系统要求 - **操作系统**: Linux (推荐) / macOS / Unix-like - **内存**: 最小 10MB,推荐 50MB - **磁盘**: 至少 100MB 可用空间 - **网络**: 能够访问 MySQL 服务器 ## 快速开始 ### 5 分钟快速部署 ```bash # 1. 打包部署文件(在开发机器上) make package-deploy-all # 2. 上传到服务器 scp release/slow_log_rotation-linux-amd64-deploy.tar.gz user@server:/tmp/ # 3. 解压并配置 ssh user@server cd /tmp tar xzf slow_log_rotation-linux-amd64-deploy.tar.gz cd slow_log_rotation-linux-amd64-deploy # 4. 编辑配置文件 vi config.yaml # 5. 安装并启动 sudo ./install.sh ``` ### 最小配置示例 ```yaml check_time: "03:00" # 每天凌晨 3 点检查 instances: - host: "localhost" port: 3306 username: "slow_log_rotation" password: "your_password" rotation_days: 7 # 每 7 天轮转一次 encrypted: true # 密码加密存储 ``` --- ## 部署方式 本程序提供三种部署方式: - **方式一:systemd 部署**(推荐生产环境)⭐ - **方式二:Docker 部署**(容器化环境) - **方式三:手动安装**(开发/测试环境) --- ## 方式一:systemd 部署(推荐) 使用 systemd 服务管理,适合生产环境直接部署。 ### 部署步骤 #### 1. 打包部署文件 在开发机器上执行: ```bash # 打包 Linux AMD64 部署包(最常用) make package-deploy # 或打包所有平台 make package-deploy-all ``` 生成的部署包位于 `release/` 目录: ``` release/slow_log_rotation-linux-amd64-deploy.tar.gz # Linux AMD64 release/slow_log_rotation-linux-arm64-deploy.tar.gz # Linux ARM64(树莓派等) ``` #### 2. 上传到服务器 ```bash scp release/slow_log_rotation-linux-amd64-deploy.tar.gz user@server:/tmp/ ``` #### 3. 解压并安装 在目标服务器上执行: ```bash # 解压 cd /tmp tar xzf slow_log_rotation-linux-amd64-deploy.tar.gz cd slow_log_rotation-linux-amd64-deploy # 编辑配置文件 vi config.yaml # 执行安装脚本(一键安装) sudo ./install.sh ``` **安装脚本会自动完成:** - ✅ 将程序安装到 `/usr/local/slow_log_rotation/` - ✅ 安装并启用 systemd 服务 - ✅ 配置开机自启动 - ✅ 启动服务 ### 服务管理 ```bash # 启动服务 sudo systemctl start slow_log_rotation # 停止服务 sudo systemctl stop slow_log_rotation # 重启服务 sudo systemctl restart slow_log_rotation # 查看服务状态 sudo systemctl status slow_log_rotation # 查看日志(推荐使用 cat 格式,避免重复时间戳) sudo journalctl -u slow_log_rotation -f -o cat # 查看日志(ISO 格式) sudo journalctl -u slow_log_rotation -f -o short-iso ``` ### 配置管理 ```bash # 编辑配置 sudo vi /usr/local/slow_log_rotation/config/config.yaml # 修改后重启 sudo systemctl restart slow_log_rotation ``` ### 卸载 ```bash # 在部署包目录执行 sudo ./uninstall.sh ``` --- ## 方式二:Docker 部署 使用 Docker 容器运行,适合容器化环境。 ### 前置要求 - 已安装 Docker - 或已安装 docker-compose(可选) ### 部署步骤 #### 1. 打包部署文件 ```bash # Linux AMD64(最常用) make package-deploy # 或打包所有平台(包含 Docker 脚本) make package-deploy-all ``` 生成的部署包包含 Docker 相关文件: ``` slow_log_rotation-linux-amd64-deploy/ ├── install-docker.sh # Docker 安装脚本 ├── uninstall-docker.sh # Docker 卸载脚本 ├── docker-compose.yaml # Docker Compose 配置 ├── config.yaml # 配置文件模板 └── README.md ``` #### 2. 上传到服务器 ```bash scp release/slow_log_rotation-linux-amd64-deploy.tar.gz user@server:/tmp/ ``` #### 3. 解压并安装 在目标服务器上执行: ```bash # 解压 cd /tmp tar xzf slow_log_rotation-linux-amd64-deploy.tar.gz cd slow_log_rotation-linux-amd64-deploy # 编辑配置文件 vi config.yaml # 执行 Docker 安装脚本(一键安装) sudo ./install-docker.sh ``` **安装脚本会自动完成:** - ✅ 创建配置目录 `/usr/local/slow_log_rotation/config` - ✅ 拉取 Docker 镜像 - ✅ 启动容器 - ✅ 配置开机自启动 ### 容器管理 ```bash # 查看容器状态 docker ps # 查看日志 docker logs -f slow_log_rotation # 重启容器 docker restart slow_log_rotation # 停止容器 docker stop slow_log_rotation # 进入容器 docker exec -it slow_log_rotation sh ``` ### 配置管理 ```bash # 编辑配置 vi /usr/local/slow_log_rotation/config/config.yaml # 重启容器应用配置 docker restart slow_log_rotation ``` ### 使用 docker-compose(可选) ```bash # 启动 docker-compose up -d # 查看日志 docker-compose logs -f # 停止 docker-compose down ``` ### 卸载 ```bash # 使用卸载脚本 sudo ./uninstall-docker.sh ``` --- ## 方式三:手动安装(开发/测试) 仅用于开发和测试环境。 ```bash # 编译 go build # 运行 ./slow_log_rotation -config config.yaml ``` **注意:** 手动安装方式在服务器重启后需要手动启动程序。 ## 配置说明 配置文件使用 YAML 格式,默认路径为 `config.yaml`: ```yaml check_time: "03:00" # 每天检查时间 instances: - host: "localhost" port: 3306 username: "root" password: "your_password" rotation_days: 1 # 轮转周期(天) encrypted: true # 密码是否加密 ``` ### 配置项说明 - `check_time`: 每天检查是否需要轮转的时间点(24小时制) - `instances`: MySQL 实例列表 - `host`: 主机地址 - `port`: 端口号 - `username`: 用户名 - `password`: 密码 - `rotation_days`: 轮转周期(天) - `encrypted`: 配置文件中的密码是否已加密(`true`=加密存储,`false`=明文存储) - `last_rotation`: 上次轮转时间(程序自动维护) **关于 `encrypted` 参数的说明:** | encrypted 值 | 含义 | 程序行为 | 适用场景 | |-------------|------|----------|----------| | `false` | 密码以明文形式存储 | 启动时直接使用,保存时保持明文 | 开发/测试环境 | | `true` | 密码应加密存储 | 启动时解密使用,保存时重新加密 | 生产环境,推荐使用 | **`encrypted` 参数的使用方式:** 方式一:手动设置(不设置默认为true) ```yaml # 直接在配置文件中设置 encrypted: true instances: - host: "localhost" port: 3306 username: "root" password: "your_password" encrypted: true # 设置为 true rotation_days: 1 ``` 程序启动时会自动加密密码并保存到配置文件。 方式二:使用 `-encrypt` 参数 ```bash ./slow_log_rotation -encrypt -config config.yaml ``` **程序行为说明:** - 如果 `encrypted: true` 且密码已加密 → 解密使用 - 如果 `encrypted: true` 但密码是明文 → 自动加密并保存配置文件 - 如果 `encrypted: false` → 直接使用明文,保存时保持明文 ## 轮转逻辑详解 ### 轮转判断机制 程序使用以下逻辑来判断是否需要进行日志轮转: 1. **时间检查**: - 每天在配置的 `check_time` 时间点进行检查 - 计算上次轮转时间到当前时间的天数差 - 如果天数差大于或等于配置的 `rotation_days`,则触发轮转 2. **轮转周期示例**: - 如果 `rotation_days = 1`: - 每天都会轮转 - 示例:上次轮转时间是 6月13日,在 6月14日就会轮转 - 如果 `rotation_days = 2`: - 每两天轮转一次 - 示例:上次轮转时间是 6月13日,要到 6月15日才会轮转 3. **首次运行**: - 如果没有上次轮转记录(`last_rotation` 为空),将立即执行轮转 ### 轮转流程 1. **准备阶段**: - 验证数据库连接 - 检查权限 2. **执行轮转**: - 删除已存在的 `slow_log_old` 表(如果有) - 创建新的 `slow_log_new` 表 - 执行表重命名操作: ```sql RENAME TABLE mysql.slow_log TO mysql.slow_log_old, mysql.slow_log_new TO mysql.slow_log; ``` 3. **后续处理**: - 更新配置文件中的 `last_rotation` 时间 - 记录操作日志 ### 错误处理 - 如果轮转过程中出现错误,会自动清理临时表 - 失败的轮转操作会在下一个检查时间点重试 - 每个实例的轮转失败不会影响其他实例 ## 打包说明 ### 构建docker镜像 ```shell # 到slow_log_rotation当前目录下,执行打包 docker build -t slow_log_rotation:latest . # 查看镜像 docker images # 打成阿里云的 docker tag registry.cn-hangzhou.aliyuncs.com/public_projects/slow_log_rotation:latest # 上传到阿里云仓库 docker push registry.cn-hangzhou.aliyuncs.com/public_projects/slow_log_rotation:latest ``` ### Makefile | 命令 | 说明 | | -------------------------- | --------------------------------------------- | | make package | 打包所有平台的二进制文件到 release/ | | make package-deploy | 打包Linux AMD64部署包(最常用,用于生产环境) | | make package-deploy-arm64 | 打包Linux ARM64部署包(树莓派、ARM服务器) | | make package-deploy-darwin | 打包macOS部署包(本地开发,不含systemd) | | make package-deploy-all | 打包所有平台的部署包 | ```shell make package-deploy-all 打好的包文件在 release 目录下 二进制文件在 dist 目录下 ``` --- ## 常见问题 (FAQ) ### 1. 如何确认程序是否正常运行? ```bash # 查看服务状态 sudo systemctl status slow_log_rotation # 查看实时日志 sudo journalctl -u slow_log_rotation -f -o cat # 检查进程 ps aux | grep slow_log_rotation ``` ### 2. 密码加密后如何修改明文密码? 直接修改配置文件中的明文密码(`password` 字段),然后重启服务。程序会自动加密新的明文密码: ```yaml instances: - host: "localhost" password: "new_password" # 修改为新的明文密码 encrypted: true # 保持 true 不变 ``` ### 3. 为什么轮转后密码又变了? 这是正常现象。程序使用 AES-256-GCM 加密算法,每次加密都会生成随机的 nonce,导致密文不同。但这不影响解密,程序能正确解密任何有效的密文。 ### 4. 如何备份 slow_log_old 表的数据? **方式一:使用 mysqldump** ```bash # 备份 slow_log_old 表 mysqldump -u root -p mysql slow_log_old > slow_log_old_$(date +%Y%m%d).sql # 恢复 mysql -u root -p mysql < slow_log_old_20260310.sql ``` **方式二:导出到 CSV** ```sql -- 在 MySQL 中执行 SELECT * FROM mysql.slow_log_old INTO OUTFILE '/var/lib/mysql-files/slow_log_old.csv' FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n'; ``` **方式三:创建归档表** ```sql -- 创建归档表(按月) CREATE TABLE mysql.slow_log_archive_202603 LIKE mysql.slow_log_old; -- 复制数据 INSERT INTO mysql.slow_log_archive_202603 SELECT * FROM mysql.slow_log_old; -- 删除旧表 DROP TABLE mysql.slow_log_old; ``` ### 5. 轮转失败后如何重试? 程序会在下一个检查时间点自动重试。如果需要立即重试: ```bash # 修改配置文件中的 last_rotation 为空 sudo vi /usr/local/slow_log_rotation/config/config.yaml # 将 last_rotation: "2026-03-10 09:22:00" 改为 last_rotation: "" # 重启服务 sudo systemctl restart slow_log_rotation ``` ### 6. 如何查看某个实例的轮转历史? 查看配置文件中的 `last_rotation` 字段: ```bash sudo cat /usr/local/slow_log_rotation/config/config.yaml ``` 或者查看日志: ```bash sudo journalctl -u slow_log_rotation | grep "已更新实例.*的最后轮转时间" ``` ### 7. 如何监控系统资源使用? ```bash # 查看内存和 CPU 使用 top -p $(pidof slow_log_rotation) # 查看 Docker 容器资源使用 docker stats slow_log_rotation # 查看文件描述符 lsof -p $(pidof slow_log_rotation) ``` --- ## 性能影响 ### 对 MySQL 的影响 **轮转操作期间(通常 <1 秒):** - ✅ **表重命名是元数据操作** - RENAME TABLE 在 MySQL 中是原子操作,非常快 - ✅ **不锁表** - 不会影响正在写入的慢日志 - ✅ **短暂中断** - 轮转期间可能丢失几毫秒的慢日志(可忽略) **示例性能数据:** ``` 表大小:100MB 轮转耗时:<0.5 秒 影响范围:仅 mysql 库的 slow_log 相关表 ``` ### 对系统资源的影响 **程序运行时:** - **内存占用**:约 10-30MB(取决于实例数量) - **CPU 占用**:几乎为 0%(大部分时间在睡眠等待) - **磁盘 IO**:极小(只在轮转时读写配置文件) **轮转时:** - **网络带宽**:<1MB(连接 MySQL、执行 DDL 语句) - **磁盘 IO**:配置文件写入(<1KB) ### 优化建议 1. **合理安排轮转时间**:将 `check_time` 设置在业务低峰期(如凌晨 3 点) 2. **避免频繁轮转**:不建议 `rotation_days < 1` 3. **监控慢日志增长**:根据实际情况调整 `rotation_days` --- ## 技术支持 - **问题反馈**: 请提交 GitHub Issue - **功能建议**: 欢迎 Pull Request - **安全问题**: 请发送私密报告 --- ## 更新日志 ### v1.0.0 (2026-03-10) - ✅ 支持多 MySQL 实例管理 - ✅ 可配置的轮转周期(按天) - ✅ 密码加密存储(AES-256-GCM) - ✅ systemd 和 Docker 两种部署方式 - ✅ 启动时权限验证 - ✅ 完善的错误处理机制