mysqlクライアントがステートメントの送信中にサーバとの接続が遮断された場合、 直ちに自動的に再接続し、ステートメントの送信を試みる(reconnect)。
注意:
再試行時には全セッションオブジェクトと設定(具体的にはテンポラリテーブル、オートコミットモード、ユーザー定義変数、
セッション変数、トランザクションロールバックなど)が失われているので、ステートメントによってはreconnectすることが危険なものもある。
reconnectしないようにmysqlクライアントを利用する場合には、--skip-reconnect
オプションをつけてクライアントを立ち上げる。
C APIコードはMySQLを使って配布される mysqlclient ライブラリの中に含まれ、これによってDBにアクセスできる。 MySQL付属のクライアントの多くはCで書かれている。
#include <stdio.h>
#include <stdlib.h>
#include <mysql.h>
int main(int argc, char *argv[])
{
MYSQL *conn;
MYSQL_RES *res;
my_bool reconnect = 1; // 1: 切断時に再接続しようと試みる 0: 試みない
// この値は mysql_real_connect呼び出し後に((MYSQL* conn)->reconnect) に設定される
// 5.0.3までのMySQLではデフォルト値は1, 5.1では0
const char *server = "localhost";
const char *user = "root";
const char *password = "";
const char *database = "IMO";
conn = mysql_init(NULL);
fprintf(stdout, "%d\n", conn->reconnect);
// MYSQL_OPT_RECONNECT はMySQL5.0.13から有効
mysql_options(conn, MYSQL_OPT_RECONNECT, &reconnect);
if (mysql_real_connect(conn, server, user, password, database, 0, NULL, 0) == NULL) {
fprintf(stderr, "%s\n", mysql_error(conn));
exit(1);
}
fprintf(stdout, "%d\n", conn->reconnect);
}
ビルド例(MacOSX + homebrew)
gcc -I/usr/local/Cellar/mysql/5.6.10/include -L/usr/local/Cellar/mysql/5.6.10/lib mysql_sample.c -lmysqlclient
https://github.com/brianmario/mysql2/blob/master/ext/mysql2/client.c から抜粋
// メソッド定義
rb_define_method(cMysql2Client, "reconnect=", set_reconnect, 1);
// ...
/* call-seq:
* client.reconnect = true
*
* Enable or disable the automatic reconnect behavior of libmysql.
* Read http://dev.mysql.com/doc/refman/5.5/en/auto-reconnect.html
* for more information.
*/
static VALUE set_reconnect(VALUE self, VALUE value) {
return _mysql_client_options(self, MYSQL_OPT_RECONNECT, value);
}
// ...
static VALUE _mysql_client_options(VALUE self, int opt, VALUE value) {
int result;
void *retval = NULL;
unsigned int intval = 0;
my_bool boolval;
GET_CLIENT(self);
REQUIRE_NOT_CONNECTED(wrapper);
if (NIL_P(value))
return Qfalse;
switch(opt) {
case MYSQL_OPT_CONNECT_TIMEOUT:
intval = NUM2INT(value);
retval = &intval;
break;
case MYSQL_OPT_READ_TIMEOUT:
intval = NUM2INT(value);
retval = &intval;
break;
case MYSQL_OPT_WRITE_TIMEOUT:
intval = NUM2INT(value);
retval = &intval;
break;
case MYSQL_OPT_LOCAL_INFILE:
intval = (value == Qfalse ? 0 : 1);
retval = &intval;
break;
//
case MYSQL_OPT_RECONNECT:
// QtrueはRubyの世界のtrue, QfalseはRubyの世界のfalse
boolval = (value == Qfalse ? 0 : 1);
retval = &boolval;
break;
default:
return Qfalse;
}
// ここで実際に設定
result = mysql_options(wrapper->client, opt, retval);
/* Zero means success */
if (result != 0) {
rb_warn("%s\n", mysql_error(wrapper->client));
} else {
/* Special case for reconnect, this option is also stored in the wrapper struct */
if (opt == MYSQL_OPT_RECONNECT)
wrapper->reconnect_enabled = boolval;
}
return (result == 0) ? Qtrue : Qfalse;
}