Heim  >  Artikel  >  Datenbank  >  Detaillierte Einführung in MySQLs schnelles „Flashback“ basierend auf Offline-Binlog

Detaillierte Einführung in MySQLs schnelles „Flashback“ basierend auf Offline-Binlog

黄舟
黄舟Original
2017-03-18 14:37:121548Durchsuche

Gestern sagte ein Kunde plötzlich, er habe versehentlich eine große Datenmenge gelöscht. Der CTO zog mich direkt in eine Diskussionsgruppe und sagte, dass er ihnen bei der Wiederherstellung ihrer Daten helfen würde. Sie haben die Lücke selbst gegraben und wollten sie von der Entwicklungsseite anhand der Geschäftsprotokolle wiederherstellen lassen. Man teilte ihnen mit, dass nur Informationen wie das Löschen des Primärschlüssels aufgezeichnet würden und eine physische Löschung nicht möglich sei.

Ich habe mir die aufgezeichneten Protokolle auf dem Server angesehen und festgestellt, dass mehrere von ihnen versehentlich die Aufzeichnungsausgabe gelöscht hatten. Obwohl Alibaba RDS eine Instanz klonen und auf den Zeitpunkt vor dem Löschen wiederherstellen kann, ist es schwierig, Zehntausende verstreuter IDs zu finden, und die mit mehreren Tabellen verknüpften Daten müssen ebenfalls wiederhergestellt werden, was problematisch ist.

Denken Sie an die Flashback-Lösung von MySQL. Ich habe bereits mehrere verwandte Artikel gelesen und fast sogar Python verwendet, um das Binlog selbst zu analysieren und es umzukehren, um das Rollback-SQL zu erhalten, also muss ich es jetzt dringend verwenden . Schnell habe ich online nach „fertigen Lösungen“ gesucht.

Text beginnt


Der schnelle Flashback von MySQL (einschließlich Alibaba RDS) kann als Gegenmittel für Fehlfunktionen der Datenbank bezeichnet werden. Die Flashback-Funktion kann die Datenbank in den Zustand vor der Fehloperation zurückversetzen. Aber selbst die Oracle-Datenbank unterstützt Flashback nur innerhalb kurzer Zeit.

Die vorhandene Open-Source-MySQL-Flashback-Implementierung im Internet verwendet das Prinzip des Binlog-Parsings und der Generierung von Reverse SQL: (muss im Zeilenmodus sein)

  1. Für Löschvorgänge: Einfügung generieren (DELETE_ROWS_EVENT)

  2. Für den Aktualisierungsvorgang die Reihenfolge der Werte im Binlog austauschen (UPDATE_ROWS_EVENT)

  3. Für den Einfügungsvorgang umgekehrt generieren löschen ( WRITE_ROWS_EVENT)

  4. Für mehrere Ereignisse umgekehrt SQL generieren

Die beiden oben genannten Implementierungsmethoden erfolgen über das Python-MySQL-Replikationspaket , simulieren Sie eine Slave-Bibliothek der Originalbibliothek, rufen Sie dann mit show binary logs das Binlog ab, initiieren Sie eine Anforderung zum Synchronisieren des Binlogs und analysieren Sie dann EVENT. Nachdem jedoch das Binlog von Alibaba Cloud RDS mit der Slave-Datenbank synchronisiert wurde, wurde es schnell gelöscht . Wenn Sie den gestrigen Teil der Daten wiederherstellen möchten, erhalten beide Optionen das Binlog nicht. Mit anderen Worten: Die Flashback-Zeit ist begrenzt.

Es gibt auch einige relativ einfache Implementierungen, die die physische Binlog-Datei analysieren und ein Rollback implementieren sollen, wie zum Beispiel binlog-rollback.pl, aber die Geschwindigkeit ist zu langsam.

Um die Geschwindigkeit nicht zu beeinträchtigen, aber auch eine ausgereiftere Flashback-Lösung verwenden möchten, können wir Folgendes tun:

  1. Verwenden Sie eine selbst erstellte MySQLd-Instanz purge Kopieren Sie das Binlog in das Verzeichnis der Instanz

  2. Erstellen Sie in der selbst erstellten Instanz die Tabelle (Struktur), die im Voraus wiederhergestellt werden muss, da das Tool verbunden werden muss um Metadaten von information_schema.columns zu erhalten. Beim Kopieren von Informationen

  3. können Sie den Binlog-Dateinamen der MySQL-Instanz ersetzen, um ihn kontinuierlich zu halten

  4. Möglicherweise müssen Sie mysql-bin.index ändern, um sicherzustellen, dass der Dateiname auch von MySQL erkannt werden kann.

  5. Starten Sie die MySQL-Instanz neu, show binary logs und prüfen Sie, ob sie in der Liste enthalten ist

  6. Dann können Sie eines der oben genannten Tools verwenden, die Slave-Bibliothek simulieren, eine Binlog-Datei, Startzeit und Endzeit angeben und das Rollback-SQL abrufen

  7. und dann das erforderliche SQL herausfiltern

    basierend auf der Geschäftslogik

