1.MySQL架构组成
-
高级DBA的职责:
- 负责MySQL的容量规划,架构设计及安装、部署.
- 负责MySQL的日常管理,监控和维护, 并对MySQL进行持续性能优化.
- 负责MySQL开发支持,参与数据架构规划设计,以及相关业务的数据建模、设计评审、SQL代码审核优化
-
中级 Java开发工程师对数据库知识的掌握程度
- 熟练操作主流数据库,能够通过代码(框架) 完成日常的数据库操作.
- 熟练使用SQL, 熟悉SQL优化, 熟悉存储过程 视图 等创建及使用.
- 了解MySQL的整体体系结构,了解MySQL事务 存储引擎的特点
- 了解MySQL索引优化,了解MySQL相关锁机
- MySQL架构体系介绍:MySQL 由连接池、SQL 接口、解析器、优化器、缓存、存储引擎等组成,可以分为四层,即连接层、 服务层、引擎层和文件系统层。可插拔式
-
- 连接层:最上面是一些客户端和连接服务, 不是MySQL特有的,所有基于网络的C/S的网络应用程序都应该包括连接处理、认证、安全管理等
- 服务层:中间层是MySQL的核心,包括查询解析、分析、优化和缓存等。同时它还提供跨存储引擎的功能,包括存储过程、触发器和视图等。
- 引擎层:存储引擎层,它负责存取数据。服务器通过API可以和各种存储引擎进行交互。不同的存储引擎具有不同的功能,我们可以根据实际需求选择使用对应的存储引擎
- 存储层:数据存储层,主要是将数据存储在运行于裸设备的文件系统之上,并完成与存储引擎的交互
- 连接层:最上面是一些客户端和连接服务, 不是MySQL特有的,所有基于网络的C/S的网络应用程序都应该包括连接处理、认证、安全管理等
- SQL查询流程:用 SQL SELECT 语句的执行轨迹来说明客户端与 MySQL 的交互过程,如下图所示
1. 通过客户端/服务器通信协议与 MySQL 建立连接 2. 查询缓存,这是 MySQL 的一个可优化查询的地方,如果开启了 Query Cache 且在查询缓存过程中查询到完全相同的 SQL 语句,则将查询结果直接返回给客户端;如果没有开启Query Cache 或者没有查询到 完全相同的 SQL 语句则会由解析器进行语法语义解析,并生成解析树。 3. 预处理器生成新的解析树。 4. 查询优化器生成执行计划。 5. 查询执行引擎执行 SQL 语句,此时查询执行引擎会根据 SQL 语句中表的存储引擎类型,以及对应的API 接口与底层存储引擎缓存或者物理文件的交互情况,得到查询结果,由MySQL Server 过滤后将查询结 果缓存并返回给客户端。若开启了 Query Cache,这时也会将SQL 语句和结果完整地保存到 QueryCache 中,以后若有相同的 SQL 语句执行则直接返回结果。
- mysql物理文件
- 日志文件
- error log 错误日志,用于排错, 存放在/var/log/mysqld.log【默认开启】
- bin log 二进制日志 ,用于备份,增量备份 DDL DML DCL
- Relay log 中继日志,用于主从复制,接收 replication master
- slow log 慢查询日志,用于性能调优, 查询时间超过指定值
- 日志文件
-- 查看错误日志文件路径 show variables like ‘log_error‘; +---------------+---------------------+ | Variable_name | Value | +---------------+---------------------+ | log_error | /var/log/mysqld.log | +---------------+---------------------+ -- 慢查询日志文件路径 show variables like ‘slow_query_log_file‘; +---------------------+-----------------------------------+ | Variable_name | Value | +---------------------+-----------------------------------+ | slow_query_log_file | /var/lib/mysql/localhost-slow.log | +---------------------+-----------------------------------+ -- bin log 日志文件 需要在 my.cnf 中配置 log-bin=/var/log/mysql-bin/bin.log server-id=2 -- 查看 relay log 相关参数 show variables like ‘%relay%‘;
-
- 配置文件my.cnf进行数据库客户端服务端等高级配置
[client] #客户端设置,即客户端默认的连接参数 port = 3307 #默认连接端口 socket = /data/mysqldata/3307/mysql.sock #用于本地连接的socket套接字 default-character-set = utf8mb4 #编码 [mysqld] #服务端基本设置 port = 3307 MySQL监听端口 socket = /data/mysqldata/3307/mysql.sock #为MySQL客户端程序和服务器之间的本地通讯指定一 个套接字文件 pid-file = /data/mysqldata/3307/mysql.pid #pid文件所在目录 basedir = /usr/local/mysql-5.7.11 #使用该目录作为根目录(安装目录) datadir = /data/mysqldata/3307/data #数据文件存放的目录 tmpdir = /data/mysqldata/3307/tmp #MySQL存放临时文件的目录 character_set_server = utf8mb4 #服务端默认编码(数据库级别)
- 数据文件
-- 查看数据文件的位置 show variables like ‘%dir%‘; +-----------------------------------------+----------------------------+ | Variable_name | Value | +-----------------------------------------+----------------------------+ | datadir | /var/lib/mysql/ | +-----------------------------------------+----------------------------+ 1、.frm文件 不论是什么存储引擎,每一个表都会有一个以表名命名的.frm文件,与表相关的元数据(meta)信息都存放在此文件中,包括表结构的定义信息等。 2、.MYD文件 myisam存储引擎专用,存放myisam表的数据(data)。每一个myisam表都会有一个.MYD文件与之呼应,同样存放在所属数据库的目录下 3、.MYI文件 也是myisam存储引擎专用,存放myisam表的索引相关信息。每一个myisam表对应一个.MYI文件,其存放的位置和.frm及.MYD一样 4、.ibd文件 存放innoDB的数据文件(包括索引)。 5. db.opt文件 此文件在每一个自建的库里都会有,记录这个库的默认使用的字符集和校验规则
- 配置文件my.cnf进行数据库客户端服务端等高级配置
2.MySQL的备份与恢复
-
数据丢失与备份场景
- 开发测试环境数据库搭建
- 数据库或者数据迁移
- 数据备份方式
- 完全备份:将数据库的全部信息进行备份,包括数据库的数据文件、日志文件,还需要备份文件的存储位置以及数据库中的全部对象和相关信息。
- 差异备份:备份从最近的完全备份后对数据所做的修改,备份完全备份后变化了的数据文件、日志文件以及数据库中其他被修改的内容
- 增量备份:增量备份是指在一次全备份或上一次增量备份后,以后每次的备份只需备份与前一次相比增加或者被修改的文件。
完整备份 | 差异备份 | 增量备份 | ||
备 份 方 法 | 备份所有文件 |
一次全备份后,备份与全 备份差异的部分 |
一次全备份后,备份与上次备 份的差异部分 |
|
备 份 速 度 | 最慢 | 较快 | 最快 | |
恢 复 速 度 | 最快 | 较快 | 最慢 | |
空 间 要 求 | 最多 | 较多 | 最少 | |
优 势 |
最快的恢复速度, 只需要上 一次完全备份就能恢复 |
相比增量,更快也更简单 并且只需要最近一次的 完全备份 和最后一次的差异备份 就能恢复 |
备份速度快,较少的空间需求,没有重复的备份文件 | |
劣 势 | 最多的空间需求 大量重复的备份 |
较慢的备份速度,仍然会 存在许多的备份文件 |
最慢的恢复速度,恢复需要最近一次完全备份和全部增量备份 |
- 备份的组合方式:完全备份+差异备份;完全备份+增量备份
- 冷备份:当数据库进行备份时, 数据库不能进行读写操作, 即数据库要下线
- 是操作比较方便的备份方法(只需拷贝文件),低度维护,高度安全
- 在实施备份的全过程中,数据库必须要作备份而不能作其它工作。
- 若磁盘空间有限,只能拷贝到磁带等其它外部存储设备上,速度比较慢。
-
不能按表或按用户恢复
- 实现:
1. 关闭SELinux,修改 selinux 配置文件,将SELINUX=enforcing改为SELINUX=disabled,保存后退出 vim /etc/selinux/config SELINUX=disabled 2. 重启 reboot # 重启命令 3. 找到MySQL数据文件位置,停止MySQL服务 SHOW VARIABLES LIKE ‘%dir%‘; -- 结果显示, 数据目录就是datadir的所在位置,即 /var/lib/mysql/ service mysqld stop -- 停止mysql 4.进入到 /mysql 目录, 执行打包命令 将数据文件打包备份 cd /var/lib/ # 进入其上级目录 tar jcvf /root/backup.tar.bz2 mysql/ # 打包压缩到 root目录下 5. 删除掉数据目录下的所有数据 -- 删除原目录 rm -rf /var/lib/mysql/ 6. 恢复数据 (使用tar命令) -- 解压 tar jxvf backup.tar.bz2 mysql/ -- 把备份的文件移动到/var/lib/里面去替代原来的mysql mv /root/mysql/ /var/lib/ 7. 启动MySQL, 然后登陆MySQL,查看数据是否丢失, 如果数据正常代表冷备成功 service mysqld start
- 热备份:在数据库运行的情况下,备份数据库操作的sql语句,当数据库发生问题时,可以重新执行一遍备份的sql语句
- 可在表空间或数据文件级备份,备份时间短。备份时数据库仍可使用。可达到秒级恢复(恢复到某一时间点上)
- 不能出错,否则后果严重。因难维护,所以要特别仔细小心,不允许“以失败而告终”
-
- mysqldump工具实现热备份,可以对多个库进行备份,可以对单张表或者某几张表进行备份
## 备份单个数据库 1. 创建文件夹 , 备份数据 mkdir databackup cd databackup mysqldump -uroot -p lagou_edu > lagou_edu.sql 2.模拟数据丢失,删除数据库,然后重新创建一个新的库 DROP DATABASE lagou_edu; CREATE DATABASE lagou_edu CHARACTER SET ‘utf8‘; 3.恢复数据 cd databackup mysql -uroot -p lagou_edu < lagou_edu.sql ## 备份数据库的某些表 1. 备份数据表 [root@localhost databackup]# mysqldump -uroot -p lagou_edu course course_lesson > backupTable.sql 2. 模拟数据丢失,删除数据表 DROP TABLE course; DROP TABLE course_lesson; 3. 恢复数据 mysql -uroot -p lagou_edu < backupTable.sql ##直接将MySQL数据库压缩备份 1. 备份数据 mysqldump -uroot -p lagou_edu | gzip > lagou_edu.sql.gz 2. 模拟删除 DROP DATABASE lagou_edu; CREATE DATABASE lagou_edu CHARACTER SET ‘utf8‘; 3 .恢复数据 gunzip < lagou_edu.sql.gz | mysql -uroot -p lagou_edu
3.MySQL查询和慢查询日志分析
-
sql 性能下降原因
- 等待时间长:锁表导致查询一直处于等待状态
- 执行时间长:查询语句烂、索引失效、关联查询太多join、服务器调优及各个参数设置问题
-
优化原则
- 只返回需要的结果:一定要为查询语句指定 WHERE 条件,过滤掉不需要的数据行;避免使用 select * from , 因为它表示查询表中的所有字段
- 确保查询使用了正确的索引:经常出现在 WHERE 条件中的字段建立索引,可以避免全表扫描;将 ORDER BY 排序的字段加入到索引中,可以避免额外的排序操作;多表连接查询的关联字段建立索引,可以提高连接查询的性能;将 GROUP BY 分组操作字段加入到索引中,可以利用索引完成分组
- 避免让索引失效:在 WHERE 子句中对索引字段进行表达式运算或者使用函数都会导致索引失效;使用 LIKE 匹配时,如果通配符出现在左侧无法使用索引;如果 WHERE 条件中的字段上创建了索引,尽量设置为 NOT NULL
- sql执行顺序
1. FORM子句 : 左右两个表的笛卡尔积 2. ON: 筛选满足条件的数据 3. JOIN: 如果是 inner join 那就正常,如果是 outer join 则会添加回来上面一步过滤掉的一些行 4. WHERE: 对不满足条件的行进行移除, 并且不能恢复 5. GROUP BY: 分组后只能得到每组的第一行数据,或者聚合函数的数值 6. HAVING: 对分组后的数据进行筛选 7. SELECT: 执行select操作,获取需要的列。 8. DISTINCT: 去重 9. ORDER BY: 排序 10. LIMIT:取出指定行的记录, 并将结果返回。
- join 查询的7种方式:内连接、左右连接、全连接
- 慢查询日志分析
- MySQL的慢查询,全名是慢查询日志,是MySQL提供的一种日志记录,用来记录在MySQL中响应时间超过阈值的语句。
- 默认情况下,MySQL数据库并不启动慢查询日志,需要手动来设置这个参数。
- 如果不是调优需要的话,一般不建议启动该参数,因为开启慢查询日志会或多或少带来一定的性能影响。
- 慢查询日志支持将日志记录写入文件和数据库表
- 慢查询参数
SHOW VARIABLES LIKE "%query%"; ## slow_query_log:是否开启慢查询日志, 1 表示开启, 0 表示关闭。 ## slow-query-log-file:新版(5.6及以上版本)MySQL数据库慢查询日志存储路径 ## long_query_time: 慢查询阈值,当查询时间多于设定的阈值时,记录日志 SHOW VARIABLES LIKE "%output%"; ## log_output 日志文件放到文件里还是表里
- 配置慢查询
- 默认慢查询方式是禁用的,可以通过set方式开启;设置后只对当前数据库生效,mysql重启后会失效
SHOW VARIABLES LIKE "%query%"; set global slow_query_log=1;
- 修改my.cnf文件永久生效
-- 编辑配置 vim /etc/my.cnf -- 添加如下内容 slow_query_log =1 slow_query_log_file=/var/lib/mysql/lagou-slow.log -- 重启MySQL service mysqld restart mysql> SHOW VARIABLES LIKE ‘%slow_query_log%‘; +---------------------+-------------------------------+ | Variable_name | Value | +---------------------+-------------------------------+ | slow_query_log | ON | | slow_query_log_file | /var/lib/mysql/lagou-slow.log | +---------------------+-------------------------------+
- 设置慢查询的时间:show variables like ‘long_query_time‘;set global long_query_time=1; show variables like ‘long_query_time‘;使用命令 set global long_query_time=1 修改后,需要重新连接或新开一个会话才能看到修改值
-
log_output 参数是指定日志的存储方式。 log_output=‘FILE‘ 表示将日志存入文件,默认值是‘FILE‘。 log_output=‘TABLE‘ 表示将日志存入数据库,这样日志信息就会被写入到mysql.slow_log 表中
mysql> SHOW VARIABLES LIKE ‘%log_output%‘; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | log_output | FILE | +---------------+-------+ MySQL数据库支持同时两种日志存储方式,配置的时候以逗号隔开即可,如:log_output=‘FILE,TABLE‘。日志记录到系统的专用日志表中,要比记录到文件耗费更多的系统资源,因此对于需要启用慢查询日志,又需要能够获得更高的系统性能,那么建议优先记录到文件.
-
系统变量 log-queries-not-using-indexes :未使用索引的查询也被记录到慢查询日志中(可选项)。如果调优的话,建议开启这个选项
mysql> show variables like ‘log_queries_not_using_indexes‘; +-------------------------------+-------+ | Variable_name | Value | +-------------------------------+-------+ | log_queries_not_using_indexes | OFF | +-------------------------------+-------+ mysql> set global log_queries_not_using_indexes=1; Query OK, 0 rows affected (0.00 sec) mysql> show variables like ‘log_queries_not_using_indexes‘; +-------------------------------+-------+ | Variable_name | Value | +-------------------------------+-------+ | log_queries_not_using_indexes | ON | +-------------------------------+-------+ 1 row in set (0.00 sec)
- 查看慢查询日志 cat /var/lib/mysql/mysql.log
- 默认慢查询方式是禁用的,可以通过set方式开启;设置后只对当前数据库生效,mysql重启后会失效
4.MySQL存储引擎
- 存储引擎如何存储数据、如何为存储的数据建立索引和如何更新、查询数据等技术的实现方法。要求支持并发性、事务、引用的完整性和索引的支持
- 查看数据库的存储引擎
-
SHOW ENGINES;查看MySQL数据 的所有引擎
- 事务安全表: InnoDB
- 非事务安全表: MyISAM、MEMORY、MERGE、EXAMPLE、NDB Cluster、ARCHIVE、CSV、BLACKHOLE、FEDERATED等
- SHOW VARIABLES LIKE ‘%default_storage_engine%‘; 查看当前的默认存储引擎 (MySQL5.7 默认使用 InnoDB)
- 在MySQL中,不需要整个服务器都是用同一种引擎,针对具体的需求,可以对 每一个表使用不同的存储引擎 .并且想要进一步优化, 还可以自己编写一个存储引擎:create table(...) engine=MyISAM;
-
SHOW ENGINES;查看MySQL数据 的所有引擎
-
常见的存储引擎
-
InnoDB:一个健壮的事务型存储引擎,这种存储引擎已经被很多互联网公司使用,为用户操作非常大的数据存储提供了一个强大的解决方案。InnoDB还引入了行级锁定和外键约束,在以下场合下,使用InnoDB是最理想的选择
- 优点:Innodb引擎提供了对数据库ACID事务的支持,并且实现了SQL标准的四种隔离级别;支持多版本并发控制的行级锁,由于锁粒度小,写操作和更新操作并发高、速度快;支持自增长列;支持外键;适合于大容量数据库系统,支持自动灾难恢复
- 缺点:它没有保存表的行数,当SELECT COUNT(*) FROM TABLE时需要扫描全表
-
应用场景:当需要使用数据库事务时,该引擎当然是首选。由于锁的粒度更小,写操作不会锁定全表,所以在并发较高时,使用Innodb引擎会提升效率,更新密集的表, InnoDB存储引擎特别适合处理多重并发的更新请求。
-
MyISAM:不支持事务、也不支持外键,优势是访问速度快,对事务完整性没有 要求或者以select,insert为主的应用基本上可以用这个引擎来创建表
- 优点:MyISAM表是独立于操作系统的,这说明可以轻松地将其从Windows服务器移植到Linux服务器;MyISAM存储引擎在查询大量数据时非常迅速,进行大批量插入操作时执行速度也比较快。
- 缺点:MyISAM表没有提供对数据库事务的支持。不支持行级锁和外键。不适合用于经常UPDATE(更新)的表,效率低。
- 应用场景:以读为主的业务,例如:图片信息数据库,博客数据库,商品库等业务;对数据一致性要求不是非常高的业务(不支持事务);硬件资源比较差的机器可以用 MyiSAM (占用资源少)
-
MEMORY:将表中的数据放在内存中,适用于存储临时数据的临时表和数据仓库中的纬度表
- 优点:memory类型的表访问非常的快,因为它的数据是放在内存中的
- 缺点:一旦服务关闭,表中的数据就会丢失掉。只支持表锁,并发性能差,不支持TEXT和BLOB列类型,存储varchar时是按照char的方式
- 应用场景:目标数据较小,而且被非常频繁地访问。如果数据是临时的,而且要求必须立即可用,那么就可以存放在内存表中。存储在Memory表中的数据如果突然丢失,不会对应用服务产生实质的负面影响。
-
InnoDB:一个健壮的事务型存储引擎,这种存储引擎已经被很多互联网公司使用,为用户操作非常大的数据存储提供了一个强大的解决方案。InnoDB还引入了行级锁定和外键约束,在以下场合下,使用InnoDB是最理想的选择
- 如何选择存储引擎
- 是否需要支持事务;
- 崩溃恢复,能否接受崩溃;
- 是否需要外键支持;
- 存储的限制;
- 对索引和缓存的支持
特性 | InnoDB | MyISAM | MEMORY |
存储限制 | 64TB | 无 | 有 |
支持事务 | 支持 | 不支持 | 不支持 |
锁机制 | 行锁 | 表锁 | 表锁 |
B-tree索引 | 支持 | 支持 | 支持 |
哈希索引 | 支持 | 不支持 | 支持 |
外键支持 | 支持 | 不支持 | 不支持 |
存储空间消耗 | 高 | 低 | 低 |
内存消耗 | 高 | 低 | 高 |
批量写入数据消耗 | 慢 | 快 | 快 |
5.MySQL索引优化
- 索引就是一种将数据库中的记录按照特殊形式存储的数据结构。通过索引,能够显著地提高数据查询的效率,从而提升服务器的性能
- 使用索引后可以不用扫描全表来定位某行的数据,而是先通过索引表找到该行数据对应的物理地址然后访问相应的数据
-
索引种类
- 主键索引
CREATE TABLE tablename ( [...], PRIMARY KEY (字段名) ); ALTER TABLE tablename ADD PRIMARY KEY (字段名);
- 普通索引
CREATE INDEX <索引的名字> ON tablename (字段名); ALTER TABLE tablename ADD INDEX [索引的名字] (字段名); CREATE TABLE tablename ( [...], INDEX [索引的名字] (字段名) );
- 唯一索引
CREATE UNIQUE INDEX <索引的名字> ON tablename (字段名); ALTER TABLE tablename ADD UNIQUE INDEX [索引的名字] (字段名); CREATE TABLE tablename ( [...], UNIQUE [索引的名字] (字段名) ;
- 复合索引
-- 复合索引可以代替多个单一索引,相比多个单一索引复合索引所需的开销更小。 CREATE INDEX <索引的名字> ON tablename (字段名1,字段名2...); ALTER TABLE tablename ADD INDEX [索引的名字] (字段名1,字段名2...); CREATE TABLE tablename ( [...], INDEX [索引的名字] (字段名1,字段名2...) );
- 全文索引
--使用全文索引,查询速度会比like快很多倍。 -- 在MySQL 5.6 以前的版本,只有MyISAM存储引擎支持全文索引 -- 从MySQL 5.6开始MyISAM和InnoDB存储引擎均支持 CREATE FULLTEXT INDEX <索引的名字> ON tablename (字段名); ALTER TABLE tablename ADD FULLTEXT [索引的名字] (字段名); CREATE TABLE tablename ( [...], FULLTEXT KEY [索引的名字] (字段名) ;
-
-
.全文索引方式有自然语言检索 IN NATURAL LANGUAGE MODE 和布尔检索 IN BOOLEAN MODE两种,有自己的语法格式,使用 match 和 against 关键字
SELECT * FROM users3 WHERE MATCH(NAME) AGAINST(‘aabb‘); -- * 表示通配符,只能在词的后面 SELECT * FROM users3 WHERE MATCH(NAME) AGAINST(‘aa*‘ IN BOOLEAN MODE);
- 全文索引必须在字符串、文本字段上建立。全文索引字段值必须在最小字符和最大字符之间的才会有效。(innodb:3-84;myisam:4-84)
-
.全文索引方式有自然语言检索 IN NATURAL LANGUAGE MODE 和布尔检索 IN BOOLEAN MODE两种,有自己的语法格式,使用 match 和 against 关键字
- 索引的优缺点
- 提高数据检索的效率,降低数据库的IO成本;通过索引列对数据进行排序,降低数据排序的成本,降低了CPU的消耗
- 创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加;索引需要占物理空间,除了数据表占用数据空间之外,每一个索引还要占用一定的物理空间;当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度
- 创建索引的原则
- 在经常需要搜索的列上创建索引,可以加快搜索的速度;
- 在作为主键的列上创建索引,强制该列的唯一性和组织表中数据的排列结构;
- 在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度;
- 在经常需要根据范围(in,between and)进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的;
- 在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;
-
在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度
6.MySQL锁机制
7.MySQL高可用设计
8.MySQL集群
数据存储层,主要是将数据存储在运行于裸设备的文件系统之上,并完成与存储引擎的交互