FAKTEN
Sie sagten, Sie verwenden ext4
. Die maximale Dateigröße beträgt 16 TB. Daher Sample.ibd
sollte nicht voll sein.
Du hast gesagt, dein innodb_data_file_path
ist 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 Full
Botschaft 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
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 Sample
Tabelle lädt .
ABER WARTE...
Sie sagen wahrscheinlich "Ich lade eine leere Sample
Tabelle". Wie sind Undo Logs involviert? Bevor die Sample
Tabelle 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 Sample
Tabelle 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 ibdata2
auf 2196875759616 gewachsen ist 2145386484M
.
Ich musste die Dateigröße von ibdata2
in 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 ibdata3
wuchs auf 31G. MySQL funktionierte wieder.