Wiederherstellung aufgrund beschädigter Indizes nicht möglich (mit Hinweisen zum Umgang mit beschädigten Indizes)

Dieses Backup ist mehrmals aufgrund von Fehlern wie diesem fehlgeschlagen:

ERROR:  could not create unique index "index_incoming_referers_on_path_and_incoming_domain_id"
DETAIL:  Key (path, incoming_domain_id)=(/@dataandme, 41) is duplicated.               
ERROR:  current transaction is aborted, commands ignored until end of transaction block

Ich habe manuell alle diese Datensätze in Rails entfernt, mit Befehlen wie:
IncomingReferer.where(path: ‘/@dataandme’).destroy_all

Trotzdem schlägt es immer noch fehl, und ich habe folgendes:

...
[2019-12-30 20:29:16] 'pfaffman' hat die Wiederherstellung gestartet!
[2019-12-30 20:29:16] Markiere Wiederherstellung als laufend...
[2019-12-30 20:29:16] Stelle sicher, dass /var/www/discourse/tmp/restores/default/2019-12-30-202916 existiert...
[2019-12-30 20:29:16] Lade Archiv in das tmp-Verzeichnis herunter...
[2019-12-30 20:29:38] Keine Metadatendatei zum Extrahieren vorhanden.
[2019-12-30 20:29:38] Validiere Metadaten...
[2019-12-30 20:29:38]   Aktuelle Version: 20191129144706
[2019-12-30 20:29:38]   Wiederherzustellende Version: 20191129144706
[2019-12-30 20:29:38] Extrahiere Dump-Datei...
[2019-12-30 20:30:07] Erstelle fehlende Funktionen im discourse_functions-Schema
[2019-12-30 20:30:08] Kann nicht in ein anderes Schema wiederhergestellt werden; Wiederherstellung im aktuellen Schema
[2019-12-30 20:30:08] Aktiviere Nur-Lese-Modus...
[2019-12-30 20:30:08] Pausiere Sidekiq...
[2019-12-30 20:30:08] Warte darauf, dass Sidekiq ausgeführte Jobs abschließt...
[2019-12-30 20:30:08] Stelle Dump-Datei wieder her... (kann ziemlich lange dauern)

 ----- und so weiter -----
