CockroachDB架构的事务层通过协调并发操作实现对ACID事务的支持。
--注意:
1)如果您还没准备好,我们建议您阅读架构概览部分。

一.概览

CockroachDB认为一致性是数据库胜过一切的最重要的特性——否则,开发人员不能构建可靠的工具,并且业务会遭受潜在微妙而难以探测的异常。
为了支持一致性,CockroachDB在事务层实现了对ACID事务语义的完全支持。但是,知道所有语句包括单条语句——这有时被称为"自动提交模式(autocommit mode)"被作为事务处理非常重要,因为,其行为就像每个语句后紧跟一个commit。
CockroachDB中使用事务的代码样本,请参考有关事务的文档。
因为CockroachDB在您的整个集群中实现了事务(包括跨范围和跨表的事务),其使用称为并行提交的分布式、自动提交协议进行了正确实现。
1.写和读(阶段1)
1)写
当事务层执行写操作时,其并非将数值写入磁盘。相反,其创建几个帮助其协调分布式事务的几样东西:
a)锁(Locks):对事务写整体来说,锁提供一个临时的、未提交状态。CockroachDB有以下几种不同类型的锁:
i)非复制锁(Unreplicated Locks):其通过并发控制机制存储于每个节点内存的锁表中。这些锁不会被Raft进行复制。
ii)复制锁(Replicated Locks)(也被称为写意向(write intents)):其通过Raft进行复制,并兼任临时数据和独占锁。它们实际和标准多版本并发控制(MVCC)数据是一样的,但也包含一个指向存储于集群中事务记录的指针。
b)transaction record:事务记录存储于其第一个写发生的范围中,其包含该事务的当前状态(其可以是PENDING,STAGING,COMMITTED或ABORD)。
当创建写意向时,CockroachDB会检查更晚提交的数据。如果存在更晚提交的数据,事务也许被重启。如果已存在相同键值的写意向,其将被作为事务冲突进行解决。
如果事务因为其他原因失败了,像没经过SQL约束检查,则事务中止。
2)读
如果事务还没中止,事务层开始执行读操作。如果一个读操作仅遇到MVCC值,一切顺利。但是,如果遇到任何写意向,该操作必须作为事务冲突进行解决。
2.提交(阶段2)
CockroachDB检查运行事务的事务记录,看是否已经中止;如果已中止,将重启该事务。
通常情况下,其将事务记录的状态设置为STAGING,并检查该事务的待决写意向以查看其是否已成功(即,已完成集群内复制)。
如果事务已经过这些检查,CockroachDB将向客户端反馈事务成功信息,并进入清理阶段。此时,事务被提交,客户端可以继续向集群发送更多的请求。
提交协议的更多细节,请看并行提交部分。
3.清理(异步阶段3)
事务提交后,其会被标记,写意向的所有方面都将被解决。为了完成这些,协调节点——保持其所写所有键值轨迹的节点——开始行动:
1)将事务记录的状态从STAGING改为COMMITED。
2)通过移去指向事务记录的指针,将事务写意向转换为MVCC数据。
3)删除写意向。
不过,这只是一种优化。如果将来操作遇到写意向,其将总是检查它们的事务记录——任何操作都能通过检查事务记录状态来解决和移除写意向。
4.与其他层交互
CockroachDB事务层与其他层的关系:
1)从SQL层接收KV操作。
2)控制向分布层发送的KV操作流。

