| 1.8.7 Erreurs connues, et limitations de MySQL
 1.8 Quels standards respecte MySQL?
 1 Informations générales
 Manuel de Référence MySQL 4.1 : Version Française
 
 . Erreurs connues en 3.23 et corrigées ultérieurement
 . Erreurs de la version 4.0, corrigées plus tard
 ->Bugs connus / limitations de MySQL
 
 
 | 
  1.8.7.3 Bugs connus / limitations de MySQL Les problèmes suivants sont connus, et sont en tête de liste pour
être corrigés :  
 
Il n'est pas possible de mélanger  
UNION ALL
  et  
UNION DISTINCT
  
dans la même requête. Si vous utilisez  
ALL
  pour  
UNION
  alors
il faut l'utiliser partout.
Si un utilisateur a une transaction longue, et qu'un autre utilisateur
efface une table qui est modifiée par la même transaction, il y a quelques
chances que le log binaire n'enregistre pas la commande  
DROP TABLE
  
avant que la table ne soit utilisée par la transaction elle-même. Nous 
envisageons de corriger cela en version 5.0, en forçant
 
DROP TABLE
  a attendre jusqu'à ce que la table ne soit plus
utilisée par la transaction.
Lors de l'insertion d'un grand entier (valeur entre 2^63 et 2^64-1) dans
une colonne de type décimal ou chaîne, il sera enregistré comme une valeur
négative, car le nombre est considéré comme un entier signé dans ce contexte.
Il est prévu de corriger cela en 4.1.
FLUSH TABLES WITH READ LOCK
  ne bloque pas  
CREATE TABLE
  ou
 
COMMIT
 , ce qui peut causer des problèmes avec la position du log lors
d'une sauvegarde complète des tables et du log binaire.
ANALYZE TABLE
  sur une table de type  
BDB
 , peut rendre la table inutilisable,
dans certains cas, jusqu'au prochain redémarrage de  
mysqld
 . Lorsque cela
survient, vous rencontrez les erreurs suivantes dans le fichier d'erreur
MySQL :  
| 
001207 22:07:56  bdb:  log_flush: LSN past current end-of-log
 | 
MySQL accepte les parenthèses dans la clause  
FROM
 , mais les
ignore silencieusement. La raison de l'absence d'erreur est que de nombreux
clients qui génèrent des requêtes, ajoutent les parenthèses dans la clause  
FROM
 
même si elles sont inutiles.
Concaténer plusieurs  
RIGHT JOINS
  ou combiner des jointures  
LEFT
  et
 
RIGHT
  dans la même requête ne donnera pas de résultat correct si MySQL
ne génère que des lignes  
NULL
  pour la table précédent le  
LEFT
  ou
avant la jointure  
RIGHT
 . Cela sera corrigé en 5.0, en même temps que le 
support des parenthèses pour la clause  
FROM
 .
N'exécutez pas de commande  
ALTER TABLE
  sur une table  
BDB
  sur laquelle
vous avez exécuté des transactions à plusieurs commandes, jusqu'à ce que ces
transactions soient achevées : la transaction sera probablement ignorée.
ANALYZE TABLE
 ,  
OPTIMIZE TABLE
  et  
REPAIR TABLE
  peuvent
causer des problèmes sur les tables avec lesquelles vous utilisez la 
commande  
INSERT DELAYED
 .
Faire un  
LOCK TABLE ...
  et  
FLUSH TABLES ...
  ne vous 
garantit pas qu'il n'y a pas une transaction en court sur 
la table.
Les tables  
BDB
  sont lentes à ouvrir. Si vous avez de nombreuses tables  
BDB
 
dans une base, cela prendra du temps au client  
mysql
  pour accéder
à la base si vous n'utilisez pas l'option  
-A
 , ou si vous utilisez
la commande  
rehash
 . C'est particulièrement vrai si vous n'avez
