sql >> Database >  >> RDS >> Mysql

Verwerkt mysqldump binaire gegevens betrouwbaar?

Nee, het is niet altijd betrouwbaar als je binaire blobs hebt. In dat geval MOET u de "--hex-blob . gebruiken " vlag om correcte resultaten te krijgen.

Voorbehoud van commentaar hieronder:

Ik heb een geval waarin deze oproepen mislukken (importeren op een andere server maar beide met 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

Het produceert een bestand dat geruisloos niet kan worden geïmporteerd. Door "--skip-extended-insert" toe te voegen, krijg ik een bestand dat veel gemakkelijker te debuggen is, en ik merk dat deze regel wordt gegenereerd maar niet kan worden gelezen (maar er wordt geen fout gemeld bij het exporteren of importeren):

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

Merk op dat het afsluitende aanhalingsteken op de binaire gegevens in het origineel ontbreekt.

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

De kolom is binaire data:

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

Dus nee, niet alleen kunt u mysqldump niet per se vertrouwen, u kunt er zelfs niet op vertrouwen om een ​​fout te melden wanneer deze zich voordoet.

Een lelijke oplossing die ik gebruikte was om mysqldump de twee getroffen tabellen uit te sluiten door opties zoals deze aan de dump toe te voegen:

--ignore-table=myalarm.panels 

Dan deze BASH-scripthack. Voer in principe een SELECT uit die INSERT-waarden produceert waarbij de NULL-kolommen worden verwerkt en de binaire kolom wordt omgezet in een UNHEX()-aanroep zoals:

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

Plak het in je editor naar keuze om ermee te spelen als dat nodig is.

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

Dat geeft me een bestand met de naam "all.sql" waarvan de laatste komma in de INSERT moet worden omgezet in een puntkomma, waarna het kan worden uitgevoerd zoals hierboven. Ik had de "grote importbuffer"-tweaks nodig die zijn ingesteld in zowel de interactieve mysql-shell als de opdrachtregel om dat bestand te verwerken omdat het groot is.

mysql ... --max_allowed_packet=1GB

Toen ik de bug meldde, werd ik uiteindelijk gewezen op de vlag "--hex-blob", die hetzelfde doet als mijn tijdelijke oplossing, maar op een triviale manier van mijn kant. Voeg die optie toe, blobs worden gedumpt als hex, het einde.



  1. Achterliggende lege ruimte in een veldinhoud verwijderen

  2. Een één-op-één-relatie definiëren in SQL Server

  3. Oracle - Waarom verdwijnt de voorloopnul van een getal bij het converteren naar TO_CHAR

  4. PHP SQL:hoe u gegevens vanuit één html-formulier naar meerdere databases kunt opslaan OF hoe u automatisch gegevens van de ene database naar een andere database kopieert