һЩ�ֲ�ʽ�����ݿ�Ⱥ��ʹ�ö̴���һ���̴���ֻ��һ��ʱ���ڵ�һ����ʱ���� ��һ���Ķ�һ�£����ֺ��Զ̴�����������ͬһ�����ݿ�������н��г����� ��ȫ�ģ����Դ���Կͻ��˲�����Ӱ�졣�ͻ��˽����ᱻ����ֹ���ǵĹ���������ȥ���� ����һ�����ݿ�������Ĵ������ǽ�����һ�����Դ�������ѭ����������Ҫ�ȴ����� ��Ϣ��ʧ�����磬��ʹ�� MySQL Clusterʱ�����Կ������̴ֶ�����Ϣ�����Dz����ᱻ �����ض���Ⱥ���������С�
��������ṩ�ڶ̴����е��Զ����Դ���ѭ�����⽫��߷ֲ���������ȣ����Ҷ��� Ӧ�ó����һ����������������һֱ�����ݿ����Ⱥ��ִ�б�ø��Ӽ�
�Զ��ij���ѭ���������ϵij��ԣ�ֱ���û������ļ�ָ���Ĵ��������Ҹ�������ָ���� ���ʱ����ж��ݵĵȴ������������ѭ����������ʧ��Ӧ�ó������ٿ������ ������Ϣ���������û����ʧ�������ύ��Ӧ�ó�����д���
����ķ����У�duplicate key �Ĵ����������ύ��Ӧ�ó�����ǰ���ᱻ���Դ��� 2 �Σ� ���γ���֮���� 100 ms��
Example #1 Provoking a transient error
mysqlnd_ms.enable=1 mysqlnd_ms.collect_statistics=1
{ "myapp": { "master": { "master_0": { "host": "localhost" } }, "slave": { "slave_0": { "host": "192.168.78.136", "port": "3306" } }, "transient_error": { "mysql_error_codes": [ 1062 ], "max_retries": 2, "usleep_retry": 100 } } }
Example #2 �̴�����ѭ��
<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
if (mysqli_connect_errno())
/* Of course, your error handling is nicer... */
die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));
if (!$mysqli->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();
?>
�������̵���������ڣ�
Transient error retries before error: 0 [1062] Duplicate entry '1' for key 'PRIMARY' Transient error retries before error: 2
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.