From 6c14ac7829ac44441368fefa82317423a4ecd2f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Sat, 11 Jan 2020 11:53:01 +0200 Subject: [PATCH] MXS-2834: Make retrying of trx deadlocks configurable The behavior is not desirable in all cases and should be enabled only if needed. --- Documentation/Routers/ReadWriteSplit.md | 13 +++++++++++++ .../routing/readwritesplit/readwritesplit.cc | 1 + .../routing/readwritesplit/readwritesplit.hh | 2 ++ .../routing/readwritesplit/rwsplitsession.cc | 3 ++- 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Documentation/Routers/ReadWriteSplit.md b/Documentation/Routers/ReadWriteSplit.md index 89a6a80ba..14c06f652 100644 --- a/Documentation/Routers/ReadWriteSplit.md +++ b/Documentation/Routers/ReadWriteSplit.md @@ -537,6 +537,19 @@ controls how many server and network failures a single transaction replay tolerates. If a transaction is replayed successfully, the counter for failed attempts is reset. +### `transaction_replay_retry_on_deadlock` + +Enable automatic retrying of transactions that end up in a deadlock. This +parameter was added in MaxScale 2.4.6 and the feature is disabled by +default. MaxScale versions from 2.4.0 to 2.4.5 always tried to replay deadlocked +transactions. + +If this feature is enabled and a transaction returns a deadlock error +(e.g. `SQLSTATE 40001: Deadlock found when trying to get lock; try restarting transaction`), +the transaction is automatically retried. If the retrying of the transaction +results in another deadlock error, it is retried until it either succeeds or a +transaction checksum error is encountered. + ### `optimistic_trx` Enable optimistic transaction execution. This parameter controls whether normal diff --git a/server/modules/routing/readwritesplit/readwritesplit.cc b/server/modules/routing/readwritesplit/readwritesplit.cc index d000009c6..f00ab9346 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.cc +++ b/server/modules/routing/readwritesplit/readwritesplit.cc @@ -520,6 +520,7 @@ extern "C" MXS_MODULE* MXS_CREATE_MODULE() {"transaction_replay", MXS_MODULE_PARAM_BOOL, "false"}, {"transaction_replay_max_size",MXS_MODULE_PARAM_SIZE, "1Mi"}, {"transaction_replay_attempts",MXS_MODULE_PARAM_COUNT, "5"}, + {"transaction_replay_retry_on_deadlock",MXS_MODULE_PARAM_BOOL, "false"}, {"optimistic_trx", MXS_MODULE_PARAM_BOOL, "false"}, {"lazy_connect", MXS_MODULE_PARAM_BOOL, "false"}, {MXS_END_MODULE_PARAMS} diff --git a/server/modules/routing/readwritesplit/readwritesplit.hh b/server/modules/routing/readwritesplit/readwritesplit.hh index d8dbbb431..ca7a49c70 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.hh +++ b/server/modules/routing/readwritesplit/readwritesplit.hh @@ -161,6 +161,7 @@ struct Config , transaction_replay(params->get_bool("transaction_replay")) , trx_max_size(params->get_size("transaction_replay_max_size")) , trx_max_attempts(params->get_integer("transaction_replay_attempts")) + , trx_retry_on_deadlock(params->get_bool("transaction_replay_retry_on_deadlock")) , optimistic_trx(params->get_bool("optimistic_trx")) , lazy_connect(params->get_bool("lazy_connect")) { @@ -225,6 +226,7 @@ struct Config bool transaction_replay; /**< Replay failed transactions */ size_t trx_max_size; /**< Max transaction size for replaying */ int64_t trx_max_attempts; /**< Maximum number of transaction replay attempts */ + bool trx_retry_on_deadlock; /**< Replay the transaction if it ends up in a deadlock */ bool optimistic_trx; /**< Enable optimistic transactions */ bool lazy_connect; /**< Create connections only when needed */ }; diff --git a/server/modules/routing/readwritesplit/rwsplitsession.cc b/server/modules/routing/readwritesplit/rwsplitsession.cc index 7f7258c25..58e30d3e3 100644 --- a/server/modules/routing/readwritesplit/rwsplitsession.cc +++ b/server/modules/routing/readwritesplit/rwsplitsession.cc @@ -709,7 +709,8 @@ void RWSplitSession::clientReply(GWBUF* writebuf, DCB* backend_dcb) } } - if ((error.is_rollback() || error.is_wsrep_error()) && handle_ignorable_error(backend)) + if (((m_config.trx_retry_on_deadlock && error.is_rollback()) || error.is_wsrep_error()) + && handle_ignorable_error(backend)) { // We can ignore this error and treat it as if the connection to the server was broken. gwbuf_free(writebuf);