天天看點

MySQL 5.7版本新特性連載(四)

本文将和大家一起分享下5.7的新特性,不過我們要先從即将被删除的特性以及建議不再使用的特性說起。根據這些情況,我們在新版本及以後的版本中,應該不再使用,避免未來産生相容性問題。

本文是基于MySQL-5.7.7-rc版本,未來可能 還會發生更多變化。

1、SQL MODE變化

a. 預設啟用 STRICT_TRANS_TABLES 模式;

b. 對 ONLY_FULL_GROUP_BY 模式實作了更複雜的特性支援,并且也被預設啟用;

c. 其他被預設啟用的sql mode還有 NO_ENGINE_SUBSTITUTION;

【iMySQL建議】

對廣大MySQL使用者而言,以往不是那麼嚴格的模式還是很友善的,在5.7版本下可能會覺得略為不适,慢慢習慣吧。比如向一個20字元長度的VARCHAR列寫入30個字元,在以前會自動階段并給個提示告警,而在5.7版本下,則直接抛出錯誤了。個人認為這倒是一個好的做法,避免各種奇葩的寫法。

【新特性實踐】

-- 檢視預設的 sql_mode

[[email protected]]> select @@sql_mode;

+-----------------------------------------------------------------------------------+

| @@sql_mode |

| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |

-- 插入50個字元

[[email protected]]> insert into t_char select 0, repeat('x',50);

ERROR 1406 (22001): Data too long for column 'uname' at row 1

-- 修改本 session 的 sql_mode

[[email protected]]> set sql_mode = 'ONLY_FULL_GROUP_BY,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

Query OK, 0 rows affected (0.00 sec)

-- 去掉 STRICT_TRANS_TABLES 模式後

+---------------------------------------------------------------+

| ONLY_FULL_GROUP_BY,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |

Query OK, 1 row affected, 1 warning (0.00 sec)  -- 提示有告警資訊

Records: 1 Duplicates: 0 Warnings: 1

[[email protected]]> show warnings;

+---------+------+--------------------------------------------+

| Level | Code | Message |

| Warning | 1265 | Data truncated for column 'uname' at row 1 |

因為 uname 字段的長度為 40 個字元。

2、優化online操作,例如修改buffer pool、修改索引名(非主鍵)、修改REPLICATION FILTER、修改MATER而無需關閉SLAVE線程 等衆多特性。

可以線上修改buffer pool對DBA來說實在太友善了,執行個體運作過程中可以動态調整,避免事先配置設定不合理的情況,不過 innodb_buffer_pool_instances 不能修改,而且在 innodb_buffer_pool_instances 大于 1 時,也不能将 buffer pool 調整到 1GB 以内,需要稍加注意。

如果是加大buffer pool,其過程大緻是:

1、以innodb_buffer_pool_chunk_size為機關,配置設定新的記憶體pages;

2、擴充buffer pool的AHI(adaptive hash index)連結清單,将新配置設定的pages包含進來;

3、将新配置設定的pages添加到free list中;

如果是縮減buffer pool,其過程則大緻是:

1、重整buffer pool,準備回收pages;

2、以innodb_buffer_pool_chunk_size為機關,釋放删除這些pages(這個過程會有一點點耗時);

3、調整AHI連結清單,使用新的記憶體位址。

實際測試時,發現線上修改 buffer poo 的代價并不大,SQL指令送出完畢後都是瞬間完成,而背景程序的耗時也并不太久。在一個并發128線程跑tpcc壓測的環境中,将 buffer pool 從32G擴充到48G,背景線程耗時 3秒,而從 48G 縮減回 32G 則耗時 18秒,期間壓測的事務未發生任何鎖等待。

-- 示範1:從 1G 擴大到 16G

[[email protected]]> SET GLOBAL innodb_buffer_pool_size = 51539607552;

-- 看看日志記錄

09:21:19.460543Z 0 [Note] InnoDB: Resizing buffer pool from 1073741824 to 17179869184. (unit=134217728)

