Массовое удаление спама из форума phpBB с помощью SQL
Материал из 1GbWiki.
[править] Замечание
Перед выполнением любых действий, описанных ниже, настоятельно рекомендуем сделать дамп базы данных.
[править] Описание проблемы
Допустим, Ваш форум был завален тысячами сообщений примерно одинакового содержания, от которых Вы хотели бы избавиться. Поскольку удалять их по одному слишком долго, Вы соединились со своей базой MySQL напрямую и массово удалили множество сообщений, например такими запросами:
DELETE FROM phpbb_posts WHERE post_username = "Spammer"; DELETE FROM phpbb_posts_text WHERE post_text LIKE "%VIAGRA%";
Спам удалён, однако теперь перед Вами возникает другая проблема: база данных форума находится в неконсистентном состоянии. Например, число сообщений в списке форумов во много раз больше реального числа сообщений, ссылки на последние сообщения форума никуда не ведут и т.п.
Причина в том, что удалив пост из таблиц phpbb_posts и/или phpbb_posts_text, Вы не совершили соответветствующих изменений в таблицах phpbb_topics и phpbb_forums, а также, возможно, оставили сами таблицы phpbb_posts и phpbb_posts_text не соответствующими друг другу.
[править] Решение
Выполните следующие SQL-запросы:
-- Удалить текст постов, для которых нет соответствующих записей в таблице phpbb_posts: DELETE FROM phpbb_posts_text WHERE NOT post_id IN ( SELECT post_id FROM phpbb_posts ); -- Удалить посты, для которых нет соответствующих записей в таблице phpbb_posts_text: DELETE FROM phpbb_posts WHERE NOT post_id IN ( SELECT post_id FROM phpbb_posts_text ); -- Удалить топики, в которых не осталось ни одного поста: DELETE FROM phpbb_topics AS t WHERE 0 = ( SELECT count(post_id) FROM phpbb_posts AS p WHERE t.topic_id = p.topic_id ); -- Привести поля topic_first_post_id и topic_last_post_id таблицы phpbb_topics -- в соотвествие с действительностью: UPDATE phpbb_topics AS t SET topic_first_post_id = ( SELECT post_id FROM phpbb_posts AS p WHERE t.topic_id = p.topic_id ORDER BY post_id ASC LIMIT 1 ); UPDATE phpbb_topics AS t SET topic_last_post_id = ( SELECT post_id FROM phpbb_posts AS p WHERE t.topic_id = p.topic_id ORDER BY post_id DESC LIMIT 1 ); -- Привести поля forum_last_post_id, forum_topics и forum_posts таблицы phpbb_forums -- в соответствие с действительностью: UPDATE phpbb_forums AS f SET forum_last_post_id = ( SELECT post_id FROM phpbb_posts AS p WHERE p.forum_id = f.forum_id ORDER BY post_id DESC LIMIT 1 ); UPDATE phpbb_forums AS f SET forum_posts = ( SELECT count(post_id) from phpbb_posts AS p WHERE p.forum_id = f.forum_id ); UPDATE phpbb_forums AS f SET forum_topics = ( SELECT count(topic_id) from phpbb_topics AS t WHERE t.forum_id = f.forum_id );