2.31.0.0-b146
tagged this
08 Jun 17:22
Summary: Serialization error due to concurrent DDL should be reported to the end user as PostgreSql error 40001 (ERRCODE_T_R_SERIALIZATION_FAILURE) instead of YB003 (ERRCODE_YB_TXN_CONFLICT). Description: When ysql_enable_concurrent_ddl is false, if two concurrent transactions in repeatable read isolation level execute DDL statements, one of the COMMIT statements can run into a serialization conflict error (YB003). In yb_exec_query_wrapper_one_attempt in postgres.c, we catch this error and attempt to retry the statement. The function yb_attempt_to_retry_on_error decides that the statement retry is not possible it is a COMMIT statement. Hence, it rethrows the error. This exception is caught in the simple query execution logic of postgres.c and the exception handler calls YBPrepareCacheRefreshIfNeeded. The function YBPrepareCacheRefreshIfNeeded calls YbGetMasterCatalogVersion which in turn calls YbGetMasterCatalogVersionImpl to retrieve catalog version. This again runs into the same serialization conflict error (YB003) because in transactional DDL mode, all catalog reads after a DDL statement is done in the transaction block use the kTransactional session (see GetRequiredSessionType). So the same transaction context is used and since the transaction has aborted, the same error is returned. This error YB003 is reported to the end user. More generally, whenever a serialization conflict error is not retryable, we reported YB003 error to the end user. Conflict error with COMMIT in concurrent DDLs is only one such instance. We should report PostgreSQL error 40001 instead in all such cases. Fix: In send_message_to_frontend (elog.c), just before we report the error to the user, we translate the error code ERRCODE_YB_TXN_CONFLICT to ERRCODE_T_R_SERIALIZATION_FAILURE in yb_external_errcode. Since we are invoking yb_external_errcode in send_message_to_frontend, other invocations to yb_external_errcode are redundant and hence removed. Test Plan: ./yb_build.sh release --cxx-test pgwrapper_pg_concurrent_ddls-test --gtest_filter 'PgDdlTransactionWithoutConcurrentDDLSupportTest.TestReportProperSerializationErrorInRepeatableRead' Reviewers: pjain, amartsinchyk Reviewed By: pjain Subscribers: jason, yql Differential Revision: https://phorge.dev.yugabyte.com/D54007