mysql innodb引擎

mysql 5.5 版本以后,默认的引擎是innodb
percona默认是tokudb
mariadb默认是myrocks
特性:
1. 更高的压缩比。
2. 更快速的插入性能。

innodb核心特性

  • 聚簇索引
  • ahi 自适应hash索引
  • change buffer
  • 事务
  • mvcc 多版本并发控制
  • 行级锁
  • 外键
  • 复制特性
  • 支持热备
  • 自动故障恢复(acsr)
  • 双写机制

批量更改非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';

source /tmp/alter.sql;

查看默认存储引擎

select @@default_storage_engine;

修改表的存储引擎

alter table t1 engine innodb;
#因为经常更改数据,也用来碎片整理

物理存储结构

#独立表
city.frm       : 建表语句
city.ibd       : 表空间数据文件,存储数据行和索引、段、区、页

ibdata1        : 共享(系统)表空间文件
ib_logfilen    : redo log文件,重做日志,存储事务的前滚日志,内存数据页的变化
ibtmp1         : 临时表空间,存储sql处理过程中的中间数据(group by , having , join, union)
ib_buffer_pool : 内存预热文件

内存存储结构

innodb_buffer_pool 
介绍: 
	InnoDB最大的内存区域,官方建议最多可设置大小物理内存的80%。生产建议70%以下。
作用: 
	缓冲数据页、索引页、数据字典、AHI、change buffer 、DW
	数据页修改完成之后,会写入到磁盘表空间中。ibd frm  ibdata1文件。
参数: 
	mysql> select @@innodb_buffer_pool_size;#单位kb

innodb_log_buffer
介绍: 
	用来存储内存数据页的变化。数据修改完成之后,会将日志写入到磁盘日志文件中(ib_logfileN)。

参数: 
	mysql> select @@innodb_log_buffer_size;

表空间存储方式

介绍
在数据库引擎层,加入的逻辑的存储结构。来实现灵活的存储空间扩容。数据存放在表空间里,由表空间选择硬盘存储,解决了磁盘空间满的迁移问题。
mysql 5.5 版本引入了表空间存储管理模式。
表空间类型
– 共享表空间 :ibdata1~ibdatan
5.5 版本的默认模式。用来存储所有的系统数据+用户数据(数据行+索引)。
会造成单个文件过大的问题。
ibdata文件默认是一个,不够用了可以进行扩容。

– 独立表空间 :
5.6 版本+:
默认采用独立表空间模式。每张表都是独立的表空间(t1.ibd)。
共享表空间保留下来,只保存系统相关的数据。

5.7 和 8.0 版本中,将ibdata1进一步的瘦身。

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            : 存储事务的回滚信息日志。

查看表空间模式是独立还是共享

select @@innodb_file_per_table;
#1是独立表空间,0是共享表空间

迁移数据库

通过将新数据库数据指向的表空间更改为旧数据库表空间

  1. 锁表
lock tables t100w read;
  1. 查询建表语句,创建一模一样的表
  2. 删除空的表空间文件
alter table t100w discard tablespace;
  1. 复制表空间文件至数据目录
cp -rp /data/3306/data/test/t100w.ibd /data/3307/data/test/
  1. 刷新表空间
alter table t100w import tablespace;
  1. 解锁表
unlock tables ;

批量删除表空间

select concat('alter table ',table_schema,'.'table_name,' discard tablespace;') from information_schema.tables where table_schema='confluence' into outfile '/tmp/discad.sql';

批量刷新表空间

select concat('alter table ',table_schema,'.'table_name,' import tablespace;') from information_schema.tables where table_schema='confluence' into outfile '/tmp/import.sql';

跳过外键检查

set foreign_key_checks=0

日志存储时间

expire_logs_days=3

设置共享表空间大小

查询

select @@innodb_data_file_path;

初始化时在配置文件中设置

innodb_data_file_path=ibdata1:1024M;ibdata2:1024M;ibdata3:1024M:autoextend
#可随意设置大小,data1文件最大1024m,data2文件最大1024m,data3文件达到1024m自动扩容

初始化后设置

innodb_data_file_path=ibdata1:(当前文件)M;ibdata2:1024M;ibdata3:1024M:autoextend

设置临时表空间

innodb_temp_data_file_path=ibtmp1:12M;ibtmp2:128M:autoextend:max:500M
#最大500m

查看undo表空间

SELECT @@innodb_undo_tablespaces; #查看undo表个数
SELECT @@innodb_max_undo_log_size; #查看undo日志大小,默认1g
SELECT @@innodb_undo_log_truncate; #查看undo自动回收机制
SELECT @@innodb_purge_rseg_truncate_frequency; #查看检测是否自动回收次数

undo只能在初始化时设置

innodb_undo_tablespaces=3           
innodb_max_undo_log_size=128M
innodb_undo_log_truncate=ON
innodb_purge_rseg_truncate_frequency=32 #官方推荐

事务

atomicity, consistency, isolation, durability

A : 原子性
事务中的所有操作,都是一个完整的整体。要么全成功,要么全失败。不能出现中间状态。
C :一致性
事务发生 前 中 后,数据应当保证一致状态。数据不会受到任何的破坏。数据最终一致是事务的最终目的。
I :隔离性
多事务工作期间是互相不影响的。
D :持久性
事务工作完成(commit),数据保证永久不丢失。数据落盘。

事务的操作

begin;/start transaction;   --- 开启事务。
commit;                     --- 提交事务。
rollback;                   --- 回滚事务。

标准的事务语句:update,delete ,insert, select

开启自动触发事务

set global autocommit=0;

隐式提交

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 #查询并更新

