title | category |
---|---|
TiDB FAQ |
FAQ |
https://pingcap.com/docs-cn/overview/
TiDB 是一个分布式 NewSQL 数据库。它支持水平弹性扩展、ACID 事务、标准 SQL、MySQL 语法和 MySQL 协议,具有数据强一致的高可用特性,是一个不仅适合 OLTP 场景还适合 OLAP 场景的混合数据库。
不是,虽然 TiDB 支持 MySQL 语法和协议,但是 TiDB 是由 PingCAP 团队完全自主开发的产品。
- TiDB 是 Server 计算层,主要负责 SQL 的解析、制定查询计划、生成执行器。
- TiKV 是分布式 Key-Value 存储引擎,用来存储真正的数据,简而言之,TiKV 是 TiDB 的存储引擎。
- PD 是 TiDB 集群的管理组件,负责存储 TiKV 的元数据,同时也负责分配时间戳以及对 TiKV 做负载均衡调度。
TiDB 使用起来很简单,可以将 TiDB 集群当成 MySQL 来用,你可以将 TiDB 用在任何以 MySQL 作为后台存储服务的应用中,并且基本上不需要修改应用代码,同时你可以用大部分流行的 MySQL 管理工具来管理 TiDB。
TiDB 目前还不支持触发器、存储过程、自定义函数、外键,除此之外,TiDB 支持绝大部分 MySQL 5.7 的语法。
详情参见与 MySQL 兼容性对比。
TiDB 天然具备高可用特性,TiDB、TiKV、PD 这三个组件都能容忍部分实例失效,不影响整个集群的可用性。具体见 TiDB 高可用性。
TiDB 使用 Raft 在多个副本之间做数据同步,从而保证数据的强一致,单个副本失效时,不影响数据的可靠性。
TiDB 支持 ACID 分布式事务,事务模型是以 Google 的 Percolator 模型为基础,并做了一些优化。这个模型需要一个时间戳分配器,分配唯一且递增的时间戳。在 TiDB 集群中,PD 承担时间戳分配器的角色。
只要支持 MySQL Client/Driver 的编程语言,都可以直接使用 TiDB。
是的,除了 TiKV 之外,TiDB 还支持一些流行的单机存储引擎,比如 GolevelDB、RocksDB、BoltDB 等。如果一个存储引擎是支持事务的 KV 引擎,并且能提供一个满足 TiDB 接口要求的 Client,即可接入 TiDB。
从 TiDB 架构来讲,支持真正意义上的跨中心异地多活,从操作层面讲,依赖数据中心之间的网络延迟和稳定性,一般建议延迟在 5ms 以下,目前我们已经有相似客户方案,具体请咨询官方 info@pingcap.com。
目前官方文档是获取 TiDB 相关知识最主要、最及时的发布途径。除此之外,我们也有一些技术沟通群,如有需求可发邮件至 info@pingcap.com 获取。
详细可参考系统变量。
支持,但语义上和 MySQL 有区别,TiDB 是分布式数据库,采用的乐观锁机制,也就说 select for update 不在事务开启就锁住数据,而是其他事务在提交的时候进行冲突检查,如有冲突,会进行回滚。
TiDB 字符集默认就是 UTF8 而且目前只支持 UTF8,字符串就是 memcomparable 格式的。
在 TiDB 中用户名最长为 32 字符。
一个事务中的语句数量,默认限制最大为 5000 条。
虽然 TiDB 的 JDBC 驱动用的就是 MySQL JDBC(Connector / J),但是当使用 Atomikos 的时候,数据源要配置成类似这样的配置:type="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"
。MySQL JDBC XADataSource 连接 TiDB 的模式目前是不支持的。MySQL JDBC 中配置好的 XADataSource 模式,只对 MySQL 数据库起作用(DML 去修改 redo 等)。
Atomikos 配好两个数据源后,JDBC 驱动都要设置成 XA 模式,然后 Atomikos 在操作 TM 和 RM(DB)的时候,会通过数据源的配置,发起带有 XA 指令到 JDBC 层,JDBC 层 XA 模式启用的情况下,会对 InnoDB(如果是 MySQL 的话)下发操作一连串 XA 逻辑的动作,包括 DML 去变更 redo log 等,就是两阶段递交的那些操作。TiDB 目前的引擎版本中,没有对上层应用层 JTA / XA 的支持,不解析这些 Atomikos 发过来的 XA 类型的操作。
MySQL 是单机数据库,只能通过 XA 来满足跨数据库事务,而 TiDB 本身就通过 Google 的 Percolator 事务模型支持分布式事务,性能稳定性比 XA 要高出很多,所以不会也不需要支持 XA。
TiDB 的 show processlist
与 MySQL 的 show processlist
显示内容基本一样,不会显示系统进程号,而 ID 表示当前的 session ID。其中 TiDB 的 show processlist
和 MySQL 的 show processlist
区别如下:
1)由于 TiDB 是分布式数据库,tidb-server 实例是无状态的 SQL 解析和执行引擎(详情可参考 TiDB 整体架构),用户使用 MySQL 客户端登录的是哪个 tidb-server,show processlist
就会显示当前连接的这个 tidb-server 中执行的 session 列表,不是整个集群中运行的全部 session 列表;而 MySQL 是单机数据库,show processlist
列出的是当前整个 MySQL 数据库的全部执行 SQL 列表。
2)TiDB 的 show processlist
显示内容比起 MySQL 来讲,多了一个当前 session 使用内存的估算值(单位 Byte)。
TiDB 作为分布式数据库,在 TiDB 中修改用户密码建议使用 set password for 'root'@'%' = '0101001';
或 alter
方法,不推荐使用 update mysql.user
的方法进行,这种方法可能会造成其它节点刷新不及时的情况。修改权限也一样,都建议采用官方的标准语法。详情可参考 TiDB 用户账户管理。
TiDB 的自增 ID (AUTO_INCREMENT
) 只保证自增且唯一,并不保证连续分配。TiDB 目前采用批量分配的方式,所以如果在多台 TiDB 上同时插入数据,分配的自增 ID 会不连续。当多个线程并发往不同的 tidb-server 插入数据的时候,有可能会出现后插入的数据自增 ID 小的情况。此外,TiDB允许给整型类型的字段指定 AUTO_INCREMENT,且一个表只允许一个属性为 AUTO_INCREMENT
的字段。详情可参考数据定义语句。
TiDB 的 sql_mode 与 MySQL 的 sql_mode 设置方法有一些差别,TiDB 不支持配置文件配置设置数据库的 sql_mode,而只能使用 set 命令去设置,具体方法为:set @@global.sql_mode = 'STRICT_TRANS_TABLES';
。
这一层跟 MySQL 一样,走的 SASL 认证协议,用于用户登陆认证,对密码的处理流程。
客户端连接 TiDB 的时候,走的是 challenge-response(挑战-应答)的认证模式,过程如下:
第一步:客户端连接服务器;
第二步:服务器发送随机字符串 challenge 给客户端;
第三步:客户端发送 username + response 给服务器;
第四步:服务器验证 response。
Linux 操作系统平台 | 版本 |
---|---|
Red Hat Enterprise Linux | 7.3 及以上 |
CentOS | 7.3 及以上 |
Oracle Enterprise Linux | 7.3 及以上 |
TiDB 作为一款开源分布式 NewSQL 数据库,可以很好的部署和运行在 Intel 架构服务器环境及主流虚拟化环境,并支持绝大多数的主流硬件网络,作为一款高性能数据库系统,TiDB 支持主流的 Linux 操作系统环境,具体可以参考 TiDB 的官方部署要求。其中 TiDB 在 CentOS 7.3 的环境下进行大量的测试,同时也有很多这个操作系统的部署最佳实践,因此,我们推荐客户在部署 TiDB 的时候使用 CentOS 7.3+ 以上的Linux 操作系统。
TiDB 支持部署和运行在 Intel x86-64 架构的 64 位通用硬件服务器平台。对于开发,测试,及生产环境的服务器硬件配置有以下要求和建议:
组件 | CPU | 内存 | 本地存储 | 网络 | 实例数量(最低要求) |
---|---|---|---|---|---|
TiDB | 8核+ | 16 GB+ | SAS, 200 GB+ | 千兆网卡 | 1(可与 PD 同机器) |
PD | 8核+ | 16 GB+ | SAS, 200 GB+ | 千兆网卡 | 1(可与 TiDB 同机器) |
TiKV | 8核+ | 32 GB+ | SSD, 200 GB+ | 千兆网卡 | 3 |
服务器总计 | 4 |
组件 | CPU | 内存 | 硬盘类型 | 网络 | 实例数量(最低要求) |
---|---|---|---|---|---|
TiDB | 16核+ | 48 GB+ | SAS | 万兆网卡(2块最佳) | 2 |
PD | 8核+ | 16 GB+ | SSD | 万兆网卡(2块最佳) | 3 |
TiKV | 16核+ | 48 GB+ | SSD | 万兆网卡(2块最佳) | 3 |
监控 | 8核+ | 16 GB+ | SAS | 千兆网卡 | 1 |
服务器总计 | 9 |
作为一个分布式集群,TiDB 对时间的要求还是比较高的,尤其是 PD 需要分发唯一的时间戳,如果 PD 时间不统一,如果有 PD 切换,将会等待更长的时间。2 块网卡可以做 bond,保证数据传输的稳定,万兆可以保证数据传输的速度,千兆网卡容易出现瓶颈,我们强烈建议使用万兆网卡。
资源可接受的话,我们建议做 RAID 10,如果资源有限,也可以不做 RAID。
- TiDB 需要 CPU 和内存比较好的机器,参考官网配置要求,如果后期需要开启 Binlog,根据业务量的评估和 GC 时间的要求,也需要本地磁盘大一点,不要求 SSD 磁盘;
- PD 里面存了集群元信息,会有频繁的读写请求,对磁盘 I/O 要求相对比较高,磁盘太差会影响整个集群性能,推荐 SSD 磁盘,空间不用太大。另外集群 Region 数量越多对 CPU、内存的要求越高;
- TiKV 对 CPU、内存、磁盘要求都比较高,一定要用 SSD 磁盘。
详情可参考 TiDB 软硬件环境需求。
详细可参考 TiDB Ansible 部署方案。
这种情况一般是因为没有使用 --config
参数来指定配置文件(目前只会出现在 binary 部署的场景),TiKV/PD 会按默认值来设置。如果要使用配置文件,请设置 TiKV/PD 的 --config
参数。对于 TiKV 组件,修改配置后重启服务即可;对于 PD 组件,只会在第一次启动时读取配置文件,之后可以使用 pd-ctl 的方式来修改配置,详情可参考 https://pingcap.com/docs-cn/tools/pd-control/。
监控机建议单独部署。建议 CPU 8 core,内存 16 GB 以上,硬盘 500 GB 以上。
查看访问监控的机器时间跟集群内机器的时间差,如果比较大,更正时间后即可显示正常。
- supervise 守护进程
- svc 启停服务
- svstat 查看进程状态
变量 | 含义 |
---|---|
cluster_name | 集群名称,可调整 |
tidb_version | TiDB 版本,TiDB-Ansible 各分支默认已配置 |
deployment_method | 部署方式,默认为 binary,可选 docker |
process_supervision | 进程监管方式,默认为 systemd,可选 supervise |
timezone | 修改部署目标机器时区,默认为 Asia/Shanghai, 可调整,与set_timezone 变量结合使用 |
set_timezone | 默认为 True,即修改部署目标机器时区,关闭可修改为 False |
enable_elk | 目前不支持,请忽略 |
enable_firewalld | 开启防火墙,默认不开启 |
enable_ntpd | 检测部署目标机器 NTP 服务,默认为 True,请勿关闭 |
machine_benchmark | 检测部署目标机器磁盘 IOPS,默认为 True,请勿关闭 |
set_hostname | 根据 IP 修改部署目标机器主机名,默认为 False |
enable_binlog | 是否部署 pump 并开启 binlog,默认为 False,依赖 Kafka 集群,参见 zookeeper_addrs 变量 |
zookeeper_addrs | binlog Kafka 集群的 zookeeper 地址 |
enable_slow_query_log | TiDB 慢查询日志记录到单独文件({{ deploy_dir }}/log/tidb_slow_query.log),默认为 False,记录到 tidb 日志 |
deploy_without_tidb | KV 模式,不部署 TiDB 服务,仅部署 PD、TiKV 及监控服务,请将 inventory.ini 文件中 tidb_servers 主机组 IP 设置为空。 |
首先这不是我们建议的方式,如果中控机没有外网,也可以通过离线 Ansible 部署方式,详情可参考 https://pingcap.com/docs-cn/op-guide/offline-ansible-deployment/。
使用 docker-compose 在本地一键拉起一个集群,包括集群监控,还可以根据需求自定义各个组件的软件版本和实例个数,以及自定义配置文件,这种只限于开发环境,详细可参考官方文档。
1)TiDB 中,对慢查询的定义在 tidb-ansible 的 conf/tidb.yml
配置文件中,slow-threshold: 300
,这个参数是配置慢查询记录阈值的,单位是 ms。
慢查询日志默认记录到 tidb.log 中,如果希望生成单独的慢查询日志文件,修改 inventory.ini 配置文件的参数 enable_slow_query_log
为 True。
如上配置修改之后,需要执行 ansible-playbook rolling_update.yml --tags=tidb
,对 tidb-server 实例进行滚动升级,升级完成后,tidb-server 将在 tidb_slow_query.log
文件中记录慢查询日志。
2)如果出现了慢查询,可以从 Grafana 监控定位到出现慢查询的 tidb-server 以及时间点,然后在对应节点查找日志中记录的 SQL 信息。
TiDB 的 Label 设置是与集群的部署架构相关的,是集群部署中的重要内容,是 PD 进行全局管理和调度的依据。如果集群在初期部署过程中没有设置 Label,需要在后期对部署结构进行调整,就需要手动通过 PD 的管理工具 pd-ctl 来添加 location-labels 信息,例如:config set location-labels "zone, rack, host"
(根据实际的 label 层级名字配置)。
pd-ctl 的使用参考 PD Control 使用说明。
Direct 模式就是把写入请求直接封装成 I/O 指令发到磁盘,这样是为了绕开文件系统的缓存,可以直接测试磁盘的真实的 I/O 读写能力。
- 随机读测试:
./fio -ioengine=libaio -bs=32k -direct=1 -thread -rw=randread -size=10G -filename=fio_randread_test.txt -name='PingCAP' -iodepth=4 -runtime=60
- 顺序写和随机读混合测试:
./fio -ioengine=libaio -bs=32k -direct=1 -thread -rw=randrw -percentage_random=100,0 -size=10G -filename=fio_randr_write_test.txt -name='PingCAP' -iodepth=4 -runtime=60
2.2.8 使用 TiDB Ansible 部署 TiDB 集群的时候,遇到 UNREACHABLE! "msg": "Failed to connect to the host via ssh: "
报错是什么原因?
有两种可能性:
-
ssh 互信的准备工作未做好,建议严格参照我们的官方文档步骤配置互信(详情可参考),并使用命令
ansible -i inventory.ini all -m shell -a 'whoami' -b
来验证互信配置是否成功。 -
如果涉及到单服务器分配了多角色的场景,例如多组件混合部署或单台服务器部署了多个 TiKV 实例,可能是由于 ssh 复用的机制引起这个报错,可以使用
ansible … -f 1
的选项来规避这个报错。
滚动升级 TiKV 节点( 只升级单独服务 )
ansible-playbook rolling_update.yml --tags=tikv
滚动升级所有服务
ansible-playbook rolling_update.yml
滚动升级 TiDB 服务,滚动升级期间不影响业务运行,需要配置最小集群拓扑(TiDB * 2、PD * 3、TiKV * 3),如果集群环境中有 Pump/Drainer 服务,建议先停止 Drainer 后滚动升级(升级 TiDB 时会升级 Pump)。
Binary 不是我们建议的安装方式,对升级支持也不友好,建议换成 Ansible 部署。
常规需要一起升,因为整个版本都是一起测试的,单独升级只限当发生一个紧急故障时,需要单独对一个有问题的角色做升级。
可能有以下几种原因:进程没有正常启动;端口被占用;进程没有正常停掉;停掉集群的情况下使用 rolling_update.yml 来升级集群(操作错误)。
处理方式:登录到相应节点查看进程或者端口的状态;纠正错误的操作步骤。
任务 | Playbook |
---|---|
启动集群 | ansible-playbook start.yml |
停止集群 | ansible-playbook stop.yml |
销毁集群 | ansible-playbook unsafe_cleanup.yml (若部署目录为挂载点,会报错,可忽略) |
清除数据(测试用) | ansible-playbook cleanup_data.yml |
滚动升级 | ansible-playbook rolling_update.yml |
滚动升级 TiKV | ansible-playbook rolling_update.yml --tags=tikv |
滚动升级除 PD 外模块 | ansible-playbook rolling_update.yml --skip-tags=pd |
滚动升级监控组件 | ansible-playbook rolling_update_monitor.yml |
和 MySQL 登陆方式一样,可以按照下面例子进行登陆。
mysql -h 127.0.0.1 -uroot -P4000
和 MySQL 一样,TiDB 也分为静态参数和固态参数,静态参数可以直接通过set global xxx = n
的方式进行修改,不过新参数值只限于该实例生命周期有效。
默认在 ${data-dir}/data/ 目录下,其中包括 backup、db、raft、snap 四个目录,分别存储备份、数据、raft 数据及镜像数据。
和 MySQL 类似,TiDB 中也有系统表,用于存放数据库运行时所需信息,具体信息参考 TiDB 系统数据库文档。
默认情况下各节点服务器会在日志中输出标准错误,如果启动的时候通过 --log-file
参数指定了日志文件,那么日志会输出到指定的文件中,并且按天做 rotation。
如果是用 Ansible 部署的,可以使用 ansible-playbook stop.yml
命令停止 TiDB 集群。如果不是 Ansible 部署的,可以直接 kill 掉所有服务。如果使用 kill 命令,TiDB 的组件会做 graceful 的 shutdown。
- 可以 kill DML 语句,首先使用
show processlist
,找到对应 session 的 id,然后执行kill tidb [session id]
。 - 可以 kill DDL 语句,首先使用
admin show ddl jobs
,查找需要 kill 的 DDL job ID,然后执行admin cancel ddl jobs 'job_id' [, 'job_id'] ...
。具体可以参考 admin 操作。
TiDB 暂不支持数据库层面的会话超时,目前想要实现超时,在没 LB(Load Balancing)的时候,需要应用侧记录发起的 Session 的 ID,通过应用自定义超时,超时以后需要到发起 Query 的节点上用 kill tidb [session id]
来杀掉 SQL。目前建议使用应用程序来实现会话超时,当达到超时时间,应用层就会抛出异常继续执行后续的程序段。
TiDB 版本目前逐步标准化,每次 Release 都包含详细的 Change log,版本功能变化详情,生产环境是否有必要升级取决于业务系统,建议升级之前详细了解前后版本的功能差异。
版本号说明参考:Release Version: v1.0.3-1-ga80e796
v1.0.3
表示 GA 标准版1
表示该版本 commit 1 次ga80e796
代表版本的git-hash
TiDB 目前社区非常活跃,在 1.0 GA 版本发布后,还在不断的优化和修改 BUG,因此 TiDB 的版本更新周期比较快,会不定期有新版本发布,请关注我们的新版本发布官方网站。此外 TiDB 安装推荐使用 TiDB-Ansible 进行安装,TiDB-Ansible 的版本也会随着 TiDB 的版本发布进行更新,因此建议用户在安装升级新版本的时候使用最新的 TiDB-Ansible 安装包版本进行安装。此外,在 TiDB 1.0 GA 版本后,对 TiDB 的版本号进行了统一管理,TiDB 的版本可以通过以下两种方式进行查看:
- 通过
select tidb_version()
进行查看 - 通过执行
tidb-server -V
进行查看
暂时没有。
当您的业务不断增长时,数据库可能会面临三方面瓶颈,第一是存储空间,第二是计算资源,第三是读写容量,这时可以对 TiDB 集群做水平扩展。
- 如果是存储资源不够,可以通过添加 TiKV Server 节点来解决,新节点启动后,PD 会自动将其他节点的部分数据迁移过去,无需人工介入。
- 如果是计算资源不够,可以查看 TiDB Server 和 TiKV Server 节点的 CPU 消耗情况,再考虑添加 TiDB Server 节点或者是 TiKV Server 节点来解决,如添加 TiDB Server 节点,将其添加到前端 Load Balancer 配置之中即可。
- 如果是容量跟不上,一般可以考虑同时增加 TiDB Server 和 TiKV Server 节点。
详细可参考 https://pingcap.com/blog-cn/percolator-and-txn/。
不只是因为 Google 在用,有一些比较好的特性我们需要,比如流控、加密还有 Streaming。
转义字符是那个,默认是 (ASCII 92)
PD 的大部分 API 需要在初始化 TiKV 集群以后才能使用,如果在部署新集群的时候只启动了 PD,还没有启动 TiKV,这时候访问 PD 就会报这个错误。遇到这个错误应该先把要部署的 TiKV 启动起来,TiKV 会自动完成初始化工作,然后就可以正常访问 PD。
PD 启动参数中的 --initial-cluster
包含了某个不属于该集群的成员。遇到这个错误时请检查各个成员的所属集群,剔除错误的成员后即可正常启动。
理论上误差越小越好,切换 leader 的时候如果时钟回退,就会卡住直到追上之前的 leader。这个容忍是业务上的,PD 多长的误差都能容忍。但是误差越大,主从切换的时候,停止服务的时间越长。
Client 连接只能通过 TiDB 访问集群,TiDB 负责连接 PD 与 TiKV,PD 与 TiKV 对 Client 透明。当 TiDB 连接任意一台 PD 的时候,PD 会告知 TiDB 当前的 leader 是谁,如果此台 PD 不是 leader,TiDB 将会重新连接至 leader PD。
- leader-schedule-limit 调度是用来均衡不同 TiKV 的 leader 数,影响处理查询的负载。
- region-schedule-limit 调度是均衡不同 TiKV 的副本数,影响不同节点的数据量。
可以,目前只能调整全局的 replica 数量。首次启动时 PD 会读配置文件(conf/pd.yml),使用其中的 max-replicas 配置,之后修改需要使用 pd-ctl 配置命令 config set max-replicas $num
,配置后可通过 config show all
来查看已生效的配置。调整的时候,不会影响业务,会在后台添加,注意总 TiKV 实例数总是要大于等于设置的副本数,例如 3 副本需要至少 3 个 TiKV。增加副本数量之前需要预估额外的存储需求。pd-ctl 的详细用法可参考 PD Control 使用说明。
可以通过 pd-ctl 等工具来判断集群大概的状态,详细的集群状态还是需要通过监控来确认。
下线节点一般指 TiKV 节点通过 pd-ctl 或者监控判断节点是否下线完成。节点下线完成后,手动停止下线节点上相关的服务。从 Prometheus 配置文件中删除对应节点的 node_exporter 信息。从 Ansible inventory.ini 中删除对应节点的信息。
因为使用 TiDB Ansible 部署的集群,PD 对外服务端口不会绑定到 127.0.0.1,所以 PD Control 不会识别 127.0.0.1。
启动 TiDB Server 时,需要通过命令行参数设置 lease 参数(--lease=60),其值会影响 DDL 的速度(只会影响当前执行 DDL 的 session,其他的 session 不会受影响)。在测试阶段,lease 的值可以设为 1s,加快测试进度;在生产环境下,我们推荐这个值设为分钟级(一般可以设为 60),这样可以保证 DDL 操作的安全。
一般情况下处理一个 DDL 操作(之前没有其他 DDL 操作在处理)的耗时基本可以分如下为三种:
- add index 操作,且此操作对应表数据行数比较少,耗时约为 3s。
- add index 操作,且此操作对应表数据行数比较多,耗时具体由表中数据行数和当时 QPS 情况定(add index 操作优先级比一般 SQL 低)。
- 其他 DDL 操作耗时约为 1s。
此外,如果接收 DDL 请求的 TiDB 和 DDL owner 所处的 TiDB 是一台,那么上面列举的第一和第三种可能的耗时应该在几十到几百毫秒。
可能原因如下:
- 多个 DDL 语句一起执行的时候,后面的几个 DDL 语句会比较慢。原因是当前 TiDB 集群中 DDL 操作是串行执行的。
- 在正常集群启动后,第一个 DDL 操作的执行时间可能会比较久,一般在 30s 左右,这个原因是刚启动时 TiDB 在竞选处理 DDL 的 leader。
- 由于停 TiDB 时不能与 PD 正常通信(包括停电情况)或者用
kill -9
指令停 TiDB 导致 TiDB 没有及时从 PD 清理注册数据,那么会影响 TiDB 启动后 10min 内的 DDL 语句处理时间。这段时间内运行 DDL 语句时,每个 DDL 状态变化都需要等待 2 * lease(默认 lease = 45s)。 - 当集群中某个 TiDB 与 PD 之间发生通信问题,即 TiDB 不能从 PD 及时获取或更新版本信息,那么这时候 DDL 操作的每个状态处理需要等待 2 * lease。
不可以,目前 TiDB 只支持分布式存储引擎和 Goleveldb/Rocksdb/Boltdb 引擎。
Infomation_schema 库里面的表主要是为了兼容 MySQL 而存在,有些第三方软件会查询里面的信息。在目前 TiDB 的实现中,里面大部分只是一些空表。后续随着 TiDB 的升级,会提供更多的参数信息。当前 TiDB 支持的:Infomation_schema 请参考 TiDB 系统数据库说明文档。
TiDB-server 与 TiKV-server 随时进行通信,在进行大量数据操作过程中,会出现 Server is busy 或者 backoff.maxsleep 20000ms 的日志提示信息,这是由于 TiKV-server 在处理过程中系统比较忙而出现的提示信息,通常这时候可以通过系统资源监控到 TiKV 主机系统资源使用率比较高的情况出现。如果这种情况出现,可以根据资源使用情况进行相应的扩容操作。
TiClient Region Error 该指标描述的是在 TiDB-server 作为客户端通过 KV 接口访问 TiKV-server 进行数据操作过程中,TiDB-server 操作 TiKV-server 中的 Region 数据出现的错误类型与 mertic 指标,错误类型包括 not_leader、stale_epoch。出现这些错误的情况是当 TiDB-server 根据自己的缓存信息去操作 Region leader 数据的时候,Region leader 发生了迁移或者 TiKV 当前的 Region 信息与 TiDB 缓存的路由信息不一致而出现的错误提示。一般这种情况下,TiDB-server 都会自动重新从 PD 获取最新的路由数据,重做之前的操作。
当前版本 TiDB 没有最大连接数的限制,如果并发过大导致响应时间增加,可以通过增加 TiDB 节点进行扩容。
information_schema 库中的 tables 表里的 create_time 即为表的真实创建时间。
TiDB 在执行 SQL 时,预估出来每个 operator 处理了超过 10000 条数据就认为这条 query 是 expensive query。可以通过修改 tidb-server 配置参数来对这个门限值进行调整,调整后需要重新启动 tidb-server。
TiDB 中高优先级和低优先级的语法元素如下:
- HIGH_PRIORITY:该语句为高优先级语句,TiDB 在执行阶段会优先处理这条语句
- LOW_PRIORITY:该语句为低优先级语句,TiDB 在执行阶段会降低这条语句的优先级
以上两种参数可以结合 TiDB 的 DML 语言进行使用,具体使用方式可以参考官方文档,使用方法举例如下:
1)通过在数据库中写 SQL 的方式来调整优先级:
select HIGH_PRIORITY | LOW_PRIORITY count(*) from table_name;
insert HIGH_PRIORITY | LOW_PRIORITY into table_name insert_values;
delete HIGH_PRIORITY | LOW_PRIORITY from table_name;
update HIGH_PRIORITY | LOW_PRIORITY table_reference set assignment_list where where_condition;
replace HIGH_PRIORITY | LOW_PRIORITY into table_name;
2)全表扫会自动调整为低优先级,analyze 也是默认低优先级。
触发策略:新表达到 1000 条,并且在 1 分钟内没有写入,会自动触发。
当表的(修改数/当前总行数)大于 tidb_auto_analyze_ratio
的时候,会自动触发 analyze 语句。tidb_auto_analyze_ratio
的默认值为 0,即关闭此功能。为了保险起见,在开启此功能的时候,保证了其最小值为 0.3。但是不能大于等于 pseudo-estimate-ratio
(默认值为 0.7),否则会有一段时间使用 pseudo 统计信息,建议设置值为 0.5。
同 MySQL 的 用法一致,例如:
select column_name from table_name use index(index_name)where where_condition;
一般建议 3 副本即可,副本升高,性能会有下降,但是安全性更高。是否设置更多副本需要看具体业务需要。
TiKV 本地存储的 cluster ID 和指定的 PD 的 cluster ID 不一致。在部署新的 PD 集群的时候,PD 会随机生成一个 cluster ID,TiKV 第一次初始化的时候会从 PD 获取 cluster ID 存储在本地,下次启动的时候会检查本地的 cluster ID 与 PD 的 cluster ID 是否一致,如果不一致则会报错并退出。出现这个错误一个常见的原因是,用户原先部署了一个集群,后来把 PD 的数据删除了并且重新部署了新的 PD,但是 TiKV 还是使用旧的数据重启连到新的 PD 上,就会报这个错误。
启动参数中的地址已经被其他的 TiKV 注册在 PD 集群中了。造成该错误的常见情况:TiKV --data-dir
指定的路径下没有数据文件夹(删除或移动后没有更新 --data-dir),用之前参数重新启动该 TiKV。请尝试用 pd-ctl 的 store delete 功能,删除之前的 store,然后重新启动 TiKV 即可。
目前来看 master 有些文件的压缩率会高一些,这个取决于底层数据的分布和 RocksDB 的实现,数据大小偶尔有些波动是正常的,底层存储引擎会根据需要调整数据。
TiKV 使用了 RocksDB 的 Column Family (CF) 特性,KV 数据最终存储在默认 RocksDB 内部的 default、write、lock 3 个 CF 内。
- default CF 存储的是真正的数据,与其对应的参数位于 [rocksdb.defaultcf] 项中。
- write CF 存储的是数据的版本信息(MVCC)、索引、小表相关的数据,相关的参数位于 [rocksdb.writecf] 项中。
- lock CF 存储的是锁信息,系统使用默认参数。
- Raft Rocksdb 实例存储 Raft log。default CF 主要存储的是 Raft log,与其对应的参数位于 [raftdb.defaultcf] 项中。
- 每个 CF 都有单独的 Block-cache,用于缓存数据块,加速 RocksDB 的读取速度,Block-cache 的大小通过参数
block-cache-size
控制,block-cache-size
越大,能够缓存的热点数据越多,对读取操作越有利,同时占用的系统内存也会越多。 - 每个 CF 有各自的 Write-buffer,大小通过
write-buffer-size
控制。
- Raftstore 线程卡了,可以看一下 Raftstore 的 CPU 使用情况。
- TiKV 太忙了(读取、写入、磁盘 I/O 等),请求处理不过来。
- 网络问题导致节点间通信卡了,查看 Report failures 监控。
- 原主 Leader 的节点卡了,导致没有及时给 Follower 发送消息。
- Raftstore 线程卡了。
TiDB 使用 Raft 在多个副本之间做数据同步,从而保证数据的强一致,当一份备份出现问题时,其他的副本能保证数据的安全。通常 TiDB 配置每个 Region 为 3 副本,根据 Raft 协议,每个 Region 会选取一个 Leader 提供服务。但单个 Region Leader 失效时,在最大 2 * lease time(leasetime 是 10 秒)时间后,通过 Raft 协议会很快选新的 Region Leader 提供服务。
在大量写入、读取的场景中会占用大量的磁盘 IO、内存、CPU。在执行很复杂的查询,比如会产生很大中间结果集的情况下,会消耗很多的内存和 CPU 资源。
不可以使用,TiDB 在进行 OLTP 场景中,数据访问和操作需要高 IO 磁盘的支持,TiDB 作为强一致的分布式数据库,存在一定的写放大,如副本复制、存储底层 Compaction,因此,TiDB 部署的最佳实践中推荐用户使用 NVMe SSD 磁盘作为数据存储磁盘。另外,TiKV 与 PD 不能混合部署。
不是的,这个和 MySQL 分表规则不一样,需要提前设置好,TiKV 是根据 Region 的大小动态分裂的。
首先不是前期划分好的,但确实有 Region 分裂机制,有一个参数 region_split_size
,超过这个值就会触发分裂,分裂后的信息会汇报给 PD。
是的,TiKV 单机的存储引擎目前使用两个 RocksDB 实例,其中一个存储 raft-log,TiKV 有个 sync-log 参数,在 ture 的情况下,每次提交都会强制刷盘到 raft-log,如果发生 crash 后,通过 raft-log 进行 KV 数据的恢复。
WAL 属于顺序写,目前我们并没有单独对他进行配置,建议 SSD,RAID 如果允许的话,最好是 RAID 10,RAID 卡 cache、操作系统 I/O 调度目前没有针对性的最佳实践,Linux 7 以上默认配置即可,NUMA 没有特别建议,NUMA 内存分配策略可以尝试使用 interleave = all
,文件系统建议 ext4。
一般来说开启 sync-log 性能损耗大概 30% 左右,官方有个 sync-log = false
的基准测试,可以参考 https://github.com/pingcap/docs-cn/blob/master/benchmark/sysbench.md。
Raft 是强一致复制,写入必须同时超过 50% 的节点接受、应用才返回 ACK(三节点中二节点),在这种情况下,数据一致性是可以保证的,但理论上两个节点也可能同时 Crash,所以在诸如金融行业对数据零容忍的场景,还是需要开启 sync-log。
理论上和单机数据库比,多四个网络延迟。
TiKV 支持单独进行接口调用,理论上也可以起个实例做为 Cache,但 TiDB 最大的价值是分布式关系型数据库,我们原则上不对 TiKV 单独进行支持。
- 减少 TiDB 与 TiKV 之间的数据传输。
- 计算下推,充分利用 TiKV 的分布式计算资源。
这是磁盘空间不足导致的,需要加节点或者扩大磁盘空间。
很多用户在接触 TiDB 都习惯做一个基准测试或者 TiDB 与 MySQL 的对比测试,官方也做了一个类似测试,汇总很多测试结果后,我们发现虽然测试的数据有一定的偏差,但结论或者方向基本一致,由于 TiDB 与 MySQL 由于架构上的差别非常大,很多方面是很难找到一个基准点,所以官方的建议两点:
- 大家不要用过多精力纠结这类基准测试上,应该更多关注 TiDB 的场景上的区别。
- 大家可以直接参考官方相关测试。官方 Sysbench 测试及 TiDB 与 MySQL 对比测试请参考 https://github.com/pingcap/docs-cn/blob/master/benchmark/sysbench.md。
- 在 10 节点内,TiDB 写入能力(Insert TPS)和节点数量基本成 40% 线性递增,MySQL 由于是单节点写入,所以不具备写入扩展能力。
- MySQL 读扩容可以通过添加从库进行扩展,但写流量无法扩展,只能通过分库分表,而分库分表有很多问题,具体参考 http://t.cn/RTD18qV。
- TiDB 不管是读流量、还是写流量都可以通过添加节点快速方便的进行扩展。
TiDB 设计的目标就是针对 MySQL 单台容量限制而被迫做的分库分表的场景,或者需要强一致性和完整分布式事务的场景。它的优势是通过尽量下推到存储节点进行并行计算。对于小表(比如千万级以下),不适合 TiDB,因为数据量少,Region 有限,发挥不了并行的优势,最极端的就是计数器表,几行记录高频更新,这几行在 TiDB 里,会变成存储引擎上的几个 KV,然后只落在一个 Region 里,而这个 Region 只落在一个节点上。加上后台强一致性复制的开销,TiDB 引擎到 TiKV 引擎的开销,最后表现出来的就是没有单个 MySQL 好。
目前 TiDB 主要依赖 mydumper 逻辑导出进行备份,具体可以参考 https://github.com/maxbube/mydumper,虽然 TiDB 也支持使用 MySQL 官方的 mysqldump 工具来进行数据的备份恢复工作,但相比于 mydumper/loader,性能会慢很多,大量数据的备份恢复会花费很多时间,这里我们并不推荐。
使用 mydumper 导出来的数据文件尽可能的小, 最好不要超过 64M, 可以设置参数 -F 64;
loader的 -t 参数可以根据 TiKV 的实例个数以及负载进行评估调整,例如 3 个 TiKV 的场景, 此值可以设为 3 * (1 ~ n),当 TiKV 负载过高,loader 以及 TiDB 日志中出现大量 backoffer.maxSleep 15000ms is exceeded
可以适当调小该值,当 TiKV 负载不是太高的时候,可以适当调大该值。
具体可以参考 https://github.com/maxbube/mydumper。
具体可以参考 https://www.pingcap.com/docs-cn/tools/loader/。
TiDB 支持绝大多数 MySQL 语法,一般不需要修改代码。我们提供了一个检查工具,用于检查 MySQL 中的 Schema 是否和 TiDB 兼容。
重启 TiDB 服务,配置文件中增加 -skip-grant-table=true
参数,无密码登陆集群后,可以根据情况重建用户,或者重建 mysql.user 表,具体表结构搜索官网。
TiDB 目前暂时不支持 select into outfile
,可以通过以下方式导出 TiDB 数据:参考 MySQL 使用 mysqldump 导出某个表的部分数据,使用 mysqldump 加 where 条件导出,使用 MySQL client 将 select 的结果输出到一个文件。
DB2、Oracle 到 TiDB 数据迁移(增量+全量),通常做法有:
- 使用 Oracle 官方迁移工具,如 OGG、Gateway(透明网关)、CDC(Change Data Capture)。
- 自研数据导出导入程序实现。
- 导出(Spool)成文本文件,然后通过 Load infile 进行导入。
- 使用第三方数据迁移工具。
目前看来 OGG 最为合适。
4.1.7 用 Sqoop 批量写入 TiDB 数据,虽然配置了 --batch
选项,但还是会遇到 java.sql.BatchUpdateExecption:statement count 5001 exceeds the transaction limitation
的错误,该如何解决?
- 在 Sqoop 中,
--batch
是指每个批次提交 100 条 statement,但是默认每个 statement 包含 100 条 SQL 语句,所以此时 100 * 100 = 10000 条 SQL 语句,超出了 TiDB 的事务限制 5000 条,可以增加选项-Dsqoop.export.records.per.statement=10
来解决这个问题,完整的用法如下:
sqoop export \
-Dsqoop.export.records.per.statement=10 \
--connect jdbc:mysql://mysql.example.com/sqoop \
--username sqoop ${user} \
--password ${passwd} \
--table ${tab_name} \
--export-dir ${dir} \
--batch
- 也可以选择增大 tidb 的单个事物语句数量限制,不过这个会导致内存上涨。
详细参考 https://pingcap.com/blog-cn/tidb-syncer/。
详细参考 https://pingcap.com/docs-cn/tools/syncer/。
下载 Syncer Json 导入到 Grafana,修改 Prometheus 配置文件,添加以下内容:
- job_name: 'syncer_ops' // 任务名字 static_configs:
- targets: ['10.10.1.1:10096'] //syncer监听地址与端口,通知 prometheus 拉取 syncer 的数据。
重启 Prometheus 即可。
没有,目前依赖程序自行实现。
支持,具体参考 Syncer 使用手册 Syncer 使用文档
频繁执行 DDL 对同步速度会有影响。对于 Sycner 来说,DDL 是串行执行的,当同步遇到了 DDL,就会以串行的方式执行,所以这种场景就会导致同步速度下降。
Wormhole 是一项数据同步服务,让用户能够通过 Web 控制台, 轻松操作数据的全量 + 增量同步,支持多种同、异构数据源之间的数据迁移,如 MySQL -> TiDB,MongoDB -> TiDB。具体可联系官方进行试用 info@pingcap.com。
4.2.3 使用 Syncer gtid 的方式同步时,同步过程中会不断更新 syncer.meta 文件,如果 Syncer 所在的机器坏了,导致 syncer.meta 文件所在的目录丢失,该如何处理?
当前 Syncer 版本的没有进行高可用设计,Syncer 目前的配置信息 syncer.meta 直接存储在硬盘上,其存储方式类似于其他 MySQL 生态工具,比如 mydumper。 因此,要解决这个问题当前可以有两个方法:
1)把 syncer.meta 数据放到比较安全的磁盘上,例如磁盘做好 raid1;
2)可以根据 Syncer 定期上报到 Prometheus 的监控信息来还原出历史同步的位置信息,该方法的位置信息在大量同步数据时由于延迟会可能不准确。
我们建议通过 Syncer 或 Wormhole 搭建成多源 MySQL、MongoDB -> TiDB 实时同步环境,读写流量可以按照需求分阶段通过修改网络配置进行流量迁移,建议 DB 上层部署一个稳定的网络 LB(HAproxy、LVS、F5、DNS 等),这样直接修改网络配置就能实现无缝流量迁移。
TiDB 读流量可以通过增加 TiDB server 进行扩展,总读容量无限制,写流量可以通过增加 TiKV 节点进行扩容,基本上写容量也没有限制。
由于分布式事务要做两阶段提交,并且底层还需要做 Raft 复制,如果一个事务非常大,会使得提交过程非常慢,并且会卡住下面的 Raft 复制流程。为了避免系统出现被卡住的情况,我们对事务的大小做了限制:
- 单条 KV entry 不超过 6MB
- KV entry 的总条数不超过 30w
- KV entry 的总大小不超过 100MB
在 Google 的 Cloud Spanner 上面,也有类似的限制。
导入数据的时候,可以分批插入,每批最好不要超过 1w 行。
对于 insert 和 select,可以开启 set @@session.tidb_batch_insert=1;
隐藏参数,insert 会把大事务分批执行。这样不会因为事务太大而超时,但是可能会导致事务原子性的丢失。如果事务执行过程中报错,会导致只完成一部分事务的插入。所以建议只有在需要的时候,在 session 中使用,这样不会影响其他语句。事务完成以后,可以用 set @@session.tidb_batch_insert=0
关闭。
对 delete 和 update 语句,可以使用 limit 加循环的方式进行操作。
DELETE,TRUNCATE 和 DROP 都不会立即释放空间。对于 TRUNCATE 和 DROP 操作,在达到 TiDB 的 GC (garbage collection) 时间后(默认 10 分钟),TiDB 的 GC 机制会删除数据并释放空间。对于 DELETE 操作 TiDB 的 GC 机制会删除数据,但不会释放空间,而是当后续数据写入 RocksDB 且进行 compact 时对空间重新利用。
不可以,加载数据期间不能对目标表执行任何 DDL 操作,这会导致数据加载失败。
支持,但是 load data 不支持 replace into 语法。
大量删除数据后,会有很多无用的 key 存在,影响查询效率。目前正在开发 Region Merge 功能,完善之后可以解决这个问题,具体看参考最佳实践中的删除数据部分。
在删除大量数据的时候,建议使用 Delete * from t where xx limit 5000
(xx 建议在满足业务过滤逻辑下,尽量加上强过滤索引列或者直接使用主键选定范围,如 id >= 5000*n+m and id <= 5000*(n+1)+m
这样的方案,通过循环来删除,用 Affected Rows == 0
作为循环结束条件,这样避免遇到事务大小的限制。如果一次删除的数据量非常大,这种循环的方式会越来越慢,因为每次删除都是从前向后遍历,前面的删除之后,短时间内会残留不少删除标记(后续会被 GC 掉),影响后面的 Delete 语句。如果有可能,建议把 Where 条件细化。可以参考官网最佳实践。
主要三个方面:
- 目前正在开发分布式导入工具 Lightning,需要注意的是数据导入过程中为了性能考虑,不会执行完整的事务流程,所以没办法保证导入过程中正在导入的数据的 ACID 约束,只能保证整个导入过程结束以后导入数据的 ACID 约束。因此适用场景主要为新数据的导入(比如新的表或者新的索引),或者是全量的备份恢复(先 Truncate 原表再导入)。
- TiDB 的数据加载与磁盘以及整体集群状态相关,加载数据时应关注该主机的磁盘利用率,TiClient Error/Backoff/Thread CPU 等相关 metric,可以分析相应瓶颈。
可以设置并行 GC,加快对空间的回收速度。默认并发为 1,最大可调整为 tikv 实例数量的 50%。可使用 update mysql.tidb set VARIABLE_VALUE="3" where VARIABLE_NAME="tikv_gc_concurrency";
命令来调整。
详细解读 https://pingcap.com/docs-cn/sql/understanding-the-query-execution-plan。
详细解读 https://pingcap.com/docs-cn/sql/statistics。
Count 就是暴力扫表,提高并发度能显著的提升速度,修改并发度可以参考 tidb_distsql_scan_concurrency
变量,但是也要看 CPU 和 I/O 资源。TiDB 每次查询都要访问 TiKV,在数据量小的情况下,MySQL 都在内存里,TiDB 还需要进行一次网络访问。
提升建议:
通过 admin show ddl
查看当前添加索引 job。
可以使用 admin show ddl
语句查看正在运行的 DDL 作业。
admin show ddl jobs
:用于查看当前 DDL 作业队列中的所有结果(包括正在运行以及等待运行的任务)以及已执行完成的 DDL 作业队列中的最近十条结果。admin show ddl job queries 'job_id' [, 'job_id'] ...
:用于显示job_id
对应的 DDL 任务的原始 SQL 语句。此job_id
只搜索正在执行中的任务以及 DDL 历史作业队列中的最近十条结果。
是的,TiDB 使用的基于成本的优化器(CBO),我们有一个小组单独会对代价模型、统计信息持续优化,除此之外,我们支持 hash join、soft merge 等关联算法。
可以通过 show stats_healthy
来查看 Healthy 字段,一般小于等于 60 的表需要做 analyze。
ID 没什么规律,只要是唯一就行,不过生成的时候,是有一个计数器,生成一个 plan 就加一,执行的顺序和序号无关,整个执行计划是一颗树,执行时从根节点开始,不断地向上返回数据。执行计划的理解,请参考理解 TiDB 执行计划。
目前 TiDB 的计算任务隶属于两种不同的 task:cop task 和 root task。cop task 是指被下推到 KV 端分布式执行的计算任务,root task 是指在 TiDB 端单点执行的计算任务。一般来讲 root task 的输入数据是来自于 cop task 的;但是 root task 在处理数据的时候,TiKV 上的 cop task 也可以同时处理数据,等待 TiDB 的 root task 拉取,所以从这个观点上来看,他们是并行的;但是存在数据上下游关系;在执行的过程中,某些时间段其实也是并行的,第一个 cop task 在处理 [100, 200] 的数据,第二个 cop task 在处理 [1, 100] 的数据。执行计划的理解,请参考理解 TiDB 执行计划。
详情参考 https://pingcap.com/docs-cn/sql/server-command-option。
TiDB 中以 Region 分片来管理数据库,通常来讲,TiDB 的热点指的是 Region 的读写访问热点。而 TiDB 中对于 PK 非整数或没有 PK 的表,可以通过设置 SHARD_ROW_ID_BITS
来适度分解 Region 分片,以达到打散 Region 热点的效果。详情可参考官网 TiDB 专用系统变量和语法中 SHARD_ROW_ID_BITS
的介绍。
详情参考 https://pingcap.com/docs-cn/op-guide/tune-tikv/。
详细参考 https://pingcap.com/docs-cn/op-guide/monitor-overview。
详细参考 https://pingcap.com/docs-cn/op-guide/dashboard-overview-info。
TiDB 使用 Prometheus + Grafana 组成 TiDB 数据库系统的监控系统,用户在 Grafana 上通过 dashboard 可以监控到 TiDB 的各类运行指标,包括系统资源的监控指标,包括客户端连接与 SQL 运行的指标,包括内部通信和 Region 调度的指标,通过这些指标,可以让数据库管理员更好的了解到系统的运行状态,运行瓶颈等内容。在监控指标的过程中,我们按照 TiDB 不同的模块,分别列出了各个模块重要的指标项,一般用户只需要关注这些常见的指标项。具体指标请参见官方文档。
可以的,在 Prometheus 启动的机器上,找到启动脚本,然后修改启动参数,然后重启 Prometheus 生效。
TiDB-2.0 版本中,PD metric 监控页面中,对 Region 健康度进行了监控,其中 Region Health 监控项是对所有 Region 副本状况的一些统计。其中 miss 是缺副本,extra 是多副本。同时也增加了按 Label 统计的隔离级别,level-1 表示这些 Region 的副本在第一级 Label 下是物理隔离的,没有配置 location label 时所有 Region 都在 level-0。
代表全表扫,但是可能是很小的系统表。
QPS 会统计执行的所有 SQL 命令,包括 use database、load data、begin、commit、set、show、insert、select 等。
Statement OPS 只统计 select、update、insert 等业务相关的,所以 Statement OPS 的统计和业务比较相符。
Cloud TiDB 目前已经在腾讯云、UCloud 上线,都是数据库一级入口,欢迎大家使用。
请求 PD 超时,请检查 PD Server 状态/监控/日志以及 TiDB Server 与 PD Server 之间的网络。
请求 TiKV 超时,请检查 TiKV Server 状态/监控/日志以及 TiDB Server 与 TiKV Server 之间的网络。
TiKV 操作繁忙,一般出现在数据库负载比较高时,请检查 TiKV Server 状态/监控/日志。
清理锁超时,当数据库上承载的业务存在大量的事务冲突时,会遇到这种错误,请检查业务代码是否有锁争用。
访问的 Region 不可用,某个 Raft Group 不可用,如副本数目不足,出现在 TiKV 比较繁忙或者是 TiKV 节点停机的时候,请检查 TiKV Server 状态/监控/日志。
GC Life Time
间隔时间过短,长事务本应读到的数据可能被清理了,可使用如下命令增加 GC Life Time
:
update mysql.tidb set variable_value='30m' where variable_name='tikv_gc_life_time';
其中 30m 代表仅清理 30 分钟前的数据,这可能会额外占用一定的存储空间。
- log 中是否有 panic
- dmesg 中是否有 oom,命令:
dmesg -T | grep -i oom
- 长时间没有访问,也会收到这个报错,一般是 tcp 超时导致的,tcp 长时间不用, 会被操作系统 kill。
这类问题一般是 TiDB 和 TiKV 版本不匹配,在升级过程尽量一起升级,避免版本 mismatch。
这个问题是因为在执行 LOAD DATA LOCAL
语句的时候,MySQL 客户端不允许执行此语句(即 local_infile
选项为 0)。解决方法是在启动 MySQL 客户端时,用 --local-infile=1
选项。具体启动指令类似:mysql --local-infile=1 -u root -h 127.0.0.1 -P 4000
。有些 MySQL 客户端需要设置而有些不需要设置,原因是不同版本的 MySQL 客户端对 local-infile
的默认值不同。
这个报错一般是 TiDB 访问 PD 出了问题,TiDB 后台有个 worker 会不断地从 PD 查询 safepoint,如果超过 100s 查不成功就会报这个错。一般是因为 PD 磁盘操作过忙、反应过慢,或者 TiDB 和 PD 之间的网络有问题。TiDB 常见错误码请参考错误码与故障诊断。