mysql-Innodb

  1. 存储引擎介绍 相当于Linux 文件系统.组织存储表数据.

  2. 功能了解


数据读写
数据安全和一致性
提高性能
热备份
自动故障恢复
高可用方面支持
  1. 存储引擎的种类
show engines;  --查看当前存储引擎种类

存储引擎是作用在表上的,也就意味着,不同的表可以有不同的存储引擎类型。InnoDB 
MyISAM
CSV
Memory



其他的存储引擎: 
MariaDB  : 默认是InnoDB,TokuDB ,Myrocks  
percona  : 默认是XtraDB ,TokuDB ,Myrocks 

TokuDB ,Myrocks : 比较适合于在写入操作较多的场景,数据量级大的场景.
原因是: 插入性能很高, 压缩比较高. 

现在很多的NewSQL,使用比较多的功能特性.
监控类的业务

4.简历案例---zabbix监控系统架构整改

环境: zabbix 3.2    mariaDB 5.5  centos 7.3
现象 : zabbix卡的要死 ,  每隔3-4个月,都要重新搭建一遍zabbix,存储空间经常爆满.
问题 :
1. zabbix 版本 
2. 数据库版本
3. zabbix数据库500G,存在一个文件里
优化建议:
1.数据库版本升级到5.7版本,zabbix升级更高版本
2.存储引擎改为tokudb
3.监控数据按月份进行切割(二次开发:zabbix 数据保留机制功能重写,数据库分表)
4.关闭binlog和双1 等安全参数需要关闭
5.参数调整....
优化结果:
监控状态良好

select concat("alter table zabbix.",table_name," engine=tokudb") from information_schema.tables
where table_schema='zabbix';

为什么?
1. 原生态支持TokuDB,另外经过测试环境,5.7要比5.5 版本性能 高  2-3倍
2. TokuDB:insert数据比Innodb快的多,数据压缩比要Innodb高
3.监控数据按月份进行切割,为了能够truncate每个分区表,立即释放空间
4.关闭binlog ----->减少无关日志的记录.
5.参数调整...----->安全性参数关闭,提高性能.
5.InnoDB存储引擎的核心特性
image.png

==============================
面试题:
(1) InnoDB存储引擎的特性
​ (2) InnoDB和MyISAM的区别

InnoDB核心特性:
MVCC       多版本并发控制  
聚簇索引   PK
事务
行级锁     MyISAM支持表锁
外键       FK 
复制支持高级特性: GTID等高级复制
自适应hash索引 
支持热备,MyISAM支持温备份
ACSR(自动故障恢复)
  1. 存储引擎的操作
    4.1 查看存储引擎
    mysql> show engines;
    mysql> select @@default_storage_engine; --默认存储引擎类型
    创建表设置存储引擎类型:
    mysql> create table mt (id int) engine=myisam;
    mysql> create table et (id int) engine=innodb;
    查询所有非INNODB的表 , 并且提出修改建议
  mysql> SELECT 
      -> table_schema,
      -> table_name ,
      -> ENGINE ,
      -> CONCAT("alter table ",table_schema,".",table_name," engine=innodb;") AS "修改建议"
      -> FROM information_schema.tables
      -> WHERE table_schema NOT IN ('sys','information_schema','performance_schema','mysql')
      -> AND ENGINE <> 'innodb';
  +--------------+------------+--------+--------------------------------------+
  | table_schema | table_name | ENGINE | 修改建议                             |
  +--------------+------------+--------+--------------------------------------+
  | test         | mt         | MyISAM | alter table test.mt engine=innodb;   |
  | test         | test       | MyISAM | alter table test.test engine=innodb; |
  +--------------+------------+--------+--------------------------------------+
  2 rows in set (0.01 sec)
  mysql> 

4.2 修改表的存储引擎
alter table test.test engine=innodb;

扩展: 碎片问题解决.
由于业务中有大量的delete操作,产生了大量的碎片.
(1) 表数据逻辑导出,删除原表,重新导入.
(2) mysql> alter table test.test engine=innodb; --解决一部分

小项目:
环境:centos7.4,MySQL 5.7.20,InnoDB存储引擎
业务特点:数据量级较大,经常需要按月删除历史数据.
问题:磁盘空间占用很大,不释放
处理方法:
以前:将数据逻辑导出,手工truncate表,然后导入进去
现在:
对表进行按月进行归档表
业务替换为truncate方式

实施过程:
1.部署 Mariadb 环境 10.0.38
[root@db01 mysql]# vim /etc/yum.repos.d/mariadb.repo 
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.1/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=0
enabled=1

tar   xf mariadb-10.0.38-rhel-7-x86_64-rpms.tar


2. 改配置文件
[root@db01 my.cnf.d]# vim /etc/my.cnf.d/tokudb.cnf 

