vBulletin 5 Datenbankmigration - Import-Skriptfehler

Okay, eine kurze Zusammenfassung.

Ich bin ein Freiwilliger, der bei der Migration eines Forums hilft, das derzeit auf vbulletin3 läuft.
Auf einer Staging-Umgebung, beginnend mit einem Datenbank-Dump (20 GB, Sie haben richtig gelesen).

Führen Sie das Upgrade auf vBulletin 5 durch. Dies dauerte 5-6 Stunden, aber es hat funktioniert. Die Version ist vBulletin 5.4.
Einige Bereinigungen der Benutzernamen wurden vorgenommen, damit sie von Discourse akzeptiert werden.

Jetzt habe ich Docker Discourse installiert und mich lose an dieser Anleitung für die Vorbereitung orientiert. Lose bedeutet, dass die meiste davon überflüssig oder veraltet war, aber es half, eine Vorstellung davon zu bekommen, was zu tun ist.

Ich bin an dem Punkt angelangt, an dem ich buchstäblich blind werde, da ich fast keine Ruby-Programmiererfahrung habe.
Die relevanten Teile, nachdem die Installation abgeschlossen war, bin ich mit ./launcher enter app in den Container eingestiegen, dann:

  • freetds-dev und libmariadb-dev hinzugefügt
  • Die Gemfile bearbeitet, um die php_serialize-Gem hinzuzufügen.
  • Von der Shell aus export IMPORT=1 ausgeführt, um die Umgebung für den Import einzustellen.
  • Als discourse-Benutzer bundle install --no-deployment --without test --without development --path vendor/bundle ausgeführt.

Folgender Fehler trat auf:

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

Also weiter mit:

  • bundle config unset deployment und erneutes Ausführen des vorherigen Befehls
  • Überprüft, ob sowohl mysql2 als auch php_serialize vorhanden waren (was sie waren)
  • Die alten Foren-Avatare hinzugefügt (keine Anhänge zu importieren) und die Verzeichnisse dem discourse-Benutzer in seinem eigenen /home/discourse zugeordnet.
  • script/import_scripts/vbulletin5.rb bearbeitet, um die Referenz für die Verbindung zur DB zu ändern.
  • Als Benutzer discourse bundle exec ruby script/import_scripts/vbulletin5.rb ausgeführt.

Dies gab mir einen Fehler bezüglich tzinfo Integer values not supported zurück, der hier in diesem Discourse erwähnt wurde.

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)

@Haddoqs Vorschlag war, eine Zeile von Time.zone.at(@tz.utc_to_local(timestamp)) in Time.zone.at(timestamp) zu ändern.

Es wird auch vorgeschlagen, lastvisit in die Benutzerabfrage aufzunehmen, da es sonst zu einem weiteren Fehler kommt, was ich auch getan habe.

Wenn ich nun die Migration mit bundle exec ruby script/import_scripts/vbulletin5.rb starte, erhalte ich Folgendes:

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

An diesem Punkt bin ich etwas ratlos. Kann mir jemand helfen?

paging @Canapin, da er in “Migration Vietnam” war und vielleicht mehr weiß :heart:

Es stellt sich heraus, dass es schlecht ist, 8+ Stunden am Stück an etwas zu arbeiten.

Als ich u.lastvisit am Ende von SELECT u.userid, u.username, u.homepage, u.usertitle, u.usergroupid, u.joindate, u.email, hinzufügte, vergaß ich, danach ein , hinzuzufügen.

Entschuldige Canapin für die Benachrichtigung :frowning:

1 „Gefällt mir“

Alles klar, Folgeproblem. Die Anleitung, der ich gefolgt bin, besagte, dass der Registrierungsprozess neu gestartet werden könne, wenn er langsamer werde.

Aber als ich ihn neu startete, erhielt ich Fehler, dass Benutzer bereits in der Postgres-DB vorhanden seien.

Wie dumm von mir, ich habe alle Benutzer mit id > 1 in der DB gelöscht (im Grunde nur den Discobot, das System und den Admin übrig gelassen) und neu gestartet. Das lässt den Import fortsetzen, aber die E-Mails aller zuvor erstellten Benutzer sind irgendwo als „bereits verwendet“ markiert.

