¿Cómo se gestionan las bases de datos en desarrollo, prueba y producción?

StackOverflow https://stackoverflow.com/questions/6371

  •  08-06-2019
  •  | 
  •  

Pregunta

Me ha resultado difícil encontrar buenos ejemplos de cómo administrar esquemas de bases de datos y datos entre servidores de desarrollo, prueba y producción.

Aquí está nuestra configuración.Cada desarrollador tiene una máquina virtual ejecutando nuestra aplicación y la base de datos MySQL.Es su zona de pruebas personal para hacer lo que quieran.Actualmente, los desarrolladores realizarán un cambio en el esquema SQL y realizarán un volcado de la base de datos en un archivo de texto que enviarán a SVN.

Queremos implementar un servidor de desarrollo de integración continua que siempre ejecutará el último código comprometido.Si hacemos eso ahora, recargará la base de datos desde SVN para cada compilación.

Tenemos un servidor de prueba (virtual) que ejecuta "candidatos de liberación". La implementación en el servidor de prueba es actualmente un proceso muy manual, y generalmente me implica cargar el último SQL de SVN y ajustarlo.Además, los datos del servidor de prueba son inconsistentes.Terminará con los datos de prueba que el último desarrollador que se comprometió tenía en su servidor sandbox.

Donde todo falla es en el despliegue a producción.Dado que no podemos sobrescribir los datos en vivo con datos de prueba, esto implica recrear manualmente todos los cambios del esquema.Si hubiera una gran cantidad de cambios de esquema o scripts de conversión para manipular los datos, esto puede volverse realmente complicado.

Si el problema fuera solo el esquema, sería un problema más fácil, pero hay datos "base" en la base de datos que también se actualizan durante el desarrollo, como metadatos en las tablas de seguridad y permisos.

Esta es la barrera más grande que veo al avanzar hacia la integración continua y la construcción en un solo paso.Como hacer ¿resuélvelo?


Una pregunta de seguimiento:¿Cómo se realiza un seguimiento de las versiones de la base de datos para saber qué scripts ejecutar para actualizar una instancia de base de datos determinada?¿Hay una tabla de versiones como la que Lance menciona debajo del procedimiento estándar?


Gracias por la referencia a Tarantino.No estoy en un entorno .NET, pero encontré su Página wiki de DataBaseChangeMangement ser de mucha ayuda.Especialmente esto Presentación de PowerPoint (.ppt)

Voy a escribir un script en Python que verifique los nombres de *.sql scripts en un directorio determinado contra una tabla en la base de datos y ejecuta los que no están allí en orden basándose en un número entero que forma la primera parte del nombre del archivo.Si es una solución bastante simple, como sospecho que será, la publicaré aquí.


Tengo un guión funcional para esto.Se encarga de inicializar la base de datos si no existe y de ejecutar scripts de actualización según sea necesario.También hay opciones para borrar una base de datos existente e importar datos de prueba desde un archivo.Son alrededor de 200 líneas, así que no lo publicaré (aunque podría ponerlo en Pastebin si hay interés).

¿Fue útil?

Solución

Hay un par de buenas opciones.No usaría la estrategia de "restaurar una copia de seguridad".

  1. Programe todos los cambios de esquema y haga que su servidor de CI ejecute esos scripts en la base de datos.Tenga una tabla de versiones para realizar un seguimiento de la versión actual de la base de datos y solo ejecute los scripts si son para una versión más nueva.

  2. Utilice una solución de migración.Estas soluciones varían según el idioma, pero para .NET uso Migrator.NET.Esto le permite versionar su base de datos y moverse hacia arriba y hacia abajo entre versiones.Su esquema se especifica en código C#.

Otros consejos

Sus desarrolladores necesitan escribir scripts de cambio (cambio de esquema y datos) para cada error/característica en la que trabajan, no simplemente volcar toda la base de datos en el control de código fuente.Estos scripts actualizarán la base de datos de producción actual a la nueva versión en desarrollo.

Su proceso de compilación puede restaurar una copia de la base de datos de producción en un entorno apropiado y ejecutar todos los scripts del control de fuente en ella, lo que actualizará la base de datos a la versión actual.Hacemos esto a diario para asegurarnos de que todos los scripts se ejecuten correctamente.

Eche un vistazo a cómo Ruby on Rails hace esto.

En primer lugar, están los llamados archivos de migración, que básicamente transforman el esquema de la base de datos y los datos de la versión N a la versión N+1 (o en caso de degradar de la versión N+1 a la N).La base de datos tiene una tabla que indica la versión actual.

