一,Mysql体系结构
数据库 & 实例
数据库:物理操作系统文件和其他形式文件类型的集合(frm、MYD、ibd)
实例:Mysql数据库和后台线程以及一个共享内存区域组成。 数据库实例才是真正用于操作数据库文件的!---表现形式:进程
关系:通常情况下可以认定为一个数据库是对照一个实例的,但是也可以有一个数据对应多个实例的情况
Mysql组成部分:
连接池组件、管理服务和工具组件、SQL接口组件、查询分析器组件、优化器组件、缓冲组件、插件式存储引擎、物理文件
Mysql存储引擎:
1,InnoDB存储引擎(高性能、高可用、高可扩展)
特征:行锁设计、支持外键、非锁定读(默认读取不会产生锁)
2, MyISAM存储引擎
特征:不支持事务、表锁设计、支持全文索引。且缓冲池只缓存了索引文件,不缓冲数据文件
组成: MYD & MYI
MYD用来存放数据文件
MYI用来存放索引文件
3, NDB引擎(集群引擎)
4,Memory存储引擎: 表中数据存放内存、临时数据临时表、采用哈希索引方式存储,存储速度很快
5,Archive存储引擎: 存储压缩引擎,只支持select & insert操作
6, FeDerated存储引擎: 表数据存放非本地,远程连接数据库类引擎
7,Maria存储引擎: 设计上用意取代MyISAM,支持事务
常用连接方式:
TCP/IP连接方式: mysql -h host -u david -p
命名管道和共享内存: 配置开启 --enable-named-pipe
UNIX域套接字 --socket=/tmp/mysql.sock
--相关指令:
Mysql进程情况查看: ps -ef|grep mysqldb
Mysql查看配置文件位置信息: mysql --help | grep my.cnf (按照从左到右 的顺序覆盖读取)
Mysql数据库文件存放路径: show variables like 'datadir'
Mysql当前使用的引擎: show engines
创建表指定使用引擎: create table tableName Engine=XXX
二、InnerDB体系架构
内存池:
InnerDB有很多的内存块,可以认定为这些内存块组成了内存池
作用:
1,维护所有的进程、线程需要访问的多个内部数据结构
2,缓存磁盘上的数据,方便快速的读取,同时在对磁盘修改的之前进行缓存
3,重做日志缓冲
1,缓冲池
a,基于磁盘的数据,从磁盘中读取到的页会先放在缓冲池中,下一次重复读取时从缓冲池中读取,如果缓冲池没有
从磁盘数据页中读取到缓冲池,减少读取磁盘的次数,减少IO次数提高数据库性能
b,缓冲池的大小==》直接影响了数据库的整体性能
c,缓冲池实例通常情况下也会有多个,这里类似Redis的做法,通过hash索引判断读取到的数据应该录入到哪一个缓冲池中
多个缓冲池实例就好比Java中的HashMap数组定位的模式,多个缓冲池,在集群的情况下,平均的分配做到负载均衡,若
宕机数据丢失范围减少。默认情况下缓冲池实例为一个。
缓冲池中的数据页类型
1,索引页
2,数据页
3,undo页
4,插入缓冲
5,自适应哈希索引
6,Innodb存储的锁信息
7,数据字典信息
缓冲池与LRU算法:
缓冲池通过LRU算法来进行管理,简单的来说使用频繁的数据放在LRU列表的前端,使用少的数据放在尾端,当缓冲池满了,
不能读取数据的时候,首先释放LRU尾端的数据
LRU算法与优化:
I,通常情况下一个数据被访问,只是因为当前场景因素并不是热点数据,那么被放到LRU列表的前列,就起不到应有的作用,
相反还可能会导致热点数据被频繁刷出,所以Mysql对于访问的数据并不是直接刷到LRU列表的前列,而是放在LRU列表midPoint
位置,这个诶之的长度默认为LRU长度的5/8处。,通过innodeb_old_blocks_pct控制,但是问题是被访问了多少次才能被
当做成热点数据?通过设值innodb_old_blocks_pct的大小来设访问次数,默认次数为20次
II,为了防止无数据内存页一开始大量的创建,LRU队列一开始空的,在Free列表中存放着可以使用的页,每次从Free列表中查找空闲的
页,然后存入数据放入到LRU列表中去。midpoint之前的为new列表,之后的为old列表
III,对于缓冲池中页大小申请,向上申请与拆分,需要一个4kb的页,但是Free列表只有16kb的页,则将16kb的页分成 8kb+4kb+4kb的模式提供
页的上一层是归属于某个表空间,表空间为NULL,表示该页归属于系统表空间
通过 show engine innodb status
例子:
Buffer Pool size 327679
Free buffers 0 --> 无空闲页
Database pages 307717 -->LRU列表中页的数量
Old database pages 113570 --> old列表中页的数量
Modified db pages 24673 --> 脏页的数据
...
Pages made young 6448526, not young 0 --> 移动到LRU列表前端的页是为6448526,也就是数据转换为热点数据的次数,代表的是一个状态值非实时正在进行的值
Buffer pool hit rate 1000/1000 ...-->缓冲池命中率,通常情况下不应该小于百分之95%
2,重做日志缓冲池
3,额外的内存池(内存管理等等)
后台线程:
主要作用:负责刷新内存池中的数据,保证缓冲池中的内存缓存是最近的数据
后台线程:(多线程模型)
1,master Thread
负责缓冲池中的数据 异步 刷新,保证数据的一致性(包括脏页的刷新,合并插入缓冲)
2,IO Thread(读写线程)
使用AIO的方式处理IO请求,提高数据库的性能
分4种类线程: write,read,insert buffer, log IO Thread
3,Purge Thread
事务提交后,回收undo页,默认数量为1,可以设置多个提高Undo页回收效率
4,Page Cleaner Thread
将之前版本的脏页刷新到单独的线程中执行、减轻Master Thread 的压力
--相关指令:
查看IO Thread各类型线程的数量: show variables like 'innodb_%io_threads'
观察IO Thread使用状况: show engine innodb status(显示的不是当前时间的状态,而是过去某个时间段的时间误差允许范围内的状态)
查看缓冲池大小: show variables like 'innodb_buffer_pool_size'
查看缓冲池实例个数: show variables like 'innodb_buffer_pool_instances'