美文网首页
走向DBA之存储引擎(2)

走向DBA之存储引擎(2)

作者: 国王12 | 来源:发表于2019-06-24 21:10 被阅读0次

六、InnoDB存储引擎物理存储结构

ib开头的都是innodb存储引擎相关的数据文件
[root@mysql52 /data/mysql/data]# ll
total 188568
-rw-r----- 1 mysql mysql       56 Jun 13 15:23 auto.cnf
-rw-r----- 1 mysql mysql      875 Jun 20 16:08 ib_buffer_pool
-rw-r----- 1 mysql mysql 79691776 Jun 21 08:42 ibdata1
-rw-r----- 1 mysql mysql 50331648 Jun 21 08:42 ib_logfile0
-rw-r----- 1 mysql mysql 50331648 Jun 19 16:16 ib_logfile1
-rw-r----- 1 mysql mysql 12582912 Jun 21 08:42 ibtmp1
......

以上文件具体的存放的东西或作用:

ib_buffer_pool        重启数据库之后,回复以往的热数据到内存里。
ibdata1               存放的是系统数据字典信息(统计信息),和UNDO表空间等数据
ib_logfile0           REDO日志文件,事务日志文件。  
ib_logfile1           REDO日志文件,事务日志文件。
btmp1                临时表空间磁盘位置,存储临时表 
frm                   存储表的列信息
ibd                   表的数据行和索引

6.1表空间(Tablespace)

6.1.1共享表空间 ibdata1个版本存放的数据:

需要将所有数据存储到同一个表空间中 ,管理比较混乱
5.5版本才出现的管理模式,也是默认的管理模式。 (数据字典,undo,临时表,索引,表数据)
5.6版本以,共享表空间保留,只用来存储:数据字典信息,undo,临时表。
5.7 版本,临时表被独立出来了   (数据字典信息,undo)
8.0版本,undo也被独立出去了

具体变化参考文档:
https://dev.mysql.com/doc/refman/5.6/en/innodb-architecture.html
https://dev.mysql.com/doc/refman/5.7/en/innodb-architecture.html
https://dev.mysql.com/doc/refman/5.8/en/innodb-architecture.html

6.1.2 共享表空间设置

共享表空间设置(在搭建MySQL时,初始化数据之前设置到参数文件中,也可以后期更改)

mysql> select @@innodb_file_per_table;         查看表空间当前模式
+-------------------------+
| @@innodb_file_per_table |
+-------------------------+
|                       1 |                    默认结果是1,代表着当前为独立表空间模式。0代表共享表空间模式。
+-------------------------+
1 row in set (0.00 sec)

修改默认表空间为共享空间:
mysql> set innodb_file_per_table=0;

ERROR 1229 (HY000): Variable 'innodb_file_per_table' is a GLOBAL variable and should be set with SET GLOBAL
报错,关键字提示:GLOBAL 即表示只能影响新建的会话,不能影响现在的和过去的会话,因此,SQL语句更改为:

mysql> set global innodb_file_per_table=0;
Query OK, 0 rows affected (0.00 sec)                    修改表空间为共享模式

注意,这种修改在MySQL重启之后,失效,要想永久修改,添加到my.cnf
vim /etc/my.cnf
[mysqld]
innodb_file_per_table=0
当然,不建议修改为共享空间,默认的独立表空间就可以。
mysql> select @@innodb_data_file_path;
+-------------------------+
| @@innodb_data_file_path |
+-------------------------+
| ibdata1:12M:autoextend  |           默认ibdate1的空间大小,不够时自动增加
+-------------------------+
1 row in set (0.00 sec)

mysql> show variables like '%extend%';
+-----------------------------+-------+
| Variable_name               | Value |
+-----------------------------+-------+
| innodb_autoextend_increment | 64    |
+-----------------------------+-------+
1 row in set (0.00 sec)
每次
自增加大小为64M 
             
建议:
初始化之前,直接设置它容量为两个512M的,不够再自己增长容量。
innodb_data_file_path=ibdata1:512M:ibdata2:512M:autoextend
innodb_autoextend_increment=64

6.1.3 独立表空间

从5.6,默认表空间不再使用共享表空间,替换为独立表空间。
主要存储的是用户数据
存储特点为:一个表一个ibd文件,存储数据行和索引信息
基本表结构元数据存储:
xxx.frm
最终结论:
      元数据            数据行+索引
mysql表数据    =(ibdataX+frm)+ibd(段、区、页)
        DDL             DML+DQL

MySQL的存储引擎日志:
Redo Log: ib_logfile0  ib_logfile1,重做日志
Undo Log: ibdata1 ibdata2(存储在共享表空间中),回滚日志

