kingshard SQL黑名單功能介紹

flike發表於2019-02-16

kingshard SQL黑名單功能介紹

1. 應用場景介紹

在kingshard開源之後,有使用者多次提到能不能在kingshard中加入SQL黑名單機制,讓kingshard能夠根據特定的規則來攔截在黑名單中的SQL。有幾個比較典型的應用場景:

  1. DBA定義一些比較危險的SQL,放在SQL黑名單檔案中。可以避免前端應用發過來的SQL對資料庫造成危害。這種SQL有可能是開發者粗心編寫的,也有可能是被SQL隱碼攻擊生成的SQL。例如:delete from mytable,這種不帶where條件的SQL,會把整個表刪除。

  2. 在kingshard專案上線後,通過log發現存在大量某條SQL給DB造成了很大的壓力。這時候可以動態地將這條SQL加入黑名單,阻止該SQL的執行,從而使資料庫壓力降低。例如:select count(*) from mytable where xxxx,這類SQL如果沒有優化得當,是很容易造成系統的IO過高的。

2. 功能介紹

在kingshard如果想使用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`, `
hello
`, "hello", `\`` from foo
select ?, ?, ?, ? from foo

select `hello`

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 ?

3.功能演示

在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的效能,發現效能並沒有明顯下降,所以可以放心使用該功能。

相關文章