Merge branch 'release-1.3.0' into doc_fixes
This commit is contained in:
@ -117,7 +117,7 @@ This parameter is used to define the maximum amount of data that will be sent to
|
|||||||
This parameter is used to enable/disable incomplete transactions detection in binlog router.
|
This parameter is used to enable/disable incomplete transactions detection in binlog router.
|
||||||
When MaxScale starts an error message may appear if current binlog file is corrupted or an incomplete transaction is found.
|
When MaxScale starts an error message may appear if current binlog file is corrupted or an incomplete transaction is found.
|
||||||
During normal operations binlog events are not distributed to the slaves until a COMMIT is seen.
|
During normal operations binlog events are not distributed to the slaves until a COMMIT is seen.
|
||||||
The default value is on, set transaction_safety=off to completely disable the incomplete transactions detection.
|
The default value is off, set transaction_safety=on to enable the incomplete transactions detection.
|
||||||
|
|
||||||
A complete example of a service entry for a binlog router service would be as follows.
|
A complete example of a service entry for a binlog router service would be as follows.
|
||||||
```
|
```
|
||||||
|
@ -3,4 +3,3 @@ set(CPACK_GENERATOR "${CPACK_GENERATOR};DEB")
|
|||||||
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_BINARY_DIR}/postinst;{CMAKE_BINARY_DIR}/postrm")
|
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_BINARY_DIR}/postinst;{CMAKE_BINARY_DIR}/postrm")
|
||||||
execute_process(COMMAND dpgk --print-architecture OUTPUT_VARIABLE DEB_ARCHITECTURE)
|
execute_process(COMMAND dpgk --print-architecture OUTPUT_VARIABLE DEB_ARCHITECTURE)
|
||||||
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE ${DEB_ARCHITECTURE})
|
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE ${DEB_ARCHITECTURE})
|
||||||
set (CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -17,7 +17,7 @@ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|||||||
|
|
||||||
Copyright MariaDB Corporation Ab
|
Copyright MariaDB Corporation Ab
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** getpid */
|
/** getpid */
|
||||||
#include <my_config.h>
|
#include <my_config.h>
|
||||||
@ -33,90 +33,96 @@ EXTERN_C_BLOCK_BEGIN
|
|||||||
* The meaninful difference is where operation is done and whether master data
|
* The meaninful difference is where operation is done and whether master data
|
||||||
* is modified
|
* is modified
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum
|
||||||
QUERY_TYPE_UNKNOWN = 0x000000, /*< Initial value, can't be tested bitwisely */
|
{
|
||||||
QUERY_TYPE_LOCAL_READ = 0x000001, /*< Read non-database data, execute in MaxScale:any */
|
QUERY_TYPE_UNKNOWN = 0x000000, /*< Initial value, can't be tested bitwisely */
|
||||||
QUERY_TYPE_READ = 0x000002, /*< Read database data:any */
|
QUERY_TYPE_LOCAL_READ = 0x000001, /*< Read non-database data, execute in MaxScale:any */
|
||||||
QUERY_TYPE_WRITE = 0x000004, /*< Master data will be modified:master */
|
QUERY_TYPE_READ = 0x000002, /*< Read database data:any */
|
||||||
QUERY_TYPE_MASTER_READ = 0x000008, /*< Read from the master:master */
|
QUERY_TYPE_WRITE = 0x000004, /*< Master data will be modified:master */
|
||||||
QUERY_TYPE_SESSION_WRITE = 0x000010, /*< Session data will be modified:master or all */
|
QUERY_TYPE_MASTER_READ = 0x000008, /*< Read from the master:master */
|
||||||
|
QUERY_TYPE_SESSION_WRITE = 0x000010, /*< Session data will be modified:master or all */
|
||||||
/** Not implemented yet */
|
/** Not implemented yet */
|
||||||
// QUERY_TYPE_USERVAR_WRITE = 0x000020, /*< Write a user variable:master or all */
|
// QUERY_TYPE_USERVAR_WRITE = 0x000020, /*< Write a user variable:master or all */
|
||||||
QUERY_TYPE_USERVAR_READ = 0x000040, /*< Read a user variable:master or any */
|
QUERY_TYPE_USERVAR_READ = 0x000040, /*< Read a user variable:master or any */
|
||||||
QUERY_TYPE_SYSVAR_READ = 0x000080, /*< Read a system variable:master or any */
|
QUERY_TYPE_SYSVAR_READ = 0x000080, /*< Read a system variable:master or any */
|
||||||
/** Not implemented yet */
|
/** Not implemented yet */
|
||||||
// QUERY_TYPE_SYSVAR_WRITE = 0x000100, /*< Write a system variable:master or all */
|
// QUERY_TYPE_SYSVAR_WRITE = 0x000100, /*< Write a system variable:master or all */
|
||||||
QUERY_TYPE_GSYSVAR_READ = 0x000200, /*< Read global system variable:master or any */
|
QUERY_TYPE_GSYSVAR_READ = 0x000200, /*< Read global system variable:master or any */
|
||||||
QUERY_TYPE_GSYSVAR_WRITE = 0x000400, /*< Write global system variable:master or all */
|
QUERY_TYPE_GSYSVAR_WRITE = 0x000400, /*< Write global system variable:master or all */
|
||||||
QUERY_TYPE_BEGIN_TRX = 0x000800, /*< BEGIN or START TRANSACTION */
|
QUERY_TYPE_BEGIN_TRX = 0x000800, /*< BEGIN or START TRANSACTION */
|
||||||
QUERY_TYPE_ENABLE_AUTOCOMMIT = 0x001000, /*< SET autocommit=1 */
|
QUERY_TYPE_ENABLE_AUTOCOMMIT = 0x001000, /*< SET autocommit=1 */
|
||||||
QUERY_TYPE_DISABLE_AUTOCOMMIT = 0x002000, /*< SET autocommit=0 */
|
QUERY_TYPE_DISABLE_AUTOCOMMIT = 0x002000, /*< SET autocommit=0 */
|
||||||
QUERY_TYPE_ROLLBACK = 0x004000, /*< ROLLBACK */
|
QUERY_TYPE_ROLLBACK = 0x004000, /*< ROLLBACK */
|
||||||
QUERY_TYPE_COMMIT = 0x008000, /*< COMMIT */
|
QUERY_TYPE_COMMIT = 0x008000, /*< COMMIT */
|
||||||
QUERY_TYPE_PREPARE_NAMED_STMT = 0x010000, /*< Prepared stmt with name from user:all */
|
QUERY_TYPE_PREPARE_NAMED_STMT = 0x010000, /*< Prepared stmt with name from user:all */
|
||||||
QUERY_TYPE_PREPARE_STMT = 0x020000, /*< Prepared stmt with id provided by server:all */
|
QUERY_TYPE_PREPARE_STMT = 0x020000, /*< Prepared stmt with id provided by server:all */
|
||||||
QUERY_TYPE_EXEC_STMT = 0x040000, /*< Execute prepared statement:master or any */
|
QUERY_TYPE_EXEC_STMT = 0x040000, /*< Execute prepared statement:master or any */
|
||||||
QUERY_TYPE_CREATE_TMP_TABLE = 0x080000, /*< Create temporary table:master (could be all) */
|
QUERY_TYPE_CREATE_TMP_TABLE = 0x080000, /*< Create temporary table:master (could be all) */
|
||||||
QUERY_TYPE_READ_TMP_TABLE = 0x100000, /*< Read temporary table:master (could be any) */
|
QUERY_TYPE_READ_TMP_TABLE = 0x100000, /*< Read temporary table:master (could be any) */
|
||||||
QUERY_TYPE_SHOW_DATABASES = 0x200000, /*< Show list of databases */
|
QUERY_TYPE_SHOW_DATABASES = 0x200000, /*< Show list of databases */
|
||||||
QUERY_TYPE_SHOW_TABLES = 0x400000 /*< Show list of tables */
|
QUERY_TYPE_SHOW_TABLES = 0x400000 /*< Show list of tables */
|
||||||
} skygw_query_type_t;
|
} skygw_query_type_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum
|
||||||
QUERY_OP_UNDEFINED = 0,
|
{
|
||||||
QUERY_OP_SELECT = 1,
|
QUERY_OP_UNDEFINED = 0,
|
||||||
QUERY_OP_UPDATE = (1 << 1),
|
QUERY_OP_SELECT = 1,
|
||||||
QUERY_OP_INSERT = (1 << 2),
|
QUERY_OP_UPDATE = (1 << 1),
|
||||||
QUERY_OP_DELETE = (1 << 3),
|
QUERY_OP_INSERT = (1 << 2),
|
||||||
QUERY_OP_INSERT_SELECT = (1 << 4),
|
QUERY_OP_DELETE = (1 << 3),
|
||||||
QUERY_OP_TRUNCATE = (1 << 5),
|
QUERY_OP_INSERT_SELECT = (1 << 4),
|
||||||
QUERY_OP_ALTER_TABLE = (1 << 6),
|
QUERY_OP_TRUNCATE = (1 << 5),
|
||||||
QUERY_OP_CREATE_TABLE = (1 << 7),
|
QUERY_OP_ALTER_TABLE = (1 << 6),
|
||||||
QUERY_OP_CREATE_INDEX = (1 << 8),
|
QUERY_OP_CREATE_TABLE = (1 << 7),
|
||||||
QUERY_OP_DROP_TABLE = (1 << 9),
|
QUERY_OP_CREATE_INDEX = (1 << 8),
|
||||||
QUERY_OP_DROP_INDEX = (1 << 10),
|
QUERY_OP_DROP_TABLE = (1 << 9),
|
||||||
QUERY_OP_CHANGE_DB = (1 << 11),
|
QUERY_OP_DROP_INDEX = (1 << 10),
|
||||||
QUERY_OP_LOAD = (1 << 12)
|
QUERY_OP_CHANGE_DB = (1 << 11),
|
||||||
}skygw_query_op_t;
|
QUERY_OP_LOAD = (1 << 12)
|
||||||
|
} skygw_query_op_t;
|
||||||
|
|
||||||
typedef struct parsing_info_st {
|
typedef struct parsing_info_st
|
||||||
|
{
|
||||||
#if defined(SS_DEBUG)
|
#if defined(SS_DEBUG)
|
||||||
skygw_chk_t pi_chk_top;
|
skygw_chk_t pi_chk_top;
|
||||||
#endif
|
#endif
|
||||||
void* pi_handle; /*< parsing info object pointer */
|
void* pi_handle; /*< parsing info object pointer */
|
||||||
char* pi_query_plain_str; /*< query as plain string */
|
char* pi_query_plain_str; /*< query as plain string */
|
||||||
void (*pi_done_fp)(void *); /*< clean-up function for parsing info */
|
void (*pi_done_fp)(void *); /*< clean-up function for parsing info */
|
||||||
#if defined(SS_DEBUG)
|
#if defined(SS_DEBUG)
|
||||||
skygw_chk_t pi_chk_tail;
|
skygw_chk_t pi_chk_tail;
|
||||||
#endif
|
#endif
|
||||||
} parsing_info_t;
|
} parsing_info_t;
|
||||||
|
|
||||||
|
|
||||||
#define QUERY_IS_TYPE(mask,type) ((mask & type) == type)
|
#define QUERY_IS_TYPE(mask,type) ((mask & type) == type)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create THD and use it for creating parse tree. Examine parse tree and
|
* Create THD and use it for creating parse tree. Examine parse tree and
|
||||||
* classify the query.
|
* classify the query.
|
||||||
*/
|
*/
|
||||||
skygw_query_type_t query_classifier_get_type(GWBUF* querybuf);
|
skygw_query_type_t query_classifier_get_type(GWBUF* querybuf);
|
||||||
skygw_query_op_t query_classifier_get_operation(GWBUF* querybuf);
|
skygw_query_op_t query_classifier_get_operation(GWBUF* querybuf);
|
||||||
/** Free THD context and close MYSQL */
|
|
||||||
#if defined(NOT_USED)
|
#if defined(NOT_USED)
|
||||||
char* skygw_query_classifier_get_stmtname(GWBUF* buf);
|
char* skygw_query_classifier_get_stmtname(GWBUF* buf);
|
||||||
#endif
|
#endif
|
||||||
char* skygw_get_created_table_name(GWBUF* querybuf);
|
|
||||||
bool is_drop_table_query(GWBUF* querybuf);
|
char* skygw_get_created_table_name(GWBUF* querybuf);
|
||||||
bool skygw_is_real_query(GWBUF* querybuf);
|
bool is_drop_table_query(GWBUF* querybuf);
|
||||||
char** skygw_get_table_names(GWBUF* querybuf, int* tblsize, bool fullnames);
|
bool skygw_is_real_query(GWBUF* querybuf);
|
||||||
char* skygw_get_canonical(GWBUF* querybuf);
|
char** skygw_get_table_names(GWBUF* querybuf, int* tblsize, bool fullnames);
|
||||||
bool parse_query (GWBUF* querybuf);
|
char* skygw_get_canonical(GWBUF* querybuf);
|
||||||
|
bool parse_query(GWBUF* querybuf);
|
||||||
parsing_info_t* parsing_info_init(void (*donefun)(void *));
|
parsing_info_t* parsing_info_init(void (*donefun)(void *));
|
||||||
void parsing_info_done(void* ptr);
|
|
||||||
bool query_is_parsed(GWBUF* buf);
|
/** Free THD context and close MYSQL */
|
||||||
bool skygw_query_has_clause(GWBUF* buf);
|
void parsing_info_done(void* ptr);
|
||||||
char* skygw_get_qtype_str(skygw_query_type_t qtype);
|
bool query_is_parsed(GWBUF* buf);
|
||||||
char* skygw_get_affected_fields(GWBUF* buf);
|
bool skygw_query_has_clause(GWBUF* buf);
|
||||||
char** skygw_get_database_names(GWBUF* querybuf,int* size);
|
char* skygw_get_qtype_str(skygw_query_type_t qtype);
|
||||||
|
char* skygw_get_affected_fields(GWBUF* buf);
|
||||||
|
char** skygw_get_database_names(GWBUF* querybuf, int* size);
|
||||||
|
|
||||||
EXTERN_C_BLOCK_END
|
EXTERN_C_BLOCK_END
|
||||||
|
|
||||||
|
@ -210,7 +210,7 @@ static bool resolve_maxscale_conf_fname(
|
|||||||
char* cnf_file_arg);
|
char* cnf_file_arg);
|
||||||
|
|
||||||
static char* check_dir_access(char* dirname, bool, bool);
|
static char* check_dir_access(char* dirname, bool, bool);
|
||||||
static int set_user();
|
static int set_user(const char* user);
|
||||||
bool pid_file_exists();
|
bool pid_file_exists();
|
||||||
void write_child_exit_code(int fd, int code);
|
void write_child_exit_code(int fd, int code);
|
||||||
/** SSL multi-threading functions and structures */
|
/** SSL multi-threading functions and structures */
|
||||||
@ -968,7 +968,7 @@ static void usage(void)
|
|||||||
" (default: /etc/)\n"
|
" (default: /etc/)\n"
|
||||||
" -D, --datadir=PATH path to data directory, stored embedded mysql tables\n"
|
" -D, --datadir=PATH path to data directory, stored embedded mysql tables\n"
|
||||||
" (default: /var/cache/maxscale)\n"
|
" (default: /var/cache/maxscale)\n"
|
||||||
" -N, --language=PATH apth to errmsg.sys file\n"
|
" -N, --language=PATH path to errmsg.sys file\n"
|
||||||
" (default: /var/lib/maxscale)\n"
|
" (default: /var/lib/maxscale)\n"
|
||||||
" -P, --piddir=PATH path to PID file directory\n"
|
" -P, --piddir=PATH path to PID file directory\n"
|
||||||
" (default: /var/run/maxscale)\n"
|
" (default: /var/run/maxscale)\n"
|
||||||
@ -2433,7 +2433,7 @@ static int cnf_preparser(void* data, const char* section, const char* name, cons
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_user(char* user)
|
static int set_user(const char* user)
|
||||||
{
|
{
|
||||||
errno = 0;
|
errno = 0;
|
||||||
struct passwd *pwname;
|
struct passwd *pwname;
|
||||||
|
@ -109,13 +109,13 @@ bitmask_set(GWBITMASK *bitmask, int bit)
|
|||||||
unsigned char mask;
|
unsigned char mask;
|
||||||
|
|
||||||
spinlock_acquire(&bitmask->lock);
|
spinlock_acquire(&bitmask->lock);
|
||||||
if (bit >= bitmask->length)
|
while (bit >= bitmask->length)
|
||||||
{
|
{
|
||||||
bitmask->bits = realloc(bitmask->bits,
|
bitmask->bits = realloc(bitmask->bits,
|
||||||
(bitmask->length + BIT_LENGTH_INC) / 8);
|
(bitmask->length + BIT_LENGTH_INC) / 8);
|
||||||
memset(bitmask->bits + (bitmask->length / 8), 0,
|
memset(bitmask->bits + (bitmask->length / 8), 0,
|
||||||
BIT_LENGTH_INC / 8);
|
BIT_LENGTH_INC / 8);
|
||||||
bitmask->length += (BIT_LENGTH_INC / 8);
|
bitmask->length += BIT_LENGTH_INC;
|
||||||
}
|
}
|
||||||
ptr = bitmask->bits + (bit / 8);
|
ptr = bitmask->bits + (bit / 8);
|
||||||
mask = 1 << (bit % 8);
|
mask = 1 << (bit % 8);
|
||||||
|
@ -33,8 +33,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Both these numbers MUST be exact multiples of 8 */
|
/* Both these numbers MUST be exact multiples of 8 */
|
||||||
#define BIT_LENGTH_INITIAL 32 /**< Initial number of bits in the bitmask */
|
#define BIT_LENGTH_INITIAL 256 /**< Initial number of bits in the bitmask */
|
||||||
#define BIT_LENGTH_INC 32 /**< Number of bits to add on each increment */
|
#define BIT_LENGTH_INC 256 /**< Number of bits to add on each increment */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The bitmask structure used to store an arbitrary large bitmask
|
* The bitmask structure used to store an arbitrary large bitmask
|
||||||
|
@ -37,52 +37,55 @@
|
|||||||
* connections to. This provides the storage for routing module specific data
|
* connections to. This provides the storage for routing module specific data
|
||||||
* that is required for each of the backend servers.
|
* that is required for each of the backend servers.
|
||||||
*/
|
*/
|
||||||
typedef struct backend {
|
typedef struct backend
|
||||||
SERVER *server; /*< The server itself */
|
{
|
||||||
int current_connection_count; /*< Number of connections to the server */
|
SERVER *server; /*< The server itself */
|
||||||
int weight; /*< Desired routing weight */
|
int current_connection_count; /*< Number of connections to the server */
|
||||||
|
int weight; /*< Desired routing weight */
|
||||||
} BACKEND;
|
} BACKEND;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The client session structure used within this router.
|
* The client session structure used within this router.
|
||||||
*/
|
*/
|
||||||
typedef struct router_client_session {
|
typedef struct router_client_session
|
||||||
|
{
|
||||||
#if defined(SS_DEBUG)
|
#if defined(SS_DEBUG)
|
||||||
skygw_chk_t rses_chk_top;
|
skygw_chk_t rses_chk_top;
|
||||||
#endif
|
#endif
|
||||||
SPINLOCK rses_lock; /*< protects rses_deleted */
|
SPINLOCK rses_lock; /*< protects rses_deleted */
|
||||||
int rses_versno; /*< even = no active update, else odd */
|
int rses_versno; /*< even = no active update, else odd */
|
||||||
bool rses_closed; /*< true when closeSession is called */
|
bool rses_closed; /*< true when closeSession is called */
|
||||||
BACKEND *backend; /*< Backend used by the client session */
|
BACKEND *backend; /*< Backend used by the client session */
|
||||||
DCB *backend_dcb; /*< DCB Connection to the backend */
|
DCB *backend_dcb; /*< DCB Connection to the backend */
|
||||||
struct router_client_session *next;
|
struct router_client_session *next;
|
||||||
int rses_capabilities; /*< input type, for example */
|
int rses_capabilities; /*< input type, for example */
|
||||||
#if defined(SS_DEBUG)
|
#if defined(SS_DEBUG)
|
||||||
skygw_chk_t rses_chk_tail;
|
skygw_chk_t rses_chk_tail;
|
||||||
#endif
|
#endif
|
||||||
} ROUTER_CLIENT_SES;
|
} ROUTER_CLIENT_SES;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The statistics for this router instance
|
* The statistics for this router instance
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct
|
||||||
int n_sessions; /*< Number sessions created */
|
{
|
||||||
int n_queries; /*< Number of queries forwarded */
|
int n_sessions; /*< Number sessions created */
|
||||||
|
int n_queries; /*< Number of queries forwarded */
|
||||||
} ROUTER_STATS;
|
} ROUTER_STATS;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The per instance data for the router.
|
* The per instance data for the router.
|
||||||
*/
|
*/
|
||||||
typedef struct router_instance {
|
typedef struct router_instance
|
||||||
SERVICE *service; /*< Pointer to the service using this router */
|
{
|
||||||
ROUTER_CLIENT_SES *connections; /*< Link list of all the client connections */
|
SERVICE *service; /*< Pointer to the service using this router */
|
||||||
SPINLOCK lock; /*< Spinlock for the instance data */
|
ROUTER_CLIENT_SES *connections; /*< Link list of all the client connections */
|
||||||
BACKEND **servers; /*< List of backend servers */
|
SPINLOCK lock; /*< Spinlock for the instance data */
|
||||||
unsigned int bitmask; /*< Bitmask to apply to server->status */
|
BACKEND **servers; /*< List of backend servers */
|
||||||
unsigned int bitvalue; /*< Required value of server->status */
|
unsigned int bitmask; /*< Bitmask to apply to server->status */
|
||||||
ROUTER_STATS stats; /*< Statistics for this router */
|
unsigned int bitvalue; /*< Required value of server->status */
|
||||||
struct router_instance
|
ROUTER_STATS stats; /*< Statistics for this router */
|
||||||
*next;
|
struct router_instance
|
||||||
|
*next;
|
||||||
} ROUTER_INSTANCE;
|
} ROUTER_INSTANCE;
|
||||||
#endif
|
#endif
|
||||||
|
@ -284,7 +284,7 @@ char task_name[BLRM_TASK_NAME_LEN+1] = "";
|
|||||||
inst->m_errno = 0;
|
inst->m_errno = 0;
|
||||||
inst->m_errmsg = NULL;
|
inst->m_errmsg = NULL;
|
||||||
|
|
||||||
inst->trx_safe = 1;
|
inst->trx_safe = 0;
|
||||||
inst->pending_transaction = 0;
|
inst->pending_transaction = 0;
|
||||||
inst->last_safe_pos = 0;
|
inst->last_safe_pos = 0;
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -4653,7 +4653,7 @@ static void rwsplit_process_router_options(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Error Handler routine to resolve _backend_ failures. If it succeeds then there
|
* Error Handler routine to resolve _backend_ failures. If it succeeds then there
|
||||||
* are enough operative backends available and connected. Otherwise it fails,
|
* are enough operative backends available and connected. Otherwise it fails,
|
||||||
* and session is terminated.
|
* and session is terminated.
|
||||||
*
|
*
|
||||||
* @param instance The router instance
|
* @param instance The router instance
|
||||||
@ -4662,7 +4662,7 @@ static void rwsplit_process_router_options(
|
|||||||
* @param backend_dcb The backend DCB
|
* @param backend_dcb The backend DCB
|
||||||
* @param action The action: ERRACT_NEW_CONNECTION or ERRACT_REPLY_CLIENT
|
* @param action The action: ERRACT_NEW_CONNECTION or ERRACT_REPLY_CLIENT
|
||||||
* @param succp Result of action: true iff router can continue
|
* @param succp Result of action: true iff router can continue
|
||||||
*
|
*
|
||||||
* Even if succp == true connecting to new slave may have failed. succp is to
|
* Even if succp == true connecting to new slave may have failed. succp is to
|
||||||
* tell whether router has enough master/slave connections to continue work.
|
* tell whether router has enough master/slave connections to continue work.
|
||||||
*/
|
*/
|
||||||
@ -4670,7 +4670,7 @@ static void handleError (
|
|||||||
ROUTER* instance,
|
ROUTER* instance,
|
||||||
void* router_session,
|
void* router_session,
|
||||||
GWBUF* errmsgbuf,
|
GWBUF* errmsgbuf,
|
||||||
DCB* backend_dcb,
|
DCB* problem_dcb,
|
||||||
error_action_t action,
|
error_action_t action,
|
||||||
bool* succp)
|
bool* succp)
|
||||||
{
|
{
|
||||||
@ -4678,10 +4678,10 @@ static void handleError (
|
|||||||
ROUTER_INSTANCE* inst = (ROUTER_INSTANCE *)instance;
|
ROUTER_INSTANCE* inst = (ROUTER_INSTANCE *)instance;
|
||||||
ROUTER_CLIENT_SES* rses = (ROUTER_CLIENT_SES *)router_session;
|
ROUTER_CLIENT_SES* rses = (ROUTER_CLIENT_SES *)router_session;
|
||||||
|
|
||||||
CHK_DCB(backend_dcb);
|
CHK_DCB(problem_dcb);
|
||||||
|
|
||||||
/** Don't handle same error twice on same DCB */
|
/** Don't handle same error twice on same DCB */
|
||||||
if (backend_dcb->dcb_errhandle_called)
|
if (problem_dcb->dcb_errhandle_called)
|
||||||
{
|
{
|
||||||
/** we optimistically assume that previous call succeed */
|
/** we optimistically assume that previous call succeed */
|
||||||
/*
|
/*
|
||||||
@ -4693,24 +4693,28 @@ static void handleError (
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
backend_dcb->dcb_errhandle_called = true;
|
problem_dcb->dcb_errhandle_called = true;
|
||||||
}
|
}
|
||||||
session = backend_dcb->session;
|
session = problem_dcb->session;
|
||||||
|
|
||||||
if (session == NULL || rses == NULL)
|
if (session == NULL || rses == NULL)
|
||||||
{
|
{
|
||||||
*succp = false;
|
*succp = false;
|
||||||
}
|
}
|
||||||
|
else if (dcb_isclient(problem_dcb))
|
||||||
|
{
|
||||||
|
*succp = false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CHK_SESSION(session);
|
CHK_SESSION(session);
|
||||||
CHK_CLIENT_RSES(rses);
|
CHK_CLIENT_RSES(rses);
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case ERRACT_NEW_CONNECTION:
|
case ERRACT_NEW_CONNECTION:
|
||||||
{
|
{
|
||||||
SERVER* srv;
|
SERVER* srv;
|
||||||
|
|
||||||
if (!rses_begin_locked_router_action(rses))
|
if (!rses_begin_locked_router_action(rses))
|
||||||
{
|
{
|
||||||
*succp = false;
|
*succp = false;
|
||||||
@ -4718,14 +4722,14 @@ static void handleError (
|
|||||||
}
|
}
|
||||||
srv = rses->rses_master_ref->bref_backend->backend_server;
|
srv = rses->rses_master_ref->bref_backend->backend_server;
|
||||||
/**
|
/**
|
||||||
* If master has lost its Master status error can't be
|
* If master has lost its Master status error can't be
|
||||||
* handled so that session could continue.
|
* handled so that session could continue.
|
||||||
*/
|
*/
|
||||||
if (rses->rses_master_ref->bref_dcb == backend_dcb &&
|
if (rses->rses_master_ref->bref_dcb == problem_dcb &&
|
||||||
!SERVER_IS_MASTER(srv))
|
!SERVER_IS_MASTER(srv))
|
||||||
{
|
{
|
||||||
backend_ref_t* bref;
|
backend_ref_t* bref;
|
||||||
bref = get_bref_from_dcb(rses, backend_dcb);
|
bref = get_bref_from_dcb(rses, problem_dcb);
|
||||||
if (bref != NULL)
|
if (bref != NULL)
|
||||||
{
|
{
|
||||||
CHK_BACKEND_REF(bref);
|
CHK_BACKEND_REF(bref);
|
||||||
@ -4739,7 +4743,7 @@ static void handleError (
|
|||||||
"corresponding backend ref.",
|
"corresponding backend ref.",
|
||||||
srv->name,
|
srv->name,
|
||||||
srv->port);
|
srv->port);
|
||||||
dcb_close(backend_dcb);
|
dcb_close(problem_dcb);
|
||||||
}
|
}
|
||||||
if (!srv->master_err_is_logged)
|
if (!srv->master_err_is_logged)
|
||||||
{
|
{
|
||||||
@ -4756,35 +4760,35 @@ static void handleError (
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* This is called in hope of getting replacement for
|
* This is called in hope of getting replacement for
|
||||||
* failed slave(s). This call may free rses.
|
* failed slave(s). This call may free rses.
|
||||||
*/
|
*/
|
||||||
*succp = handle_error_new_connection(inst,
|
*succp = handle_error_new_connection(inst,
|
||||||
&rses,
|
&rses,
|
||||||
backend_dcb,
|
problem_dcb,
|
||||||
errmsgbuf);
|
errmsgbuf);
|
||||||
}
|
}
|
||||||
/* Free the lock if rses still exists */
|
/* Free the lock if rses still exists */
|
||||||
if (rses) rses_end_locked_router_action(rses);
|
if (rses) rses_end_locked_router_action(rses);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ERRACT_REPLY_CLIENT:
|
case ERRACT_REPLY_CLIENT:
|
||||||
{
|
{
|
||||||
handle_error_reply_client(session,
|
handle_error_reply_client(session,
|
||||||
rses,
|
rses,
|
||||||
backend_dcb,
|
problem_dcb,
|
||||||
errmsgbuf);
|
errmsgbuf);
|
||||||
*succp = false; /*< no new backend servers were made available */
|
*succp = false; /*< no new backend servers were made available */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
*succp = false;
|
*succp = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dcb_close(backend_dcb);
|
dcb_close(problem_dcb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -4797,7 +4801,7 @@ static void handle_error_reply_client(
|
|||||||
session_state_t sesstate;
|
session_state_t sesstate;
|
||||||
DCB* client_dcb;
|
DCB* client_dcb;
|
||||||
backend_ref_t* bref;
|
backend_ref_t* bref;
|
||||||
|
|
||||||
spinlock_acquire(&ses->ses_lock);
|
spinlock_acquire(&ses->ses_lock);
|
||||||
sesstate = ses->state;
|
sesstate = ses->state;
|
||||||
client_dcb = ses->client;
|
client_dcb = ses->client;
|
||||||
@ -4812,7 +4816,7 @@ static void handle_error_reply_client(
|
|||||||
bref_clear_state(bref, BREF_IN_USE);
|
bref_clear_state(bref, BREF_IN_USE);
|
||||||
bref_set_state(bref, BREF_CLOSED);
|
bref_set_state(bref, BREF_CLOSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sesstate == SESSION_STATE_ROUTER_READY)
|
if (sesstate == SESSION_STATE_ROUTER_READY)
|
||||||
{
|
{
|
||||||
CHK_DCB(client_dcb);
|
CHK_DCB(client_dcb);
|
||||||
|
@ -4001,7 +4001,7 @@ return_succp:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Error Handler routine to resolve _backend_ failures. If it succeeds then there
|
* Error Handler routine to resolve _backend_ failures. If it succeeds then there
|
||||||
* are enough operative backends available and connected. Otherwise it fails,
|
* are enough operative backends available and connected. Otherwise it fails,
|
||||||
* and session is terminated.
|
* and session is terminated.
|
||||||
*
|
*
|
||||||
* @param instance The router instance
|
* @param instance The router instance
|
||||||
@ -4010,7 +4010,7 @@ return_succp:
|
|||||||
* @param backend_dcb The backend DCB
|
* @param backend_dcb The backend DCB
|
||||||
* @param action The action: ERRACT_NEW_CONNECTION or ERRACT_REPLY_CLIENT
|
* @param action The action: ERRACT_NEW_CONNECTION or ERRACT_REPLY_CLIENT
|
||||||
* @param succp Result of action: true iff router can continue
|
* @param succp Result of action: true iff router can continue
|
||||||
*
|
*
|
||||||
* Even if succp == true connecting to new slave may have failed. succp is to
|
* Even if succp == true connecting to new slave may have failed. succp is to
|
||||||
* tell whether router has enough master/slave connections to continue work.
|
* tell whether router has enough master/slave connections to continue work.
|
||||||
*/
|
*/
|
||||||
@ -4018,7 +4018,7 @@ static void handleError (
|
|||||||
ROUTER* instance,
|
ROUTER* instance,
|
||||||
void* router_session,
|
void* router_session,
|
||||||
GWBUF* errmsgbuf,
|
GWBUF* errmsgbuf,
|
||||||
DCB* backend_dcb,
|
DCB* problem_dcb,
|
||||||
error_action_t action,
|
error_action_t action,
|
||||||
bool* succp)
|
bool* succp)
|
||||||
{
|
{
|
||||||
@ -4026,10 +4026,10 @@ static void handleError (
|
|||||||
ROUTER_INSTANCE* inst = (ROUTER_INSTANCE *)instance;
|
ROUTER_INSTANCE* inst = (ROUTER_INSTANCE *)instance;
|
||||||
ROUTER_CLIENT_SES* rses = (ROUTER_CLIENT_SES *)router_session;
|
ROUTER_CLIENT_SES* rses = (ROUTER_CLIENT_SES *)router_session;
|
||||||
|
|
||||||
CHK_DCB(backend_dcb);
|
CHK_DCB(problem_dcb);
|
||||||
|
|
||||||
/** Don't handle same error twice on same DCB */
|
/** Don't handle same error twice on same DCB */
|
||||||
if (backend_dcb->dcb_errhandle_called)
|
if (problem_dcb->dcb_errhandle_called)
|
||||||
{
|
{
|
||||||
/** we optimistically assume that previous call succeed */
|
/** we optimistically assume that previous call succeed */
|
||||||
*succp = true;
|
*succp = true;
|
||||||
@ -4037,19 +4037,23 @@ static void handleError (
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
backend_dcb->dcb_errhandle_called = true;
|
problem_dcb->dcb_errhandle_called = true;
|
||||||
}
|
}
|
||||||
session = backend_dcb->session;
|
session = problem_dcb->session;
|
||||||
|
|
||||||
if (session == NULL || rses == NULL)
|
if (session == NULL || rses == NULL)
|
||||||
{
|
{
|
||||||
*succp = false;
|
*succp = false;
|
||||||
}
|
}
|
||||||
|
else if (dcb_isclient(problem_dcb))
|
||||||
|
{
|
||||||
|
*succp = false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CHK_SESSION(session);
|
CHK_SESSION(session);
|
||||||
CHK_CLIENT_RSES(rses);
|
CHK_CLIENT_RSES(rses);
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case ERRACT_NEW_CONNECTION:
|
case ERRACT_NEW_CONNECTION:
|
||||||
{
|
{
|
||||||
@ -4059,33 +4063,33 @@ static void handleError (
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* This is called in hope of getting replacement for
|
* This is called in hope of getting replacement for
|
||||||
* failed slave(s).
|
* failed slave(s).
|
||||||
*/
|
*/
|
||||||
*succp = handle_error_new_connection(inst,
|
*succp = handle_error_new_connection(inst,
|
||||||
rses,
|
rses,
|
||||||
backend_dcb,
|
problem_dcb,
|
||||||
errmsgbuf);
|
errmsgbuf);
|
||||||
rses_end_locked_router_action(rses);
|
rses_end_locked_router_action(rses);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ERRACT_REPLY_CLIENT:
|
case ERRACT_REPLY_CLIENT:
|
||||||
{
|
{
|
||||||
handle_error_reply_client(session,
|
handle_error_reply_client(session,
|
||||||
rses,
|
rses,
|
||||||
backend_dcb,
|
problem_dcb,
|
||||||
errmsgbuf);
|
errmsgbuf);
|
||||||
*succp = false; /*< no new backend servers were made available */
|
*succp = false; /*< no new backend servers were made available */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
*succp = false;
|
*succp = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dcb_close(backend_dcb);
|
dcb_close(problem_dcb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user