pas de cache de table important.
La réplication utilise un log de niveau requête : le maître écrit les requêtes
exécutées dans le log binaire. C'est une méthode de log rapide,
compacte et efficace, qui fonctionne à la perfection dans la plupart
des situations. Même si nous n'avons jamais vu d'occurrence de ce problème,
il est théoriquement possible pour les données du maître et de l'esclave
de différer si une requête non-déterministe est utilisée pour modifier les
données, c'est à dire si elle est laissé au bon vouloir de l'optimiseur,
ce qui n'est pas une bonne pratique même sans la réplication.
Par exemple :  
IF et seulement si ces requêtes n'ont pas de clause 
ORDER BY
,
qui garantisse un ordre déterministe
 .Effectivement, par exemple, pour les commandes  
INSERT ... SELECT
  sans
clause  
ORDER BY
 , le  
SELECT
  peut retourner les lignes dans 
un ordre différent, ce qui aura pour résultat de donner des rangs différents
et donnera des numéros d'identifiants différents aux colonnes  
auto_increment
 ),
en fonction des choix fait par les optimiseurs du maître et de l'esclave.
Une requête sera optimisée différemment sur l'esclave et sur le maître si :
Des commandes 
 
CREATE ... SELECT
  ou
 
INSERT ... SELECT
  qui insèrent zéro ou  
NULL
  valeurs
dans la colonne  
AUTO_INCREMENT
 .
DELETE
  si vous effacez des lignes dans une table qui a une
propriété  
ON DELETE CASCADE
 .
Les commandes 
 
REPLACE ... SELECT
 , 
 
INSERT IGNORE ... SELECT
 , si vous avez des clés en double,
dans les données insérées. 
Ce problème peut aussi affecter la restauration de base,
utilisant  
mysqlbinlog
  ou  
mysql
 .
Les fichiers utilisés par les deux requêtes ne sont pas exactement les
mêmes. Par exemple,  
OPTIMIZE TABLE
  a été exécuté sur le maître et pas sur
l'esclave (pour corriger cela, depuis MySQL 4.1.1,  
OPTIMIZE
 ,  
ANALYZE
 
et  
REPAIR
  sont aussi écrits dans le log binaire).
La table est stockées sur un moteur de stockage différent sur le maître et
sur l'esclave : c'est possible d'utiliser des moteurs de tables différents.
Par exemple, le maître utiliser  
InnoDB
  et l'esclave MyISAM, car l'esclave a 
moins d'espace disque.
Les tailles de buffer MySQL ( 
key_buffer_size
 , etc.) sont différentes
sur le maître et sur l'esclave.
Le maître et l'esclave utilisent des versions différentes de MySQL,
et le code de l'optimiseur est différent entre ces versions.
 
Le plus simple pour éviter ces problèmes dans tous les cas est d'ajouter
toujours une clause  
ORDER BY
  aux requêtes non-déterministe, pour
s'assure que les lignes sont traitées dans le même ordre. Dans le futur,
MySQL va ajouter automatiquement une clause  
ORDER BY
  si nécessaire.
 
Les problèmes suivants sont connus et seront corrigés en leur temps : 
 
mysqlbinlog
  n'efface pas les fichiers temporaires laissés après une
commande  
LOAD DATA INFILE
 .  L'utilitaire binaire 
mysqlbinlog
 .
Il n'est pas possible de renommer une table temporaire.
Lors de l'utilisation de la fonction  
RPAD
 , ou de toute autre 
fonction de chaîne qui peut ajouter des espaces à droite de la chaîne, dans une
requête qui utilise une table temporaire pour la résolution, alors toutes les
chaînes verront leurs espaces terminaux être supprimés. Voici un
exemple d'une telle requête :
 
