閱讀470 返回首頁    go 阿裏雲 go 技術社區[雲棲]


AliSQL 20170716版本發布 Invisible Indexes 功能和 SELECT FROM UPDATE 語法

Abstract

在傳統的關係數據庫中,想要在堆表或者索引組織表中快速的檢索到目標數據,添加索引是一個常用的手段,但過多的索引不但增加空間的開銷,
還會帶來寫入性能的衰減,如何降低在線刪除索引的風險,Invisible Indexes 提供了一個風險可控的方法。

在麵臨一個常見的業務場景,比如更新某行記錄,然後查詢變更後的記錄內容的時候,通常都是UPDATE + SELECT 兩條語句來完成,
AliSQL 擴展了語法,提供SELECT...FROM UPDATE語句,在完成update變更的同時,返回整行記錄內容,減少一次網絡調用。

AliSQL REPO: https://github.com/alibaba/AliSQL
AliSQL Release Notes: https://github.com/alibaba/AliSQL/wiki/Changes-in-AliSQL-5.6.32-(2017-07-16)

1. Invisible Indexes

概要

AliSQL 為 index 增加了兩個新的屬性,visible/invisible,保存在FRM文件中,這兩個屬性決定了這個索引是否能夠
被優化器使用,索引默認是visible,當變更為invisible的時候,無論是否使用了force index hint,這個索引不再會被優化器使用。
在引擎層麵,這個索引屬性是透明的,即引擎會繼續維護索引記錄變更。
注意區分disabled index屬性。

語法和使用方法

新增的語法例如:

1. CREATE INDEX:

CREATE TABLE t ( a INT, b INT );
CREATE INDEX a_invisible ON t(a) INVISIBLE;
CREATE INDEX b_visible ON t(b) VISIBLE;

2. ALTER TABLE:

ALTER TABLE t ALTER INDEX a INVISIBLE;
ALTER TABLE t1 ALTER INDEX b VISIBLE;


3. SHOW CREATE TABLE:
CREATE TABLE `t` (
  `a` int(11) DEFAULT NULL,
  `b` int(11) DEFAULT NULL,
  KEY `a_invisible` (`a`) /*!50616 INVISIBLE */,
  KEY `b_visible` (`b`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1



4. SHOW INDEXES;
mysql> SHOW INDEXES FROM t;
+-------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+
| Table | Non_unique | Key_name    | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible |
+-------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+
| t     |          1 | a_invisible |            1 | a           | A         |           0 |     NULL | NULL   | YES  | BTREE      |         |               | NO      |
| t     |          1 | b_visible   |            1 | b           | A         |           0 |     NULL | NULL   | YES  | BTREE      |         |               | YES     |
+-------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+

5. mysql> SELECT * FROM information_schema.statistics WHERE is_visible='NO';
+---------------+--------------+------------+------------+--------------+-------------+--------------+-------------+-----------+-------------+----------+--------+----------+------------+---------+---------------+------------+
| TABLE_CATALOG | TABLE_SCHEMA | TABLE_NAME | NON_UNIQUE | INDEX_SCHEMA | INDEX_NAME  | SEQ_IN_INDEX | COLUMN_NAME | COLLATION | CARDINALITY | SUB_PART | PACKED | NULLABLE | INDEX_TYPE | COMMENT | INDEX_COMMENT | IS_VISIBLE |
+---------------+--------------+------------+------------+--------------+-------------+--------------+-------------+-----------+-------------+----------+--------+----------+------------+---------+---------------+------------+
| def           | test         | t          |          1 | test         | a_invisible |            1 | a           | A         |           0 |     NULL | NULL   | YES      | BTREE      |         |               | NO         |
+---------------+--------------+------------+------------+--------------+-------------+--------------+-------------+-----------+-------------+----------+--------+----------+------------+---------+---------------+------------+


場景使用

在DBA的日常運維中,為了加速SQL查詢響應,隨著業務的發展在表中積累了比較多的索引,而隨著業務的變更,有部分索引可能已經不再需要,需要做刪除處理。
在線刪除索引,變成了一個風險極高的操作,如何降低刪除索引的風險,主要評估兩點:
1. 需要統計信息展示索引的使用情況
2. 當刪除索引後,出現異常,如何快速的回滾

針對這兩個點,AliSQL提供了較完善的方法進行評估:

1. 統計信息
AliSQL提供了一個內存統計表index_statistics,來統計每張表的索引使用統計信息,如下:

mysql> select * from t where b=2;
+------+------+
| a    | b    |
+------+------+
|    1 |    2 |
+------+------+
1 row in set (0.00 sec)

mysql> select * from information_schema.index_statistics;
+--------------+------------+------------+-----------+
| TABLE_SCHEMA | TABLE_NAME | INDEX_NAME | ROWS_READ |
+--------------+------------+------------+-----------+
| test         | t          | b_visible  |         3 |
+--------------+------------+------------+-----------+
1 row in set (0.00 sec)

這表明 t 表中的 b_visible 索引被拿來檢索了3條記錄, 而t表中的其他index沒有被使用過,基於這樣的統計信息,
DBA可以評估一段時間,某些索引沒有被使用過,就可以相對安全的進行刪除。

2. 回滾
當對index進行刪除的時候, 可以分兩步操作:

invisible這個索引:

ALTER TABLE t ALTER INDEX a invisible;

完成後,這個索引就不會再被optimizer使用,觀察一段使用,確認沒有影響後,再進行安全刪除:

ALTER TABLE T DROP INDEX a;

在真正的刪除之前,如果出現異常,可以快速的回滾:

ALTER TABLE t ALTER INDEX a visible;

所以,通過index statisticindex invisible 功能,可以安全對索引進行在線刪除。

2. SELECT FROM UPDATE

概要

為了優化在業務中使用 UPDATE + SELECT 兩次調用的開銷,AliSQL提供了 SELECT...FROM UPDATE 語法,
在一次SQL請求中,完成UPDATE變更和行記錄返回。

語法和使用

CREATE TABLE t(a int, b int);
INSERT INTO t values(1, 1);
SELECT * FROM UPDATE t set a=a+1 where a=1;

mysql> SELECT * FROM UPDATE t set a=a+1 where a=1;
+------+------+
| a    | b    |
+------+------+
|    2 |    1 |
+------+------+
1 row in set (0.00 sec)

通過 SELECT...FROM UPDATE 語法,減少一次網絡調用,在核心業務集群上,收益是非常可觀的。

3. InnoDB Crash

概要

InnoDB在進行表結構變更的時候,如果是online操作,並且變更過程中失敗,那麼對於數據字典的dirty清理會延遲清理,但master thread在淘汰長時間未使用的Dictionary Object 的時候,因為對象未清理幹淨,導致實例crash。
詳細的bug複現過程和修複方法,可以參考:https://mysql.taobao.org/monthly/2017/06/05/

MySQL官方的BUG跟蹤:https://bugs.mysql.com/bug.php?id=86607
MariaDB的BUG跟蹤:https://jira.mariadb.org/browse/MDEV-13051

4. Semisync優化

概要

Semisync的 ACK receiver 線程使用了 select() 係統庫調用來監聽slave線程,但由於 select() 方法存在多種限製,
所以,使用 poll() 替換原來的監聽方法。

最後更新:2017-07-18 20:34:32

  上一篇:go  物聯網雲計算成本核算 小廠的出路在哪裏
  下一篇:go  IDEA使用筆記