临时表:ibtmp1,在做join union操作产生临时数据,用完就自动删除

6.1.4 删除恢复表空间

mysql> select @@innodb_file_per_table;
+-------------------------+
| @@innodb_file_per_table |
+-------------------------+
|                      1 |
+-------------------------+

先在命令行备份此文件 cp /mysql/world/city.ibd city.ibd.back

alter table city dicard tablespace;
删除city表的表空间(ibd文件)

此时查看city表的数据,已经无法查看了

命令行先恢复city.ibd   cp /mysql/world/city.ibd.back city.ibd (虽然命令行文件已经恢复,但是MySQL并不认识)

授权city.ibd文件权限为mysql   就这个权限问题,TM的,我想了半天。。。

alter table city import tablespace;
恢复city表的表空间(ibd)文件。

现在可以正常查看city表的数据了。

提醒三个点:
命令行把文件恢复之后,一定要授权
MySQL内部,要么use到指定库下,要么写库.表。
倘若中间报因键的问题,执行set foreign_key_checks=0 跳过外键检查。

七、事务的ACID特性

7.1作用:

影响了DML语句(insert  update delete 一部分select)

7.2ACID具体介绍:

Atomic(原子性):
所有语句作为一个单元全部成功执行或全部取消。不能出现中间状态。
比如我发五十红包,你收五十红包。不能我的扣了,你还没收到。
Consistent(一致性);
如果数据库在事务开始时处于一致状态,则在执行该事务期间将保留一致状态。
比如:我有一百块,你有一百块,我发给你五十。最后我有五十块,你有一百五十块
Isolated(隔离性):
事务之间不相互影响。
Durable(持久性):
事务成功完成后,所做的所有更改都会准确地记录在数据库中。所做的更改不会丢失。

八、事务的生命周期(事务控制语句)

8.1事务的开始

begin;  及事务的开始了
说明:在5.5 以上的版本,不需要手工begin,只要你执行的是一个DML,会自动在前面加一个begin命令。

8.2事务的结束:

commit;     提交事务
完成一个事务,一旦事务提交成功 ,就说明具备ACID特性了。

rollback;   回滚事务(就是取消事务开始之后做的操作,后悔了。)
将内存中,已执行过的操作,回滚回去

8.3自动提交策略:

mysql> select @@autocommit;            查看自动提交策略状态 0为关闭,1为开启,默认开启
+--------------+
| @@autocommit |
+--------------+
|           1  |
+--------------+
1 row in set (0.00 sec)

mysql> set autocommit=0;                     关闭当前会话自动提交策略
mysql> set global autocommit=0;              关闭全局会话自动提交策略

同样,这种修改方法,当MySQL重启的时候就会失效,想要永久关闭自动提交策略,将其写到my.cnf里

vim /etc/my.cnf
[mysqld]
autocommit=0    

自动提交是否打开,一般在有事务需求的MySQL中,将其关闭
不管有没有事务需求,我们一般也都建议设置为0,可以很大程度上提高数据库性能

8.4 隐式提交语句

用于隐式提交的 SQL 语句:
begin                 执行了一个begin(执行DML语句,默认会再前边添加一个begin)
a                     执行一条DML语句
begin                 又执行了一条DML语句,那么就会自动提交上一条语句。

在做事务期间,不要执行其他语句,否则你的事务未完成操作,就会被提交。
尽量实用标准的结束事务的语句(commit;提交或rollback;回滚)来结束事务。 

导致提交的非事务语句:
DDL语句: (ALTER、CREATE 和 DROP)
DCL语句: (GRANT、REVOKE 和 SET PASSWORD)
锁定语句:(LOCK TABLES 和 UNLOCK TABLES)
导致隐式提交的语句示例:
TRUNCATE TABLE
LOAD DATA INFILE
SELECT FOR UPDATE

8.5 开始事务流程:

1、检查autocommit(自动提交策略)是否为关闭状态
select @@autocommit;
或者:
show variables like 'autocommit';

2、开启事务,并结束事务
begin
delete from student where name='alexsb';
update student set name='alexsb' where name='alex';
rollback; 回滚,即以上语句不生效

时刻记得,事务的ACID特性(原子性,一致性,隔离性,持久性)

begin
delete from student where name='alexsb';
update student set name='alexsb' where name='alex';
commit;   提交,即让以上语句生效

九、 InnoDB 事务的ACID如何保证?

先介绍一些名词

redo log          ----> 重做日志     文件名是:ib_logfile0~1   默认大小:50M  , 轮询使用
redo log buffer   ----> redo内存区域
.ibd              ----> 存储 数据行和索引 
buffer pool       ---->数据缓冲区池,用于数据和索引的缓冲
LSN               ---->日志序列号 

