# [FAQ]TiDB slow log 里 scan_detail 那些字段

## Key Words

TiDB, slow log, scan_detail, total_process_keys, total_keys, delete_skipped_count, key_skipped_count, gc, compaction

## Description

```sql
scan_detail: {total_process_keys: 1, total_keys: 373387173, rocksdb: {delete_skipped_count: 1327789, key_skipped_count: 374902194, block: {cache_hit_count: 272471, read_count: 5144, read_byte: 118.1 MB}}}
```

在 TiDB slow log 的排查过程中，我们经常看到下发到 TiKV 的算子详情中，可以看到上述字段，下面我们来一一讲解这些字段的含义：

* MVCC 版本相关信息（是否需要 MVCC 级别的 GC ）
    * total_process_keys: 本算子在 TiKV 侧（MVCC 层）真正扫到的用户可见的 key 个数。如果个数比较多，说明确实是数据量比较大，没有优化空间。
    * total_keys: 本算子在 TiKV 侧扫到的 mvcc 版本数。如果 total_keys 比 total_process_keys 多很多，说明有很多旧版本的 mvcc 数据，需要考虑触发 GC。
   
* rocksdb 版本相关信息（compaction 是否及时）
    * rocksdb.delete_skipped_count: rocksdb 中为 tombstone 的 key 个数，个数多需要 compaction 回收空间。
    * rocksdb.key_skipped_count: 在 TiKV 中，这个的主要意思是 rocksdb 中真正 next 的个数，这个信息量有点大，可参考 [rocksdb 文档](https://github.com/facebook/rocksdb/blob/9f1c84ca471d8b1ad7be9f3eebfc2c7e07dfd7a7/include/rocksdb/perf_context.h#L84)。总之，这个如果比 total_keys 大很多，也是要 compaction 了。

For example, 如扫 \[A,D) 范围内的数据，其在 TiKV 底层的数据分布如下：

| 数据（key_tso） | 类型(MVCC，未 GC 前) | GC 前，在 rocksdb -write cf 的类型  | GC 后（还未 compaction）,rocsdb write cf 类型 | 
|:---:|:---:|:---:|:---:| 
| A_t1 | PUT | PUT | A_t1_r1=>PUT| 
||||A_t1_r2=>tombstone| 
| A_t20 | PUT | PUT | PUT | 
|||| tombstone | 
| A_t30 | PUT | PUT | PUT | 
| B_t11 | PUT | PUT | PUT | 
|||| tombstone | 
| B_t22 | PUT | PUT | PUT | 
|||| tombstone | 
| B_t33 | DELETE | PUT | PUT | 
|||| tombstone | 
| D_XXX | ... |  |  | 

如扫 \[A,C) 范围内的数据：

* total_process_keys, 从 MVCC 侧看，A 的最新版本为 PUT，计数 +1。 B 的最新版本为 DELETE，计数为 0。C 没有。总计为 0。
* total_keys: 从 MVCC 侧看，A 一共有 3 个版本，B 有 3 个版本，总扫到的版本数为 6.
* rocksdb 扫描情况（参考值，具体细节需要看最终查询操作的优化） 
    * rocksdb.delete_skipped_count: GC 后，A 留下最新版本 PUT，旧版本都被清理，被清理的旧版本计数 +2。同理，B 全被清理，清理的数据为 3，总计为 5。
    * rocksdb.key_skipped_count: 较为复杂，在 tikv 中，主要包含以下几种情况：
    
    * 
    * LOCK CF 每次数据的写入都有 2 个版本生成，会在这种情况下被 next-skip 计数 2\*3  + 2\*3 (这边只能估算，因为有些情况优化后，lock cf 不一定会被加锁)
    * WRITE CF 持续不断地更新，每次 next 计数 +1
    * WRITE CF 在 GC 后会被删除变成 tombstone,  计数也会 +1 

## Affected Versions

N/A