MySQL 存储引擎

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: MySQL 存储引擎

第一章 什么是MySQL存储引擎?

MySQL存储引擎类似linux“文件系统”

MySQL自带的存储引擎种类

mysql> show engines; 
MRG_MYISAM        
CSV               
MyISAM                      
BLACKHOLE         
PERFORMANCE_SCHEMA
InnoDB               
ARCHIVE            
MEMORY            
FEDERATED

面试题

请你列举MySQL中支持的存储引擎种类?

InnoDB、MyISAM、CSV、MEMORY 等

分支产品的引擎种类介绍

TokuDB --> percona、mariadb MyRocks、Rocksdb
特点:
  1. 压缩比15倍以上
  2. 插入数据性能
适应场景:
例如Zabbix监控类的平台、归档库、历史数据存储业务

InnoDB存储引擎特性

MVCC       :多版本并发控制 
聚簇索引   :用来组织存储数据和优化查询
支持事务   :数据安全保证
支持行级锁 :控制并发
外键
多缓冲区支持
自适应Hash索引:AHI
复制中支持高级特性。
备份恢复:支持热备。
自动故障恢复:CR  Crash Recovery
双写机制:Double Write

InnoDB 核心特性有哪些?InnoDB和MyISAM区别有哪些?

InnoDB 支持:事务、MVCC、聚簇索引、外键、缓冲区、AHI、CR、DW,MyISAM不支持。
InnoDB 支持:行级锁,MyISAM支持表级锁。
InnoDB 支持热备(业务正常运行,影响低),MyISAM支持温备份(锁表备份)。
InnoDB 支持CR(自动故障恢复),宕机自动故障恢复,数据安全和一致性可以得到保证。MyISAM不支持,宕机可能丢失当前修改。

第二章 存储引擎的基本操作

查询支持的存储引擎

mysql> show engines;

查询、设置默认存储引擎

mysql> select @@
default_storage_engine;

修改配置文件 (设置引擎默认为innodb)

vim /etc/my.cnf  default_storage_engine=InnoDB

查看、设定 表的存储引擎

查看某张表的存储引擎

mysql> show create table xta;

查询系统中所有业务表的存储引擎信息

mysql> select 
 table_schema,
 table_name ,
 engine 
 from information_schema.tables  
 where table_schema not in ('sys','mysql','information_schema','performance_schema');

创建表设定存储引擎

mysql> create table xxx (id int) engine=innodb charset=utf8mb4;

修改已有表的存储引擎

mysql> alter table xxx engine=myisam;
mysql> alter table world.xxx engine=innodb;

将所有的非InnoDB引擎的表查询出来,批量修改为InnoDB

mysql> select table_schema,table_name ,engine 
  from information_schema.tables  
  where 
  table_schema not in ('sys','mysql','information_schema','performance_schema') 
  and engine !='innodb';
  mysql> select concat("alter table ",table_schema,".",table_name," engine=innodb;")   from information_schema.tables     where    table_schema not in ('sys','mysql','information_schema','performance_schema')    and engine !='innodb' into outfile '/tmp/a.sql';
  mysql> source /tmp/a.sql


第三章 InnoDB 存储引擎的体系结构

磁盘结构

表空间结构

表空间的概念源于Oracle数据库。最初的目的是为了能够很好的做存储的扩容。

共享(系统)表空间

存储方式ibdata1~ibdataN, 5.5版本默认的表空间类型

ibdata1共享表空间在各个版本的变化

5.5版本:
  系统相关:(全局)数据字典信息(表基本结构信息、状态、系统参数、属性..)、UNDO回滚信息(记录撤销操作)、Double Write信息、临时表信息、change buffer
  用户数据:表数据行、表的索引数据  
5.6版本:共享表空间只存储于系统数据,把用户数据独立了。
  系统相关:(全局)数据字典信息、UNDO回滚信息、Double Write信息、临时表信息、change buffer
5.7版本:在5.6基础上,把临时表独立出来,UNDO也可以设定为独立
  系统相关:(全局)数据字典信息、UNDO回滚信息、Double Write信息、change buffer
