回顾:
- 联合索引
where a and c and b >
where a order by b
2.别名
where a group by b order c
==================================
执行计划
type : ALL , index , range ,ref ,eq_ref , const
key_len: 多列的最大预留长度和.
extra:
using filesort 排序操作没有受到索引优化.
====================================建立索引的规则
建表时一定要有主键,一般是个无关列
选择唯一性索引,联合索引中放在最左侧
为经常需要where 、ORDER BY、GROUP BY,join on等操作的字段
尽量使用前缀来索引 (a(10),b(5),c(8))
限制索引的数目,删除不再使用或者很少使用的索引(percona toolkit) (pt-index xxx)
(a(10),b(5),c(8)) ----> a ab abc
大表加索引,要在业务不繁忙期间操作.
尽量少在经常更新值的列上建索引
- 不走索引的情况
2.1 没有查询条件,或者查询条件没有建立索引.
select * from city;
select * from city where 1=1;
优化方法
(1)
select *from city where id>
(2)
缓存
2.2 查询结果集是原表中的大部分数据,应该是25%以上。
优化方法
(1)
select *from city where id> <
(2)
缓存
2.3 索引本身失效,统计数据不真实
经典现象: 昨天查询好好,今天查询慢.
2.5 查询条件使用函数在索引列上,或者对索引列进行运算,运算包括(+,-,*,/,! 等)
2.6 隐式转换导致索引失效.这一点应当引起重视.也是开发中经常会犯的错误.
mysql> select * from t where telnum=12306;
mysql> select * from t where telnum='12306';
2.7 <> ,not in 不走索引(辅助索引),like '%a'
特殊情况: 对于主键列,也是可以走range范围查询.
========================================
第五章 存储引擎
- 介绍
相当于Linux中的文件系统.组织存储数据. - 存储引擎种类
mysql> show engines;
InnoDB
MyISAM
CSV
Memory
MariaDB : InnoDB,TokuDB,Myrocks
percona : xtraDB
TokuDB : 插入性能高,压缩比高
Myrocks : 插入性能高,压缩比高
5.0 5.1 5.5 10.1 10.2
5.6 5.7 8.0
简历案例---zabbix监控系统架构整改
环境: zabbix 3.2 mariaDB 5.5 centos 7.3
现象 : zabbix卡的要死 , 每隔3-4个月,都要重新搭建一遍zabbix,存储空间经常爆满.
问题 :
- zabbix 版本
- 数据库版本
- zabbix数据库500G,存在一个文件里
优化建议:
1.数据库版本升级到5.7版本,zabbix升级更高版本
2.存储引擎改为tokudb
3.监控数据按月份进行切割(二次开发:zabbix 数据保留机制功能重写,数据库分表)
4.关闭binlog和双1
5.参数调整....
优化结果:
监控状态良好
为什么?
- 原生态支持TokuDB,另外经过测试环境,10.x要比5.5 版本性能 高 2-3倍
- TokuDB:insert数据比Innodb快的多,数据压缩比要Innodb高
3.监控数据按月份进行切割,为了能够truncate每个分区表,立即释放空间
4.关闭binlog ----->减少无关日志的记录.
5.参数调整...----->安全性参数关闭,提高性能.
作者:wwwoldguocom
链接:https://www.jianshu.com/p/4a344bb75d36
来源:
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
- InnoDB存储引擎核心特性
MVCC: 多版本并发控制 ***
聚簇索引
事务 *****
行级锁
Insert buffer
自适应HASH索引
热备
ACSR:自动故障恢复 *****
主从: 支持一些新特性,GTID等.
请你列举MySQL InnoDB存储引擎优点?
请你列举 InooDB和MyIsam的区别?
- 存储引擎的查看和配置
mysql> show engines;
mysql> show create table city;
mysql> select @@default_storage_engine;
mysql> show variables like '%engine%';
mysql> alter table t_engine engine=innodb;
功能说明:
1. 修改存储引擎类型
2. InnoDB碎片整理.
存储引擎替换案例
环境: centos 5.8 ,MySQL 5.0版本,MyISAM存储引擎,网站业务(LNMP),数据量50G左右
现象问题: 业务压力大的时候,非常卡;经历过宕机,会有部分数据丢失.
问题分析:
1.MyISAM存储引擎表级锁,在高并发时,会有很高锁等待
2.MyISAM存储引擎不支持事务,在断电时,会有可能丢失数据
职责
1.监控锁的情况:有很多的表锁等待
2.存储引擎查看:所有表默认是MyISAM
解决方案:
1.升级MySQL 5.6.10版本迁移所有表到新环境
开启双1安全参数
InnoDB存储引擎物理存储结构
7.1 宏观
ib_buffer_pool : 关闭数据库时,自动保存bufferpool缓冲热数据文件.
ibdata1 : 系统表空间数据文件. undo日志数据,数据字典
ib_logfile0 : 重做日志文件(redo log)
ib_logfile1
ibtmp1 : 临时表空间文件
t.frm
t.ibd
7.2 表空间介绍
7.2.1 共享表空间
MySQL 5.5版本加入的功能(ibdata1 自动扩容 ), 作为InnoDB默认数据存储方式.
7.2.2 独立表空间
MySQL 5.6 版本中,作为默认数据存储方式.
https://dev.mysql.com/doc/refman/8.0/en/innodb-architecture.html
7.2.3 共享表空间设置
innodb_data_file_path=ibdata1:512M;ibdata2:512M:autoextend
案例:
背景:
centos 6.8 系统, MySQL:5.5.40版本,默认共享表空间.数据量:600G左右
所有数据都存储在了ibdata1文件中 ,查询管理效率低(IO,CPU负载高).
解决思路:
1. 迁移 升级 MySQL 5.5.40 到 5.7.20
2. 所有业务表调整为InnoDB
3. 确认所有表都是独立表空间
结果:
IO , CPU负载受到控制.性能提升.
7.2.5 独立表空间设置
mysql> select @@innodb_file_per_table;
7.2.6 表空间迁移
mysql> alter table t discard tablespace;
mysql> alter table t import tablespace;
使用方法:
1. 新环境安装MySQL,启动
2. 新环境创建一模一样结构的表
3. alter table t discard tablespace;
4. 原环境的ibd文件拷贝过来
5. alter table t import tablespace;
7.2.7 故事-->事故
(1) 生产事故:表空间迁移实现故障恢复
背景:
硬件及软件环境:联想服务器(IBM)磁盘500G 没有raid
centos 6.8 + mysql 5.6.33 : innodb引擎 独立表空间
备份没有,日志也没开,开发用户专用库:
jira(bug追踪) 、 confluence(内部知识库) ------>LNMT
故障描述:
1. 经历断电.
2. 第二天,发现jira和confluence无法访问.
3. 检查系统,"/" 只读,提示fsck进行修复
解决流程:
1. 开发自己按照屏幕提示执行fsck. 系统正常启动,MySQL无法启动.
2. 找运维解决.通过检查:confulence库在 ,jira库不见了
3. confulence库能否临时用着.
4. 尝试 将confulence库 拷贝到 测试环境,发现用不了.
5. 有没有一款工具可以直接读取ibd文件? ----> 没有
6. 尝试用表空间迁移方法. ----> 测试成功.
7. confluence库下有107张表.
information_schema拼接语句
alter table t discard tablespace; 107次
-
alter table t import tablespace; 107次
- 执行过程中发现,有20-30个表无法成功。
主外键关系,很绝望,一个表一个表分析表结构,很痛苦。
set foreign_key_checks=0 跳过外键检查。
把有问题的表表空间也删掉了。
- 执行过程中发现,有20-30个表无法成功。
结果: 修复了7个小时,最终将confluence恢复成功
(2)案例二: 数据库变更,误删除ibdata1 ,结合周六备份.
- InnoDB 的核心特性详解--事务
伴随着交易类的业务,出现的概念.
8.1 什么是事务的ACID
A : 原子性 同一个事务中的所有语句,必须同时成功或同时失败(commit,rollback).
C : 一致性 一个事务过程中的数据,在事务开始前,中,后都将保证一致性.
I : 隔离性 事务发生过程中操作的数据,和其他事务进行隔离
D : 持久性 事务完成后,数据从内存落地磁盘.
8.2 事务生命周期控制
8.2.1 标准事务控制语句
begin; / start transaction; 开始事务
DML
DML
commit; 提交
rollback; 回滚
8.2.2 特殊的控制语句
autocommit;
begin;
a
b
commit;
db01 [(none)]>select @@autocommit;
db01 [(none)]>set autocommit=0;
db01 [(none)]>set global autocommit=0;
注:
自动提交是否打开,一般在有事务需求的MySQL中,将其关闭
不管有没有事务需求,我们一般也都建议设置为0,可以很大程度上提高数据库性能
(1)
set autocommit=0;
set global autocommit=0;
(2)
vim /etc/my.cnf
autocommit=0
8.2.3 隐式提交语句
用于隐式提交的 SQL 语句:
begin
a
b
begin
SET AUTOCOMMIT = 1
导致提交的非事务语句:
DDL语句: (ALTER、CREATE 和 DROP)
DCL语句: (GRANT、REVOKE 和 SET PASSWORD)
锁定语句:(LOCK TABLES 和 UNLOCK TABLES)
导致隐式提交的语句示例:
TRUNCATE TABLE
LOAD DATA INFILE
SELECT FOR UPDATE
8.2.5 隐式回滚语句
会话断开 (exsit , kill,连接窗口关闭)
死锁
关机
异常宕机
标准事务语句 : DML语句
begin;
update
update
commit;
- 事务的ACID如何保证的?
9.1 名词介绍
redo : 重做日志 , 保存数据页的变化 (ib_logfile0~1)
redo buffer : 日志缓冲区
undo : 回滚日志 : ibdata1
datafile : city.ibd
data buffer pool: 数据缓冲区,数据页(数据行和索引)
LSN : Log seq no. 日志序列号,数据和redo.
脏页: 未写入磁盘的被修改的内存数据页
CKPT: checkpoint ,刷写内存脏页到磁盘
TXID: 每个事务开始时,会分配一个唯一事务编号.
WAL: write ahead log,日志优先写.
9.2 redo
9.2.1 作用
记录数据页变化日志. 主要用来保证ACID 中的D的特性 ,AC特性也有保证.
9.2.2 文件位置
数据路径下,ib_logfile0~N
innodb_log_file_size=128M
innodb_log_files_in_group=5
9.2.3 redo有关的内存
redo buffer
innodb_log_buffer_size
innodb_flush_log_at_trx_commit=1 控制redo什么时候往磁盘上写.
9.2.5 redo 功能文字描述
MySQL : 在启动时,必须保证redo日志文件和数据文件LSN必须一致, 如果不一致就会触发CSR,最终保证一致
情况一:
我们做了一个事务,begin;update;commit.
1.在begin ,会立即分配一个TXID=tx_01.
2.update时,会将需要修改的数据页(dp_01,LSN=101),加载到data buffer中
3.IO线程,会进行dp_01数据页修改更新,并更新LSN=102
4.日志写线程,会将dp_01数据页的变化+LSN+TXID存储到redo buffer
- 执行commit时,日志写线程会将redo buffer信息写入redo log日志文件中,基于WAL原则,
在日志完全写入磁盘后,commit命令才执行成功,(会将此日志打上commit标记)
6.假如此时宕机,内存脏页没有来得及写入磁盘,内存数据全部丢失
7.MySQL再次重启时,必须要redo log和磁盘数据页的LSN是一致的.
但是,此时dp_01,TXID=tx_01磁盘是LSN=101,dp_01,TXID=tx_01,redo log中LSN=102
MySQL此时无法正常启动,MySQL触发CSR.在内存追平LSN号,触发ckpt,将内存数据页更新到磁盘,从而保证磁盘数据页和redo log LSN一值.这时MySQL正常启动
以上的工作过程,我们把它称之为基于 REDO 的"前滚操作"
补充:
MySQL redo具备预写入功能,刷写redo buffer 到磁盘时, 满足已经提交的时候(innodb_flush_log_at_trx_commit=1 ),
会立即触发写入磁盘,一些未提交的的redo buffer日志,也会被连带着被刷写磁盘.
此时,redo log就会存在多种状态的事务日志.
怎么区分?
通过标签不同来区分此日志对应的事务是否提交.
9.3 undo日志
9.3.1 作用
记录的是事务的反操作.
ACID ,主要作用是A的原子性,CI也有作用.
9.3.2 快照功能
undo可以实现针对不同时间点版本快照.对MVCC提供功能保证.
9.5 锁
InnoDB支持行锁,保证事务更新某行数据时,不会受到其他事务影响.
保证了ACID中I的特性.
IX, X ,IS,S
GAP 锁 , Next-lock锁 : 为了解决在RR (MySQL的隔离级别),防止幻读.
9.6 隔离级别
9.6.1 作用:
影响的是读数据的隔离.增删改查都要涉及到读数据.
9.6.2 种类
RU : 读未提交,可脏读,一般不允许出现.
RC : 读已提交,可能出现幻读,可以防止脏读.有可能出现"不可重复读"和"幻读".
RR(默认) : 可重复读,功能是防止"不可重复读"现象 ,利用的是undo的快照技术+GAP(间隙锁)+NextLock(下键锁)一同防止"幻读".
SR : 可串行化,可以防止死锁,但是并发事务性能较差
9.6.3 各种隔离级别功能演示
vim /etc/my.cnf
autocommit=0
transaction_isolation=read-uncommitted
optimize table city