美文网首页
Mysql体系结构(二)

Mysql体系结构(二)

作者: 以南之南_b9a1 | 来源:发表于2019-04-13 15:09 被阅读0次

    上章节简单的提到了连接Mysql 实例和Mysql数据库的区别 以及存储引擎的介绍,这章节 就介绍下 Mysql基础知识 。

    Mysql基础连接管理和安全性:

    连接Mysql就是两个线程之间的连接 ,连接工具的线程和Mysql实例的线程,也就是线程和线程之间通信,当客户端连接到Mysql实例的时候,会对其进行认证,基于用户名,主机信息和密码,一但连接成功,Mysql实例,会继续验证 改客户亿是否具有执行某个特定查询的权限。

    Mysql对并发的控制:

    Mysql在两个层面分别对并发进行了控制:服务器层与存储引擎层,当然 也可以加锁,Mysql有两种锁:共享锁和排他锁。共享锁:读锁是共享的,或者可以说是互补干扰的,不阻塞的,也是同时多个客户读取同一资源,而互不干扰。排它锁:写锁 是排他的,也就是说一个写锁 会阻塞其他的写锁和读锁,当然这是基于安全性考虑的。
    Mysql对并发性的控制可以加锁控制,那么加锁加在那里呢?也就是锁粒度?
    锁粒度:一种提高共享资源并发的方式是让锁定的对象更具有选择性。
    表锁:他会锁整张表,一个用户在对表进行写操作前,首先要获取锁,这会阻塞其他用户对该表的所有写操作。只有没有写操作是,其他读取的用户才能获取读锁。
    行锁:行锁最大程度支持了并发处理,行级锁知识在存储引擎层实现,而在Mysql服务器层没有实现。

    事务

    概念:事务其实就是一组具有原子性的Sql查询,或者说是一个独立的工作单元,
    如果数据库引擎能够成功的应用该组的查询的全部语句,那么执行该组语句,如果其中一条语句因为崩溃或者其他原因无法执行,那么所有的语句都不执行,也就会说事务中的语句,要么全部都执行,全部都不执行。
    事物的ACID
    原子性:
    事务中的语句要么全都提交,要么全部回滚,对一个事务来说,不可执行也是其中的一部分,
    一致性:
    事务中的语句 总是从一个一致性状态转换到另一个状态,要么是成功状态要么是失败状态
    隔离性:
    一个事务所做的修改操作在最终提交前,对其他事务是不可见的,
    持久性:
    一旦事务提交,则所做的修改就永远保留在数据库中,及时数据库系统崩溃,修改的数据也不会消失,

    mysql提供了两种支持事务的存储引擎,InnoDB和NDB Cluster 。Mysql采用自动提交模式,可用:

      show variables like 'autocommit'
    

    查看当前事务模式,

    隔离级别

    Mysql四种隔离级别:
    READ UNCOMMITED(未提交读):
    在未提交读,事务中的修改,及时没有提交,对其他事务也是可见的,事务可以读取为提交的数据,这被称为脏的,
    READ COMMITED(提交读):
    一个事务一旦开始,只能看见,已近提交的事务所做的修改,一个事务从开始直到提交之前,所做的任何修改对其他事务是不可见的,
    REPEATABLE READ(可重复读):
    可重复读会导致幻读的问题:当某个事务在读取某个范围的记录的时候,另外一个事务又在该范围内插入了新的记录,当之前的事务又再次读取该记录的时候,会产生幻行。
    SERIALIZABLE(可串行化):
    可串行化是事务最高的隔离级别,在读取的每一行数据上都加锁,所有可能导致大量的超市为题和锁争用问题。

    Mysql可以通过Set transaction isolation level命令来设置隔离级别。新的隔离级别会在下一个事务开始的时候生效。可以改变整个数据库的隔离级别也可以改变当前会话的隔离级别,set session transaction isolation level

    死锁

    是指两个或者多个事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。

    举个栗子:
    事务1:

    Start Transaction;
    Update table set close = 11 where id =1;
    Update table set close =12 where id =2;
    Commit;
    

    事务2:

    Start Transaction;
    Update table set close = 33 where id =2;
    Update table set close =44 where id =1;
    commit
    

    解决办法:
    1.当查询的时间达到锁等待超时的设定后放弃锁请求,
    2.将持有最少行级排它锁的事务进行回滚。

    InnoDB采用两阶段锁定协议,在事务执行的过程中,随时都可以执行锁定,
    锁只有在Commit和Rollback 的时候在会释放,InnoDb也支持特定的语句进行显示锁定,
    1.SELECT .... LOCK IN SHARE MODE
    2.SELECT.... For UPDATE

    多版本并发控制(MVCC):

    Mysql的大多数事务存储引擎都不是简单的行级锁,而是提升并发性能的考虑,他们一般都是实现了多版本并发控制,
    MVCC:可以认为他是行级锁的一个变种,但是在很多情况下,它避免了加锁操作,因此开销更低,虽然实现机制有所不同,但是大都实现了非阻塞的读操作,写操作也只锁定必要的行。
    MVCC的实现,是通过保存数据在某个时间的快照来实现,也就是说,不管你事务执行多长时间,每个事务看到的数据是一直的,根据事务开始的开始的时间不同,每个事务对同一张表,同一时刻看到的数据可能是不一样的。
    InnoDB的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的,一个保存了行的创建时间,一个保存行的过期时间,当然存储的并不是具体的时间值,而是系统版本号码,每开始一个新的事务,系统版本号码会递增,事务开始的时候,系统版本号作为事务的版本号,用来和查询到的每行记录的版本号进行比较。对于REPEATABLE READ隔离级别下,MVCC具体是如果操作的?
    SELECT:
    InnoDB会根据一下两个条件检查每行记录:
    a.InnoDB只查找版本早于当前事务版本的数据行(也就是,行的系统版本号小于或等于事务的系统版本行),这样可以确保事务读取的行,要么是在事务开始前一句存在的或者是事务自身修改的。
    b.行的删除版本要么未定义要么大于当前版本,这可以确保事务读取到的行,在事务开始之前未被删除。
    INSERT:
    InnoDB未新插入的行的每一行保存当前系统版本号作为版本号;
    DELETE:
    InnoDB为删除的每一行保存当前系统版本号作为行的删除表示。
    UPDATE:
    InnoDB为插入一行新记录,保存当前系统版本号作为行版本号,同时保存当前系统版本号到原来的行作为行删除标识。

    MVCC只在可重复读,和读已提交,两个隔离级别下工作。

    如何选择合适的引擎

    1.事务
    如果应用支持事务,那么InnoDB则是目前最稳定并且进过验证的选择,如果不需要事务,并且主要是SELECT和InSERT操作,那么MYISAM是不错的选择,
    2.备份
    数据备份也会影响存储引擎的选择,如果定期的关闭服务器来执行备份,那么备份的因素可以忽略,反之,需要在线热备份,那么InnoDB将是不错的选择。
    3.崩溃恢复
    数据量比较大的时候,系统崩溃后,数据如何快速回复也是一个需要考虑的问题,先对而言MyISAM崩溃后发生损坏的概率比InnoDB要高很多,而且恢复速度也慢,因此即使不需要事务支持,很多人也选择InnoDB,这是一个非常重要的因素。
    4.自身的特性,
    如果一个引擎拥有一些关键的特性,同时却又缺少必要的特性,那么有时候就不得不做取舍了,如:Mysql中也只有MyISAM支持地理空间搜索。

    转换数据表的引擎

    1.使用alter table mysqltable ENGINE = INNODB
    但是有一个问题:需要执行很多时间,MySQL会按行将数据从原表复制到一张新的表中,在复制期间会消耗系统所有的I/O能力,
    2.使用MysqlDump工具将数据导出到文件,然后修改文件中的Create table语句的存储引擎选项,但是会有问题,在创建表之前,加上Drop table 语句,如果稍微不注意会导致数据丢失。
    3.使用Insert .....Select语法来导数据

    Start transaction
    insert into innodb_table select * from myisam_table where id between x and y;
    commit 
    

    相关文章

      网友评论

          本文标题:Mysql体系结构(二)

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