Problemas con Migrate_from_s3

When migrating from S3 to local storage, we see a number of issues.

The main issue is that the migrate_from_s3 rake task is not taking the Uploads table as a starting point, but the posts. This causes it to skip a lot of uploads which are being left on S3.

  • uploads used as logo’s because they are not referenced in a post
  • uploads for avatars because they are not referenced in a post
  • uploads that are (for some reason) referenced by their CDN URL in raw because they do not match the regex that is being used to identify the uploads
  • uploads that are on non-AWS S3 storage because they do not match the regex because it requires amazonaws in the URL
  • uploads that for some reason do not match the second, different regex (we’re seeing this with non-image uploads like mp3 files, not sure why this is happening)
2 Me gusta

We’re working on improving the way we associate uploads to posts (by using the upload:// scheme) that will make these storage migrations much more bulletproof. There’s little point to fixing these rake tasks before that’s done.

7 Me gusta

Recientemente abrí un nuevo PR para permitir migrar menos publicaciones a la vez (por ejemplo, probar una a la vez) y añadí pruebas para la tarea.

Siento que tiene sentido comenzar con las publicaciones, ya que deseas recocinar las publicaciones para cambiar la URL en la publicación cocida después de cada migración; migrar todas las cargas y luego iniciar los recocinados dejaría el sitio muy roto durante potencialmente mucho tiempo en un sitio grande (necesito migrar unos 100 GB de S3 a local, así que me importa). Pero lo que escribí podría ayudar a comenzar a escribir una tarea migrate_uploads_from_s3 que se ejecutaría después de migrate_from_s3 para limpiar las cargas que no formaban parte de las publicaciones.

@zogstrip ¿Cuál es el estado actual de “Estamos trabajando en…”? ¿Esto sigue en flujo o esta migración ahora vale la pena prestarle atención?

5 Me gusta

Hemos realizado mucho trabajo en el frente de las cargas para garantizar que tengamos mejores asociaciones entre publicaciones <=> cargas.

Estas tareas de migración se pueden mejorar a voluntad :+1:

2 Me gusta

¡Me alegra mucho que estés aquí! ¿Quieres gestionar tu propio sitio comunitario? Empezar es muy sencillo.

1 me gusta

Tengo dos cosas que abordar a continuación: La primera es que el límite es útil, pero solo aplica al espacio de búsqueda; a continuación, quiero poder especificar un número máximo de publicaciones a modificar. Por lo tanto, agregaré un número máximo de publicaciones a modificar, así como un límite para la consulta.

Además, al especificar max, tiene sentido ser explícito sobre lo que se está procesando con fines de depuración, por lo que me gustaría hacer que la salida sea detallada si max no es nil. Esto permitirá a las personas validar el proceso antes de continuar, ya que ese es el caso de uso principal de este trabajo.

Creo que lo que haré es especificar max como el primer argumento y un límite opcional como el segundo, porque realmente lo más importante es el máximo; el límite solo sirve para hacer que “un solo ping” sea más económico.

La segunda cuestión son las subidas no relacionadas con la migración. Hace algo más de un año, intenté subir un video al sitio de Discourse al que me estaba uniéndome, mientras luchaba por entender cómo escribir la migración desde Google+ a Discourse, y vi que lo que se había escrito era https://#{SiteSettings.absolute_base_url}/original/3X/b/a/ba9e06ebc2f4397f26793bb5cd4e169308dd371d.mp4.

Hoy, cuando subo un video, obtengo algo como ![file_example_MP4_480_1_5MG|video](upload://caJ9ykkpshw3PFK4464VUIPWJ4l.mp4) en su lugar.

Al menos en mi prueba más reciente, migrate_from_s3 distorsionó por completo esas URLs, de modo que ya ni siquiera son URLs válidas, por lo que definitivamente eso necesita ser corregido. Luego, creo que esta tarea es poco probable que se encuentre en la práctica con ![texto](url-no-subida-para-migrar), así que como primer paso, me gustaría simplemente agregar el markdown de enlace alrededor del protocolo mágico upload, en lugar de hacer que la expresión regular maneje ambos casos y, como resultado, sea aún más difícil de leer. Pero podría cambiar de opinión al respecto.

Parece que la etiqueta video o audio se agrega en JavaScript mediante una coincidencia de expresión regular, por lo que tendré que copiar las expresiones regulares desde app/assets/javascripts/discourse/app/lib/uploads.js hacia la tarea para identificarlas correctamente. Incluiré el origen de las expresiones regulares para que la siguiente persona que las encuentre sepa dónde actualizarlas. :stuck_out_tongue:

Esta noche, encontré tiempo para trabajar en esto y tengo un borrador de PR en marcha. Aún no está terminado; sé que quedan errores en él. No creo que haya cambiado ningún comportamiento para las URLs del pseudo-protocolo upload: (normales para imágenes) en este punto, aunque agregué una verificación de coherencia.

Con los cambios en este PR, he migrado con éxito tanto las subidas normales del pseudo-protocolo upload: como los videos que actualmente se referencian explícitamente por referencia a S3 (en mi caso, espacios de Digital Ocean). Estoy usando esto para modificar solo una publicación a la vez con este comando:

bin/rake uploads:batch_migrate_from_s3[1,1000]

Tenga en cuenta que esto no irá más allá de las primeras 1000 publicaciones devueltas de manera algo aleatoria desde la consulta de la base de datos; el límite bajo es solo para acelerar la consulta mientras se migra una sola publicación a la vez, se revisa esa publicación para verificar su comportamiento correcto y luego se comienza de nuevo para encontrar otra. ¡Este comando funciona de esta manera solo con el PR en el que estoy trabajando actualmente!

Sigo agregando salida de diagnóstico mientras trabajo en esto, y estoy empezando a pensar que es importante no solo para el desarrollo. Estoy viendo muchas fallas de descarga transitorias desde los espacios de Digital Ocean, donde algunas, pero no todas, las descargas en una publicación se migran, lo cual, en el original, simplemente imprimiría un . y continuaría, y luego diría Done, pero en realidad la tarea no habrá terminado. Tuve que hacer algo como cinco o seis pasadas en una publicación antes de que se migraran todos los archivos. (No estaba contando porque pensé que al principio estaba depurando un error local). Espero tener que ejecutar esta migración repetidamente con el mismo límite hasta que los diagnósticos estén limpios. Por lo tanto, haré que la impresión de progreso detallada solo ocurra si max está establecido, pero imprimiré mensajes de advertencia útiles en cualquier caso.

Actualmente, estoy usando el siguiente truco para las descargas intermitentes que fallan en Discourse Spaces, lo cual, en la práctica, ha mejorado enormemente mi tasa de éxito (3 reintentos han sido totalmente suficientes en cientos de publicaciones migradas hasta ahora).

https://github.com/johnsonm/discourse/commit/7dfac12a2ea6ec04ba4e0616b4e0dbd1d806cff7

Además, descubrí que de alguna manera terminamos con videos más grandes que el límite que establecí cuando importé desde Google+. He tenido que aumentar temporalmente tanto SiteSettings.max_image_size_kb como SiteSettings.max_attachment_size_kb mientras realizaba migraciones puntuales de algunos videos demasiado grandes, de los cuales no tengo claro cómo terminaron en el sitio, pero no quiero romperlos ahora… No tengo idea si el error que permitió subidas demasiado grandes estaba en mi script de importación, en Discourse, o simplemente en mi memoria de los cambios que hice en la configuración con el tiempo. :wink:

Como gran parte de lo que estoy migrando fue una importación desde G+, algunas de mis publicaciones terminaron fallando las validaciones actuales. Obtuvimos algunos Unhandled failure: Validation failed: Sorry, new users can only put one image in a post y al principio no entendí por qué no se repetían. Resulta que las subidas se movieron correctamente a local y todas usaban el pseudo-protocolo upload:, por lo que el contenido sin formato no cambió. Sin embargo, post.save! aún falló con ese error en las validaciones, lo que impidió que se ejecutara post.rebake!, por lo que tengo algunas publicaciones de 30K con imágenes que necesitan ser rebakeadas; lamentablemente, no tengo registro de cuáles son esas publicaciones. Ahora he cambiado a post.save!(validate: false) como otra solución, por lo que este problema en particular no debería volver a ocurrir. Estoy muy contento de haber hecho que la migración se detenga ante errores no manejados, de lo contrario, esto podría haber causado mucho más daño que algunas publicaciones.

Para mantener mi sitio usable, incluida la entrega de notificaciones, mientras ejecuto la migración, no quiero saturar las colas de Sidekiq. Sé que nombrar cosas es uno de los dos problemas más difíciles en la informática, junto con la invalidación de caché y los errores de “off-by-one”, pero propongo DISCOURSE_MIGRATION_MAX_ENQUEUED como variable de entorno para especificar cuántos espacios de cola totales (no espacios de trabajos) se permiten llenar al proceder a migrar otro elemento después de un rebake durante una migración, para evitar saturar las colas, de modo que el sitio continúe funcionando. Tengo un parche que agrega esto, con un valor predeterminado de cero, para todas las rebakeadas por publicación en lib/tasks/uploads.rake. Estoy usando esto en mi migración de producción.

https://github.com/discourse/discourse/blob/59a761851b9c8786d3a9692f8c595372b0534f77/lib/tasks/uploads.rake

4 Me gusta

@zogstrip ¿Te importaría revisar este PR, ya que tienes contexto de la revisión reciente de mi último PR en esta área? FIX: Make migrations from S3 more robust; fix bare URL migration by johnsonm · Pull Request #10093 · discourse/discourse · GitHub

He incluido en él las correcciones que he estado aplicando mientras ejecutaba esta migración relativamente grande. No he intentado agregar pruebas para cada corrección; no estoy seguro de cómo inyectar cada tipo de error. Pero al menos la nueva funcionalidad está probada.

@RGJ Creo que mi PR, tal como está ahora, podría abordar todos tus puntos excepto los dos primeros, aunque no estoy seguro sobre el CDN. Mi sitio usaba CDN y migró videos que tenían URLs de CDN, pero eso podría haber sido un efecto secundario de la nomenclatura con los espacios de Discourse. Si tienes casos adicionales, espero que mi PR te proporcione una base sencilla para agregar al regex y crear casos de prueba para las variaciones adicionales.

Creo que es correcto migrar primero por publicación, ya que después de migrar las subidas en una publicación, esta debe volver a cocinarse para que la publicación cocinada tenga las URLs correctas. Después de terminar de migrar mis publicaciones (lo cual podría tomar menos de dos semanas ahora que he cambiado mi limitación de velocidad para verificar directamente la longitud de la cola), me ocuparé de cualquier trabajo restante para limpiar.

Dado que varias publicaciones pueden compartir referencias al mismo contenido si más de una persona sube el mismo archivo, es necesario un segundo paso que verifique los datos cocinados en busca de URLs antiguas y vuelva a cocinar esas publicaciones para adoptar la nueva ubicación. Puede utilizar la misma limitación de velocidad para evitar saturar las colas.

Probablemente no veré ningún logotipo roto en makerforums, ya que ajustamos la marca después de dejar de subir contenido nuevo a “s3” (para nosotros, espacios de Digital Ocean), pero probablemente veré muchas subidas que aún están en S3, al menos para los avatares. La migración de subidas no asociadas con una publicación debe iniciarse solo después de que todas las publicaciones hayan sido migradas, y probablemente tendré que documentarlo después de terminar de migrar las subidas en las publicaciones.

@pfaffman Veo Bizarre Problems with migrate_from_s3 - #5, que describe errores que no se repitieron. Sin mis correcciones en el PR actual, los errores se silencian, incluidas las fallas de validación. Creo que el trabajo aquí abordará al menos algunos de los problemas que viste entonces.

@hosna Los problemas que planteas en https://meta.discourse.org/t/what-does-rake-uploads-migrate-from-s3-exactly-do/97285 están parcialmente o completamente resueltos hasta ahora en este PR. Si no están completamente resueltos, he agregado pruebas que facilitarán la adición de más pruebas para validar correcciones adicionales.

@sam, dado que pusiste la etiqueta 2.6 en el PR, asumo que no se fusionará durante al menos unos días; ¿debería integrar mi trabajo sobre la función de limitación de velocidad en el PR junto con las correcciones? ¿O prefieres mantener las correcciones y el trabajo de funcionalidad en PRs separados? Puedo hacerlo de cualquier manera. La función de limitación de velocidad está funcionando muy bien; estoy migrando aproximadamente tres veces más rápido, sin impacto en la disponibilidad del sitio, ahora que estoy esperando a que la cola de Sidekiq se vacíe, por lo que tiene sentido integrarla, creo, si es algo que normalmente se acepta en los PRs. De lo contrario, tendré que esperar a que se fusione el trabajo en el que se basa, así que en cualquier caso sería bueno saber tu opinión.

..

He reutilizado (DRY) mi parche de limitación de velocidad para la migración y lo he integrado en el PR. Funciona en la práctica, y sar me indica que estoy viendo un tiempo de inactividad casi nulo de forma continua, mientras el sitio sigue funcionando, durante la migración en vivo. Una ventaja del modo por lotes es que puedo verificar si hay nuevas versiones de Discourse después de cada lote completo de migraciones; actualicé mi sitio a 2.6.0beta1 en la primera oportunidad después de su lanzamiento, y he estado ejecutando las migraciones con éxito en 2.6.0beta1 con mi PR de migración encima desde la actualización.

Creo que el PR está listo para revisión ahora; planeo enviar otro PR para las últimas etapas, pero poner esto en marcha mejorará la experiencia general de migración para todos, incluso antes de que termine las últimas piezas.

5 Me gusta

Bueno, eso fue hace mucho tiempo…

Tengo muchas ganas de ver que esto se resuelva. Por ahora tengo varios sitios en multisitio que necesitan extraer imágenes de S3 (por ahora, creo que algunas imágenes son locales y otras están en S3) y luego enviarlas a S3.

1 me gusta

@pfaffman Probablemente es algo bueno que, cuando empecé mi proyecto de migración, no supiera lo que ahora creo haber descubierto. Parece que si hubiera usado el cliente de MinIO para copiar todo el bucket de S3 a la carpeta local de uploads, modificado todos los Upload.url a nil en la consola de Rails y reconstruido el sitio, todo se habría migrado en horas sin necesidad de regenerar todas las imágenes. (En cambio, estoy limitado por la tasa de solicitudes al volver a ejecutar todas las conversiones de imágenes, como si la CPU local fuera más barata que simplemente copiar todas las imágenes procesadas desde S3.)

Y entonces, si hubiera sido tan fácil, no habría hecho todo este trabajo para hacer las migraciones más confiables en general, y nadie más se habría beneficiado. :smiling_face:

4 Me gusta

Oh. Eso suena a lo que quería saber. Quizás lo pruebo.

1 me gusta

Yo… definitivamente haría una copia de seguridad antes de intentar ese camino, ya que solo estoy especulando. No quiero confundirte.

Oh, y otra cosa: eso habría fallado completamente para las subidas de audio y video, y no me habría dado cuenta hasta más tarde, y luego habría estado tratando de averiguarlo y escribiendo código personalizado. Así que si tienes subidas de audio y video, definitivamente quieres empezar por ahí, y no funcionará correctamente sin la PR que está abierta y no se fusionará hasta después del lanzamiento de la versión 2.5, ya que @sam la etiquetó como 2.6.

2 Me gusta

Mis disculpas por unirme tan tarde a la conversación. Acabo de ver tu PR y me pregunto por qué estás recreando el modelo Upload en lugar de simplemente cambiar su URL. ¿Y por qué no iterar simplemente a través de OptimizedImages y hacer lo mismo?

2 Me gusta

@RGJ No cambié eso en absoluto; volver a crear Upload fue una corrección de error de @zogstrip en Cannot execute the rake uploads:migrate_from_s3 - #11

Solo estoy tratando de hacer que el código que ya existía funcione, y no conozco bien los internos de Discourse; he estado tropezando a ciegas mucho. Mi única experiencia con Ruby son los pocos PRs que he hecho para Discourse. Seguir el patrón del código existente parece no ser la ruta más eficiente (véase mi conversación con @pfaffman más arriba sobre la evaluación de cortocircuito), estoy totalmente de acuerdo. Como puedes ver por el hecho de que más temprano hoy ni siquiera me di cuenta de que OptimizedImages.url también tendría que modificarse a una ruta /uploads y etag establecerse en nil (y no sé qué más), todavía estoy volando a ciegas.

Aún necesito iterar sobre los posts primero, al menos para corregir las URLs literales antiguas en los posts. Todavía necesito algunas de las otras correcciones, como no volver a validar los posts y no silenciar errores. Todavía quiero aplicar límites de tasa, creo, para limitar el impacto en los sitios en vivo.

Para tus dos primeras preocupaciones relacionadas con actualizaciones que no son de posts, aquí está mi trabajo en progreso, aún no probado en un sitio en vivo (commit) que podría ayudar, pero que no probaré en mi sitio en vivo hasta que finalice toda la migración de uploads de posts.

Ajustar algo que antes funcionaba era todo lo que tenía ganas de hacer. Si te gustaría hacer una migración más rápida, estoy totalmente de acuerdo; podría tener sentido fusionar mi trabajo más lento pero al menos mejor como una mejora de Pareto, y luego podrías reemplazarlo completamente con algo mucho mejor y sería el primero en celebrar, incluso si ya no estoy en posición de usarlo en ese momento.

1 me gusta

@mcdanlj Gracias por tu explicación. Aunque mi pregunta era sincera, no estaba insinuando que haya problemas ahora. No sé si la forma en que lo sugerí sea en absoluto “mejor”; quizás introduciría muchos nuevos problemas. Supongo que el código, tal como está ahora, sin importar quién lo escribió, es así por una razón.

3 Me gusta

@RGJ lo mismo digo; soy sincero en que si alguien sabe con certeza cómo evitar el lío de volver a generar todas las imágenes, estoy totalmente a favor. Y si yo fuera un desarrollador experimentado de Discourse y supiera cómo hacerlo fácilmente, probablemente ya lo habría hecho desde el principio.

Supongo que migrar fuera de S3 no es un caso común para quienes tienen muchas imágenes, por lo que difícilmente vale la pena el tiempo en comparación con añadir características más útiles en general a Discourse. Tenía aproximadamente 100 GB de archivos subidos al importar desde Google+ a MakerForums y elegimos S3 con la idea de que era posible que mucha gente de esas comunidades se mudara a MakerForums, pero al final solo unas pocas comunidades se trasladaron activamente, por lo que el crecimiento continuo no justificaba permanecer en S3. Creo que ese es un caso bastante extremo y que reprocesar las imágenes es un costo único.

Por último, estoy muy agradecido por haber abierto este tema en primer lugar, porque de lo contrario podría haber pasado por alto fácilmente las subidas que no son publicaciones.

@RGJ Tienes toda la razón en que destruir y recrear no es bueno. Añadí una verificación: raise "Error: la URL de subida #{url} cambió a #{new_upload.short_url}, debería permanecer sin cambios." if url != new_upload.short_url, lo que al menos informa de problemas con fuentes corruptas. La interrupción de hoy en Digital Ocean Spaces me envió datos corruptos y activó este error en muchas subidas —no sé cuántas. Pero como ya había destruido la subida anterior, ahora tengo algunas páginas corruptas y no me di cuenta hasta que perdí el registro de salida con los logs que me indicaban qué páginas estaban corruptas, por lo que ni siquiera puedo entrar a corregirlas manualmente desde una copia de seguridad.

Así que, aunque mi trabajo es una mejora respecto al método anterior en el sentido de que al menos reporta algunos errores, sería mucho mejor descargar los archivos, verificar los SHA1 de los archivos descargados y escribirlos en archivos locales. Mientras tanto, he modificado mi PR para detener la migración ante cualquier error no manejado, al menos para limitar la pérdida de datos.

Aún creo que mi trabajo debería fusionarse como una mejora de Pareto, ya que no lo empeora y sí lo mejora, pero sería bastante mejor hacerlo de la manera correcta. Creo que eso consistiría en escribir lib/file_store/from_s3_migration.rb en paralelo a lib/file_store/to_s3_migration.rb, pero no estoy a la altura de hacerlo.

Como mi PR aún no ha sido revisada, he añadido más cosas a ella. Añadí una tarea uploads:report_missing_uploads que busca en raw instancias de upload://... donde el objeto de subida no está presente. Al menos en mi caso, con las copias de seguridad, podré revisar mis respaldos, encontrar los archivos huérfanos y restaurarlos en el sitio, y luego volver a generar esas publicaciones para restaurar las imágenes que faltaban. He encontrado 678 de ellos para buscar en las copias de seguridad, de los cuales hasta ahora he encontrado todos menos 10, así que me alegro de haber escrito la prueba. Tendré que ocuparme de eso antes de pasar a la fase en la que volveré a generar las publicaciones restantes.

He completado mi primera fase de migración, sin incluir la regeneración de las publicaciones afectadas con subidas compartidas ni las subidas que no son publicaciones. Después de completar otra copia de seguridad remota, planeo probar también esas características y añadirlas a mi PR.

Ahora he comenzado a probar las siguientes fases de la migración: la regeneración y la migración de subidas que no son publicaciones. Mi primera lección fue que la regeneración como siguiente paso falla debido a avatares de subidas no relacionadas con publicaciones en publicaciones citadas, por lo que la regeneración de publicaciones debe ser el último paso.

Siguiente descubrimiento: ¡Gracias a las restricciones de clave foránea! Descubrí al migrar subidas no relacionadas con publicaciones que necesito migrar al menos los perfiles antes de migrar en general las subidas que no son publicaciones.

ActiveRecord::InvalidForeignKey: PG::ForeignKeyViolation: ERROR:  update or delete on table "uploads" violates foreign key constraint "fk_rails_1d362f2e97" on table "user_profiles"

La migración de perfiles fue complicada porque tenía que migrar dos subidas adjuntas al perfil, pero en algunos casos las personas usaban la misma imagen para ambos, por lo que tuve que hacer ese trabajo en tres etapas. He migrado con éxito todos los perfiles de mi sitio con URLs de S3.

He migrado todas mis subidas que no son publicaciones ni perfiles. @RGJ, si quieres probar la rama que publiqué, está actualizada con mi trabajo. Todo lo que contiene se ha utilizado ya para una migración completa del sitio.

@cvx No sé cuándo tendrás oportunidad de revisar, pero sin mi PR, migrate_from_s3 definitivamente está lleno de errores de destrucción silenciosa de datos. Lo que he hecho no es perfecto, pero sí protege contra muchos errores con los que me he encontrado en la práctica.

He hecho todo el trabajo que tengo previsto hacer aquí por ahora. He migrado mi sitio, lo que significa que ni siquiera puedo evaluar eficazmente los cambios solicitados. Si rechazan esta PR, les sugiero encarecidamente que, en su lugar, eliminen la migración existente, ya que destruirá datos silenciosamente para los usuarios.

Con respecto a la PR, a veces obtengo fallos de prueba en CI (en la versión actual) algo así:

7867 ejemplos, 0 fallos, 11 pendientes, 1 error ocurrido fuera de los ejemplos

##[error]Proceso completado con código de salida 1.

Esto no se reproduce localmente (hasta ahora) y no veo información en los registros de CI que indique qué está mal en CI, así que no voy a perder más tiempo intentando dar vueltas explorando la salida de CI en busca de información oculta.

Una última nota: Después de completar la migración, descubrimos que las imágenes de perfil de algunos usuarios se perdieron durante la migración y que las están restaurando manualmente. Supongo que se habría requerido código adicional para tener éxito en eso, pero como no lo descubrí hasta que fue demasiado tarde, no tengo un caso de prueba para validarlo. Así que ese es un error pendiente que podría causar problemas en algunas configuraciones, pero ya no estoy en condiciones de escribir esa corrección adicional.

5 Me gusta

Dado que mi PR que corrige la corrupción silenciosa de datos en migrate_from_s3 ni siquiera ha sido revisada, ¿podemos al menos documentar migrate_to_s3 como un camino de un solo sentido?

En este momento, francamente, es una trampa para los principiantes.

@cvx @zogstrip ¿Cuál es su preferencia? ¿Revisar el PR o simplemente eliminar migrate_from_s3 por completo y ser honestos sobre el hecho de que es un camino de un solo sentido?

5 Me gusta

Lo siento, el error es mío. Revisaré la PR esta semana.

7 Me gusta

El contenido de la revisión fue básicamente que la forma actual es tan completamente errónea que debe reconstruirse desde cero y de manera diferente; que el intento de solucionarlo como se había escrito anteriormente no es aceptable. No estoy dispuesto a hacerlo, así que realmente creo que migrate_from_s3 debería eliminarse por completo y migrate_to_s3 debería marcarse como una puerta de un solo sentido que solo debes cruzar si estás seguro de quedarte para siempre. En este momento, tener migrate_from_s3 en el código fuente es un error de integridad de datos en Discourse.

No recibí una revisión oportuna mientras trabajaba en el proceso de migración, y ahora que ya he migrado hace mucho tiempo (con algunos resultados rotos, como algunos avatares dañados), no tengo un entorno de pruebas significativo. No tengo ninguna confianza de que lo haría correctamente, así que me he retirado de esta batalla. Le toca al siguiente desafortunado que pensó que sería una buena idea poner imágenes en algún servicio de almacenamiento de objetos similar a S3 para resolver el problema. ¡Lo siento!

2 Me gusta

@CxV Dado que rechazaste la migración anterior por estar completamente incorrecta y necesitar ser reiniciada desde cero, por favor revisa y fusiona esta eliminación del error de corrupción de datos:

2 Me gusta

Como se ha señalado, encontré algunos problemas con la migración que realicé. Esto respalda el punto de @cvx de que escribí la migración completamente mal, y hasta que alguien lo haga correctamente, la eliminación de la migración existente llena de corrupción silenciosa de datos realmente debería fusionarse. (Es un parche muy simple; la revisión debería ser trivial. Cuanto antes se fusione, menos probable será que alguien destruya su sitio al intentar retroceder a través de una puerta de un solo sentido. No estoy seguro de cómo pedir más enfáticamente una fusión; si lo supiera, lo haría. Edición: Gracias @cvx por la aprobación, la fusión y el seguimiento para asegurar que la migración masiva se marque como irreversible.)

Aquí están los problemas conocidos que encontré:

  • Al menos el avatar de discobot no se mostró; toda la participación de discobot mostró el avatar genérico de persona (cabeza y hombros de color gris claro sobre fondo blanco).
  • Los avatares de algunas otras personas no se migraron correctamente. Muchos se corrigieron manualmente.
  • Cuando se configuraba el sitio, el administrador original experimentó con cambios en la configuración de “S3” (en nuestro caso, Digital Ocean Spaces, con y sin CDN), lo que provocó algunas imágenes optimizadas huérfanas que no se corrigieron en la migración.

Para cualquiera que haya intentado usar mi rama y haya visto que algunas imágenes desaparecieron así, ejecuté un truco en la consola de Rails y solucioné algunas cosas. Esta no es la forma correcta de hacerlo; simplemente no conozco bien el modelo para hacerlo correctamente. Mi dominio de Ruby es muy débil; no toco Ruby fuera de mis pequeñas contribuciones a Discourse.

Pero, tal como es, este terrible truco solucionó las imágenes rotas (debido a errores de configuración iniciales) y al menos recuperó el avatar de discobot (y posiblemente otros, pero todos los de los que tenía conocimiento ya habían sido reparados).

Lo que no se muestra aquí es todo lo que hice entre los pasos, examinando cada conjunto a medida que avanzaba. Esto fue parte de una sesión de “explorar qué hay en la consola de Rails” y no realmente un script que escribí y ejecuté. Esto no tiene manejo de errores y tomé una copia de seguridad completa del sitio antes de comenzar cualquier trabajo.

No sé cómo decir con más énfasis que este código no es la forma idiomática de Ruby on Rails de realizar esta reparación. Solo quería compartir cómo reparé al menos parte del daño que me causé a mí mismo en mi intento anterior de migrar mi sitio desde Digital Ocean Spaces.

require 'set'

uploadids = Set.new
optimizedimages = Set.new
OptimizedImage.where("url like '%UNIQUEPARTOFS3URL%'").each do |oi|
  uploadids.add(oi.upload_id)
  optimizedimages.add(oi)
end

postids = Set.new
uploadids.each do |u|
  PostUpload.where(upload_id: u).each do |pu|
    postids.add(pu.post_id)
  end
end

optimizedimages.each do |oi|
  oi.delete
end

postids.each do |pid|
  Post.where(id: pid).each do |p|
    p.rebake!
  end
end
2 Me gusta