prepare的设计与实现

    prepare

    gaea在接到preprae请求后,首先计算参数个数、参数偏移位置和stmt-id。然后根据以上数据,构造statement对象并保存在SessionExecutor的stmts内,stmts为一个map,key为stmt-id,value即为构造的statement对象。

    prepare阶段主要是计算、保存execute需要使用的变量信息,prepare应答数据内也会包含这些变量信息。

    execute请求时会携带prepare应答返回的stmt-id,服务端根据stmt-id从SessionExecutor的stmts中查询对应的statement信息。根据statement信息的参数个数、偏移和execute上传的参数值,进行关联绑定,然后rewrite一条同等含义的sql。同时,为了安全性考虑,也会进行特殊字符过滤,防止比如sql注入的发生。

    处理完成之后,需要进行文本应答协议到二进制应答协议的转换,相关实现在BuildBinaryResultset内。

    execute执行完成之后,执行ResetParams,重新初始化send_long_data对应的args字段,病返回应答。

    send_long_data

    send_long_data不是必须的,但是如果execute有多个参数,且不止一个参数长度比较大,一次execute可能达到mysql max-payload-length,但是如果分多次,每次只发送一个,这样就绕过了max-payload-length,send_long_data就是基于这样的背景产生的。

    send_long_data不需要应答。

    close的处理逻辑比较简单,服务端收到close请求后,删除prepare阶段stmt-id及其数据的对应关系。

    总结

    gaea对于prepare的处理初衷还是考虑协议的兼容和简化处理逻辑,对于client->proxy->mysql这样接口来说,client->proxy是prepare协议,proxy->mysql是文本协议,所以整体来看在gaea环境下使用prepare性能提升有限,还是建议直接使用sql。