久久精品国产精品国产精品污,男人扒开添女人下部免费视频,一级国产69式性姿势免费视频,夜鲁夜鲁很鲁在线视频 视频,欧美丰满少妇一区二区三区,国产偷国产偷亚洲高清人乐享,中文 在线 日韩 亚洲 欧美,熟妇人妻无乱码中文字幕真矢织江,一区二区三区人妻制服国产

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

高性能Mysql(第三版)笔记

發布時間:2023/12/10 数据库 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 高性能Mysql(第三版)笔记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、MySQL架構與歷史

MySQL邏輯架構

  • 最上層的服務并不是MySQL所獨有的,大多數基于網絡的客戶端/服務器的工具或者服務都有類似的架構。比如連接處理、授權認證、安全等等
  • 第二層架構是MySQL比較有意思的部分。大多數MySQL的核心服務功能都在這一層,包括查詢解析、分析、優化、緩存以及所有的內置函數(例如,日期、時間、數學和加密函數),所有跨存儲引擎的功能都在這一層實現:存儲過程、觸發器、視圖等
  • 第三層包含了存儲引擎。存儲引擎負責MySQL中數據的存儲和提取。和GNU/Linux下的各種文件系統一樣,每個存儲引擎都有它的優勢和劣勢。服務器通過API與存儲引擎進行通信。這些接口屏蔽了不同存儲引擎之間的差異,使得這些差異對上層的查詢過程透明。存儲引擎API包含幾十個底層函數,用于執行諸如“開始一個事務”或者。根據主鍵提取一行記錄"等操作。但存儲引擎不會去解析SQL性,不同存儲引擎之間也不會相互通信,而只是簡單地響應上層服務器的請求
優化與執行

MySQL會解析查詢,并創建內部數據結構(解析樹),然后對其進行各種優化,包括重寫查詢、決定表的讀取順序,以及選擇合適的索引等。用戶可以通過特殊的關鍵字提示(hint)優化器,影響它的決策過程。也可以請求優化器解釋(explain) 優化過程的各個因素,使用戶可以知道服務器是如何進行優化決策的,并提供-一個參考基準,便于用戶重構查詢和schema、修改相關配置,使應用盡可能高效運行

優化器并不關心表使用的是什么存儲引擎,但存儲引擎對于優化查詢是有影響的。優化器會請求存儲引擎提供容量或某個具體操作的開銷信息,以及表數據的統計信息等

對于SELECT語句,在解析查詢之前,服務器會先檢查查詢緩存(Query Cache),如果能夠在其中找到對應的查詢,服務器就不必再執行查詢解析、優化和執行的整個過程,而是直接返回查詢緩存中的結果集

并發控制

MySQL在兩個層面實現并發控制:服務器層與存儲引擎層

在處理并發讀或寫時,可以通過實現一個由兩種鎖組成的系統來解決問題。這兩種鎖通常被稱為共享鎖和排他鎖,或者稱為讀鎖和寫鎖。讀鎖是共享的,或者說是相互不阻塞的,多個客戶可以在同時讀取同一數據。而寫鎖是排他的,同一時刻只能有一個用戶能夠寫入,并防止其他用戶讀取正在寫入的數據

鎖粒度是指加鎖的對象的大小。顯然,鎖的粒度越小,并發控制效率越高。鎖的各種操作,包括獲得鎖、檢查鎖和釋放鎖等,都會增加系統開銷。因此,如果系統花費大量時間來管理鎖,而不是用來獲取數據,就會影響系統性能

有兩種常見的縮策略,表鎖和行級鎖。表鎖開銷較小,但是并發控制不好。行級鎖可以很好地實現并發控制,但是開銷比較大

所謂的鎖策略,就是在鎖的開銷和數據的安全性之間尋求平衡,這種平衡當然也會影響到性能。大多數商業數據庫系統沒有提供更多的選擇,一般都是在表上施加行級鎖(row-level lock),并以各種復雜的方式來實現,以便在鎖比較多的情況下盡可能地提供更好的性能。而MySQL則提供了多種選擇。每種MySQL存儲引擎都可以實現自己的鎖策略和鎖粒度

事務

事務將幾個操作作為一個整體,要么全部執行,要么全部放棄。事務的四大特性ACID

  • 原子性(atomicity):一個事務必須被視為一個不可分割的最小工作單元,整個事務中所有操作要么全部提交成功,要么全部失敗回滾,對于一個事務來說,不可能只執行其中的一部分操作
  • 一致性(consistency):數據庫總是從一個一致性的狀態轉換到另外一個一致性的狀態,比如有一個事務包括四步,從零加一,從一加一,從二加一,從三加一,那么根據一致原則,最后的結果一定是0或者4,從一個狀態轉換到另一個狀態
  • 隔離性(isolation):一個事務所做的修改在最終提交以前,對其他事務是不可見的
  • 持久性(durability):一旦事務提交,則其所做的修改就會永久保存到數據庫中
隔離級別

在SQL標準中定義了四種隔離級別,每一種級別都規定了一個事務中所做的修改,哪些在事務內和事務間是可見的,哪些是不可見的。較低級別的隔離通常可以執行更高的并發,系統的開銷也更低

  • READ UNCOMMITTED (未提交讀):在READ UNCOMITTED 級別,事務中的修改,即使沒有提交,對其他事務也都是可見的。事務可以讀取未提交的數據,這也被稱為臟讀(Dirty Read)
  • READ COMITTED (提交讀):一個事務開始時,只能看見已經提交的修改,并且所做的修改對其他事務不可見。這種存在的一個問題叫不可重復讀,就是指事務A讀取某條記錄之后,事務B對其進行了修改,這時當A再次讀取該數據的時候就會發現與之前讀取的結果不一樣
  • REPEATABLE READ (可重復讀):可重復讀解決了,數據不可重復讀的問題,但仍然不能解決幻讀,所謂幻讀,指的是當某個事務在讀取某個范圍內的記錄時,另外一個事務又在該范圍內插入了新的記錄,當之前的事務再次讀取該范圍的記錄時,會產生幻行(Phantom Row)。這是mysql的默認級別,mysql還可以通過MVCC+間隙鎖解決幻讀問題
  • SERIALIZABLE (可串行化):事務按照串行的方式執行,并在每行數據上加鎖,可能產生大量的超時和鎖爭用問題

四種隔離級別與可避免操作

  • Read uncommitted【級別最低,什么都避免不了】
  • Read committed【可避免臟讀】
  • Repeatable read【可避免臟讀,不可重復讀】
  • Serializable【可避免臟讀,不可重復讀,虛讀】

臟讀、不可重復讀與幻讀(虛讀)

  • 臟讀:一個事務讀取到另外一個事務未提交的數據
  • 不可重復讀:一個事務讀取到另外一個事務已經提交的數據,也就是說一個事務可以看到其他事務所做的修改
  • 幻讀(虛讀):是指在一個事務內讀取到了別的事務插入的數據,導致前后讀取不一致
死鎖

指兩個或多個事務在同一資源上相互占用,并請求鎖定對方占用的資源,從而導致惡性循環的現象

事務日志

存儲引擎在修改表的數據時只需要修改其內存拷貝,再把該修改行為記錄到持久在硬盤上的事務日志中,而不用每次都將修改的數據本身持久到磁盤。事務日志持久以后,內存中被修改的數據在后臺可以慢慢地刷回到磁盤,稱為預寫式日志(Write-Ahead Logging),如果數據的修改已經記錄到事務日志并持久化,但數據本身還沒有寫回磁盤,此時系統崩潰,存儲引擎在重啟時能夠自動恢復這部分修改的數據。具體的恢復方式則視存儲引擎而定。MySQL提供了兩種事務型的存儲引擎: InnoDB和NDB Cluster,也有一些第三方存儲引擎

多版本并發控制

MySQL的大多數事務型存儲引擎實現的都不是簡單的行級鎖。基于提升并發性能的考慮,它們一般都同時實現了多版本并發控制(MVCC)。可以認為MVCC是行級鎖的一個變種,但是它在很多情況下避免了加鎖操作,因此開銷更低。雖然大多引擎實現機制有所不同,但大都實現了非阻塞的讀操作,寫操作也只鎖定必要的行。典型的有樂觀(optimistic) 并發控制悲觀(pessimistic) 并發控制

MVCC的實現,是通過保存數據在某個時間點的快照來實現的,且只在REPEATABLE READ 和READ COMMITTED 兩個隔離級別下工作。其他兩個隔離級別都和MVCC不兼容,因為READ UNCONMITTED總是讀取最新的數據行,而不是符合當前事務版本的數據行。而SERIALIZABLE則會對所有讀取的行都加鎖

MySQL的存儲引擎

在文件系統中,MySQL將每個數據庫( 也可以稱之為schema)保存為數據目錄下的一個子目錄。創建表時,MySQL會在數據庫子目錄下創建一個和表同名的frm文件保存表的定義。可以使用SHOW TABLE STATUS LIKE ‘tablename’ \G 顯示表的相關信息

  • Name:表名
  • Engine:表使用的引擎
  • Version:表版本信息
  • Row_format:行的格式,一般包含可變長度的字段,如VARCHAR或BLOB
  • Rows:表中的行數
  • Avg_row_ length:平均每行的字數
  • Data_ length:表數據的大小
  • Max_ data_ length:表的最大容量,該值和存儲引擎有關
  • Index_length:索引的大小
  • Data_free:對于MyISAM表,表示已分配但目前沒有使用的空間
  • Auto_ increment:下一個AUTO_ INCREMENT 的值,
  • Create_time:表的創建時間
  • Update_ time: 表的最后修改時間
  • Check_ time:使用CKECK TABLE命令或者myisamchk工具最后一次檢查表的時間
  • Col lation:表的默認字符集和字符列排序規則
  • Checksum::如果啟用,保存的是整個表的實時校驗和
  • Create_options:創建表時指定的其他選項
  • Comment :創建表時的注釋
InnoDB 存儲引擎

InnoDB是MySQL的默認事務型引擎,也是最重要、使用最廣泛的存儲引擎。InnoDB的性能和自動崩潰恢復特性,使得它在非事務型存儲的需求中也很流行。除非有非常非常特別的原因需要使用其他的存儲引擎,否則應該優先考慮InnoDB引擎

InnoDB采用MVCC來支持高并發,井且實現了四個標準的隔離級別。其默認級別是REPEATABLE READ (可重復讀),并且通過 間隙鎖(next-key locking) 策略防止幻讀的出現。間隙鎖使得InnoDB不僅僅鎖定查詢涉及的行,還會對索引中的間隙進行鎖定,以防止幻影行的插入

InnoDB內部做了很多優化,包括從磁盤讀取數據時采的可預測性預讀,能夠自動在內存中創建hash索引以加速讀操作的自適應哈希索引(adaptive hash index),以及能夠加速插人操作的插人緩沖區(insert buffer)等。后面將更詳細地討論這些內容

MyISAM 存儲引擎

在MySQL 5.1 及之前的版本,MyISAM是默認的存儲引擎。MyISAM提供了大量的特性,包括全文索引、壓縮、空間函數(GIS) 等,但MyISAM不支持事務和行級鎖,而且有一個毫無疑問的缺陷就是崩潰后無法安全恢復。所以MySQL 5.1以后版本的MySQL已經默認不用MyISAM引擎了,相對于InnoDB那一點點的并發量的增加(需要一些條件),這些缺點讓我們不在默認引擎為MyISAM,百分之九十以上情況我們需要InnoDB,MyISAM所擁有的優點大多已能在InnoDB找到代替方案,其它引擎也一樣,所以,如果不是非常特殊的要求,我們大多情況使用InnoDB引擎,MyISAM已有的特性

  • 加鎖與并發:MyISAM對整張表加鎖,而不是針對行
  • 修復:對于MyISAM表,MySQL可以手工或者自動執行檢查和修復操作,但這里說的修復和事務恢復以及崩潰恢復是不同的概念。執行表的修復可能導致一些數據丟失,而且修復操作是非常慢的
  • 索引:支持索引,且支持全文分詞索引
MyISAM 性能

MyISAM引擎設計簡單,數據以緊密格式存儲,所以在某些場景下的性能很好,比如,數據只讀,表比較小,可以忍受修復失敗,的場景下。不要輕易相信 “MyISAM比InnoDB快” 之類的話,在很多場景下,這個結論是不對的,甚至InnoDB的速度會比MyISAM望塵莫及,比如使用到聚簇索引時

其它引擎

MySQL還有一些有特殊用途的存儲引擎。在新版本中,有些可能因為一些原因已經不再支持,就不一一說明了。那么,引擎這么多,我們應該怎么選擇呢,歸納為一句話:“除非需要用到某些InnoDB不具備的特性,并且沒有其他辦法可以替代,否則都應該優先選擇InnoDB引擎。" 輕易切換引擎,轉則讓事情復雜難搞,重則翻車跑路

二、MySQL 基準測試

基準測試(benchmark) 也譯做標準檢查程序,是MySQL新手和專家都需要掌握的一項基本技能。簡單地說,基準測試是針對系統設計的一種壓力測試。通常的目標是為了掌握系統的行為。對調優而言,準確的測試相當重要,只有測試正確才知道問題出在哪里,才能加以改進

基準測試完成的工作

  • 驗證基于系統的一些假設,確認這些假設是否符合實際情況
  • 重現系統中的某些異常行為,以解決這些異常
  • 測試系統當前的運行情況
  • 模擬比當前系統更高的負載,以找出系統隨著壓力增加而可能遇到的擴展性瓶頸
  • 規劃未來的業務增長
  • 測試應用適應可變環境的能力
  • 測試不同的硬件、軟件和操作系統配置
  • 證明新采購的設備是否配置正確

基準測試的策略

基準測試有兩種主要的策略:一是針對整個系統的整體測試,另外是單獨測試MySQL。這兩種策略也被稱為集成式(ull-stack) 以及 單組件式(single-component) 基準測試。針對整個系統做集成式測試,而不是單獨測試MySQL的原因主要有以下幾點:

  • 用戶關注的是整體性能
  • MySQL并非總是性能瓶頸
  • 做整體測試,才能發現各部分之間的緩存帶來的問題

測試何種指標

  • 吞吐量:指單位時間內的事務處理數,常用的測試單位是每秒事務數(TPS),或每分鐘事務數(TPM)
  • 響應時間或者延遲:用于測試任務所需的整體時間,根據具體的應用,測試的時間單位可能是微秒、毫秒、秒或者分鐘。通常使用百分比響應時間(percentile response time)來替代最大響應時間
  • 并發性:需要關注的是正在工作中的并發操作,或者是同時工作中的線程數或者連接數,在測試期間記錄MySQL數據庫的Threads_running狀態值
  • 可擴展性:給系統增加一倍的工作,在理想情況下就能獲得兩倍的效果(即吞吐量增加一倍),對于容量規范非常有用,可以提供其他測試無法提供的信息,來幫助發現應用的瓶頸

基準測試方法

設計測試條件時,應盡量使測試過程與真實應用的場景接近,基準測試方法的一常見錯誤

  • 使用真實數據的子集而不是全集
  • 使用錯誤的數據分布
  • 在多用戶場景中,只做單用戶的測試
  • 在單服務器上測試分布式應用
  • 與真實用戶行為不匹配
  • 反復執行同一個查詢,導致全部或部分緩存
  • 沒有檢查錯誤
  • 忽略了系統預熱(warm up)的過程
  • 使用默認的服務器配置
  • 測試時間太短
  • 收集的測試信息不夠全

基準測試的一些建議

  • 應該建立將參數和結果文檔化的規范,每一輪測試都必須進行詳細記錄
  • 基準測試應該運行足夠長的時間,需要在穩定狀態下測試并觀察
  • 在執行基準測試時,需要盡可能多地收集被測試系統的信息
  • 自動化基準測試可以防止測試人員偶爾遺漏某些步驟,或者誤操作,另外也有助于歸檔整個測試過程,可以選擇shell、php、perl等
  • 要盡可能使所有測試過程都自動化,包括裝載數據、系統預熱、執行測試、記錄結果等

三、服務器性能剖析

性能優化簡介

  • 性能,為完成某件任務所需要的時間度量,性能即響應時間
  • 如果目標是降低響應時間,就需要理解為什么服務器執行查詢需要這么多時間,然后去減少或者消除那些對獲得查詢結果來說不必要的工作。無法測量就無法有效地優化
  • 性能剖析(profiling)是測量和分析時間花費在哪里的主要方法,一般有兩個步驟:測量任務所花費的時間,對結果進行統計和排序

對應用程序進行性能剖析

性能瓶頸可能的影響因素

  • 外部資源
  • 應用需要處理大量的數據
  • 在循環中執行昂貴的操作
  • 使用了低效的算法

診斷間歇性問題

間歇性的問題比如系統偶爾停頓或者慢查詢,很難診斷。有些幻影問題只在沒有注意到的時候才發生,而且無法確認如何重現,診斷這樣的問題往往要花費很多時間,此時應注意:

  • 盡量不要用試錯的方式來解決問題,如果一時無法定位,可能是測量的方式不正確,或者測量的點選擇有誤,或者使用的工具不合適
  • 確定單條查詢問題還是服務器問題
  • 捕獲盡可能多的診斷數據

其它注意點

  • 定義性能最有效的方法是響應時間
  • 如果無法測量就無法有效地優化,所以性能優化工作需要基于高質量、全方位及完整的響應時間測量
  • 測量的最佳開始點是應用程序,而不是數據庫。即使問題出在底層的數據庫,借助良好的測量也可以很容易地發現問題
  • 大多數系統無法完整地測量,測量有時候也會有錯誤的結果
  • 完整的測量會產生大量需要分析的數據,所以需要用到剖析器
  • 有兩種消耗時間的操作:工作或者等待
  • 優化和提升是兩回事。當繼續提升的成本超過收益的時候,應當停止優化

總體來說,解決性能問題的方法,首先是要澄清問題,然后選擇合適的技術來解答這些問題。

四、Schema與數據類型優化

良好的邏輯設計和物理設計是高性能的基石,應該根據系統將要執行的查詢語句來設計schema,這往往需要權衡各種因素。例如,反范式的設計可以加快某些類型的查詢,但同時可能使另一些類型的查詢變慢

選擇優化的數據類型

MySQL支持的數據類型非常多,選擇正確的數據類型對于獲得高性能至關重要。有以下幾條建議:

  • 更小的通常更好:一般情況下,應該盡量使用可以正確存儲數據的最小數據類型。更小的數據類型通常更快,因為它們占用更少的磁盤、內存和CPU緩存,并且處理時需要的CPU周期也更少
  • 簡單就好:簡單數據類型的操作通常需要更少的CPU周期。例如,整型比字符比較操作代價更低
  • 盡量避免NULL:很多表都包含可為NULL (空值)的列,即使應用程序并不需要保存NULL也是如此,這是因為可為NULL是列的默認屬性。通常情況下最好指定列為NOT NULL,除非真的需要存儲NULL值。如果查詢中包含可為NULL的列,對MySQL來說更難優化,因為可為NULL的列使得索引、索引統計和值比較都更復雜。可為NULL的列會使用更多的存儲空間,在MySQL里也需要特殊處理

在為列選擇數據類型時,第一步需要確定合適的大類型:數字、字符串、時間等,第二步就是選擇類型的精度

整數類型

MySQL整數可以指定寬度,如int(11),對大多數應用這是沒有意義的:它不會限制值的合法范圍,只是規定了MySQL的一些交互工具用來顯示字符的個數。對于存儲和計算來說,int(20)和int(1)是相同的

實數類型

因為需要額外空間和計算開銷,所以盡量只在對小數進行計算的時候才使用decimal。在數據量比較大的時候,可以考慮使用bigint代替decimal,將存儲的單位根據小數的位數乘以相應的倍數即可。例如:銀行存儲財務數據精確到萬分之一分,則可以把所有金額乘以一百萬,然后將結果存儲在BIGINT里,這樣可以同時避免浮點存儲計算不精確和DECIMAL精確計算代價高的問題

字符串類型

CHAR適合存儲短的短的字符串,或者所有的值都接近同一長度。對于經常變更的數據,CHAR也比VARCHAR好,因為定長的CHAR不容易產生碎片。對于非常短的字符串,CHAR也比VARCHAR更好,因為VARCHAR還需要1或2個額外的字節存儲字符串長度。VARCHAR適合變長范圍比較大的數據

可以使用枚舉替代常用的字符串類型,枚舉可以把一些不重復的字符串存儲成預定義的集合。枚舉字段是按照內部存儲的整數而不是字符串進行排序的。枚舉不好的地方是當向枚舉中增加字段的時候,需要使用ALTER TABLE語句來進行修改。所以,對將來可能會變的字符串,使用枚舉不是個好的主意

日期和時間類型

通常應該盡量使用TIMESTAMP,它比DATETIME空間效率更高,如果需要將時間保存到毫秒級別,可以使用BIGINT

位數據類型

MySQL有少數幾種存儲類型使用緊湊的位存儲數據。所有這些位類型,不管底層存儲格式和處理方式如何,從技術上來說都是字符串類型

可以使用BIT列在一列中存儲一個或多個true/false值。BIT(1)定義一個包含單個位的字段,bit(2)存儲兩個位。bit列最多存儲64個位MySQL將BIT當作字符串類型,而不是數字類型。當檢索bit(1)時,結果是一個包含二進制0或1值的字符串,而不是ASCII碼的"0"或"1"。然后,在數字上下文場景中檢索時,結果將是為字符串轉換成的數字

選擇標識符

如果存儲UUID值,則應該移除“-” 符號;或者更好的做法是,用UNHEX()函數轉換。UUID值為16字節的數字,并且存儲在一個BINARY(16)列中。檢索時可以通過HEX()函數來格式化為十六進制格式

關于對象關系映射(ORM)系統

寫得很爛的schema遷移程序,或者自動生成schema的程序,都會導致嚴重的性能浪費問題。有些程序存儲任何東西都會使用很大的VARCHAR列,對象關系映射(ORM) 系統(以及使用它們的“框架”)是另一種常見的性能噩夢,一些ORM系統會存儲任意類型的數據到任意類型的后端數據存儲中,這通常意味著其沒有設計使用更優的數據類型來存儲這種設計對開發者很有吸引力,因為這使得他們可以用面向對象的方式工作,不需要考慮數據是怎么存儲的。然而,“對開發者隱藏復雜性”的應用通常不能很好地擴展。我們建議在用性能交換開發人員的效率之前仔細考慮,并且總是在真實大小的數據集.上做測試,這樣就不會太晚才發現性能問題

MySQL schema設計中的陷阱

  • 太多的列:列太多,所需的列不多,容易造成轉換問題
  • 太多的關聯:mysql限制最多關聯61張表,單個查詢建議在12個表以內
  • 全能的枚舉:注意防止過度使用枚舉
  • 變相的枚舉:枚舉(ENUM)和集合(SET)不要混用
  • 非此發明(Not Invent Here)的NULL:盡量避免使用NULL,且建議盡可能地考慮替代方案,但如果除了NULL值,沒有更好的代替值時,盡情使用NULL吧,因為強行使用代替值,可能會有造成一些程序問題

范式與反范式

范式的優點和缺點
  • 范式化的更新操作通常比反范式化要快

  • 當數據較好地范式化時,就只有很少或者沒有重復數據,所以只需要修改更少的數據

  • 范式化的表通常更小,可以更好地放在內存里,所以執行操作會更快

  • 很少有多余的數據意味著檢索列表數據時更少需要DISTINCT或者GROUP BY 語句

    范式化設計的schema的缺點是通常需要關聯。稍微復雜一些的查詢語句在符合范式的schema上都可能需要至少一次關聯,也許更多。這不但代價昂貴,也可能使一些索引策略無效。例如,范式化可能將列存放在不同的表中,而這些列如果在-一個表中本可以屬于同一個索引

反范式的優點和缺點
  • 避免了關聯

  • 避免了隨機I/O

  • 更有效的使用索引策略

反范式的缺點是容易造成數據冗余,并且如果表的列數過多,使用的不多,會造成查詢轉換性能浪費

事實是,完全的范式化和完全的反范式化schema都是實驗室里才有的東西:在真實世界中很少會這么極端地使用。在實際應用中經常需要混用,可能使用部分范式化的schema、緩存表,以及其他技巧

緩存表、匯總表和計數表

