Mysql地毯式由浅入深学习(一)——Mysql的整体架构简介

最近我觉得自己各项技能都是随着工作而学习的,感觉总有一些知识没有掌握,特准备在基于《Mysql权威指南》和《高性能Mysql》这两本书来系统学习下,把每次学习的笔记整理成博客的形式。一是为了加深自己的印象,二是为了给自己提供更好的学习能力,三是和大家共同分享。

1、逻辑架构

第一层:并不是Mysql独有,大多数基于网络客户端、服务器工具,例如:连接处理、授权认证、安全等

第二层:核心服务层,包括查询解析、分析、优化、缓存、内置函数,所有跨域存储引擎都在这一层:存储过程、触发器、视图

第三层:包含存储引擎,负责Mysql数据的存储和提取。

2、Mysql的并发控制

Mysql在服务器层和存储引擎层的的并发控制。

2.1 读写锁

在处理并发读写时可以通过实现一个由两种类型的锁组成的锁系统来解决问题,这两种类型的锁被称为共享锁和排他锁(exclusive lock),也叫读锁和写锁

描述下锁的概念:读锁是共享的,写锁是排他的。

在实际数据库应用中每时每刻都在发生锁定,Mysql锁内部管理透明。

2.3 锁粒度

一种提高共享资源并发性的方式就是让锁定对象更有选择性。尽量只锁定需要修改的部分数据。更理想的方式只对修改的数据片进行精确锁定。锁定的数据量越少并发程度越高。

加锁也是消耗资源的,锁的各种操作,包括获得锁、检测锁是否是否已解除、释放锁等。

所谓的锁策略就是锁的开销和数据的安全性之间寻求平衡,这种平衡当然也会影响性能。

Mysql提供了多种选择,每种存储引擎都可以实现自己的锁策略和锁粒度。下面来介绍两种锁策略:

1、表锁

Mysql基本策略,开销最小。

2、行级锁

最大程度的支持并发,同时也带来了最大的锁开销。行级锁只在存储引擎层实现,而Mysql服务器层没有实现。服务器层完全不了解存储引擎中的锁实现。

所有的存储引擎都以自己的方式显现了锁机制。

3、事务

ACID原则

原子性atomicity、一致性consistency、隔离性isolation、持久性durability

1、隔离级别

read uncommitted(未提交读),事务可以读取到未提交的数据,称为脏读

read committed,一个事务未提交之前所做的对其他事务都是不可见的

repeatable read,解决了脏读问题,该级别保证了同一个事务中多次读取同样记录的结果是一致的。但是理论上无法解决幻读,所谓幻读是,当某个事务正在读取某一个范围的记录时,另外一个事务又向该范围插入一条新的记录,当之前事务再次读取时会产生幻行。Mysql的InnoDB和XtrsDB存储引擎通过多版本并发控制(MVVC,multiversion concurrency control )解决了幻读问题。

serializable可串行化,串行执行,隔离级别最高,超时和锁争用严重,不常用

2、死锁

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

例如:

事务1:

start transaction;

update goods set price = 20 where goods_id = 4 and date=’2015-4-22’;

update goods set price = 30 where goods_id = 3 and date = ‘2015-4-22’;

commit;

事务2:

start transction;

update goods set price = 40 where goods_id = 3 and date = ‘2015-4-22’;

update goods set price = 50 where goods_id = 4 and date = ‘2015-4-22’;

commit;

为了解决这种问题,数据库系统实现了各种死锁检测和死锁超时的机制,越复杂的系统,比如:InnoDB存储引擎,越能检测到死锁的循环依赖,并立即返回一个错误。

还有一种解放方式,当查询的时间达到锁等待超时的设定后放弃锁请求。InnoDB目前处理死锁的方法是:将持有最少行级锁排他锁事务进行回滚。

锁的行为和顺序和存储引擎相关。以同样的顺序执行语句,有些存储引擎会产生死锁有些不会。死锁有双重原因:真正的数据冲突;存储引擎的实现方式。

3、事务日志

提高事务效率,如果修改的已经记录到事务日志并持久化,但数据本身还没回写磁盘,此时系统崩溃,存储引擎在重启时能够自动恢复这部分修改的数据。具体实现方式视存储引擎而定。

4、Mysql中的事务

自动提交(autocommit)

Mysql默认采用自动提交模式,可以通过设置autocommit变量来启用或禁用自动提交模式:

show VARIABLES like ‘autocommit’;

1或on表示启用,0或off表示关闭。

Mysql可以通过执行 set transaction isolation level命令来设置隔离级别,新的隔离级别会在下一个事务开始的时候生效。

例如:set session transaction isolation level read committed;

在事务中混合使用存储引擎

如果在事务中混合使用了事务型和非事务型的表(InnoDB和Myisam)正常提交是不会有问题的,如果事务回滚,非事务型的表变更是无法撤销的,这会导致数据库处于不一致状态。

隐式和显式锁定

InnoDB在事务执行过程中,随时都可以执行锁定,锁只有在执行commit或者rollback的时候才会释放,并且所有的锁都是在同一时刻被释放,前面描述的都是隐式锁,InnoDB会根据隔离级别在需要的时候自动加锁。

