Veo el mensaje de error "Demasiadas conexiones de hombre" cuando llamo a db.sqlDB.Query (). Antes de profundizar en este tema, me pregunto si existe un problema conocido.
¿Pensamientos?
013/07/23 03:05:35 aa.UpdateThingy () db.go: 264 [No se pudo insertar el registro en XXXX: Error 1040: Demasiadas conexiones]
Estoy usando go versión 1.1.1:
go versión go1.1.1 linux / 386
Estoy usando la versión del controlador mysql:
v1.0.1
Versión de MySql:
Versión del servidor: 5.5.22-0ubuntu1 (Ubuntu)
Aquí hay una muestra de una de mis consultas:
filas, err =
db.sqlDB.Query ("insertar en XXXX (yyyy) valor (?)",
conectar.ZZZZ)
if err! = nil {
_ = filas.Cerrar ();
devolver resultado, err
}
_ = filas.Cerrar ();
Agregué "filas.Cerrar ()" con la esperanza de que solucionara el problema, pero no dados.
Para su información, algunas de mis consultas usan "filas. Escanear" y otras no.
Eche un vistazo aquí: https://github.com/VividCortex/go-database-sql-tutorial
No use .Query, use .Exec.
Tiene demasiados accesos simultáneos a la base de datos. En este caso, debe limitar manualmente el número de conexiones simultáneas hasta que el paquete database / sql proporcione un mecanismo de bloqueo en una versión futura para eso. Pero en muchos casos el almacenamiento en caché / actualizaciones asincrónicas sería la mejor alternativa.
Lo más probable es que su programa solo esté filtrando conexiones de base de datos. Esto sucede si no cierra el rows
devuelto por db.Query
u olvidó finalizar las transacciones (en la base de
Mi consejo general es usar
db.Exec
si no espera una fila devuelta (en otras palabras, no Scan
nada). La conexión es inmediatamente libre después de la ejecución.db.QueryRow
si espera una fila. Si usa la sintaxis encadenada , no puede filtrar conexionesdb.Query
si espera varias filas. Es muy importante que "liberes" la conexión leyendo todas las filas devueltas (en bucle rows.Next
) o llamando rows.Close
. Sin duda, aplazar una llamada de rows.Close
es una buena idea. No se olvide de los casos de error, etc.Cambié "db.Query ()" a "db.Prepare () y db.Exec ()" y eso solucionó mi problema. Gracias por las excelentes y rápidas respuestas.
Yo también tengo esto.
y utilizo "db.Prepare () y db.Exec ()",
var db * sql.DB
func getdb () * sql.DB {
db, err = sql.Open ("mysql", connArgs)
db.SetMaxIdleConns (100)
volver db
}
func foo (db * sql.DB) {
hacer algo ...
smint, err: = db.Prepare (....)
diferir smint.Close ()
smint.Exec (....)
}
func main () {
go func () {
db = get_db ()
aplazar db.Close ()
foo (db)
} ()
}
intenta ir 1.3
----- El mensaje original -----
De: liutaihua [email protected]
Destinatario: go-sql-driver / mysql [email protected]
Asunto: Re: [mysql] Demasiadas conexiones (# 111)
Fecha: 15:43, 16 de julio de 2014
y ... ¿por qué inicias una goroutine en main?
Si su código realmente se ve así, main puede (y probablemente lo hará) salir antes de que se ejecute goroutine y su programa no hará nada en absoluto.
Simplemente elimine go func(){
y }()
. Estarás mejor.
perdón por mi descripción, en realidad, código:
func socke_server () {
por {
// accept_something_from_socket como recibir
go func (some_receive) {
db = get_db ()
aplazar db.Close ()
foo (db)
}
}
}
func main () {
servidor_socke ()
}
Pero, ahora, uso el protocolo de dominio Unix (' usuario: pwd @ unix (/tmp/mysql.sock)/'), se solucionó.
gracias respuesta
Tampoco deberías hacer eso; puede funcionar, pero es lento.
Ponga el lazo de aceptación en main.
Convierta la goroutine en una función de nivel superior.
Coloque su código get_db en la parte superior de su main y difiera db.Closer allí también (y solo allí).
No abra y cierre la base de datos de esta manera.
Prueba el siguiente código:
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)
}
}
Gracias lo tengo.
Comentario más útil
Opción 1: concurrencia demasiado alta
Tiene demasiados accesos simultáneos a la base de datos. En este caso, debe limitar manualmente el número de conexiones simultáneas hasta que el paquete database / sql proporcione un mecanismo de bloqueo en una versión futura para eso. Pero en muchos casos el almacenamiento en caché / actualizaciones asincrónicas sería la mejor alternativa.
Opción 2: conexiones con fugas
Lo más probable es que su programa solo esté filtrando conexiones de base de datos. Esto sucede si no cierra el
rows
devuelto pordb.Query
u olvidó finalizar las transacciones (en la base deMi consejo general es usar
db.Exec
si no espera una fila devuelta (en otras palabras, noScan
nada). La conexión es inmediatamente libre después de la ejecución.db.QueryRow
si espera una fila. Si usa la sintaxis encadenada , no puede filtrar conexionesdb.Query
si espera varias filas. Es muy importante que "liberes" la conexión leyendo todas las filas devueltas (en buclerows.Next
) o llamandorows.Close
. Sin duda, aplazar una llamada derows.Close
es una buena idea. No se olvide de los casos de error, etc.