二.技术细节和组件
1.时间和混合逻辑时钟
分布式系统中,秩序和因果关系是很难解决的问题。当完全依赖Raft共识维护串行化时,读数据的效率不高。为了优化读性能,CockroachDB实施了混合逻辑时钟(HLC),其由物理组件(总是接近当地时间)和逻辑组件(用于区分物理组件相同的事件)组成。这意味着HLC时间总是大于或等于实际时间。更多细节可以参考HLC相关文档。
就事务而言,网关节点用HLC时间为事务选择时间戳。无论何时提及事务的时间戳,都是指HLC数值。该时间戳用于跟踪数据的版本(通过多版本控制),和支持我们的事务隔离。
当节点向其他节点发送请求时,它们包含本地HLC产生的时间戳(包含物理和逻辑组件)。当节点接收请求时,它们将随发送事件提供的时间戳通知给本地HLC。这保证一个节点上读写的所有数据的时间戳都小于下一个HLC时间。
于是,这使得主要负责范围(即,租约持有者)的节点,通过确保读数据事务的HLC时间比所读数据的时间戳大(即,读总是发生在写"后")来为其所存储的数据提供读服务。
1)最大时钟偏移实施
CockroachDB要求适度时钟同步以保持数据一致性。因此,当一个节点探测到其时钟与集群中至少一半的其他节点不同步,且偏移量达到最大允许值(默认为500毫秒)的80%时,其将立即崩溃。
串行化一致性维护并不考虑时钟偏移,超出配置时钟偏移边界的偏移可能导致因果依赖的事务间违反单键线性化。因此,通过在每个节点上运行NTP或其他时钟同步软件来防止时钟偏移太多非常重要。
有关时钟偏移很大导致后果的细节,可以查看节点时钟不能正确同步时将会发生什么。
2.时间戳缓冲
作为支持串行化的一部分,无论何时读取一个数值时,我们将在时间戳缓冲中存储该操作的时间戳,其将显示正被读取数值的高水位线。
无论何时发生写操作,其时间戳将根据时间戳缓冲进行检查。如果其时间戳比时间戳缓冲中的最大值小,我们试图将该操作相应事务的时间戳推到一个较晚的时间。推迟该时间戳也许引起该事务在第二阶段重启(看读刷新部分)。
3.client.Txn和TxnCoordSender
就像我们在SQL层架构概览中所说,CockroachDB将所有SQL语句转换成键值(KV)操作,这就是数据最终被存储和访问的方式。
所有从SQL层产生的KV操作都用client.Txn,其为CockroachDB KV层的事务接口——但是,就像我们上面讨论的,所有语句都被作为事务处理,因此,所有语句都使用该接口。
但是,client.Txn实际只是TxnCoordSender的一个封装,后者在我们的代码库中起着重要作用:
1)处理事务状态。事务开始后,TxnCoordSender开始异步向事务的事务记录发送心跳信息,其表示该事务将继续存活。如果TxnCoordSender的心跳信息停止,事务记录将变为ABORTED状态。
2)事务过程中跟踪每个被写的键值或键值范围。
3)事务提交或终止时,清除该事务的累积写意向。作为事务部分所有被正执行的请求,必须通过相同TxnCoordSender负责其所有写意向,其将优化该清理过程。
建立该簿记后,这些需求被传递到分布层的DistSender。
4.事务记录
为了跟踪事务执行的状态,我们向我们的键值存储写入一个称为事务记录的数值。事务的所有写意向都指回到该记录,这将允许任何事务检查其遇到的任何写意向的状态。这种规范记录对支持分布式环境的并发至关重要。
事务记录总是写到事务中第一个键值的相同范围,TxnCoordSender知道这点。但是,事务记录自己不会创建,除非发生下述情况之一:
1)写操作提交。
2)TxnCoorDSender向事务进行心跳操作。
3)某个操作强迫事务中止。
针对该机制,事务记录使用下列状态:
1)PENDING:表示写意向的事务还在进行中。
2)COMMITED:一旦事务完成,该状态表示写意向能被当做已提交数据处理。
3)STAGING:用于开启并行提交特性。依赖于该记录参考的写意向的状态,事务可以是或不是提交状态。
4)ABORTED:表示事务中止且其数据被舍弃。
5)Record does not exist: 如果一个事务遇到其事务记录并不存在的写意向,其将使用该写意向的时间戳来决定如何处理。如果写意向的时间戳在事务活跃阈值内,该写意向事务被作为PENDING状态处理,否则,其被作为事务状态ABORTED处理。
提交事务的事务记录一直保持到其所有写意向被转换为MVCC数据为止。
5.写意向
CockroachDB中的数据不会直接写到存储层;而是被写到称为"写意向"的临时状态。这实际是添加了其他鉴别该数据所属事务记录的数值的MVCC记录。可以将其认作复制锁和复制临时值的组合。
无论何时操作遇到一个写意向(而非MVCC值),其将查找事务记录的状态以了解应该如何处理该写意向值。如果事务记录缺失,该操作将检查写意向时间戳并评估该写意向是否已过期。
从v20.1开始,CockroachDB用每个节点内存中的锁表管理并发控制。该表包含正在进行事务获取锁的集合,并与评估期间发现的有关写意向的相关信息合并。更多信息,参考下面并发控制部分。
1)解决写意向
无论何时操作遇到一个键值的写意向,其将试图"解决"它,结果依赖于写意向的事务记录:
a)COMMITTED:该操作读取写意向,并通过移除到事务记录的指针将其转换成MVCC数据。
b)ABORTED:忽略写意向并将其删除。
c)PENDING:这表示有一个必须要解决的事务冲突。
d)STAGING:这表示该操作应该通过验证事务协调节点是否还在对该事务的事务记录进行心跳操作,检查该staging事务是否还在进行中。如果协调节点还在对该事务的事务记录进行心跳操作,则该操作应该等待。更多信息,请参考并行提交部分。
e)Record does not exist:如果写意向在事务活跃阈值内创建,其与PENDING状态相同,否则,按照ABORTED状态进行处理。
6.并发控制
从v20.1开始,并发管理器对输入请求进行排序,并在发布冲突意向操作的事务间提供隔离。该活动也被称为并发控制。
并发管理器组合使用闩管理器和锁表完成这项工作:
1)闩管理器对输入的请求进行排序并提供那些请求间的隔离。
2)锁表对请求进行锁定和排序(与闩管理器协同工作)。其是每个节点内存中包含进行中事务获取锁集合的数据结构。为了确保与写意向(又称复制、独占锁)现有系统的兼容性,当评估请求的过程中发现这些外部锁时,它会根据需要获取有关这些外部锁的信息。
并发管理器实现了通过SELECT FOR UPDATE语句的SQL支持悲观锁。该语句能用于增加吞吐和减少冲突操作的尾部延迟。
1)并发管理器
从v20.1开始,并发管理器是对输入请求进行排序并在发布冲突意向操作的事务间提供隔离。排序期间,冲突被发现且通过被动排队和主动推送组合进行解决。一旦请求被排序,其将进行评估并因为管理器提供的隔离而无需关心与其他进行中请求的冲突。请求生命期内保证被隔离,但一旦请求完成就会终止。
事务中的每个请求都将与其他请求隔离,包括请求生命期内和请求完成后(假设其获取了锁),除了包围事务的生命期。
并发管理器通过允许事务请求获取锁来实现这一点,这将延长这些请求的生命期。锁将特定键值的隔离期扩展到持有锁事务的生命期。该事务提交或中止时这些锁才被释放(典型地)。排序时发现这些锁的其他请求继续工作前,将在队列中等待这些锁被释放。因为排序期间会检查锁,所以,评估期间不必再对锁进行检查。
但是,并非所有的锁都直接在并发管理器控制下,因此,排序期间并非所有的锁都会被发现。尤其是,写意向(复制的、独占锁)存储于MVCC键值空间行内,因此,直到评估请求时才会探测到它们。为了实现这种形式的锁存储,并发管理器将外部锁相关信息与并发管理器结构集成到一起。
--注意:
1)目前,并发管理器对非复制锁表结构进行操作。将来,我们打算将所有锁,包括那些与写意向相关的锁,都直接通过复制锁表结构放进并发管理器中。
请求间的公平得以确保。通常,如果两个请求发生冲突,那么先到的请求将排在前面。同样地,排序保证先进先出。对此的主要例外是作为已获取了锁的事务部分的请求排序期间无需再等待该锁,所以,忽略该锁上的任何等待队列。有关排序保证的其他特例,请参考下面锁表部分。
2)锁表
从v20.1开始,锁表为每个节点内存中保存进行中事务获取锁集合的数据结构。表中每个锁有与其相关的可能为空的锁等待队列,冲突事务等待该锁释放期间可以进行排队。本地存储的锁等待队列中的项目按需广播到已有TxnWaitQueue,其存储于包含该事务记录的范围的Raft组领导者中。
数据库用"请求"进行读写。事务有一个或多个请求组成,请求间需要隔离。另外,由于事务代表一组请求,这种组之间需要隔离。这种隔离部分通过维护多版本实现,部分通过许可请求获取锁实现。甚至基于多版本的隔离也需要某种形式的互斥,以确保不会同时发生读操作和获取冲突锁。锁表支持锁定和请求的排序(与闩使用合作)。

