當前位置:首頁 » 硬碟大全 » MySQL磁碟頁和緩存區
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

MySQL磁碟頁和緩存區

發布時間: 2023-06-16 16:58:49

A. Mysql緩存

mysql 開啟查詢緩存可以有兩種方法來開啟一種是使用set命令來進行開啟,另一種是直接修改my.ini文件來直接設置都是非常的簡單的哦。

開啟緩存,設置緩存大小,具體實施如下:

windows下是my.ini,linux下是my.cnf;

在配置文件的最後追加上:

需要重啟mysql生效;

b) 開啟緩存,兩種方式:

a)使用mysql命令:

如果報錯:

Query cache is disabled; restart the server with query_cache_type=1 to enable it,還是老老實實的該配置文件,然後重啟吧,原因如下:

查看是否設置成功

show variables like "%query_cache%" 查看是否設置成功:

當然如果你的數據表有更新怎麼辦,沒關系mysql默認會和這個表有關系的緩存刪掉,下次查詢的時候會直接讀表然後再緩存

下面是一個簡單的例子:

以上的相關內容就是對mysql緩存查詢和設置的介紹,望你能有所收獲。

一般,我們會把 query_cache_type 設置為 ON,默認情況下應該是ON

query_cache_type有3個值 0代表關閉查詢緩存OFF,1代表開啟ON,2(DEMAND)代表當sql語句中有SQL_CACHE關鍵詞時才緩存,如:

這樣 當我們執行 select id,name from tableName; 這樣就會用到查詢緩存。

①在 query_cache_type 打開的情況下,如果你不想使用緩存,需要指明
select sql_no_cache id,name from tableName;
②當sql中用到mysql函數,也不會緩存

當然也可以禁用查詢緩存: mysql> set session query_cache_type=off;

上面的顯示,表示設置查詢緩存是可用的。

表示查詢緩存大小,也就是分配內存大小給查詢緩存,如果你分配大小為0,
那麼 第一步 和 第二步 起不到作用,還是沒有任何效果。

上面是 mysql6.0設置默認的,之前的版本好像默認是0的,那麼就要自己設置下。

設置

這里是設置1M左右,900多K。

再次查看下:

顯示我們設置新的大小,表示設置成功。

例如: 如果查詢結果很大, 也緩存????這個明顯是不可能的。
MySql 可以設置一個最大的緩存值,當你查詢緩存數結果數據超過這個值就不會
進行緩存。預設為1M,也就是超過了1M查詢結果就不會緩存。

這個是默認的數值,如果需要修改,就像設置緩存大小一樣設置,使用set

重新指定大小。
好了,通過4個步驟就可以 打開了查詢緩存,具體值的大小和查詢的方式 這個因不同
的情況來指定了。
mysql查詢緩存相關變數

MySQL 提供了一系列的 Global Status 來記錄 Query Cache 的當前狀態,具體如下:

Qcache_free_blocks:目前還處於空閑狀態的 Query Cache 中內存 Block 數目
Qcache_free_memory:目前還處於空閑狀態的 Query Cache 內存總量
Qcache_hits:Query Cache 命中次數
Qcache_inserts:向 Query Cache 中插入新的 Query Cache 的次數,也就是沒有命中的次數
Qcache_lowmem_prunes:當 Query Cache 內存容量不夠,需要從中刪除老的 Query Cache 以給新的 Cache 對象使用的次數
Qcache_not_cached:沒有被 Cache 的 SQL 數,包括無法被 Cache 的 SQL 以及由於 query_cache_type 設置的不會被 Cache 的 SQL
Qcache_queries_in_cache:目前在 Query Cache 中的 SQL 數量
Qcache_total_blocks:Query Cache 中總的 Block 數量

檢查是否從查詢緩存中受益的最簡單的辦法就是檢查緩存命中率
當伺服器收到SELECT 語句的時候,Qcache_hits 和Com_select 這兩個變數會根據查詢緩存
的情況進行遞增
查詢緩存命中率的計算公式是:Qcache_hits/(Qcache_hits + Com_select)。

