微信号:gh_34977e8f8c68

介绍:私有云数据库平台的分享!

Atlas支持mysql的prepare特性吗

2016-07-23 00:32 yufulong


众所周知,大家很喜欢用prepare语句来防SQL注入,在我们这里也是如此,但是在使用中,会经常有业务同学反馈说我们的数据库中间层atlas不支持prepare语句,这是真的吗?

1问题介绍

某业务使用了新的PHP 框架——laravel,在预上线某脚本执行时报错,如下:


2问题解决办法


   第一眼看到上面报错,我想第一反应肯定是说,卧槽:麻痹的,atlas不支持,可明明:http://blog.csdn.net/jhq0113/article/details/44239823 专家访谈说atlas支持prepare啊,这不逗我们玩么?我觉得有必要这里说明一下,因为开发砖家们都说,prepare是防注入的,很牛逼的咧。



在文章里,作者是这么问答的:

9.Atlas支持mysql的prepare特性吗?

目前Atlas部分支持prepare功能,支持Java,Python,PHP(PDO方式)。

其实上面说的并没有错,这里我们已PHP为例


1
PDO介绍: 

PHP 数据对象 (PDO 扩展为PHP访问数据库定义了一个轻量级的一致接口。实现 PDO 接口的每个数据库驱动可以公开具体数据库的特性作为标准扩展功能。 注意利用 PDO 扩展自身并不能实现任何数据库功能;必须使用一个 http://php.net/manual/zh/pdo.drivers.php 来访问数据库服务。

2


关于prepare的PDO的属性:( http://php.net/manual/zh/pdo.setattribute.php有介绍)

 PDO::ATTR_EMULATE_PREPARES 启用或禁用预处理语句的模拟。 有些驱动不支持或有限度地支持本地预处理。使用此设置强制PDO总是模拟预处理语句(如果为 TRUE ),或试着使用本地预处理语句(如果为 FALSE)。


这里就很清晰了,PDO是通过ATTR_EMULATE_PREPARES  来启用或者禁用预处理语句的模拟的,也就是说,当我们的PDO::ATTR_EMULATE_PREPARES=>True,pdo模拟预处理语句,模拟完毕,传到atlas就是正常的SQL语句了,而PDO::ATTR_EMULATE_PREPARES=>false,他会试着提交mysql原生的prepare语句到atlas,这种情况在开源的atlas确实是不支持的。


这里查了一下laravel 框架,默认关闭了ATTR_EMULATE_PREPARES选项!!!


所以,就会报如上错误,在实际的工作经验中,发现,当PDO::ATTR_EMULATE_PREPARES=>false,老版本的atlas读写分离其实也是有问题的,写入sql会经常被路由到mysql从库上,造成业务的错误;

当然为了满足大神们的各种口味,在线上的最新版本atlas是支持的,不过由于处理的复杂性,以及上下文必须在同一个连接里等问题,对于prepare,我们只是让它强制在主库进行操作,性能会很一般,所以在有atlas(或者其他中间层的场景中)我们还是建议PDO::ATTR_EMULATE_PREPARES=>True 让PDO模拟预处理。

此文为某业务技术leader所写,献给使用atlas的各位爷们~~


更多精彩请戳历史文章


 
dba流浪猫 更多文章 抓包,只为让DBA过的更开心 MySQL for update 死锁案例 pt-osc改表导致数据不一致案例分析 为什么redis内存不宜过大 greenplum导入数据的几种方法
猜您喜欢 传统低端运维跟高大上自动化运维的区别 这才是程序员想neng死产品经理的真正原因!! 常用Git命令清单 Android 为什么选择了Java Sublime Text 2 跨平台支持Win/Mac/Linux