Пример #1
0
// NewQueryEngine creates a new QueryEngine.
// This is a singleton class.
// You must call this only once.
func NewQueryEngine(config Config) *QueryEngine {
	qe := &QueryEngine{}
	qe.schemaInfo = NewSchemaInfo(config.QueryCacheSize, time.Duration(config.SchemaReloadTime*1e9), time.Duration(config.IdleTimeout*1e9))

	mysqlStats = stats.NewTimings("Mysql")

	// Pools
	qe.cachePool = NewCachePool("Rowcache", config.RowCache, time.Duration(config.QueryTimeout*1e9), time.Duration(config.IdleTimeout*1e9))
	qe.connPool = dbconnpool.NewConnectionPool("ConnPool", config.PoolSize, time.Duration(config.IdleTimeout*1e9))
	qe.streamConnPool = dbconnpool.NewConnectionPool("StreamConnPool", config.StreamPoolSize, time.Duration(config.IdleTimeout*1e9))
	qe.txPool = dbconnpool.NewConnectionPool("TransactionPool", config.TransactionCap, time.Duration(config.IdleTimeout*1e9)) // connections in pool has to be > transactionCap

	// Services
	qe.activeTxPool = NewActiveTxPool("ActiveTransactionPool", time.Duration(config.TransactionTimeout*1e9))
	qe.connKiller = NewConnectionKiller(1, time.Duration(config.IdleTimeout*1e9))
	qe.activePool = NewActivePool("ActivePool", time.Duration(config.QueryTimeout*1e9), qe.connKiller)
	qe.consolidator = NewConsolidator()
	qe.invalidator = NewRowcacheInvalidator(qe)
	qe.streamQList = NewQueryList(qe.connKiller)

	// Vars
	qe.spotCheckFreq = sync2.AtomicInt64(config.SpotCheckRatio * SPOT_CHECK_MULTIPLIER)
	if config.StrictMode {
		qe.strictMode.Set(1)
	}
	qe.strictTableAcl = config.StrictTableAcl
	qe.maxResultSize = sync2.AtomicInt64(config.MaxResultSize)
	qe.streamBufferSize = sync2.AtomicInt64(config.StreamBufferSize)

	// loggers
	qe.accessCheckerLogger = logutil.NewThrottledLogger("accessChecker", 1*time.Second)

	// Stats
	stats.Publish("MaxResultSize", stats.IntFunc(qe.maxResultSize.Get))
	stats.Publish("StreamBufferSize", stats.IntFunc(qe.streamBufferSize.Get))
	queryStats = stats.NewTimings("Queries")
	QPSRates = stats.NewRates("QPS", queryStats, 15, 60*time.Second)
	waitStats = stats.NewTimings("Waits")
	killStats = stats.NewCounters("Kills")
	infoErrors = stats.NewCounters("InfoErrors")
	errorStats = stats.NewCounters("Errors")
	internalErrors = stats.NewCounters("InternalErrors")
	resultStats = stats.NewHistogram("Results", resultBuckets)
	stats.Publish("RowcacheSpotCheckRatio", stats.FloatFunc(func() float64 {
		return float64(qe.spotCheckFreq.Get()) / SPOT_CHECK_MULTIPLIER
	}))
	spotCheckCount = stats.NewInt("RowcacheSpotCheckCount")

	return qe
}
Пример #2
0
// NewMysqld creates a Mysqld object based on the provided configuration
// and connection parameters.
func NewMysqld(config *Mycnf, dba, allprivs, app, repl *sqldb.ConnParams, enablePublishStats bool) *Mysqld {
	noParams := sqldb.ConnParams{}
	if *dba == noParams {
		dba.UnixSocket = config.SocketFile
	}

	// create and open the connection pool for dba access
	dbaMysqlStatsName := ""
	dbaPoolName := ""
	if enablePublishStats {
		dbaMysqlStatsName = "MysqlDba"
		dbaPoolName = "DbaConnPool"
	}
	dbaMysqlStats := stats.NewTimings(dbaMysqlStatsName)
	dbaPool := dbconnpool.NewConnectionPool(dbaPoolName, *dbaPoolSize, *dbaIdleTimeout)
	dbaPool.Open(dbconnpool.DBConnectionCreator(dba, dbaMysqlStats))

	// create and open the connection pool for allprivs access
	allprivsMysqlStatsName := ""
	if enablePublishStats {
		allprivsMysqlStatsName = "MysqlAllPrivs"
	}
	allprivsMysqlStats := stats.NewTimings(allprivsMysqlStatsName)

	// create and open the connection pool for app access
	appMysqlStatsName := ""
	appPoolName := ""
	if enablePublishStats {
		appMysqlStatsName = "MysqlApp"
		appPoolName = "AppConnPool"
	}
	appMysqlStats := stats.NewTimings(appMysqlStatsName)
	appPool := dbconnpool.NewConnectionPool(appPoolName, *appPoolSize, *appIdleTimeout)
	appPool.Open(dbconnpool.DBConnectionCreator(app, appMysqlStats))

	return &Mysqld{
		config:             config,
		dba:                dba,
		allprivs:           allprivs,
		dbApp:              app,
		dbaPool:            dbaPool,
		appPool:            appPool,
		replParams:         repl,
		dbaMysqlStats:      dbaMysqlStats,
		allprivsMysqlStats: allprivsMysqlStats,
		tabletDir:          path.Dir(config.DataDir),
	}
}
Пример #3
0
func NewSchemaInfo(queryCacheSize int, reloadTime time.Duration, idleTimeout time.Duration) *SchemaInfo {
	si := &SchemaInfo{
		queries:  cache.NewLRUCache(int64(queryCacheSize)),
		rules:    NewQueryRules(),
		connPool: dbconnpool.NewConnectionPool("", 2, idleTimeout),
		ticks:    timer.NewTimer(reloadTime),
	}
	stats.Publish("QueryCacheLength", stats.IntFunc(si.queries.Length))
	stats.Publish("QueryCacheSize", stats.IntFunc(si.queries.Size))
	stats.Publish("QueryCacheCapacity", stats.IntFunc(si.queries.Capacity))
	stats.Publish("QueryCacheOldest", stats.StringFunc(func() string {
		return fmt.Sprintf("%v", si.queries.Oldest())
	}))
	stats.Publish("SchemaReloadTime", stats.DurationFunc(si.ticks.Interval))
	_ = stats.NewMultiCountersFunc("TableStats", []string{"Table", "Stats"}, si.getTableStats)
	_ = stats.NewMultiCountersFunc("TableInvalidations", []string{"Table"}, si.getTableInvalidations)
	_ = stats.NewMultiCountersFunc("QueryCounts", []string{"Table", "Plan"}, si.getQueryCount)
	_ = stats.NewMultiCountersFunc("QueryTimesNs", []string{"Table", "Plan"}, si.getQueryTime)
	_ = stats.NewMultiCountersFunc("QueryRowCounts", []string{"Table", "Plan"}, si.getQueryRowCount)
	_ = stats.NewMultiCountersFunc("QueryErrorCounts", []string{"Table", "Plan"}, si.getQueryErrorCount)
	http.Handle("/debug/query_plans", si)
	http.Handle("/debug/query_stats", si)
	http.Handle("/debug/table_stats", si)
	http.Handle("/debug/schema", si)
	return si
}
Пример #4
0
// NewConnPool creates a new ConnPool. The name is used
// to publish stats only.
func NewConnPool(
	name string,
	capacity int,
	idleTimeout time.Duration,
	enablePublishStats bool,
	queryServiceStats *QueryServiceStats,
	checker MySQLChecker) *ConnPool {
	cp := &ConnPool{
		capacity:          capacity,
		idleTimeout:       idleTimeout,
		dbaPool:           dbconnpool.NewConnectionPool("", 1, idleTimeout),
		queryServiceStats: queryServiceStats,
		checker:           checker,
	}
	if name == "" {
		return cp
	}
	if enablePublishStats {
		stats.Publish(name+"Capacity", stats.IntFunc(cp.Capacity))
		stats.Publish(name+"Available", stats.IntFunc(cp.Available))
		stats.Publish(name+"MaxCap", stats.IntFunc(cp.MaxCap))
		stats.Publish(name+"WaitCount", stats.IntFunc(cp.WaitCount))
		stats.Publish(name+"WaitTime", stats.DurationFunc(cp.WaitTime))
		stats.Publish(name+"IdleTimeout", stats.DurationFunc(cp.IdleTimeout))
	}
	return cp
}
Пример #5
0
// NewMysqld creates a Mysqld object based on the provided configuration
// and connection parameters.
// dbaName and appName are the base for stats exports, use 'Dba' and 'App', except in tests
func NewMysqld(dbaName, appName string, config *Mycnf, dba, app, repl *sqldb.ConnParams) *Mysqld {
	if *dba == dbconfigs.DefaultDBConfigs.Dba {
		dba.UnixSocket = config.SocketFile
	}

	// create and open the connection pool for dba access
	dbaMysqlStatsName := ""
	dbaPoolName := ""
	if dbaName != "" {
		dbaMysqlStatsName = "Mysql" + dbaName
		dbaPoolName = dbaName + "ConnPool"
	}
	dbaMysqlStats := stats.NewTimings(dbaMysqlStatsName)
	dbaPool := dbconnpool.NewConnectionPool(dbaPoolName, *dbaPoolSize, *dbaIdleTimeout)
	dbaPool.Open(dbconnpool.DBConnectionCreator(dba, dbaMysqlStats))

	// create and open the connection pool for app access
	appMysqlStatsName := ""
	appPoolName := ""
	if appName != "" {
		appMysqlStatsName = "Mysql" + appName
		appPoolName = appName + "ConnPool"
	}
	appMysqlStats := stats.NewTimings(appMysqlStatsName)
	appPool := dbconnpool.NewConnectionPool(appPoolName, *appPoolSize, *appIdleTimeout)
	appPool.Open(dbconnpool.DBConnectionCreator(app, appMysqlStats))

	return &Mysqld{
		config:        config,
		dba:           dba,
		dbApp:         app,
		dbaPool:       dbaPool,
		appPool:       appPool,
		replParams:    repl,
		dbaMysqlStats: dbaMysqlStats,
		TabletDir:     TabletDir(config.ServerID),
		SnapshotDir:   SnapshotDir(config.ServerID),
	}
}
Пример #6
0
func NewTxPool(name string, capacity int, timeout, poolTimeout, idleTimeout time.Duration) *TxPool {
	axp := &TxPool{
		pool:        dbconnpool.NewConnectionPool(name, capacity, idleTimeout),
		activePool:  pools.NewNumbered(),
		lastId:      sync2.AtomicInt64(time.Now().UnixNano()),
		timeout:     sync2.AtomicDuration(timeout),
		poolTimeout: sync2.AtomicDuration(poolTimeout),
		ticks:       timer.NewTimer(timeout / 10),
		txStats:     stats.NewTimings("Transactions"),
	}
	// Careful: pool also exports name+"xxx" vars,
	// but we know it doesn't export Timeout.
	stats.Publish(name+"Timeout", stats.DurationFunc(axp.timeout.Get))
	stats.Publish(name+"PoolTimeout", stats.DurationFunc(axp.poolTimeout.Get))
	return axp
}
Пример #7
0
// NewMysqld creates a Mysqld object based on the provided configuration
// and connection parameters.
// name is the base for stats exports, use 'Dba', except in tests
func NewMysqld(name string, config *Mycnf, dba, repl *mysql.ConnectionParams) *Mysqld {
	if *dba == dbconfigs.DefaultDBConfigs.Dba {
		dba.UnixSocket = config.SocketFile
	}

	// create and open the connection pool for dba access
	mysqlStats := stats.NewTimings("Mysql" + name)
	dbaPool := dbconnpool.NewConnectionPool(name+"ConnPool", *dbaPoolSize, *dbaIdleTimeout)
	dbaPool.Open(dbconnpool.DBConnectionCreator(dba, mysqlStats))

	return &Mysqld{
		config:      config,
		dba:         dba,
		dbaPool:     dbaPool,
		replParams:  repl,
		TabletDir:   TabletDir(config.ServerId),
		SnapshotDir: SnapshotDir(config.ServerId),
	}
}
Пример #8
0
// NewConnectionKiller creates a new ConnectionKiller
func NewConnectionKiller(poolSize int, idleTimeout time.Duration) *ConnectionKiller {
	return &ConnectionKiller{
		connPool: dbconnpool.NewConnectionPool("ConnKiller", poolSize, idleTimeout),
	}
}