Skip to content

Commit cc40ae3

Browse files
committed
[feat](cloud) Support Cloud partition inverted format rollout
### What problem does this PR solve? Issue Number: None Related PR: None Problem Summary: Cloud tables previously had a single table-level inverted-index storage format. That made V2-to-V3 upgrades all-or-nothing: updating the default could not preserve the format selected when existing partitions and their tablet metadata were created. This change adds the Cloud-only partition.inverted_index_storage_format table property. It controls the format for subsequently created partitions, while each existing partition retains its resolved V2 or V3 format. The resolved value is durable in partition metadata and is carried through journal replay, recycle/recover, truncate, insert overwrite, and schema-change paths. Tablet and rowset metadata record the physical format separately so mixed-format partitions remain distinguishable during a rolling upgrade. Partition inspection commands read the value from FE partition metadata. ### Release note Cloud OLAP tables can roll out inverted-index storage formats by partition. New partitions can use V3 while existing V2 partitions remain online and queryable. ### Check List (For Author) - Test: Regression test / Unit Test - FE unit tests covering partition properties, persistence, recycle/recover, and Cloud schema-change handling - BE unit tests covering rowset and tablet metadata serialization - Cloud regression test: test_partition_cloud_inverted_index_storage_format_meta_write_switch - Behavior changed: Yes. Cloud tables accept partition.inverted_index_storage_format for new partitions and expose the resolved format in partition metadata commands. - Does this need documentation: No
1 parent 30a699a commit cc40ae3

54 files changed

Lines changed: 2510 additions & 41 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

be/src/cloud/cloud_rowset_writer.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,14 @@ Status CloudRowsetWriter::init(const RowsetWriterContext& rowset_writer_context)
7373
DCHECK_NE(_context.newest_write_timestamp, -1);
7474
_rowset_meta->set_newest_write_timestamp(_context.newest_write_timestamp);
7575
}
76-
_rowset_meta->set_tablet_schema(_context.tablet_schema);
76+
auto schema = _context.tablet_schema->need_record_variant_extended_schema()
77+
? _context.tablet_schema
78+
: _context.tablet_schema->copy_without_variant_extracted_columns();
79+
_rowset_meta->set_tablet_schema(schema);
80+
if (_context.persist_inverted_index_storage_format &&
81+
_context.inverted_index_storage_format.has_value()) {
82+
_rowset_meta->set_inverted_index_storage_format(*_context.inverted_index_storage_format);
83+
}
7784
_rowset_meta->set_job_id(_context.job_id);
7885
_context.segment_collector = std::make_shared<SegmentCollectorT<BaseBetaRowsetWriter>>(this);
7986
_context.file_writer_creator = std::make_shared<FileWriterCreatorT<BaseBetaRowsetWriter>>(this);

be/src/cloud/cloud_tablet.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,9 @@ Result<std::unique_ptr<RowsetWriter>> CloudTablet::create_rowset_writer(
839839
context.partition_id = partition_id();
840840
context.enable_unique_key_merge_on_write = enable_unique_key_merge_on_write();
841841
context.encrypt_algorithm = tablet_meta()->encryption_algorithm();
842+
context.inverted_index_storage_format = tablet_meta()->inverted_index_storage_format();
843+
context.persist_inverted_index_storage_format =
844+
tablet_meta()->has_inverted_index_storage_format();
842845
return RowsetFactory::create_rowset_writer(_engine, context, vertical);
843846
}
844847

@@ -881,6 +884,9 @@ Result<std::unique_ptr<RowsetWriter>> CloudTablet::create_transient_rowset_write
881884
context.enable_unique_key_merge_on_write = enable_unique_key_merge_on_write();
882885
context.txn_expiration = txn_expiration;
883886
context.encrypt_algorithm = tablet_meta()->encryption_algorithm();
887+
context.inverted_index_storage_format = tablet_meta()->inverted_index_storage_format();
888+
context.persist_inverted_index_storage_format =
889+
tablet_meta()->has_inverted_index_storage_format();
884890
// TODO(liaoxin) enable packed file for transient rowset
885891
context.allow_packed_file = false;
886892

