diff --git a/src/storage/ob_partition_group.cpp b/src/storage/ob_partition_group.cpp index 81be0f8bb26ba67ad7ba72374b9c387ffb646c25..e337c6a5f727ec3092af71ea23fa54644621e1e9 100644 --- a/src/storage/ob_partition_group.cpp +++ b/src/storage/ob_partition_group.cpp @@ -6025,16 +6025,14 @@ int ObPartitionGroup::clear_trans_after_restore_log(const uint64_t last_restore_ } else if (OB_UNLIKELY(OB_INVALID_ID == last_restore_log_id) || OB_UNLIKELY(OB_INVALID_TIMESTAMP == last_restore_log_ts)) { ret = OB_INVALID_ARGUMENT; - STORAGE_LOG(WARN, "invalid last_restore_log_info", KR(ret), K_(pkey), - K(last_restore_log_id), K(last_restore_log_ts)); - } else if (OB_FAIL(pg_storage_.set_last_restore_log_info(last_restore_log_id, - last_restore_log_ts))) { - STORAGE_LOG(WARN, "failed to set_last_restore_log_info", K(ret), K_(pkey), - K(last_restore_log_id), K(last_restore_log_ts)); - } else if (OB_FAIL(txs_->set_last_restore_log_info(pkey_, last_restore_log_id, - last_restore_log_ts))) { - STORAGE_LOG(WARN, "failed to set_last_restore_log_ts", KR(ret), K_(pkey), - K(last_restore_log_id), K(last_restore_log_ts)); + STORAGE_LOG( + WARN, "invalid last_restore_log_info", KR(ret), K_(pkey), K(last_restore_log_id), K(last_restore_log_ts)); + } else if (OB_FAIL(pg_storage_.set_last_restore_log_info(last_restore_log_id, last_restore_log_ts))) { + STORAGE_LOG( + WARN, "failed to set_last_restore_log_info", K(ret), K_(pkey), K(last_restore_log_id), K(last_restore_log_ts)); + } else if (OB_FAIL(txs_->set_last_restore_log_info(pkey_, last_restore_log_id, last_restore_log_ts))) { + STORAGE_LOG( + WARN, "failed to set_last_restore_log_info", KR(ret), K_(pkey), K(last_restore_log_id), K(last_restore_log_ts)); } else { ATOMIC_SET(&has_clear_trans_after_restore_, true); } diff --git a/src/storage/transaction/ob_trans_ctx_mgr.h b/src/storage/transaction/ob_trans_ctx_mgr.h index 7830c03724b737cb0ca6b3a2baed41e6ae09a949..d0268e073d2c9279b0755ce795da29db9fa3f779 100644 --- a/src/storage/transaction/ob_trans_ctx_mgr.h +++ b/src/storage/transaction/ob_trans_ctx_mgr.h @@ -612,7 +612,7 @@ private: // it is used to record the last restore log id pulling by physical backup and recovery uint64_t last_restore_log_id_; // it is used to record the last restore log ts pulling by physical backup and recovery - uint64_t last_restore_log_ts_; + int64_t last_restore_log_ts_; // the statistics for elr // number of trans with prev uint64_t with_dependency_trx_count_; diff --git a/src/storage/transaction/ob_trans_part_ctx.cpp b/src/storage/transaction/ob_trans_part_ctx.cpp index 99317695ced8b2fc7f269e9a91dd3c1e62998249..15e2d60700f4ba219f7c5cba4d65c21f949d542c 100644 --- a/src/storage/transaction/ob_trans_part_ctx.cpp +++ b/src/storage/transaction/ob_trans_part_ctx.cpp @@ -4123,21 +4123,35 @@ int ObPartTransCtx::replay_commit_log(const ObTransCommitLog& log, const int64_t return ret; } +// For pg restored in 3.x, restore_snapshot_version and last_restore_log_ts is used to +// rollback trans which is restored and superfluous +// +// For pg restored in 2.x, last_restore_log_id is used instead of last_restore_log_ts, +// as last_restore_log_ts is not maintained in pg restored from 2.x bool ObPartTransCtx::need_rollback_when_restore_(const int64_t commit_version) { + bool bret = false; const int64_t restore_snapshot_version = partition_mgr_->get_restore_snapshot_version(); const uint64_t last_restore_log_id = partition_mgr_->get_last_restore_log_id(); - return restore_snapshot_version > 0 - && (last_restore_log_id == OB_INVALID_ID || min_log_id_ <= last_restore_log_id) - && commit_version > restore_snapshot_version; + const int64_t last_restore_log_ts = partition_mgr_->get_last_restore_log_ts(); + // restore_snapshot_version is invalid, all trans need not rollback + if (OB_INVALID_TIMESTAMP == restore_snapshot_version) { + bret = false; + } else if (OB_INVALID_TIMESTAMP != last_restore_log_ts) { + // last_restore_log_ts is valid, pg is restored in 3.x + bret = min_log_ts_ <= last_restore_log_ts && commit_version > restore_snapshot_version; + } else if (OB_INVALID_ID != last_restore_log_id) { + // last_restore_log_ts is invalid and last_restore_log_id is valid, pg is restored in 2.x + bret = min_log_id_ <= last_restore_log_id && commit_version > restore_snapshot_version; + } else { + // last_restore_log_ts and last_restore_log_id are invalid, pg is in restoring + bret = commit_version > restore_snapshot_version; + } + return bret; } -// TODO: duotian -bool ObPartTransCtx::need_update_schema_version(const int64_t log_id, const int64_t log_ts) +bool ObPartTransCtx::need_update_schema_version(const uint64_t log_id, const int64_t log_ts) { - UNUSED(log_id); - UNUSED(log_ts); - /* const int64_t restore_snapshot_version = partition_mgr_->get_restore_snapshot_version(); const int64_t last_restore_log_id = partition_mgr_->get_last_restore_log_id(); bool need_update = true; @@ -4146,8 +4160,6 @@ bool ObPartTransCtx::need_update_schema_version(const int64_t log_id, const int6 need_update = false; } return need_update; - */ - return true; } int ObPartTransCtx::trans_replay_commit_(const int64_t commit_version, const int64_t checksum) @@ -11800,6 +11812,7 @@ void ObPartTransCtx::get_audit_info(int64_t& lock_for_read_elapse) const // which transactions should be kept and the log ts who is the last log ts during // restore phase. fake_terminate_log_ts is mocked as terminate_log_ts of // aborted dirty transaction. (See details in ObPartTransCtx::fake_kill_). +// For pg restored from 2.x, last_restore_log_id is used instead of last_restore_log_ts // NB: We should also take dirty txn into account. Of course, Dirty txns are // more complicated. For example, the transaction status of dirty txn may be @@ -11811,8 +11824,19 @@ int ObPartTransCtx::clear_trans_after_restore(const int64_t restore_version, con const int64_t last_restore_log_ts, const int64_t fake_terminate_log_ts) { int ret = OB_SUCCESS; + bool need_clear = false; CtxLockGuard guard(lock_); const int64_t state = get_state_(); + { + // For pg restored from 2.x, last_restore_log_ts is invalid and last_restore_log_id is valid + if (OB_INVALID_TIMESTAMP == last_restore_log_ts) { + if (cluster_version_ < CLUSTER_VERSION_3000 && OB_INVALID_ID != last_restore_log_id) { + need_clear = min_log_id_ <= last_restore_log_id; + } + } else { + need_clear = min_log_ts_ <= last_restore_log_ts; + } + } if (IS_NOT_INIT) { // skip the uninitialized transactions ret = OB_SUCCESS; @@ -11823,7 +11847,7 @@ int ObPartTransCtx::clear_trans_after_restore(const int64_t restore_version, con K(last_restore_log_id), K(last_restore_log_ts), K(fake_terminate_log_ts)); - } else if (min_log_id_ > last_restore_log_id) { + } else if (!need_clear) { // skip new transactions after restore completes ret = OB_SUCCESS; TRANS_LOG(INFO, diff --git a/src/storage/transaction/ob_trans_part_ctx.h b/src/storage/transaction/ob_trans_part_ctx.h index 053b8c6081e9f902bf8658e6ae64964f2feed1f2..6aaaa188ddbbb82e0dcd1b778225ee845536924c 100644 --- a/src/storage/transaction/ob_trans_part_ctx.h +++ b/src/storage/transaction/ob_trans_part_ctx.h @@ -389,7 +389,7 @@ public: bool is_in_trans_table_state(); virtual int64_t get_part_trans_action() const override; int rollback_stmt(const int64_t from_sql_no, const int64_t to_sql_no); - bool need_update_schema_version(const int64_t log_id, const int64_t log_ts); + bool need_update_schema_version(const uint64_t log_id, const int64_t log_ts); public: INHERIT_TO_STRING_KV("ObDistTransCtx", ObDistTransCtx, K_(snapshot_version), K_(local_trans_version),