淺談MySQL Online DDL(中)

本文首發於我的微信公衆號《andyqian》,期待你的關注!

前言

  在上一篇文章中《淺談MySQL Online DDL (上)》中,咱們談到了MySQL Online DDL的由來,還介紹了聚簇索引與二級索引的區別。今天,咱們繼續談談MySQL Online DDL。mysql

Online DDL優勢

  在上篇文章中,咱們知道了『快速索引建立』的優勢,對於MySQL 5.7版原本說,這也就成爲了Online DDL的優勢了,並且加強了很多。優勢以下:sql

  1. 不影響生產環境數據庫運行,在DDL操做時,不影響生產上的查詢,以及DML操做。數據庫

  2. 減小在建立,修改二級索引時,帶來不必的數據複製,臨時表建立時的磁盤與IO開銷。微信

  3. 可以人爲經過Lock語句平衡性能與開銷。併發

Online DDL語法

  Online DDL語法上,其實並無特殊的之處的。咱們知道Online DDL這個概念在MySQL5.6首次出現,雖然在語法上沒有特殊的之處,但官方爲咱們在原來的DDL語法上添加了一些控制性能與併發的屬性,這裏以alter爲例(以下所示):
演示MySQL版本: 5.7.20工具

alter table t_base_user modify telephone varchar(50),lock=none ;

上面這條語句很是簡單,就是修改 t_base_user 表中 telephone字段屬性。
其中 lock=none 是咱們比較陌生的,這個就是MySQL5.6中用來控制性能的屬性,須要注意的是,在MySQL5.6以前的版本中,這樣的語法是不支持的。執行時會直接報語法不支持的錯誤。那 lock=none 表明什麼意思呢?性能

鎖類型

  Online DDL語句和DDL語句是同樣的,執行時一樣的會加鎖,(這裏就統一說成鎖吧,MySQL鎖是一個比較大的話題,下次詳細說明)。測試

官方給咱們提供了幾個可選項:spa

  1. LOCK=EXCLUSIVE : 表示獨佔鎖,DDL語句執行期間會阻塞該表的全部請求。設計

  2. LOCK=SHARED:共享鎖,DDL語句執行期間會阻塞除查詢外的全部DML操做,如: insert,update等。

  3. LOCK=NONE: 容許全部查詢以及DML操做。

  4. LOCK=DEFAULT 默認級別,MySQL儘量容許最大的併發操做。

當咱們不顯示指定時,默認就爲LOCK=DEFAULT類型。

須要注意的是:

  1. 不是全部的DDL操做LOCK類型均可以指定爲NONE的。若是DDL操做的類型,不能以請求的鎖定類型執行,則會執行失敗。

rows affected

  在執行有些DDL語句時(修改字段類型),實際上是有風險的,那怎麼避免風險呢?這個時候就要經過執rows affected類分析了。
以下所示:

mysql> alter table t_base_user modify telephone varchar(50),lock=none ;
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

這裏顯示咱們修改t_base_user表telephone字段會很是快,並且不會重建表。這是因爲演示數據比較少致使的。當生產數據比較多時,是會重建表的。

下面給出了一些參考選項:

  1. 更改列的默認值(超快,徹底不影響表數據):

    Query OK, 0 rows affected (0.07 sec)
  2. 添加一個索引(須要時間,可是0 rows affected顯示錶格不被複制):

    Query OK, 0 rows affected (21.42 sec)
  3. 更改列的數據類型(須要大量的時間,而且須要重建表的全部行):

    Query OK, 1671168 rows affected (1 min 35.54 sec)

    咱們能夠經過上述的執行結果,查看該語句是否複製記錄,重建整個表格(咱們上篇說過,若是重建,成本會很是高,並且還會影響線上DML)等。顯然,直接在生產上運行該語句後,再看結果來分析。已經沒有意義了,咱們能夠經過在測試環境中來看。具體步驟以下:

  4. 複製須要ddl的生產表結構到測試環境中。

  5. 添加部分數據到該表中。

  6. 執行ddl操做。

  7. 查看rows affected 值是否爲0,非0時,意味着操做須要重建整個表,這時候就須要從新指定方案,如:在停機時進行操做,或業務低估時進行操做。

今日命令

命令:

SHOW CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name

做用:顯示指定數據庫的建立語句。
例子:

mysql> show create database andyqian\G
*************************** 1. row ***************************
       Database: andyqian
Create Database: CREATE DATABASE `andyqian` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci */
1 row in set (0.00 sec)

其中:
Database 表示數據庫名。
Create Database 表示建立數據庫語句。

這裏須要注意的是:

show create database andyqian\G

show create schema andyqian\G

上述兩個語句的,執行結果是同樣的。

注意

  1. andyqian爲指定的數據庫名,請替換至本身須要顯示的數據庫名。

  2. 在 Navicat 第三方工具時運行時,不須要添加\G。命令以下便可:
    show create schema andyqian;

小結

  在這一篇中,咱們簡單了介紹了MySQL Online DDL的語法,以及鎖類型等等。其實Online DDL也是有條件限制的,以及Online DDL語句的實現細節,咱們在下一篇文章中繼續說。盡請期待!

最後:週五了,立刻就週末了,準備好週末怎麼過了嗎?

 

推薦閱讀:

淺談MySQL Online DDL (上)

MySQL事務隔離級別

MySQL表設計踩過的坑!

談談MySQL隱式類型轉換

 

掃碼關注,一塊兒進步

我的博客: http://www.andyqian.com

相關文章
相關標籤/搜索