Las bases de datos de prueba siempre se limpian antes de las pruebas unitarias y se completan con datos fijos de archivos.

El libro Refactorización de bases de datos:Diseño de bases de datos evolutivas Podría darle algunas ideas sobre cómo administrar la base de datos.También se puede leer una versión breve en http://martinfowler.com/articles/evodb.html

En un proyecto PHP+MySQL, tenía el número de revisión de la base de datos almacenado en la base de datos, y cuando el programa se conecta a la base de datos, primero verificará la revisión.Si el programa requiere una revisión diferente, abrirá una página para actualizar la base de datos.Cada actualización se especifica en código PHP, que cambiará el esquema de la base de datos y migrará todos los datos existentes.

  • Nombra tus bases de datos de la siguiente manera: db_dev, db_test, db_qa, db_prod (Obviamente, nunca debes codificar los nombres de las bases de datos).
  • Por lo tanto, podrá implementar incluso diferentes tipos de bases de datos en el mismo servidor físico (no lo recomiendo, pero es posible que deba hacerlo...si los recursos son escasos)
  • Asegúrese de poder mover datos entre ellos automáticamente
  • Separe los scripts de creación de la base de datos de la población = Siempre debería ser posible recrear la base de datos desde cero y completarla (desde la versión anterior de la base de datos o desde una fuente de datos externa).
  • no use cadenas de conexión codificadas en el código (ni siquiera en los archivos de configuración); use en los archivos de configuración plantillas de cadenas de conexión, que se completan dinámicamente; cada reconfiguración de la capa_aplicación que necesita volver a compilarse es MALA
  • Utilice control de versiones de bases de datos y control de versiones de objetos de base de datos; si puede permitírselo, utilice productos listos para usar; si no, desarrolle algo por su cuenta.
  • realice un seguimiento de cada cambio de DDL y guárdelo en alguna tabla de historial ( ejemplo aquí )
  • Copias de seguridad DIARIAS!Pruebe qué tan rápido podría restaurar algo perdido desde una copia de seguridad (use scripts de restauración automática
  • Incluso su base de datos DEV y PROD tienen exactamente el mismo script de creación, tendrá problemas con los datos, así que permita a los desarrolladores crear la copia exacta de prod y jugar con él (sé que recibiré desventajas por este, pero cambie el La mentalidad y el proceso de negocio le costarán mucho menos cuando la mierda llegue a su fin, así que obligue a los programadores a subscribir legalmente todo lo que genere, pero asegúrese de que esto sea así.

Esto es algo con lo que estoy constantemente insatisfecho: nuestra solución a este problema.Durante varios años mantuvimos un script de cambios separado para cada versión.Este script contendría los deltas de la última versión de producción.Con cada lanzamiento de la aplicación, el número de versión aumentaría, dando algo como lo siguiente:

  • dbChanges_1.sql
  • dbChanges_2.sql
  • ...
  • dbChanges_n.sql

Esto funcionó bastante bien hasta que empezamos a mantener dos líneas de desarrollo:Trunk/Mainline para nuevos desarrollos y una rama de mantenimiento para correcciones de errores, mejoras a corto plazo, etc.Inevitablemente, surgió la necesidad de realizar cambios en el esquema de la sucursal.En este punto, ya teníamos dbChanges_n+1.sql en el Trunk, por lo que terminamos con un esquema como el siguiente:

  • dbChanges_n.1.sql
  • dbChanges_n.2.sql
  • ...
  • dbChanges_n.3.sql

Nuevamente, esto funcionó bastante bien, hasta que un día miramos hacia arriba y vimos 42 scripts delta en la línea principal y 10 en la rama.¡ARGH!

Hoy en día simplemente mantenemos un script delta y dejamos que SVN lo versione, es decir.sobrescribimos el guión con cada lanzamiento.Y evitamos realizar cambios de esquema en las ramas.

Así que tampoco estoy satisfecho con esto.Me gusta mucho el concepto de migraciones desde Rails.Me he quedado bastante fascinado con LiquiBase.Admite el concepto de refactorizaciones incrementales de bases de datos.Vale la pena echarle un vistazo y pronto lo analizaré en detalle.¿Alguien tiene experiencia con eso?Tendría mucha curiosidad por conocer sus resultados.

También podrías considerar el uso de una herramienta como Comparación SQL para programar la diferencia entre varias versiones de una base de datos, lo que le permite migrar rápidamente entre versiones

Tenemos una configuración muy similar al OP.

Los desarrolladores desarrollan en VM con bases de datos privadas.

[Los desarrolladores pronto se comprometerán con sucursales privadas]

Las pruebas se ejecutan en diferentes máquinas (en realidad en VM's alojadas en un servidor) [pronto será ejecutado por Hudson CI Server

Pruebe cargando el volcado de referencia en la base de datos.Aplicar los parches de esquema de desarrolladores y luego aplicar los parches de datos de los desarrolladores

Luego ejecute pruebas unitarias y del sistema.

La producción se despliega a los clientes como instaladores.

Qué hacemos:

Realizamos un volcado de esquema de nuestra base de datos sandbox.Luego un volcado de datos SQL.Diferenciamos eso con la línea de base anterior.ese par de deltas es actualizar n-1 a n.

Configuramos los dumps y deltas.

Entonces, para instalar la versión N CLEAN ejecutamos el volcado en una base de datos vacía.Para parchear, aplique los parches intermedios.

(Juha mencionó que la idea de Rail de tener una tabla que registre la versión actual de la base de datos es buena y debería hacer que la instalación de actualizaciones sea menos complicada.)

Los deltas y volcados deben revisarse antes de la prueba beta.No veo ninguna manera de evitar esto, ya que he visto a los desarrolladores insertar cuentas de prueba en la base de datos por sí mismos.

Revisar la implementar db, ya hay herramientas Java y .net disponibles, puede seguir sus estándares para los diseños de archivos SQL y la tabla de versiones de esquemas y escribir su versión de Python.

Me temo que estoy de acuerdo con otros carteles.Los desarrolladores necesitan escribir sus cambios.

En muchos casos, un simple ALTER TABLE no funcionará; también es necesario modificar los datos existentes; los desarrolladores deben pensar qué migraciones se requieren y asegurarse de que estén escritas correctamente (por supuesto, es necesario probar esto cuidadosamente en algún momento). el ciclo de liberación).

Además, si tiene algo de sentido común, hará que sus desarrolladores también realicen scripts de reversión de sus cambios para que puedan revertirse si es necesario.Esto también se debe probar para garantizar que su reversión no solo se ejecute sin errores, sino que deje la base de datos en el mismo estado que tenía anteriormente (esto no siempre es posible o deseable, pero es una buena regla la mayor parte del tiempo). .

Cómo se conecta eso a un servidor CI, no lo sé.Quizás su servidor CI necesite tener una instantánea de compilación conocida, a la que vuelve cada noche y luego aplica todos los cambios desde entonces.Probablemente eso sea lo mejor; de lo contrario, un script de migración roto dañará no solo la compilación de esa noche, sino todas las posteriores.

Si está en el entorno .NET, entonces la solución es Tarantino.Maneja todo esto (incluidos los scripts SQL que se instalarán) en una compilación NANT.

He escrito una herramienta que (al conectarse a Abrir DBDiff) compara esquemas de bases de datos y le sugerirá scripts de migración.Si realiza un cambio que elimina o modifica datos, generará un error, pero proporcionará una sugerencia para el script (p. ej.cuando falta una columna en el nuevo esquema, comprobará si se ha cambiado el nombre de la columna y creará xx (script.sql.suggestion generado que contiene una declaración de cambio de nombre).

http://code.google.com/p/migrationscriptgenerator/ Me temo que solo SQL Server :( También es bastante alfa, pero tiene MUY baja fricción (especialmente si lo combinas con Tarantino o http://code.google.com/p/simplescriptrunner/)

La forma en que lo uso es tener un proyecto de scripts SQL en su .sln.También tiene una base de datos db_next localmente en la que puede realizar cambios (usando Management Studio o Exportación de esquemas de NHibernate o LinqToSql Crear base de datos o algo).Luego ejecuta migracionesscriptgenerator con las bases de datos _dev y _next, que crea.los scripts de actualización de SQL para migrar.

Estamos usando la línea de comando diferencia-mysql:genera una diferencia entre dos esquemas de base de datos (de una base de datos en vivo o un script) como un script ALTER.mysql-diff se ejecuta al inicio de la aplicación y, si el esquema cambia, se informa al desarrollador.Por lo tanto, los desarrolladores no necesitan escribir ALTER manualmente, las actualizaciones del esquema se realizan de forma semiautomática.

Para la base de datos Oracle utilizamos oracle-ddl2svn herramientas.

Esta herramienta automatizó el siguiente proceso.

  1. para cada esquema de base de datos obtenga ddls de esquema
  2. ponerlo bajo control de versión

cambios entre instancias resueltos manualmente

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top