Mysql服务器已经消失,序列化和锁定等待错误

时间:2015-08-24 10:08:32

标签: php mysql pdo transactions

我有cron3min.php,cron10min.php,cron60min.php。

我正在使用PDO。

cron3min.php很忙,每3分钟一次

  1. 从送纸器下载xml供稿
  2. 解析下载的Feed
  3. 将赔率存储在赔率表,夹具固定装置,婴儿桌
  4. 每3分钟就有大约50.000 - 500.000行,所以当来自cron的其他请求到来时,通常第一个cron请求没有完成。

    当我从catch检查我的错误日志时,我看到:

    2015-08-23 10:57:36exception 'PDOException' with message 'SQLSTATE[HY000]: General error: 2006 MySQL server has gone away' in /home/27425-18594.cloudwaysapps.com/jcjdkdtaur/public_html/php/topoddsengine.php:25
    Stack trace:
    #0 /home/27425-18594.cloudwaysapps.com/jcjdkdtaur/public_html/php/topoddsengine.php(25): PDO->query('SELECT * FROM G...')
    #1 /home/27425-18594.cloudwaysapps.com/jcjdkdtaur/public_html/cron5min.php(27): TopOdds->insertTopOdds()
    #2 {main}2015-08-23 10:58:11exception 'PDOException' with message 'SQLSTATE[HY000]: General error: 2006 MySQL server has gone away' in /home/27425-18594.cloudwaysapps.com/jcjdkdtaur/public_html/php/topoddsengine.php:25
    

    Stack trace:
    #0 /home/27425-18594.cloudwaysapps.com/jcjdkdtaur/public_html/php/class.xmltodb.php(496): PDOStatement->execute()
    #1 /home/27425-18594.cloudwaysapps.com/jcjdkdtaur/public_html/php/class.xmltodb.php(468): XMLtoDB->fillMap('')
    #2 /home/27425-18594.cloudwaysapps.com/jcjdkdtaur/public_html/php/class.xmltodb.php(600): XMLtoDB->getMap('')
    #3 /home/27425-18594.cloudwaysapps.com/jcjdkdtaur/public_html/cron10min.php(22): XMLtoDB->resultsToHistoric()
    #4 {main}2015-08-24 09:33:31exception 'PDOException' with message 'SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction' in /home/27425-18594.cloudwaysapps.com/jcjdkdtaur/public_html/php/class.xmltodb.php:496
    

    Stack trace:
    #0 /home/27425-18594.cloudwaysapps.com/jcjdkdtaur/public_html/php/class.xmltodb.php(742): PDOStatement->execute()
    #1 /home/27425-18594.cloudwaysapps.com/jcjdkdtaur/public_html/php/class.xmltodb.php(677): XMLtoDB->execHistoric(Object(PDOStatement), Object(SimpleXMLElement), Object(SimpleXMLElement), '2015-08-21 18:0...', 1, NULL, 'Albania: Superl...', Object(SimpleXMLElement), 'albania:', 'Partizani Tiran...', 2337556, 'Partizani Tiran...', NULL, 1, Object(SimpleXMLElement), NULL, NULL, NULL, '62: X. Sukaj; ', NULL, '', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Laci', 2337554, NULL, 1, Object(SimpleXMLElement), NULL, NULL, NULL, 'E. \xC3\x87ela; ', NULL, '', NULL, NULL, NULL, NULL, NULL, NULL, NULL, '', '', NULL, NULL, NULL, NULL, 'tipgin', Object(SimpleXMLElement))
    #2 /home/27425-18594.cloudwaysapps.com/jcjdkdtaur/public_html/cron10min.php(22): XMLtoDB->resultsToHistoric()
    #3 {main}2015-08-23 18:18:17exception 'PDOException' with message 'SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction' in /home/27425-18594.cloudwaysapps.com/jcjdkdtaur/public_html/php/class.xmltodb.php:742
    

    在cron3min.php中有这个函数:

    $provider->getOdds();
    $xmldb->sendOddsToDb();
    $xmldb->sendFixturesToDb();
    $xmldb->fillBaby();
    $topOdds->insertTopOdds();
    
    $xmldb->copyHAtoHandicap();
    
    $con->close();
    

    最繁忙的功能是$xmldb->sendOddsToDb();$xmldb->copyHAtoHandicap();

    我将在这里复制$ xmldb-> sendOddsToDb();,在每个函数中我启动事务并在函数结束时提交并关闭。

    这里是sendOddsToDb()并请检查它,看看只是一个mysql逻辑,有什么不对,我的开始交易是好的吗? Xml解析需要大约1:30-2分钟(大部分时间需要代码的3路部分,我需要在数组中存储障碍),所以也许是打开长连接或者其他东西......

    function sendOddsToDb(){    
        try{
            $this->conn->connect();
            $this->PDO->beginTransaction();
    
            $countries = $this->OddCountries; 
            $stmt = $this->PDO->prepare($this->insOdds);
            //$dbempty = $this->countRows('odds');
            //$this->clrLeagues();                  
    
            foreach($countries as $country){
             $path = "{$this->base}/feeds/odds/{$country}odds.xml";
             $odds_feed = $this->parser->parseFile($path);
    
                foreach($odds_feed->league as $league){ //za svaku ligu u fidu
    
                    $fcountries = $this->filterCountries($league->attributes()->country);
                    $subid = $league->attributes()->sub_id;
    
                    $sportname = '';
                    $sportid = 0;
                    if($odds_feed->attributes()->sport == 'soccer' || $odds_feed->attributes()->sport == 'football'){
                        $sportname = 'football';
                        $sportid = 1;
                    }
                    else{
                        $sportname = NULL;
                    }
                    $lg2 = '';
                    $lg = $league->attributes()->name;
                    $ctr = $league->attributes()->country.':';
                    if(!contains(strtolower($lg),strtolower($ctr))){
                        $lg2 = ucfirst($ctr) . ' ' . ucfirst($lg);  
                    }
                    else{
                        $lg2 = $league->attributes()->name;
                    }
    
                    $flg = $this->getMap2($lg2);
                    $this->sendLeaguesToDb($league->attributes()->id, $flg ,$fcountries,$sportid,$subid,'tipgin');
                    foreach($league->match as $match){ 
    
                        $dbdate = date('Y-m-d',strtotime($match->attributes()->date));
                        $updateddate = date('Y-m-d H:i:s',strtotime($odds_feed->attributes()->updated));
                        $dbtime = date('H:i:s', strtotime($match->attributes()->time));
    
                        $datetime = date('Y-m-d H:i:s',strtotime($dbdate . $dbtime));   
    
                        $hteam = $this->getMap(toShort($match->home->attributes()->name));  
                        $ateam = $this->getMap(toShort($match->away->attributes()->name));  
    
                        $fixid = 0;
                        if($match->attributes()->id == 0 || $match->attributes()->id == ''){
                            if($match->attributes()->alternate_id == 0 || $match->attributes()->id == ''){
                                $fixid = $match->attributes()->alternate_id_2;
                            }
                            else{
                                $fixid = $match->attributes()->alternate_id;
                            }
                        }
                        else{
                            $fixid = $match->attributes()->id;
                        }       
                        //$m = $hteam . ' ' . $ateam;
                        //var_dump('MATCH: ' . $m . ' HTEAM: ' . mb_detect_encoding($hteam). ' ATEAM: ' . mb_detect_encoding($ateam));          
                        foreach ($match->odds as $odds) { 
                            //var_dump($odd);
                            foreach ($odds->type as $type) { 
    
                                foreach ($type->bookmaker as $bookmaker) { 
                                    //$oldbook = ;
                                    if($bookmaker->attributes()->name != 'BetClick'){
                                    if($bookmaker->attributes()->name != 'Bodog'){
                                    if($bookmaker->attributes()->name != 'YouWin'){
                                    $homeodds = NULL;
                                    $drawodds = NULL;
                                    $awayodds = NULL;
                                    $numodds = NULL;
                                    $dbhandicap = NULL;
                                    $id2 = '0';
                                    $typename = $this->getMap2($type->attributes()->name);
    
                                    $fbooks = $this->filterBooks($bookmaker->attributes()->name);   
    
                                    if($typename == 'Over/Under' || $typename == 'Over/Under 1st Half' || $typename == 'Over/Under 2nd Half'){
    
                                        foreach ($bookmaker->total as $total) { //daj kvote za svaki mec
    
                                        $numodds = $total->attributes()->name;
                                        foreach($total->odd as $odd){
                                        switch ($odd->attributes()->name) {
                                            case 'Over':
                                                $homeodds = $odd->attributes()->value;
                                                break;
                                            case 'Under':
                                                $awayodds = $odd->attributes()->value;
                                                break;
                                        }
    
                                        $id2 = $numodds;
                                        //echo 'ID: ' . $match->attributes()->alternate_id_2 . $league->attributes()->country . " ODDS: {$homeodds} {$drawodds} {$awayodds} TYPE: {$typename}  BOOK: {$fbooks}  ID2: {$id2}" . "<br>";
    
                                        }
    
                                    //echo "HOME TEAM: {$hteam} <BR>";
                                    //echo "AWAY TEAM: {$ateam} <BR>";  
    
    
                                    $this->execOdds($stmt, $fixid, $updateddate,
                                    $typename, $fcountries,$league->attributes()->name,
                                    $league->attributes()->id, $subid, $league->attributes()->cup,$sportname,
                                    $hteam,$match->home->attributes()->id,
                                    $ateam,$match->away->attributes()->id, $datetime, $dbdate,
                                    $dbtime, $match->attributes()->status, $numodds,$homeodds,$drawodds,
                                    $awayodds, $fbooks, $bookmaker->attributes()->id, $dbhandicap, $id2);
                                    }
                                    }
    
                                    else if($typename == 'Handicap' || $typename == '3Way Handicap'){
                                    $homeodds = array();
                                    $drawodds = array();
                                    $awayodds = array();
                                    $arrhandicap = array();
                                    $fhandicap = '';
    
                                    foreach ($bookmaker->handicap as $handicap) { //daj kvote za svaki mec 
                                    if (strpos($handicap->attributes()->name,'+') !== false) {
                                    $fhandicap = str_replace('+','',$handicap->attributes()->name);                             
                                    }else{
                                    $fhandicap = $handicap->attributes()->name;
                                    }
                                    $newhandi = '';
                                    foreach($handicap->odd as $odd){
                                            //$odd = $handicap->odd;
                                            switch ($odd->attributes()->name) {
                                            case '1':
                                                $newhandi = $fhandicap;
                                                $homeodds[(string)$newhandi] = 
                                                $odd->attributes()->value;
                                                break;
                                            case 'X':
                                                $newhandi = $fhandicap;
                                                $drawodds[(string)$newhandi] = 
                                                $odd->attributes()->value;
                                                break;  
                                            case '2':
                                                if (strpos($fhandicap,'-') !== false) { //if negative 
                                                    $newhandi = str_replace('-','',$fhandicap); //to positive
                                                    //echo 'NEGATIVE - OLD: ' . $fhandicap . ' NEW: '.$newhandi . '<br>';
                                                }
                                                elseif($fhandicap=='0'){
                                                    $newhandi = '0';
                                                }
                                                else{ //if positive
                                                    $newhandi = '-' . $fhandicap; //to negative
                                                    //echo 'POSITIVE - OLD: ' . $fhandicap . ' NEW: '.$newhandi . '<br>';
                                                }
                                                $awayodds[(string)$newhandi] = $odd->attributes()->value; 
                                                break;
                                            }
                                            $arrhandicap[] = $newhandi;
                                        }
                                    }
                                    //$arrhandicap[] = sort($dbhandicap);
                                    foreach($arrhandicap as $hand){
                                    if(!is_null($hand)){
                                    //echo $typename. ': ' . $hand . '<br>';
                                    if($homeodds[(string)$hand] != NULL && $awayodds[(string)$hand] != NULL){
                                    $this->execOdds($stmt, $fixid, $updateddate,
                                    $typename, $fcountries,$league->attributes()->name,
                                    $league->attributes()->id, $subid, $league->attributes()->cup,$sportname,
                                    $hteam,$match->home->attributes()->id,
                                    $ateam,$match->away->attributes()->id, $datetime, $dbdate,
                                    $dbtime, $match->attributes()->status, $numodds,$homeodds[(string)$hand],
                                    $drawodds[(string)$hand],$awayodds[(string)$hand], $fbooks, 
                                    $bookmaker->attributes()->id, $hand, $hand);
                                    echo 'ID: ' . $match->attributes()->id . $league->attributes()->country . " HOMEODDS: {$homeodds[(string)$hand]}  DRAWODDS: {$drawodds[(string)$hand]}  AWAYODDS: {$awayodds[(string)$hand]} TYPE: {$typename}  BOOK: {$fbooks}  ID2: {$hand}" . "<br>";                                                    
                                    }
                                    }
                                    }
                                    }
                                    else{
                                    foreach ($bookmaker->odd as $odd) { //daj kvote za svaki mec
                                        if($typename == 'Home/Away'){
                                            $typename = 'Draw No Bet';
                                        }
                                        switch ($odd->attributes()->name) {
                                            case '1':
                                            case '1X':
                                            case 'Yes':
                                                $homeodds = $odd->attributes()->value;
                                                break;
                                            case 'X':
                                            case 'X2':
                                                $drawodds = $odd->attributes()->value;
                                                break;
                                            case '2':
                                            case '12':
                                            case 'No':
                                                $awayodds = $odd->attributes()->value;
                                                break;
                                        }
    
                                        $id2 = 0;
                                        //echo 'ID: ' . $match->attributes()->alternate_id_2 . $league->attributes()->country . " ODDS: {$homeodds} {$drawodds} {$awayodds} TYPE: {$typename}  BOOK: {$fbooks}  ID2: {$id2}" . "<br>";
                                      }
    
                                    //echo "HOME TEAM: {$hteam} <BR>";
                                    //echo "AWAY TEAM: {$ateam} <BR>";  
    
                                    $this->execOdds($stmt, $fixid, $updateddate,
                                    $typename, $fcountries,$league->attributes()->name,
                                    $league->attributes()->id, $subid, $league->attributes()->cup,$sportname,
                                    $hteam,$match->home->attributes()->id,
                                    $ateam,$match->away->attributes()->id, $datetime, $dbdate,
                                    $dbtime, $match->attributes()->status, $numodds,$homeodds,$drawodds,
                                    $awayodds, $fbooks, $bookmaker->attributes()->id, $dbhandicap, $id2);
    
                                    }
                                }
                                }
                                }
                            }}
                        }
                    }
                }
            }
            $this->PDO->commit(); //SAVE
            $this->conn->close();
            $this->error = false;
            }
        catch(Exception $e){
    
        }
    }
    private function execOdds($stmt, $matchid, $upddate, $type, $country, $league, $leagueid, $subid, $cup, $sport, $hteam, $hteamid, $ateam, $ateamid, $datetime, $date, $time, $status, $numodds, $homeodds, $drawodds, $awayodds, $book, $bookid, $handicap, $id2){
    
        $event = $hteam . ' - ' . $ateam;
    
        $fcountry = $country;
        $fleague = $this->getMap2($league);
    
        $stmt->bindParam(':fixturematchid', $matchid);$stmt->bindParam(':updateddate',$upddate);$stmt->bindParam(':type',$type);
        $stmt->bindParam(':country',$fcountry);$stmt->bindParam(':league',$fleague);$stmt->bindParam(':leagueid',$leagueid);
        $stmt->bindParam(':subid',$subid);
        $stmt->bindParam(':cup',$cup);$stmt->bindParam(':eventname',$event);$stmt->bindParam(':sportname',$sport);
        $stmt->bindParam(':hometeam', $hteam);$stmt->bindParam(':hometeamid', $hteamid);$stmt->bindParam(':awayteam', $ateam);
        $stmt->bindParam(':awayteamid', $ateamid);$stmt->bindParam(':datetime',$datetime);$stmt->bindParam(':date',$date);
        $stmt->bindParam(':time',$time);$stmt->bindParam(':status',$status);$stmt->bindParam(':numodds', $numodds);
        $stmt->bindParam(':homeodds', $homeodds);$stmt->bindParam(':drawodds',$drawodds);$stmt->bindParam(':awayodds',$awayodds);
        $stmt->bindParam(':bookmaker',$book);$stmt->bindParam(':bookmakerid',$bookid);$stmt->bindParam(':handicap', $handicap);
        $stmt->bindParam(':id2', $id2);
        $stmt->execute(); //EXEC*/
    }
    

1 个答案:

答案 0 :(得分:1)

因为您在错误日志中遇到某些查询尝试锁定记录而其他查询已经通过锁定使用它。可能有多种原因,因此请尝试与他们核对并解决问题。

第一步:

当你在帖子中更新cron花费超过3分钟并且下一轮开始时,可​​能是第一次cron正在使用某些记录而第二次cron也试图锁定它。

但是,只有当您的查询没有正确使用索引并尝试锁定比预期更多的记录时,它才会出现。因此,如果可以优化,请检查您的查询。

第二步:

可能是某个其他进程也试图锁定此cron正在执行的行,因此检查引擎innodb状态中的详细信息,表明哪个进程正在创建死锁。

您还可以通过任何gui工具监控,例如mysqladmin在此cron时尝试获取锁定的查询,并优化查询/代码。