1. 程式人生 > >Mysql5.7 innodb innodb_* 引數詳解

Mysql5.7 innodb innodb_* 引數詳解

([email protected](none)) Mysql >show variables like 'version%';
+-------------------------+------------------------------+
| Variable_name           | Value                        |
+-------------------------+------------------------------+
| version                 | 5.7.16-log                   |
| version_comment         | MySQL Community Server (GPL) |
| version_compile_machine | x86_64                       |
| version_compile_os      | linux-glibc2.5               |
+-------------------------+------------------------------+                                                                                 
4 rows in set (0.00 sec)


(
[email protected]
(none)) Mysql >show variables like 'innodb_%';
+------------------------------------------+-----------------------------------------------------------------------------------------------
| Variable_name                            | Value                                                                                         
+------------------------------------------+-----------------------------------------------------------------------------------------------
| innodb_adaptive_flushing                 | ON    
#innodb_io_capacity, innodb_max_dirty_pages_pct,innodb_adaptive_flushing這三個引數是為了解決SSD等大容量儲存裝置的出現而導致innoDB不能很好利用這類裝置效能的困境而出現的,本文會結合mysql-5.5.34的原始碼進行這三個引數的介紹。
#指定是否要根據負荷動態地調整InnoDB緩衝池中的重新整理垃圾頁面率。動態地調整垃圾頁面率是為了避免突發的I/O併發量。該設定預設為啟用。
                                                                                        
| innodb_adaptive_flushing_lwm             | 10       
# 當自適應重新整理功能開啟時,低水位線表示重做日誌的能力的百分比。  
#該值表示redo log的一個最低容量限制百分比,預設為10,當沒有達到這個值時,則不會page cleaner執行緒不會根據redo來判斷是否刷頁,細節見函式af_get_pct_for_lsn
                                                                                  
| innodb_adaptive_hash_index               | ON   
#無論InnoDB adaptive hash index是啟用還是關閉,需要根據負荷來判斷,通過動態地開關 adaptive hash indexing來提高查詢功能。由於adaptive hash index不是對所有的負荷都起作用,需根據實際的負荷來控制它啟動和關閉的基準。詳情請見14.2.13.6, “Adaptive Hash Indexes”。
該設定預設為啟用。只需通過修改GLOBAL配置項來修改,不需要重啟伺服器。修改改配置需有超級許可權。你也可以在伺服器通過--skip-innodb_adaptive_hash_index來關閉該功能。
關閉the adaptive hash index,散列表將被立即清空。雖然散列表被清空但正常的操作仍然能繼續。之前通過散列表執行的查詢而現在將通過B-trees索引查詢。當the adaptive hash index重啟時,普通操作時將再次使用散列表。                                                                                         


S| innodb_adaptive_hash_index_parts         | 8                                                                                             
| innodb_adaptive_max_sleep_delay          | 150000  
#允許InnoDB根據現有負荷自動調整 innodb_thread_sleep_delay值的大小。任何一個非零的值都允許自動使能,動態的調整 innodb_thread_sleep_delay的值,最高值可達 innodb_thread_sleep_delay配置的最大值。在大於16執行緒併發的InnoDB這樣繁忙的系統中,這一配置項很有作用。(在實踐中,有數百或成千上萬的併發連線MySQL系統,它是最有價值的)                                                                                      


| innodb_api_bk_commit_interval            | 5  
# 在短時間內,多久通過InnoDB memcached 介面自動提交空閒連線。(5.6.17引入)                                                                                           
| innodb_api_disable_rowlock               | OFF   
#當innodb 分頁式快取執行DML操作的時候,使用這個變數去禁用行級鎖。預設情況下innodb_api_disable_rowlocky設定為off, 這意味著分頁式快取請求獲取和設定操作的行鎖。當innodb_api_disable_rowlock 設定為on ,分頁式快取請求表鎖而來代替行鎖。
Innodb_api_disable_rowlock選項不是動態,它必須指定在mydqld命令列或MYSQL配置檔案設定。外掛安裝後配置才會有效,在配置該引數需要重啟資料庫服務生效。
                                                                                        
| innodb_api_enable_binlog                 | OFF   
#允許您使用innodb memcached外掛和mysql binary log
#Lets you use the InnoDB memcached plugin with the MySQL binary log. See Section 14.18,“InnoDB Integration with memcached” forusage details for this option.  
#https://dev.mysql.com/doc/refman/5.6/en/innodb-memcached.html   
                                                                                   
| innodb_api_enable_mdl                    | OFF     
#鎖表被用於InnoDB分散式快取外掛中。因此可以在SQL介面被DDL去掉和修改。
                                                                                      
| innodb_api_trx_level                     | 0  
# 允許在分散式快取介面處理中控制獨立事務處理等級。細節請參看Section 14.18, “InnoDB Integration with memcached
一些數值的含義為:
§ 0 = READ UNCOMMITTED
§ 1 = READ COMMITTED
§ 2 = REPEATABLE READ
§ 3 = SERIALIZABLE
                                                                                          
| innodb_autoextend_increment              | 64  
#當記憶體空間滿時,增量空間被用來擴充套件InnoDB system tablespace,在MySQL5.6.6, 8之前預設值為64(M),如果你設定innodb_file_per_table=1。
這個變數將不會在你建立的tablespace 檔案裡生效。這此檔案是自動擴充套件的,不會參照innodb_autoextend_increment 值。初始化的擴充套件非常小,當擴充套件發生時增至4MB。
                                                                                          
