通過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
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23718752/viewspace-2142052/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 通過shell指令碼快速定位active session問題指令碼Session
- 通過shell指令碼抓取awr報告中的問題sql指令碼SQL
- 通過shell指令碼批量操作mysql資料庫指令碼MySql資料庫
- 通過shell指令碼檢測MySQL服務資訊指令碼MySql
- MySQL自增列ID的面試題MySql面試題
- 通過shell指令碼分析足彩指令碼
- 通過shell定製ash指令碼指令碼
- mysql自增列MySql
- 實戰模擬監控MySQL服務shell指令碼小結薦MySql指令碼
- 通過shell指令碼檢視procedure的資訊指令碼
- 通過shell指令碼檢視package的資訊指令碼Package
- [ Shell ] 通過 Shell 指令碼匯出 CDL 網表指令碼
- shell 指令碼的除錯問題指令碼除錯
- MySQL中的自增列MySql
- 通過shell指令碼防止埠掃描指令碼
- 通過shell指令碼檢視鎖資訊指令碼
- 通過shell指令碼監控oracle session指令碼OracleSession
- [ Shell ] 通過 Shell 指令碼匯出 GDSII/OASIS 檔案指令碼
- 如何通過簡單的shell指令碼操作MongoDB指令碼MongoDB
- 通過shell指令碼得到資料字典的資訊指令碼
- 自動化指令碼安裝mysql shell指令碼範例指令碼MySql
- 透過shell指令碼抓取awr報告中的問題sql指令碼SQL
- 案例:通過shell指令碼實現mysql資料備份與清理指令碼MySql
- 通過shell指令碼 批量新增使用者指令碼
- 通過shell指令碼新增備庫日誌指令碼
- 通過shell指令碼來統計段大小指令碼
- 如何解決自增列賦值的問題賦值
- 通過shell指令碼得到資料庫的基本資訊(一)指令碼資料庫
- 通過shell指令碼批量驗證dataguard的有效性指令碼
- 通過shell指令碼生成查詢表資料的sql指令碼SQL
- 70個經典的 Shell 指令碼面試問題指令碼面試
- shell指令碼自動清理超過指定大小的檔案指令碼
- MySQL自增列的重複值問題(r12筆記第25天)MySql筆記
- 【Linux】通過shell指令碼對mysql的增刪改查以及my.cnf的配置Linux指令碼MySql
- 通過shell指令碼監控sql執行頻率指令碼SQL
- 通過shell指令碼定位效能sql和生成報告指令碼SQL
- ADAMS 指令碼模擬指令碼
- 通過shell指令碼生成資料統計資訊的報表指令碼