不定期更新,记录一些小知识

1

关于 tikv 侧事务冲突检测

tikv 默认参数侧:

  • scheduler-concurrency
    • scheduler 内置一个内存锁机制,防止同时对一个 Key 进行操作。每个 Key hash 到不同的槽。
    • 默认值:2048000

监控侧:

  • scheduler latency wait duration 值很高时,说明大量时间消耗在锁等待上面,如果不存在底层写入问题,那就可以判断在该时间段冲突比较多。

建议:

  • 在实际应用时,如果业务场景能够预判断写入不存在冲突(如导入数据操作),建议关闭冲突检测。

2

关于 tidb 事务重试

步骤:

  1. 重新获取 start timestamp
  2. 重新执行包含写操作 sql 语句
  3. 再次进行两阶段提交

条件:

  1. select for update 无法进行事务重试
  2. 事务只重试数据写操作,读操作不重试

1

答:

关于 feedback-probability,概率自动更新直方图和 Count-Min Sketch,老版本默认值为 0.05,新版本已经优化为 0.0,如果从老版本升级上来出现慢语句或者性能问题,可以将其调整下来。

1

答:

tiup destroy 时会检测端口是否关闭,如果该端口一直被占用,将会失败,及时该端口运行着与 tidb 无关的服务。

1

dm 在 Dump 阶段报错:

“errors”: [ { “Type”: “UnknownError”, “msg”: “[code=32001:class=dump-unit:scope=internal:level=high] mydumper runs with error: exit status 1. \n\n”, “error”: null } ],

答:

在 dump 阶段出现问题,可以从 权限 问题入手,检查上游执行 mydumper 用户是否有响应的权限,一般情况,大都缺少 reload,本问题就是其中一种报错,通过在 task 任务文件中 添加如下配置即可,通过扩展 mydumper 参数的方式,跳过锁表操作。


mysqdumpers:
  global:
    extra-args: “--no-locks”

2

4.0 版本 tikv 参数中多了一个 storage.reserver-space 参数,默认是 2G,作为预留空间,会在 {tikv_data} 目录下创建一个 space_placeholder_file 文件,用于提前占用空间,磁盘使用满的时候可以用于释放空间。

1

答:

  • 如果您对于大小写不敏感的排序规则有强需求,可以打开 TiDB 4.0 的 CI Collation 选项,使用 utf8_general_ci collation
  • 如果没有上述需求,请直接使用 utf8_bin,这也是除 TiDB 4.0 CI Collation 之外,唯一支持的排序规则。

2

答:

tiup v0.5.0 在 deploy 阶段存在 bug,远程创建目录会失败,大家可以注意下,想和版本会修复,使用 tiup update cluster --force 升级即可

1

答:

0.6.0 默认使用 home 下的密钥,如果要使用密码模式传 -p 或者 --password;

–password 的情况下各个服务器的密码得一样

2

【tiup 启动集群后 pd tikv tidb 显示 down ,实际服务正常。】

答:

排查方向现在可以延伸至防火墙,deploy、start 阶段并没有报错,但是监控节点状态却出现问题。

1

SHARD_ROW_ID_BITS 使用条件(或者说 _tidb_rowid 的存在条件)

  1. 没有 primary key 关键字
  2. primary key 非整数类型(不能是 int,bigint 等)

使用方法:

  1. alter table t SHARD_ROW_ID_BITS = 4(2^4 个分片)
  2. create table t (id int) shard_row_id = 4;

2

开启 alter-primary-key,

  1. 需要开启 alter-primary-key: true
  2. 如果你的主键类型为 int,需要进行数据迁移,重新建表,将数据导入新表才 ok ,因为著名的 pkishandle
1赞

1

问:pump 报错,参数设置,【no available space】

答:

思路:

空间不足,但查看可剩余空间是超过 10GB ,怀疑有参数限制去获取空间大小。

so:

stop-write-at-available-space

  • 可用存储空间低于指定值时不再接收 binlog 写入请求。可以用例如 900 MB、5 GB、12 GiB 的格式指定空间大小。如果集群中 Pump 节点多于一个,那么在某个 Pump 节点因为空间不足而拒绝写入时,TiDB 端会自动写入到其他 Pump 节点。
  • 默认:10 GiB

1

目前 tiup 下载 tar 中如果出现错误将会推出,再次下载将会跳过,目前没有校验一步,此时需要删除对应安装包完成下载 .tiup/storage/cluster/packages/

2

答:

