" />

欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Mysql如何在線添加索引

 更新時間:2024年01月27日 16:20:00   作者:還是轉(zhuǎn)轉(zhuǎn)  
這篇文章主要介紹了Mysql如何在線添加索引問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

在實際工作中,經(jīng)常遇到需要給數(shù)據(jù)庫表添加索引的情況。雖然操作是由dba來執(zhí)行,但開發(fā)還是應(yīng)該了解在線添加索引會引起的性能問題。比如博主最近就遇到了線上添加索引導(dǎo)致業(yè)務(wù)報警的問題。

問題描述

出于業(yè)務(wù)需要,給一個表添加普通索引,但這個表有100個分表,因此需要給100個分表都加上。

平均每張表大概有500萬行的數(shù)據(jù)量。線上業(yè)務(wù)流量也比較高。mysql版本為5.7版本,在線添加索引問題不大。

跟dba商量好之后,提交sql腳本由dba實施。經(jīng)實踐發(fā)現(xiàn),平均一張表添加索引大概需要3~5分鐘。在添加完20多張表之后,發(fā)現(xiàn)業(yè)務(wù)開始報警。查看業(yè)務(wù)日志,發(fā)現(xiàn)有不少接口超時。

根據(jù)經(jīng)驗判斷,應(yīng)該是服務(wù)端TCP連接滿了,查看監(jiān)控信息,果然如此,直接使用該數(shù)據(jù)庫表的服務(wù)的tcp連接溢出。很顯然,應(yīng)該是數(shù)據(jù)庫操作變慢導(dǎo)致接口響應(yīng)時間增加,從而導(dǎo)致吞吐量降低,而業(yè)務(wù)流量保持不變的情況下,大量請求造成堆積,進而導(dǎo)致TCP連接被占滿甚至溢出。

同時,即使沒有使用該數(shù)據(jù)庫表,使用其他庫的服務(wù)也出現(xiàn)同樣的問題。原因在于兩者使用的數(shù)據(jù)庫在同一個實例上,添加索引導(dǎo)致數(shù)據(jù)庫服務(wù)器負載增加(實際增加不算多,正常來說應(yīng)該不影響?),影響到了其他庫。

這時候只能讓dba將索引添加操作暫停,等待晚上12點之后流量降低再執(zhí)行。晚上執(zhí)行時不再報警。

online ddl

通常情況下,對數(shù)據(jù)量大的表進行ddl操作時,一般都會選在流量低的時候進行。

但是在mysql5.6之后,引入了一些新的特性,支持DDL執(zhí)行期間DML語句的并行操作,提高了數(shù)據(jù)庫的吞吐量。

據(jù)mysql官方文檔介紹,online ddl操作不會加鎖,很快就能完成操作。

正是基于這一點考慮,所以才直接在白天加。結(jié)果就出現(xiàn)了上面的問題。

那么什么是online ddl呢?

其結(jié)構(gòu)圖如下:

Online DDL原理

oneline ddl大致分為3個部分:

  • copy(ALGORITHM=COPY)這部分是offline的,ddl執(zhí)行時會阻塞dml,中間需要臨時表的中轉(zhuǎn)。這也是5.6版本前的DDL執(zhí)行方法。在innodb中不支持使用inplace的操作都會自動使用copy方式執(zhí)行,而MyISAM表只能使用copy方式。
  • inplace(ALGORITHM=INPLACE)所有操作在innodb引擎層完成,不需要經(jīng)過臨時表的中轉(zhuǎn)。除上圖兩種特殊索引創(chuàng)建外,其他以inplace方式執(zhí)行的操作都是online的,執(zhí)行期間其他DML操作可以并行,其中又以是否重建表又分為兩個部分rebuild和no-rebuild。

rebuild部分涉及表的重建,在原表路徑下創(chuàng)建新的.frm和.ibd文件,消耗的IO會較多。

期間(原表可以修改)會申請row log空間記錄DDL執(zhí)行期間的DML操作,這部分操作會在DDL提交階段應(yīng)用新的表空間中。

no-rebuild部分由于不涉及表的重建,除創(chuàng)建添加索引,會產(chǎn)生部分二級索引的寫入操作外,其余操作均只修改元數(shù)據(jù)項,即只在原表路徑下產(chǎn)生.frm文件,不會申請row log,不會消耗過多的IO,速度通常很快。

  • inplace but offline的幾種特殊DDL操作,本身是按inplace方式執(zhí)行,但是執(zhí)行期間DML語句卻不能并行。

如何區(qū)分DDL語句是使用了copy方式還是inplace方式,只需要查看語句執(zhí)行完成輸出結(jié)果中的 X rows