[2019-12-30 20:33:17] ERROR:  current transaction is aborted, commands ignored until end of transaction block
[2019-12-30 20:33:17] ERROR:  current transaction is aborted, commands ignored until end of transaction block
[2019-12-30 20:33:17] EXCEPTION: psql failed
[2019-12-30 20:33:17] /var/www/discourse/lib/backup_restore/restorer.rb:331:in `restore_dump'
/var/www/discourse/lib/backup_restore/restorer.rb:75:in `run'
/var/www/discourse/lib/backup_restore.rb:166:in `block in start!'
/var/www/discourse/lib/backup_restore.rb:163:in `fork'
/var/www/discourse/lib/backup_restore.rb:163:in `start!'
/var/www/discourse/lib/backup_restore.rb:22:in `restore!'
/var/www/discourse/app/controllers/admin/backups_controller.rb:119:in `restore'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/abstract_controller/base.rb:196:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_controller/metal/rendering.rb:30:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/abstract_controller/callbacks.rb:42:in `block in process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.1/lib/active_support/callbacks.rb:135:in `run_callbacks'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/abstract_controller/callbacks.rb:41:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_controller/metal/rescue.rb:22:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_controller/metal/instrumentation.rb:33:in `block in process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.1/lib/active_support/notifications.rb:180:in `block in instrument'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.1/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.1/lib/active_support/notifications.rb:180:in `instrument'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_controller/metal/instrumentation.rb:32:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_controller/metal/params_wrapper.rb:245:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.1/lib/active_record/railties/controller_runtime.rb:27:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/abstract_controller/base.rb:136:in `process'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionview-6.0.1/lib/action_view/rendering.rb:39:in `process'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-mini-profiler-1.1.3/lib/mini_profiler/profiling_methods.rb:104:in `block in profile_method'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_controller/metal.rb:191:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_controller/metal.rb:252:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/routing/route_set.rb:51:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/routing/route_set.rb:33:in `serve'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/routing/mapper.rb:18:in `block in <class:Constraints>'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/routing/mapper.rb:48:in `serve'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/journey/router.rb:49:in `block in serve'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/journey/router.rb:32:in `each'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/journey/router.rb:32:in `serve'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/routing/route_set.rb:837:in `call'
/var/www/discourse/lib/middleware/omniauth_bypass_middleware.rb:68:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/tempfile_reaper.rb:15:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/conditional_get.rb:38:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/head.rb:12:in `call'
/var/www/discourse/lib/content_security_policy/middleware.rb:12:in `call'
/var/www/discourse/lib/middleware/anonymous_cache.rb:318:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/session/abstract/id.rb:232:in `context'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/session/abstract/id.rb:226:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/cookies.rb:648:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.1/lib/active_support/callbacks.rb:101:in `run_callbacks'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/callbacks.rb:26:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/actionable_exceptions.rb:17:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/debug_exceptions.rb:32:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/logster-2.4.2/lib/logster/middleware/reporter.rb:43:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.1/lib/rails/rack/logger.rb:38:in `call_app'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.1/lib/rails/rack/logger.rb:28:in `call'
/var/www/discourse/config/initializers/100-quiet_logger.rb:18:in `call'
/var/www/discourse/config/initializers/100-silence_logger.rb:31:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/request_id.rb:27:in `call'
/var/www/discourse/lib/middleware/enforce_hostname.rb:17:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/method_override.rb:22:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/executor.rb:14:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/sendfile.rb:111:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/host_authorization.rb:77:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-mini-profiler-1.1.3/lib/mini_profiler/profiler.rb:296:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/message_bus-2.2.3/lib/message_bus/rack/middleware.rb:57:in `call'
/var/www/discourse/lib/middleware/request_tracker.rb:181:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.1/lib/rails/engine.rb:526:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.1/lib/rails/railtie.rb:190:in `public_send'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.1/lib/rails/railtie.rb:190:in `method_missing'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/urlmap.rb:68:in `block in call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/urlmap.rb:53:in `each'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/urlmap.rb:53:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:605:in `process_client'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:700:in `worker_loop'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:548:in `spawn_missing_workers'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:144:in `start'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/bin/unicorn:128:in `<top (required)>'
/var/www/discourse/vendor/bundle/ruby/2.6.0/bin/unicorn:23:in `load'
/var/www/discourse/vendor/bundle/ruby/2.6.0/bin/unicorn:23:in `<main>'
[2019-12-30 20:33:17] Versuche Rollback...
[2019-12-30 20:33:17] Führe Rollback durch...
[2019-12-30 20:33:17] Räum auf...
[2019-12-30 20:33:17] Lösche Funktion aus dem discourse_functions-Schema
[2019-12-30 20:33:17] Entferne tmp-Verzeichnis '/var/www/discourse/tmp/restores/default/2019-12-30-202916'...
[2019-12-30 20:33:17] Setze Sidekiq fort...
[2019-12-30 20:33:17] Deaktiviere Nur-Lese-Modus...
[2019-12-30 20:33:17] Markiere Wiederherstellung als abgeschlossen...
[2019-12-30 20:33:17] Benachrichtige „pfaffman“ über das Ende der Wiederherstellung...
[2019-12-30 20:33:34] Fertig!

Jetzt sehe ich nichts mehr, was ich beheben könnte.

Ich könnte die Staging-Umgebung, auf die ich wiederherstellen möchte, upgraden, möchte aber die Produktionsumgebung nicht upgraden, bevor ich nicht sicherstellen kann, dass auf Staging alles funktioniert…

Sind Sie sicher, dass psql vor diesem Fehler keine weiteren Fehler protokolliert hat? Dies tritt normalerweise auf, wenn ein vorheriger SQL-Befehl fehlgeschlagen ist.

Außerdem: Warum enthält die ursprüngliche Datenbank doppelte Datensätze in der Tabelle incoming_referers? Der eindeutige Index in dieser Tabelle existiert seit 2014. Vielleicht hat die Datenbank, die Sie wiederherstellen möchten, noch viel mehr Probleme als nur dieses?

Danke, Gerhard! Ich schätze deine Hilfe. Das wird immer seltsamer.

Es ergibt für mich auch keinen Sinn, dass es ein Problem mit incoming_referers gab. Ich habe erst im Oktober eine Wiederherstellung von der Produktion auf diese Staging-Umgebung durchgeführt.

Es scheint, als ob etwas mit der Datenbank oder den Indizes nicht stimmt. Ich habe einen Plugin-Verdacht, aber die Fehler treten in so vielen verschiedenen Indizes auf, dass es unwahrscheinlich erscheint, dass ein einzelnes Plugin schuld ist. Eine frühere grep-Suche in den Plugins nach den Problemen mit den beschädigten Indizes lieferte keine Ergebnisse.

Bei einer Wiederherstellung erhielt ich dies:

[2020-01-03 16:25:30] ERROR:  could not create unique index "index_plugin_store_rows_on_plugin_name_and_key"

Ich habe Folgendes ausgeführt:

[10] pry(main)> PluginStoreRow.where(plugin_name: 'discourse-data-explorer',key: 'q:-8').destroy_all

Und es erneut versucht:

[2020-01-03 16:49:16] ERROR:  could not create unique index "index_tags_on_lower_name"
[2020-01-03 16:49:16] DETAIL:  Key (lower(name::text))=(addins) is duplicated.

Hier ist der vollständige Anfang der neuesten Wiederherstellung:

[2020-01-03 16:41:34] 'pfaffman' hat die Wiederherstellung gestartet!
[2020-01-03 16:41:34] Markiere Wiederherstellung als laufend...
[2020-01-03 16:41:34] Stelle sicher, dass /var/www/discourse/tmp/restores/default/2020-01-03-164133 existiert...
[2020-01-03 16:41:34] Lade Archiv in das tmp-Verzeichnis herunter...
[2020-01-03 16:45:20] Keine Metadatendatei zum Extrahieren vorhanden.
[2020-01-03 16:45:20] Validiere Metadaten...
[2020-01-03 16:45:20]   Aktuelle Version: 20191220134101
[2020-01-03 16:45:20]   Wiederhergestellte Version: 20191129144706
[2020-01-03 16:45:20] Extrahiere Dump-Datei...
[2020-01-03 16:49:15] CREATE INDEX
[2020-01-03 16:49:15] CREATE INDEX
[2020-01-03 16:49:15] CREATE INDEX
[2020-01-03 16:49:15] CREATE INDEX
[2020-01-03 16:49:15] CREATE INDEX
[2020-01-03 16:49:15] CREATE INDEX
[2020-01-03 16:49:15] CREATE INDEX
[2020-01-03 16:49:15] CREATE INDEX
[2020-01-03 16:49:15] CREATE INDEX
[2020-01-03 16:49:15] CREATE INDEX
[2020-01-03 16:49:15] CREATE INDEX
[2020-01-03 16:49:15] CREATE INDEX
[2020-01-03 16:49:16] CREATE INDEX
[2020-01-03 16:49:16] CREATE INDEX
[2020-01-03 16:49:16] CREATE INDEX
[2020-01-03 16:49:16] CREATE INDEX
[2020-01-03 16:49:16] CREATE INDEX
[2020-01-03 16:49:16] CREATE INDEX
[2020-01-03 16:49:16] CREATE INDEX
[2020-01-03 16:49:16] CREATE INDEX
[2020-01-03 16:49:16] CREATE INDEX
[2020-01-03 16:49:16] CREATE INDEX
[2020-01-03 16:49:16] CREATE INDEX
[2020-01-03 16:49:16] CREATE INDEX
[2020-01-03 16:49:16] CREATE INDEX
[2020-01-03 16:49:16] ERROR:  could not create unique index "index_tags_on_lower_name"
[2020-01-03 16:49:16] DETAIL:  Key (lower(name::text))=(addins) is duplicated.
[2020-01-03 16:49:16] ERROR:  current transaction is aborted, commands ignored until end of transaction block
[2020-01-03 16:49:16] ERROR:  current transaction is aborted, commands ignored until end of transaction block
[2020-01-03 16:49:16] ERROR:  current transaction is aborted, commands ignored until end of transaction block

