Notes on restoring deleted Moodle Forum
Someone deleted a Moodle Discussion Forum with 137 posts, and it was urgent to recover it because in that course, these were part of the grade.
This is not a guaranteed solution, just a record of what we did. We only attempted it because of the urgency of the situation. Our experiment seems successful, and here’s what we did.
Note: this is in the form of a shell script, with most of the lines commented out, because we only ran one step at a time, then did queries to check that results were what we expected.
restore.sh# April 7, 2011 - experiment in restoring a forum that had been deleted.# First we found the daily database backup prior to the forum deletion time, and copied and unzipped it to backupdb.sql.# cd /data-archive/mysqldumps/# ls -al /data-archive/mysqldumps/# cp /data-archive/mysqldumps/moodle.4.gz /data-archive/mysqldumps/backupdb.gz# gunzip backupdb.gz# mv backupdb backupdb.sql# Then we copied the schema (but not the data) from our production moodle database to a new db called "forum_restore"# These could be combined but we didn't realize how many we'd need at first.# grep "INSERT INTO \`mdl_forum" backupdb.sql > foruminserts# mysql forum_restore < foruminserts# grep "INSERT INTO \`mdl_course_modules" backupdb.sql > course_modules# mysql forum_restore < course_modules# grep "INSERT INTO \`mdl_course_sections" backupdb.sql > course_sections# mysql forum_restore < course_sections# grep "INSERT INTO \`mdl_grade_items" backupdb.sql > grade_items# mysql forum_restore < grade_items# grep "INSERT INTO \`mdl_grade_grades" backupdb.sql > grade_grades# mysql forum_restore < grade_grades# Then we made a dump of the current production moodle db then restored it to clone_moodle, then pointed our stage server at it.# mysql clone_moodle < moodle_nolog.110407.mysql# Here we started putting the data back.# Note you have to hardcode the forum number.#mysql -e 'insert into clone_moodle.mdl_forum select * from forum_restore.mdl_forum where id = 11067' clone_moodle#mysql -e 'insert into clone_moodle.mdl_forum_discussions select * from forum_restore.mdl_forum_discussions where forum = 11067'#mysql -e 'insert into clone_moodle.mdl_forum_posts select * from forum_restore.mdl_forum_posts where discussion in (select id from forum_restore.mdl_forum_discussions where forum=11067)'#mysql -e 'insert into clone_moodle.mdl_forum_queue select * from forum_restore.mdl_forum_queue where discussionid IN (select id from forum_restore.mdl_forum_discussions where forum=11067)'#mysql -e 'insert into clone_moodle.mdl_forum_ratings select * from forum_restore.mdl_forum_ratings where post IN (select id from forum_restore.mdl_forum_posts where discussion in (select id from forum_restore.mdl_forum_discussions where forum=11067))'#mysql -e 'insert into clone_moodle.mdl_forum_read select * from forum_restore.mdl_forum_read where discussionid IN (select id from forum_restore.mdl_forum_discussions where forum = 11067)'#mysql -e 'insert into clone_moodle.mdl_forum_subscriptions select * from forum_restore.mdl_forum_subscriptions where forum=11067'#mysql -e 'insert into clone_moodle.mdl_forum_track_prefs select * from forum_restore.mdl_forum_track_prefs where forumid=11067'## This next one assumes that it is a forum, which is module=7#mysql -e 'insert into clone_moodle.mdl_course_modules SELECT * FROM forum_restore.mdl_course_modules WHERE module= 7 and instance = 11067'## This next one is not an INSERT, but is an UPDATE and assumes it is a forum and is in section 0. Note you have to hardcode the course number.#mysql -e "update clone_moodle.mdl_course_sections set sequence=concat(sequence, ',', (select id from forum_restore.mdl_course_modules where module = (select id from clone_moodle.mdl_modules where name='forum') and instance='11067')) where course=7410 and section=0"## Untested because they were empty# mysql -e "insert into clone_moodle.mdl_grade_items select * from forum_restore.mdl_grade_items where courseid=7410 and itemtype='mod' and itemmodule='forum' and iteminstance=11067"# mysql -e "insert into clone_moodle.mdl_grade_grades select * from forum_restore.mdl_grade_grades where itemid IN (select id from forum_restore.mdl_grade_items where courseid=7410 and itemtype='mod' and itemmodule='forum' and iteminstance=11067)"## Untested and not converted to updates because they were empty. Actually, according to David Choi, this history table wouldn't be updated anyway.#select * from mdl_grade_items_history where oldid = (select id from mdl_grade_items where courseid=7410 and itemtype='mod' and itemmodule='forum' and iteminstance=11067) and action=3;#select * from mdl_grade_grades_history where oldid=(select id from mdl_grade_grades where itemid IN (select id from mdl_grade_items where courseid=7410 and itemtype='mod' and itemmodule='forum' and iteminstance=11067)) and action=3;## Since there were no grades, and we don't yet push our grades to MyUCLA Gradebook yet, we ignored that problem.
After the steps above were done, we had a working version of the deleted forum on our stage server. Then we tested it, did a Moodle backup of the cloned course, backed up the real class site (just in case), then restored this forum into the it. Since our course format is programmed to automatically create a Discussion Forum when it finds a site doesn’t have one, the students had a bunch of posts on the new forum that we copied over to the recovered forum. We renamed the restored forum to “Discussion Forum Restored,” and went into each posting in the restored forum and used Moodle’s “Move this discussion to…” tool in the upper right hand corner of the forum post. Once all of the posts were moved to the Discussion Forum, we deleted “Discussion Forum Restored.”
I think we need to make it harder to delete a forum. Maybe we should suggest or force a backup first? Or, remove the ability of instructors or TAs to remove Forums?