“这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战”
1. 简介
相当于 Linux 文件系统,只不过比文件系统强大
2. 功能了解
- 数据读写
- 数据安全与一致性
- 提高性能
- 热备份
- 自动故障恢复
- 高可用方面支持等
3. 存储引擎介绍
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.01 sec)
默认的存储引擎是:InnoDB
下一代存储引擎:RocksDB、MyRocks、TokuDB 原因:压缩比较高,数据的插入性能高,其他功能和 InnoDB 没差。
4. InnoDB 核心特性说明
- 事务(Transaction)
- MVCC(Multi-Version Cocurrency Control,多版本并发控制)
- 外键
- ACSR(Auto Crash Safey Recovery)自动的故障安全恢复
- 行级锁(Row-level Lock)
- 支持热备份(Hot Backup)
- 复制(多线程,GTID,MTS)
5. 存储引擎的查看
5.1 查看存储引擎设置
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.02 sec)
5.2 查看表存储引擎状态
mysql> show create table student;
+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| student | CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '学号',
`sname` varchar(64) NOT NULL COMMENT '姓名',
`age` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '年龄',
`sex` char(4) NOT NULL COMMENT '性别',
`intime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '入学时间',
PRIMARY KEY (`id`),
KEY `idx_name` (`sname`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 |
+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
6. 存储引擎的修改
6.1 修改存储引擎
mysql> alter table student engine=innodb;
Query OK, 4 rows affected (0.06 sec)
Records: 4 Duplicates: 0 Warnings: 0
6.2 整理碎片
mysql> alter table student engine=innodb;
Query OK, 0 rows affected (0.08 sec)
Records: 0 Duplicates: 0 Warnings: 0
注意:只有 InnoDB 可以
可以用来定期碎片整理。
7. InnoDB 存储引擎物理存储结构
7.1 最直观的存储方式(/data/mysql/data)
- ibdata1:系统数据字典信息(统计信息),undo 表空间等数据(5.6版本,共享表空间保留,只用来存储:数据字典信息,undo,临时表;5.7 版本,临时表被独立出来了;8.0 版本,undo 也被独立出去了)
- ib_logfile0、ib_logfile1:redo 日志文件,事务日志文件
- ibtmp1:临时表空间磁盘位置,存储临时表
- frm:存储表的列信息
- ibd:表的数据行和索引
7.2 表空间(Tablespace)
7.2.1 表空间数据问题
- ibdata1:整个库的统计信息 + undo
- ibd:数据行和索引
5.5 共享表空间 =》 5.6 独立表空间
7.2.2 共享表空间(ibdata1 ~ N)
5.5 版本默认模式,5.6 中转换为了独立表空间 需要将所有数据存储到同一个表空间中,管理比较混乱
是 5.5 版本出现的管理模式,也是默认的管理模式 5.6 版本共享表空间被保留,只是用来存储:数据字典信息、undo、临时表 5.7 版本 临时表被独立出来了 8.0 版本,undo 也被独立出来了
具体变化参考官方文档:
dev.mysql.com/doc/refman/… dev.mysql.com/doc/refman/… dev.mysql.com/doc/refman/…
共享表空间设置(在搭建 MySQL 时,初始化数据之前设置到参数文件中)
查看共享表空间设置:
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)
该配置文件的含义是:
- 共享表空间的名称是 ibdata1;
- 分配的空间大小是 12M;
- 如果空间大小不够的话,autoextend,自动扩容;
- 每次扩容的大小是 64M
我们可以在初始化配置文件时,就制定共享表空间大小
mysqld --initialize-insecure xxxxxxxxx innodb_data_file_path=ibdata1:512M:ibdata2:512M:autoextend innodb_autoextend_increment=64
指定两个配置文件 ibdata1,ibdata2,每个大小 512M,用完 ibdata1 则用 ibdata2,两个都用完了,再自动扩容。
7.2.3 独立表空间
从 5.6 开始,默认表空间不再使用共享表空间,替换为独立表空间
主要存储的是用户数据。
存储特点为:一个表为一个 ibd 文件,存储数据行和索引信息
结论:一个数据表=ibd+frm+ibdata1
Redo Log:ib_logfile0、ib_logfile1,重做日志 Undo Log:ibdata1、ibdata2(存储在共享表空间中),存储回滚日志 临时表:ibtmp1,在做 join、union 操作时产生临时数据,用完自动清除
mysql> select @@innodb_file_per_table;
+-------------------------+
| @@innodb_file_per_table |
+-------------------------+
| 1 |
+-------------------------+
1 row in set (0.00 sec)
1 表示开启了独立表空间。
表空间模式的切换只会影响后续的表,之前的表不会受到影响。
7.2.4 独立表空间迁移
直接迁移 .rfm 文件和 .ibd 文件是不可以的,因为表的元数据信息还在 ibdata1 文件中,缺少这个信息,就没办法看这个表了。因此,我们需要一个一模一样的元数据,那么怎么样才能有一模一样的元数据呢,我们把最开始的建表语句拿过来就可以了。
首先,我们在 3306 库上有个 student 表,我想给他迁移到多实例 3307 库下。
我们把文件复制过去:
# cp /data/mysql/data/account/student.* /data/3307/data/account/
# cd /data/3307/data/account/
# chown mysql.mysql student.*
我们再去 3307 库上查看这个表:
Database changed
mysql> show tables;
+-------------------+
| Tables_in_account |
+-------------------+
| student |
+-------------------+
1 row in set (0.00 sec)
发现是可以查看到的。那么我们再用 desc 命令执行一下。
mysql> desc student;
ERROR 1146 (42S02): Table 'account.student' doesn't exist
发现这个命令是不可以执行的,为什么呢,是因为 desc 命令查看这个表的元数据信息了,虽然我们有 .frm 文件,但是数据字典和 .frm 文件不一样,.frm 文件只是这个表的结构信息,但是 desc 命令是使用系统的配置文件。
虽然我们能看到这个表名,但是看不了列信息,也看不了数据信息。
那缺什么呢,其实是缺少 iddata1 里面的统计信息。
元数据怎么来的呢?元数据不能直接进行增删改查,只能通过专用的命令来生成,只能通过专用的命令来查。
那我们怎么生成呢?我们只能把它创建出来了。我们找到最开始的建表语句。
我们先把这两个文件删了
# mv /data/3307/data/account/student.* /tmp/
我们去查看一下建表语句
mysql> show create table student;
+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| student | CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '学号',
`sname` varchar(64) NOT NULL COMMENT '姓名',
`age` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '年龄',
`sex` char(4) NOT NULL COMMENT '性别',
`intime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '入学时间',
PRIMARY KEY (`id`),
KEY `idx_name` (`sname`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 |
+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
我们再去 3307 库中创建一下:
mysql> CREATE TABLE `student` (
-> `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '学号',
-> `sname` varchar(64) NOT NULL COMMENT '姓名',
-> `age` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '年龄',
-> `sex` char(4) NOT NULL COMMENT '性别',
-> `intime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '入学时间',
-> PRIMARY KEY (`id`),
-> KEY `idx_name` (`sname`)
-> ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;
ERROR 1146 (42S02): Table 'account.student' doesn't exist
好像不可以,我们把数据库删一下:
mysql> drop database account;
Query OK, 0 rows affected (0.01 sec)
mysql> create database account;
Query OK, 1 row affected (0.00 sec)
mysql> use account;
Database changed
CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '学号',
`sname` varchar(64) NOT NULL COMMENT '姓名',
`age` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '年龄',
`sex` char(4) NOT NULL COMMENT '性别',
`intime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '入学时间',
PRIMARY KEY (`id`),
KEY `idx_name` (`sname`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;
ERROR 1146 (42S02): Table 'account.student' doesn't exist
再创建还是不可以。
我们试着修改一下名字:
CREATE TABLE `student1` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '学号',
`sname` varchar(64) NOT NULL COMMENT '姓名',
`age` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '年龄',
`sex` char(4) NOT NULL COMMENT '性别',
`intime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '入学时间',
PRIMARY KEY (`id`),
KEY `idx_name` (`sname`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;
Query OK, 0 rows affected (0.09 sec)
结果创建成功了。
我们将 .ibd 文件再复制过去,.rfm 文件就不需要了,因为已经有了。
之前的数据库表文件:
-rw-r----- 1 mysql mysql 60 1月 23 22:36 db.opt
-rw-r----- 1 mysql mysql 8714 1月 27 21:46 student.frm
-rw-r----- 1 mysql mysql 114688 1月 27 21:46 student.ibd
新创建的数据库表文件:
-rw-r----- 1 mysql mysql 65 1月 28 13:45 db.opt
-rw-r----- 1 mysql mysql 8714 1月 28 13:46 student1.frm
-rw-r----- 1 mysql mysql 114688 1月 28 13:46 student1.ibd
我们把 .ibd 文件复制过去
# cp /data/mysql/data/account/student.ibd /data/3307/data/account/
# chown mysql.mysql /data/3307/data/account/student.ibd
原来有一个 student1.ibd 文件,但是我们不能直接覆盖,也不能直接 rm,那么我么怎么处理呢,我们得需要使用数据库命令:
mysql> alter table student1 discard tablespace;
Query OK, 0 rows affected (0.09 sec)
然后,我们查看一下文件,发现 student1.ibd 文件没有了。
-rw-r----- 1 mysql mysql 65 1月 28 13:45 db.opt
-rw-r----- 1 mysql mysql 8714 1月 28 13:46 student1.frm
-rw-r----- 1 mysql mysql 114688 1月 28 13:50 student.ibd
我们再把 student.ibd 文件给复制过去
# mv student.ibd student1.ibd
那么我们现在可以查看数据了吗?我们试一下
mysql> select * from student1;
ERROR 1814 (HY000): Tablespace has been discarded for table 'student1'
我们得再加上 tablespace,把 .ibd 文件导入进去
mysql> alter table student1 import tablespace;
Query OK, 0 rows affected, 1 warning (0.07 sec)
我们再来查看一下:
mysql> select * from student1;
+----+--------+-----+-----+---------------------+
| id | sname | age | sex | intime |
+----+--------+-----+-----+---------------------+
| 1 | 关羽 | 20 | m | 2021-01-24 20:21:50 |
| 2 | 刘备 | 21 | m | 2021-01-24 20:23:23 |
| 3 | 赵云 | 22 | m | 2021-01-24 20:24:38 |
| 4 | 黄忠 | 23 | m | 2021-01-24 20:24:38 |
+----+--------+-----+-----+---------------------+
4 rows in set (0.00 sec)
总结
- 创建和原表结构一致的空表
- 将空表的 ibd 文件删除:
alter table table_name discard tablespace; - 将原表的 ibd 拷贝过来,并且修改权限;
- 将原表 ibd 进行导入:
alter table table_name import tablespaces;
作用:可以用于数据备份、复制等。
8. InnoDB 核心特性
8.1 事务
8.1.1 事务的 ACID 特性
-
Atomic(原子性)
- 所有语句作为一个单元全部成功执行或全部取消,不能出现中间状态。
-
Consistent(一致性)
- 如果数据库在事务开始时处于一致状态,则在执行该事务期间将保留一致状态。
-
Isolated(隔离性)
- 事务之间不相互影响。
-
Durable(持久性)
- 事务成功完成后,所做的所有更改都会准确地记录在数据库中。所做的更改不会丢失。
8.1.2 事务的生命周期(标准的事务控制语句)
-
如何开启事务
begin;
-
标准的事务语句
- DML
- insert
- update
- delete
- DML
-
事务的结束
- 提交:
commit; - 回滚:
rollback;(注意回滚只能回滚未提交的)
- 提交:
8.1.3 自动提交机制(autocommit)
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 1 |
+--------------+
1 row in set (0.00 sec)
只要执行了 DML 语句,MySQL 就会自动开始 begin,自动提交。
在线修改参数:
set autocommit=0;会话级别修改,只影响当前会话,即时生效
mysql> set autocommit=0;
Query OK, 0 rows affected (0.01 sec)
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 0 |
+--------------+
1 row in set (0.00 sec)
我们在另一个会话,查看一下:
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 1 |
+--------------+
1 row in set (0.00 sec)
我们把会话断开再重连查看一下:
mysql> exit
Bye
[root@VM-0-3-centos account]# mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 146
Server version: 5.7.26 MySQL Community Server (GPL)
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 1 |
+--------------+
1 row in set (0.00 sec)
set global autocommit=0;全局级别修改,断开窗口重连后生效。影响所有新开的窗口
mysql> set global autocommit=0;
Query OK, 0 rows affected (0.00 sec)
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 0 |
+--------------+
1 row in set (0.00 sec)
我们去另一个还没断开的窗口查看一下:
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 1 |
+--------------+
1 row in set (0.00 sec)
我们把窗口断开再重连一下,再查看一下:
mysql> exit
Bye
[root@VM-0-3-centos ~]# mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 143
Server version: 5.7.26 MySQL Community Server (GPL)
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 0 |
+--------------+
1 row in set (0.00 sec)
- 修改配置文件,永久生效。需要重启
vim /etc/my.cnf
autocommit=0
8.1.4 隐式提交的情况
触发隐式提交的语句:
begin
a
b
(commit) 隐式提交
begin / set 命令
其他导致提交的非事务语句:
- DDL 语句:alter、create、drop
- DCL 语句:grant、revoke、set password
- 锁定语句:lock tables、unlock tables
导致隐式提交的语句示例:
- truncate table
- load data infile
- select for update
8.2 事务的 ACID 如何保证》
8.2.1 一些概念名词
-
redo log:
- 重做日志,ib_logfile0~1,50M 大小,轮询使用
-
redo log buffer:
- redo 内存区域
-
ibd:
- 存储数据行和索引
-
buffer pool:
- data buffer pool,缓冲区池,数据和索引的缓冲
-
LSN:
- 日志序列号。
- 存储在磁盘数据页、redo 文件、buffer pool、redo buffer。
- MySQL 每次数据库启动,都会比较磁盘数据页和 redolog 的 LSN,必须要求两者 LSN 一致数据库才能正常启动
-
WAL:
- write ahead log。日志优先写的方式实现持久化
- 日志是优先于数据写入磁盘的
-
脏页:
- 内存脏页,内存中发生了修改,没写入到磁盘之前,我们把内存页称之为脏页。
-
CKPT:
- checkpoint,检查点,就是将脏页刷写到磁盘的动作
-
TXID:
- 事务号,InnoDB 会为每一个事务生成一个事务号,伴随着整个事务
8.2.2 事务日志 —— redo
作用:
- 主要功能:保证 “D”,AC 也有一定的作用
记录了什么?
- 记录了内存数据页的变化。
- 提供快速的持久化功能(WAL)
- CSR 过程中实现前滚的操作(磁盘数据页和 redo 日志 LSN 一直)
redo 日志位置
redo 的日志文件:ib_logfile0、ib_logfile1
redo buffer
redo 的 buffer:数据页的变化信息 + 数据页当时的 LSN 号
redo 的刷写策略
commit; 刷新当前事务的 redo buffer 到磁盘 还会顺便将一部分 redo buffer 中没有提交的事务日志也刷新到磁盘
MySQL:在启动时,必须抱枕 redo 日志文件和数据文件 LSN 必须一致,如果不一致就会触发 CSR,最终保证一致。
MySQL CSR —— 前滚
MySQL:在启动时,必须保证 redo 日志文件和数据文件 LSN 必须一致,如果不一致就会触发 CSR,最终保证一致
情况一:
我们做了一个事务:begin; update; commit.
- 在 begin ,会立即分配一个 TXID=tx_01.
- update 时,会将需要修改的数据页(dp_01,LSN=101),加载到 data buffer 中
- DBWR 线程,会进行 dp_01 数据页修改更新,并更新 LSN=102
- LOGBWR 日志写线程,会将 dp_01 数据页的变化 +LSN+TXID 存储到 redobuffer
- 执行 commit 时,LGWR 日志写线程会将 redobuffer 信息写入 redolog 日志文件中,基于 WAL 原则,在日志完全写入磁盘后,commit 命令才执行成功,(会将此日志打上 commit 标记)
- 假如此时宕机,内存脏页没有来得及写入磁盘,内存数据全部丢失
- 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 的"前滚操作"
8.2.3 undo —— 回滚日志
作用
在 ACID 特性中,主要保证 A 的特性,同时对 CI 也有一定功效
记录了什么
- 记录了数据修改之前的状态;
- rollback 时将内存的数据修改恢复到修改之前
- 在 CSR 中实现未提交数据的回滚操作
- 实现一致性快照,配合锁机制,保证 MVCC,读和写的操作不会互相阻塞
8.2.4 锁
实现了事务之间的隔离功能。
InnoDB 中实现的行锁(row-level lock)
gap
next-lock
8.2.5 隔离级别
- RU:读未提交,可脏读
- RC:读已提交,可能出现幻读,可以防止脏读
- RR:可重复度,功能是防止“幻读”现象,利用的是 undo 的快照技术 + GAP(间隙锁)+ NextLock(下键锁)
- SR:可串行化,可以防止死锁,但是并发事务性能较差
MVCC ------> undo 快照
- RU 会出现脏读
- RC 会出现不可重复读
- RR 通过 MVCC 基础解决了不可重复读,但是有可能会出现幻读现象,可以通过 GAP + NextLock 进行避免。
MySQL 查看当前隔离级别:
mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set, 1 warning (0.00 sec)
在 RR 模式下,通过 GAP 和 Next-lock 避免幻读现象,必须索引支持。
8.2.6 InnoDB 核心参数
- 存储引擎默认设置:
default_storage_engine=innodb
- 表空间模式:
innodb_file_per_table=1
- 共享表空间文件个数和大小
innodb_data_file_path=ibdata1:512M:ibdata2:512M:autoextend
- "双一"表中的其中一个
innodb_flush_log_at_trx_commit=1
- 日志刷新方法
innodb_flush_method=(O_DERECT, fsync)
默认是 fsync,建议是 O_DERECT
fsync 模式:
O_DIRECT 模式:
O_DSYNC
最高安全模式
innodb_flush_log_at_trx_commit=1
innodb_flush_method=O_DERECT
最高性能模式
innodb_flush_log_at_trx_commit=0
innodb_flush_method=fsync
- redo 日志大小
innodb_log_buffer_size=16777216
innodb_log_file_size=50331648
innodb_log_file_in_group=3
- 脏页刷写策略
innodb_max_dirty_pages_pct=75
还有哪些机制会触发写磁盘?
- CSR
- redo 空间满了的时候