Ich vermute, du musst die Daten manuell bereinigen, bis die Wiederherstellung funktioniert und alle eindeutigen Indizes erstellt werden können.

Abgesehen davon frage ich mich, ob wir in einem der jüngsten Basis-Images eine fehlerhafte Version von PostgreSQL ausgeliefert haben. In den letzten ein bis zwei Monaten gab es ziemlich viele Berichte über Probleme mit beschädigten Indizes. Das scheint eine seltsame Übereinstimmung zu sein. :thinking:

Ich würde gerne eine Erklärung hören, die nicht einfach nur lautet: „Jay hat wieder etwas Dummes gemacht.

Sie könnten sich die created_at-Zeitstempel der duplizierten Datensätze ansehen und versuchen herauszufinden, welche Version von Postgres zu diesem Zeitpunkt verwendet wurde. @falco hat erwähnt, dass PG 10.0 und 10.1 Probleme mit beschädigten Indizes hatten, aber das ist schon lange her (10.2 wurde am 2018-02-08 veröffentlicht), und wir haben PG 10 erst ab April 2018 ausgeliefert (also nach der Veröffentlichung von 10.2). Entweder ist es also ein neuer Fehler in PG oder einfach nur Pech. :man_shrugging:

Hmm. Nun, die Produktionsumgebung hat 10.10 und die Testumgebung 10.11.

Außerdem gab es bei einigen der Datensätze, bei denen die Logs einen Fehler wegen eines Duplikats meldeten, tatsächlich nur einen einzigen Datensatz. Vielleicht wurde der Datensatz gelöscht, aber nicht auch aus dem Index entfernt? Macht das Sinn?

Nun, aber Indizes werden bei jedem Update nicht neu erstellt.

Ja, da es sich um unterschiedliche Objekte auf der Festplatte handelt.

Nun, hier ist ein Hinweis:

discourse=> reindex table tags;
ERROR:  could not create unique index "index_tags_on_lower_name"
DETAIL:  Key (lower(name::text))=(addins) is duplicated.

discourse=> select * from tags where name='addins';
 id  |  name  | topic_count |         created_at         |         updated_at         | pm_topic_count 
-----+--------+-------------+----------------------------+----------------------------+----------------
 143 | addins |          16 | 2017-11-13 20:08:51.345607 | 2017-11-13 20:08:51.345607 |              0
(1 row)

discourse=> select * from tags where name like '%dins';
 id  |  name  | topic_count |         created_at         |         updated_at         | pm_topic_count 
-----+--------+-------------+----------------------------+----------------------------+----------------
 143 | addins |          16 | 2017-11-13 20:08:51.345607 | 2017-11-13 20:08:51.345607 |              0
 721 | addins |           3 | 2019-11-19 10:01:32.406178 | 2019-11-19 10:01:32.406178 |              0

Ich kann den Unterschied zwischen diesen beiden nicht erkennen, aber die erste Abfrage hat nur einen davon gefunden?

