linux下大文件编码转码及将oracle中数据导入mysql

来源:互联网 发布:淘宝联盟导购推广微信 编辑:程序博客网 时间:2024/06/08 14:37

        这篇文章有不少废话,只是为了发泄一下。如果读者找需要解决的问题的办法,直接无视这些废话。    

        本文章为原创,转载文章请注明出处:   http://blog.csdn.net/tianxiagongzheng/article/details/71812876

        最近做的项目要将Oracle中数据导入Mysql, 数据量约有两千万条,庆幸的是只有一张表,而且数据结构比较简单。在这个过程中遇到不少坑,现在一 一记录下来。

        首先说一下Mysql的环境是 Centos 7, Oracle是Windows系统下的。

        第一,第二次倒腾的时候,我将Oralcle表中的数据以100万条为单位,导入到20个csv文件中,每个文件有60M上下,导出的csv文件是默认的编码格式,但是具体是什么编码格式不知道,反正不是你自以为的gbk,gb2312,这为后面一次性导出导入一个大文件的悲剧埋下了伏笔。

       为了先测试导入Mysql的效果,我先建一个2M的文件test.csv。在linux下打开测试文件,一堆乱码。然后我在Windows下用notepad++将每一个文件先转码成utf-8的无bom格式,然后传到linux下,进入Mysql,挨个用load data命令执行导入csv文件。刚开始的时候容易遇到 ERROR 1290 (HY000),解决办法见我的另一篇博客http://blog.csdn.net/tianxiagongzheng/article/details/71037734  。用load data是我在选了3种方法,各种出错,和浪费无数时间后,找到的第四种方法,这简直是棵救命稻草,速度足够快。

        第三次倒腾的时候,我直接用了导出了一个1G多的csv文件,直接在linux下用vim打开当然还是乱码,需要转成utf-8编码格式。可是notepad++不能打开直接打开这么大的文件,于是开始了我的艰难的转码过程。

        如果知道文件的编码格式当然容易转码,再次强调一下,这不是gbk, gb2312 格式,在linux下执行file命令,得到如下信息:   Non-ISO extended-ASCII text, with very long lines, with CRLF, NEL line terminators。

在网上搜索,终于找到一篇靠谱的博客:

http://blog.csdn.net/niityzu/article/details/42494477 ,这篇文章的关键是:

  1. $ iconv --list | sed 's/\/\/$//' | sort > encodings.list  
  2. $ for a in `cat encodings.list`; do  
  3.   printf "$a  "  
  4.   iconv -f $a -t UTF-8 systeminfo.txt > /dev/null 2>&1 \&& echo "ok: $a" || echo "fail: $a"  
  5. done | tee result.txt  

注意systeminfo.txt 是你自己要转码的文件。

悲催的是,我没有那么幸运能直接找到正确的编码。

由于我的文件很大,先建了一个只有1000条记录的文件,没有起作用。于是我又建了一个大概2M的temp.csv文件,执行后,result.txt中居然有好多ok,我去.........

这是逼我发飙啊。

于是我将上面的代码放到了一个脚本中,如下:

 for a in `cat encodings.list`; do
  printf "$a  "
  iconv -f $a -t UTF-8  temp.csv > /home/myfile/$a.txt  && echo "ok: $a" || echo "fail: $a"  
done | tee result.txt


要知道共有一千一百多个编码啊,生成了一千一百多个文件(这一千一百多个文件的文件名就是生成文件的编码格式)。看了一下result.txt文件中,依然是有好多ok。

于是用find 命令 在这一千一百多个文件中查找某个 中文 字符串,比如temp.csv中有 “你好吗”,我就查找“你好吗”三个字,谢天谢地,只有11个文件有这三个字。好了,我用这11一个编码格式挨个对我的1个多G的文件进行编码转换:

iconv -f xxx编码 -t UTF-8 my_1G.csv >my_1G.csv  

这11个编码格式快试完了,依然都是出错,我近乎绝望的时候,奇迹发生了,居然成了,这个格式是GB18030, 

有心人,终不负。。。终于成了。我长长长的舒了口气。

你以为可以在Mysql中直接用load data命令导入了,NO, NO ...老天折磨人的恶趣味永远都没有停止的时候。

在执行load data 的时候,出现了如下错误:

ERROR 29 (HY000): File '/var/lib/mysql-files/my_1G.csv' not found (Errcode: 13 - Permission denied)

尼玛。。。

还是网上搜索,有:http://www.linuxidc.com/Linux/2012-02/55533.htm, 

摘抄如下 # setsebool -P mysqld_disable_trans=1  

Ubuntu下 ,可以对AppArmor(/etc/apparmor.d/usr.sbin.mysqld) 修改,类似selinux。  添加/etc/squid/lists/eighties.txt w,类似。  

重启Mysql,没有作用。

再次绝望, 这个坑再次折磨了我很久。

我不死心,将以前的100万条的小文件执行了load data 命令,没有问题,这说明不是Mysql 的问题。

无奈之下。我将 my_1G.csv 按照每百万行一个文件进行了分割,然后对分割后的第一个文件xaa执行load data,居然成功了。。。。

于是我灵感来了,用cp命令将  my_1G.csv 复制了一份 ,对复制后的文件my_1G_new.csv执行load data,终于不再报ERROR 29 (HY000)了,

于是静静加忐忑地等待,在5分多钟后,终于报执行成功了。。。。。。

皇天不负有心人,有心人,终不负。。。。。。。。

这次的磨难终于结束了。




       


0 0
原创粉丝点击