Crius
(Crius)
2022 年12 月 20 日 17:22
1
好的,快速回顾一下。
我正在从一个目前使用 vbulletin3 的论坛迁移。
在一个暂存环境中,从数据库转储开始(20GB,你没看错)。
运行升级到 vBulletin 5。花费了 5-6 小时,但成功了。版本是 vBulletin 5.4。
对用户名进行了一些清理,以便 Discourse 可以接受。
现在,安装了 docker discourse ,并大致遵循了 此指南 进行准备。大致意思是,其中大部分是多余的或过时的,但它有助于了解该怎么做。
我现在处于一个我完全看不懂的步骤,因为我几乎没有 Ruby 编码经验。
所以,相关部分是,在完成安装后,我使用 ./launcher enter app 进入容器,然后:
添加了 freetds-dev 和 libmariadb-dev
编辑了 Gemfile 以添加 php_serialize gem。
从 shell 运行 export IMPORT=1 来设置导入的环境
以 discourse 用户身份运行 bundle install --no-deployment --without test --without development --path vendor/bundle
出现了错误:
You are trying to install in deployment mode after changing
your Gemfile. Run `bundle install` elsewhere and add the
updated Gemfile.lock to version control.
If this is a development machine, remove the /var/www/discourse/Gemfile freeze
by running `bundle config unset deployment`.
The list of sources changed
The dependencies in your gemfile changed
You have added to the Gemfile:
* mysql2
* redcarpet
* php_serialize
* sqlite3 (>= 1.3, ~> 1.3.13)
* ruby-bbcode-to-md
* reverse_markdown
* tiny_tds
* csv
* parallel
所以,继续执行:
bundle config unset deployment 并再次运行之前的命令
检查了 mysql2 和 php_serialize 是否都存在(它们存在)
添加了旧论坛的头像(没有附件需要导入),并将目录所有权分配给 discourse 用户在其自己的 /home/discourse 下
编辑了 script/import_scripts/vbulletin5.rb 以更改连接到数据库的引用
以用户 discourse 身份运行 bundle exec ruby script/import_scripts/vbulletin5.rb
这给了我一个关于 tzinfo Integer values not supported 的错误,我在 这里 的 discourse 上找到了提及。
Loading existing groups...
Loading existing users...
Loading existing categories...
Loading existing posts...
Loading existing topics...
importing groups...
41 / 41 (100.0%) [2294 items/min] ]
importing users
Traceback (most recent call last):
15: from script/import_scripts/vbulletin5.rb:726:in `<main>'
14: from /var/www/discourse/script/import_scripts/base.rb:47:in `perform'
13: from script/import_scripts/vbulletin5.rb:46:in `execute'
12: from script/import_scripts/vbulletin5.rb:79:in `import_users'
11: from /var/www/discourse/script/import_scripts/base.rb:916:in `batches'
10: from /var/www/discourse/script/import_scripts/base.rb:916:in `loop'
9: from /var/www/discourse/script/import_scripts/base.rb:917:in `block in batches'
8: from script/import_scripts/vbulletin5.rb:98:in `block in import_users'
7: from /var/www/discourse/script/import_scripts/base.rb:264:in `create_users'
6: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/mysql2/alias_method.rb:8:in `each'
5: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/mysql2/alias_method.rb:8:in `each'
4: from /var/www/discourse/script/import_scripts/base.rb:265:in `block in create_users'
3: from script/import_scripts/vbulletin5.rb:110:in `block (2 levels) in import_users'
2: from script/import_scripts/vbulletin5.rb:718:in `parse_timestamp'
1: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/tzinfo-2.0.5/lib/tzinfo/timezone.rb:575:in `utc_to_local'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/tzinfo-2.0.5/lib/tzinfo/timestamp.rb:138:in `for': Integer values are not supported (ArgumentError)
@Haddoq 的建议是将一行代码从 Time.zone.at(@tz.utc_to_local(timestamp)) 更改为 Time.zone.at(timestamp)。
它还建议添加 lastvisit 到用户查询中,因为否则会导致另一个错误,我也这样做了。
然而,现在当我用 bundle exec ruby script/import_scripts/vbulletin5.rb 启动迁移时,我得到以下结果:
Loading existing groups...
Loading existing users...
Loading existing categories...
Loading existing posts...
Loading existing topics...
importing groups...
41 / 41 (100.0%) [120217 items/min]
importing users
Traceback (most recent call last):
13: from script/import_scripts/vbulletin5.rb:727:in `<main>'
12: from /var/www/discourse/script/import_scripts/base.rb:47:in `perform'
11: from script/import_scripts/vbulletin5.rb:46:in `execute'
10: from script/import_scripts/vbulletin5.rb:79:in `import_users'
9: from /var/www/discourse/script/import_scripts/base.rb:916:in `batches'
8: from /var/www/discourse/script/import_scripts/base.rb:916:in `loop'
7: from /var/www/discourse/script/import_scripts/base.rb:917:in `block in batches'
6: from script/import_scripts/vbulletin5.rb:80:in `block in import_users'
5: from script/import_scripts/vbulletin5.rb:723:in `mysql_query'
4: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/mysql2/alias_method.rb:22:in `query'
3: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/mysql2-0.5.4/lib/mysql2/client.rb:147:in `query'
2: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/mysql2-0.5.4/lib/mysql2/client.rb:147:in `handle_interrupt'
1: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/mysql2-0.5.4/lib/mysql2/client.rb:148:in `block in query'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/mysql2-0.5.4/lib/mysql2/client.rb:148:in `_query': You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'CASE WHEN u.scheme='blowfish:10' THEN token (Mysql2::Error)
WHEN u.scheme='lega' at line 2
这时我有点迷茫了。有人能帮忙吗?
Crius
(Crius)
2022 年12 月 20 日 17:29
2
paging @Canapin as he’s been in “Migration Vietnam” and might know more
Crius
(Crius)
2022 年12 月 20 日 17:50
3
连续工作 8 小时以上是坏的。
在 SELECT u.userid, u.username, u.homepage, u.usertitle, u.usergroupid, u.joindate, u.email, 的末尾添加 u.lastvisit 时,我忘记在后面添加逗号 ,。
抱歉打扰 Canapin
1 个赞
Crius
(Crius)
2022 年12 月 20 日 18:31
4
好的,又一个后续问题。我之前遵循的指南提到,如果注册过程变慢,可以重新启动它。
但是重新启动后,我收到了关于用户已存在于 postgres 数据库中的错误。
我太傻了,我删除了数据库中所有 id > 1 的用户(基本上只留下 discobot、system 和 admin),然后重新启动。这使得导入继续进行,但所有先前创建的用户电子邮件都被标记为“已使用”。
我该如何清理它,并且这个过程不应该在用户名匹配时跳过插入吗?
编辑:好的,我发现我需要清理 users、email_tokens 和 user_emails。
1 个赞
Canapin
(Coin-coin le Canapin)
2022 年12 月 20 日 19:30
5
不幸的是,我没有跟踪我在之前的导入中调整过的内容,所以我知之甚少。我现在有一个个人 Discourse 实例,我可以在其中编写这类东西……我应该早点这样做的!
当我实际处理导入时,我对导入内容更在行。
至于删除用户,你可能想通过 rails 控制台使用 UserDestroyer:
UserDestroyer is what you should use. It will delete other data associated with the user.
Don’t know why you’d get that error.
You might restore your backup to before you started the delete and try the destroyer instead.
2 个赞
Crius
(Crius)
2022 年12 月 20 日 20:22
6
很棒,我会在“真正”迁移时记住这一点。现在我只是在编写运行手册时对整个过程进行试运行
1 个赞
pfaffman
(Jay Pfaffman)
2022 年12 月 20 日 22:28
7
你为什么这么做?除非你更改了脚本中导入这些用户的不同方式,否则你应该直接重新启动,让它导入那些尚未导入的用户。
如果你确实需要从头开始,恢复备份或删除并创建一个新数据库要容易得多。
它应该能在 UserCustomFields 表中找到导入 ID。我不太确定你是如何遇到那个错误的。
Crius
(Crius)
2022 年12 月 20 日 23:02
8
Jay Pfaffman:
你为什么那样做?
更改是我列出的那些。我很惊讶,但脚本无法继续,只会出错并停止。
Crius
(Crius)
2022 年12 月 21 日 10:06
9
导入是否有办法加速?
我的社区有超过 90,000 名用户,但导入速度不知何故会随着时间的推移而下降,我无法想象原因。
它运行了一整夜,仅用户我们就达到了 25123 / 95635 ( 26.3%) [42 items/min]
帖子的数量是用户数量的好几个数量级。我应该期望迁移需要多长时间?几天?几周?
pfaffman
(Jay Pfaffman)
2022 年12 月 21 日 11:40
11
内存多少?这很可能是问题所在。你可以停止并重启。
我曾遇到过需要几周时间的情况。这就是为什么需要批量导入程序。
Crius
(Crius)
2022 年12 月 21 日 13:54
12
Jay Pfaffman:
这就是为什么存在批量导入器。
它只有 2GB 内存。这是一台测试机器。我可以在本地运行它,而不是在虚拟机中运行(16GB 内存会好很多吗?),然后打包所有东西并最终上传,我想。
你能详细介绍一下批量导入器吗?我第一次听说它,在我用谷歌搜索“将 vBulletin 迁移到 Discourse”时,它肯定应该弹出:“愤怒”
Crius
(Crius)
2022 年12 月 21 日 14:22
14
即使另一个导入器已经处理了一些用户,我也可以运行这个,还是应该清理一下?
Crius
(Crius)
2022 年12 月 21 日 14:33
15
我已经尝试过了,最坏的情况是它不起作用。我不断收到垃圾邮件:
ERROR: no implicit conversion of nil into String
/var/www/discourse/script/bulk_import/base.rb:861:in `encode'
/var/www/discourse/script/bulk_import/base.rb:861:in `normalize_charset'
/var/www/discourse/script/bulk_import/base.rb:856:in `normalize_text'
script/bulk_import/vbulletin5.rb:123:in `block in import_users'
/var/www/discourse/script/bulk_import/base.rb:725:in `block (2 levels) in create_records'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/mysql2/alias_method.rb:8:in `each'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/mysql2/alias_method.rb:8:in `each'
/var/www/discourse/script/bulk_import/base.rb:723:in `block in create_records'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/pg-1.4.5/lib/pg/connection.rb:196:in `copy_data'
/var/www/discourse/script/bulk_import/base.rb:722:in `create_records'
/var/www/discourse/script/bulk_import/base.rb:340:in `create_users'
script/bulk_import/vbulletin5.rb:120:in `import_users'
script/bulk_import/vbulletin5.rb:63:in `execute'
/var/www/discourse/script/bulk_import/base.rb:100:in `run'
script/bulk_import/vbulletin5.rb:781:in `<main>'
我猜我应该清理一下用户和组,这是其他导入器创建/开始创建的唯一内容。
在我再次弄乱数据库之前,有没有什么 Ruby 命令可以干净地处理这个问题?
这次我将继续销毁并重新创建 Discourse 安装。感谢 Docker。
Crius
(Crius)
2022 年12 月 21 日 15:36
16
不,是干净的安装,脚本仍然会因这个通用错误而失败
ERROR: no implicit conversion of nil into String
/var/www/discourse/script/bulk_import/base.rb:861:in `encode'
/var/www/discourse/script/bulk_import/base.rb:861:in `normalize_charset'
/var/www/discourse/script/bulk_import/base.rb:856:in `normalize_text'
script/bulk_import/vbulletin5.rb:123:in `block in import_users'
/var/www/discourse/script/bulk_import/base.rb:725:in `block (2 levels) in create_records'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/mysql2/alias_method.rb:8:in `each'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/mysql2/alias_method.rb:8:in `each'
/var/www/discourse/script/bulk_import/base.rb:723:in `block in create_records'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/pg-1.4.5/lib/pg/connection.rb:196:in `copy_data'
/var/www/discourse/script/bulk_import/base.rb:722:in `create_records'
/var/www/discourse/script/bulk_import/base.rb:340:in `create_users'
script/bulk_import/vbulletin5.rb:120:in `import_users'
script/bulk_import/vbulletin5.rb:63:in `execute'
/var/www/discourse/script/bulk_import/base.rb:100:in `run'
script/bulk_import/vbulletin5.rb:781:in `<main>'
有什么办法可以调试这个问题,至少让我知道哪个值是 nil 而不是预期的值吗?
好的,错误似乎与编码有关。
在 bulk_import/vbulletin5.rb 中,我可以指定编码(在我们的例子中是 UTF8mb4,但在 base.rb 文件中,它似乎没有映射到字符集映射中的任何内容
module BulkImport; end
class BulkImport::Base
NOW ||= "now()"
PRIVATE_OFFSET ||= 2**30
# rubocop:disable Layout/HashAlignment
CHARSET_MAP = {
"armscii8" => nil,
"ascii" => Encoding::US_ASCII,
"big5" => Encoding::Big5,
"binary" => Encoding::ASCII_8BIT,
"cp1250" => Encoding::Windows_1250,
"cp1251" => Encoding::Windows_1251,
"cp1256" => Encoding::Windows_1256,
"cp1257" => Encoding::Windows_1257,
"cp850" => Encoding::CP850,
"cp852" => Encoding::CP852,
leonardo
(Leonardo Mosquera)
2022 年12 月 21 日 15:50
17
您好!
一些通用建议:
如果您对脚本进行了更改,通常建议从头开始,或者至少从一个已知的良好点开始。您可以按照 @pfaffman 所说,恢复迁移运行之前的备份,这是最简单的方法。
批量导入程序通常会花费更少的时间,但这个特定的程序可能会消耗大量的内存,因为它会在内存中缓存数据。我曾经从一个 2GB 未压缩的 SQL 文件迁移 vBulletin,该过程需要 22GB RAM(已仔细检查,不是笔误)。
如果您对脚本进行了更改,我建议您为输入创建一个测试版本,例如每个表包含 100 或 1000 条记录(但要注意引用完整性 - 即不要截断被其他表引用的表)。使用超过 8 小时的进程测试更改会很快让您精神崩溃。
关于堆栈跟踪的更具体建议:查找提及您运行的特定文件的行。在这种情况下,是的,这是一个编码问题,但更相关的是它与用户名有关:
end
end
def import_users
puts "Importing users..."
users = mysql_stream <<-SQL
SELECT u.userid, u.username, u.joindate, u.birthday,
u.ipaddress, u.usergroupid, ub.bandate, ub.liftdate, u.email
FROM #{DB_PREFIX}user u
LEFT JOIN #{DB_PREFIX}userban ub ON ub.userid = u.userid
WHERE u.userid > #{@last_imported_user_id}
ORDER BY u.userid
SQL
create_users(users) do |row|
u = {
imported_id: row[0],
username: normalize_text(row[1].truncate(60)),
name: normalize_text(row[1]),
email: row[8],
您说您必须清理用户名,所以我建议您仔细检查您是否按照脚本的预期对其进行了编码。
2 个赞
pfaffman
(Jay Pfaffman)
2022 年12 月 21 日 15:52
18
您可以直接删除、创建、迁移数据库,而不是重新创建 Discourse。不过,这有点棘手,因为您必须
sv stop unicorn
然后
rake db:drop db:create db:migrate
它会抱怨并告诉您设置一个 ENV 变量,您需要将其放在 rake 任务的前一行。
您也可以恢复备份,这可能更方便。
供您参考,我不认为我曾经使用过批量迁移脚本。
1 个赞
Crius
(Crius)
2022 年12 月 21 日 15:54
19
这更奇怪了,因为用户名都经过清理,以遵循 Discourse 的准则,基本上它们都被更改为仅包含字母、数字或下划线,没有其他字符。
无论如何,将字符集从 utf8mb4 更改为 utf8(这是默认设置)后,它就可以通过了,但现在我收到无效电子邮件的错误。
ERROR: can't modify frozen String: "24ef401b30f5161e5a0bb27ec49ed921@email.invalid"
/var/www/discourse/script/bulk_import/base.rb:457:in `downcase!'
/var/www/discourse/script/bulk_import/base.rb:457:in `process_user_email'
/var/www/discourse/script/bulk_import/base.rb:726:in `block (2 levels) in create_records'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/mysql2/alias_method.rb:8:in `each'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/mysql2/alias_method.rb:8:in `each'
/var/www/discourse/script/bulk_import/base.rb:723:in `block in create_records'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/pg-1.4.5/lib/pg/connection.rb:196:in `copy_data'
/var/www/discourse/script/bulk_import/base.rb:722:in `create_records'
/var/www/discourse/script/bulk_import/base.rb:351:in `create_user_emails'
script/bulk_import/vbulletin5.rb:151:in `import_user_emails'
script/bulk_import/vbulletin5.rb:66:in `execute'
/var/www/discourse/script/bulk_import/base.rb:100:in `run'
script/bulk_import/vbulletin5.rb:781:in `<main>'
我现在要去弄清楚这是怎么回事,因为“非批量”导入检测到了一些格式错误的电子邮件,但会自动替换它们。
RGJ
(Richard - Communiteq)
2022 年12 月 21 日 16:03
20
完成之后,只需备份您空置的、全新的 Discourse 安装。
您可以随时快速恢复它并重新开始。
2 个赞
RGJ
(Richard - Communiteq)
2022 年12 月 21 日 16:28
21
此外,如果您在导入帖子等方面遇到问题,也可以在用户导入成功完成后退出脚本,并创建另一个备份。然后,您可以重新启动脚本,并从已导入用户的时刻继续。
1 个赞