您的位置:首页 > 数据库 > SQL

MySQL架构组成--存储引擎

2017-01-17 21:57 1191 查看

防伪码:尊重现在,往事不记,后事不提。 在前一节中我们学习了 mysql 的物理文件组成,接下来我们来学习 mysql 的逻辑模块组成。逻辑模块组成:MySQL 逻辑结构可以看成是二层架构,第一层我们通常叫做 SQL Layer,在 MySQL 数据库系统处理底层数据之前的所有工作都是在这一层完成的,包括权限判断,sql 解析,执行计划优化,query cache 的处理等等;第二层就是存储引擎层,我们通常叫做 StorageEngine Layer,也就是底层数据存取操作实现部分,由多种存储引擎共同组成。所以,可以用如下一张最简单的架构示意图来表示 MySQL 的基本架构,如图所示: 从上图看起来 MySQL 逻辑架构非常的简单,但实际上每一层中都含有各自的很多小模块,尤其是第一层 SQL Layer,结构相当复杂的。接下来我们来学习 mysql 存储引擎。一、mysql 存储引擎介绍:MySQL在5.1 (不包括)之前的版本中,存储引擎是需要在MySQL 安装的时候就必须和MySQL一起被编译并同时被安装的。但是从 MySQL5.1 开始,MySQL AB 对其结构体系做了较大的改造,并引入了一个新的概念:插件式存储引擎体系结构。MySQL AB 在架构改造的时候,让存储引擎层和 sqllayer 各自更为独立,耦合更小,甚至可以做到在线加载新的存储引擎,也就是完全可以将一个新的存储引擎加载到一个正在运行的 MySQL 中,而不影响 MySQL 的正常运行。插件式存储引擎的架构,为存储引擎的加载和移出更为灵活方便,也使自行开发存储引擎更为方便简单。


