Skip to content

Commit 073a778

Browse files
committed
workload/schemachanger: apply statement_timeout out to CTAS
Previously, the schema changer workload never used statement_timeouts since schema changes are normally not predictable operations. However, since we added CREATE TABLE AS support, its possible to have multiple joins where a CREATE TABLE AS can take more then 5 minutes. This patch modifies the operation generator support adding statement timeouts for individual statements. Fixes: #148342 Release note: None
1 parent c58cccf commit 073a778

File tree

1 file changed

+26
-0
lines changed

1 file changed

+26
-0
lines changed

pkg/workload/schemachange/operation_generator.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1546,6 +1546,10 @@ func (og *operationGenerator) createTableAs(ctx context.Context, tx pgx.Tx) (*op
15461546
if opStmt.expectedExecErrors.empty() {
15471547
opStmt.potentialExecErrors.merge(getValidGenerationErrors())
15481548
}
1549+
// Limit any CTAS statements to a maximum time of 1 minute.
1550+
opStmt.statementTimeout = time.Minute
1551+
opStmt.potentialExecErrors.add(pgcode.QueryCanceled)
1552+
og.potentialCommitErrors.add(pgcode.QueryCanceled)
15491553

15501554
opStmt.sql = fmt.Sprintf(`CREATE TABLE %s AS %s FETCH FIRST %d ROWS ONLY`,
15511555
destTableName, selectStatement.String(), MaxRowsToConsume)
@@ -3052,6 +3056,8 @@ type opStmt struct {
30523056
// potentialExecErrors errors that could be potentially seen on execution.
30533057
potentialExecErrors errorCodeSet
30543058
queryResultCallback opStmtQueryResultCallback
3059+
// statementTimeout if this statement has a timeout.
3060+
statementTimeout time.Duration
30553061
}
30563062

30573063
// String implements Stringer
@@ -3168,6 +3174,16 @@ func (og *operationGenerator) WrapWithErrorState(err error, op *opStmt) error {
31683174
func (s *opStmt) executeStmt(ctx context.Context, tx pgx.Tx, og *operationGenerator) error {
31693175
var err error
31703176
var rows pgx.Rows
3177+
// Apply any timeout for this statement
3178+
if s.statementTimeout > 0 {
3179+
_, err = tx.Exec(ctx, fmt.Sprintf("SET LOCAL statement_timeout='%s'", s.statementTimeout.String()))
3180+
if err != nil {
3181+
return errors.Mark(
3182+
og.WrapWithErrorState(errors.Wrap(err, "***UNEXPECTED ERROR; Unable to set statement timeout."), s),
3183+
errRunInTxnFatalSentinel,
3184+
)
3185+
}
3186+
}
31713187
// Statement doesn't produce any result set that needs to be validated.
31723188
if s.queryResultCallback == nil {
31733189
_, err = tx.Exec(ctx, s.sql)
@@ -3241,6 +3257,16 @@ func (s *opStmt) executeStmt(ctx context.Context, tx pgx.Tx, og *operationGenera
32413257
return err
32423258
}
32433259
}
3260+
// Reset any timeout for this statement
3261+
if s.statementTimeout > 0 {
3262+
_, err = tx.Exec(ctx, "SET LOCAL statement_timeout=0")
3263+
if err != nil {
3264+
return errors.Mark(
3265+
og.WrapWithErrorState(errors.Wrap(err, "***UNEXPECTED ERROR; Unable to reset statement timeout."), s),
3266+
errRunInTxnFatalSentinel,
3267+
)
3268+
}
3269+
}
32443270
return nil
32453271
}
32463272

0 commit comments

Comments
 (0)