MXS-1310: Add deterministic conflict resolution

The schemarouter can now resolve database mapping conflicts in a
deterministic manner. This will fix the problem of central databases which
are replicated shards being assigned in a non-deterministic manner.
This commit is contained in:
Markus Mäkelä 2017-07-05 19:19:49 +03:00
parent a23e81c438
commit 9618e63b5f
3 changed files with 28 additions and 3 deletions

View File

@ -51,6 +51,17 @@ List of databases to ignore when checking for duplicate databases.
Regular expression that is matched against database names when checking for duplicate databases.
### `preferred_server`
The name of a server in MaxScale which will be used as the preferred server when
a database is found on more than one server. If a database exists on two
servers, of which neither is the server referred by this parameter, the server
that replies first will be assigned as the location of the database.
This parameter allows deterministic conflict resolution when a sharded cluster
has a central database server and one or more sharded databases spread across
multiple servers which replicate from the central database server.
**Note:** As of version 2.1 of MaxScale, all of the router options can also be
defined as parameters. The values defined in _router_options_ will have priority
over the parameters.

View File

@ -357,6 +357,17 @@ showdb_response_t parse_showdb_response(ROUTER_CLIENT_SES* rses, backend_ref_t*
rses->rses_client_dcb->user,
rses->rses_client_dcb->remote);
}
else if (rses->router->preferred_server &&
strcmp(target, rses->router->preferred_server->unique_name) == 0)
{
/** In conflict situations, use the preferred server */
MXS_INFO("Forcing location of '%s' from '%s' to ''%s",
data, (char*)hashtable_fetch(rses->shardmap->hash,
data), target);
hashtable_delete(rses->shardmap->hash, data);
hashtable_add(rses->shardmap->hash, data, target);
}
}
MXS_FREE(data);
}
@ -651,6 +662,7 @@ MXS_MODULE* MXS_CREATE_MODULE()
{"refresh_databases", MXS_MODULE_PARAM_BOOL, "true"},
{"refresh_interval", MXS_MODULE_PARAM_COUNT, DEFAULT_REFRESH_INTERVAL},
{"debug", MXS_MODULE_PARAM_BOOL, "false"},
{"preferred_server", MXS_MODULE_PARAM_SERVER},
{MXS_END_MODULE_PARAMS}
}
};
@ -719,6 +731,7 @@ static MXS_ROUTER* createInstance(SERVICE *service, char **options)
router->schemarouter_config.max_sescmd_hist = config_get_integer(conf, "max_sescmd_history");
router->schemarouter_config.disable_sescmd_hist = config_get_bool(conf, "disable_sescmd_history");
router->schemarouter_config.debug = config_get_bool(conf, "debug");
router->preferred_server = config_get_server(conf, "preferred_server");
if ((config_get_param(conf, "auth_all_servers")) == NULL)
{

View File

@ -365,14 +365,15 @@ typedef struct router_instance
unsigned int bitvalue; /*< Required value of server->status */
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 */
bool available_slaves; /*< The router has some slaves available */
HASHTABLE* ignored_dbs; /*< List of databases to ignore when the
* database mapping finds multiple servers
* with the same database */
pcre2_code* ignore_regex; /*< Databases matching this regex will
pcre2_code* ignore_regex; /*< Databases matching this regex will
* not cause the session to be terminated
* if they are found on more than one server. */
pcre2_match_data* ignore_match_data;
pcre2_match_data* ignore_match_data;
SERVER* preferred_server; /**< Server to prefer in conflict situations */
} ROUTER_INSTANCE;