Faltan filas después de la conversión en línea de MyISAM a InnoDB

16

Tenemos una base de datos razonablemente pequeña que queríamos convertir de MyISAM a InnoDB. Al ser novatos de la base de datos, acabamos de convertir (usando la tabla alter) sin siquiera quitar el sitio.

Ahora que se ha realizado la conversión, parece que faltan muchas filas intermitentes. ¿Es esto posiblemente debido a las operaciones durante la conversión? ¿O es el problema en otro lugar?

Yuvi
fuente
¿En qué tablas faltan filas? ¿Las que convertiste u otras tablas?
longneck

Respuestas:

20

Realizar un ALTER para cambiar los motores de almacenamiento no hará que las filas desaparezcan. Sin embargo, déjame ofrecerte algunos consejos, ya que dijiste que eres 'novatos de la base de datos' en tu pregunta.

Al modificar el esquema existente o hacer cualquier cosa que pueda afectar los datos, aquí hay algunos consejos básicos:

  1. Haga una copia de seguridad primero.
  2. Tener un plan de cambio.
  3. Pon a prueba tu plan en un host fuera de línea.
  4. Tenga un plan de prueba para comparar datos antes y después.
  5. Programe y tome un tiempo de inactividad.
  6. Realice una copia de seguridad e instantánea inmediatamente después de que su tiempo de inactividad entre en vigencia y verifique que el tráfico se haya detenido.
  7. Si está ejecutando MYISAM, el uso 'CHECK TABLE' para evaluar lo que se está tratando con antes de modificar.
  8. Copie la tabla localmente además de su copia de seguridad, por si acaso.
  9. Proceder con cautela, permitirá "advertencias --show" y otra de salida por lo que tiene el cuadro completo como de realizar los cambios.
  10. Si los datos son importantes para usted, contratar a un DBA, aunque sólo sea para consultar durante la migración por lo que tiene un veterano a su lado.

Probablemente hay mucho más que podría entrar, pero lo anterior le proporcionará opciones cuando algo va mal.

En cuanto a sus datos / filas desaparecidos, no hay manera de saber w / OA "antes / después" instantánea para comparar. Puede comparar con su último respaldo para al menos verificar eso.

randomx
fuente
Leo esto. Buen plan DR. Su respuesta obtiene +1 por ser más sensibles a la cuestión de lo que era, además de un plan de ir hacia adelante.
RolandoMySQLDBA
1
@randy Marcó esta pregunta como favorita por su buena respuesta
techExplorer
8

Una de las mejores formas de convertir MyISAM a InnoDB sin mucho tiempo de inactividad tiene solo un requisito previo: usar un esclavo de replicación.

Aquí hay una vista panorámica del plan

  1. Crear configuración de replicación maestro / esclavo
  2. Convertir cada tabla MyISAM en el esclavo a InnoDB
  3. Apunte su aplicación al esclavo

¿Suena simple? Hay muchos detalles detrás de esto.

Crear configuración de replicación maestro / esclavo

Hay un camino resbaladizo para crear un esclavo sin mucha perturbación del Maestro. Escribí dos publicaciones:

En lugar de detalle cómo utilizar rsync, por favor leer esos dos puestos.

Convertir cada tabla MyISAM en el esclavo a InnoDB

En DB Slave, puede hacer la siguiente instrucción SQL:

Para MySQL 5.5:

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;')
FROM information_schema.tables
WHERE engine = 'MyISAM' AND table_schema NOT IN
('information_schema','mysql','performance_schema');

Versión para MySQL anterior a MySQL 5.5

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;')
FROM information_schema.tables
WHERE engine = 'MyISAM' AND table_schema NOT IN
('information_schema','mysql');

Usando el resultado de la consulta, tiene un script de conversión para el esclavo.

Debe colocar estas dos líneas en la parte superior del script:

SET SQL_LOG_BIN = 0;
STOP SLAVE;

El script primero deshabilitará el registro binario (si configuró el esclavo para tener registros binarios), detendrá la replicación y convertirá cada tabla MyISAM a InnoDB.

Aquí se explica cómo crear ese script y ejecutarlo:

