TiDB-GC

垃圾回收机制 GC (Garbage Collection)

TiDB 的事务的实现采用了 MVCC(多版本并发控制)机制,当新写入的数据覆盖旧的数据时,旧的数据不会被替换掉,而是与新写入的数据同时保留原数据,并以时间戳来区分版本。GC 的任务便是清理不再需要的旧数据。

整体流程

GC leader 选举

一个 TiDB 集群中会有一个 TiDB 实例被选举为 GC leader,GC 的运行由 GC leader 来控制。

GC Leader 的选举是从 TiDB Server 中选出一个作为 GC Leader ,GC Worker 是 TiDB Server 上的一个模块,只有 GC Leader 会处理 GC 的工作,其他 TiDB Server 上的 GC Worker 是不工作的。选举 GC Leader 的方式很简单,GC Worker 每分钟 Tick 时,如果发现没有 Leader 或 Leader 失效,就把自己写进去,成为 GC Leader。

safe point

GC 会被定期触发。每次 GC 时,首先,TiDB 会计算一个称为 safe point 的时间戳,接下来 TiDB 会在保证 safe point 之后的快照全部拥有正确数据的前提下,删除更早的过期数据。

GC 流程

每一轮 GC 分为以下三个步骤,这三个步骤在整个 GC 的流程中是串行执行。如果一轮 GC 运行时间太久,上次 GC 还在前两个阶段,下轮 GC 又开始了,下一轮 GC 会忽略,GC Leader 会报 “there’s already a gc job running,skipped”:

  1. Resolve Locks (清理锁)

    该阶段会对所有 Region 扫描 safe point 之前的锁,并清理这些锁。

  2. Delete Ranges (删除区间)

    该阶段快速地删除由于 DROP TABLE/DROP INDEX 等操作产生的整区间的废弃数据。

  3. Do GC (进行 GC 清理)

    该阶段每个 TiKV 节点将会各自扫描该节点上的数据,并对每一个 key 删除其不再需要的旧版本。

默认配置下,GC 每 10 分钟触发一次,每次 GC 会保留最近 10 分钟内的数据(即默认 GC life time 为 10 分钟,safe point 的计算方式为当前时间减去 GC life time)。如果一轮 GC 运行时间太久,那么在一轮 GC 完成之前,即使到了下一次触发 GC 的时间也不会开始下一轮 GC。另外,为了使持续时间较长的事务能在超过 GC life time 之后仍然可以正常运行,safe point 不会超过正在执行中的事务的开始时间 (start_ts)。

GC 配置

查询配置

TiDB 的 GC 相关的配置存储于 mysql.tidb 系统表中,可以通过 SQL 语句对这些参数进行查询和更改

select VARIABLE_NAME, VARIABLE_VALUE from mysql.tidb where VARIABLE_NAME like "tikv_gc%";

修改配置

-- 将 GC 调整为保留最近一天以内的数据
update mysql.tidb set VARIABLE_VALUE="24h" where VARIABLE_NAME="tikv_gc_life_time";

注意:
mysql.tidb 系统表中除了下文列出的 GC 的配置以外,还包含一些 TiDB 用于储存部分集群状态(包括 GC 状态)的记录。请勿手动更改这些记录。其中,与 GC 有关的记录如下:

  • tikv_gc_leader_uuid,tikv_gc_leader_desc 和 tikv_gc_leader_lease 用于记录 GC Leader 的状态
  • tikv_gc_last_run_time:最近一次 GC 运行的时间(每轮 GC 开始时更新)
  • tikv_gc_safe_point:当前的 Safepoint (每轮 GC 开始时更新)

流控(限制资源使用量)

TiKV 在 3.0.6 版本开始支持 GC 流控,并且仅仅针对 GC 的 DO GC 阶段进行限流。可通过配置 gc.max-write-bytes-per-sec 限制 GC worker 每秒数据写入量,降低对正常请求的影响,0 为关闭该功能。该配置可通过 tikv-ctl 动态修改:

tikv-ctl --host=ip:port modify-tikv-config -m server -n gc.max_write_bytes_per_sec -v 10MB

GC 日志

在分析 GC Leader 的 GC 相关的日志前,先要通过 mysql.tidb 来确认当前的 GC Leader 的信息

select VARIABLE_NAME,VARIABLE_VALUE from mysql.tidb where VARIABLE_NAME in('tikv_gc_leader_uuid','tikv_gc_leader_desc');

GC 日志内容,如下:

image-20210121104148148

原文地址:https://www.cnblogs.com/binliubiao/p/14393213.html