MySQL存储引擎介绍(1)
一、MySQL存储引擎介绍
1.1.1 MySQL存储引擎介绍
- 什么是mysql存储引擎
MySQL是用来保存数据的,MySQL中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种技术都使用不同的存储机制、索引技巧、锁定水平并且最终提供广泛的不同的功能和能力。通过选择不同的技术,你能够获得额外的速度或者特定的功能,从而改善你的应用的整体功能。这些不同的技术以及配套的相关功能在MySQL中被称作存储引擎(也称作表类型),一句话描述就是MySQL存储引擎类似于Linux系统中文件系统。
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 |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
- 存储引擎的功能
数据读写
数据安全和一致性
提高性能
热备份
自动故障恢复
高可用方面支持
等.
- MySQL存储引擎的分类
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 |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
- 查看表的存储引擎
mysql> select table_schema,table_name,engine from information_schema.tables where engine='myisam';
+--------------+------------------+--------+
| table_schema | table_name | engine |
+--------------+------------------+--------+
| mysql | columns_priv | MyISAM |
| mysql | db | MyISAM |
| mysql | event | MyISAM |
| mysql | func | MyISAM |
| mysql | ndb_binlog_index | MyISAM |
| mysql | proc | MyISAM |
| mysql | procs_priv | MyISAM |
| mysql | proxies_priv | MyISAM |
| mysql | tables_priv | MyISAM |
| mysql | user | MyISAM |
+--------------+------------------+--------+
10 rows in set (0.01 sec)
mysql> select table_schema,table_name,engine from information_schema.tables where engine='innodb' limit 10;
+--------------------+-----------------+--------+
| table_schema | table_name | engine |
+--------------------+-----------------+--------+
| information_schema | COLUMNS | InnoDB |
| information_schema | EVENTS | InnoDB |
| information_schema | OPTIMIZER_TRACE | InnoDB |
| information_schema | PARAMETERS | InnoDB |
| information_schema | PARTITIONS | InnoDB |
| information_schema | PLUGINS | InnoDB |
| information_schema | PROCESSLIST | InnoDB |
| information_schema | ROUTINES | InnoDB |
| information_schema | TRIGGERS | InnoDB |
| information_schema | VIEWS | InnoDB |
+--------------------+-----------------+--------+
10 rows in set (0.01 sec)
- 项目案例——监控系统架构整改
环境: zabbix 4.0 mariaDB 5.5 centos 7.3
现象 : zabbix卡的要死 , 每隔3-4个月,都要重新搭建一遍zabbix,存储空间经常爆满.
问题 :
1. zabbix 版本
2. 数据库版本
3. zabbix数据库500G,存在一个文件
优化建议:
1.数据库版本升级到10.0版本,zabbix升级更高版本
2.存储引擎改为tokudb
3.监控数据按月份进行切割(二次开发:zabbix 数据保留机制功能重写,数据库分表)
4.关闭binlog和双1
5.参数调整....
优化结果:
监控状态良好
为什么?
1. 原生态支持TokuDB,另外经过测试环境,10.0要比5.5 版本性能 高 2-3倍
2. TokuDB:insert数据比Innodb快的多,数据压缩比要Innodb高
3.监控数据按月份进行切割,为了能够truncate每个分区表,立即释放空间
4.关闭binlog ----->减少无关日志的记录.zabbix不需要注重安全,注重性能
5.参数调整...----->安全性参数关闭,提高性能.
环境: centos 5.8 ,MySQL 5.0版本,MyISAM存储引擎,网站业务(LNMP),数据量50G左右
现象问题: 业务压力大的时候,非常卡;经历过宕机,会有部分数据丢失.
问题分析:
1.MyISAM存储引擎表级锁,在高并发时,会有很高锁等待
2.MyISAM存储引擎不支持事务,在断电时,会有可能丢失数据
职责
1.监控锁的情况:有很多的表锁等待
2.存储引擎查看:所有表默认是MyISAM
解决方案:
1.升级MySQL 5.6.10版本
2. 迁移所有表到新环境
3. 开启双1安全参数
4. 重新主从
- MyISAM和InnoDB区别
1、MyISAM:
①不支持事务,但是整个操作是原子性的(事务具备四种特性:原子性、一致性、隔离性、持久性)
②不支持外键,支持表锁,每次所住的是整张表
MyISAM的表锁有读锁和写锁(两个锁都是表级别):
表共享读锁和表独占写锁。在对MyISAM表进行读操作时,不会阻塞其他用户对同一张表的读请求,
但是会阻塞其他用户对表的写请求;对其进行写操作时会阻塞对同一表读操作和写操作
MyISAM存储引擎的读锁和写锁是互斥的,读写操作是串行的。那么,一个进程请求某个MyISAM表的读锁,
同时另一个进程也请求同一表的写锁,MySQL如何处理呢?答案是写进程先获得锁。不仅如此,即使读请求先到锁等待队列,
写请求后到,写锁也会插到读锁请求之前!这是因为MySQL认为写请求一般比读请求要重要。这也正是MyISAM表不太适合于有大量更新操作和查询操作应用的原因,
因为,大量的更新操作会造成查询操作很难获得读锁,从而可能永远阻塞。这种情况有时可能会变得非常糟糕!
③一个MyISAM表有三个文件:索引文件,表结构文件,数据文件
④存储表的总行数,执行select count(*) from table时只要简单的读出保存好的行数即可
(myisam存储引擎的表,count(*)速度快的也仅仅是不带where条件的count。这个想想容易理解的,因为你带了where限制条件,原来所以中缓存的表总数能够直接返回用吗?
不能用。这个查询引擎也是需要根据where条件去表中扫描数据,进行统计返回的。)
⑤采用非聚集索引,索引文件的数据域存储指向数据文件的指针。辅索引与主索引基本一致,但是辅索引不用保证唯一性。
⑥支持全文索引和空间索引
⑦对于AUTO_INCREMENT类型的字段,在MyISAM表中,可以和其他字段一起建立联合索引。
2、Innodb:
①支持事务,支持事务的四种隔离级别;是一种具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。
②支持行锁和外键约束,因此可以支持写并发
③不存储总行数;也就是说,执行select count(*) from table时,InnoDB要扫描一遍整个表来计算有多少行。注意的是,当count(*)语句包含 where条件时,两种表的操作是一样的。
④对于AUTO_INCREMENT类型的字段,InnoDB中必须包含只有该字段的索引
⑤DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除
⑥一个Innodb表存储在一个文件内(共享表空间,表大小不受操作系统的限制),也可能为多个(设置为独立表空间,表大小受操作系统限制,大小为2G),受操作系统文件大小的限制
⑦主键索引采用聚集索引(索引的数据域存储数据文件本身),辅索引的数据域存储主键的值;因此从辅索引查找数据,需要先通过辅索引找到主键值,
再访问主键索引;最好使用自增主键,防止插入数据时,为维持B+树结构,文件的大调整。
- Innodb的优点
核心特性
1、事务(Transaction)
2、MVCC(Multi-Version Concurrency Control多版本并发控制)
3、行级锁(Row-level Lock)
4、ACSR(Auto Crash Safey Recovery)自动的故障安全恢复
5、支持热备份(Hot Backup)
6、Replication: Group Commit , GTID (Global Transaction ID) ,多线程(MTS,Multi-Threads-SQL )
- 储引擎操作类命令
查看默认引擎
mysql> SELECT @@default_storage_engine;
+--------------------------+
| @@default_storage_engine |
+--------------------------+
| InnoDB |
+--------------------------+
1 row in set (0.00 sec)
mysql> show variables like '%engine%';
+----------------------------------+--------+
| Variable_name | Value |
+----------------------------------+--------+
| default_storage_engine | InnoDB |
| default_tmp_storage_engine | InnoDB |
| disabled_storage_engines | |
| internal_tmp_disk_storage_engine | InnoDB |
+----------------------------------+--------+
4 rows in set (0.00 sec)
修改存储引擎
回话生效,打开新窗口就失效
mysql> set default_tmp_storage_engine=Myisam;
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like '%engine';
+----------------------------------+--------+
| Variable_name | Value |
+----------------------------------+--------+
| default_storage_engine | InnoDB |
| default_tmp_storage_engine | MyISAM |
| internal_tmp_disk_storage_engine | InnoDB |
+----------------------------------+--------+
3 rows in set (0.00 sec)
临时全局生效 重启数据库失效
mysql> set global default_storage_engine=myisam;
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> show global variables like '%engine';
+----------------------------------+--------+
| Variable_name | Value |
+----------------------------------+--------+
| default_storage_engine | MyISAM |
| default_tmp_storage_engine | InnoDB |
| internal_tmp_disk_storage_engine | InnoDB |
+----------------------------------+--------+
3 rows in set (0.00 sec)
全局修改在配置文件里添加
/etc/my.cnf
[mysqld]
default_storage_engine=myisam
9.查看表的存储引擎
查看单表的存储引擎
mysql> show create table world.city;
| city | CREATE TABLE `city` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`Name` char(35) NOT NULL DEFAULT '',
`CountryCode` char(3) NOT NULL DEFAULT '',
`District` char(20) NOT NULL DEFAULT '',
`Population` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`),
KEY `CountryCode` (`CountryCode`),
KEY `idx_name` (`Name`(5)),
KEY `idx_co_po` (`CountryCode`,`Population`),
CONSTRAINT `city_ibfk_1` FOREIGN KEY (`CountryCode`) REFERENCES `country` (`Code`)
) ENGINE=InnoDB AUTO_INCREMENT=4080 DEFAULT CHARSET=latin1 |
#也可以利用查看单个表的全部信息查看存储索引
mysql> show table status like 'city'G; #常有用命令
*************************** 1. row ***************************
Name: city
Engine: InnoDB
Version: 10
Row_format: Dynamic
Rows: 4188
Avg_row_length: 97
Data_length: 409600
Max_data_length: 0
Index_length: 507904
Data_free: 0
Auto_increment: 4080
Create_time: 2020-06-14 16:48:10
Update_time: NULL
Check_time: NULL
Collation: latin1_swedish_ci
Checksum: NULL
Create_options:
Comment:
1 row in set (0.00 sec)
mysql> select table_schema,table_name,engine from information_schema.tables where table_schema not in ('mysql','information_schema','ssys','performance_schema');
+--------------+-----------------------+--------+
| table_schema | table_name | engine |
+--------------+-----------------------+--------+
| chenhj | chen | InnoDB |
| chenhj | oldchen | InnoDB |
| chenhj | stu | InnoDB |
| school | course | InnoDB |
| school | score | InnoDB |
| school | student | InnoDB |
| school | teacher | InnoDB |
| test | t100w | InnoDB |
| wordpress | wp_commentmeta | InnoDB |
| wordpress | wp_comments | InnoDB |
| wordpress | wp_links | InnoDB |
| wordpress | wp_options | InnoDB |
| wordpress | wp_postmeta | InnoDB |
| wordpress | wp_posts | InnoDB |
| wordpress | wp_term_relationships | InnoDB |
| wordpress | wp_term_taxonomy | InnoDB |
| wordpress | wp_termmeta | InnoDB |
| wordpress | wp_terms | InnoDB |
| wordpress | wp_usermeta | InnoDB |
| wordpress | wp_users | InnoDB |
| world | city | InnoDB |
| world | country | InnoDB |
| world | countrylanguage | InnoDB |
+--------------+-----------------------+--------+
23 rows in set (0.00 sec)
10 修改表的存储引擎
mysql> create table t1 (id int not null) engine=myisam;
mysql> show create table t1;
+-------+------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+------------------------------------------------------------------------------------+
| t1 | CREATE TABLE `t1` (
`id` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
+-------+------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
替换t1表的存储引擎
mysql> alter table t1 engine='innodb';
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table t1;
+-------+------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+------------------------------------------------------------------------------------+
| t1 | CREATE TABLE `t1` (
`id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
#批量修改存储引擎
mysql> select concat("alter table ",table_name," engine innodb;") #注意使用concat的时候 变量需要加双引号,常量不需要,双方用逗号隔开
-> from information_schema.tables
-> where table_schema not in ('mysql','information_schema','sys','performance_schema')
-> into outfile '/tmp/alter.sql';
Query OK, 24 rows affected (0.00 sec)
[root@db01 /tmp]# cat alter.sql
alter table chen engine innodb;
alter table oldchen engine innodb;
alter table stu engine innodb;
alter table course engine innodb;
alter table score engine innodb;
- 平常处理过的MySQL问题(碎片处理)
环境:centos7.4,MySQL 5.7.20,InnoDB存储引擎
业务特点:数据量级较大,经常需要按月删除历史数据.
问题:磁盘空间占用很大,不释放
处理方法:
以前:将数据逻辑导出,手工drop表,然后导入进去
现在:
对表进行按月进行分表(partition,中间件)
业务替换为truncate方式
定期执行:
alter table t1 engine='innodb'; (这条语句除了可以修改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';