设为首页 收藏本站
查看: 637|回复: 0

[经验分享] MySQL之并发控制、锁、事务

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2017-2-14 08:53:37 | 显示全部楼层 |阅读模式
连接管理器:监听在某个套接字上,接收请求、创建线程、做用户认证,建立安全的会话连接
线程池:用来缓存MySQL的线程,实现线程复用,提高MySQL的性能
缓存器:里面有许多缓存槽,一个缓存槽中可以缓存多个数据,缓存那些值不经常变化的数据,供下次相同请求从缓存中直接响应,加速MySQL处理性能。但缓存也有缺点,如想要的数据不管有没有在缓存槽中缓存,连接管理器和解析器都要每次去缓存中看一看,会加大开销。并且不是所有数据都能缓存,如经常变化的数据(如时间)。

并发控制:任何时候当出现两个及以上的人同时访问某一个数据时,都会带来并发控制的问题,要做到让以个人的操作不影响到其他人的操作,这流需要并发控制

MVCC(多版本并发控制):每个人在对数据进行操作时,操作的并不是原始数据,而是其副本或者快照,操作完成后再将多个快照进行合并(一般在某个时间值上创建快照,并按照时间点合并快照,且以后一个快照为准)

锁:
  • 读锁:也叫做共享锁(读的时候允许让多人同时读,但任何时候都不允许任何人写)
  • 写锁:也叫做独占锁(读的时候允许其他人读,但不允许写;而写的时候即不能让其他人写,也不能让其他人读)


mysql> lock tables test1 read|write; 加读|写锁
mysql> unlock tables; 解锁

锁粒度(从大到小)
  • 表锁 锁一个页面
  • 页锁 锁一个数据块,一个数据块中存储着多个行
  • 行锁 锁一个行(实体)



注:MySQL服务器只支持表锁,行锁要由存储引擎来完成

会话1 mysql> lock tables test1 read; 加读锁
会话2 mysql> select * from test1; 可以查看
+-----+---------+-----+
| cid | name    | sid |
+-----+---------+-----+
|   1 | zxl     | A   |
|   2 | jiamian | B   |
|   3 | fade    | C   |
+-----+---------+-----+
3 rows in set (0.03 sec)

会话2 mysql> insert into test1 (cid,name,sid) values (4,'faded','D');插不进去
会话1 mysql> unlock tables; 解锁
会话2 mysql> insert into test1 (cid,name,sid) values (4,'faded','D');
    Query OK, 1 row affected (2 min 13.83 sec) 现在才插进去了


事务:一个RDBMS(关系数据库管理系统)要支持事务,必须满足四个要求(ACID)
原子性:用户转账 A-500,B+500 要么A和B都完成,要么都不完成;事务引起的数据操作要么完成,要      么不完成
一致性:用户转账 A-500,则B必须加500,及完成之前和完成之后事务要一致;事务状态平稳过度
持久性:一个事务一旦完成,就算server崩溃了,下次启动后这个完成的事务也必须有效
隔离型:一个事务的中间操作不能影响另一个事务的执行

如果一个事务的完成要经过4步,但执行到第三步时server崩溃了,则必须对执行的前3步进行撤销,并对数据进行还原,但具体是如何实现的?
答:依靠日志

事务的日志分为两种
  • 重做日志 每次操作都要写入重做日志中,server崩溃后,重启后会根据重做日志中的记录重新执行一遍操作
  • 撤销日志 每次执行操作时都要将原来的状态保存下来,server崩溃后,可以按照撤销日志中记录的原状态还原回去

关于日志的记录,一般日志只是记录了操作,而不是数据本身,所以执行起来非常快

事务一旦提交,不管数据有没有同步到磁盘,都表示事务已经完成;而一般来说所有的操作都先是在内存中执行一遍后,再斜土日志中,最后才写入磁盘的数据存储文件中(如innodb的.ibd数据文件)

