MySQL: Use transaction_isolation instead of tx_isolation (#68575)

will use the correct system var name for transaction isolation
This commit is contained in:
owensmallwood 2023-05-23 09:22:05 -06:00 committed by GitHub
parent e3e8a7965a
commit b43206e26b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 1 deletions

1
.github/CODEOWNERS vendored
View File

@ -178,6 +178,7 @@
/devenv/docker/blocks/influxdb1/ @grafana/observability-metrics
/devenv/docker/blocks/jaeger/ @grafana/observability-traces-and-profiling
/devenv/docker/blocks/maildev/ @grafana/alerting-squad-frontend
/devenv/docker/blocks/mariadb/ @grafana/grafana-bi-squad
/devenv/docker/blocks/memcached/ @grafana/backend-platform
/devenv/docker/blocks/mssql/ @grafana/grafana-bi-squad
/devenv/docker/blocks/mssql_arm64/ @grafana/grafana-bi-squad

View File

@ -0,0 +1,10 @@
mariadb:
image: mariadb:latest
restart: always
environment:
MARIADB_ROOT_PASSWORD: rootpass
MARIADB_DATABASE: grafana
MARIADB_USER: grafana
MARIADB_PASSWORD: password
ports:
- "3306:3306"

View File

@ -298,7 +298,7 @@ func (ss *SQLStore) buildConnectionString() (string, error) {
if isolation := ss.dbCfg.IsolationLevel; isolation != "" {
val := url.QueryEscape(fmt.Sprintf("'%s'", isolation))
cnnstr += fmt.Sprintf("&tx_isolation=%s", val)
cnnstr += fmt.Sprintf("&transaction_isolation=%s", val)
}
if ss.Cfg.IsFeatureToggleEnabled(featuremgmt.FlagMysqlAnsiQuotes) || ss.Cfg.IsFeatureToggleEnabled(featuremgmt.FlagNewDBLibrary) {
@ -402,6 +402,14 @@ func (ss *SQLStore) initEngine(engine *xorm.Engine) error {
if err != nil {
return err
}
// Only for MySQL or MariaDB, verify we can connect with the current connection string's system var for transaction isolation.
// If not, create a new engine with a compatible connection string.
if ss.dbCfg.Type == migrator.MySQL {
engine, err = ss.ensureTransactionIsolationCompatibility(engine, connectionString)
if err != nil {
return err
}
}
}
engine.SetMaxOpenConns(ss.dbCfg.MaxOpenConn)
@ -423,6 +431,32 @@ func (ss *SQLStore) initEngine(engine *xorm.Engine) error {
return nil
}
// The transaction_isolation system variable isn't compatible with MySQL < 5.7.20 or MariaDB. If we get an error saying this
// system variable is unknown, then replace it with it's older version tx_isolation which is compatible with MySQL < 5.7.20 and MariaDB.
func (ss *SQLStore) ensureTransactionIsolationCompatibility(engine *xorm.Engine, connectionString string) (*xorm.Engine, error) {
var result string
_, err := engine.SQL("SELECT 1").Get(&result)
var mysqlError *mysql.MySQLError
if errors.As(err, &mysqlError) {
// if there was an error due to transaction isolation
if strings.Contains(mysqlError.Message, "Unknown system variable 'transaction_isolation'") {
ss.log.Debug("transaction_isolation system var is unknown, overriding in connection string with tx_isolation instead")
// replace with compatible system var for transaction isolation
connectionString = strings.Replace(connectionString, "&transaction_isolation", "&tx_isolation", -1)
// recreate the xorm engine with new connection string that is compatible
engine, err = xorm.NewEngine(ss.dbCfg.Type, connectionString)
if err != nil {
return nil, err
}
}
} else if err != nil {
return nil, err
}
return engine, nil
}
// readConfig initializes the SQLStore from its configuration.
func (ss *SQLStore) readConfig() error {
sec := ss.Cfg.Raw.Section("database")