mysql - sistema - ¿Cómo administra las bases de datos en desarrollo, prueba y producción?
que es base de datos mysql (14)
Me ha costado trabajo intentar encontrar buenos ejemplos de cómo administrar los esquemas de bases de datos y los datos entre los servidores de desarrollo, prueba y producción.
Aquí está nuestra configuración. Cada desarrollador tiene una máquina virtual que ejecuta nuestra aplicación y la base de datos MySQL. Es su caja de arena personal para hacer lo que quieran. Actualmente, los desarrolladores harán un cambio en el esquema de SQL y realizarán un volcado de la base de datos a un archivo de texto que se comprometerá en SVN.
Queremos implementar un servidor de desarrollo de integración continua que siempre ejecutará el último código comprometido. Si lo hacemos ahora, volverá a cargar la base de datos desde SVN para cada compilación.
Tenemos un servidor de prueba (virtual) que ejecuta "candidatos de lanzamiento". Implementar en el servidor de prueba es actualmente un proceso muy manual, y generalmente implica que cargue el SQL más reciente de SVN y lo ajuste. Además, los datos en el servidor de prueba son inconsistentes. Terminas con los datos de prueba que el último desarrollador haya tenido en su servidor de espacio aislado.
Donde todo se descompone es el despliegue a la producción. Como no podemos sobrescribir los datos en vivo con los datos de prueba, esto implica volver a crear manualmente todos los cambios de esquema. Si hubo una gran cantidad de cambios de esquema o scripts de conversión para manipular los datos, esto puede ponerse realmente complicado.
Si el problema era solo el esquema, sería un problema más fácil, pero también hay datos "básicos" en la base de datos que se actualizan durante el desarrollo, como los metadatos en las tablas de seguridad y permisos.
Esta es la mayor barrera que veo para avanzar hacia la integración continua y las construcciones de un solo paso. ¿Cómo lo resuelves?
Una pregunta de seguimiento: ¿cómo rastreas las versiones de la base de datos para que sepas qué scripts ejecutar para actualizar una instancia de base de datos determinada? ¿Hay una tabla de versiones como Lance mencionada debajo del procedimiento estándar?
Gracias por la referencia a Tarantino. No estoy en un entorno .NET, pero encontré su página wiki DataBaseChangeMangement muy útil. Especialmente esta Presentación en Powerpoint (.ppt)
Voy a escribir una secuencia de comandos de Python que verifique los nombres de las secuencias de comandos *.sql
en un directorio determinado en una tabla de la base de datos y ejecute las que no están en orden en función de un número entero que forme la primera parte del nombre del archivo. Si es una solución bastante simple, como sospecho que será, la publicaré aquí.
Tengo un script en funcionamiento para esto. Maneja la inicialización del DB si no existe y la ejecución de scripts de actualización según sea necesario. También hay interruptores para borrar una base de datos existente e importar datos de prueba de un archivo. Se trata de 200 líneas, por lo que no lo publicaré (aunque podría ponerlo en pastebin si hay interés).
Eche un vistazo a dbdeploy , hay herramientas Java y .net ya disponibles, puede seguir sus estándares para los diseños de archivos SQL y la tabla de versiones de esquema y escribir su versión de python.
Eche un vistazo a cómo Ruby on Rails hace esto.
Primero hay 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 el caso de la degradación de la versión N + 1 a N). La base de datos tiene una tabla que le dice a la versión actual.
Las bases de datos de prueba siempre se borran antes de las pruebas unitarias y se rellenan con datos fijos de los archivos.
El libro Refactoring Databases: Evolutionary Database Design puede brindarle algunas ideas sobre cómo administrar la base de datos. También se puede leer una versión corta en http://martinfowler.com/articles/evodb.html
En un proyecto de PHP + MySQL, he almacenado el número de revisión de la base de datos en la base de datos, y cuando el programa se conecta a la base de datos, primero verifica la revisión. Si el programa requiere una revisión diferente, se 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.
Estamos utilizando la línea de comandos mysql-diff : genera una diferencia entre dos esquemas de bases de datos (desde Live DB o script) como ALTER script. mysql-diff se ejecuta al inicio de la aplicación, y si el esquema cambia, informa al desarrollador. Entonces los desarrolladores no necesitan escribir ALTERs manualmente, las actualizaciones de esquema ocurren de forma semiautomática.
Esto es algo con lo que estoy constantemente insatisfecho, es nuestra solución a este problema. Durante varios años mantuvimos un script de cambio por separado para cada lanzamiento. Este script contendría los deltas del último lanzamiento de producción. Con cada versión 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 comenzamos a mantener dos líneas de desarrollo: Troncal / Mainline para nuevo desarrollo, y una rama de mantenimiento para correcciones de fallas, mejoras a corto plazo, etc. Inevitablemente, surgió la necesidad de realizar cambios en el esquema en la rama. En este punto, ya teníamos dbChanges_n + 1.sql en el Troncal, así que terminamos con un esquema como el siguiente:
- dbChanges_n.1.sql
- dbChanges_n.2.sql
- ...
- dbChanges_n.3.sql
De nuevo, 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!
En estos días simplemente mantenemos un script delta y dejamos que SVN lo actualice, es decir, sobrescribimos el script con cada lanzamiento. Y evitamos hacer cambios de esquema en las sucursales.
Entonces, tampoco estoy satisfecho con esto. Realmente me gusta el concepto de migraciones de Rails. Me he sentido bastante fascinado con LiquiBase . Es compatible con el concepto de refactorizaciones de bases de datos incrementales. Vale la pena echarle un vistazo y pronto lo veré en detalle. Alguien tiene experiencia con eso? Estaría muy interesado en conocer tus resultados.
Hay un par de buenas opciones. No utilizaría la estrategia "restaurar una copia de seguridad".
Escriba todos sus cambios de esquema y haga que su servidor de CI ejecute esos scripts en la base de datos. Disponga de una tabla de versiones para realizar un seguimiento de la versión actual de la base de datos y solo ejecute las secuencias de comandos si son para una versión más nueva.
Use una solución de migración. Estas soluciones varían según el idioma, pero para .NET utilizo Migrator.NET. Esto le permite versionar su base de datos y moverse hacia arriba y hacia abajo entre versiones. Su esquema está especificado en el código C #.
He escrito una herramienta que (al enlazar con Open DBDiff ) compara los esquemas de la base de datos y le sugerirá las secuencias de comandos de migración. Si realiza un cambio que elimina o modifica los datos, arrojará un error, pero proporcionará una sugerencia para el script (por ejemplo, cuando falte una columna en el nuevo esquema, se verificará si la columna ha sido renombrada y se creará xx - generado script.sql.suggestion que contiene una instrucción de cambio de nombre).
http://code.google.com/p/migrationscriptgenerator/ SQL Server solo me temo :( También es bastante alpha, pero tiene MUY baja fricción (particularmente 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 a la que realiza los cambios (utilizando Management Studio o NHibernate Schema Export o LinqToSql CreateDatabase o algo así). Luego ejecuta migrationscriptgenerator con _dev y _next DBs, que crea. las secuencias de comandos de actualización de SQL para la migración.
Me temo que estoy de acuerdo con otros carteles. Los desarrolladores necesitan guiar sus cambios.
En muchos casos, un simple ALTER TABLE no funcionará, también debe modificar los datos existentes: los desarrolladores necesitan tener en cuenta qué migraciones se requieren y asegurarse de que estén escritas correctamente (por supuesto, debe probar esto cuidadosamente en algún momento en el ciclo de lanzamiento).
Además, si tiene sentido, conseguirá que sus desarrolladores también registren retrocesos para sus cambios, de modo que puedan revertirse si fuera necesario. Esto también debe probarse, para garantizar que su reversión no solo se ejecute sin error, sino que deje el DB en el mismo estado que antes (esto no siempre es posible o deseable, pero es una buena regla la mayor parte del tiempo) .
Cómo lo engancha en un servidor de CI, no lo sé. Tal vez su servidor de CI necesite tener una instantánea de compilación conocida, a la que revierte todas las noches y luego aplique todos los cambios desde entonces. Probablemente sea mejor, de lo contrario, una secuencia de comandos de migración interrumpida no solo romperá la compilación de esa noche, sino todas las subsiguientes.
Para la base de datos Oracle utilizamos las herramientas oracle-ddl2svn .
Esta herramienta automatizó el siguiente proceso
- para cada esquema db obtener esquema ddls
- ponlo bajo la versión contol
cambios entre instancias resueltas manualmente
Si se encuentra en el entorno .NET, la solución es Tarantino . Maneja todo esto (incluso qué scripts sql instalar) en una compilación NANT.
Sus desarrolladores necesitan escribir scripts de cambio (cambio de esquema y datos) para cada error / función 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 todas las secuencias de comandos desde el control de origen, que actualizará la base de datos a la versión actual. Hacemos esto diariamente para asegurarnos de que todos los scripts se ejecuten correctamente.
También podría utilizar una herramienta como SQL Compare para establecer 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 a la OP.
Los desarrolladores desarrollan en máquinas virtuales con bases de datos privadas.
[Los desarrolladores pronto se comprometerán en sucursales privadas]
Las pruebas se ejecutan en diferentes máquinas (en realidad, en máquinas virtuales alojadas en un servidor) [Pronto lo ejecutará el servidor de Hudson CI]
Pruebe cargando el volcado de referencia en el db. Aplique los parches de esquema de los desarrolladores y luego aplique los parches de datos de los desarrolladores
Luego ejecute pruebas de unidad y sistema.
La producción se implementa en clientes como instaladores.
Qué hacemos:
Tomamos un volcado de esquema de nuestro banco de pruebas DB. Luego, un volcado de datos sql. Diferimos eso a la línea de base anterior. ese par de deltas es actualizar n-1 a n.
configuramos los volcados y deltas.
Entonces, para instalar la versión N CLEAN ejecutamos el volcado en un db vacío. Para aplicar parches, aplique los parches intermedios.
(Juha mencionó la idea de Rail de tener una mesa que registre la versión actual de DB es buena y debería hacer que las actualizaciones de instalación sean menos complicadas).
Deltas y vuelcos deben revisarse antes de la prueba beta. No veo ninguna forma de evitar esto, ya que he visto a los desarrolladores insertar cuentas de prueba en la base de datos por sí mismos.
- Nombra tus bases de datos de la siguiente manera: db_dev, db_test, db_qa, db_prod (Obviamente, nunca deberías codificar los nombres de los db
- Por lo tanto, podría implementar incluso los diferentes tipos de bases de datos en el mismo servidor físico (no lo recomiendo, pero puede que tenga que ... si los recursos son escasos)
- Asegúrese de poder mover datos entre esos automáticamente
- Separe los scripts de creación de db de la población = Siempre debería ser posible recrear el db desde cero y rellenarlo (desde la versión anterior de db o fuente de datos externa)
- no use cadenas de conexión de código duro en el código (ni siquiera en los archivos de configuración): use en las plantillas de cadena de conexión de archivos de configuración, que puede poblar dinámicamente, cada reconfiguración de la aplicación_capa que necesita recompilar es MALA
- utilice el control de versiones de base de datos y el control de versiones de objetos db; si puede permitírselo, utilice productos listos, si no desarrolla algo por su cuenta
- rastrear cada cambio de DDL y guardarlo en alguna tabla de historial ( ejemplo aquí )
- ¡Copias de seguridad DIARIAS! Compruebe qué tan rápido podrá restaurar algo perdido a partir de una copia de seguridad (utilice scripts de restauración automáticos)
- incluso su base de datos DEV y el 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é menos para este, pero cambiaré en el la mentalidad y el proceso comercial le costará mucho menos cuando la mierda golpea al ventilador, así que obligue a los codificadores a subinvertir legalmente lo que sea que haga, pero asegúrese de que este