sql >> Base de Datos >  >> RDS >> MariaDB

Cómo realizar cambios de esquema en MySQL y MariaDB de forma segura

Antes de intentar realizar cualquier cambio de esquema en sus bases de datos de producción, debe asegurarse de tener un plan de reversión sólido como una roca; y que su procedimiento de cambio ha sido probado y validado con éxito en un entorno separado. Al mismo tiempo, es su responsabilidad asegurarse de que el cambio no cause el menor impacto posible aceptable para el negocio. Definitivamente no es una tarea fácil.

En este artículo, veremos cómo realizar cambios en la base de datos en MySQL y MariaDB de forma controlada. Hablaremos sobre algunos buenos hábitos en su trabajo diario de DBA. Nos centraremos en los requisitos previos y las tareas durante las operaciones reales y los problemas que puede enfrentar cuando se trata de cambios en el esquema de la base de datos. También hablaremos sobre herramientas de código abierto que pueden ayudarlo en el proceso.

Escenarios de prueba y reversión

Copia de seguridad

Hay muchas maneras de perder sus datos. El error de actualización del esquema es uno de ellos. A diferencia del código de la aplicación, no puede soltar un paquete de archivos y declarar que se ha implementado correctamente una nueva versión. Tampoco puede simplemente volver a colocar un conjunto anterior de archivos para revertir sus cambios. Por supuesto, puede ejecutar otra secuencia de comandos SQL para cambiar la base de datos nuevamente, pero hay casos en los que la única forma precisa de revertir los cambios es restaurar toda la base de datos desde la copia de seguridad.

Sin embargo, ¿qué sucede si no puede permitirse revertir su base de datos a la última copia de seguridad, o si su ventana de mantenimiento no es lo suficientemente grande (teniendo en cuenta el rendimiento del sistema), por lo que no puede realizar una copia de seguridad completa de la base de datos antes del cambio?

Uno puede tener un entorno sofisticado y redundante, pero siempre que los datos se modifiquen en las ubicaciones principal y de reserva, no hay mucho que hacer al respecto. Muchos scripts solo se pueden ejecutar una vez, o los cambios son imposibles de deshacer. La mayor parte del código de cambio de SQL se divide en dos grupos:

  • Ejecutar una vez:no puede agregar la misma columna a la tabla dos veces.
  • Imposible de deshacer:una vez que sueltas esa columna, desaparece. Sin duda, podría restaurar su base de datos, pero eso no es precisamente deshacer.

Puede abordar este problema al menos de dos maneras posibles. Una sería habilitar el registro binario y realizar una copia de seguridad, que es compatible con PITR. Dicha copia de seguridad debe ser completa, completa y coherente. Para xtrabackup, siempre que contenga un conjunto de datos completo, será compatible con PITR. Para mysqldump, también hay una opción para hacerlo compatible con PITR. Para cambios más pequeños, una variación de la copia de seguridad de mysqldump sería tomar solo un subconjunto de datos para cambiar. Esto se puede hacer con la opción --where. La copia de seguridad debe ser parte del mantenimiento planificado.

mysqldump -u -p --lock-all-tables --where="WHERE employee_id=100" mydb employees> backup_table_tmp_change_07132018.sql

Otra posibilidad es usar CREAR TABLA COMO SELECCIONAR.

Puede almacenar datos o cambios de estructura simples en forma de una tabla temporal fija. Con este enfoque, obtendrá una fuente si necesita revertir sus cambios. Puede ser bastante útil si no cambia muchos datos. La reversión se puede hacer extrayendo datos de él. Si se produce algún error al copiar los datos en la tabla, se eliminan automáticamente y no se crean, así que asegúrese de que su extracto cree la copia que necesita.

Obviamente, también hay algunas limitaciones.

Dado que no siempre se puede determinar el orden de las filas en las sentencias SELECT subyacentes, CREATE TABLE... IGNORE SELECT y CREATE TABLE... REPLACE SELECT se marcan como no seguras para la replicación basada en sentencias. Tales declaraciones producen una advertencia en el registro de errores cuando se usa el modo basado en declaraciones y se escriben en el registro binario usando el formato basado en filas cuando se usa el modo MIXTO.

Un ejemplo muy simple de dicho método podría ser:

CREATE TABLE tmp_employees_change_07132018 AS SELECT * FROM employees where employee_id=100;
UPDATE employees SET salary=120000 WHERE employee_id=100;
COMMMIT;

Otra opción interesante puede ser la base de datos flashback de MariaDB. Cuando ocurre una actualización o eliminación incorrecta, y le gustaría volver a un estado de la base de datos (o solo una tabla) en un momento determinado, puede usar la función de flashback.

