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
- Admitir transacciones que están correctamente aisladas con
START TRANSACTION/COMMIT
bloques
- control de DDL mediante secuencias de comandos de DDL usted mismo, ejecutando DDL como constructor o destructor
- Constructor: DDL para hacer tablas con un nuevo diseño
- Destructor: DDL para hacer que las tablas vuelvan al diseño anterior
- nunca combine estas operaciones bajo un solo trabajo
ADVERTENCIA: 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
- Sistema de tablas
- Diccionario de datos
- Doble búfer de escritura (soporte de consistencia de datos; utilizado para la recuperación de fallos)
- Insertar almacenamiento intermedio (almacena cambios en los índices secundarios no únicos)
- Segmentos de reversión
- Deshacer espacio (donde puede ocurrir el crecimiento más descontrolado)
- InnoDB Buffer Pool
- Páginas de datos sucios
- Páginas de índice sucias
- Cambios en los índices no únicos
- Otros cachés de memoria importantes
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
- correr
SET GLOBAL innodb_fast_shutdown = 0;
- correr
SET GLOBAL innodb_max_dirty_pages_pct = 0;
- correr
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
- Repita el paso 3 hasta que Innodb_buffer_pool_pages_dirty sea 0 o lo más cerca posible a 0
service mysql stop
- Tomar una instantánea de LVM
service mysql stop
Si no puede apagar pero tomar una instantánea con MySQL Live
- correr
SET GLOBAL innodb_max_dirty_pages_pct = 0;
- correr
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
- Repita el paso 2 hasta que Innodb_buffer_pool_pages_dirty sea 0 o lo más cerca posible a 0
- Tomar una instantánea de LVM
- correr
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
- correr
SET GLOBAL innodb_fast_shutdown = 0;
- correr
SET GLOBAL innodb_max_dirty_pages_pct = 0;
- correr
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
- Repita el paso 3 hasta que Innodb_buffer_pool_pages_dirty sea 0 o lo más cerca posible a 0
service mysql stop
- Tomar una instantánea de LVM
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
- correr
SET GLOBAL innodb_max_dirty_pages_pct = 0;
- correr
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
- Repita el paso 2 hasta que Innodb_buffer_pool_pages_dirty sea 0 o lo más cerca posible a 0
- Ejecutar
FLUSH TABLES innodb_tbl1,... FOR EXPORT;
en tablas críticas de InnoDB
- correr
FLUSH TABLES WITH READ LOCK;
- Tomar una instantánea de LVM
- correr
UNLOCK TABLES;
- correr
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 ejecutar START 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
- Es mejor usar múltiples servidores de DB (3 o más) para realizar restauraciones y pruebas de regresión.
- Convierta las tablas restantes de MyISAM a InnoDB si esas tablas no necesitan permanecer como MyISAM.
- Si el contenido de sus datos es confidencial, debe ejecutar un trabajo de CI para eliminar los datos después de restaurar una instantánea antes de iniciar cualquier prueba. Como alternativa, es posible que desee tomar instantáneas de MySQL con los datos ya borrados.