<div class="show-content-free"> <h2>一. 场景</h2> <blockquote> <p>现有俩个体积较大的单表sql文件,一个为8G,一个为4G,要在一天内完整导入到阿里云的mysql中,须要同时蛮子时间和空间这俩种要求。</p> </blockquote> <h2>二. 思路</h2> <blockquote> <p>搜索了网上一堆的方案,总结了以下几个:<br> 方案一:利用navicat远程导入<br> 方案二:在阿里云ECS安装一个mysql-client,用source方案导入<br> 方案三:购买阿里云DBMS高级版服务,能够导入1G之内ZIP压缩包</p> </blockquote> <h2>三. 尝试</h2> <p>折腾了许久的尝试,终于总结了一下的经验:</p> <h3>3.1 尝试navicat远程导入</h3> <blockquote> <p>操做简单,可是缺点很明显:导入效率低,严重占用本地的IO,影响机器的正常工做,因此立马放弃。</p> </blockquote> <h3>3.2 尝试source方案</h3> <h4>3.2.1 实现步骤</h4> <blockquote> <p><strong>STEP1</strong> 在测试环境的ECS上安装一个mysql-client<br> <strong>STEP2</strong> 修改mysql中的<strong>max_allowed_packet</strong>参数为<strong>10G</strong>大小,<strong>net_buffer_length</strong>参数也根据需求适度调大。<br> <strong>STEP3</strong> 由于是俩个表,写俩个脚本太麻烦了,能够利用一个sql脚本聚合实现,因此all.sql 的内容能够以下</p> </blockquote> <pre class="hljs bash"><code class="bash hljs"><span class="hljs-built_in"><span class="hljs-built_in">source</span></span> /mydata/sql/a.sql; <span class="hljs-built_in"><span class="hljs-built_in">source</span></span> /mydata/sql/b.sql; </code></pre> <blockquote> <p><strong>STEP4</strong> 为避免ssh链接掉线而致使执行关闭,须要写一个shell脚本,经过nohup后台执行。<br> myshell.sh脚本以下</p> </blockquote> <pre class="hljs javascript"><code class="javascript hljs">mysql -h host -uxxx -pxxx --database=user_database<<span class="hljs-regexp"><span class="hljs-regexp">/mydata/</span></span>sql/all.sql </code></pre> <blockquote> <p><strong>STEP5</strong> 后台执行指令</p> </blockquote> <pre class="hljs undefined"><code class="hljs nginx"><span class="hljs-attribute">nohup</span> ./myshell.sh & </code></pre> <h4>3.2.2 结果</h4> <blockquote> <p>测试速度相对快多了,可是因为次日就须要,因此俩个表接近4000w行的数据绝对不能完成任务,因此方案取消。可是不是否认该方案,其余场景确定知足。</p> </blockquote> <h3>3.3 尝试DMBS</h3> <p>因为咱们数据库是阿里云的RDS,因此咱们购买了对应的DBMS服务升级版,能够支持文件上传导入(包含1G内的ZIP)</p> <br> <div class="image-package"> <div class="image-container" style="max-width: 653px; max-height: 412px; background-color: transparent;">javascript
<div class="image-view" data-width="653" data-height="412"><img data-original-src="//upload-images.jianshu.io/upload_images/3362699-5b22590a7e292cc9.png" data-original-width="653" data-original-height="412" data-original-format="image/png" data-original-filesize="27334" class="" style="cursor: zoom-in;" src="https://img2018.cnblogs.com/blog/1112483/201908/1112483-20190822094334846-1850490909.png"></div> </div> <div class="image-caption">DBMS功能</div> </div> <h4>3.3.1 压缩文件</h4> <p>压缩单表SQL文件为单独zip文件,压缩下来一个为0.9G,一个为1.2G</p> <h4>3.3.2 拆分文件</h4> <p>第一个sql文件上传后执行很顺利,可是第二个1.2G的zip包须要进行拆分</p> <h4>3.3.3 拆分方案</h4> <p><strong>1.拆分zip压缩包</strong><br> </p><div class="image-package"> <div class="image-container" style="max-width: 460px; max-height: 440px; background-color: transparent;">css
<div class="image-view" data-width="460" data-height="440"><img data-original-src="//upload-images.jianshu.io/upload_images/3362699-7dcccb9fcf2d1029.png" data-original-width="460" data-original-height="440" data-original-format="image/png" data-original-filesize="31932" class="" style="cursor: zoom-in;" src="https://img2018.cnblogs.com/blog/1112483/201908/1112483-20190822094359883-1398213167.png"></div> </div> <div class="image-caption">压缩包拆分</div> </div><br> 拆分出来的文件,手动改后缀后不知足DBMS的文件规范,失败~<br> <strong>2.高比例压缩文件</strong><br> 利用7z高比例压缩sql为7z后缀,压缩后体积明显小了,只有0.7G的体积,而后经过更改后缀为zip来上传。结果阿里云解析不出这样的格式,失败~<br> <strong>3.使用linux split 命令</strong><p></p> <pre class="hljs css"><code class="css hljs"><span class="hljs-selector-tag"><span class="hljs-selector-tag">split</span></span> <span class="hljs-selector-attr"><span class="hljs-selector-attr">[--help]</span></span><span class="hljs-selector-attr"><span class="hljs-selector-attr">[--version]</span></span><span class="hljs-selector-attr"><span class="hljs-selector-attr">[-<行数>]</span></span><span class="hljs-selector-attr"><span class="hljs-selector-attr">[-b <字节>]</span></span><span class="hljs-selector-attr"><span class="hljs-selector-attr">[-C <字节>]</span></span><span class="hljs-selector-attr"><span class="hljs-selector-attr">[-l <行数>]</span></span><span class="hljs-selector-attr"><span class="hljs-selector-attr">[要切割的文件]</span></span><span class="hljs-selector-attr"><span class="hljs-selector-attr">[输出文件名]</span></span> </code></pre> <blockquote> <p>补充说明:<br> split可将文件切成较小的文件,预设每1000行会切成一个小文件。<br> -<行数>或-l<行数> 指定每多少行就要切成一个小文件。<br> -b<字节> 指定每多少字就要切成一个小文件。支持单位:m,k<br> -C<字节> 与-b参数相似,但切割时尽可能维持每行的完整性。</p> </blockquote> <p>虽然linux能够根据行拆分文件(这也是阿里云工单提供的解决方案),可是这个操做上传上去拆分,在下载下来上传到DBMS,文件体积这么大,来来回回一天过去了,因此放弃~<br> <strong>4.拆分单表sql文件为多份</strong><br> 网上有个SQLDumpSplitter的工具能够拆分表为多份,可是搜索记录中和文章中都是推荐SQLDumpSplitter2的版本,版本太老了,体积较大的sql彻底不支持,失败~<br> 可是!我在SQLDumpSplitter2里面看到了软件的官网,发现官网有SQLDumpSplitter3版本,不抱但愿的尝试了一下,竟然支持大致积文件。成功了!!!<br> 附带下载连接:<a href="https://links.jianshu.com/go?to=https%3A%2F%2Fphiliplb.de%2Fsqldumpsplitter3%2F" target="_blank">https://philiplb.de/sqldumpsplitter3/</a> 太值得推广了。<br> </p><div class="image-package"> <div class="image-container" style="max-width: 455px; max-height: 274px; background-color: transparent;">java
<div class="image-view" data-width="455" data-height="274"><img data-original-src="//upload-images.jianshu.io/upload_images/3362699-f7d2f4e1b5aa07e0.png" data-original-width="455" data-original-height="274" data-original-format="image/png" data-original-filesize="24174" class="" style="cursor: zoom-in;" src="https://img2018.cnblogs.com/blog/1112483/201908/1112483-20190822094425842-452379798.png"></div> </div> <div class="image-caption">SQLDumpSplitter3</div> </div><br> <div class="image-package"> <div class="image-container" style="max-width: 700px; max-height: 480px; background-color: transparent;">mysql
<div class="image-view" data-width="1176" data-height="480"><img data-original-src="//upload-images.jianshu.io/upload_images/3362699-00e675ab7893cae9.png" data-original-width="1176" data-original-height="480" data-original-format="image/png" data-original-filesize="66057" class="" style="cursor: zoom-in;" src="https://img2018.cnblogs.com/blog/1112483/201908/1112483-20190822094448944-973299596.png"></div> </div> <div class="image-caption">拆分结果</div> </div><br> 剩下就是按序上传对应文件便可完成,不得不得夸阿里云这方面作得真的好!<br> <div class="image-package"> <div class="image-container" style="max-width: 700px; max-height: 341px; background-color: transparent;">linux
<div class="image-view" data-width="1567" data-height="341"><img data-original-src="//upload-images.jianshu.io/upload_images/3362699-88b55f7b7382681c.png" data-original-width="1567" data-original-height="341" data-original-format="image/png" data-original-filesize="50643" class="" style="cursor: zoom-in;" src="https://img2018.cnblogs.com/blog/1112483/201908/1112483-20190822094513410-1506194439.png"></div> </div> <div class="image-caption">多任务执行</div> </div><br> 执行效率上面来讲,也是可圈可点的:<br> <div class="image-package"> <div class="image-container" style="max-width: 694px; max-height: 125px; background-color: transparent;">nginx
<div class="image-view" data-width="694" data-height="125"><img data-original-src="//upload-images.jianshu.io/upload_images/3362699-f96b475f702914ce.png" data-original-width="694" data-original-height="125" data-original-format="image/png" data-original-filesize="16884" class="" style="cursor: zoom-in;" src="https://img2018.cnblogs.com/blog/1112483/201908/1112483-20190822094536752-1873678646.png"></div> </div> <div class="image-caption">切片入库的效率</div> </div><p></p> <h2>四. 总结</h2> <blockquote> <p><strong>今天针对这个需求,我首先查询了网上的大致方案,而后挑选了几个可执行的方案进行测试。排除了多个方案的状况下,采用了第三方的解决方案来完成这个问题。在阿里云DBMS的支持下,咱们又尝试了多种文件的切割方案,最后经过SQLDumpSplitter3+DBMS来实现了,而且效率可观。过程当中也发现,经常使用的client-source方案能够知足自建mysql+效率要求不是极致的场景。<br> 综上,对于大型sql,最好的方案也是先切割(确保顺序性),而后利用一些更高效率的软件执行来实现最终结果,也须要根据时间空间场景灵活选用方案。</strong></p> </blockquote> 原文地址:https://www.jianshu.com/p/968fa5963d07 </div>sql