Сначала я хочу извиниться перед всеми, кто может почувствовать себя атакованным этим постом, потому что, честно говоря, я борюсь с этими проблемами с понедельника, и к этому моменту я устал от отладки и горячих исправлений кода Discourse.
После N-й попытки (перестал считать после седьмой) я думаю, что сдамся, потому что, похоже, миграция — это то, на что Discourse не потратил много времени для поддержки.
Я считаю, что главная проблема в том, что кодировка, используемая в этой огромной базе данных, — utf8mb4, которая, возможно, не поддерживается скриптом.
Использование utf8 (по умолчанию) просто генерирует множество ошибок, о которых сообщается, но неясно, что происходит, так как скрипт продолжает работу. Запись в БД пропускается? Копируется с некоторыми неподдерживаемыми символами (классические квадратики)?
Кроме того, три последних запуска (с использованием пакетных импортеров) с точно таким же набором инструкций дали разные результаты. Этот последний запуск дошел до импорта тем, сразу начал сообщать об ошибках, но продолжил работу (???):
Loading application...
Starting...
Preloading I18n...
Fixing highest post numbers...
Loading imported group ids...
Loading imported user ids...
Loading imported category ids...
Loading imported topic ids...
Loading imported post ids...
Loading groups indexes...
Loading users indexes...
Loading categories indexes...
Loading topics indexes...
Loading posts indexes...
Loading post actions indexes...
Importing categories...
Importing parent categories...
5 - 1104/sec
Importing children categories...
500 - 1539/secERROR: duplicate key value violates unique constraint "unique_index_categories_on_name"
DETAIL: Key (COALESCE(parent_category_id, '-1'::integer), name)=(-1, Armata Brancaleone) already exists.
CONTEXT: COPY categories, line 69
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/pg-1.4.5/lib/pg/connection.rb:204:in `get_last_result'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/pg-1.4.5/lib/pg/connection.rb:204:in `copy_data'
/var/www/discourse/script/bulk_import/base.rb:720:in `create_records'
/var/www/discourse/script/bulk_import/base.rb:361:in `create_categories'
script/bulk_import/vbulletin5.rb:291:in `import_categories'
script/bulk_import/vbulletin5.rb:69:in `execute'
/var/www/discourse/script/bulk_import/base.rb:98:in `run'
script/bulk_import/vbulletin5.rb:779:in `<main>'
Importing topics...
600 - 4073/sec
ERROR: undefined method `[]' for nil:NilClass
/var/www/discourse/script/bulk_import/base.rb:513:in `process_topic'
/var/www/discourse/script/bulk_import/base.rb:724: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:721: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:720:in `create_records'
/var/www/discourse/script/bulk_import/base.rb:364:in `create_topics'
script/bulk_import/vbulletin5.rb:321:in `import_topics'
script/bulk_import/vbulletin5.rb:70:in `execute'
/var/www/discourse/script/bulk_import/base.rb:98:in `run'
script/bulk_import/vbulletin5.rb:779:in `<main>'
Наконец, он упал на этом:
script/bulk_import/vbulletin5.rb:779:in `<main>'
572329 - 531/sec
Importing replies...
client_loop: send disconnect: Connection reset
Но не прежде, чем практически постоянно спамить этими двумя ошибками влево и вправо:
ERROR: undefined method `gsub!' for nil:NilClass
script/bulk_import/vbulletin5.rb:727:in `preprocess_raw'
script/bulk_import/vbulletin5.rb:369:in `block in import_topic_first_posts'
/var/www/discourse/script/bulk_import/base.rb:723: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:721: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:720:in `create_records'
/var/www/discourse/script/bulk_import/base.rb:367:in `create_posts'
script/bulk_import/vbulletin5.rb:361:in `import_topic_first_posts'
script/bulk_import/vbulletin5.rb:71:in `execute'
/var/www/discourse/script/bulk_import/base.rb:98:in `run'
script/bulk_import/vbulletin5.rb:779:in `<main>'
и
ERROR: invalid byte sequence in UTF-8
script/bulk_import/vbulletin5.rb:727:in `gsub!'
script/bulk_import/vbulletin5.rb:727:in `preprocess_raw'
script/bulk_import/vbulletin5.rb:369:in `block in import_topic_first_posts'
/var/www/discourse/script/bulk_import/base.rb:723: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:721: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:720:in `create_records'
/var/www/discourse/script/bulk_import/base.rb:367:in `create_posts'
script/bulk_import/vbulletin5.rb:361:in `import_topic_first_posts'
script/bulk_import/vbulletin5.rb:71:in `execute'
/var/www/discourse/script/bulk_import/base.rb:98:in `run'
script/bulk_import/vbulletin5.rb:779:in `<main>'
Обратите внимание, что я шел шаг за шагом, закомментировывая, какую функцию запускать, затем выполняя rake import:ensure_consistency перед продолжением, закомментировав те, которые уже были выполнены, и так далее, потому что если я просто позволю всему скрипту перезапустить ранее выполненные шаги, он просто упадет, найдя дублирующиеся ID.
Прежде чем появится обычный аргумент «вы не можете жаловаться на бесплатное ПО», я хочу уточнить, что я вношу вклад в другие проекты с открытым исходным кодом и также создаю бесплатное программное обеспечение, но для меня крайне важно, чтобы если я выпускаю что-то, это что-то работало и было хорошо документировано (даже просто чтобы избежать тысяч сообщений, справедливо спрашивающих «как это работает»), или я готов исправить любую ошибку, которая возникнет.
Хотя у Discourse, кажется, отличный опыт «из коробки», должно быть совершенно ясно, что сейчас 2022 год, и сообщества существовали задолго до этого продукта. «Принятие» потребовало бы мощной поддержки миграции, и, похоже, это не текущее состояние для Discourse.
Я признаю, что база данных объемом 20 ГБ — это крайний случай, но у нас здесь нет проблем с размером, скорее с кодировкой или кто знает чем еще, так как нет даже постоянной ошибки, и в большинстве случаев: нет никакой документации, кроме как искать темы и сообщения, оставленные теми, кто прошел через те же испытания в прошлом, надеясь, что был найден обходной путь и что исходный код с тех пор сильно не изменился.
На данном этапе я настоятельно рекомендую всем, кто переходит с vBulletin, воздержаться от любой миграции до тех пор, пока не будет завершена, по-видимому, уже начавшаяся полная переработка скриптов миграции.