1. 背景
在日常业务开发中,经常可能需要对MySQL中数据进行导出、导入,最常使用的工具便是mysqldump。mysqldump功能很丰富,可以支持导出表结构、导出整个库数据、导出指定表数据、甚至导出满足指定条件的数据到本地文件以及从一个库中将数据导入另一个库。本文不打算介绍mysqldump具体用法,网上也有很多相关介绍文档可以参考,本文中主要想介绍下mysqldump跨库导数据时存在的一个“坑”——“假死锁”现象,以及分析下该现象产生原因及解决办法,帮助大家在今后的使用过程中掉进"坑"。这里“假死锁”是我自己取得名字^-^!,之所以称之为"假"死锁,是因为其表现结果和死锁一样,两个进程都互相阻塞,但其本质并非是两个进程互相锁死了对方导致的。
2. 问题复现
mysqldump跨库导数据基本命令格式如下:
mysqldump --host=h1 -uroot -proot --databases db1 | mysql --host=h2 -uroot -proot db2
复制代码
上述命令在在跨服务器的数据库之间(h1、h2不同)导数据时没有任何问题,但是在同一个服务器的不同库之间(h1、h2相同, db1、db2不同)导数据时可能会发生死锁现象。下面先把问题重现一下,首先在本地MySQL Server中准备两个库(注意: 是同一个MySQL Server中两个不同的库)test库和test1库,其中test库中部分表信息如图1所示,test1库是个空库,不包含任何表结构和数据, 另外再有一台公有云MySQL Server中的test库,也是一个空库。
图 1: test库中表信息
首先尝试通过mysqldump将本地MySQL test库的数据导入到远程MySQL的test库中:
mysqldump -h127.0.0.1 -P3306 -uroot --databases test | mysql --host=cd-cdb-1ygx58w2.sql.tencentcdb.com -P3306 -uxxxx -p'test123!' test
复制代码
执行结果:
命令执行正常
切换至远程MySQL Server,可以看到test库中已经有相关表及数据