![当与 puppet-dashboard 一起使用时,如何防止 MySQL 增加其磁盘空间使用量?](https://linux22.com/image/640476/%E5%BD%93%E4%B8%8E%20puppet-dashboard%20%E4%B8%80%E8%B5%B7%E4%BD%BF%E7%94%A8%E6%97%B6%EF%BC%8C%E5%A6%82%E4%BD%95%E9%98%B2%E6%AD%A2%20MySQL%20%E5%A2%9E%E5%8A%A0%E5%85%B6%E7%A3%81%E7%9B%98%E7%A9%BA%E9%97%B4%E4%BD%BF%E7%94%A8%E9%87%8F%EF%BC%9F.png)
设置
我们安装了 Debian Linux,其中安装了 MySQL v5.1.73(innoDB 存储引擎)和 puppet-dashboard 版本 1.2.23。您可能已经猜到了,puppet-dashboard 使用 MySQL 作为其后端。
此外,这不应该相关,但这是 vSphere 5.5 上的 VMware 虚拟机。
问题
问题在于,尽管 Puppet 节点的数量和运行频率保持相对相同,但 MySQL 使用的磁盘空间却以令人不安的方式不断增加,以至于现在成为了一个问题。
下图说明了这个问题。
我们已设置了两个 cron 作业,它们应该可以释放磁盘空间。它们如下,并且每天都会运行:
- rake RAILS_ENV=生产数据库:原始:优化
- rake RAILS_ENV=生产报告:prune:孤立最多=3 单位=mon
您可以在图表中看到的下降是 cron 作业正在运行并占用更多空间以尝试释放一些空间。
未启用 MySQL 二进制日志。此服务器上使用的 95% 的磁盘空间位于 /var/lib/mysql/dashboard_production,该目录是存储 MySQL 数据的目录。
我们之前在另一个应用程序(Zabbix 监控)上遇到过这个问题,不得不转储数据库并重新导入以释放空间。这是一个非常痛苦的过程,也不是一个非常优雅的解决方案,但最终还是成功了。
有什么方法可以回收这些磁盘空间?我们可以做什么来阻止这种行为?
编辑1
我们确实正在使用 innoDB,并且我们没有使用配置指令“innodb_file_per_table”。
根据 Felix 的要求,该命令的输出如下:
+----------------------+-------------------+-------------+
| table_schema | table_name | data_length |
+----------------------+-------------------+-------------+
| dashboard_production | resource_statuses | 39730544640 |
| dashboard_production | metrics | 643825664 |
| dashboard_production | report_logs | 448675840 |
| dashboard_production | timeline_events | 65634304 |
| dashboard_production | reports | 50937856 |
| dashboard_production | resource_events | 38338560 |
| glpidb | glpi_crontasklogs | 21204608 |
| ocsweb | softwares | 8912896 |
| ocsweb | deploy | 5044208 |
| phpipam | logs | 1269584 |
+----------------------+-------------------+-------------+
此外,我将尝试不带“孤立”选项的报告:修剪任务以及其他替代方案,并将保持该问题的更新。
编辑2
我运行了报告:prune rake 任务,尽管删除了 230000 份报告,但它仍然占用更多空间...因此,我将转向其他选项。
解决方案
删除数据库中三分之二的条目后,只释放了 200MB 的磁盘空间,这毫无意义。我们最终转储了内容并重新导入,并小心启用了“innodb_file_per_table”。
我们只需要拭目以待,看看这是否能从长远角度解决问题,但目前看来确实如此。
答案1
我发现这篇文章似乎很好地解决了这个问题
http://ximunix.blogspot.co.uk/2014/01/howto-cleanup-puppet-reports-and-db.html
由 Ximena Cardinali 发布
简而言之,开始小批量删除报告,然后从 MySQL 回收空间
如何清理 Puppet 报告和数据库
如果 Puppet Dashboard 的数据库使用了数 GB 并且每天都在变大,这是一种恢复部分空间的方法。
作为 Puppet Dashboard 日常维护的一部分,您应该每天运行两个 rake 作业。
cd /usr/share/puppet-dashboard
env RAILS_ENV=production rake reports:prune upto=5 unit=day
env RAILS_ENV=production rake reports:prune:orphaned
您可以更改 RAILS_ENV 和天数(day)、周数(wk)、月数(mon)等以匹配您的系统及其需求。
停止传入报告:
cd /路径/到/puppet-dashboard
env RAILS_ENV=生产脚本/delayed_job -p 仪表板 -m 停止
开始小批量删除报告
继续努力,直到达到您想要保留报告的时间长度。原因是 Innodb 表在一次删除超过 10k 行时性能不佳。如果您尝试删除几十万行,它将超时,您必须将其分解为较小的删除。此外,Ruby rake 进程可能会使用您所有的 RAM,并且很可能在完成之前被内核杀死。这种进展应该适用于大多数人,但如果您有几个月的数据,您可能希望从最早的一两个月的记录开始。在我们的例子中,我们只保留 2 周的报告(14 天)。
env RAILS_ENV=production rake reports:prune upto=6 unit=mon
env RAILS_ENV=production rake reports:prune upto=4 unit=mon
env RAILS_ENV=production rake reports:prune upto=2 unit=mon
env RAILS_ENV=production rake reports:prune upto=3 unit=wk
env RAILS_ENV=production rake reports:prune upto=1 unit=wk
env RAILS_ENV=production rake reports:prune upto=5 unit=day
- 确定从 MySQL 回收空间的最佳方法
根据 MySQL 的配置,有两种方法可以回收空间。运行此命令以确定“innodb_file_per_table”是否已启用。如果已启用,则应将其设置为“ON”。注意:对于这种情况,我建议在 MySQL 上使用 innodb。
mysqladmin variables -u root -p | grep innodb_file_per_table
您还可以列出数据库以查看是否有更大的数据文件。最有可能较大的表是 resource_statuses.ibd。
ls -lah /var/lib/mysql/dashboard_production
...
-rw-rw---- 1 mysql mysql 8.9K Jan 08 12:50 resource_statuses.frm
-rw-rw---- 1 mysql mysql 15G Jan 08 12:50 resource_statuses.ibd
...
- 轻松回收空间
如果 MySQL 配置了 innodb_file_per_table,并且您的 Dashoard DB 显示您的数据位于大型表文件中,请执行以下操作:
mysql -u root -p
use puppet_dashboard;
OPTIMIZE TABLE resource_statuses;
这将根据当前数据创建一个新表并将其复制到位。如果您在此过程中执行列表,则应该看到类似以下内容:
-rw-rw---- 1 mysql mysql 8.9K Jan 08 12:50 resource_statuses.frm
-rw-rw---- 1 mysql mysql 15G Jan 08 12:50 resource_statuses.ibd
-rw-rw---- 1 mysql mysql 8.9K Jan 08 12:50 #sql-379_415.frm
-rw-rw---- 1 mysql mysql 238M Jan 08 12:51 #sql-379_415.ibd
完成后,它会将 tmp 文件复制到位。在本例中,我们从 15GB 扩展到 708MB。
-rw-rw---- 1 mysql mysql 8.9K Jan 08 13:01 resource_statuses.frm
-rw-rw---- 1 mysql mysql 708M Jan 08 13:03 resource_statuses.ibd
- 艰难地夺回太空
如果您的系统未配置 innodb_file_per_table,或者所有当前数据都驻留在大型 ibdata 文件中,则回收空间的唯一方法是清除整个安装并重新导入所有数据。总体方法应该是这样的:首先配置 innodb_file_per_table,转储所有数据库,然后停止 Mysql,删除 /var/lib/mysql,运行 mysql_install_db 再次创建 /var/lib/mysql,启动 MySQL,最后重新导入数据。由于数据导入,将不需要优化步骤。
最后,重新启动delayed_job:
cd /路径/到/puppet-dashboard
env RAILS_ENV=生产脚本/delayed_job -p 仪表板 -n 2 -m 启动
每日报告清理和数据库维护:
对于每日报告清理,您可以创建一个简单的 BASH 脚本,该脚本按时间(在我们的例子中是 mtime +14)搜索 /var/lib/puppet/reports 上的报告,删除它们,然后使用(upto=2 unit=wk)清理数据库并将其设置在 crontab 中。脚本示例如下:
#!/bin/bash
REPORTS=`find /var/lib/puppet/reports -type f -mtime +14`
for i in $REPORTS; do rm -f $i; done
cd /usr/share/puppet-dashboardenv RAILS_ENV=production rake reports:prune upto=2 unit=wk