高效导出远程服务器上的Mysql数据

[文章作者:磨延城 转载请注明原文出处: http://notes.mo2g.com/database/mysql/export-data/ ]

mysql 通过命令行导出数据,网上已经有很多的示例了,之所以写这篇笔记,第一是为了记录特定场景的解决方案,第二也许能帮助到其他人。

导出远程 mysql 数据库的某一张表数据到本地

出于安全考虑,mysql 默认的 3306 端口只开放给内网使用的,外网无法直连,再有网上的教程大部分都是以直连的方式导数据,所以很多人只会通过以下步骤来操作:

  1. 登录 mysql 服务器
  2. 通过命令行导出数据文件 xxx.sql.gz,保存在 mysql 服务器的磁盘上
  3. 下载 mysql 服务器磁盘上的 xxx.sql.gz
  4. 本地命令行操作

并不是说这种方式不好,只是在某些场景下有些尴尬。我举个例子说明。

我手上有个系统,一张主表就独占了 2TB 的磁盘空间大小,导出的 xxx.sql.gz 文件需要预留更多的磁盘空间来存储,存储成本就上去了,所以引入了 SSH 端口转发的方案。

SSH 端口转发(SSH 隧道)

使用 SSH 隧道的端口转发特性,可以把远程服务器上的任意端口转发到本地,接下来我们就把 mysql 服务器的 3306 端口转发到本地的 13306 使用。

1
ssh -L localhost:13306:localhost:3306 username@xx.xx.xx.xx -p 22 -i ~/.ssh/key

这样我们就可以通过本地的 13306 端口操作远程的数据库了。

SSH 命令关键参数说明

1
2
3
4
5
6
-L 本机地址:本机端口:服务器地址:服务器端口
-f 后台运行
-N 不执行shell
-T 不分配TTY
-o ServerAliveInterval=60 每隔60跟服务器交互保持连接存活
-i 使用密钥

关于 SSH 隧道的稳定性

SSH 隧道会被网络质量影响变得不稳定,所以在网络不稳定的环境中使用需要改用 autossh 这类工具来实现断线重连。

感觉这又是另一个话题,我们先点到为止,以后有机会再细聊。

1
autossh -N -L localhost:13306:127.0.0.1:3306 username@xx.xx.xx.xx -p 22 -i ~/.ssh/key

mysqldump 原生导出

1
mysqldump -h 127.0.0.1 -p --no-create-info --add-drop-table=FALSE bigdata user --where="id >= 1943229" | gzip > bigdata_user_mysql.sql.gz;

mysqldump 命令关键参数说明

1
2
3
4
5
6
mysqldump -h 服务器IP -p --no-create-info --add-drop-table=FALSE 数据库 表 --where="表查询条件"
-h 服务器IP
-p 密码登陆
--no-create-info 只导出数据,不导出结构,可以配合where条件导出增量数据
--add-drop-table=FALSE 不生成删除语句
--where 查询条件

mysql 原生导入

1
gunzip < bigdata_user_mysql.sql.gz | mysql -p bigdata

由于原生的 mysql 导入导出命令基于单线程运行,无法充分使用多核优势,所以衍生了很多第三方工具,有时间可以多了解一下。

其他第三方工具推荐

maxbube 开发的mydumper/myloader,实现了多线程导出导入功能,在多核服务器上执行效率上比 mysql 原生命令要快。

Pingcap 开发的mydumper/loader,由于 myloader 缺乏出错重试、断点续传这样的功能,无法满足 TiDB 的使用场景,所以 Pingcap 公司开发了新的工具。