SELECT    RPAD(t1.field1, 50, ' ') AS f2,    RPAD(t2.field2, 50, '
') AS f1  FROM    table1 as t1     LEFT JOIN table2 AS t2 ON
t1.record=t2.joinID ORDER BY t2.record;
Le résultat final de ceci est que vous ne pourrez pas obtenir les
espaces à gauche dans ces chaînes. 
Le comportement décrit ci-dessus existe dans toutes les versions de
MySQL.
La raison à cela est due au fait que les tables de type HEAP, qui sont
utilisées en premier comme table temporaires, ne sont pas capables
de gérer des colonnes de type VARCHAR. 
Ce comportement sera corrigé dans l'une des versions de la série des 4.1.
A cause de la méthode de stockage des tables de définitions de fichiers,
il n'est pas possible d'utiliser le caractère 255 ( 
CHAR(255)
 ) 
dans les noms des tables, colonnes ou énumérations. Il est prévu de corriger
de problème dans les versions version 5.1, lorsque nous aurons établi
un nouveau format de définition des fichiers.
Lorsque vous utilisez la commande  
SET CHARACTER SET
 , il n'est pas
possible d'utiliser les caractères traduits dans les noms de bases, 
de tables ou de colonnes.
Il n'est pas possible d'utiliser  
_
  ou  
%
  avec la commande
 
ESCAPE
  dans la clause  
LIKE... ESCAPE
 .
Si vous avez une colonne de type  
DECIMAL
  avec un nombre stocké dans un
autre format (+01.00, 1.00, 01.00),  
GROUP BY
  peut considérer ces
valeurs comme différentes.
Lorsque  
DELETE FROM merge_table
  est utilisé sans la clause  
WHERE
 ,
elle va simplement effacer le fichier de la table, et ne pas effacer les
tables associées.
Vous ne pouvez pas compiler le serveur dans un autre dossier lorsque vous
utilisez les  
MIT-pthreads
 . Comme cela requiert une modification des  
MIT-pthreads
 , 
nous ne corrigerons pas ce problème.  Remarques sur MIT-pthreads .
Les valeurs de type  
BLOB
  ne peuvent pas être utilisées ``correctement'' dans
les clauses  
GROUP BY
  ou  
ORDER BY
  ou  
DISTINCT
 . Seuls, les 
 
max_sort_length
  premiers octets (par défaut, 1024) seront utilisés
pour les comparaisons de  
BLOB
 . Ceci peut être modifié avec l'option
 
-O max_sort_length
  de  
mysqld
 . Un palliatif à ce problème est
d'utiliser une sous partie de chaîne : 
 
SELECT DISTINCT LEFT(blob,2048) FROM tbl_name
 .
Les calculs sont faits avec des  
BIGINT
  ou  
DOUBLE
  (les deux
sont normalement de 64 bits). La précision dépend alors de la fonction
utilisée. La règle générale est que les fonctions de bits utilisent la
précision des  
BIGINT
 ,  
IF
  et  
ELT()
  utilisent la 
précision des  
BIGINT
  ou  
DOUBLE
 , et les autres utilisent
la précision des  
DOUBLE
 . Il faut donc éviter d'utiliser les
entiers non signés de grande taille, surtout s'ils dépassent la
taille de 63 bits (9223372036854775807) pour toute autre fonction que les
champs de bits ! La version 4.0 gère bien mieux les  
BIGINT
  que la 3.23.
Toutes les colonnes de type chaînes, hormis les  
BLOB
  et  
TEXT
 , 
voient automatiquement leurs caractères blancs finaux supprimés. Pour le type
 
CHAR
  c'est correct, et c'est considéré comme une fonctionnalité par
la norme ANSI SQL92. Le hic est que pour le serveur MySQL les colonnes
 
VARCHAR
  sont traitées de la même façon.
Vous ne pouvez avoir que des colonnes de taille 255 pour les
 
ENUM
  et  
SET
 .
Avec les fonctions d'agrégation  
MIN()
 ,  
MAX()
  et compagnie,
MySQL compare actuellement les colonnes de type  
ENUM
  et  
SET
 
par leur valeur de chaîne, plutôt que par leur position relative dans l'ensemble.
safe_mysqld
  redirige tous les messages de  
mysqld
  vers le log
 
mysqld
 . Le problème est que si vous exécutez 
 
mysqladmin refresh
  pour fermer et ouvrir à nouveau l'historique,
 
stdout
  et  
stderr
  sont toujours redirigés vers l'ancien log.
Si vous utilisez  
--log
 , vous devriez éditer  
safe_mysqld
  
pour envoyer les messages vers  
'hostname'.err
  au lieu de  
'hostname'.log
 , de façon
à pouvoir facilement récupérer la place de l'ancien log, en effaçant les vieux,
et en exécutant  
mysqladmin refresh
 .
Dans la commande  
UPDATE
 , les colonnes sont modifiées de gauche à droite.
Si vous faite référence à une colonne modifiée, vous obtiendrez sa valeur modifiée,
plutôt que sa valeur originale. Par exemple :  
Cette commande va modifier la colonne  
KEY
  avec  
2
  au lieu de  
1
 .| 
mysql> UPDATE tbl_name SET KEY=KEY+1,KEY=KEY+1;
 | 
Vous ne pouvez pas utiliser les tables temporaires plus d'une fois dans 
la même requête. Par exemple, cette commande ne fonctionne pas :  
| 
mysql> SELECT * FROM temporary_table, temporary_table AS t2;
 | 
RENAME
  ne fonctionne pas avec les tables  
TEMPORARY
 , ou les tables
utilisées dans un rassemblement ( 
MERGE
 ).
L'optimiseur peut gérer la clause  
DISTINCT
  différemment si vous utilisez
des colonnes cachées dans une jointure. Dans une jointure, les colonnes
cachées sont comptées comme une partie du résultat (même si elles ne sont
pas montrées), tandis que dans les requêtes normales, les colonnes cachées
ne participent pas aux  
DISTINCT
 . Nous allons probablement modifier
ceci dans le futur, pour ne jamais exploiter les colonnes cachées avec
 
DISTINCT
 .
 
Voici un exemple : 
 et| 
SELECT DISTINCT mp3id FROM band_downloadsWHERE userid = 9 ORDER BY id DESC;
 | 
 Dans le second cas, MySQL 3.23.x pourrait vous donner deux lignes
identiques dans le résultat (car les lignes cachées  
id
  
diffèrent).Notez que cela n'arrive que pour les requêtes où vous n'avez pas
de colonnes de la clause ORDER BY dans le résultat, ce que vous ne
pourriez pas faire en ANSI SQL.| 
SELECT DISTINCT band_downloads.mp3idFROM band_downloads,band_mp3
 WHERE band_downloads.userid = 9
 AND band_mp3.id = band_downloads.mp3id
 ORDER BY band_downloads.id DESC;
 | 
Comme le serveur MySQL vous permet de travailler avec des tables qui
ne supportent pas les transactions, et donc, l'annulation  
rollback
 ,
certains comportements sont différents avec MySQL d'avec d'autres serveurs
SQL. C'est nécessaire pour s'assurer que MySQL n'a jamais besoin d'annuler
une commande SQL. Cela peut sembler un peu étrange au moment ou les colonnes
doivent être vérifiées par l'application, mais cela vous fournit une
accélération notable, à cause d'optimisations qui ne pourraient pas avoir
lieu ailleurs.Si vous donnez une valeur incorrecte à une colonne, MySQL va stocker
le  
meilleur code possible
  dans la colonne, au lieu d'annuler la
transaction :  
Si vous essayez de stocker une valeur qui est hors de l'intervalle
de validité dans une colonne numérique, MySQL va stocker la plus petite
ou la plus grande valeur qu'il connaisse dans cette colonne.
Si vous essayez de stocker une chaîne qui ne commence pas par un chiffre
dans une colonne numérique, MySQL va stocker 0.
Si vous essayez de stocker la valeur  
NULL
  dans une colonne qui
n'accepte pas la valeur  
NULL
 , le serveur MySQL va stocker 0 ou  
''
  
(chaîne vide) à la place : ce comportement peut être modifié avec l'option
de compilation -DDONT_USE_DEFAULT_FIELDS).
MySQL vous autorise le stockage de dates erronées dans les colonnes de type  
DATE
  et
 
