閱讀811 返回首頁    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;

  1. ALTER TABLE:

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

  1. 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

  2. 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 |
    +-------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+

  3. 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可以評估一段時間,某些索引沒有被使用過,就可以相對安全的進行刪除。

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

先invisible這個索引:

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

ALTER TABLE T DROP INDEX a;
在真正的刪除之前,如果出現異常,可以快速的回滾:

ALTER TABLE t ALTER INDEX a visible;
所以,通過index statistic 和 index invisible 功能,可以安全對索引進行在線刪除。

  1. 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 語法,減少一次網絡調用,在核心業務集群上,收益是非常可觀的。

  1. 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

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

最後更新:2017-07-19 11:32:31

  上一篇:go  簡單不簡單,如何開啟雲計算服務全新模式?
  下一篇:go  KDD論文解讀 | 想要雙11搶單快?靠這個技術提速9MS