(磁盘数据页,redo文件,buffer pool,redo buffer
MySQL 每次数据库启动,都会比较磁盘数据页和redolog的LSN,必须要求两者LSN一致数据库才能正常启动)

WAL                ----> write ahead log 日志优先写的方式实现持久化 (就是保证日志先于数据写到磁盘)
脏页                ----> 内存脏页,内存中发生了修改,没写入到磁盘之前,我们把内存页称之为脏页.
CKPT                ---->Checkpoint,检查点,就是将脏页刷写到磁盘的动作
TXID                ----> 事务号,InnoDB会为每一个事务生成一个事务号,伴随着整个事务.

9.1 redo log

9.1.1 Redo是什么?

redo,顾名思义“重做日志”,是事务日志的一种。

9.1.2 作用是什么?

在事务ACID过程中,实现的是“D”持久化的作用。对于AC也有相应的作用

9.1.3 redo日志位置

redo的日志文件:iblogfile0 iblogfile1

9.1.4 redo buffer

redo的buffer:数据页的变化信息+数据页当时的LSN号
LSN:日志序列号  磁盘数据页、内存数据页、redo buffer、redolog

9.1.5 redo的刷新策略

commit;
刷新当前事务的redo buffer到磁盘
还会顺便将一部分redo buffer中没有提交的事务日志也刷新到磁盘

9.1.6 MySQL CSR——前滚

MySQL : 在启动时,必须保证redo日志文件和数据文件LSN必须一致, 如果不一致就会触发CSR,最终保证一致
情况一:
我们做了一个事务,begin;update;commit.
1.在begin ,会立即分配一个TXID=tx_01.
2.update时,会将需要修改的数据页(dp_01,LSN=101),加载到data buffer中
3.DBWR线程,会进行dp_01数据页修改更新,并更新LSN=102
4.LOGBWR日志写线程,会将dp_01数据页的变化+LSN+TXID存储到redobuffer
5. 执行commit时,LGWR日志写线程会将redobuffer信息写入redolog日志文件中,基于WAL原则,
在日志完全写入磁盘后,commit命令才执行成功,(会将此日志打上commit标记)
6.假如此时宕机,内存脏页没有来得及写入磁盘,内存数据全部丢失
7.MySQL再次重启时,必须要redolog和磁盘数据页的LSN是一致的.但是,此时dp_01,TXID=tx_01磁盘是LSN=101,dp_01,TXID=tx_01,redolog中LSN=102
MySQL此时无法正常启动,MySQL触发CSR.在内存追平LSN号,触发ckpt,将内存数据页更新到磁盘,从而保证磁盘数据页和redolog LSN一值.这时MySQL正长启动
以上的工作过程,我们把它称之为基于REDO的"前滚操作"

10.2 undo 回滚日志

10.2.1 undo是什么?

undo,顾名思义“回滚日志”

10.2.2 作用是什么?

在事务ACID过程中,实现的是“A” 原子性的作用
另外CI也依赖于Undo
在rolback时,将数据恢复到修改之前的状态
在CSR实现的是,将redo当中记录的未提交的时候进行回滚.
undo提供快照技术,保存事务修改之前的数据状态.保证了MVCC,隔离性,mysqldump的热备

十一、锁

介绍:

就是锁定的意思,提供的是事务特性中I(隔离性)方面的功能。需要配合undo+隔离级别以一起实现

InnoDB锁级别

行级锁(要修改哪一行,就持有了哪一行的锁)
本章节不做过多讲述,请看后期更新的MySQL优化

悲观锁、乐观锁

悲观锁:行级锁定(行锁)
谁先操作某个数据行,就会持有<这行>的(X)锁.
乐观锁: 没有锁

十二、事务的隔离级别(RR、RC、RU、SR)

RR 、RC是重点

查看隔离级别(默认为RR模式)

select @@tx_isolation; 
show variables like '%iso%';                      这三条语句都可查询隔离级别
mysql> select @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| REPEATABLE-READ         |
+-------------------------+
1 row in set (0.00 sec)
RU  : 读未提交,可脏读,一般部议叙出现
RC  : 读已提交,可能出现幻读,可以防止脏读.
RR  : 可重复读,功能是防止"幻读"现象 ,利用的是undo的快照技术+GAP(间隙锁)+NextLock(下键锁)
SR   : 可串行化,可以防止死锁,但是并发事务性能较差
补充: 在RC级别下,可以减轻GAP+NextLock锁的问题,但是会出现幻读现象,一般在为了读一致性会在正常select后添加for update语句.
但是,请记住执行完一定要commit 否则容易出现所等待比较严重.
示例:
mysql> select * from city where id=999 for update;
mysql> commit

