MXS-852: Store prepared statement handles in RWBackend
The readwritesplit Backend implementation maps the returned PS handles to session command identifiers. This allows the handles to be retrieven later on when the prepared statements are executed.
This commit is contained in:
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include <maxscale/dcb.h>
|
#include <maxscale/dcb.h>
|
||||||
#include <maxscale/hashtable.h>
|
#include <maxscale/hashtable.h>
|
||||||
|
#include <maxscale/log_manager.h>
|
||||||
#include <maxscale/router.h>
|
#include <maxscale/router.h>
|
||||||
#include <maxscale/service.h>
|
#include <maxscale/service.h>
|
||||||
#include <maxscale/backend.hh>
|
#include <maxscale/backend.hh>
|
||||||
@ -117,8 +118,8 @@ enum ld_state
|
|||||||
(SERVER_IS_SLAVE((b)->backend_server) ? BE_SLAVE : BE_UNDEFINED));
|
(SERVER_IS_SLAVE((b)->backend_server) ? BE_SLAVE : BE_UNDEFINED));
|
||||||
|
|
||||||
/** Reply state change debug logging */
|
/** Reply state change debug logging */
|
||||||
#define LOG_RS(a, b) MXS_DEBUG("[%s]:%d %s -> %s", (a)->server()->name, \
|
#define LOG_RS(a, b) MXS_INFO("%s %s -> %s", (a)->uri(), \
|
||||||
(a)->server()->port, rstostr((a)->get_reply_state()), rstostr(b));
|
rstostr((a)->get_reply_state()), rstostr(b));
|
||||||
|
|
||||||
struct ROUTER_INSTANCE;
|
struct ROUTER_INSTANCE;
|
||||||
struct ROUTER_CLIENT_SES;
|
struct ROUTER_CLIENT_SES;
|
||||||
@ -153,6 +154,8 @@ struct rwsplit_config_t
|
|||||||
* been idle for too long */
|
* been idle for too long */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef std::map<uint64_t, uint32_t> HandleMap;
|
||||||
|
|
||||||
class RWBackend: public mxs::Backend
|
class RWBackend: public mxs::Backend
|
||||||
{
|
{
|
||||||
RWBackend(const RWBackend&);
|
RWBackend(const RWBackend&);
|
||||||
@ -191,8 +194,27 @@ public:
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void add_ps_handle(uint64_t id, uint32_t handle)
|
||||||
|
{
|
||||||
|
m_ps_handles[id] = handle;
|
||||||
|
MXS_INFO("PS response for %s: %lu -> %u", name(), id, handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t get_ps_handle(uint64_t id) const
|
||||||
|
{
|
||||||
|
HandleMap::const_iterator it = m_ps_handles.find(id);
|
||||||
|
|
||||||
|
if (it != m_ps_handles.end())
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
reply_state_t m_reply_state;
|
reply_state_t m_reply_state;
|
||||||
|
HandleMap m_ps_handles;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::tr1::shared_ptr<RWBackend> SRWBackend;
|
typedef std::tr1::shared_ptr<RWBackend> SRWBackend;
|
||||||
|
@ -36,8 +36,19 @@ void process_sescmd_response(ROUTER_CLIENT_SES* rses, SRWBackend& backend,
|
|||||||
{
|
{
|
||||||
uint8_t cmd;
|
uint8_t cmd;
|
||||||
gwbuf_copy_data(*ppPacket, MYSQL_HEADER_LEN, 1, &cmd);
|
gwbuf_copy_data(*ppPacket, MYSQL_HEADER_LEN, 1, &cmd);
|
||||||
|
uint8_t command = backend->next_session_command()->get_command();
|
||||||
uint64_t id = backend->complete_session_command();
|
uint64_t id = backend->complete_session_command();
|
||||||
|
|
||||||
|
if (command == MYSQL_COM_STMT_PREPARE)
|
||||||
|
{
|
||||||
|
MXS_PS_RESPONSE resp;
|
||||||
|
|
||||||
|
if (mxs_mysql_extract_ps_response(*ppPacket, &resp))
|
||||||
|
{
|
||||||
|
backend->add_ps_handle(id, resp.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (rses->recv_sescmd < rses->sent_sescmd &&
|
if (rses->recv_sescmd < rses->sent_sescmd &&
|
||||||
id == rses->recv_sescmd + 1 &&
|
id == rses->recv_sescmd + 1 &&
|
||||||
(!rses->current_master || // Session doesn't have a master
|
(!rses->current_master || // Session doesn't have a master
|
||||||
|
Reference in New Issue
Block a user