锁延长了请求的生命期,所以,将特定键值的隔离期扩展到了持有锁事务的生命期。该事务提交或中止时这些锁才被释放(通常这样)。排序时发现这些锁的其他请求在继续工作前将在队列中等待其释放。因为排序期间会检查锁,请求在排序后保证可以访问所有声明的键值。换句话说,评估期间无需再检查锁。
--注意:
1)目前,并非所有锁直接存储于锁表中。某些锁作为写意向存储于MVCC层,其在序列化期间不会被发现。特别是,写意向(复制、独占锁)存储于MVCC键空间行内,因此,通常直到请求评估时才会被探测到。
为了实现这种形式的锁存储,评估期间遇到这些锁的话,会将其相关信息添加到锁表中。将来,我们打算将所有锁,包括写意向相关的那些锁,都直接放入锁表中。
锁表也提供请求间的公平。如果两个请求发生冲突,那么,先到的请求通常排在前面。也有一些例外:
a)已获取锁事务的请求序列化期间无需等待该锁,所以,可以忽略该锁上的任何队列。
b)不同级别冲突的竞争请求也许并不按照FIFO顺序排序。这将允许更大的并发。例如:如果请求R1和R2在键值K2上发生了冲突,但R1也在等待K1,R2可能跳过R1进行评估。
3)闩管理器
闩管理器对输入请求进行排序且在并发管理器的监督下提供那些请求间的隔离。
闩管理器按照如下方式工作:
当一个范围上发生写请求时,该范围的租约持有者对这些请求进行排序,它们被按照某种一致的顺序排列。
为了强制这种排序,租约持有者为写数值中那些键值创建一个"闩",以支持对这些键值的无竞争访问。
如果其他请求要访问该租约持有者的同一套键值,那么,这些请求继续工作前必须等该闩释放。
读请求也会产生闩。多个读请求可以同时持有同一组键值上的闩,但不能同时持有同一组键值上的读闩和写闩。
另一种理解闩的方式是其像一个仅在单个、低级请求期间需要的互斥体。为了协调较长运行的高级请求(即,客户端事务),我们使用写意向的一个持久系统。
7.隔离级别
隔离是ACID事务的一个元素,其决定了并发如何被控制,并最终保证一致性。
CockroachDB以最强ANSI事务隔离级别:SERIABLIZATION执行所有事务。所有其他ANSI事务隔离级别(例如:SNAPSHOT,READ UNCOMMITTED,READ COMMITTED,和REPEATABLE READ)自动升级到SERIABLIZATION。较弱的隔离级别历史上用于最大化事务吞吐。但是,最近的研究证明弱隔离级别会导致基于并发袭击的重大漏洞。
CockroachDB现在只支持SERIABLIZATION隔离。CockroachDB的先前版本,您能将事务设置为SNAPSHOT隔离,但该特性已被移除。
SERIABLIZATION隔离不允许您的数据发生任何异常,并且,将对违反串行化的客户端事务进行重试。
8.事务冲突
CockroachDB事务允许下列涉及意向的冲突:
1)写/写:两个未决事务对同一键值创建写意向。
2)写/读:读操作遇到比自己时间戳小的已有写意向。
为了易于理解,我们称第一个事务为TxnA,遇到写意向的为TxnB。
CockroachDB将经历如下步骤:
1)如果事务有一个显式权限集(即,HIGH或LOW),较低权限的事务被中止(写/写场景中)或将其时间戳推后(写/读场景中)。
2)如果遇到的事务已过期,将其中止并成功解决冲突。如果发生如下场景,我们将其认作一个写意向过期:
a)该写意向没有一个事务记录,且其时间戳超出了事务活跃阈值。
b)事务活跃阈值内该写意向的事务记录没有心跳活动。
c)TxnB进入TxnWaitQueue等待TxnA完成。
另外,下列不涉及意向的冲突类型也可能发生:
1)先读后写:当低时间戳的写遇到稍晚的读,将通过时间戳缓冲进行处理。
2)不确定时间窗内的读:当读遇到较高时间戳的数值,但因为时钟偏移,不确定该数值为将来还是过去的事务,那么,将试图把该事务时间戳推到超过某个不确定的值进行处理(参考读刷新部分)。注意,如果事务必须重试,对先前访问过的任何节点进行读将绝不会遇到不确定问题,且该事务从网关节点上读到的数值绝不会有不确定问题。
9.TxnWaitQueue
TxnWaitQueue对不能推后其遇到写的事务的所有事务进行跟踪,且在其继续工作前必须等待阻塞事务完成。
TxnWaitQueue的结构是正阻塞事务ID到其正被阻塞事务的映射,例如:
txnA-->txn1,txn2
txnB-->txn3,txn4,txn5
重要的是,所有这些活动发生在单个节点上,该节点为包含事务记录的范围Raft组的领导者。
一旦该事务得以解决——通过提交或中止——将会给TxnWaitQueue发送一个信号,以让被该已解决事务阻塞的所有事务开始执行。
被阻塞事务也检查其自身状态以确保它们还活着。如果被阻塞事务已中止,仅仅将其移除。
如果事务间存在死锁(即,它们互相被对方的写意向阻塞),将随机中止一个事务。上述例子中,如果TxnA在key1上阻塞TxnB且TxnB在key2上阻塞了TxnA。
10.读刷新
无论何时一个事务的时间戳被推后,允许其在推后的时间戳提交前都需要进行另外的检查:该事务先前读的任何数值必须被检查,以验证原来时间戳和推后时间戳间后续没有对其进行写。该检查防止违反串行化。
该检查通过专用的RefreshRequest跟踪所有读来完成。如果成功,将允许该事务提交(如果其被不同事务或时间戳缓冲推后了时间戳,则事务在提交时进行该检查,或者,其遇到一个ReadWithinUncertaintyIntervalError时,在继续工作前立刻进行检查)。如果刷新不成功,那么,该事务必须在推后时间戳进行重试。
11.事务流水化
当事务写复制或写到磁盘时将进行流水化,这大幅降低了执行多个写事务的延迟。例如:考虑下述事务:
-- CREATE TABLE kv (id UUID PRIMARY KEY DEFAULT gen_random_uuid(), key VARCHAR, value VARCHAR);
BEGIN;
INSERT into kv (key, value) VALUES ('apple', 'red');
INSERT into kv (key, value) VALUES ('banana', 'yellow');
INSERT into kv (key, value) VALUES ('orange', 'orange');
COMMIT;
事务流水化时,写意向并行从租约持有者进行复制,因此,等待都发生在最后,事务提交时。
在高层次上,事务流水化工作原理如下:
1)对每个语句,该事务网关节点与想写入范围的租约持有者们(L1,L2,L3,...,Li)进行通信。由于表的主键为UUID,范围可能会拆分到多个租约持有者(这是好事,因为这将减少事务冲突)。
2)每个租约持有者Li接收从事务网关节点的通信,且并行进行如下工作:
a)创建写意向并将其发送到追随节点。
b)对写意向发送的事务网关节点做出响应。注意该意向的复制现阶段还在进行中。
3)当试图提交时,该事务网关节点等待写意向并行复制到租约持有者的追随节点。当其从广播写意向的租约持有者收到响应时,其提交该事务。
就上述显示的SQL代码片段而言,所有写意向广播和提交的等待仅发生一次,其在该事务最后,而非每个单独写都发生。这意味着多个写的成本不是SQL DML语句的O(n),而是O(1)。
12.并行提交
并行提交特性引入了一个新的、优化的原子提交协议,其将事务的提交延迟减少一半,从两轮共识减少为一轮。与事务流水化相结合,将常见OLTP事务延迟降到接近理论最小值:所有读延迟加上一轮共识延迟的和。
新原子提交协议下,当事务协调器得知事务中的写已成功时,将快速返回客户端。这一旦发生,事务协调器可以将事务记录的状态设置为COMMITTED,并异步解决事务的写意向。
因为事务协调器在事务记录中保存了足够的信息(通过一个新的STAGING状态,和一组进行中的写)以让其他事务决定该事务中所有写是否存在,并证明该事务是否已提交,所以,其能确保正确的完成这些工作。
为了更详细显示并行提交工作的机制,请参考逐步并行提交。
--注意:
1)解决写意向前的延迟并没因为并行提交的引入而发生改变:写意向的解决还是需要两轮共识。这意味着竞争类的负载也许从该特性获益较少。
1)逐步并行提交
本节包含一个事务的逐步实例,该事务用并行提交原子提交协议写数据,并未遇到任何错误或冲突:
a)步骤1
客户端开始该事务。创建一个事务协调器来管理该事务的状态。