query_cache_min_res_unit的配置是一柄」雙刃劍」,默認是4KB,設置值大對大數據查詢有好處,但如果你的查詢都是小數據 查詢,就容易造成內存碎片和浪費。

查詢緩存碎片率 = Qcache_free_blocks / Qcache_total_blocks * 100%

如果查詢緩存碎片率超過20%,可以用FLUSH QUERY CACHE整理緩存碎片,或者試試減小query_cache_min_res_unit,如果你的查詢都是小數據量的話。

查詢緩存利用率 = (query_cache_size - Qcache_free_memory) / query_cache_size * 100%

查詢緩存利用率在25%以下的話說明query_cache_size設置的過大,可適當減小;查詢緩存利用率在80%以上而且 Qcache_lowmem_prunes > 50的話說明query_cache_size可能有點小,要不就是碎片太多。

查詢緩存命中率 = (Qcache_hits - Qcache_inserts) / Qcache_hits * 100%

示例伺服器 查詢緩存碎片率 = 20.46%,查詢緩存利用率 = 62.26%,查詢緩存命中率 = 1.94%,命中率很差,可能寫操作比較頻繁吧,而且可能有些碎片。

查詢緩存可以看做是SQL文本和查詢結果的映射。如果第二次查詢的SQL和第一次查詢的SQL完全相同(注意必須是完全相同,即使多一個空格或者大小寫不同都認為不同)且開啟了查詢緩存,那麼第二次查詢就直接從查詢緩存中取結果,可以通過下面的SQL來查看緩存命中次數(是個累加值):

另外即使完全相同的SQL,如果使用不同的字元集、不同的協議等也會被認為是不同的查詢而分別進行緩存。

在表的結構或數據發生改變時,查詢緩存中的數據不再有效。有這些INSERT、UPDATE、 DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE會導致緩存數據失效。所以查詢緩存適合有大量相同查詢的應用,不適合有大量數據更新的應用。

可以使用下面三個SQL來清理查詢緩存:

1、FLUSH QUERY CACHE; // 清理查詢緩存內存碎片。

2、RESET QUERY CACHE; // 從查詢緩存中移出所有查詢。

3、FLUSH TABLES; //關閉所有打開的表,同時該操作將會清空查詢緩存中的內容。

Query Cache是MySQL Server層的一個非常好的特性,對於小數據集或訪問量非常集中的應用場景,有非常好的性能提升,但是Query Cache引入了一些新的問題,而且大部分場景下比較雞肋,官方打算棄用了

參考:
https://www.cnblogs.com/wangzhuxing/p/5223881.html
https://www.cnblogs.com/lixiuran/archive/2014/03/08/3588654.html

B. mysql 如何分配內存

我們仍然使用兩個會話,一個會話 run,用於運行主 SQL;另一個會話 ps,用於進行 performance_schema 的觀察:

主會話線程號為 29,

可以看到寫入的線程是 page_clean_thread,是一個刷臟操作,這樣就能理解數據為什麼是慢慢寫入的。

也可以看到每個 IO 操作的大小是 16K,也就是刷數據頁的操作。


結論:

我們可以看到,

1. MySQL 會基本遵守 max_heap_table_size 的設定,在內存不夠用時,直接將表轉到磁碟上存儲

2. 由於引擎不同(內存中表引擎為 heap,磁碟中表引擎則跟隨 internal_tmp_disk_storage_engine 的配置),本次實驗寫磁碟的數據量和實驗 05中使用內存的數據量不同。

3. 如果臨時表要使用磁碟,表引擎配置為 InnoDB,那麼即使臨時表在一個時間很短的 SQL 中使用,且使用後即釋放,釋放後也會刷臟頁到磁碟中,消耗部分 IO。

C. mysql連接數,緩存區大小,連接超時時間如何設置呢

在配置文件my.ini中加上相應語句即可如:max_connections=100

