Skip to content

Commit 4ddb3e2

Browse files
craig[bot]alyshanjahani-crlmgartnermsbutlerjeffswenson
committed
154028: sql: Fix idle latency tracking r=alyshanjahani-crl a=alyshanjahani-crl Previously idle latencies were not being tracked accurately in two situations. First, there was massive over counting of idle latencies in transactions that had INSERTs with placeholders (more generally statement that executed a prepare/bind before running). See issue #146116. In these situations we had missed setting the QueryServiced time for the statements within the transaction, resulting in all the intermediate idle latencies calulating their `waitingSince` from the transaction start time. The control flow of the conn executor can be difficult to track and through adding print statements, the difference between a transaction with `INSERT INTO ... VALUES (1)` vs `INSERT INTO ... VALUES ($1)` highlighted that setting QueryServiced at the end of the `ExecStmt` case in `execCmd` meant that for the prepare/bind version of the INSERT statements, we never set QueryServiced. Simple statements: ``` execCmd ExecStmt execStmtInOpenState INSERT INTO test_idle VALUES (1) execCmd Setting QueryServiced execCmd ExecStmt execStmtInOpenState INSERT INTO test_idle VALUES (1) execCmd Setting QueryServiced execCmd ExecStmt execStmtInOpenState INSERT INTO test_idle VALUES (1) execCmd Setting QueryServiced ``` Notice how after every `execStmtInOpenState`, the flow returns to `execCmd`. Whereas in the case below, we just flow back into `execStmtInOpenState`. Prepare/bind statements: ``` prepare statsCollector.Reset bind statsCollector.Reset execStmtInOpenState INSERT INTO test_idle VALUES ($1) prepare statsCollector.Reset bind statsCollector.Reset execStmtInOpenState INSERT INTO test_idle VALUES ($1) prepare statsCollector.Reset bind statsCollector.Reset execStmtInOpenState INSERT INTO test_idle VALUES ($1) ``` The second situation in which idle latencies were not tracked correctly was when observer statements were run in between statements in the transaction. This is a situation that occurs when using the `cockroach sql` cli. In this case, idle latencies were severely undercounted because we'd reset the stats collector before running the observer statement, and then when the non observer statement ran and we recorded the statement summary, the idle latency would be calculated from the previous observer statement time. This commit fixes the first situation by additionally setting QueryServiced after `execStmt`. This commit fixes the second situation by accumulating idle latencies in between observer statements. Lastly this commit removes the existing TestSQLStatsIdleLatencies as it evidently had poor coverage and replaces it with TestTransactionLatencies which enforces invariants like: totalTxnTime >= txnServiceLatency >= txnIdleLatency p.s debugging session phase times is really tedious and we should consider refactoring. Fixes: #146116 Release note (bug fix): Fixes discrepencies between idle and service latencies. 154162: sql: fix `COPY` with hidden and inaccessible columns r=mgartner a=mgartner Fixes #119524 Release note (bug fix): A bug has been fixed that caused panics when executing `COPY` into a table with hidden columns and expression indexes. The panic only occurred when the `expect_and_ignore_not_visible_columns_in_copy` setting was enabled. This bug has been present since `expect_and_ignore_not_visible_columns_in_copy` was introduced in v22.1.0. 154201: external connection: deflake privs test r=jeffswenson a=msbutler Informs #154141 Release note: none 154262: retry: deflake TestRetryWithMaxDurationAndMaxRetries r=jeffswenson a=jeffswenson Previously, the time bound for the retry test was quite small. So an overloaded or slow test runner may hit the timeout before the goroutine was scheduled for max retries. Fixes: #154160 Release note: none Co-authored-by: Alyshan Jahani <[email protected]> Co-authored-by: Marcus Gartner <[email protected]> Co-authored-by: Michael Butler <[email protected]> Co-authored-by: Jeff Swenson <[email protected]>
5 parents a352f16 + 3a62640 + 566f0bb + 4324415 + 530360f commit 4ddb3e2

File tree

8 files changed

+182
-246
lines changed

8 files changed

+182
-246
lines changed

pkg/ccl/cloudccl/externalconn/testdata/privileges_external_connection

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,11 @@ GRANT DROP ON EXTERNAL CONNECTION "drop-privileged" TO testuser;
6363

6464
# Verify that the privileges exist.
6565
query-sql
66-
SELECT * FROM system.privileges
66+
SELECT username, path, privileges FROM system.privileges order by user_id
6767
----
68-
root /externalconn/drop-privileged {ALL} {} 1
69-
root /externalconn/drop-privileged-dup {ALL} {} 1
70-
testuser /externalconn/drop-privileged {DROP} {} 100
68+
root /externalconn/drop-privileged {ALL}
69+
root /externalconn/drop-privileged-dup {ALL}
70+
testuser /externalconn/drop-privileged {DROP}
7171

7272
exec-sql user=testuser
7373
DROP EXTERNAL CONNECTION "drop-privileged"
@@ -131,11 +131,11 @@ CREATE EXTERNAL CONNECTION 'not-root' AS 'userfile:///bar'
131131