Was kann ich tun, um das zu bereinigen, und sollte dieser Prozess nicht stattdessen die Einfügung überspringen, wenn bereits ein passender Benutzername vorhanden ist?

Bearbeiten: Alles klar, ich habe herausgefunden, dass ich users, email_tokens und user_emails löschen muss.

1 „Gefällt mir“

Leider habe ich nicht verfolgt, was ich bei meinen früheren Importen geändert habe, daher habe ich wenig Wissen. Ich habe jetzt eine persönliche Discourse-Instanz, in der ich diese Art von Dingen schreibe… Das hätte ich schon früher tun sollen!
Ich bin besser im Importieren, wenn ich gerade an einem arbeite.

Was die Zerstörung von Benutzern angeht, hätten Sie vielleicht UserDestroyer über die Rails-Konsole verwenden wollen:

2 „Gefällt mir“

Großartige Arbeit, das werde ich für die „echte“ Migration im Hinterkopf behalten. Vorerst mache ich nur einen Testlauf des gesamten Prozesses, während ich ein Runbook schreibe :slight_smile:

1 „Gefällt mir“

Warum hast du das getan? Es sei denn, du hast etwas am Skript geändert, das diese anders importieren würde, dann solltest du es einfach neu starten und es die importieren lassen, die noch nicht importiert wurden.

Wenn du neu anfangen musst, ist es viel einfacher, ein Backup wiederherzustellen oder eine neue Datenbank zu löschen und zu erstellen.

Es sollte die Import-IDs in der Tabelle UserCustomFields finden. Ich bin mir nicht ganz sicher, wie du diesen Fehler bekommen hast.

Die Änderungen sind die, die ich aufgelistet habe. Ich bin genauso überrascht wie du, aber das Skript konnte nicht fortgesetzt werden und gab einfach einen Fehler aus und stoppte.

Gibt es eine Möglichkeit, den Import zu beschleunigen?

Ich habe über 90.000 Benutzer in dieser Community und die Importgeschwindigkeit nimmt aus irgendeinem Grund mit der Zeit ab, und ich kann mir nicht vorstellen, warum.

Er lief die ganze Nacht und nur für die Benutzer sind wir bei 25123 / 95635 ( 26,3%) [42 Elemente/Min]

Es gibt um mehrere Größenordnungen mehr Beiträge. Wie lange sollte ich erwarten, dass eine Migration dauert? Tage? Wochen?

Wie viel RAM? Das ist wahrscheinlich das Problem. Sie können anhalten und neu starten.

Ich habe sie schon Wochen dauern sehen. Deshalb gibt es Massenimporteure.

Er hat nur 2 GB RAM. Es ist eine Testmaschine. Ich könnte es lokal statt einer VM ausführen (wären 16 GB RAM so viel besser?) und dann alles verpacken und schließlich hochladen, schätze ich.

Können Sie Massenimporteure näher erläutern? Ich höre zum ersten Mal davon und es hätte definitiv auftauchen sollen, als ich bei Google nach „vBulletin nach Discourse migrieren“ gesucht habe :angry:

Frustrierter Jason Segel GIF von NETFLIX

Kann ich das ausführen, auch wenn der andere Importeur bereits einige Benutzer verarbeitet hat, oder sollte ich aufräumen?

Ich habe es versucht, im schlimmsten Fall funktioniert es nicht. Ich werde zugespammt mit

ERROR: keine implizite Konvertierung von nil in 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>'

Ich gehe davon aus, dass ich Benutzer und Gruppen bereinigen sollte, die die einzigen Dinge sind, die der andere Importeur erstellt/zu erstellen begonnen hat.

Bevor ich wieder in der Datenbank herumfummele, gibt es einen Ruby-Befehl, den ich ausführen kann, der das auf saubere Weise erledigt?

Für dieses Mal werde ich einfach die Discourse-Installation zerstören und neu erstellen. Gott sei Dank für Docker.

Nein, saubere Installation, das Skript schlägt immer noch mit diesem generischen Fehler fehl

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>'

Gibt es eine Möglichkeit, dies zu debuggen, damit ich zumindest verstehen kann, welcher Wert nil ist und etwas anderes sein sollte?

