Mysql: λ„ˆλ¬΄ λ§Žμ€ μ—°κ²°

에 λ§Œλ“  2013λ…„ 07μ›” 23일  Β·  9μ½”λ©˜νŠΈ  Β·  좜처: go-sql-driver/mysql

db.sqlDB.Query ()λ₯Ό 호좜 ν•  λ•Œ "Too man connections"λΌλŠ” 였λ₯˜ λ©”μ‹œμ§€κ°€ λ‚˜νƒ€λ‚©λ‹ˆλ‹€. 이 문제λ₯Ό μžμ„Ένžˆ μ‚΄νŽ΄λ³΄κΈ° 전에 μ•Œλ €μ§„ λ¬Έμ œκ°€ μžˆλŠ”μ§€ κΆκΈˆν•©λ‹ˆλ‹€.

생각?

013/07/23 03:05:35 yy.UpdateThingy () db.go : 264 [XXXX에 λ ˆμ½”λ“œ μ‚½μž… μ‹€νŒ¨ : 였λ₯˜ 1040 : 연결이 λ„ˆλ¬΄ 많음]

go 버전 1.1.1을 μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.
go 버전 go1.1.1 linux / 386

mysql λ“œλΌμ΄λ²„ 버전을 μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.
v1.0.1

MySql 버전 :
μ„œλ²„ 버전 : 5.5.22-0ubuntu1 (Ubuntu)

λ‹€μŒμ€ λ‚΄ 쿼리 쀑 ν•˜λ‚˜μ˜ μƒ˜ν”Œμž…λ‹ˆλ‹€.
ν–‰, 였λ₯˜ =
db.sqlDB.Query ( "XXXX (yyyy) κ°’ (?)에 μ‚½μž…",
connect.ZZZZ)
if err! = nil {
_ = rows.Close ();
λ°˜ν™˜ κ²°κ³Ό, 였λ₯˜
}
_ = rows.Close ();

λ¬Έμ œκ°€ ν•΄κ²°λ˜κΈ°λ₯Ό λ°”λΌλ©΄μ„œ "rows.Close ()"λ₯Ό μΆ”κ°€ν–ˆμ§€λ§Œ μ£Όμ‚¬μœ„λŠ” μ—†μŠ΅λ‹ˆλ‹€.

참고둜, λ‚΄ 쿼리 쀑 μΌλΆ€λŠ” "rows.Scan"을 μ‚¬μš©ν•˜κ³  μΌλΆ€λŠ” μ‚¬μš©ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

question working as intended

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

μ˜΅μ…˜ 1 : λ„ˆλ¬΄ 높은 λ™μ‹œμ„±

λ™μ‹œ λ°μ΄ν„°λ² μ΄μŠ€ μ•‘μ„ΈμŠ€κ°€ λ„ˆλ¬΄ λ§ŽμŠ΅λ‹ˆλ‹€. 이 경우 λ°μ΄ν„°λ² μ΄μŠ€ / SQL νŒ¨ν‚€μ§€κ°€ ν–₯ν›„ λ²„μ „μ—μ„œ 차단 λ©”μ»€λ‹ˆμ¦˜μ„ 제곡 ν•  λ•ŒκΉŒμ§€ λ™μ‹œ μ—°κ²° 수λ₯Ό μˆ˜λ™μœΌλ‘œ μ œν•œν•΄μ•Όν•©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ λ§Žμ€ 경우 캐싱 / 비동기 μ—…λ°μ΄νŠΈκ°€ 더 λ‚˜μ€ λŒ€μ•ˆμ΄ 될 κ²ƒμž…λ‹ˆλ‹€.

μ˜΅μ…˜ 2 : λˆ„μˆ˜ μ—°κ²°

μ•„λ§ˆλ„ ν”„λ‘œκ·Έλž¨μ΄ λ°μ΄ν„°λ² μ΄μŠ€ 연결을 λˆ„μΆœν•˜κ³ μžˆμ„ κ²ƒμž…λ‹ˆλ‹€. 당신은 κ°€κΉŒμ΄ν•˜μ§€ μ•ŠλŠ” κ²½μš°μ— λ°œμƒν•©λ‹ˆλ‹€ rows 에 μ˜ν•΄ λ°˜ν™˜ db.Query λ˜λŠ” (에 거래λ₯Ό μ’…λ£Œν•˜λŠ” 것을 μžŠμ—ˆλ‹€ λ°μ΄ν„°λ² μ΄μŠ€ / SQL의 TX APIλ₯Ό ).

λ‚˜μ˜ 일반적인 쑰언은

  • λ°˜ν™˜ 된 행을 κΈ°λŒ€ν•˜μ§€ μ•ŠλŠ” 경우 db.Exec (즉, Scan 아무것도 μ—†μŒ). 연결은 μ‹€ν–‰ ν›„ μ¦‰μ‹œ λ¬΄λ£Œμž…λ‹ˆλ‹€.
  • ν•œ 행을 μ˜ˆμƒν•˜λ©΄ db.QueryRow . μ—°κ²° ꡬ문 을 μ‚¬μš©ν•˜λ©΄
  • μ—¬λŸ¬ 행을 μ˜ˆμƒ db.Query . λ°˜ν™˜ 된 λͺ¨λ“  ν–‰ ( rows.Next 반볡)을 μ½κ±°λ‚˜ rows.Close ν˜ΈμΆœν•˜μ—¬ 연결을 "ν•΄μ œ"ν•˜λŠ” 것이 맀우 μ€‘μš”ν•©λ‹ˆλ‹€. ν™•μ‹€νžˆ rows.Close 톡화λ₯Ό μ—°κΈ°ν•˜λŠ” 것은 쒋은 μƒκ°μž…λ‹ˆλ‹€. 였λ₯˜ 사둀 등을 μžŠμ§€ λ§ˆμ‹­μ‹œμ˜€.