b)步骤2
客户端向"Apple"键值发布一个写操作。事务协调器开始在该将要写入数据的键值上放一个写意向的过程。该写意向有一个时间戳和一个指向还不存在的事务记录的指针。另外,事务中的每个写意向被分配一个唯一鉴别它的唯一序列号。
作为一种优化,事务协调器在事务生命期内尽可能的避免创建事务记录。图中用虚线说明事务记录还不存在的事实。
--注意:
1)移到客户端的下一个语句前,事务协调器不必等待写意向从租约持有者的复制,因为其被事务流水化进行并行处理。


c)客户端向"Berry"键值发布一个写操作。事务协调器会在将向其写入数据的键值上放置一个写意向。该写意向有一个指向步骤b)中创建写意向所指向相同事务的指针,因为这些写意向都是相同事务的部分。
与前面一样,该事务协调器在移到客户端下一个语句前,不必等待写意向从租约持有者复制。


d)步骤4
客户端发布一个提交该事务写的请求。事务协调器创建事务记录并将记录的状态设置为STAGING,并记录事务中正在执行的每个写操作的键值。
其完成这些工作而不必等待查看步骤b)到步骤c)的写操作是否已完成。


e)步骤5
事务协调器,已经收到客户端COMMIT请求,等待未决写操作成功(即,完成集群内复制)。一旦所有未决写操作成功,事务协调器向客户端返回一个信息,以让其知道事务已提交成功。