改为RC模式(那边提交事务之后,这边结果立马刷新)

set global transaction_isolation='read-committed';
然后退出MySQL重连即可生效。重启数据库后失效。

十三、InnoDB核心参数

13.1 双一标准之一*****: innodb_flush_log_at_trx_commit=1;

mysql> select @@innodb_flush_log_at_trx_commit;
+----------------------------------+
| @@innodb_flush_log_at_trx_commit |
+----------------------------------+
|                                1 |
+----------------------------------+
1 row in set (0.00 sec)
作用: 控制了redo buffer 刷写策略 (是一个安全参数,是在5.6版本以上默认参数)
等于1: 默认参数,在每次事务提交都会立即刷写redo到磁盘(redo buffer --->os buffer --->磁盘)
等于0:当事务提交时,不立即做日志写入操作(redo buffer ---每秒--->os buffer ---每秒  ---->磁盘)
等于2:每次事务提交引起写入文件系统缓存(redo buffer ---每事务--->os buffer--每秒 ---->磁盘)

redo buffer 是MySQL内存   os buffer 是文件系统内存  

13.2InnoDB_fulsh_method=(O_DIRECT,fdatasync)

作用:

控制了 redo buffer 和 data buffer  刷写磁盘的方式,默认为空
ccclipboard.png
mysql> select @@innodb_flush_method;
+-----------------------+
| @@innodb_flush_method |
+-----------------------+
| NULL                  |
+-----------------------+
1 row in set (0.00 sec)
建议设置为如图所示的第三种,数据直接跳过文件系统刷进磁盘,而日志则正常的先进入文件系统内存,再进入磁盘。
设置方法:
vim /etc/my.cnf
innodb_flush_method=O_DIRECT
然后重启mysql

最大安全模式:

innodb_flush_log_at_trx_commit=1
innodb_flush_method=O_DIRECT

最大性能模式

innodb_flush_log_at_trx_commit=0
innodb_flush_method=fsync

13.2关于redo设置

innodb_log_buffer_size=128M   业务系统CPU压力有关
innodb_log_file_size=256   一般是一到两倍
innodb_log_filees_in_group=3   一般是3-4组
mysql> select @@innodb_buffer_pool_size;
+---------------------------+
| @@innodb_buffer_pool_size |
+---------------------------+
|                 134217728 |
+---------------------------+
1 row in set (0.00 sec)
该参数一般调整为物理内存的50%-80%左右(前提你的系统中中有一个实例)

相关文章

  • 走向DBA之存储引擎(2)

    六、InnoDB存储引擎物理存储结构 以上文件具体的存放的东西或作用: 6.1表空间(Tablespace) 6....

  • 走向DBA之存储引擎(1)

    一、存储引擎介绍: 二、功能了解: 三、存储引擎种类: 3.1Oracle的MySQL 3.2MySQL支持的其他...

  • MySQL-存储引擎

    如果您对数据库感兴趣,可以添加 DBA解决方案QQ群:855439640 1、简介 2、功能了解 3、存储引擎种类...

  • 老男孩-标杆班级-MySQL-lesson05-存储引擎

    如果您对数据库感兴趣,可以添加 DBA解决方案QQ群:855439640 1、简介 2、功能了解 3、存储引擎种类...

  • 「Mysql索引原理(一)」1.存储引擎简介

    存储引擎 0. 前言1. 存储引擎查看2. InnoDB存储引擎特性存储InnoDB历史3. MyISAM存储引擎...

  • MySQL数据库中存储引擎和数据类型

    一.什么是存储引擎 二.操作存储引擎 查看存储引擎 1.查看mysql支持的存储引擎 2.看你的mysql当前默认...

  • 58到家MySQL军规升级版

    转载 2018-03-30 58到家DBA 架构师之路 一、基础规范 1. 表存储引擎必须使用InnoDB 解读:...

  • 走向DBA之索引

    前言:如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车...

  • MySQL设计规范

    引言:想成为DBA吗?那就先看完今天这篇基础文章吧。 一、基础规范 1、表存储引擎必须使用InnoDB,至于原因,...

  • 07-存储引擎-01

    1.存储引擎介绍 相当于Linux 文件系统.组织存储表数据. 2.存储引擎的种类 查看存储引擎的种类 其他的存储...

网友评论

      本文标题:走向DBA之存储引擎(2)

      本文链接:https://www.haomeiwen.com/subject/ltpvqctx.html