如何从数据库和文件系统彻底删除Moodle备份文件?
解决Moodle备份文件堆积的有效清理方案
核心思路
Moodle的备份文件关联mdl_files文件表和mdl_backup_controllers备份控制器表,直接删除物理文件或单删某张表会导致数据不一致。必须通过Moodle原生文件API同步清理文件和数据库记录,避免残留。
1. 先定位目标备份记录与文件
先通过SQL确认待清理的备份文件关联关系,避免误删:
SELECT f.id AS file_id, f.contenthash, f.filename, bc.backupid, bc.timecreated FROM mdl_files f JOIN mdl_backup_controllers bc ON f.itemid = bc.id WHERE f.component = 'backup' AND f.filearea IN ('backup', 'automated') -- automated对应自动备份,backup对应手动备份 ORDER BY bc.timecreated DESC;
2. 批量清理旧备份(文件+数据库)
使用Moodle原生API编写清理脚本,确保同步删除:
global $DB, $CFG; require_once($CFG->libdir . '/filelib.php'); // 保留最近30天的备份,可自行调整时间阈值 $threshold = time() - (30 * 24 * 60 * 60); // 获取需清理的备份关联记录 $target_records = $DB->get_records_sql(" SELECT bc.id AS backup_id, f.id AS file_id FROM mdl_backup_controllers bc JOIN mdl_files f ON bc.id = f.itemid WHERE f.component = 'backup' AND f.filearea IN ('backup', 'automated') AND bc.timecreated < ? ", [$threshold]); $fs = get_file_storage(); foreach ($target_records as $record) { // 删除文件(自动同步删除mdl_files记录+物理文件) $file = $fs->get_file_by_id($record->file_id); if ($file) { $file->delete(); } // 删除备份控制器记录 $DB->delete_records('backup_controllers', ['id' => $record->backup_id]); }
3. 清理孤立文件记录
如果存在无对应备份控制器的孤立文件(比如备份中断遗留),单独清理:
$orphaned_files = $DB->get_records_sql(" SELECT f.id FROM mdl_files f LEFT JOIN mdl_backup_controllers bc ON f.itemid = bc.id WHERE f.component = 'backup' AND f.filearea IN ('backup', 'automated') AND bc.id IS NULL "); foreach ($orphaned_files as $file) { $file_obj = $fs->get_file_by_id($file->id); if ($file_obj) { $file_obj->delete(); } }
4. 验证清理效果
- 重新执行第一步的SQL,确认目标记录已被删除
- 检查
moodledata/filedir下的对应哈希文件夹(由contenthash前2位+后2位组成)是否已被自动清理(Moodle的delete()方法会移除空文件夹)
5. 预防堆积的措施
在自定义备份代码中,备份完成后立即清理临时文件:
// 假设已创建并执行完备份控制器 $backup_controller = backup_controller::create(...); // 执行备份逻辑... // 备份完成后清理对应文件和记录 $fs = get_file_storage(); $file = $fs->get_file_by_area( 'backup', 'backup', $backup_controller->get_id(), '/', $backup_controller->get_backupid() . '.mbz' ); if ($file) { $file->delete(); } $DB->delete_records('backup_controllers', ['id' => $backup_controller->get_id()]);
或者通过Moodle任务调度,添加定时清理任务,定期自动清理旧备份。
内容的提问来源于stack exchange,提问作者Avatar
相关产品推荐
相关产品推荐