| innodb_autoinc_lock_mode                 | 1    
# 此方式為innodb在插入自增欄位時用到的鎖定方式, 有三種模式,traditional(5.1 before),consecutive(5.1 begin default),interleaved,
# consecutive 是最安全,其他兩種型別往往獲得更好效能。
# 結論:innodb_autoinc_lock_mode為0時的,也就是官方說的traditional級別,該自增鎖是表鎖級別,且必須等待當前SQL執行完成後或者回滾掉才會釋放,這樣在高併發的情況下可想而知自增鎖競爭是比較大的。                                                                                       
# 結論:innodb_autoinc_lock_mode為1時的,也就是官方說的consecutive級別,這時如果是單一的insert SQL,可以立即獲得該鎖,並立即釋放,而不必等待當前SQL執行完成(除非在其他事務中已經有session獲取了自增鎖)。另外當SQL是一些批量insert sql時,比如insert into ...select ...,load data,replace ..select..時,這時還是表級鎖,可以理解成退化為必須等待當前SQL執行完才釋放。
可以認為,該值為1時是相對比較輕量的鎖,也不會對複製產生影響,唯一的缺陷是產生的自增值不一定是完全連續的(不過個人認為這個往往不是很重要,也沒必要根據自增id值來統計行數之類)。
# 結論:當innodb_autoinc_lock_mode設定為2時,所有insert種類的SQL都可以立馬獲得鎖並釋放,這時的效率最高。但是會引入一個新的問題:當binlog_format為statement時,這時的複製沒法保證安全,因為批量的insert,比如insert ..select..語句在這個情況下,也可以立馬獲取到一大批的自增id值,不必鎖整個表,slave在回放這個sql時必然會產生錯亂。
但是反應到從庫時,因為是基於statement的複製,必然出現主鍵衝突。
總結:1 innodb  row複製時,可將innodb_autoinc_lock_mode設定為2,這時可在所有insert情況下表獲得最大併發度
      2 innodb statement複製時,可將innodb_autoinc_lock_mode設定為1,保證複製安全的同時,獲得簡單insert語句的最大併發度
 3 myisam引擎情況下,無論什麼樣自增id鎖都是表級鎖,設定innodb_autoinc_lock_mode引數無效。
 4 實際上提問者說到的在innodb引擎下自增id值作為主鍵的情況下,相比uuid或者自定義的主鍵,是可以提到插入速度的,因為innodb是主鍵聚集索引,實際的主鍵值必須按照主鍵順序存取,那麼自增id本身就是升序的,那麼在插入資料時,底層就不必再做額外的排序操作,也減少了索引頁分裂的次數,從而大大增加insert速度(除非其他方案也能保證主鍵完全自增)。
 
| innodb_buffer_pool_chunk_size            | 134217728     
#(5.7 引入),MySQL 5.7.5後Innodb_buffer_pool_size一方面可以動態分配。但另一方面也引入了一個新特性,Innodb_buffer_pool_size分配必須是innodb_buffer_pool_chunk_size的倍數。同時最好是:innodb_buffer_pool_chunk_size*innodb_buffer_pool_instances.
預設為128M
                                                                                
| innodb_buffer_pool_dump_at_shutdown      | ON
#解釋:在關閉時把熱資料dump到本地磁碟。
                                                                                            
| innodb_buffer_pool_dump_now              | OFF 
#解釋:採用手工方式把熱資料dump到本地磁碟。
                                                                                          
| innodb_buffer_pool_dump_pct              | 40   
#mysql5.7開始預設在資料庫服務啟動,停止時,預熱與dump資料,設定dump的百分比,這部分資料是最熱的資料.
#表示轉儲每個bp instance LRU上最熱的page的百分比。通過設定該引數可以減少轉儲的page數。


                                                                                         
| innodb_buffer_pool_filename              | ib_buffer_pool    
# 如果開啟InnoDB預熱功能,停止MySQL服務時,MySQL將InnoDB緩衝池中的熱資料儲存到資料庫根目錄中,預設檔名為ib_buffer_pool.
                                                                            
| innodb_buffer_pool_instances             | 1     
#innodb_buffer_pool_instances可以開啟多個記憶體緩衝池,把需要緩衝的資料hash到不同的緩衝池中,這樣可以並行的記憶體讀寫.
為了更好的併發效能,通過指定innodb_buffer_pool_instances(該值取值範圍為1-64)建立多個快取池,每個快取池的大小為
innodb_buffer_pool_size/innodb_buffer_pool_instances,通常需要保持當個快取池的大小大於1GB。
                                                                                        
| innodb_buffer_pool_load_abort            | OFF   
#預設為關閉OFF。如果開啟該引數,即便開啟InnoDB預熱功能,啟動MySQL服務室,MySQL也不會將本地硬碟的熱資料載入到InnoDB緩衝池中。
                                                                                        
| innodb_buffer_pool_load_at_startup       | ON    
#解釋:在啟動時把熱資料載入到記憶體。
                                                                                        
| innodb_buffer_pool_load_now              | OFF     
#解釋:採用手工方式把熱資料載入到記憶體。
                                                                                      
| innodb_buffer_pool_size                  | 536870912  
# 調整innodb_buffer_pool_size大小,如果是單例項且絕大多數是InnoDB引擎表的話,可考慮設定為實體記憶體的50% ~ 75%左右;
#快取資料塊和索引塊,對InnoDB表效能影響最大。通過查詢show status like 'Innodb_buffer_pool_read%',保證 (Innodb_buffer_pool_read_requests – Innodb_buffer_pool_reads) / Innodb_buffer_pool_read_requests越高越好.
#假設是一臺單獨給 MySQL 使用的主機,實體記憶體總大小為 8G,MySQL 最大連線數為 500,同時還使用 了 MyISAM 儲存引擎,這時候我們的整體記憶體該如何分配呢?
記憶體分配為如下幾大部分:
a)     系統使用,假設預留 800M;
b)     執行緒獨享,約 2GB  = 500  * (1MB  + 1MB  + 1MB  + 512KB  + 512KB),組成大概如下:sort_buffer_size:1MB join_buffer_size:1MB read_buffer_size:1MB read_rnd_buffer_size:512KB thread_statck:512KB
c)    MyISAM  Key Cache,假設大概為 1.5GB;
d)     Innodb Buffer  Pool 最大可用量:8GB  - 800MB  - 2GB  - 1.5GB = 3.7GB;
假設這個時候我們還按照 50%~80%的建議來設定,最小也是 4GB,而通過上面的估算,最大可用值 在 3.7GB 左右,那麼很可能在系統負載很高當執行緒獨享記憶體差不多出現極限情況的時候,系統很可能就 會出現記憶體不足的問題了                                                                                  


| innodb_change_buffer_max_size            | 25 
# 如果是日值類服務,可以考慮把這個增值調到 50
                                                                                           
