mysql 默认page大小_MySQL innodb_page_size
原標題:MySQL innodb_page_size
墨墨導讀:Page是MySQL Innodb存儲的最基本結構,也是Innodb磁盤管理的最小單位,了解page的一些特性,可以更容易理解MySQL。
innodb_page_size作為innodb和OS交互單位。文件系統對文件的buffer IO,也是page為單位進行處理的。Linux的默認page的大小4096字節,當要將數據寫入到文件的時候,會先在內存里,然后將對應的page cache,整個的從內存刷到磁盤上。但是如果要寫入的文件區域,因為還沒有被緩存或者被置換出去了等原因,在內存里不存在對應的page cache,則需要先將對應page的內容從磁盤上讀到內存里,修改要寫入的數據,然后在將整個page寫回到磁盤;在這種情況下,會有一次額外的讀IO開銷,IO的性能會有一定的損失。假如mysql的16K的頁表數據支持起,那就是一次內存IO光是虛擬地址到物理地址的轉換就要去內存查4次頁表,再算上真正的內存訪問,需要5次內存IO才能獲取一個內存數據。
操作系統PAGE:
在操作系統層面,每個進程都有自己獨立的地址空間,看到的都是操作系統虛擬出來的地址空間,虛擬地址最終還是要落在實際內存的物理地址上進行操作的。操作系統就會通過頁表的機制來實現進程的虛擬地址到物理地址。其中每一頁的大小都是固定的。
獲取當前操作系統的page size:
####X86:
[root@ens8 ~] # getconf PAGESIZE
4096
####ARM:
root@ens8ARM :~# getconf PAGESIZE
65536
頁表級數:
頁表級數越少,虛擬地址到物理地址的映射會很快,但是需要管理的頁表項會很多,能支持的地址空間也有限。
相反頁表級數越多,需要的存儲的頁表數據就會越少,而且能支持到比較大的地址空間,但是虛擬地址到物理地址的映射就會越慢。
備注:ARM系統來說需要編譯指定才可以。因為Linux 默認4kb頁是通過長期的跟MySQL磨合,才有現在的穩定的表現。
MySQL數據庫Page
InnoDB邏輯存儲單元主要分為表空間、段、區和頁。層級關系為tablespace -> segment -> extent(64個page,1M) -> page。(非常經典的圖)
在看看innodb_page_size的官方描述:
第一個系統表空間數據文件(ibdata1)的最小文件大小取決于innodb_page_size值
innodb_page_size只能在初始化MySQL實例之前配置,不能在之后修改。如果沒有指定值,則使用默認頁面大小初始化實例。
MySQL 5.7增加了對32KB和64KB頁面大小的支持。對于32KB和64KB的頁面大小,最大行長度約為16000字節。當innodb_page_size設置為32KB或64KB時,不支持ROW_FORMAT= compression。對于innodb_page_size=32k,區段大小為2MB。對于innodb_page_size=64KB,區段大小為4MB。當使用32KB或64KB的頁面大小時,innodb_log_buffer_size應該至少設置為16M(默認)。
默認的16KB或更大的頁面大小適用于各種工作負載,特別是涉及表掃描的查詢和涉及批量更新的DML操作。對于涉及許多小寫操作的OLTP工作負載,較小的頁面大小可能更有效,在這種工作負載中,當單個頁面包含許多行時,可能會出現爭用問題。對于通常使用較小塊的SSD存儲設備,較小的頁面也可能是有效的。保持InnoDB頁面大小接近存儲設備塊大小,可以最大限度地減少被重寫到磁盤的未更改數據量.
對于row,index,tablesapce的影響
Page對Row的影響:
對于4KB、8KB、16KB和32KB的頁大小,最大行大小(不包括存儲在頁外的任何可變長度的列)略小于頁大小的一半。例如,默認innodb_page_size為16KB的最大行大小約為8000字節。然而,對于InnoDB頁面大小為64KB的頁面,最大行大小大約是16000字節。LONGBLOB和LONGTEXT列必須小于4GB,包括BLOB和文本列在內的總行大小必須小于4GB。
Page對index的影響:
如果在創建MySQL實例時通過指定innodb_page_size選項將InnoDB頁面大小減少到8KB或4KB,索引鍵的最大長度將按比例降低,這是基于16KB頁面大小的3072字節限制。也就是說,當頁面大小為8KB時,最大索引鍵長度為1536字節,而當頁面大小為4KB時,最大索引鍵長度為768字節。
不同的Page大小,表空間限制:
Pages對字段的影響 :
對于4KB、8KB、16KB和32KB的innodb_page_size設置,最大行長度略小于數據庫頁的一半。例如,對于默認的16KB InnoDB頁面大小,最大行長度略小于8KB。對于64KB的頁面,最大行長度略小于16KB。
如果一行不超過最大行長度,則所有行都存儲在本地頁中。如果一行超過最大行長,則選擇可變長度列用于外部頁外存儲,直到該行符合最大行長限制為止。可變長度列的外部離頁存儲因行格式不同而不同:
COMPACTRow Formats:
當一個可變長度的列被選擇用于外部頁外存儲時,InnoDB將前768個字節本地存儲在行中,其余的存儲在外部溢出的頁面中。每個這樣的列都有自己的溢出頁列表。768字節的前綴伴有一個20字節的值,該值存儲列的真實長度,并指向存儲其余值的溢出列表
DYNAMICRow Formats:
當一個可變長度的列被選擇用于外部頁外存儲時,InnoDB在本地的行中存儲一個20字節的指針,其余的則在外部存儲到溢出的頁面中,LONGBLOB和LONGTEXT列必須小于4GB,包括BLOB和TEXT列在內的總行長度必須小于4GB。
Page如何計算記錄數
page構成結構:
除數據外ROW額外信息存在哪些:
16k頁為基準,能保存多少記錄數:
按照上面Page結構圖,可以如下計算:
1.page大小(16*1024=16384)- 必要信息(File Header38字節+page header56字節+虛擬最大最小記錄26字節+Page Directory4字節+File Trailer8字節)=16252字節
2.約每4條記錄占用一個slot,一個slot大小占用2字節
3.row header(5字節+可變長+非空占位符)+ 主鍵key長度(如果沒有顯示聲明默認會創建6字節row id)+ trxid6字節+ rollptr7字節
4.假如單行長度計算公式為:row header5字節 + 主鍵索引列4字節 + 指針4字節 = 13字節
單個page最多能容納最多行數為 單行長度N+N/4*2 = 16252,
N為1203測試:
通過sysben壓測,發現MySQL默認頁16K 相比8K 對CPU壓力較小,但8k頁的情況下所有指標都會有所提升。
sysbench壓測是基于主鍵,8k的頁來說,行小于4k的數據來說性能提升,假如大于4k的數據,性能肯定會有下降,因為會出現行溢出,會導致讀取列需要多一個IO。所以不同的業務場景可以有效的調整innodb page size 進行調試。當然硬件也要支持,傳統的SAS硬盤會存在IO效率下降,更上一層的硬盤(SSD,PCIE)能提供更高的IOPS。
總結
那么innodb_page_size的如何設置,按照個人理解,生產環境中,可以選擇16kb 和8kb的長度。
可以考慮一下方面:
1.遵守單行略小于頁大小的一半。不能發生行溢出現象,隨之而來的要求是盡量主鍵操作,分配跟多的內存
2.硬件設備的支持,很多高端服務器cpu使用率也就在30%以內的服務器,完全可以使用8kb,提高整體性能。
innodb_page_size設置問題,最終還是io性能方面的優化。需要有效的利用MySQL的一些特性(索引組織表,盡量走主鍵避免回表,盡量減少隨機讀寫等)結合實際情況進行配置。
前幾天一起工作的同事聊到,現在出現新的高端內存。又能放到內存,又能保存數據的內存條!
墨天輪原文鏈接:https://www.modb.pro/db/40387(復制到瀏覽器中打開或者點擊“閱讀原文”)返回搜狐,查看更多
責任編輯:
總結
以上是生活随笔為你收集整理的mysql 默认page大小_MySQL innodb_page_size的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php linux 删除文件夹,linu
- 下一篇: mysql delette_关于字符串: