数据库(一)

作者: FrankerSung | 来源:发表于2019-02-19 23:05 被阅读4次

    First And MOST Important

    \color{red}{如果有错误还请在评论区提出🙏🙏 建议看下本文末尾的参考地址,有些具体的点应该比我总结的更为详尽,希望大家从中受益并尊重原创。🙂}

    锁机制介绍:行锁、表锁、排他锁、共享锁

    共享锁指对于多个不同的事务,对同一个资源共享同一个锁。
    排它锁与共享锁对应:对于多个不同的事务,对同一个资源只能有一把锁。

    行锁,就是给某一行记录加上锁。
    表锁,和行锁相对应,给整张表加上锁。

    乐观锁与悲观锁的业务场景及实现方式

    乐观锁:读多写少。
    乐观锁实现方式:CAS、Version字段

    悲观锁:写多读少。
    悲观锁实现方式:如行锁,表锁等,读锁,写锁等都是在做操作之前先上锁。

    Mysql各存储引擎使用的锁

    MyISAM和MEMORY存储引擎采用表级锁(table-level locking);
    BDB存储引擎采用页面锁(page-level locking),也支持表级锁;
    InnoDB存储引擎默认情况下是采用行级锁(row-level locking),也支持表级锁。

    事务介绍,分布式事务的理解,常见的解决方案有哪些,什么是两阶段提交、三阶段提交;

    1. 数据库事务
      数据库事务,要么完全地执行,要么完全地不执行。 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性。事务是数据库运行中的逻辑工作单位,由DBMS中的事务管理子系统负责事务的处理。

    2. 分布式事务
      分布式事务是指会涉及到操作多个数据库的事务。其实就是将对同一库事务的概念扩大到了对多个库的事务。目的是为了保证分布式系统中的数据一致性。分布式事务处理的关键是必须有一种方法可以知道事务在任何地方所做的所有动作,提交或回滚事务的决定必须产生统一的结果(全部提交或全部回滚)
      CAP理论认为在分布式的环境下设计和部署系统时,有3个核心的需求:Consistency,Availability和Partition Tolerance:
      2.1.1 Consistency:一致性,这个和数据库ACID的一致性类似,但这里关注的所有数据节点上的数据一致性和正确性,而数据库的ACID关注的是在在一个事务内,对数据的一些约束。系统在执行过某项操作后仍然处于一致的状态。在分布式系统中,更新操作执行成功后所有的用户都应该读取到最新值。
      2.1.2 Availability:可用性,每一个操作总是能够在一定时间内返回结果。需要注意“一定时间”和“返回结果”。“一定时间”是指,系统结果必须在给定时间内返回。“返回结果”是指系统返回操作成功或失败的结果。
      2.1.3 Partition Tolerance:分区容忍性,是否可以对数据进行分区。这是考虑到性能和可伸缩性。

    3. 两阶段提交
      二阶段提交(Two-phase Commit)是指,在计算机网络以及数据库领域内,为了使基于分布式系统架构下的所有节点在进行事务提交时保持一致性而设计的一种算法(Algorithm)。通常,二阶段提交也被称为是一种协议(Protocol))。在分布式系统中,每个节点虽然可以知晓自己的操作时成功或者失败,却无法知道其他节点的操作的成功或失败。当一个事务跨越多个节点时,为了保持事务的ACID特性,需要引入一个作为协调者的组件来统一掌控所有节点(称作参与者)的操作结果并最终指示这些节点是否要把操作结果进行真正的提交(比如将更新后的数据写入磁盘等等)。因此,二阶段提交的算法思路可以概括为:参与者将操作成败通知协调者,再由协调者根据所有参与者的反馈情报决定各参与者是否要提交操作还是中止操作。
      二阶段提交的缺点:
      3.1.1 同步阻塞问题。执行过程中,所有参与节点都是事务阻塞型的。当参与者占有公共资源时,其他第三方节点访问公共资源不得不处于阻塞状态。
      3.1.2 单点故障。由于协调者的重要性,一旦协调者发生故障。参与者会一直阻塞下去。尤其在第二阶段,协调者发生故障,那么所有的参与者还都处于锁定事务资源的状态中,而无法继续完成事务操作。(如果是协调者挂掉,可以重新选举一个协调者,但是无法解决因为协调者宕机导致的参与者处于阻塞状态的问题)
      3.1.3 数据不一致。在二阶段提交的阶段二中,当协调者向参与者发送commit请求之后,发生了局部网络异常或者在发送commit请求过程中协调者发生了故障,这回导致只有一部分参与者接受到了commit请求。而在这部分参与者接到commit请求之后就会执行commit操作。但是其他部分未接到commit请求的机器则无法执行事务提交。于是整个分布式系统便出现了数据不一致性的现象。
      3.1.4 二阶段无法解决的问题:协调者再发出commit消息之后宕机,而唯一接收到这条消息的参与者同时也宕机了。那么即使协调者通过选举协议产生了新的协调者,这条事务的状态也是不确定的,没人知道事务是否被已经提交。

    4. 三阶段提交
      三阶段提交协议是在二阶段提交的基础上做了优化:在协调者和参与者中都引入超时机制,并且把两阶段提交协议的第一个阶段拆分成了两步:询问,然后再锁资源,最后真正提交。
      缺点:
      也会导致数据一致性问题,因为,由于网络原因,协调者发送的Abort响应没有及时被参与者接收到,那么参与者在等待超时之后执行了commit操作。这样就和其他接到Abort命令并执行回滚的参与者之间存在数据不一致的情况。

    5. Paxos
      参考 https://zh.wikipedia.org/zh-cn/Paxos%E7%AE%97%E6%B3%95

    MySQL记录binlog的方式?优缺点是什么?

    1. Row Level 行级别
      日志中会记录每一行数据被修改的形式,然后在slave端再对相同的数据进行修改
      优点:在row level模式下,bin-log中可以不记录执行的sql语句的上下文相关的信息,仅仅只需要记录哪一条被修改。所以rowlevel的日志内容会非常清楚的记录下每一行数据修改的细节。不会出现某些特定的情况下的存储过程或function,以及trigger的调用和触发无法被正确复制的问题。
      缺点:会产生大量的日志。

    2. Statement Level 语句级别
      每一条会修改数据的sql都会记录到master的bin-log中。slave在复制的时候sql进程会解析成和原来master端执行过的相同的sql来再次执行
      优点:statement level下的优点首先就是解决了row level下的缺点,不需要记录每一行数据的变化,减少bin-log日志量,节约IO,提高性能,因为它只需要在Master上锁执行的语句的细节,以及执行语句的上下文的信息。
      缺点:由于只记录语句,所以,在statement level下肯能会造成MySQL的复制出现问题,如修改数据时使用了某些特定函数或功能。

    3. Mixed 混合模式
      在Mixed模式下,MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志格式,也就是在Statement和Row之间选择一种。如果sql语句确实就是update或者delete等修改数据的语句,那么还是会记录所有行的变更。

    行模式和语句模式在删除一百万行记录时的区别:

    行模式 语句
    只需1条delete * from table 需要记录100万条delete语句

    数据库隔离级别,每层级别分别用什么方法实现

    数据库的四种隔离级别:

    隔离级别 描述
    READ UNCOMMITTED(读未提交) 允许事务读取未被其他事务提交的变更数据,会出现脏读、不可重复读和幻读问题。
    READ COMMITTED(读已提交) 只允许事务读取已经被其他事务提交的变更数据,可避免脏读,仍会出现不可重复读和幻读问题。
    REPEATABLE READ(可重复读) 确保事务可以多次从一个字段中读取相同的值,在此事务持续期间,禁止其他事务对此字段的更新,可以避免脏读和不可重复读,仍会出现幻读问题。
    SERIALIZABLE(序列化) 确保事务可以从一个表中读取相同的行,在这个事务持续期间,禁止其他事务对该表执行插入、更新和删除操作,可避免所有并发问题,但性能非常低。
    img

    数据库如果让你来垂直和水平拆分,谁先拆分,拆分的原则有哪些?

    垂直拆分是把不同的表根据不同的业务拆到不同的数据库中。
    相对于垂直切分更进一步的是服务化,简单来说就是要把原来强耦合的系统拆分成多个弱耦合的服务,通过服务间的调用来满足业务需求看。因为表拆之后不能直接调用了,所以要通过服务化的形式暴露出去。

    单机瓶颈时可以使用水平拆分,水平拆分按照某个字段的某种规则来分散到多个库之中,每个表中包含一部分数据。主要有分表,分库两种模式。

    拆分顺序:先垂直,后水平。
    拆分原则:
    1. 最大可能的找到最合适的切分维度。
    2. 单表拆分到数据1000万以内。
    3. 垂直拆分的依据,尽量把长度较短,访问频率较高的属性放在主表里
    4. 尽量避免分布式事务。

    参考资料
    http://www.hollischuang.com/archives/681

    相关文章

      网友评论

        本文标题:数据库(一)

        本文链接:https://www.haomeiwen.com/subject/yefgeqtx.html