Acelerar la conversión de MyISAM a InnoDB


15

Tengo un servidor mysql 5.1 con una base de datos de aproximadamente 450 tablas, ocupando 4GB. La gran mayoría de estas tablas (todas menos 2) son MyIsam. Esto ha estado bien en su mayor parte (no necesita transacciones), pero la aplicación ha estado ganando tráfico y ciertas tablas se han visto afectadas debido al bloqueo de la tabla en las actualizaciones. Esa es la razón por la que 2 de las tablas son InnoDB ahora.

La conversión en las tablas más pequeñas (100k filas) no toma mucho tiempo, causando un tiempo de inactividad mínimo. Sin embargo, algunas de mis tablas de seguimiento se están acercando a 50 millones de filas. ¿Hay alguna forma de acelerar una ALTER TABLE...ENGINE InnoDBmesa grande? Y si no, ¿hay otros métodos para convertir, minimizando el tiempo de inactividad en estas tablas de escritura pesada?


1
Algo a tener en cuenta: múltiples preguntas en una sola publicación tienden a desalentar a las personas que pueden responder una de las preguntas de publicar una respuesta.
BenV

I VtC ya que esto es bastante complicado de responder. Debe abrir como varias preguntas individualmente.
jcolebrand

con mucho gusto tomaré el consejo para convertirlo en una sola pregunta, pero ¿se recomienda eliminar esta pregunta y simplemente abrir una nueva? la reescritura en su mayoría eliminaría las 2 segundas viñetas y alteraría la primera (también actualicé el título para reflejar qué motores de almacenamiento)
Derek Downey,

Cualquiera de los dos estaría bien. Por lo general, es más fácil escribir otras dos preguntas y eliminar una. Sin embargo, podría dejarlo fácilmente como "referencia" y hacer que los otros dos lo consulten nuevamente, como una pregunta de "este es mi objetivo general".
jcolebrand

edite este en una viñeta, luego publique las preguntas de seguimiento.
Brian Ballsun-Stanton

Respuestas:


10

Permítanme comenzar diciendo: Odio ALTER. Es malvado, en mi humilde opinión.

Digamos, este es tu esquema de tabla actual:

CREATE TABLE my_table_of_love (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
my_value VARCHAR(40),
date_created DATE,
PRIMARY KEY(id)
) ENGINE=MyISAM CHARSET=utf8;

Aquí está el camino que recomiendo:

Cree un nuevo objeto de tabla que reemplazará al anterior:

CREATE TABLE my_table_of_love_NEW (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
my_value VARCHAR(40),
date_created DATE,
PRIMARY KEY(id)
) ENGINE=InnoDB CHARSET=utf8

Inserte todas las filas de la tabla anterior por nombre en la tabla nueva:

INSERT INTO my_table_of_love_NEW (id,my_value,date_created)
SELECT id,my_value,date_created FROM my_table_of_love;

Prueba de humo tu migración:

SELECT COUNT(*) FROM my_table_of_love_NEW;
SELECT COUNT(*) FROM my_table_of_love;
SELECT a.id,a.my_value,a.date_created FROM my_table_of_love_NEW a
LEFT JOIN my_table_of_love b ON (b.id = a.id)
WHERE a.my_value != b.my_value;

Cambie los nombres de las tablas para que pueda mantener una copia de seguridad en caso de que necesite deshacer.

RENAME TABLE my_table_of_love TO my_table_of_love_OLD;
RENAME TABLE my_table_of_love_NEW TO my_table_of_love;

Proceda a la prueba de regresión.

Este enfoque se vuelve cada vez más preferible con tablas con múltiples índices y millones de filas.

Pensamientos?


1
De acuerdo ... aunque si es muy transaccional, es posible que deba eliminar la base de datos mientras lo hace. (pero una tabla alternativa le dará un período de inactividad más largo, lo más probable)
Joe

Sí, pensé que requeriría tiempo de inactividad para las tablas más activas. Voy a tener que ejecutar algunas pruebas, pero ¿por qué ALTER TABLEtomaría más tiempo que INSERT INTO...SELECTen 50 millones de filas?
Derek Downey el

No lo hará. Básicamente, MySQL hace internamente exactamente como lo sugiere este póster. Crea una copia de la definición y cargas de goteo en la copia.
Morgan Tocker

Me gusta este método porque omite la parte de "copiar a tmp", que puede tomar algún tiempo para tablas grandes.
Haluk

Permítanme agregar ahora, que en MySQL 5.7, ALTER es mucho más rápido y más fácil de manejar.
randomx

7

1) La protección contra pérdidas es una función de la paranoia. Siempre haz una copia de seguridad. Si eres realmente paranoico, haz una copia de seguridad y luego restaura desde la copia de seguridad.

2) Esta página del manual de MySQL tiene instrucciones para convertir tipos de tablas.

La forma más rápida de alterar una tabla a InnoDB es hacer las inserciones directamente en una tabla InnoDB. Es decir, use ALTER TABLE ... ENGINE = INNODB, o cree una tabla InnoDB vacía con definiciones idénticas e inserte las filas con INSERT INTO ... SELECT * FROM ....

3) PostgreSQL realiza búsquedas de texto completo , The Sphinx Engine parece hacerlo para MySQL


Definitivamente voy a investigar la esfinge, ya que solo recientemente he oído hablar de ella.
Derek Downey el

3

Es X veces más fácil optimizar todo el servidor (configuración de memoria, cachés, índices) cuando solo se utiliza un motor. Mezclar myisam con innodb en bases de datos grandes siempre se atascará en algún momento forzado por algún comprosise para que ambos motores funcionen bien (pero no excelente :)

Le recomiendo que se interese en algunos motores de búsqueda de texto completo dedicados como sphinx , lucene ( solr ) y lo elimine de la capa de base de datos.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.