• mysql相关问题总结


      mysql我们经常使用,但是我们对其中的知识也要了解和熟悉,我们需要做一下必要的总结,方便自己和同学们一起学习。接下来我们一起来看看平时我们需要了解和掌握的知识有哪些。

      1. myisam和innodb的区别?

      2. mysql的几种事务隔离级别。

      3. 什么是聚簇索引和非聚簇索引。

      4. 什么是覆盖索引、回表。

      5. ACID是如何保证的。

      6. 主从是如何同步的,有什么缺点?

      

    1. myisam和innodb的区别。

      myisam是之前mysql的默认引擎,主要用于读大于写的时候使用,数据存放在内存中,这样读的速度非常快,但是当数据库重启之后数据将需要重新加载到内存中。这个引擎从5.1之前都是默认的引擎。但是它不支持事务、行锁、外键,这些都是它的缺点。

      innodb的产生就是为了解决它的缺点。innodb支持事务、行锁、外键。现在非常流行的就是这个数据库引擎。通过MVCC实现高并发访问。

    2.mysql的几种事务隔离级别。

     mysql支持未提交读,已提交读,可重复读,串行Serializable。mysql默认隔离级别为可重复读,oracle的默认隔离级别为已提交读。

     未提交读(Read Uncommitted) :即事务还没有提交的时候别的事务可以查看到数据,也成为脏读。举个例子,

     事务A,查询id=1的name,此时name为hqs。

     事务B,更新id=1的name为hhh。我们将看到如下的结果:

       已提交读(Read Committed),  当事务提交的了之后,另外一个事务才能看到。不会出现上边的问题,即不会出现脏读,但是在这个过程中会出现不可重复读,接下来我们继续看,基本上还是刚才的例子。

       可重复读(Read Repeatable):每次可以正确的读取数据的结果,但是会出现幻读,接下来我们看看这种情况。

      说道可重复读,我们需要了解一下他是如何实现的。它采用MVCC(Multi Version Concurency Control), 多版本并发控制,类似于数据库的乐观锁,通过版本号来控制该读哪个版本号的数据,实现对数据的高并发访问。

      首先我们需要知道什么是undolog,redolog,binlog。

      undolog,即未做日志,也就是加入数据库里边有一条id=1 and name='hqs'的数据,那么我修改了这个数据的name='hhh',当事务提交了之后,会有一条undolog,这个时候执行的语句就是update table set name='hqs' where id=1,即还原之前的数据。相应的如果有一条insert语句会有一条对应的delete语句,当事务出现了问题之后需要回滚到上一个版本上。这个也是mvcc的关键。

      redolog,数据库的操作过程是非常快速的,一般执行数据库操作的时候需要将数据先写入到缓存,即write ahead log,比如写入数据会有一条insert语句,更新会有一条update语句等,这个时候需要先写到缓存中,然后当执行成功后会刷到磁盘上。这个时候实现了快速的处理和写入。写入缓存的时候为parepare,写完之后即变为commit,这也就是两阶段提交时进行的数据处理,当commit之后然后就可以flush到磁盘上。

      binlog,即所有引擎日志,数据有了之后就有这个日志,记录了server的操作日志。用于主从复制,数据恢复时使用,这个需要定时保存。

      数据库在执行了事务之后,每条记录除了数据之外,还有几个关键字段db_trx_id, db_roll_ptr。

      db_trx_id,即执行事务的id。

      db_roll_ptr,事务回滚的指针,用于指向undolog的记录,当事务执行失败之后需要需要回滚到之前的版本号。

         

      MVCC就是采用事务版本号进行读取的,当commit之后,我们知道最后一个事务成功的版本号,然后根据这个版本号产生一个读视图(read view),通过读视图读取数据时,这个时候就能正确的读取数据。

      那我们知道了可重复读的隔离情况下,如何解决幻读呢?

      假如我们数据库里边有这几条数据。

       这个时候我们执行下边的两条事务,第一条语句执行的时候加了行锁,然后第二条语句开始进行写入。

    begin;
    select * from table where age = 20 for update;
    
    
    begin;
    insert into table (name, age) values (h4, 10); #成功
    insert into table (name, age) values (h5, 20); #失败
    insert into table (name, age) values (h6, 25); #失败
    insert into table (name, age) values (h7, 30); #失败

      这个时候就出现了Gap Lock,这个是可重复读隔离级别独有的。通过这种方式可以获取“当前读”,即当前最新的数据,避免产生幻读。行锁+间隙所解决幻读的问题。

      关于间隙锁,我们接下来继续认识一下。以上数据产生的间隙锁如下(左包含右边不包含):

    (负无穷, 10], (10 20], (20, 30], (30, 正无穷)

      因为数据里边有age=20的记录,所以(10, 20]会锁定,这些记录段的数据不能进行更新操作。所以10成功了,20失败了之后,后边的就全部失败了,因为有失败了之后进行了数据的回滚。

      如果索引是唯一索引的话不存在间隙锁。

      基于上边的总结,我整理出一个表格可以更清晰的认识这个事务的级别。 

          

    3. 什么是聚簇索引和非聚簇索引。

      每个表都有一个唯一主键,唯一主键形成的索引树就是聚簇索引,采用B+树进行的数据存储。每个节点存储这个数据的索引id,一层一层的按范围分的,越往上越范围越大,越往下范围越小。叶子节点存储的真实的数据,真实的数据是id从小到大的数据进行分布的,数据采用双向链表用于数据的快速查找。如下图所示:

       非聚簇索引也称为非主索引,加入以name+age为索引的话,那么效果就是这样的,根据索引字段生成一个索引id,然后索引id和主键形成一个映射。然后再根据主键进行数据的查询。效果如下:

      

    4. 什么是覆盖索引、回表。

      覆盖索引理解起来比较简单,即执行explain的时候的时候提示“using index”,即使用了覆盖索引。

      比如有一个table,有表A、B、C字段,假如有index( A,B,C) 那么,我们查询顺序A, AB, ABC的时候,都是采用覆盖索引。

      当我们使用字段B,C的时候,那么没有走到数据库的索引,这个时候需要先查询到索引对应的主键id,然后再进行二次查询,这个就是回表。

      

    5. ACID是如何保证的。  

      A原子性,通过undolog保证,当事务执行失败的时候,通过unlog将数据还原来保证事务的一致性。

      C一致性,当两个事务提交后,最终能保证数据的结果是一致的。

      I隔离性,通过MVCC来保证。

      D持久性,通过内存+redolog,数据一般会刷到内存,然后事务提交之后再刷到磁盘上。当数据有问题的时候通过redolog来进行数据恢复。

    6. 主从是如何同步的,有什么缺点?

      主从同步,分为几个步骤:

      1. master写入binlog。

      2. slave连接到master,并且记录好binlog的id.

      3. master的binlog进行slave日志同步。

      4. slave开启一个线程,读取binlog的日志,然后写到中继日中relaylog中。

      5. slave在开启一个线程,从relaylog读取日志之后写到slave数据库看。

      6. slave会记录到自己的数据库中。

      如下图所示:

      

      由于默认mysql同步日志是采用异步的,所以主库写入不写入从库,主库不关心,这个时候从库出现了问题的话,主库无感知。如果主库失败了,那么从库读取失败的话,从库升级为主库,日志就丢失了。这个时候就会出现两种情况:

      全同步复制:

        全同步就是当主库往从库写数据采用的同步处理,这个时候主库写完binlog,然后等待从库处理完成,这样会影响效率。

      半同步复制:

        半同步是在数据发给从库后,从库处理完之后会发一个ACK给主库,这样主库就知道了,然后确认传输完成。

      当然,我们除了数据库的解决数据丢失问题,我们还需要程序来保证额外的数据冗余处理,比如将传输的数据发送到MQ或KAFKA,其他系统可以从这个里边去读取,然后进行下一步处理。保证数据的安全可靠。

      

      

  • 相关阅读:
    Domain Logic approaches
    Comparing Spring AOP and AspectJ
    CDI Features
    Java Design Patterns
    第二阶段:代码片段
    第一阶段:学生在线系统需求分析报告
    load data语句实验报告
    Sping AOP Capabilities and Goals
    Java Design Patterns
    CDI Features
  • 原文地址:https://www.cnblogs.com/huangqingshi/p/13620711.html
Copyright © 2020-2023  润新知