TiDB和Mysql的sql差异总结

简介

根据网上一些使用案例列出目前TiDB和mysql在使用上的区别和目前的遇到的常见问题及解决方案,当然具体的使用问题还需要大量的线下测试才能确认。

 

问题类型问题描述原因及解决办法
DDL在一个 DDL 里不能对多个列或者多个索引做操作。

ADD/DROP INDEX/COLUMN 操作目前不支持同时创建或删除多个索引或列,

需要拆分单独执行,官方表示 3.0 版本有计划改进。

建表语句执行速度相比 MySQL 较慢

多台 TiDB 的时候,Owner 和接收 create table 语句的 TiDB Server 不在一台 Server 上时,

可能比 MySQL 慢一些,每次操作耗时在 0.5s 左右,官方表示会在后续的版本中不断完善。

大表建索引时对业务有影响官方建议在业务低峰期操作,在 2.1 版本中已经增加了操作优先级以及并发读的控制,情况有改善。

TiDB 对于 MySQL 用户授权 SQL 语法的兼容支持尚不完善,

目前不支持 SHOW CREATE USER 语法,

有时候不得不读取系统表(mysql.user)来查看一个数据库账户的基本信息

希望后续版本优化
DML  

部分操作符查询优化器支持不够好,比如 or 操作符会使用 TableScan,

改写成 union all 可避免。

官方表示目前使用 or 操作符确实在执行计划上有可能不准确,

已经在改进计划中,后续 3.0 版本会有优化。

MySQL 事务中,可以通过影响条数,作为写入(或修改)是否成功的依据;

而在 TiDB 中,这却是不可行的。

原因:

对于 MySQL,当更新某条记录时,会先获取该记录对应的行级锁(排他锁),

获取成功则进行后续的事务操作,获取失败则阻塞等待。

对于 TiDB,使用 Percolator 事务模型:可以理解为乐观锁实现,事务开启、

事务中都不会加锁,而是在提交时才加锁。

解决方案:

在业务层,可以借助分布式锁,实现串行化处理,但是会增加开发成本。

对于热数据,数据量一般不大,但是查询频度很高,比如查询 sql 为:
SELECT * FROM t_job_record where status=0 
and execute_time<= 1546361579646

这个在 MySQL 中很高效的查询,在 TiDB 中虽然也可从索引检索,

但其耗时却不尽人意(百万级数据量,耗时百毫秒级)。

原因:在 TiDB 中,底层索引结构为 LSM-Tree。当从内存级的 C0 层查询不到数据时,

会逐层扫描硬盘中各层;且 merge 操作为异步操作,索引数据更新会存在一定的延迟,可能存在无效索引。

由于逐层扫描和异步 merge,使得查询效率较低。

解决方案:

尽可能缩小过滤范围,比如结合异步 job 获取记录频率,在保证不遗漏数据的前提下,

合理设置 execute_time 筛选区间,例如 1 小时,sql 改写为:

SELECT * FROM t_job_record  where status=0 and execute_time>1546357979646 
and execute_time<= 1546361579646
select count(1) tidb查询慢

原因:和上面类似。

tidb因为存储结构和查询方式的不同,tidb其实是暴力扫表。很多使用方也都反应慢,

这个是目前的TiDB的一个常见的问题。这里给出官方的解决方案:

 

尚不支持的sql语法:
  • 增加、删除主键
  • 非 UTF8 字符集
  • 视图(即将支持)、存储过程、触发器、部分内置函数
  • Event
  • 全文索引、空间索引
 
PD 

重启一个 PD 节点的时候,业务能捕捉到 PD 不可用的异常,

会报 PD server timeout 。

因为重启的是 Leader 节点,所以重启之前需要手动切换 Leader,然后进行重启。

官方建议这里可以通过重启前做 Leader 迁移来减缓,

另外后续 TiDB 也会对网络通讯相关参数进行梳理和优化。

pd-ctl 命令行参数解析严格,多一个空格会提示语法错误。官方表示低版本中可能会有这个问题,在 2.0.8 及以上版本已经改进。
TiDB

现在 TiDB 的 GC 对于每个 kv-instance 是单线程的,

当业务删除数据的量非常大时,会导致 GC 速度较慢,

很可能 GC 的速度跟不上写入。

目前可以通过增多 TiKV 个数来解决,长期需要靠 GC 改为多线程执行,后续版本会支持。
TiKV 存储空间放大问题

该问题属于 RocksDB,RocksDB 的空间放大系数最理想的值为 1.111,

官方建议在某些场景下通过 TiKV 开启 RocksDB 的 dynamic-level-bytes 以减少空间放大。

TiKV 容易发生 Write Stall

原因:

TiKV 底层有 2 个 RocksDB 作为存储。新写的数据写入 L0 层,当 RocksDB 的 L0 层数量达到一定数量,

就会发生减速,更高则发生 Stall,用来自我保护。

生 L0 文件过多可能的原因有 2 个:

 

  • 写入量大,Compact 完不成。
  • Snapshot 一直创建不完,导致堆积的副本一下释放,rocksdb-raft 创建大量的 L0 文件

解决:

TiKV调优:

  • 减缓 Raft Log Compact 频率(增大 raft-log-gc-size-limit、raft-log-gc-count-limit)
  • 加快 Snapshot 速度(整体性能、包括硬件性能)
  • 调整max-sub-compactions 、max-background-jobs参数等
添加 TiKV 节点后需要较长时间才能完成数据再平衡1TB 数据大约需要 24 个小时才能完成拷贝,建议在低峰期引入


TiDB和Mysql优缺点对比

简单总结一下TiDB的优缺点:

TiDB优点

  1. 高度兼容mysql协议,迁移成本低
  2. 高可用:相比于传统主从(M-S)复制方案,基于 Raft 的多数派选举协议可以提供金融级的 100% 数据强一致性保证,且在不丢失大多数副本的前提下,可以实现故障的自动恢复(auto-failover),无需人工介入。
  3. 支持海量数据,可拓展性强:分布式数据库,可通过增加TiKV节点拓展,支持分裂和自动迁移,对业务基本无感知。
  4. 和传统的分库分表,相比业务拓展性较强:传统的分库分表技术,开发和维护成本都较高,业务侵入性也较大,使用TiDB会明显降低 RD 和 DBA 的开发维护成本。
  5. 分布式事务

TiDB的不足

  1. 对机器配置门槛要求较高,特别是内存和CPU的要求很高,当数据量不大时会增加机器的资源使用成本。
  2. TiDB对sql的支持尚不完善,对一些sql的执行性能并不理想,一些复杂sql需要重新设计,还有一些mysql的功能并不支持。
  3. TiDB技术较新,尚在不断优化中,因此也容易踩坑。

综合

综上所述,个人认为和mysql相比,

  1. TiDB目前更适合TB级的海量数据处理,数据量越大,使用场景和优势越明显,
  2. 也比较适合对查询性能要求不高的数据分析场景或离线计算场景
  3. 即时场景下查询上最适合海量数据下进行多维度的精确查询
  4. 整体而言TiDB技术仍不能算成熟,目前还在快速的更新和迭代过程中,容易采坑,建议引入也是先从离线业务->非核心业务->核心业务的使用过程。

 

 

 

  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值