From 5a133dd1d92ee3b925227c0b91827b1499d07d60 Mon Sep 17 00:00:00 2001 From: Ulf Wendel Date: Mon, 17 Jun 2013 17:39:19 +0000 Subject: [PATCH] MS 1.6 (current development series, alpha) - transient errors: config, concept and example, stats git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@330540 c90b9560-bf6c-de11-be94-00142212c4b1 --- reference/mysqlnd_ms/changes.xml | 66 +++++++- reference/mysqlnd_ms/concepts.xml | 160 ++++++++++++++++++ .../functions/mysqlnd-ms-get-stats.xml | 14 ++ reference/mysqlnd_ms/setup.xml | 129 +++++++++++++- 4 files changed, 363 insertions(+), 6 deletions(-) diff --git a/reference/mysqlnd_ms/changes.xml b/reference/mysqlnd_ms/changes.xml index 265a44377b..e250cd54aa 100644 --- a/reference/mysqlnd_ms/changes.xml +++ b/reference/mysqlnd_ms/changes.xml @@ -12,6 +12,63 @@ for a complete list of changes. +
+ PECL/mysqlnd_ms 1.6 series + + 1.6.0-alpha + + + + Release date: TBD + + + + + Motto/theme: Maintenance + + + + + + + This is the current development series. All + features are at an early stage. Changes may happen at any time without + prior notice. Please, do not use this version in production environments. + + + The documentation may not reflect all changes yet. + + + + Bug fixes + + + + No new bugs reported + + + + + + Feature changes + + + + Introduced automatic retry loop for transient errors and + corresponding statistic + to count the number of implicit retries. Some distributed + database clusters use transient errors to hint a client to retry + its operation in a bit. Most often, the client is then supposed + to halt execution (sleep) for a short moment before retrying the + desired operation. Immediately failing over to another node + is not necessary in response to the error. Instead, a retry loop + can be performed. Common situation when using MySQL Cluster. + + + + +
+
PECL/mysqlnd_ms 1.5 series @@ -31,12 +88,11 @@ - This is the current development series. All - features are at an early stage. Changes may happen at any time without - prior notice. Please, do not use this version in production environments. + This is the current release series. Albeit a stable release is missing, + it can be considered stable. Use this version in production environments. - The documentation may not reflect all changes yet. + The documentation is complete. @@ -140,7 +196,7 @@ modified to use the new C API calls of the mysqlnd library to begin, commit, and rollback a transaction or savepoint. If trx_stickiness - is used to enable transaction aware load balancing, the mysqli_begin, + is used to enable transaction aware load balancing, the mysqli_begin, mysqli_commit and mysqli_rollback functions will now be monitered by the plugin, to go along with the mysqli_autocommit function that was already supported. All SQL features to control diff --git a/reference/mysqlnd_ms/concepts.xml b/reference/mysqlnd_ms/concepts.xml index 85bb7b5ccc..5fa17e2ae3 100755 --- a/reference/mysqlnd_ms/concepts.xml +++ b/reference/mysqlnd_ms/concepts.xml @@ -658,6 +658,166 @@ version = 5.6.2-m5-log
+
+ Transient errors + + Some distributed database clusters make use of transient errors. A transient + error is a temporary error that is likely to disappear soon. By definition + it is safe for a client to ignore a transient error and retry the failed + operation on the same database server. The retry is free of side effects. + Clients are not forced to abort their work or to fail over to another database + server immediately. They may enter a retry loop before to wait for the + error to disappear before giving up on the database server. + Transient errors can be seen, for example, when using MySQL Cluster. But they + are not bound to any specific clustering solution per se. + + + PECL/mysqlnd_ms can perform an automatic retry loop in + case of a transient error. This increases distribution transparency and thus + makes it easier to migrate an application running on a single database + server to run on a cluster of database servers without having to change + the source of the application. + + + The automatic retry loop will repeat the requested operation up to a user + configurable number of times and pause between the attempts for a configurable + amount of time. If the error disappears during the loop, the application will + never see it. If not, the error is forwarded to the application for handling. + + + In the example below a duplicate key error is provoked to make the plugin + retry the failing query two times before the error is passed to the application. + Between the two attempts the plugin sleeps for 100 milliseconds. + + + + Provoking a transient error + + + + + + + + + + + Transient error retry loop + +query("DROP TABLE IF EXISTS test") || + !$mysqli->query("CREATE TABLE test(id INT PRIMARY KEY)") || + !$mysqli->query("INSERT INTO test(id) VALUES (1))")) { + printf("[%d] %s\n", $mysqli->errno, $mysqli->error); +} + +/* Retry loop is completely transparent. Checking statistics is + the only way to know about implicit retries */ +$stats = mysqlnd_ms_get_stats(); +printf("Transient error retries before error: %d\n", $stats['transient_error_retries']); + +/* Provoking duplicate key error to see statistics change */ +if (!$mysqli->query("INSERT INTO test(id) VALUES (1))")) { + printf("[%d] %s\n", $mysqli->errno, $mysqli->error); +} + +$stats = mysqlnd_ms_get_stats(); +printf("Transient error retries after error: %d\n", $stats['transient_error_retries']); + +$mysqli->close(); +?> +]]> + +&example.outputs.similar; + + + + + + + Because the execution of the retry loop is transparent from a users point of + view, the example checks the + statistics + provided by the plugin to learn about it. + + + As the example shows, the plugin can be instructed to consider any error + transient regardless of the database servers error semantics. The only error + that a stock MySQL server considers temporary has the error code + 1297. When configuring other error codes but + 1297 make sure your configuration reflects + the semantics of your clusters error codes. + + + The following mysqlnd C API calls are monitored by the plugin to check + for transient errors: query(), + change_user(), select_db(), + set_charset(), set_server_option() + prepare(), execute(), + set_autocommit(), + tx_begin(), tx_commit(), + tx_rollback(), tx_commit_or_rollback(). + The corresponding user API calls have similar names. + + + The maximum time the plugin may sleep during the retry loop depends on the + function in question. The a retry loop for query(), + prepare() or execute() will sleep for + up to max_retries * usleep_retry milliseconds. + + + However, functions that + control connection state + are dispatched to all all connections. The retry loop settings are applied + to every connection on which the command is to be run. Thus, such a function + may interrupt program execution for longer than a function that is run + on one server only. For example, set_autocommit() is + dispatched to connections and may sleep up to + (max_retries * usleep_retry) * number_of_open_connections) + milliseconds. Please, keep this in mind when setting long sleep times + and large retry numbers. Using the default settings of + max_retries=1, usleep_retry=100 and + lazy_connections=1 it is unlikely that you will + ever see a delay of more than 1 second. + +
+
Failover diff --git a/reference/mysqlnd_ms/functions/mysqlnd-ms-get-stats.xml b/reference/mysqlnd_ms/functions/mysqlnd-ms-get-stats.xml index fc04303d09..084508a37c 100755 --- a/reference/mysqlnd_ms/functions/mysqlnd-ms-get-stats.xml +++ b/reference/mysqlnd_ms/functions/mysqlnd-ms-get-stats.xml @@ -442,6 +442,18 @@ Since 1.2.0. + + + transient_error_retries + + + How often an operation has been retried when a transient error was + detected. See also, + transient_error + plugin configuration file setting. + + Since 1.6.0. + @@ -519,6 +531,8 @@ array(26) { string(1) "0" ["gtid_implicit_commit_injections_failure"]=> string(1) "0" + ["transient_error_retries"]=> + string(1) "0" } ]]> diff --git a/reference/mysqlnd_ms/setup.xml b/reference/mysqlnd_ms/setup.xml index ac682a839a..9259cc004c 100755 --- a/reference/mysqlnd_ms/setup.xml +++ b/reference/mysqlnd_ms/setup.xml @@ -2399,9 +2399,136 @@ $mysqli->set_charset("latin1"); + + + + transient_error + object + + + + The setting has been introduced in 1.6.0. + + + A database cluster node may reply a transient error to a client. The client + can then repeat the operation on the same node, fail over to a different node + or abort the operation. Per definition is it safe for a client to + retry the same operation on the same node before giving up. + + + PECL/mysqlnd_ms can perform the retry + loop on behalf of the application. + By configuring transient_error the plugin can be + instructed to repeat operations failing with a certain error code for + a certain maximum number of times with a pause between the retries. + If the transient error disappears during loop execution, it is + hidden from the application. Otherwise, the error is + forwarded to the application by the end of the loop. + + + + Retry loop for transient errors + + + + + + + + + + + + + Keyword + Description + Version + + + + + + mysql_error_codes + + + + List of transient error codes. You may add any MySQL error code + to the list. It is possible to consider any error as transient + not only 1297 + (HY000 (ER_GET_TEMPORARY_ERRMSG), + Message: Got temporary error %d '%s' from %s). + Before adding other codes but 1297 to the list, + make sure your cluster supports a new attempt without impacting + the state of your application. + + + Since 1.6.0. + + + + max_retries + + + + How often to retry an operation which + fails with a transient error before forwarding the + failure to the user. + + + Default: 1 + + + Since 1.6.0. + + + + usleep_retry + + + + Milliseconds to sleep between transient error retries. + The value is passed to the C function usleep, + hence the name. + + + Default: 100 + + + Since 1.6.0. + + + + + + + -
+ +
Plugin configuration file (<= 1.0.x)