Repository: tikv/tikv
File: src/storage/mvcc/reader/scanner/mod.rs (Rust)

Code before:
    statistics: &mut Statistics,
) -> Result<Option<Write>>
where
    I: Iterator,
{
    let mut ret = None;
    while write_cursor.valid()?
        && Key::is_user_key_eq(
            write_cursor.key(&mut statistics.write),
            user_key.as_encoded(),
        )
    {
        let write_ref = WriteRef::parse(write_cursor.value(&mut statistics.write))?;
        if !write_ref.check_gc_fence_as_latest_version(gc_fence_limit) {
            break;
        }
        match write_ref.write_type {
            WriteType::Put | WriteType::Delete => {
                // After a pessimistic transaction is committed,
                // a non-pessimistic lock of the same transaction can be also prewritten
                // successfully. The lock TS of such a lock is smaller than the commit TS of the
                // latest write record.
                // See https://github.com/tikv/tikv/issues/11187
                let latest_write_ts = Key::decode_ts_from(write_cursor.key(&mut statistics.write))?;
                if after_ts < latest_write_ts {
                    warn!("found the user key of which ts > after_ts. There may be exist an unexpected stale non-pessimistic lock";
                        "user_key" => %user_key,
                        "after_ts" => after_ts,
                        "latest_write_ts" => latest_write_ts,
                        "write_type" => ?write_ref.write_type,
                    );
                }
                ret = Some(write_ref.to_owned());
                break;
            }
            WriteType::Lock | WriteType::Rollback => {
                // Move to the next write record.
                write_cursor.next(&mut statistics.write);
            }
        }
    }
    Ok(ret)
}

/// Seek for the last written value.
/// The write cursor must indicate a data key of the user key of which ts <=
/// after_ts. Return None if cannot find any valid write record or found a
/// delete record.
///
/// GC fence will be checked against the specified `gc_fence_limit`. If
/// `gc_fence_limit` is greater than the `commit_ts` of the current write record

Review comment (suggestion):
```suggestion
                    warn!("found the user key of which ts > after_ts. There may exist an unexpected stale non-pessimistic lock";
```

Code after:
    statistics: &mut Statistics,
) -> Result<Option<Write>>
where
    I: Iterator,
{
    let mut ret = None;
    while write_cursor.valid()?
        && Key::is_user_key_eq(
            write_cursor.key(&mut statistics.write),
            user_key.as_encoded(),
        )
    {
        let write_ref = WriteRef::parse(write_cursor.value(&mut statistics.write))?;
        if !write_ref.check_gc_fence_as_latest_version(gc_fence_limit) {
            break;
        }
        match write_ref.write_type {
            WriteType::Put | WriteType::Delete => {
                // After a pessimistic transaction is committed,
                // a non-pessimistic lock of the same transaction can be also prewritten
                // successfully. The lock TS of such a lock is smaller than the commit TS of the
                // latest write record.
                // See https://github.com/tikv/tikv/issues/11187
                let latest_write_commit_ts =
                    Key::decode_ts_from(write_cursor.key(&mut statistics.write))?;
                if after_ts < latest_write_commit_ts {
                    warn!("found the user key of which ts > after_ts. There may exist an unexpected stale non-pessimistic lock";
                        "user_key" => %user_key,
                        "after_ts" => after_ts,
                        "latest_write_commit_ts" => latest_write_commit_ts,
                        "latest_write_start_ts" => write_ref.start_ts,
                        "write_type" => ?write_ref.write_type,
                    );
                }
                ret = Some(write_ref.to_owned());
                break;
            }
            WriteType::Lock | WriteType::Rollback => {
                // Move to the next write record.
                write_cursor.next(&mut statistics.write);
            }
        }
    }
    Ok(ret)
}

/// Seek for the last written value.
/// The write cursor must indicate a data key of the user key of which ts <=
/// after_ts. Return None if cannot find any valid write record or found a
/// delete record.
///