精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

MySQL如何優雅的執行DDL

京東云 ? 來源:jf_75140285 ? 作者:jf_75140285 ? 2024-07-18 15:06 ? 次閱讀

一、前言

關于MySQL DDL表結構變更,各個工單平臺基本上都支持了pt-osc及Online DDL的方式,但是,我相信仍然有一大部分人,不太了解這兩種方式各自的優缺點是啥,以至于實際當中,會稀里糊涂的隨機選一種去執行,選對了固然好,選錯了,自然免不了領導的一頓K,這......當然是開玩笑的哈。

?

在各搜索平臺上,介紹關于pt-osc及Online DDL工作原理的文章,不計其數,但是,對于非專業選手而已,又有幾個人是完全吃透的呢?所以,在這,不打算對其原理再重復一遍,僅從他們的執行機制角度出發,介紹各種DDL在選擇不同方式時所產生的影響,并基于此來分析該如何選擇。

?

另,現在普遍使用的版本為5.7,所以,咱就以 MySQL 5.7.24 版本為例。

?

二、pt-osc及Online DDL執行機制

2.1 Online DDL

?機制:MySQL通過Innodb引擎在內部執行一系列的操作進行表變更,當然,同一個表,不同的DDL,會有不同效果,甚至會出現一天上一個地下的差異,所以不同DDL,后面再對其進行具體分析;如果有從庫,則在主庫執行完成后,從庫再操作一遍,動作和主庫一模一樣(執行時間也很接近)。

?優點:這個咱后面在講具體SQL時再進行具體分析。

?缺點:

?某些場景下,會鎖表引發堵塞增刪改操作,這個是需要重點注意的,具體場景后面會標紅說明。

?如果有從庫,這有一個很致命的弱點:復制延遲。因為主庫執行的動作,會在從庫再來一遍,如果這個動作是非常耗時的,那在從庫執行(重放主庫的動作)的時間點開始,其后續所有動作都被堵塞住,直到從庫也執行完這個DDL后,才會繼續按順序執行其他SQL。這就就意味著,從從庫執行開始,從庫復制就出現了延遲,延遲的時間會慢慢變大,直到DDL執行完后,延遲才會慢慢變小。

?存在數據copy的情況時,需要額外的磁盤空間,但有可能同樣的SQL,空間需求會比使用pt-osc低。

?特殊情況:云側MySQL RDS,本身有一個隱藏從庫用于高可用,因為這個隱藏從庫不對外提供服務,所以基本上業務側也不需要去關注他。但極端情況,如果大表DDL操作使用Online DDL模式時,在隱藏從庫正在執行DDL期間,主庫掛了,那常理就需要切換到隱藏從庫,才能繼續提供服務,但為了保證數據的一致性,隱藏從庫必須要等DDL執行完,再回放DDL之后的binlog,然后,才能將其提升為主庫,對外提供服務,所以這個恢復時間有可能很長。總得來講,這個情況對業務而言也是致命的,只不過概率極低。

?

2.2 pt-osc

?機制:創建一個新臨時表,并在老表上創建3個觸發器,再進行新老表的數據同步,直至新老表數據一致后,再進行表名互換,達到表變更的目的。不同的DDL,只要pt-osc支持,他的操作方式都是一樣的,這點與Online DDL完全不同。

?優點:

?可以設置相應的參數,根據主、從庫負載(比如復制延遲)的情況,動態調整數據拷貝速度,整個表結構變更過程相對比較溫和。

?不會引發從庫復制延遲超級大的情況;

?執行完后,新表會將老表占用的碎片空間完全釋放掉。

?缺點:

?需要將老表的所有數據都拷貝到新表上,這就意味著拷貝期間,磁盤IO可能較高。

?要拷貝全量數據,所以執行時間也會很長。

?新臨時表存放數據也需要空間(最大空間需求可能和原表一樣),拷貝數據時還會產生大量binlog,所以對于本來空間就緊張的實例而言,這方式真的是雪上加霜。

?

2.3 加鎖

加鎖情況,想必是大家使用時關心較多的一個問題,但是,我想說,MySQL 5.7加鎖情況會比你想象中的要好。Online DDL及pt-osc,大部分情況下,只會在執行前后加表元數據鎖,其在獲取到表元數據鎖并上鎖后,在極短時間內做完后續相關動作,緊接著就會將鎖釋放掉。Online DDL除特殊操作外(后面會說明),大部分情況下,不會對現有業務造成堵塞影響。在業務足夠繁忙時,反而有可能會出現表結構變更操作獲取不到表元數據鎖(鎖等待超時),從而導致執行失敗的情況。

