一条Select语句引发的反思

最近在写一个数据转储的程序,功能是从源数据库读取数据、对数据加工、插入到指定数据库。采用的方式是调用mysql -e 将查询的结果重定向到指定文件。

eg: mysql -hxxx -uxxx -pxxx DatabaseName -e "select * from t_test;" > test

测试过程中:

  • 源数据库的数据量少:

    程序正常运行,没有任何异常

  • 源数据库的数据量大(21G,2亿+条)

    因为在程序中直接调用mysql 来执行,在使用top命令对程序使用的内存进行监控的时候,发现15S,mysql的内存占用量已经达到50%(4核,8G机器)

分析原因:

  • 测试mysqldump命令的内存和CPU占用量

    cpu的占用率为50%左右,内存始终维持在0.1

    • 为什么不用mysqldump命令?

    因为不合适,这里的使用场景之一是将源数据库的指定列都读取出来,加工,插入到目标数据库。mysqldump主要的使用场景是对数据库的复制。

  • mysql命令行直连mysql server测试

    内存升的更快,内存在5S的时候就升到了40%

终极大招——Google+Stackoverflow

  • 烟雾弹

    由于笔者读东西一直是一目十行的,所以在查到https://bugs.mysql.com/bug.php?id=77403这个mysql的bug后就查了下产品预发布和线上的MySQL的版本,哈哈,居然都是5.6(小版本忽略),于是很高兴的跟老板说,这个问题是MySQL的bug。

    老板用来2秒钟大致看了下文档,告诉我这个跟我的问题不一样,解释下这个mysql的bug是有人发现5.5的MySQL升级到5.6.25后发现MySQL Server 的内存使用量暴增,而我的是客户端的内存 使用量暴增。感觉差点想要找一个地缝钻进去,唉,做人还是要认真!!!

  • 正解

    • mysql [options] database

    options中有个–quick的选项,详细解释如下:


    -q, --quick Don't cache result, print it row by row. This may slow
    down the server if the output is suspended. Doesn't use
    history file.

    你以为这就结束了是不是,不,知其然还要知其所以然!

myql –quick命令介绍

以下这部分英语是直接摘自MySQL的英文帮助文档,笔者翻译水平有限,怕翻译有误,所以直接摘录过来。


Out of memory

If you issue a query using the mysql client program and receive an error like the following one, it means that mysql does not have enough memory to store the entire query result:

mysql: Out of memory at line 42, 'malloc.c'
mysql: needed 8136 byte (8k), memory in use: 12481367 bytes (12189k)
ERROR 2008: MySQL client ran out of memory

To remedy the problem, first check whether your query is correct. Is it reasonable that it should return so many rows? If not, correct the query and try again. Otherwise, you can invoke mysql with the --quick option. This causes it to use the mysql_use_result() C API function to retrieve the result set, which places less of a load on the client (but more on the server).


归根节点就是在使用–quick的选项后,会强制调用mysql_use_result() 的函数,我的理解是客户端不会缓存MySQL返回的结果而是直接打印出来,这样就不会撑爆内存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值