diff --git a/src/base/xserver_interface.h b/src/base/xserver_interface.h index 8fb3e8456e..7c85405b62 100644 --- a/src/base/xserver_interface.h +++ b/src/base/xserver_interface.h @@ -262,7 +262,7 @@ extern int xlocator_upgrade_instances_domain (THREAD_ENTRY * thread_p, OID * cla extern int xsession_create_new (THREAD_ENTRY * thread_p, SESSION_ID * id); extern int xsession_check_session (THREAD_ENTRY * thread_p, const SESSION_ID id); -extern int xsession_end_session (THREAD_ENTRY * thread, const SESSION_ID id); +extern int xsession_end_session (THREAD_ENTRY * thread, const SESSION_ID id, bool is_keep_session); extern int xsession_set_row_count (THREAD_ENTRY * thread_p, int row_count); extern int xsession_get_row_count (THREAD_ENTRY * thread_p, int *row_count); diff --git a/src/broker/cas.c b/src/broker/cas.c index 0baf8e44bc..c99e546184 100644 --- a/src/broker/cas.c +++ b/src/broker/cas.c @@ -127,6 +127,7 @@ static void set_db_connection_info (void); static void clear_db_connection_info (void); static bool need_database_reconnect (void); +extern bool db_Keep_session; extern bool ssl_client; extern int cas_init_ssl (int); extern void cas_ssl_close (int client_sock_fd); @@ -1974,11 +1975,13 @@ process_request (SOCKET sock_fd, T_NET_BUF * net_buf, T_REQ_INFO * req_info) cas_log_msg = "RESET"; cas_log_write_and_end (0, true, cas_log_msg); fn_ret = FN_KEEP_SESS; + db_Keep_session = true; } if (as_info->con_status == CON_STATUS_CLOSE_AND_CONNECT) { cas_log_msg = "CHANGE CLIENT"; fn_ret = FN_KEEP_SESS; + db_Keep_session = true; } if (cas_log_msg == NULL) @@ -2170,6 +2173,10 @@ process_request (SOCKET sock_fd, T_NET_BUF * net_buf, T_REQ_INFO * req_info) net_buf->client_version = req_info->client_version; set_hang_check_time (); fn_ret = (*server_fn) (sock_fd, argc, argv, net_buf, req_info); + if (fn_ret == FN_KEEP_SESS) + { + db_Keep_session = true; + } set_hang_check_time (); #if !defined(CAS_FOR_ORACLE) && !defined(CAS_FOR_MYSQL) @@ -2242,6 +2249,7 @@ process_request (SOCKET sock_fd, T_NET_BUF * net_buf, T_REQ_INFO * req_info) else if (restart_is_needed ()) { fn_ret = FN_KEEP_SESS; + db_Keep_session = true; } if (shm_appl->sql_log2 != as_info->cur_sql_log2) { @@ -2352,6 +2360,7 @@ process_request (SOCKET sock_fd, T_NET_BUF * net_buf, T_REQ_INFO * req_info) { cas_log_debug (ARG_FILE_LINE, "process_request: reset_flag && !CON_STATUS_IN_TRAN"); fn_ret = FN_KEEP_SESS; + db_Keep_session = true; goto exit_on_end; } diff --git a/src/communication/network_interface_cl.c b/src/communication/network_interface_cl.c index 8e4c74779a..2fb0db7156 100644 --- a/src/communication/network_interface_cl.c +++ b/src/communication/network_interface_cl.c @@ -101,6 +101,8 @@ static int net_Deferred_end_queries_count = 0; */ unsigned int db_on_server = 0; +extern bool db_Keep_session; + #if defined(CS_MODE) static char *pack_const_string (char *buffer, const char *cstring); static char *pack_string_with_null_padding (char *buffer, const char *stream, int len); @@ -4742,7 +4744,7 @@ csession_end_session (SESSION_ID session_id) int req_error; OR_ALIGNED_BUF (OR_INT_SIZE) a_reply; char *reply; - OR_ALIGNED_BUF (OR_INT_SIZE) a_request; + OR_ALIGNED_BUF (OR_INT_SIZE * 2) a_request; char *request; char *ptr; @@ -4750,6 +4752,7 @@ csession_end_session (SESSION_ID session_id) request = OR_ALIGNED_BUF_START (a_request); ptr = or_pack_int (request, session_id); + ptr = or_pack_int (ptr, db_Keep_session); req_error = net_client_request (NET_SERVER_SES_END_SESSION, request, OR_ALIGNED_BUF_SIZE (a_request), reply, @@ -4765,7 +4768,7 @@ csession_end_session (SESSION_ID session_id) THREAD_ENTRY *thread_p = enter_server (); - result = xsession_end_session (thread_p, session_id); + result = xsession_end_session (thread_p, session_id, db_Keep_session); exit_server (*thread_p); diff --git a/src/communication/network_interface_sr.c b/src/communication/network_interface_sr.c index 1f0ca0742d..a74478f28e 100644 --- a/src/communication/network_interface_sr.c +++ b/src/communication/network_interface_sr.c @@ -8986,14 +8986,16 @@ void ssession_end_session (THREAD_ENTRY * thread_p, unsigned int rid, char *request, int reqlen) { int err = NO_ERROR; + int is_keep_session; SESSION_ID id; OR_ALIGNED_BUF (OR_INT_SIZE) a_reply; char *reply = OR_ALIGNED_BUF_START (a_reply); char *ptr = NULL; - (void) or_unpack_int (request, (int *) &id); + ptr = or_unpack_int (request, (int *) &id); + ptr = or_unpack_int (ptr, (int *) &is_keep_session); - err = xsession_end_session (thread_p, id); + err = xsession_end_session (thread_p, id, (bool) is_keep_session); ptr = or_pack_int (reply, err); css_send_data_to_client (thread_p->conn_entry, rid, reply, OR_ALIGNED_BUF_SIZE (a_reply)); diff --git a/src/compat/db_admin.c b/src/compat/db_admin.c index 823c495fcb..af18c4606e 100644 --- a/src/compat/db_admin.c +++ b/src/compat/db_admin.c @@ -101,6 +101,8 @@ struct db_host_status_list The macros for testing this variable were moved to db.h so the query interface functions can use them as well. */ +extern bool db_Keep_session; + char db_Database_name[DB_MAX_IDENTIFIER_LENGTH + 1]; char db_Program_name[PATH_MAX]; char db_Client_ip_addr[16] = { 0 }; diff --git a/src/compat/db_macro.c b/src/compat/db_macro.c index 2fd7addab9..f73a2f4387 100644 --- a/src/compat/db_macro.c +++ b/src/compat/db_macro.c @@ -90,6 +90,7 @@ int db_Connect_status = DB_CONNECTION_STATUS_CONNECTED; int db_Connect_status = DB_CONNECTION_STATUS_NOT_CONNECTED; #endif int db_Disable_modifications = 0; +bool db_Keep_session = false; static int transfer_string (char *dst, int *xflen, int *outlen, const int dstlen, const char *src, diff --git a/src/session/session.c b/src/session/session.c index fab62a4997..e51f545d24 100644 --- a/src/session/session.c +++ b/src/session/session.c @@ -118,6 +118,7 @@ struct session_state pthread_mutex_t mutex; /* state mutex */ UINT64 del_id; /* delete transaction ID (for lock free) */ + bool is_keep_session; bool is_trigger_involved; bool is_last_insert_id_generated; bool auto_commit; @@ -302,6 +303,7 @@ session_state_init (void *st) /* initialize fields */ db_make_null (&session_p->cur_insert_id); db_make_null (&session_p->last_insert_id); + session_p->is_keep_session = false; session_p->is_trigger_involved = false; session_p->is_last_insert_id_generated = false; session_p->row_count = -1; @@ -743,9 +745,10 @@ session_state_create (THREAD_ENTRY * thread_p, SESSION_ID * id) * session_state_destroy () - close a session state * return : NO_ERROR or error code * id(in) : the identifier for the session + * is_keep_session(in) : whether to keep the session */ int -session_state_destroy (THREAD_ENTRY * thread_p, const SESSION_ID id) +session_state_destroy (THREAD_ENTRY * thread_p, const SESSION_ID id, bool is_keep_session) { SESSION_STATE *session_p; int error = NO_ERROR, success = 0; @@ -762,6 +765,13 @@ session_state_destroy (THREAD_ENTRY * thread_p, const SESSION_ID id) return ER_SES_SESSION_EXPIRED; } + if (is_keep_session == true) + { + session_p->is_keep_session = true; + pthread_mutex_unlock (&session_p->mutex); + return NO_ERROR; + } + #if defined (SERVER_MODE) assert (session_p->ref_count > 0); @@ -936,8 +946,17 @@ session_remove_expired_sessions (THREAD_ENTRY * thread_p) expired_sid_buffer[n_expired_sids++] = state->id; - /* Destroy the session related resources like session parameters */ - (void) session_state_uninit (state); + if (state->is_keep_session == true) + { + /* keep session */ + pthread_mutex_unlock (&state->mutex); + continue; + } + else + { + /* Destroy the session related resources like session parameters */ + (void) session_state_uninit (state); + } if (n_expired_sids == EXPIRED_SESSION_BUFFER_SIZE) { diff --git a/src/session/session.h b/src/session/session.h index 6b55c12afe..eafa019153 100644 --- a/src/session/session.h +++ b/src/session/session.h @@ -41,7 +41,7 @@ struct xasl_cache_ent; extern void session_states_init (THREAD_ENTRY * thread_p); extern void session_states_finalize (THREAD_ENTRY * thread_p); extern int session_state_create (THREAD_ENTRY * thread_p, SESSION_ID * id); -extern int session_state_destroy (THREAD_ENTRY * thread_p, const SESSION_ID id); +extern int session_state_destroy (THREAD_ENTRY * thread_p, const SESSION_ID id, bool is_keep_session); extern int session_check_session (THREAD_ENTRY * thread_p, const SESSION_ID id); extern int session_get_session_id (THREAD_ENTRY * thread_p, SESSION_ID * id); extern int session_get_last_insert_id (THREAD_ENTRY * thread_p, DB_VALUE * value, bool update_last_insert_id); diff --git a/src/session/session_sr.c b/src/session/session_sr.c index 107666218f..6b4a37d9a6 100644 --- a/src/session/session_sr.c +++ b/src/session/session_sr.c @@ -62,11 +62,12 @@ xsession_check_session (THREAD_ENTRY * thread_p, const SESSION_ID id) * return : error code * id (in) : session id * thread_p (in) + * is_keep_session (in) : whether to keep the session */ int -xsession_end_session (THREAD_ENTRY * thread_p, const SESSION_ID id) +xsession_end_session (THREAD_ENTRY * thread_p, const SESSION_ID id, bool is_keep_session) { - return session_state_destroy (thread_p, id); + return session_state_destroy (thread_p, id, is_keep_session); } /*