Veritabanı Hatası

5 Cevap php

Ben her gün sadece yaklaşık 100 kişiyi alan bir site var ama bir kullanıcı olarak oturum açtığınızda bu hata mesajını aldım:

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

Ben sayfa zaman bir çift yenilemek ve şimdi onun ok, ama ben hata sanıyorum birçok kullanıcı kendi kodumu, nerede bunun için bakmak gerektiğini dont beri?

Thx

Düzenleme: Bu modeli dosyasıdır:

<?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;
    }



}

?>

5 Cevap

Bu sorunu düzeltmek gerekir, ama bunu test etmedi. fark: getConnection() ilk kez çağrılırsa, bir bağlantı yapılır ve saklanır. Zaman dinlenme, zaten kurulmuş bağlantı kullanılır.

bu ilk değişiklik işe yaramaz hale getirecektir çünkü ben, CloseConnection eylemi kaldırıldı. taşıyamazsınız o execSQL gelen CloseConnection aramayı kaldırmak için daha iyi olurdu.

komut (sürece mysqli sebat desteklemiyor gibi) sonlandırıldığında, normalde (bildiğim kadarıyla), veritabanı bağlantısı otomatik olarak kapanır. ama tüm veritabanı şeyler bittikten sonra el CloseConnection (bir çalışma) aramak için daha iyi olurdu.

<?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 (...)
}

?>

ve ... ben gelecekte bu tür sorunları önlemek için varolan bir veritabanı erişim soyutlama katmanı kullanmanızı tavsiye ediyorum.

Bir veritabanı bağlantısı açar web sitenizde Her isabet aynı veritabanı kullanıcı adı ve şifreyi kullanıyor. Sizin veritabanı ayarları kullanıcı başına temelinde bağlantı sınırlı sayıda, ve bu maksimum üzerinden gidiyoruz.

Bu MySQL manuel sayfasına göz atın: http://dev.mysql.com/doc/refman/5.0/en/user-resources.html

Bu açılış ve her bireyin sorgu üzerinde bir veritabanı bağlantısını kapatma gibi görünüyor gibi model sınıf, büyük değildir. Açılış ve kapanış bağlantıları pahalı gibi bu kaynakların çok kötü kullanımıdır. Ben $ db-> close () adında bir model nesne üzerinde bir yıkıcı fonksiyon yazmak, ve bir kez bağlantıyı açmak için getConnection () olarak değiştirin ve sonra onu bundan sonra her zaman dönecekti. Bu statik olmayan kullanım için model sınıf dönüştürme anlamına gelir, ama bunu yapmak için veritabanı üzerinde çok daha kolay olacaktır.

Her neyse, bu mümkün değil, tüm bağlantı ve sınıf MySQL yedekleme bağları olduğunu yapıyor deconnecting ve size maksimum kullanım sınırına ulaşmadan önce yeterince hızlı takas edilmez.

Veritabanı bağlantıları başa çıkıyor sizin kod bak. Eğer bir havuz kullanıyor musunuz? Eğer PHP veritabanı soyutlama çerçeveler birini kullanıyor musunuz?

Are you handling connections in each database access? If so, you're looking for code that doesn't explicitly release/close the database connections. (if you're doing it this way, I'd suggest looking at an article like this: http://www.devshed.com/c/a/PHP/Database-Abstraction-With-PHP/ )

Sen bakmak isteyebilirsiniz this doc page - yorumlarda bazı yararlı ipuçları vardır.

Iki sorun var burada; Bir diğer arttıran.

@ Zombat büyük sorun belirlemiştir: bağlanmak için gereken ve her bir sorgu için kesmeyin. MySQL hızlı kurulum ve devrelerde döngüsü vardır rağmen, diğer kaynaklara harcar. Sayfa sona kadar, bir zamanlar kodun kurulum aşamasında bağlantısını açın ve daha sonra her bir sorgu için tekrar tekrar bağlantısını kullanmak daha mantıklı. Ben mysqli nesnesi için bir örnek değişkeni kullanarak öneririm.

Eğer birden fazla veritabanı ve hangisinin nesneye bağlıdır vardır bir yapı varsa, (o zaman bunun sadece ihtiyacı olanları açar bu yüzden açık sahip olduğu veritabanı bağlantıları takip veritabanı işleyicisi geliştirmek gerekir. Fakat bu olduğunu çoğu insan yapmak gerekmez çok daha gelişmiş bir konudur.)

Burada oynamak "diğer kaynaklar" MySQL bağlantıları vardır. Mysqli kalıcı bağlantılarını oluşturmak ise, aslında (hatta bu sorunu olmazdı bu yüzden de, aslında, bağlantıları yeniden kullanıyor olmalıdır, ama sapmak) MySQL bağlantıyı kapatmadan olmayacaktır. Muhtemelen bu sınırın içine koşuyoruz yüzden bu tür bağlantıları aşımından için MySQL'in varsayılan değer, birkaç saattir. Eğer SHOW PROCESSLIST sonra bu olup bitenler de "uyku" parçacığı yüzlerce görürseniz. Değiştirilebilir bir parametredir wait_timeout. Ve max_connections çok, çok düşük olabilir.

Ama ilk veritabanı işleyicisi düzeltmek öneririz.