Error al actualizar a la última versión de Discourse — resuelto

He recibido un error con mi instalación de Discourse al intentar actualizar a 3.5.0.beta3-dev:

Discourse no se inicia. Cualquier sugerencia es muy apreciada.

Status: Image is up to date for discourse/base:2.0.20250226-0128

...

I, [2025-04-18T15:16:34.677745 #1]  INFO -- : cd /var/www/discourse & su discourse -c 'LOAD_PLUGINS=0 bundle exec rake plugin:pull_compatible_all'
I, [2025-04-18T15:16:40.775977 #1]  INFO -- : discourse-bbcode-color is already at latest compatible version
discourse-cakeday is already at latest compatible version
discourse-chat-integration is already at latest compatible version
discourse-data-explorer is already at latest compatible version
discourse-math is already at latest compatible version
discourse-oauth2-basic is already at latest compatible version
discourse-rss-polling is already at latest compatible version
discourse-solved is already at latest compatible version
discourse-whos-online is already at latest compatible version
discourse-yearly-review is already at latest compatible version
docker_manager is already at latest compatible version

Error:

I, [2025-04-18T15:16:50.782650 #1]  INFO -- : cd /var/www/discourse & su discourse -c 'bundle exec rake db:migrate'
2025-04-18 15:16:59.705 UTC [911] discourse@discourse ERROR:  null value in column "answer_post_id" of relation "discourse_solved_solved_topics" violates not-null constraint
2025-04-18 15:16:59.705 UTC [911] discourse@discourse DETAIL:  Failing row contains (768, 16673, null, -1, null, 2021-05-10 18:32:53.008822, 2021-05-10 18:32:53.008822).
2025-04-18 15:16:59.705 UTC [911] discourse@discourse STATEMENT:  INSERT INTO discourse_solved_solved_topics (
          topic_id,
          answer_post_id,
          topic_timer_id,
          accepter_user_id,
          created_at,
          updated_at
        )
        SELECT
          tc.topic_id,
          tc.answer_post_id,
          tc.topic_timer_id,
          tc.accepter_user_id,
          tc.created_at,
          tc.updated_at
        FROM (
          SELECT
            tc.topic_id,
            CAST(tc.value AS INTEGER) AS answer_post_id,
            CAST(tc2.value AS INTEGER) AS topic_timer_id,
            COALESCE(ua.acting_user_id, -1) AS accepter_user_id,
            tc.created_at,
            tc.updated_at,
            ROW_NUMBER() OVER (PARTITION BY tc.topic_id ORDER BY tc.created_at ASC) AS rn_topic,
            ROW_NUMBER() OVER (PARTITION BY CAST(tc.value AS INTEGER) ORDER BY tc.created_at ASC) AS rn_answer
          FROM topic_custom_fields tc
          LEFT JOIN topic_custom_fields tc2 ON tc2.topic_id = tc.topic_id AND tc2.name = 'solved_auto_close_topic_timer_id'
          LEFT JOIN user_actions ua ON ua.target_topic_id = tc.topic_id AND ua.action_type = 15
          WHERE tc.name = 'accepted_answer_post_id'
            AND tc.id > 0
            AND tc.id <= 0 + 10000
        ) tc
        WHERE tc.rn_topic = 1 AND tc.rn_answer = 1
        ON CONFLICT DO NOTHING

rake aborted!
StandardError: An error has occurred, all later migrations canceled: (StandardError)
1 me gusta

Acabo de ejecutar discourse-doctor, que falla con el mismo error.

Detalle adicional; la fila que falla:

DETAIL:  La fila que falla contiene (1152, 16673, null, -1, null, 2021-05-10 18:32:53.008822, 2021-05-10 18:32:53.008822)

Si pudiera acceder a la base de datos sin que el contenedor estuviera en ejecución, podría eliminar la fila…

Arreglado.

Requirió algo de manipulación de la base de datos. Usé la imagen de docker de postgres para montar la base de datos:

docker run --name postgres_container_2 -e POSTGRES_PASSWORD=mysecretpassword -d -p 5432:5432 -v /var/discourse/shared/standalone/postgres_data:/var/lib/postgresql/data postgres:15

Luego localicé la fila de la tabla ofensiva:

SELECT
          tc.topic_id,
          tc.answer_post_id,
          tc.topic_timer_id,
          tc.accepter_user_id,
          tc.created_at,
          tc.updated_at
        FROM (
          SELECT
            tc.topic_id,
            CAST(tc.value AS INTEGER) AS answer_post_id,
            CAST(tc2.value AS INTEGER) AS topic_timer_id,
            COALESCE(ua.acting_user_id, -1) AS accepter_user_id,
            tc.created_at,
            tc.updated_at,
            ROW_NUMBER() OVER (PARTITION BY tc.topic_id ORDER BY tc.created_at ASC) AS rn_topic,
            ROW_NUMBER() OVER (PARTITION BY CAST(tc.value AS INTEGER) ORDER BY tc.created_at ASC) AS rn_answer
          FROM topic_custom_fields tc
          LEFT JOIN topic_custom_fields tc2 ON tc2.topic_id = tc.topic_id AND tc2.name = 'solved_auto_close_topic_timer_id'
          LEFT JOIN user_actions ua ON ua.target_topic_id = tc.topic_id AND ua.action_type = 15
          WHERE tc.name = 'accepted_answer_post_id'
            AND tc.id > 0
            AND tc.id <= 0 + 10000
            AND tc.value IS NULL
        ) tc

Una vez que me aseguré de que esto seleccionaba solo la fila del error, cambié el select a un DELETE, crucé los dedos y ejecuté ./launcher rebuild app.

Después de mucho tiempo esperando a que se construyera la imagen, ahora tengo una comunidad feliz y un sitio reconstruido, con correcciones de seguridad incluidas.

No sé qué causó que la fila mencionada anteriormente se volviera inválida, pero una vez que se eliminó, todo está bien.

4 Me gusta

Estas son instrucciones peligrosas para acceder a la base de datos cuando Discourse no se está ejecutando.

Úselo bajo su propio riesgo.

2 Me gusta

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.