D. 緩沖區和磁碟緩存,分別是啥含義我怎麼覺得差不多呢

一般編程所說的緩沖區指的是內存緩沖區,這是程序所設置的一塊內存區域,用來暫存從其他設備讀入的數據或即將寫入其他設備的數據。
硬碟緩沖區有兩種:
一是上面說的內存緩沖區,只是它是專門為讀取或寫入硬碟而設置的,因此可以簡稱為硬碟緩沖區。這個的例子是很多下載軟體如迅雷中都有的磁碟緩存設置,即先將數據下載到內存中緩存起來,達到一定數量後再寫到硬碟里,從而減少了讀寫硬碟的次數,達到保護硬碟的目的。
另一種是硬碟本身攜帶的一塊隨機存儲器,大小通常為數MB到幾十MB,這個是固化在硬碟內部的。它的作用和前一種類似,也是為了增加讀寫效率和保護硬碟,只是它是系統中所有程序所共用的,並且除了驅動程序外,通常的程序無法控制它,因此很多程序還會從內存中再設置一塊緩存供自己使用。

E. MySQL性能調優 – 你必須了解的15個重要變數

前言:

MYSQL 應該是最流行了 WEB 後端資料庫。雖然 NOSQL 最近越來越多的被提到,但是相信大部分架構師還是會選擇 MYSQL 來做數據存儲。本文作者總結梳理MySQL性能調優的15個重要變數,又不足需要補充的還望大佬指出。

1.DEFAULT_STORAGE_ENGINE

如果你已經在用MySQL 5.6或者5.7,並且你的數據表都是InnoDB,那麼表示你已經設置好了。如果沒有,確保把你的表轉換為InnoDB並且設置default_storage_engine為InnoDB。

為什麼?簡而言之,因為InnoDB是MySQL(包括Percona Server和MariaDB)最好的存儲引擎 – 它支持事務,高並發,有著非常好的性能表現(當配置正確時)。這里有詳細的版本介紹為什麼

2.INNODB_BUFFER_POOL_SIZE

這個是InnoDB最重要變數。實際上,如果你的主要存儲引擎是InnoDB,那麼對於你,這個變數對於MySQL是最重要的。

基本上,innodb_buffer_pool_size指定了MySQL應該分配給InnoDB緩沖池多少內存,InnoDB緩沖池用來存儲緩存的數據,二級索引,臟數據(已經被更改但沒有刷新到硬碟的數據)以及各種內部結構如自適應哈希索引。

根據經驗,在一個獨立的MySQL伺服器應該分配給MySQL整個機器總內存的80%。如果你的MySQL運行在一個共享伺服器,或者你想知道InnoDB緩沖池大小是否正確設置,詳細請看這里。

3.INNODB_LOG_FILE_SIZE

InnoDB重做日誌文件的設置在MySQL社區也叫做事務日誌。直到MySQL 5.6.8事務日誌默認值innodb_log_file_size=5M是唯一最大的InnoDB性能殺手。從MySQL 5.6.8開始,默認值提升到48M,但對於許多稍繁忙的系統,還遠遠要低。

根據經驗,你應該設置的日誌大小能在你伺服器繁忙時能存儲1-2小時的寫入量。如果不想這么麻煩,那麼設置1-2G的大小會讓你的性能有一個不錯的表現。這個變數也相當重要,更詳細的介紹請看這里。

當然,如果你有大量的大事務更改,那麼,更改比默認innodb日誌緩沖大小更大的值會對你的性能有一定的提高,但是你使用的是autocommit,或者你的事務更改小於幾k,那還是保持默認的值吧。

4.INNODB_FLUSH_LOG_AT_TRX_COMMIT

默認下,innodb_flush_log_at_trx_commit設置為1表示InnoDB在每次事務提交後立即刷新同步數據到硬碟。如果你使用autocommit,那麼你的每一個INSERT, UPDATE或DELETE語句都是一個事務提交。

同步是一個昂貴的操作(特別是當你沒有寫回緩存時),因為它涉及對硬碟的實際同步物理寫入。所以如果可能,並不建議使用默認值。

