Pregunta

¿Está bien ejecutar aplicaciones de Hibernate configuradas con hbm2ddl.auto = update para actualizar el esquema de la base de datos en un entorno de producción?

¿Fue útil?

Solución

No, no es seguro.

A pesar de los mejores esfuerzos del equipo de Hibernate, simplemente no puede confiar en las actualizaciones automáticas en producción . Escriba sus propios parches, revíselos con DBA, pruébelos y luego aplíquelos manualmente.

En teoría, si hbm2ddl update funcionó en el desarrollo, también debería funcionar en producción. Pero en realidad, no siempre es el caso.

Incluso si funcionó bien, puede ser subóptimo. Los DBA se pagan tanto por una razón.

Otros consejos

Lo hacemos en producción, aunque con una aplicación que no es de misión crítica y que no cuenta con DBA altamente pagados en el personal. Es solo un proceso manual menos que está sujeto a errores humanos: la aplicación puede detectar la diferencia y hacer lo correcto, además, presumiblemente lo ha probado en varios entornos de desarrollo y prueba.

Una advertencia: en un entorno en clúster, es posible que desee evitarlo porque pueden aparecer varias aplicaciones al mismo tiempo e intentar modificar el esquema que podría ser malo. O coloque algún mecanismo en el que solo una instancia pueda actualizar el esquema.

Los creadores de Hibernate desalientan hacerlo en un entorno de producción en su libro " Persistencia de Java con Hibernate " :

  

ADVERTENCIA: hemos visto a usuarios de Hibernate tratar de usar la actualización de esquema para actualizar el esquema de una base de datos de producción automáticamente. Esto puede terminar rápidamente en un desastre y su DBA no lo permitirá.

Consulte LiquiBase XML para mantener un registro de cambios de actualizaciones. Nunca lo había usado hasta este año, pero descubrí que es muy fácil de aprender y que el control de revisión de DB / migración / gestión de cambios es muy infalible. Trabajo en un proyecto Groovy / Grails, y Grails usa Hibernate debajo de todo su ORM (llamado "GORM"). Usamos Liquibase para administrar todos los cambios en el esquema SQL, lo que hacemos con bastante frecuencia a medida que nuestra aplicación evoluciona con nuevas características.

Básicamente, usted mantiene un archivo XML de conjuntos de cambios que continúa agregando a medida que su aplicación evoluciona. Este archivo se guarda en git (o lo que esté usando) con el resto de su proyecto. Cuando se implementa su aplicación, Liquibase comprueba su tabla de cambios en la base de datos a la que se está conectando para que sepa lo que ya se ha aplicado, luego se aplica de manera inteligente cualquier conjunto de cambios que aún no se haya aplicado desde el archivo. Funciona absolutamente bien en la práctica, y si lo usa para todos los cambios de esquema, entonces puede estar 100% seguro de que el código que extraiga y despliegue siempre podrá conectarse a un esquema de base de datos totalmente compatible.

Lo increíble es que puedo tomar una base de datos mysql de pizarra totalmente en blanco en mi computadora portátil, iniciar la aplicación y de inmediato el esquema está configurado para mí. También hace que sea más fácil probar los cambios de esquema al aplicarlos primero a un dev local o a un db provisional.

La forma más fácil de comenzar probablemente sería tomar su base de datos existente y luego usar Liquibase para generar un archivo baseline.xml inicial. Luego, en el futuro, simplemente puede agregarlo y dejar que liquibase asuma la administración de los cambios de esquema.

http://www.liquibase.org/

Hibernate tiene que poner el descargo de responsabilidad acerca de no usar actualizaciones automáticas en prod para cubrirse a sí mismos cuando las personas que no saben lo que están haciendo lo usan en situaciones donde no se debe usar.

Admitió que las situaciones en las que no se debe usar superan en gran medida a las que están bien.

Lo he usado durante años en muchos proyectos diferentes y nunca he tenido un solo problema. Esa no es una respuesta tonta, y no es una codificación de vaquero. Es un hecho histórico.