La reversión en un punto en el tiempo permite a los DBA recuperar datos más rápido al revertir las transacciones a un punto en el tiempo anterior en lugar de realizar una restauración desde una copia de seguridad. Basado en eventos DML basados ​​en ROW, el flashback puede transformar el registro binario y los propósitos inversos. Eso significa que puede ayudar a deshacer cambios de fila dados rápidamente. Por ejemplo, puede cambiar los eventos DELETE a INSERT y viceversa, y cambiará las partes WHERE y SET de los eventos UPDATE. Esta simple idea puede acelerar drásticamente la recuperación de ciertos tipos de errores o desastres. Para aquellos que están familiarizados con la base de datos de Oracle, es una característica bien conocida. La limitación de MariaDB flashback es la falta de compatibilidad con DDL.

Crear un esclavo de replicación retrasada

Desde la versión 5.6, MySQL admite la replicación retrasada. Un servidor esclavo puede retrasarse con respecto al maestro al menos una cantidad de tiempo específica. El retraso predeterminado es de 0 segundos. Use la opción MASTER_DELAY para CHANGE MASTER TO para establecer el retraso en N segundos:

CHANGE MASTER TO MASTER_DELAY = N;

Sería una buena opción si no tuviera tiempo para preparar un escenario de recuperación adecuado. Debe tener suficiente retraso para notar el cambio problemático. La ventaja de este enfoque es que no necesita restaurar su base de datos para eliminar los datos necesarios para corregir su cambio. La base de datos en espera está en funcionamiento, lista para recopilar datos, lo que minimiza el tiempo necesario.

Cree un esclavo asíncrono que no sea parte del clúster

Cuando se trata del clúster de Galera, probar los cambios no es fácil. Todos los nodos ejecutan los mismos datos y una carga pesada puede dañar el control de flujo. Por lo tanto, no solo debe verificar si los cambios se aplicaron correctamente, sino también cuál fue el impacto en el estado del clúster. Para que su procedimiento de prueba sea lo más parecido posible a la carga de trabajo de producción, es posible que desee agregar un esclavo asíncrono a su clúster y ejecutar su prueba allí. La prueba no afectará la sincronización entre los nodos del clúster, porque técnicamente no es parte del clúster, pero tendrá la opción de verificarlo con datos reales. Dicho esclavo se puede agregar fácilmente desde ClusterControl.

ClusterControl agregar esclavo asíncrono

Como se muestra en la captura de pantalla anterior, ClusterControl puede automatizar el proceso de agregar un esclavo asíncrono de varias maneras. Puede agregar el nodo al clúster, retrasar el esclavo. Para reducir el impacto en el maestro, puede usar una copia de seguridad existente en lugar del maestro como fuente de datos al construir el esclavo.

Clonar base de datos y medir el tiempo

Una buena prueba debe estar lo más cerca posible del cambio de producción. La mejor manera de hacer esto es clonar su entorno existente.

ClusterControl Clone Cluster para prueba

Realizar cambios a través de la replicación

Para tener un mejor control sobre sus cambios, puede aplicarlos en un servidor esclavo con anticipación y luego hacer el cambio. Para la replicación basada en declaraciones, esto funciona bien, pero para la replicación basada en filas, esto puede funcionar hasta cierto punto. La replicación basada en filas permite que existan columnas adicionales al final de la tabla, por lo que siempre que pueda escribir las primeras columnas, estará bien. Primero aplique esta configuración a todos los esclavos, luego realice la conmutación por error a uno de los esclavos y luego implemente el cambio en el maestro y conéctelo como esclavo. Si su modificación implica insertar o eliminar una columna en el medio de la tabla, funcionará con la replicación basada en filas.

Operación

Durante la ventana de mantenimiento, no queremos tener tráfico de aplicaciones en la base de datos. A veces es difícil cerrar todas las aplicaciones repartidas por toda la empresa. Alternativamente, queremos permitir que solo algunos hosts específicos accedan a MySQL de forma remota (por ejemplo, el sistema de monitoreo o el servidor de respaldo). Para ello, podemos utilizar el filtrado de paquetes de Linux. Para ver qué reglas de filtrado de paquetes están disponibles, podemos ejecutar el siguiente comando:

iptables -L INPUT -v

Para cerrar el puerto MySQL en todas las interfaces usamos:

iptables -A INPUT -p tcp --dport mysql -j DROP

y para abrir el puerto MySQL nuevamente después de la ventana de mantenimiento:

iptables -D INPUT -p tcp --dport mysql -j DROP

Para aquellos sin acceso de raíz, puede cambiar max_connection a 1 o 'omitir redes'.

Registro

Para iniciar el proceso de registro, use el comando tee en el indicador del cliente de MySQL, así:

mysql> tee /tmp/my.out;

Ese comando le dice a MySQL que registre tanto la entrada como la salida de su sesión de inicio de sesión de MySQL actual en un archivo llamado /tmp/my.out. Luego ejecute su archivo de script con el comando fuente.

Para tener una mejor idea de sus tiempos de ejecución, puede combinarlo con la función de generador de perfiles. Inicie el generador de perfiles con

SET profiling = 1;

Luego ejecute su Consulta con

