tidb如何获取表的最新一条数据

为提高效率,请提供以下信息,问题描述清晰能够更快得到解决:
【 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

【附件】

  1. TiUP Cluster Display 信息

  2. TiUP Cluster Edit Config 信息

  3. TiDB- Overview 监控

  • 对应模块日志(包含问题前后1小时日志)

可以通过 _tidb_rowid来判断,_tidb_rowid最大值的那一条数据,就是最新插入的数据


直接报错了,获取_tidb_rowid的语法是什么:sweat_smile:

自增主键就是tidb_rowid,非bigint类的主键才能查tidb_rowid

如果主键是int型的,就没有_tidb_rowid了 :thinking:

在mysql里,自增的都是int类型的,能够根据id查到最新的一条数据,迁移到tidb后,就不行了,自增id最大的并不能确定是最新的一条数据了

TiDB 中 和 MySQL 的 auto increment 确实存在兼容性差异,这样的情况下,使用 max(pd_id) 的方式来获取最新的一条记录,确实不准确:

针对上面的情况,是否可以在建表时添加 create_time, update_time 字段,按照数据写入的时间顺序来获取最新的记录 ~

在分布式的环境下,你如果需要一个严格意义上的最新数据,实际上是要实现一个全局锁,就看这个锁是在哪个层次实现。这个需求从一个单实例数据库迁移到分布式上,无侵入式是不可能的。有两个建议:
1.建议构建一张表,只用于保存最新的数据,用数据库的锁帮你实现这个需求,这样的热点小表,建议打散或者使用SHARD_ROW_ID_BITS和PRE_SPLIT_REGIONS提前打散。如果还是担心高峰时的性能问题,可以加个消息队列。
2.如果是物联网的场景,考虑使用时序数据库。

这个怎么看起无法实现,如果在没有使用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);
加上索引,性能应该还行。

我较个真哈,不喜勿怪。
TIMESTAMP这个字段,加上ON UPDATE CURRENT_TIMESTAMP能达到这个效果。
不过 and 但是:
1.这是个分布式的数据库,假设TiDB是多个,假设TiDB前面有个HA proxy,负载算法是轮询。
2.根据现有资料推断,TIMESTAMP这个字段的自动更新是在TiDB上执行的,不至于类似TSO的模式,那样太消耗性能。
3.机器之间的时间同步是NTP做的,那么到微秒级的TIMESTAMP必然会有差异。
这确实是个很好的方案,但是不是严格意义上的最新。

嗯,很多细节问题都考虑到,非常棒。
分布式环境下并且有并发冲突的情况下这个问题比较明显,时间戳最大的可能不是最新的,时间戳小的反而可能是最新.

1 个赞

此话题已在最后回复的 1 分钟后被自动关闭。不再允许新回复。