事务现在被认为是原子提交,即使事务记录的状态还是STAGING。其还被认为是一个原子提交的原因是,如果事务处于下列逻辑等价状态之一,其就被认为已提交:
i)事务记录状态是STAGING,其未决写列表都已成功(即,InFlightWrites已在集群内获得了共识)。该事务的任何观察者能验证其写操作已被复制。该状态的事务被隐式提交。
ii)事务记录状态为COMMITTED。该状态的事务被显式提交。
不管它们逻辑上的等价,事务协调器尽可能快的将事务记录从STAGING移为COMMITTED,以便其他事务不会遇到STAGING状态的可能冲突的事务,并必须验证该事务的未决写操作已经成功。该验证(也被称为"事务状态恢复过程")不会很快。
另外,当其他事务遇到STAGING状态的事务时,它们通过验证其事务协调器是否还在对该STAGING状态的事务进行心跳操作,来检查该STAGING状态的事务是否还在进行。如果其事务协调器还在对该事务记录进行心跳操作,则其他事务将会等待,理论上,让事务协调器用试图提交的最终结果更改该事务记录,比完成事务状态恢复过程更快。这意味着实际上,如果事务协调器因为最终崩溃而死掉,事务状态恢复过程才被使用。

三.与其他层的技术交互
1.事务和SQL层
事务层接收来自SQL层执行planNOdes的KV操作。
2.事务和分布层
TxnCoordSender将其KV请求送至分布层的DistSender。

