纯干货,Mysql innodb的ACID特性是怎么实现的?以及高并发情况下会出现的问题
首先说说什么是ACID:
它们分别是Atomicity(原子性),Consistency(一致性),Isolation(隔离性),Transaction(持久性)
原子性:
意为单个事务里的多个操作要么一起成功,要么一起失败.比如现在有三个插入操作,那么前两个成功,第三个失败了,此时,前两个也不再算数,数据库会回滚到事务开始之前的状态.
innodb靠着undo缓冲区实现,也就是当事务开始的时候,首先将会受到影响的行当前的状态保存到undo缓冲区中,一旦失败,则回滚.
一致性:
单个事务对数据库的影响必须要保证是从一个状态到另一个状态的,这个怎么理解呢?将它理解为对原子性的补充就行了,也就是说,你一个事务里三个操作,如果其中一个失败了,其它的也不能对我的数据库造成影响,必须要三个一起成功才行.
这个的实现就是原子性的实现
隔离性:
这个是靠数据库锁实现的,数据库锁实在太繁杂,我这里就说说怎么mysql是怎么保证了在可重复读的情况下就避免了不可重复读和幻读吧.
首先,mysql的读操作在innodb下的读提交和可重复读的情况下都是使用了Mvcc,这个Mvcc将它理解为一个快照就可以了,而读已提交在一个事务里多次读的情况下,每次读都会读最新的已提交的数据.由此也就出现了幻读和不可重复读
比如A线程在一个事务里连续两次select
在第一次select后,B线程插入了一条数据,并且提交了事务.
此时A线程因为每次都是读最新的已提交的数据自然就读到了B线程插入的数据.
而在可重复读的情况下呢?
首先可重复读的情况下读Mvcc每次都是读第一次select的数据,由此就避免了可重复读和幻读的产生,因为B线程插入的数据对线程A的事务没有任何影响,但这样就代表没问题了吗?
假设这样一个场景,线程A要拿到当前最大的ID然后自增之后插入
假设现在数据库最大ID为10
线程A查询后,自增为11,并准备插入
但此时线程B插入一条数据,并且ID为11.
此时线程A插入,然后报错.
由此可见,此时还是会有问题.
那么怎么解决呢?很简单,使用select max(id) from table for update
因为在可重复读的情况下,使用排它锁,会默认升级为间隙排他锁,什么叫间隙排他锁呢?就是会锁离你最近的两个行数据,并且还有他们之间,不让别人进行增删改查操作,如果没有则取无限集.
那么此时,10右区间无限集就被锁起来了,线程B自然没法查询数据(当然也有可能是A,看谁先拿到锁).此时线程A就插入成功,然后B开始查询,之后插入(这里说下为什么是排他锁而不是共享锁呢?因为线程A和线程B在并发的情况下查了max(id)后,他们拿到的都是相同的数据,也就会在插入的时候报错,所以此时直接让他们其中一个堵在select那里,这样另一方拿到数据后,就会更新id,另一方也能拿到最新值了)
持久性:
事务提交后,事务里的数据必须要进行刷盘,也就是强同步
这里要插一句的是,当事务提交后,数据本身不会马上刷盘,而是由一个redo缓冲区保存了插入日志,进行刷盘,为什么要这样做呢?因为redo是日志数据,所以可以顺序写,而数据刷盘则是要找到文件里数据所在的索引,也就是随机写,而随机写比顺序写慢很多,毕竟多了硬盘寻址的操作.
纯干货,Mysql innodb的ACID特性是怎么实现的?以及高并发情况下会出现的问题的更多相关文章
- Mysql高并发情况下的解决方案(转)
查询了下Mysql 关于高并发的处理的资料,在这记录一下. 高并发大多的瓶颈在后台数据逻辑处理,在存储,mysql的正常的优化方案如下: 1.代码中sql语句优化 2.数据库字段优化,索引优化 3.加 ...
- Mysql在高并发情况下,防止库存超卖而小于0的解决方案
背景: 本人上次做申领campaign的PHP后台时,因为项目上线后某些时段同时申领的人过多,导致一些专柜的存货为负数(<0),还好并发量不是特别大,只存在于小部分专柜而且一般都是-1的状况,没 ...
- 深入学习MySQL事务:ACID特性的实现原理
事务是MySQL等关系型数据库区别于NoSQL的重要方面,是保证数据一致性的重要手段.本文将首先介绍MySQL事务相关的基础概念,然后介绍事务的ACID特性,并分析其实现原理. MySQL博大精深,文 ...
- MySQL事务及ACID特性
一.事物 1.定义:事务是访问和更新数据库的程序执行单元,事务中包含一条或者多条SQL语句,这些语句要么全部执行成功,要么都不执行. 在MySQL中,事务支持是在引擎层实现的,MySQL是一个支持多引 ...
- 一文说尽MySQL事务及ACID特性的实现原理
MySQL 事务基础概念 事务(Transaction)是访问和更新数据库的程序执行单元:事务中可能包含一个或多个 sql 语句,这些语句要么都执行,要么都不执行.作为一个关系型数据库,MySQL 支 ...
- MySql计数器,如网站点击数,如何实现高性能高并发的计数器功能
MySql计数器,如网站点击数,如何实现高性能高并发的计数器功能 Clicks: Date: -- :: Power By 李轩Lane TagMysql计数器高性能 现在有很多的项目,对计数器的实现 ...
- 【转】记录PHP、MySQL在高并发场景下产生的一次事故
看了一篇网友日志,感觉工作中值得借鉴,原文如下: 事故描述 在一次项目中,上线了一新功能之后,陆陆续续的有客服向我们反应,有用户的个别道具数量高达42亿,但是当时一直没有到证据表示这是,确实存在,并且 ...
- 搞懂MySQL InnoDB事务ACID实现原理
前言 说到数据库事务,想到的就是要么都做修改,要么都不做.或者是ACID的概念.其实事务的本质就是锁和并发和重做日志的结合体.那么,这一篇主要讲一下InnoDB中的事务到底是如何实现ACID的. 原子 ...
- [纯干货] MySQL索引背后的数据结构及算法原理
摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...
随机推荐
- UVA 1661 Equation (后缀表达式,表达式树,模拟,实现)
题意:给出一个后缀表达式f(x),最多出现一次x,解方程f(x) = 0. 读取的时候用一个栈保存之前的结点,可以得到一颗二叉树,标记出现'X'的路径,先把没有出现'X'的子树算完,由于读取建树的时候 ...
- 树形dp——覆盖所有边的最少费用(Protecting Zonk)
一.问题描述 有一个n(n<=10000)个节点的无根树.有两种装置A,B,每种都有无限多个. 1.在某个节点X使用A装置需要C1(C1<=1000)的花费,并且此时与节点X相连的边都被覆 ...
- 并查集+思维——Destroying Array
一.题目描述(题目链接) 给定一个序列,按指定的顺序逐一删掉,求连续子序列和的最大值.例如序列1 3 2 5,按3 4 1 2的顺序删除,即依次删除第3个.第4个.第1个.第2个,答案为5 4 3 0 ...
- OpenCV2:总结篇 core模块
一.cv::Mat 1.作用 cv::Mat表示图像类,用来操作图像和矩阵,它包含很多属性和方法 2.构造方法 cv::Mat image; //cv::Mat image() 无参数构造 ...
- VS2019 KEY
VS2019正式版 密钥 Visual Studio 2019 破解 激活码 Key Visual Studio 2019 Enterprise 企业版(亲测可用):BF8Y8-GN2QH-T84 ...
- Sql Server 自动备份
1)启动代理服务 服务->Sql server 代理启动 2)设置维护计划 维护计划->设置维护计划向导->修改名称及说明 3)更改计划 4)选择维护任务 5)顺序调整不做解释 6) ...
- flask模板语言
由于Django的模板引擎和Flask中的Jinja2模板引擎有很多一样的地方,所以我将一样的地方总结到了独立的文章中 https://www.cnblogs.com/kuxingseng95/art ...
- jquery html5 实现placeholder 兼容password ie6
<style type="text/css"> /* 设置提示文字颜色 */ ::-webkit-input-placeholder { color: #838383; ...
- django-ckeditor添加代码功能(codesnippet)
最近做了一个博客,使用python3+django2.1开发的,后台编辑器和前端显示用的Django-ckeditor富文本编辑器,由于发现没有代码块功能,写上去的代码在前端展示有点乱,于是一顿问度娘 ...
- python 多线程 压测 mysql
#!/usr/bin/env python # encoding: utf-8 #@author: 东哥加油 #@file: sthread.py #@time: 2018/9/17 17:07 im ...