?

三、各種DDL操作

在具體分析后面各種DDL之前,咱統一假設要操作的表足夠大,要不然表太小的話,不管什么方式都是瞬間完成,就沒有對比的意義了。另,編寫的DDL語句,如果想用Online DDL方式,咱也不需要刻意去指定 ALGORITHM 及 LOCK 選項,就讓MySQL自動判斷后默認選擇就好。

?

下面,咱就從MySQL官方文檔Online DDL對各種操作的支持角度去分析兩種方式的差異情況。當然,如果你的DDL語句同時含有好幾種不同的操作,那就以最壞的那種情形做參考即可。

?

3.1 索引操作

圖一:Online DDL 索引操作

wKgZomaYvvKAb4HjAAGyklNYP_0685.png

??

?

3.1.1 創建普通二級索引

Online DDL:從圖一,我們可以看出,這會選擇In Place的方式執行,整個過程,只會涉及到拷貝二級索引列相關的數據用于創建索引,所以需要拷貝的數據,相對于pt-osc而已,肯定會少很多,反過來說,執行需要的時間也相對會少。如果沒從庫,不存在復制延遲的問題,那選擇Online DDL顯然會比pt-osc更優;但如果有從庫,那復制延遲的問題,自然是需要考慮的,而且大表復制延遲的時間,當然也會較長,如果接受不了延遲,那直接選pt-osc就好。

?

pt-osc:復制整個表的數據用于建新表,優勢是有從庫時,幾乎不存在復制延遲的問題;劣勢也很明顯,因為拷貝整個表的數據,所以時間長,同時磁盤IO也會變高。

?

3.1.2 刪除索引、索引重命名

Online DDL:從圖一可以看到Only Modifies Metadata對應的是YES,也就意味著僅修改元數據,速度非常快,幾乎瞬間完成,必選Online DDL。

?

pt-osc:直接無視

?

3.1.3 變更索引類型、全文索引、空間索引

咱現在使用的索引類型基本上都是BTREE,幾乎很少用到HASH,同時也很少見到有用全文索引及空間索引的,所以,這幾種咱就不討論了。

?

3.2 唯一索引及主鍵操作

圖二:Online DDL主鍵操作

wKgaomaYvvOASSbnAAGEruH2AyE360.png

??

?

因為pt-osc拷貝數據的過程,會依賴于唯一鍵(主鍵或者唯一索引)來校驗數據的一致性,對唯一鍵進行相關的操作可能會引發各種各樣的問題,所以不管pt-osc實際支持或不支持這類操作,咱都直接默認為不支持就好。也就是涉及主鍵及唯一索引相關的操作,都直接選Online DDL。但是,需要注意的是,單獨刪除主鍵的操作,會引發鎖表,導致不允許對表進行其他增刪改的操作,也就是增刪改會被堵塞住,這操作需要慎重考慮。而同一個DDL里面,刪除老主鍵的同時又加上新主鍵,是不會引起堵塞的。

?

3.3 列操作

圖三:Online DDL列操作

wKgZomaYvvSAVCEgAAO4PeRxRVA931.png

??

?

3.3.1 添加列、刪除列、重排列順序、變更列類型、修改列為空或非空

Online DDL:從圖三可以看出,這6種DDL操作,在選擇Online方式時,都會重建表,效果上與pt-osc并無太大差別,還得擔憂從庫復制延遲的問題,那既然如此,直接選擇pt-osc的方式更省事。

?

Online DDL以下這幾種情況會鎖表,堵塞其他增刪改操作,需要注意:

1)增加一個自增列。

2)單純修改列類型。

3)修改列名,同時修改了列類型(該情形應該算修改列類型的一個特殊例子)(只支持 Online DDL)。

?

pt-osc:首選。需要注意的是,因為pt-osc不支持修改列名,所以上述的第三點,只能選擇Online DDL的方式執行,但是選擇Online DDL,又會出現鎖表導致堵塞其他增刪改的操作,所以慎重。

?

3.3.2 VARCHAR列增加列大小

