@@ -12,39 +12,56 @@ import (
12
12
13
13
"github.com/cockroachdb/cockroach/pkg/jobs/jobspb"
14
14
"github.com/cockroachdb/cockroach/pkg/kv"
15
+ "github.com/cockroachdb/cockroach/pkg/settings"
16
+ "github.com/cockroachdb/cockroach/pkg/settings/cluster"
15
17
"github.com/cockroachdb/cockroach/pkg/sql/isql"
16
18
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
19
+ "github.com/cockroachdb/cockroach/pkg/util/metamorphic"
17
20
"github.com/cockroachdb/errors"
18
21
)
19
22
23
+ var testingAvoidFullScans = metamorphic .ConstantWithTestBool (
24
+ "jobs.avoid_full_scans_in_find_running_jobs" ,
25
+ false , /* defaultValue */
26
+ )
27
+
28
+ var avoidFullScans = settings .RegisterBoolSetting (
29
+ settings .ApplicationLevel ,
30
+ "jobs.avoid_full_scans_in_find_running_jobs.enabled" ,
31
+ "when true, enables hints to avoid full scans for internal, jobs-related queries" ,
32
+ testingAvoidFullScans )
33
+
20
34
// RunningJobExists checks that whether there are any job of the given types
21
35
// in the pending, running, or paused status, optionally ignoring the job with
22
36
// the ID specified by ignoreJobID as well as any jobs created after it, if
23
37
// the passed ID is not InvalidJobID.
24
38
func RunningJobExists (
25
- ctx context.Context , ignoreJobID jobspb.JobID , txn isql.Txn , jobTypes ... jobspb.Type ,
39
+ ctx context.Context ,
40
+ cs * cluster.Settings ,
41
+ ignoreJobID jobspb.JobID ,
42
+ txn isql.Txn ,
43
+ jobTypes ... jobspb.Type ,
26
44
) (exists bool , retErr error ) {
27
45
typeStrs , err := getJobTypeStrs (jobTypes )
28
46
if err != nil {
29
47
return false , err
30
48
}
31
49
32
- orderBy := " ORDER BY created"
50
+ orderBy := "ORDER BY created"
33
51
if ignoreJobID == jobspb .InvalidJobID {
34
52
// There is no need to order by the created column if there is no job to
35
53
// ignore.
36
54
orderBy = ""
37
55
}
38
56
39
- stmt := `
40
- SELECT
41
- id
42
- FROM
43
- system.jobs@jobs_status_created_idx
44
- WHERE
45
- job_type IN ` + typeStrs + ` AND
46
- status IN ` + NonTerminalStatusTupleString + orderBy + `
47
- LIMIT 1`
57
+ hint := "jobs_status_created_idx"
58
+ if avoidFullScans .Get (& cs .SV ) {
59
+ hint = "{FORCE_INDEX=jobs_status_created_idx,AVOID_FULL_SCAN}"
60
+ }
61
+
62
+ q := `SELECT id FROM system.jobs@%s WHERE job_type IN %s AND status IN %s %s LIMIT 1`
63
+ stmt := fmt .Sprintf (q , hint , typeStrs , NonTerminalStatusTupleString , orderBy )
64
+
48
65
it , err := txn .QueryIterator (
49
66
ctx ,
50
67
"find-running-jobs-of-type" ,
@@ -74,28 +91,31 @@ LIMIT 1`
74
91
// by ignoreJobID as well as any jobs created after it, if the passed ID is not
75
92
// InvalidJobID.
76
93
func RunningJobs (
77
- ctx context.Context , ignoreJobID jobspb.JobID , txn isql.Txn , jobTypes ... jobspb.Type ,
94
+ ctx context.Context ,
95
+ cs * cluster.Settings ,
96
+ ignoreJobID jobspb.JobID ,
97
+ txn isql.Txn ,
98
+ jobTypes ... jobspb.Type ,
78
99
) (jobIDs []jobspb.JobID , retErr error ) {
79
100
typeStrs , err := getJobTypeStrs (jobTypes )
80
101
if err != nil {
81
102
return jobIDs , err
82
103
}
83
104
84
- orderBy := " ORDER BY created"
105
+ orderBy := "ORDER BY created"
85
106
if ignoreJobID == jobspb .InvalidJobID {
86
107
// There is no need to order by the created column if there is no job to
87
108
// ignore.
88
109
orderBy = ""
89
110
}
90
111
91
- stmt := `
92
- SELECT
93
- id
94
- FROM
95
- system.jobs@jobs_status_created_idx
96
- WHERE
97
- job_type IN ` + typeStrs + ` AND
98
- status IN ` + NonTerminalStatusTupleString + orderBy
112
+ hint := "jobs_status_created_idx"
113
+ if avoidFullScans .Get (& cs .SV ) {
114
+ hint = "{FORCE_INDEX=jobs_status_created_idx,AVOID_FULL_SCAN}"
115
+ }
116
+
117
+ q := `SELECT id FROM system.jobs@%s WHERE job_type IN %s AND status IN %s %s`
118
+ stmt := fmt .Sprintf (q , hint , typeStrs , NonTerminalStatusTupleString , orderBy )
99
119
it , err := txn .QueryIterator (
100
120
ctx ,
101
121
"find-all-running-jobs-of-type" ,
0 commit comments