mysql 5.5 版本以后,默认的引擎是innodb
percona默认是tokudb
mariadb默认是myrocks
特性:
1. 更高的压缩比。
2. 更快速的插入性能。
批量更改非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是共享表空间
通过将新数据库数据指向的表空间更改为旧数据库表空间
lock tables t100w read;
alter table t100w discard tablespace;
cp -rp /data/3306/data/test/t100w.ibd /data/3307/data/test/
alter table t100w import tablespace;
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 #查询并更新
中间命令执行失败
会话关闭
数据库停止
redo log
重做日志。主要保证:ACID中的“D”的特性,对于AC也有相关辅助作用。
执行一条完整的事务语句时,将数据页从磁盘中取出放入内存的buffer pool中,修改完成之后,不立刻写入磁盘,而是在log buffer里存放更改信息和LSN,log buffer实时写入磁盘ib_logfile中,此时如果数据库crash,buffer pool重新从日志里读取未完成更改的信息,叫做redo log
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
脏页: Dirty pages
内存脏页,内存中发生了修改,没写入到磁盘之前,我们把内存页称之为脏页.
Checkpoint(CKPT)
MySQL维护着检查点队列(checkpoint list),就是将脏页刷写到磁盘的动作,故障恢复时会实时写盘
DB_TRX_ID:
事务号,InnoDB会为每一个事务生成一个事务号,伴随着整个事务生命周期
WAL日志优先写
针对未提交的事务语句
— 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字节),进行回滚
因为mysql中最小单位数据页是16k,linux block是4k,防止内存写盘时数据丢失(Page particularly fsync),内存数据会1m1m分两次的写入doublewrite(默认2m),由doublewrite写入磁盘
innodb_flush_log_at_trx_commit
主要控制了innodb将log buffer中的数据写入ib_logfile文件并flush磁盘的时间点
select @@transaction_isolation;
各种类型的隔离会造成的问题
RU : 读未提交。脏读、可重复读、幻读
RC :读已提交。可重复读、幻读
RR :可重复读。幻读(默认,因为有gap避免幻读,mvcc避免重复读)
SR :可串行化。
脏读:数据未提交,就读到了修改过的数据
不可重复读:因为另一个事务窗口已经提交了修改,在同一个事务窗口,做相同数据的读取,得到的是不同的值。
幻读:在事务更新过程中,出现了其他事务已提交数据幻行,造成数据更新有误。
每次开启一个全新的事务窗口(begin),都会生成当前最新的一致性快照(undo),直到事务commit或者rollback
此次事务,都会在此快照中进行操作。
我们也把这种技术,称之为一致性快照读取(一致性非锁定读)。
可以大大提高事务的并发能力。
Latch(闩锁): mutex,rw-lock
作用: 控制内存中的线程使用资源的一种锁。防止数据页被意外置换出去。
线程对于数据页修改:需要申请mutex #修改不可以多线程
线程对于数据页读取:需要申请rw-lock #读取可以多线程
--- 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.