`ERROR 1114 (HY000) the table… is full`, wobei innodb_file_per_table auf autoextend gesetzt ist

26

Ich habe eine MySQL-Datenbank, die eine große Datenmenge enthält (100-200 GB - eine Reihe von wissenschaftlichen Messungen). Die überwiegende Mehrheit der Daten wird in einer Tabelle gespeichert Sample. Jetzt erstelle ich ein Slave-Replikat der Datenbank und wollte dabei die Vorteile nutzen innodb_file_per_table. Also habe ich innodb_file_per_tablemeine Slave-Konfiguration eingestellt und den Dump der Datenbank importiert. Zu meiner Überraschung scheiterte es mit

FEHLER 1114 (HY000) in Zeile 5602: Die Tabelle 'Sample' ist voll

Die Datei Sample.ibdhat derzeit eine Größe von 93 GB. Auf der Partition sind mehr als 600 GB freier Speicherplatz verfügbar. Es handelt sich also nicht um ein Problem mit freiem Speicherplatz. Weder scheint es irgendeine Art von Dateisystemlimit zu erreichen (ich verwende ext4).

Ich wäre dankbar für jede Idee, was die Ursache sein könnte oder was untersucht werden sollte.


Update: Ich benutze mysql Ver 14.14 Distrib 5.1.66, for debian-linux-gnu (x86_64).

SELECT @@datadir; -- returns `/home/var/lib/mysql/`
SHOW VARIABLES LIKE '%innodb_data_file_path%'; -- ibdata1:10M:autoextend 

df -h /home/var/lib/mysql/
768G   31G  699G   5% /home
Petr Pudlák
quelle

Antworten:

33

FAKTEN

Sie sagten, Sie verwenden ext4. Die maximale Dateigröße beträgt 16 TB. Daher Sample.ibdsollte nicht voll sein.

Du hast gesagt, dein innodb_data_file_pathist ibdata1:10M:autoextend. Daher hat die ibdata1-Datei selbst keine Begrenzung auf ihre Größe, außer vom Betriebssystem.

Warum kommt diese Nachricht überhaupt? Beachten Sie, dass die Meldung "Die Tabelle ... ist voll" und nicht "Die Festplatte ... ist voll" lautet. Diese Bedingung für die vollständige Tabelle ist logisch . Denken Sie an InnoDB. Welche Interaktionen finden statt?

Ich vermute, InnoDB versucht, 93 GB Daten als einzelne Transaktion zu laden. Woher würde die Table is FullBotschaft kommen? Ich würde die ibdata1 nicht in Bezug auf ihre physische Größe (die Sie bereits ausgeschlossen haben) betrachten, sondern in Bezug darauf, welche Transaktionslimits erreicht werden.

Was ist in ibdata1, wenn innodb_file_per_table aktiviert ist und Sie neue Daten in MySQL laden?

Mein Verdacht sagt mir, dass die Undo Logs und / oder Redo Logs schuld sind.

Was sind diese Protokolle? Nach dem Buch

sxs

Kapitel 10: "Speicher-Engines" In den Absätzen 3 und 4 heißt es:

Die InnoDB-Engine führt zwei Arten von Protokollen: ein Undo-Protokoll und ein Redo-Protokoll. Der Zweck eines Rückgängig-Protokolls besteht darin, Transaktionen zurückzusetzen und die älteren Versionen der Daten für Abfragen anzuzeigen, die in der erforderlichen Transaktionsisolationsstufe ausgeführt werden. Der Code, der das Rückgängig-Protokoll verarbeitet, befindet sich in storage / innobase / buf / log / log0log.c .

Der Zweck des Redo-Protokolls besteht darin, die Informationen zu speichern, die bei der Wiederherstellung nach einem Absturz verwendet werden sollen. Es ermöglicht dem Wiederherstellungsprozess, die Transaktionen erneut auszuführen, die möglicherweise vor dem Absturz abgeschlossen wurden oder nicht. Nach dem erneuten Ausführen dieser Transaktionen wird die Datenbank in einen konsistenten Zustand versetzt. Der Code für das Redo-Log befindet sich in storage / innobase / log / log0recv.c .

ANALYSE

In ibdata1 befinden sich 1023 Undo-Protokolle (siehe Rollback-Segmente und Undo-Space) . Da in den Rückgängig-Protokollen Kopien der Daten gespeichert werden, die vor dem erneuten Laden angezeigt wurden, haben alle 1023 Rückgängig-Protokolle ihr Limit erreicht. Aus einer anderen Perspektive können alle 1023-Rückgängig-Protokolle der einen Transaktion zugeordnet sein, die die SampleTabelle lädt .

ABER WARTE...

