Suppression d'une table MySQL avec des transactions en attente


10

Existe-t-il un moyen de supprimer une table ou une base de données InnoDB avec des transactions en attente dans MySQL (de préférence au niveau du système de fichiers)?

Qu'est-il arrivé:

J'utilise MySQL 5.5.28 et j'ai couru LOAD DATA INFILE…pour importer un énorme ensemble de données (300 millions de lignes) dans une table InnoDB. Je n'en utilisais pas set autocommit = 0;avant. Malheureusement, a mysqldété arrêté en plein milieu de l'importation.

Lorsque je redémarre mysql, il essaie de restaurer la transaction en remplissant le journal système avec des messages comme celui-ci:

mysqld_safe [4433]: 121212 16:58:52 InnoDB: Attendre la fin de 1 transactions actives

Le problème est que la restauration est en cours d'exécution depuis plus de 25 heures maintenant, ce qui mysqldn'accepte aucune connexion de socket.

Je ne peux pas simplement supprimer /var/lib/mysql/*et recommencer à zéro car il existe également d'autres bases de données / tables InnoDB sur cette machine. Cependant, la table problématique est la seule table dans une base de données distincte. La suppression de la table entière ou de la base de données entière n'est pas un problème car je peux réimporter toutes les données par la suite.

Réponses:


8

Il n'y a rien que vous puissiez vraiment faire car une restauration est en cours via l'espace de table UNDO à l'intérieur d'ibdata1 , qui aurait dû se développer considérablement.

Si vous tuez le processus mysqld et redémarrez mysql, il reprendra simplement là où il s'était arrêté dans le cadre du cycle de récupération après incident.

AVERTISSEMENT: pas responsable de la perte de données

Ce que vous pourriez faire peut entraîner une perte de données pour d'autres tables, mais vous pouvez faire quelque chose pour contourner le cycle normal de récupération après incident d'InnoDB.

Il existe une option de démarrage appelée innodb_force_recovery , qui vous permet de contourner les différentes étapes de la récupération après incident d'InnoDB.

Selon la documentation MySQL sur Forcing InnoDB Recovery , voici les paramètres et leurs effets:

1 (SRV_FORCE_IGNORE_CORRUPT)

Laissez le serveur s'exécuter même s'il détecte une page corrompue. Essayez de faire SELECT * FROM tbl_name sauter par-dessus les enregistrements et les pages d'index corrompus, ce qui aide à vider les tables.

2 (SRV_FORCE_NO_BACKGROUND)

Empêchez l'exécution du thread principal. Si un plantage se produisait pendant l'opération de purge, cette valeur de récupération l'empêche.

3 (SRV_FORCE_NO_TRX_UNDO)

N'exécutez pas de restauration de transactions après une récupération après incident.

4 (SRV_FORCE_NO_IBUF_MERGE)

Empêcher les opérations de fusion de tampon d'insertion. S'ils provoquaient un crash, ne les faites pas. Ne calculez pas les statistiques de table.

5 (SRV_FORCE_NO_UNDO_LOG_SCAN)

Ne regardez pas les journaux d'annulation lors du démarrage de la base de données: InnoDB traite même les transactions incomplètes comme validées.

6 (SRV_FORCE_NO_LOG_REDO)

N'effectuez pas la restauration du journal de reprise dans le cadre de la récupération.

Avec les modifications transactionnelles enfouies dans les journaux UNDO et REDO, vous courez le risque de

  • perte de données destinées à être écrites
  • conserver les données destinées à être supprimées

Dans le cas où vous vous attendez à de mauvais effets secondaires, sauvegardez l'intégralité de / var / lib / mysql et placez-le quelque part au cas où vous voudriez copier ibdata1, ib_logfile0 et ib_logfile1 et réessayer la récupération normale.

Si mysql est complètement opérationnel dans l'un des modes

  • mysqldump toutes les données sauf la table incriminée
  • arrêter mysql
  • supprimer tout dans / var / lib / mysql sauf / var / lib / mysql / mysql
  • démarrer mysql
  • recharger le mysqldump

CAVEAT: Assurez-vous de tout sauvegarder !!!

J'espère que ça aide !!!


1

J'ai eu une situation similaire cette semaine.

Et après quatre itérations de restauration d'une sauvegarde complète sur un serveur de test et de tentative de suppression, de suppression ou de suppression des tables avec les transactions géantes en attente, nous sommes finalement arrivés au vendredi après-midi et avons décidé de simplement le laisser s'exécuter. Pendant trois jours, la transaction s'est terminée avec une charge de serveur négligeable et la base de données était correcte. Ce qui était bien mieux que toutes les opérations manuelles sur les fichiers .frm et les tables mysql qui avaient échoué.

Ma solution: ne le supprimez pas . Laissez les transactions en attente se terminer, même si vous devez interrompre d'autres opérations pendant quelques jours, ou trouver de l'espace disque quelque part, ou laisser votre serveur esclave prendre la charge.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.