L'histoire de la suppression physique de 300 millions d'enregistrements dans MySQL

introduction



Hey. Je suis ningenMe, un développeur Web.



Comme le titre l'indique, mon histoire concerne la suppression physique de 300 millions d'enregistrements dans MySQL.



Je me suis intéressé à cela, alors j'ai décidé de faire un mémo (instruction).



DĂ©marrer - Alerte



Le serveur de traitement par lots que j'utilise et gère a un processus régulier qui collecte les données du mois dernier à partir de MySQL une fois par jour.



Habituellement, ce processus se termine en environ 1 heure, mais cette fois, il ne s'est pas terminé pendant 7 ou 8 heures, et l'alerte n'a jamais cessé de sortir ...



Recherche d'une raison



J'ai essayé de redémarrer le processus, de regarder les journaux, mais je n'ai rien vu de terrible.

La demande a été correctement indexée. Mais quand je me suis demandé ce qui n'allait pas, j'ai réalisé que la taille de la base de données est assez grande.



hoge_table | 350'000'000 |


350 millions d'enregistrements. L'indexation semblait fonctionner correctement, juste très lente.



La collecte de données requise par mois était d'environ 12 000 000 d'enregistrements. Il semble que la commande select ait pris beaucoup de temps et que la transaction n'ait pas été exécutée pendant longtemps.



DB



En gros, c'est une table qui augmente d'environ 400 000 enregistrements chaque jour. La base de données était censée collecter des données uniquement pour le mois dernier, par conséquent, le calcul était basé sur le fait qu'elle résisterait exactement à cette quantité de données, mais, malheureusement, l'opération de rotation n'a pas été incluse.



Cette base de données n'a pas été développée par moi. Je l'ai repris d'un autre développeur, donc c'était comme si c'était une dette technique.



Le moment est venu où la quantité de données insérées quotidiennement est devenue importante et a finalement atteint sa limite. On suppose qu'en travaillant avec une si grande quantité de données, il serait nécessaire de les séparer, mais cela n'a malheureusement pas été fait.



Et puis je suis intervenu.



Correction



Il était plus rationnel de réduire la base de données elle-même et de réduire le temps de son traitement que de changer la logique elle-même.



La situation devrait changer considérablement si 300 millions d'enregistrements étaient effacés, alors j'ai décidé de le faire ... Eh, je pensais que ça marcherait définitivement.



Étape 1



Après avoir préparé une sauvegarde fiable, j'ai finalement commencé à soumettre des demandes.



「Soumettre une demande」



DELETE FROM hoge_table WHERE create_time <= 'YYYY-MM-DD HH:MM:SS';


「...」



「...」



«Hmm… Pas de réponse. Peut-être que le processus prend beaucoup de temps? " - J'ai pensé, mais juste au cas où je regardais dans grafana et voyais que la charge du disque augmentait très rapidement.

"Dangereux" - J'ai pensé à nouveau et j'ai immédiatement arrêté la demande.



Étape 2



Après avoir tout analysé, j'ai réalisé que la quantité de données était trop importante pour tout supprimer en une seule fois.



J'ai décidé d'écrire un script qui pourrait supprimer environ 1 000 000 d'enregistrements et de l'exécuter.



「J'implémente le script」



"Maintenant, cela fonctionnera certainement," pensai-je



Étape 3



La deuxième méthode a fonctionné, mais s'est avérée très longue.

Pour tout faire proprement, sans nerfs supplémentaires, cela prendrait environ deux semaines. Mais encore, ce scénario ne répondait pas aux exigences du service, j'ai donc dû m'en éloigner.



Par conséquent, voici ce que j'ai décidé de faire:



Copiez le tableau et renommez-le



À partir de l'étape précédente, j'ai réalisé que la suppression d'une si grande quantité de données crée une charge tout aussi importante. Par conséquent, j'ai décidé de créer une nouvelle table à partir de zéro en utilisant insérer et de déplacer les données que j'allais supprimer.



| hoge_table     | 350'000'000|
| tmp_hoge_table |  50'000'000|


Si vous donnez Ă  la nouvelle table la mĂŞme taille que ci-dessus, la vitesse de traitement devrait Ă©galement devenir 1/7 plus rapide.



Après avoir créé la table et l'avoir renommée, j'ai commencé à l'utiliser comme table principale. Maintenant, si je laisse tomber une table avec 300 millions d'enregistrements, tout devrait bien se passer.

J'ai découvert que la troncature ou la suppression était moins lourde que la suppression et j'ai décidé d'utiliser cette méthode.



Performance



「Soumettre une demande」



INSERT INTO tmp_hoge_table SELECT FROM hoge_table create_time > 'YYYY-MM-DD HH:MM:SS';


「...」

「...」

「euh ...?」



Étape 4



Je pensais que l'idée précédente fonctionnerait, mais après avoir soumis la demande d'insertion, plusieurs erreurs sont apparues. MySQL n'épargne pas.



J'étais déjà tellement fatiguée que j'ai commencé à penser que je ne voulais plus faire ça.



Je me suis assis et j'ai pensé et j'ai réalisé qu'il y avait peut-être trop de demandes d'insertion pour une seule fois ...

J'ai essayé d'envoyer une demande d'insertion pour la quantité de données que la base de données devrait traiter en 1 jour. Arrivé!



Eh bien, après cela, nous continuons à envoyer des demandes pour la même quantité de données. Comme nous devons supprimer la quantité mensuelle de données, nous répétons cette opération environ 35 fois.



Renommer une table



Ici, la chance était de mon côté: tout s'est bien passé.



Alerte partie



La vitesse de traitement par lots a augmenté.



Auparavant, ce processus prenait environ une heure, maintenant il prend environ 2 minutes.



Après avoir été convaincu que tous les problèmes étaient résolus, j'ai laissé tomber 300 millions de disques. J'ai supprimé la table et je me suis sentie renaître.



RĂ©sumer



J'ai réalisé que le traitement par rotation était négligé dans le traitement par lots et que c'était le principal problème. Une telle erreur d'architecture est une perte de temps.



Pensez-vous à la charge de réplication des données en supprimant des enregistrements de la base de données? Ne surchargons pas MySQL.



Ceux qui connaissent bien les bases de données ne seront certainement pas confrontés à un tel problème. Pour le reste, j'espère que cet article vous a été utile.



Merci d'avoir lu!



Nous serons très heureux si vous nous dites si vous avez aimé cet article, la traduction était-elle claire, vous a-t-elle été utile?



All Articles