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:
Markus Mäkelä
2017-06-21 13:54:30 +03:00
parent dd90ad01b6
commit 3eac28248d
2 changed files with 35 additions and 2 deletions

View File

@ -27,6 +27,7 @@
#include <maxscale/dcb.h>
#include <maxscale/hashtable.h>
#include <maxscale/log_manager.h>
#include <maxscale/router.h>
#include <maxscale/service.h>
#include <maxscale/backend.hh>
@ -117,8 +118,8 @@ enum ld_state
(SERVER_IS_SLAVE((b)->backend_server) ? BE_SLAVE : BE_UNDEFINED));
/** Reply state change debug logging */
#define LOG_RS(a, b) MXS_DEBUG("[%s]:%d %s -> %s", (a)->server()->name, \
(a)->server()->port, rstostr((a)->get_reply_state()), rstostr(b));
#define LOG_RS(a, b) MXS_INFO("%s %s -> %s", (a)->uri(), \
rstostr((a)->get_reply_state()), rstostr(b));
struct ROUTER_INSTANCE;
struct ROUTER_CLIENT_SES;
@ -153,6 +154,8 @@ struct rwsplit_config_t
* been idle for too long */
};
typedef std::map<uint64_t, uint32_t> HandleMap;
class RWBackend: public mxs::Backend
{
RWBackend(const RWBackend&);
@ -191,8 +194,27 @@ public:
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:
reply_state_t m_reply_state;
HandleMap m_ps_handles;
};
typedef std::tr1::shared_ptr<RWBackend> SRWBackend;

View File

@ -36,8 +36,19 @@ void process_sescmd_response(ROUTER_CLIENT_SES* rses, SRWBackend& backend,
{
uint8_t 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();
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 &&
id == rses->recv_sescmd + 1 &&
(!rses->current_master || // Session doesn't have a master