Me sorprendió un poco descubrir que las declaraciones DDL ( alter table
, create index
etc.) comprometen implícitamente la transacción actual en MySQL. Procedente de MS SQL Server, la capacidad de realizar alteraciones en la base de datos en una transacción local (que luego se revertió) fue una parte importante de mi flujo de trabajo. Para una integración continua, la reversión se usó si la migración se interrumpió por algún motivo, por lo que al menos no dejamos la base de datos en un estado medio migrado.
¿Cómo resuelve la gente estos dos problemas cuando usa MySQL con migraciones e integración continua?
mysql
transaction
ddl
rollback
sennett
fuente
fuente
Respuestas:
Para muchas personas, el talón de MySQL Achilles es un compromiso implícito.
De acuerdo con la página 418, párrafo 3 del libro
los siguientes comandos pueden y romperán una transacción
ALTER TABLE
BEGIN
CREATE INDEX
DROP DATABASE
DROP INDEX
DROP TABLE
RENAME TABLE
TRUNCATE TABLE
LOCK TABLES
UNLOCK TABLES
SET AUTOCOMMIT = 1
START TRANSACTION
SUGERENCIA
Cuando se trata de MySQL, cualquier trabajo de ContinuousIntegration (CI) / SelfService que construya siempre debe hacer que los trabajos transaccionales y los scripts DDL se excluyan mutuamente.
Esto le brinda la oportunidad de crear paradigmas que
START TRANSACTION/COMMIT
bloquesADVERTENCIA: si está utilizando MyISAM para esto, puede (des) agregar amablemente MyISAM a la lista de cosas que pueden interrumpir una transacción, tal vez no en términos de confirmación implícita, pero definitivamente en términos de consistencia de datos si alguna vez se produce un retroceso necesario.
¿POR QUÉ NO LVM?
Las instantáneas LVM son excelentes y es ideal restaurar instancias completas de bases de datos sin tener que realizar un procesamiento SQL pesado. Sin embargo, cuando se trata de MySQL, debe tener en cuenta dos motores de almacenamiento: InnoDB y MyISAM.
Base de datos All-InnoDB
Mire la arquitectura de InnoDB (Imagen cortesía de Percona CTO Vadim Tkachenko)
InnoDB tiene muchas partes móviles
Tomar una instantánea LVM de una base de datos de todo InnoDB con cambios no confirmados flotando en el Buffer Pool y las memorias caché de memoria produciría un conjunto de datos que requeriría la recuperación de InnoDB una vez que se restaura el LUN y se inicia mysqld.
SUGERENCIA PARA ALL-InnoDB
Si puede cerrar MySQL antes de tomar una instantánea
SET GLOBAL innodb_fast_shutdown = 0;
SET GLOBAL innodb_max_dirty_pages_pct = 0;
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
service mysql stop
service mysql stop
Si no puede apagar pero tomar una instantánea con MySQL Live
SET GLOBAL innodb_max_dirty_pages_pct = 0;
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
SET GLOBAL innodb_max_dirty_pages_pct = 75;
All-MyISAM Database o InnoDB / MyISAM Mix
MyISAM, cuando se accede, mantiene un recuento de identificadores de archivos abiertos en su contra. Si MySQL se bloquea, cualquier tabla de MyISAM con un conteo de identificadores de archivo abierto> 0 se marcará como bloqueada y necesita reparación (incluso si no hay ningún problema con los datos).
Tomar una instantánea LVM de una base de datos que tiene tablas MyISAM en uso tendrá una o más tablas MyISAM que necesitan reparación cuando se restaura la instantánea y se inicia mysqld.
SUGERENCIA PARA All-MyISAM o InnoDB / MyISAM Mix
Si puede cerrar MySQL antes de tomar una instantánea
SET GLOBAL innodb_fast_shutdown = 0;
SET GLOBAL innodb_max_dirty_pages_pct = 0;
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
service mysql stop
service mysql stop
Si no puede apagar pero tomar una instantánea con MySQL Live
Podría forzar un vaciado de ciertas tablas de InnoDB
SET GLOBAL innodb_max_dirty_pages_pct = 0;
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
FLUSH TABLES innodb_tbl1,... FOR EXPORT;
en tablas críticas de InnoDBFLUSH TABLES WITH READ LOCK;
UNLOCK TABLES;
SET GLOBAL innodb_max_dirty_pages_pct = 75;
¿Podría la replicación MySQL ayudar?
Si bien puede restaurar una instantánea LVM en dos servidores y configurar MySQL Master / Slave Replication, eso se convierte en una fuente adicional de limpieza doméstica al restaurar las instantáneas.
Si ejecuta trabajos de CI en un maestro y esos trabajos son pequeños, la replicación podría ahorrar tiempo en determinadas circunstancias. Podrías simplemente ejecutar
STOP SLAVE;
el Esclavo, iniciar los trabajos de CI en el Maestro y ejecutarSTART SLAVE;
el Esclavo cuando los datos del Maestro estén certificados.Si los trabajos de CI alertan demasiados datos, puede restaurar la instantánea LVM y configurar la replicación desde cero. Si te encuentras haciendo esto a menudo, probablemente podrías hacerlo con la configuración de MySQL Replication.
PENSAMIENTOS FINALES
fuente
Si habla de integración continua, supongo que es un entorno de desarrollo. En ese caso, diría que la persona que realiza cambios estructurales tiene que probarlos para asegurarse de no romper las cosas para otros, de la misma manera que alguien actualiza una biblioteca común: pruebe en su propia caja de arena antes de cometer dichos cambios.
En un proceso de implementación de producción, normalmente pasaría por entornos de desarrollo, control de calidad o incluso de preproducción para probar sus cambios, de la misma manera que lo haría para cualquier cambio de código.
Tenga en cuenta que esto no es específico de MySQL: las bases de datos de Oracle también harían COMMIT implícitamente al emitir 'alter table', etc.
Ahora, si desea protegerse, puede hacer una copia de seguridad de antemano, o una instantánea de LVM o del sistema de archivos si su sistema puede hacerlo. También puede tener un esclavo que podría retrasar / detener como seguridad antes de operaciones sensibles.
fuente