Toutes les versions de MySQL sont testées sur plusieurs plates-formes avant leur publication. Cela ne signifie pas qu'elles sont exemptées de bogues, cela signifie juste que si il y a des bogues, il y en a très peu et sont durs à trouver. Si vous avez un problème, cela nous aidera toujours si vous essayez de trouver d'où vient exactement le plantage système, et vous aurez plus de chances de le voir résolu rapidement.
D'abord, vous devez essayer de trouver si le problème vient du
démon mysqld
qui se termine, ou s'il est
lié à votre client. Vous pouvez savoir depuis combien de temps
le serveur mysqld
tourne en exécutant
mysqladmin version
. Si
mysqld
s'est terminé, vous trouverez
sûrement la raison dans le fichier de log d'erreurs. See
Section 5.9.1, « Le log d'erreurs ».
Sur certains systèmes, vous pouvez trouver dans ce fichier une
trace de la pile, au moment où mysqld
s'est
arrêté, que vous pouvez étudier avec
resolve_back_stack
. See
Section D.1.4, « Utilisation d'un tra¸age de pile mémoire ». Notez que les valeurs des
variables écrites dans .err
peuvent ne pas
être toujours correctes.
Plusieurs plantages de MySQL sont causés par des fichiers de
données ou d'index corrompus. MySQL écrira les données sur le
disque avec un appel système à write()
,
après chaque requête et avant d'en notifier le client. (Cela
n'est pas vrai si vous utilisez
delay_key_write
, auquel cas seul les données
sont écrites.) Cela signifie que les données sont intègres
même si mysqld
plante, puisque le système
d'exploitation s'assurera que les données non sorties du tampon
ne sont pas enregistrée sur le disque. Vous pouvez forcer MySQL
à se synchroniser avec le disque après chaque requête en
démarrant mysqld
avec
--flush
.
Ce qui précède signifie que normalement, vous ne devriez obtenir de tables corrompues que si :
Quelqu'un ou quelque chose a coupé
mysqld
ou la machine au milieu d'une mise
à jour.
Vous avez trouvé un bogue dans mysqld
qui le termine au milieu d'une mise à jour.
Quelqu'un manipule les fichiers de données ou d'index en
dehors de mysqld
sans verrouiller
proprement les tables.
Si vous faites tourner plusieurs serveurs
mysqld
avec les mêmes données sur un
système qui ne gère pas bien les verrous de fichiers
(normalement gérés par le démon lockd
)
ou que vous le faites avec
--skip-external-locking
Vous avez un fichier de données ou d'index corrompu qui
contient des données faussées ce qui amène
mysqld
à confusion.
Vous avez trouvé un bogue dans le système de stockage des
données. Cela parait impossible, mais sait-on jamais ?
Dans ce cas, essayez de changer le type de fichier pour
qu'il soit pris en charge par un autre gestionnaire de bases
de données en utilisant ALTER TABLE
sur
une copie réparée de la table !
Parce qu'il est très difficile de savoir pourquoi quelque chose plante, essayez d'abord de voir si les choses qui marchent pour les autres ne fonctionnent pas chez vous. Merci d'essayer les différentes choses suivantes :
Coupez le démon mysqld
avec
mysqladmin shutdown
, exécutez
myisamchk --silent --force */*.MYI
sur
toutes les tables, et redémarrez le démon
mysqld
. Cela vous assurera que vous partez
d'un bon point de départ. See
Chapitre 5, Administration du serveur.
Utilisez mysqld --log
et essayez de
déterminer à partir des informations du log si une
requête spécifique fait planter le serveur. Plus de 95% de
tous les bogues sont liés à une requête spécifique !
Normalement, c'est la dernière requête dans le fichier de
log avant que MySQL n'ait redémarré. See
Section 5.9.2, « Le log général de requêtes ». Si vous pouvez faire planter
MySQL à plusieurs reprise avec une requête, même après
avoir vérifié toutes les tables avant de l'exécuter,
alors vous avez trouvé le bogue et vous devez faire un
rapport de bogue pour nous en avertir ! See
Section 1.4.1.3, « Comment rapporter un bogue ou un problème ».
Essayer d'effectuer une batterie de tests que nous pourrons utiliser pour reproduire le problème. See Section D.1.6, « Faire une batterie de tests lorsque vous faites face à un problème de table corrompue ».
Essayez d'exécuter le test inclus du dossier
mysql-test
et les benchmarks MySQL. See
Section 27.1.2, « Suite de test de MySQL ». Ils devraient tester
plutôt bien MySQL. Vous pouvez aussi ajouter ce code au
benchmarks pour simuler votre application ! Les benchmarks
peuvent être trouvés dans le répertoire
sql-bench
dans la distribution des
sources ou, pour une distribution binaire, dans le
répertoire sql-bench
de votre dossier
d'installation MySQL.
Essayez fork_test.pl
. Il est situé dans
le dossier tests
de la distribution
source.
Si vous configurez MySQL pour le débogage, il sera plus
facile d'obtenir des informations à propos des erreurs
possibles si quelque chose se passe mal. Reconfigurez MySQL
avec l'option --with-debug
ou
--with-debug=full
de
configure
puis recompilez. See
Section D.1, « Déboguer un serveur MySQL ».
Configurer MySQL pour le débogage inclus un outil d'allocation de mémoire qui peut trouver quelques erreurs. Il fournit aussi beaucoup d'informations sur ce qui se passe.
Avez-vous appliqué les derniers patches de votre système d'exploitation ?
Utilisez l'option --skip-external-locking
de mysqld
. Sur quelques systèmes, le
gestionnaire des verrous lockd
ne
fonctionne pas convenablement; l'option
--skip-external-locking
dit à
mysqld
de ne pas utiliser de pas utiliser
de verrous externes. (Cela signifie que vous ne pouvez pas
faire tourner deux serveurs mysqld
sur
les mêmes données et que vous devez faire attention si
vous utilisez myisamchk
, mais il peut
être instructif d'essayer cette option comme test.)
Avez-vous essayé mysqladmin -u root
processlist
lorsque mysqld
semble fonctionner mais ne répond plus ? Quelquefois,
mysqld
n'est pas comateux, même si vous
le croyez. Le problème peut-être que toutes les connexions
sont utilisées, ou qu'il y a quelques problèmes avec les
verrous internes. mysqladmin processlist
devra normalement être en mesure d'effectuer une connexion
même dans ce cas, et peut fournir des informations utiles
à propos du nombre de connexions courantes et de leur
statut.
Exécutez la commande mysqladmin -i 5
status
ou mysqladmin -i 5 -r
status
ou dans une fenêtre séparée pour
produire des statistiques pendant que vous exécutez vos
autres requêtes.
Essayez ce qui suit :
Démarrez mysqld
à partir de
gdb
(ou d'un autre débogueur). See
Section D.1.3, « Déboguer mysqld
sous gdb
».
Exécutez vos scripts de tests.
Affichez le tra¸age et les variables locales aux trois
niveaux les plus bas. Avec gdb vous pouvez le faire avec
les commandes suivantes lorsque
mysqld
s'est planté à l'intérieur
de gdb :
backtrace info local up info local up info local
Avec gdb vous pouvez aussi savoir quels threads existent
avec info threads
et en prendre un
avec thread #
, où
#
est l'identifiant du thread.
Essayez de simuler votre application avec un script Perl pour forcer MySQL à planter ou à avoir un comportement défectueux.
Envoyez un rapport de bogue normal. See Section 1.4.1.3, « Comment rapporter un bogue ou un problème ». Soyez le plus précis possible et donnez plus de détails que d'habitude. Puisque MySQL fonctionne pour beaucoup de personnes, il se peut que le plantage résulte de quelque chose de spécifique à votre système (par exemple, une erreur liée à la particularité de vos bibliothèques système).
Si vous avez des problèmes avec des tables à lignes de
longueurs dynamiques et que vous n'utilisez pas de colonnes
BLOB/TEXT
(mais seulement des colonnes
VARCHAR
), vous pouvez essayer de changer
tous les VARCHAR
en
CHAR
avec ALTER TABLE
.
Cela forcera MySQL à utiliser des lignes de tailles fixes.
Les lignes à tailles fixées prennent un peu plus d'espace,
mais sont plus tolérants aux corruptions !
Le code courant des lignes dynamiques est utilisé chez MySQL AB depuis au moins 3 ans sans aucun problème, mais par nature, les lignes à longueur dynamique sont plus exposées aux erreurs, il est donc bon d'essayer ce qui précède pour voir si cela vous aide !
This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.