Hi @denesb ,
I found that view_updates::update_entry(const partition_key& base_key, const clustering_or_static_row& update, const clustering_or_static_row& existing, gc_clock::time_point now)
was called in function view_updates::generate_update
. There is a line of statement auto diff = update.cells().difference(*_base, kind, existing.cells());
in generate_update
.
I found through reproducing problem Major bug: Repair will cause index table data loss! that the diff (actually a row type) here is empty, which results in the cells of the generated GSI being empty.
If the data modified from the base table(update
) is the same as the data existing in the node(existing
), then diff
is empty, resulting in the record only having a key and no cells in GSI.
Why use update_entry
, can’t we just use create_entry
directly?
void view_updates::update_entry(const partition_key& base_key, const clustering_or_static_row& update, const clustering_or_static_row& existing, gc_clock::time_point now) {
// While we know update and existing correspond to the same view entry,
// they may not match the view filter.
if (!matches_view_filter(*_base, _view_info, base_key, existing, now)) {
create_entry(base_key, update, now);
return;
}
if (!matches_view_filter(*_base, _view_info, base_key, update, now)) {
do_delete_old_entry(base_key, existing, update, now);
return;
}
if (can_skip_view_updates(update, existing)) {
return;
}
auto view_rows = get_view_rows(base_key, update, std::nullopt);
auto update_marker = compute_row_marker(update);
const auto kind = update.column_kind();
for (const auto& [r, action] : view_rows) { // r deletablerow
if (auto rm = std::get_if<row_marker>(&action)) {
r->apply(*rm);
vlogger.info("view_updates::update_entry bbb {}", row::printer(*_base, kind, r->cells()));
} else {
r->apply(update_marker);
}
r->apply(update.tomb());
vlogger.info("view_updates::update_entry update {}", row::printer(*_base, kind, update.cells()));
vlogger.info("view_updates::update_entry existing {}", row::printer(*_base, kind, existing.cells()));
auto diff = update.cells().difference(*_base, kind, existing.cells()); // row
vlogger.info("view_updates::update_entry diif {}", row::printer(*_base, kind, diff)); // diff is none
add_cells_to_view(*_base, *_view, kind, std::move(diff), r->cells());
vlogger.info("view_updates::update_entry r {}", row::printer(*_base, kind, r->cells())); // r is none
}
_op_count += view_rows.size();
}