09:21:19.468069Z 0 [Note] InnoDB: disabled adaptive hash index.

09:21:20.760724Z 0 [Note] InnoDB: buffer pool 0 : 60 chunks (491511 blocks) were added.

09:21:21.922869Z 0 [Note] InnoDB: buffer pool 1 : 60 chunks (491520 blocks) were added.

09:21:21.935114Z 0 [Note] InnoDB: buffer pool 0 : hash tables were resized.

09:21:21.947264Z 0 [Note] InnoDB: buffer pool 1 : hash tables were resized.

09:21:22.203031Z 0 [Note] InnoDB: Resized hash tables at lock_sys, adaptive hash index, dictionary.

09:21:22.203062Z 0 [Note] InnoDB: Completed to resize buffer pool from 1073741824 to 17179869184.

09:21:22.203075Z 0 [Note] InnoDB: Re-enabled adaptive hash index.

-- 示範2:從 16G 縮減到 1G

[[email protected]]> SET GLOBAL innodb_buffer_pool_size = 1073741824;

09:22:55.591669Z 0 [Note] InnoDB: Resizing buffer pool from 17179869184 to 1073741824. (unit=134217728)

09:22:55.680836Z 0 [Note] InnoDB: disabled adaptive hash index.

09:22:55.680864Z 0 [Note] InnoDB: buffer pool 0 : start to withdraw the last 491511 blocks.

09:22:55.765778Z 0 [Note] InnoDB: buffer pool 0 : withdrew 489812 blocks from free list. Tried to relocate 1698 pages (491510/491511).

09:22:55.774492Z 0 [Note] InnoDB: buffer pool 0 : withdrew 0 blocks from free list. Tried to relocate 1 pages (491511/491511).

09:22:55.782745Z 0 [Note] InnoDB: buffer pool 0 : withdrawn target 491511 blocks.

09:22:55.782786Z 0 [Note] InnoDB: buffer pool 1 : start to withdraw the last 491520 blocks.

09:22:55.892068Z 0 [Note] InnoDB: buffer pool 1 : withdrew 489350 blocks from free list. Tried to relocate 2166 pages (491517/491520).

09:22:55.900743Z 0 [Note] InnoDB: buffer pool 1 : withdrew 0 blocks from free list. Tried to relocate 2 pages (491519/491520).

09:22:55.908257Z 0 [Note] InnoDB: buffer pool 1 : withdrew 0 blocks from free list. Tried to relocate 0 pages (491519/491520).

09:22:55.915778Z 0 [Note] InnoDB: buffer pool 1 : withdrew 0 blocks from free list. Tried to relocate 1 pages (491520/491520).

09:22:55.923836Z 0 [Note] InnoDB: buffer pool 1 : withdrawn target 491520 blocks.

09:22:56.149172Z 0 [Note] InnoDB: buffer pool 0 : 60 chunks (491511 blocks) were freed.

09:22:56.308997Z 0 [Note] InnoDB: buffer pool 1 : 60 chunks (491520 blocks) were freed.

09:22:56.316258Z 0 [Note] InnoDB: buffer pool 0 : hash tables were resized.

09:22:56.324027Z 0 [Note] InnoDB: buffer pool 1 : hash tables were resized.

09:22:56.393589Z 0 [Note] InnoDB: Resized hash tables at lock_sys, adaptive hash index, dictionary.

09:22:56.393616Z 0 [Note] InnoDB: Completed to resize buffer pool from 17179869184 to 1073741824.

09:22:56.393628Z 0 [Note] InnoDB: Re-enabled adaptive hash index.

再來看下線上修改非主鍵索引名,直接用 ALTER TABLE RENAME INDEX 文法即可。

例如下面的SQL文法:

[[email protected]]> ALTER TABLE orders RENAME INDEX idx1 TO idxxx1;

Query OK, 0 rows affected (0.11 sec)

Records: 0 Duplicates: 0 Warnings: 0

可以看到,幾乎瞬間完成,盡管我在執行這個SQL時正跑着64個并發tpcc壓測。