fc430c7db1eecf4621f4fc8a5479f894
Kurz gesagt, es geht darum, ein anderes MySQL zu verwenden Übertragen Sie das Binlog-Ereignis. Warme Erinnerung:

  1. Keine zu große Versionslücke zwischen den beiden Instanzen

  2. Achten Sie auf Dateiberechtigungen

  3. Wenn gtid in der Originalbibliothek aktiviert ist, muss diese selbst erstellte Instanz auch gtid aktivieren

Beispiel:

python mysqlbinlog_back.py --host="localhost" --username="ecuser" --password="ecuser" --port=3306 \
--schema=dbname --tables="t_xx1,t_xx2,t_xx3" -S "mysql-bin.000019" -E "2017-03-02 13:00:00" -N "2017-03-02 14:09:00" -I -U

===log will also  write to .//mysqlbinlog_flashback.log===
parameter={'start_binlog_file': 'mysql-bin.000019', 'stream': None, 'keep_data': True,
 'file': {'data_create': None, 'flashback': None, 'data': None}, 'add_schema_name': False, 'start_time': None, 
 'keep_current_data': False, 'start_to_timestamp': 1488430800,
 'mysql_setting': {'passwd': 'ecuser', 'host': 'localhost', 'charset': 'utf8', 'port': 3306, 'user': 'ecuser'},
 'table_name': 't_xx1,t_xx2,t_xx3', 'skip_delete': False, 'schema': 'dbname', 'stat': {'flash_sql': {}},
 'table_name_array': ['t_xx1', 't_xx2', 't_xx3'],
 'one_binlog_file': False, 'output_file_path': './log', 'start_position': 4, 'skip_update': True,
 'dump_event': False, 'end_to_timestamp': 1488434940, 'skip_insert': True, 'schema_array': ['dbname']
}
scan 10000 events ....from binlogfile=mysql-bin.000019,timestamp=2017-03-02T11:42:14
scan 20000 events ....from binlogfile=mysql-bin.000019,timestamp=2017-03-02T11:42:29
...

Tipps:
binlog ist im ROW-Format, dml. Jede betroffene Zeile zeichnet zwei Ereignisse auf: Table_map und Row_log. Die table_id in table_map hat keinen Einfluss darauf, auf welche Instanz sie angewendet wird. Diese ID kann als logischer Mechanismus zum Aufzeichnen der Tabellenstrukturversion betrachtet werden. Wenn die Tabellendefinition nicht im table_definition_cache gefunden wird, wird die ID um 1 erhöht und zugewiesen Das Ziel. In der Binlog-Tabelle aufzeichnen.

mysqlbinlog_back.py-Nutzungserfahrung:

  • Stellen Sie sicher, dass Sie den Namen der Bibliothek, die Angabe, den Namen der Start-Binlog-Datei, die Startzeit und das Ende angeben Zeit. Kann den Scan beschleunigen.

  • Wählen Sie entsprechend den Wiederherstellungsanforderungen -I, -U, -D aus, um anzugeben, welche Arten von Vorgängen zurückgesetzt werden sollen.

  • Wenn nur teilweise Tabellendaten wiederhergestellt werden (nicht vollständiger Flashback), kann die zugehörige Tabelle nicht korrekt wiederhergestellt werden. Beispielsweise ist es notwendig, gelöschte Daten wiederherzustellen, aber es ist unmöglich, Daten im Unternehmen wiederherzustellen, die dazu geführt haben, dass andere Tabellen aufgrund des Löschvorgangs aktualisiert wurden, es sei denn, sie werden vollständig zurückgeblendet.

  • Unterstützt keine Tabellenfelder vom Typ „enum“, wie z. B. das Feld „f_do_type“ von t_xx3. Sie können die Enum-Definition auf der selbst erstellten Instanz in int ändern.

Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in MySQLs schnelles „Flashback“ basierend auf Offline-Binlog. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn