Eliminación masiva para tabla grande en MySQL


9

Tengo una tabla de notificaciones que contiene alrededor de 100 millones de filas de host en Amazon RDS con 1000 IOPS, y quiero eliminar esas filas de más de un mes.

Si lo hago DELETE FROM NOTIFICATION WHERE CreatedAt < DATE_SUB(CURDATE(), INTERVAL 30 day);, se tomarán todos los IOPS, el proceso tomará horas y no se pueden insertar muchas entradas nuevas debido a que "Se excedió el tiempo de espera de bloqueo; intente reiniciar la transacción".

Estaba tratando de hacer la forma descrita aquí: http://mysql.rjweb.org/doc.php/deletebig Sin embargo, estoy usando UUID en lugar de ID de incremento.

¿Cuál es la forma correcta y eficiente de eliminar esas filas sin afectar la inserción / actualización de nuevos datos?


Eres correcto ypercubo, lo he rectificado. Gracias por señalar!
Tianyi Cong

Eliminar registros en fragmentos más pequeños, no afecta la operación de inserción, lo intenté con el bucle y termina de eliminar 70 millones de registros en menos de una hora rathishkumar.in/2017/12/…
Rathish

Respuestas:


11

Haga una tabla temporal, enciéndala y extráigala, y copie los datos de los últimos 30 días.

#
# Make empty temp table
#
CREATE TABLE NOTIFICATION_NEW LIKE NOTIFICATION;
#
# Switch in new empty temp table
#
RENAME TABLE NOTIFICATION TO NOTIFICATION_OLD,NOTIFICATION_NEW TO NOTIFICATION;
#
# Retrieve last 30 days data 
#
INSERT INTO NOTIFICATION SELECT * FROM NOTIFICATION_OLD
WHERE CreatedAt >= DATE_SUB(CURDATE(), INTERVAL 30 DAY);

En tus horas libres, deja caer la vieja mesa

DROP TABLE NOTIFICATION_OLD;

Aquí están las ventajas de hacer DELETEs como este

  1. NOTIFICATION se vacía rápidamente mediante el cambio en una tabla vacía.
  2. NOTIFICATION está disponible de inmediato para nuevos INSERT
  3. Los 30 días restantes se vuelven a agregar NOTIFICATIONmientras se pueden realizar nuevos INSERT.
  4. Descartar la versión anterior de NOTIFICATIONno interfiere con los nuevos INSERT
  5. NOTA: He recomendado hacer cebo y cambiar para la tabla DELETEs antes: (Ver mi publicación del 19 de julio de 2012: Optimización de la consulta ELIMINAR en la tabla de MEMORIA MySQL )

Darle una oportunidad !!!


Gracias la respuesta Rolando! ¿Cómo maneja MySql internamente la tabla desplegable? Primero elimine todas las columnas y luego elimine la tabla o algo más. ¿Tomará mucho menos tiempo que eliminar esas nubes?
Tianyi Cong

Estoy aplicando esta estrategia en la preparación, ¿el comando de cambio de nombre debe comenzar con "RENAME TABLE"?
Tianyi Cong

¿Habría alguna diferencia si lo uso dentro de un bloque de transacciones, teniendo en cuenta el tiempo de espera de bloqueo? También tendría algún inconveniente si mi tabla real es realmente enorme, que ahora cambia de nombre y tiene que descartarse
Muhammad Omer Aslam

1
@MuhammadOmerAslam en ese caso, el archivo ibdata1 (espacio de tabla del sistema) simplemente crecería en los registros de deshacer. Este es especialmente el caso cuando ibdata1 comenzaría a crecer en tamaño de archivo (vea mi publicación anterior dba.stackexchange.com/questions/40730/… ). Debe tener más cuidado al usar pt-archiver como se menciona en la respuesta de akuzminsky. Podría limitarse para eliminar filas en fragmentos y luego usar pt-online-schema-change para ejecutar ALTER TABLE ENGINE=InnoDB y reducir la tabla.
RolandoMySQLDBA

1
@MuhammadOmerAslam El enfoque anterior sería perfecto cuando haya programado un tiempo de inactividad. Siguiendo el enlace en la respuesta de akuzminsky ( percona.com/doc/percona-toolkit/LATEST/pt-archiver.html ). Puede usar pt-archiver para archivar datos o simplemente eliminar datos sin archivar.
RolandoMySQLDBA

3

Mi favorito es pt-archiver de Percona Toolkit. Se encarga de la carga de MySQL, el retraso de replicación.


Gracias la respuesta akuzminsky! Lo investigaré. Solía ​​probar Percona cuando quería alterar esta tabla de notificación con pt-online-schema-change. Sin embargo, se requería el privilegio SUPER para realizar el cambio, que RDS no proporciona. Por cierto, ¿conoces alguna buena manera de alterar la gran mesa?
Tianyi Cong

@TianyiCong tiene una nueva pregunta: por favor hágalo como una nueva pregunta y tal vez comente aquí con un enlace, no lo pregunte en los comentarios que no es así como funciona este sitio.
Jack dice que intente topanswers.xyz

-2

cree la tabla notificación_temp como select * desde la notificación donde CreatedAt <DATE_SUB (CURDATE (), INTERVAL 30 day);

notificación de caída de tabla;

NOMBRAR notificación_temp A NOTIFICACIÓN;


¿Y esto no afectará la inserción / actualización de nuevos datos? No lo creo.
Colin 't Hart

Este método tiene 2 problemas 1) hace que la NOTIFICACIÓN no esté disponible mientras dure la TABLA DE GOTAS. 2) INSERTOS que ocurren durante el CREATE TABLEse pierden.
RolandoMySQLDBA

Otro problema: debería decirRENAME TABLE notification_temp ...
RolandoMySQLDBA el
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.