MySQL--4--系统架构

目录

1

在前一节中我们学习了mysql的逻辑模块组成,接下来我们来学习mysql存储引擎。


I.mysql存储引擎介绍

回目录

MySQL在5.1(不包括)之前的版本中,存储引擎是需要在MySQL安装的时候就必须和MySQL 一起被编译并同时被安装的。

但是从MySQL5.1 开始,MySQL AB对其结构体系做了较大的改造,并引入了一个新的概念:插件式存储引擎体系结构。MySQL AB 在架构改造的时候,让存储引擎层和sql layer各自更为独立,耦合更小,甚至可以做到在线加载新的存储引擎,也就是完全可以将一个新的存储引擎加载到一个正在运行的MySQL 中,而不影响MySQL 的正常运行。插件式存储引擎的架构,为存储引擎的加载和移出更为灵活方便,也使自行开发存储引擎更为方便简单。

MySQL的插件式存储引擎主要包括MyISAM,Innodb,NDB Cluster,Maria,Falcon,Memory,Archive等,其中最著名而且使用最为广泛的MyISAMInnodb两种存储引擎。MyISAM是MySQL 最早的ISAM存储引擎的升级版本,也是MySQL 默认的存储引擎。而Innodb实际上并不是MySQ公司的,而是第三方软件公司Innobase(在2005 年被Oracle公司所收购)所开发,其最大的特点是提供了事务控制等特性,所以使用者也非常广泛。

其他的一些存储引擎相对来说使用场景要稍微少一些,都是应用于某些特定的场景,如NDB Cluster虽然也支持事务,但是主要是用于分布式高可用集群环境。Maria是MySQL最新开发的对MyISAM的升级版存储引擎,Falcon 是MySQL 公司自行研发的为了替代当前的Innodb存储引擎的一款带有事务等高级特性的数据库存储引擎。Memory存储引擎所有数据和索引均存储于内存中,仅保存.frm文件在硬盘,所以主要是用于一些临时表,或者对性能要求极高,但是允许在Crash 的时候丢失数据的特定场景下,会消耗内存较大。Archive 是一个数据经过高比例压缩存放的存储引擎,仅支持insert,select,不支持update和delete,主要用于存放过期而且很少访问的历史信息,不支持索引。


II.MyISAM 存储引擎简介

回目录

1.mysql5.1之前默认存储引擎

2.MyISAM

回目录

存储引擎的表在数据库中,每一个表都被存放为三个以表名命名的物理文件。首先肯定会有任何存储引擎都不可缺少的存放表结构定义信息的.frm 文件,另外还有.MYD和.MYI 文件,分别存放了表的数据(.MYD)和索引数据(.MYI)。每个表都有且仅有这样三个文件做为MyISAM 存储类型的表的存储,也就是说不管这个表有多少个索引,都是存放在同一个.MYI 文件中。

3.MyISAM 支持以下三种类型的索引

回目录

B-Tree 索引

  • B-Tree 索引,就是所有的索引节点都按照balance tree 的数据结构来存储,所有的索引数据节点都在叶节点。

R-Tree 索引

R-Tree 索引的存储方式和b-tree 索引有一些区别,主要设计用于为存储空间和多维数据的字段做索引,所以目前的MySQL 版本来说,也仅支持geometry 类型的字段作索引。

Full-text 索引

Full-text 索引就是全文索引,他的存储结构也是b-tree。主要是为了解决在我们需要用like 查询的低效问题。

MyISAM 上面三种索引类型中,最经常使用的就是B-Tree 索引了,偶尔会使用到Fulltext,但是R-Tree 索引一般系统中都是很少用到的。另外MyISAM 的B-Tree 索引有一个较大的限制,那就是参与一个索引的所有字段的长度之和不能超过1000 字节。

4.不支持事务

5.只有表锁

6.如下情况会造成表损坏

回目录

Mysqld正在写入该表时,被kill掉

主机宕机(Crash)

磁盘硬件故障

MyISAM存储引擎的bug

7.表存放格式

回目录

