2009-04-22 4 views
0

: 시간의 커플 이제 확인을 나는 페이지를 새로 고침데이터베이스 난 그냥 약 백명 매일 얻는 사이트가 있지만 사용자로 로그인이 오류 메시지가있어 오류

Warning: mysqli::mysqli() [mysqli.mysqli]: (42000/1203): User mexautos_Juan already has more than 'max_user_connections' active connections in /home/mexautos/public_html/kiubbo/data/model.php on line 26 

Warning: mysqli::query() [mysqli.query]: Couldn't fetch mysqli in /home/mexautos/public_html/kiubbo/data/model.php on line 87 
Query failed 

을하지만, 이후로 나는 많은 사람들이 내 코드에서 오류를 의심하지 않는다. 어디에서 찾아야 하는가?

들으

편집 : 데이터베이스 연결을 처리하는 것 코드에서

<?php 
/* 

    Model is the base class from which the other 
    model classes will be derived. It offers basic 
    functionality to access databases 

*/ 
require_once($_SERVER['DOCUMENT_ROOT'].'/config.php'); 
require_once(SITE_ROOT.'includes/exceptions.php'); 

class Model { 

    private $created; 
    private $modified; 

    static function getConnection() 
    { 
     /* 

      Connect to the database and return a 
      connection or null on failure 

     */ 

     $db = new mysqli (DB_HOST, DB_USER, DB_PASS, DB_NAME); 
     if(!$db) { 
      echo mysql_error(); 
      throw new Exception('Could not connect to database', EX_NO_DATABASE_CONNECTION); 
     } 

     return $db; 

    } 

    static function execSQL($query) 
    { 
    /* 
      Execute a SQL query on the database 
      passing the tablename and the sql query. 
      Returns the resultset 
    */ 


     $db = null; 
     $results = null; 
     //echo "query is $query"; 

     try 
     { 
      $db = Model::getConnection(); 
      $results = $db->query($query); 
      if(!$results) { 
       throw new Exception('Query failed', EX_QUERY_FAILED); 
      } 
     } 
     catch(Exception $e) 
     { 
      /* errors are handled higher in the 
        object hierarchy 
      */ 

      throw $e; 
     } 

     Model::closeConnection($db); 

     return $results; 
    } 

    static function execSQl2($query) 
    { 
    /* 
      Execute a SQL query on the database 
      passing the tablename and the sql query. 
      Returns the LAST_INSERT_ID 
    */ 


     $db = null; 
     $lastid = null; 
     //echo "query is $query"; 

     try 
     { 
      $db = Model::getConnection(); 
      $results = $db->query($query); 
      if(!$results) { 
       throw new Exception('Query failed', EX_QUERY_FAILED); 
      } 
      $lastid = $db->insert_id; 
     } 
     catch(Exception $e) 
     { 
      /* errors are handled higher in the 
        object hierarchy 
      */ 

      throw $e; 
     } 

     Model::closeConnection($db); 

     return $lastid; 
    } 

    function delete($table, $id, $conditions = '') 
    { 
     $query = "delete from $table where id = $id"; 
     try 
     { 
      $db = Model::getConnection(); 
      $results = Model::execSQL($query); 
      if(!$results){ 
       throw new Exception('Could not delete this object', EX_DELETE_ERROR); 
      } 
      return $results->num_rows; 
     } 

     catch(Exception $e) 
     { 
      throw $e; 
     } 
    } 

    static function closeConnection($db) 
    { 
     $db->close(); 
    } 

    function getCreated() 
    { 
     return $this->created; 
    } 

    function setCreated($value) 
    { 
     $this->created = $value; 
    } 

    function getModified() 
    { 
     return $this->modified; 
    } 

    function setModified($value) 
    { 
     $this->modified = $value; 
    } 



} 

?> 
+0

감사합니다. 그렇다면 기본적으로 $ db와 동일한 작업을 수행해야합니까? 다음 함수를 사용하여 다른 함수를 작성하십시오. $ results-> close(); ? – jcslzr

+0

솔직히, 나는 잘 모르겠다. 내 의견을 삭제했는데, 이는 내 마음에 들지 않았다. 그러나 mysqli에 대한 문서를 살펴보면 쿼리 결과 집합이 데이터베이스에 대한 버퍼링 된 연결이라는 것을 강하게 알 수 있습니다. $ db-> close()가 연결을 종료하는 것처럼 보일 때까지 질의에 대한 문서는 결과를 얻기 위해 데이터베이스 연결을 사용하고 있음을 나타냅니다. – GoingTharn

+0

고마워요. 내가 살펴볼 것입니다. – jcslzr

답변

1

이 문제가 해결되어야하지만 테스트하지 않았습니다. 차이점 : getConnection()이 처음 호출되면 연결이 만들어져 저장됩니다. 나머지 시간에는 이미 설정된 연결이 사용됩니다.