Una persona que dice "nunca lo hagas en producción" está pensando en un conjunto específico de implementaciones de producción, es decir, con las que está familiarizado (su empresa, su industria, etc.).

El universo de las "implementaciones de producción" es vasto y variado.

Un desarrollador experimentado de Hibernate sabe exactamente qué DDL va a resultar de una configuración de mapeo dada. Siempre que pruebe y valide que lo que espera termina en el DDL (en dev, qa, puesta en escena, etc.), estará bien.

Cuando agrega muchas características, las actualizaciones automáticas de esquemas pueden ser un ahorro de tiempo real.

La lista de cosas que las actualizaciones automáticas no pueden manejar es interminable, pero algunos ejemplos son la migración de datos, la adición de columnas que no admiten nulos, los cambios de nombre de columna, etc., etc.

También debe tener cuidado en entornos agrupados.

Pero, de nuevo, si supieras todo esto, no harías esta pregunta. Hmm . . De acuerdo, si está haciendo esta pregunta, debe esperar hasta que tenga mucha experiencia con las actualizaciones de Hibernate y el esquema automático antes de pensar en usarlo en prod.

Yo votaría no. Hibernate no parece entender cuándo los tipos de datos para las columnas han cambiado. Ejemplos (usando MySQL):

String with @Column(length=50)  ==> varchar(50)
changed to
String with @Column(length=100) ==> still varchar(50), not changed to varchar(100)

@Temporal(TemporalType.TIMESTAMP,TIME,DATE) will not update the DB columns if changed

Probablemente también haya otros ejemplos, como aumentar la longitud de una columna de Cadena a más de 255 y verla convertir a texto, texto intermedio, etc. etc.

Por supuesto, no creo que realmente haya una forma de " tipos de datos " sin crear una nueva columna, copiando los datos y eliminando la columna anterior. Pero el minuto en que su base de datos tiene columnas que no reflejan el mapa actual de Hibernate en el que vive, es muy peligroso ...

Flyway es una buena opción para tratar este problema:

http://flywaydb.org

Como expliqué en este artículo , no es una buena idea use hbm2ddl.auto en producción.

La única forma de administrar el esquema de la base de datos es usar scripts de migración incremental porque:

  • los scripts residirán en VCS a lo largo de su código base. Cuando desprotege una rama, recrea todo el esquema desde cero.
  • los scripts incrementales pueden probarse en un servidor de control de calidad antes de aplicarse en producción
  • no hay necesidad de intervención manual ya que los scripts pueden ejecutarse por Flyway , por lo tanto, reduce la posibilidad de que haya humanos. error asociado con la ejecución manual de scripts.

Incluso el Hibernate User Guide aconsejarle que evite usar la herramienta hbm2ddl para entornos de producción.

 ingrese la descripción de la imagen aquí

No me arriesgaría porque podría terminar perdiendo datos que deberían haberse conservado. hbm2ddl.auto = actualizar es una forma puramente fácil de mantener actualizada su base de datos de desarrollo.

Lo hacemos en un proyecto que se ejecuta en producción desde hace meses y nunca tuvimos un problema hasta ahora. Tenga en cuenta los 2 ingredientes necesarios para esta receta:

  1. Diseñe su modelo de objetos con un enfoque de compatibilidad con versiones anteriores, es decir, desapruebe los objetos y atributos en lugar de eliminarlos / alterarlos. Esto significa que si necesita cambiar el nombre de un objeto o atributo, deje el anterior tal como está, agregue el nuevo y escriba algún tipo de script de migración. Si necesita cambiar una asociación entre objetos, si ya está en producción, esto significa que su diseño fue incorrecto en primer lugar, así que intente pensar en una nueva forma de expresar la nueva relación, sin afectar los datos antiguos.

  2. Siempre realice una copia de seguridad de la base de datos antes de la implementación.

Mi opinión es, después de leer este post, que el 90% de las personas que participan en esta discusión están horrorizadas solo con la idea de utilizar automatizaciones como esta en un entorno de producción. Algunos lanzan la pelota al DBA. No obstante, tómese un momento para considerar que no todos los entornos de producción proporcionarán un DBA y no muchos equipos de desarrollo podrán costear uno (al menos para proyectos de tamaño medio). Entonces, si estamos hablando de equipos donde todos tienen que hacer todo, la pelota está en ellos.

