innodb存储引擎

1.mysql5.5开始将innodb作为mysql的默认存储引擎.完整的支持ACID特性,且支持行级锁,多版本并发控制(MVCC).外键,以及一致性非锁定读.
2.显示的开启一个事务,作用类似于autocommit =0;开启后需要手动提交事务;
begin;开启一个事务.
在开启一个事务以后期间进行的所有的操作都会成为汇聚成一整个事务.
只有使用commit;手动提交或者rollback;事务回滚才可以完成这个手动事务.
start trunsaction;同样开启一个事务,
使用 rollback; 或者commit;进行事务的回滚或者提交.
3.innodb多版本控制
为保证并发操作和回滚操作,innodb会将修改前的数据存放在回滚段中.
innodb会在数据库的每一行上额外增加三个字段已实现多版本控制,
第一个字段是DB_TRX_id,用来存放指针对应该行最后此次执行insert,update操作的事务ID.
delete操作也会被认为是 update,只是会有额外的以为来代表事务为删除造作.
第二个字段是DB_ROLL_PTR指针指向回滚段里面对应的undo日志记录,
第三个字段是DB_ROW_ID代表每一行的ID,回滚段中的undo日志记录只有在事务commit之后
才会被丢弃,为避免回滚段越来越大,要注意即是执行commit;
4.innodb数据文件存储结构(树形结构)
每一个叶子节点中的数据都是有序排列的,如果有主键(primary key的话按照主键排序).
并且每个数据页为16K,存储完成第一个页子节点后自动生成第二个页,
以此类推.一张表中可以占用多个页子节点.在进行数据插入,所以就产生了如下的特点:
    1.根据主键寻址速度是非常快的.查询速度较快.
    2.主键之递增的insert插入效率较好.
    3.主键随机insert插入操作效率比较差.
5.事务执行过程
接下来我就以update为例,讲解下MySQL5.6的innodb的事务流程,总结起来就是:
真对update he set name='liuwenhe' where id=5;
1)事务开始
2)对id=5这条数据上排他锁,并且给5两边的临近范围加gap锁,
gap就是索引树中插入新纪录的间隙.防止别的事务insert新数据;
3)将需要修改的数据页PIN到innodb_buffer_cache中;
4)彻底修改数据前:记录id=5的数据到undo log.
5)将要修改的数据:记录修改id=5的信息到redo log.
6)修改id=5的name='liuwenhe'.
7)刷新innodb_buffer_cache中脏数据到底层磁盘,这个过程和commit无关;
8)commit,触发page cleaner线程把redo从redo buffer cache中刷新到底层磁盘,并且刷新innodb_buffer_cache中脏数据到底层磁盘也会触发对redo的刷新;
9)记录binlog (记录到binlog_buffer_cache中)
10)事务结束;
6.redo log buffer
    redo log buffer 是一块用来存放写入redo log文件内容的内存区域,
内存的大小有 innodb_log_buffer_size参数确定,改buffer的内容会定期刷新到
磁盘的redo log文件中.参数 innodb_flush_log_at_trx_commit决定了刷新到
文件的方式,参数innodb_flush_log_at_timeout参数决定刷新的频率.
    其中innodb_flush_log_at_commit有三个参数,默认值是 1 .
    0.每秒写入持久化一次,(不安全,性能高,无论mysql或服务宕机都会丢失最多1秒数据.)
    1.每次commit都会持久化,(安全,但是性能低,IO负担重,)
    2.每次commit都会写入内存的缓存,每秒再刷新到磁盘(安全,性能折中,
    mysql宕机数据不会丢失,服务器宕机数据会丢失最多一秒,这里的内存缓存并
    不是buffer_pool,而是服务器内存中.)
innodb_flush_log_at_timeout 表示最多可以丢失多少时间的数据.默认是1.
7.redo log大小的设置,
一般情况下载业务高峰期一小时内的数据量总和不超过redo log的大小.就表示比较合理.
这个日志再系统层面可以查到,名字叫做ib_logfile,主要起到在事务中前滚和后滚的作用.
也成为了redo log.无法用铭文看到.在设置大小的时候查看一下文件修改时间,业务高峰期
文件修改时间大于1小时即可.
innodb_log_file_size 范围5M-4G之间.两个文件 ib_logfile0和ib_logfile1.累加
不超过4G,
事务日志大,checkpoint会少,节省磁盘IO,但是大的事务日
志意味着数据库crash时,恢复起来较慢.
8.innodb体系结构(关于缓存)
buffer pool 换存池
    1.buffer pool缓存池是innodb在内存中开辟的用来缓存表数据和索引数据的区域,
一般可以设置为总物理内存的50%-80%,留一部分给系统,够用就行,通过对经常访问
的数据放置到内存当中来加快访问速度.
    2.buffer pool 以page页的格式组成,叶志坚组成list列表,并通过lru算法(最近最少使用算法)
对长久不使用的也进行置换.
    3.数据页的读写要经过缓存(缓存在buffer_pool记在内存中)数据以整页(16K)为单位读取到缓存中.
缓存中的数据以lru策略换出(最少使用策略,)IO效率高,性能好.
9.doublewrite缓存
    应用(apply)重做日志钱,用户需要一个页的副本,当写入失效发生时,先通过也的副本来还原该页,
在进行重做,这就是doublewrite.
doublewrite组成:
    内存中的doublewrite buffer 大小为2M,
物理磁盘上的共享表空间连续的128个页,2个区,大小同样为2M,对缓冲池的葬爷进行刷新时,
不是直接写磁盘,而是会通过memcpy()函数将葬爷先复制到内存中的doublewrite buffer,
然后通过doublewrite分两次,每次1M顺序的写入共享表空间的物理磁盘上,在这个过程
中doublewrite页是连续的,因此这个过程是顺序写的,开销并不是很大.在完成doublewrite页
的写入后,再将doublewrite buffer中的也写入各个表空间中,此时写入的测试离散的.
如果操作系统再将页写入磁盘的过冲中发生率崩溃,再回复过冲中,innodb可以从共享表空间
中的doublewrite中找到该页的一个副本,将其复制到表空间文件,在应用重做日志.
    大概意思就是 先修改buffer,然后buffer写入共享表空间,然后再写入数据磁盘,
    如果在写入数据磁盘的时候宕机了,那么开机的时候就会从共享表空间中取获取大概2M的预存数据
    剩下的从redolog中获取.前者是批量恢复,后者是逐条恢复,起到一个补充作用.
10.undolog
10.undo log 总共有128个回滚段信息,其中32个是用于系统服务的,96个事用于日常表数据的回滚.
每个回滚段支持1023个事务.总共支持96K个事务回滚.
11.temp porary
如果临时表空间占用过多,可以重启一下数据库.或者直接删除ibtemp1.底层文件.
在数据库重启完成以后会自动穿件.

 

posted on 2019-09-24 19:01  DisCover_ry  阅读(1376)  评论(0)    收藏  举报