| innodb_change_buffering                  | all  
#預設即可
#5.5之前。這還不叫change buffer,而是insert buffer;
#當更新/插入的非聚集索引的資料所對應的頁不在記憶體中時(對非聚集索引的更新操作通常會帶來隨機IO),會將其放到一個insert buffer中,當隨後頁面被讀到記憶體中時,會將這些變化的記錄merge到頁中。當伺服器比較空閒時,後臺執行緒也會做merge操作 
但insert buffer會佔用buffer pool,並且在非聚集索引很少時,並不總是必要的,反而會降低buffer pool做data cache的能力,
根據官方文件的描述,主要包括以下幾個值:
1.all
The default value: buffer inserts, delete-marking operations, and purges.
2.none
Do not buffer any operations.
3.inserts
Buffer insert operations.
4.deletes
Buffer delete-marking operations.(包括delete和update操作)
5.changes
Buffer both inserts and delete-marking.
6.purges
Buffer the physical deletion operations that happen in the background


                                                                           
| innodb_checksum_algorithm                | crc32
#Innodb引入了新的checksum計算方式,checksum演算法由新引數 innodb_checksum_algorithm來控制,預設為crc32演算法,主要有兩種演算法,一種是老的計算方法(innodb_checksum_algorithm=innodb),使用這種演算法是相容老版本的MySQL。                                                                                         
因為使用了不同的演算法計算checksum,會導致校驗page失敗。




| innodb_checksums                         | ON       
#InnoDB在所有對磁碟的頁面讀取上使用校驗和驗證以確保額外容錯防止硬體損壞或資料檔案
                                                                                     
| innodb_cmp_per_index_enabled             | OFF    
##表示是否統計每個表的每個索引的壓縮狀態,如果開啟,資訊會進行收集,並顯示在information_schema的INNODB_CMP_PER_INDEX/INNODB_CMP_PER_INDEX_RESET中,這會有一定的效能損耗 .




                                                                                       
| innodb_commit_concurrency                | 0 
#如你所見innodb_commit_concurrency僅用來保護行訪問,使用內部結構和鎖定分階段提交,他仍是為保護變數。他限制innodb核心啟用執行緒的commit。一個最佳的值也依賴很多其他因素。但是從5.1.36開始mysql不允許將該值設定為非0,該值只能為預設值0,mysql不限制併發提交。


                                                                                            
| innodb_compression_failure_threshold_pct | 5  
#該引數和下面的引數來自facebook對壓縮表的改進,當一個非壓縮page無法壓縮到指定size時,會產生索引分裂,這會大大影響效能,我們可以 給非壓縮頁留一些空白,少存一點資料,這樣會降低壓縮失敗率,但也有可能減小壓縮比,該選項表示當壓縮失敗率高於這個值時,進行apdative padding .
#當壓縮失敗rate大於這個值時,會增加padding來減小失敗率,為0表示禁止該padding.
                                                                                           
| innodb_compression_level                 | 6     
#定義壓縮表的壓縮級別,在具有較好壓縮特性的資料集上,可以適當調小該值,還獲得更好的TPS效能
#可通過 innodb_compression_level 配置為 InnoDB 表選擇 0-9 的不同壓縮級別(預設值6)
                                                                                        
| innodb_compression_pad_pct_max           | 50   
#一個page中最大允許留白的百分比
                                                                                         
| innodb_concurrency_tickets               | 5000  
#直到執行緒用盡了這個值,在再次進入innodb時才需要檢查
                                                                                        
| innodb_data_file_path                    | 
/data/mysql/ibdata1:12M;/data/mysql/innodb1/ibdata2:12M;/data/mysql/innodb2/ibdata3:12M;/data/mysql/innodb3/ibdata4:12M:autoextend:max:1G  
| innodb_data_home_dir                     |                                                                                               
| innodb_deadlock_detect                   | ON   
# 增加了innodb_deadlock_detect 引數,控制是否開啟死鎖檢測。關閉死鎖檢測,在效能上有非常大的提高,曾經在其他mysql分支增加了這個引數,而官方版本直到5.7.15才增加了這個引數,預設是開啟的。
                                                                                        
| innodb_default_row_format                | dynamic        
# 5.6 及之前版本為 row_format 引數制定,5.7以後,由此替代:
#mysql中若一張表裡面存在varchar、text以及其變形、blob以及其變形的欄位的話,那麼這個表其實也叫動態表,即該表的 row_format是dynamic,就是說每條記錄所佔用的位元組是動態的。其優點節省空間,缺點增加讀取的時間開銷。反之,這張表叫靜態表,該表 row_format為fixed,即每條記錄佔用位元組一樣。優點讀取快,缺點浪費部分空間
所以,做搜尋查詢量大的表一般都以空間來換取時間,設計成靜態表。
fixed--->dynamic: 這會導致CHAR變成VARCHAR
                                                                               
| innodb_disable_sort_file_cache           | OFF    
##設定該選項表示作業系統不對merge-sort的臨時檔案cache,使用O_DIRECT 
                                                                                      
| innodb_doublewrite                       | ON     
#如果這個變數啟用(預設啟用),InnoDB儲存所有資料 兩次,首先寫到 doublewrite buffer,然後到實際資料檔案。對基準或需要高效能而不關心資料完整性或可能的失敗可以使用 --skip-innodb_doublewrite關閉。
                                                                                       
| innodb_fast_shutdown                     | 1    
#InnoDB關閉模式。
如果該值為0,InnoDB緩慢關閉,在關閉之前,做一個完整的清洗和插入緩衝合併。
如果該值為1(預設),InnoDB在關閉時跳過這些操作,這一過程稱為快速關閉。
如果該值為2,InnoDB沖洗日誌和冷關閉,好像MySQL發生崩潰;提交事務不會丟失,但是崩潰恢復操作使下一次啟動需要更長的時間。    
緩慢關閉可能花幾分鐘,甚至在極端情況下幾小時,大量的資料仍然被緩衝。在MySQL主版本之間升級或降級之前使用慢關閉技術,這樣所有的資料檔案做充分的準備,以防升級過程更新檔案格式。    
在緊急或故障情況下,資料冒著被破壞風險,使用 innodb_fast_shutdown=2,獲得絕對最快關閉。
                                                                                         
| innodb_file_format                       | Barracuda   
#innodb 的檔案格式為Antelope, innoDB-Plugin的檔案格式為Barracuda, 如果開啟8KB的資料壓縮頁,就必須設定為Barracuda , 以後會是Cheetah, 預設為Antelope, 可動態修改,建議改為 Barracuda。
注意: 必須採用 Barracuda 檔案格式且獨立表空間,才支援資料頁的壓縮。
                                                                                  