En este caso, ¿por qué no tratar de tener lo mejor de ambos mundos? Herramientas como esta están aquí para ayudar, que, con un diseño y un plan cuidadosos, pueden ayudar en muchas situaciones. Y créanme, inicialmente los administradores pueden ser difíciles de convencer, pero si saben que la pelota no está en sus manos, les encantará.

Personalmente, nunca volvería a escribir guiones a mano para extender cualquier tipo de esquema, pero esa es solo mi opinión. Y luego de comenzar a adoptar las bases de datos sin esquema NoSQL recientemente, puedo ver que más pronto, todas estas operaciones basadas en esquemas pertenecerán al pasado, por lo que es mejor que empieces a cambiar tu perspectiva y mires hacia el futuro.

  • En mi caso (Hibernate 3.5.2, Postgresql, Ubuntu), establecer hibernate.hbm2ddl.auto = update solo creó nuevas tablas y creó nuevas columnas en tablas ya existentes.

  • No eliminó tablas, ni eliminó columnas, ni alteró columnas. Puede llamarse una opción segura, pero algo como hibernate.hbm2ddl.auto = create_tables add_columns sería más claro.

No es seguro, no se recomienda, pero es posible.

Tengo experiencia en una aplicación con la opción de actualización automática en producción.

Bueno, los principales problemas y riesgos encontrados en esta solución son:

  • Implementar en la base de datos incorrecta . Si comete el error de ejecutar el servidor de aplicaciones con una versión anterior de la aplicación (EAR / WAR / etc) en la base de datos incorrecta ... Tendrá muchas columnas, tablas, claves externas y errores nuevos. El mismo problema puede ocurrir con un simple error en el archivo de fuente de datos, (copiar / pegar archivo y olvidó cambiar la base de datos). En resumen, la situación puede ser un desastre en su base de datos.
  • El servidor de aplicaciones tarda demasiado en iniciarse . Esto ocurre porque Hibernate intenta encontrar todas las tablas / columnas / etc creadas cada vez que inicia la aplicación. Necesita saber qué (tabla, columna, etc.) necesita ser creado. Este problema solo empeorará a medida que las tablas de la base de datos crezcan.
  • Las herramientas de la base de datos son casi imposibles de usar . Para crear scripts de base de datos para ejecutar con una nueva versión, debe pensar en lo que se creará mediante la actualización automática después de iniciar el servidor de aplicaciones. Por ejemplo, si necesita llenar una nueva columna con algunos datos, debe iniciar el servidor de aplicaciones, esperar a que Hibernate cree la nueva columna y ejecutar el script SQL solo después de eso. Como puede ver, las herramientas de migración de base de datos (como Flyway, Liquibase, etc.) son casi imposibles de usar con la actualización automática habilitada.
  • Los cambios en la base de datos no están centralizados . Con la posibilidad de que Hibernate cree las tablas y todo lo demás, es difícil ver los cambios en la base de datos en cada versión de la aplicación, porque la mayoría de ellos son automáticos.
  • Fomenta la basura en la base de datos . Debido a la facilidad de la actualización automática, existe la posibilidad de que su equipo deje de colocar columnas y tablas antiguas.
  • Desastre inminente . El riesgo inminente de que ocurra algún desastre en la producción (como algunas personas mencionadas en otras respuestas). Incluso con una aplicación en ejecución y actualizable durante años, no creo que sea segura. Nunca me sentí seguro con esta opción.

Por lo tanto, no recomendaré utilizar la actualización automática en la producción.

Si realmente desea utilizar la actualización automática en producción, le recomiendo:

  • Redes separadas . Su entorno de prueba no puede acceder al entorno homólogo. Esto ayuda a evitar que una implementación que debía estar en el entorno de prueba cambie la base de datos de homologación.
  • Administrar orden de scripts . Debe organizar sus scripts para que se ejecuten antes de su implementación (cambio de tabla de estructura, caída de tabla / columnas) y script después de la implementación (complete la información para las nuevas columnas / tablas).

