mysql - mysqldump 是否可靠地处理二进制数据?

标签 mysql mysqldump binary-data

我在 MySQL 5.6 中有一些表,在某些字段中包含大量二进制数据。我想知道我是否可以信任由 mysqldump 创建的转储,并确保在通过 FTP、SCP 等系统传输转储文件时不会轻易损坏这些二进制字段。另外,我是否应该强制此类系统将转储文件视为二进制传输而不是 ascii?

提前感谢您的任何评论!

最佳答案

不,当你有二进制 blob 时,它并不总是可靠的。在这种情况下,您必须使用“--hex-blob”标志来获得正确的结果。

注意以下评论:

If you combine the --hex-blob with the -T flag (file per table) then the hex-blob flag will be ignored, silently

我遇到过这些调用失败的情况(在不同的服务器上导入但都运行 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

它生成一个无法导入的文件。添加“--skip-extended-insert”给了我一个更容易调试的文件,我发现生成了这一行但无法读取(但无论是导出还是导入都没有报告错误):

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

请注意,原始数据中缺少二进制数据的终止引号。

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

该列是二进制数据:

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

所以不,你不仅不一定信任 mysqldump,你甚至不能依赖它在发生错误时报告错误。


我使用的一个丑陋的解决方法是通过向转储添加这样的选项来排除两个受影响的表的 mysqldump:

--ignore-table=myalarm.panels 

然后这个 BASH 脚本 hack。基本上运行一个 SELECT 生成 INSERT 值,其中处理 NULL 列并将二进制列转换为 UNHEX() 调用,如下所示:

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

如果需要,将其粘贴到您选择的编辑器中以使用它。

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

这给了我一个名为“all.sql”的文件,它需要 INSERT 中的最后一个逗号变成分号,然后它可以像上面那样运行。我需要在交互式 mysql shell 和命令行中设置“大导入缓冲区”调整来处理该文件,因为它很大。

mysql ... --max_allowed_packet=1GB

当我报告这个错误时,我最终被指向了“--hex-blob”标志,它与我的解决方法相同,但从我的角度来看是微不足道的。添加该选项,blob 将转储为十六进制,结束。

关于mysql - mysqldump 是否可靠地处理二进制数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16559086/

相关文章:

php - 使用 CodeIgniter 从 MySQL 数据库检索图像,而不使用上传库。是否可以?

MySQL:如何用这一记录之前的值更新字段

mysqldump 备份和恢复到远程服务器

c# - 将从网络服务接收到的二进制图像数据转换为 byte[]

java - 直接从 Windows 剪贴板获取二进制数据

Java tomcat 应用程序显示许多客户端连接到 MySql DB

php - 如何从两个表中获取结果? (MySQLi)

mysql - ExpressionEngine->要备份哪些表?

mysql - 有没有一种方便的方法可以在我的 git 提交中包含一个 mysqldump?

node.js - 将 Binary.toString ('encode64' ) 转换回二进制