summaryrefslogtreecommitdiffstats
path: root/store/sql_store.go
diff options
context:
space:
mode:
authorChristopher Speller <crspeller@gmail.com>2016-10-27 13:50:24 -0400
committerGitHub <noreply@github.com>2016-10-27 13:50:24 -0400
commit55803ebcc80848267894bb655b979e539c6f0507 (patch)
treead2e7a79d59b377b8d309697ff9c0bee5e1c75fb /store/sql_store.go
parentf82667f3b86202dafff3a2a4ea56aec74c80316d (diff)
downloadchat-55803ebcc80848267894bb655b979e539c6f0507.tar.gz
chat-55803ebcc80848267894bb655b979e539c6f0507.tar.bz2
chat-55803ebcc80848267894bb655b979e539c6f0507.zip
Changing read replica selection method to round-robin instead of random. (#4351)
Diffstat (limited to 'store/sql_store.go')
-rw-r--r--store/sql_store.go89
1 files changed, 47 insertions, 42 deletions
diff --git a/store/sql_store.go b/store/sql_store.go
index 532ba1fc6..215e0f894 100644
--- a/store/sql_store.go
+++ b/store/sql_store.go
@@ -15,14 +15,15 @@ import (
"encoding/json"
"errors"
"fmt"
- l4g "github.com/alecthomas/log4go"
"io"
sqltrace "log"
- "math/rand"
"os"
"strings"
+ "sync/atomic"
"time"
+ l4g "github.com/alecthomas/log4go"
+
"github.com/go-gorp/gorp"
_ "github.com/go-sql-driver/mysql"
_ "github.com/lib/pq"
@@ -84,10 +85,13 @@ type SqlStore struct {
status StatusStore
fileInfo FileInfoStore
SchemaVersion string
+ rrCounter int64
}
func initConnection() *SqlStore {
- sqlStore := &SqlStore{}
+ sqlStore := &SqlStore{
+ rrCounter: 0,
+ }
sqlStore.master = setupConnection("master", utils.Cfg.SqlSettings.DriverName,
utils.Cfg.SqlSettings.DataSource, utils.Cfg.SqlSettings.MaxIdleConns,
@@ -205,11 +209,11 @@ func setupConnection(con_type string, driver string, dataSource string, maxIdle
return dbmap
}
-func (ss SqlStore) TotalMasterDbConnections() int {
+func (ss *SqlStore) TotalMasterDbConnections() int {
return ss.GetMaster().Db.Stats().OpenConnections
}
-func (ss SqlStore) TotalReadDbConnections() int {
+func (ss *SqlStore) TotalReadDbConnections() int {
if len(utils.Cfg.SqlSettings.DataSourceReplicas) == 0 {
return 0
@@ -225,12 +229,12 @@ func (ss SqlStore) TotalReadDbConnections() int {
return 0
}
-func (ss SqlStore) GetCurrentSchemaVersion() string {
+func (ss *SqlStore) GetCurrentSchemaVersion() string {
version, _ := ss.GetMaster().SelectStr("SELECT Value FROM Systems WHERE Name='Version'")
return version
}
-func (ss SqlStore) MarkSystemRanUnitTests() {
+func (ss *SqlStore) MarkSystemRanUnitTests() {
if result := <-ss.System().Get(); result.Err == nil {
props := result.Data.(model.StringMap)
unitTests := props[model.SYSTEM_RAN_UNIT_TESTS]
@@ -241,7 +245,7 @@ func (ss SqlStore) MarkSystemRanUnitTests() {
}
}
-func (ss SqlStore) DoesTableExist(tableName string) bool {
+func (ss *SqlStore) DoesTableExist(tableName string) bool {
if utils.Cfg.SqlSettings.DriverName == model.DATABASE_DRIVER_POSTGRES {
count, err := ss.GetMaster().SelectInt(
`SELECT count(relname) FROM pg_class WHERE relname=$1`,
@@ -286,7 +290,7 @@ func (ss SqlStore) DoesTableExist(tableName string) bool {
}
}
-func (ss SqlStore) DoesColumnExist(tableName string, columnName string) bool {
+func (ss *SqlStore) DoesColumnExist(tableName string, columnName string) bool {
if utils.Cfg.SqlSettings.DriverName == model.DATABASE_DRIVER_POSTGRES {
count, err := ss.GetMaster().SelectInt(
`SELECT COUNT(0)
@@ -341,7 +345,7 @@ func (ss SqlStore) DoesColumnExist(tableName string, columnName string) bool {
}
}
-func (ss SqlStore) CreateColumnIfNotExists(tableName string, columnName string, mySqlColType string, postgresColType string, defaultValue string) bool {
+func (ss *SqlStore) CreateColumnIfNotExists(tableName string, columnName string, mySqlColType string, postgresColType string, defaultValue string) bool {
if ss.DoesColumnExist(tableName, columnName) {
return false
@@ -375,7 +379,7 @@ func (ss SqlStore) CreateColumnIfNotExists(tableName string, columnName string,
}
}
-func (ss SqlStore) RemoveColumnIfExists(tableName string, columnName string) bool {
+func (ss *SqlStore) RemoveColumnIfExists(tableName string, columnName string) bool {
if !ss.DoesColumnExist(tableName, columnName) {
return false
@@ -391,7 +395,7 @@ func (ss SqlStore) RemoveColumnIfExists(tableName string, columnName string) boo
return true
}
-func (ss SqlStore) RenameColumnIfExists(tableName string, oldColumnName string, newColumnName string, colType string) bool {
+func (ss *SqlStore) RenameColumnIfExists(tableName string, oldColumnName string, newColumnName string, colType string) bool {
if !ss.DoesColumnExist(tableName, oldColumnName) {
return false
}
@@ -412,7 +416,7 @@ func (ss SqlStore) RenameColumnIfExists(tableName string, oldColumnName string,
return true
}
-func (ss SqlStore) GetMaxLengthOfColumnIfExists(tableName string, columnName string) string {
+func (ss *SqlStore) GetMaxLengthOfColumnIfExists(tableName string, columnName string) string {
if !ss.DoesColumnExist(tableName, columnName) {
return ""
}
@@ -434,7 +438,7 @@ func (ss SqlStore) GetMaxLengthOfColumnIfExists(tableName string, columnName str
return result
}
-func (ss SqlStore) AlterColumnTypeIfExists(tableName string, columnName string, mySqlColType string, postgresColType string) bool {
+func (ss *SqlStore) AlterColumnTypeIfExists(tableName string, columnName string, mySqlColType string, postgresColType string) bool {
if !ss.DoesColumnExist(tableName, columnName) {
return false
}
@@ -455,19 +459,19 @@ func (ss SqlStore) AlterColumnTypeIfExists(tableName string, columnName string,
return true
}
-func (ss SqlStore) CreateUniqueIndexIfNotExists(indexName string, tableName string, columnName string) {
+func (ss *SqlStore) CreateUniqueIndexIfNotExists(indexName string, tableName string, columnName string) {
ss.createIndexIfNotExists(indexName, tableName, columnName, INDEX_TYPE_DEFAULT, true)
}
-func (ss SqlStore) CreateIndexIfNotExists(indexName string, tableName string, columnName string) {
+func (ss *SqlStore) CreateIndexIfNotExists(indexName string, tableName string, columnName string) {
ss.createIndexIfNotExists(indexName, tableName, columnName, INDEX_TYPE_DEFAULT, false)
}
-func (ss SqlStore) CreateFullTextIndexIfNotExists(indexName string, tableName string, columnName string) {
+func (ss *SqlStore) CreateFullTextIndexIfNotExists(indexName string, tableName string, columnName string) {
ss.createIndexIfNotExists(indexName, tableName, columnName, INDEX_TYPE_FULL_TEXT, false)
}
-func (ss SqlStore) createIndexIfNotExists(indexName string, tableName string, columnName string, indexType string, unique bool) {
+func (ss *SqlStore) createIndexIfNotExists(indexName string, tableName string, columnName string, indexType string, unique bool) {
uniqueStr := ""
if unique {
@@ -526,7 +530,7 @@ func (ss SqlStore) createIndexIfNotExists(indexName string, tableName string, co
}
}
-func (ss SqlStore) RemoveIndexIfExists(indexName string, tableName string) {
+func (ss *SqlStore) RemoveIndexIfExists(indexName string, tableName string) {
if utils.Cfg.SqlSettings.DriverName == model.DATABASE_DRIVER_POSTGRES {
_, err := ss.GetMaster().SelectStr("SELECT $1::regclass", indexName)
@@ -580,22 +584,23 @@ func IsUniqueConstraintError(err string, indexName []string) bool {
return unique && field
}
-func (ss SqlStore) GetMaster() *gorp.DbMap {
+func (ss *SqlStore) GetMaster() *gorp.DbMap {
return ss.master
}
-func (ss SqlStore) GetReplica() *gorp.DbMap {
- return ss.replicas[rand.Intn(len(ss.replicas))]
+func (ss *SqlStore) GetReplica() *gorp.DbMap {
+ rrNum := atomic.AddInt64(&ss.rrCounter, 1) % int64(len(ss.replicas))
+ return ss.replicas[rrNum]
}
-func (ss SqlStore) GetAllConns() []*gorp.DbMap {
+func (ss *SqlStore) GetAllConns() []*gorp.DbMap {
all := make([]*gorp.DbMap, len(ss.replicas)+1)
copy(all, ss.replicas)
all[len(ss.replicas)] = ss.master
return all
}
-func (ss SqlStore) Close() {
+func (ss *SqlStore) Close() {
l4g.Info(utils.T("store.sql.closing.info"))
ss.master.Db.Close()
for _, replica := range ss.replicas {
@@ -603,75 +608,75 @@ func (ss SqlStore) Close() {
}
}
-func (ss SqlStore) Team() TeamStore {
+func (ss *SqlStore) Team() TeamStore {
return ss.team
}
-func (ss SqlStore) Channel() ChannelStore {
+func (ss *SqlStore) Channel() ChannelStore {
return ss.channel
}
-func (ss SqlStore) Post() PostStore {
+func (ss *SqlStore) Post() PostStore {
return ss.post
}
-func (ss SqlStore) User() UserStore {
+func (ss *SqlStore) User() UserStore {
return ss.user
}
-func (ss SqlStore) Session() SessionStore {
+func (ss *SqlStore) Session() SessionStore {
return ss.session
}
-func (ss SqlStore) Audit() AuditStore {
+func (ss *SqlStore) Audit() AuditStore {
return ss.audit
}
-func (ss SqlStore) Compliance() ComplianceStore {
+func (ss *SqlStore) Compliance() ComplianceStore {
return ss.compliance
}
-func (ss SqlStore) OAuth() OAuthStore {
+func (ss *SqlStore) OAuth() OAuthStore {
return ss.oauth
}
-func (ss SqlStore) System() SystemStore {
+func (ss *SqlStore) System() SystemStore {
return ss.system
}
-func (ss SqlStore) Webhook() WebhookStore {
+func (ss *SqlStore) Webhook() WebhookStore {
return ss.webhook
}
-func (ss SqlStore) Command() CommandStore {
+func (ss *SqlStore) Command() CommandStore {
return ss.command
}
-func (ss SqlStore) Preference() PreferenceStore {
+func (ss *SqlStore) Preference() PreferenceStore {
return ss.preference
}
-func (ss SqlStore) License() LicenseStore {
+func (ss *SqlStore) License() LicenseStore {
return ss.license
}
-func (ss SqlStore) PasswordRecovery() PasswordRecoveryStore {
+func (ss *SqlStore) PasswordRecovery() PasswordRecoveryStore {
return ss.recovery
}
-func (ss SqlStore) Emoji() EmojiStore {
+func (ss *SqlStore) Emoji() EmojiStore {
return ss.emoji
}
-func (ss SqlStore) Status() StatusStore {
+func (ss *SqlStore) Status() StatusStore {
return ss.status
}
-func (ss SqlStore) FileInfo() FileInfoStore {
+func (ss *SqlStore) FileInfo() FileInfoStore {
return ss.fileInfo
}
-func (ss SqlStore) DropAllTables() {
+func (ss *SqlStore) DropAllTables() {
ss.master.TruncateTables()
}