MySQL: Add parseTime=true to SQL connections (#92469)

pull/92475/head
Ryan McKinley 9 months ago committed by GitHub
parent c98e3e0483
commit c59dddf7af
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md
  2. 1
      packages/grafana-data/src/types/featureToggles.gen.ts
  3. 6
      pkg/services/featuremgmt/registry.go
  4. 1
      pkg/services/featuremgmt/toggles_gen.csv
  5. 4
      pkg/services/featuremgmt/toggles_gen.go
  6. 12
      pkg/services/featuremgmt/toggles_gen.json
  7. 6
      pkg/services/searchV2/index_test.go
  8. 4
      pkg/services/sqlstore/database_config.go
  9. 14
      pkg/services/sqlstore/sqlstore.go
  10. 1
      pkg/storage/unified/sql/db/dbimpl/dbEngine.go

@ -122,6 +122,7 @@ Experimental features might be changed or removed without prior notice.
| `logRequestsInstrumentedAsUnknown` | Logs the path for requests that are instrumented as unknown |
| `showDashboardValidationWarnings` | Show warnings when dashboards do not validate against the schema |
| `mysqlAnsiQuotes` | Use double quotes to escape keyword in a MySQL query |
| `mysqlParseTime` | Ensure the parseTime flag is set for MySQL driver |
| `alertingBacktesting` | Rule backtesting API for alerting |
| `editPanelCSVDragAndDrop` | Enables drag and drop for CSV and Excel files |
| `lokiQuerySplittingConfig` | Give users the option to configure split durations for Loki queries |

@ -45,6 +45,7 @@ export interface FeatureToggles {
cloudWatchCrossAccountQuerying?: boolean;
showDashboardValidationWarnings?: boolean;
mysqlAnsiQuotes?: boolean;
mysqlParseTime?: boolean;
accessControlOnCall?: boolean;
nestedFolders?: boolean;
alertingBacktesting?: boolean;

@ -214,6 +214,12 @@ var (
Stage: FeatureStageExperimental,
Owner: grafanaSearchAndStorageSquad,
},
{
Name: "mysqlParseTime",
Description: "Ensure the parseTime flag is set for MySQL driver",
Stage: FeatureStageExperimental,
Owner: grafanaSearchAndStorageSquad,
},
{
Name: "accessControlOnCall",
Description: "Access control primitives for OnCall",

@ -26,6 +26,7 @@ grpcServer,preview,@grafana/search-and-storage,false,false,false
cloudWatchCrossAccountQuerying,GA,@grafana/aws-datasources,false,false,false
showDashboardValidationWarnings,experimental,@grafana/dashboards-squad,false,false,false
mysqlAnsiQuotes,experimental,@grafana/search-and-storage,false,false,false
mysqlParseTime,experimental,@grafana/search-and-storage,false,false,false
accessControlOnCall,preview,@grafana/identity-access-team,false,false,false
nestedFolders,GA,@grafana/search-and-storage,false,false,false
alertingBacktesting,experimental,@grafana/alerting-squad,false,false,false

1 Name Stage Owner requiresDevMode RequiresRestart FrontendOnly
26 cloudWatchCrossAccountQuerying GA @grafana/aws-datasources false false false
27 showDashboardValidationWarnings experimental @grafana/dashboards-squad false false false
28 mysqlAnsiQuotes experimental @grafana/search-and-storage false false false
29 mysqlParseTime experimental @grafana/search-and-storage false false false
30 accessControlOnCall preview @grafana/identity-access-team false false false
31 nestedFolders GA @grafana/search-and-storage false false false
32 alertingBacktesting experimental @grafana/alerting-squad false false false

@ -115,6 +115,10 @@ const (
// Use double quotes to escape keyword in a MySQL query
FlagMysqlAnsiQuotes = "mysqlAnsiQuotes"
// FlagMysqlParseTime
// Ensure the parseTime flag is set for MySQL driver
FlagMysqlParseTime = "mysqlParseTime"
// FlagAccessControlOnCall
// Access control primitives for OnCall
FlagAccessControlOnCall = "accessControlOnCall"

@ -1789,6 +1789,18 @@
"codeowner": "@grafana/search-and-storage"
}
},
{
"metadata": {
"name": "mysqlParseTime",
"resourceVersion": "1724750152191",
"creationTimestamp": "2024-08-27T09:15:52Z"
},
"spec": {
"description": "Ensure the parseTime flag is set for MySQL driver",
"stage": "experimental",
"codeowner": "@grafana/search-and-storage"
}
},
{
"metadata": {
"name": "nestedFolders",

@ -791,7 +791,11 @@ func TestIntegrationSoftDeletion(t *testing.T) {
// Set up dashboard store.
quotaService := quotatest.New(false, nil)
featureToggles := featuremgmt.WithFeatures(featuremgmt.FlagPanelTitleSearch, featuremgmt.FlagDashboardRestore)
featureToggles := featuremgmt.WithFeatures(
featuremgmt.FlagPanelTitleSearch,
featuremgmt.FlagDashboardRestore,
featuremgmt.FlagMysqlParseTime,
)
dashboardStore, err := database.ProvideDashboardStore(replStore, cfg, featureToggles, tagimpl.ProvideService(sqlStore), quotaService)
require.NoError(t, err)

@ -166,6 +166,10 @@ func (dbCfg *DatabaseConfig) buildConnectionString(cfg *setting.Cfg, features fe
cnnstr += fmt.Sprintf("&transaction_isolation=%s", val)
}
if features != nil && features.IsEnabledGlobally(featuremgmt.FlagMysqlParseTime) {
cnnstr += "&parseTime=true"
}
if features != nil && features.IsEnabledGlobally(featuremgmt.FlagMysqlAnsiQuotes) {
cnnstr += "&sql_mode='ANSI_QUOTES'"
}

@ -296,15 +296,24 @@ func (ss *SQLStore) initEngine(engine *xorm.Engine) error {
}
}
if engine == nil {
connection := ss.dbCfg.ConnectionString
// Ensure that parseTime is enabled for MySQL
if ss.dbCfg.Type == migrator.MySQL && !strings.Contains(connection, "parseTime=") {
if ss.features.IsEnabledGlobally(featuremgmt.FlagMysqlParseTime) {
connection += "&parseTime=true"
}
}
var err error
engine, err = xorm.NewEngine(ss.dbCfg.Type, ss.dbCfg.ConnectionString)
engine, err = xorm.NewEngine(ss.dbCfg.Type, connection)
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, ss.dbCfg.ConnectionString)
engine, err = ss.ensureTransactionIsolationCompatibility(engine, connection)
if err != nil {
return err
}
@ -481,6 +490,7 @@ func getCfgForTesting(opts ...InitTestDBOpt) *setting.Cfg {
func getFeaturesForTesting(opts ...InitTestDBOpt) featuremgmt.FeatureToggles {
featureKeys := []any{
featuremgmt.FlagPanelTitleSearch,
featuremgmt.FlagMysqlParseTime,
}
for _, opt := range opts {
if len(opt.FeatureFlags) > 0 {

@ -31,6 +31,7 @@ func getEngineMySQL(getter *sectionGetter, tracer tracing.Tracer) (*xorm.Engine,
config.Loc = time.UTC
config.AllowNativePasswords = true
config.ClientFoundRows = true
config.ParseTime = true
// allow executing multiple SQL statements in a single roundtrip, and also
// enable executing the CALL statement to run stored procedures that execute

Loading…
Cancel
Save