| innodb_file_format_check                 | ON    
#用來檢查共享表空間檔案格式,如果共享表空間的檔案格式高於當前版本,並且 此引數為ON, 就會檢查出有問題。 此引數預設為ON, 不支援動態修改。 建議預設值。
#該變數可以設定1和0,對應著服務在啟動時,Innodb是否檢查系統表空間的檔案格式標誌位(如: Antelope 或 Barracuda)。如果該標誌被檢查,並且比當前Innodb支援的值更高。會產生一個錯誤,並且Innodb 不能啟動。如果不高,innodb會設定 innodb_file_format_max 的值到檔案標誌位。注意:儘管預設值有時被顯示為ON或OFF,在您的配置檔案或命令列總是用數值1或0將開啟或關閉此選項。
                                                                                       
| innodb_file_format_max                   | Barracuda        
#在服務啟動時,Innodb把這個變數的值設定給系統表空間的檔案格式標誌(如 Antelope 或 Barracuda)。如果服務用一個“higher”檔案格式建立或開啟一個表,把 innodb_file_format_max的值設定為表的標誌
                                                                             
| innodb_file_per_table                    | ON 
 #innodb 預設在共享表空間中存放表和索引資料,使用此選項,你可以告知它將表的索引和資料存放在單獨的檔案裡。
在MySQL的配置檔案[mysqld]部分,增加innodb_file_per_table引數。
可以修改InnoDB為獨立表空間模式,每個資料庫的每個表都會生成一個數據空間。
獨立表空間:
優點:
1.每個表都有自已獨立的表空間。
2.每個表的資料和索引都會存在自已的表空間中。
3.可以實現單表在不同的資料庫中移動。
4.空間可以回收(除drop table操作處,表空不能自已回收)
a) Drop table操作自動回收表空間,如果對於統計分析或是日值表,刪除大量資料後可以通過:alter table TableName engine=innodb;回縮不用的空間。
b) 對於使innodb-plugin的Innodb使用turncate table也會使空間收縮。
c) 對於使用獨立表空間的表,不管怎麼刪除,表空間的碎片不會太嚴重的影響效能,而且還有機會處理。
缺點:
單表增加過大,如超過100個G。
結論:
共享表空間在Insert操作上少有優勢。其它都沒獨立表空間表現好。當啟用獨立表空間時,請合理調整一 下:innodb_open_files 。
InnoDB Hot Backup(冷備)的表空間cp不會面對很多無用的copy了。而且利用innodb hot backup及表空間的管理命令可以實現單現移動。
1.innodb_file_per_table設定.開啟方法:
在my.cnf中[mysqld]下設定
innodb_file_per_table=1
2.檢視是否開啟:
mysql> show variables like ‘%per_table%’;
3.關閉獨享表空間
innodb_file_per_table=0關閉獨立的表空間
mysql> show variables like ‘%per_table%’; 


| innodb_fill_factor                       | 100   
                                                                                   
| innodb_flush_log_at_timeout              | 1    
#每N秒寫和沖洗事務日誌,這個選項僅當設定innodb_flush_log_at_trx_commit 為2才有效,刷日誌 innodb_flush_neighbors 該變數在MySQL5.6.6新增。
                                                                                         
| innodb_flush_log_at_trx_commit           | 1   
# (說 明:如果是遊戲伺服器,建議此值設定為2;如果是對資料安全要求極高的應用,建議設定為1;設定為0效能最高,但如果發生故障,資料可能會有丟失的危險! 預設值1的意思是每一次事務提交或事務外的指令都需要把日誌寫入(flush)硬碟,這是很費時的。特別是使用電池供電快取 (Battery backed up cache)時。設成2對於很多運用,特別是從MyISAM錶轉過來的是可以的,它的意思是不寫入硬碟而是寫入系 統快取。日誌仍然會每秒flush到硬碟,所以你一般不會丟失超過1-2秒的更新。設成0會更快一點,但安全方面比較差,即使MySQL掛了也可能會丟失 事務的資料。而值2只會在整個作業系統掛了時才可能丟資料。)                                                                                            


| innodb_flush_method                      | O_DIRECT 
##新引數,在IO時使用O_DIRECT,但不再隨後做fsync,可以參考bug#45892的描述;這種配置不適合一些檔案系統,因為metadata沒有被fsync到磁碟。
                                                                                     
| innodb_flush_neighbors                   | 1  
#重新整理領接頁
工作原理:
當重新整理一個髒頁時,innodb會檢測該頁所在區(extent)的所有頁,如果是髒頁,那麼一起進行重新整理。
這樣做,通過AIO將多個IO寫入操作合併為一個IO操作。在傳統機械磁碟下有著顯著優勢。
innodb_flush_neighbors 引數來控制是否開啟。
                                                                                           
| innodb_flush_sync                        | ON     


                                                                                       
| innodb_flushing_avg_loops                | 30 
#這個選項可以控制adaptive flush對工作負載變化的響應速度。在這麼多次loop內,innodb會保持上次的重新整理狀態快照不變,增加這個值有助於重新整理操作更加平穩,而減小這個值有助於對工作負載的變化更快的調整adaptive flush,不過,如果設定的過小的話,在突然增大/減小的工作的負載中,容易引起效能尖峰。
                                                                                           
| innodb_force_load_corrupted              | OFF    
#在啟動時讓InnoDB載入那些標記為損壞的表。只在排除故障期間用於恢復資料,否則無法訪問。當故障檢修完成後,將此設定OFF並重新啟動服務。
                                                                                       
| innodb_force_recovery                    | 0 
#因為日誌已經損壞,這裡採用非常規手段,首先修改innodb_force_recovery引數,使mysqld跳過恢復步驟,將mysqld 啟動,將資料匯出來然後重建資料庫。
innodb_force_recovery可以設定為1-6,大的數字包含前面所有數字的影響。
  1. (SRV_FORCE_IGNORE_CORRUPT):忽略檢查到的corrupt頁。
  2. (SRV_FORCE_NO_BACKGROUND):阻止主執行緒的執行,如主執行緒需要執行full purge操作,會導致crash。
  3. (SRV_FORCE_NO_TRX_UNDO):不執行事務回滾操作。
  4. (SRV_FORCE_NO_IBUF_MERGE):不執行插入緩衝的合併操作。
  5. (SRV_FORCE_NO_UNDO_LOG_SCAN):不檢視重做日誌,InnoDB儲存引擎會將未提交的事務視為已提交。
  6. (SRV_FORCE_NO_LOG_REDO):不執行前滾的操作。