Y, a diferencia de las otras publicaciones, no creo que la actualización automática habilitada esté relacionada con " muy bien pagada " DBA (como se menciona en otras publicaciones) ... Los DBA tienen cosas más importantes que hacer que escribir sentencias de SQL para crear / cambiar / eliminar tablas y columnas. Los desarrolladores pueden realizar y automatizar estas simples tareas cotidianas y solo se pueden aprobar para que el equipo de DBA las revise, sin necesidad de Hibernate y DBA "muy bien pagados". para escribirlos.

No, nunca lo hagas. Hibernate no maneja la migración de datos. Sí, hará que su esquema se vea correctamente, pero no garantiza que no se pierdan datos valiosos de producción en el proceso.

  • Normalmente, las aplicaciones empresariales en grandes organizaciones se ejecutan con privilegios reducidos.

  • El nombre de usuario de la base de datos

    puede no tener el privilegio DDL para agregar columnas que hbm2ddl.auto = update requiere.

Estoy de acuerdo con Vladimir. Los administradores de mi empresa definitivamente no lo apreciarían si incluso sugiriera tal curso.

Además, crear un script SQL en lugar de confiar ciegamente en Hibernate le brinda la oportunidad de eliminar campos que ya no se usan. Hibernate no hace eso.

Y encuentro que comparar el esquema de producción con el nuevo esquema le da una mejor perspectiva de lo que ha cambiado en el modelo de datos. Ya sabes, por supuesto, porque lo hiciste, pero ahora ves todos los cambios de una vez. Incluso los que te hacen ir como "¡¿Qué diablos?!".

Hay herramientas que pueden hacer un esquema delta para usted, por lo que ni siquiera es un trabajo duro. Y entonces sabes exactamente lo que va a pasar.

El esquema de las aplicaciones puede evolucionar con el tiempo; Si tiene varias instalaciones, que pueden estar en diferentes versiones, debe tener alguna forma de asegurarse de que su aplicación, algún tipo de herramienta o script sea capaz de migrar esquemas y datos de una versión paso a paso a cualquiera.

Tener toda su persistencia en las asignaciones (o anotaciones) de Hibernate es una muy buena manera de mantener la evolución del esquema bajo control.

Debe considerar que la evolución del esquema tiene varios aspectos a considerar:

  1. evolución del esquema de la base de datos en agregando más columnas y tablas

  2. caída de antiguas columnas, tablas y relaciones

  3. llenar nuevas columnas con valores predeterminados

Las herramientas de hibernación son importantes en particular en caso de que (como en mi experiencia) tenga diferentes versiones de la misma aplicación en diferentes tipos de bases de datos.

El punto 3 es muy sensible en caso de que esté utilizando Hibernate, como en el caso de que introduzca una nueva propiedad con valor booleano o una numérica, si Hibernate encontrará algún valor nulo en dichas columnas, si genera una excepción.

Entonces, lo que haría es: de hecho, use la capacidad de las herramientas de Hibernate para la actualización del esquema, pero debe agregar junto con ella algunos datos y devolución de llamada de mantenimiento del esquema, como para rellenar valores predeterminados, descartar columnas que ya no se usan, y similares. De esta forma, obtiene las ventajas (guiones de actualización de esquemas independientes de la base de datos y evita la codificación duplicada de las actualizaciones, en persistencia y en guiones), pero también cubre todos los aspectos de la operación.

Entonces, por ejemplo, si una actualización de la versión consiste simplemente en agregar una propiedad de valor varchar (por lo tanto, columna), que puede ser nula por defecto, con la actualización automática se completará. Donde más complejidad es necesaria, más trabajo será necesario.

Esto se supone que la aplicación, cuando se actualiza, puede actualizar su esquema (se puede hacer), lo que también significa que debe tener los derechos de usuario para hacerlo en el esquema. Si la política del cliente lo impide (probablemente en el caso de Lizard Brain), deberá proporcionar los scripts específicos de la base de datos.

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