四.个人观点
1.CockroachDB支持ACID事务。
2.CockroachDB具备完备的并行机制和实现。
3.CockroachDB比较完美的实现了锁机制,而非使用了Rocksdb的现有机制。

4.CockroachDB行锁通过存储进行实现,虽然其事务表并未实现指向undo空间,但这对RocksDB来讲没必要,KV库事务的rollback和一致性读无需undo空间,虽然有诸多差别,但与Oracle的行锁机制有异曲同工之妙。

CockroachDB架构——事务层相关推荐

  1. CockroachDB架构——SQL层

    ChockroachDB架构的SQL层向开发人员公开SQL API并将SQL语句转换成数据库其他部分使用的键值操作. --注意: 1)如果您还没有准备好,我们建议您阅读架构概览部分. 一.概览 一旦C ...

  2. CockroachDB架构-分布式层

    本文知识点来源于官网地址https://www.cockroachlabs.com/docs/v22.1/architecture/distribution-layer.html 概览 Cockroa ...

  3. CockroachDB架构——CockroachDB中的读和写

    本文解释CockroachDB复制和分布特性如何影响读和写. 本文以总结某些重要的CockroachDB架构概念开始,接着,介绍几个简单的读写场景. --注意: 1)一个查询通过CockroachDB ...

  4. CockroachDB分布式SQL层架构解析

    SQL 层 SQL层主要用来将SQL语句转化为K-V操作,并将操作送给事务层. SQL Parser, Planner, Executor,CRDB通过yacc将语句解析为抽象语句树(AST),yac ...

  5. CockroachDB 分布式事务源码分析之 TxnCoordSender

    前言 本源码分析假设读者已经了解 CockroachDB 架构和各层设计要点. 理论知识见 CockRoachDB Documentation. TxnCoordSender TxnCoordSend ...

  6. CockroachDB架构浅析

    本文源自:http://www.cockroachchina.cn/?p=685 这篇文档介绍和说明了cockroachdb的架构,简单明了. 作为Spanner的开源实现,CockroachDB具有 ...

  7. 系统架构师-基础到企业应用架构-表现层

    一.前言 最近也许是由于假期的原因,我发布的文章的速度变慢了,对大家说下抱歉,这个系列的确我很难写,感谢大家对我的支持和关注,的确我在发布后得到大家的支 持和认可,让我有了更多的动力,之前发布的有些内 ...

  8. 9月29日云栖精选夜读:武装到“牙齿”!阿里云发布史上最强企业云安全架构 11层防护...

    未来的企业都会基于云来搭建业务的安全系统,企业云安全架构(Cloud Security Compass)就是这么一份供上云企业参考的设计蓝图-- 企业可以像"建房子"一样,依据模块 ...

  9. pcie数据反_PCIe事务层の详解(一)

    PCIe总线的通信机制:当一个设备要想另一个设备进行读取通信时,请求方requester需要向另一个设备发送请求request,靶向方作为事件完成方completer,以complete Packet ...