Ok, der Fehler scheint mit der Kodierung zusammenzuhängen.
In bulk_import/vbulletin5.rb kann ich die Kodierung angeben (in unserem Fall UTF8mb4, aber in der Datei base.rb scheint sie nichts in der Zeichensatzzuordnung abzubilden.

Hallo!

Einige allgemeine Tipps:

  1. Wenn Sie Änderungen am Skript vornehmen, ist es generell ratsam, von vorne zu beginnen oder zumindest von einem bekannten guten Punkt aus. Am einfachsten geht das, indem Sie ein Backup wiederherstellen, das kurz vor der Ausführung der Migration erstellt wurde, wie @pfaffman sagte.
  2. Massenimporteure benötigen im Allgemeinen viel weniger Zeit, aber dieser spezielle Import hat das Potenzial, RIESIGE Mengen an RAM zu verbrauchen, da er Dinge im Speicher zwischenspeichert. Bei einer bestimmten vBulletin-Massenmigration, die ich von einer 2 GB großen SQL-Datei unkomprimiert durchgeführt habe, benötigte der Prozess 22 GB RAM (doppelt geprüft, kein Tippfehler).
  3. Wenn Sie Änderungen am Skript vornehmen, schlage ich vor, dass Sie eine Testversion der Eingabe mit z. B. 100 oder 1000 Datensätzen für jede Tabelle erstellen (achten Sie jedoch auf referentielle Integrität – d. h. kürzen Sie keine Tabellen, auf die von anderen Tabellen verwiesen wird). Das Testen von Änderungen mit einem Prozess, der länger als 8 Stunden dauert, wird Ihre geistige Gesundheit sehr schnell zermürben.

Ein spezifischerer Tipp zu Stacktraces: Achten Sie auf Zeilen, die sich auf die spezifische Datei beziehen, die Sie ausgeführt haben. In diesem Fall handelt es sich tatsächlich um ein Codierungsproblem, aber relevanter ist die Tatsache, dass es um Benutzernamen geht:

Sie sagten, Sie müssten Benutzernamen bereinigen, daher würde ich noch einmal überprüfen, ob Sie sie wie vom Skript erwartet codiert haben.

2 „Gefällt mir“

Sie können die Datenbank einfach löschen, erstellen und migrieren, anstatt Discourse neu zu erstellen. Es ist jedoch etwas knifflig, da Sie

  sv stop unicorn

und dann

  rake db:drop db:create db:migrate

ausführen müssen. Es wird sich beschweren und Ihnen mitteilen, dass Sie eine Umgebungsvariable festlegen müssen, die Sie in die Zeile vor der Rake-Aufgabe einfügen müssen.

Sie können auch ein Backup wiederherstellen, was bequemer sein kann.

FWIW, ich glaube nicht, dass ich jemals ein Massenmigrationsskript verwendet habe.

1 „Gefällt mir“

Das ist noch seltsamer, da die Benutzernamen alle bereinigt wurden, um die Discourse-Richtlinien einzuhalten. Im Grunde wurden sie alle so geändert, dass sie nur Buchstaben, Zahlen oder _ enthalten, nichts anderes.

Auf jeden Fall hat die Änderung des Charsets von utf8mb4 zu utf8, wie es der Standard war, dazu geführt, dass es durchging, aber dann erhalte ich Fehler wegen ungültiger E-Mails

ERROR: kann die eingefrorene Zeichenkette nicht ändern: "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>'

Ich werde jetzt herausfinden, worum es dabei geht, da der “Nicht-Massen”-Import einige fehlerhafte E-Mails erkannt, sie aber automatisch ersetzt hat.

Nachdem Sie dies getan haben, erstellen Sie einfach ein Backup Ihrer leeren, makellosen Discourse-Installation.
Sie können dieses jederzeit sehr schnell wiederherstellen und neu beginnen.

2 „Gefällt mir“

Um dem hinzuzufügen, wenn Sie beispielsweise Probleme mit dem Import von Beiträgen haben, könnten Sie das Skript auch beenden, nachdem der Benutzerimport zufriedenstellend abgeschlossen wurde, und ein weiteres Backup erstellen. Dann können Sie das Skript neu starten und dort fortfahren, wo Sie die Benutzer bereits importiert haben.

1 „Gefällt mir“