注意 
  a 當設定引數值大於0後,可以對錶進行select,create,drop操作,但insert,update或者delete這類操作是不允許的。
  b 當innodb_purge_threads 和 innodb_force_recovery一起設定會出現一種loop現象:   
#0 代表黨MySql關閉時,InnoDB需要完成所有的full purge 和 merge insert buffer操作,這會需要一些時間。1 代表不需要完成上述的full purge ,merge insert buffer操作,但是在緩衝池的一些資料髒頁還是會重新整理到磁碟。2 代表不完成full purge ,merge insert buffer操作,也 不將緩衝池中的資料髒頁寫回磁碟,而是將日誌都寫入日誌檔案。這樣不會有任何事物會丟失,但是Mysql資料庫下次啟動時,會執行recovery
引數Innodb_force_recovery影響了整個InnoDB儲存引擎的恢復狀況。預設0


                                                                                            
| innodb_ft_aux_table                      |           
#給Innodb 包含全文索引的表指定合格名稱,你設定這個變數的名稱格式為 db_name/table_name,然而INFORMATION_SCHEMA中的表 INNODB_FT_INDEX_TABLE, INNODB_FT_INDEX_CACHE, INNODB_FT_CONFIG,INNODB_FT_DELETED,和 INNODB_FT_BEING_DELETED 反映對指定表的索引搜尋資訊。該變數在MySQL5.6.4新增的。


                                                                                    
| innodb_ft_cache_size                     | 8000000   
#當建立一個InnoDB全文索引,用於儲存解析文件在記憶體的快取的大小。
                                                                                    
| innodb_ft_enable_diag_print              | OFF                                                                                           
| innodb_ft_enable_stopword                | ON    
#在建立索引的時,指定一組與InnoDB全文索引相關禁用詞(stopwords)。如果innodb_ft_user_stopword_table 選項被設定,暫停詞來自那張表。另外,如果innodb_ft_server_stopword_table選項被設定,暫停詞來自那張表。否則,使用一個內建預設的暫停片語。
                                                                                        
| innodb_ft_max_token_size                 | 84                                                                                            
| innodb_ft_min_token_size                 | 3                                                                                             
| innodb_ft_num_word_optimize              | 2000                                                                                          
| innodb_ft_result_cache_limit             | 2000000000                                                                                    
| innodb_ft_server_stopword_table          |                                                                                               
| innodb_ft_sort_pll_degree                | 2                                                                                             
| innodb_ft_total_cache_size               | 640000000                                                                                     
| innodb_ft_user_stopword_table            |       
--innodb_ft_*  全部為全文索引相關資訊。
                                                                                        
| innodb_io_capacity                       | 4000  
#預設是200, 單位是頁,該設定大小取決與硬碟的IOPS。 如果6塊15000轉的磁碟RAID10, 可考慮設定為2000比較合適。
#單盤 sas/sata   --> 200左右:(10000rpm轉速)
#sas*12/raid10   -->2000
#ssd             --> 5000
#pusion-io  -->50000
                                                                                        
| innodb_io_capacity_max                   | 8000  
##當flush操作落後太多時,可能會做一些非常有侵略性的重新整理(超過指定的innodb_io_capacity),這會影響到正常的業務,指定這個值,可以限制io capacity的上限,減少對正常應用的影響.
                                                                                        
| innodb_large_prefix                      | ON   
#對使用 DYNAMIC和COMPRESSED 行格式的InnoDB表,啟用這個選項允許字首索引 長度可以長於767位元組(最大為3072位元組).(建立這些表也需要這些選項innodb_file_format=barracuda 和innodb_file_per_table=true.)在不同變數設定下,對應字首索引的最大值見 Section 14.2.7, “Limits on InnoDB Tables” 。對使用REDUNDANT 和 COMPACT 行格式的表,這個選項不影響索引字首所允許的長度。當這個選項被設定,當對REDUNDANT或COMPACT嘗試建立一個索引大於3072,發生一個ER_INDEX_COLUMN_TOO_LONG (1727)錯誤
                                                                                        
| innodb_lock_wait_timeout                 | 5  
# 這是innodb等待行鎖直到放棄的秒數,當超過innodb_lock_wait_timeout設定的值後,會返回錯誤“ERROR 1205(HY000):Lock wait timeout exceeded; try restarting transaction” 。
# 這設定很大防止查詢失敗,只會導致更嚴重問題,因為很多阻塞transaction 會相互鎖住。    
# 預設為50s(大多數支援預設或小一些)                                                                                      
| innodb_locks_unsafe_for_binlog           | OFF 
# 此變數定義innodb如何使用間隙鎖來搜尋和掃描索引,預設值(為0),間隙鎖開啟。
# 推薦用READ COMMITTED 替代他,這個變數不能設定為session級別。  
                                                                                       
| innodb_log_buffer_size                   | 16777216   
#這個引數就是用來設定 Innodb 的 Log Buffer 大小的,系統預設值為 1MB。Log  Buffer 的主要作用就是緩衝 Log 資料,提高寫 Log 的 IO 效能。一般來說,如果你的系統不是寫負載非常高且以 大事務居多的話,8MB 以內的大小就完全足夠了。
#如果完全從 Log Buffer 本身來說,自然是大一些會減少更多的磁碟 IO。但是由於 Log 本身是 為了保護資料安全而產生的,而 Log 從 Buffer 到磁碟的重新整理頻率和控制資料安全一致的事務直接相關, 並且也有相關引數來控制(innodb_flush_log_at_trx_commit).
                                                                                   
| innodb_log_checksums                     | ON                                                                                            
| innodb_log_compressed_pages              | ON    
#指定重壓縮頁的點陣圖是否儲存到Innodb redo logs。這個變數在MySQL5.6.11新增的
                                                                                        
