©
本文档使用
php.cn手册 发布
应用程序使用本插件,应该针对用户的 API 调用实现一些错误处理。并且由于插件 改变了连接控制,API 调用可能返回不可预期的错误。如果插件被用于连接控制中, 那么连接将不在代表一个独立的网络链接,他是一个连接池。那么一个错误编号和 错误消息将被设置在连接控制中,那么他可能被设置在任何一个实际的连接中。
如果使用默认的被动连接,那么连接再实际查询执行以前是不建立实际连接的。 这样一个执行语句的 API 调用会产生一个连接错误。下面的范例中,当尝试在 slave 中执行一个语句的时候将产生一个错误。连接错误的产生是因为在配置文件中 没有设定一个有效的 slave。
Example #1 Provoking a connection error
{ "myapp": { "master": { "master_0": { "host": "localhost", "socket": "\/tmp\/mysql.sock" } }, "slave": { "slave_0": { "host": "invalid_host_name", } }, "lazy_connections": 1 } }
明确的指定被动连接设定只是为了范例目的使用。
Example #2 在查询执行时产生连接错误
<?php
$mysqli = new mysqli ( "myapp" , "username" , "password" , "database" );
if ( mysqli_connect_errno ())
die( sprintf ( "[%d] %s\n" , mysqli_connect_errno (), mysqli_connect_error ()));
if (! $mysqli -> query ( "SET @myrole='master'" )) {
printf ( "[%d] %s\n" , $mysqli -> errno , $mysqli -> error );
}
if (!( $res = $mysqli -> query ( "SELECT @myrole AS _role" ))) {
printf ( "[%d] %s\n" , $mysqli -> errno , $mysqli -> error );
} else {
$row = $res -> fetch_assoc ();
$res -> close ();
printf ( "@myrole = '%s'\n" , $row [ '_role' ]);
}
$mysqli -> close ();
?>
以上例程的输出类似于:
PHP Warning: mysqli::query(): php_network_getaddresses: getaddrinfo failed: Name or service not known in %s on line %d PHP Warning: mysqli::query(): [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known (trying to connect via tcp://invalid_host_name:3306) in %s on line %d [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known
应用程序希望通过有效的错误处理控制这种连接错误。
处于使用的目的,应用程序应该希望控制这些错误,典型的错误内容 2002 (CR_CONNECTION_ERROR) - Can't connect to local MySQL server through socket '%s' (%d), 2003 (CR_CONN_HOST_ERROR) - Can't connect to MySQL server on '%s' (%d) 和 2005 (CR_UNKNOWN_HOST) - Unknown MySQL server host '%s' (%d)。 例如,应用程序可以判断这些错误编号,进而手动的执行某些错误处理。插件并不会自动的进行 这些错误处理,包括 master 错误处理,因为这些并不是透明的操作。
Example #3 产生一个连接错误
{ "myapp": { "master": { "master_0": { "host": "localhost" } }, "slave": { "slave_0": { "host": "invalid_host_name" }, "slave_1": { "host": "192.168.78.136" } }, "lazy_connections": 1, "filters": { "roundrobin": [ ] } } }
明确的指定被动连接只为了进行范例使用,包括使用默认的负载均衡策略 random once。
Example #4 非常基础的错误处理
<?php
$mysqli = new mysqli ( "myapp" , "username" , "password" , "database" );
if ( mysqli_connect_errno ())
die( sprintf ( "[%d] %s\n" , mysqli_connect_errno (), mysqli_connect_error ()));
if (! $mysqli -> query ( "SET @myrole='master'" )) {
printf ( "[%d] %s\n" , $mysqli -> errno , $mysqli -> error );
}
$res = $mysqli -> query ( "SELECT VERSION() AS _version" );
if ( 2002 == $mysqli -> errno || 2003 == $mysqli -> errno || 2004 == $mysqli -> errno ) {
$res = $mysqli -> query ( "SELECT VERSION() AS _version" );
}
if (! $res ) {
printf ( "ERROR, [%d] '%s'\n" , $mysqli -> errno , $mysqli -> error );
} else {
printf ( "SUCCESS, [%d] '%s'\n" , $mysqli -> errno , $mysqli -> error );
$row = $res -> fetch_assoc ();
$res -> close ();
printf ( "version = %s\n" , $row [ '_version' ]);
}
$mysqli -> close ();
?>
以上例程的输出类似于:
[1045] Access denied for user 'username'@'localhost' (using password: YES) PHP Warning: mysqli::query(): php_network_getaddresses: getaddrinfo failed: Name or service not known in %s on line %d PHP Warning: mysqli::query(): [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known (trying to connect via tcp://invalid_host_name:3306) in %s on line %d SUCCESS, [0] '' version = 5.6.2-m5-log
由于一些原因,连接控制并不可能很容易在所有网络连接中检查所有的错误。 例如,我们假设在连接池中有 3 个网络链接,一个连接是 master 连接,2个是 slave 链接。 应用程序通过 mysqli_select_db() API 调用改变当前操作数据库, 插件监控到这个函数,并且尝试更改当前的所有连接来统一他们的链接状态。如果 master 已经成功的更改了数据库,两个 slave 连接更改失败,那么在使用第一个 slave 连接的时候, 其中会包含一个连接错误。对于第二个 slave 链接也是一样的,那么在第一个 slave 上的 错误信息将被丢失。
这种情况下,可以通过检查 E_WARNING 类型的错误,或者检查 mysqlnd_ms debug and trace log。