[FIX] use ls clog checkpoint to recycle tx data
This commit is contained in:
		@ -5507,11 +5507,13 @@ int ObLSTabletService::get_ls_min_end_scn(
 | 
				
			|||||||
  } else if (OB_FAIL(tablet_id_set_.foreach(op))) {
 | 
					  } else if (OB_FAIL(tablet_id_set_.foreach(op))) {
 | 
				
			||||||
    STORAGE_LOG(WARN, "fail to get all tablet ids from set", K(ret));
 | 
					    STORAGE_LOG(WARN, "fail to get all tablet ids from set", K(ret));
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
 | 
					    SCN ls_checkpoint = ls_->get_clog_checkpoint_scn();
 | 
				
			||||||
    for (int64_t i = 0; OB_SUCC(ret) && i < tablet_ids.count(); ++i) {
 | 
					    for (int64_t i = 0; OB_SUCC(ret) && i < tablet_ids.count(); ++i) {
 | 
				
			||||||
      ObTabletMapKey key(ls_id, tablet_ids.at(i));
 | 
					      ObTabletMapKey key(ls_id, tablet_ids.at(i));
 | 
				
			||||||
      SCN min_end_scn_from_latest = SCN::max_scn();
 | 
					      SCN min_end_scn_from_latest = SCN::max_scn();
 | 
				
			||||||
      SCN min_end_scn_from_old = SCN::max_scn();
 | 
					      SCN min_end_scn_from_old = SCN::max_scn();
 | 
				
			||||||
      if (OB_FAIL(t3m->get_min_end_scn_for_ls(key,
 | 
					      if (OB_FAIL(t3m->get_min_end_scn_for_ls(key,
 | 
				
			||||||
 | 
					                                              ls_checkpoint,
 | 
				
			||||||
                                              min_end_scn_from_latest,
 | 
					                                              min_end_scn_from_latest,
 | 
				
			||||||
                                              min_end_scn_from_old))) {
 | 
					                                              min_end_scn_from_old))) {
 | 
				
			||||||
        if (OB_ENTRY_NOT_EXIST != ret) {
 | 
					        if (OB_ENTRY_NOT_EXIST != ret) {
 | 
				
			||||||
@ -5520,11 +5522,19 @@ int ObLSTabletService::get_ls_min_end_scn(
 | 
				
			|||||||
          ret = OB_SUCCESS;
 | 
					          ret = OB_SUCCESS;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        min_end_scn_from_latest_tablets = MIN(min_end_scn_from_latest_tablets, min_end_scn_from_latest);
 | 
					        if (min_end_scn_from_latest < min_end_scn_from_latest_tablets) {
 | 
				
			||||||
        min_end_scn_from_old_tablets = MIN(min_end_scn_from_old_tablets, min_end_scn_from_old);
 | 
					          LOG_DEBUG("update", K(key), K(min_end_scn_from_latest_tablets), K(min_end_scn_from_latest));
 | 
				
			||||||
 | 
					          min_end_scn_from_latest_tablets = min_end_scn_from_latest;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (min_end_scn_from_old < min_end_scn_from_old_tablets) {
 | 
				
			||||||
 | 
					          LOG_DEBUG("update", K(key), K(min_end_scn_from_old_tablets), K(min_end_scn_from_old));
 | 
				
			||||||
 | 
					          min_end_scn_from_old_tablets = min_end_scn_from_old;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    LOG_INFO("get ls min end scn finish", K(ls_checkpoint));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  return ret;
 | 
					  return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -794,6 +794,7 @@ void *ObTenantMetaMemMgr::recycle_tablet(ObTablet *tablet, TabletBufferList *hea
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int ObTenantMetaMemMgr::get_min_end_scn_for_ls(
 | 
					int ObTenantMetaMemMgr::get_min_end_scn_for_ls(
 | 
				
			||||||
    const ObTabletMapKey &key,
 | 
					    const ObTabletMapKey &key,
 | 
				
			||||||
 | 
					    const SCN &ls_checkpoint,
 | 
				
			||||||
    SCN &min_end_scn_from_latest,
 | 
					    SCN &min_end_scn_from_latest,
 | 
				
			||||||
    SCN &min_end_scn_from_old)
 | 
					    SCN &min_end_scn_from_old)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -814,7 +815,7 @@ int ObTenantMetaMemMgr::get_min_end_scn_for_ls(
 | 
				
			|||||||
    ret = OB_ERR_UNEXPECTED;
 | 
					    ret = OB_ERR_UNEXPECTED;
 | 
				
			||||||
    LOG_WARN("unexpected invalid tablet handle", K(ret), K(key), K(handle));
 | 
					    LOG_WARN("unexpected invalid tablet handle", K(ret), K(key), K(handle));
 | 
				
			||||||
  } else if (OB_FAIL(get_min_end_scn_from_single_tablet(
 | 
					  } else if (OB_FAIL(get_min_end_scn_from_single_tablet(
 | 
				
			||||||
      handle.get_obj(), false/*is_old*/, min_end_scn_from_latest))) {
 | 
					      handle.get_obj(), false/*is_old*/, ls_checkpoint, min_end_scn_from_latest))) {
 | 
				
			||||||
    LOG_WARN("fail to get min end scn from latest tablet", K(ret), K(key), K(handle));
 | 
					    LOG_WARN("fail to get min end scn from latest tablet", K(ret), K(key), K(handle));
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    // get_ls_min_end_scn_in_latest_tablets must before get_ls_min_end_scn_in_old_tablets
 | 
					    // get_ls_min_end_scn_in_latest_tablets must before get_ls_min_end_scn_in_old_tablets
 | 
				
			||||||
@ -829,7 +830,7 @@ int ObTenantMetaMemMgr::get_min_end_scn_for_ls(
 | 
				
			|||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      // since the last tablet may not be the oldest, we traverse the wholo chain
 | 
					      // since the last tablet may not be the oldest, we traverse the wholo chain
 | 
				
			||||||
      while (OB_SUCC(ret) && OB_NOT_NULL(tablet)) {
 | 
					      while (OB_SUCC(ret) && OB_NOT_NULL(tablet)) {
 | 
				
			||||||
        if (OB_FAIL(get_min_end_scn_from_single_tablet(tablet, true/*is_old*/, min_end_scn_from_old))) {
 | 
					        if (OB_FAIL(get_min_end_scn_from_single_tablet(tablet, true/*is_old*/, ls_checkpoint, min_end_scn_from_old))) {
 | 
				
			||||||
          LOG_WARN("fail to get min end scn from old tablet", K(ret), KP(tablet));
 | 
					          LOG_WARN("fail to get min end scn from old tablet", K(ret), KP(tablet));
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
          tablet = tablet->get_next_tablet();
 | 
					          tablet = tablet->get_next_tablet();
 | 
				
			||||||
@ -840,8 +841,10 @@ int ObTenantMetaMemMgr::get_min_end_scn_for_ls(
 | 
				
			|||||||
  return ret;
 | 
					  return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int ObTenantMetaMemMgr::get_min_end_scn_from_single_tablet(
 | 
					int ObTenantMetaMemMgr::get_min_end_scn_from_single_tablet(ObTablet *tablet,
 | 
				
			||||||
    ObTablet *tablet, const bool is_old, SCN &min_end_scn)
 | 
					                                                           const bool is_old,
 | 
				
			||||||
 | 
					                                                           const SCN &ls_checkpoint,
 | 
				
			||||||
 | 
					                                                           SCN &min_end_scn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int ret = OB_SUCCESS;
 | 
					  int ret = OB_SUCCESS;
 | 
				
			||||||
  ObTabletMemberWrapper<ObTabletTableStore> table_store_wrapper;
 | 
					  ObTabletMemberWrapper<ObTabletTableStore> table_store_wrapper;
 | 
				
			||||||
@ -853,25 +856,24 @@ int ObTenantMetaMemMgr::get_min_end_scn_from_single_tablet(
 | 
				
			|||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    ObITable *first_minor_mini_sstable =
 | 
					    ObITable *first_minor_mini_sstable =
 | 
				
			||||||
        table_store_wrapper.get_member()->get_minor_sstables().get_boundary_table(false /*is_last*/);
 | 
					        table_store_wrapper.get_member()->get_minor_sstables().get_boundary_table(false /*is_last*/);
 | 
				
			||||||
    ObITable *last_major_sstable = nullptr;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SCN end_scn = SCN::max_scn();
 | 
					    SCN end_scn = SCN::max_scn();
 | 
				
			||||||
    if (OB_NOT_NULL(first_minor_mini_sstable)) {
 | 
					    if (OB_NOT_NULL(first_minor_mini_sstable)) {
 | 
				
			||||||
      // step 1 : get end_scn if minor/mini sstable exist
 | 
					      // step 1 : get end_scn if minor/mini sstable exist
 | 
				
			||||||
      end_scn = first_minor_mini_sstable->get_end_scn();
 | 
					      end_scn = first_minor_mini_sstable->get_end_scn();
 | 
				
			||||||
    } else if (is_old) {
 | 
					    } else if (is_old) {
 | 
				
			||||||
 | 
					      // step 2 :
 | 
				
			||||||
      /* If an old tablet has no minor sstable, it means that all the data inside it has been assigned version numbers,
 | 
					      /* If an old tablet has no minor sstable, it means that all the data inside it has been assigned version numbers,
 | 
				
			||||||
         and therefore it does not depend on trx data.
 | 
					         and therefore it does not depend on trx data.
 | 
				
			||||||
         Thus, it's only necessary to focus on the recycle scn provided by the latest tablet. */
 | 
					         Thus, it's only necessary to focus on the recycle scn provided by the latest tablet. */
 | 
				
			||||||
    } else if (OB_NOT_NULL(last_major_sstable =
 | 
					 | 
				
			||||||
        table_store_wrapper.get_member()->get_major_sstables().get_boundary_table(true /*is_last*/))) {
 | 
					 | 
				
			||||||
      // step 2 : if minor/mini sstable do not exist, get end_scn from major sstable
 | 
					 | 
				
			||||||
      end_scn = last_major_sstable->get_end_scn();
 | 
					 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      // step 3 : if minor/major sstable do not exist, get end_scn from tablet clog_checkpoint
 | 
					      // step 3 : if minor sstable do not exist, us max{tablet_clog_checkpoint, ls_clog_checkpoint} as end_scn
 | 
				
			||||||
      end_scn = tablet->get_tablet_meta().clog_checkpoint_scn_;
 | 
					      end_scn = SCN::max(tablet->get_tablet_meta().clog_checkpoint_scn_, ls_checkpoint);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (end_scn < min_end_scn) {
 | 
				
			||||||
 | 
					      min_end_scn = end_scn;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    min_end_scn = MIN(end_scn, min_end_scn);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return ret;
 | 
					  return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -186,6 +186,7 @@ public:
 | 
				
			|||||||
  //  - only for tx data table to find min log ts.
 | 
					  //  - only for tx data table to find min log ts.
 | 
				
			||||||
  int get_min_end_scn_for_ls(
 | 
					  int get_min_end_scn_for_ls(
 | 
				
			||||||
      const ObTabletMapKey &key,
 | 
					      const ObTabletMapKey &key,
 | 
				
			||||||
 | 
					      const SCN &ls_checkpoint,
 | 
				
			||||||
      share::SCN &min_end_scn_from_latest,
 | 
					      share::SCN &min_end_scn_from_latest,
 | 
				
			||||||
      share::SCN &min_end_scn_from_old);
 | 
					      share::SCN &min_end_scn_from_old);
 | 
				
			||||||
  int get_min_mds_ckpt_scn(const ObTabletMapKey &key, share::SCN &scn);
 | 
					  int get_min_mds_ckpt_scn(const ObTabletMapKey &key, share::SCN &scn);
 | 
				
			||||||
@ -282,8 +283,11 @@ private:
 | 
				
			|||||||
  int64_t cal_adaptive_bucket_num();
 | 
					  int64_t cal_adaptive_bucket_num();
 | 
				
			||||||
  int push_tablet_into_gc_queue(ObTablet *tablet);
 | 
					  int push_tablet_into_gc_queue(ObTablet *tablet);
 | 
				
			||||||
  void push_tablet_list_into_gc_queue(ObTablet *tablet);
 | 
					  void push_tablet_list_into_gc_queue(ObTablet *tablet);
 | 
				
			||||||
  int get_min_end_scn_from_single_tablet(
 | 
					  int get_min_end_scn_from_single_tablet(ObTablet *tablet,
 | 
				
			||||||
      ObTablet *tablet, const bool is_old, share::SCN &min_end_scn);
 | 
					                                         const bool is_old,
 | 
				
			||||||
 | 
					                                         const SCN &ls_checkpoint,
 | 
				
			||||||
 | 
					                                         share::SCN &min_end_scn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  typedef ObResourceValueStore<ObMetaPointer<ObTablet>> TabletValueStore;
 | 
					  typedef ObResourceValueStore<ObMetaPointer<ObTablet>> TabletValueStore;
 | 
				
			||||||
  typedef ObMetaObjBuffer<ObTablet, NORMAL_TABLET_POOL_SIZE> ObNormalTabletBuffer;
 | 
					  typedef ObMetaObjBuffer<ObTablet, NORMAL_TABLET_POOL_SIZE> ObNormalTabletBuffer;
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user