Upgrade-Fehler - rake db:migrate Index auf theme_field_id

In den neuesten Versionshinweisen (3.2.0.beta1) habe ich das Plugin discourse-ai bemerkt, das ich vorher noch nicht gesehen hatte. Ich habe versucht, dieses Plugin hinzuzufügen und gleichzeitig meine Discourse-Instanz zu aktualisieren.

Wie im Titel erwähnt, sehe ich derzeit einen Fehler beim Bootstrap, bei dem rake db:migrate fehlschlägt, einen eindeutigen Index für theme_field_id zu erstellen. Hier sind einige Details, wie ich dorthin gelangt bin…

Erster Upgrade-Versuch (Fehler bei patch-package)

Ich verwende eine geteilte Container-Installation, also habe ich:

  • Meine web_only.yml bearbeitet, um das neue Plugin discourse-ai hinzuzufügen

    z.B. Eine zusätzliche Zeile zu den Plugin-Hooks hinzugefügt
    ## Plugins kommen hierher
    ## siehe https://meta.discourse.org/t/19157 für Details
    hooks:
      after_code:
        - exec:
            cd: $home/plugins
            cmd:
              - sudo -E -u discourse git clone https://github.com/discourse/docker_manager.git
              - sudo -E -u discourse git clone https://github.com/discourse/discourse-voting.git
              - sudo -E -u discourse git clone https://github.com/discourse/discourse-ai.git
    
  • ./launcher bootstrap web_only ausgeführt

Es gab einen Fehler mit einer Meldung, dass patch-package nicht gefunden wurde.

Git Pull → Bootstrap (pg-vector-Fehler)

Ich dachte, ich würde sicherstellen, dass ich die neuesten Launcher-Updates habe, da es nicht schaden würde, bevor ich es erneut versuche:

  • Einen git pull ausgeführt, um sicherzustellen, dass ich die neuesten Launcher-bezogenen Updates habe
  • ./launcher bootstrap web_only erneut ausgeführt

Dieses Mal erhielt ich Fehlermeldungen im Zusammenhang mit pg-vector.

:page_facing_up: Log-Snippet vom Bootstrap mit discourse-ai

Ich habe meine PostgreSQL-Versionen notiert, damit ich sie für meine Aufzeichnungen habe, wenn ich mich wieder mit dem Plugin discourse-ai beschäftige.

  • web_only:
    • Client: psql (PostgreSQL) 13.10 (Debian 13.10-1.pgdg110+1)
  • data:
    • Server: PostgreSQL 13.9 (Debian 13.9-1.pgdg110+1)

discourse-ai Plugin entfernen → Bootstrap

Und dann habe ich das Plugin discourse-ai aus der Datei web_only.yml entfernt und erneut einen Bootstrap ausgeführt.

Zu meiner Überraschung sah ich immer noch Fehler, aber dieses Mal scheinen sie sich auf rake db:migrate zu beziehen, das den eindeutigen Index index_javascript_caches_on_theme_field_id nicht erstellen kann, mit der Meldung: Key (theme_field_id)=(3) is duplicated.

:page_facing_up: Log-Snippet vom Bootstrap ohne discourse-ai

Deine Hilfe? :folded_hands:

Das bringt mich hierher, um Hilfe zu suchen. Ich dachte, ich mache eine Pause und hole mir Einblicke von der Community, bevor ich weitergrabe, falls jemand anderes das schon einmal gesehen hat.

Zur Referenz, ich habe 3.2.0.beta1-dev (993ed10cf0 ~ 9. August) installiert.

Und obwohl ich nicht glaube, dass es damit zusammenhängt, denke ich, es schadet nicht zu erwähnen, dass ich Anfang des Jahres zwischen Host-Maschinen migriert habe… obwohl ich seitdem mehrere Discourse-Updates über die Admin-Oberfläche durchgeführt habe.

Migrationsansatz

