web-dev-qa-db-fra.com

Suppression de données d'une grande table avec réplication

J'ai besoin de supprimer tous les rangées d'une table donnée. La table contient des millions ou des enregistrements. La base de données principale est répliquée à plusieurs esclaves et je tiens à le faire sans créer de décalage de réplication ni avoir un impact sur la performance.

Après quelques recherches, j'ai essayé de laisser tomber la table. Cela a pris plusieurs longues secondes, au cours de laquelle ma DB Master a été verrouillée.

Je sais que je peux supprimer progressivement des lots plus petits, je me demandais simplement qu'il y a un moyen plus rapide.

Merci, z

6
zvikico

Au lieu de faire TRUNCATE TABLE (qui verrouille toutes les connexions accédant à la table), essayez de faire une copie vide de la table, en l'échangeant et laissez tomber l'ancienne table.

EXEMPLE

Supposons que la table soit appelée mydb.mytable. Fais-le comme ça

USE mydb
CREATE TABLE mytable_new LIKE mytable;
ALTER TABLE mytable RENAME mytable_old;
ALTER TABLE mytable_new RENAME mytable;
DROP TABLE mytable_old;

Ce faisant de cette façon, MyTable devient vide immédiatement et ne se verrouille pas pendant la suppression des données. Maintenant, cela devrait aller rapide sur le maître et devrait reproduire. La dernière ligne DROP TABLE mytable_old; Peut prendre le plus longtemps. Si cela vous concerne, alors exécutez ceci sur le maître et l'esclave (basé sur la Réponse de Jynus )

SET sql_log_bin = 0;
USE mydb
CREATE TABLE mytable_new LIKE mytable;
ALTER TABLE mytable RENAME mytable_old;
ALTER TABLE mytable_new RENAME mytable;
DROP TABLE mytable_old;
SET sql_log_bin = 1;

ESSAIE !!!

Réserve

En ce qui concerne la suppression de données en petits morceaux, ce ne serait pas une bonne idée si vous devez table immédiatement disponible après que les données de la table soient supprimées. Pourquoi ?

  • En faisant DELETE FROM mytable.mytable; est une transaction unique. Toutes les lignes seraient préparées pour la restauration dans l'architecture InnoDB. Une fois la suppression terminée, toutes les informations MVCC doivent être rejetées. Cela explique pourquoi il faut si longtemps.
  • La suppression en petits morceaux créerait plus de transactions et de rentabilisations plus petites. Néanmoins, cela crée toujours la même quantité d'informations de restauration et de travail. Il peut vous permettre de surveiller la quantité de données à supprimer.
  • S'il vous plaît ne courez pas DELETE FROM mydb.mytable LIMIT 1000;. Utilisation LIMIT sur un DELETE sans une clause WHERE n'est pas une réplication en toute sécurité.
7
RolandoMySQLDBA

Bien que TRUNCATE TABLE est définitivement plus rapide que DELETE FROM Je sert à supprimer les enregistrements en petits morceaux. Le TRUNCATE TABLE Parfois, peut être encore lent car beaucoup de choses se passent derrière des scènes: il doit saisir une serrure exclusive sur le dictionnaire, il doit toujours supprimer le fichier IBD et re-créer un, il doit expulser des pages de la piscine tampon. . Avec PT-Archiver C'est super facile. Il ne laissera pas les esclaves à la traîne, il n'y aura pas de pointes de rinçage soudaines, etc., aucun segment d'annulation gonflable.

5
akuzminsky

Utilisation TRUNCATE TABLE (cela videra la table de la manière la plus rapide possible, en le laissant tomber et de le recréer de manière non roulée.

Si cela prend trop de temps pour vous (peut se produire dans les anciennes versions de MySQL en utilisant innodb_file_per_table), vous pouvez l'exécuter de manière indépendante sur le maître et chaque esclave avec

SET sql_log_bin = 0;

Le bogue sous-jacent est probablement celui-ci: http://www.percona.com/blog/2011/04/20/drop-table-performance/ .

4
jynus