兩個可選的值是0和2:

* 0表示刷新到硬碟,但不同步(提交事務時沒有實際的IO操作)

* 2表示不刷新和不同步(也沒有實際的IO操作)

所以你如果設置它為0或2,則同步操作每秒執行一次。所以明顯的缺點是你可能會丟失上一秒的提交數據。具體來說,你的事務已經提交了,但伺服器馬上斷電了,那麼你的提交相當於沒有發生過。

顯示的,對於金融機構,如銀行,這是無法忍受的。不過對於大多數網站,可以設置為innodb_flush_log_at_trx_commit=0|2,即使伺服器最終崩潰也沒有什麼大問題。畢竟,僅僅在幾年前有許多網站還是用MyISAM,當崩潰時會丟失30s的數據(更不要提那令人抓狂的慢修復進程)。

那麼,0和2之間的實際區別是什麼?性能明顯的差異是可以忽略不計,因為刷新到操作系統緩存的操作是非常快的。所以很明顯應該設置為0,萬一MySQL崩潰(不是整個機器),你不會丟失任何數據,因為數據已經在OS緩存,最終還是會同步到硬碟的。

5.SYNC_BINLOG

已經有大量的文檔寫到sync_binlog,以及它和innodb_flush_log_at_trx_commit的關系,下面我們來簡單的介紹下:

a) 如果你的伺服器沒有設置從伺服器,而且你不做備份,那麼設置sync_binlog=0將對性能有好處。

b) 如果你有從伺服器並且做備份,但你不介意當主伺服器崩潰時在二進制日誌丟失一些事件,那麼為了更好的性能還是設置為sync_binlog=0.

c) 如果你有從伺服器並且備份,你非常在意從伺服器的一致性,以及能及時恢復到一個時間點(通過使用最新的一致性備份和二進制日誌將資料庫恢復到特定時間點的能力),那麼你應該設置innodb_flush_log_at_trx_commit=1,並且需要認真考慮使用sync_binlog=1。

問題是sync_binlog=1代價比較高 – 現在每個事務也要同步一次到硬碟。你可能會想為什麼不把兩次同步合並成一次,想法正確 – 新版本的MySQL(5.6和5.7,MariaDB和Percona Server)已經能合並提交,那麼在這種情況下sync_binlog=1的操作也不是這么昂貴了,但在舊的mysql版本中仍然會對性能有很大影響。

6.INNODB_FLUSH_METHOD

將innodb_flush_method設置為O_DIRECT以避免雙重緩沖.唯一一種情況你不應該使用O_DIRECT是當你操作系統不支持時。但如果你運行的是Linux,使用O_DIRECT來激活直接IO。

不用直接IO,雙重緩沖將會發生,因為所有的資料庫更改首先會寫入到OS緩存然後才同步到硬碟 – 所以InnoDB緩沖池和OS緩存會同時持有一份相同的數據。特別是如果你的緩沖池限制為總內存的50%,那意味著在寫密集的環境中你可能會浪費高達50%的內存。如果沒有限制為50%,伺服器可能由於OS緩存的高壓力會使用到swap。

簡單地說,設置為innodb_flush_method=O_DIRECT。

7.INNODB_BUFFER_POOL_INSTANCES

MySQL 5.5引入了緩沖實例作為減小內部鎖爭用來提高MySQL吞吐量的手段。

在5.5版本這個對提升吞吐量幫助很小,然後在MySQL 5.6版本這個提升就非常大了,所以在MySQL5.5中你可能會保守地設置innodb_buffer_pool_instances=4,在MySQL 5.6和5.7中你可以設置為8-16個緩沖池實例。

你設置後觀察會覺得性能提高不大,但在大多數高負載情況下,它應該會有不錯的表現。

對了,不要指望這個設置能減少你單個查詢的響應時間。這個是在高並發負載的伺服器上才看得出區別。比如多個線程同時做許多事情。

