数据迁移方案之mysql自带的导入导出功能

  

  场景:数据源是一个mysql私有库,docker部署(未暴漏端口)。项目也用docker部署,使用docker自带的网络桥接模式使用数据库,外界工具无法连接。现在要做数据迁移,目标是oracle数据库。

 

  方案1:使用etl工具进行迁移。

  etl工具免费有spoon,可视化操作,支持映射关系配置。但是需要数据源库和目标库都可以远程连接。而且需要windows系统。现在数据源是不能远程连接的。。

为了使用此方案,我们可以重新给生成的mysql镜像添加主机映射端口3306,并重启使之生效。然后服务器上也开通3306供外界访问。这一套操作会比较麻烦。

  修改docker容器配置文件,文件路径如下:

    /var/lib/docker/containers/id

  配置文件config.v2.json:

"Args": [
    "mysqld"
],
"Config": {
    "Hostname": "754306b71e74",
    "Domainname": "",
    "User": "",
    "AttachStdin": false,
    "AttachStdout": false,
    "AttachStderr": false,
    "ExposedPorts": {
        "3306/tcp": {
            "HostIp": "",
            "HostPort": "3333"
        }
    }
  .......
  "Service": null,
  "Ports": {
      "3306/tcp": [
          {
              "HostIp": "0.0.0.0",
              "HostPort": "3333"
          }
      ]
  },
  "SandboxKey": "/var/run/docker/netns/99a37a9efa50"
 

  修改另一个配置文件hostconfig.json:

"PortBindings": {
    "3306/tcp": [
        {
            "HostIp": "",
            "HostPort": "3333"
        }
    ]
},
"RestartPolicy": {
    "Name": "always",
    "MaximumRetryCount": 0
}

   修改完毕,远程连接数据库运行etl中的转换即可。etl的使用方式,就自己探索吧。

 

  方案2:使用spring batch项目的形式,也使用docker网络桥接进去,读库,输出到另一个能读到的库中。需要开发,灵活,可持续迁移数据

   spring batch是一个批处理框架。迁移数据效率很高,而且在一定程度上屏蔽了数据库之间的差异。使用可视化工具迁移最痛苦的就是处理数据库之间的不同。它支持自定义chunk,支持自定义映射规则。以工作流的形式,按步骤执行数据迁移,支持多切点的时间监听,以便跟踪迁移的情况。

  spring batch是支持事务的,也支持迁移情况记录,只是需要创建几张属于batch的表。如果不想在数据源中创建这几张表,那就只能自己想办法在监听中去记录处理数据的offset了。

  但有一个不好处理的问题。当以分页的模式读取并迁移数据时,一页数据中有一条数据类型错误就会导致整个job失败(默认对错误0容忍)。但是我们无法确定这一页数据是那一条出错了。只能得到这一页的起始位置。。需要想办法确定错误数据在哪一行,最好以某种形式推送给运维人员,让他们能够处理这个数据问题,让迁移继续进行下去。

 

  方案3:将表记录输出到文件中,拷贝下载;

  命令如下:

-- 查看导出文件的位置
show global variables like '%secure%'; 
-- 导出到文件夹下
SELECT * FROM table_name
INTO OUTFILE '/var/lib/mysql-files/table_name.txt'
    FIELDS TERMINATED BY ';'
    ENCLOSED BY '"'
    LINES TERMINATED BY '\n';
-- 从容器中复制出来
docker cp mysql:/var/lib/mysql-files/table_name.txt /mnt
-- 进入到另一台数据库中
load data infile '/var/lib/mysql-files/table_name.txt' into table table_name FIELDS TERMINATED BY '|' ENCLOSED BY '"' LINES TERMINATED BY '\n';

  这一套下来,数据记录就会存在文件里。可以下载下来,导入到指定库中去。600万数据大概有2G左右,具体要看数据表字段是否很多(测试表33个字段)。

这种方式只有mysql数据库支持。如果是跨库的迁移,特别是还有映射规则,那就只能借助工具或程序了。导入导出一般只支持在全局配置的那个文件夹下进行。

 

  记录一下昨天生产数据的导出,一张表1200W数据大概有3G(字段较少)。使用load命令加载入库中,不到10分钟。另一张表570w数据,7G。使用load加载了半个多小时。

posted @ 2021-06-01 11:15  冬藏  阅读(265)  评论(0)    收藏  举报