affected,如果X為0則是inplace(online)方式,如果不為0則是copy(offline)方式。

copy的整體執(zhí)行過程如下:

  • 1.鎖表,期間DML不可并行執(zhí)行
  • 2.生成臨時表以及臨時表文件(.frm .ibd)
  • 3.拷貝原表數(shù)據(jù)到臨時表
  • 4.重命名臨時表及文件
  • 5.刪除原表及文件
  • 6.提交事務(wù),釋放鎖

inplace(rebuild)的整體執(zhí)行過程如下:

準備階段

1.對表加元數(shù)據(jù)共享升級鎖,并升級為排他鎖(此時DML不能并行)

2.在原表所在的路徑下創(chuàng)建.frm和.ibd臨時中轉(zhuǎn)文件(no-rebuild除創(chuàng)建二級索引外只創(chuàng)建.frm文件,其中添加二級索引操作最為特殊,該操作屬于no-rebuild不會生成.ibd,但實際上對.ibd文件卻做了修改,該操作會在參數(shù)tmpdir指定路徑下生成臨時文件,用于存儲索引排序結(jié)果,然后再合并到.ibd文件中)

3.申請row log空間,用于存放DDL執(zhí)行階段產(chǎn)生的DML操作(no-rebuild不需要)

執(zhí)行階段

1.釋放排他鎖,保留元數(shù)據(jù)共享升級鎖(此時DML可以并行)

2.掃描原表主鍵以及二級索引的所有數(shù)據(jù)頁,生成 B+ 樹,存儲到臨時文件中

3.將所有對原表的DML操作記錄在日志文件row log中

如果只修改元數(shù)據(jù)部分(no-rebuild),該階段只是修改.frm文件,不需要其他操作,也不需要申請row log

提交階段

1.升級元數(shù)據(jù)共享升級鎖,產(chǎn)生排他鎖鎖表(此時DML不能并行)。

2.重做row log中的內(nèi)容。(no-rebuild不需要)

3.重命名原表文件,將臨時文件改名為原表文件名,刪除原表文件

4.提交事務(wù),變更完成。

顯式online ddl參數(shù)

可以在執(zhí)行online DDL語句的時候,使用ALGORITHM和LOCK關(guān)鍵字,這兩個關(guān)鍵字在DDL語句的最后面,用逗號隔開。

ALGORITHM有如下選項:

  • INPLACE:直接在原表上面執(zhí)行DDL的操作。
  • COPY:使用臨時表。這期間需要多出一倍的磁盤空間來支撐這樣的 操作。執(zhí)行期間,表不允許DML的操作。
  • DEFAULT:默認方式,由MySQL自己選擇,優(yōu)先使用INPLACE的方式。

LOCK有如下選項:

  • SHARE:共享鎖,執(zhí)行DDL的表可以讀,但是不可以寫。
  • NONE:沒有任何限制,執(zhí)行DDL的表可讀可寫。
  • EXCLUSIVE:排它鎖,執(zhí)行DDL的表不可以讀,也不可以寫。
  • DEFAULT:默認值,也就是在DDL語句中不指定LOCK子句的時候使用的默認值,由MySQL自動判斷,優(yōu)先使用NONE的方式。

例句如下,參數(shù)間使用逗號隔開:

alter table test add col int,ALGORITHM=INPLACE,LOCK=DEFAULT;

執(zhí)行DDL操作時,顯式參數(shù)可以不指定,mysql會自動選擇合適的方式去執(zhí)行,優(yōu)先使用inplace,none的方式,效果與指定ALGORITHM=DEFAULT,LOCK=DEFAULT一樣。

但是如果顯式指定了這兩個參數(shù),則必須按照指定的方式來執(zhí)行,不支持的話則直接報錯。

總結(jié)分析

從上面的內(nèi)容來看,online ddl添加索引正常應(yīng)該是很快的,但并不是完全不會加鎖。

在對表元數(shù)據(jù)加互斥鎖的時候,會阻塞dml操作。

但從整體來看,這個時間應(yīng)該是極短的,所以官方才有online ddl操作不會加鎖的說法。

上面說到在inplace模式的online ddl操作時,會申請一個緩存空間,用于存放在此期間的dml操作。

這個緩存大小由參數(shù)innodb_online_alter_log_max_size控制,默認為128mb,支持動態(tài)修改。

如果更新的表比較大,并且在ddl過程中有大量的寫操作,就可能遇到空間不足的情況,會拋出相應(yīng)的錯誤。

另外,如果ddl操作的目標表上有未結(jié)束的事務(wù)或者有鎖沒有釋放,那么在加元數(shù)據(jù)獨占鎖(mdl)時就會等待前面的鎖釋放,這個時候的狀態(tài)為:waiting for table metadata lock。

