Mysql: Trop de connections

Créé le 23 juil. 2013  ·  9Commentaires  ·  Source: go-sql-driver/mysql

Je vois le message d'erreur "Connexions trop humaines" lorsque j'appelle db.sqlDB.Query (). Avant d'approfondir ce problème, je me demande s'il existe un problème connu.

Pensées?

013/07/23 03:05:35 yy.UpdateThingy () db.go: 264 [Impossible d'insérer l'enregistrement dans XXXX: Erreur 1040: Trop de connexions]

J'utilise la version 1.1.1 de go:
aller à la version go1.1.1 linux / 386

J'utilise la version du pilote mysql:
v1.0.1

Version MySql:
Version du serveur: 5.5.22-0ubuntu1 (Ubuntu)

Voici un exemple de l'une de mes requêtes:
lignes, err =
db.sqlDB.Query ("insérer dans la valeur XXXX (aaaa) (?)",
connect.ZZZZ)
si err! = nil {
_ = lignes.Fermer ();
retourne le résultat, err
}
_ = lignes.Fermer ();

J'ai ajouté "rows.Close ()" en espérant que cela résoudrait le problème, mais pas de dés.

Pour info, certaines de mes requêtes utilisent "rows.Scan" et d'autres non.

question working as intended

Commentaire le plus utile

Option 1: concurrence trop élevée

Vous avez trop d'accès simultanés à la base de données. Dans ce cas, vous devez limiter manuellement le nombre de connexions simultanées jusqu'à ce que le package base de données / sql fournisse un mécanisme de blocage dans une version future pour cela. Mais dans de nombreux cas, la mise en cache / les mises à jour asynchrones seraient la meilleure alternative.

Option 2: Fuites de connexions

Très probablement, votre programme ne fait que fuir les connexions à la base de données. Cela se produit si vous ne fermez pas le rows retourné par db.Query ou si vous oubliez de terminer les transactions (dans l'api tx de la base de

Mon conseil général est d'utiliser

  • db.Exec si vous n'attendez pas une ligne retournée (en d'autres termes, vous ne Scan rien). La connexion est immédiatement gratuite après l'exécution.
  • db.QueryRow si vous attendez une ligne. Si vous utilisez la syntaxe chaînée , vous ne pouvez pas fuir les connexions
  • db.Query si vous attendez plusieurs lignes. Il est très important que vous "libériez" la connexion en lisant soit toutes les lignes retournées (en boucle rows.Next ) ou en appelant rows.Close . Pour être sûr, reporter un appel rows.Close est une bonne idée. N'oubliez pas les cas d'erreur, etc.

Tous les 9 commentaires

Veuillez jeter un œil ici: https://github.com/VividCortex/go-database-sql-tutorial

N'utilisez pas .Query, utilisez .Exec.

Option 1: concurrence trop élevée

Vous avez trop d'accès simultanés à la base de données. Dans ce cas, vous devez limiter manuellement le nombre de connexions simultanées jusqu'à ce que le package base de données / sql fournisse un mécanisme de blocage dans une version future pour cela. Mais dans de nombreux cas, la mise en cache / les mises à jour asynchrones seraient la meilleure alternative.

Option 2: Fuites de connexions

Très probablement, votre programme ne fait que fuir les connexions à la base de données. Cela se produit si vous ne fermez pas le rows retourné par db.Query ou si vous oubliez de terminer les transactions (dans l'api tx de la base de

Mon conseil général est d'utiliser

  • db.Exec si vous n'attendez pas une ligne retournée (en d'autres termes, vous ne Scan rien). La connexion est immédiatement gratuite après l'exécution.
  • db.QueryRow si vous attendez une ligne. Si vous utilisez la syntaxe chaînée , vous ne pouvez pas fuir les connexions
  • db.Query si vous attendez plusieurs lignes. Il est très important que vous "libériez" la connexion en lisant soit toutes les lignes retournées (en boucle rows.Next ) ou en appelant rows.Close . Pour être sûr, reporter un appel rows.Close est une bonne idée. N'oubliez pas les cas d'erreur, etc.

J'ai changé "db.Query ()" en "db.Prepare () et db.Exec ()" et cela a résolu mon problème. Merci pour les réponses rapides et excellentes.

J'ai aussi ça.
et, j'utilise "db.Prepare () et db.Exec ()",

var db * sql.DB

func getdb () * sql.DB {
db, err = sql.Open ("mysql", connArgs)
db.SetMaxIdleConns (100)
retour db
}

func foo (db * sql.DB) {
faire quelque chose .....
smint, err: = db.Prepare (....)
reporter smint.Close ()
smint.Exec (....)
}

func main () {
aller func () {
db = get_db ()
différer db.Close ()
toto (db)
} ()
}

essayez go 1.3
----- Le message d'origine -----
De: liutaihua [email protected]
Destinataire: go-sql-driver / mysql [email protected]
Sujet: Re: [mysql] Trop de connexions (# 111)
Date: 16 juillet 2014 à 15h43

et ... pourquoi commencez-vous une goroutine en gros?
Si votre code ressemble vraiment à ceci, main peut (et sera probablement) quitter avant que la goroutine ne soit lancée et votre programme ne fera rien du tout.
Supprimez simplement les go func(){ et }() . Vous serez mieux.

désolé pour ma description, en fait, code:

func socke_server () {
pour {
// accepter_something_from_socket comme réception
go func (some_receive) {
db = get_db ()
différer db.Close ()
toto (db)
}
}
}

func main () {
serveur_socke ()
}

Mais, maintenant, j'utilise le protocole de domaine Unix (' user: pwd @ unix (/tmp/mysql.sock)/'), cela a été corrigé.

merci réponse

Vous ne devriez pas faire cela non plus - cela peut fonctionner, mais c'est lent.

Mettez la boucle d'acceptation dans main.
Convertissez le goroutine en une fonction de niveau supérieur.
Mettez votre code get_db en haut de votre main et ajustez db.Closer là aussi (et seulement là).
N'ouvrez et ne fermez pas la base de données de cette manière.

Essayez le code suivant:

func handleConnection(db *sql.DB, args...interface{}) {
    // do someting.....
    // db.Exec("STATEMENT", args...)
}

func main() {
    db, err := sql.Open("mysql", connArgs)
    if err != nil {
        panic(err)
    }
    db.SetMaxIdleConns(100)
    defer db.Close()
    for {
        // accept connections and pass relevant stuff to handleConnection
        go handleConnection(db, nil)
    }
}

Merci je l'ai eu.

Cette page vous a été utile?
0 / 5 - 0 notes