[BUG] fix 4138 because unclear session timestamp

This commit is contained in:
Handora
2023-06-06 07:42:32 +00:00
committed by ob-robot
parent f16a8319fc
commit 82b923c9db
4 changed files with 94 additions and 27 deletions

View File

@ -1347,46 +1347,91 @@ bool GetMinActiveSnapshotVersionFunctor::operator()(sql::ObSQLSessionMgr::Key ke
share::SCN snapshot_version(share::SCN::max_scn());
if (sess_info->is_in_transaction()) {
share::SCN desc_snapshot;
transaction::ObTxDesc *tx_desc = nullptr;
share::SCN sess_snapshot = sess_info->get_reserved_snapshot_version();
if (OB_ISNULL(tx_desc = sess_info->get_tx_desc())) {
MVCC_LOG(WARN, "tx desc is nullptr", KPC(sess_info));
ret = OB_ERR_UNEXPECTED;
MVCC_LOG(ERROR, "tx desc is nullptr", K(ret), KPC(sess_info));
} else if (FALSE_IT(desc_snapshot = tx_desc->get_snapshot_version())) {
} else if (transaction::ObTxIsolationLevel::SERIAL == tx_desc->get_isolation_level() ||
transaction::ObTxIsolationLevel::RR == tx_desc->get_isolation_level()) {
// Case 1: RR/SI with tx desc exists, so we can get snapshot version from tx desc
share::SCN tmp_snapshot_version = tx_desc->get_snapshot_version();
if (tmp_snapshot_version.is_valid()) {
snapshot_version = tmp_snapshot_version;
// Case 1: RR/SI with tx desc exists, it means the snapshot is get from
// scheduler and must maintained in the session and tx desc
if (desc_snapshot.is_valid()) {
snapshot_version = desc_snapshot;
}
MVCC_LOG(DEBUG, "RR/SI txn with tx_desc", K(MTL_ID()), KPC(tx_desc), KPC(sess_info),
K(snapshot_version), K(min_active_snapshot_version_));
K(snapshot_version), K(min_active_snapshot_version_), K(desc_snapshot),
K(sess_snapshot));
} else if (transaction::ObTxIsolationLevel::RC == tx_desc->get_isolation_level()) {
// Case 2: RC with tx desc exists, while the snapshot version is not
// maintained, so we use query start time instead
// TODO(handora.qc): use better snapshot version
// Case 2: RC with tx desc exists, it may exists that snapshot is get from
// the executor and not maintained in the session and tx desc. So we need
// use session query start time carefully
if (sql::ObSQLSessionState::QUERY_ACTIVE == sess_info->get_session_state()) {
snapshot_version.convert_from_ts(sess_info->get_cur_state_start_time());
if (desc_snapshot.is_valid()) {
snapshot_version = desc_snapshot;
} else if (sess_snapshot.is_valid()) {
snapshot_version = sess_snapshot;
} else {
// We gave a 5 minutes redundancy when get from session query start
// time under the case that local snapshot from tx_desc and session
// is unusable
snapshot_version.convert_from_ts(sess_info->get_cur_state_start_time()
- 5L * 1000L * 1000L * 60L);
MVCC_LOG(INFO, "RC txn with tx_desc while from session start time",
K(MTL_ID()), KPC(tx_desc), KPC(sess_info), K(snapshot_version),
K(min_active_snapshot_version_), K(sess_info->get_cur_state_start_time()));
}
}
MVCC_LOG(DEBUG, "RC txn with tx_desc", K(MTL_ID()), KPC(tx_desc), KPC(sess_info),
K(snapshot_version), K(min_active_snapshot_version_));
K(snapshot_version), K(min_active_snapshot_version_), K(desc_snapshot),
K(sess_snapshot));
} else {
MVCC_LOG(WARN, "unknown txn with tx_desc", K(MTL_ID()), KPC(tx_desc), KPC(sess_info),
MVCC_LOG(INFO, "unknown txn with tx_desc", K(MTL_ID()), KPC(tx_desc), KPC(sess_info),
K(snapshot_version), K(min_active_snapshot_version_));
}
} else {
share::SCN sess_snapshot = sess_info->get_reserved_snapshot_version();
if (transaction::ObTxIsolationLevel::SERIAL == sess_info->get_tx_isolation() ||
transaction::ObTxIsolationLevel::RR == sess_info->get_tx_isolation()) {
// Case 3: RR/SI with tx desc does not exist, it is not for the scheduler
MVCC_LOG(DEBUG, "RR/SI txn with non tx_desc", K(MTL_ID()), KPC(sess_info),
K(snapshot_version), K(min_active_snapshot_version_));
} else if (transaction::ObTxIsolationLevel::RC == sess_info->get_tx_isolation()) {
// Case 4: RC with tx desc does not exist, while the snapshot version is not
// maintained, so we use query start time instead
// TODO(handora.qc): use better snapshot version
// Case 3: RR/SI with tx desc does not exist or not in tx, it is not for
// the current running scheduler
if (sql::ObSQLSessionState::QUERY_ACTIVE == sess_info->get_session_state()) {
snapshot_version.convert_from_ts(sess_info->get_cur_state_start_time());
if (sess_snapshot.is_valid()) {
snapshot_version = sess_snapshot;
} else {
// We gave a 5 minutes redundancy when get from session query start
// time under the case that local snapshot from tx_desc and session
// is unusable
snapshot_version.convert_from_ts(sess_info->get_cur_state_start_time()
- 5L * 1000L * 1000L * 60L);
MVCC_LOG(INFO, "RR/SI txn with non tx_desc while from session start time",
K(MTL_ID()), KPC(sess_info), K(snapshot_version), K(sess_snapshot),
K(min_active_snapshot_version_), K(sess_info->get_cur_state_start_time()));
}
}
MVCC_LOG(DEBUG, "RR/SI txn with non tx_desc", K(MTL_ID()), KPC(sess_info),
K(snapshot_version), K(min_active_snapshot_version_), K(sess_snapshot));
} else if (transaction::ObTxIsolationLevel::RC == sess_info->get_tx_isolation()) {
// Case 4: RC with tx desc does not exist, and the snapshot version may not
// maintained, so we use query start time instead
if (sql::ObSQLSessionState::QUERY_ACTIVE == sess_info->get_session_state()) {
if (sess_snapshot.is_valid()) {
snapshot_version = sess_snapshot;
} else {
// We gave a 5 minutes redundancy when get from session query start
// time under the case that local snapshot from tx_desc and session
// is unusable
snapshot_version.convert_from_ts(sess_info->get_cur_state_start_time()
- 5L * 1000L * 1000L * 60L);
MVCC_LOG(INFO, "RC txn with non tx_desc while from session start time",
K(MTL_ID()), KPC(sess_info), K(snapshot_version), K(sess_snapshot),
K(min_active_snapshot_version_), K(sess_info->get_cur_state_start_time()));
}
}
MVCC_LOG(DEBUG, "RC txn with non tx_desc", K(MTL_ID()), KPC(sess_info),
K(snapshot_version), K(min_active_snapshot_version_));
K(snapshot_version), K(min_active_snapshot_version_), K(sess_snapshot));
} else {
MVCC_LOG(INFO, "unknown txn with non tx_desc", K(MTL_ID()), KPC(sess_info),
K(snapshot_version), K(min_active_snapshot_version_));