Las migraciones duplicadas de bases de datos son más fáciles de prevenir cuando los cambios de esquema se ejecutan como un único paso de implementación explícito, en lugar de hacerlo durante el inicio de cada contenedor de la aplicación.
El diseño preventivo consiste en asignar a las migraciones un único responsable, un único conjunto de credenciales y una señal de finalización antes de que las nuevas réplicas comiencen a atender tráfico. Mantén los contenedores web y de trabajo libres para reiniciarse sin adquirir privilegios de modificación del esquema, haz que el despliegue espere a que un trabajo de migración finalice correctamente y diseña los cambios de esquema para que las versiones antigua y nueva de la aplicación puedan coexistir brevemente. Así se elimina la condición de carrera, en lugar de limitarse a esperar que todas las réplicas detecten primero el mismo historial de migraciones.
Elimina los comandos de migración del inicio normal de la aplicación
Inspecciona el punto de entrada de la imagen, el comando de Compose, el comando del trabajador, el envoltorio de comprobación de estado y el script de despliegue en busca de llamadas automáticas a migraciones. La aplicación debe poder reiniciarse sin modificar el esquema, a menos que ese reinicio sea el paso de migración elegido deliberadamente.
Un artículo de Octopus sobre despliegues sostiene que las migraciones necesitan un ciclo de vida separado, en lugar de estar acopladas al inicio de cada proceso de microservicio.
Mantén disponible el binario de migración donde sea necesario, pero no lo invoques desde el punto de entrada web y desde un segundo trabajo a la vez. Un único responsable explícito es más fácil de auditar que varias rutas de inicio que dependen del bloqueo del framework.
Ejecuta un trabajo de migración previo al despliegue
Crea un trabajo de una sola ejecución que utilice los mismos archivos de migración que la versión publicada y que finalice correctamente solo después de que la base de datos de destino alcance el estado de esquema esperado. Haz que el despliegue de la aplicación dependa de ese resultado.
Una guía actual de despliegue muestra cómo un trabajo se ejecuta antes del despliegue, en lugar de permitir que todas las réplicas compitan durante el inicio.
No escales la tarea de migración como si fuera el servicio de la aplicación. El trabajo debe tener un único responsable de ejecución por base de datos de destino, un tiempo de espera limitado, registros y un estado de error claro que bloquee la nueva versión de la aplicación.
Condiciona el inicio de la aplicación al éxito de la migración
Haz que los nuevos contenedores web y de trabajo esperen hasta que la etapa de migración informe de un resultado satisfactorio, pero no hagas que cada contenedor en espera vuelva a ejecutar la migración. La dependencia es del resultado, no de volver a ejecutar el cambio de esquema.
El patrón de despliegue de Andrew Lock utiliza pods de la aplicación que esperan a la migración, mientras la lógica de migración permanece centralizada.
En una pila pequeña para un servidor doméstico, el mismo principio puede implementarse con un servicio dedicado de Compose y un script de despliegue controlado. Mantén el mecanismo lo bastante sencillo como para que una migración fallida detenga visiblemente el despliegue.
Utiliza cambios de esquema compatibles con versiones anteriores durante la coexistencia
Los despliegues graduales pueden ejecutar temporalmente versiones antiguas y nuevas de la aplicación contra una misma base de datos. Evita una migración que elimine o cambie el nombre de un campo antes de que la versión antigua haya dejado de utilizarlo.
Una guía reciente sobre migraciones sin tiempo de inactividad recomienda expandir antes de contraer, de modo que los cambios aditivos del esquema se incorporen antes de realizar la limpieza destructiva.
Divide los cambios grandes en fases de expansión, migración de datos, conmutación y contracción cuando sea necesario. El trabajo de migración no debe crear un esquema que solo entienda el contenedor nuevo mientras las réplicas antiguas aún atienden solicitudes.
Mantén las credenciales de migración fuera de las réplicas de la aplicación
Cuando sea práctico, utiliza una cuenta de base de datos con privilegios para modificar el esquema únicamente durante la etapa de migración de una sola ejecución. Los contenedores normales de la aplicación deben conservar los permisos más limitados de lectura y escritura necesarios para los datos de la aplicación.
Un artículo de Liquibase sobre despliegues describe que los cambios de base de datos pertenecen a la automatización, con una aplicación de cambios controlada y repetible.
Esta separación reduce la probabilidad de que una migración se ejecute accidentalmente, incluso si un proceso de la aplicación se reinicia o se duplica. Guarda la credencial elevada en la ruta de secretos del despliegue, no en el entorno del servicio normal de larga duración.
Verifica que el despliegue no pueda aplicar el lote dos veces
Prueba el despliegue en una base de datos desechable o en una instantánea restaurada iniciando varias réplicas de la aplicación, reiniciándolas y volviendo a ejecutar el comando de despliegue. La etapa de migración debe informar del estado de esquema existente sin modificarlo por segunda vez.
JetBrains resume la regla operativa como ejecutar las migraciones como un paso del despliegue antes del inicio normal de la aplicación.
La política de prevención está completa cuando los reinicios de la aplicación no pueden modificar el esquema, una migración fallida bloquea la versión y la ejecución repetida del despliegue deja la base de datos sin cambios. El artículo relacionado de ZimaSpace sobre el diagnóstico de migraciones duplicadas es la vía de recuperación si ya se ha producido una ejecución duplicada.
Soporte y Consejos
Más para leer

¿Puede Plex compartir una GPU con otro contenedor de Docker?
Plex y otro contenedor suelen poder acceder a la misma GPU, pero debes probar la compatibilidad de los controladores, la asignación de dispositivos, la...

Cómo saber si un error de Plex proviene del cliente o del servidor
Reproduce el mismo elemento en otro cliente, compara la ruta de la sesión y recopila pruebas del servidor solo después de que el alcance...

Cómo configurar la caché de Plex y el almacenamiento temporal para la transcodificación
Protege el estado persistente de Plex mientras colocas los archivos temporales de transcodificación en un almacenamiento local adecuado; después, verifica la limpieza, el espacio...