Online DDL:MySQL底層在存儲變長列VARCHAR列的內容時,還會額外記錄內容占用字節數的大小,記錄這個大小,也是需要空間的。另外,還有個東西咱需要了解下,VARCHAR列存儲一個字符,使用utf8字符集時,最大需要3字節(比如存儲一個中文字符),而utf8mb4最大需要4字節(比如存儲一個表情符)。知道了使用什么字符集,咱就可以計算出存儲一個VARCHAR變長列最大需要多少字節了。

?

列存儲最大需要字節數 = VARCHAR列定義的長度 * 不同字符集存儲單個字符需要最大字節數

?

而記錄列占用字節數大小,所需的空間,會根據 列存儲最大需要字節數 細分出兩種情況:

1)列存儲最大需要字節數為0-255時,記錄列占用字節數大小需要1字節。

2)列存儲最大需要字節數為256-65535時,記錄列占用字節數大小需要2字節。

3)因表數據行,非大對象的列,總的存儲內容長度限制就是65535,所以,單列VARCHAR存儲需求自然也不能超過這個限制,也就是不存在超過65535的情況。

?

回歸正題,VARCHAR列增加大小:

1)如果列長度增加后,記錄列占用字節數大小所需字節數不變,也就是列存儲最大需要字節數依然在同一個范圍內:0-255或256-65535,那這類操作,ALGORITHM支持使用 In Place算法,只會修改表的元數據信息,瞬間完成,此情形,直接選Online DDL即可。

2)如果列長度增加后,記錄列占用字節數大小所需字節數變了,從1字節變成2字節,ALGORITHM 則只支持COPY算法,這就意味著會出現數據拷貝的情況,同時會堵塞其他增刪改的操作,這情形選pt-osc。

?

例子:

# 建表
create table t1(name varchar(10) null) charset=utf8mb4;

# 列存儲最大需要字節數計算:長度 10,utf8mb4字符集存儲單字符最大需要字節數 4
# 列存儲最大需要字節數 = 10 * 4 = 40
# 記錄列占用字節數大小所需空間為1字節


# 表結構變更一
alter table t1 modify name varchar(63) null;

# 列存儲最大需要字節數計算:長度 63,utf8mb4字符集存儲單字符最大需要字節數 4
# 列存儲最大需要字節數 = 63 * 4 = 252
# 記錄列占用字節數大小所需空間依然為1字節,ALGORITHM默認選用In Place,Online DDL執行瞬間完成


# 表結構變更二
alter table t1 modify name varchar(64) null;

# 列存儲最大需要字節數計算:長度 64,utf8mb4字符集存儲單字符最大需要字節數 4
# 列存儲最大需要字節數 = 64 * 4 = 256
# 記錄列占用字節數大小所需空間變為2字節,ALGORITHM只能使用COPY,引發數據拷貝,堵塞其他增刪改操作,選擇pt-osc


?

pt-osc:根據上述信息選合適的。

?

3.3.3 修改列名(只改列名)、設置/刪除默認值、修改ENUM/SET列定義

Online DDL:從圖三可以看出,這類操作會只修改表元數據信息,速度極快,直接選Online DDL方式即可

?

pt-osc:直接無視

?

3.3.4 修改自增列的自增值

Online DDL:在MySQL 8.0版本前,自增值不存在持久化的概念,修改這個值,只會在內存中修改,更不涉及數據的拷貝及變動,所以直接使用Online DDL方式即可。

?

pt-osc:直接無視

?

3.4 Generated列操作

圖四:Online DDL 虛擬列操作

wKgaomaYvvWAbgIbAAIWU26vLqM873.png

??

?

3.4.1 新增/刪除Generated虛擬列

Online DDL:虛擬列不涉及數據存儲的問題,所以新增和刪除都只會涉及到表元數據的變更,幾乎瞬間完成,直接選用Online DDL方式執行即可。

?

pt-osc:直接無視

?

3.4.2 新增/修改/刪除Generated存儲列、修改Generated虛擬列順序

Online DDL:這幾種操作,在選擇Online DDL時,都會涉及到表重建的問題,大表執行時間不會短,另外,新增/修改Generated存儲列 以及 修改Generated虛擬列順序,都會鎖表,引發堵塞其他增刪改操作,所以,建議選pt-osc。

?

pt-osc:首選

?

3.5 外鍵操作

圖五:Online DDL外鍵操作

wKgZomaYvvaALI-YAAFwC3Ekk1Q448.png

??

?

如果表存在外鍵依賴,后期對父表進行各種DDL操作時,數據庫會有較大的風險,嚴重的甚至會鎖表,所以不建議用外鍵。