DATETIME
  (comme 2000-02-31 ou 2000-02-00). L'idée est que ce n'est pas
au serveur SQL de faire le travail de validation. Si MySQL peut stocker
une date, et relire exactement cette date, alors MySQL va stocker cette
date. Si la date est totalement fausse (hors de l'intervalle de validité
du serveur), la valeur spéciale 0000-00-00 sera utilisée.
Si vous utilisez une valeur non supportée avec une colonne de type  
ENUM
 ,
la valeur stockée sera la chaîne vide, de valeur numérique 0.
Si vous utilisez une valeur invalide dans une colonne de type  
SET
 ,
la valeur sera ignorée.
Si vous exécutez une  
PROCEDURE
  sur une requête qui retourne un résultat vide,
dans certains cas,  
PROCEDURE
  ne transformera pas les colonnes.
La création de table de type  
MERGE
  ne vérifie pas si les tables
sous-jacentes sont de type compatible.
Le serveur MySQL ne supporte pas encore les valeurs Server  
NaN
 ,  
-Inf
  
et  
Inf
  pour les doubles. Utiliser ces valeurs générera des problèmes
lorsque vous essayerez d'exporter et d'importer des données. Comme solution
temporaire, vous pouvez remplacer  
NaN
  par
 
NULL
  (si possible) et  
