Mysql
 sql >> Base de données >  >> RDS >> Mysql

mysqldump gère-t-il les données binaires de manière fiable ?

Non, ce n'est pas toujours fiable lorsque vous avez des blobs binaires. Dans ce cas, vous DEVEZ utiliser le "--hex-blob " drapeau pour obtenir des résultats corrects.

Mise en garde du commentaire ci-dessous :

J'ai un cas où ces appels échouent (importation sur un serveur différent mais exécutant 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

Il produit un fichier dont l'importation échoue silencieusement. L'ajout de "--skip-extended-insert" me donne un fichier beaucoup plus facile à déboguer, et je trouve que cette ligne est générée mais ne peut pas être lue (mais aucune erreur n'est signalée lors de l'exportation ou de l'importation) :

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

Notez que le guillemet de fin sur les données binaires est manquant dans l'original.

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

La colonne contient des données binaires :

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`),
  ...

Donc non, non seulement vous ne pouvez pas nécessairement faire confiance à mysqldump, mais vous ne pouvez même pas compter sur lui pour signaler une erreur lorsqu'elle se produit.

Une solution de contournement laide que j'ai utilisée consistait à exclure mysqldump des deux tables affectées en ajoutant des options comme celle-ci au vidage :

--ignore-table=myalarm.panels 

Ensuite, ce hack de script BASH. En gros, exécutez un SELECT qui produit des valeurs INSERT où les colonnes NULL sont gérées et la colonne binaire est transformée en un appel UNHEX() comme ceci :

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

Collez-le dans l'éditeur de votre choix pour jouer avec si nécessaire.

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

Cela me donne un fichier appelé "all.sql" qui a besoin de la virgule finale dans l'INSERT transformé en point-virgule, puis il peut être exécuté comme ci-dessus. J'avais besoin des réglages "large import buffer" définis à la fois dans le shell mysql interactif et dans la ligne de commande pour traiter ce fichier car il est volumineux.

mysql ... --max_allowed_packet=1GB

Lorsque j'ai signalé le bogue, j'ai finalement été pointé vers le drapeau "--hex-blob", qui fait la même chose que ma solution de contournement, mais de manière triviale de mon côté. Ajoutez cette option, les blobs sont vidés en hexadécimal, la fin.