Tengo una tabla InnoDB de 700 GB en la que no escribo más datos (solo lectura). Me gustaría eliminar los datos más antiguos que contiene y recuperar ese espacio en disco (ya que me estoy quedando sin él). La parte de eliminar es bastante fácil, porque tengo un índice primario autoincluido, así que solo puedo iterar en trozos usándolo y eliminar las filas, pero eso no me devolverá el espacio. Supongo que lo OPTIMIZE TABLEhará, pero eso podría llevar una eternidad en una mesa de 700GB, entonces, ¿hay otra opción que estoy pasando por alto?
Editar por RolandoMySQLDBA
Suponiendo que su tabla es mydb.mytable, ejecute la siguiente consulta y publíquela aquí para que pueda determinar el espacio en disco necesario para la reducción de la tabla:
SELECT
FORMAT(dat/POWER(1024,3),2) datsize,
FORMAT(ndx/POWER(1024,3),2) ndxsize,
FORMAT((dat+ndx)/POWER(1024,3),2) tblsize
FROM (SELECT data_length dat,index_length ndx
FROM information_schema.tables WHERE
table_schema='mydb' AND table_name='mytable') A;
También debemos ver la estructura de la tabla, si está permitido.
Editar por Noam
Este es el resultado de la consulta:
datsize ndxsize tblsize
682.51 47.57 730.08
Esta es la estructura de la tabla ( SHOW CREATE TABLE)
`CREATE TABLE `mybigtable` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`uid` int(11) NOT NULL,
`created_at` datetime NOT NULL,
`tid` bigint(20) NOT NULL,
`text` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`ft` tinyint(1) NOT NULL,
`irtsd` bigint(20) NOT NULL,
`irtuid` int(11) NOT NULL,
`rc` int(11) NOT NULL,
`r` tinyint(1) NOT NULL,
`e` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, `timezone` varchar(5) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uid_tid` (`uid`,`tid`)) ENGINE=InnoDB AUTO_INCREMENT=2006963844 DEFAULT CHARSET=utf8`

ALTER TABLE ... ENGINE=InnoDB;(si tiene espacio para hacerlo). La mayoría está satisfecha con sus SSD muy rápidos y ya no se preocuparía.Respuestas:
Esta es una buena pregunta. Tienes varias soluciones, pero tu mesa es bastante grande, así que ninguna será sin dolor :)
Tiene tres soluciones para "reducir" las tablas de InnoDB:
1. OPTIMIZAR LA TABLA
Puede usarlo
OPTIMIZE TABLEcomo lo mencionó, pero debe preocuparse por lainnodb_file_per_tablevariable:Dejame explicar:
Con las
OPTIMIZE TABLEtablas InnoDB, bloquea la tabla, copia los datos en una nueva tabla limpia (por eso se reduce el resultado), suelta la tabla original y cambia el nombre de la nueva tabla con el nombre original. Es por eso que debería preocuparse por tener el doble de la volumetría de su tabla disponible en su disco (durante la operación necesitará 2x700GB).Cuando estás en innodb_file_per_table = ON. Todas las tablas tienen el archivo de datos adecuado. Por lo tanto, la
OPTIMIZEdeclaración creará un nuevo archivo de datos (~ 700 GB) cuando finalice la operación, MySQL eliminará el original y cambiará el nombre del nuevo (por lo que al final los 700 GB, probablemente menos porque se reducirán) de datos generado durante la operación será lanzado)Cuando estás en innodb_file_per_table = OFF. Todos los datos van a un archivo de datos: ibdata . Este archivo tiene una triste particularidad, no se puede reducir. Por lo tanto, durante el
OPTIMIZEproceso, se creará su nueva tabla (cerca de 700 GB), pero incluso después de la operación de caída y cambio de nombre (y al final de laOPTIMIZEfase) su ibdata no liberará ~ 700 GB, por lo que quería liberar algunos datos pero tiene 700 GB más, genial ¿no?2. CAMBIAR TABLA
También puede usar una
ALTER TABLEdeclaración, laALTER TABLEfuncionará de la misma manera queOPTIMIZE TABLE. Solo puedes usar:3. ALTERAR TABLA (EN LÍNEA)
El problema de
OPTIMIZEyALTER TABLEque bloquea la mesa durante la operación. Puede usar la herramienta Percona: pt-online-schema-change (desde Percona Toolkit: enlace ). pt-online-schema ... construirá un mecanismo con disparadores y una tabla temporal en la que permite que la tabla original esté disponible para leer y escribir durante la operación. Utilizo esta herramienta en producción porqueALTERes genial.Tenga en cuenta que debería haber hecho
FOREIGN KEYreferencia a su tabla, FK y desencadena el riesgo de producir un desastre. Para verificar estos requisitos previos, consulte:Así es como uso pt-online-schema-change:
Tenga en cuenta que mi nota sobre innodb_file_per_table también es cierta para esta solución.
4. mysqldump
La última solución es recrear todas las bases de datos de un volcado. Terriblemente largo, pero terriblemente eficiente. Tenga en cuenta que es la única solución para "reducir" el archivo ibdata.
Max.
fuente
Si tiene poco tamaño de disco, le sugiero que haga lo mismo que Max sugirió con pt-online-schema-change (ONLINE). He estado en la misma situación con una mesa mucho más pequeña (200 GB) y elegí hacer algo de compresión al mismo tiempo. Algo en este sentido debería funcionar:
Esto solo funcionará si está en formato de barracuda y en formato COMPACTO de la tabla. También debe tener innodb_file_per_table habilitado. Esto puede hacer maravillas en el tamaño de su tabla, especialmente si hay mucho texto y si usa KEY_BLOCK_SIZE más pequeño, como 8K o incluso 4K (el valor predeterminado es 16K). También puede ver cuánto espacio puede ganar de múltiples puntos de referencia con respecto a este problema en otros blogs, pero la documentación de MySQL anuncia entre un 25% y un 50% (para mí era casi el 90%).
Tenga en cuenta que esto también puede afectar el rendimiento al hacer SELECT (de la documentación de MySQL):
MySQL también tiene que descomprimir los datos cuando no está en el grupo de búferes. Así que ten cuidado.
Esto realmente ha funcionado bien en mi caso. Tenía un mensaje largo. 200 GB se convirtieron en 26 GB. Las actuaciones no fueron alteradas.
Para obtener información más detallada, consulte estos enlaces:
https://dev.mysql.com/doc/refman/5.5/en/innodb-compression-usage.html
https://dev.mysql.com/doc/refman/5.5/en/innodb-compression-internals.html
fuente