SHOW PROFILES;

verá una lista de consultas para las que el generador de perfiles tiene estadísticas. Entonces, finalmente, elige con qué consulta examinar

SHOW PROFILE FOR QUERY 1;

Herramientas de migración de esquemas

Muchas veces, un ALTER directo en el maestro no es posible; en la mayoría de los casos, provoca un retraso en el esclavo, y esto puede no ser aceptable para las aplicaciones. Sin embargo, lo que se puede hacer es ejecutar el cambio en un modo continuo. Puede comenzar con esclavos y, una vez que se aplica el cambio al esclavo, migrar uno de los esclavos como nuevo maestro, degradar el antiguo maestro a esclavo y ejecutar el cambio en él.

Una herramienta que puede ayudar con esta tarea es pt-online-schema-change de Percona. Pt-online-schema-change es sencillo:crea una tabla temporal con el nuevo esquema deseado (por ejemplo, si agregamos un índice o eliminamos una columna de una tabla). Luego, crea activadores en la tabla anterior. Esos disparadores están ahí para reflejar los cambios que ocurren en la tabla original en la nueva tabla. Los cambios se reflejan durante el proceso de cambio de esquema. Si se agrega una fila a la tabla original, también se agrega a la nueva. Emula la forma en que MySQL modifica las tablas internamente, pero funciona en una copia de la tabla que desea modificar. Significa que la tabla original no está bloqueada y los clientes pueden continuar leyendo y cambiando datos en ella.

Asimismo, si se modifica o elimina una fila en la tabla anterior, también se aplica en la tabla nueva. Luego, comienza un proceso en segundo plano de copia de datos (usando LOW_PRIORITY INSERT) entre la tabla antigua y la nueva. Una vez que se han copiado los datos, se ejecuta RENAME TABLE.

Otra herramienta interesante es gh-ost. Gh-ost crea una tabla temporal con el esquema alterado, tal como lo hace pt-online-schema-change. Ejecuta consultas INSERT, que utilizan el siguiente patrón para copiar datos de la tabla antigua a la nueva. Sin embargo, no utiliza disparadores. Desafortunadamente, los disparadores pueden ser la fuente de muchas limitaciones. gh-ost utiliza el flujo de registro binario para capturar los cambios de la tabla y los aplica de forma asíncrona en la tabla fantasma. Una vez que verificamos que gh-ost puede ejecutar nuestro cambio de esquema correctamente, es hora de ejecutarlo. Tenga en cuenta que es posible que deba eliminar manualmente las tablas antiguas creadas por gh-ost durante el proceso de prueba de la migración. También puede usar las banderas --initially-drop-ghost-table y --initially-drop-old-table para pedirle a gh-ost que lo haga por usted. El comando final a ejecutar es exactamente el mismo que usamos para probar nuestro cambio, solo le agregamos --ejecutar.

pt-online-schema-change y gh-ost son muy populares entre los usuarios de Galera. No obstante, Galera tiene algunas opciones adicionales. Los dos métodos Aislamiento de orden total (TOI) y Actualización de esquema continuo (RSU) tienen sus pros y sus contras.

TOI:este es el método de replicación DDL predeterminado. El nodo que origina el conjunto de escritura detecta DDL en el momento del análisis y envía un evento de replicación para la instrucción SQL incluso antes de iniciar el procesamiento de DDL. Las actualizaciones de esquema se ejecutan en todos los nodos del clúster en la misma secuencia de orden total, lo que evita que se confirmen otras transacciones durante la operación. Este método es bueno cuando desea que sus actualizaciones de esquema en línea se repliquen a través del clúster y no le importa bloquear toda la tabla (similar a cómo ocurrieron los cambios de esquema predeterminados en MySQL).

SET GLOBAL wsrep_OSU_method='TOI';

RSU:realice las actualizaciones del esquema localmente. En este método, sus escrituras afectan solo al nodo en el que se ejecutan. Los cambios no se replican en el resto del clúster. Este método es bueno para operaciones sin conflictos y no ralentizará el clúster.

SET GLOBAL wsrep_OSU_method='RSU';

Mientras el nodo procesa la actualización del esquema, se desincroniza con el clúster. Cuando termina de procesar la actualización del esquema, aplica eventos de replicación retrasados ​​y se sincroniza con el clúster. Esta podría ser una buena opción para ejecutar creaciones de índices pesados.

Conclusión

Aquí presentamos varios métodos diferentes que pueden ayudarlo a planificar sus cambios de esquema. Por supuesto, todo depende de la aplicación y los requisitos comerciales. Puede diseñar su plan de cambio, realizar las pruebas necesarias, pero aún existe una pequeña posibilidad de que algo salga mal. De acuerdo con la ley de Murphy, "las cosas saldrán mal en cualquier situación dada, si les das una oportunidad". Así que asegúrese de probar diferentes formas de realizar estos cambios y elija la que le resulte más cómoda.