Aus der Erinnerung war dies im Grunde das Upgrade der Quellinstanz auf die neueste Discourse-Version, die Installation von Discourse auf dem neuen Host, das Einfrieren der Quelle, ein Discourse-Backup auf der Quelle, rsync von Bildern/etc. zwischen den Hosts, Wiederherstellung des Backups auf dem neuen Host.

Bei den doppelten Indexfehlern denke ich, wenn Sie restart web_only ausführen und diese über die Benutzeroberfläche behandeln können, ist das viel einfacher, als dies in der Datenbank zu tun. Ich glaube jedoch nicht, dass ich jemals einen bei theme_field_id gesehen habe.

Die Zeile direkt über rake aborted! in den Protokollen erwähnt, dass discourse-voting jetzt discourse-topic-voting ist. Sie könnten versuchen, den Link im Plugin-Bereich auf den aktuellen zu aktualisieren und sehen, ob das hilft?

Können Sie bitte klarstellen, welche Ressource mit einer doppelten ID gemeint ist? Ich war mir nicht sicher, wofür theme_field_id genau steht.

Zur Information: Ich hatte den web_only-Container nicht heruntergefahren. Normalerweise boote ich den Container zuerst, um das Ausfallzeitfenster zu minimieren:

Ich werde es versuchen. Ich vermute, dass es nicht helfen wird, da ich denke, dass GitHub Dinge im Hintergrund stillschweigend umleitet und es sich nur um eine Warnung auf der Discourse-Seite handelt. :slight_smile:

Wenn Sie eine funktionierende Website mit installiertem Daten-Explorer haben, können Sie wahrscheinlich sehen, worauf sich dies bezieht, indem Sie diese Abfrage verwenden:

SELECT *
FROM theme_fields
WHERE id = 3
1 „Gefällt mir“

Ich war mir dieses Plugins nicht bewusst – das ist praktisch! Ich habe es nicht installiert, kann aber trotzdem den Datencontainer aufrufen und Abfragen ausführen.

Das ist ein guter Hinweis! Wenn ich die Fehlermeldung richtig lese, glaube ich nicht, dass es an der theme_fields-Tabelle liegt, da diese Tabelle keinen theme_field_id hat. Ich habe den Quellcode nicht überprüft, aber ich würde vermuten, dass das erste Argument von add_index() der Tabellenname und das zweite die Spalte ist.

Basierend darauf sieht es so aus, als wäre es die Tabelle javascript_caches.

== 20230817174049 EnsureJavascriptCacheIsUniquePerTheme: migrating ===========
-- remove_index(:javascript_caches, :theme_id)
   -> 0.0208s
-- add_index(:javascript_caches, :theme_id, {:unique=>true})
   -> 0.0079s
-- remove_index(:javascript_caches, :theme_field_id)
   -> 0.0026s
-- add_index(:javascript_caches, :theme_field_id, {:unique=>true})

Ich habe die Struktur dieser Tabelle überprüft und sie enthält die Spalte theme_field_id:

discourse=# \d javascript_caches
                                          Table "public.javascript_caches"
     Column     |            Type             | Collation | Nullable |                    Default
----------------+-----------------------------+-----------+----------+-----------------------------------------------
 id             | bigint                      |           | not null | nextval('javascript_caches_id_seq'::regclass)
 theme_field_id | bigint                      |           |          |
 digest         | character varying           |           |          |
 content        | text                        |           | not null |
 created_at     | timestamp without time zone |           | not null |
 updated_at     | timestamp without time zone |           | not null |
 theme_id       | bigint                      |           |          |
 source_map     | text                        |           |          |
Indexes:
    "javascript_caches_pkey" PRIMARY KEY, btree (id)
    "index_javascript_caches_on_digest" btree (digest)
    "index_javascript_caches_on_theme_field_id" btree (theme_field_id)
    "index_javascript_caches_on_theme_id" btree (theme_id)
