通过mysql删除mediawiki垃圾邮件用户



与MediaWiki 1.31一样,没有批量删除垃圾邮件用户的扩展(只有手动合并和删除)。我们将通过 MySQL 删除用户,但有警告指出此方法可能会因为引用的表而破坏您的数据库。删除用户表/行时,是否有办法确保没有引用受到损害?有什么经验或建议吗?

今天我遇到了一个旧的Mediawiki 1.23的问题,并搜索了一下。

  • 媒体维基手册:数据库布局
  • 数据库架构图
  • 手册:页表 - 删除页面及其在文本和修订表中的关系

根据上面的信息,我做了一些实验。

首先,我想评估一下损坏情况:

外部链接

select  count(*) from externallinks
select convert(el_to using utf8) as href 
from externallinks l

那里有大约 150.000 个外部链接

用于查找用户的 SQL 查询

select 
convert(user_name using utf8) as name,
convert(user_touched using utf8) as time,
user_editcount 
from user 
order by 2 desc

就我而言,所有垃圾邮件用户都在同一时间段内创建。

SQL查询,带有页面,修订,文本和用户表的连接。

select 
convert(u.user_name using utf8) as username,
p.page_id,
convert(p.page_title using utf8) as pagetitle,
r.rev_user as userid,
convert(t.old_text using utf8) as text
from page p
inner join revision r
on p.page_id=r.rev_page
inner join user u
on r.rev_user=u.user_id  
inner join text t
on r.rev_text_id=t.old_id

SQL 查询以查找每个用户的修订数:

select count(*),u.user_id,convert(u.user_name using utf8) as username
from revision r
inner join user u
on r.rev_user=u.user_id
group by 2
order by 1 desc 

就我而言,幸运的是,所有"好"页面仅由一个用户创建,user_id=1,因此我可以通过以下方式评估损害:

select count(*) as textcount from text where old_id in (select rev_text_id from revision where not rev_user in (1));

结果给了我超过五十万次点击,这意味着删除最好以逐步的方式完成:

select count(*) as textcount from text where old_id in (select rev_text_id from revision where not rev_user in (1)); 
set autocommit=0;
start transaction;
delete from text where old_id in (select rev_text_id from revision where not rev_user in (1)) limit 2000; 
commit;

请注意,2000 的限制已经导致大约 2 分钟的运行时间。 所以我必须运行上面的 SQLStatement 大约 250 次,每次等待 2 分钟......

如果遇到删除计时问题,可以考虑以下提示:

  • 如何提高大型InnoDB表的DELETE FROM性能?

您可以通过以下方式查看我们的表格状态:

show table status from <wiki-databasename>;

在我的情况下,使用INNODB的表。

我尝试将innod_buffer_pool_size增加到 128 MByte,但这并没有产生积极的影响。删除仍然很慢。

我仍然会尝试完成此操作并通过删除相关行来工作

  • 外部链接
  • 校订

我还检查了/var/lib/mysql/中的文件。由于我每个表都有 innodb 文件,我看到很多表都变得非常大。

所以调查

  • https://www.percona.com/blog/2013/09/25/how-to-reclaim-space-in-innodb-when-innodb_file_per_table-is-on/

并开始

optimize table text

这需要8个小时才能完成。

幸运的是,就我而言,它并不是一个真正的生产维基。我只是想检查该方法的可行性,看起来它在很大程度上取决于所涉及的行数。

基于 API 和基于维护的方法可能更有效,具体取决于具体方案。

你试过这个吗:https://www.mediawiki.org/wiki/Manual:RemoveUnusedAccounts.php?

这是一个内置的 scipt 可以毫无问题地删除未使用的帐户。阅读上面链接中的说明。

最新更新