[CP] fix build multiple hybrid table store

This commit is contained in:
Tsunaou 2024-10-12 05:14:23 +00:00 committed by ob-robot
parent fdbf373821
commit ceedc31a99
11 changed files with 321 additions and 116 deletions

View File

@ -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),

View File

@ -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;

View File

@ -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

View File

@ -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<ObTabletTableStore> 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<ObTabletTableStore> 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()

View File

@ -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
};

View File

@ -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 {

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -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);
};

View File

@ -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;
}

View File

@ -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);