| innodb_log_file_size                     | 1073741824     (Kb)
#在一個日誌組中每一個日誌檔案大小。日誌檔案合併後的大小((innodb_log_file_size *innodb_log_files_in_group)可以到達512G。預設是48M。值明智範圍從1MB到緩衝池的大小的1/n,N是日誌檔案組中檔案數。值越大,在緩衝池執行checkpoint 重新整理活動次數越小,節省磁碟I/O。日誌檔案越大,崩潰恢復越慢。儘管在MySQL5.5改善了恢復的效能和使日誌檔案更少考慮。
                                                                               
| innodb_log_files_in_group                | 2       
#在日誌組的日誌檔案數。
                                                                                      
| innodb_log_group_home_dir                | /data/mysql/   
#在日誌組的日誌路徑
                                                                               
| innodb_log_write_ahead_size              | 8192     
#全域性動態變數,預設8192,即8K,範圍:512bytes~innodb_page_size,以位元組為單位。
表示redo log寫前的塊大小。InnoDB以512位元組一個block的方式對齊寫入ib_logfile檔案,但檔案系統一般以4096位元組為一個block單位。如果即將寫入的日誌檔案塊不在OS Cache時,就需要將對應的4096位元組的block讀入記憶體,修改其中的512位元組,然後再把該block寫回磁碟。該引數解決這個問題,噹噹前寫入檔案的偏移量不能整除該值時,則補0,多寫一部分資料。這樣當寫入的資料是以磁碟block size對齊時,就可以直接write磁碟,而無需read-modify-write這三步了。
                                                                                    
| innodb_lru_scan_depth                    | 2000   
#影響page cleaner執行緒一次掃描LRU/UNZIP_LRU的深度,預設為1024,IO有空餘可以適當調大;
                                                                                       
| innodb_max_dirty_pages_pct               | 75.000000      
關閉資料庫之前,可以手工調整@@global.innodb_max_dirty_pages_pct為比較小的數值,然後等待dity pages變少,然後restart,可以減少啟動要恢復的時間。
對於很大的innodb buffer的,設定小點的innodb_max_dirty_pages_pct理論上是比較合理的。誰見過在oracle資料庫 中,v$bh.dirty佔到90%的。反正dirty buffer writer是backgound async的,只要不要太lazy或者crazy就行。
                                                                               
| innodb_max_dirty_pages_pct_lwm           | 0.000000  
#防止在到達innodb_max_dirty_pages_pct時瘋狂重新整理,而是在達到這樣一個限定值時,開始“優雅”的做重新整理髒頁(預重新整理)。詳細見函式af_get_pct_for_dirty
#mysql檢查點事件受兩個因素的制約:一個是amount,另外一個是age.amount主要由 innodb_max_dirty_pages_pct引數控制;至於age,主要是由日誌檔案大小有關。
                                                                                  
| innodb_max_purge_lag                     | 0     
#該變數控制 purge 操作滯後多長,才延遲INSERT,UPDATE和DELETE 操作。預設是0(不延遲)。
InnoDB 事務系統維護一個事務列表。它記錄被UPDATE 和DELETE 操作標誌為刪除的記錄。這個列表的長度
代表 purge_lag值。當purge_lag超過innodb_max_purge_lag,每個 INSERT, UPDATE, 和 DELETE 操作被延遲。延遲的數量是 ((purge_lag/innodb_max_purge_lag)*10)-5 毫秒。在極端情況下 purge_lag 巨大,以防止過度延遲。你可以設定一個延遲的時間上限通過 innodb_max_purge_lag_delay 配置選項,延遲是從開始清洗批次計算,每十秒。如果由於舊一致性讀 讀到要清除的行,不能執行清除,則操作不能延遲。
滯後的值顯示在InnoDB監控輸出的事務部分中的 history list length。例如,如果輸出包括以下行,滯後值是20:History list length 20
                                                                                        
| innodb_max_purge_lag_delay               | 0     
#指定最大延遲時間毫秒。任何非零值表示一個基於innodb_max_purge_lag值計算延遲時間的上限。預設為零意味著沒有強制延遲間隔的上限。
                                                                                        
| innodb_max_undo_log_size                 | 1073741824  
#控制最大undo tablespace檔案的大小,超過這個閥值時才會去嘗試truncate. truncate後的大小預設為10M
                                                                                  
| innodb_monitor_disable                   |     
#關閉 INFORMATION_SCHEMA.INNODB_METRICS 表中一個或更多計數器。
                                                                                          
| innodb_monitor_enable                    |      
#開啟 INFORMATION_SCHEMA.INNODB_METRICS 表中一個或更多計數器。
                                                                                         
| innodb_monitor_reset                     |      
#重置INFORMATION_SCHEMA.INNODB_METRICS 表中一個或更多計數器的值為0.       
                                                                                  
| innodb_monitor_reset_all                 |                     
#重置INFORMATION_SCHEMA.INNODB_METRICS 表中一個或更多計數器所有值(最小,最大,等待)
                                                                          
| innodb_old_blocks_pct                    | 37     
#指定buffer pool用於舊塊分表的百分比。範圍從5到95。預設是37(即pool的3/8).通常結合innodb_old_blocks_time一起使用
                                                                                       
| innodb_old_blocks_time                   | 1000         
#全域性動態變數。5.6.6之後預設是1000,之前是0。單位是毫秒。
#該引數表示等到該時間後,再讀取該頁則會進入到new端,有效的避免了對於上述SQL對BP的汙染。預設是0,單位是毫秒。如設定為1000則表示:讀到該頁到midpoint的位置,要再等1秒之後讀取該頁才能進入new列表。而0則表示讀取到該頁則會直接被放入到new列表。具體的可以看這裡。和innodb_old_blocks_pct配合使用,該引數預設是37(3/8),即BP的3/8處。
BP(Buffer_pool) 
                                                                                
| innodb_online_alter_log_max_size         | 134217728   
# #online ddl時併發DML產生的row log最大size,超過這個限制會導致DDL回滾 .
#對InnoDB表在Online DDL 操作,臨時日誌檔案最大值。每個索引建立或修改表都有這個日誌檔案,這個日誌檔案儲存在DDL操作期間對錶插入,更新,刪除的資料。當 innodb_sort_buffer_siz的值需要,臨時日誌檔案自動擴充套件直到innodb_online_alter_log_max_size指定的值。如果任何臨時日誌檔案超過這個上限,ALTER TABLE操作失敗和所有未提交的併發DML操作被回滾。因此在ONLINE DDL 操作期間,有大量DML併發,應該增大該值。但也導致結束DDL操作需要更長時間當表被鎖用來從日誌應用資料。
                                                                                  
