it-swarm-eu.dev

Chyba tabulky vytvoření InnoDB: "Příliš velká velikost řádku"

Máme několik inženýrů, kteří sloučili normalizovanou strukturu db do dočasné tabulky za účelem vygenerování sestavy. Sloupce jsou specifikovány jako TEXT NOT NULL (Vím „proč to dělají?“; Předpokládejme, že se tím zabýváme).

Používáme MySQL 5.1.48 Community RHEL5 s InnoDB plug-in 1.0.9 na Linuxu.

Při použití MyISAMu jsme nikdy nenarazili na maximální velikost sloupců tabulky nebo maximální délku řádku (během vyšetřování jsme dosáhli maximálního limitu sloupců na 2598 (2599. způsobuje chybu 1117). S InnoDB jsme zasáhli limity. Tyto limity se projevují při vytváření tabulka (bez vložení dat) jako:

ERROR 1118 (42000) na řádku 1: Příliš velká velikost řádku. Maximální velikost řádku pro použitý typ tabulky, nepočítající BLOB, je 8126. Některé sloupce musíte změnit na TEXT nebo BLOB.

Hledám odpovědi na následující:

  1. Jaký je podrobný vzorec pro určování velikosti řádků zejména při použití šarží sloupců v/v/b/t? Vyzkoušel jsem několik různých formálů pomocí sloupců varchar(N) (kde N je mezi 1 a 512), znakovou sadu UTF8 (* 3) a tolik sloupců, kolik bude tabulka trvat, dokud se nezdaří. Žádné komba, které jsem zkusil, nedává hodnoty, které odpovídají skutečným výsledkům testu.

  2. Jaké další „režijní náklady“ musím vzít v úvahu při výpočtu velikosti řádku?

  3. Proč se chybová zpráva mění z 8126 na 65535, když přejdu z vytváření tabulek se sloupci varchar (109) na sloupce varchar (110)?

11
Evan

Odpovědi na vaše otázky jsou složité, protože se liší podle InnoDB formát soubor . Dnes existují dva formáty, nazývané Antelope a Barracuda.

Soubor centrálního tabulkového prostoru (ibdata1) je vždy ve formátu Antelope . Pokud používáte soubor podle tabulky, můžete nastavit, aby jednotlivé soubory používaly formát Barracuda nastavením innodb_file_format=Barracuda v my.cnf.

Základní body:

  • Jedna stránka 16 kB dat InnoDB musí obsahovat alespoň dva řádky dat. Každá stránka má navíc záhlaví a zápatí obsahující kontrolní součty stránek a pořadové číslo protokolu atd. Zde získáte svůj limit o něco méně než 8 kB za řádek.

  • Na této stránce s primárními údaji jsou uloženy datové typy s pevnou velikostí, jako je INTEGER, DATUM, FLOAT, CHAR, a počítají se do limitu velikosti řádku.

  • Datové typy s proměnnou velikostí, jako jsou VARCHAR, TEXT, BLOB, jsou uloženy na přetečených stránkách, takže se do limitu velikosti řádku plně nezapočítávají. V antilopách je až 768 bajtů takových sloupců uloženo na stránce primárních dat kromě toho, že je uloženo na stránce přetečení. Barracuda podporuje dynamický formát řádk , takže může ukládat pouze 20-bajtový ukazatel na stránce primárních dat.

  • Datové typy s proměnnou velikostí jsou také předponovány 1 nebo více bajty pro kódování délky. Formát řádků InnoDB má také řadu posunů pole. Takže vnitřní struktura je víceméně dokumentováno na jejich wiki . [ÚPRAVA] Mrtvý odkaz - zde nyní vypadá lépe.

Barracuda také podporuje ROW_FORMAT = COMPRESSED k získání další efektivity úložiště pro data přetečení.

Musím také poznamenat, že jsem nikdy neviděl dobře navrženou tabulku překračující limit velikosti řádku. Je to silný „zápach kódu“, který porušuje podmínku opakující se skupiny prvního normálního formuláře.

19
Bill Karwin

Moje situace je trochu jiná. Jeden z datových prvků, které musím uložit do každého řádku, je potenciálně velmi velký. (Datové pole je LONGBLOB pro dokument, který může obsahovat více vložených obrázků. Moje ukázková databáze obsahuje dokumenty velké až 25 - 30 MB, ale tyto dokumenty mohou být v některých případech větší.) Žádné z řešení, které jsem našel online, nepomohlo. . (Změnil se typ souboru InnoDB na Barracuda, zvětšila se velikost souboru protokolu, nastavte formát řádků na COMPRESSED.)

Jediné řešení, které jsem pro mě našel, bylo vrátit se k MySQL 5.5.x z MySQL 5.6.x.

1
David