/* * Calculate reverse modify and clear the history store records with timestamps when * inserting the first update. Always write on-disk data store updates to the history * store as a full update because the on-disk update will be the base update for all the * updates that are older than the on-disk update. Limit the number of consecutive * reverse modifies for standard updates. We want to ensure we do not store a large * chain of reverse modifies as to impact read performance. * * Due to concurrent operation of checkpoint and eviction, it is possible that history * store may have more recent versions of a key than the on-disk version. Without a * proper base value in the history store, it can lead to wrong value being restored by * the RTS. */ nentries = MAX_REVERSE_MODIFY_NUM; if (!F_ISSET(upd, WT_UPDATE_DS) && !F_ISSET(prev_upd, WT_UPDATE_DS) && enable_reverse_modify && modify_cnt < WT_MAX_CONSECUTIVE_REVERSE_MODIFY && __wt_calc_modify(session, prev_full_value, full_value, prev_full_value->size / 10, entries, &nentries) == 0)
The check !F_ISSET(upd, WT_UPDATE_DS) && !F_ISSET(prev_upd, WT_UPDATE_DS) in this code is to ensure we don't insert a reverse modify update for the update that is just older than the onpage value to the history store. However, it fails to consider the case that there are multiple updates have the same transaction id and timestamp as the onpage value. In this case, we will squash the onpage update and the update that is previous to the current update is not marked with WT_UPDATE_DS.