He encontrado varios sitios que hablan de hacer exactamente esto, pero me faltan algunos detalles importantes. Los pasos generales son
- correr
FLUSH TABLES WITH READ LOCK
- Tome la instantánea de ZFS
- correr
UNLOCK TABLES
Varias fuentes informan que InnoDB, que estoy usando, en realidad no respeta a FLUSH
. El manual de usuario de MySQL señala que hay una FLUSH TABLES...FOR EXPORT
variante para usar con InnoDB, pero eso requiere especificar cada tabla individualmente, en lugar de hacer una copia de seguridad de toda la base de datos. Prefiero evitar especificar cada tabla individualmente porque hay una posibilidad decente de que la lista de tablas no esté sincronizada con las tablas que realmente existen.
El otro problema que tengo es que planeé hacer algo así mysql -h"$HOST" -u"$USERNAME" -p"$PASSWORD" --execute="FLUSH TABLES WITH READ LOCK"
. Sin embargo, esto cierra el bloqueo inmediatamente después de que finaliza la sesión. Esto tiene sentido, pero también es bastante molesto ya que necesito mantener el bloqueo de lectura cuando tomo mi instantánea.
Mi otra idea es hacer una copia de seguridad en caliente usando una herramienta como Percona XtraBackup y tomar instantáneas de la copia de seguridad, pero preferiría no pagar el costo de escribir todos mis datos en una segunda ubicación solo para capturarla.
Respuestas:
Si solo usa InnoDB para todas las tablas y se establece
innodb_flush_log_at_trx_commit
en:1
(el contenido del búfer de registro de InnoDB se escribe en el archivo de registro en cada confirmación de transacción y el archivo de registro se vacía en el disco) o,2
(el contenido del búfer de registro de InnoDB se escribe en el archivo de registro después de cada confirmación de transacción y el archivo de registro se vacía en el disco aproximadamente una vez por segundo),entonces no necesita FLUSH TABLES antes de hacer una instantánea, simplemente ejecute la instantánea ZFS directamente. InnoDB puede recuperar datos de registros de confirmación de transacciones sin pérdida de datos.
Ref: https://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar_innodb_flush_log_at_trx_commit
fuente
Necesita un bloqueo completo de la base de datos para hacer una copia de seguridad de una (la mayoría) de las bases de datos de manera consistente.
El manual https://dev.mysql.com/doc/refman/5.5/en/backup-methods.html dice FLUSH TABLES WITH READ LOCK es correcto para las instantáneas de ZFS específicamente.
Es un poco ridículo que dejaron el hecho de que usted necesita
FLUSH TABLES table_a, table_b, table_c FOR EXPORT
para InnoDB de estas instrucciones. También es estúpido tener que especificar cada tabla de esa manera. Pero como dice EEAA, puede generar una lista de tablas a medida que comienza la copia de seguridad con bastante facilidad.En cuanto a mantener el bloqueo, debe mantener activa la conexión db mientras realiza la instantánea
En general, usaría algo como Perl u otro lenguaje de programación que pueda conectarse, bloquear la base de datos y, mientras mantengo la conexión de la base de datos, tomar la instantánea, luego desbloquear y desconectar. No es complejo Apostaría a que existen herramientas que ya hacen esto, pero escribir una es fácil.
Digo fácil, no complejo, etc. algunas veces. Supongo que tienes algo de programación básica o buenas habilidades de secuencias de comandos.
fuente
FLUSH TABLES WITH READ LOCK
y luegoFLUSH TABLES...FOR EXPORT
, mientras que mi lectura del manual de MySQL dice que solo una debería ser necesaria.He estafado y adaptado un script conceptualmente simple en Bash que encontré en otra publicación de Server Fault de Tobia . Debería llevarte aproximadamente el 90% del camino hasta allí.
Aquí, el
mysql
comando que usa se ejecuta en segundo plano y toca un archivo. Espera en segundo plano a que el archivo desaparezca antes de salir y, por lo tanto, desbloquear las tablas. Mientras tanto, el script principal espera hasta que el archivo exista, luego crea la instantánea y elimina el archivo.El archivo señalado por
$mysql_locked
debe ser accesible para ambas máquinas, lo que debería poder hacer con bastante facilidad ya que ambos pueden acceder a un conjunto de datos común (aunque podrían usar rutas diferentes, y debe tener esto en cuenta).fuente
system zfs snapshot...
dentro de la secuencia de comandos principal? ¿O el snap-shotting tiene que ejecutarse en un proceso separado?SYSTEM
comando ejecuta las cosas localmente. Si ejecuto el cliente mysql en el cuadro de FreeBSD y ejecutoLOCK; SYSTEM zfs snapshot; UNLOCK
, parece que funcionaría.Necesita FLUSH TABLES WITH READ LOCK para myisam porque no es diario.
Realmente no necesitas nada para innodb, IMO, porque es un diario. De todos modos, será consistente, solo retrocede el diario automáticamente si algo está sucediendo en el instante atómico de la instantánea.
Si desea que el nivel de aplicación sea coherente, su aplicación debe usar transacciones. Si su aplicación usa transacciones e innodb, cualquier instantánea será coherente, pregunte el camino al nivel de la aplicación automáticamente.
fuente
Esta es mi solución para crear una instantánea de ZFS manteniendo el bloqueo:
fuente