天天看点

【原创】MySQL Proxy - read_query()

       read_query() 函数会在客户端提交每一个 query 后被调用一次,其具有一个单独的参数,即 query 包内容本身。为了访问包的内容,你必须手动解析包内容。 

例如,你能够拦截一个 query 包并将其内容打印出来,函数定义如下: 

       该例子检查了包的第一个字节以确定包中内容的类型。如果其类型为 com_query(参阅 server command constants),我们就可以从包中提取 query 信息并将其打印。提供包类型这个结构是非常重要的。对于 com_query 包,类型后的剩余内容是 query 字串的文本内容。在该例子中,没有对最终发送到 mysql 服务器的 query 和 query 列表进行任何形式的改变, 

       如果想要修改一个 query ,或者添加新的 query ,你必须将其填入 query 队列中,然后才能执行你之前放入队列中的那些 query 。如果你没有修改原始的 query 或者 队列,那么从客户端处发送来的 query 将原封不动的发送到服务器。 

当向队列中添加 query 时,你应该遵循下面的规则: 

a.插入到队列中的包必须是有效的 query 包。对于每一个包,你必须在包的第一个字节中设置包类型。如果你是再队列尾部添加的 query ,你可以将该 query 语句附加到其余包的后面。 

b.一旦你向队列中添加了 query ,该队列将被用作向服务器发送 query 的源。如果你是为了获得更多可供使用的信息而向队列中添加 query ,你同样必须将原始 query 也添加到队列中,否则原始的 query 将得不到执行。 

c.一旦队列被填入了内容,你必须设置 read_query() 的返回值以表明 query 队列是否应该被发送到服务器。 

d.当你向队列中添加 query 时,你应该同时添加一个 id 。你指定的这个 id 会伴随结果集返回回来,故你可以通过它将每一个 query 和相应的结果集对应起来。该 id 除了作为关联 query 和结果集的标识符为没有其他用途。当运行于被动模式时,例如在 profiling 中,你可以标示出相应的原始 query 和相应的结果集,故客户端能够获取到所期望的结果集。 

       除非你的客户端设计成能够处理返回结果集数量多于原始 query 数量,你应该确保来自客户端的 query 的数量和返回给客户端的结果集数量是相同的。通过使用唯一的 id ,然后移除你自己插入的 query 对应的结果集将会满足上述功能。 

       通常来讲,read_query() 函数和 read_query_result() 函数会在一起配合使用,以提供注入额外 query 和移除额外结果集的功能。然而,read_query_result() 函数只有在你在 read_query() 函数内向 query 队列中填入了 query 的前提下才会被调用。

继续阅读