又因為獨占鎖的優(yōu)先權(quán)限,后面的DML操作都要排隊等待。從而導(dǎo)致db操作阻塞。

最終的結(jié)論是:

  • 如果表數(shù)據(jù)量較小,或者加索引的表數(shù)量較少,online ddl操作是可以接受的,建議顯式指定algorithm和lock參數(shù)。
  • 但如果數(shù)據(jù)量較大,或者加索引的表比較多,那么就需要充分考慮上面說到的問題,最好在業(yè)務(wù)流量低的時候執(zhí)行。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 教你使用idea連接服務(wù)器mysql的步驟

    教你使用idea連接服務(wù)器mysql的步驟

    這篇文章主要介紹了如何使用idea連接服務(wù)器上的mysql,具體步驟本文給大家介紹的非常詳細,需要的朋友可以參考下
    2024-02-02
  • mac系統(tǒng)OS X10.10版本安裝最新5.7.9mysql的方法

    mac系統(tǒng)OS X10.10版本安裝最新5.7.9mysql的方法

    這篇文章給大家介紹mac系統(tǒng)OS X10.10版本安裝最新5.7.9mysql的方法,本文分步驟純文字說明,介紹的非常詳細,具有參考價值,在此分享供大家參考
    2015-10-10
  • MySQL慢查詢優(yōu)化解決問題

    MySQL慢查詢優(yōu)化解決問題

    這篇文章主要介紹了MySQL慢查詢優(yōu)化解決問題,MySQL的慢查詢,全名是慢查詢?nèi)罩?,是MySQL提供的一種日志記錄,用來記錄在MySQL中響應(yīng)時間超過閥值的語句,下文詳細介紹慢查詢的調(diào)優(yōu)情況,需要的小伙伴可以參考一下
    2022-03-03
  • MySQL數(shù)據(jù)庫統(tǒng)計函數(shù)COUNT的使用及說明

    MySQL數(shù)據(jù)庫統(tǒng)計函數(shù)COUNT的使用及說明

    這篇文章主要介紹了MySQL數(shù)據(jù)庫統(tǒng)計函數(shù)COUNT的使用及說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • MySQL中索引的分類詳解

    MySQL中索引的分類詳解

    這篇文章主要介紹了MySQL中索引的分類詳解,普通索引就是最基礎(chǔ)的索引,這種索引沒有任何的約束作用,它存在的主要意義就是提高查詢效率,唯一性索引是在普通索引的基礎(chǔ)上增加了數(shù)據(jù)唯一性的約束,一個表中可以有多個,需要的朋友可以參考下
    2023-08-08
  • MySQL登錄時出現(xiàn) Access denied for user ‘root‘@‘xxx.xxx.xxx.xxx‘ (using password: YES) 的原因及解決辦法

    MySQL登錄時出現(xiàn) Access denied for user ‘

    今天打開mysql的時候突然提示:Access denied for user 'root'@'localhost' (using password: YES) 在網(wǎng)上搜索了很多文章,本文就來做一下總結(jié),介紹了幾種場景的解決方法,感興趣的可以了解一下
    2024-03-03
  • 如何使用MySQL查詢一年中每月的記錄數(shù)

    如何使用MySQL查詢一年中每月的記錄數(shù)

    這篇文章主要給大家介紹了關(guān)于如何使用MySQL查詢一年中每月的記錄數(shù)的相關(guān)資料,文中通過實例代碼以及圖文介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2022-09-09
  • win10 安裝mysql 8.0.18-winx64的步驟詳解

    win10 安裝mysql 8.0.18-winx64的步驟詳解

    這篇文章主要介紹了win10 安裝mysql 8.0.18-winx64的步驟,本文圖文并茂給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-11-11
  • MySQL動態(tài)列轉(zhuǎn)行的實現(xiàn)示例

    MySQL動態(tài)列轉(zhuǎn)行的實現(xiàn)示例

    本文介紹了如何在MySQL中實現(xiàn)動態(tài)列轉(zhuǎn)行的功能,通過使用格式化日期、計數(shù)函數(shù)、分組、存儲過程、分組合并函數(shù)和SQL拼接等技巧,可以將動態(tài)列轉(zhuǎn)換為行,從而更好地進行數(shù)據(jù)分析和展示,感興趣的可以了解一下
    2024-11-11
  • MySQL 選擇合適的存儲引擎

    MySQL 選擇合適的存儲引擎

    這篇文章主要介紹了MySQL如何選擇合適的存儲引擎,幫助大家更好的理解和使用MySQL數(shù)據(jù)庫,感興趣的朋友可以了解下
    2020-09-09

最新評論