MySQL存储引擎介绍(1)

MySQL存储引擎介绍(1)

一、MySQL存储引擎介绍

1.1.1 MySQL存储引擎介绍

  1. 什么是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       |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
  1. 存储引擎的功能
数据读写
数据安全和一致性
提高性能
热备份
自动故障恢复
高可用方面支持
等.
  1. 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       |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
  1. 查看表的存储引擎
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)
  1. 项目案例——监控系统架构整改
环境: 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. 重新主从
  1. 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+树结构,文件的大调整。
  1. 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 )
  1. 储引擎操作类命令
查看默认引擎
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;

  1. 平常处理过的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';
posted @ 2020-06-16 17:07  海上月  阅读(121)  评论(0编辑  收藏  举报