InnoDB crée une erreur de table: "Taille de ligne trop grande"

11

Certains ingénieurs ont aplati une structure de base de données normalisée dans une table temporaire afin de générer un rapport. Les colonnes sont spécifiées comme TEXT NOT NULL(je sais "pourquoi font-ils cela?"; Supposons simplement que nous abordons ce problème).

Nous utilisons MySQL 5.1.48 Community RHEL5 avec le plug-in InnoDB 1.0.9 sous Linux.

Lors de l'utilisation de MyISAM, nous n'avons jamais rencontré de limites de taille de table de colonnes max ou de longueur de ligne max (au cours de l'enquête, nous avons atteint la limite de colonnes max à 2598 (le 2599ème provoque l'erreur 1117). Avec InnoDB, nous atteignons des limites. Ces limites se manifestent lors de la création du table (pas d'insertion de données) comme:

ERREUR 1118 (42000) à la ligne 1: taille de ligne trop grande. La taille de ligne maximale pour le type de table utilisé, sans compter les BLOBs, est 8126. Vous devez modifier certaines colonnes en TEXT ou BLOBs

Je cherche des réponses aux questions suivantes:

  1. Quelle est la formule détaillée pour déterminer la taille des lignes de particules lors de l'utilisation de lots de colonnes v / v / b / t? J'ai essayé quelques formules différentes en utilisant des varchar(N)colonnes (où N est compris entre 1 et 512), le jeu de caractères UTF8 (* 3) et autant de colonnes que le tableau prendra jusqu'à l'échec. Aucun des combos que j'ai essayés ne donne des valeurs qui correspondent aux résultats des tests réels.

  2. Quels autres «frais généraux» dois-je considérer lors du calcul de la taille de la ligne?

  3. Pourquoi le message d'erreur passe-t-il de 8126 à 65535 lorsque je passe de la création de tables avec des colonnes varchar (109) à des colonnes varchar (110)?


la source
J'ai eu le même problème. Lorsque je vérifiais une base de données, j'ai trouvé que l'un des modules complémentaires du navigateur Web insérait du code html dans le code source de la page (même dans le formulaire) et cela causait le problème.
HTML n'est pas le méchant. Ni la taille de ce HTML. Vous devez avoir eu plusieurs colonnes text / varchar et avoir rencontré certaines limitations qui peuvent être contournées.
Rick James

Réponses:

19

Les réponses à vos questions sont complexes, car elles varient selon le format de fichier InnoDB . Aujourd'hui, il existe deux formats, appelés Antelope et Barracuda.

Le fichier d'espace de table central (ibdata1) est toujours au format Antelope . Si vous utilisez un fichier par table, vous pouvez faire en sorte que les fichiers individuels utilisent le format Barracuda en définissant innodb_file_format=Barracudadans my.cnf.

Points de base:

  • Une page de 16 Ko de données InnoDB doit contenir au moins deux lignes de données. De plus, chaque page a un en-tête et un pied de page contenant des sommes de contrôle de page et un numéro de séquence de journal, etc. C'est là que vous obtenez votre limite d'un peu moins de 8 Ko par ligne.

  • Les types de données de taille fixe comme INTEGER, DATE, FLOAT, CHAR sont stockés sur cette page de données principale et comptent dans la limite de taille de ligne.

  • Les types de données de taille variable tels que VARCHAR, TEXT, BLOB sont stockés sur les pages de débordement, de sorte qu'ils ne comptent pas pleinement dans la limite de taille de ligne. Dans Antelope, jusqu'à 768 octets de ces colonnes sont stockés sur la page de données principale en plus d'être stockés sur la page de débordement. Barracuda prend en charge un format de ligne dynamique , il ne peut donc stocker qu'un pointeur de 20 octets sur la page de données principale.

  • Les types de données de taille variable sont également préfixés avec 1 ou plusieurs octets pour coder la longueur. Et le format de ligne InnoDB a également un tableau de décalages de champ. Il y a donc une structure interne plus ou moins documentée dans leur wiki . [EDIT] Lien mort - ici, c'est mieux maintenant.

Barracuda prend également en charge ROW_FORMAT = COMPRESSED pour gagner en efficacité de stockage pour les données de débordement.

Je dois également dire que je n'ai jamais vu un tableau bien conçu dépasser la limite de taille de ligne. C'est une forte "odeur de code" que vous violez la condition de groupes répétitifs de la première forme normale.

Bill Karwin
la source
2
Il est très facile pour les ingénieurs qui ne sont pas soucieux de la DB de suivre la voie des données plates. il ne fonctionne JAMAIS. Ma propre base de données héritée qui a une situation similaire ne frappe pas la taille des rangées de manière moins dramatique, mais c'est une aubaine pour les performances! Je dirais que votre ingénieur reporting doit accepter qu'il devra faire des jointures et simplement compenser ce travail avec une bonne indexation.
TechieGurl
1

Ma situation est légèrement différente. L'un des éléments de données que je dois stocker dans chaque ligne est potentiellement très volumineux. (Le champ de données est un LONGBLOB pour un document qui peut contenir plusieurs images intégrées. Mon exemple de base de données contient des documents pouvant atteindre 25 à 30 Mo, mais ces documents peuvent être plus volumineux dans certains cas.) Aucune des solutions que j'ai trouvées en ligne n'a fourni de secours . (Modification du type de fichier InnoDB en Barracuda, augmentation de la taille du fichier journal, définition du format de ligne sur COMPRESSED.)

La seule solution que j'ai trouvée qui a fonctionné pour moi était de revenir à MySQL 5.5.x à partir de MySQL 5.6.x.

David
la source