另外,InnoDB也支持通过特定的语句进行显示锁定

select … lock in share mode – 共享锁

select … for update – 排他锁

Mysql也支持lock tables和unlock tables,这都是在服务器层实现的,和存储引擎无关。

5、多版本并发控制

Mysql的大多数事务型存储引擎实现都不是简单的行级锁。基于提升并发性考虑,一般都同时实现了多版本并发控制(MVCC),包括Oracle、PostgreSQL。不过实现各不相同。

可以认为MVCC是行级锁一个变种,但是他很多情况下避免了加锁操作,开销更低。虽然实现机制有所不同,但大都实现了非阻塞的读操作,写操作也只锁定必要的行。

MVCC的实现是通过保存数据在某一个时间点快照来实现的。也就是说不管实现时间多长,每个事物看到的数据都是一致的。

分为乐观(optimistic)并发控制和悲观(pressimistic)并发控制。下面来说说是如何工作的:

InnoDB的MVCC是通过在每行记录后面保存两个隐藏的列来实现。这两个列一个保存了行的创建时间,一个保存行的过期时间(删除时间)。当然存储的并不是真实的时间而是系统版本号,每开始一个新的事务,系统版本号都会自动新增。事务开始时刻的系统版本号会作为事务的版本号,用来查询到每行记录的版本号进行比较,下面看下REPEATABLE READ隔离级别下MVCC如何工作:

SELECT

InnoDB会根据以下条件检查每一行记录:

a.InnoDB只查找版本早于当前事务版本的数据行,这样可以确保事务读取的行要么是在开始事务之前已经存在要么是事务自身插入或者修改过的

b.行的删除版本号要么未定义,要么大于当前事务版本号,这样可以确保事务读取到的行在事务开始之前未被删除

只有符合上述两个条件的才会被查询出来

INSERT

InnoDB为新插入的每一行保存当前系统版本号作为行版本号

DELETE

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

UPDATE

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

保存这两个版本号使大多数操作都不用加锁。使数据操作简单,性能很好,并且能保证只会读取到复合要求的行。不足之处是每行记录都需要额外的存储空间,需要做更多的行检查工作和一些额外的维护工作。

MVCC只在REPEATABLE READ和COMMITTED READ

6、Mysql的存储引擎

6.1 InnoDB存储引擎

数据存储在表空间,表空间是由InnoDB管理的一个黑盒子,由一系列数据文件组成,在Mysql4.1以后版本,InnoDB可以将表的数据和索引放在单独的文件中。

InnoDB采用MVCC来支持高并发,默认隔离级别是REPEATEABLE READ,并且通过间隙锁(nex-key locking)策略防止幻读的出现,使得InnoDB不仅仅锁定查询涉及的行还会对索引中的间隙进行锁定,防止幻影行的插入。

InnoDB基于聚簇索引建立,对主键查询有很高的性能,不过他的二级索引(非主键索引)必须能包含主键列,如果主键列很大的话其他的所有索引都会很大。因此如果索引较多的话主键当尽可能的小。

6.2 Myisam存储引擎

Myisam会将表存储在两个文件中:数据文件和索引文件,可存储的行记录数一般受限于可用的磁盘空间或者操作系统中单个文件的最大尺寸。

特性:

1、加锁与并发

对整张表加锁,读取时会对需要读到的所有表加共享锁,写入时则对表加排他锁

2、修复

Mysql可用手工或自动执行检查和修复操作,但不同于事务回复及崩溃修复。执行表的修复可能导致一些数据丢失,而且修复操作非常慢。

3、索引特性

即使是BLOB和TEXT等长字段也可以基于其前500个字符创建索引。也支持全文索引,这是一种基于分词创建的索引

大数据量

当我们创建或者管理很多InnoDB数据的数据量在3~5TB之间或者更大,这是但台机器的量不是一个分片(shard),这些系统运行得还不错。如果数据量继续增长到10TB可能需要建立数据仓库,Infobright是Mysql数据仓库最成功的解决方案。

转换表的存储引擎:

1、alter table mytable engine = InnoDB;执行时间长,消耗I/O能力,同时会在原表上加锁,将会失去原引擎相关的所有特性,例如:如果将一张InnoDB表转换为Myisam再转回去,原InnoDB表上所有的外键将丢失。

2、导出与导入

使用mysqldump工具将数据导出到文件,然后修改文件create table语句的存储引擎选项,同时修改表名,因为同一个数据库中不能存在相同的表名,即使使用不同的存储引擎。

3、创建与查询

综合上述两种方法的高效和安全,不需要导出整个表的数据,而是先创建一个新的存储引擎表。然后利用insert … select语法来到数据

create table innodb_table like myisam_table;

alter table innodb_table engine=InnoDB;

insert into innodb_table select * from myisam_table;

数据量大考虑分批处理

start transaction;

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

commit;

时间: 2024-10-05 04:44:53

Mysql地毯式由浅入深学习(一)——Mysql的整体架构简介的相关文章

Biztalk学习第一章(整体架构)

