From d1551be54fea235fc7b1c203ae20bf31fd40d004 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Thu, 23 Apr 2015 19:35:08 +0300 Subject: [PATCH] Added support for disabling the saving of the session command history for the schemarouter. --- server/modules/include/schemarouter.h | 15 ++--- .../routing/schemarouter/schemarouter.c | 59 ++++++++++++++++++- 2 files changed, 64 insertions(+), 10 deletions(-) diff --git a/server/modules/include/schemarouter.h b/server/modules/include/schemarouter.h index 83db86dc6..e15d79357 100644 --- a/server/modules/include/schemarouter.h +++ b/server/modules/include/schemarouter.h @@ -136,6 +136,7 @@ typedef struct mysql_sescmd_st { GWBUF* my_sescmd_buf; /*< Query buffer */ unsigned char my_sescmd_packet_type;/*< Packet type */ bool my_sescmd_is_replied; /*< Is cmd replied to client */ + int position; /*< Position of this command */ #if defined(SS_DEBUG) skygw_chk_t my_sescmd_chk_tail; #endif @@ -170,6 +171,7 @@ typedef struct sescmd_cursor_st { rses_property_t** scmd_cur_ptr_property; /*< address of pointer to owner property */ mysql_sescmd_t* scmd_cur_cmd; /*< pointer to current session command */ bool scmd_cur_active; /*< true if command is being executed */ + int position; /*< Position of this cursor */ #if defined(SS_DEBUG) skygw_chk_t scmd_cur_chk_tail; #endif @@ -221,6 +223,7 @@ typedef struct backend_ref_st { DCB* bref_dcb; /*< Backend DCB */ bref_state_t bref_state; /*< State of the backend */ bool bref_mapped; /*< Whether the backend has been mapped */ + bool last_sescmd_replied; int bref_num_result_wait; /*< Number of not yet received results */ sescmd_cursor_t bref_sescmd_cur; /*< Session command cursor */ GWBUF* bref_pending_cmd; /*< For stmt which can't be routed due active sescmd execution */ @@ -237,6 +240,7 @@ typedef struct schemarouter_config_st { int rw_max_slave_conn_count; target_t rw_use_sql_variables_in; int max_sescmd_hist; + bool disable_sescmd_hist; } schemarouter_config_t; /** @@ -248,6 +252,7 @@ typedef struct { int longest_sescmd; /*< Longest chain of stored session commands */ int n_hist_exceeded;/*< Number of sessions that exceeded session * command history limit */ + time_t ses_longest; /*< Session start time */ } ROUTER_STATS; /** @@ -280,7 +285,8 @@ struct router_client_session { DCB* dcb_route; /*< Internal DCB used to trigger re-routing of buffers */ DCB* dcb_reply; /*< Internal DCB used to send replies to the client */ ROUTER_STATS stats; /*< Statistics for this router */ - int n_sescmd; + int n_sescmd; + int pos_generator; #if defined(SS_DEBUG) skygw_chk_t rses_chk_tail; #endif @@ -303,15 +309,10 @@ typedef struct router_instance { ROUTER_STATS stats; /*< Statistics for this router */ struct router_instance* next; /*< Next router on the list */ bool available_slaves; /*< The router has some slaves available */ - //HASHTABLE* dbnames_hash; /** Hashtable containing the database names and where to find them */ - //char** ignore_list; + } ROUTER_INSTANCE; #define BACKEND_TYPE(b) (SERVER_IS_MASTER((b)->backend_server) ? BE_MASTER : \ (SERVER_IS_SLAVE((b)->backend_server) ? BE_SLAVE : BE_UNDEFINED)); -#if 0 -void* dbnames_hash_init(ROUTER_INSTANCE* inst,BACKEND** backends); -bool update_dbnames_hash(ROUTER_INSTANCE* inst,BACKEND** backends, HASHTABLE* hashtable); -#endif #endif /*< _SCHEMAROUTER_H */ diff --git a/server/modules/routing/schemarouter/schemarouter.c b/server/modules/routing/schemarouter/schemarouter.c index 508a61e06..d9b190237 100644 --- a/server/modules/routing/schemarouter/schemarouter.c +++ b/server/modules/routing/schemarouter/schemarouter.c @@ -721,6 +721,11 @@ createInstance(SERVICE *service, char **options) } router->service = service; router->schemarouter_config.max_sescmd_hist = 0; + router->stats.longest_sescmd = 0; + router->stats.n_hist_exceeded = 0; + router->stats.n_queries = 0; + router->stats.n_sescmd = 0; + router->stats.ses_longest = 0; spinlock_init(&router->lock); /** Calculate number of servers */ @@ -752,6 +757,10 @@ createInstance(SERVICE *service, char **options) { router->schemarouter_config.max_sescmd_hist = atoi(value); } + else if(strcmp(options[i],"disable_sescmd_history") == 0) + { + router->schemarouter_config.disable_sescmd_hist = config_truth_value(value); + } else { skygw_log_write(LOGFILE_ERROR,"Error: Unknown router options for Schemarouter: %s",options[i]); @@ -1158,14 +1167,15 @@ static void closeSession( dcb_close(router_cli_ses->dcb_reply); dcb_close(router_cli_ses->dcb_route); - - /** Unlock */ rses_end_locked_router_action(router_cli_ses); spinlock_acquire(&inst->lock); if(inst->stats.longest_sescmd < router_cli_ses->stats.longest_sescmd) inst->stats.longest_sescmd = router_cli_ses->stats.longest_sescmd; + time_t ses_time = difftime(time(NULL),router_cli_ses->rses_client_dcb->session->stats.connect); + if(inst->stats.ses_longest < ses_time) + inst->stats.ses_longest = ses_time; spinlock_release(&inst->lock); } } @@ -2342,6 +2352,10 @@ diagnostic(ROUTER *instance, DCB *dcb) router->stats.longest_sescmd); dcb_printf(dcb,"Session command history limit exceeded: %d times\n", router->stats.n_hist_exceeded); + + dcb_printf(dcb,"\n\33[1;4mSession Time Statistics\33[0m\n"); + dcb_printf(dcb,"Longest session: %d seconds\n",router->stats.ses_longest); + dcb_printf(dcb,"\n"); } /** @@ -3186,7 +3200,7 @@ static mysql_sescmd_t* mysql_sescmd_init ( /** Set session command buffer */ sescmd->my_sescmd_buf = sescmd_buf; sescmd->my_sescmd_packet_type = packet_type; - + sescmd->position = atomic_add(&rses->pos_generator,1); return sescmd; } @@ -3238,6 +3252,7 @@ static GWBUF* sescmd_cursor_process_replies( */ while (scmd != NULL && replybuf != NULL) { + scur->position = scmd->position; /** Faster backend has already responded to client : discard */ if (scmd->my_sescmd_is_replied) { @@ -3805,6 +3820,44 @@ static bool route_session_write( goto return_succp; } + + if(router_cli_ses->rses_config.disable_sescmd_hist) + { + rses_property_t *prop, *tmp; + backend_ref_t* bref; + bool conflict; + + prop = router_cli_ses->rses_properties[RSES_PROP_TYPE_SESCMD]; + while(prop) + { + conflict = false; + + for(i = 0;irses_nbackends;i++) + { + bref = &backend_ref[i]; + if(BREF_IS_IN_USE(bref)) + { + + if(bref->bref_sescmd_cur.position <= prop->rses_prop_data.sescmd.position) + { + conflict = true; + break; + } + } + } + + if(conflict) + { + break; + } + + tmp = prop; + router_cli_ses->rses_properties[RSES_PROP_TYPE_SESCMD] = prop->rses_prop_next; + rses_property_done(tmp); + prop = router_cli_ses->rses_properties[RSES_PROP_TYPE_SESCMD]; + } + } + /** * * Additional reference is created to querybuf to