存储引擎相当于Linux 文件系统。
插件的模式存在。作用在表的一种属性。
Oracle MySQL :
mysql> show engines;
MRG_MYISAM
CSV
MyISAM
BLACKHOLE
PERFORMANCE_SCHEMA
InnoDB
ARCHIVE
MEMORY
FEDERATED
笔试题: 请你列举MySQL 支持的存储引擎种类?
InnoDB、MyISAM、CSV、Memory…
MySQL 5.5 版本以后,默认的引擎是InnoDB。
Percona , MariaDB 其他的存储引擎种类:
TokuDB , Myrocks等。
特性:
1. 更高的压缩比。
2. 更快速的插入性能。
生产案例:真实学生案例-监控系统优化。
环境: zabbix 3.x , centos 7.3 , mariaDB 5.5 ,监控2000+节点
现象 : zabbix卡的要死 ,每隔3-4个月,都要重新搭建一遍zabbix,存储空间经常爆满.
问题 : 1. zabbix 版本
2. 数据库版本
3. zabbix数据库500G,存在一个文件里
优化建议:
1.数据库版本升级到10.x最新版本,zabbix升级更高版本
2.存储引擎改为tokudb
3.监控数据按月份进行切割(二次开发:zabbix 数据保留机制功能重写,数据库分表)
4.关闭binlog和双1
5.参数调整....
优化结果:
监控状态良好
为什么?
1. 原生态支持TokuDB,另外经过测试环境,10.x要比5.5版本性能 高2-3倍
2. TokuDB:insert数据比Innodb快的多,数据压缩比要Innodb高
3.监控数据按月份进行切割,为了能够truncate每个分区表,立即释放空间
4.关闭binlog ----->减少无关日志的记录.
5.参数调整...----->安全性参数关闭,提高性能.
晚上作业:
参考文档:
https://www.jianshu.com/p/898d2e4bd3a7
聚簇索引
AHI 自适应hash索引
change buffer
事务
MVCC 多版本并发控制
行级锁
外键
复制特性
支持热备
自动故障恢复(ACSR)
双写机制
面试题:
1. 请你介绍InnoDB存储引擎的核心特性?
2. 请说明InnoDB和MyISAM的区别?
经典案例: 将MyIAM存储引擎替换为InnoDB-1
环境: centos 5.8 ,MySQL 5.0版本,MyISAM存储引擎,网站业务(LAMT),数据量50G左右
现象问题: 业务压力大的时候,非常卡;经历过宕机,会有部分数据丢失.
问题分析:
1.MyISAM存储引擎表级锁,在高并发时,会有很高锁等待
2.MyISAM存储引擎不支持事务,在断电时,会有可能丢失数据
3.主从复制,1年多没同步了。
职责
1.监控锁的情况:有很多的表锁等待
2.存储引擎查看:所有表默认是MyISAM
解决方案:
1.升级MySQL 5.6.2x版本
2. 迁移所有表到新环境,替换存储引擎
3. 开启双1安全参数
经典案例: 将MyIAM存储引擎替换为InnoDB-2
MySQL 版本 5.6 ,由于历史遗留问题,一部分表是MyISAM。
找出MyISAM表,全部替换为InnoDB。
查询业务库中,非InnoDB的表。
SELECT table_schema,table_name,ENGINE
FROM information_schema.tables
WHERE table_schema NOT IN ('sys','information_schema','performance_schema','mysql')
AND ENGINE!='INNODB';
查询业务库中,非InnoDB的表批量替换为InnoDB
修改配置文件
vim /etc/my.cnf
#添加配置并重启
secure-file-priv=/tmp
SELECT CONCAT("ALTER TABLE ",table_schema,".",table_name," ENGINE=INNODB;")
FROM information_schema.tables
WHERE table_schema NOT IN ('sys','information_schema','performance_schema','mysql')
AND ENGINE!='INNODB' INTO OUTFILE '/tmp/alter.sql';
SELECT @@default_storage_engine;
set default_storage_engine=myisam;
set global default_storage_engine=myisam;
重启之后,所有参数均失效.
如果要永久生效:
写入配置文件
vim /etc/my.cnf
[mysqld]
default_storage_engine=InnoDB
存储引擎是表级别的,每个表创建时可以指定不同的存储引擎,但是我们建议统一为innodb.
SHOW CREATE TABLE City\G;
SHOW TABLE STATUS LIKE 'CountryLanguage'\G
select table_schema,table_name ,engine from information_schema.tables where table_schema not in ('sys','mysql','information_schema','performance_schema');
Master [world]>show table status;
Master [world]>show create table city;
alter table t1 engine innodb;
批量替换:
SELECT CONCAT("ALTER TABLE ",table_schema,".",table_name," ENGINE=INNODB;")
FROM information_schema.tables
WHERE table_schema NOT IN ('sys','information_schema','performance_schema','mysql')
AND ENGINE!='INNODB' INTO OUTFILE '/tmp/alter.sql';
注意:此命令我们经常使用他,进行innodb表的碎片整理
环境:centos7.4,MySQL 5.7.20,InnoDB存储引擎
业务特点:数据量级较大,经常需要按月delete删除历史数据.
问题:磁盘空间占用很大,不释放
处理方法:
以前:将数据逻辑导出,手工drop表,然后导入进去
现在:
对表进行按月进行分表(partition,中间件,归档表pt-archive)
业务替换为truncate方式
需求:将zabbix库中的所有表,innodb替换为tokudb
select concat(“alter table zabbix.”,table_name," engine tokudb;") from
information_schema.tables where table_schema=‘zabbix’ into outfile ‘/tmp/tokudb.sql’;
city.frm : 数据字典信息(列定义)
city.ibd : 表空间数据文件,存储数据行和索引
ibdata1 : 共享(系统)表空间文件
ib_logfileN : redo log文件,重做日志。
ibtmp1 : 临时表空间
ib_buffer_pool : 内存预热文件
(1)ibd : 表空间数据文件,段---》区 ----》页
(2)ibdata1:https://dev.mysql.com/doc/refman/8.0/en/innodb-architecture.html
#5.5 版本 :
Data Dictionary,Double write,change buffer ,Undo,临时表,用户数据
#5.6 版本 :
Data Dictionary,Double write,change buffer ,Undo,临时表
#5.7 版本 :
Data Dictionary,Double write,change buffer ,Undo
#8.0 版本
change buffer
Data Dictionary :数据库当中所有表的结构、属性、状态、参数....
Double write :自动故障恢复应用到的数据。
change buffer :辅助索引需要更新数据。
Undo : 存储事务的回滚信息日志。
(3) ib_logfileN : 存储事务的前滚日志。内存数据页的变化。
(4) ibtmp1 :存储SQL处理过程中的中间数据(group by , having , join, union)。
#介绍
在数据库引擎层,加入的逻辑的存储结构。来实现灵活的存储空间扩容。
MySQL 5.5 版本引入了表空间存储管理模式。
#表空间类型
– 共享表空间 :ibdata1~ibdataN
5.5 版本的默认模式。用来存储所有的系统数据+用户数据(数据行+索引)。
ibdata文件默认是一个,不够用了可以进行扩容。
独立表空间 :
5.6 版本+:
默认采用独立表空间模式。每张表都是独立的表空间(t1.ibd)。
共享表空间保留下来,只保存系统相关的数据。
5.7 和 8.0 版本中,将ibdata1进一步的瘦身。
操作
查看和配置表空间模式
mysql> select @@innodb_file_per_table;
mysql> set global innodb_file_per_table=0;
mysql> set global innodb_file_per_table=1;
==============================================
案例: 表空间迁移技术:实现表快速迁移。
1. 停止相关业务
mysql> lock tables t100w read;
mysql> delete from t100w where id=1000;
ERROR 1099 (HY000): Table 't100w' was locked with a READ lock and can't be updated
mysql> select * from t100w limit 10;
2. 目标库创建一摸一样的表
mysql> create database test charset utf8mb4;
Query OK, 1 row affected (0.01 sec)
mysql> use test;
mysql> CREATE TABLE `t100w` (
-> `id` int(11) NOT NULL,
-> `num` int(11) DEFAULT NULL,
-> `k1` char(2) DEFAULT NULL,
-> `k2` char(4) DEFAULT NULL,
-> `dt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-> PRIMARY KEY (`id`),
-> KEY `idx` (`k1`,`k2`)
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ;
3. 将目标空的ibd表空间删除
mysql> alter table t100w discard tablespace;
4. 迁移ibd至目标库
[root@db01 test]# cp /data/3306/data/test/t100w.ibd /data/3307/data/test/
[root@db01 test]# chown -R mysql.mysql /data
5. 导入表空间
mysql> alter table t100w import tablespace;
4. 迁移ibd至目标库
[root@db01 test]# cp /data/3306/data/test/t100w.ibd /data/3307/data/test/
[root@db01 test]# chown -R mysql.mysql /data
5. 导入表空间
mysql> alter table t100w import tablespace;
真实学员案例2则:
1. 表空间迁移技术实现数据损坏恢复
案例背景:
硬件及软件环境:
联想服务器(IBM)
磁盘500G 没有raid
centos 6.8
mysql 5.6.33 innodb引擎 独立表空间
备份没有,日志也没开
开发用户专用库:
jira(bug追踪) 、 confluence(内部知识库) ------>LNMT
运维小组长 : 运维工作 + 数据库
故障描述: 断电了,启动完成后 “/” 只读
fsck 重启,系统成功启动,mysql启动不了。
结果:confulence库在 , jira库不见了
交流
学员求助内容:
求助:这种情况怎么恢复?
我问:有备份没
求助:没有备份,没有主从,连二进制日志都没有。
我说:没招了,jira库需要硬盘恢复了。
求助:
1、jira问题拉倒中关村了
2、能不能暂时把confulence库先打开用着
学员尝试: 将生产库confulence,拷贝到1:1虚拟机上/var/lib/mysql,直接访问时访问不了的
问:有没有工具能直接读取ibd
我说:我查查,最后发现没有
虚拟机测试可行
我想出一个办法来:
表空间迁移:
create table xxx
alter table confulence.t1 discard tablespace;
alter table confulence.t1 import tablespace;
confulence库中一共有107张表。
1、创建107和和原来一模一样的表。
他有2016年的历史库,我让他去他同事电脑上 mysqldump备份confulence库
mysqldump -uroot -ppassw0rd -B confulence --no-data >test.sql
拿到你的测试库,进行恢复
到这步为止,表结构有了。
2、表空间删除。
select concat(‘alter table ‘,table_schema,’.‘table_name,’ discard tablespace;’) from information_schema.tables where table_schema=‘confluence’ into outfile ‘/tmp/discad.sql’;
source /tmp/discard.sql
执行过程中发现,有20-30个表无法成功。主外键关系
很绝望,一个表一个表分析表结构,很痛苦。
set foreign_key_checks=0 跳过外键检查。
把有问题的表表空间也删掉了。
3、拷贝生产中confulence库下的所有表的ibd文件拷贝到准备好的环境中
select concat(‘alter table ‘,table_schema,’.‘table_name,’ import tablespace;’) from information_schema.tables where table_schema=‘confluence’ into outfile ‘/tmp/import.sql’;
4、验证数据
表都可以访问了,数据挽回到了出现问题时刻的状态(2-8)
案例:
交通口: 核心库 ---抽取----》 违章数据 MySQL 5.6 (有备份,每周六全备,每天做日志增量)
周四下午 , 晚上8:00处理
背景:
1. 环境 : 5.6 版本 ,centos 7 , 两个核心库,数据量300G-400G。
2. 备份策略: 每周六全备,每天做日志增量
3. 故障时间周四下午,晚上20:00 开始处理故障
4. 网上文章,修改参数,误删除 rm -rf ibdata1 ,数据库再也起不来了。
恢复过程:
1. 恢复上周六全备,失败了。
原因:
mysqldump -uroot -p123 -A &> /tmp/full.sql
mysqldump -uroot -p123 -A > /tmp/full.sql 2>/tmp/error.log
处理方法: 注释掉备份中的错误信息。正常恢复。
2. 尝试恢复binlog到故障之前的时间点。
失败了。
expire_logs_days=3
结论: 日志中间缺失,无法补偿。放弃这种恢复方案。
3. 尝试使用表空间迁移技术。
具体参照表空间迁移过程。
介绍:
InnoDB最大的内存区域,官方建议最多可设置大小物理内存的80%。生产建议70%以下。
作用:
缓冲数据页、索引页、数据字典、AHI、change buffer 、DW
数据页修改完成之后,会写入到磁盘表空间中。ibd frm ibdata1文件。
参数:
mysql> select @@innodb_buffer_pool_size;
介绍:
用来存储内存数据页的变化。数据修改完成之后,会将日志写入到磁盘日志文件中(ib_logfileN)。
参数:
mysql> select @@innodb_log_buffer_size;
晚上作业:
作业1 :
使用工具从frm文件中取出建表语句,实现表空间迁移。
https://pdf.us/2019/01/10/2620.html
作业2:
https://www.jianshu.com/p/898d2e4bd3a7