在使用 DM 进行迁移时,以下是写流量的切换建议,请根据实际场景进行评估:

DM + 完全业务双写

该方案是在应用端实现双写,并且在指定时间窗口上线双写功能,运行稳定后,可评估写流量切换到 TiDB。

1)使用 DM 完成业务数据的全量和增量同步

2)寻找时间窗口将线上以及 DM 的流量同时切断,并确认数据是否完全同步

3)应用程序端上线双写功能

4)DM 不再作为增量同步的介质,评估后可计划下线

5)应用端正常写入数据到 MySQL 以及 TiDB

6)评估后,写流量切换至 TiDB

如果采用您之前提供的方案,业务 A 和业务 B 同时使用表 1 ,并且使用 DM 同步表 1 到 TiDB。DM 同步的粒度是 table,此时,切业务 A 到 TiDB,业务 B 会持续写入数据到 MySQL ,并同步到 TiDB。

1

关于统计信息和执行计划学习

基础概念:

INL_JOIN() 中的参数是建立查询计划时内表的候选表,通过执行计划可以看出当前执行计划的驱动表是谁(outer 为小表,为驱动表):inner key outer key

mysql 执行计划:上面的为驱动表

分析,

第一次通过 mysql 和 tidb 的执行计划看出,mysql tidb 驱动表选择不一致,

方向:使用 hint 将 tidb sql 驱动表保持和 mysql 一致,并使用驱动表索引。

由于开启 tiflash,对 sql 进行了加速,但这不是问题的原因,通过 hint 使用 tikv 存储引擎看查询时间是否接近 mysql。

2

答:

单线程下一个事务在多条 sql 和单条 sql 执行效率基本无差,都进行 1 次 2pc。

1

tidb oom 问题:

通过设置参数以下两个参数控制。目前可能出现设置参数后还是出现 oom 情况,可能是没有 trace 到,这种情况可以联系 pingcap,或者在 tidb github 上提个 issue。


oom-action = “cancel” #指定当单个SQL语句超出 mem-quota-query 指定的内存配额且无法溢出到磁盘时,TiDB执行的操作。有效选项:[“ log”,“ cancel”]

2

tiflash 相关:

  1. 当 tikv peer > tikv store ,tiflash 将不同步副本

  2. placement rules 规则为全局规则需要通过对应 api 来修改。

  3. https://pingcap.com/docs-cn/stable/how-to/configure/placement-rules/

1

关于 tidb 的 session 连接限制:

先看下相关参数,在使用过程中如果发现,tidb 连接数不能满足业务需求,可以调整 a 参数:

a.

–token-limit

  • TiDB 中同时允许运行的 Session 数量,用于流量控制
  • 默认:1000
  • 如果当前运行的连接多于该 token-limit,那么请求会阻塞,等待已经完成的操作释放 Token

b.

max-server-connections

  • TiDB 中同时允许的最大客户端连接数,用于资源控制。
  • 默认值:0
  • 默认情况下,TiDB 不限制客户端连接数。当本配置项的值大于 0 且客户端连接数到达此值时,TiDB 服务端将会拒绝新的客户端连接。

1

tiup edit-config 中配置生成

答:

editconfig 的值和 config 里面的 config 做 merge

可能原因:

  1. 他这个是不是因为配置项的位置变化了啊?这样的话把 ~/.tiup/storage/cluster/clusters/{cluster-name}/config 这里面 ansible 导入的配置文件里面对应那一项删掉(或者注释掉)就不会再被自动添加进去了
  2. config 下面 所有 tidb*.toml 里配置项删掉
  3. 是的,这些文件是从 ansible 导入的时候备份的各个组件实际使用的文件,在 reload 的时候会自动跟 edit-config 的那份配置合并,然后这里应该是因为这个配置项出现在了两个不同的位置所以没有被覆盖掉而是变成了两项

2

tiup display 状态展示 pd 节点的获取是通过 pd-ctl member 获取的,如果 /home/tidb/.tiup/storage/cluster/clusters/qh/meta.yaml 文件的 pd name 与 pd-ctl 获取不一致 display 状态显示可能为 N/A

1

监控中小于 1M 的region 被定义 空 region 所以和其他 region 一样,有 leader 和 副本。监控中统计的也是 region leader 的个数。

2

