说明:
1.在 COM_STMT_PREPARE 阶段,DBLE 此时接收的 SQL 不完整,不能确定下发节点,但 MySQL Prepared Statement 协议要求此处返回一个 response 报文,因此 DBLE 会伪装 COM_STMT_PREPARE_OK 报文返回。若有些 MySQL 驱动(如 JDBC )想从 response 报文中获取信息,这些信息会不准确。
2.在 COM_STMT_EXECUTE 阶段,DBLE 会根据客户端传输的参数将预编译 SQL 替换为具体的 SQL,并使用 COM_QUERY 命令下发至后端节点,因为 COM_QUERY 不再使用二进制协议传输,因此 DBLE 需要对后端返回的数据进行转换后再返回客户端。
3、DBLE 不支持 COM_STMT_FETCH 命令。
好了,当我们了解完 MySQL 和 DBLE 对 Prepared Statement 协议实现过程后,我们再回过头来看那个两个Bug到底是怎么来的。
经过分析,在同一连接中,当发起 COM_STMT_CLOSE 销毁当前 prepare statement 后,紧接着又创建一个 prepare statement。这两个操作是在 DBLE 中是异步进行,存在线程安全的问题。知道问题的根源之后,解决方案是 DBLE 将两个操作变成同步操作,避免线程安全的问题。
#1124 Bug分析
使用JDBC时,在URL中设置 useCursorFetch=true 的参数,希望开启 MySQL Server Side 游标功能。但是要使用 MySQL Server Side 游标需要满足下面条件:
- 必须是 SELECT 语句
- 设置了 fetchSize > 0
- 设置了 useCursorFetch = true
- 数据集类型为 ResultSet.TYPE_FORWARD_ONLY
- 数据集并发设置为 ResultSet.CONCUR_READ_ONLY
- Server versions 5.0.5 or newer