隐式回滚

中间命令执行失败
会话关闭
数据库停止

保证ACID机制

  1. redo log
    重做日志。主要保证:ACID中的“D”的特性,对于AC也有相关辅助作用。
    执行一条完整的事务语句时,将数据页从磁盘中取出放入内存的buffer pool中,修改完成之后,不立刻写入磁盘,而是在log buffer里存放更改信息和LSN,log buffer实时写入磁盘ib_logfile中,此时如果数据库crash,buffer pool重新从日志里读取未完成更改的信息,叫做redo log

  2. LSN 日志序列号
    MySQL 每次数据库启动,都会比较ibdata和ib_logfile的LSN,必须要求两者LSN一致数据库才能正常启动,show engine innodb status\G查看lsn
    Log sequence number:当前系统最大的LSN号
    log flushed up to:当前已经写入redo日志文件的LSN
    pages flushed up to:已经将更改写入脏页的lsn号
    Last checkpoint at:就是系统最后一次刷新buffer pool脏中页数据到磁盘的checkpoint

  3. 脏页: Dirty pages
    内存脏页,内存中发生了修改,没写入到磁盘之前,我们把内存页称之为脏页.

  4. Checkpoint(CKPT)
    MySQL维护着检查点队列(checkpoint list),就是将脏页刷写到磁盘的动作,故障恢复时会实时写盘

  5. DB_TRX_ID:
    事务号,InnoDB会为每一个事务生成一个事务号,伴随着整个事务生命周期

  6. WAL日志优先写

undo ACSR故障恢复

针对未提交的事务语句
— undo 介绍
回滚日志。内容: 记录的是事务操作的逆向操作。
主要保证: ACID中的“A”的特性,实现rollbackup回滚的功能。也是MVCC特性的主要保障。所以对于C和I也有保证。
undo最多128个segments。96个在undo tablespace中,32个在temp tablespace。每个段默认1024槽位。

将要修改的数据页原数据放入undo slot中,根据DB_TRX_ID(事务编号6字节)+ DB_ROLL_PTR(数据行编号7字节),进行回滚

DoubleWrite

因为mysql中最小单位数据页是16k,linux block是4k,防止内存写盘时数据丢失(Page particularly fsync),内存数据会1m1m分两次的写入doublewrite(默认2m),由doublewrite写入磁盘

innodb_flush_log_at_trx_commit
主要控制了innodb将log buffer中的数据写入ib_logfile文件并flush磁盘的时间点

隔离级别+锁+MVCC

select @@transaction_isolation;
各种类型的隔离会造成的问题
	RU  : 读未提交。脏读、可重复读、幻读
	RC  :读已提交。可重复读、幻读
	RR  :可重复读。幻读(默认,因为有gap避免幻读,mvcc避免重复读)
	SR  :可串行化。

脏读:数据未提交,就读到了修改过的数据
不可重复读:因为另一个事务窗口已经提交了修改,在同一个事务窗口,做相同数据的读取,得到的是不同的值。
幻读:在事务更新过程中,出现了其他事务已提交数据幻行,造成数据更新有误。

mvcc

每次开启一个全新的事务窗口(begin),都会生成当前最新的一致性快照(undo),直到事务commit或者rollback
此次事务,都会在此快照中进行操作。
我们也把这种技术,称之为一致性快照读取(一致性非锁定读)。
可以大大提高事务的并发能力。

内存资源锁

Latch(闩锁): mutex,rw-lock
作用: 控制内存中的线程使用资源的一种锁。防止数据页被意外置换出去。
线程对于数据页修改:需要申请mutex #修改不可以多线程
线程对于数据页读取:需要申请rw-lock #读取可以多线程

server层锁

--- Matedata lock  :元数据锁 
触发条件: DDL操作

--- table lock     :表锁   
在InnoDB中,虽然锁粒度是行锁,也有可能触发表锁。
从行锁升级至表锁。ALL,Index执行计划时,会升级为表锁。

引擎层

record  lock      :记录锁       ----> 聚簇索引 #行锁,精确到id号,不会影响其他行
GAP     lock      :间隙锁       ----> 辅助索引范围
#update test set name='oldguo' where num<5;1 2 3 4 5 都会上锁,就算num里没有2,也不能插入2数据
Next    lock      :下一键锁     ----> record+GAP
mysql> select * from innodb_lock_waits\G #查看因为锁表需要等待的进程

总结

A:undo
C:MVCC
I:RR锁
D:redo

重要参数

InnoDB 重要参数
innodb_flush_log_at_trx_commit=0/1/2
作用:
	控制redo log 刷新磁盘策略
参数值介绍: 
	1: 默认值。每次事务提交刷写redo buffer 到os cache,立即fsync()到磁盘。
		能够真正保证ACID中的D的特性。双一标准之一。
	2: 每次commit,刷写redo buffer到OS cache,每秒钟fsync()到磁盘。服务器有保障时性能高
		如果是边缘业务或者离线业务可以使用。有一定风险,在服务器crash掉,有可能丢失1s事务。
	0: 每秒刷新redo buffer 到OS cache,然后fsync()到磁盘。

innodb_flush_method 刷盘方式
作用: 控制 buffer pool 和redo buffer 数据和日志刷写磁盘的方式

fsync    : 默认值。刷新数据页和redobuffer 到磁盘,都是先刷到os cache ,再fsync()到磁盘
O_DIRECT : 刷写数据页时,直接跨过OS Cache ,刷写到磁盘。redo buffer先刷到os cache ,再fsync()到磁盘
	        建议使用高IO能力的存储配合O_DIRECT.		

你可能感兴趣的:(mysql innodb引擎)