You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Summary:
### Motivation
Consider the following scenario
Setup:
```
CREATE TABLE tokens(token INT);
INSERT INTO tokens SELECT i FROM GENERATE_SERIES(1, 100) i;
```
The following txn faces a read restart error when there is a concurrent insert:
```
BEGIN ISOLATION LEVEL READ COMMITTED;
SELECT token FROM tokens LIMIT 1;
SELECT token FROM tokens ORDER BY token; <--- read restart error here.
ROLLBACK;
```
Concurrent insert:
```
INSERT INTO tokens SELECT i FROM GENERATE_SERIES(200, 300) i;
```
Error:
```
2025-04-03 15:37:39.463 UTC [321440] ERROR: Restart read required at: { read: { days: 20181 time: 15:37:39.460582 } local_limit: { days: 20181 time: 15:37:39.460582 } global_limit: <min> in_txn_limit: <max> serial_no: 0 } (query layer retry isn't possible because data was already sent, if this is the read committed isolation (or) the first statement in repeatable read/ serializable isolation transaction, consider increasing the tserver gflag ysql_output_buffer_size)
2025-04-03 15:37:39.463 UTC [321440] STATEMENT: SELECT token FROM tokens ORDER BY token
```
The error recommends increasing ysql_output_buffer_size if this is the first statement of a repeatable read txn. This is not the first statement of the txn. However, thats difficult to read. Users often miss the condition and increase the buffer size.
Moreover, the error message does not provide a good recommendation when the error is on a non-first statement of repeatable read.
### Fix
Change recommendation to consider read committed isolation level.
```
2025-04-03 15:28:26.175 UTC [309395] ERROR: Restart read required at: { read: { days: 20181 time: 15:28:26.171916 } local_limit: { days: 20181 time: 15:28:26.171916 } global_limit: <min> in_txn_limit: <max> serial_no: 0 } (query layer retry isn't possible because this is not the first command in the transaction. Consider using READ COMMITTED isolation level. Please turn on yb_enable_read_committed_isolation to enable READ COMMITTED isolation level.)
2025-04-03 15:28:26.175 UTC [309395] STATEMENT: SELECT token FROM tokens ORDER BY token
```
Fixes#26648
Jira: DB-16025
Test Plan:
Jenkins
```
./yb_build.sh --cxx-test pg_debug_read_restarts-test
./yb_build.sh --java-test TestPgRegressIsolationWithoutWaitQueues#testPgRegress
./yb_build.sh --java-test TestPgRegressWaitQueues#testPgRegress
./yb_build.sh --java-test TestPgRegressIsolation#testPgRegress
./yb_build.sh --java-test TestPgRegressIsolation#testPgRegressWithDelayedTxnApply
```
Backport-through: 2024.2
Reviewers: pjain, smishra
Reviewed By: pjain
Subscribers: yql
Differential Revision: https://phorge.dev.yugabyte.com/D42974
Copy file name to clipboardExpand all lines: src/postgres/src/test/isolation/expected/yb.orig.deadlock.out
+2-2
Original file line number
Diff line number
Diff line change
@@ -34,7 +34,7 @@ step s3_upd_all_k_except_2: UPDATE test SET v=3 where k!=2; <waiting ...>
34
34
step s1c: COMMIT;
35
35
step s2_upd_all_k_except_1: <... completed>
36
36
step s3_upd_all_k_except_2: <... completed>
37
-
ERROR: deadlock detected (query layer retry isn't possible because data was already sent, if this is the read committed isolation (or) the first statement in repeatable read/ serializable isolation transaction, consider increasing the tserver gflag ysql_output_buffer_size)
37
+
ERROR: deadlock detected (query layer retry isn't possible because this is not the first command in the transaction. Consider using READ COMMITTED isolation level.)
38
38
step s2c: COMMIT;
39
39
step s3c: COMMIT;
40
40
step s1_select: SELECT * FROM test ORDER BY k;
@@ -70,7 +70,7 @@ step s2_upd_k1: UPDATE test SET v=2 WHERE k=1;
70
70
step s3_upd_k2: UPDATE test SET v=3 WHERE k=2;
71
71
step s2_upd_all_k_except_1: UPDATE test SET v=2 where k!=1; <waiting ...>
72
72
step s3_upd_all_k_except_2: UPDATE test SET v=3 where k!=2;
73
-
ERROR: deadlock detected (query layer retry isn't possible because data was already sent, if this is the read committed isolation (or) the first statement in repeatable read/ serializable isolation transaction, consider increasing the tserver gflag ysql_output_buffer_size)
73
+
ERROR: deadlock detected (query layer retry isn't possible because this is not the first command in the transaction. Consider using READ COMMITTED isolation level.)
step s1_update_fk1: UPDATE tb SET fk1 = 10 WHERE k = 1;
97
97
step s2_update_fk2: UPDATE tb SET fk2 = 10 WHERE k = 1;
98
98
step s1_commit: COMMIT;
99
-
ERROR: could not serialize access due to concurrent update (query layer retry isn't possible because data was already sent, if this is the read committed isolation (or) the first statement in repeatable read/ serializable isolation transaction, consider increasing the tserver gflag ysql_output_buffer_size)
99
+
ERROR: could not serialize access due to concurrent update (query layer retry isn't possible because this is not the first command in the transaction. Consider using READ COMMITTED isolation level.)
step s1_update_fk1: UPDATE tb SET fk1 = 10 WHERE k = 1;
140
140
step s2_update_fk2: UPDATE tb SET fk2 = 10 WHERE k = 1;
141
141
step s1_commit: COMMIT;
142
-
ERROR: could not serialize access due to concurrent update (query layer retry isn't possible because data was already sent, if this is the read committed isolation (or) the first statement in repeatable read/ serializable isolation transaction, consider increasing the tserver gflag ysql_output_buffer_size)
142
+
ERROR: could not serialize access due to concurrent update (query layer retry isn't possible because this is not the first command in the transaction. Consider using READ COMMITTED isolation level.)
Copy file name to clipboardExpand all lines: src/postgres/src/test/isolation/expected/yb.orig.modify-transaction-characteristics.out
+8-8
Original file line number
Diff line number
Diff line change
@@ -21,7 +21,7 @@ step s1_update: UPDATE test SET v=v+1 WHERE k=1;
21
21
step s2_update: UPDATE test SET v=v*2 WHERE k=1; <waiting ...>
22
22
step s1_commit: COMMIT;
23
23
step s2_update: <... completed>
24
-
ERROR: could not serialize access due to concurrent update (query layer retry isn't possible because data was already sent, if this is the read committed isolation (or) the first statement in repeatable read/ serializable isolation transaction, consider increasing the tserver gflag ysql_output_buffer_size)
24
+
ERROR: could not serialize access due to concurrent update (query layer retry isn't possible because this is not the first command in the transaction. Consider using READ COMMITTED isolation level.)
25
25
step s2_rollback: ROLLBACK;
26
26
step s2_select: SELECT * FROM test;
27
27
k|v
@@ -51,7 +51,7 @@ step s1_update: UPDATE test SET v=v+1 WHERE k=1;
51
51
step s2_update: UPDATE test SET v=v*2 WHERE k=1; <waiting ...>
52
52
step s1_commit: COMMIT;
53
53
step s2_update: <... completed>
54
-
ERROR: could not serialize access due to concurrent update (query layer retry isn't possible because data was already sent, if this is the read committed isolation (or) the first statement in repeatable read/ serializable isolation transaction, consider increasing the tserver gflag ysql_output_buffer_size)
54
+
ERROR: could not serialize access due to concurrent update (query layer retry isn't possible because this is not the first command in the transaction. Consider using READ COMMITTED isolation level.)
55
55
step s2_rollback: ROLLBACK;
56
56
step s2_select: SELECT * FROM test;
57
57
k|v
@@ -83,7 +83,7 @@ step s1_update: UPDATE test SET v=v+1 WHERE k=1;
83
83
step s2_update: UPDATE test SET v=v*2 WHERE k=1; <waiting ...>
84
84
step s1_commit: COMMIT;
85
85
step s2_update: <... completed>
86
-
ERROR: could not serialize access due to concurrent update (query layer retry isn't possible because data was already sent, if this is the read committed isolation (or) the first statement in repeatable read/ serializable isolation transaction, consider increasing the tserver gflag ysql_output_buffer_size)
86
+
ERROR: could not serialize access due to concurrent update (query layer retry isn't possible because this is not the first command in the transaction. Consider using READ COMMITTED isolation level.)
87
87
step s2_rollback: ROLLBACK;
88
88
step s2_select: SELECT * FROM test;
89
89
k|v
@@ -113,7 +113,7 @@ step s1_update: UPDATE test SET v=v+1 WHERE k=1;
113
113
step s2_update: UPDATE test SET v=v*2 WHERE k=1; <waiting ...>
114
114
step s1_commit: COMMIT;
115
115
step s2_update: <... completed>
116
-
ERROR: could not serialize access due to concurrent update (query layer retry isn't possible because data was already sent, if this is the read committed isolation (or) the first statement in repeatable read/ serializable isolation transaction, consider increasing the tserver gflag ysql_output_buffer_size)
116
+
ERROR: could not serialize access due to concurrent update (query layer retry isn't possible because this is not the first command in the transaction. Consider using READ COMMITTED isolation level.)
117
117
step s2_rollback: ROLLBACK;
118
118
step s2_select: SELECT * FROM test;
119
119
k|v
@@ -259,7 +259,7 @@ k|v
259
259
260
260
step s1_update: UPDATE test SET v=v+1 WHERE k=1; <waiting ...>
261
261
step s2_update: UPDATE test SET v=v*2 WHERE k=1;
262
-
ERROR: deadlock detected (query layer retry isn't possible because data was already sent, if this is the read committed isolation (or) the first statement in repeatable read/ serializable isolation transaction, consider increasing the tserver gflag ysql_output_buffer_size)
262
+
ERROR: deadlock detected (query layer retry isn't possible because this is not the first command in the transaction. Consider using READ COMMITTED isolation level.)
263
263
step s1_update: <... completed>
264
264
step s1_commit: COMMIT;
265
265
step s2_rollback: ROLLBACK;
@@ -289,7 +289,7 @@ k|v
289
289
290
290
step s1_update: UPDATE test SET v=v+1 WHERE k=1; <waiting ...>
291
291
step s2_update: UPDATE test SET v=v*2 WHERE k=1;
292
-
ERROR: deadlock detected (query layer retry isn't possible because data was already sent, if this is the read committed isolation (or) the first statement in repeatable read/ serializable isolation transaction, consider increasing the tserver gflag ysql_output_buffer_size)
292
+
ERROR: deadlock detected (query layer retry isn't possible because this is not the first command in the transaction. Consider using READ COMMITTED isolation level.)
293
293
step s1_update: <... completed>
294
294
step s1_commit: COMMIT;
295
295
step s2_rollback: ROLLBACK;
@@ -321,7 +321,7 @@ k|v
321
321
322
322
step s1_update: UPDATE test SET v=v+1 WHERE k=1; <waiting ...>
323
323
step s2_update: UPDATE test SET v=v*2 WHERE k=1;
324
-
ERROR: deadlock detected (query layer retry isn't possible because data was already sent, if this is the read committed isolation (or) the first statement in repeatable read/ serializable isolation transaction, consider increasing the tserver gflag ysql_output_buffer_size)
324
+
ERROR: deadlock detected (query layer retry isn't possible because this is not the first command in the transaction. Consider using READ COMMITTED isolation level.)
325
325
step s1_update: <... completed>
326
326
step s1_commit: COMMIT;
327
327
step s2_rollback: ROLLBACK;
@@ -351,7 +351,7 @@ k|v
351
351
352
352
step s1_update: UPDATE test SET v=v+1 WHERE k=1; <waiting ...>
353
353
step s2_update: UPDATE test SET v=v*2 WHERE k=1;
354
-
ERROR: deadlock detected (query layer retry isn't possible because data was already sent, if this is the read committed isolation (or) the first statement in repeatable read/ serializable isolation transaction, consider increasing the tserver gflag ysql_output_buffer_size)
354
+
ERROR: deadlock detected (query layer retry isn't possible because this is not the first command in the transaction. Consider using READ COMMITTED isolation level.)
Copy file name to clipboardExpand all lines: src/postgres/src/test/isolation/expected/yb.orig.only-abort-sub-txn.out
+1-1
Original file line number
Diff line number
Diff line change
@@ -19,7 +19,7 @@ step s1_pick_read_time: SELECT * FROM tbl;
19
19
step s2_update_conflicting_key: UPDATE tbl SET v = 2 WHERE k = 1;
20
20
step s1_savepoint_a: SAVEPOINT a;
21
21
step s1_update_conflicting_key: UPDATE tbl SET v = 3 WHERE k = 1;
22
-
ERROR: could not serialize access due to concurrent update (query layer retry isn't possible because data was already sent, if this is the read committed isolation (or) the first statement in repeatable read/ serializable isolation transaction, consider increasing the tserver gflag ysql_output_buffer_size)
22
+
ERROR: could not serialize access due to concurrent update (query layer retry isn't possible because this is not the first command in the transaction. Consider using READ COMMITTED isolation level.)
23
23
step s1_rollback_to_a: ROLLBACK TO a;
24
24
step s1_update_non_conflicting_key: UPDATE tbl SET v = 3 WHERE k = 2;
step s1_update: UPDATE t SET v1 = add_with_limit(v1, v2, 35) WHERE k = 1;
68
68
step s2_update: UPDATE t SET v2 = add_with_limit(v2, v1, 35) WHERE k = 1;
69
69
step s1_commit: COMMIT;
70
-
ERROR: could not serialize access due to concurrent update (query layer retry isn't possible because data was already sent, if this is the read committed isolation (or) the first statement in repeatable read/ serializable isolation transaction, consider increasing the tserver gflag ysql_output_buffer_size)
70
+
ERROR: could not serialize access due to concurrent update (query layer retry isn't possible because this is not the first command in the transaction. Consider using READ COMMITTED isolation level.)
step s1_update: UPDATE t SET v1 = add_with_limit(v1, v2, 35) WHERE k = 1;
85
85
step s2_update: UPDATE t SET v2 = add_with_limit(v2, v1, 35) WHERE k = 1;
86
86
step s1_commit: COMMIT;
87
-
ERROR: could not serialize access due to concurrent update (query layer retry isn't possible because data was already sent, if this is the read committed isolation (or) the first statement in repeatable read/ serializable isolation transaction, consider increasing the tserver gflag ysql_output_buffer_size)
87
+
ERROR: could not serialize access due to concurrent update (query layer retry isn't possible because this is not the first command in the transaction. Consider using READ COMMITTED isolation level.)
88
88
step s1_select: select *, v1 + v2 from t;
89
89
k|v1|v2|?column?
90
90
-+--+--+--------
@@ -193,7 +193,7 @@ step s2_update_case:
193
193
UPDATE t SET v2 = CASE WHEN v1 + v2 < 35 THEN v1 + v2 ELSE 0 END WHERE k = 1;
194
194
195
195
step s1_commit: COMMIT;
196
-
ERROR: could not serialize access due to concurrent update (query layer retry isn't possible because data was already sent, if this is the read committed isolation (or) the first statement in repeatable read/ serializable isolation transaction, consider increasing the tserver gflag ysql_output_buffer_size)
196
+
ERROR: could not serialize access due to concurrent update (query layer retry isn't possible because this is not the first command in the transaction. Consider using READ COMMITTED isolation level.)
197
197
step s1_select: select *, v1 + v2 from t;
198
198
k|v1|v2|?column?
199
199
-+--+--+--------
@@ -214,7 +214,7 @@ step s2_update_case:
214
214
UPDATE t SET v2 = CASE WHEN v1 + v2 < 35 THEN v1 + v2 ELSE 0 END WHERE k = 1;
215
215
216
216
step s1_commit: COMMIT;
217
-
ERROR: could not serialize access due to concurrent update (query layer retry isn't possible because data was already sent, if this is the read committed isolation (or) the first statement in repeatable read/ serializable isolation transaction, consider increasing the tserver gflag ysql_output_buffer_size)
217
+
ERROR: could not serialize access due to concurrent update (query layer retry isn't possible because this is not the first command in the transaction. Consider using READ COMMITTED isolation level.)
0 commit comments