8.0.19版本:在5.7的基础上将UNDO回滚信息默认独立,数据字典不再集中存储了。
      系统相关:Double Write信息、change buffer
8.0.20版本:在之前版本基础上,独立 Double Write信息
系统相关:change buffer
https://dev.mysql.com/doc/refman/5.7/en/innodb-architecture.html

共享表空间管理

扩容共享表空间

mysql> select @@innodb_data_file_path;
mysql> select @@innodb_autoextend_increment;
ibdata1文件,默认初始大小12M,不够用会自动扩展,默认每次扩展64M

设置方式

先查看实际大小:
[root@db01 data]# ls -lh ibdata1 
-rw-r----- 1 mysql mysql 76M May  6 17:11 ibdata1
配置文件设定为和实际大小一致:
innodb_data_file_path=ibdata1:76M;ibdata2:100M;ibdata3:100M:autoextend

模拟在初始化时设置共享表空间(生产建议)

5.7 中建议:设置共享表空间2-3个,大小建议512M或者1G,最后一个定制为自动扩展。
8.0 中建议:设置1个就ok,大小建议512M或者1G
$ /etc/init.d/mysqld stop
$ rm -rf /data/3306/data/*
$ vim /etc/my.cnf
# 修改 
innodb_data_file_path=ibdata1:100M;ibdata2:100M;ibdata3:100M:autoextend
# 重新初始化
$ mysqld --initialize-insecure --user=mysql --basedir=/data/app/mysql --datadir=/data/3306/data
# 重启数据库生效
$ /etc/init.d/mysqld start

注:数据库配置文件改动则需重启生效

独立表空间

5.6版本中,针对用户数据,单独的存储管理。存储表的数据行和索引。

通过参数控制:
mysql> select @@innodb_file_per_table;
+-------------------------+
| @@innodb_file_per_table |
+-------------------------+
|                       1 |
+-------------------------+
测试:共享表空间存储用户数据
mysql> set global innodb_file_per_table=0;

利用独立表空间进行快速数据迁移

源端:3306/test/t100w  -----> 目标端:3307/test/t100w
1. 锁定源端t100w表 
mysql> lock tables test.t100w read;
mysql> show create table test.t100w;
CREATE TABLE `t100w` (
  `id` int(11) DEFAULT NULL,
  `num` int(11) DEFAULT NULL,
  `k1` char(2) DEFAULT NULL,
  `k2` char(4) DEFAULT NULL,
  `dt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2. 目标端创建test库和t100w空表
mysql> create database test charset=utf8mb4;
CREATE TABLE `t100w` (
  `id` int(11) DEFAULT NULL,
  `num` int(11) DEFAULT NULL,
  `k1` char(2) DEFAULT NULL,
  `k2` char(4) DEFAULT NULL,
  `dt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
3.  单独删除空的表空间文件(保留t100w的frm,ibdata1中关于t100w的系统数据)
mysql> alter table test.t100w discard tablespace;
4. 拷贝源端ibd文件到目标端目录,并设置权限
[root@db01 test]# cp /data/3306/data/test/t100w.ibd /data/3307/data/test/
[root@db01 test]# chown -R mysql.mysql /data/*
5. 导入表空间
mysql> alter table test.t100w import tablespace;
mysql> select count(*) from test.t100w;
+----------+
| count(*) |
+----------+
|  1000000 |
6. 解锁源端数据表
mysql> unlock tables;

undo表空间

1. 作用:用来作撤销工作。
2. 存储位置:5.7版本,默认存储在共享表空间中(ibdataN)。8.0版本以后默认就是独立的(undo_001-undo_002)。
3. 生产建议:5.7版本后,将undo手工进行独立。

undo 表空间管理

如何查看undo的配置参数SELECT @@innodb_undo_tablespaces;  ---->3-5个  
#打开独立undo模式,并设置undo的个数。
SELECT @@innodb_max_undo_log_size;            
#undo日志的大小,默认1G。SELECT @@innodb_undo_log_truncate;            
#开启undo自动回收的机制(undo_purge)。SELECT @@innodb_purge_rseg_truncate_frequency;   #触发自动回收的条件,单位是检测次数。

配置undo表空间

$ /etc/init.d/mysqld stop
$ rm -rf /data/3306/data/*
$ vim /etc/my.cnf
# 添加参数
innodb_undo_tablespaces=3           
innodb_max_undo_log_size=128M
innodb_undo_log_truncate=ON
innodb_purge_rseg_truncate_frequency=32
$ mysqld --initialize-insecure --user=mysql --basedir=/data/app/mysql --datadir=/data/3306/data
$ /etc/init.d/mysqld start
$ ll /data/3306/data/undo00*
-rw-r----- 1 mysql mysql 10485760 May  7 15:39 /data/3306/data/undo001
-rw-r----- 1 mysql mysql 10485760 May  7 15:39 /data/3306/data/undo002
-rw-r----- 1 mysql mysql 10485760 May  7 15:39 /data/3306/data/undo003

临时表空间

作用:存储临时表。
管理:
建议数据初始化之前设定好,一般2-3个,大小512M-1G。
innodb_temp_data_file_path=ibtmp1:12M;ibtmp2:128M:autoextend:max:500M

InnoDB 事务日志

redo log 重做日志

作用: 记录数据页的变化。实现“前进”的功能。WAL(write ahead log),MySQL保证redo优先于数据写入磁盘。

存储位置:数据路径下,进行轮序覆盖记录日志

查询redo log文件配置
mysql> show variables like '%innodb_log_file%';
+---------------------------+----------+
| Variable_name             | Value    |
+---------------------------+----------+
| innodb_log_file_size      | 50331648 |
| innodb_log_files_in_group | 2        |
+---------------------------+----------+
生产建议:
  大小:512M-4G
  组数:2-4组
$ vim  /etc/my.cnf 
# 添加参数:
innodb_log_file_size=100M
innodb_log_files_in_group=3
$ /etc/init.d/mysqld restart
$ ll /data/3306/data/ib_logfile*
-rw-r----- 1 mysql mysql 104857600 May  7 16:17 /data/3306/data/ib_logfile0
-rw-r----- 1 mysql mysql 104857600 May  7 16:17 /data/3306/data/ib_logfile1
-rw-r----- 1 mysql mysql 104857600 May  7 16:17 /data/3306/data/ib_logfile2
其他结构
ib_buffer_pool
作用:
缓冲和缓存,用来做“热”(经常查询或修改)数据页,减少物理IO。
当关闭数据库的时候,缓冲和缓存会失效。
5.7版本中,MySQL正常关闭时,会将内存的热数据存放(流方式)至ib_buffer_pool。下次重启直接读取ib_buffer_pool加载到内存中。
# Double Write Buffer(DWB)(5.7 默认在ibdataN中,8.0.20以后可以独立了。)
作用:
MySQL,最小IO单元page(16KB),OS中最小的IO单元是block(4KB)
为了防止出现以下问题:
mysqld process crash in the middle of a page write

其他结构

ib_buffer_pool

作用:

缓冲和缓存,用来做“热”(经常查询或修改)数据页,减少物理IO。

当关闭数据库的时候,缓冲和缓存会失效。

管理:
  查询:
  mysql> select @@innodb_buffer_pool_size;
    默认大小:128M
  生产建议:物理内存的:50-80%。
  在线设置:
  mysql> set global innodb_buffer_pool_size=268435456;
    重新登录mysql生效。
  永久设置:
  vim /etc/my.cnf 
  #添加参数
  innodb_buffer_pool_size=256M
    重启生效

内存结构

InnoDB BUFFER POOL(IBP)

作用:

用来缓冲、缓存,MySQL的数据页和索引页。MySQL中最大的、最重要的内存区域。

管理 :
    查询:
    mysql> select @@innodb_log_buffer_size;
      默认大小:16M
    生产建议:和innodb_log_file_size有关,1-N倍
      设置方式 :
    vim /etc/my.cnf 
    innodb_log_buffer_size=33554432
      重启生效:
    [root@db01 data]# /etc/init.d/mysqld restart

InnoDB LOG BUFFER (ILB)

作用:用来缓冲 redo log日志信息。

管理 :
    查询:
    mysql> select @@innodb_log_buffer_size;
      默认大小:16M
    生产建议:和innodb_log_file_size有关,1-N倍
      设置方式 :
    vim /etc/my.cnf 
    innodb_log_buffer_size=33554432
      重启生效:
    [root@db01 data]# /etc/init.d/mysqld restart


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
22天前
|
存储 SQL 关系型数据库
MySQL存储引擎
本文介绍了数据库优化的多个方面,包括选择合适的存储引擎、字段定义原则、避免使用外键和触发器、大文件存储策略、表拆分及字段冗余处理等。强调了从业务层面进行优化的重要性,如通过活动设计减少外部接口调用,以及在高并发场景下的流量控制与预处理措施。文章还提供了具体的SQL优化技巧和表结构优化建议,旨在提高数据库性能和可维护性。
MySQL存储引擎
|
7天前
|
存储 缓存 关系型数据库
【赵渝强老师】MySQL的MyISAM存储引擎
在MySQL5.1版本之前,默认存储引擎为MyISAM。MyISAM管理非事务表,提供高速存储和检索,支持全文搜索。其特点包括不支持事务、表级锁定、读写互阻、仅缓存索引等。适用于读多、写少且对一致性要求不高的场景。示例代码展示了MyISAM存储引擎的基本操作。
|
7天前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL的InnoDB存储引擎
InnoDB是MySQL的默认存储引擎,广泛应用于互联网公司。它支持事务、行级锁、外键和高效处理大量数据。InnoDB的主要特性包括解决不可重复读和幻读问题、高并发度、B+树索引等。其存储结构分为逻辑和物理两部分,内存结构类似Oracle的SGA和PGA,线程结构包括主线程、I/O线程和其他辅助线程。
【赵渝强老师】MySQL的InnoDB存储引擎
|
7天前
|
存储 关系型数据库 MySQL
【赵渝强老师】MySQL的Memory存储引擎
MySQL 的存储引擎层负责数据的存储和提取,支持多种存储引擎,如 InnoDB、MyISAM 和 Memory。InnoDB 是最常用的存储引擎,从 MySQL 5.5.5 版本起成为默认引擎。Memory 存储引擎的数据仅存在于内存中,重启后数据会丢失。示例中创建了使用 Memory 引擎的 test3 表,并展示了数据在重启后消失的过程。
|
1月前
|
存储 SQL 缓存
MySQL存储引擎如何完成一条更新语句的执行!
MySQL存储引擎如何完成一条更新语句的执行!
MySQL存储引擎如何完成一条更新语句的执行!
|
2月前
|
存储 缓存 关系型数据库
MySQL高级篇——存储引擎和索引
MyISAM:不支持外键和事务,表锁不适合高并发,只缓存索引,内存要求低,查询快MyISAM提供了大量的特性,包括全文索引、压缩、空间函数(GIS)等,但MyISAM不支持事务、行级锁、外键,有一个毫无疑问的缺陷就是崩溃后无法安全恢复。5.5之前默认的存储引擎优势是访问的速度快,对事务完整性没有要求或者以SELECT、INSERT为主的应用针对数据统计有额外的常数存储。故而 count(*) 的查询效率很高表名.frm 存储表结构;表名.MYD 存储数据 (MYData);
MySQL高级篇——存储引擎和索引
|
3月前
|
存储 关系型数据库 MySQL
MySQL 中的事务存储引擎深入解析
【8月更文挑战第31天】
53 0
|
5月前
|
存储 关系型数据库 MySQL
|
4月前
|
存储 关系型数据库 MySQL
MySQL InnoDB存储引擎的优点有哪些?
上述提到的特性和优势使得InnoDB引擎非常适合那些要求高可靠性、高性能和事务支持的场景。在使用MySQL进行数据管理时,InnoDB通常是优先考虑的存储引擎选项。
173 0
|
5月前
|
存储 关系型数据库 MySQL
MySQL数据库进阶第一篇(存储引擎与Linux系统上安装MySQL数据库)
MySQL数据库进阶第一篇(存储引擎与Linux系统上安装MySQL数据库)