Mysql資料讀取方式以及InnoDb頁儲存

2021-10-06 20:49:33 字數 2644 閱讀 5435

將資料劃分為若干個頁,以頁作為磁碟和記憶體之間互動的基本單位,inoodb中頁的大小為16kb,一般情況下一次最少讀取16kb到記憶體中並重新整理到磁碟。(1頁中至少存放兩行記錄)

mysql表中行儲存資料分四種:compact、redundant、dynamic和compressed行格式。

儲存結構類似於compact格式,但是對於處理行溢位(當乙個字段儲存長度過大時,會發生行溢位)不同。compact會儲存字串的前768個位元組,記錄其他資訊會儲存其他頁的位址;它們則是將所有位元組儲存到其他頁,並記錄真實資料儲存在其他頁面的位址。

innodb頁結構如下所示;資料被儲存user records中,但是在開始時並沒有該空間,只有當插入時,會從free space中申請空間分到user space。當free space使用完成後表示該頁使用完成,繼續申請新頁。

當資料被存入時,對應儲存的每條資料結構如下

其中記錄頭資訊結構如下所示

記錄當前在本頁的位置,從2開始。0和1為自動加入的偽記錄資料,不占用user records。分別代表最大記錄和最小記錄(根據主鍵比較大小)

當前記錄屬性,0表示普通記錄,1表示b+樹非葉節點記錄,2表示最小記錄,3表示最大記錄。我們自己插入的記錄就是普通記錄,它們的record_type值都是0,而最小記錄和最大記錄的record_type值分別為2和3。

表示從當前記錄的真實資料到下一條記錄的真實資料的位址偏移量。下一條位址不是按照插入順序,而是按照主鍵由小到大的記錄。規定最小記錄的下一條記錄就是本頁最小的使用者記錄,本頁中主鍵最大的記錄的下一條記錄位址就是最大記錄。最大記錄值為0,代表沒有下一條記錄。記錄按照主鍵的大小形成單鏈表。結構如圖所示

當刪除一條操作,netxt_reord變換方式為:

1.delete_mask值設定為1

2.被刪除記錄next_record值為0

4.n_owned值變小(n_owned在下文說)

不論我們怎麼對頁中的記錄做增刪改操作,innodb始終會維護一條記錄的單鏈表,鍊錶中的各個節點是按照主鍵值由小到大的順序連線起來的。

**規定:

1.初始情況下乙個資料頁裡只有最小記錄和最大記錄兩條記錄,它們分屬於兩個分組。之後每插入一條記錄,都會從頁目錄中找到主鍵值比本記錄的主鍵值大並且差值最小的槽,然後把該槽對應的記錄的n_owned值加1,表示本組內又新增了一條記錄,直到該組中的記錄數等於8個。

2.在乙個組中的記錄數等於8個後再插入一條記錄時,會將組中的記錄拆分成兩個組,乙個組中4條記錄,另乙個5條記錄。這個過程會在頁目錄中新增乙個槽來記錄這個新增分組中最大的那條記錄的偏移量。

innodb會為把頁中的記錄劃分為若干個組,每個組的最後乙個記錄的位址偏移量作為乙個槽,存放在page directory中,在乙個資料頁中查詢資料分兩部分:通過二分法查詢記錄所在的槽;通過記錄的next_record屬性遍歷該所在組的記錄

製作過程:

1. 將所有正常的記錄(包括最大和最小記錄,不包括標記為已刪除的記錄)劃分為幾個組。

2. 每個組的最後一條記錄(也就是組內最大的那條記錄)的頭資訊中的n_owned屬性表示該記錄擁有多少條記錄,也就是該組內共有幾條記錄。

3. 將每個組的最後一條記錄的位址偏移量單獨提取出來按順序儲存到靠近頁的尾部的地方,這個地方就是所謂的page directory,也就是頁目錄(此時應該返回頭看看頁面各個部分的圖)。頁面目錄中的這些位址偏移量被稱為槽(英文名:slot),所以這個頁面目錄就是由槽組成的。

注:最小記錄的n_owned值為1,這就代表著以最小記錄結尾的這個分組中只有1條記錄,也就是最小記錄本身。最大記錄的n_owned值為5,這就代表著以最大記錄結尾的這個分組中只有5條記錄,包括最大記錄本身還有我們自己插入的4條記錄。

當多條資料插入時分槽下圖所示:

用來標識乙個資料頁的儲存記錄的狀態資訊,比如本頁中已經儲存了多少條記錄,第一條記錄的位址是什麼。
為保證從記憶體中同步到磁碟的頁的完整性,在頁的首部和尾部都會儲存頁中資料的校驗和和頁面最後修改時對應的lsn值,如果首部和尾部的校驗和和lsn值校驗不成功的話,就說明同步過程出現了問題。

Presto讀取MySQL資料

環境presto 0.216 配置檔案 root bigdata 003 catalog vi mysql.properties connector.name mysql connection url jdbc mysql bigdata 001 3306 connection user root ...

python 讀取mysql資料

import pymysql import pandas as pd defload data from mysql conn pymysql.connect host 127.0.0.1 port 3306 user test password test db database charset u...

Shell讀取mysql資料

今天有個需求需要寫個shell讀取mysql記錄,操作一些檔案,搜尋了一下踩了些坑記錄一下 shell2.0寫法 注釋 注意 done 的寫法,第乙個 要和 done 之間沒空格,兩個 之間有乙個空格,和 之間沒空格 command1 mysql h p u p e.g.while read a r...