不会的东西真多啊,,,
(面试官说我说的不准,我说的是两个事务并发执行,其他事务的数据插入删除引起的问题。我举的例子是两次查询count,结果集不一样,但其实这个不是幻读,是不可重复读的一种。)
幻读,并不是说两次读取获取的结果集不同,幻读侧重的方面是某一次的 select 操作得到的结果所表征的数据状态无法支撑后续的业务操作。更为具体一些:select 某记录是否存在,不存在,准备插入此记录,但执行 insert 时发现此记录已存在,无法插入,此时就发生了幻读。
https://www.jb51.net/article/251790.htm
说到局部性原理,那我们首先要知道什么是局部性原理,局部性原理分为两部分:
简单来说就是一个变量在程序运行过程中,如果被引用过一次,那后续很有可能会再被引用到;一个变量被访问到过后,这个变量所在的位置附近的位置很有可能在程序后续运行中被访问到。
应用就是,比如cacheline,每次会拿一批数据。
其实我们的局部性原理不单单是上面提到的狭义性的局部性,还可以是广义的局部性。我们系统里面的热点数据,CDN 数据,微博的热点流量等等这些都利用了局部性原理。只是我们可能没有意识到而已,实际上已经在使用了。我们会通过 Redis 缓存热点数据,会通过 CDN 提前加载图片或者视频资源,等等,都是因为这些数据本身就符合局部性原理,合理的利用局部性可以得到了能效、成本上的提升。
缺点就是,常见的数据库单分片热点问题。
要了解网络通信模型:
第一层:应用层。
使用http协议(底层采用tcp)
第二层:传输层。
使用网络协议。(一种数据传输规则)
常见:TCP/UDP
TCP:面向链接,客户端与服务端建立连接要经历三次握手,采用字节流进行数据的传输,较为安全,效率比udp慢。连接需要经历三次握手,断开需要经历四次挥手。
UDP:面向无连接(不用建连接),可能会出现丢包,每个数据报文限制在64k内,不安全。速度快,但不安全。直接发送数据。
第三层:网络层。
基于IP地址
第四层:链路层
基于网络。
socket:网络编程,建立计算机之间的连接,能够发送数据。
TCP三次握手:
客户端 --------SYN=j(建立连接请求,j为序号)------->服务端
客户端<-------SYN=j+1,ACK(确认连接报文,请求连接)---------服务端
客户端 --------SYN=j+2,ACK(确认连接报文)------->服务端
TCP协议中客户端服务器建立连接后,客户端挂掉,那么有保护机制报文,用来探活,如果一定次数内探活失败,那么连接断开。
TCP四次挥手:(当客户端服务器断开情况,同时断开)
客户端--------FIN(断开连接)------->服务端
客户端<--------ACK(确认)-------服务端
|
(等待时间,等待所有数据传输完毕)
|
客户端<--------FIN,ACK(确认最终数据,断开)-------服务端
客户端--------ACK(确认断开)------->服务端
通过DNS(域名系统)解析IP地址。
然后就是tcp三次握手,构建连接后发送请求,传包,其实和上面那个问题绑定的。
(因为我是面数据库内核研发,所以主要考察的是网络方面,前端怎么做不会问的。)
类似mysql的buffer pool。
(我目前的项目中是没有实现全缓存的,但是需要理解缓存的概念。)
缓存是局部性原理的应用,了解一下cpu的cacheline。
这个需要了解F1的论文,或者看一下polarx或者是tidb是怎么做的。
我们原来项目的实现方式比较差,就是左右的proxy都隔一段时间去执行一个,去元数据节点拉取数据的操作,是没有办法保证这段期间的数据一致性的。
了解一下两阶段提交的原理。
mysql的话,了解一下XA事务。
分布式事务比较慢,但是作为事务,需要保证ACID,那么就需要看一下全局MVCC的实现方法。
简单想一下。单机mvcc是通过版本号来实现的,那么全局MVCC就需要一个全局的版本号,这里就不是版本号了, 可以用一个全局的时间戳来判断,可以通过单机事务版本号和一个时间戳绑定的状态来构建一个全局的mvcc。
这里细节的东西就比较多了,比如修复了XA一些缺点的TSO怎么做的(事务的start_ts,prepare_ts,commit_ts),读操作和写操作并发情况下,读操作如何判断写操作可不可见。
可以通过sts和cts的比较来判断,sts>cts,那么数据就可见;sts 两阶段提交还要有pts,这个就需要分情况讨论。sts 看这个:PolarDB-X 分布式事务的实现(一) - 知乎