InnoDB存储引擎核心特性说明
事务
行锁
MVCC
外键
ACSR自动故障恢复
热备
复制(多线程,GTID,MTS)
查看存储引擎
mysql> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| CSV | YES | CSV storage engine | NO | NO | NO |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.00 sec)
查看系统默认存储引擎
mysql> select @@default_storage_engine;
+--------------------------+
| @@default_storage_engine |
+--------------------------+
| InnoDB |
+--------------------------+
1 row in set (0.00 sec)
配置文件修改默认存储引擎
vim /etc/my.cnf
[mysqld]
default_storage_engine=InnoDB
修改存储引擎
alter table t1 engine=innodb;
整理碎片(只能innodb自动整理,但是会短暂锁表)
alter table t1 engine=innodb; 这个命令依旧可以整理碎片
批量替换zabbix 100多张表,innodb为tokudb
select concat("alter table",table_schema,".",table_name," engine=tokudb;") from information_schema.tables
where table_schema='zabbix';
innodb存储引擎物理存储结构
(/data/mysql/data)
ibdata1:系统数据字典信息(统计信息),undo表空间等数据
ib_logfile0~ib_logfie1: REDO日志文件,事务日志文件
ibtmp1: 临时表空间磁盘位置,存储临时表
frm:存储表的列信息
ibd:表的数据行和索引
共享表空间
5.5 版本默认模式(ibdata1会越来越大)
5.6独立表空间
查看默认表空间
mysql> select @@innodb_data_file_path;
+-------------------------+
| @@innodb_data_file_path |
+-------------------------+
| ibdata1:12M:autoextend |
+-------------------------+
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)
在搭建mysql时,初始化数据之前设置到参数文件中
innodb_data_file_path=ibdata1:512M:ibdata2:512M:autoextend
innodb_autoextend_increment=64
独立表空间
从5.6,默认表空间不再使用共享表空间,替换为独立表空间。
主要存储的是用户数据
存储特点为:一个表一个ibd文件,存储数据
一张innodb表 = frm+idb+ibdata1
mysql存储引擎日志:
redo log:ib_logfile0 ib_logfile1,重做日志
undo log: ibdata1 ibdata2(存储在共享表空间中),回滚日志
临时表:ibtmp1,在做join union操作产生临时数据,用完就自动
select @@innodb_file_per_table;
独立表空间迁移
1创建和原表结构一致的空表
2.将空表的ibd文件删除
alter table t100w discard tablespace;
3,将原表的ibd拷贝过来,并且修改权限
4.将原表ibd进行导入
alter table t100w import tablespace;
innodb核心特性
事务的ACID特性
Atomic(原子性)
所有语句作为一个单元全部成功执行或全部取消,不能出现中间状态
Consistent(一致性)
如果数据库在事务开始时处于一致状态,则在执行该事务期间将保留一致状态
Isolated(隔离性)
事务之间不互相影响
Durable(持久性)
事务成功完成后,所做的所有更改都会准确记录在数据库中,所做的更改不会丢失
事务的生命周期(事务控制语句)
1开启事务
begin;
2标准的事务语句(DML:insert update delete)
3事务的结束
提交
commit;
回滚
rollback;
自动提交机制(autocommit默认是打开的)
select @@autocommit;
在线修改参数:
1会话级别:set autocommit=0;
2全局级别:set global autocommit=0; (断开窗口重连生效)
3永久修改:[mysqld] autocommit=0 需要重启
隐式提交的情况
触发隐式提交语句:
begin
a
b
[这个地方会自动commit]
begin
set 命令
DDL语句 (alter,create 和drop)
DCL语句 (GRANT,REVOKE和set password)
锁定语句 (lock tables和unlock tables)
事务的ACID如何保证
一些概念名词
redo log:
重做日志 ib_logfile0~1 默认50M ,轮询使用
redo log buffer:
redo内存区域
ibd:
存储 数据行和索引
buffer pool:
缓冲区池,数据和索引的缓冲
LSN:日志序列号
ibd,redolog,buffer pool,redo buffer
MySQL每页数据库启动,都会比较磁盘数据页和redolog的LSN,必须要求两者LSN一致数据库才能启动
WAL:(持久化)
write ahead log 日志优先写的方式实现持久化
日志是优先与数据写入磁盘的
脏页:
内存脏页,内存中发生了修改,没写入到磁盘之前,我们把内存页称之为脏页
内存中修改的数据 没写入磁盘的状态 称为脏页
ckpt:
checkpoint 检查点,就是将脏页刷写到磁盘的动作
TXID:
事务号,innodb会为每一个事务生成一个事务号,伴随着整个事务
redo 事务日志(重做日志)
作用:主要功能 保证"D",持久性 AC也有一定作用
记录了什么?
记录了内存数据页的变化
感谢老男孩郭老师
1.记录了内存数据页的变化
2.提供快速的持久化功能(WAL)
3.CSR过程中实现前滚的操作(磁盘数据页和redo日志lsn号一致)
redo日志位置
iblogfile0 iblogfile1
redo buffer
redo的buffer:数据页的变化信息+数据页当时的LSN号
LSN:日志序列号 磁盘数据页 内存数据页 redo buffer redolog
redo的刷写策略
commit;
刷新当前事务的redo buffer到磁盘
还会顺便将一部分redo buffer中没有提交的事务日志也刷到磁盘
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原则
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,将内存数据页更新到磁盘,从而保证磁盘数据页和redologLSN一致,这时mysql正常启动
以上操作称为REDO“前滚”
undo
回滚日志
作用:在acid特性中,主要保证A的特性,同时对CI也有一定功效
1.记录了数据修改之前的状态
2.rollback 将内存的数据修改恢复到修改之前
3.在CSR中实现未提交数据的回滚操作
4.实现一致性快照,配合隔离界别保证MVCC,读和写的操作不会互相堵塞
redo
1.记录内存数据页变化日志
2.提供快速的事务的提交(commit)
3.CSR redo提供的前滚功能
undo
1.记录数据修改之前的状态
2.提供事务工作工程中回滚操作(rollback)
3.CSR中将未提交的事务进行回滚
锁
实现了事务之间的隔离功能,innodb中实现的是行级锁
row-level lock(默认50秒,然后回滚)
gap
next-lock
隔离级别
RU:读未提交,可脏读,幻读,不可重复读
RC:读已提交,可能出现幻读,可以防止脏读
RR:可重复读,功能是防止"幻读"现象,利用的是undo的快照技术+GAP(间隙锁)+NEXT-LOCK(下键锁)
SR :可串行化,可以减轻GAP+NEXT-LOCK锁的问题,但是会出现幻读现象,一般在为了读一致性会在正常select后添加for update语句,但是,请记住执行完一定要commit否则容易出现锁等待比较严重
查看
select @@tx_isolation;
修改
vi /etc/my.cnf
[mysqld]
transaction_isolation=read-uncommitted
transaction_isolation=read-committed
transaction_isolation=repeatable-read
RU 会出现脏读
RC 会出现不可重复读,也会出现幻读
RR 通过MVCC技术解决了不可重复读,但是有可能会出现幻读现象,可以通过GAP和next-lock进行避免
Innodb核心参数的介绍
存储引擎默认设置
default_storage_engine=innodb
表空间
设置共享表空间,还是独立表空间,默认1 独立表空间
innodb_file_per_table=1
共享表空间文件个数和大小
innodb_data_file_path=ibdata1:512M:ibddata2:512M:autoextend
双一标准的其中一个(从内存往磁盘刷写日志,redo buffer 写入到redolog)默认1,还有0,2
innodb_flush_log_at_trx_commit=1
innodb_flush_method=(o_DIRECT,fsync)
默认fsync
作用:控制的是redo buffer和 buffer pool
fsync:
o_direct: 建议使用
o_dsync
最安全的模式
innodb_flush_log_at_trx_commit=1
innodb_flush_method=o_direct
最高性能
innodb_flush_log_at_trx_commit=0
innodb_flush_metho=fsync
redo日志设置有关的
innodb_log_buffer_size=16777216 #redo buffer缓冲区大小
innodb_log_file_size=50331648 #默认50M 日志文件大小 字节
innodb_log_files_in_group=3 #redo日志个数
脏页刷写策略
innodb_max_dirty_pages_pct=75 #百分之75