MySQL-lesson05-存储引擎

1、存储引擎种类

Innodb、Myisam、Memory
还可以使用第三方存储引擎
TokuDB --------> zabibx常用的引擎 :插入数据比Innodb块2-3倍,压缩比是Innodb的8-10倍
myrocks 监控系统常用的引擎
插件类存储引擎,是在表级别设定的

2、InnoDB与Myisam的区别

image.png

3、查看存储引擎

show engines;
show create table city;
select @@default_storage_engine;   //查看默认的存储引擎
show table status like 'city'\G      //查看表的存储引擎

//把数据库里所有innodb的表都打印出来
[world]>select table_schema,table_name ,engine from information_schema.tables where engine='innodb';

设置引擎

# 会话级别:
set default_storage_engine=myisam;
# 全局级别(仅影响新会话):
set global default_storage_engine=myisam;
重启之后,所有参数均失效.

# 如果要永久生效,写入配置文件
vim /etc/my.cnf
[mysqld]
default_storage_engine=myisam
存储引擎是表级别的,每个表创建时可以指定不同的存储引擎,但是我们建议统一为innodb.

# 修改一个表的存储引擎
db01 [oldboy]>alter table t1 engine innodb;
注意:此命令我们经常使用,进行innodb表的碎片整理

# 批量修改存储引擎
# 需求:将zabbix库中的所有表,innodb替换为tokudb
select concat("alter table zabbix.",table_name," engine tokudb;") from
information_schema.tables where table_schema='zabbix' into outfile '/tmp/tokudb.sql';

平常处理的MySQL问题-碎片处理:

环境:centos7.4,MySQL 5.7.20,InnoDB存储引擎
业务特点:数据量级较大,经常需要按月删除历史数据.
问题:磁盘空间占用很大,不释放
处理方法:
以前:将数据逻辑导出,手工drop表,然后导入进去
现在:
对表进行按月进行分表(partition,中间件)
业务替换为truncate方式

4、InnoDB存储引擎物理存储的方式

5.5默认是共享表空间
5.6以后默认独立表空间,但是共享表空间也存在

表空间(TBS)的管理模式:

  • 共享表空间:ibdata1、ibdata2
    存储内容:系统数据、undo日志、磁盘临时表

  • 独立表空间:每个表单独使用表空间
    存储内容:
    t1.ibd------>单独表的数据和索引
    t1.frm------>t1表的列相关信息

5、表空间操作

共享表空间:我们建议在初始化数据的时候就配置好
一般建议2-3个,512M
vim /etc/my.cnf
[mysqld]
innodb_data_file_path=ibdata1:512M;ibdata2:512M:autoextend //查看data目录ibdata1大小,配置ibdata1要按照真实大小设置,第一个表空间无法扩展
mysql_install_db //初始化时使用

独立表空间:
show variables like 'innodb_file_per_table';
alter table t1 discard tablesapce; 将表的ibd文件删掉
alter table t1 import tablesapce; 将ibd文件导入数据库
将原表ibd文件删除,将新的ibd文件拷贝到独立表空间,拷贝后改权限;将ibd文件导入数据库。
set foreign_key_checks=0 跳过外键检查

6、事务

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

事务的ACID特性

Atomic(原子性)
所有语句作为一个单元全部成功执行或全部取消。不能出现中间状态。

Consistent(一致性)
如果数据库在事务开始时处于一致状态,则在执行该事务期间将保留一致状态。

Isolated(隔离性)
事务之间不相互影响。

Durable(持久性)
事务成功完成后,所做的所有更改都会准确地记录在数据库中。所做的更改不会丢失。

7、事务控制语句

  • 事务正常生命周期
    begin; 开启事务
    DML
    ···
    commit; 结束事务

  • 事务不正常生命周期
    begin; 开启事务
    DML
    ···
    rollback; 回滚

mysql 5.5版本后,begin不用手敲,自动开启;commit要手动提交。

自动提交
select @@autocommit; //查看自动提交状态
autocommit=1 默认开启;
我们手动关闭自动提交:
set autocommit=0;
set global autocommit=0;

