fix "Unexpected old row update or delete a non exist index row"
This commit is contained in:
		@ -43,6 +43,7 @@ int ObMvccValueIterator::init(const ObIMvccCtx& ctx, const ObTransSnapInfo& snap
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  skip_compact_ = skip_compact;
 | 
			
		||||
  bool can_read_by_sql_no = false;
 | 
			
		||||
  reset();
 | 
			
		||||
  int64_t lock_for_read_start = ObClockGenerator::getClock();
 | 
			
		||||
  // snapshot version equal INT64_MAX is unexpected
 | 
			
		||||
@ -62,28 +63,32 @@ int ObMvccValueIterator::init(const ObIMvccCtx& ctx, const ObTransSnapInfo& snap
 | 
			
		||||
    value_ = value;
 | 
			
		||||
    is_inited_ = true;
 | 
			
		||||
    version_iter_ = value->get_list_head();
 | 
			
		||||
  } else if (read_by_sql_no(ctx, snapshot_info, const_cast<ObMvccRow*>(value), query_flag)) {
 | 
			
		||||
    ctx_ = &ctx;
 | 
			
		||||
    value_ = value;
 | 
			
		||||
    is_inited_ = true;
 | 
			
		||||
  } else if (OB_FAIL(read_by_sql_no(ctx, snapshot_info, const_cast<ObMvccRow*>(value), query_flag, can_read_by_sql_no))) {
 | 
			
		||||
    //do nothing
 | 
			
		||||
  } else {
 | 
			
		||||
    // read by snapshot
 | 
			
		||||
    ctx_ = &ctx;
 | 
			
		||||
    value_ = value;
 | 
			
		||||
    // not need lock_for_read when row is not locked
 | 
			
		||||
    if (value->row_lock_.is_locked() && OB_FAIL(value->lock_for_read(key, const_cast<ObIMvccCtx&>(ctx)))) {
 | 
			
		||||
      TRANS_LOG(WARN, "wait row lock fail", K(ret), K(ctx), KP(value), K(*value));
 | 
			
		||||
    } else if (OB_FAIL(find_start_pos(snapshot_info.get_snapshot_version()))) {
 | 
			
		||||
      TRANS_LOG(WARN, "fail to find start pos for iterator", K(ret));
 | 
			
		||||
    } else {
 | 
			
		||||
      if (GCONF.enable_sql_audit) {
 | 
			
		||||
        mark_trans_node(snapshot_info.get_snapshot_version(), query_flag.is_prewarm());
 | 
			
		||||
      }
 | 
			
		||||
      // set has_read_relocated_row flag true when reading relocated row
 | 
			
		||||
      if (value->is_has_relocated()) {
 | 
			
		||||
        const_cast<ObIMvccCtx*>(&ctx)->set_has_read_relocated_row();
 | 
			
		||||
      }
 | 
			
		||||
    if (can_read_by_sql_no) {
 | 
			
		||||
      ctx_ = &ctx;
 | 
			
		||||
      value_ = value;
 | 
			
		||||
      is_inited_ = true;
 | 
			
		||||
    } else {
 | 
			
		||||
      // read by snapshot
 | 
			
		||||
      ctx_ = &ctx;
 | 
			
		||||
      value_ = value;
 | 
			
		||||
      // not need lock_for_read when row is not locked
 | 
			
		||||
      if (value->row_lock_.is_locked() && OB_FAIL(value->lock_for_read(key, const_cast<ObIMvccCtx&>(ctx)))) {
 | 
			
		||||
        TRANS_LOG(WARN, "wait row lock fail", K(ret), K(ctx), KP(value), K(*value));
 | 
			
		||||
      } else if (OB_FAIL(find_start_pos(snapshot_info.get_snapshot_version()))) {
 | 
			
		||||
        TRANS_LOG(WARN, "fail to find start pos for iterator", K(ret));
 | 
			
		||||
      } else {
 | 
			
		||||
        if (GCONF.enable_sql_audit) {
 | 
			
		||||
          mark_trans_node(snapshot_info.get_snapshot_version(), query_flag.is_prewarm());
 | 
			
		||||
        }
 | 
			
		||||
        // set has_read_relocated_row flag true when reading relocated row
 | 
			
		||||
        if (value->is_has_relocated()) {
 | 
			
		||||
          const_cast<ObIMvccCtx*>(&ctx)->set_has_read_relocated_row();
 | 
			
		||||
        }
 | 
			
		||||
        is_inited_ = true;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // stat lock for read time
 | 
			
		||||
@ -273,11 +278,10 @@ void ObMvccValueIterator::move_to_next_node()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// check if read self transaction when fetch cursor
 | 
			
		||||
bool ObMvccValueIterator::read_by_sql_no(
 | 
			
		||||
    const ObIMvccCtx& ctx, const ObTransSnapInfo& snapshot_info, ObMvccRow* value, const ObQueryFlag& query_flag)
 | 
			
		||||
int ObMvccValueIterator::read_by_sql_no(
 | 
			
		||||
    const ObIMvccCtx& ctx, const ObTransSnapInfo& snapshot_info, ObMvccRow* value, const ObQueryFlag& query_flag, bool& can_read_by_sql_no)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  bool can_read_by_sql_no = false;
 | 
			
		||||
  bool is_locked = false;
 | 
			
		||||
 | 
			
		||||
  ObMvccTransNode* iter = value->get_list_head();
 | 
			
		||||
@ -343,7 +347,7 @@ bool ObMvccValueIterator::read_by_sql_no(
 | 
			
		||||
  if (is_locked) {
 | 
			
		||||
    value->latch_.unlock();
 | 
			
		||||
  }
 | 
			
		||||
  return can_read_by_sql_no;
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ObMvccValueIterator::reset()
 | 
			
		||||
 | 
			
		||||
@ -115,8 +115,8 @@ public:
 | 
			
		||||
  {
 | 
			
		||||
    return version_iter_;
 | 
			
		||||
  }
 | 
			
		||||
  bool read_by_sql_no(const ObIMvccCtx& ctx, const transaction::ObTransSnapInfo& snapshot_info, ObMvccRow* value,
 | 
			
		||||
      const ObQueryFlag& query_flag);
 | 
			
		||||
  int read_by_sql_no(const ObIMvccCtx& ctx, const transaction::ObTransSnapInfo& snapshot_info, ObMvccRow* value,
 | 
			
		||||
      const ObQueryFlag& query_flag, bool& can_read_by_sql_no);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
  int find_start_pos(const int64_t read_snapshot);
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user