?

3.6 表操作

圖六:Online DDL表操作

wKgaomaYvveAdDmkAALYuWHnn0c540.png

??

?

3.6.1 修改表名

Online DDL:從圖六看出,Online DDL修改表名,只會涉及到修改表的元數據信息,瞬間完成。

?

pt-osc:不支持

?

3.6.2 表碎片整理、更改行格式、修改字符集、收集統計信息

Online DDL:咱對表的操作,常用到的,可能就是表碎片整理、更改行格式(比如改成壓縮模式),修改字符集(含內容轉換)以及收集統計信息,這些操作,從圖六也看到了,基本都是需要重建表,建議首選pt-osc。

?

pt-osc:首選

?

3.6.3 其他相關的表操作

其他操作平常基本很少用到,暫時不討論。

?

3.7 表空間操作

圖七:Online DDL表空間操作

wKgZomaYvviAKXiTAAEQrGq-8tc779.png

??

?

在實際使用中,幾乎見不到,咱就不討論了。

?

3.8 表分區操作

圖八:Online DDL表分區操作

wKgaomaYvvmAE75kAAdjVH5DRuc440.png

??

?

表分區相關的操作較多,咱就挑比較常用的進行分析,其他操作不做贅述。

?

3.8.1 普通表轉分區表

Online DDL:他的本質是新建一個臨時表,每個分區對應一個數據文件,然后進行拷貝,拷貝完畢后,表名互換,刪除老表。眼熟不?從某種程度上講,這個過程與pt-osc是相似的,但是,Online DDL方式會鎖表,堵塞其他增刪改操作,所以,直接選擇pt-osc方式即可。

?

pt-osc:必選

?

3.8.2 新增分區、刪除分區、TRUNCATE分區

Online DDL:

新增分區,只分析常用的RANGE及LIST分區。RANGE分區新增分區,有個嚴格的限制,新分區less than的值必須是遞增的,換句話講就是不存在數據拷貝的問題。LIST分區,這個更直接,相關內容如果在LIST分區中不存在,直接不允許插入,新增分區也不存在數據拷貝的問題。所以,這兩種選用Online DDL時,操作幾乎都是瞬時完成的,直接使用Online DDL即可。

?

刪除分區時,會對當前分區上鎖,堵塞該分區的其他增刪改操作,但既然你都打算刪除分區了,想必自然也不會再對該分區有其他操作。 其對應系統底層的操作,類似于直接將分區對應的物理文件進行刪除,操作時,如果文件足夠大,系統IO會瞬間暴漲,繼而影響業務,所以建議在業務低峰期間進行。

?

TRUNCATE分區操作,對應系統底層的操作,類似于直接將分區對應的物理文件進行清空,操作時,如果文件足夠大,系統IO會瞬間暴漲,繼而影響業務,所以建議在業務低峰期間進行。

?

pt-osc:直接無視

?

四、結束語

從上面的介紹可以看出,DDL相關的操作較多,想要完全記住各種操作選那種方式最合適,想必也是件費神的事情。如果上面信息對你有用,點贊收藏起來,用到時再慢慢參考即可。

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • MySQL
    +關注

    關注

    1

    文章

    789

    瀏覽量

    26286
  • DDL
    DDL
    +關注

    關注

    0

    文章

    12

    瀏覽量

    6309
