MySQL有时会错误地为count(*)返回0

时间:2015-10-06 15:27:21

标签: mysql count heisenbug

我维护了一个论坛,其中包含论坛帖子。要确定线程有多少页面,我执行查询

[info] Compiling 1 Scala source to /shared/wfdemo/project/target/scala-2.10/sbt-0.13/classes...
/shared/wfdemo/build.sbt:1: error: not found: value port
port in container.Configuration := 8081

然后得到结果,除以每页的帖子数量,然后向上舍入。上面的查询偶尔会返回0的结果,因为我无法理解,这会导致分页错误。通常问题“神奇地”在几分钟内自我修复,所以这是一个有趣的旅程,甚至诊断它到目前为止。或者更确切地说,它可以持续数小时,但在我登录后试图看看发生了什么事情似乎神奇地修复了自己(虽然这可能是我的想象)。

当问题显示所有时,此类查询会为SELECT COUNT(*) AS `numrows` FROM `forum_posts` WHERE `thread_id` = '3004' AND `deleted` = 0; 返回0,当它突然解析时,上述查询会再次开始返回正确的值。

可能导致此问题的原因是什么?

2 个答案:

答案 0 :(得分:4)

我们也遇到了这个问题。它也发生在mysql客户端(而不是通过代码)。这似乎是mysql的一个bug。它是由索引合并交集引起的

您可以按会话设置它并尝试 SET SESSION optimizer_switch =" index_merge_intersection = off&#34 ;;

或者在my.cnf中全局设置

的[mysqld] optimizer_switch = index_merge_intersection =关

此处提交的错误报告

http://bugs.mysql.com/bug.php?id=81031

答案 1 :(得分:2)

这个答案包含很多猜测,原始问题没有包含足够的信息来确定这些。但是,这个答案可能对其他读者有用。

  

上述查询偶尔会返回0的结果,因为我无法理解,这会导致分页错误。

时,您可以获得0条记录(或COUNT(*)查询中的0条记录)
  1. 没有行满足WHERE条件(例如论坛帖子中没有帖子)。
  2. 在“似乎不好”的查询和发现错误的代码点之间存在错误/异常。 (例如,客户端无法连接到数据库服务器,并且会自动忽略错误。)
  3.   

    当问题出现时,所有此类查询都会为numrows返回0,当它突然自行解析时,上述查询会再次开始返回正确的值。

    在这种特殊情况下,我的赌注是:达到mysql中的最大连接数。 数据库访问层默默地忽略错误,这会导致结果可以转换为数值0.正如我们所知,将0除以任何值(0除外)等于0。

    这是一个例子(复制粘贴:不要使用此代码!)

    try {
        /**
          Note for OO syntax only: If a connection fails an object is still returned.
          To check if the connection failed then use either the
          mysqli_connect_error() function or the
          mysqli->connect_error property as in the preceding examples.
        */
        $connection = new \mysqli('localhost', 'user', 'superSecretPass', 'database');
        $query = 'SELECT COUNT(*) AS cnt FROM myTable WHERE this_flag IS NULL';
        $result = $connection->query($connection, $query);
        $itemCount = $result->fetchAssoc()['cnt'];
        $result->close();
    }
    catch (\Exception $e) {
        //Do nothing
    }
    
    $itemsPerPage = 15;
    $sumPages = \ceil($itemCount / $itemsPerPage);
    

    发生异常或上述示例中未处理连接错误时:

    • $ itemCount未定义
    • $ itemCount将被视为NULL
    • NULL将被转换为0
    • 0/15 = 0

    如果要处理底层(例如数据库访问)类中的错误,请以允许调用方通知错误/异常的方式执行此操作。