Skip to content
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

[CBRD-25734] Fix assert on CUBRID server stop with incomplete XA transactions #6085

Draft
wants to merge 5 commits into
base: develop
Choose a base branch
from

Conversation

InChiJun
Copy link
Contributor

@InChiJun InChiJun commented Apr 3, 2025

http://jira.cubrid.org/browse/CBRD-25734

Purpose

  • XA 트랜잭션이 완료되지 않은 상태에서 트랜잭션의 연결이 끊기면 트랜잭션 정보가 초기화되지 않고 있음
    • 이 상태로 cubrid server stop 시 assert 발생(자세한 과정은 jira issue 참고)
  • assert 발생을 막기 위해 완료되지 않은 XA 트랜잭션 연결이 끊기면 abort로 초기화되도록 함

Implementation

  • XA 트랜잭션 연결이 종료될 때 완료되지 않은 상태(2PC_PREPARE)의 트랜잭션도 abort로 초기화하도록 구현

Remarks

  • 일반 XA 트랜잭션은 2PC를 활용하기 위해 coordinator를 사용합니다. 이때 완료되지 않은 트랜잭션이 종료되면 recovery 시 coordinator의 명령에 따라 commit/abort 여부를 결정하고 진행합니다.

  • 현재 CUBRID 코드에는 XA 트랜잭션을 위한 coordinator가 활용되지 않고 있으며, recovery 시 abort를 발생시키도록 구현됐기 때문에, 완료되지 않은 XA 트랜잭션은 server stop 시 abort로 초기화 되도록 구현하였습니다.

  • 본 PR의 코드 수정은 [CBRD-25645] [bug-fix] Assert when restarting server after committing some XA transactions #5677 PR을 cherry-pick 하여 진행되었으니 리뷰시 참고 부탁드립니다.

@InChiJun InChiJun self-assigned this Apr 3, 2025
@InChiJun InChiJun marked this pull request as ready for review April 3, 2025 09:58
@InChiJun InChiJun requested a review from hornetmj as a code owner April 3, 2025 09:58
@hornetmj hornetmj requested review from hyahong and removed request for YeunjunLee April 4, 2025 02:12
@InChiJun InChiJun requested review from hyahong and removed request for hyahong April 4, 2025 02:13
@InChiJun InChiJun marked this pull request as draft April 7, 2025 02:01
@InChiJun InChiJun changed the title [CBRD-25734]Fix assert on CUBRID server stop with incomplete XA transactions [CBRD-25734] Fix assert on CUBRID server stop with incomplete XA transactions Apr 7, 2025
@InChiJun InChiJun marked this pull request as ready for review April 7, 2025 08:41
@InChiJun InChiJun requested a review from youngjun9072 April 7, 2025 08:43
Copy link
Collaborator

@hyahong hyahong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 오류는 XA transaction이 완료되지 않은 채로 종료될 때 LOG_TDES가 정리되지 않아서 일어나는 것은 맞지만, 근본적인 원인은 JIRA에 기술하신 것처럼 잘못된 자원 해제 순서입니다.

따라서 완료되지 않은 XA transaction이 종료될 때 abort처리하여 문제를 막는 방식보다는 근본적인 해결이 우선되고, 그 이후에 XA의 처리에 따른 후 처리를 하는 게 맞지 않을까요?

/* If the transaction is active abort it */
if (LOG_ISTRAN_ACTIVE (tdes)) /* logtb_is_current_active (thread_p) */
/* If the transaction is active or unactive_2pc_prepare abort it */
if (LOG_ISTRAN_ACTIVE (tdes) || LOG_ISTRAN_2PC_PREPARE(tdes))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 코드는 근본적인 문제 해결보다는 logtb_release_tran_index에서 trid를 release하여 추후 destroy된 객체 자체에 대한 접근을 막으려는 시도로 보입니다.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1. transaction은 정상적/비정상적인 종료와 무관하게 transaction을 commit/abort한 후, tran_index를 release하고 trid를 NULL_TRANID로 설정하여 이 LOG_TDES가 사용되지 않음과 재사용 가능함을 명시합니다.

그러나 transaction의 state가 특정 XA state에 있을 때는 LOG_TDES에 대한 clear가 이뤄지지 않습니다. 따라서 XA를 요청한 client는 이미 끊어졌는데, 상태는 그대로 남아있게 됩니다.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2. 서버를 종료할 때 일어나는 자원 해제의 순서가 이상합니다.

css_init ( .. )의 하단부 shutdown 라벨 이후의 처리를 보면 css_Server_request_worker_pool을 destroy합니다. 그리고 이후 호출되는 log_abort_all_active_transaction ( ... )에서 만약 trid가 NULL_TRANID가 아닌 LOG_TDES가 있다면, 해당 transaction thread가 아직 실행 중인 지 확인하기 위해 css_Server_request_worker_pool에 접근하며 segfault가 발생합니다.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3. prepare된 XA transaction이 임의로 abort 되면 원자성이 깨질 수 있습니다.

조건문에 LOG_ISTRAN_2PC_PREPARE ( ... )를 추가하면 transaction의 state가 TRAN_UNACTIVE_2PC_PREPARE인 경우에도 abort를 수행하게 됩니다. 그러나 아래
lock_internal_perform_lock_object 처리를 보면, XA transaction이 prepare에 들어간 시점에서는 log에 기록되었고 추후 redo가 가능함을 보여줍니다.
물론, 현재 CUBRID의 XA가 어느 수준으로 구현되어 있고, partial commit 상황에서 어떤 정책을 취하는 지는 모르나 종료될 때 바로 abort를 하게 되면 원자성이 깨질 수 있습니다.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다만, 현 시점에서는 coordinator가 없어 각각 commit 성공/실패 여부를 알 수 없기 때문에 애초에 원자성이 보장되지 않는 상황입니다.
그러나 그와 동시에 transaction의 state가 prepare라는 것은, 사용자가 이미 commit을 요청한 상태고, transaction이 원자성 보장을 위한 내부적인 phase에 있다는 것을 의미합니다. 따라서 모든 트랜잭션들이 반드시 commit 되기만 한다면 원자성을 강제로 보장할 수 있습니다.

이를 위해서 서버 종료 시 prepare된 transaction이 있거나, recovery 시 prepare된 트랜잭션이 있다면 무조건 commit을 수행하여 강제로 원자성을 보장한다거나 하는 등의 추가적인 매커니즘이 필요해 보입니다. 물론 이 방법은 모든 XA transaction에서 prepare가 정상적으로 이뤄졌는 지에 대한 보장과 반드시 commit이 성공해야함을 전제로 가져야 합니다.

@InChiJun InChiJun marked this pull request as draft April 8, 2025 04:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants