教育行业A股IPO第一股(股票代码 003032)

全国咨询/投诉热线:400-618-4000

Innodb和MySIAM在存储方式上有什么区别?

更新时间:2018年11月16日15时07分 来源:传智播客 浏览次数:

1.MySQL5.5.8之后版本默认Innodb存储引擎

2.Innodb使用表空间进行 数据存储
    a.Innodb是支持事物的存储引擎,也就是说支持ACID特性的,适合处理更多的小事物,小事物也就是正常的提交,很少回滚;          
    b. Innodb和MySIAM在存储方式上也有很大的区别,Innodb有自己的表空间的概念,表中的数据是存储在表空间之中的,具体存储在什么样的表空间中呢?是由innodb_file_per_table这个参数决定的,如果这个参数为ON:独立表空间,存储的表名为(表名.ibd),如果参数为OFF:系统表空间(系统的共享表空间),存储的表名为(ibdataX(X为数字)))      
       命令:show variables like 'innodb_file_per_table';           
       查看mysql数据库的存放位置: show global variables like "%datadir%";
       接下来我们创建一个表来看一下
            create  table myinnodb(id int,c1 varchar(100)) engine='innodb';                   

            看一下文件系统是如何存储的,进入到数据库存放的位置,ls -lh myinnodb*                   
            可以看到有myinnodb.frm和myinnodb.ibd两个文件,frm文件时记录表结构的,ibd就是innodb表实际存储的位置           
            接着把innodb_file_per_table参数设置为off,命令为set global innodb_file_per_table=off;                   
            show variables like 'innodb_file_per_table'; 用这个命令检查是否关闭了                  
            再创建一个表:create  table myinnodb_g(id int,c1 varchar(100)) engine='innodb';                   
           查看存储的位置,可以看到只有一个myinnodb_g.frm的文件,不存在ibd文件,也就是说它的数据存储在系统共享表的空间 存储在ibdata1中
3.系统表空间和独立表空间要如何选择?
           首先看一下系统文件对表空间的管理方式      
           在mysql5.6之前的Innodb的innodb_file_per_table参数默认值设置是off,也就是说在mysql5.5版本的时候,所使用的innodb表的数据都存储在系统共享表空间的,如果有人觉得使用这个是最合适的话呢,那么他可能遇到下面的情况,在系统繁忙中,他会发现系统表空间在不断的增长,本来呢,这个也没有什么问题,只要没有超过磁盘你的限制是可以接受的,但是一旦我们的磁盘空间出现不足,我们为了释放磁盘空间,不得不需要在系统中删除大量的、无效的数据或者是一些长期不会使用的数据,比如像日志类的数据,我们在删除之后,系统表空间并不会减小,另外我们在这种情况下想通过复制日志文件的方式对数据库进行备份,由于虽然删除了数据,表空间的大小也不会改变,这就意味着我们在每次删除时都要浪费很大的空间,不要以为我么不会遇到这种问题,实际上我们目前是使用的innodb的热备方式就是这样处理的,因为这时候我们遇到了用到了使用系统表空间进行数据的存储的问题;而想要收缩系统表空间的唯一方式,就是把整个数据库所有Innodb表导出后,删除Innodb表相关的文件后,重启mysql服务器,进行表空间的重建,然后再导入数据,这个过程其实是很复杂的,并且十分耗时,在业务繁忙的生成环境中呢,显然是不可能做到的,使用系统表空间存储文件很显然的问题就是无法简单的收缩文件大小,造成大量的课件浪费,会产生大量的磁盘碎片,从而降低系统的性能              如果我们使用独立表空间的话上面的问题就很好解决了,我们如果对一个大表的数据进行清理之后,可以很方便的只对这一个表进行optimize table操作,这样的话也会对这个表进行重建,但是对比对整个系统文件进行重建的话要快的多,而且不需要重启数据库服务器,甚至不会影响正常访问,从这点来看,显然使用独立表空间比使用系统表空间方便      再来看一下使用系统表空间和独立表空间对IO产生的影响      对于系统表空间来说呢,由于只有一个文件,如果同时对一个数据表空间进行刷新时,实际上在文件系统层面上来说,是按照顺序进行的,会产生IO瓶颈      对于独立表空间来说呢,由于每一个表都有自己的独立表空间文件,自己在数据写入时,可以利用多个文件增加对IO处理的性能,所以对频繁写入来说不太适合系统表空间统一存放数据,而是要使用独立表空间的方式      我强烈建议大量使用Innodb引擎时候,使用独立表空间来进行管理      在mysql5.6版本之后,独立表空间也成为了默认的配置     
          如果是5.6之前的版本想转换位独立表空间需要进行如下的步骤:     
                 1.使用mysqldump导出所有数据库表数据  (注意:数据库使用的是存储过程、触发器、计划事件等一定要记得一起导出)       
                 2.停止Mysql服务,修改参数(在mysql的配置文件中加入innodb_file_per_table=on),并删除相关的Innodb相关文件       
                 3.重启Mysql服务,重建Innodb系统表空间        
                 4.重新导入备份的数据
      

         我们系统表空间的数据迁移到独立表空间后,现在的系统表空间还会有什么内容呢?        
               虽然我们已经把表的数据从系统表空间中迁移到了独立表空间,但是在系统表空间中还是有一部分很重要的东西要存储的        
               其中之就是Innodb数据字典,数据字典是数据库结构对象的元数据的信息,它存放一些与数据库对象相关的一些信息,如表、列、索引、外键等,细心的同学已经发现了,Mysql数据库是使用frm文件来存储表结构的定义的,那么frm文件与系统表空间中存放的数据字典有什么区别呢?首先frm文件是mysql数据库服务器层产生的文件,可以理解为mysql数据库服务器层的数据字典,对于mysql所有的存储引擎是一样的;在mysql服务器层保存的多线程是与存储引擎无关的Innodb内存产生的数据字典,是innodb内部产生的,并可以保证一些事物的安全性,另外,innodb存储引擎没有使用mysql数据库上传的类型,而是自己封装了一些自定义,数据字典都是存储了一些innodb相关的一些内容,frm文件只是一个简单的二进制文件,而innodb数据字典是通过计数来进行数据管理的;         还有Undo 回滚段和innodb临时表,这两种数据呢,在mysql5.7的时候呢,都是从系统表空间中移出了,但是还是有很多的默认存储在系统表空间中,对于Undo 段在mysql5.6的时候就支持了

4.Innodb存储引擎的特性
        1.Innodb是一种事物性存储引擎            
             a.完全支持事物的ACID特性(原子性、一致性、隔离性和持久性)               
                   Innodb是如何实现ACID的特性?                 
                   能够实现原子性、一致性和持久性,Innodb使用了两个特殊的日志类型,Redo Log(实现事物的持久性,由两部分组成,重做日志缓冲区---->innodb_log_buffer_size)和Undo Log()            
             b.Innodb支持的是行级锁                
                  行级锁的特点:                   
                        在进行写操作时,需要锁定的资源更少,支持的并发就会更多                     
                        innodb行级锁是由存储引擎层实现的                 
                  什么是锁,锁的作用是什么呢?                      
                        答:锁是数据库系统区别于文件系统的重要特性,锁的主要作用是管理共享资源的并发访问,并发访问是一个很让人头疼的问题,对于任何的串行环境下工作良好的一个系统,一旦出现并发就会出现各种各样的问题 ;锁的另一个作用就是实现事物的隔离性                        
                  锁的类型:   
                        共享锁(也称读锁):相互不会被堵塞的,多个线程可以在同一时间读取同一资源,而不相互干扰                           
                        独占锁(也称为写锁): 排他的,一个写锁可以堵塞其他的写锁和读锁,这是出于数据完成性的考虑,只有这样在改填的时间里,只有一个线程执行戏写入,并防止其他用户读取正在写入的同一资源,也就是实现事物的隔离性                                                             
                        | Item      |  写锁      |  读锁    |       
                        | :-------- | --------: |    :--:     |
                        | 写锁       | 不兼容   |  不兼容 |        
                        | 读锁       |  不兼容  | 兼容   |                  
                        写锁和其他的锁都是不兼容的,读锁和读锁之间是兼容的           
                        需要注意的是:对于Innodb来说,读锁和写锁都是行锁,所谓的兼容性就是对同一行的记录兼容性的情况                                        
                        什么是阻塞?           
                              阻塞是因为不同锁之间的兼容性的关系,在有些时刻,一个事物中的锁需要等待另一个事物中锁的释放它所占用的资源,形成的阻塞,阻塞是为了确保事物可以并发,且可以正常的运行,当系统中出现了大量的阻塞,往往系统中就存在着问题,也可能是一个被频繁更新的表上出现了慢查询                                                
        2.Innodb状态检查                
              show engine innodb status 包含了一些平均值的统计信息,平均值是指上次输出结果生成的统计数;两次输入的间隔时间不能少于30秒

作者:传智播客人工智能+Python培训学院
首发:http://python.itcast.cn/



0 分享到:
和我们在线交谈!