be/src/cloud/pb_convert.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ void doris_rowset_meta_to_cloud(RowsetMetaCloudPB* out, const RowsetMetaPB& in)
108108
if (in.has_reference_instance_id()) {
109109
out->set_reference_instance_id(in.reference_instance_id());
110110
}
111+
if (in.has_inverted_index_storage_format()) {
112+
out->set_inverted_index_storage_format(in.inverted_index_storage_format());
113+
}
111114
auto* slice_locations = out->mutable_packed_slice_locations();
112115
slice_locations->clear();
113116
slice_locations->insert(in.packed_slice_locations().begin(), in.packed_slice_locations().end());
@@ -204,6 +207,9 @@ void doris_rowset_meta_to_cloud(RowsetMetaCloudPB* out, RowsetMetaPB&& in) {
204207
if (in.has_reference_instance_id()) {
205208
out->set_reference_instance_id(in.reference_instance_id());
206209
}
210+
if (in.has_inverted_index_storage_format()) {
211+
out->set_inverted_index_storage_format(in.inverted_index_storage_format());
212+
}
207213
auto* slice_locations = out->mutable_packed_slice_locations();
208214
slice_locations->clear();
209215
slice_locations->insert(in.packed_slice_locations().begin(), in.packed_slice_locations().end());
@@ -304,6 +310,9 @@ void cloud_rowset_meta_to_doris(RowsetMetaPB* out, const RowsetMetaCloudPB& in)
304310
if (in.has___split_schema()) {
305311
out->mutable___split_schema()->CopyFrom(in.__split_schema());
306312
}
313+
if (in.has_inverted_index_storage_format()) {
314+
out->set_inverted_index_storage_format(in.inverted_index_storage_format());
315+
}
307316
if (in.has_visible_ts_ms()) {
308317
out->set_visible_ts_ms(in.visible_ts_ms());
309318
}
@@ -399,6 +408,9 @@ void cloud_rowset_meta_to_doris(RowsetMetaPB* out, RowsetMetaCloudPB&& in) {
399408
if (in.has___split_schema()) {
400409
out->mutable___split_schema()->Swap(in.mutable___split_schema());
401410
}
411+
if (in.has_inverted_index_storage_format()) {
412+
out->set_inverted_index_storage_format(in.inverted_index_storage_format());
413+
}
402414
if (in.has_visible_ts_ms()) {
403415
out->set_visible_ts_ms(in.visible_ts_ms());
404416
}
@@ -796,6 +808,9 @@ void doris_tablet_meta_to_cloud(TabletMetaCloudPB* out, const TabletMetaPB& in)
796808
if (in.has_encryption_algorithm()) {
797809
out->set_encryption_algorithm(in.encryption_algorithm());
798810
}
811+
if (in.has_inverted_index_storage_format()) {
812+
out->set_inverted_index_storage_format(in.inverted_index_storage_format());
813+
}
799814
}
800815

801816
void doris_tablet_meta_to_cloud(TabletMetaCloudPB* out, TabletMetaPB&& in) {
@@ -890,6 +905,9 @@ void doris_tablet_meta_to_cloud(TabletMetaCloudPB* out, TabletMetaPB&& in) {
890905
if (in.has_encryption_algorithm()) {
891906
out->set_encryption_algorithm(in.encryption_algorithm());
892907
}
908+
if (in.has_inverted_index_storage_format()) {
909+
out->set_inverted_index_storage_format(in.inverted_index_storage_format());
910+
}
893911
}
894912

895913
TabletMetaPB cloud_tablet_meta_to_doris(const TabletMetaCloudPB& in) {
@@ -988,6 +1006,9 @@ void cloud_tablet_meta_to_doris(TabletMetaPB* out, const TabletMetaCloudPB& in)
9881006
if (in.has_encryption_algorithm()) {
9891007
out->set_encryption_algorithm(in.encryption_algorithm());
9901008
}
1009+
if (in.has_inverted_index_storage_format()) {
1010+
out->set_inverted_index_storage_format(in.inverted_index_storage_format());
1011+
}
9911012
}
9921013

9931014
void cloud_tablet_meta_to_doris(TabletMetaPB* out, TabletMetaCloudPB&& in) {
@@ -1082,6 +1103,9 @@ void cloud_tablet_meta_to_doris(TabletMetaPB* out, TabletMetaCloudPB&& in) {
10821103
if (in.has_encryption_algorithm()) {
10831104
out->set_encryption_algorithm(in.encryption_algorithm());
10841105
}
1106+
if (in.has_inverted_index_storage_format()) {
1107+
out->set_inverted_index_storage_format(in.inverted_index_storage_format());
1108+
}
10851109
}
10861110

10871111
} // namespace doris::cloud

be/src/service/http/action/show_nested_index_file_action.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <exception>
2323
#include <string>
2424

25+
#include "cloud/cloud_tablet.h"
2526
#include "common/status.h"
2627
#include "service/http/http_channel.h"
2728
#include "service/http/http_headers.h"
@@ -54,6 +55,10 @@ Status ShowNestedIndexFileAction::_handle_show_nested_index_file(HttpRequest* re
5455
}
5556

5657
auto tablet = DORIS_TRY(ExecEnv::get_tablet(tablet_id));
58+
if (auto cloud_tablet = std::dynamic_pointer_cast<CloudTablet>(tablet)) {
59+
// The debug endpoint must inspect all visible cloud rowsets, not only the local cache.
60+
RETURN_IF_ERROR(cloud_tablet->sync_rowsets());
61+
}
5762
RETURN_IF_ERROR(tablet->show_nested_index_file(json_meta));
5863
return Status::OK();
5964
}

be/src/storage/rowset/beta_rowset_writer.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,14 @@ Status BaseBetaRowsetWriter::init(const RowsetWriterContext& rowset_writer_conte
387387
_rowset_meta->set_newest_write_timestamp(_context.newest_write_timestamp);
388388
}
389389
_rowset_meta->set_tablet_uid(_context.tablet_uid);
390-
_rowset_meta->set_tablet_schema(_context.tablet_schema);
390+
auto schema = _context.tablet_schema->need_record_variant_extended_schema()
391+
? _context.tablet_schema
392+
: _context.tablet_schema->copy_without_variant_extracted_columns();
393+
_rowset_meta->set_tablet_schema(schema);
394+
if (_context.persist_inverted_index_storage_format &&
395+
_context.inverted_index_storage_format.has_value()) {
396+
_rowset_meta->set_inverted_index_storage_format(*_context.inverted_index_storage_format);
397+
}
391398
_rowset_meta->set_compaction_level(_context.compaction_level);
392399
if (_context.write_binlog_opt().enable) {
393400
_rowset_meta->mark_row_binlog();

be/src/storage/rowset/rowset_meta.cpp

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,19 @@ bool RowsetMeta::init(const RowsetMeta* rowset_meta) {
7070
}
7171

7272
bool RowsetMeta::init_from_pb(const RowsetMetaPB& rowset_meta_pb) {
73+
if (rowset_meta_pb.has_inverted_index_storage_format()) {
74+
_rowset_meta_pb.set_inverted_index_storage_format(
75+
rowset_meta_pb.inverted_index_storage_format());
76+
} else {
77+
_rowset_meta_pb.clear_inverted_index_storage_format();
78+
}
7379
if (rowset_meta_pb.has_tablet_schema()) {
74-
set_tablet_schema(rowset_meta_pb.tablet_schema());
80+
TabletSchemaPB schema_pb = rowset_meta_pb.tablet_schema();
81+
if (rowset_meta_pb.has_inverted_index_storage_format()) {
82+
schema_pb.set_inverted_index_storage_format(
83+
rowset_meta_pb.inverted_index_storage_format());
84+
}
85+
set_tablet_schema(schema_pb);
7586
}
7687
// Release ownership of TabletSchemaPB from `rowset_meta_pb` and then set it back to `rowset_meta_pb`,
7788
// this won't break const semantics of `rowset_meta_pb`, because `rowset_meta_pb` is not changed
@@ -209,6 +220,10 @@ void RowsetMeta::to_rowset_pb(RowsetMetaPB* rs_meta_pb, bool skip_schema) const
209220
if (!skip_schema) {
210221
// For cloud, separate tablet schema from rowset meta to reduce persistent size.
211222
_schema->to_schema_pb(rs_meta_pb->mutable_tablet_schema());
223+
if (rs_meta_pb->has_inverted_index_storage_format()) {
224+
rs_meta_pb->mutable_tablet_schema()->set_inverted_index_storage_format(
225+
rs_meta_pb->inverted_index_storage_format());
226+
}
212227
}
213228
}
214229
rs_meta_pb->set_has_variant_type_in_schema(has_variant_type_in_schema());
@@ -221,6 +236,12 @@ RowsetMetaPB RowsetMeta::get_rowset_pb(bool skip_schema) const {
221236
}
222237

223238
void RowsetMeta::set_tablet_schema(const TabletSchemaSPtr& tablet_schema) {
239+
if (_rowset_meta_pb.has_inverted_index_storage_format()) {
240+
TabletSchemaPB schema_pb;
241+
tablet_schema->to_schema_pb(&schema_pb);
242+
set_tablet_schema(schema_pb);
243+
return;
244+
}
224245
if (_handle) {
225246
TabletSchemaCache::instance()->release(_handle);
226247
}
@@ -230,22 +251,42 @@ void RowsetMeta::set_tablet_schema(const TabletSchemaSPtr& tablet_schema) {
230251
}
231252

232253
void RowsetMeta::set_tablet_schema(const TabletSchemaPB& tablet_schema) {
254+
TabletSchemaPB resolved_schema = tablet_schema;
255+
if (_rowset_meta_pb.has_inverted_index_storage_format()) {
256+
resolved_schema.set_inverted_index_storage_format(
257+
_rowset_meta_pb.inverted_index_storage_format());
258+
}
233259
if (_handle) {
234260
TabletSchemaCache::instance()->release(_handle);
235261
}
236262
auto pair = TabletSchemaCache::instance()->insert(
237-
TabletSchema::deterministic_string_serialize(tablet_schema));
263+
TabletSchema::deterministic_string_serialize(resolved_schema));
238264
_handle = pair.first;
239265
_schema = pair.second;
240266
}
241267

268+
void RowsetMeta::set_inverted_index_storage_format(InvertedIndexStorageFormatPB format) {
269+
_rowset_meta_pb.set_inverted_index_storage_format(format);
270+
if (_schema && _schema->get_inverted_index_storage_format() != format) {
271+
TabletSchemaPB schema_pb;
272+
_schema->to_schema_pb(&schema_pb);
273+
schema_pb.set_inverted_index_storage_format(format);
274+
set_tablet_schema(schema_pb);
275+
}
276+
}
277+
242278
bool RowsetMeta::_deserialize_from_pb(std::string_view value) {
243279
if (!_rowset_meta_pb.ParseFromArray(value.data(), cast_set<int32_t>(value.size()))) {
244280
_rowset_meta_pb.Clear();
245281
return false;
246282
}
247283
if (_rowset_meta_pb.has_tablet_schema()) {
248-
set_tablet_schema(_rowset_meta_pb.tablet_schema());
284+
TabletSchemaPB schema_pb = _rowset_meta_pb.tablet_schema();
285+
if (_rowset_meta_pb.has_inverted_index_storage_format()) {
286+
schema_pb.set_inverted_index_storage_format(
287+
_rowset_meta_pb.inverted_index_storage_format());
288+
}
289+
set_tablet_schema(schema_pb);
249290
_rowset_meta_pb.set_allocated_tablet_schema(nullptr);
250291
}
251292
return true;
@@ -258,6 +299,10 @@ bool RowsetMeta::_serialize_to_pb(std::string* value) {
258299
RowsetMetaPB rowset_meta_pb = _rowset_meta_pb;
259300
if (_schema) {
260301
_schema->to_schema_pb(rowset_meta_pb.mutable_tablet_schema());
302+
if (rowset_meta_pb.has_inverted_index_storage_format()) {
303+
rowset_meta_pb.mutable_tablet_schema()->set_inverted_index_storage_format(
304+
rowset_meta_pb.inverted_index_storage_format());
305+
}
261306
}
262307
return rowset_meta_pb.SerializeToString(value);
263308
}

be/src/storage/rowset/rowset_meta.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,16 @@ class RowsetMeta : public MetadataAdder<RowsetMeta> {
107107

108108
void set_index_id(int64_t index_id) { _rowset_meta_pb.set_index_id(index_id); }
109109

110+
bool has_inverted_index_storage_format() const {
111+
return _rowset_meta_pb.has_inverted_index_storage_format();
112+
}
113+
114+
InvertedIndexStorageFormatPB inverted_index_storage_format() const {
115+
return _rowset_meta_pb.inverted_index_storage_format();
116+
}
117+
118+
void set_inverted_index_storage_format(InvertedIndexStorageFormatPB format);
119+
110120
TabletUid tablet_uid() const { return _rowset_meta_pb.tablet_uid(); }
111121

112122
void set_tablet_uid(TabletUid tablet_uid) {

be/src/storage/rowset/rowset_writer_context.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,13 @@ struct RowsetWriterContext {
7070
RowsetTypePB rowset_type {BETA_ROWSET};
7171

7272
TabletSchemaSPtr tablet_schema;
73-
73+
// Immutable inverted-index file format inherited from the owner tablet.
74+
std::optional<InvertedIndexStorageFormatPB> inverted_index_storage_format;
75+
// Whether the owner tablet persists the format in its top-level metadata.
76+
// This is derived from TabletMeta and keeps rowset metadata consistent with it.
77+
bool persist_inverted_index_storage_format = false;
78+
// for variant schema update
79+
TabletSchemaSPtr merged_tablet_schema;
7480
// PREPARED/COMMITTED for pending rowset
7581
// VISIBLE for non-pending rowset
7682
RowsetStatePB rowset_state {PREPARED};

be/src/storage/tablet/tablet.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2302,6 +2302,7 @@ void Tablet::_init_context_common_fields(RowsetWriterContext& context) {
23022302
context.tablet_id = tablet_id();
23032303
context.partition_id = partition_id();
23042304
context.tablet_schema_hash = schema_hash();
2305+
context.inverted_index_storage_format = tablet_meta()->inverted_index_storage_format();
23052306
context.rowset_type = tablet_meta()->preferred_rowset_type();
23062307
// Alpha Rowset will be removed in the future, so that if the tablet's default rowset type is
23072308
// alpha rowset, then set the newly created rowset to storage engine's default rowset.

be/src/storage/tablet/tablet_meta.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -315,8 +315,8 @@ TabletMeta::TabletMeta(const TabletMeta& b)
315315
_time_series_compaction_empty_rowsets_threshold(
316316
b._time_series_compaction_empty_rowsets_threshold),
317317
_time_series_compaction_level_threshold(b._time_series_compaction_level_threshold),
318-
_vertical_compaction_num_columns_per_group(
319-
b._vertical_compaction_num_columns_per_group) {};
318+
_vertical_compaction_num_columns_per_group(b._vertical_compaction_num_columns_per_group),
319+
_inverted_index_storage_format(b._inverted_index_storage_format) {};
320320

321321
void TabletMeta::init_column_from_tcolumn(uint32_t unique_id, const TColumn& tcolumn,
322322
ColumnPB* column) {
@@ -827,6 +827,10 @@ void TabletMeta::init_from_pb(const TabletMetaPB& tablet_meta_pb) {
827827
_cumulative_layer_point = tablet_meta_pb.cumulative_layer_point();
828828
_tablet_uid = TabletUid(tablet_meta_pb.tablet_uid());
829829
_ttl_seconds = tablet_meta_pb.ttl_seconds();
830+
_inverted_index_storage_format.reset();
831+
if (tablet_meta_pb.has_inverted_index_storage_format()) {
832+
_inverted_index_storage_format = tablet_meta_pb.inverted_index_storage_format();
833+
}
830834
if (tablet_meta_pb.has_tablet_type()) {
831835
_tablet_type = tablet_meta_pb.tablet_type();
832836
} else {
@@ -857,7 +861,11 @@ void TabletMeta::init_from_pb(const TabletMetaPB& tablet_meta_pb) {
857861

858862
// init _schema
859863
TabletSchemaSPtr schema = std::make_shared<TabletSchema>();
860-
schema->init_from_pb(tablet_meta_pb.schema());
864+
TabletSchemaPB schema_pb = tablet_meta_pb.schema();
865+
if (_inverted_index_storage_format.has_value()) {
866+
schema_pb.set_inverted_index_storage_format(*_inverted_index_storage_format);
867+
}
868+
schema->init_from_pb(schema_pb);
861869
if (_handle) {
862870
TabletSchemaCache::instance()->release(_handle);
863871
}
@@ -1014,6 +1022,11 @@ void TabletMeta::to_meta_pb(TabletMetaPB* tablet_meta_pb, bool cloud_get_rowset_
10141022
}
10151023

10161024
_schema->to_schema_pb(tablet_meta_pb->mutable_schema());
1025+
if (_inverted_index_storage_format.has_value()) {
1026+
tablet_meta_pb->set_inverted_index_storage_format(*_inverted_index_storage_format);
1027+
tablet_meta_pb->mutable_schema()->set_inverted_index_storage_format(
1028+
*_inverted_index_storage_format);
1029+
}
10171030

10181031
if (_row_binlog_schema != nullptr) {
10191032
_row_binlog_schema->to_schema_pb(tablet_meta_pb->mutable_row_binlog_schema());

0 commit comments

Comments
 (0)