| innodb_open_files                        | 2000   
#這變數僅與你使用InnoDB多表空間檔案有關,它指定MySQL在一時間保持開啟.ibd 檔案數。最小值是10,自從MySQL5.6.6預設值是300.
                                                                                       
| innodb_optimize_fulltext_only            | OFF  
#改變OPTIMIZE TABLE語句操作Innodb表的方法,對含有全文索引的innodb表的維護操作期間,臨時啟用改變數。預設情況, OPTIMIZE TABLE 會對有聚集索引表進行重新整理資料。當啟用這選項,OPTIMIZE TABLE跳過表資料重新整理,僅對有全文索引的新增,更新和刪除的資料進行處理。
                                                                                         
| innodb_page_cleaners                     | 1     
全域性變數, 5.7.7之前預設1,5.7.8之後預設4,範圍:1~64
表示刷寫BP髒頁的執行緒數,5.6.2開始從master執行緒中獨立出來,5.7.4開始支援多執行緒flush。這個值必須小於等於innodb_buffer_pool_instances。
                                                                                        
| innodb_page_size                         | 16384     
#如果使用SSD或是固態盤需要考慮:
#innodb_page_size = 4K
#Innodb_flush_neighbors = 0
# Innodb page size 可以選擇 8K、 16K、 32K、 64K。不過因為Innodb每個page都有不小的冗餘空間,從空間和記憶體利用的角度來講,page size越大越好。但是從checkpoint的角度來講恰恰相反,page size越小,效能越好
                                                                                    
| innodb_print_all_deadlocks               | ON    
# #儲存全部死鎖資訊
                                                                                       
| innodb_purge_batch_size                  | 300     
#  當開啟獨立執行緒清除undo 頁時,表示一次刪除多少個頁,預設是20,不支援動態修改,一般不需要修改。
#控制每次full purge回收的undo頁的數量


                                                                                      
| innodb_purge_rseg_truncate_frequency     | 128  
#控制回收(收縮)undo log的頻率.undo log空間在它的回滾段沒有得到釋放之前不會收縮,
想要增加釋放回滾區間的頻率,就得降低innodb_purge_rseg_truncate_frequency設定值。
                                                                                        
| innodb_purge_threads                     | 4   
# purge執行緒數,可以加快purge速度
#從InnoDB 1.2版本開始,InnoDB支援多個Purge Thread,這樣做的目的是為了進一步加快undo頁的回收。同時由於Purge Thread需要離散地讀取undo頁,這樣也能更進一步利用磁碟的隨機讀取效能。如使用者可以設定4個Purge Thread:
#而其目的是為了減輕原Master Thread的工作及對於使用者查詢執行緒的阻塞,進一步提高InnoDB儲存引擎的效能。


| innodb_random_read_ahead                 | OFF    
#InnoDB 提供了兩種預讀的方式,一種是 Linear read ahead,由引數innodb_read_ahead_threshold控制,當你連續讀取一個 extent 的 threshold 個 page 的時候,會觸發下一個 extent 64個page的預讀。另外一種是Random read-ahead,由引數innodb_random_read_ahead控制,當你連續讀取設定的數量的page後,會觸發讀取這個extent的剩餘page。
                                                                                       
| innodb_read_ahead_threshold              | 56  
#當順序讀取extent塊(包含64個page) innodb_read_ahead_threshold 設定的page頁數量時,觸發一個非同步讀取請求,將下一個頁提前讀取到buffer_pool 中。 預設為56, 不支援動態修改,一般採用預設。
                                                                                          
| innodb_read_io_threads                   | 4    
# 控制後臺執行緒處理資料頁上的寫請求, 預設是4,不支援動態修改,建議根據伺服器的核數以及讀寫請求 的比例加以調整。
而在MySQL5.5.x中用2個innodb_read_io_threads和Innodb_write_io_threads取代此版本之前引數, 
該引數值之和=2*cpu個數*cpu核數;如果你的系統讀>寫,可以設定innodb_read_io_threads值相對大點;反之,也可以.
   
| innodb_read_only                         | OFF      
#啟動server 在read-only模式。對於分佈在資料庫應用或者資料設定為只讀介質。   
也可以用於資料倉庫共享相同的資料目錄在多個例項之間。


|  read_only                               | OFF
當read_only 系統變數啟用時, server 不允許client 更新除了使用者有超級許可權, 預設這個變數是關閉的。 
                                                                                     
| innodb_replication_delay                 | 0         
#  當innodb_thread_concurrency 執行緒已滿時,Slave 端複製執行緒的延遲時間(ms), 預設為0, 不延遲,可動態修改。
                                                                                   
| innodb_rollback_on_timeout               | OFF 
# 當查詢因鎖定等待錯誤而中斷時,最後一條語句回滾了,整個事物還沒有終止,如果將該選項設定為1,將會改變此行為。
#innodb_rollback_on_timeout是啥作用?
答:事務B在鎖等待超時後是回滾事務內所有的statement還是最後一條語句;
      0表示rollback最後一條語句,預設值;有點坑
      1表示回滾事務B內所有的statements;
 此引數是隻讀引數,需在my.cnf中配置,並且重啟生效;
 注意:回滾statements後不自動commit或rollback事務;坑  
#總結:
1,關閉innodb_rollback_on_timeout後,一旦以begin;start transaction;等語句開啟一個事務,當鎖等待超時後,該事務請求的鎖將不釋放,直到事務提交或回滾或會話超時;
所以autocommit引數建議設定成ON,只要程式沒有顯示開啟事務,就可以避免上述鎖未釋放問題。
2、開啟innodb_rollback_on_timeout後,一旦鎖等待超時,是事務內sql將全部回滾,且釋放之前請求的鎖。
3、當autocommit=on,只要不顯示開啟事務,將不存在上面2個問題,即鎖的問題和回滾的問題
 
| innodb_rollback_segments                 | 128   
# 由innodb_undo_logs 替代:
                                                                                        
