
Replace the original version of the function with the reference version and use it everywhere. Added runtime assertions to check that an invalid DCB is never processed.
139 lines
5.3 KiB
C++
139 lines
5.3 KiB
C++
#pragma once
|
|
/*
|
|
* Copyright (c) 2016 MariaDB Corporation Ab
|
|
*
|
|
* Use of this software is governed by the Business Source License included
|
|
* in the LICENSE.TXT file and at www.mariadb.com/bsl11.
|
|
*
|
|
* Change Date: 2020-01-01
|
|
*
|
|
* On the date above, in accordance with the Business Source License, use
|
|
* of this software will be governed by version 2 or later of the General
|
|
* Public License.
|
|
*/
|
|
|
|
#include "readwritesplit.hh"
|
|
|
|
#include <string>
|
|
|
|
#include <maxscale/query_classifier.h>
|
|
#include <maxscale/protocol/mysql.h>
|
|
|
|
#include "rwsplitsession.hh"
|
|
|
|
#define RW_CHK_DCB(b, d) \
|
|
do{ \
|
|
if(d->state == DCB_STATE_DISCONNECTED){ \
|
|
MXS_NOTICE("DCB was closed on line %d and another attempt to close it is made on line %d." , \
|
|
(b) ? (b)->closed_at : -1, __LINE__); \
|
|
} \
|
|
}while (false)
|
|
|
|
#define RW_CLOSE_BREF(b) do{ if (b){ (b)->closed_at = __LINE__; } } while (false)
|
|
|
|
static inline bool is_ps_command(uint8_t cmd)
|
|
{
|
|
return cmd == MXS_COM_STMT_EXECUTE ||
|
|
cmd == MXS_COM_STMT_SEND_LONG_DATA ||
|
|
cmd == MXS_COM_STMT_CLOSE ||
|
|
cmd == MXS_COM_STMT_FETCH ||
|
|
cmd == MXS_COM_STMT_RESET;
|
|
}
|
|
|
|
/*
|
|
* The following are implemented in rwsplit_mysql.c
|
|
*/
|
|
bool route_single_stmt(RWSplit *inst, RWSplitSession *rses,
|
|
GWBUF *querybuf);
|
|
void closed_session_reply(GWBUF *querybuf);
|
|
void print_error_packet(RWSplitSession *rses, GWBUF *buf, DCB *dcb);
|
|
void check_session_command_reply(GWBUF *buffer, SRWBackend& backend);
|
|
bool execute_sescmd_in_backend(SRWBackend& backend_ref);
|
|
bool handle_target_is_all(route_target_t route_target,
|
|
RWSplit *inst, RWSplitSession *rses,
|
|
GWBUF *querybuf, int packet_type, uint32_t qtype);
|
|
void log_transaction_status(RWSplitSession *rses, GWBUF *querybuf, uint32_t qtype);
|
|
bool is_packet_a_query(int packet_type);
|
|
bool send_readonly_error(DCB *dcb);
|
|
|
|
/*
|
|
* The following are implemented in readwritesplit.c
|
|
*/
|
|
int router_handle_state_switch(DCB *dcb, DCB_REASON reason, void *data);
|
|
int rses_get_max_replication_lag(RWSplitSession *rses);
|
|
|
|
/*
|
|
* The following are implemented in rwsplit_route_stmt.c
|
|
*/
|
|
|
|
bool route_single_stmt(RWSplit *inst, RWSplitSession *rses,
|
|
GWBUF *querybuf, const RouteInfo& info);
|
|
SRWBackend get_target_backend(RWSplitSession *rses, backend_type_t btype,
|
|
char *name, int max_rlag);
|
|
route_target_t get_route_target(RWSplitSession *rses, uint8_t command,
|
|
uint32_t qtype, HINT *hint);
|
|
void handle_multi_temp_and_load(RWSplitSession *rses, GWBUF *querybuf,
|
|
uint8_t packet_type, uint32_t *qtype);
|
|
SRWBackend handle_hinted_target(RWSplitSession *rses, GWBUF *querybuf,
|
|
route_target_t route_target);
|
|
SRWBackend handle_slave_is_target(RWSplit *inst, RWSplitSession *rses,
|
|
uint8_t cmd, uint32_t id);
|
|
bool handle_master_is_target(RWSplit *inst, RWSplitSession *rses,
|
|
SRWBackend* dest);
|
|
bool handle_got_target(RWSplit *inst, RWSplitSession *rses,
|
|
GWBUF *querybuf, SRWBackend& target, bool store);
|
|
bool route_session_write(RWSplitSession *rses, GWBUF *querybuf,
|
|
uint8_t command, uint32_t type);
|
|
|
|
void process_sescmd_response(RWSplitSession* rses, SRWBackend& bref,
|
|
GWBUF** ppPacket, bool* reconnect);
|
|
/*
|
|
* The following are implemented in rwsplit_select_backends.c
|
|
*/
|
|
|
|
/** What sort of connections should be create */
|
|
enum connection_type
|
|
{
|
|
ALL,
|
|
SLAVE
|
|
};
|
|
|
|
bool select_connect_backend_servers(int router_nservers,
|
|
int max_nslaves,
|
|
MXS_SESSION *session,
|
|
const Config& config,
|
|
SRWBackendList& backends,
|
|
SRWBackend& current_master,
|
|
mxs::SessionCommandList* sescmd,
|
|
int* expected_responses,
|
|
connection_type type);
|
|
/*
|
|
* The following are implemented in rwsplit_tmp_table_multi.c
|
|
*/
|
|
void check_drop_tmp_table(RWSplitSession *router_cli_ses, GWBUF *querybuf);
|
|
bool is_read_tmp_table(RWSplitSession *router_cli_ses,
|
|
GWBUF *querybuf,
|
|
uint32_t type);
|
|
void check_create_tmp_table(RWSplitSession *router_cli_ses,
|
|
GWBUF *querybuf, uint32_t type);
|
|
bool check_for_multi_stmt(GWBUF *buf, void *protocol, uint8_t packet_type);
|
|
bool check_for_sp_call(GWBUF *buf, uint8_t packet_type);
|
|
|
|
void close_all_connections(SRWBackendList& backends);
|
|
|
|
uint32_t determine_query_type(GWBUF *querybuf, int command);
|
|
|
|
/**
|
|
* @brief Get the routing requirements for a query
|
|
*
|
|
* @param rses Router client session
|
|
* @param buffer Buffer containing the query
|
|
* @param command Output parameter where the packet command is stored
|
|
* @param type Output parameter where the query type is stored
|
|
* @param stmt_id Output parameter where statement ID, if the query is a binary protocol command, is stored
|
|
*
|
|
* @return The target type where this query should be routed
|
|
*/
|
|
route_target_t get_target_type(RWSplitSession* rses, GWBUF* buffer, uint8_t* command,
|
|
uint32_t* type, uint32_t* stmt_id);
|