#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 #include #include #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 == MYSQL_COM_STMT_EXECUTE || cmd == MYSQL_COM_STMT_SEND_LONG_DATA || cmd == MYSQL_COM_STMT_CLOSE || cmd == MYSQL_COM_STMT_FETCH || cmd == MYSQL_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 *writebuf, SRWBackend bref); 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); SRWBackend get_backend_from_dcb(RWSplitSession *rses, DCB *dcb); 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); 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);