Check constraints:
    "enforce_theme_or_theme_field" CHECK (theme_id IS NOT NULL AND theme_field_id IS NULL OR theme_id IS NULL AND theme_field_id IS NOT NULL)
Foreign-key constraints:
    "fk_rails_58f94aecc4" FOREIGN KEY (theme_id) REFERENCES themes(id) ON DELETE CASCADE
    "fk_rails_ed33506dbd" FOREIGN KEY (theme_field_id) REFERENCES theme_fields(id) ON DELETE CASCADE

Ich konnte diese Tabelle abfragen (mit gekürzten Inhaltsfeldern, damit ich sie tatsächlich lesen konnte) und sehe die Duplikate. Aber ich bin mir nicht sicher, welche Auswirkungen diese Duplikate haben.

discourse=# select id, theme_field_id, digest, substring(content from 1 for 64) as content_64, created_at, updated_at, theme_id, substring(source_map from 1 for 64) as source_64 from javascript_caches where theme_field_id = 3;
 id | theme_field_id |                  digest                  |                            content_64                            |         created_at         |         updated_at         | theme_id |                            source_64
----+----------------+------------------------------------------+------------------------------------------------------------------+----------------------------+----------------------------+----------+------------------------------------------------------------------
  1 |              3 | d0b6ec642d5649064ff0501cadc775a9217b16e0 | "define"in window&&define("discourse/theme-3/initializers/theme- | 2019-02-25 01:26:56.606537 | 2023-08-18 20:47:19.596923 |          | {"version":3,"sources":["discourse/initializers/theme-field-3-co
  2 |              3 | 7fd74ecf4448afccdbcd9ccde87acddb4ec6f514 | "define"in window&&define("discourse/theme-3/initializers/theme- | 2019-02-25 01:26:58.228209 | 2023-08-18 20:50:41.049209 |          | {"version":3,"sources":["discourse/initializers/theme-field-3-co

Der Inhalt kam mir bekannt vor, also ging ich zu Anpassen → Thema → Mein Thema → Allgemein → Kopfzeile, nahm eine kleine Änderung vor und speicherte. Ich konnte sehen, dass ein Eintrag aktualisiert wurde und einer alt blieb…

discourse=# select id, theme_field_id, digest, substring(content from 1 for 64) as content_64, created_at, updated_at, theme_id, substring(source_map from 1 for 64) as source_64 from javascript_caches where theme_field_id = 3;
 id | theme_field_id |                  digest                  |                            content_64                            |         created_at         |         updated_at         | theme_id |                            source_64
----+----------------+------------------------------------------+------------------------------------------------------------------+----------------------------+----------------------------+----------+------------------------------------------------------------------
  2 |              3 | 7fd74ecf4448afccdbcd9ccde87acddb4ec6f514 | "define"in window&&define("discourse/theme-3/initializers/theme- | 2019-02-25 01:26:58.228209 | 2023-08-18 20:50:41.049209 |          | {"version":3,"sources":["discourse/initializers/theme-field-3-co
  1 |              3 | 7f4132b1f9ced1b90b8f8fc24812cc11e81fea8d | "define"in window&&define("discourse/theme-3/initializers/theme- | 2019-02-25 01:26:56.606537 | 2023-09-13 21:56:56.312263 |          | {"version":3,"sources":["discourse/initializers/theme-field-3-co
(2 rows)

Auch hier bin ich mir nicht sicher, welche Auswirkungen diese Duplikate haben, ob es sicher ist, das ‘alte’ zu löschen, oder ob es eine andere Möglichkeit gibt, die Caches zu ‘rebuilden’, die dies bereinigen würde?

Um ehrlich zu sein, bin ich bisher bei 0/2, daher bin ich wahrscheinlich keine gute Informationsquelle dafür. :slight_smile:

Es gibt ein paar frühere Themen, in denen etwas Ähnliches für index_tags_on_name passiert ist, falls diese von Nutzen sein könnten? z.B.

1 „Gefällt mir“

Bauen Sie Ihren Datencontainer neu auf. Das KI-Plugin erfordert eine Erweiterung, die Sie noch nicht haben.

Ich schätze deine Hilfe! Es scheint, als hättest du mich auf den richtigen Weg gebracht. :star_struck:

Ich habe ein Backup der Tabelle mit pg_dump gemacht, den alten doppelten Eintrag gelöscht und der Bootstrap wurde erfolgreich abgeschlossen. :+1:

Danke für die Bestätigung! Ich dachte, ich müsste den Datencontainer aktualisieren (oder pgvector anderweitig installieren). Ich habe das aufgeschoben, da ich mich nicht mit den Ausfallzeiten auseinandersetzen wollte.

Aus dem Discourse-KI-Thread geht hervor, dass PG15 am Horizont ist, also werde ich vielleicht noch etwas darauf warten.

Es scheint, dass die pgvector-Abhängigkeit für die Embeddings-Funktion sein könnte, die ich nicht nutzen wollte, aber leider scheint es, dass alles zusammen gebündelt ist. Ich wollte hauptsächlich mit einigen der OpenAI / ChatGPT Magic Rewrite-Funktionen spielen, also vielleicht ein weiterer Grund, bis zum nächsten großen Datencontainer-Update zu warten. :slight_smile:

1 „Gefällt mir“

Du kannst warten, wenn du willst, aber Single-Container-Benutzer (was die überwiegende Mehrheit der Self-Hosters ausmacht) aktualisieren ihre Postgres potenziell bei jedem Upgrade, daher gibt es keinen wirklichen Grund zu warten, außer ein paar zusätzliche Minuten Ausfallzeit. Du musst den web_only Container nach dem Datenbank-Rebuild neu erstellen (oder vielleicht nur zerstören und starten).

1 „Gefällt mir“

Das ist der Hauptgrund. Selbst wenn es nur ein paar Minuten sind, ziehe ich es vor, sie zu minimieren, wenn sie nicht kritisch sind.

In diesem Sinne sollte ich wahrscheinlich auf die Verwendung eines Beta-Plugins verzichten, allein schon wegen der möglichen Ausfallzeit. :stuck_out_tongue:

Ich habe einige der Diskussionen über ‘Zero Downtime’-Upgrades lose verfolgt. Vielleicht ist es nur eine rosarote Brille, die auf die jüngste Geschichte zurückblickt, aber es fühlt sich an, als ob ich /admin/upgrade für die meisten Updates im letzten Jahr verwenden konnte, so dass ich mich vorerst auf kritischere Projekte konzentriert und das Interesse an der Zero Downtime-Methode verloren habe.

Als ich im Januar zu einem größeren Hoster wechselte, war es ‘Zero Downtime’ in dem Sinne, dass die Benutzer weiterhin auf Inhalte auf der Website zugreifen konnten, aber es gab eine kurze Zeit, in der die Dinge schreibgeschützt waren, während wir den Übergang vollzogen. Ich schätze, ich könnte diesen Ansatz für ein großes data-Container-Upgrade verwenden, wenn ich wirklich die Ausfallzeit während des nächsten großen data-Upgrades minimieren wollte.

PS. Ich habe im Laufe der Jahre eine Menge Ihrer Beiträge in der Community hier gelesen. Vielen Dank für all Ihre Bemühungen zur Unterstützung der Community! :star2:

Das tut es wirklich! Ich habe schon seit einer Weile kein Upgrade mehr für meine „Rebuilds, wenn Sie sie brauchen“-Kunden durchgeführt. Für Websites wie Ihre erledigt mein Dashboard den Rebuild und führt die Post-Upgrade-Migrationen durch, nachdem der neue Container gestartet wurde (wenn Ihr vorhandener Container diese Migrationen so eingestellt hat, dass sie beim ersten Mal nicht ausgeführt werden).

1 „Gefällt mir“