線上服務宕機,碼農試用期被畢業,原因竟是給MySQL加個欄位

来源:https://www.cnblogs.com/yidengjiagou/archive/2022/10/08/16769180.html
-Advertisement-
Play Games

工作中最常遇到的問題,怎麼給線上頻繁使用的大表添加欄位? 比如:給下麵的用戶表(user)添加年齡(age)欄位。 有同學會說,這還不簡單,直接加不加完了,用下麵的命令: ...


1. 問題:怎麼給線上表加欄位?

工作中最常遇到的問題,怎麼給線上頻繁使用的大表添加欄位?

比如:給下麵的用戶表(user)添加年齡(age)欄位。

CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主鍵',
  `name` varchar(100) DEFAULT NULL COMMENT '姓名',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='用戶表';

有同學會說,這還不簡單,直接加不加完了,用下麵的命令:

ALTER TABLE `user` ADD `age` int NOT NULL DEFAULT '0' COMMENT '年齡';

添加完,再查看一下表結構:

CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主鍵',
  `name` varchar(100) DEFAULT NULL COMMENT '姓名',
  `age` int NOT NULL DEFAULT '0' COMMENT '年齡',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='用戶表';

這不是添加成功了嗎?有什麼呀!

是的,線下資料庫怎麼整都行,但是如果線上上資料庫這樣操作,整個服務都有宕機的風險!自己也離畢業不遠了。

不是危言聳聽,我們找個case測試一下:

image

  1. Session1啟動了一個事務,沒有提交。
  2. Session2執行添加列的操作,被阻塞。
  3. 更嚴重的是,Session3執行簡單查詢的語句也被阻塞了。

2. 線上服務宕機的原因

為什麼會出現這種情況呢?

原因是在執行查詢語句的時候,MySQL自動加了MDL鎖(metadata lock,即元數據鎖)

不行的話,我們可以再執行一下show processlist命令,查看有哪些正在執行的進程:

image

可以清楚的看到Session2和Session3的語句正在等待MDL鎖,Waiting for table metadata lock

MDL鎖的作用是什麼?

為了保證併發操作下數據的一致性。

如果一個事務正在執行中,另一個在這時修改了表結構,不但可能導致當前事務出現不可重覆讀的問題,還有可能連事務都無法提交。

什麼時候會加MDL鎖?

MDL鎖是MySQL自動隱式加鎖,無需我們手動操作。

在我們執行DDL語句的時候,MySQL自動添加MDL讀鎖。

在我們執行DML語句的時候,MySQL自動添加MDL寫鎖。

讀鎖與讀鎖之間不互斥,讀鎖與寫鎖、寫鎖與寫鎖之間互斥。

註意:MDL鎖是表鎖,會對整張表加鎖。

普及額外的小知識點,什麼是DML和DDL:

DML(Data Manipulation Language)數據操縱語言:

適用範圍:對錶數據進行操作,比如 insert、delete、select、update等。

DDL(Data Definition Language)數據定義語言:

適用範圍:對錶結構進行操作,比如create、drop、alter、rename、truncate等。

3. 如何優雅的給線上表加欄位

既然修改表結構的時候,MySQL會自動添加表鎖,並且是寫鎖,會阻塞後續的所有讀寫請求,造成非常嚴重的後果。

還有沒有辦法能優雅的給線上表添加欄位呢?

當然有,從MySQL5.6版本開始增加了Online DDL,作用就是在執行DDL的時候,允許併發執行DML。簡單翻譯就是修改表結構的時候,也能同時支持併發執行增刪查改操作。

從MySQL8.0版本開始又優化了Online DDL,支持快速添加列,可以實現給大表秒級加欄位。

具體用法就是在DDL語句後面增加兩個參數ALGORITHMLOCK

比如下麵這樣:

ALTER TABLE `user` ADD `age` int NOT NULL DEFAULT '0' COMMENT '年齡', 
ALGORITHM=Inplace, 
LOCK=NONE;

這兩個參數分別是幹嘛用的?有哪些選項呢?

ALGORITHM可以指定使用哪種演算法執行DDL,可選項有:

  • Copy:

    拷貝方式,MySQL5.6 之前 DDL 的執行方式,過程就是先創建新表,修改新表結構,把舊表數據複製到新表,刪除舊表,重命名新表。執行過程非常耗時,產生大量的磁碟IO和占用CPU,還有使Buffer poll失效,而且需要鎖住舊表,性能較差,現在基本很少使用。

  • Inplace:

    原地修改,MySQL5.6開始引入的,優點是不會在Server層發生表數據拷貝,過程中允許併發執行DML操作。過程就是先添加MDL寫鎖,執行初始化操作,然後降級為MDL讀鎖,執行DDL操作(比較耗時,允許併發執行DML操作),升級為MDL寫鎖,完成DDL操作。

  • Instant:

    快速修改,MySQL8.0開始引入的,可以實現快速給大表添加欄位。

