MySQL存储引擎

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL存储引擎相关的知识,希望对你有一定的参考价值。

mysql存储引擎

第1章 存储引擎介绍:

1.1 linux文件系统回顾:

1.      文件系统是操作系统组织和存取数据的一种机制

2.      文件系统是一种软件

1.2 文件系统的类型:

ext2  3  4  ;xfs 

不管使用什么文件系统,数据内容不会变化

不同的是,存储空间,大小,速度

1.3 MySQL引擎:

可以理解为,MySQL的文件系统,只不过它的功能更加强大

1.4 MySQL引擎功能:

处了可以提供基本的存取功能,还有事物功能锁定;备份和恢复;优化及特殊功能

第2章 MySQL存储引擎的种类:

?  最常用的两种 : innoDB;MyISAM

2.1 InnoDB存储引擎简介:

存储引擎都是基于表级别的

InnoDB:

1.      支持ACID的事务,支持事务的四种隔离级别;

2.      支持行级锁及外键约束,因此可以支持写并发;

3.      Oracle样式一致非锁定读取

4.       表数据进行整理来优化基于主键的查询

5.      支持外键引用完整性约束

6.      大型数据卷上的最大性能

7.      将对表的查询与不同存储引擎混合

8.      出现故障后快速自动修复

9.      用于在内存中缓存数据和索引的缓冲区池

10.  备份恢复特有的方式

11.  主从特有的属性

2.2 InnoDB功能总览:

技术分享图片

第1章 存储的引擎的操作:

1.1 查看存储引擎:

1.1.1 查看存储引擎:

mysql> show engines;

1.1.2 确认会话存储引擎

mysql> SELECT @@default_storage_engine;

+--------------------------+

| @@default_storage_engine |

+--------------------------+

| InnoDB                   |

+--------------------------+

1.1.3 查看某张表的存储引擎:

mysql> show create table stu;

1.1.4 查看存储引擎是innoDB的数据库:

mysql> select table_schema ,table_name ,engine from information_schema.tables where engine='innodb';

1.2 设置存储引擎的方法:

1.2.1 在启动配置文件中设置服务器存储引擎

[mysqld]

default-storage-engine=<Storage Engine>

1.2.2 使用set命令为当前客户机会话设置

SET @@storage_engine=<Storage Engine>;

1.2.3 create table 创建语句设置

CREATE TABLE t (i INT) ENGINE = <Storage Engine>;

第2章 InnoDB存储引擎的存储结构:

2.1 InnoDB系统表空间特性

1.      默认情况下,InnoDB元数据,撤销日志和缓冲区存储在系统表空间中

2.      这是单个逻辑存储区域,可以包含一个或者多个文件

3.      每个文件可以是常规文件或者原始分区

4.      最后的文件可以自动扩展

2.1.1 表空间的定义:

表空间:mysql数据库存储的方式

表空间中包含数据文件

mysql表空间和数据文件是1:1的关系

共享表空间除外,是可以1:n关系

技术分享图片

1.1 表空间的类型:

1.      共享表空间:ibdata1~ibdataN;一般是2-3

2.      独立表空间:存放在指定库目录下,例如:mysql程序data目录中的.ibd文件

3.      表空间位置:datadir

1.2 系统表空间的存储内容:

1.2.1 共享表空间(物理存储结构)

ibdata1~n通常被叫做系统表空间,是数据初始化产生的

系统元数据,基表数据,除了表内容数据之外的数据

tmp表空间

undo日志:数据-回滚数据(回滚日志使用)

redo日志:ib_logfile~n存放系统的InnoDB表的一些重做日志

说明:undo日志默认是在ibdata中的,5,6以后可以单独定义

1.2.2 独立表空间(一个存储引擎的功能)

5.6以后,默认的情况下会单表单独存储到独立表空间文件

除了系统表空间之外,InnoDB还在数据库目录中创建另外的表空间,用于每个InnoDB表的.ibd文件

InnoDB创建的每个新表在数据库目录中设置一个.ibd文件来搭配表的.frm文件

可以使用innoDB_file_per_table选项控制此设置,更改该设置仅会更改已创建的新表的默认值

技术分享图片

1.1 设置共享表空间:

1.1.1 查看当前共享表空间设置:

mysql> show variables ‘innodb_data_file_path';

1.1.2 设置共享表空间:

一般是在初识搭建环境的时候就配置好,预设值一般为1G,且最后一个为自动扩展

[[email protected] world]# vim /etc/my.cnf

[mysqld]