8.INNODB_THREAD_CONCURRENCY

InnoDB有一種方法來控制並行執行的線程數 – 我們稱為並發控制機制。大部分是由innodb_thread_concurrency值來控制的。如果設置為0,並發控制就關閉了,因此InnoDB會立即處理所有進來的請求(盡可能多的)。

在你有32CPU核心且只有4個請求時會沒什麼問題。不過想像下你只有4CPU核心和32個請求時 – 如果你讓32個請求同時處理,你這個自找麻煩。因為這些32個請求只有4 CPU核心,顯然地會比平常慢至少8倍(實際上是大於8倍),而然這些請求每個都有自己的外部和內部鎖,這有很大可能堆積請求。

下面介紹如何更改這個變數,在mysql命令行提示符執行:

對於大多數工作負載和伺服器,設置為8是一個好開端,然後你可以根據伺服器達到了這個限制而資源使用率利用不足時逐漸增加。可以通過show engine innodb statusG來查看目前查詢處理情況,查找類似如下行:

9.SKIP_NAME_RESOLVE

這一項不得不提及,因為仍然有很多人沒有添加這一項。你應該添加skip_name_resolve來避免連接時DNS解析。

大多數情況下你更改這個會沒有什麼感覺,因為大多數情況下DNS伺服器解析會非常快。不過當DNS伺服器失敗時,它會出現在你伺服器上出現「unauthenticated connections」 ,而就是為什麼所有的請求都突然開始慢下來了。

所以不要等到這種事情發生才更改。現在添加這個變數並且避免基於主機名的授權。

10.INNODB_IO_CAPACITY, INNODB_IO_CAPACITY_MAX

* innodb_io_capacity:用來當刷新臟數據時,控制MySQL每秒執行的寫IO量。

* innodb_io_capacity_max: 在壓力下,控制當刷新臟數據時MySQL每秒執行的寫IO量

首先,這與讀取無關 – SELECT查詢執行的操作。對於讀操作,MySQL會盡最大可能處理並返回結果。至於寫操作,MySQL在後台會循環刷新,在每一個循環會檢查有多少數據需要刷新,並且不會用超過innodb_io_capacity指定的數來做刷新操作。這也包括更改緩沖區合並(在它們刷新到磁碟之前,更改緩沖區是輔助臟頁存儲的關鍵)。

第二,我需要解釋一下什麼叫「在壓力下」,MySQL中稱為」緊急情況」,是當MySQL在後台刷新時,它需要刷新一些數據為了讓新的寫操作進來。然後,MySQL會用到innodb_io_capacity_max。

那麼,應該設置innodb_io_capacity和innodb_io_capacity_max為什麼呢?

最好的方法是測量你的存儲設置的隨機寫吞吐量,然後給innodb_io_capacity_max設置為你的設備能達到的最大IOPS。innodb_io_capacity就設置為它的50-75%,特別是你的系統主要是寫操作時。

通常你可以預測你的系統的IOPS是多少。例如由8 15k硬碟組成的RAID10能做大約每秒1000隨機寫操作,所以你可以設置innodb_io_capacity=600和innodb_io_capacity_max=1000。許多廉價企業SSD可以做4,000-10,000 IOPS等。

這個值設置得不完美問題不大。但是,要注意默認的200和400會限制你的寫吞吐量,因此你可能偶爾會捕捉到刷新進程。如果出現這種情況,可能是已經達到你硬碟的寫IO吞吐量,或者這個值設置得太小限制了吞吐量。

11.INNODB_STATS_ON_METADATA

如果你跑的是MySQL 5.6或5.7,你不需要更改innodb_stats_on_metadata的默認值,因為它已經設置正確了。

不過在MySQL 5.5或5.1,強烈建議關閉這個變數 – 如果是開啟,像命令show table status會立即查詢INFORMATION_SCHEMA而不是等幾秒再執行,這會使用到額外的IO操作。

從5.1.32版本開始,這個是動態變數,意味著你不需要重啟MySQL伺服器來關閉它。