性能依次是,Instant > Inplace > Copy。

LOCK可以指定執行過程中,是否加鎖,可選項有:

  • NONE

    不加鎖,允許DML操作。

  • SHARED

    加讀鎖,允許讀操作,禁止DML操作。

  • DEFAULT

    預設鎖模式,在滿足DDL操作前提下,預設鎖模式會允許儘可能多的讀操作和DML操作。

  • EXCLUSIVE

    加寫鎖,禁止讀操作和DML操作。

Online DDL並不是支持所有DDL操作,看一下到底支持哪些操作?

操作 Instant Inplace Rebuilds Table 允許併發DML 僅修改元數據
添加列 Yes Yes No Yes No
刪除列 No Yes Yes Yes No
重命名列 No Yes No Yes Yes
更改列順序 No Yes Yes Yes No
設置列預設值 Yes Yes No Yes Yes
更改列數據類型 No No Yes No No
設置VARCHAR列大小 No Yes No Yes Yes
刪除列預設值 Yes Yes No Yes Yes
更改自動增量值 No Yes No Yes No
設置列為null No Yes Yes Yes No
設置列not null No Yes Yes Yes No

像最常見的添加列就可以使用Instant,而像刪除列、重命名列、更改列數據類型就只能使用Inplace了。

image


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家介紹的是一種靈活的i.MXRT下多串列NOR Flash型號選擇的量產方案。 對於以 i.MXRT 這類沒有內部 NVM (Non-Volatile Memory) 的 MCU 為主控的項目來說,為其選配一顆 NVM 作為代碼存儲器是頭等大事, ...
  • 如何設計藝術字?如何進行圖標設計?Art Text 4 Mac版是一款藝術字體製作和圖標設計軟體,它支持多圖層,可以輕鬆創造複雜圖形。可將該程式創建的圖形應用於iWork,Microsoft office、BeLight等應用程式,以及各種其他文本編輯和網頁設計程式。使用Art Text 4 Mac ...
  • @(文章目錄) 前言 上一篇和大家一起分享瞭如何使用LabVIEW OpenCV dnn實現手寫數字識別,今天我們一起來看一下如何使用LabVIEW OpenCV dnn實現圖像分類。 一、什麼是圖像分類? 1、圖像分類的概念 圖像分類,核心是從給定的分類集合中給圖像分配一個標簽的任務。實際上,這意 ...
  • 還在尋找一款好玩的休閑益智游戲嗎?現為大家分享一款經典割繩子游戲Cut the Rope Remastered Mac版,這款游戲的目標很簡單,就是合理的切割繩子,讓小怪物吃到糖果即可過關,但是要想得到高評價,就要想辦法吃到所有的星星。 詳情:經典割繩子游戲Cut the Rope Remaster ...
  • 作者:小牛呼嚕嚕 | https://xiaoniuhululu.com 電腦內功、JAVA底層、面試相關資料等更多精彩文章在公眾號「小牛呼嚕嚕 」 什麼是CPU上下文 Linux是一個多任務的操作系統,多任務操作系統是指多個進程運行在一個 CPU 中互不打擾,看起來像同時運行一樣。多任務的操作系 ...
  • MySQL事務 先來看一個例子 有一張balance表: 需求:將tom的100塊錢轉到King賬戶中 執行的操作是: update balance set money = money -100 where id = 100 update balance set money = money +100 ...
  • 1. 視窗函數概念和語法 視窗函數對一組查詢行執行類似聚合的操作。然而,聚合操作將查詢行分組到單個結果行,而視窗函數為每個查詢行產生一個結果: 函數求值發生的行稱為當前行 與發生函數求值的當前行相關的查詢行組成了當前行的視窗 相比之下,視窗操作不會將一組查詢行摺疊到單個輸出行。相反,它們為每一行生成 ...
  • 一、CentOS 7.9 安裝 rabbitmq-3.10.2.tar.gz 地址 https://www.rabbitmq.com https://github.com/rabbitmq/rabbitmq-server https://github.com/rabbitmq/rabbitmq-se ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...