[mariadb]
plugin-load-add=ha_tokudb.so
plugin-dir=/data/tokudb/plugin/
tokudb_commit_sync=ON
tokudb_cache_size=128M
tokudb_directio=ON
tokudb_row_format=tokudb_fast
tokudb_tmp_dir=/data/tokudb/tmp
tokudb_write_status_frequency =1
tokudb_read_status_frequency=1
tokudb_data_dir=/data/tokudb/data
tokudb_log_dir=/data/tokudb/log
~                                                                                                                                   
mkdir -p ~    /data/tokudb/{plugin,tmp,data,log}                                       
chown -R mysql.mysql /data/*
cd /usr/lib64/mysql/plugin/
cp -a * /data/tokudb/plugin/
chown -R mysql.mysql /data/*

3. 启动数据库
[root@db01 data]# mysqld_safe &


4. 生成批量替换语句 
select concat('alter table ',table_schema,'.',table_name,' drop FOREIGN KEY ', CONSTRAINT_NAME,";") from information_schema.TABLE_CONSTRAINTS  where table_schema='zabbix'  and CONSTRAINT_TYPE='FOREIGN KEY';

select concat('alter table ',table_schema,'.'table_name,' engine=tokudb') from information_schema.tables where table_schema='zabbix' into outfile '/tmp/alter.sql';


percona-server+tokudb+zabbix
https://www.jianshu.com/p/898d2e4bd3a7

5.InnoDB存储引擎物理存储结构
5.1 表空间(tablespace)

(1) MySQL5.5版本出现了共享表空间模式(移植了Oracle) 实现了较为方便的扩容功能,但是所有的表数据都集中在几个文件中,管理十分不方便. (2) MySQL 5.6中 ,默认使用独立表空间模式实现数据的存储. 主要存储的是用户数据 存储特点为:一个表一个ibd文件,存储数据行和索引信息 基本表结构元数据存储: xxx.frm 最终结论: 元数据 数据行+索引 mysql表数据 =(ibdataX+frm)+ibd(段、区、页) DDL DML+DQL 保留了共享表空间,只用来存储系统相关数据(数据字典+undo+tmp表空间) 把用户表数据和索引单独存储(独立表空间)

MySQL的存储引擎日志: Redo Log: ib_logfile0 ib_logfile1,重做日志 Undo Log: ibdata1 ibdata2(存储在共享表空间中),回滚日志 临时表:ibtmp1,在做join union操作产生临时数据,用完就自动

(3) MySQL 5.7 保留了共享表空间ibdata1,只用来存储系统相关数据(数据字典+undo),undo在5.7 手工配置将他独立出来= (4) MySQL 8.0 保留了共享表空间ibdata1,只用来存储系统相关数据(dw,cb) undo自动独立出来,移除了数据字典的存储

5.2 表空间管理
查看表空间模式:
mysql> select @@innodb_file_per_table;
共享表空间的设置:
mysql> select @@innodb_data_file_path;
ibdata1:332M;ibdata2:128M:autoextend

一般情况下: 安装MySQL ,提前设置好
mysqld --initialize-insecure ....
my.cnf
ibdata1:512M:ibdata2:512M:autoextend

5.3 表的物理存储介绍

 t1表:
   ibd          :  数据行

   frm          :  数据字典部分信息(列,列属性)
   ibdata1      :  整个数据库的数据字典(所有表的列信息,列属性....),undo
   ib_logfileN  :  redo事务日志

5.4 表空间迁移(快速迁移部分表数据)
(1) 准备一个新环境
(2) 创建和原表结构一样的表
show create table t1 ;
create ....
(3) 删除空表的ibd表空间文件
alter table t1 discard tablespace;
(4) cp 原表的ibd表空间到新环境
[root@db01 test]# cp -a t1.ibd /data/mysql/data_3307/db1
(5) 导入表空间文件.
alter table t1 import tablespace;

5.5 学员的项目

  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/discad.sql';
(4)、验证数据
表都可以访问了,数据挽回到了出现问题时刻的状态(2-8)

6.物理存储结构
6.0 最直观的存储方式(/data/mysql/data)

undefined
ibdata1:系统数据字典信息(统计信息),UNDO表空间等数据
ib_logfile0 ~ ib_logfile1: REDO日志文件,事务日志文件。
ibtmp1: 临时表空间磁盘位置,存储临时表
frm:存储表的列信息
ibd:表的数据行和索引

6.1 表空间

支持两类表空间: 共享,独立
5.5 版本 :  默认共享表空间.    包含: 数据字典\undo\tmp\用户表数据和索引
5.6 版本 :  默认独立表空间.    包含: 数据字典\undo\tmp,将用户数据和索引独立,每个表单独存储
5.7 版本 :  默认独立表空间.    包含: 数据字典\undo,tmp独立,将用户数据和索引独立,每个表单独存储
8.0 版本 :  默认独立表空间.    数据字典取消掉, undo,tmp独立  将用户数据和索引独立,每个表单独存储

6.2 功能名词介绍

transaction           事务
undo  : ibdata1       回滚日志
tmp   : ibtmp1        临时表空间 
redo  : ib_logfile0~N 重做日志
ibd   : t1.ibd        表空间数据文件
​
​
Innodb Buffer Pool    数据缓冲区池(70-80%)
log buffer            重做日志缓冲区
LSN                   日志序列号  
Trx_id                事务ID
checkpoint            检查点  

6.3 事务?

6.3.1 什么是事务?
将多条DML(标准的事务语句),放在一个"组"中运行,要么全成功要么全失败.

6.3.2 事务ACID特性atomicity, consistency, isolation, and durability.
A : 原子性 : 每一个事务都是一个完整整体,不可再分性 . 要么全执行成功要么全失败.
C : 一致性 : 在事务前,中,后,保证事务操作的数据前后一致.
I : 隔离性 : 多个事务之间,所做事务互不干扰,不能同时更新同一行数据.
D : 持久性 : 事务完成之后,所涉及到的数据,必须永久有效(落地)

6.3.3 事务的生命周期管理 标准的事务生命周期:
(1) 开启一个事务
begin / start transaction;

(2) 标准的事务语句
insert
update
delete
(3) 结束事务
commit; # 提交事务
rollback; # 回滚事务(commit提交后,rollback无法回滚)

非标准的事务生命周期
(1) 自动提交机制
MySQL 5.6 以后:

  1. begin子句会自动添加
  2. 每一条执行完成之后都会自动提交 mysql> select @@autocommit;
    +--------------+
    | @@autocommit |
    +--------------+
    | 1 |
    +--------------+

[root@db01 data_3306]# vim /etc/my.cnf
autocommit=0
[root@db01 data_3306]# /etc/init.d/mysqld restart
说明: 默认情况下,开启事务时不加begin,逐条自动提交. 手工开启begin命令,按照正常事务工作过程.

6.3.4隐式提交语句

用于隐式提交的 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

6.3.5隐式回滚
会话断开
数据库重启
死锁

6.3.6 事务底层的工作过程
画图说明.
(1) redo 分布:
内存: log buffer
磁盘: ib_logfile0~N

功能:
1.保存内存数据页的变化

  1. commit时, 实现事务的快速持久化的特性: 量少,顺序IO
  2. 宕机时,通过redo实现重做事务,将数据库恢复到宕机之前的状态. 我们由把这步称之为 ACSR 中的"前滚"操作

(2) undo 回滚日志
分布: 默认 ibdata1, 5.7开始可以独立undo,8.0后自动独立
功能 :
1.保存当前事务操作的反操作

  1. 在执行rollback命令时,undo提供回滚操作,在ACID中主要实现A的特性,CI也有部分功能
  2. 宕机时,ACSR过程中提供回滚操作(将没有commit标记的)

6.3.7 锁(写) 及 隔离级别(读)主要保证隔离性
(1) 锁 :
S : 共享锁,读锁
X : 排它锁,写锁 (和任何锁都不兼容)
IS : 意向S
IX : 意向X

(2) X 锁的细分
TX ------> 表锁 DDL
全局锁表:
备份时,备份系统表时(非INOODB表),FTWRL
mysql> flush table with read lock;
mysql> unlock tables;

单表: DDL mysql> lock table t1 read ; mysql> unlock tables;

RX ------> 记录锁 DML GAP LOCK X ------> 间隙锁 特殊DML Next LOCK X ------> 下一键锁定

(3) 隔离级别(transaction_isolation) mysql> select @@transaction_isolation; RU :读未提交 READ-UNCOMMITTED模拟:

session A mysql> begin; mysql> use world mysql> delete from city where id=1000;

session B mysql> begin; mysql> use world mysql> select *from city where id=1000;

会产生的问题: 1. 脏读 2. 不可重复读现象 3. 幻读

RC :读已提交 ***** READ-COMMITTED 1. 不可重复读现象 2. 幻读

RR :可重复读 ***** REPEATABLE-READ 1. 幻读 说明:

  1. RR级别+ GAP+ Next lock(GAP+RX)有效防止幻读现象

  2. 通过MVCC,多版本并发控制中,一致性快照读技术,解决了不可重复读问题.

SR :串行化

总结: AID 都是为了数据库最终一致性 C SQL_MODE 约束

自己扩展: MDL 原数据锁 page lock 页锁 latch 内存页锁

  1. InnoDB 存储引擎核心参数 ***** mysql> select @@innodb_data_file_path; mysql> select @@innodb_file_per_table; mysql> select @@innodb_buffer_pool_size; #不要超过80%物理内存 ----> Out of memory mysql> select @@innodb_log_buffer_size; mysql> select @@innodb_log_file_size; mysql> select @@innodb_log_file_in_group; mysql> select @@innodb_flush_log_at_trx_commit; # 双1标准之一.控制redo刷写的策略. 0 每秒钟刷写redo到磁盘. 1 每次事务提交,理解刷写redo到磁盘 2 每次事务提交,立即写日志到OS cache中,然后每秒钟刷写到磁盘.

mysql> select @@innodb_flush_method; 控制(buffer脏页,redo buffer日志)刷写方式 建议设置: O_DIRECT : 数据页刷写磁盘直接穿过文件系统缓存,redo 刷写时,先写os cache,再写到磁盘。

=================

  1. 日志

  2. 备份恢复

  3. 主从复制

  4. 高可用

  5. 分布式

  6. 优化

  7. NoSQL

你可能感兴趣的:(mysql-Innodb)