如果事务已近提交,但是并未同步到磁盘是,server崩溃了,这时在sever重启时,如果日志中已近有记录如何操作,则会根据日志进行数据修复,将数据写入磁盘上(如果数据量很大的话,修复起来很慢,你若在中间ctrl+c,则很可能导致数据崩溃或者错乱),如果操作未记录入日志中,则会执行撤销操作

事务的隔离级别,下面的隔离级别按照从高到低排序(即并发能力从大到小排序)
read uncommitted(读未提交):只要别人对数据进行了修改,我立马就能看到
read committed(读提交):只有当别人将事务提交了,我才能看到修改
repatable read(可重读):mysql默认的,不管别人有没有提交,只有当我的事务提交了才能看到修                  改)
seriablizable(串行):别人完成事务后,我才能对数据进行操作


mysql> show global variables like '%iso%'; 查看当前MySQL的隔离级别
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| tx_isolation  | REPEATABLE-READ |
+---------------+-----------------+
1 row in set (0.08 sec)
mysql> set session tx_isolation='READ-UNCOMMITTED'; 修改隔离级别变量
Query OK, 0 rows affected (0.00 sec)

mysql> select @@tx_isolation; 查看某一个变量的值
+------------------+
| @@tx_isolation   |
+------------------+
| READ-UNCOMMITTED |
+------------------+
1 row in set (0.00 sec)

事务的状态有以下几种:

  • 正在执行语句
  • 部分提交(事务已进执行完毕,但最后一条语句还处于往磁盘写入的状态)
  • 失败的(事务已经完成,但是提交失败)
  • 中止的(事务没有完成就中止)
  • 已提交(事务已经成功提交)


注:事务一旦提交就无法撤销

只有从第一个语句到最后一个语句写入磁盘,才算事务提交且执行成功

事务:并发执行
  • 提高吞吐量和资源利用
  • 减少等待时间



事务调度
  • 可恢复调度:任何一个事务进行调度时,如果出现交叉执行,都不会对另一个事务的调度产生影响
  • 无级连:避免事务撤销时彼此之间影响


并发控制依赖的技术手段:


  • 时间戳
  • MVCC和快照隔离


例:

mysql> start transaction; 启动事务

mysql> delete from test1 where name='jiamian';
Query OK, 1 row affected (0.26 sec)

mysql> select * from test1;
+-----+-------+-----+
| cid | name  | sid |
+-----+-------+-----+
|   1 | zxl   | A   |
|   3 | fade  | C   |
|   4 | faded | D   |
+-----+-------+-----+
3 rows in set (0.00 sec)

mysql> ROLLBACK; 回滚,撤销
Query OK, 0 rows affected (0.02 sec)

mysql> select * from test1;
+-----+---------+-----+
| cid | name    | sid |
+-----+---------+-----+
|   1 | zxl     | A   |
|   2 | jiamian | B   |
|   3 | fade    | C   |
|   4 | faded   | D   |
+-----+---------+-----+
4 rows in set (0.00 sec)

mysql> commit; 事务提交
Query OK, 0 rows affected (0.00 sec)

mysql> select @@autocommit;
+--------------+   
| @@autocommit |
+--------------+
|    1     |
+--------------+
1 row in set (0.00 sec)

autocommit是否开启了事务自动提交 1表示开启,如果不是每次明确启动事务(start transaction),则每执行一个操作都自动提交

建议:明确使用事务,并且关闭自动提交

>set session autocommit=0;

MySQL支持事务的保存点,如一个事务的执行有100个操作,当执行到75个时出错了,可以撤销到保存点的位置(如每10个操作一个保存点),则可以撤销到第70个保存点,而不必从第一个操作重新执行

>start transaction;
>delete from tutors where tid=18;
>savepoint num1; 设定保存点num1
>delete from tutors where tid=14;
>savepoint num2;
>delete from tutors where tid=12;
>savepoint num3;
>select * from tutors;
>rollback to num3;
>selete * from tutors;
这是你会发现tid=12的还原了
>commit;






运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-341816-1-1.html 上篇帖子: percona-toolkit工具包的安装和使用 下篇帖子: centos7 mysql5.7(5.7.17-linux-glibc2.5)源码安装
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表