При вызове db.sqlDB.Query () появляется сообщение об ошибке «Слишком много соединений». Прежде чем я углублюсь в эту проблему, мне интересно, есть ли известная проблема.
Мысли?
013/07/23 03:05:35 yy.UpdateThingy () db.go: 264 [Не удалось вставить запись в XXXX: Ошибка 1040: Слишком много подключений]
Я использую версию 1.1.1:
go версия go1.1.1 linux / 386
Я использую версию драйвера mysql:
v1.0.1
Версия MySql:
Версия сервера: 5.5.22-0ubuntu1 (Ubuntu)
Вот пример одного из моих запросов:
строки, err =
db.sqlDB.Query ("вставить в XXXX (yyyy) значение (?)",
connect.ZZZZ)
if err! = nil {
_ = rows.Close ();
вернуть результат, ошибка
}
_ = rows.Close ();
Я добавил rows.Close (), надеясь, что это решит проблему, но без кубиков.
К вашему сведению, некоторые из моих запросов используют "rows.Scan", а некоторые нет.
Взгляните сюда: https://github.com/VividCortex/go-database-sql-tutorial
Не используйте .Query, используйте .Exec.
У вас слишком много одновременных обращений к базе данных. В этом случае вы должны вручную ограничить количество одновременных подключений, пока пакет database / sql не предоставит для этого механизм блокировки в будущей версии. Но во многих случаях кеширование / асинхронные обновления были бы лучшей альтернативой.
Скорее всего, ваша программа просто теряет соединения с базой данных. Это происходит, если вы не закрываете rows
возвращаемое db.Query
или забыли завершить транзакции (в базе данных / sql tx api ).
Мой общий совет - использовать
db.Exec
если вы не ожидаете возвращаемой строки (другими словами, вы ничего не Scan
). После казни соединение сразу же становится свободным.db.QueryRow
если вы ожидаете одну строку. Если вы используете цепной синтаксис , вы не можете утечь соединенияdb.Query
если вы ожидаете несколько строк. Очень важно, чтобы вы «освободили» соединение, прочитав все возвращенные строки (цикл rows.Next
) или вызвав rows.Close
. Конечно, неплохо отложить вызов rows.Close
. Не забывайте об ошибках и т. Д.Я изменил "db.Query ()" на "db.Prepare () и db.Exec ()", и это устранило мою проблему. Спасибо за быстрые и отличные ответы.
Я тоже получил это.
и я использую "db.Prepare () и db.Exec ()",
var db * sql.DB
func getdb () * sql.DB {
db, err = sql.Open ("mysql", connArgs)
db.SetMaxIdleConns (100)
вернуть db
}
func foo (db * sql.DB) {
сделать что-нибудь .....
smint, err: = db.Prepare (....)
отложить smint.Close ()
smint.Exec (....)
}
func main () {
go func () {
db = get_db ()
отложить db.Close ()
foo (db)
} ()
}
попробуйте пойти 1.3
----- Исходное сообщение -----
От: liutaihua [email protected]
Получатель: go-sql-driver / mysql [email protected]
Тема: Re: [mysql] Слишком много соединений (# 111)
Дата: 15:43, 16 июля 2014 г.
и ... почему вы запускаете горутину в основном?
Если ваш код действительно выглядит так, main может (и, вероятно, будет) завершиться до запуска горутины, и ваша программа вообще ничего не сделает.
Просто удалите go func(){
и }()
. Тебе будет лучше.
извините за мое описание, собственно, код:
func socke_server () {
для {
// accept_something_from_socket как получить
go func (some_receive) {
db = get_db ()
отложить db.Close ()
foo (db)
}
}
}
func main () {
socke_server ()
}
Но теперь я использую протокол домена Unix (' user: pwd @ unix (/tmp/mysql.sock)/'), это исправлено.
спасибо ответ
Вы тоже не должны этого делать - это может сработать, но медленно.
Поместите цикл принятия в файл main.
Преобразуйте горутину в функцию верхнего уровня.
Поместите код get_db в верхнюю часть основного файла и отложите db.Closer там (и только там).
Не открывайте и не закрывайте БД таким образом.
Попробуйте следующий код:
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)
}
}
Спасибо, поняла.
Самый полезный комментарий
Вариант 1. Слишком высокая степень параллелизма
У вас слишком много одновременных обращений к базе данных. В этом случае вы должны вручную ограничить количество одновременных подключений, пока пакет database / sql не предоставит для этого механизм блокировки в будущей версии. Но во многих случаях кеширование / асинхронные обновления были бы лучшей альтернативой.
Вариант 2: негерметичные соединения
Скорее всего, ваша программа просто теряет соединения с базой данных. Это происходит, если вы не закрываете
rows
возвращаемоеdb.Query
или забыли завершить транзакции (в базе данных / sql tx api ).Мой общий совет - использовать
db.Exec
если вы не ожидаете возвращаемой строки (другими словами, вы ничего неScan
). После казни соединение сразу же становится свободным.db.QueryRow
если вы ожидаете одну строку. Если вы используете цепной синтаксис , вы не можете утечь соединенияdb.Query
если вы ожидаете несколько строк. Очень важно, чтобы вы «освободили» соединение, прочитав все возвращенные строки (циклrows.Next
) или вызвавrows.Close
. Конечно, неплохо отложить вызовrows.Close
. Не забывайте об ошибках и т. Д.