-Inf
  et  
Inf
  par les
valeurs maximales possibles des colonnes  
double
 .
Si vous utilisez la commande  
ALTER TABLE
  pour ajouter un index de type  
UNIQUE
 
à un table utilisée dans un rassemblement de tables  
MERGE
 , puis que 
vous utilisez  
ALTER TABLE
  pour ajouter un index normal à la table
 
MERGE
 , l'ordre des clés sera différent pour les tables s'il y avait déjà
une ancienne clé qui n'était pas unique. Ceci est dû au fait que 
 
ALTER TABLE
  place les clés  
UNIQUE
  avant les clés normales,
pour être capable de détecter les clés doublons plus vite.
 
Les bogues suivants sont connus dans les anciennes versions de MySQL :
 
Vous pouvez obtenir un thread gelé si vous utilisez la commande  
DROP TABLE
  sur
une table qui fait partie des tables verrouillées par  
LOCK TABLES
 .
Dans les cas suivants, vous pouvez obtenir un crash :  
Le gestionnaire d'insertions retardées a déjà des insertions
en attente pour une table.
LOCK table
  avec  
WRITE
 .
FLUSH TABLES
 .
Pour les versions de MySQL avant la 3.23.2, une commande  
UPDATE
  qui
modifiait une clé avec la clause  
WHERE
  sur la même clé, pouvait
échouer car la même clé était utilisée pour rechercher les lignes et
la même ligne pouvait être trouvée plusieurs fois :  
Un palliatif est :| 
UPDATE tbl_name SET KEY=KEY+1 WHERE KEY > 100;
 | 
 Cela fonctionnera, car MySQL ne va pas utiliser d'index sur une expression
dans la clause  
WHERE
 .| 
mysql> UPDATE tbl_name SET KEY=KEY+1 WHERE KEY+0 > 100;
 | 
Avant la version 3.23 de MySQL, tous les types numériques étaient
traités comme des champs à virgule fixe. Cela signifie que vous deviez
spécifier le nombre de décimales que le champ devait avoir. Tous les
résultats étaient retournés avec le nombre correct de
décimales.
 
Pour les bogues spécifiques aux systèmes d'exploitation, voyez la section
sur la compilation et le port.
 Installer MySQL à partir des sources .
 Port vers d'autres systèmes .
 |