MySQL由以下幾個部分組成居暖,了解MySQL必須牢牢記住其體系結(jié)構(gòu)圖诗充。
連接池組件
管理服務(wù)和工具組件
SQL接口組件
查詢分析器組件
優(yōu)化器組件
緩沖組件
插件式存儲引擎
物理文件
圖中可以發(fā)現(xiàn),MySQL數(shù)據(jù)庫區(qū)別與其他數(shù)據(jù)庫的最重要的一個特點就是其插件式的表存儲引擎。
需要注意的是夹攒,存儲引擎是基于表的,而不是數(shù)據(jù)庫胁塞。存儲引擎的好處是咏尝,每個存儲引擎都有各自的特點,能夠根據(jù)具體的應(yīng)用建立不同存儲引擎表啸罢。
常見引擎有:
InnoDB存儲引擎
支持事務(wù)编检,行鎖設(shè)計、支持外鍵扰才,非讀鎖定允懂,新版本添加了全文索引。從MySQL數(shù)據(jù)庫5.5.8版本開始衩匣,InnoDB存儲引擎是默認(rèn)的存儲引擎蕾总。
MyISAM存儲引擎
不支持事務(wù),表鎖設(shè)計琅捏,支持全文索引谤专。5.5.8版本之前是默認(rèn)存儲引擎。
Memory存儲引擎
數(shù)據(jù)存放在內(nèi)存中午绳,重啟或崩潰表中的數(shù)據(jù)都將消失置侍。適合存儲臨時數(shù)據(jù)的臨時表,默認(rèn)使用哈希索引拦焚。
Archive存儲引擎
只支持INSERT和SELECT操作蜡坊,使用zlib算法將數(shù)據(jù)行進(jìn)行壓縮后存儲,適合存儲歸檔數(shù)據(jù)赎败,如日志信息秕衙。
連接MySQL
連接MySQL操作是一個連接進(jìn)程和MySQL數(shù)據(jù)庫實例進(jìn)行通信。從程序設(shè)計的角度來說僵刮,本質(zhì)上就是進(jìn)程通信据忘。常用的進(jìn)程通信方式有管道鹦牛、命名管道、命名字勇吊、TCP/IP套接字曼追、UNIX域套接字。MySQL數(shù)據(jù)庫提供的連接方式從本質(zhì)上看都是上述提及的進(jìn)程通信方式汉规。
TCP/IP
這種方式在TCP/IP連接上建立一個基于網(wǎng)絡(luò)的連接請求礼殊,一般情況下客戶端在一臺服務(wù)器上,而MySQL實例在另一臺服務(wù)器上针史。
在通過TCP/IP連接到MySQL實例時晶伦,數(shù)據(jù)庫會先檢查一張權(quán)限視圖,用來判斷發(fā)起請求的客戶端IP是否允許連接到MySQL實例啄枕。
命名管道與共享內(nèi)存
在windows平臺上婚陪,如果兩個需要進(jìn)程通信的進(jìn)程在同一臺服務(wù)器上,那么可以使用命名管道频祝。在MySQL4.1之后的版本中泌参,MySQL還提供了共享內(nèi)存的連接方式。
UNIX域套接字
在Linux和UNIX環(huán)境下智润,還可以使用UNIX域套接字及舍。UNIX域套接字其實不是一個網(wǎng)絡(luò)協(xié)議,所以只能在MySQL客戶端和數(shù)據(jù)庫實例在一臺服務(wù)器上的情況下使用窟绷。用戶可以在配置文件中指定套接字文件的路徑锯玛,如--socket=/tmp/mysql.sock。當(dāng)數(shù)據(jù)庫實例啟動后兼蜈,用戶可以通過下列命令來進(jìn)行UNIX域套接字文件的查找:
SHOW VARIABLES LIKE 'socket'
知道了UNIX域套接字文件的路徑后攘残,就可以使用該方式進(jìn)行連接了。
mysql -udavid -S /tmp/mysql.sock
文件
參數(shù)文件
MySQL實例啟動時为狸,數(shù)據(jù)庫會先去讀一個配置參數(shù)文件歼郭,用來尋找數(shù)據(jù)庫的各種文件所在位置以及制定某些初始化參數(shù),這些參數(shù)通常定義了某種內(nèi)存結(jié)構(gòu)有多大等辐棒。在默認(rèn)情況下病曾,MySQL實例會按照一定的順序在指定的位置進(jìn)行讀取,用戶只需要通過命令mysql--help|grep my.cnf來尋找即可漾根。
MySQL數(shù)據(jù)庫的參數(shù)可以分為兩類:動態(tài)參數(shù)泰涂、靜態(tài)參數(shù)。
靜態(tài)參數(shù)在整個實例生命周期內(nèi)不得更改辐怕,動態(tài)參數(shù)可以通過SET命令對動態(tài)的參數(shù)值進(jìn)行修改逼蒙。
日志文件
日志文件記錄了影響MySQL數(shù)據(jù)庫的各種類型活動。MySQL中常見的日志文件有:
錯誤日志
二進(jìn)制日志
慢查詢?nèi)罩?/p>
查詢?nèi)罩?/p>
錯誤日志
錯誤日志文件對MySQL的啟動寄疏、運行是牢、關(guān)閉過程進(jìn)行了記錄僵井。不僅記錄了所有的錯誤信息,也記錄一些警告信息或正確的信息驳棱∨玻可通過命令 SHOW VARIABLES LIKE 'log_error'來定位該文件。
當(dāng)數(shù)據(jù)庫不能正常啟動時蹈胡,第一個必須查找的文件就應(yīng)該是錯誤日志文件渊季。
錯誤日志還會提供一些數(shù)據(jù)庫優(yōu)化信息朋蔫,例如告訴用戶需要增大InnoDB存儲引擎的redo log罚渐。
慢查詢?nèi)罩?/b>
慢查詢?nèi)罩究梢詭椭脩舳ㄎ豢赡艽嬖趩栴}的SQL語句,例如可以在MySQL啟動時設(shè)一個閾值驯妄,將運行時間超過該值的所有SQL語句都記錄到慢查詢?nèi)罩局泻刹ⅰT撻撝悼赏ㄟ^參數(shù)long_query_time來設(shè)置,默認(rèn)值10秒青扔。
在默認(rèn)情況下MySQL數(shù)據(jù)庫并不啟動慢查詢?nèi)罩驹粗脩粜枰止⑦@個參數(shù)設(shè)置為ON。
另一個和慢查詢?nèi)罩居嘘P(guān)的參數(shù)是log_queries_not_using_indexes微猖,如果運行的SQL語句沒有使用索引谈息,則MySQL數(shù)據(jù)庫同樣會將這條SQL語句記錄到慢查詢?nèi)罩尽og_throttle_queries_not_using_indexes凛剥,用來表示每分鐘允許記錄到slow log且未使用索引的SQL語句次數(shù)侠仇,防止日志增長過快。
當(dāng)越來越多的SQL查詢被記錄到慢查詢?nèi)罩局袝r犁珠,要分析該文件就顯得不那么簡單直觀了逻炊。這時MySQL數(shù)據(jù)庫提供了mysqldumpslow命令幫助進(jìn)行分析。
當(dāng)數(shù)據(jù)庫的容量較小時犁享,可能因為數(shù)據(jù)庫剛建立余素,此時非常大可能是數(shù)據(jù)庫全部被緩存在緩沖池中,SQL語句運行的時間可能都是非常短的炊昆。
為了加強(qiáng)對SQL語句的捕獲方式桨吊,MySQL增加了邏輯讀取和物理讀取的統(tǒng)計。這里物理讀取指從磁盤進(jìn)行IO讀取的次數(shù)凤巨,邏輯讀取包含所有的讀取视乐,不管磁盤還是緩沖池。
用戶可以通過額外的參數(shù)long_query_io將超過指定邏輯IO次數(shù)的SQL語句記錄到slow log中磅甩,默認(rèn)為100炊林。為了兼容原MySQL數(shù)據(jù)庫的運行方式,還添加了slow_query_type來表示啟動slow log的方式:
0不啟動slow log
1按運行時間記錄
2按邏輯IO次數(shù)記錄
3按運行時間和邏輯IO次數(shù)記錄
查詢?nèi)罩?/b>
查詢?nèi)罩居涗浟怂袑ySQL數(shù)據(jù)庫請求的信息卷要,無論這些請求是否得到了正確的執(zhí)行渣聚。默認(rèn)文件名為:主機(jī)名.log独榴。從5.1開始,可以將查詢?nèi)罩镜挠涗浄湃雊eneral_log表中奕枝。
二進(jìn)制日志
二進(jìn)制日志記錄了對MySQL數(shù)據(jù)庫執(zhí)行更改的所有操作棺榔,但是不包括SELECT和SHOW這類操作。即便UPDATE等修改操作未能產(chǎn)生實際作用隘道,也會進(jìn)行記錄症歇。
總的來說,二進(jìn)制日志主要有以下幾種作用谭梗。
恢復(fù):某些數(shù)據(jù)的恢復(fù)需要二進(jìn)制日志忘晤。
復(fù)制:其原理與恢復(fù)類似,通過復(fù)制和執(zhí)行二進(jìn)制日志使一臺遠(yuǎn)程的MySQL數(shù)據(jù)庫與一臺MySQL數(shù)據(jù)庫進(jìn)行實時同步激捏。
審計:用戶可以通過二進(jìn)制日志中的信息來進(jìn)行審計设塔,判斷是否有對數(shù)據(jù)庫進(jìn)行注入的攻擊。
通過配置參數(shù)log-bin [name] 可以啟動二進(jìn)制日志远舅。如果不指定name闰蛔,則默認(rèn)文件名為主機(jī)名,所在路徑為數(shù)據(jù)庫所在目錄图柏。
參數(shù)max_binlog_size指定了單個二進(jìn)制日志文件的最大值序六,如果超過該值,則產(chǎn)生新的二進(jìn)制日志文件蚤吹,后綴名+1例诀,默認(rèn)為1G。
二進(jìn)制日志文件的文件格式為二進(jìn)制距辆,不能像錯誤日志文件余佃、慢查詢?nèi)罩疚募菢佑胏at、head跨算、tail等命令查看爆土。要查看二進(jìn)制日志文件的內(nèi)容,必須通過MySQL提供的工具mysqlbinlog诸蚕。
套接字文件
在UNIX系統(tǒng)下本地連接MySQL可以采用UNIX域套接字方式步势,這種方式需要一個套接字(socket)文件。套接字文件可由參數(shù)socket控制背犯。一般在/tmp目錄下坏瘩,名為mysql.sock。
pid文件
當(dāng)MySQL實例啟動時漠魏,會將自己的進(jìn)程ID寫入一個文件中——該文件即為pid文件倔矾。該文件可由參數(shù)pid_file控制,默認(rèn)位于數(shù)據(jù)庫目錄下,文件名為主機(jī)名.pid
表結(jié)構(gòu)定義文件
因為MySQL插件式存儲引擎的體系結(jié)構(gòu)的關(guān)系哪自,MySQL數(shù)據(jù)的存儲是根據(jù)表進(jìn)行的丰包,每個表會有與之對應(yīng)的文件。但不論表采用何種存儲引擎壤巷,MySQL都有一個以frm為后綴名的文件邑彪,這個文件記錄了該表的表結(jié)構(gòu)定義。
frm還用了存放視圖的定義胧华,如用戶創(chuàng)建了一個v_a視圖寄症,那么對應(yīng)會產(chǎn)生一個v_a.frm文件,用來記錄視圖的定義矩动。
InnoDB存儲引擎文件
每個表存儲引擎也有自己獨有的文件有巧,包括重做日志文件、表空間文件铅忿。
表空間文件
InnoDB采用將存儲的數(shù)據(jù)按表空間進(jìn)行存放的設(shè)計剪决。在默認(rèn)配置下會有一個初始大小為10MB灵汪,名為ibdata1的文件檀训。用戶可以通過參數(shù)innodb_data_file_path對其進(jìn)行設(shè)置。
用戶可以通過多個文件組成一個表空間享言,同時制定文件的屬性峻凫。若文件位于不同的磁盤上,磁盤的負(fù)載可能被平衡览露,因此可以提高數(shù)據(jù)庫的整體性能荧琼。
設(shè)置innodb_data_file_path參數(shù)后,所有基于InnoDB存儲引擎的表的數(shù)據(jù)都會記錄到該共享表空間中差牛。若設(shè)置了參數(shù)innodb_file_per_table命锄,則用戶可以將每個基于InnoDB存儲引擎的表產(chǎn)生一個獨立表空間。
重做日志文件
在默認(rèn)情況下偏化,在InnoDB存儲引擎的數(shù)據(jù)目錄下會有兩個名為ib_logfile0和ib_logfile1的文件脐恩。MySQL官方手冊稱其為InnoDB的日志文件或者叫重做日志文件。它們記錄了對于InnoDB存儲引擎的事務(wù)日志侦讨。
當(dāng)實例或介質(zhì)失敗時驶冒,重做日志文件就能派上用場。例如韵卤,數(shù)據(jù)庫掉電導(dǎo)致實例失敗骗污,InnoDB存儲引擎會使用重做日志恢復(fù)到掉電前的時刻,來保證數(shù)據(jù)的完整性沈条。
每個InnoDB存儲引擎至少有1個重做日志文件組需忿,每個文件組下至少有2個重做日志文件,如默認(rèn)的ib_logfile0和ib_logfile1。為了更高的可靠性屋厘,用戶可以設(shè)置多個鏡像日志組汞扎,將不同的文件組放在不同的磁盤上。
在日志組中擅这,兩個日志文件以循環(huán)寫入的方式運行澈魄。InnoDB先寫日志文件1,文件寫滿時仲翎,會切換至重做日志文件2痹扇,循環(huán)寫入。
參數(shù)innodb_log_file_size指定每個重做日志文件的大小溯香。
參數(shù)innodb_log_files_in_group指定了日志文件組中重做日志文件的數(shù)量鲫构,默認(rèn)為2。
參數(shù)innodb_mirrored_log_groups指定了日志鏡像文件組的數(shù)量玫坛,默認(rèn)為1结笨,沒有鏡像。
小結(jié)
當(dāng)MySQL數(shù)據(jù)庫發(fā)送任何錯誤時湿镀,首先就應(yīng)該去查看錯誤日志炕吸。建議在任何時候都開啟二進(jìn)制日志的記錄,用來進(jìn)行point in time的恢復(fù)以及復(fù)制環(huán)境的搭建勉痴。
InnoDB包括表空間文件和重做日志文件赫模,表空間文件用來管理InnoDB存儲引擎的存儲。重做日志用來記錄InnoDB存儲引擎的事務(wù)日志蒸矛,保證InnoDB存儲引擎可以提供可靠的事務(wù)瀑罗。
參考