| innodb_sort_buffer_size                  | 27108864      
#specifies the size of sort buffers used for sorting data during creation of an InnoDB index.
                                                                                
| innodb_spin_wait_delay                   | 6    
#引數的值預設是6,可動態調整。
#為了防止自旋鎖迴圈過快,耗費CPU,在MySQL5.5.X版本里引入了innodb_spin_wait_delay引數,作用是控制輪訓間 隔,也就是說在每次輪訓的過程中,會休息一會兒然後再輪訓。
                                                                                        
| innodb_stats_auto_recalc                 | ON  


#對InnoDB表統計資訊持久化時,表的row發生變化大於
10%(counter > n_rows / 10 /* 10%)並且innodb_stats_auto_recalc=on,統計信資訊會更新(雖然innodb_stats_auto_recalc=on是自動重新計算,但是也是非同步的,可能會延時,比如當瞬間的DML批量操作就可能有延時) 2.統計資訊非持久化還是和5.5 一致的(表的row發生變化大於1/16時更新統計資訊)


| innodb_stats_method | nulls_equal     
#計算統計資訊時,擁有相同key prefix的行算作一個value group(類似oracle索引中的num_distinct,其值越多意味著索引選擇性越好),average group size是非常重要的指標,即平均一個索引值返回的錶行數,主要有兩個用途:
1估算每次ref access要讀取多少行
2 估算一個partial join要產生多少行 (…) join tab on tab.key = expr
 
由此可知,average group size越高則索引選擇性越低,表基數即value group數量計算公式為N/S(N:錶行數 S:average group size),可通過show index檢視
 
除了主鍵,索引不可避免的會遇到Null(對於<=>操作符,NULL和Non-null被同等對待,而Null = Null則會返回false),mysql將NULL視作無窮小;
收集統計資訊時,為了靈活的處理Null,InnoDB/MyISAM各引入一個引數Innodb_stats_method/myisam_stats_method,分別三個候選值:nulls_equal/nulls_unequal/nulls_ignored(其中innod_stats_method只有全域性變數)
Nulls_equal:所有Null都相等,即算作一個value group;若Null過多則會導致average group size偏大
Nulls_unequal:所有Null互不相同,每個算作一個value group;如果non-null group size過大且null數量過多,此設定會拉低整體的average group size,可能導致濫用索引
Nulls_ignored:忽略Null
 
對於已經收集的統計資訊,無法分辨其採用了那種方式;對於非InnoDB/MyISAM表,只有一種收集方式,即nulls_equal;
 
手工收集統計資訊需要呼叫analyze table,但若表自上次analye至今沒有任何改動,即便呼叫此命令實際也不會收集統計資訊,需先讓統計資訊過期(插入一行再刪除即可)
Mysql也可自動收集,諸如bulk insert/delete以及某些alter table語句均會觸發
如何檢視統計資訊
Show index from table或檢視information_schema.statistics表
Show table status或information_schema.tables表


                                                                              
| innodb_stats_on_metadata                 | OFF      
#預設是關閉了這個會對INFORMATION_SCHEMA中的一些表進行查詢操作,以方便索引統計資訊,如果讀要求高的建議關閉
#也就是說,當使用 SHOW INDEX, SHOW TABLE STATUS and SHOW [FULL] TABLES時,會自動更新統計資訊,或者對應的從 INFORMATION_SCHEMA.TABLES和INFORMATION_SCHEMA.STATISTICS 表中查詢時。
#實際上這個動態統計的功能已經不推薦了,以後增加引數控制 DML 期間也不作動態統計了。因此這個引數配置成 off 更合理些
                                                                                    
| innodb_stats_persistent                  | ON       
#優化器永久統計資訊通過把統計資訊儲存在磁碟上,使得MySQL在選擇語句的執行計劃時,會選擇相對一致的執行計劃,提升了SQL執行計劃的穩定性。
當開啟innodb_stats_persistent=ON這個引數時或在建表時帶了STATS_PERSISTENT=1引數,優化器的統計資訊會永久儲存到磁碟上。
                                                                                    
| innodb_stats_persistent_sample_pages     | 20   
#每次取樣的塊數,預設為20
                                                                                         
| innodb_stats_sample_pages                | 8        
#每次收集統計資訊時取樣的頁數,預設為8


                                                                                     
| innodb_stats_transient_sample_pages      | 8           
#預設為8個,取8個頁塊,分析結果作為統計資訊
                                                                                  
| innodb_status_output                     | OFF                                                                                           
| innodb_status_output_locks               | OFF  
# InnoDB各類監控輸出結果
#僅在必要時開啟,因為會造成效能開銷,觀察結束後切記關閉監控。若監控期間伺服器重新啟動,則監控不會自動開啟,需刪除原來的表並重建相關表,或者重新設定相關變數。表結構不重要,重要的是名字和需為InnoDB引擎。
#有四類InnoDB monitor:Standard Monitor、Lock Monitor、Tablespace Monitor、Table Monitor。其中Tablespace Monitor和Table Monitor將在後續版本(MySQL5.7中移除,對應的資訊可從information_schema的表中獲取)
Standard Monitor:監視活動事務持有的表鎖、行鎖;事務鎖等待;執行緒訊號量等待;檔案IO請求;buffer pool統計資訊;InnoDB主執行緒purge和change buffer merge活動。
Lock Monitor:提供額外的鎖資訊。
Tablespace Monitor:顯示共享表空間中的檔案段以及表空間資料結構配置驗證。
Table Monitor:顯示內部資料字典的內容。
# show engine innodb status\G; --顯示更多關於監控資訊,當開啟後。
(
[email protected]
(none)) Mysql >SET GLOBAL innodb_status_output=ON;
Query OK, 0 rows affected (0.00 sec)


([email protected](none)) Mysql >SHOW variables like 'innodb_status_output';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| innodb_status_output | ON    |
+----------------------+-------+
1 row in set (0.00 sec)


(
[email protected]
(none)) Mysql >show engine innodb status\G;
*************************** 1. row ***************************
  Type: InnoDB
  Name: 
Status: 
=====================================
2017-03-15 16:12:04 0x7fad2c2f5700 INNODB MONITOR OUTPUT
=====================================


                                                                                        
| innodb_strict_mode                       | ON