MXS-1661 Introduce 'users_refresh_time'

It is now possible to explicitly specify how frequently MaxScale
may refresh the users of a service.
This commit is contained in:
Johan Wikman
2018-02-09 11:40:17 +02:00
parent ae160f3ff2
commit b4760c5bbe
6 changed files with 80 additions and 6 deletions

View File

@ -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

View File

@ -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

View File

@ -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;
/**

View File

@ -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

View File

@ -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++)

View File

@ -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;
}
}