closeConnection에서 작업을 제거했습니다. 첫 번째 변경 사항을 쓸모 없게 만들었 기 때문입니다. execSQL에서 closeConnection 호출을 제거하는 것이 좋습니다.

정상적으로 (내가 아는 한) mysqli가 지속성을 지원하지 않는 한 스크립트가 종료되면 데이터베이스 연결이 자동으로 닫힙니다. 그러나 모든 database-stuff가 끝난 후에 수동으로 closeConnection을 호출하는 것이 낫습니다.

<?php 
class Model { 

    private $created; 
    private $modified; 

    private static $db = false; 

    static function getConnection() 
    { 
     /* 

      Connect to the database and return a 
      connection or null on failure 

     */ 


     if (self::$db === false) { 
      self::$db = new mysqli (DB_HOST, DB_USER, DB_PASS, DB_NAME); 
     } 

     if(!self::$db) { 
      echo mysql_error(); 
      throw new Exception('Could not connect to database', EX_NO_DATABASE_CONNECTION); 
     } 

     return self::$db; 
    } 

    static function closeConnection() 
    { 
     // self::$db->close(); 
    } 

    // moar functions (...) 
} 

?> 

및 ... 나는 이러한 문제를 피하기 위해 기존 데이터베이스 액세스 추상화 레이어를 사용하는 것이 좋습니다.

+0

감사합니다 Dude was worked – jcslzr

2

봐 :이 모델 파일입니다. 수영장을 이용하고 있습니까? PHP 데이터베이스 추상화 프레임 워크 중 하나를 사용하고 있습니까?

각 데이터베이스 액세스에서 연결을 처리하고 있습니까? 그렇다면 명시 적으로 데이터베이스 연결을 해제하거나 닫지 않는 코드를 찾고 있습니다. 당신은 코멘트에 몇 가지 유용한 팁이 --there 있습니다을 this doc page를 살펴 할 수 있습니다

5

웹 사이트에서 데이터베이스 연결을 열 때마다 동일한 데이터베이스 사용자 이름과 암호가 사용됩니다. 데이터베이스 설정에 따라 사용자 당 연결 수가 제한되어 있으며 그 최대 값을 초과합니다.

체크 아웃이 MySQL의 메뉴얼 페이지 : 그것을 열고 모든 개인 쿼리에 대한 데이터베이스 연결을 닫는 것으로 보인다으로 http://dev.mysql.com/doc/refman/5.0/en/user-resources.html

귀하의 모델 클래스, 즉 크지 않다. 열기 및 닫기 연결이 비용이 많이 들기 때문에 이것은 매우 나쁜 자원 사용입니다. $ db-> close()를 호출 한 모델 객체에 소멸자 함수를 작성하고 getConnection()을 변경하여 연결을 한 번 연 다음 그 후에 매번 리턴합니다. 이는 모델 클래스를 비 정적 사용으로 변환하는 것을 의미하지만 데이터베이스에서 그렇게하는 것이 훨씬 쉬울 것입니다.

어쨌든 클래스 연결 및 연결 해제로 MySQL 연결이 백업되고 최대 사용자 한도에 도달하기 전에 충분히 빠르게 지워지지 않을 수 있습니다.

1

여기에는 두 가지 문제가 있습니다. 하나는 다른 쪽을 악화시킨다.

@zombat은 더 큰 문제를 확인했습니다. 각 쿼리에 대해 연결하거나 연결을 끊을 필요가 없습니다. MySQL은 빠른 셋업과 분해 (teardown) 사이클을 가지고 있지만, 다른 리소스를 낭비합니다. 코드 설정 단계에서 연결을 한 번 연 다음 페이지가 끝날 때까지 각 쿼리에 대해 반복적으로 연결을 사용하는 것이 좋습니다. mysqli 객체에 인스턴스 변수를 사용하는 것이 좋습니다.

(여러 데이터베이스가 있고 오브젝트에 종속 된 구조가있는 경우 열려있는 데이터베이스 연결을 추적하여 데이터베이스가 필요로하는 데이터베이스 핸들러를 향상시켜야합니다. 그러나 이것은 대부분의 사람들이 할 필요가없는 훨씬 더 진보 된 주제입니다.)

"기타 리소스"는 MySQL 연결입니다. mysqli가 영구적 인 연결을 만들고 있다면 실제로 MySQL에 대한 연결을 닫지는 않을 것이다 (실제로이 연결을 다시 사용하면이 문제조차 갖지 않을 것이다. 그러나 나는 빗나간 다.). 이러한 연결을 시간 초과시키기위한 MySQL의 기본값은 몇 시간이기 때문에 아마 그 한계에 부딪 힐 수 있습니다. SHOW PROCESSLIST에 수백 개의 "sleeping"스레드가있는 경우 이것이 발생합니다. 변경할 매개 변수는 wait_timeout입니다. max_connections도 너무 낮을 수 있습니다.

하지만 먼저 데이터베이스 처리기를 수정하는 것이 좋습니다.

관련 문제