Скрипт не плох, хотя бы потому, что хорошо документирован. Но проблема с основной идеей - останавливать сервер ради резервного копирования. Если бы копирование выполнялось 5 минут, то всё ничего, можно потерпеть. Но когда ваш сервер наполнится данными как следует, на резервирование могут уходить часы. Поэтому:
Проблема согласованности резервных копий состоит в согласованности копии базы данных, и папки moodledata. При этом, если вы будете делать копию папки moodledata после снятия базы, но до запуска очистки корзины, у вас из этой папки не смогут удалиться файлы, только добавиться. От нескольких лишних файлов в случае, если вдруг потребуется восстановить систему из бэкапа, вреда не будет.
Поэтому как примерно следует делать бэкап:
Для бэкапа базы данных на mysql следует использовать Percona. Она позволяет сделать моментальный снимок базы данных не останавливая сервер. То есть в один момент времени запись данных переключается на новый файл, а основной не трогается. Пока он копируется, пусть даже долго, запись идёт только во временный файлом. После окончания копирования основного файла изменения из нового файла копируются обратно в основной, и запись переключается обратно на него. В результате получается согласованная копия.
Перед тем, как запускать копирование БД таким способом, нужно добавить в config.php строчку $CFG->fileslastcleanup=time(); - это предотвратит очистку корзины во время резервного копирования.
После окончания резервного копирования БД следует сделать rsync папки moodledata в место бэкапа. В этой папке много всего, но копировать нужно только filedir и trashdir. В filedir хранятся все файл системы, в trashdir хранятся файлы, которые были удалены, но так как они могли быть удалены после снятия копии базы, их придется хранить, чтобы возвращать потом в filedir. Правда непонятно, какие из них именно нужны. Идеальный вариант, чтобы быть уверенными насчёт файлов в trashdir, что они реально нужны, это делать прямо перед снятием бэкапа БД очистку корзины, потом, если какой-то файл на момент копирования moodledata оказался в trashdir, значит удаление было уже после снятия бэкапа базы и его следует при восстановлении возвращать в filedir.
Другие папки в moodledata вообще не нужно переносить. Кэш моментально будет перестроен при восстановлении, поэтому о нём жалеть не стоит, а вот несогласованный кэш часто приводит к полной недоступности сайта. Остальные файлы - сессии, блокировки, временные, их копировать тоже нет смысла, так как при восстановлении все будут заходить в систему заново.
Теперь про rsync. в Moodledata 99% файлов неизменны и 1% это то, что появилось с последнего бэкапа. Поэтому копирование с rsyns в разы ускорит процесс резервирования. Так как в filedir файлы хранятся по хэшам и содержимое файла никогда не меняется, можно использовать максимально быстрые режимы сравнения. Хорошо подходит --size-only, а вот --ignore-times и --checksum не стоит включать, только замедлят. Но в случае, если используете rsync, возникает другая проблема - можно иметь только одну копию файлов - последнюю. Чтобы этого избежать, в месте, куда будут закидывать бэкапы moodledata следует создать LVM разделы - они поддерживают snapshot-ы, за счёт которых можно хранить несколько копий moodledata не расходуя места на совпадающие между копиями файлы. В идеале, использовать LVM и там, где у Вас находится оригинал папки moodledata. Ещё лучше вообще всё держать на LVM, тогда можно вообще ограничиться созданием снимков LVM.
Так что вот итоговый алгоритм бэкапа.
1. Добавляете в config.php строку $CFG->fileslastcleanup=time() - 60 * 60 * 24 *365;
2. Запускаете через cli задачу планировщика по очистке корзины.
3. Меняете в config.php строку на $CFG->fileslastcleanup=time();
4. Стартуете бэкап бд с помощью Percona. Можно фоновым процессом, чтобы минимизировать расхождения между базой данных и moodledata.
5. Если у вас LVM на разделе с moodledata, создаёте снимок и монтируете состояние до создания снимка по отдельному пути.
6. Если у вас LVM на разделе с резервной копией moodledata, создаёте там новый снимок, чтобы старая резервная копия сохранилась в старом снимке.
7. Делаете rsync папок moodledata/filedir и moodledata/trashdir в папку с резервной копией. Для rsync нужно использовать в том числе параметр --delete, так как удаленные в оригинале файлы можно удалить и из копии (так как старые копии этого файла можно поднять из снимков). Если вдруг у вас нет LVM на приёмнике резервной копии, то не используйте параметр --delete - более новую копию можно будет использовать и со старой базой данных, просто будут копиться лишние файлы.
8. Удаляете снимок на разделе с moodledata, если создавали. Изменения при этом нужно объединить.
9. Убираете из config.php строку $CFG->fileslastcleanup=time();
10. Где-то фоном заканчивает копироваться база данных, если ещё не докопировалась.
В общем, достаточно сложно. Гораздо проще использовать нормальный гипервизор и нормальное средство резервирования виртуальных машин, которое может автоматически копировать всё без отключения и экономить место за счёт использования snapshot-ов виртуальной машины, так что можно резервировать хоть по 3 раза в день. А на выходе у вас всегда будет готовая к запуску копия машины, о чём Вы и сами говорили.
Неудачный бесплатный гипервизор - настройте в виртаулке диск с LVM и создавайте снимки всей системы, а старые снимки удаляйте. Всё равно сейчас бэкапите в рамках той же самой машины. Правда есть нюанс - как тут пишут нужно перед созданием снимка в mysql нужно сделать FLUSH TABLES WITH READ LOCK, а после - UNLOCK TABLES.
Но на самом InnoDB выполняет дамп базы в транзакции, поэтому даже при использовании традиционного способа с mysqldump, дамп базы будет консистентным. Поэтому вполне будет достаточно сделать дамп БД и скопировать moodledata/filedir не останавливая сервер. А не запустился бэкап у вас после восстановления, скорее всего, из-за того, что скопировали всю moodledata, а не только filedir, и битым оказался именно кэш.