λͺ¨λ“  9 λŒ“κΈ€

https://github.com/VividCortex/go-database-sql-tutorial μ—μ„œ μ‚΄νŽ΄λ³΄μ‹­μ‹œμ˜€.

.Queryλ₯Ό μ‚¬μš©ν•˜μ§€ 말고 .Exec을 μ‚¬μš©ν•˜μ‹­μ‹œμ˜€.

μ˜΅μ…˜ 1 : λ„ˆλ¬΄ 높은 λ™μ‹œμ„±

λ™μ‹œ λ°μ΄ν„°λ² μ΄μŠ€ μ•‘μ„ΈμŠ€κ°€ λ„ˆλ¬΄ λ§ŽμŠ΅λ‹ˆλ‹€. 이 경우 λ°μ΄ν„°λ² μ΄μŠ€ / SQL νŒ¨ν‚€μ§€κ°€ ν–₯ν›„ λ²„μ „μ—μ„œ 차단 λ©”μ»€λ‹ˆμ¦˜μ„ 제곡 ν•  λ•ŒκΉŒμ§€ λ™μ‹œ μ—°κ²° 수λ₯Ό μˆ˜λ™μœΌλ‘œ μ œν•œν•΄μ•Όν•©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ λ§Žμ€ 경우 캐싱 / 비동기 μ—…λ°μ΄νŠΈκ°€ 더 λ‚˜μ€ λŒ€μ•ˆμ΄ 될 κ²ƒμž…λ‹ˆλ‹€.

μ˜΅μ…˜ 2 : λˆ„μˆ˜ μ—°κ²°

μ•„λ§ˆλ„ ν”„λ‘œκ·Έλž¨μ΄ λ°μ΄ν„°λ² μ΄μŠ€ 연결을 λˆ„μΆœν•˜κ³ μžˆμ„ κ²ƒμž…λ‹ˆλ‹€. 당신은 κ°€κΉŒμ΄ν•˜μ§€ μ•ŠλŠ” κ²½μš°μ— λ°œμƒν•©λ‹ˆλ‹€ 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, 였λ₯˜ = 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)
λ‚ μ§œ : 2014 λ…„ 7 μ›” 16 일 15:43

그리고 ... μ™œ λ©”μΈμ—μ„œ κ³  루틴을 μ‹œμž‘ν•©λ‹ˆκΉŒ?
μ½”λ“œκ°€ μ‹€μ œλ‘œ 이와 같이 보인닀면 κ³  루틴이 μ‹€ν–‰λ˜κΈ° 전에 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 ()
}

ν•˜μ§€λ§Œ μ§€κΈˆμ€ μœ λ‹‰μŠ€ 도메인 ν”„λ‘œν† μ½œ ( ' user : pwd @ unix (/tmp/mysql.sock)/')을 μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

κ³ λ§ˆμ›Œ λ‹΅μž₯

κ·Έλ ‡κ²Œν•΄μ„œλŠ” μ•ˆλ©λ‹ˆλ‹€. μž‘λ™ ν•  수 μžˆμ§€λ§Œ λŠλ¦½λ‹ˆλ‹€.

메인에 accept-loopλ₯Ό λ„£μœΌμ‹­μ‹œμ˜€.
κ³  루틴을 μ΅œμƒμœ„ ν•¨μˆ˜λ‘œ λ³€ν™˜ν•©λ‹ˆλ‹€.
get_db μ½”λ“œλ₯Ό 메인 상단에 λ„£κ³  db.λ₯Ό 더 κ°€κΉκ²Œ μ—°κΈ°ν•˜μ‹­μ‹œμ˜€ (그리고 κ±°κΈ°μ—λ§Œ).
μ΄λ ‡κ²Œ dbλ₯Ό μ—΄κ³  닫지 λ§ˆμ‹­μ‹œμ˜€.

λ‹€μŒ μ½”λ“œλ₯Ό μ‹œλ„ν•˜μ‹­μ‹œμ˜€.

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)
    }
}

κ³ λ§ˆμ›Œμš”.

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰

κ΄€λ ¨ 문제

xuewindy picture xuewindy  Β·  3μ½”λ©˜νŠΈ

pedromorgan picture pedromorgan  Β·  6μ½”λ©˜νŠΈ

lunemec picture lunemec  Β·  7μ½”λ©˜νŠΈ

Dieterbe picture Dieterbe  Β·  6μ½”λ©˜νŠΈ

zhaohui-kevin picture zhaohui-kevin  Β·  5μ½”λ©˜νŠΈ