虽然每一个MyISAM的表都是存放在一个相同后缀名的.MYD文件中,但是每个文件的存放格式实际上可能并不是完全一样的,因为MyISAM的数据存放格式是分为

  • 静态(FIXED)固定长度
  • 动态(DYNAMIC)可变长度
  • 以及压缩(COMPRESSED)这三种格式。

当然三种格式中是否压缩是完全可以任由自己选择的,可以在创建表的时候通过ROW_FORMAT 来指定{COMPRESSED | DEFAULT},也可以通过myisampack工具来进行压缩,默认是不压缩的。而在非压缩的情况下,是静态还是动态,就和我们表中个字段的定义相关了。

只要表中有可变长度类型的字段存在,那么该表就肯定是DYNAMIC格式的,如果没有任何可变长度的字段,则为FIXED格式,当然,你也可以通过alter table 命令,强行将一个带有VARCHAR类型字段的DYNAMIC 的表转换为FIXED,但是所带来的结果是原VARCHAR 字段类型会被自动转换成CHAR类型。相反如果将FIXED转换为DYNAMIC,也会将CHAR 类型字段转换为VARCHAR 类型,

8.如何根据表的记录数量估算占用的磁盘空间

回目录

首先先算一个表中一行有多少个字节。

然后根据数据库中的表每天增加多少行记录,就能够算出每天要增加多少硬盘空间,这样就可根据数据量估算规划多大的空间。

例如在数据库test中创建一张tb1表

2

执行mysql>desc test1.tb1查看tb1的表结构

3

10个字节+20个字节+2个字节+20字节+8字节+8字节+100个字节=168字节

Tb1表的一个行有118个字节

如果每天增加10000条记录,大约需要10000x168/1024/1024=1.6MB

这样就可以根据每天增加的记录数,合理规划好磁盘空间了

MyISAM存储引擎的某个表文件出错之后,仅影响到该表,而不会影响到其他表,更不会影响到其他的数据库。如果我们的数据库正在运行过程中发现某个MyISAM 表出现问题了,则可以在线通过mysql> check table命令来尝试校验他,并可以通过mysql> repair table 命令来尝试修复。在数据库关闭状态下,我们也可以通过myisamchk 工具来对数据库中某个(或某些)表进行检测或者修复。不过强烈建议不到万不得已不要轻易对表进行修复操作,修复之前尽量做好可能的备份工作,以免带来不必要的后果。


III.Innodb 存储引擎简介

回目录

Innodb 之所以能如此受宠,主要是在于其功能方面的较多特点:

1.支持事务

回目录

Innodb在功能方面最重要的一点就是对事务的支持,这无疑是让Innodb 成为MySQL最为流行的存储引擎之一的一个非常重要原因。

2.锁定机制的改进

回目录

Innodb 改变了MyISAM 的锁机制,实现了行锁。

3.实现外键

回目录

Innodb实现了外键引用这一数据库的重要特性。

4.表存放方式

回目录

Innodb 存储引擎也和MyISAM 不太一样,虽然也有.frm文件来存放表结构定义相关的元数据,但是表数据和索引数据是存放在一起的。至于是每个表单独存放还是所有表存放在一起,完全由用户来决定。

5.Innodb 的物理结构分为两大部分

回目录

i.数据文件(表数据和索引数据)

回目录

存放数据表中的数据和所有的索引数据,包括主键和其他普通索引。在Innodb 中,存在了表空间(tablespace)这样一个概念,但是他和Oracle 的表空间又有较大的不同。

首先,Innodb 的表空间分为两种形式。

一种是共享表空间也就是所有表和索引数据被存放在同一个表空间(一个或多个数据文件)中,通过innodb_data_file_path来指定,增加数据文件需要停机重启。


另外一种是独享表空间,也就是每个表的数据和索引被存放在一个单独的.ibd文件中。

虽然我们可以自行设定使用共享表空间还是独享表空间来存放我们的表,但是共享表空间都是必须存在的,因为Innodbundo信息和其他一些元数据信息都是存放在共享表空间里面的。共享表空间的数据文件是可以设置为固定大小可自动扩展大小两种形式的。

