为什么raft log都committed了。用户transaction还不能返回提交成功。写的操作不应该是在内存中有数据么?此时虽然没有apply到kv里面。但是应该在内存中应该可以读到了。那么就应该可以给客户端返回提交成功了吧?

为什么raft log都committed了。用户transaction还不能返回提交成功。写的操作不应该是在内存中有数据么?此时虽然没有apply到kv里面。但是应该在内存中应该可以读到了。那么就应该可以给客户端返回提交成功了吧?

在基于Raft共识算法的分布式系统中,即使日志(log entries)已经被committed ,也不意味着用户的事务(transaction)可以立即向客户端返回提交成功。这主要是因为Raft算法的设计目标不仅仅是保证数据的安全性(通过共识),还要确保数据的一致性和持久性。

1 个赞

这个时候机器忽然故障了,内存里的数据不都丢失了,但是你返回提交成功不对吧,实际也没写到磁盘啊。

这是为了保证数据一致性和持久性,此时宕机了,内存里面的东西就没有了,需要apply到Rocksdb kv中才算永久成功

1 个赞

集中式数据库redo日志commit了以后就可以查询是因为内存也存储了对应的数据,查询可以直接返回,一般只有数据库挂了恢复才会用到redo和undo日志。
分布式数据库tidb没有redo和undo日志,是raft日志,查询是根据kvdb的返回的。如果写入raft就返回成功,这时发生leader节点切换或者在从节点查询数据(没有数据的详细内存信息,不能根据raft日志信息直接返回),但是raft日志对应的数据还没有写入kvdb,就查不到已经提交到raft日志的数据。
仅供参考

raft 共识算法,必须大多数,也就是大多数持久化,要不挂了就可能丢数据了

应该是大多数raft log都committed就行

不对啊。raft log写到rocksdb raft中了不应该持久化了么,只是没有apply到rocksdb kv中而已

raft log写到rocksdb raft中了不应该持久化了么,只是没有apply到rocksdb kv中而已,而且已经replicat到别的node的rocksdb raft中了

https://docs.pingcap.com/zh/tidb/stable/system-variables#tidb_enable_async_commit-从-v50-版本开始引入

不应该出现你说的这个情况,当然也不是说楼上关于raft算法的内容,说的不对。

而是tidb做过这个优化。是可以允许异步提交的。而且这个异步提交的参数,除非是5.0以下版本升级上来的,否则默认设置就是on。

还有一些专栏也是介绍相关内容的,供参考。

另外还有一个参数
https://docs.pingcap.com/zh/tidb/stable/system-variables#tidb_enable_1pc-从-v50-版本开始引入
允许只涉及一个 Region 的事务上启用一阶段提交特性。

这是两个主要的关于事务提交方面的参数了。

2 个赞

了解下acid 中的 d

我了解。。看来这个数据库写了日志并不代表d。必须apply到kv里面。

应该是持久化到rocksdb里才算事务结束

有道理。

也不是只有一个tidb节点。如果给客户端返回成功了。其他节点正常也应该能读到。但是没有apply的话,其他节点读不到,内存中也没有。这样不对了吧

要等到大多数节点apply以后才算事务的commit

在tikv中,其他节点要读这个region肯定也是连接到主region所在的tikv中。那这个主节点内存中应该可以读到。

实际上是只要主region所在tikv apply就commit返回了。

哦 对,是这样

读请求不解析raftlog啊。读请求直接读取rocksdb-kv。事务的两阶段提交中说的缓存,是在commit前在tidb节点缓存。所以如果其他tidb节点读取一个未apply的变更是读不到的。