sql >> Databáze >  >> RDS >> Mysql

Zpracovává mysqldump binární data spolehlivě?

Ne, není to vždy spolehlivé, když máte binární bloby. V takovém případě MUSÍTE použít "--hex-blob ", abyste získali správné výsledky.

Upozornění z komentáře níže:

Mám případ, kdy tato volání selžou (import na jiný server, ale oba běží 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

Vytváří soubor, který se tiše nepodaří importovat. Přidáním "--skip-extended-insert" získám soubor, který je mnohem snazší ladit, a zjistil jsem, že tento řádek je vygenerován, ale nelze jej přečíst (ale není hlášena žádná chyba při exportu ani importu):

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

Všimněte si, že koncová uvozovka na binárních datech v originále chybí.

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

Sloupec obsahuje binární 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`),
  ...

Takže ne, nejen že nemusíte nutně důvěřovat mysqldump, ale nemůžete se ani spolehnout na to, že nahlásí chybu, když k ní dojde.

Ošklivým řešením, které jsem použil, bylo mysqldump vyloučení dvou postižených tabulek přidáním možností, jako je tato:

--ignore-table=myalarm.panels 

Pak tento hack skriptu BASH. V podstatě spusťte SELECT, který vytvoří hodnoty INSERT, kde se zpracují sloupce NULL a binární sloupec se změní na volání UNHEX() takto:

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

Vložte jej do svého editoru, abyste si s ním mohli hrát, pokud budete potřebovat.

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

To mi dává soubor nazvaný "all.sql", který potřebuje, aby se poslední čárka v INSERT změnila na středník, a pak jej lze spustit jako výše. Ke zpracování tohoto souboru jsem potřeboval „velký import buffer“ nastavený jak v interaktivním mysql shellu, tak v příkazovém řádku, protože je velký.

mysql ... --max_allowed_packet=1GB

Když jsem nahlásil chybu, byl jsem nakonec nasměrován na příznak „--hex-blob“, který funguje stejně jako moje řešení, ale je z mé strany triviální. Přidejte tuto možnost, bloby se vyhodí jako hex, konec.



  1. Jak přejmenovat databázi SQL Server pomocí T-SQL

  2. Je možné vypnout zpracování nabídek v příkazu Postgres COPY s formátem CSV?

  3. Jak vytvořit a používat dočasnou tabulku v uložené proceduře Oracle?

  4. FIND_IN_SET se dvěma řetězci