緩存表表示存儲那些可以簡單地從schema其他表獲取數據的表。

匯總表保存的是使用GROUP BY語句聚合數據的表,使用匯總表的原因是,實時計算和統計值是很昂貴的操作,因為要么需要掃描表中的大部分數據,要么只能在某些索引上才能有效運行

計數器表是用來統計某個操作的次數的表,我們可以在一個表中定義一個名為cnt的字段來表示操作的次數,然后每次執行了操作之后將其加1。但是,加1需要更新操作來完成,每次更新的時候要獲取記錄的鎖,因此并發效率不高。解決這個問題,我們可以再增加一些字段slot作為隨機的槽,例如增加100個slot字段,每次執行操作的時候,我們使用隨機數選擇某個slot,并對其進行+1更新(只用鎖住部分數據,因此效率比較高)。最后統計的時候將全部記錄加起來即可

更慢的寫,更快的讀

為了提升讀查詢的速度,經常會需要建一些額外索引,增加冗余列,甚至是創建緩存表和匯總表。這些方法會增加寫查詢的負擔,也需要額外的維護任務,但在設計高性能數據庫時,這些都是常見的技巧:雖然寫操作變得更慢了,但更顯著地提高了讀操作的性能

加快ALTER TABLE操作的速度

MySQL的ALTER TABLE 操作的性能對大表來說是個大問題。MySQL執行大部分修改表結構操作的方法是,鎖住表,然后用新的結構創建一個空表,從舊表中查出所有數據插入新表,然后刪除舊表。這樣操作可能需要花費很長時間,如果內存不足而表又很大,而且還有很多索引的情況下尤其如此。一般而言,大部分ALTER TABLE操作將導致MySQL服務中斷,這里介紹兩種DDL操作技巧,避免這種情況:

  • 一是在一臺不提供服務的機器上執行ALTER TABLE操作,然后和提供服務的主庫進行切換
  • 二是通過“影子拷貝”,創建一張新表,然后通過重命名和刪表操作交換兩張表及里面的數據

五、創建高性能的索引