永久关闭:
vim /etc/my.cnf
autocommit=0

隐式提交

用于隐式提交的 SQL 语句:
START TRANSACTION
SET AUTOCOMMIT = 1

导致提交的非事务语句:
DDL语句: (ALTER、CREATE 和 DROP)
DCL语句: (GRANT、REVOKE 和 SET PASSWORD)
锁定语句:(LOCK TABLES 和 UNLOCK TABLES)

导致隐式提交的语句示例:
TRUNCATE TABLE
LOAD DATA INFILE
SELECT FOR UPDATE

8、InnoDB 存储引擎物理存储层

表空间(t1.ibd)------>
段 一个表就是一个段(除了分区表)
区 连续的多个页
页 page(16k)

存储引日志
redo:重做日志
磁盘区域:ib_logfile0、ib_logfile1
存储位置:/data目录下,默认两个日志,默认大小式48M;
使用方式:轮询覆盖

由两个参数控制,可设定redo日志大小和个数
innodb_log_file_size=50331648
innodb_log_files_in_group=2

  • redo记录的是什么?
    内存数据页的变化

undo:回滚日志
磁盘区域:ibdata1、ibdata2
存储位置:/data目录下,在共享表空间文件

  • undo记录了什么?
    数据页修改之前的状态

txid 事务ID
LSN 日志版本号

CSR过程

当执行sql语句的时候表文件导入内存页(只导入要改的那一页数据),并做快照形成undo内存(原数据,包括事务ID,日志版本号),undo内存实时写入磁盘undo日志文件;然后表文件内存页根据SQL语句更改,将更改过程记录到redo内存(更新事务ID和日志版本号),redo内存写入磁盘redo日志文件。
1、执行commit,写入redo断电
2、没有执行commit,但是写入redo断电
3、没有执行commit,没有写入redo断电

第一种情况:原数据、redo日志、undo日志导入内存,redo内存记录的更改过程与原数据进行数据重做得到数据;原数据与undo内存数据对比,查看commit标签,如果有标签,重做数据写入磁盘表文件;
第二种情况:原数据、redo日志、undo日志导入内存,redo内存记录的更改过程与原数据进行数据重做得到数据;原数据与undo内存对比,查看commit标签,没有标签,则会数据前滚,把undo内存数据写入磁盘表文件;
第三种情况:原数据、redo日志、undo日志导入内存,redo内存没有更改过程数据;原数据与undo内存数据对比,也没有commit标签,则将undo内存数据写入磁盘表文件;

1)什么是“锁”?
“锁”顾名思义就是锁定的意思。

2)“锁”的作用是什么?
在事务ACID特性过程中,“锁”和“隔离级别”一起来实现“I”隔离性的作用。

排他锁:保证在多事务操作时,数据的一致性。
共享锁:保证在多事务工作期间,数据查询时不会被阻塞。

12.多版本并发控制(MVCC)
1)只阻塞修改类操作,不阻塞查询类操作
2)乐观锁的机制(谁先提交谁为准)

13.锁的粒度
MyIsam:低并发锁(表级锁)
Innodb:高并发锁(行级锁)

四种隔离级别:

影响到数据的读取,默认的级别是 RR模式.
transaction_isolation 隔离级别(参数)
负责的是,MVCC,读一致性问题
RU : 未提交读,可脏读,一般部议叙出现
RC : 已提交读,可能出现幻读,可以防止脏读.
RR : 可重复读,前提时表中有索引,功能是防止"幻读"现象 ,利用的是undo的快照技术+GAP(间隙锁)+NextLock(下键锁)
SR : 可串行化,可以防止死锁,但是并发事务性能较差
补充: 在RC级别下,可以减轻GAP+NextLock锁的问题,但是会出现幻读现象,一般在为了读一致性会在正常select后添加for update语句.但是,请记住执行完一定要commit 否则容易出现所等待比较严重.
例如:
[world]>select * from city where id=999 for update;
[world]>commit;

你可能感兴趣的:(MySQL-lesson05-存储引擎)