将phpBB3论坛迁移到Discourse

实际上是 3.3,所以我正在进行准备工作,等待 PR 使脚本与该版本的 phpBB 兼容,或者我可能会尝试使用当前脚本,使用您之前建议的编辑来进行版本检查……

所以我想我需要使用 xml_to_markdown.rb?

2 个赞

我尝试使用 phpBB 3.3.x 论坛进行测试导入,但失败了,但稍后会详细介绍。

在这个尝试过程中,我学到了很多东西,并认为我可以分享我的经验,这可能对其他导入以及更新后的 phpBB 3.3 导入脚本有所帮助。

如果您需要编辑 /script/import_scripts/phpbb3/database/database.rb 来绕过版本检查,或者编辑 /script/import_scripts/phpbb3/support/bbcode/xml_to_markdown.rb 来添加自定义 BBcode,那么在执行此命令进入导入操作后,是时候进行编辑了:

/var/discourse/launcher enter import

届时,您可以使用 nano 来编辑文件。

由于我尝试在 phpBB 3.3 论坛上运行导入失败了,所以我不能确定我的自定义 BBcode 更改是否有效,但看起来对于 phpBB 3.2+,您只需要编辑文件:

/script/import_scripts/phpbb3/support/bbcode/xml_to_markdown.rb

如上所述,并以以下格式添加定义:

def visit_<您的区分大小写的自定义 BBcode> (xml_node, md_node)
  # 处理代码放在这里
end

再次声明,我还没有机会测试这一点,但在 phpBB 中一个非常常见的自定义 BBcode,在我拥有的 xml_to_markdown.rb 版本中没有出现,就是这个:

[YouTube]{Identifier}[/YouTube]

其中 {Identifier} 是 YouTube URL 查询字符串中的“v”值。

所以,我这个 Ruby 新手尝试添加该代码到 xml_to_markdown.rb 的代码是:

def visit_YouTube(xml_node, md_node)
      content = xml_node.content
      url = "https://www.youtube.com/watch?v=" + content
      md_node.text = "#{url}"
      md_node.prefix_linebreaks = md_node.postfix_linebreaks = 2
      md_node.prefix_linebreak_type = LINEBREAK_HTML
end

最后,当我运行导入脚本时,只进行到数据库加载步骤,并收到此错误:

ERROR 1071 (42000) at line 1233035: Specified key was too long; max key length is 1000 bytes

我不确定这是否是数据库引擎问题——原始数据库使用 InnoDB——或者其他原因,但我怀疑这个问题将在 phpBB 3.3 版本的脚本中得到解决。

2 个赞

好的,我无法停止这件事。

虽然我认为我遇到的错误可能可以通过导入脚本来处理,但它确实看起来像是 phpBB3 数据库结构的问题,以及我的数据库排序规则是 UTF8 的问题。我在运行导入脚本时遇到了这个错误:

ERROR 1071 (42000) at line 1233035: Specified key was too long; max key length is 1000 bytes

当我查看我的 phpbb_mysql.sql 文件的第 1233035 行时——我使用的是数据转储的本地副本——我看到了这个:

ALTER TABLE `phpbb_config`
  ADD PRIMARY KEY (`config_name`),
  ADD KEY `is_dynamic` (`is_dynamic`);

查看 phpbb_config 表中的 config_name 列,我发现它被设置为 VARCHAR(255)。

多亏了 Stackoverflow 上的这个帖子,我发现我可以使用“前缀索引”来缩短键的长度。我测试了一下,它奏效了。

对于我的 phpBB 3.3.8 数据库,实际上有四个表受到影响:

  • phpbb_config
  • phpbb_config_text
  • phpbb_migrations
  • phpbb_oauth_accounts

如果其他人想尝试一下,以下是针对 phpbb_config 表的步骤,我将在最后包含其他表的查询。

使用此查询计算前缀索引的最短值:

SELECT
 ROUND(SUM(LENGTH(`config_name`)<10)*100/COUNT(`config_name`),2) AS pct_length_10,
 ROUND(SUM(LENGTH(`config_name`)<20)*100/COUNT(`config_name`),2) AS pct_length_20,
 ROUND(SUM(LENGTH(`config_name`)<50)*100/COUNT(`config_name`),2) AS pct_length_50,
 ROUND(SUM(LENGTH(`config_name`)<100)*100/COUNT(`config_name`),2) AS pct_length_100