索引(在MySQL中也叫做“鍵(key)") 是存儲引擎用于快速找到記錄的一種數據結構。索引優化應該是對查詢性能優化最有效的手段了。索引能夠輕易將查詢性能提高幾個數量級。

索引基礎

數據庫的索引類似于書的索引,實際的查找某個值的時候,先按照值進行查找,然后返回包含該值的數據行。索引可以包含一個或多個列的值,如果索引包含多個列,那么列的順序也很重要,索引對多個列排序的依據是CREATE TABLE時定義索引的順序,所以MySQL只能高效地使用索引的最左前綴列,這里要注意的是,創建一個包含多個列的索引,和創建多個只包含一列的索引是大不相同的

ORM工具能夠產生符合邏輯的、合法的查詢,除非只是生成非常基本的查詢(例如僅是根據主鍵查詢),否則它很難生成適合索引的查詢

索引的類型

索引有很多種類型,可以為不同的場景提供更好的性能。在MySQL中,索引是在存儲引擎層而不是服務器層實現的。所以,并沒有統一的索引標準:不同存儲引擎的索引的工作方式并不一樣,也不是所有的存儲引擎都支持所有類型的索引。即使多個存儲引擎支持同一種類型的索引,其底層的實現也可能不同

B-Tree索引

通常人們所說的索引。實際上很多存儲引擎使用的是B+Tree。這里B-Tree索引適用于全鍵值鍵值范圍鍵前綴查找,B-Tree通常意味著所有的值都是按順序存儲的,并且每一個葉子頁到根的距離相同

類型,以多列索引key(last_name, first_name, dob)為例:

  • 全值匹配:指定查詢的人的fitst_name, last_name和dob
  • 匹配最左前綴:查找指定了last_name的記錄
  • 匹配列前綴:匹配某一列的值的開頭部分,比如last_name以J開頭
  • 匹配范圍值:匹配某兩個索引之間的值,例如Allen和Barrymore之間的人
  • 精確匹配某一列并范圍匹配另一列:查找last_name為Allen,并且first_name以k開頭的
  • 只訪問索引的查詢:B-Tree通常可以支持只訪問索引的查詢,即查詢只需要訪問索引,而無需訪問數據行

因為索引樹中的節點是有序的,所以除了按值查找之外,索引還可以用于查詢中的ORDER BY 操作( 按順序查找)。一般來說,如果B-Tree可以按照某種方式查找到值,那么也可以按照這種方式用于排序。所以,如果ORDERBY子句滿足前面列出的幾種查詢類型,則這個索引也可以滿足對應的排序需求

B-Tree的一些限制:

  • 如果不是按照從最左列開始查找,則無法使用索引。例如無法查找只指定了first_name或者dob的記錄
  • 不能跳過索引中的列:不能在查找的時候只指定了last_name和dob,那么dob不會使用索引
  • 如果查詢的時候有某個列的查詢范圍,則其右邊的所有列都無法使用索引優化查找。比如對last_name使用了like,那么first_name和dob將不會使用索引
哈希索引

哈希索引(hash index)基于哈希表實現,只有精確匹配索引所有列的查詢才有效。對于每一行數據,存儲引擎都會對所有的索引列計算一個哈希碼(hash code),哈希碼是一個較小的值,并且不同鍵值的行計算出來的哈希碼也不一樣。哈希索引將所有的哈希碼存儲在索引中,同時在哈希表中保存指向每個數據行的指針,因為索引自身只需存儲對應的哈希值,所以索引的結構十分緊湊,這也讓哈希索引查找的速度非常快。然而,哈希索引也有它的限制:

  • 哈希索引只包含哈希值和行指針,而不存儲字段值,所以不能使用索引中的值來避免讀取行。不過,訪問內存中的行的速度很快,所以大部分情況下這一點對性能的影響并不明顯
  • 哈希索引數據并不是按照索引值順序存儲的,所以也就無法用于排序
  • 哈希索引也不支持部分索引列匹配查找,因為哈希索引始終是使用索引列的全部內容來計算哈希值的。例如,在數據列(A,B) 上建立哈希索引,如果查詢只有數據列A,則無法使用該索引
  • 哈希索引只支持等值比較查詢,包括=、IN()、<=> (注意<>和<=>是不同的操作)。也不支持任何范圍查詢,例如WHERE price > 100
  • 訪問哈希索引的數據非常快,除非有很多哈希沖突(不同的索引列值卻有相同的哈希值)。當出現哈希沖突的時候,存儲引擎會把值存到鏈表中,所以此時必須遍歷鏈表中所有的行指針,逐行進行比較,直到找到所有符合條件的行
  • 如果哈希沖突很多的話,一些索引維護操作的代價也會很高。沖突越多,代價越大

因為這些限制,哈希索引只適用于某些特定的場合。而一旦適合哈希索引,則它帶來的性能提升將非常顯著。

空間數據索引(R-Tree)

MyISAM表支持空間索引,可以用作地理數據存儲

全文索引

全文索引是一種特殊類型的索引,它查找的是文本中的關鍵詞,而不是直接比較索引中的值。全文搜索和其他幾類索引的匹配方式完全不一樣。它有許多需要注意的細節,如停用詞、詞干和復數、布爾搜索等。全文索引更類似于搜索引擎做的事情,而不是簡單的WHERE條件匹配。在相同的列上同時創建全文索引和基于值的B-Tree索引不會有沖突,全文索引適用于MATCH AGAINST 操作,而不是普通的WHERE條件操作

還有很多第三方的存儲引擎使用不同類型的數據結構來存儲索引,例如分型樹索引等

索引的優點

索引可以讓服務器快速地定位到表的指定位置。但是這并不是索引的唯一作用,到目前為止可以看到,根據創建索引的數據結構不同,索引也有一些其他的附加作用。總結下來索引共有三個優點:

  • 索引大大減少了服務器需要掃描的數據量
  • 索引可以幫助服務器避免排序和臨時表
  • 索引可以將隨機I/O變為順序I/O

索引三星系統

  • 索引將相關的記錄放到一起則獲得一星
  • 如果索引中的數據順序和查找中的排序一致則獲得二星
  • 如果索引中的列包含了查詢中需要的全部列則獲得三星

對于小型的表,使用全表掃描更高效;對中到大型的表,使用索引非常有效。對于特大型的表,建立和使用索引的代價會隨之增長。這種情況下可以使用分區來查出一組數據,而不是一條一條地匹配

高性能的索引策略

MySQL EXPLAIN

EXPLAIN命令是查詢表信息的工具,我們可以根據查詢的信息做出正確的優化行為,所以這里有必要加一下它的使用介紹

  • id:執行編號,標識select所屬的行。如果在語句中沒子查詢或關聯查詢,只有唯一的select,每行都將顯示1。否則,內層的select語句一般會順序編號,對應于其在原始語句中的位置
  • select_type:SELECT類型,可以為以下任何一種
    • SIMPLE:簡單SELECT(不使用UNION或子查詢)
    • PRIMARY:最外面的SELECT
    • UNION:UNION中的第二個或后面的SELECT語句
    • DEPENDENT UNION:UNION中的第二個或后面的SELECT語句,取決于外面的查詢
    • UNION RESULT:UNION 的結果
    • SUBQUERY:子查詢中的第一個SELECT
    • DEPENDENT SUBQUERY:子查詢中的第一個SELECT,取決于外面的查詢
    • DERIVED:導出表的SELECT(FROM子句的子查詢)
  • table:訪問引用哪個表(引用某個查詢,如“user”)
  • type:聯接類型。下面給出各種聯接類型,按照從最佳類型到最壞類型進行排序:
    • system:表僅有一行(=系統表)。這是const聯接類型的一個特例
    • const:表最多有一個匹配行,它將在查詢開始時被讀取。因為僅有一行,在這行的列值可被優化器剩余部分認為是常數。const表很快,因為它們只讀取一次!
    • eq_ref:對于每個來自于前面的表的行組合,從該表中讀取一行。這可能是最好的聯接類型,除了const類型
    • ref:對于每個來自于前面的表的行組合,所有有匹配索引值的行將從這張表中讀取
    • ref_or_null:該聯接類型如同ref,但是添加了MySQL可以專門搜索包含NULL值的行
    • index_merge:該聯接類型表示使用了索引合并優化方法
    • unique_subquery:該類型替換了下面形式的IN子查詢的ref: value IN (SELECT primary_key FROM single_table WHERE some_expr) unique_subquery是一個索引查找函數,可以完全替換子查詢,效率更高
    • index_subquery:該聯接類型類似于unique_subquery。可以替換IN子查詢,但只適合下列形式的子查詢中的非唯一索引: value IN (SELECT key_column FROM single_table WHERE some_expr)
    • range:只檢索給定范圍的行,使用一個索引來選擇行
    • index:該聯接類型與ALL相同,除了只有索引樹被掃描。這通常比ALL快,因為索引文件通常比數據文件小
    • ALL:對于每個來自于先前的表的行組合,進行完整的表掃描
  • possible_keys:揭示哪一些索引可能有利于高效的查找
  • key:顯示MySQL實際決定使用的鍵(索引)。如果沒有選擇索引,鍵是NULL
  • key_len:顯示MySQL決定使用的鍵長度。如果鍵是NULL,則長度為NULL
  • ref:顯示使用哪個列或常數與key一起從表中選擇行
  • rows:顯示MySQL認為它執行查詢時必須檢查的行數。多行之間的數據相乘可以估算要處理的行數
  • filtered:顯示了通過條件過濾出的行數的百分比估計值
  • Extra:該列包含MySQL解決查詢的詳細信息
    • Distinct:MySQL發現第1個匹配行后,停止為當前的行組合搜索更多的行
    • Not exists:MySQL能夠對查詢進行LEFT JOIN優化,發現1個匹配LEFT JOIN標準的行后,不再為前面的的行組合在該表內檢查更多的行
    • range checked for each record (index map: #):MySQL沒有發現好的可以使用的索引,但發現如果來自前面的表的列值已知,可能部分索引可以使用
    • Using filesort:MySQL需要額外的一次傳遞,以找出如何按排序順序檢索行
    • Using index:從只使用索引樹中的信息而不需要進一步搜索讀取實際的行來檢索表中的列信息
    • Using temporary:為了解決查詢,MySQL需要創建一個臨時表來容納結果
    • Using where:WHERE 子句用于限制哪一個行匹配下一個表或發送到客戶
    • Using sort_union(…), Using union(…), Using intersect(…):這些函數說明如何為index_merge聯接類型合并索引掃描
    • Using index for group-by:類似于訪問表的Using index方式,Using index for group-by表示MySQL發現了一個索引,可以用來查 詢GROUP BY或DISTINCT查詢的所有列,而不要額外搜索硬盤訪問實際的表
獨立的列

如果查找中的列不是獨立的,則MySQL不會使用索引。獨立的列是指索引列不能是表達式的一部分,也不能是函數的參數

前綴索引和索引的選擇性

索引很長的字符串會讓索引變得大且慢。通常可以只索引開始部分的字符,這樣可以節約索引空間,從而提高索引的效率。缺點是會降低索引的選擇性。索引的選擇性是指不重復的索引值和記錄總數的比,顯然越大越好。所以,我們需要選擇足夠長的前綴來保證選擇性,同時又不能太長以降低索引空間

我們可以使用語句

select count(distinct left(col_name, 3)) / count(*) from tbl_name;

來統計使用3個字符的前綴選擇性,同理可以計算出4個,5個等的情況。最后,選擇一個合理的前綴長度即可。選擇了長度之后可以像下面這樣設置指定長度的索引:

alter table add key(col_nane(4));
多列索引

很多人對多列索引的理解都不夠。一個常見的錯誤就是,為每個列創建獨立的索引,或者按照錯誤的順序創建多列索引

在多個列上建立獨立的單列索引大部分情況下并不能提高MySQL的查詢性能。MySQL5.0和更新版本引入了一種叫“ 索引合并”(index merge)的策略,一定程度上可以使用表上的多個單列索引來定位指定的行。更早版本的MySQL只能使用其中某一個單列索引,然而這種情況下沒有哪一個獨立的單列索引是非常有效的

但在MySQL 5.0和更新的版本中,查詢能夠同時使用這兩個單列索引進行掃描,并將結果進行合并。這種算法有三個變種:OR條件的聯合(union) ,AND條件的相交(intersection),組合前兩種情況的聯合及相交。

索引合并策略有時候是一種優化的結果,但實際上更多時候說明了表上的索引建得很糟糕:

  • 當出現服務器對多個索引做相交操作時(通常有多個AND條件),通常意味著需要一個包含所有相關列的多列索引,而不是多個獨立的單列索引。
  • 當服務器需要對多個索引做聯合操作時(通常有多個OR條件),通常需要耗費大量CPU和內存資源在算法的緩存、排序和合并操作上。特別是當其中有些索引的選擇性不高,需要合并掃描返回的大量數據的時候
  • 更重要的是,優化器不會把這些計算到“查詢成本”(cost) 中,優化器只關心隨機頁面讀取。這會使得查詢的成本被“ 低估”,導致該執行計劃還不如直接走全表掃描。這樣做不但會消耗更多的CPU和內存資源,還可能會影響查詢的并發性,但如果是單獨運行這樣的查詢則往往會忽略對并發性的影響。通常來說,還不如像在MySQL4.1或者更早的時代一樣,將查詢改寫成UNION的方式往往更好

如果在EXPLAIN中看到有索引合并,應該好好檢查一下查詢和表的結構,看是不是已經是最優的。也可以通過參數optimizer_ switch 來關閉索引合并功能。也可以使用IGNORE INDEX 提示讓優化器忽略掉某些索引

選擇合適的索引順序

如果要對多個列建立一個索引,除了上面的問題之外,還應該考慮所建的索引中列的順序。比如,對col1, col2兩列數據建立索引,那么我們的順序應被指定為(col1, col2)還是(col2, col1)呢。我們要先知道,在一個多列B-Tree索引中,索引列的順序意味著索引首先按照最左列進行排序,其次是第二列,等等。所以,在沒有特殊要求的情況下,我們可以使用選擇性來解決這個問題,我們可以將選擇性比較高的列作為索引的第一列,另一列作為第二列,以次類推

聚簇索引

聚簇索引并不是一種單獨的索引類型,而是一種數據存儲方式。具體的細節依賴于其實現方式,但InnoDB的聚簇索引實際上在同一個結構中保存了B-Tree 索引和數據行

當表有聚簇索引時,它的數據行實際上存放在索引的葉子頁(leaf page)中。術語“聚簇”表示數據行和相鄰的鍵值緊湊地存儲在一起。因為無法同時把數據行存放在兩個不同的地方,所以一個表只能有一個聚簇索引

因為是存儲引擎負責實現索引,因此不是所有的存儲引擎都支持聚簇索引。這里我們主要關注InnoDB,但是這里討論的原理對于任何支持聚簇索引的存儲引擎都是適用的。

下圖展示了聚簇索引中的記錄是如何存放的。注意到,葉子頁包含了行的全部數據,但是節點頁只包含了索引列。在這個案例中,索引列包含的是整數值,圖中的索引列即為主鍵列

如果沒有定義主鍵,InnoDB會選擇一個唯一的非空索引代替。如果沒有這樣的索引,InnoDB會隱式定義一個主鍵來作為聚簇索引。InnoDB只聚集在同一個頁面中的記錄。包含相鄰鍵值的頁面可能會相距甚遠

聚簇主鍵可能對性能有幫助,但也可能導致嚴重的性能問題。所以需要仔細地考慮聚簇索引,尤其是將表的存儲引擎從InnoDB改成其他引擎的時候(反過來也一樣)

聚集的數據有一些重要的優點:

  • 可以把相關數據保存在一起。例如實現電子郵箱時,可以根據用戶ID來聚集數據,這樣只需要從磁盤讀取少數的數據頁就能獲取某個用戶的全部郵件。如果沒有使用聚簇索引,則每封郵件都可能導致一次磁盤I/O
  • 數據訪問更快。聚簇索引將索引和數據保存在同一個B-Tree中,因此從聚簇索引中獲取數據通常比在非聚簇索引中查找要快
  • 使用覆蓋索引掃描的查詢可以直接使用頁節點中的主鍵值

如果在設計表和查詢時能充分利用上面的優點,那就能極大地提升性能。同時,聚簇索引也有一些缺點:

  • 聚簇數據最大限度地提高了I/O密集型應用的性能,但如果數據全部都放在內存中,則訪問的順序就沒那么重要了,聚簇索引也就沒什么優勢了
  • 插入速度嚴重依賴于插入順序。按照主鍵的順序插入是加載數據到InnoDB表中速度最快的方式。但如果不是按照主鍵順序加載數據,那么在加載完成后最好使用OPTIMIZE TABLE 命令重新組織一下表
  • 更新聚簇索引列的代價很高,因為會強制InnoDB將每個被更新的行移動到新的位置
  • 基于聚簇索引的表在插人新行,或者主鍵被更新導致需要移動行的時候,可能面臨“頁分裂(page split)” 的問題。當行的主鍵值要求必須將這一行插入到某個已滿的頁中時,存儲引擎會將該頁分裂成兩個頁面來容納該行,這就是一次頁分裂操作。頁分裂會導致表占用更多的磁盤空間
  • 聚簇索引可能導致全表掃描變慢,尤其是行比較稀疏,或者由于頁分裂導致數據存儲不連續的時候
  • 二級索引(非聚簇索引)可能比想象的要更大,因為在二級索引的葉子節點包含了引用行的主鍵列
  • 二級索引訪問需要兩次索引查找,而不是一次

最后一點可能讓人有些疑惑,為什么二級索引需要兩次索引查找?答案在于二級索引中保存的“行指針”的實質。要記住,二級索引葉子節點保存的不是指向行的物理位置的指針,而是行的主鍵值
這意味著通過二級索引查找行,存儲引擎需要找到二級索引的葉子節點獲得對應的主鍵值,然后根據這個值去聚簇索引中查找到對應的行。這里做了重復的工作:兩次B-Tree查找而不是一次。對于InnoDB,自適應哈希索引能夠減少這樣的重復工作

InnoDB和MyISAM的數據分布對比

聚簇索引和非聚簇索引的數據分布有區別,以及對應的主鍵索引和二級索引的數據分布也有區別,通常會讓人感到困擾和意外。來看看InnoDB和MyISAM是如何存儲下面這個表的:

CREATE TABLE layout_test (col1 int NOT NULL,col2 int NOT NULL,PRIMARY KEY(col1),KEY(col2) );

假設該表的主鍵取值為1 ~ 10 000,按照隨機順序插入并使用OPTIMIZE TABLE 命令做了優化。換句話說,數據在磁盤上的存儲方式已經最優,但行的順序是隨機的。列col2的值是從1 ~ 100 之間隨機賦值,所以有很多重復的值

MyISAM的數據分布

MyISAM 的數據分布非常簡單,所以先介紹它。MyISAM按照數據插入的順序存儲在磁盤上,如下圖所示

在行的旁邊顯示了行號(可理解為地址),從0開始遞增。因為行是定長的,所以MyISAM可以從表的開頭跳過所需的字節找到需要的行(MyISAM 并不總是使用圖中的“行號”,而是根據定長還是變長的行使用不同策略)

這種分布方式很容易創建索引。下面顯示的一系列圖,隱藏了頁的物理細節,只顯示索引中的“節點”,索引中的每個葉子節點包含“行號”。下圖顯示了表的主鍵

這里忽略了一些細節,例如前一個B-Tree節點有多少個內部節點,不過這并不影響對非聚簇存儲引擎的基本數據分布的理解

那col2列上的索引又會如何呢?有什么特殊的嗎?回答是沒什么區別,下圖顯示了col2列上的索引

事實上,MyISAM中主鍵索引和其他索引在結構上沒有什么不同。主鍵索引就是一個名為PRIMARY的唯一非空索引

InnoDB的數據分布

因為InnoDB支持聚簇索引,所以使用非常不同的方式存儲同樣的數據。InnoDB如下圖所示的方式存儲數據

第一眼看上去,感覺該圖和前面的MyISAM主鍵分布圖沒有什么不同,但再仔細看細節,會注意到該圖顯示了整個表,而不是只有索引。因為在InnoDB中,聚簇索引“就是”表,所以不像MyISAM那樣需要獨立的行存儲

聚簇索引的每一個葉子節點都包含了主鍵值事務ID、用于事務和MVCC的回滾指針以及所有的剩余列(在這個例子中是col2)。如果主鍵是一個列前綴索引,InnoDB 也會包含完整的主鍵列和剩下的其他列

還有一點和MyISAM的不同是,InnoDB的二級索引和聚簇索引很不相同。InnoDB 二級索引的葉子節點中存儲的不是“行指針”,而是主鍵值,并以此作為指向行的“指針” 這樣的策略減少了當出現行移動或者數據頁分裂時二級索引的維護工作。使用主鍵值當作指針會讓二級索引占用更多的空間,換來的好處是,InnoDB 在移動行時無須更新二級索引中的這個“指針”

下圖顯示了示例表的col2索引。每一個葉子節點都包含了索引列(這里是col2),緊接著是主鍵值(col1)。并展示了B-Tree的葉子節點結構,但我們故意省略了非葉子節點這樣的細節。InnoDB的非葉子節點包含了索引列和一個指向下級節點的指針(下一級節點可以是非葉子節點,也可以是葉子節點)。這對聚簇索引和二級索引都適用

下圖是描述InnoDB和MyISAM如何存放表的抽象圖。從圖中可以很容易看出InnoDB和MyISAM保存數據和索引的區別

在InnoDB表中按主鍵順序插入行
如果正在使用InnoDB表并且沒有什么數據需要聚集,那么可以定義一個代理鍵(surrogate key)作為主鍵,這種主鍵的數據應該和應用無關,最簡單的方法是使用AUTO_ INCREMENT 自增列。這樣可以保證數據行是按順序寫人,對于根據主鍵做關聯操作的性能也會更好
最好避免隨機的(不連續且值的分布范圍非常大)聚簇索引,特別是對于1/O密集型的應用。例如,從性能的角度考慮,使用UUID來作為聚簇索引則會很糟糕:它使得聚簇索引的插人變得完全隨機,這是最壞的情況,使得數據沒有任何聚集特性,下面總結了一些缺點:

  • 寫入的目標頁可能已經刷到磁盤上并從緩存中移除,或者是還沒有被加載到緩存中,InnoDB在插人之前不得不先找到并從磁盤讀取目標頁到內存中。這將導致大量的隨機I/O
  • 因為寫人是亂序的,InnoDB 不得不頻繁地做頁分裂操作,以便為新的行分配空間。頁分裂會導致移動大量數據,一次插入最少需要修改三個頁而不是一個頁
  • 由于頻繁的頁分裂,頁會變得稀疏并被不規則地填充,所以最終數據會有碎片

在把這些隨機值載入到聚簇索引以后,也許需要做一次OPTIMIZE TABLE 來重建表并優化頁的填充。不難看出,使用InnoDB時應該盡可能地按主鍵順序插入數據,并且盡可能地使用單調增加的聚簇鍵的值來插入新行

覆蓋索引

如果一個索引包含了所有需要查詢的字段的值,就稱之為覆蓋索引。覆蓋索引就是從索引中直接獲取查詢結果,要使用覆蓋索引需要注意select查詢列中包含在索引列中,此時不用第二次查詢表,所以速度很快;where條件包含索引列或者復合索引的前導列;查詢結果的字段長度盡可能少

使用延遲關聯解決索引無法覆蓋問題:下面的解決方法對效率的提升不是絕對的

SELECT * FROM products WHERE actor = 'SEAB CARREY' AND title like '%APPOLO%'

上面的SQL中要查詢全部的列,而我們沒有覆蓋全部列的索引,因此沒有覆蓋索引。另外,like操作無法使用索引,因為like操作只有在匹配左前綴時才能使用索引

我們可以像下面這樣解決問題:

SELECT * FROM products JOIN (SELECT prod_id FROM products WHERE actor = 'SEAB CARREY' AND title like '%APPOLO%') AS t1 ON (t1.prod_id = products.prod_id)

這里,需要先建立(actor, title, prod_id)索引。我們先在子查詢中找到匹配的prod_id,然后跟外層中數據進行匹配來獲取所有列值。當符合where條件的數據數量遠小于actor過濾出的數據數量的時候,它的效率尤其高。因為,根據子查詢的where過濾出數據之后才與外層查詢關聯,而后者使用actor讀取出數據之后,再用title進行關聯。前者需要讀取的數據量更少

按索引掃描來排序

生成有序結果的兩種方式:排序,按索引順序掃描。當explain出的type為index時,說明使用索引掃描來進行排序。MySQL可以使用一個索引既滿足排序,又滿足查找。只有當索引的列順序和ORDER BY子句順序一致,且列的排序方向都一樣時,才能用索引對結果做排序

冗余和重復索引

MySQL允許在相同列上創建多個索引,無論是有意的還是無意的。但重復索引是指在相同的列上按照相同的順序創建的相同類型的索引。應該避免這樣創建重復索引,發現后也應刪除。常見的錯誤有:

  • 使用主鍵和唯一約束時與已有的所沖突,因為主鍵和唯一約束是通過索引來實現的,如果再定義索引就會冗余,例如:無意間給主鍵也加個索引
  • 若創建了索引(A,B)再創建索引(A)則冗余,而索引(B,A)和(B)不是,因為(B)不是最左前綴,故應該盡量擴展已有的索引而不是創建新索引
索引和鎖

InnoDB只有在訪問行的時候才會對其加鎖,而索引能夠減少訪問行的次數,所以索引能減少鎖的數量

維護索引和表

即使用正確的類型創建了表并加上了合適的索引,工作也沒有結束:還需要維護表和索引來確保它們都正常工作。維護表有三個主要的目的:找到并修復損壞的表維護準確的索引統計信息減少碎片

  • CHECK TABLE檢查表是否損壞,ALTER TABLE innodb_tb1 ENGINE=INNODB;修復表
  • records_in_range()通過向存儲引擎傳入兩個邊界值獲取在這個范圍大概有多少條記錄,對于innodb不精確
  • info()返回各種類型的數據,包括索引的基數
  • 可以使用SHOW INDEX FROM命令來查看索引的基數
  • B-Tree索引可能會碎片化,這會降低查詢的效率

六、查詢性能優化

為什么查詢速度會慢

  • 如果要優化查詢,實際上要優化其子任務,要么消除其中一些子任務,要么減少子任務的執行次數,要么讓子任務運行得更快
  • 查詢的生命周期大致可以按照順序來看:從客戶端,到服務器,然后在服務器上進行解析,生成執行計劃,執行,并返回結果給客戶端

慢查詢基礎:優化數據訪問

兩個分析步驟
  • 確認應用程序是否在檢索大量超過需要的數據
  • 確認MySQL服務器層是否在分析大量超過需要的數據行

是否向數據庫請求了不需要的數據

  • 查詢不需要的記錄
  • 多表關聯并返回全部列
  • 總是取出全部列
  • 重復查詢相同的數據
MySQL是否在掃描額外的記錄
  • 查詢開銷三個指標:響應時間、掃描的行數、返回的行數
  • 響應時間:服務時間和排隊時間之和,“快速上限估計”法
  • 掃描的行數:較短的行的訪問速度更快,內存中的行也比磁盤中的行的訪問 速度要快得多
  • 訪問類型:EXPLAIN中的type列反應了訪問類型;通過增加合適的索引
  • 三種方式應用WHERE條件:在索引中使用WHERE條件來過濾不匹配的記錄;使用索引覆蓋掃描(Extra中出現Using index)來返回記錄,直接從索引中過濾不需要的記錄并返回命中結果;從數據表中返回數據,然后過濾不滿足條件的記錄(Extra中出現Using Where)
  • 需要掃描大量數據但只返回少數的行的優化技巧:使用索引覆蓋掃描,改變庫表結構,重寫復雜的查詢
重構查詢的方式
  • MySQL從設計上讓連接和斷開連接都很輕量級,在返回一個小的查詢結果方面很高效
  • 切分查詢,將大查詢切分成小查詢,每個查詢功能完全一樣,只完成一小部分,每次只返回一小部分查詢結果,可以避免鎖住很多數據、占滿事務日志、耗盡系統資源、阻塞很多小的但重要的查詢
  • 分解關聯查詢優勢:
    • 讓緩存的效率更高
    • 將查詢分解后,執行單個查詢可以減少鎖的競爭
    • 在應用層做關聯,可以更容易對數據庫進行拆分,更容易做到高性能和可擴展
    • 查詢本身效率也可能會有所提升
    • 可以減少冗余記錄的查詢
    • 相當于在應用中實現了哈希關聯,而不是使用MySQL的嵌套循環關聯
  • 分解關聯查詢的場景
    • 當應用能夠方便地緩存單個查詢的結果的時候當
    • 可以將數據分布到不同的MySQL服務器上的時候
    • 當能夠使用IN()的方式代替關聯查詢的時候
    • 當查詢中使用同一個數據表的時候
查詢執行的基礎
  • 查詢執行路徑
    • 客戶端發送一條查詢給服務器
    • 服務器先檢查查詢緩存,如果命中則立刻返回,否則進入下一階段
    • 服務器端進行SQL解析、預處理,再由優化器生成對應的執行計劃
    • MySQL根據優化器生成的執行計劃,調用存儲引擎的API來執行查詢
    • 將結果返回給客戶端
  • MySQL客戶端和服務器之間的通信協議是“半雙工”的,無法將一個消息切成小塊獨立來發送,沒法進行流量控制,一旦一端開始發生消息,另一端要接收完整個消息才能響應它
  • MySQL通常需要等所有的數據都已經發送給客戶端才能釋放這條查詢所占用的資源,所以接收全部結果并緩存通常可以減少服務器的壓力
  • 查詢狀態,SHOW FULL PROCESSLIST命令查看:
    • Sleep,線程正在等待客戶端發送新的請求
    • Query,線程正在執行查詢或者正在將結果發送給客戶端
    • Locked,在MySQL服務器層,該線程正在等待表鎖
    • Analyzing and statistics,線程正在收集存儲引擎的統計信息,并生成查詢的執行計劃
    • Copying to tmp table [on disk],線程正在執行查詢,并且將其結果集都復制到一個臨時表中,要么是在做GROUP BY操作,要么是文件排序操作,或者是UNION操作
    • Sorting result,線程正在對結果集進行排序
    • Sending data,線程可能在多個狀態之間傳送數據,或者在生成結果集,或者在向客戶端返回數據
  • 語法解析器和預處理,通過關鍵字將SQL語句進行解析,并生成一棵對應的“解析樹”,解析器將使用MySQL語法規則驗證和解析查詢,預處理器則根據一些MySQL規則進一步檢查解析樹是否合法
  • 查詢優化器,找到最好的執行計劃,使用基本成本的優化器,將嘗試預測一個查詢使用某種執行計劃時的成本,并選擇其中成本最小的一個,使用SHOW STATUS LIKE ‘Last_query_cost’;查看需要多少個數據頁的隨機查找
  • 導致MySQL查詢優化器選擇錯誤的原因:
    • 統計信息不準確,Innodb不能維護一個數據表的行數的精確統計信息執行計劃中的成本估算不等同于實際執行的成本
    • MySQL的最優可能和你想的最優不一樣
    • MySQL從不考慮其他并發執行的查詢
    • MySQL也并不是任何時候都是基于成本的優化
    • MySQL不會考慮不受其控制的操作的成本
    • 優化器有時候無法去估算所有可能的執行計劃
  • MySQL能處理的優化類型
    • 重新定義關聯表的順序
    • 將外鏈接轉化成內鏈接
    • 使用等價變換規則
    • 優化COUNT()、MIN()和MAX(),在EXPLAIN中可以看到“Select tables optimized away”
    • 預估并轉化為常數表達式,當檢測到一個表達式可以轉化為常數的時候,就會一直把該表達式作為常數進行優化處理
    • 覆蓋索引掃描,當索引中的列包含所有查詢中需要使用的列的時候,就可以使用索引返回需要的數據,而無須查詢對應的數據行
    • 子查詢優化
    • 提前終止查詢,在發現已經滿足查詢需求的時候,MySQL總是能夠立刻終止查詢
    • 等值傳播,如果兩個列的值通過等式關聯,那么MySQL能夠把其中一個列的WHERE條件傳遞到另一列上
    • 列表IN()的比較,MySQL將IN()列表中的數據先進行排序,然后通過二分查找的方式來確定列表中的值是否滿足條件
  • 在服務器層有查詢優化器,卻沒有保存數據和索引的統計信息,統計信息由存儲引擎實現,不同的存儲引擎可能會存儲不同的統計信息
  • 在MySQL中,每一個查詢,每一個片段(包括子查詢,甚至基于單表的SELECT)都可能是關聯
  • 對于UNION查詢,MySQL先將一系列的單個查詢結果放到一個臨時表中,然后再重新讀出臨時表數據來完成UNION查詢
  • MySQL對任何關聯都執行“嵌套循環關聯”操作,即MySQL先在一個表中循環取出單條數據,然后再嵌套到下一個表中尋找匹配的行,依次下去,直到找到所有表中匹配的行為為止
  • 全外連接就無法通過嵌套循環和回溯的方式完成,當發現關聯表中沒有找到任何匹配行的時候,則可能是因為關聯恰好從一個沒有任何匹配的表開始,MySQL不支持全外連接
  • 關聯查詢優化器,會嘗試在所有的關聯順序中選擇一個成本最小的來生成執行計劃樹,如果可能,優化器會遍歷每一個表然后逐個做嵌套循環計算每一棵可能的執行樹的成本,最后返回一個最優的執行計劃
  • 如果有超過n個表的關聯,那么需要檢查n的階乘關聯順序,稱為“搜索空間”,搜索空間的增長速度非常快
  • 無論如何排序都是一個成本很高的操作,所以從性能角度考慮,應盡可能避免排序或者盡可能避免對大量數據進行排序
  • 當不能使用索引生成排序結果的時候,MySQL需要自己進行排序,如果數據量小則在內存中進行,如果數據量大則需要使用磁盤,MySQL將這個過程稱為文件排序(filesort),即使完全是內存排序不需要任何磁盤文件時也是如此
MySQL查詢優化器的局限性
  • 關聯子查詢:MySQL的子查詢實現得非常糟糕,最糟糕的一類查詢是WHERE條件中包含IN()的子查詢語句,使用GROUP_CONCAT()在IN()中構造一個由逗號分隔的列表,或者使用EXISTS()來改寫
  • UNION的限制:有時,MySQL無法將限制條件從外層“下推”到內層,這使得原本能夠限制部分返回結果的條件無法應用到內層查詢的優化上
  • MySQL無法利用多核特性來并行執行查詢
  • MySQL不支持哈希關聯,MariaDB已經實現了哈希關聯
  • MySQL不支持松散索引掃描,5.0后版本在分組查詢中需要找到分組的最大值和最小值時可以使用松散索引掃描
  • 對于MIN()和MAX()查詢,MySQL的優化做得并不好
查詢優化器的提示
  • HIGH_PRIORITY和LOW_PRIORITY,當多個語句同時訪問某一個表的時候,哪些語句的優先級相對高些、哪些語句的優先級相對低些
  • DELAYED,對INSERT和REPLACE有效,會將使用該提示的語句立即返回給客戶端,并將插入的行數據放入到緩沖區,然后在表空閑時批量將數據寫入,并不是所有的存儲引擎都支持,并且該提示會導致函數LAST_INSERT_ID()無法正常工作
  • STRAIGHT_JOIN,可以放置在SELECT語句的SELECT關鍵字之后,也可以放置在任何兩個關聯表的名字之間。第一個用法是讓查詢中所有的表按照在語句中出現的順序進行關聯,第二個用法則是固定其前后兩個表的關聯順序
  • SQL_SMALL_RESULT和SQL_BIG_RESULT,只對SELECT語句有效,它們告訴優化器對GROUP BY或者DISTINCT查詢如何使用臨時表及排序
  • SQL_BUFFER_RESULT,告訴優化器將查詢結果放入到一個臨時表,然后盡可能快地釋放表鎖
  • SQL_CACHE和SQL_NO_CACHE,告訴MySQL這個結果集是否應該緩存在查詢緩存中
  • SQL_CALC_FOUND_ROWS,會計算除去LIMIT子句后這個查詢要返回的結果集的總數,而實際上只返回LIMIT要求的結果集,可以通過函數FOUND_ROW()獲得這個值
  • FOR UPDATE和LOCK IN SHARE MODE,主要控制SELECT語句的鎖機制,但只對實現了行級鎖的存儲引擎有效,僅InnoDB支持
  • USE INDEX、IGNORE INDEX和FORCE INDEX,告訴優化器使用或者不使用哪些索引來查詢記錄
  • MySQL5.0后新增的用來控制優化器行為的參數:
    • optimizer_search_depth,控制優化器在窮舉執行時的限度
    • optimizer_prune_level,讓優化器會根據需要掃描的行數來決定是否跳過某些執行計劃
    • optimizer_switch,包含了一些開啟/關閉優化器特性的標志位
優化特定類型的查詢
  • 優化COUNT()查詢
    • COUNT()是一個特殊的函數,有兩種非常不同的作用:可以統計某個列值的數量,也可以統計行數,在統計列值時要求列值是非空的(不統計NULL)
    • COUNT(*)并不是會像我們猜想的那樣擴展成所有的列,實際上,它會忽略所有的列而直接統計所有的行數,當MySQL確認括號內的表達值不可能為空時,實際上就是在統計行數
    • MyISAM的COUNT()函數只有沒有任何WHERE條件下的COUNT(*)才非常快
    • 使用近似值,如EXPLAIN出來的優化器估算行數
    • 使用索引覆蓋
    • 使用匯總表
    • 使用外部緩存系統
  • 優化關聯查詢
    • 確保ON或者USING子句中的列上有索引
    • 確保任何的GROUP BY和ORDER BY中的表達式只涉及到一個表中的列
    • 當升級MySQL的時候需要注意:關聯語法、運算符優先級等其他可能會發生變化的地方
  • 優化子查詢
    • 盡可能使用關聯查詢代替,如果使用MySQL5.6以上或MariaDB則可以忽略這個建議
  • 優化GROUP BY和DISTINCT
    • 使用索引優化
    • 當無法使用索引時,GROUP BY使用兩種策略來完成:使用臨時表或者文件排序來做分組
    • 盡可能的將WITH ROLLUP(超級聚合)功能移動應用程序中處理
  • 優化LIMIT分頁
    • 最簡單的辦法是盡可能地使用索引覆蓋掃描,而不是查詢所有的列,然后根據需要做一次關聯操作再返回所需的列,select id,name,…… from table innert join (select id from table order by xxx limit 5000,5) as table1 USING(id);
    • offset會導致MySQL掃描大量不需要的行然后再拋棄掉,如果可以記錄上次取數據的位置,下次就可以直接從該記錄的位置開始掃描,可以避免使用offset
    • 使用預先計算的匯總表,或者關聯到一個冗余表
  • 優化UNION查詢
    • 通過創建并填充臨時表的方式來執行UNION查詢,因此很多優化策略在UNION查詢中都沒法很好地使用,經常需要手工地將WHERE、LIMIT、ORDER BY等子句下推到UNION的各個子查詢中
    • 除非確實需要服務器消除重復的行,否則就一定要使用UNION ALL

七、MySQL高級特性

分區表

  • 對用戶來說,分區表是一個獨立的邏輯表,但是底層由多個物理子表組成,實際上是對一組底層表的句柄對象(Handler Object)的封裝

  • 適用場景:

    • 表非常大以至于無法全部都放在內存中,或者只在表的最后部分有熱點數據,其他均是歷史數據
    • 分區表的數據更容易維護
    • 分區表的數據可以分布在不同的物理設備上,從而高效地利用多個硬件設備
    • 可以使用分區表來避免某些特殊的瓶頸
    • 如果需要,還可以備份和恢復獨立的分區
  • 使用限制:

    • 一個表最多只能有1024個分區
    • 在MySQL5.1中,分區表達式必須是整數,或者是返回整數的表達式。在MySQL5.5中,某些場景中可以直接使用列來進行分區
    • 如果分區字段中有主鍵或者唯一索引的列,那么所有主鍵列和唯一索引列都必須包含進來
    • 分區表中無法使用外鍵約束
  • 使用分區表

  • 在數據量超大的時候,B-Tree索引就無法起作用了,除非是索引覆蓋查詢,否則數據庫服務器需要根據索引掃描的結果回表,查詢所有符合條件的記錄,如果數據量巨大,將產生大量隨機I/O

  • 保證大數據量的可擴展性兩個策略:

    • 命題掃描數據,不要任何索引
    • 索引數據,并分離熱點
  • 分區策略的問題:

    • NULL值會使分區過濾無效
    • 分區列和索引列不匹配
    • 選擇分區的成本可能很高
    • 打開并鎖住所有底層表的成本可能很高
    • 維護分區的成本可能很高
    • 所有分區都必須使用相同的存儲引擎
    • 分區函數中可以使用的函數和表達式也有一些限制
    • 某些存儲引擎不支持分區
    • 對于MyISAM的分區表,不能再使用LOAD INDEX INTO CACHE操作
    • 對于MyISAM表,使用分區表時需要打開更多多的文件描述符
  • 查詢優化

    • 很重要的一點是要在WHERE條件中帶入分區列

    • 只能在使用分區函數的列本身進行比較時才能過濾分區,而不能根據表達式的值去過濾分區,即使這個表達式是分區函數也不行

視圖

  • 視圖本身是一個虛擬表,不存放任何數據,返回的數據是MySQL從其他表中生成的
  • MySQL使用兩種算法:合并算法(MERGE)和臨時表算法(TEMPTABLE),會盡可能地使用合并算法
  • 如果視圖中包含GROUP BY、DISTINCT、任何聚合函數、UNION、子查詢等,只要無法在原表記錄和視圖記錄中建立一一映射的場景中,MySQL都將使用臨時表算法來實現視圖
  • 可更新視圖(updatable view)是指可以通過更新這個視圖來更新視圖涉及的相關表,CHECK OPTION表示任何通過視圖更新的行,都必須符合視圖本身的WHERE條件定義
  • 在重構schema的時候可以使用視圖,使得在修改視圖底層表結構的時候,應用代碼還可能繼續不報錯運行
  • MySQL中不支持物化視圖(指將視圖結果數據存放在一個可以查看的表中,并定期從原始表中刷新數據到這個表中)
  • 不會保存視圖定義的原始SQL語句

外鍵約束

  • 使用外鍵是有成本的,通常要求每次在修改數據時都要在另外一張表中多執行一次查找操作
  • 如果想確保兩個相關表始終有一致的數據,那么使用外鍵比在應用程序中檢查一致性的性能要高得多,在相關數據的刪除和更新上,也比在應用中維護要更高效
  • 外鍵會帶來很大的額外消耗

在MySQL內部存儲代碼

  • MySQL允許通過觸發器、存儲過程、函數的形式來存儲代碼,從5.1開始還可以在定時任務中存放代碼,這個定時任務也被稱為“事件”。存儲過程和存儲函數都被統稱為“存儲程序”

  • 存儲代碼的優點:

    • 它在服務器內部執行,離數據最近,另外在服務器上執行還可以節省帶寬和網絡延遲
    • 這是一種代碼重用,可以方便地統一業務規則,保證某些行為總是一致,所以也可以為應用提供一定的安全性
    • 它可以簡化代碼的維護和版本更新
    • 可以幫助提升安全,比如提供更細粒度的權限控制
    • 服務器端可以緩存存儲過程的執行計劃,這對于需要反復調用的過程,會大大降低消耗
    • 因為是在服務器端部署的,所以備份、維護都可以在服務器端完成
    • 可以在應用開發和數據庫開發人員之間更好地分工
  • 存儲代碼的缺點:

    • MySQL本身沒有提供好用的開發和調試工具
    • 較之應用程序的代碼,存儲代碼效率要稍微差些
    • 存儲代碼可能會給應用程序代碼的部署帶來額外的復雜性
    • 因為存儲程序都部署在服務器內,所以可能有安全隱患
    • 存儲過程會給數據庫服務器增加額外的壓力,而數據庫服務器的擴展性相比應用服務器要差很多
    • MySQL并沒有什么選項可以控制存儲程序的資源消耗,所以在存儲過程中的一個小錯誤,可能直接把服務器拖死
    • 存儲代碼在MySQL中的實現也有很多限制——執行計劃緩存是連接級別的,游標的物化和臨時表相同,異常處理也非常困難
    • 調試MySQL的存儲過程是一件很困難的事情
    • 它和基于語句的二進投影日志復制合作得并不好

    基于以上原因阿里手冊里都強制禁止使用存儲過程方式操作SQL

  • 存儲過程和函數的限制:

    • 優化器無法使用關鍵字DETERMINISTIC來優化單個查詢中多次調用存儲函數的情況
    • 優化器無法評估存儲函數的執行成本
    • 每個連接都有獨立的存儲過程的執行計劃緩存
    • 存儲程序和復制是一組詭異組合
  • 觸發器:可以讓你在執行INSERT、UPDATE或者DELETE的時候,執行一些特定的操作,可以在MySQL中指定是在SQL語句執行前觸發還是在執行后觸發,可以使用觸發器實現一些強制限制,或者某些業務邏輯,否則,就需要在應用程序中實現這些邏輯

  • 觸發器的注意和限制:

    • 對每一個表的每一個事件,最多只能定義一個觸發器
    • 只支持“基于行的觸發”,也就是說,觸發器是針對一條記錄的,而不是針對整個SQL語句的,如果變更的數據集非常大的話,效率會很低
    • 觸發器可以掩蓋服務器背后的工作
    • 觸發器可以掩蓋服務器背后的工作,一個簡單的SQL語句背后可能包含了很多看不見的工作
    • 觸發器的問題也很難排查,如果某個性能問題和觸發器相關,會很難分析和定位
    • 觸發器可能導致死鎖和鎖等待
    • 觸發器并不能一定保證更新的原子性
  • 觸發器的用處:

    • 實現一些約束、系統維護任務,以及更新反范式化數據的時候

    • 記錄數據變更日志

  • 事件:類似于Linux的定時任務,指定MySQL在某個時候執行一段SQL代碼,或者每隔一個時間間隔執行一段SQL代碼

游標

  • MySQL在服務器端提供提供只讀的、單向的游標,而且只能在存儲過程或者更底層的客戶端API中使用,指向的對象都是存儲在臨時表中而不是實際查詢到的數據,所以總是只讀的
  • 會帶來額外的性能開銷
  • 不支持客戶端的游標

綁定變量

  • 當創建一個綁定變量SQL時,客戶端向服務器發送了一個SQL語句的原型。服務器端收到這個SQL語句框架后,解析并存儲這個SQL語句的部分執行計劃,返回給客戶端一個SQL語句處理句柄。以后每次執行這類查詢,客戶端都指定使用這個句柄

  • 可以更高效地執行大量的重復語句:

    • 在服務器端只需要解析一次SQL語句
    • 在服務器端某些優化項的工作只需要執行一次,因為它會緩存一部分的執行計劃
    • 以二進制的方式只發送參數和句柄,比起每次都發送ASC2碼文本效率更高
    • 僅僅是參數——而不是整個查詢語句——需要發送到服務器端,所以網絡開銷會更小
    • MySQL在存儲參數的時候,直接將其存放到緩存中,不再需要在內存中多次復制
  • 綁定變量相對也更安全。無須在應用程序中處理轉義,一則更簡單了,二則也大大減少了SQL注入和攻擊的風險

  • 最主要的用途就是在存儲過程中使用,構建并執行“動態”的SQL語句

  • 綁定變量的限制:

    • 綁定變量是會話級別的,所以連接之間不能共用綁定變量句柄

    • 在5.1版本之前,綁定變量的SQL是不能使用查詢緩存的

    • 并不是所有的時候使用綁定變量都能獲得更好的性能

    • 如果總是忘記釋放綁定變量資源,則在服務器端很容易發生資源“泄漏”

    • 有些操作,比如BEGIN,無法在綁定變量中完成

  • 用戶自定義函數

    • 用戶自定義函數(UDF)必須事先編譯好并動態鏈接到服務器上,這種平臺相關性使得UDF在很多方面都很強大,但一個錯誤也很可能讓服務器直接崩潰,甚至擾亂服務器的內存或者數據

插件

  • 插件可以在MySQL中新增啟動選項和狀態值,還可以新增INFORMATION_SCHEMA表,或者在MySQL的后臺執行任務等等

  • 在5.1后支持的插件接口:

    • 存儲過程插件

    • 后臺插件,可以讓程序在MySQL中運行,可以實現自己的網絡監聽、執行自己的定期任務

    • INFORMATION_SCHEMA插件,提供一個新的內存INFORMATION_SCHEMA表

    • 全文解析插件,提供一種處理文本的功能,可以根據自己的需求來對一個文檔進行分詞

    • 審計插件,在查詢執行的過程中的某些固定點被調用,可以記錄MySQL的事件日志

    • 認證插件,既可可以在MySQL客戶端也可在它的服務器端,可以使用這類插件來擴展MySQL的認證功能

字符集和校對

  • 字符集是一種從二進制編碼到某類字符符號的映射,可以參考如何使用一個字節來表示英文字母。“校對”是指一組用于某個字符集的排序規則
  • 每種字符集都可能有多種校對規則,并且都有一個默認的校對規則,每個校對規則都是針對某個特定的字符集的,和其他的字符集沒有關系
  • MySQL有很多的選項用于控制字符集,這些選項和字符集很容易混淆,只有基于字符的值才真正的“有”字符集的概念
  • MySQL的兩類設置:創建對象時的默認設置、服務器和客戶端通信時的設置
  • 如果比較的兩個字符串的字符集不同,MySQL會先將其轉成同一個字符集再進行比較
  • 一些需要注意的地方:
    • 詭異的character_set_database設置,當改變默認數據庫的時候,這個變量也會跟著變,所以當連接到MySQL實例上又沒有指定要使用的數據庫時,默認值會和character_set_server相同
    • LOAD DATA INFILE,當使用時,數據庫總是將文件中的字符按照字符集character_set_database來解析
    • SELECT INTO OUTFILE,MySQL會將結果不做任何轉碼地寫入文件
    • 嵌入式轉義序列,MySQL會根據character_set_client的設置來解析轉義序列
  • 某些字符集和校對規則可能會需要更多的CPU操作,可能會消耗更多的內存和存儲空間,甚至還會影響索引的正常使用
    • 不同的字符集和校對規則之間的轉換可能會帶來額外的系統開銷
    • 只有排序查詢要求的字符集與服務器數據的字符集相同的時候,才能使用索引進行排序
    • 為了能夠適應各種字符集,包括客戶端字符集、在查詢中顯式指定的字符集,MySQL會在需要的時候進行字符集轉換

全文索引

  • MyISAM的全文索引作用對象是一個“全文集合”,這可能是某個數據表的一列,也可能是多個列
  • 可以根據WHERE子句中的MATCH AGAINST來區分查詢是否使用全文索引
  • 在使用全文索引進行排序的時候,MySQL無法再使用索引排序,如果不想使用文件排序的話,就不要在查詢中使用ORDER BY子句
  • 在布爾搜索中,用戶可以在查詢中自定義某個被搜索的詞語的相關性,可能通過一些前綴修飾符來定制搜索
  • 全文索引在INSERT、UPDATE、DELETE中的操作代價很大
  • 全文索引會影響索引選擇、WHERE子句、ORDER BY等:
    • 如果查詢中使用了MATCH AGAINST子句,而對應列上又有可用的全文索引,那么MySQL就一定會使用這個全文索引
    • 全文索引只能用作全文搜索匹配
    • 全文索引不存儲索引列的實際值,也就不可能用作索引覆蓋掃描
    • 除了相關性排序,全文索引不能用作其他的排序
  • 全文索引的配置和優化:
    • 經常使用OPTIMIZE TABLE來減少碎片,如果是I/O密集型的定期進行全文索引重建
    • 保證索引緩存足夠大
    • 提供一個好的停用詞表
    • 忽略一些太短的單詞
    • 導入大量數據時,最好通過命令DISABLE KEYS來禁用全文索引,然后導入結束后使用ENABLE KEYS來建立全文索引
    • 如果數據集特別大,則需要對數據進行手動分區,然后將數據分布到不同的節點,再做并行的搜索

分布式(XA)事務

  • XA事務中需要有一個事務協調器來保證所有的事務參與者都完成了準備工作。如果協調器收到所有的參與者都準備好的消息,就會告訴所有的事務可以提交了,MySQL在這個XA事務過程中扮演一個參與者的角色,而不是協調者
  • 因為通信延遲和參與者本身可能失敗,所以外部XA事務比內部消耗會更大

查詢緩存

  • MySQL查詢緩存保存查詢返回的完整結果,當查詢命中該緩存,MySQL會立刻返回結果,跳過了解析、優化和執行階段

  • MySQL判斷緩存命中的方法很簡單:緩存放在一個引用表中,通過一個哈希值引用,這個哈希值包括了如下因素,即查詢本身、當前要查詢的數據庫、客戶端協議的版本等一些其他可能會影響返回結果的信息

  • 當判斷緩存是否命中時,MySQL不會解析、“正規化”或者參數化查詢語句,而是直接使用SQL語句和客戶端發送過來的其他原始信息。任何字符上的不同,例如空格、注釋——都會導致緩存的不命中

  • 當查詢語句中有一些不確定的數據時,則不會被緩存,例如包含函數NOW()或者CURRENT_DATE()的查詢不會被緩存,只要包含任何用戶自定義函數、存儲函數、用戶變量、臨時表、mysql庫中的系統表,或者任何包含列級別權限的表,都不會被緩存

  • 打開查詢緩存對讀和寫操作都會帶來額外的消耗:

    • 讀查詢在開始之前必須先檢查是否命中緩存

    • 如果這個讀查詢可以被緩存,那么當完成執行后,MySQL若發現查詢緩存中沒有這個查詢,會將其結果存入查詢緩存,這會帶來額外的系統消耗

    • 當向某個表寫入數據的時候,MySQL必須將對應表的所有緩存都設置失效,如果查詢緩存非常大或者碎片很多,這個操作就可能會帶來很大系統消耗

  • 對于需要消耗大量資源的查詢通常都是非常適合緩存的

  • 緩存未命中:

    • 查詢語句無法被緩存
    • MySQL從未處理這個查詢
    • 查詢緩存的內存用完了
    • 查詢緩存還沒有完成預熱
    • 查詢語句之前從未執行過
    • 緩存失效操作太多了
  • 緩存參數配置:

    • query_cache_type,是否打開查詢緩存
    • query_cache_size,查詢緩存使用的總內存空間
    • query_cache_min_res_unit,在查詢緩存中分配內存塊時的最小單位,可以幫助減少由碎片導致的內存空間浪費
    • query_cache_limit,MySQL能夠緩存的最大查詢結果
    • query_cache_wlock_invalidate,如果某個數據表被其他的連接鎖住,是否仍然從查詢緩存中返回結果
  • InnoDB和查詢緩存

    • 事務是否可以訪問查詢緩存取決于當前事務ID,以及對應的數據表上是否有鎖
    • 如果表上有任何的鎖,那么對這個表的任何查詢語句都是無法被緩存的
  • 通用查詢緩存優化:

    • 用多個小表代替一個大表對查詢緩存有好處
    • 批量寫入時只需要做一次緩存失效,所以相比單條寫入效率更好
    • 因為緩存空間太大,在過期操作的時候可能會導致服務器僵死,控制緩存空間的大小
    • 無法在數據庫或者表級別控制查詢緩存,但是可以通過SQL_CACHE和SQL_NO_CACHE來控制某個SELECT語句是否需要進行緩存
    • 對于寫密集型的應用來說,直接禁用查詢緩存可能會提高系統的性能
    • 因為對互斥信號量的競爭,有時直接關閉查詢緩存對讀密集型的應用也會有好處

八、優化服務器設置

MySQL配置的工作原理

  • 任何打算長期使用的設置都應該寫到全局配置文件,而不是在命令行特別指定,命令行指定重啟服務后,配置將消失
  • 常用變量和動態修改它們的效果:
    • key_buffer_size,可以一次性為鍵緩沖區(key buffer,也叫鍵緩存key cache)分配所有指定的空間
    • table_cache_size,不會立即生效——會延遲到下次有線程打開表才有效果,如果值大于緩存中表的數量,線程可以把最新打開的表放入緩存,如果比緩存中的表數小,將從緩存中刪除不常使用的表
    • thread_cache_size,不會立即生效——將在下次有連接被關閉時產生效果,檢查緩存中是否還有空間來緩存線程,如果有空間,則緩存該線程以備下次連接征用,如果沒空間,將銷毀該線程而不再緩存
    • query_cache_size,一次性分配并初始化這塊內存
    • read_buffer_size,只在有查詢需要使用時才會為該緩存分配內存
    • read_rnd_buffer_size,只在有查詢需要使用時才會為該緩存分配內存,并且只會分配需要的內存大小而不是全部指定的大小
    • sort_buffer_size,只會在有查詢需要做排序時才會為該緩存分配內存
  • 對于連接級別的設置,不要輕易地在全局級別增加它們的值,除非確認這樣做是對的
  • 設置變量時請小心,并不是值越大就越好,而且如果設置的值太高,可能更容易導致問題:可能會由于內存不足導致服務器內存交換,或者超過地址空間
  • 不要期望通過建立一套基準測試方案,然后不斷迭代地驗證對配置項的修改來找到最佳配置方案,而要把時間花在檢查備份、監控執行計劃的變動之類的事情上,可能會更有意義

什么不該做

  • 不要根據一些“比率”來調優:例如緩存命中率跟緩存是否過大或過小沒有關系
  • 不要使用調優腳本
  • 不要相信很流行的內存消耗公式

創建MySQL配置文件

  • MySQL編譯的默認設置并不都是靠譜的,雖然其中大部分都比較合適
  • 從一個比默認值大一點但不是大得很離譜的安全值開始是比較好的,MySQL的內存利用率并不總是可以預測的:它可能依賴很多的因素,例如查詢的復雜性和并發性
  • 配置服務器的首選途徑:了解它內部做了什么,以及參數之間如何相互影響,然后再決定怎么配置
  • open_files_limit,在Linux系統上設置得盡可能大,如果參數不夠大,將會踫到24號錯誤“打開的文件太多(too many open files)”
  • 每隔60秒查看狀態變量的增量變化:mysqladmin extended-status ri60

配置內存使用

  • 配置MySQL正確地使用內存量對高性能是至關重要的,內存消耗分為兩類:可以控制的內存和不可以控制的內存

  • 配置內存:

    • 確定可以使用的內存上限

    • 確定每個連接MySQL需要使用多少內存

    • 確定操作系統需要多少內存才夠用

    • 把剩下的內存全部給MySQL的緩存

  • MySQL保持一個連接(線程)只需要少量的內存,它還需要一個基本量的內存來執行任何給定查詢,需要為高峰時期執行的大量查詢預留好足夠的內存,否則,查詢執行可能因為缺乏內存而導致執行效率不佳或執行失敗

  • 跟查詢一樣,操作系統也需要保留足夠的內存給它工作,如果沒有虛擬內存正在交換(Paging)到磁盤,就是表明操作系統內存足夠的最佳跡象

  • 如果服務器只運行MySQL,所有不需要為操作系統以及查詢處理保留的內存都可以用作MySQL緩存

  • 大部分情況下最重要的緩存:

    • InnoDB緩沖池
    • InnoDB日志文件和MyISAM數據的操作系統緩存
    • MyISAM鍵緩存
    • 查詢緩存
    • 無法手工配置的緩存,例如二進制日志和表定義文件的操作系統緩存
  • InnoDB緩沖池并不僅僅緩存索引:它還會緩存行的數據、自適應哈希索引、插入緩沖(Insert Buffer)、鎖,以及其他內部數據結構,還使用緩沖池來幫助延遲寫入,InnoDB嚴重依賴緩沖池

  • 如果事先知道什么時候需要關閉InnoDB,可以在運行時修改innodb_max_dirty_pages_pct變量,將值改小,等待刷新純種清理緩沖池,然后在臟頁數量較少時關閉,可以監控the Innodb_buffer_pool_pages_dirty狀態變量或者使用innotop來監控SHOW INNODB STATUS來觀察臟頁的刷新量

  • MyISAM的鍵緩存也被稱為鍵緩沖,默認只有一個鍵緩存,但也可以創建多個,MyISAM自身只緩存索引,不緩存數據,最重要的配置項是key_buffer_size,不要超過索引的總大小,或者不超過操作系統緩存保留總內存的25%-50%,以更小的為準

  • 了解MyISAM索引實際上占用多少磁盤空間,查詢INFORMATION_SCHEMA表的INDEX_LENGTH字段,把它們的值相加,就可以得到索引存儲占用空間

  • 塊大小也是很重要的(特別是寫密集型負載),因為它影響了MyISAM、操作系統緩存,以及文件系統之間的交互,如果緩存塊太小,可能會踫到寫時讀取

  • 線程緩存保存那些當前沒有與連接關聯但是準備為后面新的連接服務的線程,當一個新的連接創建時,如果緩存中有線程存在,MySQL從緩存中刪除一個線程,并且把它分配給這個新的連接,當連接關閉時,如果線程緩存還有空間的話,MySQL又會把線程放回緩存,如果沒有空間的話,MySQL會銷毀這個線程

  • thread_cache_size變量指定了MySQL可以保持在緩存中的線程數,一般不需要配置這個值,除非服務器會有很多連接請求

  • 表緩存(Table Cache)和線程緩存的概念是相似的,但存儲的對象代表的是表,緩存對象包含相關表.frm文件的解析結果,加上其他數據。表緩存可以重用資源,讓服務器避免修改MyISAM文件頭來標記表“正在使用中”,對InnoDB的重要性要小得多

  • 表緩存的缺點是,當服務器有很多MyISAM表時,可能會導致關機時間較長,因為關機前索引塊必須完成刷新,表都必須標記為不再打開

  • InnoDB數據字典(Data Dictionary),InnoDB自己的表緩存,當InnoDB打開一張表,就增加了一個對應的對象到數據字典

  • InnoDB沒有將統計信息持久化,而是在每次打開表時重新計算,5.6以后可以打開innodb_use_sys_stats_table選項來持久化存儲統計信息到磁盤

  • 可以關閉InnoDB的innodb_stats_on_metadata選項來避免耗時的表統計信息刷新

  • 如果可以,最好把innodb_open_files的值設置得足夠大以使服務器可以保持所有的.ibd文件同時打開

配置MySQL的I/O行為

  • InnoDB I/O配置
    • InnoDB不僅允許控制怎么恢復,還允許控制怎么打開和刷新數據(文件),這會對恢復和整體性能產生巨大的影響
    • 對于常見的應用,最重要的一小部分內容是InnoDB日志文件大小、InnoDB怎樣刷新它的日志緩沖,以及InnoDB怎樣執行I/O
    • 整體的日志文件大小受控于innodb_log_file_size和innodb_log_files_in_group兩個參數,對寫性能非常重要
    • 通常不需要把日志緩沖區設置得非常大,推薦的范圍是1MB-8MB,除非要寫很多相當大的BLOB記錄
    • 可以通過檢查SHOW INNODB STATUS的輸出中LOG部分來監控InnoDB的日志和日志緩沖區的I/O性能,通過觀察Innodb_os_log_written狀態變量來查看InnodDB對日志文件寫出了多少數據。日志文件的全部大小,應該足夠容納服務器一個小時的活動內容
    • 如果和持久相比更在乎性能,可以修改innodb_flush_log_at_trx_commit變量來控制日志緩沖刷新的頻繁程度
    • 使用innodb_flush_method選項可以配置InnoDB如何跟文件系統相互作用
    • InnoDB用表空間并不只是存儲表和索引,還保存了回滾日志、插入緩沖(Insert Buffer)、雙寫緩沖(Doublerite Buffer)及其他內部數據結構
    • 為了控制寫入速度,可以設置innodb_max_purge_lag變量為一個大于0的值,這個值表示InnoDB開始延遲后面的語句更新數據之前,可以等待被清除的最大的事務數量
    • 雙寫緩沖是表空間的一個特殊的保留區域,在一些連續的塊中足夠保存100個頁,本質上是一個最近寫回的頁面的備份拷貝,當InnoDB從緩沖池刷新頁面到磁盤時,首先把它們寫(或者刷新)到雙寫緩沖,然后再把它們寫到其所屬的數據區域中,這可以保證每個頁面的寫入都是原子并且持久化的
    • 設置innodb_doublewrite為0來關閉雙寫緩沖
    • sync_binlog選項控制MySQL怎么刷新二進制日志到磁盤
    • 二進制日志,如果希望使用expire_logs_days選項來自動清理舊的二進制日志,就不要用rm命令去刪
  • MyISAM的I/O配置
    • MyISAM通常每次寫操作之后就把索引變更刷新磁盤,批量操作會更快一些
    • 通過設置delay_key_write變量,可以延遲索引的寫入,修改的鍵緩沖塊直到表被關閉才會刷新
    • myisam_recover選項控制MyISAM怎樣尋找和修復錯誤
    • 內存映射使得MyISAM直接通過操作系統的頁面緩存訪問.MYD文件,避免系統調用的開銷,5.1后可以通過myisam_use_mmap選項打開內存映射

配置MySQL并發

  • InnoDB并發配置

    • InnoDB有自己的“線程調度器”控制線程怎么進入內核訪問數據,以及它們在內核中一次可以做哪些事,最基本的限制并發的方式是使用innodb_thread_concurrency變量,它會限制一次性可以有多少線程進入內核

    • 并發值 = CPU數量 * 磁盤數量 * 2,在實踐中使用更小的值會更好一點

  • MyISAM并發配置

    • 盡管MyISAM是表級鎖,它依然可以一邊讀取,一邊并發追加新行,這種情況下只能讀取到查詢開始時的所有數據,新插入的數據是不可見的,這樣可以避免不一致讀

    • 通過設置concurrent_insert這個變量,可以配置MyISAM打開并發插入

    • 讓INSERT、REPLACE、DELETE、UPDATE語句的優先級比SELECT語句更低,設置low_priority_updates選項就可以

基于工作負載的配置

  • 當服務器滿載情況下運行時,請嘗試記錄所有的查詢語句,因為這是最好的方式來查看哪種類型的查詢語句占用資源最多,同時創建processlist快照,通過state或者command字段來聚合它們
  • 優化BLOB和TEXT場景
    • BLOB有幾個限制使得服務器對它的處理跟其他類型不一樣,不能在內存臨時表中存儲BLOB值,效率很低
    • 通過SUBSTRING()函數把值轉換為VARCHAR
    • 讓臨時表更快一些:放在基于內存的文件系統
    • 如果使用的是InnoDB,也可以調大InnoDB日志緩沖大小
    • 大字段在InnoDB里可能浪費大量空間
    • 擴展存儲禁用了自適應哈希,因為需要完整地比較列的整個長度,才能發現是不是正確的數據
    • 太長的值可能使得查詢中作為WHERE條件不能使用索引
    • 如果一張表里有很多大字段,最好是把它們組合起來單獨存到一個列里面
    • 有時候可以把大字段用COMPRESS()壓縮后再存為BLOB,或者發送到MySQL前在應用程序中進行壓縮
  • 優化排序(Filesorts):當MySQL必須排序BLOG或TEXT字段時,它只會使用前綴,然后忽略剩下部分的值

完成基本配置

  • tmp_table_size和max_heap_table_size,這兩個設置控制使得Memory引擎的內存臨時表能使用多大的內存
  • max_connections,這個設置的作用就像一個緊急剎車,以保證服務器不會因應用程序激增的連接而不堪重負,設置得以容納正常可能達到的負載,并且要足夠安全,能保證允許你登錄和管理服務器
  • thread_cache_size,可以通過觀察服務器一段時間的活動,來計算一個有理有據的值,250的上限是一個不錯的估算值
  • table_cache_size,應該被設置得足夠大,以避免總是需要重新打開和重新解析表的定義,可能通過觀察Open_tables的值及其在一段時間的變化來檢查該變量

安全和穩定的設置

  • expire_logs_days,如果啟用了二進制日志,應該打開這個選項,可以讓服務器在指定的天數之后清理舊的二進制日志
  • max_allowed_packet,防止服務器發送太大的包,也會控制多大的包可以被接收
  • max_connect_errors,如果知道服務器可以充分抵御蠻力攻擊,可以把這個值設得非常大,以有效地禁用主機黑名單
  • skip_name_resolve,禁用了另一個網絡相關和鑒權誰相關的陷阱:DNS查找
  • sql_mode,不建議修改
  • sysdate_is_now,可能導致與應用預期向后不兼容的選項
  • read_only,禁止沒有特權的用戶在備庫做變更,只接受從主庫傳輸過來的變更,不接受從應用來的變更,可以把備庫設置為只讀模式
  • skip_slave_start,阻止MySQL試圖自動啟動復制
  • slave_net_timeout,控制備庫發現跟主庫的連接已經失敗并且需要重連之前等待的時間,設置為一分鐘或更短
  • sync_master_info、sync_relay_log、sync_relay_log_info,5.5以后版本可用,解決了復制中備庫長期存在的問題:不把它們的狀態文件同步到磁盤,所以服務器崩潰后可能需要人來猜測復制的位置實際上在主庫是哪個位置,并且可能在中繼日志(Relay Log)里有損壞

高級InnoDB設置

  • innodb,如果設置為FORCE,只有在InnoDB可以啟動時,服務器才會啟動
  • innodb_autoinc_lock_mode,控制InnoDB如何生成自增主鍵值
  • innodb_buffer_pool_instances,在5.5以后,可以把緩沖池切分為多段,在高負載的多核機器上提升MySQL可擴展性的一個重要方式
  • innodb_io_capacity,有時需要把這個設置得相當高,才能穩定地刷新臟頁
  • innodb_read_io_threads和innodb_write_io_threads,控制有多少后臺線程可以被I/O操作使用
  • innodb_strict_mode,讓MySQL在某些條件下把警告改成拋錯,尤其是無效的或者可能有風險的CREATE TABLE選項
  • innodb_old_blocks_time,指定一個頁面從LRU鏈表的“年輕”部分轉移到“年老”部分之前必須經過的毫秒數,默認為0,設置為1000毫秒(1秒)非常有效

九、操作系統和硬件優化

什么限制了MySQL的性能

  • 當數據可以放在內存中或者可以從磁盤中以足夠快的速度讀取時,CPU可能出現瓶頸,把大量的數據集完全放到大容量的內存中,以現在的硬件條件完全是可行的
  • I/O瓶頸,一般發生在工作所需的數據遠遠超過有效內存容量的時候,如果應用程序是分布在網絡上的,或者如果有大量的查詢和低延遲的要求,瓶頸可能轉移到網絡上

如何為MySQL選擇CPU

  • 可以通過檢查CPU利用率來判斷是否是CPU密集型的工作負載,還需要看看CPU使用率和大多數重要的查詢的I/O之間的平衡,并注意CPU負載是否分配均勻
  • 當遇到CPU密集型的工作時,MySQL通常可以從更快的CPU中獲益,但還依賴于負載情況和CPU數量
  • MySQL復制也能在高速CPU下工作得非常好,而多CPU對復制的幫助卻不大
  • 多CPU在聯機事務處理(OLTP)系統的場景中非常有用,在這樣的環境中,并發可能成為瓶頸

平衡內存和磁盤資源

  • 配置大量內存最終目的是避免磁盤I/O,最關鍵的是平衡磁盤的大小、速度、成本和其他因素,以便為工作負載提供高性能的表現
  • 設計良好的數據庫緩存(如InnoDB緩沖池),其效率通常超過操作系統的緩存,因為操作系統緩存是為通用任務設計的
  • 數據庫服務器同時使用順序和隨機I/O,隨機I/O從緩存從受益最多
  • 每個應用程序都有一個數據的“工作集”——就是這個工作確實需要用到的數據
  • 工作集包括數據和索引,所以應該采用緩存單位來計數,一個緩存單位是存儲引擎工作的數據最小單位
  • 找到一個良好的內存/磁盤比例最好的方式是通過試驗和基準測試
  • 硬盤選擇考慮因素:存儲容量、傳輸速度、訪問時間、主軸轉速、物理尺寸
  • MySQL如何擴展到多個磁盤上取決于存儲引擎和工作負載,InnoDB能很好地擴展到多個硬盤驅動器,然而,MyISAM的表鎖限制其寫的可擴展性,因此寫繁重的工作加在MyISAM上,可能無法從多個驅動器中收益

固態存儲

  • 高質量閃存設備具備:

    • 相比硬盤有更好的隨機讀寫性能

    • 相比硬盤有更好的順序讀寫性能

    • 相比硬盤能更好地支持并發

    • 提升隨機I/O和并發性

  • 閃存的最重要特征是可以迅速完成多次小單位讀取,但是寫入更有挑戰性。閃存不能在沒有做擦除操作前改寫一個單元(Cell),并且一次必須擦除一個大塊。擦除周期是緩慢的,并且最終會磨損整個塊

  • 垃圾收集對理解閃存很重要。為了保持一些塊是干凈的并且可以被寫入,設備需要回收臟塊。這需要設備上有一些空閑空間

  • 許多設備被填滿后會開始變慢,速度下降是由于沒有空閑塊時必須等待擦寫完成所造成的

  • 固態存儲最適合使用在任何有著大量隨機I/O工作負載的場景下,隨機I/O通常是由于數據大于服務器的內存導致的,閃存設備可能大大緩解這種問題

  • 單線程工作負載也是另一個閃存的潛在應用場景

  • 閃存也可以為服務器整合提供巨大的幫助

  • Flashcache,磁盤和內存技術的結合,適合以讀為主的I/O密集型負載,并且工作集太大,用內存優化并不經濟的情況

  • 優化固態存儲上的MySQL

    • 增加InnoDB的I/O容量
    • 讓InnoDB日志文件更大
    • 把一些文件從閃存轉移到RAID
    • 禁用預讀
    • 配置InnoDB刷新算法
    • 禁用雙寫緩沖的可能
    • 限制插入緩沖大小,插入緩沖設計來用于減少當更新行時不在內存中的非唯一索引引起的隨機I/O
    • InnoDB的頁大小
    • 優化InnoDB頁面校驗(Checksum)的替代算法

為備庫選擇硬件

  • 通常需要跟主庫差不多的配置

RAID性能優化

  • RAID可以幫助做冗余、擴展存儲容量、緩存,以及加速
  • RAID 0:如果只是簡單的評估成本和性能,是成本最低和性能最高的RAID配置
  • RAID 1:在很多情況下提供很好的讀性能,并且在不同的磁盤間冗余數據,所以有很好的冗余性,非常適合用來存放日志或者類似的工作
  • RAID 5:通過分布奇偶校驗把數據分散到多個磁盤,如果任何一個盤的數據失效,都可以從奇偶校驗塊中重建,但如果有兩個磁盤失效了,則整個卷的數據無法恢復,最經濟的冗余配置。隨機寫是昂貴的,存放數據或者日志是一種可接受的選擇,或者是以讀為主的業務
  • RAID 10:對數據存儲是個非常好的選擇,由分片的鏡像組成,對讀和寫都有良好的擴展性
  • RAID 50:由條帶化的RAID 5組成

SAN和NAS

  • SAN(Storage Area Network)和NAS(Network-Attached Storage)是兩個外部文件存儲設備加載到服務器的方法,訪問SAN設備時通過塊接口,NAS設備通過基于文件的協議來訪問
  • SAN允許服務器訪問非常大量的硬盤驅動器,并且通常配置大容量智能高速緩存來緩沖寫入
  • 哪些工作放在SAN上不合適:執行大量的隨機I/O的單線程任務
  • SAN的應用:
    • 備份,可以只備份SAN
    • 簡化容量規劃
    • 存儲整合還是服務器整合
    • 高可用
    • 服務器之間的交互
    • 成本

使用多磁盤卷

  • 二進制日志和數據文件分離的真正的優勢,是減少事故中同時丟失數據和日志文件的可能性
  • 如果有很多磁盤,投入一些給事務日志可能會從中受益

網絡配置

  • 在生產服務器上啟用skip_name_resolve是個好主意,損壞或緩慢的DNS解析對許多應用程序都是個問題,對MySQL尤嚴重,如果啟用skip_name_resolve選項,MySQL將不會做任何DNS查找的工作
  • 可以通過MySQL的back_log選項控制MySQL的傳入TCP連接隊列的大小,在每秒有很多連接創建和銷毀的環境中,默認值50是不夠的
  • 網絡物理隔離也是很重要的因素,盡可能避免實時的跨數據中心的操作是明智的

選擇操作系統

  • 一般的企業級部署MySQL大多在類UNIX操作系統上

選擇文件系統

  • 如果可能,最好使用日志文件系統,如ext3、ext4、XFS、ZFS或者JFS
  • 可以調整文件系統的預讀行為,因為這可能也是多余的

選擇磁盤隊列調度策略

  • 在GUN/Linux上,隊列調度決定了到塊設備的請求實際上發送到底層設備的順序,默認情況下使用cfq(Completely Fair Queueing,完全公平排隊)策略,在MySQL的工作負載類型下,cfq會導致很差的響應時間,因為會在隊列中延遲一些不必要的請求
  • cfq之外的兩個選項都適合服務器級的硬件,noop調度適合沒有自己的調度算法的設備,deadline則對RAID控制器和直接使用的磁盤都工作良好

線程

  • MySQL每個連接使用一個線程,另外還有內部處理線程、特殊用途的線程,以及所有存儲引擎創建的線程
  • MySQL確實需要內核級線程的支持,而不只是用戶級線程,這樣才能更有效地使用多個CPU,另外也需要有效的同步原子

內存交換區

  • 內存交換對MySQL性能影響是很糟糕的,它破壞了緩存在內存的目的,并且相對于使用很小的內存做緩存,使用交換區的性能更差
  • 在GNU/Linux上,可以用vmstat來監控內存交換,最好查看si和so列報告的內存交換I/O活動,這比看swpd列報告的交換區利用率更重要,最佳為0
  • 設置/proc/sys/vm/swappiness為一個很小的值
  • 修改存儲引擎怎么讀取和寫入數據,使用innodb_flush_method=0_DIRECT減輕I/O壓力
  • 使用MySQL的memlock配置項,可以把MySQL鎖定在內存

操作系統狀態

  • vmstat

    • vmstat 5,每隔5秒刷新一次
    • procs,r列顯示多少進程正在等待CPU,b列顯示多少進程正在不可中斷地休眠
    • memory,swpd列顯示多少塊被換出到了磁盤,剩下的三個列顯示了多少塊是空閑的、多少塊正在被用作緩沖,以及多少正在被用作操作系統的緩存
    • swap,顯示頁面交換活動
    • io,顯示有多少塊從塊設備讀取( bi)和寫出(bo)
    • system,顯示了每秒中斷(in)和上下文切換(cs)的數量
    • cpu,顯示所有的CPU時間花費在各類操作的百分比
  • iostat

    • iostats -dx 5,每5秒刷新

    • rrqm/s和wrqm/s,每秒合并的讀和寫請求,意味著操作系統從隊列中拿出多個邏輯請求合并為一個請求到實際磁盤

    • r/s和w/s,每秒發送到設備的讀和寫請求

    • rsec/s和wsec/s,每秒讀和寫的扇區數

    • avgrq-sz,請求的扇區數

    • avgqu-sz,在設備隊列中等待的請求數

    • await,磁盤排除上花費的毫秒數

    • svctm,服務請求花費的毫秒數,不包括排除時間

    • %util,至少有一個活躍請求所占時間的百分比

  • CPU密集型的機器,vmstat輸出通常在us列會有一個很高的值,也可能在sy列有很高的值

  • I/O密集型工作負載下,vmstat會顯示很多處理器在非中斷休眠(b列)狀態,并且wa這一列的值很高

  • 發生內存交換的機器可能在swpd列有一個很高的值

十、復制

復制概述

  • MySQL支持兩種復制方式:基于行的復制和基于語句的復制,都是通過在主庫上記錄二進制日志、在備庫重放日志的方式來實現異步的數據復制

  • 復制通常不會增加主庫的開銷,主要是啟用二進制日志帶來的開銷,但出于備份或及時從崩潰中恢復的目的,這點開銷也是必要的

  • 通過復制可以將讀操作指向備庫來獲得更好的讀擴展,但對于寫操作,除非設計得當,否則并不適合通過寫復制來擴展寫操作

  • 復制解決的問題:

    • 數據分布

    • 負載均衡

    • 備份

    • 高可用性和故障切換

    • MySQL升級測試

  • 復制如何工作

    • 在主庫上把數據更新記錄到二進制日志(Binary Log)中

    • 備庫將主庫上的日志復制到自己的中繼日志(Relay Log)中

    • 備庫讀取中繼日志中的事件,將其重放到備庫數據之上

配置復制

  • 在每臺服務器上創建復制帳號
    • 用來監控和管理復制的帳號需要REPLICATION CLIENT權限,并且針對這兩種目的使用同一個帳號更加容易
    • 如果在主庫上建立了帳號,然后從主庫將數據克隆到備庫時,備庫也就設置好了——變成主庫所需要的配置
  • 配置主庫和備庫
    • 必須明確地指定一個唯一的服務器ID
    • 有時候只開啟了二進制日志,但卻沒有開啟log_slave_updates,可能會踫到一些奇怪的現象
    • 如果可能的話,最好使用read_only配置選項,會阻止任何沒有特權權限的線程修改數據
  • 通知備庫連接到主庫并從主庫復制數據
  • 推薦的復制配置
    • sync_binlog =1,在提交事務前會將二進制日志同步到磁盤上,保證在服務器崩潰時不會丟失事件
    • 如果無法容忍服務器崩潰導致表損壞,推薦使用InnoDB
    • 推薦明確指定二進制日志的名字,log_bin=/var/lib/mysql/mysql-bin
    • 在備庫上為中繼日志指定絕對路徑,relay_log
    • 如果正在使用5.5并且不介意額外的fsync()導致的性能開銷,最好設置:sync_master_info,sync_relay_log,sync_relay_log_info

復制的原理

  • 基于語句的復制

    • 5.0之前只支持基于語句的復制(也稱為邏輯復制),主庫會記錄那些造成數據更改的查詢,當備庫讀取并重放這些事件時,實際上只是把主庫上執行過的SQL再執行一遍
    • 好處是實現相當簡單,日志更加緊湊,不會占用太多帶寬
    • 問題是基于語句的方式可能并不如其看起來那么便利,還存在一些無法被正確復制的SQL,更新必須是串行的這需要更多的鎖
  • 基于行的復制

    • 5.1開始支持,會將實際數據記錄在二進制日志中,跟其他數據庫的實現比較想像

    • 好處是可以正確地復制每一行,一些語句可以被更加有效地復制

    • 如果使用全表更新,則開銷會很大,因為每一行的數據都會被記錄到二進制日志中,這使得二進制日志事件非常龐大,并且會給主庫上記錄日志和復制增加額外的負載,更慢的日志記錄則會降低并發度

  • 基于行或基于語句:哪種更優

    • 基于語句的復制模式的優點:當主備的模式不同時,邏輯復制能夠在多種情況下工作;基于語句的方式執行復制的過程基本上就是執行SQL語句
    • 基于語句的復制模式的缺點:很多情況下通過基于語句的模式無法正確復制,如果正在使用觸發器或者存儲過程,就不要使用基于語句的復制模式,除非能夠清楚地確定不會踫到復制的問題
    • 基于行的復制模式的優點:幾乎沒有基于行的復制模式無法處理的場景;可能減少鎖的使用,并不要求這種強串行化是可重復的;會記錄數據變更;占用更少的CPU;能夠幫助更快地找到并解決數據不致的情況
    • 基于行的復制模式的缺點:無法判斷執行了哪些SQL;無法知道服務器在做什么;在某些情況下,例如找不到要修改的行時,基于行的復制可能會導致復制停止
  • 復制文件

    • mysql-bin.index,二進制日志文件

    • mysql-relay-bin-index,中繼日志的索引文件

    • master.info,保存備庫連接到主庫所需要的信息

    • relay-log.info,包含了當前備庫復制的二進制日志和中繼日志坐標

  • 5.發送復制事件到其他備庫:log_slave_updates,可以讓備庫變成其他服務器的主庫

  • 6.復制過濾選項

    • 在主庫上過濾記錄到二進制日志中的事件
    • 在備庫上過濾記錄到中繼日志的事件

復制拓撲

  • 基本原則:

    • 一個MySQL備庫實例只能有一個主庫

    • 每個備庫都必須有一個唯一的服務器ID

    • 一個主庫可以有多個備庫

    • 如果打開了log_slave_updates選項,一個備庫可以把其主庫上的數據變化傳播到其他備庫

  • 一主庫多備庫

  • 主動-主動模式下的主主復制:auto_increment_increment和auto_increment_offset可以讓MySQL自動為INSERT語句選擇不互相沖突的值

  • 主動-被動模式下的主主復制:其中一臺服務器是只讀的被動服務器

  • 擁有備庫的主主結構:增加了冗余,能夠消除站點單點失效的問題

  • 環形復制:每個服務器都是在它之前的服務器的備庫,是在它之后的服務器的主庫

  • 分發主庫事實上也是一個備庫,提取和提供主庫的二進制日志

  • 樹或金字塔形:減輕了主庫的負擔,但中間層出現的任何錯誤都會影響到多個服務器

  • 定制的復制方案

    • 選擇性復制:配置replicate_wild_do_table

    • 分離功能:OLTP、OLAP

    • 數據歸檔:在備庫上保留主庫上刪除過的數據

    • 將備庫用作全文檢索

    • 只讀備庫:read_only選項

    • 模擬多主庫復制

    • 創建日志服務器:創建沒有數據的日志服務器,更加容易重放并且/或者過濾二進制日志事件

復制和容量規劃

  • 寫操作通常是復制的瓶頸,并且很難使用復制來擴展寫操作
  • 在構建一個大型應用時,有意讓服務器不被充分使用,這應該是一種聰明并且蔓延的方式,尤其在使用復制的時候,有多余容量的服務器可以更好地處理負載尖峰,也有更多能力處理慢速查詢和維護工作,并且能夠更好地跟上復制

復制管理和維護

  • 在主庫上,可以使用SHOW MASTER STATUS命令來查看當前主庫的二進制日志位置和配置
  • 從庫上,使用SHOW SLAVE STATUS

十一、擴展的MySQL

什么是可擴展性

  • 可擴展性表明了當需要增加資源以執行更多工作時系統能夠獲得劃算的等同提升(equal bang for the buck)的能力,缺乏擴展能力的系統在達到收益遞減的轉折點后,將無法進一步增長
  • 可擴展性就是能夠通過增加資源來提升容量的能力

擴展MySQL

  • 規劃可擴展性最困難的部分是估算需要承擔的負載到底有多少,還需要大致正確地估計日程表,需要知道底線在哪里
  • 可以做的準備工作:優化性能、購買性能更強的硬件
  • 向上擴展(垂直擴展)意味著購買更多性能強悍的硬件
  • 向外擴展(橫向擴展、水平擴展):復制、拆分、數據分片
    • 按功能拆分(按職責拆分),不同的節點執行不同的任務
    • 數據分片,把數據分割成一小片,或者一小塊,然后存儲到不同的節點中
    • 選擇分區鍵(partitioning key)
    • 多個分區鍵
    • 跨分片查詢,使用C或Java編寫一個輔助應用來執行查詢并聚合結果集,也可以借助匯總表來執行
    • 分配數據、分片和節點
  • 通過多實例擴展
  • 通過集群擴展
    • MySQL Cluster(NDB Cluster)
    • Clustrix
    • ScaleBase
    • GenieDB
    • Akiban
  • 向內擴展,對不再需要的數據進行歸檔和清理
  • 保持活躍數據獨立

負載均衡

  • 在一個服務器集群中盡可能地平均負載量,通常在服務器前端設置一個負載均衡器

十二、高可用性

什么是高可用性

  • 高可用性不是絕對的,只有相對更高的可用性,100%的可用性是不可能達到的
  • 可用性每提高一點,所花費的成本都會遠超之前,可用性的效果和開銷的比例并不是線性的

導致宕機的原因

  • 運行環境問題,最普遍的問題是磁盤空間耗盡
  • 性能問題,最普遍的原因是運行很糟糕的SQL,或服務器BUG或錯誤的行為
  • 糟糕的Schema和索引設計
  • 復制問題通常由于主備數據不一致導致
  • 數據丟失通常由于DROP TABLE的誤操作導致,并總是伴隨著缺少可用備份的問題

如何實現高可用性

  • 可以通過同時進行以下兩步來獲得高可用性
    • 可以嘗試避免導致宕機的原因來減少宕機時間
    • 盡量保證在發生宕機時能夠快速恢復
  • 提升平均失效時間(MTBF)
    • 對系統變更管理的缺失是所有導致宕機的事件中最普遍的原因
    • 缺少嚴格的評估
    • 沒有正確地監控MySQL的相關信息
  • 降低平均恢復時間(MTTR)
    • 所有的宕機事件都是由多方面的失效聯合在一起導致的,可以通過利用合適的方法確保單點的安全來避免

避免單點失效

  • 系統中任何不冗余的部分都是一個可能失效的單點
  • 可以采用兩種方法來為系統增加冗余:增加空余容量和重復組件
  • 共享存儲或磁盤復制
    • 能夠為數據庫服務器和存儲解耦合,通常使用的是SAN
    • 兩個優點:可以避免除存儲外的其他任何組件失效所引起的數據丟失,并為非存儲組件建立冗余提供可能
  • MySQL同步復制
    • 當使用同步復制時,主庫上的事務只有在至少一個備庫上提交后才能認為其執行完成
    • 完成了兩個目標:當服務器崩潰時沒有提交的事務會丟失,并且至少有一個備庫擁有實時的數據副本
    • MySQL Cluster
    • Percona XtraDB Cluster
  • 基于復制的冗余
    • 復制管理器是使用標準MySQL復制來創建冗余的工具

故障轉移和故障恢復

  • 冗余一點也不會增加可用性或減少宕機,和故障轉移結合可以幫助更快地恢復,故障轉移最重要的部分就是故障恢復
  • 提升備庫或切換角色
  • 虛擬IP地址或IP接管
  • 中間件解決方案,可以使用代理、端口轉發、網絡地址轉換或者硬件負載均衡來實現故障轉移和故障恢復
  • 在應用中處理故障轉移

十三、云端的MySQL

云的優點、缺點和相關誤解

  • 優點:

    • 云是一種將基礎設施外包出去無須自己管理的方法

    • 云一般是按照即用即付的方式支付

    • 隨著供應商發布新的服務和成本降低,云提供的價值越來越大

    • 云能夠幫助你輕松地準備好服務器和其他資源

    • 云代表了對基礎設施的另一種思考方式——作為通過API來定義和控制的資源——支持更多的自動化操作

  • 2.缺點:

    • 資源是共享并且不可預測的

    • 無法保證容量和可用性

    • 虛擬的共享資源導致排查故障更加困難

MySQL在云端的經濟價值

  • 云托管比較適合尚處于初級階段的企業,或者那些持續接觸新概念并且本質上是以適用為主的企業
  • 大量使用的策略是盡可能又快又便宜地開發和發布應用
  • 運行不是很重要的基礎設施

云中的MySQL的可擴展性和高可用性

  • 數據庫通常是一個應用系統中主要或唯一的有狀態并且持久化的組件
  • MySQL并不具備在一個無共享集群中的對等角色服務器之間遷移的能力

四種基礎資源

  • CPU通常少且慢
  • 內在大小受限制
  • I/O的吞吐量、延遲以及一致性受到限制
  • 網絡性能還比較好

MySQL在云主機上的性能

  • 需要高并發的工作負載并不是非常適合云計算
  • 那些需要大量I/O的工作負載在云中并不總是表現很好

MySQL數據庫即服務(DBaaS)

  • 將數據庫本身作為云資源

十四、應用層優化

  • 常見問題
    • 什么東西在消耗系統中每臺主機的CPU、磁盤、網絡,以及內存資源?這些值是否合理?如果不合理,對應用程序做基本的檢查,看什么占用了資源
    • 應用真是需要所有獲取到的數據嗎?
    • 應用在處理本應由數據庫處理的事情嗎,或者反過來?
    • 應用執行了太多的查詢?
    • 應用執行的查詢太少了?
    • 應用創建了沒必要的MySQL連接嗎?
    • 應用對一個MySQL實例創建連接的次數太多了嗎?
    • 應用做了太多的“垃圾”查詢?
    • 應用使用了連接池嗎?這既可能是好事,也可能是壞事
    • 應用是否使用長連接?
    • 應用是否在不使用的時候還保持連接撕開?

Web服務器問題

  • 最常見的問題是保持它的進程的存活(alive)時間過長,或者在各種不同的用途下混合使用,而不是分別對不同類型的工作進行優化

  • 如果用一個通用目的的Apache配置直接用于Web服務,最后很可能產生很多重量級的Apache進程

  • 不要使用Apache來做靜態內容服務,或者至少和動態服務使用不同的Apache實例

  • 進程存活時間變短策略:

    • 不要讓Apache填鴨式地服務客戶端

    • 打開gzip壓縮

    • 不要為用于長距離連接的Apache配置啟用Keep-Alive選項

緩存

  • 被動緩存除了存儲和返回數據外不做任何事情;主動緩存在訪問未命中時做一些額外工作

  • 應用可以緩存部分計算結果,所以應用層緩存可能比更低層次的緩存更有效,可以節省兩方面的工作:獲取數據以及基于這些數據進行計算,重點是緩存命中率可能更低,并且可能使用較多的內存

  • 應用層緩存:

    • 本地緩存

    • 本地共享內存緩存

    • 分布式內存緩存

    • 磁盤上的緩存

  • 緩存控制策略

    • TTL(time to live,存活時間)

    • 顯式失效,如果不能接受臟數據,那么進程在更新原始數據時需要同時使緩存失效

    • 讀時失效,在更改舊數據時,為了避免要同時失效派生出來的臟數據,可以在緩存中保存一些信息,當從緩存中讀數據時可以利用這些信息判斷數據是否已經失效

  • 可以在后臺預先請求一些頁面,并將結果存為靜態頁面,好處:

    • 應用代碼沒有復雜的命中和未命中處理路徑

    • 當未命中的處理路徑慢得不可接受時,這種方案可以很好地工作

    • 預生成內容可以避免在緩存未命中時導致的雪崩效應

MySQL的替代品

  • 搜索:Lucene和Sphinx
  • 簡單的鍵值存儲:Redis
  • 非結構化數據:Hadoop

十五、備份與恢復

為什么要備份

  • 災難恢復
  • 人們改變想法
  • 審計
  • 測試

定義恢復需求

  • 規劃備份和恢復策略時,有兩個重要的需求:恢復點目標(PRO)和恢復時間目標(RTO)

設計MySQL備份方案

  • 建議

    • 在生產實踐中,對于大數據庫來說,物理備份是必需的:邏輯備份太慢并受到資源限制,從邏輯備份中恢復需要很長時間

    • 保留多個備份集

    • 定期從邏輯備份(或者物理備份)中抽取數據進行恢復測試

    • 保存二進制日志以用于基于故障時間點的恢復

    • 完全不借助備份工具本身來監控備份和備份的過程

    • 通過演練整個恢復過程來測試備份和恢復

    • 對安全性要仔細考慮

  • 如果可能,關閉MySQL做備份是最簡單最安全的,需要考慮:鎖時間、備份時間、備份負載、恢復時間

  • 邏輯備份優點:

    • 可以用編輯器或像grep和sed之類的命令查看和操作的普通文件

    • 恢復非常簡單

    • 可能通過網絡來備份和恢復

    • 可以在類似Amazon RDS這樣不能訪問底層文件系統的系統中使用

    • 非常靈活

    • 與存儲引擎無關

    • 有助于避免數據損壞

  • 邏輯備份的缺點:

    • 必須由數據庫服務器完成生成邏輯備份的工作

    • 邏輯備份在某些場景下比數據庫文件本身更大

    • 無法保證導出后再還原出來的一定是同樣的數據

    • 從邏輯備份中還原需要MySQL加載和解釋語句

  • 物理備份優點:

    • 基于文件的備份,只需要將需要的文件復制到其他地方即可

    • 恢復簡單

    • InnoDB和MyISAM的物理備份非常容易跨平臺

  • 物理備份缺點:

    • InnoDB的原始文件通常比相應的邏輯備份要大得多

    • 物理備份不總是可以跨平臺

  • 除非經過測試,不要假定備份是正常的

  • 建議混合使用物理和邏輯兩種方式來做備份

  • MySQL備份需要考慮的幾點:

    • 非顯著數據
    • 代碼
    • 復制配置
    • 服務器配置
    • 選定的操作系統
  • 差異備份是對自上次全備份后所有改變的部分做備份,而增量備份則是自從任意類型的上次備份后所有修改做的備份

  • 差異、增量備份的建議:

    • 使用Percona XtraBackup和MySQL Enterprise Backup中的增量備份特性
    • 備份二進制日志,每次備份后FLUSH LOGS
    • 不要備份沒有改變的表
    • 不要備份沒有改變的行
    • 某些數據根本不需要備份
    • 備份所有的數據,然后發送到一個有去重特性的目的地
  • 數據一致性:當備份時,應該考慮是否需要數據在指定時間點一致

  • 文件一致性:每個文件的內部一致性

  • 從備庫中備份最大的好處是可以不干擾主庫,故意將一個備庫延時一段時間對于某些災難場景非常有用

管理和備份二進制日志

  • expire_log_days變量MySQL定期清理日志

備份數據

  • 生成邏輯備份

    • SQL導出:mysqldump方式

    • 符號分隔文件備份:使用SELECT INTO OUTFILE以符號分隔文件格式創建數據的邏輯備份

  • 文件系統快照

    • 支持快照的文件系統和設備包括FreeBSD的文件系統、ZFS文件系統、GNU/Linux的邏輯卷管理(LVM),以及許多的SAN系統和文件存儲解決方案

從備份中恢復

  • 恢復步驟:

    • 停止MySQL服務器

    • 記錄服務器的配置和文件權限

    • 將數據從備份中移到MySQL數據目錄

    • 改變配置

    • 改變文件權限

    • 以限制訪問模式重啟服務器,等待完成啟動

    • 載入邏輯備份文件

    • 檢查和重放二進制日志

    • 檢測已經還原的數據

    • 以完全權限重啟服務器

  • 備份和恢復工具

    • MySQL Enterprise Backup
    • Percona XtraBackup
    • mylvmbackup
    • Zmanda Recovery Manager
    • mydunper
    • mysqldump

十六、MySQL用戶工具

接口工具

  • MySQL Workbench
  • SQLyog
  • phpMyAdmin
  • Adminer

命令行工具集

  • Percona Toolkit
  • Maatkit and Aspersa
  • The openark kit
  • MySql workbench

SQL實用集

  • common_schema
  • mysql-sr-lib
  • MySQL UDF倉庫
  • MySQL Forge

監測工具

  • 開源的監控工具

    • Nagios

    • Zabbix

    • Zenoss

    • OpenNMS

    • Groundwork Open Source

    • MRTG

    • Cacti

    • Ganglia

    • Munin

  • 商業監控系統

    • MySQL Enterprise Monitor

    • MONyog

    • New Relic

    • Circonus

    • Monitis

    • Splunk

    • Pingdom

  • Innotop的命令行監控

總結

以上是生活随笔為你收集整理的高性能Mysql(第三版)笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

国产香蕉尹人综合在线观看 | 国产成人午夜福利在线播放 | 国产人妻人伦精品 | 亚洲高清偷拍一区二区三区 | 粗大的内捧猛烈进出视频 | 蜜桃av抽搐高潮一区二区 | 精品无码一区二区三区的天堂 | 欧美 日韩 亚洲 在线 | 亚洲高清偷拍一区二区三区 | 波多野结衣一区二区三区av免费 | 青青青手机频在线观看 | 国产免费观看黄av片 | 亚洲成熟女人毛毛耸耸多 | 99久久精品国产一区二区蜜芽 | 国产97人人超碰caoprom | 丰满少妇人妻久久久久久 | 无码成人精品区在线观看 | 国产一区二区三区精品视频 | 少妇人妻av毛片在线看 | 日韩精品乱码av一区二区 | 丰满少妇人妻久久久久久 | 亚洲熟妇色xxxxx欧美老妇 | 色婷婷综合激情综在线播放 | 国产黑色丝袜在线播放 | 精品国产一区av天美传媒 | 久久久久久a亚洲欧洲av冫 | 免费看男女做好爽好硬视频 | 图片区 小说区 区 亚洲五月 | 日本成熟视频免费视频 | 国产精品18久久久久久麻辣 | 精品久久久久久亚洲精品 | 亚洲娇小与黑人巨大交 | 亚洲另类伦春色综合小说 | 少妇激情av一区二区 | 无码毛片视频一区二区本码 | 日本一区二区三区免费播放 | 国产国语老龄妇女a片 | 亚洲精品综合五月久久小说 | 内射老妇bbwx0c0ck | 色综合视频一区二区三区 | 色五月丁香五月综合五月 | 久久99久久99精品中文字幕 | 人妻与老人中文字幕 | 久久久av男人的天堂 | 麻豆md0077饥渴少妇 | 国产熟女一区二区三区四区五区 | 丰满少妇熟乱xxxxx视频 | 131美女爱做视频 | 国产色在线 | 国产 | 丝袜人妻一区二区三区 | 红桃av一区二区三区在线无码av | 午夜无码区在线观看 | 亚洲一区二区三区四区 | 麻豆人妻少妇精品无码专区 | 一个人免费观看的www视频 | 自拍偷自拍亚洲精品被多人伦好爽 | 精品国产成人一区二区三区 | 4hu四虎永久在线观看 | 成人亚洲精品久久久久 | 漂亮人妻洗澡被公强 日日躁 | 久久人人爽人人人人片 | 色爱情人网站 | 无套内谢老熟女 | v一区无码内射国产 | 日韩人妻无码一区二区三区久久99 | 奇米影视7777久久精品 | 国产av剧情md精品麻豆 | 色五月五月丁香亚洲综合网 | 成人女人看片免费视频放人 | 18禁黄网站男男禁片免费观看 | 国产乱人偷精品人妻a片 | 亚洲国产精品久久久久久 | 一本一道久久综合久久 | 国产精品无码久久av | 大肉大捧一进一出视频出来呀 | 狠狠综合久久久久综合网 | 成人欧美一区二区三区黑人免费 | 亚洲欧美国产精品专区久久 | 欧美性生交xxxxx久久久 | 精品国产一区av天美传媒 | 久久精品国产亚洲精品 | 天堂久久天堂av色综合 | 久久精品国产精品国产精品污 | 性史性农村dvd毛片 | 国精品人妻无码一区二区三区蜜柚 | 久久久精品国产sm最大网站 | 日日噜噜噜噜夜夜爽亚洲精品 | 88国产精品欧美一区二区三区 | 色欲人妻aaaaaaa无码 | 精品夜夜澡人妻无码av蜜桃 | 亚洲熟妇色xxxxx亚洲 | 性欧美疯狂xxxxbbbb | 人妻无码αv中文字幕久久琪琪布 | 人人超人人超碰超国产 | 极品嫩模高潮叫床 | 红桃av一区二区三区在线无码av | 欧洲精品码一区二区三区免费看 | 国产亚洲tv在线观看 | 国产又爽又猛又粗的视频a片 | 久久久久久亚洲精品a片成人 | 男女下面进入的视频免费午夜 | 又湿又紧又大又爽a视频国产 | 日本高清一区免费中文视频 | 99精品久久毛片a片 | 国产精品毛多多水多 | 午夜免费福利小电影 | 国产亚洲视频中文字幕97精品 | 婷婷五月综合激情中文字幕 | 亚洲精品成人福利网站 | 图片小说视频一区二区 | 亚洲欧美色中文字幕在线 | aⅴ亚洲 日韩 色 图网站 播放 | 亚洲色欲色欲欲www在线 | 中文精品久久久久人妻不卡 | 丰满人妻一区二区三区免费视频 | 特黄特色大片免费播放器图片 | 亚洲爆乳无码专区 | 无遮挡啪啪摇乳动态图 | 高潮毛片无遮挡高清免费视频 | 欧美肥老太牲交大战 | 亚洲精品成人av在线 | 偷窥日本少妇撒尿chinese | 国产性生交xxxxx无码 | 国产精品久久久久无码av色戒 | 成人精品一区二区三区中文字幕 | а√天堂www在线天堂小说 | 美女扒开屁股让男人桶 | 国产激情精品一区二区三区 | 国产成人av免费观看 | 国产精品无码久久av | 99麻豆久久久国产精品免费 | 极品嫩模高潮叫床 | 亚洲一区二区三区国产精华液 | 97久久国产亚洲精品超碰热 | 日韩视频 中文字幕 视频一区 | 成人免费无码大片a毛片 | 水蜜桃av无码 | 国产猛烈高潮尖叫视频免费 | 亚洲熟妇色xxxxx欧美老妇 | 日韩成人一区二区三区在线观看 | 熟女少妇人妻中文字幕 | 乱人伦中文视频在线观看 | 国产精品爱久久久久久久 | 爆乳一区二区三区无码 | 99久久久无码国产aaa精品 | 国产乡下妇女做爰 | 日韩人妻系列无码专区 | 99久久久无码国产aaa精品 | 无遮挡啪啪摇乳动态图 | 1000部啪啪未满十八勿入下载 | 国产精品亚洲а∨无码播放麻豆 | 高潮喷水的毛片 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 精品日本一区二区三区在线观看 | 人妻尝试又大又粗久久 | 国产成人av免费观看 | 国产成人人人97超碰超爽8 | 女人高潮内射99精品 | 国产成人av免费观看 | 久精品国产欧美亚洲色aⅴ大片 | 国产色在线 | 国产 | 无码吃奶揉捏奶头高潮视频 | 少妇被黑人到高潮喷出白浆 | 国产绳艺sm调教室论坛 | 久久午夜无码鲁丝片午夜精品 | 麻豆精品国产精华精华液好用吗 | 高潮毛片无遮挡高清免费视频 | 成人无码精品1区2区3区免费看 | 久久综合狠狠综合久久综合88 | 最近免费中文字幕中文高清百度 | 中文字幕乱妇无码av在线 | 老子影院午夜精品无码 | 免费视频欧美无人区码 | 超碰97人人做人人爱少妇 | 久久99精品久久久久久 | 亚洲人成人无码网www国产 | 婷婷丁香六月激情综合啪 | 国内少妇偷人精品视频免费 | 清纯唯美经典一区二区 | 午夜熟女插插xx免费视频 | 一本加勒比波多野结衣 | 精品一区二区三区无码免费视频 | 成人无码影片精品久久久 | 亚洲国产欧美国产综合一区 | 人人妻人人澡人人爽欧美精品 | 两性色午夜免费视频 | 精品久久久无码中文字幕 | 青青久在线视频免费观看 | 亚洲色欲色欲欲www在线 | 亚洲一区二区三区在线观看网站 | 7777奇米四色成人眼影 | 沈阳熟女露脸对白视频 | 丰满护士巨好爽好大乳 | 性色av无码免费一区二区三区 | 老司机亚洲精品影院 | 无码人妻av免费一区二区三区 | 久久精品丝袜高跟鞋 | 欧美老熟妇乱xxxxx | 人妻互换免费中文字幕 | 亚拍精品一区二区三区探花 | 久久午夜夜伦鲁鲁片无码免费 | 综合激情五月综合激情五月激情1 | 日韩精品乱码av一区二区 | 亚洲人成人无码网www国产 | 又紧又大又爽精品一区二区 | 免费无码肉片在线观看 | 粉嫩少妇内射浓精videos | 美女黄网站人色视频免费国产 | 精品国产一区二区三区av 性色 | 欧美第一黄网免费网站 | 少妇性荡欲午夜性开放视频剧场 | 无码成人精品区在线观看 | 大地资源网第二页免费观看 | 日韩亚洲欧美精品综合 | 99久久人妻精品免费二区 | 高中生自慰www网站 | 亚洲熟悉妇女xxx妇女av | 日日麻批免费40分钟无码 | 一本加勒比波多野结衣 | 久久精品人人做人人综合试看 | 最近中文2019字幕第二页 | 亚洲国产日韩a在线播放 | 日韩 欧美 动漫 国产 制服 | 夜夜躁日日躁狠狠久久av | 黑人粗大猛烈进出高潮视频 | 色综合久久网 | 国产精品多人p群无码 | 亚洲欧美精品伊人久久 | 婷婷五月综合缴情在线视频 | 欧美黑人乱大交 | 亚洲精品综合一区二区三区在线 | 成 人影片 免费观看 | 青青草原综合久久大伊人精品 | 久久久久久国产精品无码下载 | 精品日本一区二区三区在线观看 | 对白脏话肉麻粗话av | 天天做天天爱天天爽综合网 | 国产精品久久久久久亚洲影视内衣 | 亚洲精品无码人妻无码 | 少妇无码一区二区二三区 | 成人动漫在线观看 | 人妻少妇精品无码专区动漫 | 久久亚洲中文字幕精品一区 | 成人影院yy111111在线观看 | 99久久精品午夜一区二区 | 性欧美熟妇videofreesex | 亚洲理论电影在线观看 | 免费无码午夜福利片69 | 少妇无码一区二区二三区 | 中文字幕久久久久人妻 | 一个人免费观看的www视频 | 亚洲 欧美 激情 小说 另类 | 久久综合给合久久狠狠狠97色 | 黑人巨大精品欧美一区二区 | 丰满人妻一区二区三区免费视频 | 强奷人妻日本中文字幕 | 国产片av国语在线观看 | 亚洲成熟女人毛毛耸耸多 | 欧美日韩在线亚洲综合国产人 | 男女猛烈xx00免费视频试看 | 午夜熟女插插xx免费视频 | 国产又爽又黄又刺激的视频 | 无码人妻av免费一区二区三区 | 国产精品久久久久久久9999 | 国产午夜福利100集发布 | 国产精品丝袜黑色高跟鞋 | 中文字幕无码日韩专区 | 亚洲а∨天堂久久精品2021 | 国产午夜亚洲精品不卡 | 精品亚洲韩国一区二区三区 | 99re在线播放 | 国产亚洲精品久久久久久久久动漫 | 十八禁视频网站在线观看 | 亚洲中文字幕无码中文字在线 | 亚洲国产精品无码一区二区三区 | 无码人妻精品一区二区三区不卡 | 国产欧美熟妇另类久久久 | 性做久久久久久久久 | 内射欧美老妇wbb | 天干天干啦夜天干天2017 | 欧美丰满老熟妇xxxxx性 | 亚洲综合无码一区二区三区 | 99麻豆久久久国产精品免费 | 国产精品嫩草久久久久 | 亚洲精品综合一区二区三区在线 | 日本爽爽爽爽爽爽在线观看免 | 欧美阿v高清资源不卡在线播放 | 午夜精品一区二区三区在线观看 | 沈阳熟女露脸对白视频 | 成人性做爰aaa片免费看 | 久久综合香蕉国产蜜臀av | 国产精品久久久久影院嫩草 | 伊人久久大香线焦av综合影院 | 99er热精品视频 | 午夜理论片yy44880影院 | 精品一区二区三区无码免费视频 | 日韩欧美成人免费观看 | 日韩无套无码精品 | 欧美老妇与禽交 | 国产精品免费大片 | 人人澡人摸人人添 | 国产尤物精品视频 | 成熟女人特级毛片www免费 | 国产精品久久久久久无码 | 亚洲精品久久久久avwww潮水 | 无码人妻久久一区二区三区不卡 | 日本一区二区更新不卡 | 狂野欧美性猛xxxx乱大交 | 国产人妻久久精品二区三区老狼 | 色一情一乱一伦一区二区三欧美 | 人人妻人人澡人人爽精品欧美 | 国产精品久久国产精品99 | 一区二区传媒有限公司 | 国产熟妇另类久久久久 | 波多野结衣一区二区三区av免费 | 国产成人av免费观看 | 强伦人妻一区二区三区视频18 | 欧美日韩人成综合在线播放 | 亚洲人交乣女bbw | 精品国产一区二区三区四区在线看 | 国产电影无码午夜在线播放 | 天堂亚洲免费视频 | 精品久久综合1区2区3区激情 | 中文字幕无线码免费人妻 | 久久久久99精品国产片 | 国产亚av手机在线观看 | 日日鲁鲁鲁夜夜爽爽狠狠 | 国产精品久久久久7777 | 欧美丰满少妇xxxx性 | 亚洲国产一区二区三区在线观看 | 少妇被黑人到高潮喷出白浆 | 国产成人无码av在线影院 | 亚洲精品一区国产 | 亚洲欧美色中文字幕在线 | 国产口爆吞精在线视频 | 国产偷抇久久精品a片69 | 国产在线精品一区二区三区直播 | 国产成人无码av在线影院 | 亲嘴扒胸摸屁股激烈网站 | 我要看www免费看插插视频 | 亚洲一区二区三区含羞草 | 97夜夜澡人人双人人人喊 | 色欲av亚洲一区无码少妇 | 亚洲国产欧美日韩精品一区二区三区 | 中文字幕中文有码在线 | 中文字幕+乱码+中文字幕一区 | 狠狠色噜噜狠狠狠7777奇米 | 乌克兰少妇性做爰 | 亚洲精品国产品国语在线观看 | 精品久久8x国产免费观看 | 图片小说视频一区二区 | 国产黄在线观看免费观看不卡 | 欧美兽交xxxx×视频 | 亚洲精品久久久久久久久久久 | 精品无码av一区二区三区 | 国产69精品久久久久app下载 | 秋霞特色aa大片 | 中文字幕+乱码+中文字幕一区 | 久久精品视频在线看15 | 国产熟女一区二区三区四区五区 | 人妻天天爽夜夜爽一区二区 | 成人欧美一区二区三区黑人免费 | 亚洲 欧美 激情 小说 另类 | 国产av久久久久精东av | 日韩精品成人一区二区三区 | 色欲人妻aaaaaaa无码 | 无码人妻久久一区二区三区不卡 | 国产性生交xxxxx无码 | 亚洲国产欧美日韩精品一区二区三区 | 欧美性猛交xxxx富婆 | 性生交大片免费看女人按摩摩 | 自拍偷自拍亚洲精品被多人伦好爽 | 色妞www精品免费视频 | 成人免费视频视频在线观看 免费 | 亚洲国产精品毛片av不卡在线 | 中文字幕无码日韩专区 | 亚洲国产精品久久久久久 | 久久综合给合久久狠狠狠97色 | 强辱丰满人妻hd中文字幕 | 亚洲狠狠色丁香婷婷综合 | 国内少妇偷人精品视频免费 | 国产成人无码区免费内射一片色欲 | 欧洲vodafone精品性 | 正在播放东北夫妻内射 | 国产午夜亚洲精品不卡下载 | 日本护士xxxxhd少妇 | 亚洲国产日韩a在线播放 | 丰满人妻被黑人猛烈进入 | 国语自产偷拍精品视频偷 | 欧美亚洲国产一区二区三区 | 亚洲无人区一区二区三区 | 亚洲精品成人av在线 | 精品久久综合1区2区3区激情 | 久久99精品国产.久久久久 | √天堂中文官网8在线 | 少妇无码吹潮 | 波多野结衣一区二区三区av免费 | 无遮挡国产高潮视频免费观看 | 久久99热只有频精品8 | 中文无码伦av中文字幕 | 久久久久99精品成人片 | 黑人巨大精品欧美一区二区 | 色综合天天综合狠狠爱 | 一本大道久久东京热无码av | 亚洲一区二区三区 | 亚洲午夜福利在线观看 | 四虎永久在线精品免费网址 | 精品国偷自产在线视频 | 日韩在线不卡免费视频一区 | 国产精品无码一区二区桃花视频 | 女人高潮内射99精品 | 好爽又高潮了毛片免费下载 | 乌克兰少妇性做爰 | 色婷婷av一区二区三区之红樱桃 | 日欧一片内射va在线影院 | 欧美国产亚洲日韩在线二区 | 理论片87福利理论电影 | 成年美女黄网站色大免费全看 | 日本一卡2卡3卡四卡精品网站 | 亚洲精品欧美二区三区中文字幕 | 国内揄拍国内精品少妇国语 | 亚洲精品久久久久久久久久久 | 精品国产aⅴ无码一区二区 | 日韩av激情在线观看 | 青青青手机频在线观看 | 亚洲精品久久久久久久久久久 | 玩弄人妻少妇500系列视频 | 国产舌乚八伦偷品w中 | 亚洲精品久久久久久久久久久 | 久久久精品456亚洲影院 | 国产亚洲人成在线播放 | 无码帝国www无码专区色综合 | 国产午夜精品一区二区三区嫩草 | 综合激情五月综合激情五月激情1 | 老司机亚洲精品影院无码 | 老熟女重囗味hdxx69 | 亚洲s码欧洲m码国产av | 青青草原综合久久大伊人精品 | 熟妇女人妻丰满少妇中文字幕 | 欧洲美熟女乱又伦 | 少妇性l交大片欧洲热妇乱xxx | 最近的中文字幕在线看视频 | 久久久久免费精品国产 | 中文字幕日产无线码一区 | 亚洲欧美日韩综合久久久 | 好爽又高潮了毛片免费下载 | 国产艳妇av在线观看果冻传媒 | 亚洲国产av精品一区二区蜜芽 | 亚洲精品国产第一综合99久久 | 久久国产精品二国产精品 | 欧洲精品码一区二区三区免费看 | 亚洲乱码国产乱码精品精 | 欧美 亚洲 国产 另类 | 成年美女黄网站色大免费视频 | 国产成人无码av片在线观看不卡 | 夜夜躁日日躁狠狠久久av | 天堂亚洲2017在线观看 | 久久久久国色av免费观看性色 | 成年美女黄网站色大免费全看 | 中文字幕无码日韩专区 | 在线а√天堂中文官网 | 日韩欧美群交p片內射中文 | 国产欧美熟妇另类久久久 | 日本乱人伦片中文三区 | 亚洲欧美国产精品久久 | 狠狠色欧美亚洲狠狠色www | 蜜桃视频插满18在线观看 | 亚洲精品一区三区三区在线观看 | 娇妻被黑人粗大高潮白浆 | 国产精品办公室沙发 | 国产人妻久久精品二区三区老狼 | 国产后入清纯学生妹 | 少妇一晚三次一区二区三区 | av小次郎收藏 | 88国产精品欧美一区二区三区 | 久久久久成人片免费观看蜜芽 | 国产精品久免费的黄网站 | 伊人久久大香线焦av综合影院 | 久久亚洲精品中文字幕无男同 | 国产av无码专区亚洲a∨毛片 | 在线а√天堂中文官网 | 国产农村妇女高潮大叫 | 亚洲の无码国产の无码影院 | 精品人妻人人做人人爽 | 丝袜人妻一区二区三区 | 亚洲国产精华液网站w | 少妇被黑人到高潮喷出白浆 | 国产亚洲欧美日韩亚洲中文色 | 成在人线av无码免费 | 亚洲成av人片在线观看无码不卡 | 男女下面进入的视频免费午夜 | 性啪啪chinese东北女人 | 国产精品国产自线拍免费软件 | 国产乱人伦偷精品视频 | 国产精品毛片一区二区 | 国产精品无码成人午夜电影 | 中文字幕无码av波多野吉衣 | 大肉大捧一进一出视频出来呀 | 少妇无码av无码专区在线观看 | 国产婷婷色一区二区三区在线 | 天天燥日日燥 | 97资源共享在线视频 | 精品亚洲成av人在线观看 | 色老头在线一区二区三区 | 国色天香社区在线视频 | 老司机亚洲精品影院 | 国产特级毛片aaaaaaa高清 | 国产av无码专区亚洲awww | 亚洲国产日韩a在线播放 | 我要看www免费看插插视频 | 欧美丰满熟妇xxxx性ppx人交 | 成人综合网亚洲伊人 | 国产激情艳情在线看视频 | 高潮毛片无遮挡高清免费 | 日韩av无码一区二区三区不卡 | 国内揄拍国内精品人妻 | 粉嫩少妇内射浓精videos | 国产精品久久久av久久久 | 伊人色综合久久天天小片 | 国产精品人人妻人人爽 | 中文字幕无线码 | 成人亚洲精品久久久久软件 | 午夜精品久久久久久久久 | 成人aaa片一区国产精品 | 强伦人妻一区二区三区视频18 | 日韩精品a片一区二区三区妖精 | 又湿又紧又大又爽a视频国产 | 国产激情精品一区二区三区 | 国产成人一区二区三区在线观看 | 无人区乱码一区二区三区 | 人妻体内射精一区二区三四 | 中国女人内谢69xxxx | 少妇激情av一区二区 | 亚洲色无码一区二区三区 | 亚洲午夜福利在线观看 | 亚洲国产精品一区二区第一页 | 亚洲欧美日韩国产精品一区二区 | 国产精品理论片在线观看 | 亚洲精品国产品国语在线观看 | 日日摸天天摸爽爽狠狠97 | 精品久久久久久亚洲精品 | 亚洲熟熟妇xxxx | 亚洲乱亚洲乱妇50p | 国产真实乱对白精彩久久 | 国产亚洲视频中文字幕97精品 | 波多野结衣av一区二区全免费观看 | 国产精品亚洲一区二区三区喷水 | 无码免费一区二区三区 | 亚洲欧美国产精品久久 | 色欲久久久天天天综合网精品 | 99国产欧美久久久精品 | 99精品视频在线观看免费 | 国产精华av午夜在线观看 | 无码av免费一区二区三区试看 | 高清无码午夜福利视频 | 偷窥村妇洗澡毛毛多 | 午夜男女很黄的视频 | 国产精品二区一区二区aⅴ污介绍 | 久久久久免费看成人影片 | 美女毛片一区二区三区四区 | 暴力强奷在线播放无码 | 18无码粉嫩小泬无套在线观看 | av无码电影一区二区三区 | 天天燥日日燥 | 欧美老人巨大xxxx做受 | 成年美女黄网站色大免费全看 | 日本一卡二卡不卡视频查询 | 99精品无人区乱码1区2区3区 | 又大又紧又粉嫩18p少妇 | 国内精品一区二区三区不卡 | 亚洲熟妇色xxxxx欧美老妇y | 俄罗斯老熟妇色xxxx | 欧洲精品码一区二区三区免费看 | 国产精品18久久久久久麻辣 | 免费人成网站视频在线观看 | 一本大道伊人av久久综合 | 人人澡人人透人人爽 | 欧美35页视频在线观看 | 沈阳熟女露脸对白视频 | 欧美兽交xxxx×视频 | 欧美丰满老熟妇xxxxx性 | 精品国产国产综合精品 | 又湿又紧又大又爽a视频国产 | 中文字幕无码免费久久9一区9 | 日本熟妇浓毛 | 在线天堂新版最新版在线8 | 久久视频在线观看精品 | 偷窥村妇洗澡毛毛多 | 自拍偷自拍亚洲精品被多人伦好爽 | 99国产精品白浆在线观看免费 | 丰满妇女强制高潮18xxxx | 女人被爽到呻吟gif动态图视看 | 亚洲国产精品一区二区美利坚 | 97久久精品无码一区二区 | 成 人 网 站国产免费观看 | 97精品人妻一区二区三区香蕉 | 久久97精品久久久久久久不卡 | 国产无套粉嫩白浆在线 | 日本成熟视频免费视频 | 无码精品人妻一区二区三区av | 亚洲va中文字幕无码久久不卡 | 我要看www免费看插插视频 | 伊人久久大香线焦av综合影院 | 人妻少妇被猛烈进入中文字幕 | yw尤物av无码国产在线观看 | аⅴ资源天堂资源库在线 | 少妇无套内谢久久久久 | 九九综合va免费看 | 樱花草在线播放免费中文 | 亚洲 激情 小说 另类 欧美 | 精品国产av色一区二区深夜久久 | 无码av岛国片在线播放 | 99久久久无码国产精品免费 | 色 综合 欧美 亚洲 国产 | 日韩亚洲欧美精品综合 | 图片小说视频一区二区 | 中文毛片无遮挡高清免费 | 亚洲国产精品久久久久久 | aa片在线观看视频在线播放 | 日本精品高清一区二区 | 久久综合色之久久综合 | 精品无码国产一区二区三区av | 蜜桃无码一区二区三区 | 国产乱人无码伦av在线a | 国产又粗又硬又大爽黄老大爷视 | 免费人成在线视频无码 | 未满小14洗澡无码视频网站 | 国产亚洲tv在线观看 | 欧美午夜特黄aaaaaa片 | 狠狠噜狠狠狠狠丁香五月 | 强辱丰满人妻hd中文字幕 | 中文字幕无码日韩专区 | 中文字幕精品av一区二区五区 | 麻豆精产国品 | 中文字幕av伊人av无码av | 永久免费精品精品永久-夜色 | 国产亚洲精品久久久久久国模美 | 国产内射老熟女aaaa | 国产乱子伦视频在线播放 | 色欲av亚洲一区无码少妇 | 国产精品高潮呻吟av久久 | 九九综合va免费看 | 初尝人妻少妇中文字幕 | 国产精品久免费的黄网站 | 亚洲一区二区观看播放 | 在线 国产 欧美 亚洲 天堂 | 麻豆精品国产精华精华液好用吗 | 亚洲啪av永久无码精品放毛片 | 中文字幕日韩精品一区二区三区 | 日韩精品无码免费一区二区三区 | 国产精品高潮呻吟av久久4虎 | 久久精品无码一区二区三区 | 综合激情五月综合激情五月激情1 | 国产熟妇高潮叫床视频播放 | 欧美高清在线精品一区 | 欧美乱妇无乱码大黄a片 | 国产女主播喷水视频在线观看 | 免费人成网站视频在线观看 | 欧美阿v高清资源不卡在线播放 | 色婷婷av一区二区三区之红樱桃 | 18禁止看的免费污网站 | 未满小14洗澡无码视频网站 | 大地资源中文第3页 | 国产va免费精品观看 | 国产精品毛多多水多 | 国产成人精品优优av | 国产精品人人爽人人做我的可爱 | 国产日产欧产精品精品app | 国产香蕉尹人视频在线 | 国产日产欧产精品精品app | 久久精品视频在线看15 | 国产精品久久久久久亚洲毛片 | 成人无码精品1区2区3区免费看 | 暴力强奷在线播放无码 | 草草网站影院白丝内射 | 国内精品人妻无码久久久影院 | 性欧美牲交xxxxx视频 | 少妇邻居内射在线 | 好男人社区资源 | 久久婷婷五月综合色国产香蕉 | 狂野欧美性猛xxxx乱大交 | 人人爽人人澡人人高潮 | 免费播放一区二区三区 | 成人免费视频在线观看 | 无码国产乱人伦偷精品视频 | 久久久久av无码免费网 | 欧美黑人乱大交 | 成人片黄网站色大片免费观看 | 亚洲成av人片在线观看无码不卡 | 人人妻人人澡人人爽欧美精品 | 女人被男人躁得好爽免费视频 | 2019nv天堂香蕉在线观看 | 国产成人精品一区二区在线小狼 | 亚洲中文字幕av在天堂 | 久久亚洲a片com人成 | 国产精品国产三级国产专播 | 国产精品香蕉在线观看 | 精品厕所偷拍各类美女tp嘘嘘 | 影音先锋中文字幕无码 | 日日干夜夜干 | 色综合久久网 | 少妇激情av一区二区 | 国产精品无码mv在线观看 | 亚洲精品国产精品乱码视色 | 少妇的肉体aa片免费 | 中文字幕无码av激情不卡 | 女人高潮内射99精品 | 午夜精品久久久内射近拍高清 | 国产一区二区三区四区五区加勒比 | 亚洲另类伦春色综合小说 | 亚洲色欲久久久综合网东京热 | 欧美老妇交乱视频在线观看 | 久久成人a毛片免费观看网站 | 黑森林福利视频导航 | 国产精品第一国产精品 | 精品国产一区二区三区av 性色 | 在教室伦流澡到高潮hnp视频 | 亚洲国产欧美日韩精品一区二区三区 | 亚洲成a人片在线观看日本 | 波多野结衣av一区二区全免费观看 | 欧美性生交活xxxxxdddd | 麻豆精品国产精华精华液好用吗 | 欧美性猛交内射兽交老熟妇 | 精品一区二区不卡无码av | 国产亚洲精品久久久久久 | 亚洲一区二区三区偷拍女厕 | 理论片87福利理论电影 | 成人无码精品1区2区3区免费看 | 午夜无码人妻av大片色欲 | 精品人人妻人人澡人人爽人人 | 2019午夜福利不卡片在线 | 少妇太爽了在线观看 | 中文字幕 人妻熟女 | 国内老熟妇对白xxxxhd | 九九在线中文字幕无码 | 日韩亚洲欧美精品综合 | 无码人妻精品一区二区三区不卡 | 欧美熟妇另类久久久久久不卡 | 国产免费无码一区二区视频 | 亚洲国产成人a精品不卡在线 | 精品厕所偷拍各类美女tp嘘嘘 | 国产后入清纯学生妹 | 亚洲中文字幕在线观看 | 国产无套粉嫩白浆在线 | 国产麻豆精品精东影业av网站 | 激情五月综合色婷婷一区二区 | 亚洲欧美国产精品久久 | 久久久久人妻一区精品色欧美 | 色婷婷欧美在线播放内射 | 少妇无码av无码专区在线观看 | 国产精品理论片在线观看 | 高中生自慰www网站 | 东京热男人av天堂 | 国产成人无码av在线影院 | 欧美 亚洲 国产 另类 | 亚洲阿v天堂在线 | 久久精品女人天堂av免费观看 | 久激情内射婷内射蜜桃人妖 | 欧美老妇与禽交 | 扒开双腿吃奶呻吟做受视频 | 久久99精品久久久久婷婷 | 中文字幕人妻无码一区二区三区 | 欧美丰满老熟妇xxxxx性 | 日本乱人伦片中文三区 | 色综合久久久无码中文字幕 | 天天燥日日燥 | 野外少妇愉情中文字幕 | 暴力强奷在线播放无码 | 男女性色大片免费网站 | 亚洲中文无码av永久不收费 | 嫩b人妻精品一区二区三区 | 久久婷婷五月综合色国产香蕉 | 水蜜桃色314在线观看 | 国产内射老熟女aaaa | 国产日产欧产精品精品app | 亚洲日本va中文字幕 | 国产精品久久久久久久影院 | 国产精品人人爽人人做我的可爱 | 欧美黑人巨大xxxxx | 精品无人区无码乱码毛片国产 | 国产成人精品无码播放 | 亚洲欧美精品aaaaaa片 | 国产精品久久久久影院嫩草 | 高潮毛片无遮挡高清免费视频 | 成人无码视频免费播放 | 中文毛片无遮挡高清免费 | 无码国模国产在线观看 | 国产亚洲欧美日韩亚洲中文色 | 亚洲毛片av日韩av无码 | 国产精品美女久久久 | 人妻互换免费中文字幕 | 亚洲国产一区二区三区在线观看 | 欧美人与牲动交xxxx | 亚洲国产精品久久人人爱 | 九月婷婷人人澡人人添人人爽 | 无码人妻av免费一区二区三区 | 欧美喷潮久久久xxxxx | 内射老妇bbwx0c0ck | 一区二区传媒有限公司 | 老太婆性杂交欧美肥老太 | 丰满人妻被黑人猛烈进入 | 四虎影视成人永久免费观看视频 | 强奷人妻日本中文字幕 | 麻豆国产丝袜白领秘书在线观看 | 亚洲日韩乱码中文无码蜜桃臀网站 | 国产va免费精品观看 | 国产精品手机免费 | 日本xxxx色视频在线观看免费 | 国产综合色产在线精品 | 亚洲精品久久久久久一区二区 | 国产免费无码一区二区视频 | 欧美日韩一区二区免费视频 | 日韩人妻无码中文字幕视频 | 男女猛烈xx00免费视频试看 | av在线亚洲欧洲日产一区二区 | 欧美成人家庭影院 | 国产性猛交╳xxx乱大交 国产精品久久久久久无码 欧洲欧美人成视频在线 | 久久综合九色综合欧美狠狠 | 成人免费视频在线观看 | 黑人巨大精品欧美黑寡妇 | 久久精品视频在线看15 | 日本护士xxxxhd少妇 | 欧美自拍另类欧美综合图片区 | 国产午夜手机精彩视频 | 99精品视频在线观看免费 | 婷婷丁香五月天综合东京热 | 一本色道久久综合狠狠躁 | 国产乱码精品一品二品 | 国产无遮挡吃胸膜奶免费看 | 国产精品久久久久久久影院 | 亚洲码国产精品高潮在线 | 精品无码国产自产拍在线观看蜜 | 7777奇米四色成人眼影 | 精品无码成人片一区二区98 | 综合激情五月综合激情五月激情1 | 久久国语露脸国产精品电影 | 久久精品国产一区二区三区 | 学生妹亚洲一区二区 | 亚洲aⅴ无码成人网站国产app | 国产精品第一区揄拍无码 | 欧美黑人性暴力猛交喷水 | 大屁股大乳丰满人妻 | 久久精品一区二区三区四区 | 少妇高潮喷潮久久久影院 | а√天堂www在线天堂小说 | 无码帝国www无码专区色综合 | 亚洲日本va午夜在线电影 | 国产片av国语在线观看 | 久久99精品国产麻豆 | 亚洲熟悉妇女xxx妇女av | 国产69精品久久久久app下载 | 波多野结衣av一区二区全免费观看 | 午夜理论片yy44880影院 | 国产一区二区三区精品视频 | 亚洲国产精品久久久天堂 | 欧美xxxx黑人又粗又长 | 精品欧洲av无码一区二区三区 | 国产亚洲精品久久久ai换 | 内射爽无广熟女亚洲 | 麻豆md0077饥渴少妇 | 亚洲人成影院在线观看 | 无码乱肉视频免费大全合集 | 久久www免费人成人片 | 久久午夜夜伦鲁鲁片无码免费 | 日韩精品久久久肉伦网站 | 国产精品美女久久久久av爽李琼 | 男女爱爱好爽视频免费看 | 国产精品久久精品三级 | 成人影院yy111111在线观看 | 亚洲精品一区二区三区大桥未久 | 欧美成人家庭影院 | 久久国语露脸国产精品电影 | 97无码免费人妻超级碰碰夜夜 | а天堂中文在线官网 | 精品成人av一区二区三区 | 午夜无码人妻av大片色欲 | 男女下面进入的视频免费午夜 | 久久久久成人精品免费播放动漫 | 久久无码中文字幕免费影院蜜桃 | 中文字幕av伊人av无码av | 午夜精品一区二区三区的区别 | 久久久久99精品国产片 | 日韩精品无码一区二区中文字幕 | 日本va欧美va欧美va精品 | 欧美日韩在线亚洲综合国产人 | 成人精品一区二区三区中文字幕 | 欧美日韩色另类综合 | 亚洲一区二区三区 | 国内丰满熟女出轨videos | 99国产欧美久久久精品 | 午夜福利试看120秒体验区 | 久久熟妇人妻午夜寂寞影院 | 亚洲熟妇色xxxxx欧美老妇 | 免费观看又污又黄的网站 | 午夜成人1000部免费视频 | 亚洲 高清 成人 动漫 | 国产av无码专区亚洲a∨毛片 | 免费无码av一区二区 | 婷婷丁香五月天综合东京热 | 狠狠亚洲超碰狼人久久 | 国产在线一区二区三区四区五区 | 国产人妻精品一区二区三区不卡 | 色一情一乱一伦 | 日产精品99久久久久久 | 精品国产一区二区三区av 性色 | 日本爽爽爽爽爽爽在线观看免 | 红桃av一区二区三区在线无码av | 久久久无码中文字幕久... | 免费中文字幕日韩欧美 | 久热国产vs视频在线观看 | 亚洲性无码av中文字幕 | 国产又爽又黄又刺激的视频 | 日本又色又爽又黄的a片18禁 | 爆乳一区二区三区无码 | 精品国产一区二区三区四区在线看 | 日本大香伊一区二区三区 | 亚洲精品欧美二区三区中文字幕 | 久久午夜夜伦鲁鲁片无码免费 | 超碰97人人射妻 | 97久久国产亚洲精品超碰热 | 欧美第一黄网免费网站 | 高清无码午夜福利视频 | 午夜精品一区二区三区在线观看 | 日韩精品无码免费一区二区三区 | 久久精品中文闷骚内射 | 日本精品人妻无码77777 天堂一区人妻无码 | 国产高潮视频在线观看 | 国产精品嫩草久久久久 | 草草网站影院白丝内射 | 色综合天天综合狠狠爱 | 欧美放荡的少妇 | 好爽又高潮了毛片免费下载 | 亚洲国产精品久久久天堂 | 99久久久无码国产aaa精品 | 麻豆果冻传媒2021精品传媒一区下载 | 国产成人无码av片在线观看不卡 | 成人性做爰aaa片免费看不忠 | 97人妻精品一区二区三区 | 免费国产黄网站在线观看 | 国产欧美精品一区二区三区 | 97精品国产97久久久久久免费 | 自拍偷自拍亚洲精品10p | 色婷婷av一区二区三区之红樱桃 | 亚洲午夜久久久影院 | 无码纯肉视频在线观看 | 欧洲欧美人成视频在线 | 成人女人看片免费视频放人 | 无码av岛国片在线播放 | 又粗又大又硬毛片免费看 | 国产做国产爱免费视频 | 免费播放一区二区三区 | 老子影院午夜精品无码 | 西西人体www44rt大胆高清 | 少妇人妻偷人精品无码视频 | 少妇无码一区二区二三区 | 又大又紧又粉嫩18p少妇 | 男女猛烈xx00免费视频试看 | 成年女人永久免费看片 | 成人精品视频一区二区 | 国产网红无码精品视频 | 日韩亚洲欧美中文高清在线 | 欧美日韩一区二区综合 | 四虎4hu永久免费 | 亚洲熟妇色xxxxx亚洲 | 永久免费精品精品永久-夜色 | 国产精品毛片一区二区 | 波多野42部无码喷潮在线 | 国产成人亚洲综合无码 | 国産精品久久久久久久 | 特大黑人娇小亚洲女 | 亚洲熟妇自偷自拍另类 | 国产午夜手机精彩视频 | 天天躁夜夜躁狠狠是什么心态 | 欧洲极品少妇 | 男人的天堂2018无码 | 久久久国产精品无码免费专区 | 丰满妇女强制高潮18xxxx | 天天躁夜夜躁狠狠是什么心态 | 色一情一乱一伦一视频免费看 | 久久婷婷五月综合色国产香蕉 | 啦啦啦www在线观看免费视频 | 精品aⅴ一区二区三区 | 亚洲午夜久久久影院 | 亚洲午夜福利在线观看 | 亚洲精品成a人在线观看 | 亚洲色成人中文字幕网站 | 无码国产乱人伦偷精品视频 | 伊人色综合久久天天小片 | 国产高清av在线播放 | 欧洲熟妇精品视频 | 日本一本二本三区免费 | 男女猛烈xx00免费视频试看 | 亚洲日韩av一区二区三区中文 | 国产人妖乱国产精品人妖 | 国产在线无码精品电影网 | 国产日产欧产精品精品app | 无码成人精品区在线观看 | 亚洲一区二区三区在线观看网站 | 无码av免费一区二区三区试看 | 亚洲一区二区三区国产精华液 | 国产又爽又黄又刺激的视频 | 国产超级va在线观看视频 | 2020久久超碰国产精品最新 | 国产成人一区二区三区别 | 亚洲色偷偷男人的天堂 | 无码成人精品区在线观看 | 色婷婷久久一区二区三区麻豆 | 中文字幕中文有码在线 | 日产精品99久久久久久 | 无码一区二区三区在线 | 无码av中文字幕免费放 | 精品日本一区二区三区在线观看 | 爽爽影院免费观看 | 亚洲欧洲日本无在线码 | 久精品国产欧美亚洲色aⅴ大片 | 一本大道伊人av久久综合 | 国产亚洲精品久久久ai换 | 99在线 | 亚洲 | 无遮挡啪啪摇乳动态图 | 亚洲成av人片天堂网无码】 | 一本大道伊人av久久综合 | 亚洲高清偷拍一区二区三区 | 国产亚洲精品久久久闺蜜 | 婷婷综合久久中文字幕蜜桃三电影 | 色婷婷欧美在线播放内射 | 免费视频欧美无人区码 | 婷婷丁香六月激情综合啪 | 国产艳妇av在线观看果冻传媒 | 亚洲国产精品一区二区美利坚 | 樱花草在线播放免费中文 | 日韩人妻无码中文字幕视频 | 未满小14洗澡无码视频网站 | 特级做a爰片毛片免费69 | 久青草影院在线观看国产 | 一本加勒比波多野结衣 | 永久免费观看美女裸体的网站 | 又粗又大又硬又长又爽 | 色欲久久久天天天综合网精品 | 无码一区二区三区在线 | 午夜无码区在线观看 | 精品午夜福利在线观看 | 国产一区二区不卡老阿姨 | 久久综合给合久久狠狠狠97色 | 精品国产av色一区二区深夜久久 | 亚洲一区二区三区国产精华液 | 男女爱爱好爽视频免费看 | 粗大的内捧猛烈进出视频 | 无码人妻少妇伦在线电影 | 国产免费久久精品国产传媒 | 国产亲子乱弄免费视频 | 性生交片免费无码看人 | 国产精品美女久久久网av | 一二三四在线观看免费视频 | 老熟女乱子伦 | 99精品无人区乱码1区2区3区 | 亚洲国产欧美在线成人 | 丰满妇女强制高潮18xxxx | 亚洲天堂2017无码中文 | 亚洲成a人片在线观看无码3d | 亚洲精品成a人在线观看 | 国产精品99爱免费视频 | 强开小婷嫩苞又嫩又紧视频 | 日本www一道久久久免费榴莲 | 丰满少妇人妻久久久久久 | 极品尤物被啪到呻吟喷水 | 东京无码熟妇人妻av在线网址 | 亚洲色www成人永久网址 | 欧美人与禽zoz0性伦交 | 国产精品怡红院永久免费 | 大屁股大乳丰满人妻 | 一二三四在线观看免费视频 | 欧美成人午夜精品久久久 | 夜先锋av资源网站 | 久久综合网欧美色妞网 | 亚洲va中文字幕无码久久不卡 | 欧美喷潮久久久xxxxx | 激情国产av做激情国产爱 | 又湿又紧又大又爽a视频国产 | 一本久道久久综合狠狠爱 | 亚洲日韩精品欧美一区二区 | 女人被爽到呻吟gif动态图视看 | 日日天日日夜日日摸 | 人妻天天爽夜夜爽一区二区 | 精品无码一区二区三区爱欲 | 久久亚洲a片com人成 | 久久久精品456亚洲影院 | 亚洲天堂2017无码中文 | 国产激情一区二区三区 | 成人精品一区二区三区中文字幕 | 精品欧洲av无码一区二区三区 | 中文字幕乱妇无码av在线 | 国产精品理论片在线观看 | 精品人妻人人做人人爽夜夜爽 | 荫蒂被男人添的好舒服爽免费视频 | 国产农村妇女aaaaa视频 撕开奶罩揉吮奶头视频 | 国产精品人人妻人人爽 | 蜜臀av无码人妻精品 | 捆绑白丝粉色jk震动捧喷白浆 | 精品人人妻人人澡人人爽人人 | 国产精品办公室沙发 | 国精品人妻无码一区二区三区蜜柚 | 熟妇人妻中文av无码 | 97无码免费人妻超级碰碰夜夜 | 国产乱码精品一品二品 | 亚洲欧洲日本无在线码 | 亚洲欧美中文字幕5发布 | 成人三级无码视频在线观看 | 牲欲强的熟妇农村老妇女视频 | 麻豆成人精品国产免费 | 黑人大群体交免费视频 | 国产suv精品一区二区五 | 亚洲日本在线电影 | 精品久久久久久人妻无码中文字幕 | aⅴ亚洲 日韩 色 图网站 播放 | 国产97人人超碰caoprom | 国产香蕉97碰碰久久人人 | 人妻人人添人妻人人爱 | 日韩精品无码一本二本三本色 | 免费网站看v片在线18禁无码 | 国产精品久久福利网站 | 国产精品国产三级国产专播 | 国产成人精品无码播放 | 中文字幕精品av一区二区五区 | 色五月五月丁香亚洲综合网 | 美女扒开屁股让男人桶 | 少妇无套内谢久久久久 | 亚洲熟妇色xxxxx欧美老妇y | 亚欧洲精品在线视频免费观看 | 亚洲精品一区二区三区在线观看 | 日本护士xxxxhd少妇 | 色欲久久久天天天综合网精品 | 无码人妻少妇伦在线电影 | 国产情侣作爱视频免费观看 | 国内少妇偷人精品视频免费 | 人人妻人人澡人人爽欧美一区 | 欧美性黑人极品hd | 欧美激情一区二区三区成人 | 国产又粗又硬又大爽黄老大爷视 | 欧美激情一区二区三区成人 | 日韩少妇白浆无码系列 | 无码av最新清无码专区吞精 | 国产亚洲精品久久久久久久久动漫 | 99久久婷婷国产综合精品青草免费 | 久久久精品国产sm最大网站 | 天天拍夜夜添久久精品 | 久久亚洲日韩精品一区二区三区 | 蜜桃av抽搐高潮一区二区 | 麻豆人妻少妇精品无码专区 | 狠狠色丁香久久婷婷综合五月 | 伊在人天堂亚洲香蕉精品区 | 扒开双腿疯狂进出爽爽爽视频 | 九九综合va免费看 | 黑森林福利视频导航 | 狠狠色噜噜狠狠狠7777奇米 | 天天摸天天透天天添 | 亚洲无人区午夜福利码高清完整版 | 国产婷婷色一区二区三区在线 | 一个人免费观看的www视频 | 人人妻人人澡人人爽精品欧美 | 国产激情一区二区三区 | 人妻体内射精一区二区三四 | 无人区乱码一区二区三区 | 乱人伦人妻中文字幕无码 | aⅴ亚洲 日韩 色 图网站 播放 | 国产人妻人伦精品1国产丝袜 | 久久午夜夜伦鲁鲁片无码免费 | 亚洲欧洲无卡二区视頻 | 俺去俺来也在线www色官网 | 狂野欧美性猛交免费视频 | 欧美熟妇另类久久久久久不卡 | 国产精品美女久久久久av爽李琼 | 国产99久久精品一区二区 | 亚洲精品中文字幕 | 成熟人妻av无码专区 | 国产午夜无码视频在线观看 | 国产精品无码成人午夜电影 | 国产人妻精品午夜福利免费 | 麻豆国产人妻欲求不满谁演的 | 日日橹狠狠爱欧美视频 | 欧美性猛交内射兽交老熟妇 | 九九在线中文字幕无码 | 天堂亚洲2017在线观看 | 成 人 网 站国产免费观看 | 久久久久se色偷偷亚洲精品av | 国产猛烈高潮尖叫视频免费 | 久久午夜夜伦鲁鲁片无码免费 | 成人影院yy111111在线观看 | 草草网站影院白丝内射 | 无套内谢的新婚少妇国语播放 | 国内综合精品午夜久久资源 | 日韩在线不卡免费视频一区 | 亚洲人成网站在线播放942 | 曰本女人与公拘交酡免费视频 | 日日橹狠狠爱欧美视频 | 中文字幕无码乱人伦 | 成人性做爰aaa片免费看 | 久久久久se色偷偷亚洲精品av | 欧美国产日产一区二区 | 毛片内射-百度 | 日韩视频 中文字幕 视频一区 | 欧美黑人性暴力猛交喷水 | 精品人妻av区 | 亚洲熟悉妇女xxx妇女av | 久久99国产综合精品 | 亚洲爆乳精品无码一区二区三区 | 亚洲国产成人a精品不卡在线 | 国产精品久久久久影院嫩草 | 蜜桃视频插满18在线观看 | 色婷婷av一区二区三区之红樱桃 | √8天堂资源地址中文在线 | 日日夜夜撸啊撸 | 国产精品久久久久久无码 | 兔费看少妇性l交大片免费 | 无码播放一区二区三区 | 亚洲精品中文字幕久久久久 | 美女扒开屁股让男人桶 | 波多野结衣av在线观看 | 色综合久久久久综合一本到桃花网 | 亚洲精品午夜国产va久久成人 | 欧美午夜特黄aaaaaa片 | 日韩av无码一区二区三区不卡 | 国产成人无码a区在线观看视频app | 欧美老熟妇乱xxxxx | 国产一区二区不卡老阿姨 | 精品无码一区二区三区爱欲 | 久久久精品人妻久久影视 | 久久人人爽人人爽人人片ⅴ | 亚洲经典千人经典日产 | 奇米影视7777久久精品 | 77777熟女视频在线观看 а天堂中文在线官网 | 国内少妇偷人精品视频 | 嫩b人妻精品一区二区三区 | 精品无码国产自产拍在线观看蜜 | 国产人妻久久精品二区三区老狼 | 99精品视频在线观看免费 | 亚洲中文无码av永久不收费 | 少妇人妻偷人精品无码视频 | 少妇性l交大片欧洲热妇乱xxx | √天堂中文官网8在线 | 无码av岛国片在线播放 | 老子影院午夜精品无码 | 国产精品久久久久久亚洲毛片 | 97夜夜澡人人爽人人喊中国片 | 清纯唯美经典一区二区 | 5858s亚洲色大成网站www | 性色av无码免费一区二区三区 | 久久国产精品二国产精品 | 欧美人与物videos另类 | 国产精品久久久久9999小说 | 欧美日本免费一区二区三区 | 欧美日韩一区二区三区自拍 | 久久人人爽人人爽人人片ⅴ | 国产特级毛片aaaaaaa高清 | 亚洲日本va午夜在线电影 | 色婷婷综合激情综在线播放 | 亚洲精品欧美二区三区中文字幕 | 国产黄在线观看免费观看不卡 | 波多野42部无码喷潮在线 | 女人和拘做爰正片视频 | 日韩亚洲欧美精品综合 | 无码人妻久久一区二区三区不卡 | 激情内射亚州一区二区三区爱妻 | 国内精品一区二区三区不卡 | 国产精品久久久久无码av色戒 | 国产另类ts人妖一区二区 | 国产sm调教视频在线观看 | 国产乡下妇女做爰 | 精品国偷自产在线 | 欧美精品无码一区二区三区 | 久久久亚洲欧洲日产国码αv | 暴力强奷在线播放无码 | 夫妻免费无码v看片 | 成人片黄网站色大片免费观看 | 国产亚av手机在线观看 | 熟妇人妻激情偷爽文 | 精品偷自拍另类在线观看 | 色婷婷欧美在线播放内射 | 最近的中文字幕在线看视频 | 日日干夜夜干 | 国产精品久久久久久无码 | 中文无码成人免费视频在线观看 | 欧美日韩久久久精品a片 | 无码帝国www无码专区色综合 | 色综合久久88色综合天天 | 又粗又大又硬又长又爽 | 大地资源网第二页免费观看 | 欧美日韩一区二区免费视频 | 亚洲午夜无码久久 | 在线看片无码永久免费视频 | 色婷婷综合中文久久一本 | 国产成人精品三级麻豆 | 秋霞成人午夜鲁丝一区二区三区 | 宝宝好涨水快流出来免费视频 | av人摸人人人澡人人超碰下载 | 骚片av蜜桃精品一区 | 亚洲精品成人福利网站 | 青草视频在线播放 | 色综合久久中文娱乐网 | 亚洲欧美综合区丁香五月小说 | 四虎国产精品一区二区 | 亚洲国产精品美女久久久久 | 欧美日韩在线亚洲综合国产人 | 中文字幕无码日韩专区 | 中文无码精品a∨在线观看不卡 | 中文字幕日产无线码一区 | 少妇无码一区二区二三区 | 日欧一片内射va在线影院 | 中文字幕乱码人妻无码久久 | 欧美黑人性暴力猛交喷水 | 免费人成网站视频在线观看 | 亚洲国产精品毛片av不卡在线 | 亚洲天堂2017无码中文 | 狂野欧美性猛xxxx乱大交 | 国产精品高潮呻吟av久久4虎 | 日韩亚洲欧美精品综合 | 88国产精品欧美一区二区三区 | 黑人粗大猛烈进出高潮视频 | 荫蒂被男人添的好舒服爽免费视频 | 伊人久久大香线蕉亚洲 | 在线成人www免费观看视频 | 一本无码人妻在中文字幕免费 | 亚洲欧洲日本综合aⅴ在线 | 网友自拍区视频精品 | 国产精品无码一区二区桃花视频 | 色妞www精品免费视频 | 精品国产av色一区二区深夜久久 | 性做久久久久久久免费看 | 丰满肥臀大屁股熟妇激情视频 | 国产精品亚洲专区无码不卡 | 国产av人人夜夜澡人人爽麻豆 | 中国女人内谢69xxxxxa片 | 欧美野外疯狂做受xxxx高潮 | 久久综合久久自在自线精品自 | 国产乱人偷精品人妻a片 | 青青青手机频在线观看 | 小sao货水好多真紧h无码视频 | 一本久久伊人热热精品中文字幕 | 国产一区二区三区日韩精品 | 久久久久久a亚洲欧洲av冫 | 久久精品中文字幕一区 | 老太婆性杂交欧美肥老太 | 男人扒开女人内裤强吻桶进去 | 永久黄网站色视频免费直播 | 东北女人啪啪对白 | 美女极度色诱视频国产 | 十八禁视频网站在线观看 | 少妇一晚三次一区二区三区 | 蜜桃臀无码内射一区二区三区 | aⅴ亚洲 日韩 色 图网站 播放 | 亚洲第一网站男人都懂 | 久久久久se色偷偷亚洲精品av | 欧美喷潮久久久xxxxx | 东京一本一道一二三区 | 精品无码一区二区三区的天堂 | 亚洲热妇无码av在线播放 | 在线看片无码永久免费视频 | 中文亚洲成a人片在线观看 | 国产成人一区二区三区别 | 中文字幕无码日韩专区 | 九九在线中文字幕无码 | 亚洲 欧美 激情 小说 另类 | 性色欲网站人妻丰满中文久久不卡 | 成人亚洲精品久久久久软件 | 日日碰狠狠躁久久躁蜜桃 | 狠狠综合久久久久综合网 | 国产超碰人人爽人人做人人添 | 台湾无码一区二区 | 夜精品a片一区二区三区无码白浆 | 日日麻批免费40分钟无码 | 精品欧洲av无码一区二区三区 | 日本va欧美va欧美va精品 | 久久精品女人的天堂av | 亚洲 a v无 码免 费 成 人 a v | 亚洲无人区一区二区三区 | 99久久婷婷国产综合精品青草免费 | 亚洲国产成人av在线观看 | 人人爽人人爽人人片av亚洲 | 99久久人妻精品免费一区 | 成人片黄网站色大片免费观看 | 欧美丰满熟妇xxxx | 国产成人精品无码播放 | 亚洲自偷自拍另类第1页 | 老头边吃奶边弄进去呻吟 | 国产超级va在线观看视频 | 国产乱人伦偷精品视频 | 国产精品无码久久av | 55夜色66夜色国产精品视频 | 人妻夜夜爽天天爽三区 | 欧美成人免费全部网站 | 亚洲精品欧美二区三区中文字幕 | 国产熟妇另类久久久久 | 奇米影视7777久久精品 | 欧美自拍另类欧美综合图片区 | 亚洲色成人中文字幕网站 | 久青草影院在线观看国产 | 88国产精品欧美一区二区三区 | 无码人妻久久一区二区三区不卡 | а√资源新版在线天堂 | 亚洲成av人片在线观看无码不卡 | 丰满少妇高潮惨叫视频 | 欧美人与善在线com | 影音先锋中文字幕无码 | 天天做天天爱天天爽综合网 | 波多野42部无码喷潮在线 | 日日天干夜夜狠狠爱 | 亚洲精品综合五月久久小说 | 国产做国产爱免费视频 | 亚洲国产精华液网站w | 亚洲自偷自偷在线制服 | 丰满少妇弄高潮了www | 国产网红无码精品视频 | www一区二区www免费 | 中文精品无码中文字幕无码专区 | 欧美黑人性暴力猛交喷水 | 成人亚洲精品久久久久 | 国产凸凹视频一区二区 | 激情综合激情五月俺也去 | 麻豆成人精品国产免费 | 亚洲精品综合一区二区三区在线 | 中文字幕乱码亚洲无线三区 | 成人三级无码视频在线观看 | 女人和拘做爰正片视频 | 成人免费视频在线观看 | 十八禁视频网站在线观看 | 在线а√天堂中文官网 | 少女韩国电视剧在线观看完整 | 丝袜 中出 制服 人妻 美腿 | 亚洲一区二区三区偷拍女厕 | 国产肉丝袜在线观看 | 狂野欧美性猛交免费视频 | 成人性做爰aaa片免费看不忠 | 国产明星裸体无码xxxx视频 | 国产亚洲欧美在线专区 | 日本欧美一区二区三区乱码 | 亚洲成熟女人毛毛耸耸多 | 亚洲色偷偷偷综合网 | 久久 国产 尿 小便 嘘嘘 | 动漫av网站免费观看 | 日本熟妇人妻xxxxx人hd | 久久久中文久久久无码 | 无码免费一区二区三区 | 免费无码肉片在线观看 | 亚洲国产精华液网站w | 草草网站影院白丝内射 | 亚洲色偷偷男人的天堂 | 亚洲精品久久久久中文第一幕 | 一本久久a久久精品亚洲 | 国色天香社区在线视频 | 日产精品高潮呻吟av久久 | 性欧美熟妇videofreesex | 18黄暴禁片在线观看 | 永久免费观看美女裸体的网站 | 国产午夜福利亚洲第一 | 九九在线中文字幕无码 | 中文字幕无码日韩专区 | 日日碰狠狠躁久久躁蜜桃 | 狠狠色色综合网站 | 国产口爆吞精在线视频 | 亚洲最大成人网站 | 香蕉久久久久久av成人 | 麻豆国产丝袜白领秘书在线观看 | 久久久久久亚洲精品a片成人 | 亚洲第一网站男人都懂 | 亚洲国产成人av在线观看 | 久久zyz资源站无码中文动漫 | 婷婷六月久久综合丁香 | 久久亚洲国产成人精品性色 | 98国产精品综合一区二区三区 | 天海翼激烈高潮到腰振不止 | 人人妻人人澡人人爽欧美精品 | 亚洲日韩精品欧美一区二区 | 九九久久精品国产免费看小说 | 成在人线av无码免费 | 国产精品久免费的黄网站 | 1000部啪啪未满十八勿入下载 | 婷婷五月综合缴情在线视频 | 久9re热视频这里只有精品 | 人妻少妇被猛烈进入中文字幕 | 精品久久久久久亚洲精品 | 天堂亚洲2017在线观看 | 国产人妻精品午夜福利免费 | 中文字幕亚洲情99在线 | 精品亚洲成av人在线观看 | 国产又爽又猛又粗的视频a片 | 在线精品亚洲一区二区 | 精品乱子伦一区二区三区 | 亚洲综合精品香蕉久久网 | 国产国语老龄妇女a片 | 成人无码精品1区2区3区免费看 | 色婷婷综合中文久久一本 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 一本久久a久久精品亚洲 | 日本www一道久久久免费榴莲 | 2019午夜福利不卡片在线 | 精品水蜜桃久久久久久久 | 久久伊人色av天堂九九小黄鸭 | 国产精品高潮呻吟av久久 | 亚洲另类伦春色综合小说 | 久久国产精品萌白酱免费 | 亚洲一区av无码专区在线观看 | 久久国产精品精品国产色婷婷 | 无码国产激情在线观看 | 丰满少妇弄高潮了www | 亚洲码国产精品高潮在线 | 无码国内精品人妻少妇 | 国产午夜亚洲精品不卡下载 | 亚洲精品无码国产 | 亚洲国产精品无码久久久久高潮 | 国产真实夫妇视频 | 精品国产av色一区二区深夜久久 | 亚洲成av人片在线观看无码不卡 | av小次郎收藏 | 成人性做爰aaa片免费看不忠 | 国产成人综合在线女婷五月99播放 | 99久久无码一区人妻 | 精品久久久无码中文字幕 | 中文字幕av无码一区二区三区电影 | 亚洲毛片av日韩av无码 | 大屁股大乳丰满人妻 | 在线亚洲高清揄拍自拍一品区 | 成年美女黄网站色大免费视频 | 欧美日韩人成综合在线播放 | 草草网站影院白丝内射 | 久久精品国产亚洲精品 | 熟女少妇在线视频播放 | 无码任你躁久久久久久久 | 波多野结衣乳巨码无在线观看 | 18黄暴禁片在线观看 | 未满成年国产在线观看 | 国产特级毛片aaaaaa高潮流水 | 久久精品99久久香蕉国产色戒 | 少妇无码av无码专区在线观看 | 99久久精品午夜一区二区 | 亚洲人交乣女bbw | 久久久国产一区二区三区 | 丁香花在线影院观看在线播放 | 性色欲网站人妻丰满中文久久不卡 | 久久午夜无码鲁丝片秋霞 | 兔费看少妇性l交大片免费 | 秋霞特色aa大片 | 在线观看国产午夜福利片 | 亚洲综合另类小说色区 | 免费无码的av片在线观看 | 蜜桃av抽搐高潮一区二区 | 久久伊人色av天堂九九小黄鸭 | 男女猛烈xx00免费视频试看 | 日韩少妇白浆无码系列 | 国产免费久久久久久无码 | 欧美日韩视频无码一区二区三 | 无码国产色欲xxxxx视频 | 久久97精品久久久久久久不卡 | 中文字幕av伊人av无码av | 成人女人看片免费视频放人 | 美女极度色诱视频国产 | 精品无码一区二区三区的天堂 | 亚洲精品无码国产 | 国产亚洲精品久久久久久久久动漫 | 国产免费无码一区二区视频 | 人人妻人人澡人人爽欧美精品 | 妺妺窝人体色www婷婷 | 国产成人综合美国十次 | 久久亚洲精品中文字幕无男同 | 麻豆国产人妻欲求不满谁演的 | 成人精品一区二区三区中文字幕 | 精品国产麻豆免费人成网站 | 久久99精品国产麻豆蜜芽 | 粉嫩少妇内射浓精videos | 初尝人妻少妇中文字幕 | 亚洲综合色区中文字幕 | 亚洲国产精华液网站w | 亚洲精品欧美二区三区中文字幕 | 国产性生大片免费观看性 | 精品乱子伦一区二区三区 | 欧美老妇交乱视频在线观看 | 蜜臀aⅴ国产精品久久久国产老师 | 亚洲成a人片在线观看日本 | 国内揄拍国内精品人妻 | 乌克兰少妇性做爰 | 性欧美videos高清精品 | 国产精品沙发午睡系列 | 精品无码一区二区三区爱欲 | 丝袜美腿亚洲一区二区 | 亚洲天堂2017无码 | 狠狠色色综合网站 | 牲欲强的熟妇农村老妇女 | 理论片87福利理论电影 | 久久久精品欧美一区二区免费 | 少妇激情av一区二区 | 欧美黑人巨大xxxxx | 久久精品女人的天堂av | 奇米影视888欧美在线观看 | 精品人妻中文字幕有码在线 | 成人av无码一区二区三区 | 色偷偷人人澡人人爽人人模 | 熟妇人妻无乱码中文字幕 | 亚洲成av人在线观看网址 | 又粗又大又硬又长又爽 | 麻花豆传媒剧国产免费mv在线 | 久久精品女人的天堂av | 任你躁国产自任一区二区三区 | 亚洲乱码日产精品bd | 18黄暴禁片在线观看 | 国产成人久久精品流白浆 | 亚洲成在人网站无码天堂 | 野狼第一精品社区 | 精品偷自拍另类在线观看 | 极品尤物被啪到呻吟喷水 | 亚洲熟妇色xxxxx欧美老妇y | 又大又硬又黄的免费视频 | 久久99热只有频精品8 | 天下第一社区视频www日本 | 三上悠亚人妻中文字幕在线 | 一本大道久久东京热无码av | 久久久久人妻一区精品色欧美 | 成人精品一区二区三区中文字幕 | 欧洲美熟女乱又伦 | 精品熟女少妇av免费观看 | 成人精品视频一区二区 | 久久综合狠狠综合久久综合88 | 又湿又紧又大又爽a视频国产 | 国产成人无码av片在线观看不卡 | 精品无码一区二区三区的天堂 | 动漫av网站免费观看 | 狠狠噜狠狠狠狠丁香五月 | 黑人玩弄人妻中文在线 | 亚欧洲精品在线视频免费观看 | 亚洲精品一区二区三区四区五区 | 5858s亚洲色大成网站www | 无码国产激情在线观看 | 丰满少妇熟乱xxxxx视频 | ass日本丰满熟妇pics | 久久精品99久久香蕉国产色戒 | 国产激情无码一区二区 | 国产亚洲精品久久久久久国模美 | 亚洲精品国产第一综合99久久 | 欧洲vodafone精品性 | 日本一区二区三区免费播放 | 亚洲精品久久久久中文第一幕 | 动漫av一区二区在线观看 | 一本色道久久综合亚洲精品不卡 | 丝袜美腿亚洲一区二区 | 99麻豆久久久国产精品免费 | 中文字幕无线码 | 亚洲国产精品美女久久久久 | 图片小说视频一区二区 | 精品国产青草久久久久福利 | 水蜜桃亚洲一二三四在线 | 中文无码精品a∨在线观看不卡 | 成人一在线视频日韩国产 | 国产人妻人伦精品 | 天天摸天天碰天天添 | 超碰97人人射妻 | 97久久精品无码一区二区 | 一本久久a久久精品vr综合 | 人人爽人人爽人人片av亚洲 | 麻豆国产人妻欲求不满 | 国产免费久久久久久无码 | 人人妻人人澡人人爽欧美精品 | 任你躁在线精品免费 | 日韩成人一区二区三区在线观看 | 又色又爽又黄的美女裸体网站 | 久久亚洲精品成人无码 | 女人被爽到呻吟gif动态图视看 | 国产精品第一区揄拍无码 | 中文字幕av日韩精品一区二区 | 少妇性l交大片欧洲热妇乱xxx | 国产乱人伦app精品久久 国产在线无码精品电影网 国产国产精品人在线视 | 国产极品美女高潮无套在线观看 | 爆乳一区二区三区无码 | 国产人妻久久精品二区三区老狼 | 人人妻人人澡人人爽欧美一区九九 | 东京热无码av男人的天堂 | 最新国产乱人伦偷精品免费网站 | 日本熟妇乱子伦xxxx | 久久久精品456亚洲影院 | 狠狠色噜噜狠狠狠狠7777米奇 |