diff --git a/Documentation/Getting-Started/Configuration-Guide.md b/Documentation/Getting-Started/Configuration-Guide.md index c0da590b5..9c543217c 100644 --- a/Documentation/Getting-Started/Configuration-Guide.md +++ b/Documentation/Getting-Started/Configuration-Guide.md @@ -1230,6 +1230,22 @@ The following Server side config is needed too. session_track_transaction_info = CHARACTERISTICS ``` +#### `retain_last_statements` + +How many statements MaxScale should store for each session of this service. +This overrides the value of the global setting with the same name. If +`retain_last_statements` has been specified in the global section of the +MaxScale configuration file, then if it has _not_ been explicitly specified +for the service, the global value holds, otherwise the service specific +value rules. That is, it is possible to enable the setting globally and +turn it off for a specific service, or just enable it for specific services. + +The value of this parameter can be changed at runtime using `maxctrl` and the +new value will take effect for sessions created thereafter. +``` +maxctrl alter service MyService retain_last_statements 5 +``` + ### Server Server sections are used to define the backend database servers that can be diff --git a/Documentation/Release-Notes/MaxScale-2.3.1-Release-Notes.md b/Documentation/Release-Notes/MaxScale-2.3.1-Release-Notes.md index 62727a0ad..0a11c9b73 100644 --- a/Documentation/Release-Notes/MaxScale-2.3.1-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-2.3.1-Release-Notes.md @@ -51,6 +51,11 @@ feature can be used for debugging, if there is suspicion that MaxScale sends a particular statement to the wrong server (e.g. to a slave when it should be sent to the master). +### Services + +The global configuration parameter `retain_last_statements` can now +also be specified separately for individual services. + ## Bug fixes [Here is a list of bugs fixed in MaxScale 2.3.1.](https://jira.mariadb.org/issues/?jql=project%20%3D%20MXS%20AND%20issuetype%20%3D%20Bug%20AND%20status%20%3D%20Closed%20AND%20fixVersion%20%3D%202.3.1) diff --git a/include/maxscale/service.h b/include/maxscale/service.h index d67401102..e3f030a2b 100644 --- a/include/maxscale/service.h +++ b/include/maxscale/service.h @@ -150,6 +150,8 @@ typedef struct service * track mechanism */ int active; /**< Whether the service is still * active */ + int32_t retain_last_statements; /**< How many statements to retain per session, + * -1 if not explicitly specified. */ } SERVICE; typedef enum count_spec_t diff --git a/maxctrl/lib/alter.js b/maxctrl/lib/alter.js index 6635772e8..f753e16cd 100644 --- a/maxctrl/lib/alter.js +++ b/maxctrl/lib/alter.js @@ -26,7 +26,8 @@ const service_params = [ 'strip_db_esc', 'localhost_match_wildcard_host', 'max_slave_connections', - 'max_slave_replication_lag' + 'max_slave_replication_lag', + 'retain_last_statements' ] // List of maxscale parameters that can be altered at runtime diff --git a/server/core/config.cc b/server/core/config.cc index ca958e34a..a17277a81 100644 --- a/server/core/config.cc +++ b/server/core/config.cc @@ -315,6 +315,7 @@ const MXS_MODULE_PARAM config_service_params[] = {CN_LOG_AUTH_WARNINGS, MXS_MODULE_PARAM_BOOL, "true"}, {CN_RETRY_ON_FAILURE, MXS_MODULE_PARAM_BOOL, "true"}, {CN_SESSION_TRACK_TRX_STATE, MXS_MODULE_PARAM_BOOL, "false"}, + {CN_RETAIN_LAST_STATEMENTS, MXS_MODULE_PARAM_COUNT, "0"}, {NULL} }; diff --git a/server/core/internal/session.hh b/server/core/internal/session.hh index 91a5e9922..1a5fb9fff 100644 --- a/server/core/internal/session.hh +++ b/server/core/internal/session.hh @@ -100,7 +100,7 @@ public: using FilterList = std::vector; - Session(); + Session(SERVICE* service); ~Session(); bool setup_filters(Service* service); @@ -147,7 +147,7 @@ private: QueryInfos m_last_queries; /*< The N last queries by the client */ int m_current_query = -1; /*< The index of the current query */ DCBSet m_dcb_set; /*< Set of associated backend DCBs */ - bool m_retain_last_statements; /*< Should statement information be stored */ + uint32_t m_retain_last_statements; /*< How many statements be retained */ }; } diff --git a/server/core/service.cc b/server/core/service.cc index 951c7fe23..c1964d4b7 100644 --- a/server/core/service.cc +++ b/server/core/service.cc @@ -200,6 +200,15 @@ Service::Service(const std::string& service_name, strip_db_esc = config_get_bool(params, CN_STRIP_DB_ESC); session_track_trx_state = config_get_bool(params, CN_SESSION_TRACK_TRX_STATE); + if (config_get_param(params, CN_RETAIN_LAST_STATEMENTS)) + { + retain_last_statements = config_get_integer(params, CN_RETAIN_LAST_STATEMENTS); + } + else + { + retain_last_statements = -1; // Indicates that it has not been set. + } + /** * At service start last update is set to config->users_refresh_time seconds earlier. * This way MaxScale could try reloading users just after startup. But only if user @@ -2344,7 +2353,8 @@ bool Service::is_basic_parameter(const std::string& name) CN_USER, CN_VERSION_STRING, CN_WEIGHTBY, - CN_FILTERS + CN_FILTERS, + CN_RETAIN_LAST_STATEMENTS }; return names.find(name) != names.end(); @@ -2415,4 +2425,8 @@ void Service::update_basic_parameter(const std::string& key, const std::string& { retry_start = config_truth_value(value.c_str()); } + else if (key == CN_RETAIN_LAST_STATEMENTS) + { + retain_last_statements = std::stoi(value); + } } diff --git a/server/core/session.cc b/server/core/session.cc index 6c4e9a687..618efe3ea 100644 --- a/server/core/session.cc +++ b/server/core/session.cc @@ -109,7 +109,7 @@ MXS_SESSION* session_alloc(SERVICE* service, DCB* client_dcb) MXS_SESSION* session_alloc_with_id(SERVICE* service, DCB* client_dcb, uint64_t id) { - Session* session = new(std::nothrow) Session; + Session* session = new (std::nothrow) Session(service); if (session == nullptr) { @@ -1198,9 +1198,16 @@ const char* session_get_close_reason(const MXS_SESSION* session) } } -Session::Session() - : m_retain_last_statements(this_unit.retain_last_statements) +Session::Session(SERVICE* service) { + if (service->retain_last_statements != -1) // Explicitly set for the service + { + m_retain_last_statements = service->retain_last_statements; + } + else + { + m_retain_last_statements = this_unit.retain_last_statements; + } } Session::~Session() diff --git a/server/modules/filter/test/mock_session.cc b/server/modules/filter/test/mock_session.cc index cedb1da24..29686de51 100644 --- a/server/modules/filter/test/mock_session.cc +++ b/server/modules/filter/test/mock_session.cc @@ -13,6 +13,13 @@ #include "maxscale/mock/session.hh" +namespace +{ + +SERVICE dummy_service; + +} + namespace maxscale { @@ -20,7 +27,8 @@ namespace mock { Session::Session(Client* pClient) - : m_client(*pClient) + : mxs::Session(&dummy_service) + , m_client(*pClient) , m_client_dcb(this, pClient->user(), pClient->host(), pClient) { MXS_SESSION* pSession = this;