Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Verarbeitet mysqldump binäre Daten zuverlässig?

Nein, es ist nicht immer zuverlässig, wenn Sie binäre Blobs haben. In diesem Fall MÜSSEN Sie die Datei „--hex-blob verwenden " markieren, um korrekte Ergebnisse zu erhalten.

Vorbehalt aus dem Kommentar unten:

Ich habe einen Fall, in dem diese Aufrufe fehlschlagen (Import auf einem anderen Server, aber beide mit Centos6/MariaDB 10):

mysqldump --single-transaction --routines --databases myalarm -uroot -p"PASSWORD" | gzip > /FILENAME.sql.gz
gunzip < FILENAME.sql.gz | mysql -p"PASSWORD" -uroot --comments

Es erzeugt eine Datei, die stillschweigend nicht importiert werden kann. Das Hinzufügen von "--skip-extended-insert" gibt mir eine Datei, die viel einfacher zu debuggen ist, und ich finde, dass diese Zeile generiert wird, aber nicht gelesen werden kann (aber es wird weder beim Exportieren noch beim Importieren ein Fehler gemeldet):

INSERT INTO `panels` VALUES (1003,1,257126,141,6562,1,88891,'??\\\?ŖeV???,NULL);

Beachten Sie, dass das abschließende Anführungszeichen der Binärdaten im Original fehlt.

select hex(packet_key) from panels where id=1003;
--> DE77CF5C075CE002C596176556AAF9ED

Die Spalte enthält binäre Daten:

CREATE TABLE `panels` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `enabled` tinyint(1) NOT NULL DEFAULT '1',
  `serial_number` int(10) unsigned NOT NULL,
  `panel_types_id` int(11) NOT NULL,
  `all_panels_id` int(11) NOT NULL,
  `installers_id` int(11) DEFAULT NULL,
  `users_id` int(11) DEFAULT NULL,
  `packet_key` binary(16) NOT NULL,
  `user_deleted` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  ...

Also nein, Sie können mysqldump nicht nur nicht unbedingt vertrauen, Sie können sich nicht einmal darauf verlassen, dass es einen Fehler meldet, wenn einer auftritt.

Eine hässliche Problemumgehung, die ich verwendete, bestand darin, mysqldump die beiden betroffenen Tabellen auszuschließen, indem ich Optionen wie diese zum Dump hinzufügte:

--ignore-table=myalarm.panels 

Dann dieser BASH-Skript-Hack. Führen Sie im Grunde ein SELECT aus, das INSERT-Werte erzeugt, bei denen die NULL-Spalten behandelt werden und die binäre Spalte wie folgt in einen UNHEX()-Aufruf umgewandelt wird:

(123,45678,UNHEX("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"),"2014-03-17 00:00:00",NULL),

Fügen Sie es in den Editor Ihrer Wahl ein, um bei Bedarf damit zu spielen.

echo "SET UNIQUE_CHECKS=0;SET FOREIGN_KEY_CHECKS=0;DELETE FROM panels;INSERT INTO panels VALUES " > all.sql
mysql -uroot -p"PASSWORD" databasename -e "SELECT CONCAT('(',id,',', enabled,',', serial_number,',', panel_types_id,',', all_panels_id,',', IFNULL(CONVERT(installers_id,CHAR(20)),'NULL'),',', IFNULL(CONVERT(users_id,CHAR(20)),'NULL'), ',UNHEX(\"',HEX(packet_key),'\"),', IF(ISNULL(user_deleted),'NULL',CONCAT('\"', user_deleted,'\"')),'),') FROM panels" >> all.sql
echo "SET UNIQUE_CHECKS=1;SET FOREIGN_KEY_CHECKS=1;" > all.sql

Das gibt mir eine Datei namens "all.sql", bei der das letzte Komma im INSERT in ein Semikolon umgewandelt werden muss, dann kann es wie oben ausgeführt werden. Ich brauchte die Optimierungen für den „großen Importpuffer“, die sowohl in der interaktiven MySQL-Shell als auch in der Befehlszeile eingestellt waren, um diese Datei zu verarbeiten, weil sie groß ist.

mysql ... --max_allowed_packet=1GB

Als ich den Fehler gemeldet habe, wurde ich schließlich auf das Flag "--hex-blob" verwiesen, das dasselbe tut wie mein Workaround, aber von meiner Seite aus trivial. Fügen Sie diese Option hinzu, Blobs werden als Hex ausgegeben, das Ende.