patch 4.0
This commit is contained in:
@ -13,26 +13,30 @@
|
||||
#ifndef OCEANBASE_SQL_TRANS_CONTROL_
|
||||
#define OCEANBASE_SQL_TRANS_CONTROL_
|
||||
#include "share/ob_define.h"
|
||||
#include "common/ob_partition_key.h"
|
||||
#include "storage/transaction/ob_trans_define.h"
|
||||
#include "storage/tx/ob_trans_define.h"
|
||||
#include "storage/tx/ob_trans_deadlock_adapter.h"
|
||||
#include "sql/session/ob_sql_session_info.h"
|
||||
#include "sql/session/ob_sql_session_mgr.h"
|
||||
#include "storage/tx/ob_clog_encrypt_info.h"
|
||||
#include "storage/tablelock/ob_table_lock_common.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace transaction {
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace transaction
|
||||
{
|
||||
class ObStartTransParam;
|
||||
class ObTransDesc;
|
||||
} // namespace transaction
|
||||
namespace storage {
|
||||
class ObPartitionService;
|
||||
class ObTxDesc;
|
||||
}
|
||||
|
||||
namespace share {
|
||||
namespace schema {
|
||||
namespace share
|
||||
{
|
||||
namespace schema
|
||||
{
|
||||
class ObTableSchema;
|
||||
}
|
||||
} // namespace share
|
||||
namespace sql {
|
||||
}
|
||||
namespace sql
|
||||
{
|
||||
class ObExecContext;
|
||||
class ObPhysicalPlan;
|
||||
class ObPhyOperator;
|
||||
@ -40,165 +44,108 @@ class ObStmt;
|
||||
class ObPhysicalPlanCtx;
|
||||
class ObSQLSessionInfo;
|
||||
class ObIEndTransCallback;
|
||||
class ObEndTransAsyncCallback;
|
||||
class ObNullEndTransCallback;
|
||||
class ObExclusiveEndTransCallback;
|
||||
class ObIDASTaskOp;
|
||||
|
||||
class TransState {
|
||||
class TransState
|
||||
{
|
||||
private:
|
||||
static const uint32_t START_TRANS_EXECUTED_BIT = (1 << 0);
|
||||
static const uint32_t END_TRANS_EXECUTED_BIT = (1 << 2);
|
||||
static const uint32_t START_STMT_EXECUTED_BIT = (1 << 4);
|
||||
static const uint32_t END_STMT_EXECUTED_BIT = (1 << 6);
|
||||
static const uint32_t START_PART_EXECUTED_BIT = (1 << 8);
|
||||
static const uint32_t END_PART_EXECUTED_BIT = (1 << 10);
|
||||
static const uint32_t START_TRANS_SUCC_BIT = (1 << 1);
|
||||
static const uint32_t END_TRANS_SUCC_BIT = (1 << 3);
|
||||
static const uint32_t START_STMT_SUCC_BIT = (1 << 5);
|
||||
static const uint32_t END_STMT_SUCC_BIT = (1 << 7);
|
||||
static const uint32_t START_PART_SUCC_BIT = (1 << 9);
|
||||
static const uint32_t END_PART_SUCC_BIT = (1 << 11);
|
||||
/* 两位表示一个动作:低位表示是否执行,高位表示是否成功 */
|
||||
static const uint32_t START_TRANS_EXECUTED_BIT = (1 << 0);
|
||||
static const uint32_t END_TRANS_EXECUTED_BIT = (1 << 2);
|
||||
static const uint32_t START_STMT_EXECUTED_BIT = (1 << 4);
|
||||
static const uint32_t END_STMT_EXECUTED_BIT = (1 << 6);
|
||||
static const uint32_t START_PART_EXECUTED_BIT = (1 << 8);
|
||||
static const uint32_t END_PART_EXECUTED_BIT = (1 << 10);
|
||||
static const uint32_t START_TRANS_SUCC_BIT = (1 << 1);
|
||||
static const uint32_t END_TRANS_SUCC_BIT = (1 << 3);
|
||||
static const uint32_t START_STMT_SUCC_BIT = (1 << 5);
|
||||
static const uint32_t END_STMT_SUCC_BIT = (1 << 7);
|
||||
static const uint32_t START_PART_SUCC_BIT = (1 << 9);
|
||||
static const uint32_t END_PART_SUCC_BIT = (1 << 11);
|
||||
static const uint32_t START_TRANS_EXECUTED_SHIFT = 1;
|
||||
static const uint32_t END_TRANS_EXECUTED_SHIFT = 3;
|
||||
static const uint32_t START_STMT_EXECUTED_SHIFT = 5;
|
||||
static const uint32_t END_STMT_EXECUTED_SHIFT = 7;
|
||||
static const uint32_t START_PART_EXECUTED_SHIFT = 9;
|
||||
static const uint32_t END_PART_EXECUTED_SHIFT = 11;
|
||||
static const uint32_t END_TRANS_EXECUTED_SHIFT = 3;
|
||||
static const uint32_t START_STMT_EXECUTED_SHIFT = 5;
|
||||
static const uint32_t END_STMT_EXECUTED_SHIFT = 7;
|
||||
static const uint32_t START_PART_EXECUTED_SHIFT = 9;
|
||||
static const uint32_t END_PART_EXECUTED_SHIFT = 11;
|
||||
static const uint32_t START_TRANS_EXECUTED_MASK = (0xFFFFFFFF ^ (0x3 << 0));
|
||||
static const uint32_t END_TRANS_EXECUTED_MASK = (0xFFFFFFFF ^ (0x3 << 2));
|
||||
static const uint32_t START_STMT_EXECUTED_MASK = (0xFFFFFFFF ^ (0x3 << 4));
|
||||
static const uint32_t END_STMT_EXECUTED_MASK = (0xFFFFFFFF ^ (0x3 << 6));
|
||||
static const uint32_t START_PART_EXECUTED_MASK = (0xFFFFFFFF ^ (0x3 << 8));
|
||||
static const uint32_t END_PART_EXECUTED_MASK = (0xFFFFFFFF ^ (0x3 << 10));
|
||||
|
||||
static const uint32_t END_TRANS_EXECUTED_MASK = (0xFFFFFFFF ^ (0x3 << 2));
|
||||
static const uint32_t START_STMT_EXECUTED_MASK = (0xFFFFFFFF ^ (0x3 << 4));
|
||||
static const uint32_t END_STMT_EXECUTED_MASK = (0xFFFFFFFF ^ (0x3 << 6));
|
||||
static const uint32_t START_PART_EXECUTED_MASK = (0xFFFFFFFF ^ (0x3 << 8));
|
||||
static const uint32_t END_PART_EXECUTED_MASK = (0xFFFFFFFF ^ (0x3 << 10));
|
||||
public:
|
||||
TransState() : state_(0)
|
||||
{}
|
||||
~TransState()
|
||||
{}
|
||||
TransState() : state_(0) {}
|
||||
~TransState() {}
|
||||
void set_start_trans_executed(bool is_succ)
|
||||
{
|
||||
state_ = ((state_ | START_TRANS_EXECUTED_BIT) | (is_succ << START_TRANS_EXECUTED_SHIFT));
|
||||
}
|
||||
{ state_ = ((state_ | START_TRANS_EXECUTED_BIT) | (is_succ << START_TRANS_EXECUTED_SHIFT)); }
|
||||
void set_end_trans_executed(bool is_succ)
|
||||
{
|
||||
state_ = ((state_ | END_TRANS_EXECUTED_BIT) | (is_succ << END_TRANS_EXECUTED_SHIFT));
|
||||
}
|
||||
{ state_ = ((state_ | END_TRANS_EXECUTED_BIT) | (is_succ << END_TRANS_EXECUTED_SHIFT)); }
|
||||
void set_start_stmt_executed(bool is_succ)
|
||||
{
|
||||
state_ = ((state_ | START_STMT_EXECUTED_BIT) | (is_succ << START_STMT_EXECUTED_SHIFT));
|
||||
}
|
||||
{ state_ = ((state_ | START_STMT_EXECUTED_BIT) | (is_succ << START_STMT_EXECUTED_SHIFT)); }
|
||||
void set_end_stmt_executed(bool is_succ)
|
||||
{
|
||||
state_ = ((state_ | END_STMT_EXECUTED_BIT) | (is_succ << END_STMT_EXECUTED_SHIFT));
|
||||
}
|
||||
{ state_ = ((state_ | END_STMT_EXECUTED_BIT) | (is_succ << END_STMT_EXECUTED_SHIFT)); }
|
||||
void set_start_participant_executed(bool is_succ)
|
||||
{
|
||||
state_ = ((state_ | START_PART_EXECUTED_BIT) | (is_succ << START_PART_EXECUTED_SHIFT));
|
||||
}
|
||||
{ state_ = ((state_ | START_PART_EXECUTED_BIT) | (is_succ << START_PART_EXECUTED_SHIFT)); }
|
||||
void set_end_participant_executed(bool is_succ)
|
||||
{
|
||||
state_ = ((state_ | END_PART_EXECUTED_BIT) | (is_succ << END_PART_EXECUTED_SHIFT));
|
||||
}
|
||||
{ state_ = ((state_ | END_PART_EXECUTED_BIT) | (is_succ << END_PART_EXECUTED_SHIFT)); }
|
||||
|
||||
void clear_start_trans_executed()
|
||||
{
|
||||
state_ = (state_ & START_TRANS_EXECUTED_MASK);
|
||||
}
|
||||
{ state_ = (state_ & START_TRANS_EXECUTED_MASK); }
|
||||
void clear_start_stmt_executed()
|
||||
{
|
||||
state_ = (state_ & START_STMT_EXECUTED_MASK);
|
||||
}
|
||||
{ state_ = (state_ & START_STMT_EXECUTED_MASK); }
|
||||
void clear_start_participant_executed()
|
||||
{
|
||||
state_ = (state_ & START_PART_EXECUTED_MASK);
|
||||
}
|
||||
{ state_ = (state_ & START_PART_EXECUTED_MASK); }
|
||||
void clear_end_trans_executed()
|
||||
{
|
||||
state_ = (state_ & END_TRANS_EXECUTED_MASK);
|
||||
}
|
||||
{ state_ = (state_ & END_TRANS_EXECUTED_MASK); }
|
||||
void clear_end_stmt_executed()
|
||||
{
|
||||
state_ = (state_ & END_STMT_EXECUTED_MASK);
|
||||
}
|
||||
{ state_ = (state_ & END_STMT_EXECUTED_MASK); }
|
||||
void clear_end_participant_executed()
|
||||
{
|
||||
state_ = (state_ & END_PART_EXECUTED_MASK);
|
||||
}
|
||||
{ state_ = (state_ & END_PART_EXECUTED_MASK); }
|
||||
|
||||
bool is_start_trans_executed() const
|
||||
{
|
||||
return state_ & START_TRANS_EXECUTED_BIT;
|
||||
}
|
||||
{ return state_ & START_TRANS_EXECUTED_BIT; }
|
||||
bool is_end_trans_executed() const
|
||||
{
|
||||
return state_ & END_TRANS_EXECUTED_BIT;
|
||||
}
|
||||
{ return state_ & END_TRANS_EXECUTED_BIT; }
|
||||
bool is_start_stmt_executed() const
|
||||
{
|
||||
return state_ & START_STMT_EXECUTED_BIT;
|
||||
}
|
||||
{ return state_ & START_STMT_EXECUTED_BIT; }
|
||||
bool is_end_stmt_executed() const
|
||||
{
|
||||
return state_ & END_STMT_EXECUTED_BIT;
|
||||
}
|
||||
{ return state_ & END_STMT_EXECUTED_BIT; }
|
||||
bool is_start_participant_executed() const
|
||||
{
|
||||
return state_ & START_PART_EXECUTED_BIT;
|
||||
}
|
||||
{ return state_ & START_PART_EXECUTED_BIT; }
|
||||
bool is_end_participant_executed() const
|
||||
{
|
||||
return state_ & END_PART_EXECUTED_BIT;
|
||||
}
|
||||
{ return state_ & END_PART_EXECUTED_BIT; }
|
||||
bool is_start_trans_success() const
|
||||
{
|
||||
return state_ & START_TRANS_SUCC_BIT;
|
||||
}
|
||||
{ return state_ & START_TRANS_SUCC_BIT; }
|
||||
bool is_end_trans_success() const
|
||||
{
|
||||
return state_ & END_TRANS_SUCC_BIT;
|
||||
}
|
||||
{ return state_ & END_TRANS_SUCC_BIT; }
|
||||
bool is_start_stmt_success() const
|
||||
{
|
||||
return state_ & START_STMT_SUCC_BIT;
|
||||
}
|
||||
{ return state_ & START_STMT_SUCC_BIT; }
|
||||
bool is_end_stmt_success() const
|
||||
{
|
||||
return state_ & END_STMT_SUCC_BIT;
|
||||
}
|
||||
{ return state_ & END_STMT_SUCC_BIT; }
|
||||
bool is_start_participant_success() const
|
||||
{
|
||||
return state_ & START_PART_SUCC_BIT;
|
||||
}
|
||||
{ return state_ & START_PART_SUCC_BIT; }
|
||||
bool is_end_participant_success() const
|
||||
{
|
||||
return state_ & END_PART_SUCC_BIT;
|
||||
}
|
||||
{ return state_ & END_PART_SUCC_BIT; }
|
||||
|
||||
void reset()
|
||||
{
|
||||
state_ = 0;
|
||||
}
|
||||
|
||||
const common::ObPartitionArray& get_participants() const
|
||||
{
|
||||
return participants_;
|
||||
}
|
||||
common::ObPartitionArray& get_participants()
|
||||
{
|
||||
return participants_;
|
||||
}
|
||||
{ state_ = 0; }
|
||||
|
||||
private:
|
||||
uint32_t state_;
|
||||
// cached for start_stmt, start_participants, end_participants
|
||||
common::ObPartitionArray participants_;
|
||||
};
|
||||
|
||||
class ObConsistencyLevelAdaptor {
|
||||
/* 内部类,仅用于本文件。将SQL层的Consistency转化为事务层的Consistency。
|
||||
* 事务层对Consistency只有STRONg/WEAK的概念,没有FROZEN的概念。
|
||||
**/
|
||||
class ObConsistencyLevelAdaptor
|
||||
{
|
||||
public:
|
||||
explicit ObConsistencyLevelAdaptor(common::ObConsistencyLevel sql_consistency)
|
||||
{
|
||||
switch (sql_consistency) {
|
||||
explicit ObConsistencyLevelAdaptor(common::ObConsistencyLevel sql_consistency) {
|
||||
switch(sql_consistency) {
|
||||
case common::STRONG:
|
||||
trans_consistency_ = transaction::ObTransConsistencyLevel::STRONG;
|
||||
break;
|
||||
@ -210,149 +157,123 @@ public:
|
||||
trans_consistency_ = transaction::ObTransConsistencyLevel::UNKNOWN;
|
||||
}
|
||||
}
|
||||
int64_t get_consistency()
|
||||
{
|
||||
int64_t get_consistency() {
|
||||
return trans_consistency_;
|
||||
}
|
||||
|
||||
private:
|
||||
int64_t trans_consistency_;
|
||||
};
|
||||
|
||||
class ObSqlTransControl {
|
||||
class ObSqlTransControl
|
||||
{
|
||||
public:
|
||||
static int on_plan_start(ObExecContext& exec_ctx, bool is_remote = false);
|
||||
// static int on_plan_end(ObExecContext &exec_ctx, bool is_rollback, ObExclusiveEndTransCallback &callback);
|
||||
|
||||
static int explicit_start_trans(ObExecContext& exec_ctx, const bool read_only);
|
||||
static int explicit_start_trans(ObExecContext& exec_ctx, transaction::ObStartTransParam& start_trans_param);
|
||||
static int implicit_end_trans(ObExecContext& exec_ctx, const bool is_rollback, ObExclusiveEndTransCallback& callback);
|
||||
static int explicit_end_trans(ObExecContext& exec_ctx, const bool is_rollback);
|
||||
static int explicit_end_trans(ObExecContext& exec_ctx, const bool is_rollback, ObEndTransSyncCallback& callback);
|
||||
static int explicit_end_trans(ObExecContext& exec_ctx, const bool is_rollback, ObEndTransAsyncCallback& callback);
|
||||
|
||||
// call by OB_MYSQL_COM_CHANGE_USER, always to rollback the transaction if exists
|
||||
// call by ObSQLSessionMgr::SessionReclaimCallback::reclaim_value
|
||||
static int end_trans(
|
||||
storage::ObPartitionService* partition_service, ObSQLSessionInfo* session, bool& has_called_txs_end_trans);
|
||||
/** SQL layer transaction interface
|
||||
*
|
||||
* 1. Call background
|
||||
*
|
||||
* AutoCommit=1:
|
||||
*
|
||||
* Local:StartTrans,EndTrans in ObResultSet's Open,Close;
|
||||
* StartStmt,EndStmt,in ObResultSet's Open,Close;
|
||||
* StartParticipant,EndParticipant in ObResultSet's Open,Close
|
||||
* Remote:StartTrans,EndTrans in ObRpcTaskExecuteP's before_process,after_process;
|
||||
* StartStmt,EndStmt,in ObRpcTaskExecuteP's before_process,after_process;
|
||||
* StartParticipant,EndParticipant in ObRpcTaskExecuteP's before_process,after_process
|
||||
* Distribute:StartTrans,EndTrans in ObResultSet's Open,Close;
|
||||
* StartStmt,EndStmt,in ObResultSet's Open,Close;
|
||||
* StartParticipant,EndParticipant in ObResultSet's Open,Close,
|
||||
* and in ObRpcTaskExecuteP's before_process,after_process
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* 2. arguments
|
||||
*
|
||||
* ObTransDesc:ObExecContext->ObPhysicalPlanCtx, need to serialize it;
|
||||
* Participants:All Participant information should be recorded in TaskInfo
|
||||
* tenant_id:ObExecContext->ObSQLSessionInfo
|
||||
* Considering that there are multiple PhysicalPlans for multi-statement transactions,
|
||||
* but only one SessionInfo,
|
||||
* and each statement may be executed across computers.
|
||||
* Session does not have a corresponding data structure at the remote end.
|
||||
* Therefore, before each SQL statement is executed,
|
||||
* TransDesc must be taken from SessionInfo and the execution ends. After that,
|
||||
* TransDesc will write SessionInfo.
|
||||
*/
|
||||
static int start_trans(
|
||||
ObExecContext& exec_ctx, transaction::ObStartTransParam& start_trans_param, bool is_remote = false);
|
||||
|
||||
static int start_stmt(ObExecContext& ctx, const common::ObPartitionLeaderArray& pla, bool is_remote = false);
|
||||
|
||||
static int start_participant(
|
||||
ObExecContext& exec_ctx, const common::ObPartitionArray& participants, bool is_remote = false);
|
||||
|
||||
static int end_trans(
|
||||
ObExecContext& exec_ctx, const bool is_rollback, const bool is_explicit, ObExclusiveEndTransCallback& callback);
|
||||
static int kill_query_session(
|
||||
storage::ObPartitionService* ps, ObSQLSessionInfo& session, const ObSQLSessionState& status);
|
||||
static int kill_active_trx(storage::ObPartitionService* ps, ObSQLSessionInfo* session);
|
||||
static int end_stmt(ObExecContext& exec_ctx, const bool is_rollback);
|
||||
|
||||
static int end_participant(
|
||||
ObExecContext& exec_ctx, const bool is_rollback, const common::ObPartitionArray& participants);
|
||||
static int get_discard_participants(const common::ObPartitionArray& all_partitions,
|
||||
const common::ObPartitionArray& response_partitions, common::ObPartitionArray& discard_partitions);
|
||||
static int create_savepoint(ObExecContext& exec_ctx, const common::ObString& sp_name);
|
||||
static int rollback_savepoint(ObExecContext& exec_ctx, const common::ObString& sp_name);
|
||||
static int release_savepoint(ObExecContext& exec_ctx, const common::ObString& sp_name);
|
||||
static int xa_rollback_all_changes(ObExecContext& exec_ctx);
|
||||
static int start_cursor_stmt(ObExecContext& exec_ctx);
|
||||
|
||||
static int reset_session_tx_state(ObSQLSessionInfo *session, bool reuse_tx_desc = false);
|
||||
static int reset_session_tx_state(ObBasicSessionInfo *session, bool reuse_tx_desc = false);
|
||||
static int create_stash_savepoint(ObExecContext &exec_ctx, const ObString &name);
|
||||
static int explicit_start_trans(ObExecContext &exec_ctx, const bool read_only, const ObString hint = ObString());
|
||||
static int explicit_end_trans(ObExecContext &exec_ctx, const bool is_rollback, const ObString hint = ObString());
|
||||
static int implicit_end_trans(ObExecContext &exec_ctx,
|
||||
const bool is_rollback,
|
||||
ObEndTransAsyncCallback *callback = NULL);
|
||||
static int end_trans(ObExecContext &exec_ctx,
|
||||
const bool is_rollback,
|
||||
const bool is_explicit,
|
||||
ObEndTransAsyncCallback *callback = NULL);
|
||||
static int rollback_trans(ObSQLSessionInfo *session,
|
||||
bool &need_disconnect);
|
||||
static int do_end_trans_(ObSQLSessionInfo *session,
|
||||
const bool is_rollback,
|
||||
const bool is_explicit,
|
||||
const int64_t expire_ts,
|
||||
ObEndTransAsyncCallback *callback);
|
||||
static int start_stmt(ObExecContext &ctx);
|
||||
static int stmt_sanity_check_(ObSQLSessionInfo *session,
|
||||
const ObPhysicalPlan *plan,
|
||||
ObPhysicalPlanCtx *plan_ctx);
|
||||
static int stmt_setup_snapshot_(ObSQLSessionInfo *session,
|
||||
ObDASCtx &das_ctx,
|
||||
const ObPhysicalPlan *plan,
|
||||
const ObPhysicalPlanCtx *plan_ctx,
|
||||
transaction::ObTransService *txs);
|
||||
static int stmt_refresh_snapshot(ObExecContext &ctx);
|
||||
static int stmt_setup_savepoint_(ObSQLSessionInfo *session,
|
||||
ObDASCtx &das_ctx,
|
||||
ObPhysicalPlanCtx *plan_ctx,
|
||||
transaction::ObTransService* txs);
|
||||
static int end_stmt(ObExecContext &exec_ctx, const bool is_rollback);
|
||||
static int kill_query_session(ObSQLSessionInfo &session, const ObSQLSessionState &status);
|
||||
static int kill_tx(ObSQLSessionInfo *session, int cause);
|
||||
static int kill_idle_timeout_tx(ObSQLSessionInfo *session)
|
||||
{
|
||||
using namespace oceanbase::transaction;
|
||||
return kill_tx(session, OB_TRANS_IDLE_TIMEOUT);
|
||||
}
|
||||
static int kill_deadlock_tx(ObSQLSessionInfo *session)
|
||||
{
|
||||
using namespace oceanbase::transaction;
|
||||
return kill_tx(session, OB_DEAD_LOCK);
|
||||
}
|
||||
static int kill_tx_on_session_killed(ObSQLSessionInfo *session)
|
||||
{
|
||||
using namespace oceanbase::transaction;
|
||||
return kill_tx(session, OB_SESSION_KILLED);
|
||||
}
|
||||
static int kill_tx_on_session_disconnect(ObSQLSessionInfo *session)
|
||||
{
|
||||
using namespace oceanbase::transaction;
|
||||
return kill_tx(session, static_cast<int>(ObTxAbortCause::SESSION_DISCONNECT));
|
||||
}
|
||||
static int create_savepoint(ObExecContext &exec_ctx, const common::ObString &sp_name);
|
||||
static int rollback_savepoint(ObExecContext &exec_ctx, const common::ObString &sp_name);
|
||||
static int release_savepoint(ObExecContext &exec_ctx, const common::ObString &sp_name);
|
||||
static int xa_rollback_all_changes(ObExecContext &exec_ctx);
|
||||
public:
|
||||
static int get_participants(ObExecContext& exec_ctx, common::ObPartitionArray& participants);
|
||||
static int get_root_job_participants(
|
||||
ObExecContext& exec_ctx, const ObPhyOperator& root_job_root_op, common::ObPartitionArray& participants);
|
||||
static int get_root_job_participants(
|
||||
ObExecContext& exec_ctx, const ObOperator& root_job_root_op, common::ObPartitionArray& participants);
|
||||
static int get_single_participant(ObExecContext& exec_ctx, common::ObPartitionArray& participants);
|
||||
|
||||
static int get_participants(ObExecContext& exec_ctx, common::ObPartitionLeaderArray& pla);
|
||||
static int get_participants(const common::ObIArray<ObPhyTableLocation>& table_locations,
|
||||
common::ObPartitionLeaderArray& pla, bool is_retry_for_dup_tbl);
|
||||
static int append_participant_by_table_loc(
|
||||
common::ObPartitionIArray& participants, const ObPhyTableLocation& table_loc);
|
||||
static int append_participant_to_array_distinctly(
|
||||
common::ObPartitionIArray& participants, const common::ObPartitionKey& key);
|
||||
static int append_participant_to_array_distinctly(common::ObPartitionLeaderArray& pla,
|
||||
const common::ObPartitionKey& key, const common::ObPartitionType type, const common::ObAddr& svr);
|
||||
static bool is_weak_consistency_level(const common::ObConsistencyLevel& consistency_level);
|
||||
static int decide_trans_read_interface_specs(const char* module, const ObSQLSessionInfo& session,
|
||||
const stmt::StmtType& stmt_type, const stmt::StmtType& literal_stmt_type,
|
||||
const bool& is_contain_select_for_update, const bool& is_contain_inner_table,
|
||||
const common::ObConsistencyLevel& sql_consistency_level, const bool need_consistent_snapshot,
|
||||
int32_t& trans_consistency_level, int32_t& trans_consistency_type, int32_t& read_snapshot_type);
|
||||
|
||||
static int get_stmt_snapshot_info(ObExecContext& exec_ctx, const bool is_cursor, transaction::ObTransDesc& trans_desc,
|
||||
transaction::ObTransSnapInfo& snap_info);
|
||||
static int start_standalone_stmt(
|
||||
ObExecContext& exec_ctx, ObSQLSessionInfo& session_info, ObPhysicalPlanCtx& phy_plan_ctx, bool is_remote);
|
||||
static bool is_isolation_RR_or_SE(int32_t isolation);
|
||||
|
||||
static int decide_trans_read_interface_specs(
|
||||
const common::ObConsistencyLevel &sql_consistency_level,
|
||||
transaction::ObTxConsistencyType &trans_consistency_type);
|
||||
static bool is_isolation_RR_or_SE(transaction::ObTxIsolationLevel isolation);
|
||||
static int get_trans_result(ObExecContext &exec_ctx);
|
||||
static int get_trans_result(ObExecContext &exec_ctx, transaction::ObTxExecResult &trans_result);
|
||||
static int lock_table(ObExecContext &exec_ctx,
|
||||
const uint64_t table_id,
|
||||
const transaction::tablelock::ObTableLockMode lock_mode);
|
||||
static void clear_xa_branch(const transaction::ObXATransID &xid, transaction::ObTxDesc *&tx_desc);
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObSqlTransControl);
|
||||
/* functions */
|
||||
static int implicit_start_trans(ObExecContext& exec_ctx, bool is_remote = false);
|
||||
|
||||
inline static int get_trans_timeout_ts(const ObSQLSessionInfo& my_session, int64_t& trans_timeout_ts);
|
||||
inline static int get_stmt_timeout_ts(const ObSQLSessionInfo& my_session, int64_t& stmt_timeout_ts);
|
||||
inline static int64_t get_stmt_timeout_ts(const ObPhysicalPlanCtx& plan_ctx);
|
||||
static int inc_session_ref(const ObSQLSessionInfo* my_session);
|
||||
static int merge_stmt_partitions(ObExecContext& exec_ctx, ObSQLSessionInfo& session);
|
||||
static int set_trans_param_(ObSQLSessionInfo& my_session, const ObPhysicalPlan& phy_plan,
|
||||
const common::ObConsistencyLevel sql_consistency_level, int32_t& trans_consistency_level,
|
||||
int64_t& auto_spec_snapshot_version);
|
||||
static int specify_stmt_snapshot_version_for_slave_cluster_sql_(const ObSQLSessionInfo& session,
|
||||
const stmt::StmtType& literal_stmt_type, const bool& is_contain_inner_table, const int32_t consistency_type,
|
||||
const int32_t read_snapshot_type, int64_t& auto_spec_snapshot_version);
|
||||
static int trans_param_compat_with_cluster_before_2200_(transaction::ObTransDesc& trans_desc);
|
||||
static int get_pg_key_(
|
||||
const ObIArray<ObPhyTableLocation>& table_locations, const ObPartitionKey& pkey, ObPartitionKey& pg_key);
|
||||
static int change_pkeys_to_pgs_(
|
||||
const ObIArray<ObPhyTableLocation>& table_locations, const ObPartitionArray& pkeys, ObPartitionArray& pg_keys);
|
||||
static int change_pla_info_(const ObIArray<ObPhyTableLocation>& table_locations, const ObPartitionLeaderArray& pla,
|
||||
ObPartitionLeaderArray& out_pla);
|
||||
static bool check_fast_select_read_uncommited(
|
||||
transaction::ObTransDesc& trans_desc, const common::ObPartitionLeaderArray& pla);
|
||||
static int update_safe_weak_read_snapshot(
|
||||
bool is_bounded_staleness_read, ObSQLSessionInfo& session_info, int snapshot_type, int64_t snapshot_version);
|
||||
static int get_trans_expire_ts(const ObSQLSessionInfo &session,
|
||||
int64_t &trans_timeout_ts);
|
||||
static int64_t get_stmt_expire_ts(const ObPhysicalPlanCtx *plan_ctx,
|
||||
const ObSQLSessionInfo &session);
|
||||
static int inc_session_ref(const ObSQLSessionInfo *session);
|
||||
static int acquire_tx_if_need_(transaction::ObTransService *txs, ObSQLSessionInfo &session);
|
||||
public:
|
||||
/*
|
||||
* create a savepoint without name
|
||||
* it was extremely lighweight and fast
|
||||
*
|
||||
* capability:
|
||||
* only support inner stmt savepoint, and can not been used to cross stmt rollback
|
||||
*/
|
||||
static int create_anonymous_savepoint(ObExecContext &exec_ctx, int64_t &savepoint);
|
||||
static int create_anonymous_savepoint(transaction::ObTxDesc &tx_desc, int64_t &savepoint);
|
||||
/*
|
||||
* rollback to savepoint
|
||||
*
|
||||
* [convention]:
|
||||
* transaction layer use trans_result (which maintained by SQL-engine) to decide rollback participants
|
||||
* therefore if trans_result not been collected completed, trans_result.incomplete flag must be set
|
||||
* before do rollback.
|
||||
* and if trans_result was incomplete, SQL-engine should pass the participants to transaction layer
|
||||
* (the participants was calculated from table-locations inner this function)
|
||||
*
|
||||
* for example: the sql-task executed timeout and its result was unknown, and then do rollback_savepoint;
|
||||
* in this case, the trans_result was incomplete, the flag must been set.
|
||||
*/
|
||||
static int rollback_savepoint(ObExecContext &exec_ctx, const int64_t savepoint);
|
||||
};
|
||||
|
||||
inline int ObSqlTransControl::get_trans_timeout_ts(const ObSQLSessionInfo& my_session, int64_t& trans_timeout_ts)
|
||||
inline int ObSqlTransControl::get_trans_expire_ts(const ObSQLSessionInfo &my_session,
|
||||
int64_t &trans_timeout_ts)
|
||||
{
|
||||
int ret = common::OB_SUCCESS;
|
||||
int64_t tx_timeout = 0;
|
||||
@ -364,24 +285,25 @@ inline int ObSqlTransControl::get_trans_timeout_ts(const ObSQLSessionInfo& my_se
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline int ObSqlTransControl::get_stmt_timeout_ts(const ObSQLSessionInfo& my_session, int64_t& stmt_timeout_ts)
|
||||
inline int64_t ObSqlTransControl::get_stmt_expire_ts(const ObPhysicalPlanCtx *plan_ctx,
|
||||
const ObSQLSessionInfo &session)
|
||||
{
|
||||
// NOTE: this is QUERY's timeout setting(not TRANSACTION's timeout),
|
||||
// either from Hint 'query_timeout' or from session's query_timeout setting.
|
||||
if (OB_NOT_NULL(plan_ctx) && OB_NOT_NULL(plan_ctx->get_phy_plan())) {
|
||||
// if plan not null, it is a Query, otherwise it is a Command
|
||||
return plan_ctx->get_trans_timeout_timestamp();
|
||||
}
|
||||
int ret = common::OB_SUCCESS;
|
||||
int64_t query_timeout = 0;
|
||||
if (OB_FAIL(my_session.get_query_timeout(query_timeout))) {
|
||||
SQL_LOG(WARN, "fail to get query timeout", K(ret));
|
||||
} else {
|
||||
stmt_timeout_ts = my_session.get_query_start_time() + query_timeout;
|
||||
if (OB_FAIL(session.get_query_timeout(query_timeout))) {
|
||||
SQL_LOG(ERROR, "fail to get query timeout", K(ret));
|
||||
query_timeout = 1000 * 1000; // default timeout 1s
|
||||
}
|
||||
return ret;
|
||||
return session.get_query_start_time() + query_timeout;
|
||||
}
|
||||
|
||||
inline int64_t ObSqlTransControl::get_stmt_timeout_ts(const ObPhysicalPlanCtx& plan_ctx)
|
||||
{
|
||||
return plan_ctx.get_trans_timeout_timestamp();
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
}
|
||||
#endif /* OCEANBASE_SQL_TRANS_CONTROL_ */
|
||||
//// end of header file
|
||||
|
||||
Reference in New Issue
Block a user