zoukankan      html  css  js  c++  java
  • 第一章 MYSQL的架构和历史

    在读第一章的过程中,整理出来了一些重要的概念.

    锁粒度 

    表锁(服务器实现,忽略存储引擎).

    行锁(存储引擎实现,服务器没有实现).

    事务的ACID概念

    原子性(要么全部成功,要么全部回滚).

    一致性(从一个一致性状态转换到另外一个一致性状态).

    隔离性(一个事务所做的修改在提交前,对其他事务是不可见的).

    持久性(一旦事务提交,所有修改都会永久保存到数据库中). 

    四种隔离级别

    READ UNCOMMITTED(未提交读): 事务即使没有提交,所做的修改对其他事务是可见的.  也称脏读.

    READ COMMITTED(提交读): 事务没有提交前,所做的任何修改对其他事务是不可见的.这大多数数据库默认的隔离级别,也叫不可重复读.

    REPEATABLE READ(可重复读): 当某个事务读取某个范围内记录时,另外一个事务又在该范围内插入了新纪录并且提交成功,这时前一个事务再次读取该范围内记录,便会产生幻行.

    SERIALIIZABLE(可串行化): 通过强制事务串行执行,避免幻读的问题, 也就是在读取的每一行记录上加锁,所以可能导致大量超时和锁争用,实际中很少用这个隔离级别.

    SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;  

    设置隔离级别,在下次事务时生效.

    死锁

    多个事务在同一资源相互占用,并请求锁定对方占用的资源,从而导致恶性循环. 当多个事务试图以不同的顺序锁定资源时,就可能会产生死锁.多个事务同时锁定同一资源,也会产生死锁.

    Transaction #1
    START TRANSACTION;
    UPDATE StockPrice SET close = 45.50 WHERE stock_id = 4 and date = '2002-05-01';
    UPDATE StockPrice SET close = 19.80 WHERE stock_id = 3 and date = '2002-05-02';
    COMMIT;
    Transaction #2
    START TRANSACTION;
    UPDATE StockPrice SET high  = 20.12 WHERE stock_id = 3 and date = '2002-05-02';
    UPDATE StockPrice SET high  = 47.20 WHERE stock_id = 4 and date = '2002-05-01';
    COMMIT

    上面两个事务同时执行了第一条语句,更新了一条记录,同时都锁定该条记录,接着事务执行第二条记录,发现被锁定,于是都等待对方释放锁 这时就陷入了死循环.

    解决:

    当查询等待的时间超过锁等待超时的设定后就会放弃锁请求.

    InnoDB处理: 将持有最少行级排他锁进行回滚.

    自动提交

    默认采用自动提交(AUTOCOMMIT), 如果不显示开始一个事务,则每次查询都被当作一个事务执行提交操

    SHOW VARIABLES LIKE 'AUTOCOMMIT'
    1或者ON表示启用,0或者OFF表示禁用
     
    SET AUTOCOMMIT = 1;   开启自动提交
     
    修改AUTOCOMMIT对非事务型的表,比如MYISAM或者内存表没有任何影响.
     

    同一事务中使用多种存储引擎(InnoDB和MYISAM)不可靠,正常情况下不会有什么问题,但如果该事务需要回滚,则非事务型表上的操作不可撤销.

    多版本并发控制

    MVVC是行级锁的一个变种,但它在很多情况下避免了加锁的操作,因此开销更低.

    InnoDB简化版的MVCC:通过在每行记录保存两个隐藏的列,一列保存行的创建时间, 一列保存行的过期时间(删除时间)  当然不是实际时间,而是系统版本号. 每次开始一个事务,系统版本号就会递增, 事务开始时刻的系统版本号作为事务版本号.

    SELECT

      a. InnoDB只查找版本早于当前事务版本号的数据行(也就是, 行的版本号小于等于事务的系统版本号), 这样保证事务读取的行,要么是在事务开始就已经存在,要么是事务自身插入或修改过的.

      B.行的删除版本要么未定义,要么大于事务版本号,这样确保事务读取的行在事务之前没有被删除。

      只有符合这两个条件的记录,才能作为查询结果.  

    INSERT

      InnoDB为新插入的每一行记录保存当前版本号作为行版本号.

    DELETE

      InnoDB为删除的每一行保存当前系统版本号作为删除标识.

    UPDATE

      InnoDB为插入一行新纪录,保存当前系统版本号作为行版本号,同时保存当前系统版本号到原来的行作为行删除标识.

    只有在REPEATABLE READ 和 READ COMMITED 两个隔离级别工作,其他隔离级别都和MVCC不兼容, 应为READ UNCOMMITTED总是读取最新记录行,不符合当前事务版本的数据行. 而SERIALIIZABLE会为读取到的行加锁.

  • 相关阅读:
    安装apache服务
    基于mysqld_multi实现MySQL 5.7.24多实例多进程配置
    linux安装lolcat实现彩色文字输出信息
    haproxy+keepalived实现高可用
    LVS DR模拟实验
    nginx+keepalived实现高可用
    cpu相关信息查看
    LVS集群
    session之memcache
    tomcat之redis
  • 原文地址:https://www.cnblogs.com/tanxing/p/5689947.html
Copyright © 2011-2022 走看看