收藏 人收藏

    評論

    相關推薦

    MySQL的整體邏輯架構

    支持多種存儲引擎是眾所周知的MySQL特性,也是MySQL架構的關鍵優勢之一。如果能夠理解MySQL Server與存儲引擎之間是怎樣通過API交互的,將大大有利于理解MySQL的核心
    的頭像 發表于 04-30 11:14 ?329次閱讀
    <b class='flag-5'>MySQL</b>的整體邏輯架構

    優雅停機是什么?SpringBoot+Nacos+k8s實現優雅停機

    優雅停機是什么?網上說的優雅下線、無損下線,都是一個意思。
    的頭像 發表于 02-20 10:00 ?1447次閱讀
    <b class='flag-5'>優雅</b>停機是什么?SpringBoot+Nacos+k8s實現<b class='flag-5'>優雅</b>停機

    查詢SQL在mysql內部是如何執行

    我們知道在mySQL客戶端,輸入一條查詢SQL,然后看到返回查詢的結果。這條查詢語句在 MySQL 內部到底是如何執行的呢?本文跟大家探討一下哈,我們先來看下MySQL基本架構~
    的頭像 發表于 01-22 14:53 ?415次閱讀
    查詢SQL在<b class='flag-5'>mysql</b>內部是如何<b class='flag-5'>執行</b>?

    MySQL密碼忘記了怎么辦?MySQL密碼快速重置方法步驟命令示例!

    MySQL密碼忘記了怎么辦?MySQL密碼快速重置方法步驟命令示例! MySQL是一種常用的關系型數據庫管理系統,如果你忘記了MySQL的密碼,不必擔心,可以通過一些簡單的步驟來快速重
    的頭像 發表于 01-12 16:06 ?636次閱讀

    mysql密碼忘了怎么重置

    mysql密碼忘了怎么重置? MySQL是一種開源的關系型數據庫管理系統,密碼用于保護數據庫的安全性和保密性。如果你忘記了MySQL的密碼,可以通過以下幾種方法進行重置。 方法一:使用MySQ
    的頭像 發表于 12-27 16:51 ?4297次閱讀

    一種優雅解決MySQL驅動中虛引用導致GC耗時較長問題的方法

    在之前文章中寫過 MySQL JDBC 驅動中的虛引用導致 JVM GC 耗時較長的問題,在驅動代碼(mysql-connector-java 5.1.38版本)中
    的頭像 發表于 12-20 09:52 ?702次閱讀

    MySQL執行過程 SQL語句性能優化常用策略

    回顧 MySQL執行過程,幫助介紹如何進行 sql 優化。
    的頭像 發表于 12-12 10:26 ?537次閱讀
    <b class='flag-5'>MySQL</b>的<b class='flag-5'>執行</b>過程 SQL語句性能優化常用策略

    MySQL執行過程:如何進行sql 優化

    (1)客戶端發送一條查詢語句到服務器; (2)服務器先查詢緩存,如果命中緩存,則立即返回存儲在緩存中的數據; (3)未命中緩存后,MySQL 通過關鍵字將 SQL 語句進行解析,并生成一顆對應的解析樹,MySQL 解析器將使用 MySQ
    的頭像 發表于 12-12 10:19 ?335次閱讀
    <b class='flag-5'>MySQL</b><b class='flag-5'>執行</b>過程:如何進行sql 優化

    mysql配置失敗怎么辦

    MySQL安裝目錄的子目錄中,可以通過在命令行執行 mysql --help | grep my.cnf 或 mysql --help | grep my.ini 來找到
    的頭像 發表于 12-06 11:03 ?2857次閱讀

    mysql數據庫基礎命令

    使用以下命令: mysql -u -p 其中,username是您的MySQL用戶名。執行此命令后,系統會提示您輸入密碼。成功輸入密碼后,您將登錄到MySQL命令行界面。 創建數據庫
    的頭像 發表于 12-06 10:56 ?444次閱讀

    php的mysql無法啟動

    MySQL是一種常用的關系型數據庫管理系統,而PHP是一種廣泛應用于服務器端的腳本語言。在使用PHP開發網站或應用時,經常會碰到MySQL無法啟動的問題。本文將詳細介紹解決MySQL無法啟動的方法
    的頭像 發表于 12-04 15:59 ?1105次閱讀

    mysql和sql server區別

    MySQL和SQL Server是兩種常見的關系型數據庫管理系統(RDBMS),用于存儲和管理數據庫。雖然它們都支持SQL語言,但在其他方面存在一些顯著的區別。以下是MySQL和SQL Server
    的頭像 發表于 11-21 11:07 ?1251次閱讀

    MySQL導出的步驟

    mysql -u username -p 其中,username是你的MySQL用戶名,執行命令后會提示輸入密碼
    的頭像 發表于 11-21 10:58 ?664次閱讀

    mysql基礎語句大全

    MySQL是一個開放源碼的關系型數據庫管理系統,使用SQL作為其查詢語言。它是Web開發中常用的數據庫管理系統之一。MySQL的語法十分豐富,可以執行各種數據庫操作,包括創建、修改、刪除和查詢等
    的頭像 發表于 11-16 16:42 ?1728次閱讀

    windows環境下mysql的安裝

    1 下載并安裝MySQL 首先輸入如下命令下載Yum Repository,大概25KB的樣子 [root @localhost ~ ]# wget - i - c http
    的頭像 發表于 10-08 15:29 ?419次閱讀
    windows環境下<b class='flag-5'>mysql</b>的安裝