最新文章

  1. matlab选择激发波长,【求助】怎么确定一个物质的激发波长和发射波长?
  2. CCF201312-5 I’m stuck!(100分)
  3. mysql按周统计_MySQL按周统计 WEEK 实例
  4. KlayGE 4.3开发计划
  5. Visual C++ Windows 用来定位 DLL 的搜索路径
  6. 315. Count of Smaller Numbers After Self 计算右侧小于当前元素的个数
  7. Struts2框架使用(十)之struts2的上传和下载
  8. BZOJ 1452 [JSOI2009] Count
  9. sql中join与left-join图解区别
  10. Android 中的adapter和作用以及常见的adapter
  11. WCF中配置文件解析
  12. android touch事件坐标原点,Android – 捏缩放ontouch事件坐标
  13. redis扫描特定keys脚本,可避免阻塞,不影响线上业务
  14. Eclipse SonarLint 插件 “SonarLint processing file 。。。 lombok/launch/PatchFixesHider“ 解决办法
  15. 关于艾宾浩斯曲线的一点思考
  16. [量化学院]基于协整的配对交易
  17. 你想要的宏基因组-微生物组知识全在这(1910)
  18. 驱动开发之五 --- TDI之一(飞雪楚狂人)
  19. dump文件调试技巧(产生Dump文件)
  20. 【openstack一键安装与部署】

热门文章

  1. LaTeX 如何使用双引号,单引号
  2. (转)我的endnote使用经验——管理文献
  3. 看了以后大呼过瘾的程序员必备网站,速速收藏!
  4. Redis(一)入门:NoSQL OR SQL,看完这篇你就懂了
  5. 计算机专业出国留学邮件怎么写,计算机专业留学个人陈述范文.pdf
  6. Linux常用命令——su命令
  7. 交换两个变量的值的三种方法
  8. C语言常用字符串函数详解
  9. list和dic区别
  10. 组装一台计算机需要的配件,组装一台电脑需要哪些配件【详细列举】