暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL DBA的自我修养(二)

记忆乘凉 2016-12-15
364

11:如何调整内存参数 innodb_old_blocks_pct,以及 innodb_old_blocks_pct的意义?用来避免什么问题?innodb_old_blocks_pct 如何通过相关的指标值来确认这几个参数,是否需要调整?

innodb_old_blocks_pct代表LRU列表中midpoint的位置,也是冷端所占的比例。可以在配置文件my.cnf中添加innodb_old_blocks_pct=20进行修改。

innodb_old_blocks_time表示页读取到midpoint位置后需要等待多久才会被加入到热端。

使用show engine innodb status \G;这个命令可以查看相关信息


Pagesmade young有多少页刷到热端 ;not young有多少页没有刷到热端

youngs/s每秒有多少页刷到热端;non-youngs/s每秒有多少页没被刷到热端

non-young很高的原因:

1.可能存在严重的全表扫描

2.可能是pct设置过小

3.可能是time设置过大

pages madeyoung很高的原因:

1.pct过大

2.time过小

Bufferpool hit rate 该值表示缓冲池的命中率,该值不应小于95%,如果小于,该观察LRU列表是否被污染。

 

12:关于 log buffer 调整成 100M 的理论依据

适合调整成100M的场景:

1.内存空间足够大

2.操作频繁,日志产量大

默认只有1M,根据刷新的机制,如果在大文本等情况下写入频繁,就会造成刷新频繁产生额外的IO,但IO线程是有限的,一旦发生阻塞现象造成log buffer写满,会影响数据库的正常运行,甚至宕机。可以参照Innodb_log_waits这个值,如果它不是0,就需要增加innodb_log_buffer_size了。

 

13:描述 change buffer 的作用,确认 change buffer 占用的大小,确认 change buffer 带来的效果,分析 change buffer 占用过大,或者效果不明显的原因。

Change buffer的主要目的是将对二级索引的数据操作缓存下来,以此减少二级索引的随机IO,并达到操作合并的效果。一般DML操作过多的情况下,就会产生索引的随机IO过多的问题。在MySQL5.5之前的版本中,由于只支持缓存insert操作,所以最初叫做insert buffer,只是后来的版本中支持了更多的操作类型缓存,包括 insert bufferdelete bufferpurge buffer,才改叫change bufferChange buffer innodb buffer pool 中开辟内存空间 ,物理上存储在共享表空间中。