Wenn Sie EXPLAIN ANALYZE select * from tags where name='addins'; ausführen, werden Sie herausfinden, warum.

Es handelte sich entweder um einen Index-Only-Scan (was ich bezweifle, da Sie zu viele Spalten auswählen) oder um einen Bitmap-Heap-Scan, bei dem der Index verwendet wird, um zu wissen, welche Zeilen ausgewählt werden sollen. Da der Index beschädigt ist…

Das ist genau das Problem, das ich kürzlich mit meinem beschädigten Index hatte. Ich habe diese Konten schließlich inspiziert und oft festgestellt, dass es sich um dieselben handelte (gleiche E-Mail-Adresse). Ich habe eines umbenannt und dann zusammengeführt. Es war ziemlich viel Arbeit, da es größtenteils manuell erfolgte, aber jetzt habe ich einen brandneuen Index :slight_smile:

Edit: Oops, mein Problem lag in der users-Tabelle. Trotzdem dasselbe Problem mit doppelten Schlüsseln.

Auch hier gab es zwei Einträge, bei denen ‘shiny-server’ nur einen traf, während ‘%hiney-server’ beide traf. Ich verstehe nicht, wie mir das hilft, aber ich denke, du meinst, dass mein select erwartet, dass nur ein Ergebnis zurückgegeben wird, das dann aus dem Index gezogen wird, während der andere ignoriert wird. Wenn ich jedoch % verwende, werden die Felder durchsucht.

discourse=> EXPLAIN ANALYZE select * from tags where name='shiny-server'; 
                                                        QUERY PLAN                                                        
--------------------------------------------------------------------------------------------------------------------------
 Index Scan using index_tags_on_name on tags  (cost=0.28..8.29 rows=1 width=36) (actual time=0.038..0.040 rows=1 loops=1)
   Index Cond: ((name)::text = 'shiny-server'::text)
 Planning time: 0.129 ms
 Execution time: 0.070 ms
(4 rows)

Ich bezweifle stark, dass jemand, der das nicht selbst herausfindet, dies nützlich findet, aber … Ich habe eine Reihe von tag_ids mit demselben Namen gefunden und Dinge wie folgendes gemacht:

 TopicTag.where(tag_id: 717).update_all(tag_id: 611)
 Tag.ensure_consistency!
 Tag.find(717) # sicherstellen, dass er in keinem Topic enthalten ist
 Tag.find(717).destroy

und habe dann in psql ein reindex table tags; ausgeführt.

Und es sieht so aus, als müsste ich das nun auch für users ähnlich wie von @bartv beschrieben machen. Bei meinen Benutzern sehe ich jedoch einen Benutzer David und einen anderen Benutzer david sowie [Mm]ark.

Die habe ich so behoben:

marks=User.where("username similar to  '[Mm]+ark'").pluck(:id,:username,:created_at)

Dann den neuen Mark in /admin/users finden und den Benutzernamen dort ändern. Anschließend versuchen, reindex table users; in psql auszuführen (sudo su - discourse und dann psql).

Stell es dir so vor: Wenn du Pfaffman im Telefonbuch suchen musst, gehst du zum P, suchst dann nach Einträgen zwischen Pe und Pg, dann zwischen Pfa und Pfb usw. Du nutzt die alphabetische Sortierung der Einträge, um den Eintrag schnell zu finden. Stell dir nun – als Gedankenexperiment – vor, einer der Telefonbuchredakteure das Alphabet nicht korrekt gelernt hätte und einige Pfaffmans an der falschen Stelle eingefügt hätte (ein korrupter Index). Du wirst sie nicht finden.

Jetzt musst du alle Personen suchen, deren Nachname auf „faffman“ endet. Dafür gibt es keine schnelle Methode; du musst das gesamte Telefonbuch durchgehen. Das ist viel Arbeit! Aber… auf diese Weise wirst du die falsch eingefügten Pfaffmans finden!