12.INNODB_BUFFER_POOL_DUMP_AT_SHUTDOWN & INNODB_BUFFER_POOL_LOAD_AT_STARTUP

innodb_buffer_pool_mp_at_shutdown和innodb_buffer_pool_load_at_startup這兩個變數與性能無關,不過如果你偶爾重啟mysql伺服器(如生效配置),那麼就有關。當兩個都激活時,MySQL緩沖池的內容(更具體地說,是緩存頁)在停止MySQL時存儲到一個文件。當你下次啟動MySQL時,它會在後台啟動一個線程來載入緩沖池的內容以提高預熱速度到3-5倍。

兩件事:

第一,它實際上沒有在關閉時復制緩沖池內容到文件,僅僅是復製表空間ID和頁面ID – 足夠的信息來定位硬碟上的頁面了。然後它就能以大量的順序讀非常快速的載入那些頁面,而不是需要成千上萬的小隨機讀。

第二,啟動時是在後台載入內容,因為MySQL不需要等到緩沖池內容載入完成再開始接受請求(所以看起來不會有什麼影響)。

從MySQL 5.7.7開始,默認只有25%的緩沖池頁面在mysql關閉時存儲到文件,但是你可以控制這個值 – 使用innodb_buffer_pool_mp_pct,建議75-100。

這個特性從MySQL 5.6才開始支持。

13.INNODB_ADAPTIVE_HASH_INDEX_PARTS

如果你運行著一個大量SELECT查詢的MySQL伺服器(並且已經盡可能優化),那麼自適應哈希索引將下你的下一個瓶頸。自適應哈希索引是InnoDB內部維護的動態索引,可以提高最常用的查詢模式的性能。這個特性可以重啟伺服器關閉,不過默認下在mysql的所有版本開啟。

這個技術非常復雜,在大多數情況下它會對大多數類型的查詢直到加速的作用。不過,當你有太多的查詢往資料庫,在某一個點上它會花過多的時間等待AHI鎖和閂鎖。

如果你的是MySQL 5.7,沒有這個問題 – innodb_adaptive_hash_index_parts默認設置為8,所以自適應哈希索引被切割為8個分區,因為不存在全局互斥。

不過在mysql 5.7前的版本,沒有AHI分區數量的控制。換句話說,有一個全局互斥鎖來保護AHI,可能導致你的select查詢經常撞牆。

所以如果你運行的是5.1或5.6,並且有大量的select查詢,最簡單的方案就是切換成同一版本的Percona Server來激活AHI分區。

14.QUERY_CACHE_TYPE

如果人認為查詢緩存效果很好,肯定應該使用它。好吧,有時候是有用的。不過這個只在你在低負載時有用,特別是在低負載下大多數是讀取,小量寫或者沒有。

如果是那樣的情況,設置query_cache_type=ON和query_cache_size=256M就好了。不過記住不能把256M設置更高的值了,否則會由於查詢緩存失效時,導致引起嚴重的伺服器停頓。

如果你的MySQL伺服器高負載動作,建議設置query_cache_size=0和query_cache_type=OFF,並重啟伺服器生效。那樣Mysql就會停止在所有的查詢使用查詢緩存互斥鎖。

15.TABLE_OPEN_CACHE_INSTANCES

從MySQL 5.6.6開始,表緩存能分割到多個分區。

表緩存用來存放目前已打開表的列表,當每一個表打開或關閉互斥體就被鎖定 – 即使這是一個隱式臨時表。使用多個分區絕對減少了潛在的爭用。

從MySQL 5.7.8開始,table_open_cache_instances=16是默認的配置。

歡迎做Java的工程師朋友們私信我資料免費獲取免費的Java架構學習資料(裡面有高可用、高並發、高性能及分布式、Jvm性能調優、Spring源碼,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)

其中覆蓋了互聯網的方方面面,期間碰到各種產品各種場景下的各種問題,很值得大家借鑒和學習,擴展自己的技術廣度和知識面。