innodb存储引擎
MySQL-5.5 以及之后版本默认存储引擎.
存储方式:
当innodb_file_per_table为on时,存储到tablename.idb中(推荐,默认选项)
当其为off时,存储到idbataX(系统空间,不推荐)
比较
- 系统表空间无法简单的收缩文件大小.(很麻烦,复杂,耗时)
- 独立表空间可以通过optimize table命令收缩系统文件.
- 系统表空间会产生IO瓶颈(因为多个表公用一个文件,所以将会顺序执行)
- 独立表空间可以同时向多个文件刷新数据(因为是多个文件,所以将同步进行)
从系统表空间向独立表空间迁移
数据库和实例
数据库:物理操作系统文件或其他形式文件类型的集合
实例:MySQL数据库有后台县城以及一个共享内存去组成。
通常情况下,两者时一对一的关系;但是,在集群情况下可能存在一个数据库被多个数据实例使用的情况。
MySQL实例在系统上的表现就是一个进程
特性
- 支持ACID(简单的说就是事务原子性,一致性,隔离性,持久性)
- 支持行级锁,以及类似ORACLE的一致性读,多用户并发
- 独有的聚集索引主键设计方式,可大幅提升并发读写性能。
- 支持外键
- 支持崩溃数据自修复
- 已经支持空间(GPS),和全文检索了(MyISAM引擎原特有.)
实用的建议
- 所有InnoDB数据表都创建一个和业务无关的自增数字型作为主键,对保证性能很有帮助
- 杜绝使用text/blob,确实需要使用的,尽可能拆分出去成一个独立的表
- 时间戳建议使用 TIMESTAMP 类型存储;
- IPV4 地址建议用INT UNSIGNED 类型存储;
- 性别等非是既非的逻辑,建议采用TINYINT 存储,而不是CHAR(1);
- 存储较长文本内容时,建议采用JSON/BSON 格式存储.
InnoDB存储架构
- 缓冲池:buffer pool,由innodb_pool_size配置,
- 是栈最大块内存的部分,用来存放各种数据的缓存;
- innodb 将数据库文件按page(16K)读取到缓冲池,然后按最少使用(LRU)算法来保留缓存数据;数据文件修改时,先修改缓存池中的页(即脏页),然后按一定频率将藏也刷新到文件;
- 缓冲池中的数据页类型有:
- 索引页
- 数据页
- undo页
- 插入缓冲(insert buffer)
- 自适应哈希索引
- 锁信息
- 数据字典信息
- 重做日志缓冲区:redo log buffer
- 作用: 将重做日志先放入这个区,然后按一定的频率将其刷新到重做日志文件(redo log),一般情况下每秒就会刷新一次.
- 配置: 一般不需配置很大.
- Redo Log 存储的是已经提交的事务,Undo Log存储的是未提交的事务
- 额外内存池:additional memory pool
- 作用 : innodb 申请缓冲池(buffer pool),但是每个缓冲池中的页缓冲有对应的缓冲控制对象(buffer control block),这些对象记录LRU,锁,等待等信息,这些对象的内存需要多额外内存池中申请;因此当buffer pool较大时,也许相应增大该值.
- 双重写: double write
- 描述:innodb引擎的关键特性之一;两次写保证的时innodb的可靠性,插入缓冲保证的是性能;
- 数据文件的逻辑结构:
- 页 page 16K
- 区 extent 1M
- 段 seg 2M
- 主要作用:针对写磁盘文件失败(由于各种原因)时,通过页的副本还原该页,在进行redo回复,保证数据的完整性.
- 工作原理:由两部分组成,一部分时内存中的double write buffer,大小为2M,另一部分是磁盘上共享表空间中连续的两个区 extend, 2M;
- 刷新脏页时,先做三步工作
- 先将脏页拷贝到内存的double write buffer
- 通过该buffer 两次写入(每次写入 1 M) 到共享表空间,然后马上调用fsync函数同步磁盘;这个过程时顺序写的,开销不大 ;
- 再将该buffer中的页写入各个表空间文件中,此过程中的写入时离散的。
InnoDB 相关的磁盘文件
在InnodDB 存储引擎中,默认表空间文件时ibdata1,初始化为10M,且可以扩展.(通过自动扩展机制).