1、应用程序(比如 PHP)长时间的执行批量的 MYSQL 语句。
最常见的就是采集或者新旧数据转化。
SHOW VARIABLES LIKE '%timeout%’
复制代码
解决方案:
在 my.ini 文件中添加或者修改以下两个变量:
wait_timeout=2880000
interactive_timeout = 2880000
关于两个变量的具体说明可以 google 或者看官方手册。
如果不能修改 my.cnf,则可以在连接数据库的时候设置 CLIENT_INTERACTIVE,比如:
sql = "set interactive_timeout=24*3600";
mysqlrealquery(...)
2、执行一个 SQL,但 SQL 语句过大或者语句中含有 BLOB 或者 longblob 字段。
比如,图片数据的处理
SHOW VARIABLES LIKE '%max_allowed_packet%’
复制代码
解决方案:
在 my.cnf 文件中添加或者修改以下变量:
maxallowedpacket = 10M (也可以设置自己需要的大小)
maxallowedpacket 参数的作用是,用来控制其通信缓冲区的最大长度。
3、检查 MySQL 的链接状态,使其重新链接
<?php
// 数据库操作类
class DB{
// 保存数据库连接
private static $_instance = null;
// 连接数据库
public static function get_conn($config){
if(isset(self::$instance) && !empty(self::$instance)){
return self::$_instance;
}
$dbhost = $config['host'];
$dbname = $config['dbname'];
$dbuser = $config['user'];
$dbpasswd = $config['password'];
$pconnect = $config['pconnect'];
$charset = $config['charset'];
$dsn = "mysql:host=$dbhost;dbname=$dbname;";
try {
$h_param = array(
PDO::ATTRERRMODE => PDO::ERRMODEEXCEPTION,
);
if ($charset != '') {
$hparam[PDO::MYSQLATTR_INIT_COMMAND] = 'SET NAMES ' . $charset; //設置默認編碼
}
if ($pconnect) {
$hparam[PDO::ATTRPERSISTENT] = true;
}
$conn = new PDO($dsn, $dbuser, $dbpasswd, $h_param);
} catch (PDOException $e) {
throw new ErrorException('Unable to connect to db server. Error:' . $e->getMessage(), 31);
}
self::$_instance = $conn;
return $conn;
}
// 执行查询
public static function query($dbconn, $sqlstr, $condparam){
$sth = $dbconn->prepare($sqlstr);
try{
$sth->execute($condparam);
} catch (PDOException $e) {
echo $e->getMessage().PHP_EOL;
self::reset_connect($e->getMessage()); // 出错时调用重置连接
}
$result = $sth->fetchAll(PDO::FETCH_ASSOC);
return $result;
}
// 重置连接
public static function resetconnect($errmsg){
if(strpos($err_msg, 'MySQL server has gone away')!==false){
self::$_instance = null;
}
}
}
复制代码
评论