日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

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

数据库

java有趣的技术分享ppt_技术分享 | 关于 MySQL Online DDL 有趣的验证

發布時間:2023/12/19 数据库 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java有趣的技术分享ppt_技术分享 | 关于 MySQL Online DDL 有趣的验证 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作者:胡存存

愛可生 DBA 團隊成員,主要負責 MySQL 故障處理和 SQL 審核優化。對技術執著,為客戶負責。

本文來源:原創投稿

*愛可生開源社區出品,原創內容未經授權不得隨意使用,轉載請聯系小編并注明來源。


MySQL 在 5.6 引入 Online DDL 之后,在 5.7 和 8.0 版本又對這一功能進行了大幅的優化。尤其是在 8.0 之后,已經實現了列的秒加。在 5.7 中有些 DDL 操作也實現了秒修改,比如修改字段的默認值,修改列名,但是這些在工作中不是很常見,今天我們討論下能夠實現秒修改的一種特殊情況,稍不注意可能就掉進坑中。

在日常工作中,我們用的最多的數據類型就是 int(bigint) 類型和 varchar 類型。在這兩個數據類型中,其中 int 類型只要不超過數據類型允許的最大值,int(N) 類型的中的 N 不會影響輸入的字節數,但是 varchar(N) 數據類型中的 N,當輸入的字符數超過 N 時,就不允許輸入,這時就需要擴容,這也是我們經常會遇到的一種數據變更。當出現這種需求,我們是采用 MySQL 的 Online DDL 直接修改還是用第三方的工具呢。我們先看下官網關于擴 varchar 類型的描述:

參考文章:https://dev.mysql.com/doc/refman/5.7/en/innodb-online-ddl-operations.html通過上圖可以發現,Extending VARCHAR column size 在 In Place 是 yes,Rebuilds Table 是 no,也就是在修改是在修改時不用 copy 表,那是不是這樣,我們驗證下。我們用 sysbench 準備 4 張表,單表 500w,用 4 線程壓數據庫,模擬業務量(數據庫版本:5.7.29)。表結構為:root@localhost[sbtest]> show create table sbtest1\G*************************** 1. row *************************** Table: sbtest1Create Table: CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120) NOT NULL DEFAULT '', `pad` char(60) NOT NULL DEFAULT '', `c1` varchar(10) NOT NULL DEFAULT 'cc', PRIMARY KEY (`id`), KEY `k_1` (`k`)) ENGINE=InnoDB AUTO_INCREMENT=5000001 DEFAULT CHARSET=utf8mb41 row in set (0.00 sec)此時啟動 sysbench,看到此時的 qps 在 5000 左右,

此時將 c1 列從 varchar(10) 擴到 varchar(50),我們發現秒修改,直接毫無感知,與官網上說的一樣。

這時候字節長度又不夠了,我們需要擴到 100,這時候,我們發現了異常,這次不再是秒修改,而是停在了那,現在是不是覺得有點不妙,這時候,再看我們的壓測日志,

這時候業務完全被阻塞了,這時候,腦瓜子是不是嗡嗡的了。。。

到底怎么回事,我們看下官網怎么說:Extending?VARCHAR?column sizeALTER TABLE tbl_name CHANGE COLUMN c1 c1 VARCHAR(255), ALGORITHM=INPLACE, LOCK=NONE;The number of length bytes required by a?VARCHAR?column must remain the same. For?VARCHAR?columns of 0 to 255 bytes in size, one length byte is required to encode the value. For?VARCHAR?columns of 256 bytes in size or more, two length bytes are required. As a result, in-place?ALTER TABLE?only supports increasing?VARCHAR?column size from 0 to 255 bytes, or from 256 bytes to a greater size. In-place?ALTER TABLE?does not support increasing the size of a?VARCHAR?column from less than 256 bytes to a size equal to or greater than 256 bytes. In this case, the number of required length bytes changes from 1 to 2, which is only supported by a table copy (ALGORITHM=COPY). For example, attempting to change?VARCHAR?column size for a single byte character set from VARCHAR(255) to VARCHAR(256) using in-place?ALTER TABLE?returns this error:ALTER TABLE tbl_name ALGORITHM=INPLACE, CHANGE COLUMN c1 c1 VARCHAR(256);ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY.由上文可知,在 varchar 類型中,當大小在 0 到 255 字節時,需要 1 個字節編碼,當大于 255 時,需要 2 個字節編碼。所以在相同字節編碼的長度內變更,可以用 inplace 的方式,當字節編碼長度變更時,只能用 copy 模式,這種情況下會完全阻塞表的讀寫。這樣我們大約明白怎么回事了,但細想,又在哪里有問題,剛才我們在變更時,從 varchar(50) 到 varchar(100),還沒到 255,為什么會出現 copy 表的現象?其實這里我們注意的是 varchar(N) 中,N 表示的是字符,而不是字節。所以,所以根據字符集不一樣,每個字符需要的字節也不一樣,所以在擴 varchar 長度時,N 的范圍也不一樣。在 utf8 字符集中,一個字符需要三個字節,所以,當 N<=85 時,需要一個 1 個字節編碼,當 N>85 時,需要兩個。所以我們來驗證下,這里我們建 3 張表:

我們在表中插入幾條數據,如下:

我們先修改 t1(字符集為 utf8)表,如下:

如上圖,我們看到,當字段擴到 85 時,影響的行數還為 0,當擴到 86 之后,影響行數變為 3,也就是說字符長度從 85 擴到 86,此時發生了全表的 copy。當大于 86 之后,我們怎么擴,也不會發生表的 copy 操作了。我們再來驗證 utf8mb4:

因為 utf8mb4 字符集一個字節需要 4 個字符,所以,當擴到 63 時,影響行數為 0,當擴到 64,影響行數為 3,發生了表的 copy。我們進一步用 latin1 驗證,因為拉丁 1 字符集,一個字符只需要一個字節,所以,當擴大到 255 時,仍為 0,當擴大到 256 時,影響行數變為 2。

綜上,我們可以總結:
  • 因為 varchar 字符集在存儲時除了數據,還需要存 1~2 字節的前綴,長度前綴表示 varchar 中的字節數,當字段的字節數不大于 255 時,需要 1 個字節前綴,當大于 255 時,需要 2 個字節長度。

  • innodb 存儲引擎,在擴大 varchar 字符長度時,當字節長度在 0~255 之間,或者 256 開始擴大,能用到 inplace 特性,當從 255 擴大到 256 時,只能 copy 表。

  • varchar(N) 字段類型中的 N 表示字符,根據不同字符集,單個字符需要的字節不一樣,所以范圍也不一樣。

所以,我們在日常工作中,可以制定相應開發規范,盡量防止這類的事情發生。

另外,再提醒下,MySQL 5.7.20 之前的版本可能不支持(我測試的版本是 5.7.29),生產使用時需要再測試下。

此外,varchar 類型的縮小字符長度和字段數據類型更改都只能用 copy 的方式,有此需求要小心。


相關推薦:

技術分享 | Online DDL 工具 pt-osc

技術分享 | Online DDL 工具 gh-ost

新特性解讀 | MySQL 8.0 之原子 DDL

社區近期動態

本文關鍵字:#DDL# #mysql5.7#?點一下“閱讀原文”了解更多資訊

總結

以上是生活随笔為你收集整理的java有趣的技术分享ppt_技术分享 | 关于 MySQL Online DDL 有趣的验证的全部內容,希望文章能夠幫你解決所遇到的問題。

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