为提高效率,请提供以下信息,问题描述清晰能够更快得到解决:
【 TiDB 使用环境】
centos7.5 + tidb v4.0.13
【概述】场景+问题概述
业务场景:获取表的最新一条数据,进行业务处理,在mysql里因为主键自增的,最大的id就是最新的一条数据
但是tidb里最大的id不一定是最新的,因为多个tidb server的问题
时间字段无法得到最新的一条数据,因为逻辑上有问题,相同时间可能有2条或者多条数据
问题:如何获取表的最新一条数据
【背景】做过哪些操作
【现象】业务和数据库现象
目前无法获得表的最新一条数据
试了sequence和show table next_row_id都不行
【业务影响】
无法从mysql迁移到tidb
【TiDB 版本】
v4.0.13
【附件】
-
TiUP Cluster Display 信息
-
TiUP Cluster Edit Config 信息
-
TiDB- Overview 监控
caiyfc
2
可以通过 _tidb_rowid
来判断,_tidb_rowid
最大值的那一条数据,就是最新插入的数据
直接报错了,获取_tidb_rowid的语法是什么:sweat_smile:
h5n1
(H5n1)
4
自增主键就是tidb_rowid,非bigint类的主键才能查tidb_rowid
caiyfc
5
如果主键是int型的,就没有_tidb_rowid了 
在mysql里,自增的都是int类型的,能够根据id查到最新的一条数据,迁移到tidb后,就不行了,自增id最大的并不能确定是最新的一条数据了
TiDB 中 和 MySQL 的 auto increment 确实存在兼容性差异,这样的情况下,使用 max(pd_id) 的方式来获取最新的一条记录,确实不准确:
针对上面的情况,是否可以在建表时添加 create_time, update_time 字段,按照数据写入的时间顺序来获取最新的记录 ~
数据小黑
(数据小黑)
8
在分布式的环境下,你如果需要一个严格意义上的最新数据,实际上是要实现一个全局锁,就看这个锁是在哪个层次实现。这个需求从一个单实例数据库迁移到分布式上,无侵入式是不可能的。有两个建议:
1.建议构建一张表,只用于保存最新的数据,用数据库的锁帮你实现这个需求,这样的热点小表,建议打散或者使用SHARD_ROW_ID_BITS和PRE_SPLIT_REGIONS提前打散。如果还是担心高峰时的性能问题,可以加个消息队列。
2.如果是物联网的场景,考虑使用时序数据库。
Meditator
(Wendywong020)
9
这个怎么看起无法实现,如果在没有使用auto_increment的情况下,使用AUTO_RANDOM或者SHARD_ROW_ID_BITS或者PRE_SPLIT_REGIONS,则使用内置的_tidb_rowid,此时可能id的产生有几个shard位,最大的id不一定是最新的数据。可以在表上再加个时间戳字段,类似与mysql update on current_timestamp,精确到微秒
但是这样有个限制:
1)时间字段有需要有个索引才好
2)每秒的写入数据理论上限时99w
3)批量处理可能就有问题
1 个赞
业务层面使用一个业务时间吧,或者搞个数据时间字段:
created datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6);
加上索引,性能应该还行。
数据小黑
(数据小黑)
11
我较个真哈,不喜勿怪。
TIMESTAMP这个字段,加上ON UPDATE CURRENT_TIMESTAMP能达到这个效果。
不过 and 但是:
1.这是个分布式的数据库,假设TiDB是多个,假设TiDB前面有个HA proxy,负载算法是轮询。
2.根据现有资料推断,TIMESTAMP这个字段的自动更新是在TiDB上执行的,不至于类似TSO的模式,那样太消耗性能。
3.机器之间的时间同步是NTP做的,那么到微秒级的TIMESTAMP必然会有差异。
这确实是个很好的方案,但是不是严格意义上的最新。
Meditator
(Wendywong020)
12
嗯,很多细节问题都考虑到,非常棒。
分布式环境下并且有并发冲突的情况下这个问题比较明显,时间戳最大的可能不是最新的,时间戳小的反而可能是最新.
1 个赞
system
(system)
关闭
13
此话题已在最后回复的 1 分钟后被自动关闭。不再允许新回复。