Moodle

Investigate why overrides are not being cleaned up when a context is deleted

Details

  • Type: Sub-task Sub-task
  • Status: Closed Closed
  • Priority: Minor Minor
  • Resolution: Fixed
  • Affects Version/s: 1.9.3
  • Fix Version/s: 1.9.5
  • Component/s: Roles / Access
  • Labels:
    None
  • Affected Branches:
    MOODLE_19_STABLE
  • Fixed Branches:
    MOODLE_19_STABLE

Description

From Dan's data

Moodles Affected Average Percentage rows affected Table Key Total Violated Rows Total Rows
122 0.5 role_capabilities contextid 1418 97270

Activity

Hide
Tim Hunt added a comment -

Work out where these are coming from, and see if we can devise an automated clean-up on upgrade.

Show
Tim Hunt added a comment - Work out where these are coming from, and see if we can devise an automated clean-up on upgrade.
Hide
Tim Hunt added a comment -

Probably related:

10 3.1 role_assignments contextid 389 55235
5 61.7 role_names contextid 15 21

Show
Tim Hunt added a comment - Probably related: 10 3.1 role_assignments contextid 389 55235 5 61.7 role_names contextid 15 21
Hide
Tim Hunt added a comment -

The problems is not in build_context_paths. (I mistakenly thought it might do a truncate table and rebuild, but it does not.)

cleanup_contexts in accesslib.php (called from cron and upgrade) correctly uses delete_context - and this should clean up

Ah, delete_context was missing the cleanup of role_names.

Is delete_context always called when it needs to be?

  • system: should never be deleted.
  • course category deleted: called from course/lib.php.
  • user deleted: called from delete_user in lib/moodlelib.php.
  • course deleted: called from delete_course in lib/moodlelib.php.
  • module deleted:
    + called from remove_course_contents in lib/moodlelib.php when a course is emptied (either by delete course of restore deleting existing).
    + ERROR delete_course_module in course/lib.php does not call delete_context.
    + ERROR admin/modules.php does not it when a module is uninstalled.
    + possible error: backup/restorelib.php does delete_records('course_modules' without cleaning up the context.
  • block deleted:
    + called from remove_course_contents in lib/moodlelib.php when a course is emptied (either by delete course of restore deleting existing).
    + ERROR blocks_delete_instance (lib/blocklib.php) does not call delete_context.
    + ERROR restore_create_blocks does delete_records('block_instance', ... without proper cleanup.
    + ERROR blocks_repopulate_page (lib/blocklib.php) does delete_records('block_instance', ... without proper cleanup
    + ERROR chat|lesson|quiz_delete_instance in mod/chat|lesson|quiz/lib.php do delete_records('block_instance', ... without proper cleanups.

For the blocks stuff, looking at the problematic code, a blocks_delete_all_on_page($pagetype, $pageid) to replace the delete_records call is probably the easiest solution.

I don't really understand why these errors leave bad data related to contexts floating around, however, since cleanup_contexts, called from cron, should get rid of them, and anyway the issues is to do with contexts being deleted while related data remains.

And the only place in the code we seem to delete records from the context table (checked for with regex delete_record.*context) is in the delete context function.

Show
Tim Hunt added a comment - The problems is not in build_context_paths. (I mistakenly thought it might do a truncate table and rebuild, but it does not.) cleanup_contexts in accesslib.php (called from cron and upgrade) correctly uses delete_context - and this should clean up Ah, delete_context was missing the cleanup of role_names. Is delete_context always called when it needs to be?
  • system: should never be deleted.
  • course category deleted: called from course/lib.php.
  • user deleted: called from delete_user in lib/moodlelib.php.
  • course deleted: called from delete_course in lib/moodlelib.php.
  • module deleted: + called from remove_course_contents in lib/moodlelib.php when a course is emptied (either by delete course of restore deleting existing). + ERROR delete_course_module in course/lib.php does not call delete_context. + ERROR admin/modules.php does not it when a module is uninstalled. + possible error: backup/restorelib.php does delete_records('course_modules' without cleaning up the context.
  • block deleted: + called from remove_course_contents in lib/moodlelib.php when a course is emptied (either by delete course of restore deleting existing). + ERROR blocks_delete_instance (lib/blocklib.php) does not call delete_context. + ERROR restore_create_blocks does delete_records('block_instance', ... without proper cleanup. + ERROR blocks_repopulate_page (lib/blocklib.php) does delete_records('block_instance', ... without proper cleanup + ERROR chat|lesson|quiz_delete_instance in mod/chat|lesson|quiz/lib.php do delete_records('block_instance', ... without proper cleanups.
For the blocks stuff, looking at the problematic code, a blocks_delete_all_on_page($pagetype, $pageid) to replace the delete_records call is probably the easiest solution. I don't really understand why these errors leave bad data related to contexts floating around, however, since cleanup_contexts, called from cron, should get rid of them, and anyway the issues is to do with contexts being deleted while related data remains. And the only place in the code we seem to delete records from the context table (checked for with regex delete_record.*context) is in the delete context function.
Hide
Tim Hunt added a comment -

The attached patch (cleanup_contexts.patch.txt, against 1.9) will fix:

  • delete_context should delete related records from role_names.
  • delete_course_module should call delete_context.
  • blocks_delete_instance should call delete_context.
  • admin/modules.php should call delete_context.
  • need a blocks_delete_all_on_page($pagetype, $pageid) function

Not done yet:

  • backup/restorelib.php problem (see MDL-14326).

Comments welcome.

Show
Tim Hunt added a comment - The attached patch (cleanup_contexts.patch.txt, against 1.9) will fix:
  • delete_context should delete related records from role_names.
  • delete_course_module should call delete_context.
  • blocks_delete_instance should call delete_context.
  • admin/modules.php should call delete_context.
  • need a blocks_delete_all_on_page($pagetype, $pageid) function
Not done yet:
  • backup/restorelib.php problem (see MDL-14326).
Comments welcome.
Hide
Tim Hunt added a comment -

I have no ideas, and this is not urgent, so un-targetting.

Show
Tim Hunt added a comment - I have no ideas, and this is not urgent, so un-targetting.
Hide
Tim Hunt added a comment -

Actually, cancel that last comment. I already checked in the changes for this. I wonder why I forgot to resolve the bug. Resolving now.

Show
Tim Hunt added a comment - Actually, cancel that last comment. I already checked in the changes for this. I wonder why I forgot to resolve the bug. Resolving now.

People

Vote (0)
Watch (3)

Dates

  • Created:
    Updated:
    Resolved: