Skip to content

Commit 3bba76f

Browse files
authored
modify: Add statement timeout query parmeter for MySQL (#778)
* modify: Add statement timeout query parmeter for MySQL * fix: parsing and assignment of statementTimeout * fix: bad merge
1 parent 0d585e2 commit 3bba76f

File tree

2 files changed

+27
-7
lines changed

2 files changed

+27
-7
lines changed

Diff for: database/mysql/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
|------------|---------------------|-------------|
77
| `x-migrations-table` | `MigrationsTable` | Name of the migrations table |
88
| `x-no-lock` | `NoLock` | Set to `true` to skip `GET_LOCK`/`RELEASE_LOCK` statements. Useful for [multi-master MySQL flavors](https://www.percona.com/doc/percona-xtradb-cluster/LATEST/features/pxc-strict-mode.html#explicit-table-locking). Only run migrations from one host when this is enabled. |
9+
| `x-statement-timeout` | `StatementTimeout` | Abort any statement that takes more than the specified number of milliseconds, functionally similar to [Server-side SELECT statement timeouts](https://dev.mysql.com/blog-archive/server-side-select-statement-timeouts/) but enforced by the client. Available for all versions of MySQL, not just >=5.7. |
910
| `dbname` | `DatabaseName` | The name of the database to connect to |
1011
| `user` | | The user to sign in as |
1112
| `password` | | The user's password |

Diff for: database/mysql/mysql.go

+26-7
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"os"
1515
"strconv"
1616
"strings"
17+
"time"
1718

1819
"go.uber.org/atomic"
1920

@@ -39,9 +40,10 @@ var (
3940
)
4041

4142
type Config struct {
42-
MigrationsTable string
43-
DatabaseName string
44-
NoLock bool
43+
MigrationsTable string
44+
DatabaseName string
45+
NoLock bool
46+
StatementTimeout time.Duration
4547
}
4648

4749
type Mysql struct {
@@ -242,15 +244,25 @@ func (m *Mysql) Open(url string) (database.Driver, error) {
242244
}
243245
}
244246

247+
statementTimeoutParam := customParams["x-statement-timeout"]
248+
statementTimeout := 0
249+
if statementTimeoutParam != "" {
250+
statementTimeout, err = strconv.Atoi(statementTimeoutParam)
251+
if err != nil {
252+
return nil, fmt.Errorf("could not parse x-statement-timeout as float: %w", err)
253+
}
254+
}
255+
245256
db, err := sql.Open("mysql", config.FormatDSN())
246257
if err != nil {
247258
return nil, err
248259
}
249260

250261
mx, err := WithInstance(db, &Config{
251-
DatabaseName: config.DBName,
252-
MigrationsTable: customParams["x-migrations-table"],
253-
NoLock: noLock,
262+
DatabaseName: config.DBName,
263+
MigrationsTable: customParams["x-migrations-table"],
264+
NoLock: noLock,
265+
StatementTimeout: time.Duration(statementTimeout) * time.Millisecond,
254266
})
255267
if err != nil {
256268
return nil, err
@@ -328,8 +340,15 @@ func (m *Mysql) Run(migration io.Reader) error {
328340
return err
329341
}
330342

343+
ctx := context.Background()
344+
if m.config.StatementTimeout != 0 {
345+
var cancel context.CancelFunc
346+
ctx, cancel = context.WithTimeout(ctx, m.config.StatementTimeout)
347+
defer cancel()
348+
}
349+
331350
query := string(migr[:])
332-
if _, err := m.conn.ExecContext(context.Background(), query); err != nil {
351+
if _, err := m.conn.ExecContext(ctx, query); err != nil {
333352
return database.Error{OrigErr: err, Err: "migration failed", Query: migr}
334353
}
335354

0 commit comments

Comments
 (0)