diff --git a/src/observer/ob_service.cpp b/src/observer/ob_service.cpp index f4f191fe78..56dfd34341 100644 --- a/src/observer/ob_service.cpp +++ b/src/observer/ob_service.cpp @@ -3174,7 +3174,7 @@ int ObService::inner_fill_tablet_info_( ObLSHandle ls_handle; ObTabletHandle tablet_handle; int ret = OB_SUCCESS; - bool need_wait_major_convert_in_cs_replica = false; + bool need_wait_for_report = false; ObTablet *tablet = nullptr; if (OB_UNLIKELY(!inited_)) { ret = OB_NOT_INIT; @@ -3201,14 +3201,11 @@ int ObService::inner_fill_tablet_info_( } else if (OB_ISNULL(gctx_.config_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("gctx_.config_ is null", KR(ret), K(tenant_id), K(tablet_id)); - } else if (ls->is_cs_replica() && !tablet->get_tablet_meta().ha_status_.is_data_status_complete()) { + } else if (OB_FAIL(ObCSReplicaUtil::check_need_wait_for_report(*ls, *tablet, need_wait_for_report))) { + LOG_WARN("fail to check need wait report", K(ret), KPC(ls), KPC(tablet)); + } else if (need_wait_for_report) { ret = OB_EAGAIN; - LOG_WARN("tablet is not complete in cs replica now, need retry later", KR(ret), KPC(ls), KPC(tablet)); - } else if (OB_FAIL(ObCSReplicaUtil::check_need_wait_major_convert(*ls, tablet_id, *tablet, need_wait_major_convert_in_cs_replica))) { - LOG_WARN("fail to check need wait major convert in cs replica", K(ret), KPC(ls), KPC(tablet)); - } else if (need_wait_major_convert_in_cs_replica) { - ret = OB_EAGAIN; - LOG_WARN("need wait major convert for cs replica", K(ret), K(tablet_id)); + LOG_WARN("need wait report for cs replica", K(ret), K(tablet_id)); } else if (OB_FAIL(tablet->get_tablet_report_info( gctx_.self_addr(), tablet_replica, tablet_checksum, need_checksum))) { LOG_WARN("fail to get tablet report info from tablet", KR(ret), K(tenant_id), diff --git a/src/observer/report/ob_tablet_table_updater.cpp b/src/observer/report/ob_tablet_table_updater.cpp index 6f762fd3e2..ab39fef848 100644 --- a/src/observer/report/ob_tablet_table_updater.cpp +++ b/src/observer/report/ob_tablet_table_updater.cpp @@ -627,6 +627,8 @@ int ObTabletTableUpdater::generate_tasks_( bool is_remove_task = false; if (OB_TENANT_NOT_IN_SERVER != ret && OB_LS_NOT_EXIST != ret && OB_TABLET_NOT_EXIST != ret) { LOG_WARN("failed to fill tablet replica info", KR(ret), KPC(task)); + } else if (OB_EAGAIN == ret) { + ret = OB_SUCCESS; // do not affect report of other tablets } else if (OB_TENANT_NOT_IN_SERVER == ret) { is_remove_task = true; ret = OB_SUCCESS; diff --git a/src/observer/report/ob_tenant_meta_checker.cpp b/src/observer/report/ob_tenant_meta_checker.cpp index 2c43325641..7d2b9b5683 100644 --- a/src/observer/report/ob_tenant_meta_checker.cpp +++ b/src/observer/report/ob_tenant_meta_checker.cpp @@ -704,7 +704,11 @@ int ObTenantMetaChecker::check_report_replicas_( local_replica, tablet_checksum, need_checksum))) { - LOG_WARN("fail to fill tablet replica", KR(ret), K_(tenant_id), K(ls_id), K(tablet_id)); + if (OB_EAGAIN == ret) { + ret = OB_SUCCESS; // do not affect report of other tablets + } else { + LOG_WARN("fail to fill tablet replica", KR(ret), K_(tenant_id), K(ls_id), K(tablet_id)); + } } else if (table_replica.is_equal_for_report(local_replica)) { continue; } else { // not equal diff --git a/src/storage/column_store/ob_column_store_replica_util.cpp b/src/storage/column_store/ob_column_store_replica_util.cpp index d67ad8efb8..735c3954ab 100644 --- a/src/storage/column_store/ob_column_store_replica_util.cpp +++ b/src/storage/column_store/ob_column_store_replica_util.cpp @@ -97,67 +97,20 @@ int ObCSReplicaUtil::check_has_cs_replica( return ret; } -int ObCSReplicaUtil::check_need_process_cs_replica( +int ObCSReplicaUtil::check_need_generate_cs_replica_cg_array( const ObLS &ls, const ObTabletID &tablet_id, const ObStorageSchema &schema, - bool &need_process_cs_replica) + bool &need_generate_cs_replica_cg_array) { int ret = OB_SUCCESS; - need_process_cs_replica = ls.is_cs_replica() + need_generate_cs_replica_cg_array = ls.is_cs_replica() && tablet_id.is_user_tablet() && schema.is_row_store() && schema.is_user_data_table(); return ret; } -int ObCSReplicaUtil::check_need_wait_major_convert( - const ObLS &ls, - const ObTabletID &tablet_id, - const ObTablet &tablet, - bool &need_wait_major_convert) -{ - int ret = OB_SUCCESS; - bool need_process_cs_replica = tablet.is_cs_replica_compat(); - ObStorageSchema *storage_schema = nullptr; - ObArenaAllocator arena_allocator(common::ObMemAttr(MTL_ID(), "CkMjrCvrt")); - ObTabletMemberWrapper wrapper; - const ObTabletTableStore *table_store = nullptr; - const ObITable *sstable = nullptr; - need_wait_major_convert = false; - if (OB_FAIL(tablet.load_storage_schema(arena_allocator, storage_schema))) { - LOG_WARN("fail to load storage schema", K(ret), K(tablet)); - } else if (OB_ISNULL(storage_schema)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("storage schema is nullptr", K(ret), K(tablet)); - } else if (!need_process_cs_replica && OB_FAIL(check_need_process_cs_replica(ls, tablet_id, *storage_schema, need_process_cs_replica))) { - LOG_WARN("fail to check need process cs replica", K(ret), K(ls), K(tablet_id), KPC(storage_schema)); - } else if (need_process_cs_replica) { - if (tablet.is_row_store()) { - // tablet migration but not do co convert - need_wait_major_convert = true; - } else if (OB_FAIL(tablet.fetch_table_store(wrapper))) { - LOG_WARN("failed to fetch table store", K(ret), K(tablet_id), K(tablet)); - } else if (OB_ISNULL(table_store = wrapper.get_member())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("table store is nullptr", K(ret), K(tablet_id), K(tablet)); - } else if (OB_ISNULL(sstable = table_store->get_major_sstables().get_boundary_table(true /*is_last*/))) { - if (!tablet.get_tablet_meta().table_store_flag_.with_major_sstable()) { - ret = OB_SSTABLE_NOT_EXIST; - LOG_WARN("latest major is nullptr", K(ret), K(tablet_id), K(tablet)); - } - } else { - // ddl write row store major - need_wait_major_convert = ObITable::is_row_store_major_sstable(sstable->get_key().table_type_); - } - } - - if (ls.is_cs_replica()) { - LOG_INFO("[CS-Replica] Finish check need wait major convert", K(ret), K(tablet_id), K(need_process_cs_replica), K(need_wait_major_convert), K(ls), KPC(storage_schema), K(tablet), KPC(table_store), KPC(sstable)); - } - ObTabletObjLoadHelper::free(arena_allocator, storage_schema); - return ret; -} int ObCSReplicaUtil::check_need_process_for_cs_replica_for_ddl( const ObTablet &tablet, @@ -303,6 +256,122 @@ int ObCSReplicaUtil::check_need_process_cs_replica_for_offline_ddl( return ret; } +int ObCSReplicaUtil::check_need_wait_for_report( + const ObLS &ls, + const ObTablet &tablet, + bool &need_wait_for_report) +{ + int ret = OB_SUCCESS; + need_wait_for_report = false; + ObCSReplicaTabletStatus cs_replica_status = ObCSReplicaTabletStatus::MAX_STATUS; + if (!ls.is_cs_replica()) { + } else if (OB_FAIL(ObCSReplicaUtil::init_cs_replica_tablet_status(ls, tablet, cs_replica_status))) { + LOG_WARN("fail to init cs replica tablet status", K(ret), K(ls), K(tablet)); + } else if (OB_UNLIKELY(!is_valid_cs_replica_status(cs_replica_status))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("cs replica status is invalid", K(ret), K(ls), K(tablet)); + } else if (!is_normal_status(cs_replica_status)) { + need_wait_for_report = true; + LOG_INFO("tablet status is not normal, try report later", K(ret), K(cs_replica_status), K(ls), K(tablet)); + } + return ret; +} + +int ObCSReplicaUtil::init_cs_replica_tablet_status( + const ObLS &ls, + const ObTablet &tablet, + ObCSReplicaTabletStatus &cs_replica_status) +{ + int ret = OB_SUCCESS; + cs_replica_status = ObCSReplicaTabletStatus::MAX_STATUS; + if (!ls.is_cs_replica()) { + cs_replica_status = ObCSReplicaTabletStatus::NORMAL; + } else { + bool need_procss_cs_replica = false; + ObMigrationStatus migration_status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; + if (OB_FAIL(ObCSReplicaUtil::check_need_process_cs_replica(ls, tablet, need_procss_cs_replica))) { + LOG_WARN("fail to check need process cs replica", K(ret), K(ls), K(tablet)); + } else if (!need_procss_cs_replica) { + cs_replica_status = ObCSReplicaTabletStatus::NORMAL; + } else if (OB_FAIL(ls.get_ls_meta().get_migration_status(migration_status))) { + LOG_WARN("failed to get migration status", K(ret), K(ls)); + } else if (ObMigrationStatus::OB_MIGRATION_STATUS_NONE != migration_status) { + cs_replica_status = ObCSReplicaTabletStatus::NOT_COMPLETE; + } else if (tablet.get_last_major_snapshot_version() <= 0) { + cs_replica_status = ObCSReplicaTabletStatus::NO_MAJOR_SSTABLE; + } else { + ObStorageSchema *storage_schema = nullptr; + ObArenaAllocator arena_allocator(common::ObMemAttr(MTL_ID(), "IniTbltSts")); + ObTabletMemberWrapper wrapper; + const ObTabletTableStore *table_store = nullptr; + const ObITable *sstable = nullptr; + if (OB_FAIL(tablet.load_storage_schema(arena_allocator, storage_schema))) { + LOG_WARN("fail to load storage schema", K(ret), K(tablet)); + } else if (OB_ISNULL(storage_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("storage schema is nullptr", K(ret), K(tablet)); + } else if (tablet.is_row_store() != storage_schema->is_row_store()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet and storage schema mismatch", K(ret), K(tablet), K(storage_schema)); + } else if (OB_FAIL(tablet.fetch_table_store(wrapper))) { + LOG_WARN("failed to fetch table store", K(ret), K(tablet)); + } else if (OB_FAIL(wrapper.get_member(table_store))) { + LOG_WARN("fail to fetch table store", K(ret), K(wrapper)); + } else if (OB_ISNULL(sstable = table_store->get_major_sstables().get_boundary_table(true /*is_last*/))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sstable is nullptr", K(ret), KPC(table_store)); + } else if (tablet.is_row_store()) { + if (ObITable::is_row_store_major_sstable(sstable->get_key().table_type_)) { + cs_replica_status = ObCSReplicaTabletStatus::NEED_CO_CONVERT_MERGE; + } else { + cs_replica_status = ObCSReplicaTabletStatus::NEED_CS_STORAGE_SCHEMA; + } + } else { // column store + if (ObITable::is_row_store_major_sstable(sstable->get_key().table_type_)) { + cs_replica_status = ObCSReplicaTabletStatus::NEED_CO_CONVERT_MERGE; + } else { + cs_replica_status = ObCSReplicaTabletStatus::NORMAL; + } + } + ObTabletObjLoadHelper::free(arena_allocator, storage_schema); + LOG_INFO("[CS-Replica] Finish init cs replica tablet status", K(ret), K(ls), K(tablet), K(cs_replica_status), K(need_procss_cs_replica), KPC(sstable)); + } + } + + if (OB_FAIL(ret)) { + } else if (!is_valid_cs_replica_status(cs_replica_status)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid cs replica status", K(ret), K(cs_replica_status)); + } + + return ret; +} + +int ObCSReplicaUtil::check_need_process_cs_replica( + const ObLS &ls, + const ObTablet &tablet, + bool &need_process_cs_replica) +{ + int ret = OB_SUCCESS; + need_process_cs_replica = false; + if (tablet.is_cs_replica_compat()) { + need_process_cs_replica = true; + } else { + ObStorageSchema *storage_schema = nullptr; + ObArenaAllocator arena_allocator(common::ObMemAttr(MTL_ID(), "CheckCSRepl")); + if (OB_FAIL(tablet.load_storage_schema(arena_allocator, storage_schema))) { + LOG_WARN("fail to load storage schema", K(ret), K(tablet)); + } else if (OB_ISNULL(storage_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("storage schema is nullptr", K(ret), K(tablet)); + } else if (OB_FAIL(check_need_generate_cs_replica_cg_array(ls, tablet.get_tablet_id(), *storage_schema, need_process_cs_replica))) { + LOG_WARN("fail to check need process cs replica", K(ret), K(ls), K(tablet), KPC(storage_schema)); + } + ObTabletObjLoadHelper::free(arena_allocator, storage_schema); + } + return ret; +} + /*---------------------------------- ObCSReplicaStorageSchemaGuard -------------------------------- */ ObCSReplicaStorageSchemaGuard::ObCSReplicaStorageSchemaGuard() diff --git a/src/storage/column_store/ob_column_store_replica_util.h b/src/storage/column_store/ob_column_store_replica_util.h index 5f53f7b0d9..8a21ac6ed9 100644 --- a/src/storage/column_store/ob_column_store_replica_util.h +++ b/src/storage/column_store/ob_column_store_replica_util.h @@ -22,6 +22,42 @@ namespace oceanbase namespace storage { +enum class ObCSReplicaTabletStatus : uint8_t { + NORMAL = 0, // local ls is not cs replica (F/R) + // local ls is cs replica (C), but no need to be column store (like index or inner table) || valid schema and valid major in cs replica + NOT_COMPLETE = 1, // ha status not data complete, need wait transfer/migration/rebuild finish + NO_MAJOR_SSTABLE = 2, // offline ddl or direct load data not finish + NEED_CO_CONVERT_MERGE = 3, // lastest major is row store MAJOR + NEED_CS_STORAGE_SCHEMA = 4, // lastest major is column store CO_MAJOR but storage schema is row store. + MAX_STATUS +}; + +inline bool is_valid_cs_replica_status(const ObCSReplicaTabletStatus &status) +{ + return ObCSReplicaTabletStatus::NORMAL <= status && status < ObCSReplicaTabletStatus::MAX_STATUS; +} + +inline bool is_normal_status(const ObCSReplicaTabletStatus &status) +{ + return ObCSReplicaTabletStatus::NORMAL == status; +} + +inline bool is_need_wait_status(const ObCSReplicaTabletStatus &status) +{ + return ObCSReplicaTabletStatus::NOT_COMPLETE == status + || ObCSReplicaTabletStatus::NO_MAJOR_SSTABLE == status; +} + +inline bool is_need_major_convert_status(const ObCSReplicaTabletStatus &status) +{ + return ObCSReplicaTabletStatus::NEED_CO_CONVERT_MERGE == status; +} + +inline bool is_need_cs_storage_schema_status(const ObCSReplicaTabletStatus &status) +{ + return ObCSReplicaTabletStatus::NEED_CS_STORAGE_SCHEMA == status; +} + class ObCSReplicaUtil { public: @@ -42,16 +78,11 @@ public: const share::ObLSID &ls_id, bool &has_column_store_replica); // local ls need process column store replica for specific tablet - static int check_need_process_cs_replica( + static int check_need_generate_cs_replica_cg_array( const ObLS &ls, const ObTabletID &tablet_id, const ObStorageSchema &schema, - bool &need_process_cs_replica); - static int check_need_wait_major_convert( - const ObLS &ls, - const ObTabletID &tablet_id, - const ObTablet &tablet, - bool &need_wait_major_convert); + bool &need_generate_cs_replica_cg_array); // whole ls replica set need process column store replica for specific tablet static int check_need_process_for_cs_replica_for_ddl( const ObTablet &tablet, @@ -67,6 +98,18 @@ public: static int check_need_process_cs_replica_for_offline_ddl( const ObTableSchema &orig_table_schema, bool &need_process); + static int check_need_wait_for_report( + const ObLS &ls, + const ObTablet &tablet, + bool &need_wait_for_report); + static int init_cs_replica_tablet_status( + const ObLS &ls, + const ObTablet &tablet, + ObCSReplicaTabletStatus &cs_replica_status); + static int check_need_process_cs_replica( + const ObLS &ls, + const ObTablet &tablet, + bool &need_process_cs_replica); public: static const int64_t DEFAULT_CHECK_LS_REPLICA_LOCATION_TIMEOUT = 10 * 1000 * 1000L; // 10s }; diff --git a/src/storage/compaction/ob_schedule_tablet_func.cpp b/src/storage/compaction/ob_schedule_tablet_func.cpp index f0462ef945..7d7a4a56e3 100644 --- a/src/storage/compaction/ob_schedule_tablet_func.cpp +++ b/src/storage/compaction/ob_schedule_tablet_func.cpp @@ -194,7 +194,9 @@ int ObScheduleTabletFunc::schedule_tablet_execute( const ObTabletID &tablet_id = tablet.get_tablet_id(); bool can_merge = false; int64_t schedule_scn = 0; - if (OB_FAIL(get_schedule_execute_info(tablet, schedule_scn))) { + if (OB_FAIL(ObTenantTabletScheduler::check_ready_for_major_merge(ls_id, tablet, MEDIUM_MERGE))) { + LOG_WARN("failed to check ready for major merge", K(ret), K(ls_id), K(tablet_id)); + } else if (OB_FAIL(get_schedule_execute_info(tablet, schedule_scn))) { if (OB_NO_NEED_MERGE == ret) { ret = OB_SUCCESS; } else { diff --git a/src/storage/compaction/ob_tenant_tablet_scheduler.cpp b/src/storage/compaction/ob_tenant_tablet_scheduler.cpp index 233a7aabf6..2252f5f7c9 100644 --- a/src/storage/compaction/ob_tenant_tablet_scheduler.cpp +++ b/src/storage/compaction/ob_tenant_tablet_scheduler.cpp @@ -920,34 +920,48 @@ int ObTenantTabletScheduler::check_ready_for_major_merge( const ObMergeType merge_type) { int ret = OB_SUCCESS; - if (tablet.is_row_store() && (is_medium_merge(merge_type) || is_major_merge(merge_type))) { + if (is_medium_merge(merge_type) || is_major_merge(merge_type)) { + ObCSReplicaTabletStatus cs_replica_status = ObCSReplicaTabletStatus::MAX_STATUS; ObLSHandle ls_handle; ObLS *ls = nullptr; bool need_wait_major_convert = false; if (OB_FAIL(MTL(ObLSService*)->get_ls(ls_id, ls_handle, ObLSGetMod::HA_MOD))) { LOG_WARN("failed to get ls", K(ret), K(ls_id)); - } else if (OB_UNLIKELY(!ls_handle.is_valid()) || OB_ISNULL(ls = ls_handle.get_ls())) { + } else if (OB_UNLIKELY(!ls_handle.is_valid())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls is invalid or nullptr", K(ret), K(ls_id), K(ls_handle), KPC(ls)); + LOG_WARN("ls is invalid", K(ret), K(ls_id), K(ls_handle)); + } else if (FALSE_IT(ls = ls_handle.get_ls())) { } else if (!ls->is_cs_replica()) { - } else if (OB_FAIL(ObCSReplicaUtil::check_need_wait_major_convert(*ls, tablet.get_tablet_meta().tablet_id_, tablet, need_wait_major_convert))) { - LOG_WARN("fail to check need wait major convert in cs replica", K(ret), KPC(ls), K(tablet)); - } else if (need_wait_major_convert) { + } else if (OB_FAIL(ObCSReplicaUtil::init_cs_replica_tablet_status(*ls, tablet, cs_replica_status))) { + LOG_WARN("fail to init cs replica tablet status", K(ret), KPC(ls), K(tablet)); + } else if (OB_UNLIKELY(!is_valid_cs_replica_status(cs_replica_status))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("cs replica status is invalid", K(ret), KPC(ls), K(tablet)); + } else if (is_normal_status(cs_replica_status)) { + } else if (is_need_wait_status(cs_replica_status)) { ret = OB_EAGAIN; - LOG_WARN("need wait major convert in cs replica", K(ret), KPC(ls), K(tablet)); - // if ls migration finished, schedule convert co merge - ObMigrationStatus migration_status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; + LOG_WARN("tablet is not complete or no major", K(ret), K(cs_replica_status), K(tablet)); + } else if (is_need_major_convert_status(cs_replica_status)) { + ret = OB_EAGAIN; + LOG_WARN("need wait major convert in cs replica", K(ret), K(cs_replica_status), K(tablet)); int tmp_ret = OB_SUCCESS; - if (OB_TMP_FAIL(ls->get_ls_meta().get_migration_status(migration_status))) { - LOG_WARN("failed to get migration status", K(tmp_ret), KPC(ls)); - } else if (ObMigrationStatus::OB_MIGRATION_STATUS_NONE == migration_status) { - ObDagId co_dag_net_id; - int schedule_ret = OB_SUCCESS; - co_dag_net_id.init(GCTX.self_addr()); - if (OB_TMP_FAIL(schedule_convert_co_merge_dag_net(ls_id, tablet, 0 /*retry_times*/, co_dag_net_id, schedule_ret))) { - LOG_WARN("failed to schedule convert co merge for cs replica", K(tmp_ret), K(ls_id), K(tablet), K(schedule_ret)); - } + ObDagId co_dag_net_id; + int schedule_ret = OB_SUCCESS; + co_dag_net_id.init(GCTX.self_addr()); + if (OB_TMP_FAIL(schedule_convert_co_merge_dag_net(ls_id, tablet, 0 /*retry_times*/, co_dag_net_id, schedule_ret))) { + LOG_WARN("failed to schedule convert co merge for cs replica", K(tmp_ret), K(ls_id), K(tablet), K(schedule_ret)); } + } else if (is_need_cs_storage_schema_status(cs_replica_status)) { + ret = OB_EAGAIN; + LOG_WARN("need construct column store stroage schema", K(ret), K(cs_replica_status), K(tablet)); + int tmp_ret = OB_SUCCESS; + const ObTabletDataStatus::STATUS data_status = ObTabletDataStatus::COMPLETE; + if (OB_TMP_FAIL(ls->update_tablet_ha_data_status(tablet.get_tablet_id(), data_status))) { + LOG_WARN("failed to update tablet data status", K(tmp_ret), K(ls_id), K(tablet)); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected new cs replica tablet status", K(ret), K(cs_replica_status)); } } return ret; diff --git a/src/storage/high_availability/ob_storage_ha_tablet_builder.cpp b/src/storage/high_availability/ob_storage_ha_tablet_builder.cpp index 8f57605b63..d82033da30 100644 --- a/src/storage/high_availability/ob_storage_ha_tablet_builder.cpp +++ b/src/storage/high_availability/ob_storage_ha_tablet_builder.cpp @@ -2235,7 +2235,28 @@ int ObStorageHATabletBuilderUtil::build_tablet_with_major_tables( return ret; } - +/* + * There may be hybrid type of major sstable in column store replica. + * + * Time (evnet) F replica C Rreplica + * t1 (init) MAJOR_V0 + * t2 (compaction) MAJOR_V1 + * MAJOR_V0 + * t3 (migration) MAJOR_V1 CO_MAJOR_V1 + * MAJOR_V0 MAJOR_V0 + * t4 (compaction) MAJOR_V2 CO_MAJOR_V2 + * MAJOR_V1 CO_MAJOR_V1 + * MAJOR_V0 MAJOR_V0 + * t5 (compaction) MAJOR_V3 replay slow, network partition.. + * MAJOR_V2 CO_MAJOR_V2 + * MAJOR_V1 CO_MAJOR_V1 + * MAJOR_V0 MAJOR_V0 + * + * t6 (ls rebuild) MAJOR_V3 MAJOR_V3 + * MAJOR_V2 CO_MAJOR_V2 + * MAJOR_V1 CO_MAJOR_V1 + * MAJOR_V0 MAJOR_V0 + */ int ObStorageHATabletBuilderUtil::build_tablet_for_hybrid_store_( ObLS *ls, const common::ObTabletID &tablet_id, @@ -2245,12 +2266,11 @@ int ObStorageHATabletBuilderUtil::build_tablet_for_hybrid_store_( { // tablet with alter column group delayed with have major sstable in the front int ret = OB_SUCCESS; - ObTablesHandleArray major_tables; - ObTablesHandleArray co_major_tables; - major_tables.reset(); - co_major_tables.reset(); + ObTablesHandleArray row_store_major_tables; + ObTablesHandleArray column_store_major_tables; + row_store_major_tables.reset(); + column_store_major_tables.reset(); int64_t table_idx = 0; - bool is_co_major_tables_start = false; ObTableHandleV2 table_handle; int64_t last_snapshot_version = 0; int64_t cur_snapshot_version = 0; @@ -2262,26 +2282,47 @@ int ObStorageHATabletBuilderUtil::build_tablet_for_hybrid_store_( } else if (cur_snapshot_version < last_snapshot_version) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get snapshot version in reverse order", K(ret), K(last_snapshot_version), K(cur_snapshot_version)); - } else if (!table_handle.get_table()->is_column_store_sstable()) { - if (is_co_major_tables_start) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("get unsorted sstables in hybrid major tables", K(ret), K(table_idx), K(hybrid_major_tables)); - } else if (OB_FAIL(major_tables.add_table(table_handle))) { - LOG_WARN("failed to add major table", K(ret), K(table_handle)); + } else if (FALSE_IT(last_snapshot_version = cur_snapshot_version)) { + } else if (!table_handle.get_table()->is_column_store_sstable()) { // row store + if (!column_store_major_tables.empty()) { + if (OB_FAIL(ObStorageHATabletBuilderUtil::build_tablet_for_column_store_(ls, tablet_id, column_store_major_tables, storage_schema, extra_param))) { + LOG_WARN("failed to build tablet with co tables", K(ret), K(tablet_id), K(hybrid_major_tables), K(column_store_major_tables)); + } else { + column_store_major_tables.reset(); + } + } + if (FAILEDx(row_store_major_tables.add_table(table_handle))) { + LOG_WARN("failed to add row store major table", K(ret), K(table_handle)); + } + } else { // column store + if (!row_store_major_tables.empty()) { + if (OB_FAIL(ObStorageHATabletBuilderUtil::build_tablet_for_row_store_(ls, tablet_id, row_store_major_tables, storage_schema, extra_param))) { + LOG_WARN("failed to build tablet with co tables", K(ret), K(tablet_id), K(hybrid_major_tables), K(row_store_major_tables)); + } else { + row_store_major_tables.reset(); + } + } + if (FAILEDx(column_store_major_tables.add_table(table_handle))) { + LOG_WARN("failed to add row store major table", K(ret), K(table_handle)); } - } else if (OB_FAIL(co_major_tables.add_table(table_handle))) { - LOG_WARN("failed to add co major table", K(ret), K(table_handle)); - } else { - // column store sstables should exist at the back of array - is_co_major_tables_start = true; - last_snapshot_version = cur_snapshot_version; } } - if (FAILEDx(ObStorageHATabletBuilderUtil::build_tablet_for_row_store_(ls, tablet_id, major_tables, storage_schema, extra_param))) { - LOG_WARN("failed to build tablet with major tables", K(ret), K(tablet_id), K(hybrid_major_tables), K(major_tables)); - } else if (OB_FAIL(ObStorageHATabletBuilderUtil::build_tablet_for_column_store_(ls, tablet_id, co_major_tables, storage_schema, extra_param))) { - LOG_WARN("failed to build tablet with co tables", K(ret), K(tablet_id), K(hybrid_major_tables), K(co_major_tables)); + + if (OB_FAIL(ret)) { + } else if (row_store_major_tables.empty() && column_store_major_tables.empty()) { + } else if (!row_store_major_tables.empty() && !column_store_major_tables.empty()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("only one sstable array could have major tables", K(ret), K(row_store_major_tables), K(column_store_major_tables), K(hybrid_major_tables)); + } else if (!column_store_major_tables.empty()) { + if (OB_FAIL(ObStorageHATabletBuilderUtil::build_tablet_for_column_store_(ls, tablet_id, column_store_major_tables, storage_schema, extra_param))) { + LOG_WARN("failed to build tablet with co tables", K(ret), K(tablet_id), K(hybrid_major_tables), K(column_store_major_tables)); + } + } else { + if (OB_FAIL(ObStorageHATabletBuilderUtil::build_tablet_for_row_store_(ls, tablet_id, row_store_major_tables, storage_schema, extra_param))) { + LOG_WARN("failed to build tablet with co tables", K(ret), K(tablet_id), K(hybrid_major_tables), K(row_store_major_tables)); + } } + return ret; } @@ -2293,6 +2334,7 @@ int ObStorageHATabletBuilderUtil::build_tablet_with_major_tables( const BatchBuildTabletTablesExtraParam &extra_param) { int ret = OB_SUCCESS; + bool is_hybrid_store = false; if (OB_UNLIKELY(NULL == ls || !tablet_id.is_valid() || !storage_schema.is_valid())) { ret = OB_INVALID_ARGUMENT; @@ -2302,7 +2344,9 @@ int ObStorageHATabletBuilderUtil::build_tablet_with_major_tables( tablet_id, major_tables, storage_schema, extra_param))) { LOG_WARN("failed to build tablet with major tables", K(ret), K(tablet_id), KPC(ls)); } - } else if (OB_UNLIKELY(NULL == major_tables.get_table(0) || !major_tables.get_table(0)->is_column_store_sstable())) { + } else if (OB_FAIL(check_hybrid_store(storage_schema, major_tables, is_hybrid_store))) { + LOG_WARN("failed to check hybrid store", K(ret), K(storage_schema), K(major_tables)); + } else if (is_hybrid_store) { if (OB_FAIL(ObStorageHATabletBuilderUtil::build_tablet_for_hybrid_store_(ls, tablet_id, major_tables, storage_schema, extra_param))) { LOG_WARN("failed to built tablet with hybrid tables", K(ret), K(tablet_id), KPC(ls)); @@ -2810,6 +2854,31 @@ int ObStorageHATabletBuilderUtil::append_sstable_array_( return ret; } +int ObStorageHATabletBuilderUtil::check_hybrid_store( + const ObStorageSchema &storage_schema, + const ObTablesHandleArray &major_tables, + bool &is_hybrid_store) +{ + int ret = OB_SUCCESS; + is_hybrid_store = false; + if (storage_schema.is_row_store()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("storage schema is row store, should not check hybrid store", K(ret), K(storage_schema)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < major_tables.get_count(); ++i) { + const ObITable *table = major_tables.get_table(i); + if (OB_ISNULL(table) || !table->is_major_sstable()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid null major table", K(ret), K(i), KPC(table), K(major_tables)); + } else if (!table->is_column_store_sstable()) { + is_hybrid_store = true; + break; + } + } + } + return ret; +} + } } diff --git a/src/storage/high_availability/ob_storage_ha_tablet_builder.h b/src/storage/high_availability/ob_storage_ha_tablet_builder.h index 208b954d26..722ebbe21a 100644 --- a/src/storage/high_availability/ob_storage_ha_tablet_builder.h +++ b/src/storage/high_availability/ob_storage_ha_tablet_builder.h @@ -408,6 +408,11 @@ private: const ObTablesHandleArray &co_tables, const BatchBuildTabletTablesExtraParam &extra_batch_param); static int append_sstable_array_(ObTablesHandleArray &dest_array, const ObTablesHandleArray &src_array); + // only allow column store storage schema with row store major tables + static int check_hybrid_store( + const ObStorageSchema &storage_schema, + const ObTablesHandleArray &major_tables, + bool &is_hybrid_store); }; diff --git a/src/storage/tablet/ob_tablet.cpp b/src/storage/tablet/ob_tablet.cpp index 13cb09069c..b546421176 100644 --- a/src/storage/tablet/ob_tablet.cpp +++ b/src/storage/tablet/ob_tablet.cpp @@ -695,7 +695,7 @@ int ObTablet::init_with_migrate_param( ObTableHandleV2 mds_mini_sstable; const blocksstable::ObSSTable *sstable = nullptr; const bool need_compat = !tablet_id.is_ls_inner_tablet() && param.version_ < ObMigrationTabletParam::PARAM_VERSION_V3; - bool need_process_cs_replica = false; + bool need_generate_cs_replica_cg_array = false; if (is_transfer) { // do nothing } else if (!need_compat) { @@ -747,7 +747,7 @@ int ObTablet::init_with_migrate_param( // since transfer use storage schema from ls leader, need convert into cs storage schema in cs replica if (!is_transfer) { ALLOC_AND_INIT(allocator, storage_schema_addr_, param.storage_schema_); - } else if (OB_FAIL(inner_alloc_and_init_storage_schema(allocator, ls_id, tablet_id, param.storage_schema_, need_process_cs_replica))) { + } else if (OB_FAIL(inner_alloc_and_init_storage_schema(allocator, ls_id, tablet_id, param.storage_schema_, need_generate_cs_replica_cg_array))) { LOG_WARN("failed to int storage schema", K(ret), K(ls_id), K(tablet_id), K(param)); } } @@ -8613,24 +8613,24 @@ int ObTablet::inner_alloc_and_init_storage_schema( const share::ObLSID &ls_id, const ObTabletID &tablet_id, const ObStorageSchema &input_storage_schema, - bool &need_process_cs_replica) + bool &need_generate_cs_replica_cg_array) { int ret = OB_SUCCESS; ObLSHandle ls_handle; ObLS *ls = nullptr; - need_process_cs_replica = false; + need_generate_cs_replica_cg_array = false; if (OB_FAIL(MTL(ObLSService*)->get_ls(ls_id, ls_handle, ObLSGetMod::HA_MOD))) { LOG_WARN("failed to get ls", K(ret), K(ls_id)); } else if (OB_UNLIKELY(!ls_handle.is_valid()) || OB_ISNULL(ls = ls_handle.get_ls())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ls is invalid or nullptr", K(ret), K(ls_id), K(ls_handle), KPC(ls)); - } else if (OB_FAIL(ObCSReplicaUtil::check_need_process_cs_replica(*ls, tablet_id, input_storage_schema, need_process_cs_replica))) { + } else if (OB_FAIL(ObCSReplicaUtil::check_need_generate_cs_replica_cg_array(*ls, tablet_id, input_storage_schema, need_generate_cs_replica_cg_array))) { LOG_WARN("failed to check need process cs replica", K(ret), K(ls_id), K(tablet_id), K(input_storage_schema)); } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, storage_schema_addr_.ptr_))) { LOG_WARN("fail to alloc and new storage schema", K(ret)); } else if (OB_FAIL(storage_schema_addr_.get_ptr()->init(allocator, input_storage_schema, - false /*skip_column_info*/, nullptr /*column_group_schema*/, need_process_cs_replica))) { - LOG_WARN("fail to init storage schema", K(ret), K(input_storage_schema), K(need_process_cs_replica)); + false /*skip_column_info*/, nullptr /*column_group_schema*/, need_generate_cs_replica_cg_array))) { + LOG_WARN("fail to init storage schema", K(ret), K(input_storage_schema), K(need_generate_cs_replica_cg_array)); } return ret; } diff --git a/src/storage/tablet/ob_tablet.h b/src/storage/tablet/ob_tablet.h index bff512ffc4..5ff2eef41a 100644 --- a/src/storage/tablet/ob_tablet.h +++ b/src/storage/tablet/ob_tablet.h @@ -469,7 +469,7 @@ public: const share::ObLSID &ls_id, const ObTabletID &tablet_id, const ObStorageSchema &input_storage_schema, - bool &need_process_cs_replica); + bool &need_generate_cs_replica_cg_array); int get_ddl_kv_mgr(ObDDLKvMgrHandle &ddl_kv_mgr_handle, bool try_create = false); int set_ddl_kv_mgr(const ObDDLKvMgrHandle &ddl_kv_mgr_handle); int remove_ddl_kv_mgr(const ObDDLKvMgrHandle &ddl_kv_mgr_handle);