InnoDB crea errore tabella: "Dimensione riga troppo grande"


11

Abbiamo alcuni ingegneri che appiattiscono una struttura db normalizzata in una tabella temporanea allo scopo di generare un report. Le colonne sono specificate come TEXT NOT NULL(so "perché lo stanno facendo?"; Supponiamo che ci stiamo occupando di questo).

Utilizziamo MySQL 5.1.48 Community RHEL5 con plug-in InnoDB 1.0.9 su Linux.

Quando si utilizza MyISAM non abbiamo mai riscontrato limiti di dimensione della tabella per colonne massime o lunghezza massima della riga (durante l'indagine abbiamo raggiunto il limite massimo di colonne a 2598 (il 2599 causa errore 1117). Con InnoDB stiamo raggiungendo limiti. Questi limiti si manifestano durante la creazione del tabella (nessun inserimento di dati) come:

ERRORE 1118 (42000) alla riga 1: dimensione della riga troppo grande. La dimensione massima della riga per il tipo di tabella utilizzata, senza contare i BLOB, è 8126. È necessario modificare alcune colonne in TESTO o BLOB

Cerco risposte a quanto segue:

  1. Qual è la formula dettagliata per determinare le dimensioni delle righe quando si usano lotti di colonne v / v / b / t? Ho provato alcuni formati diversi usando le varchar(N)colonne (dove N è compreso tra 1 e 512), il set di caratteri UTF8 (* 3) e tutte le colonne che la tabella prenderà fino al fallimento. Nessuna delle combinazioni che ho provato fornisce valori che corrispondono ai risultati dei test effettivi.

  2. Quali altri "costi generali" devo considerare nel calcolo delle dimensioni della riga?

  3. Perché il messaggio di errore cambia da 8126 a 65535 quando passo dalla creazione di tabelle con colonne varchar (109) a colonne varchar (110)?


Ho avuto lo stesso problema. Quando stavo controllando un database ho scoperto che uno dei componenti aggiuntivi del browser Web stava inserendo il codice html nel codice sorgente della pagina (anche nel modulo) e questo causava il problema.

HTML non è il cattivo. Né la dimensione di quell'HTML. Devi avere più colonne text / varchar e avere colpito alcune limitazioni che possono essere aggirate.
Rick James,

Risposte:


19

Le risposte alle tue domande sono complesse, perché variano in base al formato del file InnoDB . Oggi ci sono due formati, chiamati Antelope e Barracuda.

Il file del tablespace centrale (ibdata1) è sempre in formato Antelope . Se usi file per tabella, puoi fare in modo che i singoli file utilizzino il formato Barracuda impostando innodb_file_format=Barracudain my.cnf.

Punti di base:

  • Una pagina da 16 KB di dati InnoDB deve contenere almeno due righe di dati. Inoltre ogni pagina ha un'intestazione e un piè di pagina che contiene checksum di pagina e numero di sequenza del registro e così via. Ecco dove ottieni il tuo limite di poco meno di 8 KB per riga.

  • I tipi di dati a dimensione fissa come INTEGER, DATE, FLOAT, CHAR sono memorizzati in questa pagina di dati primaria e vengono conteggiati per il limite della dimensione della riga.

  • I tipi di dati di dimensioni variabili come VARCHAR, TEXT, BLOB sono archiviati in pagine di overflow, quindi non vengono conteggiati completamente ai fini del limite di dimensioni della riga. In Antelope, fino a 768 byte di tali colonne sono memorizzati nella pagina dei dati primari oltre a essere archiviati nella pagina di overflow. Barracuda supporta un formato di riga dinamico , quindi può memorizzare solo un puntatore da 20 byte nella pagina dei dati primari.

  • I tipi di dati di dimensioni variabili sono inoltre preceduti da 1 o più byte per codificare la lunghezza. E il formato di riga InnoDB ha anche una matrice di offset di campo. Quindi c'è una struttura interna più o meno documentata nella loro wiki . [EDIT] Dead link - qui sembra meglio ora.

Barracuda supporta anche un ROW_FORMAT = COMPRESSED per ottenere ulteriore efficienza di archiviazione per i dati di overflow.

Devo anche commentare che non ho mai visto una tabella ben progettata superare il limite delle dimensioni della riga. È un forte "odore di codice" che stai violando la condizione di gruppi ripetuti di First Normal Form.


2
È molto semplice per gli ingegneri che non sono coscienti di DB seguire la strada dei dati flat. non esegue MAI. Il mio DB legacy che ha una situazione simile non sta colpendo le dimensioni delle file in modo meno drammatico, ma ragazzo è un vantaggio prestazionale! Direi che il vostro ingegnere addetto ai rapporti deve accettare che dovranno fare unirsi e compensare bene quel lavoro con tutta l'indicizzazione.
TechieGurl,

1

La mia situazione è leggermente diversa. Uno degli elementi di dati che devo memorizzare in ogni riga è potenzialmente molto grande. (Il campo dati è un LONGBLOB per un documento che può contenere più immagini incorporate. Il mio database di esempio contiene documenti di dimensioni comprese tra 25 e 30 MB, ma in alcuni casi questi documenti potrebbero essere più grandi.) Nessuna delle soluzioni che ho trovato online ha fornito sollievo . (Modificato il tipo di file InnoDB su Barracuda, aumentato la dimensione del file di registro, impostato il formato di riga su COMPRESSED.)

L'unica soluzione che ho trovato che ha funzionato per me è stata quella di ripristinare MySQL 5.5.x da MySQL 5.6.x.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.