当我们的文件表空间快要用完的时候,我们必须要为其增加数据文件,当然,只有共享表空间有此操作。

共享表空间增加数据文件的操作比较简单,只需要在innodb_data_file_path参数后面按照标准格式设置好文件路径和相关属性即可,不过这里有一点需要注意的,就是Innodb在创建新数据文件的时候是不会创建目录的,如果指定目录不存在,则会报错并无法启动。

ii.日志文件

回目录

Innodb 的日志文件和Oracle 的redo日志比较类似,同样可以设置多个日志组(最少2个),同样采用轮循策略来顺序的写入。

由于Innodb是事务的存储引擎,所以系统Crash(宕机)对他来说并不能造成非常严重的损失,由于有redo日志(即事物日志)的存在,有checkpoint机制的保护,Innodb完全可以通过redo 日志将数据库Crash时刻已经完成但还没有来得及将数据写入磁盘的事务恢复,也能够将所有部分完成并已经写入磁盘的未完成事务回滚并将数据还原。

Innodb 不仅在功能特性方面和MyISAM存储引擎有较大区别,在配置上面也是单独处理的。在MySQL启动参数文件(/etc/my.cnf)设置中,Innodb的所有参数基本上都带有前缀innodb_,不论是innodb数据和日志相关,还是其他一些性能,事务等等相关的参数都是一样。和所有Innodb相关的系统变量一样,所有的Innodb相关的系统状态值也同样全部以Innodb_前缀。


IV.MyISAMInnoDB的区别

回目录

1. MyISAM不支持事务,而InnoDB支持

回目录

InnoDBAUTOCOMMIT默认是打开的,即每条SQL语句会默认被封装成一个事务,自动提交,这样会影响速度,所以最好是把多条SQL语句显示放在begincommit之间,组成一个事务去提交。

4

mysql> use test_db;
mysql> show tables;
mysql> desc tb1;
mysql> begin;
mysql> insert into tb1 values('lisi',1);
mysql> insert into tb1 values('zhangsan',2);
mysql> commit;

2.InnoDB支持数据行锁定,MyISAM不支持行锁定,只支持锁定整个表

回目录

MyISAM同一个表上的读锁和写锁是互斥的,MyISAM并发读写时如果等待队列中既有读请求又有写请求,默认写请求的优先级高,即使读请求先到,所以MyISAM不适合于有大量查询和修改并存的情况,那样查询进程会长时间阻塞。因为MyISAM是锁表。

3.InnoDB支持外键,MyISAM不支持

回目录

4.InnoDB不支持全文索引,而MyISAM支持

回目录


V.Mysqlslap性能测试MySQL二种存储引擎

回目录

mysqlslapmysql自带的基准测试工具,优点:查询数据,语法简单,灵活容易使用.该工具可以模拟多个客户端同时并发的向服务器发出查询更新,给出了性能测试数据而且提供了多种引擎的性能比较.msqlslapmysql性能优化前后提供了直观的验证依据,建议系统运维和DBA人员应该掌握一些常见的压力测试工具,才能准确的掌握线上数据库支撑的用户流量上限及其抗压性等问题。

现在看一下这个压力测试工具mysqlslap,关于他的选项手册上以及--help介绍的很详细。
这里解释一下一些常用的选项。

1.mysqlslap常用选项

回目录

选项 作用
--concurrency 代表并发数量,多个可以用逗号隔开。例如:concurrency=50,100,200
--engines 代表要测试的引擎,可以有多个,用分隔符隔开。
--iterations 代表要运行这些测试多少次,即运行多少次后,得到结果。
--auto-generate-sql 代表用系统自己生成的SQL脚本来测试。
--auto-generate-sql-load-type 代表要测试的是读还是写还是两者混合的(read,write,update,mixed)
--number-of-queries 代表总共要运行多少次查询。每个客户运行的查询数量可以用查询总数/并发数来计算。比如倒数第二个结果2=200/100
--debug-info 代表要额外输出CPU以及内存的相关信息(注:只有在MySQL--with-debug编译时可)。
--number-int-cols 代表测试表中的INTEGER类型的属性有几个。
--number-char-cols 代表测试表的char类型字段的数量。
--create-schema 代表自己定义的模式(在MySQL中也就是库即创建测试的数据库)。
--query 代表自己的SQL脚本。
--only-print 如果只想打印看看SQL语句是什么,可以用这个选项。
--csv=name 生产CSV格式数据文件

