173 lines
5.8 KiB
C++
173 lines
5.8 KiB
C++
/*
|
|
* Copyright (c) 2018 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: 2023-11-12
|
|
*
|
|
* 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.
|
|
*/
|
|
#pragma once
|
|
|
|
#include "schemarouter.hh"
|
|
|
|
#include <string>
|
|
#include <list>
|
|
|
|
#include <maxscale/protocol/mysql.hh>
|
|
#include <maxscale/router.hh>
|
|
#include <maxscale/session_command.hh>
|
|
|
|
#include "shard_map.hh"
|
|
|
|
namespace schemarouter
|
|
{
|
|
/**
|
|
* Bitmask values for the router session's initialization. These values are used
|
|
* to prevent responses from internal commands being forwarded to the client.
|
|
*/
|
|
enum init_mask
|
|
{
|
|
INIT_READY = 0x00,
|
|
INIT_MAPPING = 0x01,
|
|
INIT_USE_DB = 0x02,
|
|
INIT_UNINT = 0x04,
|
|
INIT_FAILED = 0x08
|
|
};
|
|
|
|
enum showdb_response
|
|
{
|
|
SHOWDB_FULL_RESPONSE,
|
|
SHOWDB_PARTIAL_RESPONSE,
|
|
SHOWDB_DUPLICATE_DATABASES,
|
|
SHOWDB_FATAL_ERROR
|
|
};
|
|
|
|
#define SCHEMA_ERR_DUPLICATEDB 5000
|
|
#define SCHEMA_ERRSTR_DUPLICATEDB "DUPDB"
|
|
#define SCHEMA_ERR_DBNOTFOUND 1049
|
|
#define SCHEMA_ERRSTR_DBNOTFOUND "42000"
|
|
|
|
/**
|
|
* Route target types
|
|
*/
|
|
enum route_target
|
|
{
|
|
TARGET_UNDEFINED,
|
|
TARGET_NAMED_SERVER,
|
|
TARGET_ALL,
|
|
TARGET_ANY
|
|
};
|
|
|
|
/** Helper macros for route target type */
|
|
#define TARGET_IS_UNDEFINED(t) (t == TARGET_UNDEFINED)
|
|
#define TARGET_IS_NAMED_SERVER(t) (t == TARGET_NAMED_SERVER)
|
|
#define TARGET_IS_ALL(t) (t == TARGET_ALL)
|
|
#define TARGET_IS_ANY(t) (t == TARGET_ANY)
|
|
|
|
class SchemaRouter;
|
|
|
|
/**
|
|
* The client session structure used within this router.
|
|
*/
|
|
class SchemaRouterSession : public mxs::RouterSession
|
|
{
|
|
public:
|
|
|
|
SchemaRouterSession(MXS_SESSION* session, SchemaRouter* router, SSRBackendList& backends);
|
|
|
|
/**
|
|
* The RouterSession instance will be deleted when a client session
|
|
* has terminated. Will be called only after @c close() has been called.
|
|
*/
|
|
~SchemaRouterSession();
|
|
|
|
/**
|
|
* Called when a client session has been closed.
|
|
*/
|
|
void close();
|
|
|
|
/**
|
|
* Called when a packet being is routed to the backend. The router should
|
|
* forward the packet to the appropriate server(s).
|
|
*
|
|
* @param pPacket A client packet.
|
|
*/
|
|
int32_t routeQuery(GWBUF* pPacket);
|
|
|
|
/**
|
|
* Called when a packet is routed to the client. The router should
|
|
* forward the packet to the client using `MXS_SESSION_ROUTE_REPLY`.
|
|
*
|
|
* @param pPacket A client packet.
|
|
* @param pBackend The backend the packet is coming from.
|
|
*/
|
|
void clientReply(GWBUF* pPacket, DCB* pBackend);
|
|
|
|
/**
|
|
*
|
|
* @param pMessage The error message.
|
|
* @param pProblem The DCB on which the error occurred.
|
|
* @param action The context.
|
|
* @param pSuccess On output, if false, the session will be terminated.
|
|
*/
|
|
void handleError(GWBUF* pMessage,
|
|
DCB* pProblem,
|
|
mxs_error_action_t action,
|
|
bool* pSuccess);
|
|
private:
|
|
/**
|
|
* Internal functions
|
|
*/
|
|
|
|
/** Helper functions */
|
|
SERVER* get_shard_target(GWBUF* buffer, uint32_t qtype);
|
|
SSRBackend get_bref_from_dcb(DCB* dcb);
|
|
bool get_shard_dcb(DCB** dcb, const char* name);
|
|
bool have_servers();
|
|
bool handle_default_db();
|
|
bool ignore_duplicate_table(const std::string& data);
|
|
SERVER* get_query_target(GWBUF* buffer);
|
|
SERVER* get_ps_target(GWBUF* buffer, uint32_t qtype, qc_query_op_t op);
|
|
|
|
/** Routing functions */
|
|
bool route_session_write(GWBUF* querybuf, uint8_t command);
|
|
void process_sescmd_response(SSRBackend& bref, GWBUF** ppPacket);
|
|
SERVER* resolve_query_target(GWBUF* pPacket,
|
|
uint32_t type,
|
|
uint8_t command,
|
|
enum route_target& route_target);
|
|
|
|
/** Shard mapping functions */
|
|
void send_databases();
|
|
bool send_shards();
|
|
void query_databases();
|
|
int inspect_mapping_states(SSRBackend& bref, GWBUF** wbuf);
|
|
enum showdb_response parse_mapping_response(SSRBackend& bref, GWBUF** buffer);
|
|
void route_queued_query();
|
|
void synchronize_shards();
|
|
void handle_mapping_reply(SSRBackend& bref, GWBUF** pPacket);
|
|
bool handle_statement(GWBUF* querybuf, SSRBackend& bref, uint8_t command, uint32_t type);
|
|
|
|
/** Member variables */
|
|
bool m_closed; /**< True if session closed */
|
|
DCB* m_client; /**< The client DCB */
|
|
MYSQL_session* m_mysql_session; /**< Session client data (username, password, SHA1). */
|
|
SSRBackendList m_backends; /**< Backend references */
|
|
SConfig m_config; /**< Session specific configuration */
|
|
SchemaRouter* m_router; /**< The router instance */
|
|
Shard m_shard; /**< Database to server mapping */
|
|
std::string m_connect_db; /**< Database the user was trying to connect to */
|
|
std::string m_current_db; /**< Current active database */
|
|
int m_state; /**< Initialization state bitmask */
|
|
std::list<mxs::Buffer> m_queue; /**< Query that was received before the session was ready */
|
|
Stats m_stats; /**< Statistics for this router */
|
|
uint64_t m_sent_sescmd; /**< The latest session command being executed */
|
|
uint64_t m_replied_sescmd;/**< The last session command reply that was sent to the client */
|
|
SERVER* m_load_target; /**< Target for LOAD DATA LOCAL INFILE */
|
|
};
|
|
}
|