FROM `phpbb_config`;

在我的例子中,它显示 100% 的行使用的字符数少于 50 个,所以我编辑了我的数据转储文件:

nano /var/discourse/shared/standalone/import/data/phpbb_mysql.sql

并使用搜索 Ctrl+W 查找以下字符串:

ALTER TABLE `phpbb_config`

然后将此更改为:

ALTER TABLE `phpbb_config`
  ADD PRIMARY KEY (`config_name`(50)),
  ADD KEY `is_dynamic` (`is_dynamic`);

其中的 (50) 是前缀索引的长度。

在我的例子中,我不得不对其他三个表重复此过程,使用以下查询来获得最佳前缀键长度:

SELECT
 ROUND(SUM(LENGTH(`config_name`)<10)*100/COUNT(`config_name`),2) AS pct_length_10,
 ROUND(SUM(LENGTH(`config_name`)<20)*100/COUNT(`config_name`),2) AS pct_length_20,
 ROUND(SUM(LENGTH(`config_name`)<50)*100/COUNT(`config_name`),2) AS pct_length_50,
 ROUND(SUM(LENGTH(`config_name`)<100)*100/COUNT(`config_name`),2) AS pct_length_100
FROM `phpbb_config_text`;

SELECT
 ROUND(SUM(LENGTH(`migration_name`)<10)*100/COUNT(`migration_name`),2) AS pct_length_10,
 ROUND(SUM(LENGTH(`migration_name`)<20)*100/COUNT(`migration_name`),2) AS pct_length_20,
 ROUND(SUM(LENGTH(`migration_name`)<50)*100/COUNT(`migration_name`),2) AS pct_length_50,
 ROUND(SUM(LENGTH(`migration_name`)<100)*100/COUNT(`migration_name`),2) AS pct_length_100
FROM `phpbb_migrations`;

SELECT
 ROUND(SUM(LENGTH(`provider`)<10)*100/COUNT(`provider`),2) AS pct_length_10,
 ROUND(SUM(LENGTH(`provider`)<20)*100/COUNT(`provider`),2) AS pct_length_20,
 ROUND(SUM(LENGTH(`provider`)<50)*100/COUNT(`provider`),2) AS pct_length_50,
 ROUND(SUM(LENGTH(`provider`)<100)*100/COUNT(`provider`),2) AS pct_length_100
FROM `phpbb_oauth_accounts`;

以下是其他表的搜索字符串,可以为您节省一些时间:

ALTER TABLE `phpbb_config_text`
ALTER TABLE `phpbb_migrations`
ALTER TABLE `phpbb_oauth_accounts`

我不能说我万事大吉了,但上述方法解决了我的初始数据库错误,并且导入正在运行:

#import_phpbb3.sh
The phpBB3 import is starting...

Loading existing groups...
Loading existing users...
Loading existing categories...
Loading existing posts...
Loading existing topics...

importing from phpBB 3.3.8

creating users
      722 / 5014 ( 14.4%)  [58 items/min]

更新:
导入脚本在 9 小时 28 分钟后完成。谢天谢地有 Screen。这个脚本太棒了!

现在正在进行后期处理。

导入脚本的输出是否有日志记录在某个地方,或者我应该将其管道传输到文件中?

3 个赞

在 WSL 中的 Docker 容器内运行 discourse_dev 时,应使用哪种 phpbb3 导入程序?

我尝试了程序 1. 使用 Docker 容器导入和程序 2. 使用开发环境导入。两者都未能成功,尽管我在程序 1 下成功运行了脚本,但尽管许多查询似乎都已成功,但没有任何数据实际进入论坛数据库。是否存在一个不同的数据库被填充,因为导入在其自己的容器中运行,与 discourse_dev 容器分离?

在程序 2 的情况下,根本无法执行构建,它因“安装 tiny_tds (2.1.5) 时出错,Bundler 无法继续。”而失败。

我应该尝试在 WSL 中进行“标准安装”(非 Docker,非开发环境),然后进行基于 Docker 的导入吗?

1 个赞

我推荐这样做。我现在很少在开发环境进行迁移了。

另外,除非你使用的是mssql而不是mysql/mariadb,否则你不需要tiny_tds。

1 个赞

非常感谢你,Jay。你的教程非常准确,我真的很感激有它们。

2 个赞