innodb_data_file_path=ibdata1:76M;ibdata2:100M:autoextend

1.1.3 重启服务器查看当前的共享表空间设置即可

1.2 设置独立表空间

独立表空间是在5.6版本是默认开启的

注意事项:不开启独立表空间,共享表空间会占用很大

1.2.1 查看独立表空间:

mysql> show variables like '%per_table%';

+-----------------------+-------+

| Variable_name         | Value |

+-----------------------+-------+

| innodb_file_per_table | ON    |

+-----------------------+-------+

1 row in set (0.00 sec)

1.2.2 修改my.cnf配置文件,控制独立包空间:

[[email protected] data]# vim /etc/my.cnf

[mysqld]

innodb_file_per_table=0

第2章 MySQL中的事务

2.1 什么是事务?

一组数据操作执行步骤,这些步骤被视为一个工作单元

用于对多个语句进行分组,可以在多个客户机并发放文同一个表中的数据时使用,即想实现所有语句全部成功,则执行,如果出现错误或者语句不完整,则回滚

简单来说,事务就是:保证工作单元中的语句同时成功或者同时失败

技术分享图片

1.1 事务的特性:ACID

1.1.1 A原子性:

一个事务的执行被视为一个不可分割的最小单元,事务里面的操作,要么全部执行,要么全部失败回滚,不能只执行期中一部分

例子:给别人转账的情况中,xiaoming要给xiaohua转账17,即在字段中先扣除17,然后在xiaohua的账户字段中增加17,这个事务中,无论那一条命令没有执行成功,那么这个事务都不应该成功!

updata t1 set money=100-17 where  id=xiaoming

updata t1 set money=100+17  where  id=xiaohua

1.1.2 C一致性:

如果数据库在事务开始时处于一致状态,则在执行该事务起价将保留一致状态,要保证xiaomingxiaohua的金钱总记不能变化

 

1.1.3 I隔离性:

通常来说,事务之间的行为不应该互相影响,然而实际情况中,事务相互影响程度受隔离级别控制

事务之间不互相影响,在做操作的时候,其他人对这两个账户做任何操作,在不同的隔离条件下,可能一致性保证又不一样

 

1.1.4 持久性:

事务提交之后,需要将提交的事务持久化到磁盘,即使系统崩溃,提交的数据也不应该丢失,也就是保证事务安全落地,才算真正安全

第2章 事务的日志

2.1 Redo重做日志:实现事务持久性的作用

2.1.1 redo log的原理:

undo log相反,redo log记录的是新数据的备份,在事务提交前,只要将redo log持久化即可,不需要将数据持久化,当系统崩溃时,虽然数据没有持久化,但是redo log 已经是持久化

系统可以根据redo log的内容,将所有数据恢复到最新的状态

技术分享图片

1.1.1 redo log日志的位置:

/application/mysql/data

-rw-rw---- 1 mysql mysql 50331648 Apr  8 21:26 ib_logfile0

-rw-rw---- 1 mysql mysql 50331648 Apr  1 23:31 ib_logfile1

1.1.2 redo记录了什么?

记录了内存数据页的变化

1.1.3 内存数据页是什么?

和数据有关的一个概念,用来缓冲数据库数据的内存区域

1.2 redo日志的工作过程:

例如转账的过程:

1.      a要给b转账100,这个过程就需要几条sql语句来组成一个事务

2.      首先会将要修改的数据加载到内存区域中,这时假如lsn=100

3.      数据库实例进行修改内存数据页中的信息,整个过程都会被记录到redo buffer,然后lsn=101

4.      事务提交后,redo buffer会优先写入磁盘ib+logfile0文件中,包括lsncommit等标记信息都会记录

5.      当有意外情况发生时,首先会读取redo log日志,和磁盘中的数据进行比对,并按照事务的信息,重新执行事务,保证数据一致

1.3 undo回滚日志:

undo log的原理很简单,为了满足事务的原子性,在操作任何数据前,首先将数据备份到一个地方(这个存储数据备份的地方叫做undo log)然后进行数据的修改

如果出现了错误或者用户执行了rollback语句,系统则利用undo log中的备份数据恢复到事务开始之前的状态,除了可以保证事务的原子性即保证事务ACID特性的A特性,undo log也可以用来辅助完成事务的持久化

技术分享图片

1.1 事务的控制语句:

1.1.1 事务的生命周期:

1.      begin开始,commit结束

2.      begin开始,rollback结束,回滚用

3.      mysql中默认不需要输入begin,只要执行DML语句(update insert delete),自动开启事务

