title: golang MySQL "connection refused"
body: <p>I'm new in Go (Golang). I wrote a simple benchmark program to test the concurrent processing with MySQL. Keep getting "dial tcp 52.55.254.165:3306: getsockopt: connection refused", "unexpected EOF" errors when I increase the number of concurrent channels. </p>
  
  <p>Each go routine is doing a batch insert of 1 to n number of row to a simple customer table. The program allows to set variable insert size (number of rows in a single statement) and number of parallel go routine (each go routine performs one insert above).  Program works fine with small numbers row&lt;100 and number go routines&lt;100. But start getting Unexpected EOF errors when the numbers increase, especially the number of parallel go routines.</p>
  
  <p>Did search for clues. Based on them, I've set the database max connection and 'max_allowed_packet' and 'max_connections'. I've also set the go program <code>db.db.SetMaxOpenConns(200)</code>, <code>db.SetConnMaxLifetime(200)</code>, <code>db.SetMaxIdleConns(10)</code>. I've experimented with big numbers and small (from 10 to 2000). Nothing seems to solve the program.</p>
  
  <p>I have one global db connection open. Code snippet below:</p>
  
  <pre><code>// main package
  
  func main() {
  
      var err error
      db, err = sql.Open("mysql","usr:pwd@tcp(ip:3306)/gopoc")
      if err != nil {
          log.Panic(err)
      }
      db.SetMaxOpenConns(1000)
      db.SetConnMaxLifetime(1000)
      db.SetMaxIdleConns(10)
  
      // sql.DB should be long lived "defer" closes it once this function ends
      defer db.Close()
  
      if err = db.Ping(); err != nil {
          log.Panic(err)
      }
  
      http.HandleFunc("/addCust/", HFHandleFunc(addCustHandler))
  
      http.ListenAndServe(":8080", nil)
  }
  
  // add customer handler
  func addCustHandler(w http.ResponseWriter, r *http.Request) {
  
      // experected url: /addCust/?num=3$pcnt=1
      num, _ := strconv.Atoi(r.URL.Query().Get("num"))
      pcnt, _ := strconv.Atoi(r.URL.Query().Get("pcnt"))
  
      ch := make([]chan string, pcnt) // initialize channel slice
      for i := range ch {
          ch[i] = make(chan string, 1)
      }
  
      var wg sync.WaitGroup
  
      for i, chans := range ch {
          wg.Add(1)
          go func(cha chan string, ii int) {
              defer wg.Done()
              addCust(num)
              cha &lt;- "Channel[" + strconv.Itoa(ii) + "]\n"
          }(chans, i)
      }
  
      wg.Wait()
  
      var outputstring string
  
      for i := 0; i &lt; pcnt; i++ {
          outputstring = outputstring + &lt;-ch[i]
      }
  
      fmt.Fprintf(w, "Output:\n%s", outputstring)
  }
  
  func addCust(cnt int) sql.Result {
  ...
      sqlStr := "INSERT INTO CUST (idCUST, idFI, fName, state, country) VALUES "
  
      for i := 0; i &lt; cnt; i++ {
  
          sqlStr += "(" + strconv.Itoa(FiIDpadding+r.Intn(CidMax)+1) + ", " + strconv.Itoa(FiID) +", 'fname', 'PA', 'USA), " 
  
      }
  
      //trim the last ,
      sqlStr = sqlStr[0:len(sqlStr)-2] + " on duplicate key update lname='dup';"
  
      res, err := db.Exec(sqlStr)
      if err != nil {
          panic("\nInsert Statement error\n" + err.Error()) 
      }
  
      return res
  }
  </code></pre>