Mysql
 sql >> Database >  >> RDS >> Mysql

mysqldump gestisce i dati binari in modo affidabile?

No, non è sempre affidabile quando hai BLOB binari. In tal caso DEVI usare "--hex-blob " flag per ottenere risultati corretti.

Avvertimento dal commento qui sotto:

Ho un caso in cui queste chiamate non riescono (importazione su un server diverso ma entrambi eseguono 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

Produce un file che non riesce a importare silenziosamente. L'aggiunta di "--skip-extended-insert" mi dà un file molto più facile da eseguire il debug e trovo che questa riga sia generata ma non può essere letta (ma non viene segnalato alcun errore né durante l'esportazione né nell'importazione):

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

Nota che la virgoletta di chiusura sui dati binari non è presente nell'originale.

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

La colonna è di dati binari:

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

Quindi no, non solo non puoi necessariamente fidarti di mysqldump, ma non puoi nemmeno fare affidamento su di esso per segnalare un errore quando si verifica.

Una brutta soluzione che ho usato è stata mysqldump escludendo le due tabelle afflitte aggiungendo opzioni come questa al dump:

--ignore-table=myalarm.panels 

Quindi questo hack di script BASH. Fondamentalmente esegui un SELECT che produce valori INSERT in cui vengono gestite le colonne NULL e la colonna binaria viene trasformata in una chiamata UNHEX() in questo modo:

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

Incollalo nel tuo editor preferito per giocarci se necessario.

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

Questo mi dà un file chiamato "all.sql" che ha bisogno della virgola finale in INSERT trasformata in un punto e virgola, quindi può essere eseguito come sopra. Avevo bisogno delle modifiche del "buffer di importazione di grandi dimensioni" impostate sia nella shell mysql interattiva che nella riga di comando per elaborare quel file perché è grande.

mysql ... --max_allowed_packet=1GB

Quando ho segnalato il bug, alla fine sono stato puntato sul flag "--hex-blob", che fa lo stesso della mia soluzione alternativa ma in modo banale dal mio lato. Aggiungi questa opzione, i blob vengono scaricati come esadecimali, la fine.