2.Mysql最大连接数

回目录

i.查看Mysql数据库默认最大连接数

回目录

5

可以看到mysql5.7.13默认是151,注:不同版本默认最大连接数不差别。

ii.修改最大连接数

回目录

一般生产环境是不够的,在my.cnf [mysqld]下添加 max_connections=1024 增加到1024,重启Mysql

修改my.cnf文件并重起mysqld服务

6

iii.查看修改后的最大连接数

回目录

7

查看Mysql默认使用存储引擎

mysql> show engines;

8

3.测试

回目录

现在我们来看一下具体测试的例子

i.用自带的SQL脚本来测试

回目录

[root@localhost ~]# mysqlslap --defaults-file=/etc/my.cnf \
--concurrency=100,200 --iterations=1 --number-int-cols=20 \
--number-char-cols=30 --auto-generate-sql \
--auto-generate-sql-add-autoincrement \
--auto-generate-sql-load-type=mixed --engine=myisam,innodb \
--number-of-queries=2000 -uroot -p123456 --verbose

显示结果:

9

测试说明:模拟测试两次读写并发,第一次100,第二次200,自动生成SQL脚本,测试表包含20init字段,30char字段,每次执行2000查询请求。测试引擎分别是myisaminnodb

测试结果说明:

  • Myisam第一次100客户端同时发起增查用0.413/s,第二次200客户端同时发起增查用0.509/s

  • Innodb第一次100客户端同时发起增查用0.692/s,第二次200客户端同时发起增查用0.617/s

由此可见MyISAM存储引擎处理性能是最好的,也是最常用的,但不支持事务。InonDB存储引擎提供了事务型数据引擎(ACID),在事务型引擎里使用最多的。具有事务回滚,系统修复等特点。

ii.Mysqlslap测试工具生产CSV格式数据文件并转换成图表形式

回目录

[root@localhost ~]# mysqlslap --defaults-file=/etc/my.cnf \ 
--concurrency=100,200 --iterations=1 --number-int-cols=20 \ 
--number-char-cols=30 --auto-generate-sql \ 
--auto-generate-sql-add-autoincrement \ 
--auto-generate-sql-load-type=mixed --engine=myisam,innodb \ 
--number-of-queries=2000 -uroot -p123456 --csv=/root/a.csv

执行结果:

10

a.csv拷贝到windows主机上,打开并生成图表

11

iii.用自定义的SQL 脚本或语句来测试

回目录

首先准备好要测试的数据库表,这里我们编写一个生成表的脚本去完成

脚本内容

[root@localhost ~]# cat /root/mysql3.sh 
#!/bin/bash
HOSTNAME="localhost"
PORT="3306"
USERNAME="root"
PASSWORD="123.abc"

DBNAME="test1"
TABLENAME="tb1"

#create database
mysql -h ${HOSTNAME} -P ${PORT} -u ${USERNAME} -p${PASSWORD} -e "drop database if exists ${DBNAME}"
create_db_sql="create database if not exists ${DBNAME}"
mysql -h ${HOSTNAME} -P ${PORT} -u ${USERNAME} -p${PASSWORD} -e "${create_db_sql}"

#create table
create_table_sql="create table if not exists ${TABLENAME}(stuid int not null primary key,stuname varchar(20) not null,stusex char(1) not null,cardid varchar(20) not null,birthday datetime,entertime datetime,address varchar(100) default null)"
mysql -h ${HOSTNAME} -P ${PORT} -u ${USERNAME} -p${PASSWORD} ${DBNAME} -e "${create_table_sql}"

