-
Notifications
You must be signed in to change notification settings - Fork 1.1k
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[YSQL] Explicit locking fails with "Not implemented" error for a specific corner case #12004
Labels
Comments
pkj415
added
area/ysql
Yugabyte SQL (YSQL)
status/awaiting-triage
Issue awaiting triage
labels
Apr 6, 2022
pkj415
added a commit
to pkj415/yugabyte-db
that referenced
this issue
May 18, 2022
…ansaction when using READ COMMITTED in YSQL that maps to REPEATABLE READ Summary: If yb_enable_read_committed_isolation=false, a "READ COMMITTED" transaction in YSQL maps to SNAPSHOT ISOLATION in docdb. Currently, a user running with yb_enable_read_committed_isolation=false is not able to issue a "select ... for update" as the first statement, if a txn was started with "begin transaction isolation level read committed;". This is because no transaction seems to be created if three conditions occur - (i) "yb_enable_read_committed_isolation=false", (ii) a READ COMMITTED txn is started in YSQL, and (iii) the first statement is a "SELECT ... FOR UPDATE" or any other explicit locking statement. ``` yugabyte=# begin transaction isolation level read committed; BEGIN yugabyte=# select * from test where k=1 for update; ERROR: Not implemented: Read request with row mark types must be part of a transaction: OPERATION_NOT_SUPPORTED yugabyte=# ``` There are 2 bugs in code that cause this (only if present together) - one is a regression which is the cause, another is a bug in read committed implementation which, if corrected, masks the regression. More details - (1) The regression: As part of D15991, RunHelper::Apply() in pg_session.cc doesn't set read_only to false for a "SELECT ... FOR UPDATE" type of statement if the pg_isolation_level is READ COMMITTED. Before this diff, read_only was set to false for explicit locking statements always irrespective of the isolation level. Not setting read_only to false, causes no transaction to be started if that is the first operation in the YSQL transaction block. (2) Day-0 bug, which if fixed separately, it would mask bug (1): In xact.c, we set pg_isolation_level to XactIsoLevel. And, as part of D15383, we have extra logic to set it to XACT_REPEATABLE_READ if XactIsoLevel is XACT_READ_COMMITTED and read committed mode is on. This is the place where READ COMMITTED isolation maps to REPEATABLE READ if yb_enable_read_committed_isolation=false (i.e., the old behaviour when read committed isolation was not implemented). But, we forgot to add the same logic before calling YBCPgSetTransactionIsolationLevel() in assign_XactIsoLevel(). This diff adds that. Not adding that logic causes "READ COMMITTED" isolation in ysqlsh to use READ COMMITTED in doc db even if yb_enable_read_committed_isolation=false. Bug (1) is a regression (D15991) and bug (2) was part of the READ COMMITTED isolation implementation (D15383). Bug (2) along with bug (1) results in the bad behaviour above. NOTE: in a later diff, I will rename pg_isolation_level_ in pg_txn_manager.cc to mapped_pg_isolation_level_ to reflect the true meaning. Test Plan: ./yb_build.sh --java-test org.yb.pgsql.TestPgTransactions#testMiscellaneous Reviewers: rsami, dmitry, mtakahara Subscribers: yql Differential Revision: https://phabricator.dev.yugabyte.com/D16866
pkj415
added a commit
that referenced
this issue
May 19, 2022
…n when using READ COMMITTED in YSQL that maps to REPEATABLE READ Summary: If yb_enable_read_committed_isolation=false, a "READ COMMITTED" transaction in YSQL maps to SNAPSHOT ISOLATION in docdb. Currently, a user running with yb_enable_read_committed_isolation=false is not able to issue a "select ... for update" as the first statement, if a txn was started with "begin transaction isolation level read committed;". This is because no transaction seems to be created if three conditions occur - (i) "yb_enable_read_committed_isolation=false", (ii) a READ COMMITTED txn is started in YSQL, and (iii) the first statement is a "SELECT ... FOR UPDATE" or any other explicit locking statement. ``` yugabyte=# begin transaction isolation level read committed; BEGIN yugabyte=# select * from test where k=1 for update; ERROR: Not implemented: Read request with row mark types must be part of a transaction: OPERATION_NOT_SUPPORTED yugabyte=# ``` There are 2 bugs in code that cause this (only if present together) - one is a regression which is the cause, another is a bug in read committed implementation which, if corrected, masks the regression. More details - (1) The regression: As part of D15991, RunHelper::Apply() in pg_session.cc doesn't set read_only to false for a "SELECT ... FOR UPDATE" type of statement if the pg_isolation_level is READ COMMITTED. Before this diff, read_only was set to false for explicit locking statements always irrespective of the isolation level. Not setting read_only to false, causes no transaction to be started if that is the first operation in the YSQL transaction block. (2) Day-0 bug, which if fixed separately, it would mask bug (1): In xact.c, we set pg_isolation_level to XactIsoLevel. And, as part of D15383, we have extra logic to set it to XACT_REPEATABLE_READ if XactIsoLevel is XACT_READ_COMMITTED and read committed mode is on. This is the place where READ COMMITTED isolation maps to REPEATABLE READ if yb_enable_read_committed_isolation=false (i.e., the old behaviour when read committed isolation was not implemented). But, we forgot to add the same logic before calling YBCPgSetTransactionIsolationLevel() in assign_XactIsoLevel(). This diff adds that. Not adding that logic causes "READ COMMITTED" isolation in ysqlsh to use READ COMMITTED in doc db even if yb_enable_read_committed_isolation=false. Bug (1) is a regression (D15991) and bug (2) was part of the READ COMMITTED isolation implementation (D15383). Bug (2) along with bug (1) results in the bad behaviour above. Test Plan: ./yb_build.sh --java-test org.yb.pgsql.TestPgTransactions#testMiscellaneous Reviewers: rsami, mtakahara, dmitry Reviewed By: dmitry Subscribers: yql Differential Revision: https://phabricator.dev.yugabyte.com/D16866
pkj415
added a commit
that referenced
this issue
May 24, 2022
…ate a transaction when using READ COMMITTED in YSQL that maps to REPEATABLE READ Summary: This backport to 2.12 fixes two bugs in code as mentioned in the original commit summary below. The first bug which is a regression due to D15991 isn't valid for 2.12 since D15991 isn't backported to 2.12. The second fix is still valid. Also, the changes that fix the first bug are still cherry-picked since they don't change any behaviour in 2.12 and will moreover ensure safety by throwing a merge conflict when an attempt to cherry-pick D15991 to 2.12 is made. If yb_enable_read_committed_isolation=false, a "READ COMMITTED" transaction in YSQL maps to SNAPSHOT ISOLATION in docdb. Currently, a user running with yb_enable_read_committed_isolation=false is not able to issue a "select ... for update" as the first statement, if a txn was started with "begin transaction isolation level read committed;". This is because no transaction seems to be created if three conditions occur - (i) "yb_enable_read_committed_isolation=false", (ii) a READ COMMITTED txn is started in YSQL, and (iii) the first statement is a "SELECT ... FOR UPDATE" or any other explicit locking statement. ``` yugabyte=# begin transaction isolation level read committed; BEGIN yugabyte=# select * from test where k=1 for update; ERROR: Not implemented: Read request with row mark types must be part of a transaction: OPERATION_NOT_SUPPORTED yugabyte=# ``` There are 2 bugs in code that cause this (only if present together) - one is a regression which is the cause, another is a bug in read committed implementation which, if corrected, masks the regression. More details - (1) The regression: As part of D15991, RunHelper::Apply() in pg_session.cc doesn't set read_only to false for a "SELECT ... FOR UPDATE" type of statement if the pg_isolation_level is READ COMMITTED. Before this diff, read_only was set to false for explicit locking statements always irrespective of the isolation level. Not setting read_only to false, causes no transaction to be started if that is the first operation in the YSQL transaction block. (2) Day-0 bug, which if fixed separately, it would mask bug (1): In xact.c, we set pg_isolation_level to XactIsoLevel. And, as part of D15383, we have extra logic to set it to XACT_REPEATABLE_READ if XactIsoLevel is XACT_READ_COMMITTED and read committed mode is on. This is the place where READ COMMITTED isolation maps to REPEATABLE READ if yb_enable_read_committed_isolation=false (i.e., the old behaviour when read committed isolation was not implemented). But, we forgot to add the same logic before calling YBCPgSetTransactionIsolationLevel() in assign_XactIsoLevel(). This diff adds that. Not adding that logic causes "READ COMMITTED" isolation in ysqlsh to use READ COMMITTED in doc db even if yb_enable_read_committed_isolation=false. Bug (1) is a regression (D15991) and bug (2) was part of the READ COMMITTED isolation implementation (D15383). Bug (2) along with bug (1) results in the bad behaviour above. Original commit: 331a48b / D16866 Test Plan: Jenkins: urgent ./yb_build.sh --java-test org.yb.pgsql.TestPgTransactions#testMiscellaneous Reviewers: dmitry, mtakahara Reviewed By: mtakahara Subscribers: yql Differential Revision: https://phabricator.dev.yugabyte.com/D17146
yugabyte-ci
added
kind/bug
This issue is a bug
priority/medium
Medium priority issue
labels
May 24, 2022
pkj415
added a commit
that referenced
this issue
May 27, 2022
…te a transaction when using READ COMMITTED in YSQL that maps to REPEATABLE READ Summary: If yb_enable_read_committed_isolation=false, a "READ COMMITTED" transaction in YSQL maps to SNAPSHOT ISOLATION in docdb. Currently, a user running with yb_enable_read_committed_isolation=false is not able to issue a "select ... for update" as the first statement, if a txn was started with "begin transaction isolation level read committed;". This is because no transaction seems to be created if three conditions occur - (i) "yb_enable_read_committed_isolation=false", (ii) a READ COMMITTED txn is started in YSQL, and (iii) the first statement is a "SELECT ... FOR UPDATE" or any other explicit locking statement. ``` yugabyte=# begin transaction isolation level read committed; BEGIN yugabyte=# select * from test where k=1 for update; ERROR: Not implemented: Read request with row mark types must be part of a transaction: OPERATION_NOT_SUPPORTED yugabyte=# ``` There are 2 bugs in code that cause this (only if present together) - one is a regression which is the cause, another is a bug in read committed implementation which, if corrected, masks the regression. More details - (1) The regression: As part of D15991, RunHelper::Apply() in pg_session.cc doesn't set read_only to false for a "SELECT ... FOR UPDATE" type of statement if the pg_isolation_level is READ COMMITTED. Before this diff, read_only was set to false for explicit locking statements always irrespective of the isolation level. Not setting read_only to false, causes no transaction to be started if that is the first operation in the YSQL transaction block. (2) Day-0 bug, which if fixed separately, it would mask bug (1): In xact.c, we set pg_isolation_level to XactIsoLevel. And, as part of D15383, we have extra logic to set it to XACT_REPEATABLE_READ if XactIsoLevel is XACT_READ_COMMITTED and read committed mode is on. This is the place where READ COMMITTED isolation maps to REPEATABLE READ if yb_enable_read_committed_isolation=false (i.e., the old behaviour when read committed isolation was not implemented). But, we forgot to add the same logic before calling YBCPgSetTransactionIsolationLevel() in assign_XactIsoLevel(). This diff adds that. Not adding that logic causes "READ COMMITTED" isolation in ysqlsh to use READ COMMITTED in doc db even if yb_enable_read_committed_isolation=false. Bug (1) is a regression (D15991) and bug (2) was part of the READ COMMITTED isolation implementation (D15383). Bug (2) along with bug (1) results in the bad behaviour above. Original commit: 331a48b / D16866 Test Plan: ./yb_build.sh --java-test org.yb.pgsql.TestPgTransactions#testMiscellaneous Reviewers: dmitry, mtakahara Reviewed By: mtakahara Subscribers: yql Differential Revision: https://phabricator.dev.yugabyte.com/D17210
pkj415
added a commit
to pkj415/yugabyte-db
that referenced
this issue
May 31, 2022
…ansaction when using READ COMMITTED in YSQL that maps to REPEATABLE READ Summary: If yb_enable_read_committed_isolation=false, a "READ COMMITTED" transaction in YSQL maps to SNAPSHOT ISOLATION in docdb. Currently, a user running with yb_enable_read_committed_isolation=false is not able to issue a "select ... for update" as the first statement, if a txn was started with "begin transaction isolation level read committed;". This is because no transaction seems to be created if three conditions occur - (i) "yb_enable_read_committed_isolation=false", (ii) a READ COMMITTED txn is started in YSQL, and (iii) the first statement is a "SELECT ... FOR UPDATE" or any other explicit locking statement. ``` yugabyte=# begin transaction isolation level read committed; BEGIN yugabyte=# select * from test where k=1 for update; ERROR: Not implemented: Read request with row mark types must be part of a transaction: OPERATION_NOT_SUPPORTED yugabyte=# ``` There are 2 bugs in code that cause this (only if present together) - one is a regression which is the cause, another is a bug in read committed implementation which, if corrected, masks the regression. More details - (1) The regression: As part of D15991, RunHelper::Apply() in pg_session.cc doesn't set read_only to false for a "SELECT ... FOR UPDATE" type of statement if the pg_isolation_level is READ COMMITTED. Before this diff, read_only was set to false for explicit locking statements always irrespective of the isolation level. Not setting read_only to false, causes no transaction to be started if that is the first operation in the YSQL transaction block. (2) Day-0 bug, which if fixed separately, it would mask bug (1): In xact.c, we set pg_isolation_level to XactIsoLevel. And, as part of D15383, we have extra logic to set it to XACT_REPEATABLE_READ if XactIsoLevel is XACT_READ_COMMITTED and read committed mode is on. This is the place where READ COMMITTED isolation maps to REPEATABLE READ if yb_enable_read_committed_isolation=false (i.e., the old behaviour when read committed isolation was not implemented). But, we forgot to add the same logic before calling YBCPgSetTransactionIsolationLevel() in assign_XactIsoLevel(). This diff adds that. Not adding that logic causes "READ COMMITTED" isolation in ysqlsh to use READ COMMITTED in doc db even if yb_enable_read_committed_isolation=false. Bug (1) is a regression (D15991) and bug (2) was part of the READ COMMITTED isolation implementation (D15383). Bug (2) along with bug (1) results in the bad behaviour above. NOTE: in a later diff, I will rename pg_isolation_level_ in pg_txn_manager.cc to mapped_pg_isolation_level_ to reflect the true meaning. Test Plan: ./yb_build.sh --java-test org.yb.pgsql.TestPgTransactions#testMiscellaneous Reviewers: rsami, dmitry, mtakahara Subscribers: yql Differential Revision: https://phabricator.dev.yugabyte.com/D16866
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
Jira Link: DB-523
Description
The below snippet explains the issue -
NOTE: "begin transaction isolation level read committed;" uses repeatable read isolation since yb_enable_read_committed_isolation is false by default.
The cause might be "isolation_level_ = IsolationLevel::NON_TRANSACTIONAL;" in PgTxnManager::ResetTxnAndSession() in the refactor commit c5f5125
The text was updated successfully, but these errors were encountered: