max_idle_conns = 5
max_open_conns = 30
max_life_time=600
timeout=600
+-----------------------------+----------+
| Variable_name | Value |
+-----------------------------+----------+
| connect_timeout | 60 |
| delayed_insert_timeout | 300 |
| interactive_timeout | 600 |
| lock_wait_timeout | 31536000 |
| log_output | FILE |
| net_read_timeout | 30 |
| net_write_timeout | 60 |
| wait_timeout | 600 |
+-----------------------------+----------+
srv_promo 12672 root 10u sock 0,6 0t0 63382668 can't identify protocol
srv_promo 12672 root 11u sock 0,6 0t0 63366850 can't identify protocol
srv_promo 12672 root 12u sock 0,6 0t0 63366688 can't identify protocol
srv_promo 12672 root 13u sock 0,6 0t0 63366690 can't identify protocol
package dbtest
import (
"database/sql"
"fmt"
"github.com/golang/glog"
"gopkg.in/gorp.v2"
"log"
"os"
"sync"
"time"
)
type DatabaseConfig struct {
DBName string `toml:"dbname"`
Host string `toml:"host"`
Port int `toml:"port"`
User string `toml:"user"`
Password string `toml:"password"`
Sslmode string `toml:"sslmode"`
ShowLog bool
DataSaveDir string
DataFileSaveLoopSize int
MaxIdleConns int `toml:"max_idle_conns"`
MaxOpenConns int `toml:"max_open_conns"`
MaxLifeTime int `toml:"max_life_time"`
Timeout int `toml:"timeout"`
RTimeout int `toml:"rtimeout"`
WTimeout int `toml:"wtimeout"`
}
func (c DatabaseConfig) MySQLSource() string {
params := make(map[string]string, 0)
params["charset"] = "utf8mb4"
cfg := mysql.Config{}
cfg.User = c.User
cfg.Passwd = c.Password
cfg.DBName = c.DBName
cfg.ParseTime = true
cfg.Collation = "utf8mb4_unicode_ci"
cfg.Params = params
cfg.Loc, _ = time.LoadLocation("Asia/Chongqing")
cfg.Timeout = time.Duration(c.Timeout) * time.Second
cfg.MultiStatements = true
cfg.ReadTimeout = time.Duration(c.RTimeout) * time.Second
cfg.WriteTimeout = time.Duration(c.WTimeout) * time.Second
return cfg.FormatDSN()
}
var (
dbmap *gorp.DbMap
Dbm *gorp.DbMap
config DatabaseConfig
opened bool
openMutex sync.RWMutex
DB *sql.DB
)
//Open open the database for passport with config
func Open(cfg DatabaseConfig) {
if !opened {
config = cfg
db, err := sql.Open("mysql", config.MySQLSource())
glog.Infof("open err %v ", err)
if err != nil {
panic(fmt.Errorf("sql.Open failed: %v", err))
}
if config.MaxLifeTime > 0 {
db.SetConnMaxLifetime(time.Duration(config.MaxLifeTime) * time.Second)
}
db.SetMaxIdleConns(config.MaxIdleConns)
db.SetMaxOpenConns(config.MaxOpenConns)
db.Ping()
DB = db
// construct a gorp DbMap
dbmap = &gorp.DbMap{Db: db, Dialect: gorp.MySQLDialect{"InnoDB", "utf8mb4"}}
Dbm = dbmap
err = dbmap.CreateTablesIfNotExists()
if err != nil {
panic("create table failed " + err.Error())
}
openMutex.Lock()
opened = true
openMutex.Unlock()
if config.ShowLog {
dbmap.TraceOn("[gorp]", log.New(os.Stdout, schemaName+" ", log.Lmicroseconds))
}
}
}
//Close close the database for passport
func Close() {
if dbmap != nil && opened {
glog.Infof("close database %s for %s", config.DBName, schemaName)
dbmap.Db.Close()
openMutex.Lock()
opened = false
openMutex.Unlock()
}
}
(Not an answer, but too much for a comment.)
Two things:
Please try to come up with an MCVE—first for yourself and second (if that alone won't help you solve your problem)—for us.
What I mean, is that there's too much going on in your example: you're using gorp
which is not a part of the Go standard library, and this package—which supposedly wraps database/sql
machinery—can do absolutely anything when working with the database.
That's not how such problems are approached. Instead, you should start from the ground up and first use plain database/sql
layer and see whether it works. If it does, the problem is with that gorp
thing.
Another, however minor, detail is that you should not use 3rd-party packages to do trivial stuff in your MCVEs; here, I'm talking about logging: in a stripped down example, the standard fmt.Print*
functions would be just OK, or, if you feel like it's impossible to go full-on-Enterprise-y, the standard log
package would fill the bill.
The SQL database layer in Go is explicitly designed to have the semantics which are quite unlike the SQL database layers implemented by other popular languages / frameworks.
The Go's is different in that it was designed to handle massive workloads typically generated on the server software. Among other things, it means that
Ping()
method is called).