dm 延迟信息获取:

  1. query status 看到的 sync binlog 实际上是从 checkpoint 表读取的,这个表记录的 flushed binlog position 只有 dml 的情况下默认超过 30s 才更新,实际同步的位置可能已经是最新了
  2. 目前如果要准确监控同步延迟,在 DM 上游连接 mysql 主库的情况下,可以开启 heartbeat,开启 heartbeat 后,不会影响到 query-status 这里的状态,需要通过 binlog replication 1 中的 replicate lag 监控复制延迟

1

lightning 导入问题如果服务器性能不足,可以调整以下参数缓解:

  1. tidb-lightning:

  2. region-concurrency 默认值设置为 cpu 核数,混合部署建议设置 70% CPU 核数

  3. tikv-importer:

  4. 降低 index-concurrency 和 table-concurrency 来减少磁盘用量,之和小于 max-open-engines

  5. 降低 num-import-jobs 来减少 cpu 和 内存的使用量

  6. 设置 upload-speed-limit 来限制上传的速度,防止带宽被用尽,导致 pd 无法联络 tikv

  7. 预留可用空间 store_available_space/store_capacity >= min-available-ratio(0.05),停止 sst 文件上传。为 pd 提供负载均衡。

2

RocksDB 特性相關

  1. column family:根据不同的数据类型,调整 compaction 的策略,小表可以都放在内存中。
  2. rate limiter 代表 compaction 的速率
  3. Rocksdb中引入了ColumnFamily(列族, CF)的概念,所谓列族也就是一系列kv组成的数据集。所有的读写操作都需要先指定列族。写操作先写WAL,再写memtable,memtable达到一定阈值后切换为Immutable Memtable,只能读不能写。后台Flush线程负责按照时间顺序将Immu Memtable刷盘,生成level0层的有序文件(SST)。后台合并线程负责将上层的SST合并生成下层的SST。

Column Family

  1. default CF:存储 raft log,真正的数据。
  2. write CF:存储索引,MVCC,小表的数据。
  3. lock CF:存储锁信息
  4. 每个 CF 有各自的 Write-buffer,大小通过 write-buffer-size 控制
  5. 所有 CF 共享一个 Block-cache,通过参数 storage.block-cache 控制,用于缓存数据块,加速 RocksDB 的读取速度,Block-cache 的大小通过参数 block-cache-size 控制,block-cache-size 越大,能够缓存的热点数据越多,对读取操作越有利,同时占用的系统内存也会越多。

1

tiup v1.0.7 及以前版本,manifests 过期问题。