1.1.2 事务隐式控制:

1.      在事务执行的期间,再一次出现了begin的话,会开启一个新事务,并永久提交上一个事务

2.      在事务执行期间,出现DDLDCL,会自动commit上一个事务,并进入到新的事务中

1.1.3 自动提交配置:

修改配置文件:

[mysqld]

autocommit=0   表示开启自动提交

是否开启自动提交,要根据自己的业务来斟酌使用,有的业务需求几条DML语句全部执行成功或者全部失败的情况下,就无法使用自动提交

1.2 四中隔离级别:

作用:主要用来控制读操作的

种类:

?  READ UNCOMMITTED

允许事务查看其它事务锁进行的未提交更改

?  READ COMMITTED

允许事务查看其它事务所进行的已提交更改

?  REPEATABLE READ******

确保每个事务的select输出一致   InnoDB的默认级别:

?  SERIALIZABLE

将一个事务的结果与其它事务完全隔离

my.cnf配置文件中配置参数:

transaction_isolation = 'read-uncommitted'  

transaction_isolation = 'read-committed'

第2章 MySQL故障案例:

2.1 背景说明:

mysql的架构中没有主从复制的体系,也没有按时进行备份

数据库中有两个库conf库和jira,仅有一份备份的数据,还是一年前的备份

2.2 故障场景:

意外宕机,导致磁盘物理损坏,也就是说mysql软件程序中data数据目录中的jira文件都没有了

数据库无法启动,经过检查,conf库数据文件都还在,也就是ibdfrm文件都存在

领导要求,conf还是好的,能不能临时先把数据库跑起来,然后想办法修复jira

2.3 故障环境模拟:

2.3.1 进入到data数据库目录下,删除某一个库的.ibd文件

[[email protected] jiang]# pwd

/application/mysql/data/jiang

[[email protected] jiang]# ll

total 16

-rw-rw---- 1 mysql mysql   61 Apr  3 19:01 db.opt

-rw-rw---- 1 mysql mysql 8556 Apr  8 21:19 stu.frm

-rw-rw---- 1 mysql mysql    0 Apr  8 21:25 stu.ibd

[[email protected] jiang]# echo 123 >stu.ibd

2.3.2 重启mysql服务

[[email protected] jiang]# /etc/init.d/mysqld  start

Starting MySQL... ERROR! The server quit without updating PID file (/application/mysql/data/db01.pid).

2.4 临时解决方案:

2.4.1 搭建一个临时节点,也就是mysql多实例,多实例的搭建这里不进行演示,然后启动多实例

[[email protected] 3307]# sh /server/scripts/mysql.sh start

MySQL 3307  Starting                                       [  OK  ]

[[email protected] 3307]# ss -tunlp|grep 3307

tcp    LISTEN     0      80       :::3307                 :::*                   users:(("mysqld",pid=5219,fd=11))

2.4.2 进入到数据库,创建表结构

要恢复什么表,需要创建好和故障前一样的表结构,然后导入.ibd文件,否则无法导入,

mysql> create table people (id int,name varchar(20));

2.4.3 删除新创建的库的.ibd文件,因为没有数据,一会要导入新的数据

mysql> alter table people discard tablespace;

Query OK, 0 rows affected (0.27 sec)

2.4.4 .ibd文件复制到多实例的数据库目录下,并授权给mysql用户

[[email protected] zabbix]# cp -a ../people.ibd  .

[[email protected] zabbix]# chown mysql.mysql people.ibd

2.4.5 重新导入.ibd文件

mysql> alter table people import tablespace;

Query OK, 0 rows affected, 1 warning (0.34 sec)

mysql> select * from people;

+------+-----------------------------------------------------------------------------------------------------------------+

| id   | name                                                                                                            |

+------+-----------------------------------------------------------------------------------------------------------------+

| NULL | ang  ??        1       ssd            1       angbo      (??        1       angbosd                        |

| NULL | NULL                                                                                                            |

| NULL | angbosd                                                                                                         |

| NULL | ssd            1       angbo     (??        1       angbosd                                                  |

+------+-----------------------------------------------------------------------------------------------------------------+

4 rows in set (0.00 sec)

查看表中所有内容,已经可以看到数据了


以上是关于MySQL存储引擎的主要内容,如果未能解决你的问题,请参考以下文章

MySQL支持的存储引擎

mysql存储引擎

Mysql存储引擎Myisam小结

Mysql存储引擎之myisam

mysql存储引擎

MySQL(十六)—— 存储引擎