MySQL 的插件式存储引擎主要包括 MyISAM,Innodb,NDB Cluster,Maria,Falcon,Memory,Archive 等,其中最著名而且使用最为广泛的 MyISAM 和 Innodb 两种存储引擎。MyISAM 是MySQL 最早的 ISAM 存储引擎的升级版本,也是 MySQL 默认的存储引擎。而 Innodb 实际上并不是 MySQ 公司的,而是第三方软件公司 Innobase(在 2005 年被 Oracle 公司所收购)所开发,其最大的特点是提供了事务控制等特性,所以使用者也非常广泛。其他的一些存储引擎相对来说使用场景要稍微少一些,都是应用于某些特定的场景,如 NDBCluster 虽然也支持事务,但是主要是用于分布式高可用集群环境。Maria 是 MySQL 最新开发的对 MyISAM 的升级版存储引擎,Falcon 是 MySQL 公司自行研发的为了替代当前的Innodb 存储引擎的一款带有事务等高级特性的数据库存储引擎。Memory 存储引擎所有数据和索引均存储于内存中,仅保存.frm 文件在硬盘,所以主要是用于一些临时表,或者对性能要求极高,但是允许在 Crash 的时候丢失数据的特定场景下,会消耗内存较大。Archive 是一个数据经过高比例压缩存放的存储引擎,仅支持 insert,select,不支持 update 和 delete,主要用于存放过期而且很少访问的历史信息,不支持索引。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 字节。3、不支持事务4、只有表锁5、如下情况会造成表损坏:Mysqld 正在写入该表时,被 kill 掉主机宕机(Crash)磁盘硬件故障MyISAM 存储引擎的 bug6、虽然每一个 MyISAM 的表都是存放在一个相同后缀名的.MYD 文件中,但是每个文件的存放格式实际上可能并不是完全一样的,因为 MyISAM 的数据存放格式是分为静态(FIXED)固定长度、动态(DYNAMIC)可变长度以及压缩(COMPRESSED)这三种格式。当然三种格式中是否压缩是完全可以任由自己选择的,可以在创建表的时候通过 ROW_FORMAT 来指定{COMPRESSED | DEFAULT},也可以通过 myisampack 工具来进行压缩,默认是不压缩的。而在非压缩的情况下,是静态还是动态,就和我们表中个字段的定义相关了。只要表中有可变长度类型的字段存在,那么该表就肯定是 DYNAMIC 格式的,如果没有任何可变长度的字段,则为 FIXED 格式,当然,你也可以通过 alter table 命令,强行将一个带有 VARCHAR 类型字段的 DYNAMIC 的表转换为 FIXED,但是所带来的结果是原 VARCHAR 字段类型会被自动转换成 CHAR 类型。相反如果将 FIXED 转换为 DYNAMIC,也会将 CHAR 类型字段转换为 VARCHAR类型,知识点扩展:如何根据表的记录数量估算占用的磁盘空间首先先算一个表中一行有多少个字节。然后根据数据库中的表每天增加多少行记录,就能够算出每天要增加多少硬盘空间,这样就可根据数据量估算规划多大的空间。例如在数据库 test 中创建一张 tb1 表 执行 mysql>desc test1.tb1 查看 tb1 的表结构 10 个字节+20 个字节+2 个字节+20 字节+8 字节+8 字节+100 个字节=168 字节Tb1 表的一个行有 118 个字节如果每天增加 10000 条记录,大约需要 10000x168/1024/1024=1.6MB这样就可以根据每天增加的记录数,合理规划好磁盘空间了MyISAM 存储引擎的某个表文件出错之后,仅影响到该表,而不会影响到其他表,更不会影响到其他的数据库。如果我们的数据库正在运行过程中发现某个 MyISAM 表出现问题了,则可以在线通过 check table 命令来尝试校验他,并可以通过 repair table 命令来尝试修复。在数据库关闭状态下,我们也可以通过 myisamchk 工具来对数据库中某个(或某些)表进行检测或者修复。不过强烈建议不到万不得已不要轻易对表进行修复操作,修复之前尽量做好可能的备份工作,以免带来不必要的后果。Innodb  存储引擎简介 :Innodb 之所以能如此受宠,主要是在于其功能方面的较多特点:1、支持事务Innodb 在功能方面最重要的一点就是对事务的支持,这无疑是让 Innodb 成为 MySQL 最为流行的存储引擎之一的一个非常重要原因。2、锁定机制的改进Innodb 改变了 MyISAM 的锁机制,实现了行锁。3、实现外键Innodb 实现了外键引用这一数据库的重要特性。4、Innodb 存储引擎也和 MyISAM 不太一样,虽然也有.frm 文件来存放表结构定义相关的元数据,但是表数据和索引数据是存放在一起的。至于是每个表单独存放还是所有表存放在一起,完全由用户来决定。Innodb 的物理结构分为两大部分:1、数据文件(表数据和索引数据)存放数据表中的数据和所有的索引数据,包括主键和其他普通索引。在 Innodb 中,存在了表空间(tablespace)这样一个概念,但是他和 Oracle 的表空间又有较大的不同。首先,Innodb的表空间分为两种形式。一种是共享表空间,也就是所有表和索引数据被存放在同一个表空间(一个或多个数据文件)中,通过 innodb_data_file_path 来指定,增加数据文件需要停机重启。另外一种是独享表空间,也就是每个表的数据和索引被存放在一个单独的.ibd 文件中。虽然我们可以自行设定使用共享表空间还是独享表空间来存放我们的表,但是共享表空间都是必须存在的,因为 Innodb 的 undo 信息和其他一些元数据信息都是存放在共享表空间里面的。共享表空间的数据文件是可以设置为固定大小和可自动扩展大小两种形式的。当我们的文件表空间快要用完的时候,我们必须要为其增加数据文件,当然,只有共享表空间有此操作。共享表空间增加数据文件的操作比较简单,只需要在 innodb_data_file_path 参数后面按照标准格式设置好文件路径和相关属性即可,不过这里有一点需要注意的,就是Innodb 在创建新数据文件的时候是不会创建目录的,如果指定目录不存在,则会报错并无法启动。2、日志文件Innodb 的日志文件和 Oracle 的 redo 日志比较类似,同样可以设置多个日志组(最少 2个),同样采用轮循策略来顺序的写入。由于 Innodb 是事务的存储引擎,所以系统 Crash(宕机)对他来说并不能造成非常严重的损失,由于有 redo 日志(即事物日志)的存在,有 checkpoint 机制的保护,Innodb 完全可以通过 redo 日志将数据库 Crash 时刻已经完成但还没有来得及将数据写入磁盘的事务恢复,也能够将所有部分完成并已经写入磁盘的未完成事务回滚并将数据还原。Innodb 不仅在功能特性方面和 MyISAM 存储引擎有较大区别,在配置上面也是单独处理的。在 MySQL 启动参数文件(/etc/my.cnf)设置中,Innodb 的所有参数基本上都带有前缀“innodb_”,不论是 innodb 数据和日志相关,还是其他一些性能,事务等等相关的参数都是一样。和所有 Innodb 相关的系统变量一样,所有的 Innodb 相关的系统状态值也同样全部以“Innodb_”前缀。MyISAM 和 InnoDB 的区别1、 MyISAM 不支持事务,而 InnoDB 支持。InnoDB 的 AUTOCOMMIT 默认是打开的,即每条SQL 语句会默认被封装成一个事务,自动提交,这样会影响速度,所以最好是把多条 SQL语句显示放在 begin 和 commit 之间,组成一个事务去提交。 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 支持。二、MySQL 自带工具使用介绍MySQL 数据库不仅提供了数据库的服务器端应用程序,同时还提供了大量的客户端工具程序,如 mysql,mysqladmin,mysqldump 等等1、mysql 命令Mysql 命令是用的最多的一个命令工具了,为用户提供一个命令行接口来操作管理 MySQL服务器。语法格式:Usage: mysql [OPTIONS] [database]例如:# mysql-e "select user,host from user"mysql大家只要运行一下“mysql --help”就会得到如下相应的基本使用帮助信息: 这里主要介绍一些在运维过程中会用到的相关选项:首先看看“-e, --execute=name”参数,这个参数是告诉 mysql,我要执行“-e”后面的某个命令,而不是要通过 mysql 连接登录到 MySQL Server 上面。此参数在我们写一些基本的MySQL 检查和监控的脚本中非常有用,运维 mysql 时经常在脚本中使用到它。#mysql -hhostname -Pport -uusername -ppassword -e 相关 mysql 的 sql 语句例 1:通过 binlog_cache_use 以及 binlog_cache_disk_use 来分析设置的 binlog_cache_size是否足够 例 2:通过脚本创建数据库、表及对表进行增、改、删、查操作。脚本内容如下: 创建授予 test 用户可以在指定的源登录 测试 test 用户连接 mysql 服务器 授予脚本执行权限#chmod +x /root/mysql1.sh执行脚本: 如果在连接时候使用了“-E, --vertical”参数,登入之后的所有查询结果都将以纵列显示,效果和我们在一条 query 之后以“\G”结尾一样。#mysql -E -u root -p “--prompt=name”参数对于做运维的人来说是一个非常重要的参数选项,其主要功能是定制自己的 mysql 提示符的显示内容。在默认情况下,我们通过 mysql 登入到数据库之后,mysql的提示符只是一个很简单的内容”mysql>“,没有其他任何附加信息。非常幸运的是 mysql通过“--prompt=name”参数给我们提供了自定义提示信息的办法,可以通过配置显示登入的主机地址,登录用户名,当前时间,当前数据库 schema,MySQL Server 的一些信息等等。我个人强烈建议将登录主机名,登录用户名和所在的 schema 这三项加入提示内容,因为当大家手边管理的 MySQL 越来越多,操作越来越频繁的时候,非常容易因为操作的时候没有太在意自己当前所处的环境而造成在错误的环境执行了错误的命令并造成严重后果的情况。如果我们在提示内容中加入了这几项之后,至少可以更方便的提醒自己当前所处环境,以尽量减少犯错误的概率。个人强烈建议提示符定义: "\\u@\\h : \\d \\r:\\m:\\s> ",显示效果: 切换数据库: 提示符解释:\u 表示用户名, \h 表示主机名, \d 表示当前数据库,\r 小时(12 小时制),\m 分种,\s秒,\R The current time, in 24-hour military time (0–23)“--tee=name”参数也是对运维人员非常有用的参数选项,用来告诉 mysql,将所有输入和输出内容都记录进文件。在我们一些较大维护变更的时候,为了方便被查,最好是将整个操作过程的所有输入和输出内容都保存下来。假如 mysql 命令行状态下,要进行大量的交互操作,其实可以把这些操作记录在 log 中进行审计,很简单 mysql -u root -p --tee=/path/xxxx.log 也可以 在服务器上的/etc/my.cnf 中的[client]加入 tee =/tmp/client_mysql.log 即可.注:若没有[client]就添加即可或者在 mysql>提示符下执行下面的命令 mysql 其他参数选项可以通过 MySQL 官方参考手册查阅,也可以通过执行“mysql --help”或 man mysql 得到帮助信息之后通过自行实验来做进一步的深刻认识。2、mysqladminUsage: mysqladmin [OPTIONS] command command ...mysqadmin,顾名思义,提供的功能都是与 MySQL 管理相关的各种功能。如 MySQL Server状态检查,各种统计信息的 flush,创建/删除数据库,关闭 MySQL Server 等等。mysqladmin所能做的事情,虽然大部分都可以通过 mysql 连接登录上 MySQL Server 之后来完成,但是大部分通过 mysqladmin 来完成操作会更简单更方便。这里将介绍一下经常使用到的几个常用功能:ping 命令可以很容易检测 MySQL Server 是否还能正常提供服务mysql 本机上测试: 在其他主机上测试 mysql server 是否正常提供服务 注 1:地址 192.168.1.1 是 mysql server 的 ip注 2:mysql server 的防火墙要允许 3306/tcp 通信注 3:在 mysql server 上创建授权用户 status 命令可以获取当前 MySQL Server 的几个基本的状态值: mysqladmin status 命令结果有下述列Uptime:是 mysql 服务器运行的秒数。Threads:活跃线程的数量即开启的会话数。Questions: 服务器启动以来客户的问题(查询)数目 (只要跟 mysql 作交互,不管查询表,还是查询服务器状态都记一次)。Slow queries:是慢查询的数量。Opens:mysql 已经打开的数据库表的数量Flush tables: mysql 已经执行的 flush tables,refresh 和 reload 命令的数量。注:flush tables //刷新表(清除缓存)reload 重载授权表refresh 洗掉所有表并关闭和打开日志文件open:打开数据库的表的数量,以服务器启动开始。Queries per second avg:select 语句平均查询时间Memory in use 分配的内存(只有在 MySQL 用--with-debug 编译时可用)Max memory used 分配的最大内存(只有在 MySQL 用--with-debug 编译时可用)processlist 获取当前数据库的连接线程信息:监控 mysql 进程运行状态: 上面的这三个功能在一些简单监控脚本中经常使用到的。mysqladmin 其他参数选项可以通过执行“mysqladmin --help”或 man mysqladmin 得到帮助信息。编写一个简单的 mysql 监控脚本,内容如下: 附加知识点 1:Mysql 的系统数据库:1) INFORMATION_SCHEMA 数据字典:此数据库存贮了其他所有数据库的信息(元数据)。元数据是关于数据的数据,如 database name 或 table name,列的数据类型,或访问权限等。 INFORMATION_SCHEMA 库的主要系统表TABLES  表:提供了关于数据库中的表和视图的信息。(Table_schema 字段代表 数据表所属的数据库名)SELECT * FROM information_schema.TABLES WHERE TABLE_SCHEMA='数据库名';COLUMNS  表:提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息。SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='数据库名‘' AND TABLE_NAME='表名'TABLE_CONSTRAINTS  表:存储主键约束、外键约束、唯一约束、check 约束。各字段的说明信息ELECT * FROM information_schema.TABLE_CONSTRAINTS WHERE TABLE_SCHEMA=' 数 据 库 名' AND TABLE_NAME='表名'STATISTICS  表:提供了关于表索引的信息。SELECT * FROM information_schema.STATISTICS WHERE TABLE_SCHEMA=' 数 据 库 名' AND TABLE_NAME='表名'2)performance_schema 性能字典,此数据库为数据库性能优化提供重要的参考信息3)MYSQL 数据库: 该数据库也是个核心数据库,存储用户的权限信息与帮助信息。4)MySQL5.7 提供了 sys 系统数据库。 sys 数据库里面包含了一系列的存储过程、自定义函数以及视图来帮助我们快速的了解系统的元数据信息。sys 系统数据库结合了information_schema 和 performance_schema 的相关数据,让我们更加容易的检索元数据。附加知识点 2:未经允许不得转载传播--陈英宏博客地址:hongge.blog.51cto.commysql 有关 show 的用法SHOW DATABASES 列出 MySQL Server 上的数据库。SHOW TABLES [FROM db_name]列出数据库中的表。SHOW TABLE STATUS [FROM db_name]列出数据库的表信息,比较详细。SHOW COLUMNS FROM tbl_name [FROM db_name]列出表的列信息,同 SHOW FIELDS FROM tbl_name [FROM db_name],DESCRIBE tbl_name [col_name]。SHOW FULL COLUMNS FROM tbl_name [FROM db_name] 列 出 表 的 列 信 息 , 比 较 详 细 ,同 SHOW FULL FIELDS FROM tbl_name [FROM db_name]。SHOW INDEX FROM tbl_name [FROM db_name]列出表的索引信息。SHOW STATUS 列出 Server 的状态信息。SHOW VARIABLES 列出 MySQL 系参数值SHOW PROCESSLIST 查看当前 mysql 查询进程SHOW GRANTS FOR user 列出用户的授权命令3、mysqldump:这个工具其功能就是将 MySQL Server 中的数据以 SQL 语句的形式从数据库中 dump 成文本文件。mysqldump 是做为 MySQL 的一种逻辑备份工具4、mysqlbinlogmysqlbinlog 程序的主要功能就是分析 MySQL Server 所产生的二进制日志(也就是 binlog)。通过 mysqlbinlog,我们可以解析出 binlog 中指定时间段或者指定日志起始和结束位置的内容解析成 SQL 语句。三 、Mysqlslap  性能测试 MySQL  二 种存储引擎mysqlslap 是 mysql 自带的基准测试工具,优点:查询数据,语法简单,灵活容易使用.该工具可以模拟多个客户端同时并发的向服务器发出查询更新,给出了性能测试数据而且提供了多种引擎的性能比较.msqlslap 为 mysql 性能优化前后提供了直观的验证依据,建议系统运维和 DBA人员应该掌握一些常见的压力测试工具,才能准确的掌握线上数据库支撑的用户流量上限及其抗压性等问题。现在看一下这个压力测试工具 mysqlslap,关于他的选项手册上以及--help 介绍的很详细。这里解释一下一些常用的选项。--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格式数据文件查看 Mysql 数据库默认最大连接数 可以看到 mysql5.7.13 默认是 151,注:不同版本默认最大连接数不差别。一般生产环境是不够的,在 my.cnf [mysqld]下添加 max_connections=1024 增加到 1024,重启 Mysql。修改 my.cnf 文件并重启mysqld 服务 查看修改后的最大连接数 查看 Mysql 默认使用存储引擎,如下查看:mysql> show engines; 现在我们来看一下具体测试的例子用自带的 SQL 脚本来测试:[root@localhost ~]# mysqlslap --defaults-file=/etc/my.cnf --concurrency=50,100 --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 显示结果: 测试说明:模拟测试两次读写并发,第一次50,第二次 100,自动生成 SQL 脚本,测试表包含 20 个 init 字段,30 个 char 字段,每次执行 2000 查询请求。测试引擎分别是 myisam,innodb。测试结果说明:Myisam第一次50客户端同时发起增查用0.223/s,第二次100客户端同时发起增查用0.234/sInnodb第一次50客户端同时发起增查用0.436/s,第二次100客户端同时发起增查用0.448/s由此可见 MyISAM 存储引擎处理性能是最好的,也是最常用的,但不支持事务。InonDB 存储引擎提供了事务型数据引擎(ACID),在事务型引擎里使用最多的。具有事务回滚,系统修复等特点。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 将 a.csv 拷贝到 windows 主机上,打开并生成图表 注:通过 mysqlslap 工具对 mysql server 进行压力测试,可以通过--concurrency、--number-of-queries 等选项的值查看每次测试的结果,通过反复测试、优化得出 mysql server的最大并发数。如果 mysqlslap 工具输出结果为 Segmentation fault (core dumped)基本表示走超出 mysqlserver 的负载。


谢谢观看,真心的希望能帮到您!

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: