Was sind Benutzerverbindungen - wann werden die erstellt und zerstört?


7

Wir haben vor Ort einen zeitweiligen Fehler erhalten:

Warnung: mysql_connect () [function.mysql-connect]: Benutzer '557574_prod' hat die Ressource 'max_user_connections' überschritten (aktueller Wert: 10)

Dies verhindert, dass auf die Site zugegriffen wird, und ist effektiv nicht verfügbar.

(Offensichtlich würde eine Erhöhung der 'max_user_connections' das Problem beheben, aber dies ist keine Option durch unser Hosting-Schema.)

Ich habe es vielleicht 'behoben', bin mir aber nicht 100% sicher, ob ich das Problem verstehe und möchte klar sein. Ich dachte, das Problem muss durch zu viele Cron-Jobs verursacht werden, die die Verbindungen verbrauchen (wir haben ein paar pro Minute), und ich habe die Anzahl der Cron-Jobs reduziert und das schien die Anzahl der Fehler zu verringern. Ich habe ein separates Benutzerkonto für die Cron-Jobs erstellt. Wenn dies das Problem war, sollte es jetzt behoben werden.

Unser Protokollierungssystem zeichnet den Fehler jedoch nicht auf, wenn er auftritt, daher bin ich immer noch besorgt.

Ich frage also: Was macht eine 'user_connection' in MySQL aus?

  • Gibt es für jeden DB-Aufruf eine separate Verbindung?
  • Wenn nicht, wann würden DB-Aufrufe eine separate Verbindung erfordern?
  • Warum sollte dieser Fehler nur auf der Live-Produktionsstätte auftreten? Vielleicht gibt es eine separate Verbindung für jede einzelne IP oder Simialr?

Ich habe das Gefühl, ich überdenke es. . .


Dies ist eine sehr nützliche Frage, über die die Community jetzt nachdenken und später beraten kann. +1 !!!
RolandoMySQLDBA

Antworten:


10

Bitte beachten Sie das Make-up von mysql.user:

mysql> show create table mysql.user\G
*************************** 1. row ***************************
       Table: user
Create Table: CREATE TABLE `user` (
  `Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',
  `User` char(16) COLLATE utf8_bin NOT NULL DEFAULT '',
  `Password` char(41) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '',
  `Select_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Insert_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Update_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Delete_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Create_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Drop_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Reload_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Shutdown_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Process_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `File_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Grant_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `References_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Index_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Alter_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Show_db_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Super_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Create_tmp_table_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Lock_tables_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Execute_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Repl_slave_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Repl_client_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Create_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Show_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Create_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Alter_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Create_user_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Event_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Trigger_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `Create_tablespace_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
  `ssl_type` enum('','ANY','X509','SPECIFIED') CHARACTER SET utf8 NOT NULL DEFAULT '',
  `ssl_cipher` blob NOT NULL,
  `x509_issuer` blob NOT NULL,
  `x509_subject` blob NOT NULL,
  `max_questions` int(11) unsigned NOT NULL DEFAULT '0',
  `max_updates` int(11) unsigned NOT NULL DEFAULT '0',
  `max_connections` int(11) unsigned NOT NULL DEFAULT '0',
  `max_user_connections` int(11) unsigned NOT NULL DEFAULT '0',
  `plugin` char(64) COLLATE utf8_bin DEFAULT '',
  `authentication_string` text COLLATE utf8_bin,
  PRIMARY KEY (`Host`,`User`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges'
1 row in set (0.00 sec)

Beachten Sie die Spalte max_user_connections. Es gibt ein Moratorium für die Anzahl der Verbindungen, die ein Benutzer pro Stunde herstellen kann. Überprüfen Sie, ob der Benutzer '557574_prod' innerhalb von weniger als einer Stunde tonnenweise eine Verbindung zu MySQL herstellt.

Dies wird in Verbindung mit der Option max_user_connections verwendet, die Sie in /etc/my.cnf festlegen können

Bitte ändern Sie entweder max_user_connections in /etc/my.cnf oder, wenn der einzelne Benutzer diese Spalte festgelegt hat, diese Spalte mysql.user.max_user_connections. Wenn Sie keine Konfigurationskontrolle über my.cnf haben und SQL nicht gegen das MySQL-Schema ausführen können, bitten Sie Ihr Hosting-Unternehmen, diese Grenzwerte für Sie anzuheben.

Ich glaube, Sie können die max_user_connections als Sitzungsvariable festlegen, aber Sie benötigen möglicherweise bestimmte Berechtigungen, wahrscheinlich SUPER.

Um Verbindungen herzustellen, müssen Sie diese Verbindungen offen halten. Vielleicht einen Herzschlag durch Auswählen senden. Aber rate mal was ??? Die DB-Spalten max_questions überwachen SELECT-Abfragen pro Stunde und max_updates überwacht INSERTs, UPDATEs und DELETEs pro Stunde. Möglicherweise müssen Sie diese Spalten in mysql.user überprüfen. Sie können diese Nummer schnell überprüfen mit:

SHOW GRANTS;

Ich bin nicht sicher, ob die Verbindungsbeschränkungen des Benutzers pro Stunde pro Thread oder pro Benutzer gelten. Sie können dies schnell beantworten, indem Sie eine aggressive Verbindung zur DB herstellen, indem Sie zwei oder drei DB-Verbindungen gleichzeitig verwenden. Die Fehlermeldung sollte sich dann manifestieren. Es liegt an Ihnen, wie Sie die Anzahl der Verbindungen zählen, vielleicht "STATUS WIE 'Verbindungen' ANZEIGEN;" Es sollte entweder die maximale Grenze der Verbindung innerhalb der einen Verbindung erreichen oder es kann die Summe des Verbindungsstatuswerts aller Verbindungen sein.

Bitte überprüfen Sie auch die Werte wait_timeout und interaktive_timeout. Der Standardwert ist 28800 auf einem eigenständigen Server. Sie können bereits eingestellt sein. Sie können sie nicht innerhalb einer aktuellen Verbindung einstellen. Sie müssen in der Lage sein, sie wie folgt einzustellen: (für neue Verbindungen)

SET GLOBAL interactive_timeout = 86400;
SET GLOBAL wait_timeout = 86400;

Wenn Sie nicht einmal diese Befehle ausführen können, mein Beileid !!! :((


Ah, ich habe nicht einmal SELECT-Berechtigungen für mysql.user, aber ein Chat mit dem Support hat ergeben, dass wir aufgrund zu vieler langsamer Abfragen eine Ratenbeschränkung haben. Trotzdem fand ich Ihren Beitrag wie immer informativ und hilfreich.
JIStone

Sehr schöne Zusammenfassung.
Derek Downey

Klarstellung, die Anzahl der Verbindungen des Benutzers ist begrenzt . max_user_connections begrenzt gleichzeitige Verbindungen, nicht Verbindungen pro Stunde.
Brad Koch
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.