diff --git a/Documentation/Getting-Started/Configuration-Guide.md b/Documentation/Getting-Started/Configuration-Guide.md index 947741d2d..127444a3b 100644 --- a/Documentation/Getting-Started/Configuration-Guide.md +++ b/Documentation/Getting-Started/Configuration-Guide.md @@ -548,6 +548,22 @@ has multiple interfaces. local_address=192.168.1.254 ``` +#### `users_refresh_time` + +How often, in seconds, MaxScale at most may refresh the users from the +backend server. + +MaxScale will at startup load the users from the backend server, but if +the authentication of a user fails, MaxScale assumes it is because a new +user has been created and will thus refresh the users. By default, MaxScale +will do that at most once per 30 seconds and with this configuration option +that can be changed. The minimum allowed value is 10 seconds. A negative +value disables the refreshing entirelly. Note that using `maxadmin` it is +possible to explicitly cause the users of a service to be reloaded. +``` +users_refresh_time=120 +``` + ### Service A service represents the database service that MariaDB MaxScale offers to the diff --git a/Documentation/Release-Notes/MaxScale-2.1.14-Release-Notes.md b/Documentation/Release-Notes/MaxScale-2.1.14-Release-Notes.md index eb9f4426f..80b3ca07f 100644 --- a/Documentation/Release-Notes/MaxScale-2.1.14-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-2.1.14-Release-Notes.md @@ -28,6 +28,12 @@ For any problems you encounter, please consider submitting a bug report at ## New Features +### Users Refresh Time + +It is now possible to adjust how frequently MaxScale may refresh +the users of service. Please refer to the documentation for +[details](../Getting-Started/Configuration-Guide.md#users_refresh_time). + ### Local Address It is now possible to specify what local address MaxScale should diff --git a/include/maxscale/config.h b/include/maxscale/config.h index 7a1265470..4337d6f77 100644 --- a/include/maxscale/config.h +++ b/include/maxscale/config.h @@ -78,6 +78,7 @@ typedef struct int query_retries; /**< Number of times a interrupted query is retried */ time_t query_retry_timeout; /**< Timeout for query retries */ char* local_address; /**< Local address to use when connecting */ + time_t users_refresh_time; /**< How often the users can be refreshed */ } MXS_CONFIG; /** diff --git a/include/maxscale/service.h b/include/maxscale/service.h index 72de694f5..871ea6d0b 100644 --- a/include/maxscale/service.h +++ b/include/maxscale/service.h @@ -99,7 +99,8 @@ typedef struct server_ref_t #define SERVICE_PARAM_UNINIT -1 /* Refresh rate limits for load users from database */ -#define USERS_REFRESH_TIME 30 /* Allowed time interval (in seconds) after last update*/ +#define USERS_REFRESH_TIME_DEFAULT 30 /* Allowed time interval (in seconds) after last update*/ +#define USERS_REFRESH_TIME_MIN 10 /* Minimum allowed time interval (in seconds)*/ /** Default timeout values used by the connections which fetch user authentication data */ #define DEFAULT_AUTH_CONNECT_TIMEOUT 3 diff --git a/server/core/config.c b/server/core/config.c index bd31b3f6b..348491205 100644 --- a/server/core/config.c +++ b/server/core/config.c @@ -1405,6 +1405,44 @@ handle_global_item(const char *name, const char *value) { gateway.local_address = MXS_STRDUP_A(value); } + else if (strcmp(name, "users_refresh_time") == 0) + { + char* endptr; + long users_refresh_time = strtol(value, &endptr, 0); + if (*endptr == '\0') + { + if (users_refresh_time < 0) + { + MXS_NOTICE("Value of 'users_refresh_time' is less than 0, users will " + "not be automatically refreshed."); + // Strictly speaking they will be refreshed once every 68 years, + // but I just don't beleave the uptime will be that long. + users_refresh_time = INT32_MAX; + } + else if (users_refresh_time < USERS_REFRESH_TIME_MIN) + { + MXS_WARNING("%s is less than the allowed minimum value of %d for the " + "configuration option 'users_refresh_time', using the minimum value.", + value, USERS_REFRESH_TIME_MIN); + users_refresh_time = USERS_REFRESH_TIME_MIN; + } + + if (users_refresh_time > INT32_MAX) + { + // To ensure that there will be no overflows when + // we later do arithmetic. + users_refresh_time = INT32_MAX; + } + + gateway.users_refresh_time = users_refresh_time; + } + else + { + MXS_ERROR("%s is an invalid value for 'users_refresh_time', " + "using default %d instead.", value, USERS_REFRESH_TIME_DEFAULT); + gateway.users_refresh_time = USERS_REFRESH_TIME_DEFAULT; + } + } else { for (i = 0; lognames[i].name; i++) diff --git a/server/core/service.c b/server/core/service.c index c69d73e26..8fb3a2dc5 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -337,10 +337,19 @@ serviceStartPort(SERVICE *service, SERV_LISTENER *port) /** * At service start last update is set to USERS_REFRESH_TIME seconds earlier. This way MaxScale - * could try reloading users just after startup. + * could try reloading users just after startup. But only if user refreshing has not been turned off. */ - service->rate_limit.last = time(NULL) - USERS_REFRESH_TIME; - service->rate_limit.warned = false; + MXS_CONFIG* config = config_get_global_options(); + if (config->users_refresh_time == INT32_MAX) + { + service->rate_limit.last = time(NULL); + service->rate_limit.warned = true; // So that there will not be a refresh rate warning. + } + else + { + service->rate_limit.last = time(NULL) - config->users_refresh_time; + service->rate_limit.warned = false; + } if (port->listener->func.listen(port->listener, config_bind)) { @@ -1612,13 +1621,16 @@ int service_refresh_users(SERVICE *service) if (spinlock_acquire_nowait(&service->spin)) { time_t now = time(NULL); + MXS_CONFIG* config = config_get_global_options(); /* Check if refresh rate limit has been exceeded */ - if (now < service->rate_limit.last + USERS_REFRESH_TIME) + if (now < service->rate_limit.last + config->users_refresh_time) { if (!service->rate_limit.warned) { - MXS_WARNING("[%s] Refresh rate limit exceeded for load of users' table.", service->name); + MXS_WARNING("[%s] Refresh rate limit (once every %ld seconds) exceeded for " + "load of users' table.", + service->name, config->users_refresh_time); service->rate_limit.warned = true; } }