Da das Unternehmen eine große Transaktion schrieb, wurde das Binlog von MySQL erweitert. Beim Parsen eines großen Binlogs stoßen wir häufig auf dieses Problem, das das Parsen unmöglich macht. Ohne andere Tools ist es schwierig, das Problem zu analysieren.
Autor: Sun Xuzong, Ingenieur des Sina Weibo DBA-Teams, hauptsächlich verantwortlich für den Betrieb und die Wartung relationaler Datenbanken wie MySQL und PostgreSQL.
Produziert von der Aikeson Open Source Community. Originalinhalte dürfen nicht ohne Genehmigung verwendet werden. Bitte kontaktieren Sie den Herausgeber und geben Sie die Quelle für den Nachdruck an.
Dieser Artikel umfasst insgesamt 3200 Wörter und die Lektüre dauert voraussichtlich 10 Minuten.
Fehlerphänomen
Da das Unternehmen eine große Transaktion schrieb, wurde das Binlog von MySQL erweitert. Beim Parsen eines großen Binlogs stoßen wir häufig auf dieses Problem, das das Parsen unmöglich macht. Ohne andere Tools ist es schwierig, das Problem zu analysieren.
Wiederkehr des Fehlers
[root@xuzong mysql]# ls -lh mysql-bin.003300
-rw-r----- 1 my3696 mysql 6.7G Oct 30 16:24 mysql-bin.003300
[root@xuzong mysql]# /usr/local/mysql-5.7.35/bin/mysqlbinlog -vv mysql-bin.003300 > 1.sql
mysqlbinlog: Error writing file '/tmp/tmp.0Uirch' (Errcode: 28 - No space left on device)
mysqlbinlog: Error writing file '/tmp/tmp.0Uirch' (Errcode: 28 - No space left on device)
mysqlbinlog: Error writing file '/tmp/tmp.0Uirch' (Errcode: 28 - No space left on device)
mysqlbinlog: Error writing file '/tmp/tmp.0Uirch' (Errcode: 28 - No space left on device)
mysqlbinlog: Error writing file '/tmp/tmp.334z3P' (Errcode: 28 - No space left on device)
mysqlbinlog: Error writing file '/tmp/tmp.0Uirch' (Errcode: 28 - No space left on device)
mysqlbinlog: Error writing file '/tmp/tmp.0Uirch' (Errcode: 28 - No space left on device)
mysqlbinlog: Error writing file '/tmp/tmp.0Uirch' (Errcode: 28 - No space left on device)
mysqlbinlog: Error writing file '/tmp/tmp.0Uirch' (Errcode: 28 - No space left on device)
mysqlbinlog: Error writing file '/tmp/tmp.0Uirch' (Errcode: 28 - No space left on device)
erraten
- Möglicherweise liegt ein Problem mit tmpdir in der Konfigurationsdatei vor, aber um dies zu ändern, müssen Sie MySQL neu starten.
- Ist es möglich, diesen temporären Speicherplatz zu ändern, ohne MySQL neu zu starten?
Vermutung bestätigen
Erraten Sie eins
Als ich mir das von my.cnf festgelegte tmpdir ansah, stellte ich fest, dass dieser Parameter nicht verwendet wurde. Es scheint, dass die Vermutung falsch war.
[root@mysql mysql]# cat my.cnf | grep tmpdir
tmpdir = /data1/dbatemp
Rate mal 2
Nach der Online-Suche sprechen die meisten darüber, wie das Problem der vollständigen temporären Tabelle gelöst werden kann. Dies ist die erste Vermutung: Es gibt keine klare Möglichkeit, den vom temporären Handle belegten Speicherplatz zu ändern, der beim Parsen von mybinlog verwendet wird.
Problemanalyse
Wir können uns nur den Quellcode ansehen und sehen, wie mysqlbinlog tmpdir erhält.
mysqbinlog.cc
int main(int argc, char** argv)
{
........
MY_TMPDIR tmpdir;
tmpdir.list= 0;
if (!dirname_for_local_load)
{
if (init_tmpdir(&tmpdir, 0))
exit(1);
dirname_for_local_load= my_strdup(PSI_NOT_INSTRUMENTED,
my_tmpdir(&tmpdir), MY_WME);
}
........
}
mf_tempdir.cc
my_bool init_tmpdir(MY_TMPDIR *tmpdir, const char *pathlist)
{
char *end, *copy;
char buff[FN_REFLEN];
DBUG_ENTER("init_tmpdir");
DBUG_PRINT("enter", ("pathlist: %s", pathlist ? pathlist : "NULL"));
Prealloced_array<char*, 10, true> full_list(key_memory_MY_TMPDIR_full_list);
memset(tmpdir, 0, sizeof(*tmpdir));
if (!pathlist || !pathlist[0])
{
/* Get default temporary directory */
pathlist=getenv("TMPDIR"); /* Use this if possible */ //这里能看到是获取的机器环境变量
#if defined(_WIN32)
if (!pathlist)
pathlist=getenv("TEMP"); //windows是temp
if (!pathlist)
pathlist=getenv("TMP"); //linux是tmp
#endif
if (!pathlist || !pathlist[0])
pathlist= DEFAULT_TMPDIR;
}
........
}
Guter Kerl, es stellte sich heraus, dass es sich um die erhaltene Maschinenumgebungsvariable handelte, also ist dieses Problem gelöst.
Probleme lösen
Ändern Sie einfach vorübergehend die tmpdir-Variable der Maschine.
[root@mysql mysql]# export TMPDIR="/data1"
[root@mysql mysql]# echo ${TMPDIR:-/tmp}
[root@xuzong mysql]# /usr/local/mysql-5.7.35/bin/mysqlbinlog -vv mysql-bin.003300 > 1.sql
Zusammenfassen
- Wenn Sie Fragen haben, überprüfen Sie bitte den Quellcode.
- Sie können erwägen, Binlog-Analysetools wie bin2sql zu verwenden, um das Problem zu lösen.
- Sie können überprüfen, ob im langsamen Protokoll ein Eintrag vorhanden ist.
Auffüllen
Es stellt sich heraus, dass dieses Problem im offiziellen MySQL-Handbuch beschrieben ist , daher werde ich hier eine Ergänzung vornehmen.
Wenn Sie mysqlbinlog für ein großes Binärprotokoll ausführen, achten Sie darauf, dass das Dateisystem über genügend Speicherplatz für die resultierenden Dateien verfügt. Um das Verzeichnis zu konfigurieren, das mysqlbinlog für temporäre Dateien verwendet, verwenden Sie die Umgebungsvariable TMPDIR.
Weitere technische Artikel finden Sie unter: https://opensource.actionsky.com/
Über SQLE
SQLE ist eine umfassende SQL-Qualitätsmanagementplattform, die die SQL-Prüfung und -Verwaltung von der Entwicklung bis zur Produktionsumgebung abdeckt. Es unterstützt gängige Open-Source-, kommerzielle und inländische Datenbanken, bietet Prozessautomatisierungsfunktionen für Entwicklung, Betrieb und Wartung, verbessert die Online-Effizienz und verbessert die Datenqualität.
SQLE erhalten
Typ | Adresse |
---|---|
Repository | https://github.com/actiontech/sqle |
dokumentieren | https://actiontech.github.io/sqle-docs/ |
Neuigkeiten veröffentlichen | https://github.com/actiontech/sqle/releases |
Entwicklungsdokumentation für das Datenaudit-Plug-in | https://actiontech.github.io/sqle-docs/docs/dev-manual/plugins/howtouse |