max_user_connections trotz persistenter Verbindung
lima-city → Forum → Programmiersprachen → PHP, MySQL & .htaccess
array
aufruf
begrenzung
code
datenbank
host
limit
made
maximale anzahl
null
nutzer
problem
session
start
stunde
test
url
verbindung
verwaltung
zugreifen
-
Hallo zusammen,
da ich damals manchmal die Fehlermeldung "User '...' has exceeded the 'max_user_connections' resource (current value: 20)" erhalten habe, habe ich meine Verbindung zur MySQL Datenbank auf eine persistente Verbindung umgestellt, da dabei ja angeblich nur eine Verbindung erstellt wird, auf die alle zugreifen. So sieht also jetzt meine Verbindung aus:
try{ $handler = new PDO('mysql:host=localhost;dbname=...', '...', '...', array(PDO::ATTR_PERSISTENT => true)); $handler->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch(PDOException $e){ echo $e->getMessage(); die(); }
Trotzdem kommt hin und wieder noch die oben genannte Fehlermeldung. So wird sie dann im Catch Teil ausgegeben:
SQLSTATE[HY000] [1226] User '...' has exceeded the 'max_user_connections' resource (current value: 20)
Ist an meinem Code was falsch oder fehlt da was? Oder habe ich einfach nur was falsch verstanden bei den persistenten Verbindungen?
Ich hoffe mir kann jemand helfen.
Viele Grüße
Beitrag zuletzt geändert: 30.9.2014 11:26:28 von ultimate-bravery -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Eine persistente Verbindung wird einmalig aufgebaut und ab dann immer wieder verwendet. Wenn du allerdings 10 Verbindungen gleichzeitig nutzen willst, dann werden auch 10 persistente Verbindungen aufgebaut. Das Manual von MySQL sagt zu der Variablen:
This limits the number of simultaneous connections that can be made by any given account, but places no limits on what a client can do once connected.
Mit den persistenten Verbindungen umgehst du übrigens nur eine einzige Einschränkungen: die maximale Anzahl an Verbindungen pro Stunde. -
hackyourlife schrieb:
Mit den persistenten Verbindungen umgehst du übrigens nur eine einzige Einschränkungen: die maximale Anzahl an Verbindungen pro Stunde.
Gibt es denn eine Möglichkeit, mein Problem zu lösen, ohne das Limit anheben zu lassen? Weil wenn ich das richtig verstanden habe könnten ja sonst nicht mehr als 20 Leute gleichzeitig auf meine Website oder? -
Hi,
mal ein Gedankengang dazu.
Du kannst doch beim ausführen des Skriptes prüfen was bereits an Verbindungen besteht, wenn eine Gewissen Anzahl erreicht ist (zb.15) drosselst Du die Ausführung des Skriptes runter und führst die aktuelle Anfrage etwas später aus. So vermeidest Du vielleicht den Kollaps.
Die bestehenden Verbindungen kann man soweit ich weiß mit
abfragen, da müsstest Du aber für genauere Infos selber mal schauen.SHOW PROCESSLIST
Ich denke aber das Du auf Dauer wohl bei steigender User Zahl nicht um das erhöhen der Begrenzung herumkommen wirst.
Vieleicht hilft es Dir ja weiter.
Gruß Marco
-
Also bei PHP hast du die besonderheit, dass jeder user in seiner eigenen session versinkt und du direkt nicht sehen kannst, was andere user gerade machen... also gelten die persistenten Verbindungen auch User-bezogen, das heißt bei einem Limit von 20 hast du 20 User die gleichzeitig drauf zugreifen können...
was jetzt etwas kurios ist, ist das problem, welches durch die Persistenten verbindungen zusätzlich entsteht, dass du die session manuell wieder schließen musst, da die sonst offen bleibt... persistente verbindungne geben dir eigentlich nur 2 Vorteile: das öffnen und schließen für jede kleine geschichte entfällt, du sparst etwas zeit und du kannst für dich als Admin die ausnahmne machen, dass du immer eine persistente verbindung an deine Admin-session bindest, über die du deine Verwaltung machst. Dann kannst du das ding verwalten, auch wenn die Seite zu ist... aber ansonsten bringt dir das wenig, wenn, dann müstest du über C# eigenen CodeBehind schreiben, da geht das... ansosnten hättest du die Möglichkeit, auf XML-Dateien zum Cachen auszuweichen... die dann sich regelmäßig mit der Datenbank syncronisieren... -
Hi,
ich denke ich weiß wo dein Problem liegt und das sind nicht die "vielen" Nutzer deiner Website. Ich glaube nämlich nicht, dass da so viele Nutzer gleichzeitig Anfragen an den Webserver stellen, sodass dein Limit an Verbindungen überschritten wird. Ich denke eher, dass dein Script nicht sinnvoll aufgebaut ist und ständig neue Datenbankverbindungen aufbaut, obwohl es eigentlich nur eine Verbindung bräuchte, somit überschreitest du natürlich schnell die Anzahl der gültigen Zugriffe, wenn du die Verbindungen nicht richtig schließt.
Wenn du PDO benutzt, welches ich auch empfehlen würde, dann musst du die Variable expliziet mit null füllen, um die Verbindung zu schließen, aber das nur nebenbei.
Was du brauchst ist eine Factory, die dir immer eine funktionierende Verbindungsinstanz zurück gibt. Dazu habe ich dir mal dieses kleine Script geschrieben, welches solch eine Factory und deren Aufruf zeigt, außerdem enthält es einen einfachen Test, der dein Problem darstellt. Der Test zeigt auch, dass dein Problem mit der Factory nicht auftrit.
<?php define('DB_NAME', 'test_db'); define('DB_HOST', 'localhost'); define('DB_USER', 'testuser'); define('DB_PASS', 'testpassword'); define( 'DB_DSN', 'mysql:dbname=' . DB_NAME . ';host=' . DB_HOST ); class DbFactory { private static $connection = null; public static function getConnectin( $dsn, $user, $pass, $options = array() ) { if(!isset(self::$connection)){ self::$connection = new PDO( $dsn, $user, $pass, $options ); } return self::$connection; } public static function closeConnection() { if(isset(self::$connection)){ self::$connection = null; } } } // Here starts the classic-test-case $x = array(); echo 'Start classic-test' . PHP_EOL; $errorRaised = false; for($i = 1000; $i--; ){ try { $x[] = new PDO(DB_DSN, DB_USER, DB_PASS); }catch(Exception $e){ if(!$errorRaised){ echo $e->getMessage() . PHP_EOL; } $errorRaised = true; } } $x = array(); // Here ends the classic-test-case // Here starts the factory-test-case $x = array(); echo 'Start factory-test' . PHP_EOL; $errorRaised = false; for($i = 1000; $i--; ){ try { $x[] = DbFactory::getConnectin( DB_DSN, DB_USER, DB_PASS ); }catch(Exception $e){ if(!$errorRaised){ echo $e->getMessage() . PHP_EOL; } $errorRaised = true; } } DbFactory::closeConnection(); $x = array(); // Here ends the factory-test-case
Am Anfang des Scripts musst du zum testen natürlich noch die Konstanten ändern
Mit freundlichen Grüßen -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage