Skip to content

Commit 29dffc3

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 6d30ef4 commit 29dffc3

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
@@ -1493,6 +1493,10 @@ func (og *operationGenerator) createTableAs(ctx context.Context, tx pgx.Tx) (*op
14931493
if opStmt.expectedExecErrors.empty() {
14941494
opStmt.potentialExecErrors.merge(getValidGenerationErrors())
14951495
}
1496+
// Limit any CTAS statements to a maximum time of 1 minute.
1497+
opStmt.statementTimeout = time.Minute
1498+
opStmt.potentialExecErrors.add(pgcode.QueryCanceled)
1499+
og.potentialCommitErrors.add(pgcode.QueryCanceled)
14961500

14971501
opStmt.sql = fmt.Sprintf(`CREATE TABLE %s AS %s FETCH FIRST %d ROWS ONLY`,
14981502
destTableName, selectStatement.String(), MaxRowsToConsume)
@@ -3172,6 +3176,8 @@ type opStmt struct {
31723176
potentialExecErrors errorCodeSet
31733177
// queryResultCallback handles the results of the query execution.
31743178
queryResultCallback opStmtQueryResultCallback
3179+
// statementTimeout if this statement has a timeout.
3180+
statementTimeout time.Duration
31753181
}
31763182

31773183
// String implements Stringer
@@ -3288,6 +3294,16 @@ func (og *operationGenerator) WrapWithErrorState(err error, op *opStmt) error {
32883294
func (s *opStmt) executeStmt(ctx context.Context, tx pgx.Tx, og *operationGenerator) error {
32893295
var err error
32903296
var rows pgx.Rows
3297+
// Apply any timeout for this statement
3298+
if s.statementTimeout > 0 {
3299+
_, err = tx.Exec(ctx, fmt.Sprintf("SET LOCAL statement_timeout='%s'", s.statementTimeout.String()))
3300+
if err != nil {
3301+
return errors.Mark(
3302+
og.WrapWithErrorState(errors.Wrap(err, "***UNEXPECTED ERROR; Unable to set statement timeout."), s),
3303+
errRunInTxnFatalSentinel,
3304+
)
3305+
}
3306+
}
32913307
// Statement doesn't produce any result set that needs to be validated.
32923308
if s.queryResultCallback == nil {
32933309
_, err = tx.Exec(ctx, s.sql)
@@ -3361,6 +3377,16 @@ func (s *opStmt) executeStmt(ctx context.Context, tx pgx.Tx, og *operationGenera
33613377
return err
33623378
}
33633379
}
3380+
// Reset any timeout for this statement
3381+
if s.statementTimeout > 0 {
3382+
_, err = tx.Exec(ctx, "SET LOCAL statement_timeout=0")
3383+
if err != nil {
3384+
return errors.Mark(
3385+
og.WrapWithErrorState(errors.Wrap(err, "***UNEXPECTED ERROR; Unable to reset statement timeout."), s),
3386+
errRunInTxnFatalSentinel,
3387+
)
3388+
}
3389+
}
33643390
return nil
33653391
}
33663392

0 commit comments

Comments
 (0)