SQLSTMT="SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;') FROM information_schema.tables WHERE engine = 'MyISAM' AND table_schema NOT IN ('information_schema','mysql','performance_schema')"
INNODB_CONV_SCRIPT=MassConvertMyISAMTablesToInnoDB.sql
echo "SET SQL_LOG_BIN = 0;" > ${INNODB_CONV_SCRIPT}
echo "STOP SLAVE;" >> ${INNODB_CONV_SCRIPT}
mysql -h(IP of Master) -u... -p... --skip-column-names -A -e"${SQL}" >> ${INNODB_CONV_SCRIPT}
echo "START SLAVE;" >> ${INNODB_CONV_SCRIPT}
mysql -h(IP of Slave) -u... -p... --skip-column-names -A < ${INNODB_CONV_SCRIPT}

Apunte su aplicación al esclavo

Realizar consultas SELECT desde el esclavo. Si está satisfecho con el contenido de datos en el Esclavo, no dude en señalar su aplicación al esclavo de la siguiente manera:

  1. En Slave, corre SHOW SLAVE STATUS\Gy asegúrate de que Seconds_Behind_Master sea 0
  2. En el Esclavo, mysqldump -h (IP del Esclavo) -u ... -p ... - transacción única --rutinas - activadores --todas las bases de datos> MySQLBackup.sql (Hey, una copia de seguridad sería bueno justo ahora)
  3. En el maestro, ejecute service mysql stop(comienza el tiempo de inactividad)
  4. Repita el paso 1
  5. Apunte su aplicación al esclavo (el tiempo de inactividad termina en la primera conexión de la aplicación)

Si llegaste a este punto ileso, ¡FELICIDADES!

BONIFICACIÓN AGREGADA : Si configura la replicación maestra / maestra (también conocida como replicación circular) en lugar de maestra / esclava, puede hacer esto en su lugar:

  1. En Slave, corre SHOW SLAVE STATUS\Gy asegúrate de que Seconds_Behind_Master sea 0
  2. En el Esclavo, mysqldump -h (IP del Esclavo) -u ... -p ... - transacción única --rutinas - activadores --todas las bases de datos> MySQLBackup.sql (Hey, una copia de seguridad sería bueno justo ahora)
  3. Apunte su aplicación al esclavo (el tiempo de inactividad comienza y finaliza en la primera conexión de la aplicación)
  4. En el nuevo maestro, corre STOP SLAVE;
  5. En el nuevo maestro, corre CHANGE MASTER TO MASTER_HOST='';

Lo que ahora tienes es Maestro / Esclavo en reversa. El nuevo maestro tiene datos de InnoDB y el viejo maestro ahora es un esclavo con datos de MyISAM. Si divide lecturas y escrituras, las lecturas pueden ir desde el esclavo (las lecturas son más rápidas desde MyISAM que InnoDB) y las escrituras van al maestro (soporte transaccional para InnoDB). Como canta Hannah Montana, obtienes lo mejor de ambos mundos (¡¡Sí, tengo dos hijas que aman el espectáculo) !!!

OTRA BONIFICACIÓN ADICIONAL : Debido a que el Maestro ahora es InnoDB, puede hacer mysqldump desde el Maestro sin tiempo de inactividad y sin interferir con las transacciones. El único inconveniente es aumentar la CPU y la E / S de disco. Por lo tanto, podría utilizar un mysqldump de estructuras de tabla solo en el Maestro (InnoDB) y un mysqldump de los datos solo en el esclavo (Tal volcado no tendrá referencias a InnoDB o MyISAM. Solo serán datos) más un mysqldump del estructuras de tabla para que el esclavo tenga el diseño MyISAM.

Las posibilidades pueden continuar debido a esta nueva configuración ...

ACTUALIZACIÓN 2011-08-27 19:50 EDT

Mis disculpas. No leí completamente la pregunta. Ya realizó la conversación .

Solo si ya tenía activado el registro binario y tiene una copia de seguridad anterior, podría

  • restaurar / var / lib / mysql a otra ubicación, como / var / lib / mysql2
  • correr service mysql stop
  • correr service mysql start --datadir=/var/lib/mysql2
  • mysqldump la base de datos de esa copia de seguridad a /root/olddata.sql
  • ejecute mysqlbinlog contra todos los registros binarios en / var / lib / mysql (no / var / lib / mysql2) desde el punto en el tiempo desde la última copia de seguridad en /root/changes.sql
  • Cargue change.sql en mysql (ya que todavía apunta a / var / lib / mysql2)

Esto debería capturar todo lo que se grabó y la conversión debería iniciarse. Nuevamente, todo esto es continuo en que ya tenía activado el registro binario antes de la última copia de seguridad . De lo contrario, mis condolencias.

RolandoMySQLDBA
fuente