SAE 表过大导致数据查询不出来的bug

今天下午,用户反馈我们微信某个操作,显示数据库报错。我就准备扫码进候选人面板看看问题,结果发现怎么扫都扫不进去。

Clipboard Image.png

错误显示在这,我仔细看了下生成微信二维码的数据,确实插入进去了。

然后就是这个sql 框架查询不出来。但是奇怪的是同样的代码,测试环境跑的好好的。

假设 当时的$scan_num 是65648, 那么对应的sql 就是 

SELECT * FROM `weixin_scan` WHERE `num` ='65648' ORDER by `id` DESC

然后把 这个sql 拿到sae的phpmyadmin里查询:

Clipboard Image.png

又有值,真是见了鬼了。

当时我就懵了,不知道怎么解决。打电话给老大,老大分析说可能是SAE主从有延迟,让我先把业务用kvdb替代下,找原因。确认是主从分离就和罗飞要sae人的联系方式反应一下。

我问飞哥,飞哥说你先跳出框架,写个原生的查询试试。确认是主从分离的问题再说。

我就查着sae的手册,写了一下脚本。

<?php
//----------------------下面是通用函数-------------------------
function error($msg,$data=''){
    exit(json_encode(array('status'=>0,'info'=>$msg,'data'=>$data)));
}

function success($msg,$data=''){
    exit(json_encode(array('status'=>1,'info'=>$msg,'data'=>$data)));
}

// 连主库
$db = 'app_jobdb';
$user = '8888888';//演示用户
$pass = 88888888';//演示密码
$link=mysql_connect(SAE_MYSQL_HOST_M.':'.SAE_MYSQL_PORT,$user,$pass);

// 连从库
// $link=mysql_connect(SAE_MYSQL_HOST_S.':'.SAE_MYSQL_PORT,$user,$pass);

if($link)
{
    mysql_select_db($db,$link);
    mysql_set_charset('UTF8', $link);
    //your code goes here
    $result = mysql_query("SELECT * FROM `weixin_scan` WHERE `num`='65693' ORDER BY `id` DESC");
    if(!$result){
        error(mysql_error());
    }else{
        while($row = mysql_fetch_assoc($result)){
          $res[] = $row;
        }
        success('主库查询成功,数据为:',$res);
    }
    mysql_close();
}else{
 error('连接数据库失败', mysql_error());
}

// 连从库
$link=mysql_connect(SAE_MYSQL_HOST_S.':'.SAE_MYSQL_PORT,$user,$pass);

if($link)
{
    mysql_select_db($db,$link);
    mysql_set_charset('UTF8', $link);
    //your code goes here
    $result = mysql_query("SELECT * FROM `weixin_scan` WHERE `num`='65693'");
    if(!$result){
        error(mysql_error());
    }else{
        while($row = mysql_fetch_assoc($result)){
          $res[] = $row;
        }
        success('从库查询成功',$res);
    }
    mysql_close();
}else{
    error('连接数据库失败', mysql_error());
}

//pdo
$dsn = 'mysql:host=' . SAE_MYSQL_HOST_M . ';port=' . SAE_MYSQL_PORT . ';dbname=' . $db . ';charset=utf8';
$pdo = new PDO( $dsn , $user , $pass );
if(!$pdo){
    error('主库pdo连接失败');
}
if($result = $pdo->query("SELECT * FROM `weixin_scan` WHERE `num`='65693' ORDER BY `id` DESC", PDO::FETCH_ASSOC)){
    foreach( $result as $item ){
        $res[] = $item;
    }
    success('主库pdo查询成功', $res);
}else{
    error('主库pdo查询失败', $pdo->errorInfo());
}

Clipboard Image.png

跑了一下,报出这么一个错误,说行数太多了,网上搜了一下,说表太大,排序查不了,要加limit 65000 我试了,不行。后来我想,查条数据条件num 又是唯一的,要什么降序主键。把order去掉,然后 就好了,不管主从域名、pdo 都一样。

Clipboard Image.png

看来数据不能放太多,尤其这种临时表。

后来问了罗飞,为什么phpmyadmin可以,应用不行,他说应用层做了个rdc中间件,可能那边出bug了。

先这么招把,回头清完数据表,写个cron定时清 两天前的。

标签:<a href="/?tag=sae">sae</a>,<a href="/?tag=filesort">filesort</a>,<a href="/?tag=mysql">mysql</a>