innodb_change_buffer_max_size确定change buffer 最大使用内存(默认25,最大50

如何解决索引的离散读问题(因为DML造成的):

1.尽量调大change buffer的大小

2.适度建立索引 ,单表索引数不要过多,建议使用联合索引

 

Change buffer: size 1, free list len 0, segsize 2, 0 merges

merged operations:   被合并的操作

 insert 0, delete mark 0, delete 0

discarded operations: 消失的操作

 insert0, delete mark 0, delete 0

seg size(表示change buffer 占用内存的大小 2*16k

 

change buffer 过大且增长迅猛的原因:

1.数据库的索引列DML操作频繁,或者出现批量操作

2.表的索引过多

3.有一些索引几乎不会被使用

 

14:调整 change buffer 占用空间大小,以及调整依据,调整只是对 insert 进行合并(merge)。

附加一个问题:怎么判断一个表上索引的数量,以及在那些列上建立索引(查询数据字典)?

innodb_change_buffer_max_size=50 该大小与buffer pool 相关。

索引被缓存的条件:

1.用户设置了选项innodb_change_buffering

2.只有叶子节点才会去考虑是否使用change buffer

3.对于聚集索引,不可以缓存操作;

4.对于唯一二级索引(unique key),由于索引记录具有唯一性,因此无法缓存插入操作,但可以缓存删除操作;

5.表上没有flush 操作,例如执行flush table for export时,不允许对表进行 change buffer 缓存

 

被合并的条件:

1.用户线程选择二级索引进行数据查询,这时候必须要读入二级索引页,相应的change buffer需要mergePage中。

2.当尝试缓存插入操作时,如果预估page的空间不足,可能导致索引分裂,则定位到尝试缓存的page nochange buffer btree中的位置,最多merge 8pagemerge方式为异步,即发起异步读索引页请求。

3.若当前change buffer  tree size 超过change buffer->max_size + 10时,执行一次同步的mergemergepage no为随机定位的cursor,最多一次merge 8page,同时放弃本次缓存。

4.若本次插入change buffer操作可能产生change buffer btree索引分裂时:

当前change buffer size< change buffer max_size 不做处理;

当前change buffer size>= change buffer max_size + 5 时,执行一次同步change buffer merge,位置随机;

当前Change buffer size介于change buffer max_size change buffer max_size +5 之间时。执行一次异步change buffer merge,位置随机。

5.后台master线程发起merge

master线程有三种工作状态:

IDLE:实例处于空闲状态,以100%io capacity来作merge操作,相当于一次mergepage数等于innodb_io_capacity

ACTIVE:实例处于活跃状态,这时候会以如下算法计算需要mergepage数,默认merge的数量为innodb_io_capacity5%,如果当前change bufferbtree size超过最大值的一半,则尝试多做一些merge操作。

SHUTDOWN:当执行slow shutdown时,会强制做一次全部的change buffer merge

6.对某个表执行flush table 操作时,会触发对该表的强制change buffer merge,例如执行:

 flush table tbname for export;

 flush table tbname with read lock;

实际上强制change buffermerge主要是为flush forexport准备的,当执行该命令后,为了保证能安全的将ibd拷贝到其他实例上, 需要对该表应用全部的change buffer 缓存。

show index from tblname;或者show keys from tblname;可以查看表的索引信息

命令查询的信息:

Table(表的名称)

Non_unique(是否唯一)

Key_name(索引名称)

Seq_in_index(索引的序号)

Column_name(列名称)

Collation(列的存储方式,有值‘A’(升序)或NULL(无分类))

Cardinality(索引中唯一值的数目的估计值。通过运行ANALYZE TABLEmyisamchk -a可以更新。基数根据被存储为整数的统计数据来计数,所以即使对于小型表,该值也没有必要是精确的。基数越大,当进行联合时,MySQL使用该索引的机 会就越大)

Sub_part(如果列只是被部分地编入索引,则为被编入索引的字符的数目。如果整列被编入索引,则为NULL。)

Packed(指示关键字如何被压缩。如果没有被压缩,则为NULL。)

Null(判断列是否含有NULL

Index_type(用过的索引方法:BTREE, FULLTEXT, HASH, RTREE

 

15:描述一下索引的工作过程,适合使用的场合,描述一下索引如何结合 insert buffer 进行数据访问。如何建立索引,确认索引是否生效。

索引的工作过程:索引是对记录按照多个字段进行排序的一种方式。对表中的某个字段建立索引会创建另一种数据结构,其中保存着字段的值,每个值又指向与它相关的记录。这种索引的数据结构是经过排序的,因而可以对其执行二分查找。 假设使用线性查找搜索id字段共100万个数据块,且这个字段是键字段(每个字段的值唯一),需要访问 N/2 500 000个数据块才能找到目标值。不过,因为这个字段是经过排序的,所以可以使用二分查找法,而这样平均只需要访问log2 1000000 = 19.93 = 20 个块。显然,这会给性能带来极大的提升。辅助索引比主键索引多一倍的IO,因为需要回表进行查询具体数据。

适合的场合:

1.建索引的列应该是热条件。

2.建索引的列的唯一性要高。

3.在经常使用范围和排序的列上可以建立索引。

4.在经常做表连接的列上可以建立索引。

5.where条件中经常出现的列上可以建立索引。

6.使用函数和运算的列不会走索引。

7.在经常查询的多个列上建立复合索引,但要按频率来确定索引的顺序。

8.数据量小的情况下可以使用覆盖索引避免回表。

9.对于长字段的列不使用索引,但MySQL支持前缀索引。

 

insertbuffe带来的问题:

1.磁盘上的索引在正常工作期间,索引数据和表数据有可能是不一致的;

2.通过索引进行数据查询时,需要先将索引页读取到内存,再将change buffer中的相关数据合并到索引页中,保证数据一致性,再进行进一步的查询;

3.数据库崩溃后,要使索引能够正常使用,需要磁盘上的索引数据+change buffer中的索引数据+内存中的changebuffer 对应的redo log进行恢复。

建立索引: CREATE [UNIQUE|CLUSTERED]INDEX INDEX_NAME ON TABLE_NAME(PROPERTY_NAME)

要查看索引是否生效,可以通过explain执行计划查看相应的SQL进行分析查询。

 

16:描述一下 double write 解决的场景,工作过程,如何打开和关闭这个功能,通过这个功能对应的指标(status),来确认系统写操作是否有压力,并做出解释.

 

innodb存储引擎正在写入某页到表中的时候,如果这个时候发生数据库宕机,就可能出现这个页只写了一部分的现象,比如16K可能只写了4K,这种情况被称为部分写失效,会导致数据丢失。利用double write就可以解决这个问题,它保证了数据页的可靠性。

工作过程:double write 具有两个部分,一个是在内存中doublewrite buffer,一个是在共享表空间里的连续的128个页,两部分大小都为2MB。刷新脏页时,会先将脏页写到doublewrite buffer中,然后分两次每次1MB顺序的写入到共享表空间中,完成这个操作后,再将脏页通过fsync函数同步到磁盘中。


innodb_doublewrite # 该参数为double write 的开关


Innodb_dblwr_pages_written表示通过double write写入的页数

Innodb_dblwr_writes 表示实际写入的次数

因为double write是按照1MB的大小写入的,所以一次最多写64页。也就是说这两个参数的比如果是64:1的话表示每次都写满,代表着系统写的压力很高;如果远小于64:1的话就说明系统写入压力不高。

 

17:通过索引来访问表,主要资源消耗分析,尤其在什么情况下,资源消耗特别厉害(多行的时候)。

  1. 索引页也是B+树结构,通过索引会消耗树高

  2. 走非聚集索引时,会进行回表,消耗IO

  3. 通过索引进行group byorder by时会进行排序,消耗CPU

  4. 范围查找同样需要排序,也会消耗CPU

 

18:自适应哈希索引要降低的是哪个资源消耗,描述其工作过程,理解哈希运算,通过读取相关指标,来确认这个功能效果,学会打开和关闭这个功能。

哈希是一种非常快的查找方法,其时间复杂度为O(1)。哈希算法是由哈希表实现的,哈希表也称散列表是直接寻址表改进得来,在哈希表中,有关键字域和元素链表,每一个关键字都映射着链表中的某一个元素,实现数据查询。在innodb中,哈希函数就采用了除法散列的方式,哈希表都会有一个指向相同哈希函数值的页,其关键字则是表空间space_id左移20位加上自身space_id和数据页偏移量offset的值。

自适应哈希索引可以降低树高消耗的问题,访问树高一般是消耗内存,基本上不会造成性能影响。

工作过程:innodb存储引擎会监控表上各索引页的情况,会自动根据访问的频率和模式来自动的为某些热点页建立哈希索引。其规则有三点:

  1. 条件中使用等值查询即=

  2. 以同一模式访问同一数据100

  3. 以同一模式访问同一数据N次,N=页中记录/16


可以通过hashsearches/snon-hashsearches/s大概了解AHI的效率,据官方文档显示,启用该功能后,IO速度可以提升2倍,副主索引的连接操作性能可以提升5倍。

Innodb_adaptive_hash_index 该参数为AHI的开关,默认为开启状态。

 

19:描述异步 io 的好处,如何确认打开异步 io(操作系统层面确认异步 io 开启,linux 默认开启,数据库层面开启 参数:| innodb_use_native_aio | ON

Sync IO:每进行一次IO操作,需要等待整个操作流程结束才可以进行下一次的操作。

AIO:异步IO可以发出一个IO请求后立即发出另一个IO请求,都发送完成后再等待其操作结束。它还可以进行IO merge操作,会将相同的多个IO合并为1IO,可以提高IOPS性能。

如果是进行像全文查询这样的操作,异步IO就可以解决死等的问题,大大提高了磁盘的操作性能。官方文档中,启用该功能可以提高恢复速度75%。数据库开启该功能需要操作系统的支持,windowsLinux支持,mac osx不支持。

 

20:描述一下 innodb_flush_neighbors 的功能,以及学会如何打开和关闭。

刷新邻接页工作原理:当写一个脏页到磁盘时,innodb存储引擎会检测该页所在区的所有页,如果有脏页便会一起写入,

优点:利用AIO将多个IO操作合并成一个,提高IO和效率。

缺点:一般进行写入的脏页是比较冷的,进行邻接页写入的时候有可能会把比较热的页一起写入,那比较热的页可能很快又会脏,反而降低了效率。

是否开启该参数应参考实际情况,主要是磁盘的选型和IOPS的性能,一般建议关闭该功能。


文章转载自记忆乘凉,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论