132132
# Verify that the privileges exist.
133133
query-sql
134-
SELECT * FROM system.privileges
134+
SELECT username, path, privileges FROM system.privileges order by user_id
135135
----
136-
root /externalconn/root {ALL} {} 1
137-
testuser /externalconn/not-root {ALL} {} 101
138-
testuser /global/ {EXTERNALCONNECTION} {} 101
136+
root /externalconn/root {ALL}
137+
testuser /externalconn/not-root {ALL}
138+
testuser /global/ {EXTERNALCONNECTION}
139139

140140
exec-sql user=testuser
141141
BACKUP TABLE foo INTO 'external://not-root'

pkg/sql/conn_executor_exec.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ func (ex *connExecutor) execStmt(
135135
if _, ok := ast.(tree.ObserverStatement); ok {
136136
ex.statsCollector.Reset(ex.applicationStats, ex.phaseTimes)
137137
err := ex.runObserverStatement(ctx, ast, res)
138+
ex.extraTxnState.idleLatency += ex.phaseTimes.GetIdleLatency(ex.statsCollector.PreviousPhaseTimes())
139+
ex.phaseTimes.SetSessionPhaseTime(sessionphase.SessionQueryServiced, crtime.NowMono())
138140
// Note that regardless of res.Err(), these observer statements don't
139141
// generate error events; transactions are always allowed to continue.
140142
return nil, nil, err
@@ -178,6 +180,7 @@ func (ex *connExecutor) execStmt(
178180
case eventNonRetryableErrPayload:
179181
ex.recordFailure(p)
180182
}
183+
ex.phaseTimes.SetSessionPhaseTime(sessionphase.SessionQueryServiced, crtime.NowMono())
181184

182185
case stateAborted:
183186
ev, payload = ex.execStmtInAbortedState(ctx, ast, res)

pkg/sql/copy_from.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,9 +343,15 @@ func newCopyMachine(
343343
// to have field data then we have to populate the expectedHiddenColumnIdxs
344344
// field with the columns indexes we expect to be hidden.
345345
if c.p.SessionData().ExpectAndIgnoreNotVisibleColumnsInCopy && len(n.Columns) == 0 {
346+
numInaccessibleCols := 0
346347
for i, col := range tableDesc.PublicColumns() {
347348
if col.IsHidden() {
348-
c.expectedHiddenColumnIdxs = append(c.expectedHiddenColumnIdxs, i)
349+
// Offset the index by the number of preceding inaccessible
350+
// columns, which are never expected in the input.
351+
c.expectedHiddenColumnIdxs = append(c.expectedHiddenColumnIdxs, i-numInaccessibleCols)
352+
}
353+
if col.IsInaccessible() {
354+
numInaccessibleCols++
349355
}
350356
}
351357
}

pkg/sql/pgwire/testdata/pgtest/copy

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,52 @@ ReadyForQuery
199199
{"Type":"CommandComplete","CommandTag":"SELECT 3"}
200200
{"Type":"ReadyForQuery","TxStatus":"I"}
201201

202+
# Regression test for #119524. expect_and_ignore_not_visible_columns_in_copy
203+
# should behave correctly with inaccessible columns.
204+
send
205+
Query {"String": "CREATE TABLE t119524 (x INT PRIMARY KEY, y INT, INDEX ((x + y)))"}
206+
----
207+
208+
until
209+
ReadyForQuery
210+
----
211+
{"Type":"CommandComplete","CommandTag":"CREATE TABLE"}
212+
{"Type":"ReadyForQuery","TxStatus":"I"}
213+
214+
send
215+
Query {"String": "ALTER TABLE t119524 ADD COLUMN z INT NOT VISIBLE"}
216+
----
217+
218+
until
219+
ReadyForQuery
220+
----
221+
{"Type":"CommandComplete","CommandTag":"ALTER TABLE"}
222+
{"Type":"ReadyForQuery","TxStatus":"I"}
223+
224+
send crdb_only
225+
Query {"String": "COPY t119524 FROM STDIN"}
226+
CopyData {"Data": "1\t2\t3\n"}
227+
CopyDone
228+
----
229+
230+
until crdb_only
231+
ReadyForQuery
232+
----
233+
{"Type":"CopyInResponse","ColumnFormatCodes":[0,0]}
234+
{"Type":"CommandComplete","CommandTag":"COPY 1"}
235+
{"Type":"ReadyForQuery","TxStatus":"I"}
236+
237+
send crdb_only
238+
Query {"String": "SELECT *, z FROM t119524"}
239+
----
240+
241+
until ignore=RowDescription crdb_only
242+
ReadyForQuery
243+
----
244+
{"Type":"DataRow","Values":[{"text":"1"},{"text":"2"},null]}
245+
{"Type":"CommandComplete","CommandTag":"SELECT 1"}
246+
{"Type":"ReadyForQuery","TxStatus":"I"}
247+
202248
send crdb_only
203249
Query {"String": "SET expect_and_ignore_not_visible_columns_in_copy = false"}
204250
----

pkg/sql/sessionphase/session_phase.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ func NewTimes() *Times {
114114
}
115115

116116
// SetSessionPhaseTime sets the time for a given SessionPhase.
117+
// TODO(alyshan): Session Phase Times are set throughout the conn executor, it is
118+
// a tedious process to track when and where these times are set.
119+
// Found a bug again? Consider refactoring.
117120
func (t *Times) SetSessionPhaseTime(sp SessionPhase, time crtime.Mono) {
118121
t.times[sp] = time
119122
}

0 commit comments

Comments
 (0)