解决方案: rm ~/.tiup/manifests/*

2

tiup 离线/在线环境切换。

tiup 在线环境:export TIUP_MIRRORS=https://tiup-mirrors.pingcap.com
tiup 离线环境:export TIUP_MIRRORS=/path/to/local – 你的 package 目录

3

4.0.0-rc2 pre split region 在 truncate table 之后将会继续生效。

2020年7月6日 09点38分

1

dm-worker 下线流程:

stop.yml -l dm-worker1

删除 inventory 文件中 dm-worker1 的配置

rolling_update.yml -l dm-master

rolling_update_monitor.yml -t prometheus

删除节点后,监控的历史信息会在 30 天后被删除,此为 prometheus 的 gc 时间

2

数据被误删除操作流程

  1. 将 gc 时间调大,避免数据被删除

  2. 设置 session 级别 snapshot 时间查看数据是否存在,是否被 gc 掉,

  3. 已被 gc 将无法恢复

  4. 未被 gc 恢复流程

  5. drop table 3.0 可以使用 recover table 进行恢复,drop table / truncate table 4.0 可以使用 flashback table 进行恢复

  6. 还有办法是可以通过 mydumper 和 dumping 设置 snapshot 导出数据,在将数据导回。

2020年7月7日 17:50:23

1

tiup 在 鲲鹏云上部署可以使用 arm64 的安装包。

离线部署可以手动下文档中的地址并将 amd64 更改为 arm64 并且设置版本为 v4.0.2

2

pd 参数 key-type 使用注意

  • 可以将 key-type 设为 table,同时设置 enable-cross-table-merge 为 true
  • 如果此前设置 key-type 为 txn ,则不要切换成 raw,或者如果此前设置 key-type 为 raw,则不要切换成 txn,以免使用 placement-rules 时,decode 失败。

3

tikv 无法使用大页内存

2020年7月13日 18点58分

1

dm dump 阶段如果是大表备份可以使用 -r --row 来指定单词拿的行数

2

gc 相关

  • safepoint 和 gc 的问题
    • 如果一条 sql 在 5 点开始执行,gc 时间为 10min,safe point 会随着 gc 的时间不断刷新,直到当该 sql 需要在 safe point 之前拿数据就会出现报错。
      • 解决方案:调大 gc life time 的时间

2020年7月14日 22点34分

1

如果 tidb-server 中部分没有开启 tidb-binlog 可能出现 not found table id 的报错,因为 ddl owner 是在整个 tidb-server 中进行的,恰好 ddl owner 在没有开启 binlog 的 tidb-server 上,同步可能该错误。

2

mydumper 期间,发现当前 gc life time 不能满足备份要求,可以对 gc life time 继续调整,来保证备份的持续性。

3

drainer 同步数据是只保证同事务内顺序一致,如果存在主业务先插入 A 再插入 B,可能无法保证其顺序。

2020年8月5日 11:26:12

1

v3.0.17 之前 drainer 对于上游 mediumint 类型消费到 kafka 会以 string 的形式写进入,需要确认下游是如何消费这个消息的,来判断数据是否有问题。

2

hashagg 的内存统计目前还未统计到,如果 sql 在 hash agg 使用内存超了,导致 oom,那么调整 memory quota 是不起作用的。(tidb_mem_quota_hashjoin 参数已经失效,需要调整 oom-use-tmp-storage = true 和 tidb_mem_quota_query 来控制 sql 内存使用和使用策略)

3

pd-ctl store limit 看到 Tombstone 节点为正常显示,需要使用

4

tidb lightning checksum 时,Lightning 会自动将 GC 的生命周期增加到 100 小时,因为对于一个巨大的表,通常要花费 10 分钟以上的时间。这需要对 mysql.tidb 表具有 SELECT 和UPDATE 特权,否则将会报错:

  • [ERROR] [restore.go:605] [“restore table failed”] [table=db_img.project_pic] [takeTime=18m1.12739272s] [error=“restore table db_img.project_pic failed: obtain GC lifetime failed: Error 1142: SELECT command denied to user ‘test’@‘192.168.%’ for table ‘tidb’”]

5

max_execution_time v3.0.10 之前不生效,程序发起的 kill 操作,在 tidb backoff 并没有被检测到这个 kill信号,如果是 max_execution_time 发起的 kill 操作会有 [kill] [connID=xxxx] [query=true] 的日志打印

这个应该是,我们加 kill 检查的位置是在 executor.Next 里面

像一些比如 锁冲突重试, region cache miss 重试,

这些重试逻辑里面都没有检查 kill 信号

而这些重试逻辑持续了比较久,于是导致了前面观察到的现象

延伸:
[query=true] 表示 show processlist - Command = query。
false 为 conn 状态。

6

gRPC message count没有大的变化,但是 gRPC message duration 从1ms飙涨到几十ms.同时间段内

  • 调整 TiKV 相关配置 rate-bytes-per-sec = 30MB 进行 Compaction 限流
  • 磁盘 IO 性能问题,导致 compaction 时影响正常读写操作
  • ONCALL-1046

2020年8月31日 14:35:39

1

show stats_healthy 经验值为当 health 字段小于 80 需要进行 analyze table 操作。

官方文档建议小于 60 需要进行 analyze table 操作

2

dm 支持上游执行 alter table add col1, add col2; dm 会对其进行拆分多个 alter table 语句在 tidb 中执行。同等效果的 alter table add column (col1 int, col2 int); 目前是不支持的。

3

dm - 使用 query-status 中的信息执行 skip-sql 操作,需要使用 message - current pos 点位进行跳过

4

4.0.0 - 4.0.4

4.0 增加了一个 low space 的阈值判断条件,目前是写死的 100G。比如集群 3T,配置的 low-space-ratio 是 80%,原来的情况小于 600G 就会认为 low space,现在的话会在小于 100G 的时候,才认为 low space。同理,如果磁盘只有 300G,那这个时候就是按照 300*20%=60G 作为 low space 的界限。原有的配置和代码写死的参数取最小值。不过这个逻辑目前没有在文档中体现出来。

2020年9月17日 10:37:42

1

sync-log 在 v3.0.19+ 和 v4.0.7+ 将会被去掉,代码中将写死,值为 false,这个参数在 tidb 这边做了优化,true and false 将区别不大。

2

查看 tidb config 方式:

  1. select @@tidb_config;
  2. curl http://tidb-ip:tidb_status_port/config
  3. tidb.log search
  4. select * from INFORMATION_SCHEMA.CLUSTER_CONFIG where KEY like ‘%run-auto-analyze%’;