在kingshard開源以後,有用戶屢次提到能不能在kingshard中加入SQL黑名單機制,讓kingshard可以根據特定的規則來攔截在黑名單中的SQL。有幾個比較典型的應用場景:前端
DBA定義一些比較危險的SQL,放在SQL黑名單文件中。能夠避免前端應用發過來的SQL對數據庫形成危害。這種SQL有多是開發者粗心編寫的,也有多是被SQL注入生成的SQL。例如:delete from mytable
,這種不帶where條件的SQL,會把整個表刪除。mysql
在kingshard項目上線後,經過log發現存在大量某條SQL給DB形成了很大的壓力。這時候能夠動態地將這條SQL加入黑名單,阻止該SQL的執行,從而使數據庫壓力下降。例如:select count(*) from mytable where xxxx
,這類SQL若是沒有優化得當,是很容易形成系統的IO太高的。正則表達式
在kingshard若是想使用SQL黑名單功能,只須要在配置中添加:sql
blacklist_sql_file: /Users/flike/blacklist
而後咱們在blacklist定義SQL黑名單,這樣kingshard在轉發的時候,就會阻止黑名單中SQL的轉發。數據庫
黑名單SQL以正則表達式的形式定義。對於SQL中的值用?
或?+
代替。爲保證黑名單有效,最好手動驗證一下,kingshard是否正確攔截了黑名單中的SQL。定義規則(上一條是原SQL,對應的下一條是黑名單形式的SQL)能夠參考下列例子:性能
SELECT c FROM t WHERE id=1 select c from t where id=? SELECT * FROM prices.rt_5min where id=1 select * from prices.rt_5min where id=? select null, 5.001, 5001. from foo select ?, ?, ? from foo select 'hello', '\nhello\n', \"hello\", '\\'' from foo select ?, ?, ?, ? from foo select 'hello'\n select ? select * from t where (base.nid IN ('1412', '1410', '1411')) select * from t where (base.nid in(?+)) select * from foo where a in (5) and b in (5, 8,9 ,9 , 10) select * from foo where a in(?+) and b in(?+) select * from foo limit 5 select * from foo limit ? select * from foo limit 5, 10 select * from foo limit ?, ? select * from foo limit 5 offset 10 select * from foo limit ? offset ? INSERT INTO t (ts) VALUES (NOW()) insert into t (ts) values(?+) insert into foo(a, b, c) values(2, 4, 5) insert into foo(a, b, c) values(?+) CALL foo(1, 2, 3) call foo LOAD DATA INFILE '/tmp/foo.txt' INTO db.tbl load data infile ? into db.tbl administrator command: Init DB administrator command: Init DB use `foo` use ?
在blacklist加入以下SQL:測試
select count(*) from test_shard_hash where id > ? select count(*) from test_shard_range SELECT * FROM WORLD DELETE FROM WORLD
鏈接kingshard,執行SQL顯示以下:優化
mysql> select * from world; ERROR 1105 (HY000): sql in blacklist. mysql> select * from world where a > 0; +------+------+ | a | b | +------+------+ | 10 | 23 | | 45 | 565 | +------+------+ 2 rows in set (0.00 sec) mysql> delete from world; ERROR 1105 (HY000): sql in blacklist. mysql> delete from world where a =10; Query OK, 1 row affected (0.00 sec) #注意在SQL黑名單中該SQL是大於後面有個空格,必需要嚴格匹配,不然#kingshard不會認爲是黑名單SQL mysql> select count(*) from test_shard_hash where id >1; +----------+ | count(*) | +----------+ | 24 | +----------+ 1 row in set (0.02 sec) mysql> select count(*) from test_shard_hash where id > 1; ERROR 1105 (HY000): sql in blacklist.
用sysbench測試了一下存在blacklist時kingshad的性能,發現性能並無明顯降低,因此能夠放心使用該功能。code