您好,登錄后才能下訂單哦!
小編給大家分享一下如何解決通過shell腳本模擬MySQL自增列的不一致問題,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
MySQL的自增列問題其實很有意思,在重啟數據庫之后,會按照max(id)+1的方式來計算,這樣一個看起來有些別扭的實現方式在早期版本就飽受詬病,在MySQL 5.7都沒有解決掉,終于在8.0松口了,計劃在這個版本中修復。
而重啟會帶來自增列一類的潛在問題,而如果不重啟其實也有可能會有自增列的不一致問題。和兩個參數table_definition_cache和table_open_cache還是密切相關的。
主要的原因是什么呢,引用阿里數據庫內核團隊的解釋(https://www.kancloud.cn/taobaomysql/monthly/67171):一方面InnoDB表自增值是存儲在表對象中的,表對象又是放在緩存中的,如果表太多而不能全部放在緩存中的話,老的表就會被置換出來,這種被置換出來的表下次再使用的時候,就要重新打開一遍,對自增列來說,這個過程就和實例重啟類似,需要 select max(id) + 1 算一下自增值。
表對象緩存大小由 table_definition_cache 系統變量控制,最小值為400,表緩存相關的另一個系統變量是table_open_cache,這個控制的是所有線程打開表的緩存大小,這個緩存放在server層。
我在查看了5.6.14的環境之后,發現這個值已經提升到了500,而在MySQL 5.7中,提升到了1400,可見這方面了下了大功夫。
MySQL 5.6.14的參數值情況
# mysqladmin var|grep table_open_cache
| table_open_cache | 256
| table_open_cache_instances | 1
# mysqladmin var|grep table_definition_cache
| table_definition_cache | 500
MySQL 5.7中的參數值情況:
mysql> show variables like 'table_definition_cache';
| Variable_name | Value |
| table_definition_cache | 1400 |
mysql> show variables like 'table_open_cache';
| Variable_name | Value |
| table_open_cache | 2000 | 阿里的同學給出了testcase的偽代碼,我就來實現以下,給出shell版本的測試腳本。
首先我們可以模擬一下這個測試的基線,把兩個變量都修改為400.
SET GLOBAL table_definition_cache = 400;
SET GLOBAL table_open_cache = 400;
然后使用如下的shell腳本,仔細來看,腳本邏輯很簡單了。
生成500個表,然后插入一條數據,修改自增列值,然后查詢表里的數據,使得數據能夠刷出,稍作等待,查看show create table的結果。
for i in {1..500}
do
mysql test_new <<EOF
CREATE TABLE t$i(id INT NOT NULL AUTO_INCREMENT, name VARCHAR(30), PRIMARY KEY(id)) ENGINE=InnoDB;
INSERT INTO t$i(name) VALUES("InnoDB");
ALTER TABLE t$i AUTO_INCREMENT = 100;
EOF
done
for i in {1..500}
do
mysql test_new <<EOF
SELECT * FROM t$i;
EOF
done
sleep 10;
for i in {1..3}
do
mysql test_new <<EOF
SHOW CREATE TABLE t$i;
EOF
done
測試完成之后,來查看自增列的值情況.
在5.6.14中效果很明顯。
Table Create Table
t1 CREATE TABLE `t1` (\n `id` int(11) NOT NULL AUTO_INCREMENT,\n `name` varchar(30) DEFAULT NULL,\n PRIMARY KEY (`id`)\n) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
而在5.7中,發現這類問題竟然還復現不了了,至于是代碼層級做了修復還是和其它參數有關,就需要深入一下了。
Table Create Table
t1 CREATE TABLE `t1` (\n `id` int(11) NOT NULL AUTO_INCREMENT,\n `name` varchar(30) DEFAULT NULL,\n PRIMARY KEY
(`id`)\n) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=latin1
看完了這篇文章,相信你對“如何解決通過shell腳本模擬MySQL自增列的不一致問題”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。