你的 SQL 語句為什么變“慢”了
當內存數(shù)據(jù)頁跟磁盤數(shù)據(jù)頁內容不一致的時候,我們稱這個內存頁為“臟頁”姨伤。內存數(shù)據(jù)寫入到磁盤后哨坪,內存和磁盤上的數(shù)據(jù)頁的內容就一致了,稱為“干凈頁”乍楚。
MySQL 偶爾“抖”一下的那個瞬間当编,可能就是在刷臟頁(flush)。
- 第一種場景,redo log 寫滿了徒溪。這時候系統(tǒng)會停止所有更新操作忿偷,把 checkpoint 往前推進,對應的所有臟頁都 flush 到磁盤上臊泌。
- 第二種場景,系統(tǒng)內存不足鲤桥。當需要新的內存頁,而內存不夠用的時候缺虐,就要淘汰一些數(shù)據(jù)頁芜壁,空出內存給別的數(shù)據(jù)頁使用。如果淘汰的是“臟頁”,就要先將臟頁寫到磁盤慧妄。
- 第三種場景,認為系統(tǒng)“空閑”的時候,只要有機會就刷一點“臟頁”顷牌。
- 第四種場景, MySQL 正常關閉的情況塞淹,把內存的臟頁都 flush 到磁盤上窟蓝。
你要正確地告訴 InnoDB 所在主機的 IO 能力,這樣 InnoDB 才能知道需要全力刷臟頁的時候饱普,可以刷多快运挫。
fio -filename=$filename -direct=1 -iodepth 1 -thread -rw=randrw -ioengine=psync -bs=16k -size=500M -numjobs=10 -runtime=10 -group_reporting -name=mytest
然后設置 innodb_io_capacity的值。
平時要多關注臟頁比例套耕,不要讓它經常接近 75%谁帕。
mysql> select VARIABLE_VALUE into @a from global_status where VARIABLE_NAME = 'Innodb_buffer_pool_pages_dirty';
select VARIABLE_VALUE into @b from global_status where VARIABLE_NAME = 'Innodb_buffer_pool_pages_total';
select @a/@b;