Неконсистентные состояния системы
1)
Несоответствие объектов в базе и на файловой системе
Объект | В базе | На файловой системе |
Решение | submits (id, userid, taskid, filename,…) | solution/<filename> solution/<filename>.md5 |
Архив тестов | tasks (tasked) | tests/<taskid>/archive.zip tests/<taskid>/archive.zip.md5 |
Условие тура | files_for_tour (fid, tourid, filename, comment) | tours/<tourid>.zip/<filename> |
Условия задач | tasks (tasked, tourid) | tasks/<tourid>/<tasked>.<txt> |
Детализированный отчет (ошибка компиляции и тд) | submits (id) | solution/<solution_id>.zip |
Текст на печать | print (filename) | ... |
Проблемы
слишком много записей, большой запрос к БД,оценить время выполнения
Алгоритм устранения
...
2)
Внешний ключ указывает на несуществующий объект (удаленный)
Private key | Foreign key |
Olympiad.id? | Forms.olympiadid? Log.olympid? Tour.olympid? Users.current_olympiad? Userlist.olympiadid? Olympiad_freeze.olympiadid? |
tour.tourid | Files_for_tour.tourid? Langs_for_tour.tourid? News.tourid? Qna.tourid? Virtualtours.tourid? users.selected_tourid Notifications.tourid? Tasks.tourid? Timeshift.tourid? |
Users.userid? | Formvalues.userid? Online.userid? Print.userid? Priv.userid? Submits.userid? Virtualtours.userid? Timeshift.userid? Notifications.userid? Qna.userid? Qna.ansid? |
Forms.id? | Formvalues.formid? Userlist.formid? |
Langs.langid? | Langs_for_tour.langid? Submits.langid? |
Tasks.taskid? | Submits.taskid? |
Cities.id? | Universities.cityid? Users.cityid? |
Universities.id? | Users.univerid? |
Алгоритм устранения
A.id ->
- a_id
1) Пробегаем по всем B, смотрим, что существует соответствующий A.id = B.a_id
Если нет, то удаляем строку В или пишем предупреждение.
SELECT b.* FROM `B` AS b
LEFT JOIN `A` AS a
ON (b.a_id = a.id)
WHERE a.id IS NULL;
2) При удалении A.id удаляем все связные строки B
P.S. Удаление данных нужно не всегда, например
— в таблице userlist есть поля с фиксированными formid (1..6), означающие город, универ, название, т.е. поля по умолчанию. их нет в form.id
— не надо удалять пользователя, если у него несуществующая олимпиада или тур
Такие данные игнорируются
Внимание! Использовать такой скрипт надо осторожно!