Biztalk运行时的结构 BizTalk Server 本质上就是消息处理引擎.个人认为在了解Biztalk之前必须要知道的一部分便是BizTalk Server 的整体架构,只有对架构烂熟于心这样才能为往下深入学习做好基础. 首先来看一下Biztalk的整体架构图 如上图所示,完整的绘制了Biztalk在接受端口接收到文件后整个处理文件的过程. 接下来分开叙述:(参照微软官方文档) 接收端口和接收位置 "接收端口"是一个或多个接收位置的集合,是BizTalk Server 的特定入

mysql 5.0存储过程学习总结

mysql存储过程的创建,删除,调用及其他常用命令 本人qq群也有许多的技术文档,希望可以为你提供一些帮助(非技术的勿加). QQ群:   281442983 (点击链接加入群:http://jq.qq.com/?_wv=1027&k=29LoD19)  mysql 5.0存储过程学习总结 一.创建存储过程 1.基本语法: create procedure sp_name()begin………end 2.参数传递 二.调用存储过程 1.基本语法:call sp_name()注意:存储过程名称后面必

Mysql DBA高级运维学习笔记-mysql数据库介绍

本文为我自己学习老男孩MySQL DBA 高级运维课程的学习笔记,内容均出自老男孩MySQL DBA 高级运维课程,老男孩老师讲的很好,非常感谢老男孩老师.我是一个菜鸟刚接触运维,如果我写的文章有不对的地方:请各位行业的精英.老师多多批评指点,呵呵~ 1.1 数据库介绍 1.1.1 什么是数据库?简单的说,数据库就是一个存放数据的仓库,这个仓库是按照一定的数据结构(数据结构是指数据的组织形式或数据之间的联系)来组织.存储的,我们可以通过数据库提供的多种方法来管理数据库里的数据. 1.2 数据库的

MySQL 马哥视频教程学习笔记

1.        关系型数据库 关系:由行和列组成的二维表 表:至少要有列,可以没有行. 列:是实体的属性. 数据模型:层次模型.网状模型.关系模型.非关系模型. DBMS:DataBase Mangenent System   数据库管理系统. 2.        数据库必须要有缓存  存放索引. 存储引擎:并发性好很好, 读,写: 读锁:共享锁 写锁:独占锁 减少锁粒度: 表锁:对整个表进行锁 页锁:对页和块进行锁 行锁:对行进行锁 数据库锁:对表进行加锁. 锁管理器: 数据库:mysql

总结今天学习的mysql语句

关键字 进入mysql:mysql -uroot -p 查看数据库:show databases 进入数据库:use DATABASE'S_NAME 查看数据库中表:show tables 以上在doc下演示,以后的在工具中演示 mysql中大小写不敏感 创建库:create database if not exists DATABASE'S_NAME 创建表:create table  if not exists  TABLE'S_NAME(列名1 属性,列名2 属性,......) 1 cr

MySQl Study学习之--MySQl二进制日志管理

MySQl Study学习之--MySQl二进制日志管理 MySQL二进制日志(Binary Log):   a.它包含的内容及作用如下:    包含了所有更新了数据或者已经潜在更新了数据(比如没有匹配任何行的一个DELETE)    包含关于每个更新数据库(DML)的语句的执行时间信息    不包含没有修改任何数据的语句,如果需要启用该选项,需要开启通用日志功能    主要目的是尽可能的将数据库恢复到数据库故障点,因为二进制日志包含备份后进行的所有更新    用于在主复制服务器上记录所有将发送

MYSQL存储过程和函数学习笔记

学至Tarena金牌讲师何山,金色晨曦科技公司技术总监沙利穆课程笔记的综合. 1. 什么是存储过程和函数 将SQL语句放入一个集合里,然后直接调用存储过程和函数来执行已经定义好的SQL语句,通过存储过程和函数,可以避免开发人员重复编写相同的SQL语句. MYSQL存储过程和函数是保存在服务器中,在服务器中存储和执行,可以减少客户端和服务器端之间数据传输的消耗. 存储过程就是一组已经保存在数据库中的语句,并且可以随时地调用. 存储过程允许标准组件式编程,存储过程在被创建以后可以在程序中被多次调用而

Mysql学习之--Mysql二进制日志管理

Mysql学习之--Mysql二进制日志管理 简介:     MySQL的二进制日志可以说或是MySQL最重要的日志了,它记录了所有的DDL和DML(除了数据查询语句)语句,以事件形式记录,还包含语句所执行的消耗的时间,MySQL的二进制日志是失误安全型的.      MySQL的二进制日志的作用是显而易见的,可以方便的备份这些日志以便做数据恢复,也可以作为主从复制的同步文件,然而二进制日志的大小可能会根据不同的需求而存在麻烦,所以让日志回滚是必须的,当然MySQL已经为我们提供了二进制回滚的功

MySql基本语法(学习笔记)

MySQL语法大全_自己整理的学习笔记 select * from emp;  #注释 #--------------------------- #----命令行连接MySql--------- #启动mysql服务器 net start mysql #关闭 net stop mysql #进入 mysql -h 主机地址 -u 用户名 -p 用户密码 #退出 exit #--------------------------- #----MySql用户管理--------- #修改密码:首先在D