作者:楊濤濤
資深資料庫專家,專研 MySQL 十餘年。擅長 MySQL、PostgreSQL、MongoDB 等開源資料庫相關的備份恢復、SQL 調優、監控運維、高可用架構設計等。目前任職於愛可生,為各大運營商及銀行金融企業提供 MySQL 相關技術支援、MySQL 相關課程培訓等工作。
本文來源:原創投稿
*愛可生開源社群出品,原創內容未經授權不得隨意使用,轉載請聯絡小編並註明來源。
以往 MySQL 想要限制單個連線的記憶體,只能小心翼翼的設定各種 SESSION 變數,防止執行某些 SQL 導致單個連線的記憶體溢位! 能不能直接在 MySQL 服務端包含這樣一個功能,簡化資料庫的運維呢?
MySQL 最新版本 8.0.28 在前幾天釋出,其中有一項新功能就是在資料庫側來限制單個連線記憶體,著實有點小興奮。
MySQL 8.0.28 與此功能有關的幾個新引數如下:
- connection_memory_limit:核心引數!用來限制單使用者連線的記憶體上限值,預設為 BIGINT UNSIGNED 的最大值:18446744073709551615 位元組,最小為2MB。
- global_connection_memory_tracking:設定是否開啟對連線記憶體功能的追蹤,並且把連線記憶體資料存入狀態變數 Global_connection_memory 。為了效能考慮,預設關閉。
- connection_memory_chunk_size: 在引數 global_connection_memory_tracking 開啟的場景下,設定狀態變數 Global_connection_memory 的更新頻率。
接下來我們體驗下這個新特性。
管理員端設定記憶體限制引數上限:為了儘快看到效果,設定為最小值。
localhost:(none)>set global connection_memory_limit=2097152;
Query OK, 0 rows affected (0.00 sec)
建立一個新使用者 tt1 ,並賦予基於庫 ytt 的只讀許可權。
localhost:(none)>create user tt1 identified by 'tt';
Query OK, 0 rows affected (0.03 sec)
localhost:(none)>grant select on ytt.* to tt1;
Query OK, 0 rows affected (0.02 sec)
建立一張表,插入一行記錄: 這裡使用 longtext 資料型別能讓查詢結果更快記憶體溢位。
localhost:ytt>create table t(id int primary key, r1 longtext);
Query OK, 0 rows affected (2.39 sec)
localhost:ytt>insert t values (1,lpad('mysql',6000000,'database'));
Query OK, 1 row affected (0.63 sec)
使用者 tt1 登入驗證:對欄位 r1 進行簡單 GROUP BY 檢索 ,報連線記憶體超出設定限制錯誤,連線關閉。
debian-ytt1:ytt>select count(r1) from t group by r1;
ERROR 4082 (HY000): Connection closed. Connection memory limit 2097152 bytes exceeded. Consumed 7094928 bytes.
不過這個新功能對管理員和內建使用者不生效。 用 ROOT 使用者重新登入 MySQL 執行剛才那條 SQL :
root@debian-ytt1:~# mysql -S /tmp/mysqld_3306.sock
...
localhost:(none)>use ytt
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
localhost:ytt>select count(r1) from t group by r1;
+-----------+
| count(r1) |
+-----------+
| 1 |
+-----------+
1 row in set (0.03 sec)