Sie sagen wahrscheinlich "Ich lade eine leere SampleTabelle". Wie sind Undo Logs involviert? Bevor die SampleTabelle mit 93 GB Daten geladen wurde, war sie leer. Die Darstellung jeder Zeile, die nicht vorhanden war, muss in den Rückgängig-Protokollen einen gewissen Platz in Anspruch nehmen. Das Ausfüllen von 1023-Rückgängig-Protokollen erscheint angesichts der Datenmenge, in die Daten eingehen, trivial ibdata1. Ich bin nicht die erste Person, die das vermutet:

Beachten Sie in der MySQL 4.1-Dokumentation Folgendes Posted by Chris Calender on September 4 2009 4:25pm:

Beachten Sie, dass in 5.0 (vor 5.0.85) und in 5.1 (vor 5.1.38) der Fehler "Tabelle ist voll" für eine InnoDB-Tabelle angezeigt werden kann, wenn InnoDB nicht mehr über genügend Undo-Slots verfügt (Fehler Nr. 18828).

Hier ist der Fehlerbericht für MySQL 5.0: http://bugs.mysql.com/bug.php?id=18828

VORSCHLÄGE

Wenn Sie den mysqldump der SampleTabelle erstellen , verwenden Sie bitte --no-autocommit

mysqldump --no-autocommit ... mydb Sample > Sample.sql

Dies wird COMMIT;nach jedem expliziten setzen INSERT. Laden Sie dann die Tabelle neu.

Wenn dies nicht funktioniert (das wird Ihnen nicht gefallen ), tun Sie dies

mysqldump --no-autocommit --skip-extended-insert ... mydb Sample > Sample.sql

Dadurch hat jedes INSERT nur eine Zeile. Der mysqldump wird viel größer (10+ mal größer) und es könnte 10 bis 100 mal länger dauern, bis er neu geladen wird.

In beiden Fällen werden die Rückgängig-Protokolle nicht überschwemmt.

Versuche es !!!

UPDATE 2013-06-03 13:05 EDT

ZUSÄTZLICHE VORSCHLÄGE

Wenn die InnoDB-Systemtabelle (auch bekannt als ibdata1) ein Dateigrößenlimit überschreitet und Rückgängig-Protokolle nicht verwendet werden können, können Sie einfach einen weiteren Systemtabellenbereich (ibdata2) hinzufügen.

Ich bin gerade vor zwei Tagen auf diese Situation gestoßen. Ich habe meinen alten Beitrag mit dem aktualisiert, was ich getan habe: Siehe Datenbankdesign - Erstellen mehrerer Datenbanken, um das Problem der Beschränkung der Tabellengröße zu vermeiden

Im Wesentlichen müssen Sie innodb_data_file_path ändern , um eine neue System-Tablespace-Datei aufzunehmen. Lassen Sie mich erklären, wie:

SZENARIO

Auf der Festplatte (ext3) hatte der Server meines Clients Folgendes:

[root@l*****]# ls -l ibd*
-rw-rw---- 1 s-em7-mysql s-em7-mysql     362807296 Jun  2 00:15 ibdata1
-rw-rw---- 1 s-em7-mysql s-em7-mysql 2196875759616 Jun  2 00:15 ibdata2

Die Einstellung war

innodb_data_file_path=ibdata1:346M;ibdata2:500M:autoextend:max:10240000M

Beachten Sie, dass ibdata2auf 2196875759616 gewachsen ist 2145386484M.

Ich musste die Dateigröße von ibdata2in innodb_data_file_path einbetten und hinzufügenibdata3

innodb_data_file_path=ibdata1:346M;ibdata2:2196875759616;ibdata3:10M:autoextend

Als ich mysqld neu gestartet habe, hat es funktioniert:

[root@l*****]# ls -l ibd*
-rw-rw---- 1 s-em7-mysql s-em7-mysql     362807296 Jun  3 17:02 ibdata1
-rw-rw---- 1 s-em7-mysql s-em7-mysql 2196875759616 Jun  3 17:02 ibdata2
-rw-rw---- 1 s-em7-mysql s-em7-mysql   32315015168 Jun  3 17:02 ibdata3

In 40 Stunden ibdata3wuchs auf 31G. MySQL funktionierte wieder.

RolandoMySQLDBA
quelle
Ich gehe davon aus, dass Ihr Kunde unter dem Namen des Eigentümers ein aufstrebendes Überwachungstool verwendet hat.
Steve
Ich frage mich, ob dies immer noch ein Problem ist (hoffe nicht)
Evan Carroll
3

Ich hatte das gleiche Problem und ich habe nur eine Sache gemacht und es hat funktioniert.

Sie haben anscheinend eine zu geringe Maximalgröße für innodb_data_file_pathIhre my.cnfKonfigurationsdatei. Ändern Sie einfach den folgenden Code -

innodb_data_file_path = ibdata1:10M:autoextend:max:512M

Wichtiger Hinweis Sie können nicht mehr als 512MBDaten in allen InnoDB Tabellen zusammen hosten .

Sie können auch mit zu einem Innodb-per-Table-Schema wechseln innodb_file_per_table.

Joomler
quelle