#insert data to table
i=1
while [ $i -le 20000 ]
do 
insert_sql="insert into ${TABLENAME} values ($i,'zhangsan','1','1234567890123456','1999-10-10','2016-9-3','zhongguo beijingshi changpinqu')"
mysql -h ${HOSTNAME} -P ${PORT} -u ${USERNAME} -p${PASSWORD} ${DBNAME} -e "${insert_sql}"
let i++
done
#select data
select_sql="select count(*) from ${TABLENAME}"
mysql -h ${HOSTNAME} -P ${PORT} -u ${USERNAME} -p${PASSWORD} ${DBNAME} -e "${select_sql}"

授权脚本x执行权限

[root@localhost ~]# chmod +x /root/mysql3.sh

执行脚本mysql3.sh生成mysqlslap工具需要的测试表

[root@localhost ~]# /root/mysql3.sh

执行mysqlslap工具进行测试

[root@localhost ~]# mysqlslap --defaults-file=/etc/my.cnf
--concurrency=10,20 --iterations=1 --create-schema='test1'
--query='select * from test1.tb1' --engine=myisam,innodb
--number-of-queries=2000 -uroot -p123456 –verbose

显示结果

mysqlslap: [Warning] Using a password on the command line interface can be insecure.
Benchmark
    Running for engine myisam
    Average number of seconds to run all queries: 14.128 seconds
    Minimum number of seconds to run all queries: 14.128 seconds
    Maximum number of seconds to run all queries: 14.128 seconds
    Number of clients running queries: 10
    Average number of queries per client: 200

Benchmark
    Running for engine myisam
    Average number of seconds to run all queries: 13.646 seconds
    Minimum number of seconds to run all queries: 13.646 seconds
    Maximum number of seconds to run all queries: 13.646 seconds
    Number of clients running queries: 20
    Average number of queries per client: 100

Benchmark
    Running for engine innodb
    Average number of seconds to run all queries: 13.837 seconds
    Minimum number of seconds to run all queries: 13.837 seconds
    Maximum number of seconds to run all queries: 13.837 seconds
    Number of clients running queries: 10
    Average number of queries per client: 200

Benchmark
    Running for engine innodb
    Average number of seconds to run all queries: 13.768 seconds
    Minimum number of seconds to run all queries: 13.768 seconds
    Maximum number of seconds to run all queries: 13.768 seconds
    Number of clients running queries: 20
    Average number of queries per client: 100

注:通过mysqlslap工具对mysql server进行压力测试,可以通过--concurrency--number-of-queries等选项的值查看每次测试的结果,通过反复测试、优化得出mysql server的最大并发数。

如果mysqlslap工具输出结果为Segmentation fault(core dumped)基本表示走超出mysql server的负载。

[root@master ~]# mysqlslap --defaults-file=/etc/my.cnf --concurrency=10,20 --iterations=1 --create-schema='test1' --query='select * from test1.tb1' --engine=myisam,innodb --number-of-queries=2000 -uroot -p123.abc --verbose 
mysqlslap: [Warning] Using a password on the command line interface can be insecure.
Benchmark
    Running for engine myisam
    Average number of seconds to run all queries: 12.608 seconds
    Minimum number of seconds to run all queries: 12.608 seconds
    Maximum number of seconds to run all queries: 12.608 seconds
    Number of clients running queries: 10
    Average number of queries per client: 200

Benchmark
    Running for engine myisam
    Average number of seconds to run all queries: 12.699 seconds
    Minimum number of seconds to run all queries: 12.699 seconds
    Maximum number of seconds to run all queries: 12.699 seconds
    Number of clients running queries: 20
    Average number of queries per client: 100

Benchmark
    Running for engine innodb
    Average number of seconds to run all queries: 11.296 seconds
    Minimum number of seconds to run all queries: 11.296 seconds
    Maximum number of seconds to run all queries: 11.296 seconds
    Number of clients running queries: 10
    Average number of queries per client: 200

Benchmark
    Running for engine innodb
    Average number of seconds to run all queries: 9.778 seconds
    Minimum number of seconds to run all queries: 9.778 seconds
    Maximum number of seconds to run all queries: 9.778 seconds
    Number of clients running queries: 20
    Average number of queries per client: 100

回目录


results matching ""

    No results matching ""