MySQL--存储引擎

1. 存储引擎

1.1 存储引擎相关的命令

查看MySQL提供的所有存储引擎

show engines;
  • MySQL当前默认的存储引擎是InnoDB

  • 在5.7版本所有的存储引擎中只有InnoDB支持事务

查看MySQL当前默认的存储引擎

show variables like `%storage_engine%`;

查看表的存储引擎

show table status like `table_name`;

1.2 MyISAM 和 InnoDB的区别

MySQL 5.5 之前,MyISAM 引擎是 MySQL 的默认存储引擎,可谓是风光一时。虽然,MyISAM 的性能还行,各种特性也还不错(比如全文索引、压缩、空间函数等)。但是,MyISAM 不支持事务和行级锁,而且最大的缺陷就是崩溃后无法安全恢复。5.5 版本之后,MySQL 引入了 InnoDB(事务性数据库引擎),MySQL 5.5 版本后默认的存储引擎为 InnoDB。小伙子,一定要记好这个 InnoDB ,你每次使用 MySQL 数据库都是用的这个存储引擎吧?

1. 是否支持行级锁?

​ MyISAM只支持表级锁(table-level locking),而InnoDB支持行级锁(row-level locking)和表级锁,默认为行级锁,因此在并发写时,InnoDB的性能会更好。

2. 是否支持事务?

​ MyISAM不支持事务,而InnoDB提供事务支持,具有提交(commit)和回滚(rollback)事务的能力。

3. 是否支持外键?

​ MyISAM不支持外键,而InnoDB支持外键

​ 🌈 拓展:一般我们也是不建议在数据库层面使用外键的,应用层面可以解决。不过,这样会对数据的一致性造成威胁。具体要不要使用外键还是要根据你的项目来决定。

4. 是否支持数据库异常崩溃后的安全恢复?

​ MyISAM不支持,而InnoDB支持,使用InnoDB的数据库异常崩溃后能够通过redo log将数据库恢复到崩溃前的状态。

​ 🌈 拓展:

  • MySQL InnoDB 引擎使用 redo log(重做日志) 保证事务的持久性,使用 undo log(回滚日志) 来保证事务的原子性
  • MySQL InnoDB 引擎通过 锁机制MVCC 等手段来保证事务的隔离性( 默认支持的隔离级别是 REPEATABLE-READ )。
  • 保证了事务的持久性、原子性、隔离性之后,一致性才能得到保障。

5. 是否支持MVCC?

​ MyISAM 不支持,而 InnoDB 支持。

​ MyISAM 连行级锁都不支持,而MVCC 可以看作是行级锁的一个升级,可以有效减少加锁操作,提供性能。

1.4 关于 MyISAM 和 InnoDB 的选择问题(非重点)

​ 大多数时候我们使用的都是 InnoDB 存储引擎,但是某些情况下你并不在乎可扩展能力和并发能力,也不需要事务支持,也不在乎崩溃后的安全恢复问题的话,选择 MyISAM 也是一个不错的选择。但是一般情况下,我们都是需要考虑到这些问题的。

1. 5 锁机制与InnoDB算法

MyISAM 和 InnoDB 存储引擎使用的锁:

  • MyISAM 采用表级锁(table-level locking)。
  • InnoDB 支持行级锁(row-level locking)和表级锁,默认为行级锁。

表级锁和行级锁对比:

  • 表级锁: MySQL 中锁定 粒度最大 的一种锁,对当前操作的整张表加锁,实现简单,资源消耗也比较少,加锁快,不会出现死锁。其锁定粒度最大,触发锁冲突的概率最高,并发度最低,MyISAM 和 InnoDB 引擎都支持表级锁。
  • 行级锁: MySQL 中锁定 粒度最小 的一种锁,只针对当前操作的行进行加锁。 行级锁能大大减少数据库操作的冲突。其加锁粒度最小,并发度高,但加锁的开销也最大,加锁慢,会出现死锁。

INNODB的2种标准行级锁:

  • 共享锁:共享锁又叫做读锁,所有的事务只能对其进行读操作不能写操作,加上共享锁后在事务结束之前其他事务只能再加共享锁,除此之外其他任何类型的锁都不能再加了。
  • 排他锁:若某个事务对某一行加上了排他锁,只能这个事务对其进行读写,在此事务结束之前,其他事务不能对其进行加任何锁,其他进程可以读取,不能进行写操作,需等待其释放。

InnoDB 存储引擎的锁的算法有三种:

  • Record lock:单个行记录上的锁
  • Gap lock:间隙锁,锁定一个范围,不包括记录本身
  • Next-key lock:record+gap 锁定一个范围,包含记录本身

1.6 查询缓存

执行查询语句的时候,会先查询缓存。不过,MySQL 8.0 版本后移除,因为这个功能不太实用

my.cnf 加入以下配置,重启 MySQL 开启查询缓存

query_cache_type=1
query_cache_size=600000 

MySQL 执行以下命令也可以开启查询缓存

set global  query_cache_type=1;
set global  query_cache_size=600000;

如上,开启查询缓存后在同样的查询条件以及数据情况下,会直接在缓存中返回结果。这里的查询条件包括查询本身、当前要查询的数据库、客户端协议版本号等一些可能影响结果的信息。因此任何两个查询在任何字符上的不同都会导致缓存不命中。此外,如果查询中包含任何用户自定义函数、存储函数、用户变量、临时表、MySQL 库中的系统表,其查询结果也不会被缓存。

缓存建立之后,MySQL 的查询缓存系统会跟踪查询中涉及的每张表,如果这些表(数据或结构)发生变化,那么和这张表相关的所有缓存数据都将失效。

缓存虽然能够提升数据库的查询性能,但是缓存同时也带来了额外的开销,每次查询后都要做一次缓存操作,失效后还要销毁。 因此,开启查询缓存要谨慎,尤其对于写密集的应用来说更是如此。如果开启,要注意合理控制缓存空间大小,一般来说其大小设置为几十 MB 比较合适。此外,还可以通过 sql_cache 和 sql_no_cache 来控制某个查询语句是否需要缓存:

select sql_no_cache count(*) from usr;
posted @ 2021-04-28 11:27  sinlearn  阅读(118)  评论(0编辑  收藏  举报