Struct tikv::storage::mvcc::Write [−][src]
Fields
write_type: WriteTypestart_ts: TimeStampshort_value: Option<Vec<u8, Global>>has_overlapped_rollback: boolThe commit_ts of transactions can be non-globally-unique. But since we store Rollback
records in the same CF where Commit records is, and Rollback records are saved with
user_key{start_ts} as the internal key, the collision between Commit and Rollback
records can’t be avoided. In this case, we keep the Commit record, and set the
has_overlapped_rollback flag to indicate that there’s also a Rollback record.
Also note that has_overlapped_rollback field is only necessary when the Rollback record
should be protected.
gc_fence: Option<TimeStamp>Records the next version after this version when overlapping rollback happens on an already existed commit record.
When a rollback flag is written on an already-written commit record, it causes rewriting the commit record. It may cause problems with the GC compaction filter. Consider this case:
Key_100_put, Key_120_del
and a rollback on 100 happens:
Key_100_put_R, Key_120_del
Then GC with safepoint = 130 may happen. However a follower may not have finished applying the change. So on the follower, it’s possible that:
Key_100_put,Key_120_delapplied- GC with safepoint = 130 started and
Key_100_put,Key_120_delare deleted - Finished applying
Key_100_put_R, which means to rewriteKey_100_put - Read at
140should get nothing (since it’s MVCC-deleted at 120) but findsKey_100_put
To solve the problem, when marking has_overlapped_rollback on an already-existed commit
record, add a special field gc_fence on it. If there is a newer version after the record
being rewritten, the next version’s commit_ts will be recorded. When MVCC reading finds
a commit record with a GC fence timestamp but the corresponding version that matches that ts
doesn’t exist, the current version will be believed to be already GC-ed and ignored.
Therefore, for the example above, in the 3rd step it will record the version 120 to the
gc_fence field:
Key_100_put_R_120, Key_120_del
And when the reading in the 4th step finds the PUT record but the version at 120 doesn’t
exist, it will be regarded as already GC-ed and ignored.
For CDC and TiFlash, when they receives a commit record with gc_fence field set, it can
determine that it must be caused by an overlapped rollback instead of an actual commit.
Note: GC fence will only be written on PUT and DELETE versions, and may only point to
a PUT or DELETE version. If there are other Lock and Rollback records after the
record that’s being rewritten, they will be skipped. For example, in this case:
Key_100_put, Key_105_lock, Key_110_rollback, Key_120_del
If overlapped rollback happens at 100, the Key_100_put will be rewritten as
Key_100_put_R_120. It points to version 120 instead of the nearest 105.
The meaning of the field:
None: A record that haven’t been rewrittenSome(0): A commit record that has been rewritten due to overlapping rollback, but it doesn’t have an newer version.Some(ts): A commit record that has been rewritten due to overlapping rollback, and it’s next version’scommit_tsists
Implementations
impl Write[src]
pub fn new(
write_type: WriteType,
start_ts: TimeStamp,
short_value: Option<Vec<u8, Global>>
) -> Write[src]
write_type: WriteType,
start_ts: TimeStamp,
short_value: Option<Vec<u8, Global>>
) -> Write
Creates a new Write record.
pub fn new_rollback(start_ts: TimeStamp, protected: bool) -> Write[src]
pub fn set_overlapped_rollback(
self,
has_overlapped_rollback: bool,
gc_fence: Option<TimeStamp>
) -> Write[src]
self,
has_overlapped_rollback: bool,
gc_fence: Option<TimeStamp>
) -> Write
pub fn parse_type(b: &[u8]) -> Result<WriteType, Error>[src]
pub fn as_ref(&self) -> WriteRef<'_>[src]
Trait Implementations
impl Clone for Write[src]
impl Debug for Write[src]
impl PartialEq<Write> for Write[src]
impl StructuralPartialEq for Write[src]
Auto Trait Implementations
impl RefUnwindSafe for Write
impl Send for Write
impl Sync for Write
impl Unpin for Write
impl UnwindSafe for Write
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized, [src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized, [src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized, [src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T[src]
impl<V, W> ConvertFrom<W> for V where
W: ConvertTo<V>, [src]
W: ConvertTo<V>,
pub fn convert_from(ctx: &mut EvalContext, from: W) -> Result<V, Error>[src]
impl<T> From<T> for T[src]
impl<T> Instrument for T[src]
pub fn instrument(self, span: Span) -> Instrumented<Self>[src]
pub fn in_current_span(self) -> Instrumented<Self>[src]
impl<T, U> Into<U> for T where
U: From<T>, [src]
U: From<T>,
impl<T> Pointable for T[src]
pub const ALIGN: usize[src]
type Init = T
The type for initializers.
pub unsafe fn init(init: <T as Pointable>::Init) -> usize[src]
pub unsafe fn deref<'a>(ptr: usize) -> &'a T[src]
pub unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T[src]
pub unsafe fn drop(ptr: usize)[src]
impl<T> Pointable for T[src]
pub const ALIGN: usize[src]
type Init = T
The type for initializers.
pub unsafe fn init(init: <T as Pointable>::Init) -> usize[src]
pub unsafe fn deref<'a>(ptr: usize) -> &'a T[src]
pub unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T[src]
pub unsafe fn drop(ptr: usize)[src]
impl<T> Same<T> for T[src]
type Output = T
Should always be Self
impl<T> Sealed<T> for T where
T: ?Sized, [src]
T: ?Sized,
impl<T> SendSyncUnwindSafe for T where
T: Send + Sync + UnwindSafe + ?Sized, [src]
T: Send + Sync + UnwindSafe + ?Sized,
impl<T> ToOwned for T where
T: Clone, [src]
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
pub fn to_owned(&self) -> T[src]
pub fn clone_into(&self, target: &mut T)[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>, [src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>, [src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
pub fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>[src]
impl<V, T> VZip<V> for T where
V: MultiLane<T>, [src]
V: MultiLane<T>,