我在新的 VPS 上使用标准的 Docker 安装流程成功安装了 Discourse。然后我按照这些说明运行了导入过程,脚本顺利完成。我退出了容器,然后执行了停止导入命令,收到了以下消息:

''您在 /var/lib/docker 所在的磁盘上剩余的可用空间不到 5GB。您需要更多空间才能继续
文件系统 大小 已用可用容量使用%挂载点
/dev/vda1 24G 20G 2.7G 89% /

您想尝试通过清理系统中的 docker 镜像和容器来恢复空间吗? (y/N)‘’

恢复空间没有产生额外的空间。那么如何继续?我可以安全地删除我上传到 /data 的所有镜像文件吗?我不确定它们是否仍然需要。

谢谢。

1 个赞

如果导入似乎已完成,并且您正在谈论应该已导入的图片,那应该没问题,但您可能没有足够的空间进行备份。我建议升级您的 droplet 以获得更多空间。每天的价格应该不会有太大影响。

1 个赞

感谢您的建议,Jay。

为了方便他人参考,我删除了(仅)图片文件,释放了约 3.4 GB 的空间,总可用空间达到 6.1 GB,然后 Sidekiq 成功完成了后续处理。此后,磁盘空间又增加了 20 GB。

记录一下,这是一次从 phpBB 3.3.0 版本论坛导入的数据,包含略多于 73,000 篇帖子,略多于 8,000 个主题,以及略多于 1300 个用户。

到目前为止,我发现的唯一问题是一些用户名有点奇怪,但这已经在上面讨论过,并非致命问题。

本次导入和关闭源 phpBB 论坛之间会有一段间隔。我可以保留导入的 Docker 容器,然后使用增量备份来迁移本次导入之后生成的帖子吗?

1 个赞

当我进行 phpBB 3.3.x 迁移时,为了进行最终导入,我将 phpBB 网站置于“维护模式”,使用 rsync 更新附件、头像和表情符号,然后导入新的数据转储,并需要重建导入以运行最终导入脚本,但我在此之前退出了导入。

@DonH 你导入了 phpBB 密码并使用 Migrate Passwords 插件使其生效了吗?

2 个赞

我没有导入 phpBB 密码是出于几个原因。我希望避免与插件产生潜在冲突,并且我希望强制用户升级他们的密码,这次迁移似乎是一个好方法(也是一个好借口)。phpBB 网站托管的安全由托管公司处理,而新的 VPS 没有这种便利。

需要说明的是,您是最后一次重新导入了整个数据库,而不是进行增量更新?

1 个赞

我的理解和经验是,如果您从 phpMyAdmin 等工具导出 phpBB 论坛的数据库转储文件,将其上传到 /var/discourse/shared/standalone/import/data,然后重建导入并重新运行导入命令,迁移脚本将不会触及已导入的用户帐户、帖子等,只会处理先前未导入的数据库条目。

本质上,它是在进行增量更新,但它不会触及现有条目,因此您可能会丢失一些数据;例如,如果用户编辑了已导入的帖子或更改了他们的电子邮件地址。

1 个赞

如果您不勾选插件设置 migratepassword_allow_insecure_passwords,那么 migratepassword 插件将不允许迁移被 Discourse 视为不安全的密码,从而遵守所有复杂性设置,例如最小长度和唯一字符。

我不确定您指的是哪种类型的插件冲突?

2 个赞

@RGJ migratepassword 插件是否支持 phpBB 3.3?

我正在使用 phpBB 3.3.8 论坛进行导入,并且正在导入密码来尝试一下。

1 个赞

您将如何从 myBB 迁移?

1 个赞

您可以搜索 myBB 和标签 #migration::tag,也许您会找到一个 howto

2 个赞

好的,谢谢你的信息!

1 个赞

感谢理查德的澄清。我并不是指任何具体的冲突,只是在不熟悉的地形中可能发生意外情况。我在添加任何插件之前故意进行了导入。但最重要的是,我想强制我们的会员升级他们的密码。

这次迁移确实进行得很顺利,所以要归功于格哈德和所有参与编写脚本的人。我期待着定制我们的新论坛。

2 个赞

是的,它支持。我们最近在插件中添加了 Argon2 支持。

4 个赞

Richard 在他的主机上支持该插件。我从未听说过它会引起问题。许多导入器导入密码并且它就能正常工作。我甚至用它为一个我为其他随机论坛编写的导入脚本编写了代码。

1 个赞