mysql事务隔离级别的实现原理

mysql事务隔离级别的实现原理 mysql innodb中的四种事务隔离级别上文主要以实验的形式的展示了四种隔离级别产生的读一致性问题,本文主要讨论一下mysql是如何实现这四种隔离级别的。 一、什么是事务的隔离级别 在数据库系统中,一个事务是指:由一系列数据库操作组成的一个完整的逻辑过程。具备ACID的特性。ACID分别指原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、永久性(Durability)。 事务隔离(Isolation):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。针对这种不一致的级别,产生了事务隔离的四个类别,包括未提交读(Read uncommitted)、提交读(read committed)、可重复读(repeatable read)和串行化(Serializable)。 可重复读(Repeated Read)是mysql的默认级别,本文以它为分析重点。 二、再看可重复读 可重复读:举例来说就是在一个事务内,如果先后发生了两次查询$Q_1, Q_2$,如果$Q_2$看到的内容只包含$Q_1$的内容和自已在本次事务中的内容,看不到其他事务操作的结果(无论其他事务对$Q_1$内容更新还是删除),那么这个就叫可重复读。 这里需要再次强调不可重复读和幻读的区别,不可重复读是针对删除和更新的,幻读是针对插入的。看起来幻读是属于不可以重复读的范畴的,但是为什么要分开呢? 个人觉得是因为解决这两个的方式是不同的,对于不可重复读,可以直接用普通的锁来解决。但是对于幻读,由于不可能锁住不存在的记录,所以这里就分开了,对于幻读其实是用的Next_Key锁(行锁+Gap锁)来解决的,这个上一篇文章有提到。 三 实验一(读-写操作) 关闭自动提交、设置隔离级别为可重复读 开始时刻,会话A,B查询到的结果如下: mysql> select * from test; +----+---------+ | id | account | +----+---------+ | 1 | 400 | | 2 | 500 | | 3 | 600 | +----+---------+ 3 rows in set (0.00 sec) 会话B插入一条记录并提交 mysql> select * from test; +----+---------+ | id | account | +----+---------+ | 1 | 400 | | 2 | 500 | | 3 | 600 | +----+---------+ 3 rows in set (0....

3 分钟 · pan

nvidia smi docker usage

正文 docker 和 nvidia-docker命令的区别 如果容器中需要用到cuda,但是使用docker 启动是找不到cuda的,nvidia-smi命令也无法使用。必须使用nvidia-docker启动。经试验,如下命令也是ok的,docker指定参数 –gpus docker run --rm --gpus all nvidia/cuda nvidia-smi 指定使用那一块GPU 使用全部的gpu docker run --rm --gpus all nvidia/cuda nvidia-smi 使用环境变量NVIDIA_VISIBLE_DEVICES来指定使用那一个GPU(必须指定runtime,–runtime=nvidia) docker run --rm --runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=all nvidia/cuda nvidia-smi 容器内可以使用两块gpu docker run --rm --gpus 2 nvidia/cuda nvidia-smi 指定gpu编号 docker run --gpus '"device=1,2"' nvidia/cuda nvidia-smi --query-gpu=uuid --format-csv [参考文档] https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/user-guide.html nvidia-docker2 安装

1 分钟 · pan

TLS

本文借助wireshark抓包详细的讲解SSL/TLS协议。HTTPS是为了解决http报文明文传输过程中的安全问题。HTTPS是“HTTP over SSL”的缩写。所以要了解HTTPS就必须先了解SSL/TLS协议。 一、HTTP协议的风险 HTTP协议中所有消息都是明文传播,存在如下三大风险 窃听风险(eavesdropping):第三方可以获知通信内容。 篡改风险(tampering):第三方可以修改通信内容。 冒充风险(pretending):第三方可以冒充他人身份参与通信。 为了解决这个三个风险,分别对应如下三个解决方案。 加密:所有信息都是加密传播,第三方无法窃听。 校验:具有校验机制,一旦被篡改,通信双方会立刻发现。 身份验证:配备身份证书,防止身份被冒充。 二、SSL/TLS 发展历史 1994年,NetScape公司设计了SSL协议(Secure Sockets Layer)的1.0版,但是未发布。 1995年,NetScape公司发布SSL 2.0版,很快发现有严重漏洞。 1996年,SSL 3.0版问世,得到大规模应用。 1999年,互联网标准化组织ISOC接替NetScape公司,发布了SSL的升级版TLS 1.0版。 2006: TLS 1.1. 作为 RFC 4346 发布。主要fix了CBC模式相关的如BEAST攻击等漏洞。 2008: TLS 1.2. 作为RFC 5246 发布 。增进安全性。目前(2015年)应该主要部署的版本。 2015之后: TLS 1.3,还在制订中,支持0-rtt,大幅增进安全性,砍掉了aead之外的加密方式。 由于SSL的2个版本都已经退出历史舞台了,所以本文后面只用TLS这个名字。 一般所说的SSL就是TLS。 三、报文解析(rfc5246) TLS建立连接的过程如下图,先有个大概的印象,后面我们再详细分析。整个需要四次握手。 SSL/TLS工作在应用层和传输层之间,在建立连接的之前需要先建立TCP连接(三次握手),如下图。 3.1 详细过程 (1)Client Hello 从截图中可以看出TLS协议分为两个部分记录协议(Record Layer)和握手协议(Handshake Protocal)。 3.1.1 记录协议(Record Layer) 记录协议根据rfc描述记录协议(Record Layer)有如下4种类型,即上图中Content Type可以取的值。 记录协议(Record Layer) 数据结构 对照着wireshark抓包为:Content Type:Handshake(22), Version: TLS 1.0(0x0301), Length: 512 3.1.2 握手协议(Handshake Protocal) 握手协议(Handshake Protocal)有如下10种类型。 握手协议(Handshake Protocal)数据结构 对照着wireshark抓包为:Handshake Type: Client Hello, Length: 508, Version : TLS 1....

1 分钟 · pan

Transformer研究综述

一、基础部分 2017年google发表了一篇All Attention Is All You Need论文, 在机器翻译任务中取得了SOTA 的成绩。论文中提出的Transformer结构取消了传统的Seg2Seg模型中RNN和CNN传统神经网络单元,取而代之代之的Self-Attention(自注意力机制)的计算单元。该计算单元并行化程度高,训练时间短。所以Transformer引起了学术界和工业界的广泛注意。目前已经是NLP领域的标配。随后在2019年google提出基本Transformer的bert模型, 该模型在大量的数据集中通过自监督的训练,然后在特定任务上只需要做少量改动和训练就可以得到非常好的效果,开源的bert模型在11个NLP任务取得SOTA结果。 Transformer除了在NLP任务上表现优异,在CV领域也取得了很多突破。2020年google又发表了一篇 VIT Transformer的论文,实验证明Transformer在imagenet分类任务上取得了SOTA结果。后来CV领域中的各种基本问题,比如目标检测、语义分割、物体追踪、视频等各种任务都用Transformer方法又搞了一遍,基本上也取得了一些不错的结果。 鉴于Transformer在NLP和CV上的巨大成功,本文竟可能详细描述Transformer的基本原理;特定的一些应用,主要是一些经典论文的方法;以及目前Transformer在效率问题上的一些改进的方案。 1.1 Attention 在学习Transformer之前,了解一些基础问题是很有必要。毕竟在没有Transformer之前,学术上在NLP领域也做了大量的研究和成果。我们先从Encoder Decoder和Seq2Seq开始说起。我想大家肯定都听过这两个名称,简单来说就是如下图。 Encoder输入(可以是文字也可以是图像)编程成一个固定长度的向量(content),那么这个content向量肯定是包含输入的信息的(至于包含多少那就看这个编码了),Decoder根据content解码出我们需要的结果。Encoder Decoder可以是机器翻译问题、语义分割问题等等。那么Seq2Seq(Sequence-to-sequence )是什么?输入一个序列,输出另一个序列。这种结构最重要的地方在于输入序列和输出序列的长度是可变的。如下图所示。 从本质上看,Encoder-Decoder和seq2seq好像差不多,但是又有一点区别。 Seq2Seq 属于 Encoder-Decoder 的大范畴 Seq2Seq 更强调目的,Encoder-Decoder 更强调方法 那么这个Encoder-Decoder有什么缺陷呢? 从上面的示意图我们看到,无论输入的信息又多少,Encoder后就剩下一个content向量了,那么这里面有一个缺陷就是这个content向量会丢掉一些信息,特别是输入很大(文本很长图像分辨率很高)的情况下。尽管后面出现的LSTM、GRU等通过门设计的循环神经网络单元,可以一定程度上缓解长距离问题,但是效果有限。 从这里开始,我们要进入文章的正题了,Transformer的核心是Self-Attention,那么在这之前,我们最起码要了解什么是Attention,然后再看是这么在 Attention的基础上加上self的。 1.1.1 NLP中的Attention 由于传统的Encoder-Decoder模型将所有的输入信息编码成一个固定长度的content向量存在长距离问题。那么随之而然的一个做法就是我们在decoder阶段解码$h_t$不仅依赖前一个节点的隐藏状态$h_{t-1}$, 同时依赖Encoder阶段所有的状态,就和我们自已翻译的时候一样。这里有两个经典注意力机制,Bahdanau Attention (2014年提出)和 Luong Attention(2015年)。 1.1.1.1 Bahdanau Attention 注意力机制 示意图如下: 假设现在我们Decoder t时刻。 那么$h_t$隐状态计算过程如下: 计算对齐向量$a_t$ $a_t$的长度与Encoder输出向量的个数相同。$a_t(s)$表示Decoder阶段的转态$h_{t-1}$与Encoder阶段第s个隐状态,通过align对齐函数计算出的一个权重。$a_t$就是$h_{t-1}与每一个Encoder隐状态计算权重后组成的一个向量。 计算$c_t$即content vector 将上一步计算出的$a_t$向量乘以Encoder所有的隐向量。即Encoder所有的隐向量的加权和。 计算Decoder阶段t时刻的输出,$h_t$ 将$h^{l-1}{t-1}$与concat($c_t$, $h{t-1}$)送入多层RNN(最后一层)。其中$h^{l-1}{t-1}$为上一阶段的预测输出。concat($c_t$, $h{t-1}$)相当于RNN的隐状态。最终将$h_t$过一个softmax就可以预测最终的输出($y^t$)了。 1.1.1.2 Luong Attention 注意力机制 Luong Attention是在Bahdanau Attention之后提出的。结构更加简洁,效果也更加好一点。 假设现在我们Decoder t时刻。 那么$h_t$隐状态计算过程如下: 计算对齐向量$a_t$ $a_t$的长度与Encoder输出向量的个数相同。$a_t(s)$表示Decoder阶段的状态$h_t$与Encoder阶段第s个隐状态,通过align对齐函数计算出的一个权重。$a_t$就是$h_t$与每一个Encoder隐状态计算权重后组成的一个向量。...

4 分钟 · Pan

VAE

updates-20241020: 添加变分相关概念 Vanilla VAE( Autoencoder) 一、AutoEncoder 回顾 生成模型 最理想的生成就是知道输入样本的分布$P(X)$, 然后我们并不知道该分布。那么可以近似求解。 $P(X) = \Sigma P(X|Z)*P(Z)$。但$P(X|Z), P(Z)$我们同样不知道。但是我们可以用神经网络去学习这两个分布。上图中的latent vector可以看成是$P(Z)$的一个采样,decoder可以看成条件概率$P(X|Z)$。但是我们真的可以采样一个z,然后用加一个decoder来作为我们的生成模型吗? z是Encoder对应着样本X的输出,如果我们直接用Decoder对z还原,那么最终得到的$\hat{X}$是和X是差不多的,我们需要生成模型是生成一个和X类似的,而不是一模一样的 如果对z做一些扰动,必然加一些噪声,那是不是就可以生成类似但是不一样的东西呢?理论上是可以,但是到目前为止,我们的模型并没有保证这一点(模型还没有学习) 加噪声是一个好的思路,如何加噪声? 让z从一个分布采样(注意不是直接使用encoder的输出),就是噪声。 那不放让z从一个$N(u, \sigma^2)$中采样。那需要知道$u, \sigma^2$, 既然不知道那就用神经网络生成吧。 如果我们按照上述去训练我们的模型,生成的方差$\sigma^2$会倾向于变成0(因为容易学)。那如何加以限制?使z倾向于一个标准正态分布,即$\sigma^2$倾向于1。 如下图 如何监督模型达到该目的,KL loss作为监督信号,KL loss如下 reparameterization trick 让z从$N(u, \sigma^2)$中采样,由于这个操作是不可导的,所以需要使用重采样技巧去解决不可导的问题。 $$z \sim N(u, \sigma^2) \iff z \sim u+\sigma^2 \times \epsilon$$ ,其中$\epsilon \sim N(0,1)$ 思考? 为什么要正态分布、其它分布可否? Variational Bayes 什么是变分贝叶斯推断?将贝叶斯后验概率计算问题转化为一个优化问题(计算->优化)。本章节汇总记录一些概念,上面讲解的部分已经可以支撑去训练一个VAE模型了,但是如果还不知道VAE中Variational的含义就有点说不过去了,我本来以为Variational是一个简单的概念,但是了解后发现并不简单,涉及一个数学分支。所以下面就记录一些涉及的相关概念,有助于大家的理解。后续我有新的认知会进一步完善。 泛函(functional) 定义1:泛函(functional)通常是指定义域为函数集,而值域为实数或者复数的映射。换而言之,泛函是从由函数组成的一个向量空间到标量域的映射。 定义2:设C是函数的集合,B是实数集合;如果对C中的任一个元素y(x),在B中都有一个元素J与之对应,则称J为y(x)的泛函,记为J[y(x)]。 通俗的讲泛函就是函数的函数,对于函数的定义我们再熟悉不过了,y = f(x),其中x是一个数值(定义域),y是一个数值(值域),f为映射关系。如果将x变成一个函数集合,那么就称之为泛函,即f[g(x)]。 变分(variational) 变分与函数的微分类似,变分为定义在泛函上的微分。g(x)和新函数g(x)+m$\eta(x)$的差导致泛函的变化就叫变分。即 $$\delta J = J[g(x)+m\eta(x)]-J(g(x))$$ ,其中$\delta J$就是变分。 变分法(Calculus of Variations or variational method) 使用变分来找到泛函的最大值和最小值的方法...

1 分钟 · Pan