web-dev-qa-db-fra.com

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

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 nous en occupons).

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 changer 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é plusieurs formules différentes en utilisant les colonnes varchar(N) (où N est compris entre 1 et 512), le jeu de caractères UTF8 (* 3), et autant de colonnes que la table 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 prendre en compte lors du calcul de la taille de 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)?

11
Evan

Les réponses à vos questions sont complexes, car elles varient selon InnoDB format de fichier . 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=Barracuda dans 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 entièrement 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 peut donc stocker uniquement 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 semble mieux maintenant.

Barracuda prend également en charge un 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 groupes répétitifs de la première forme normale.

19
Bill Karwin

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 incorporé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.

1
David