What's New In MySQL 8.0
由於8.0內有很多C++11特性。需要gcc4.8版本以上。Rhel6系列默認gcc是4.7。在安裝gcc6.1之後仍然檢查不過。
原因可能是6.1版本不一定高於4.7,暫不討論。鑒於升級gcc耗時較長,與測試目的不符。暫用官方rpm包安裝。以便達到快速測試目的。
以下新功能介紹中,跟日常工作強相關大都經過測試。時間有限,未能面面俱到,有興趣自行測試。
以下大部分來源自 https://dev.mysql.com/doc/refman/8.0/en/mysql-nutshell.html。其中部分以此引申出來。測試版本為MySQL8.0.11 GA版。
水平有限,有問題多多指教。qq 475982055
一 MySQL 8.0發行說明及特性
Ⅰ 安全以及賬戶管理方面
認證加密插件變更
除了sha256_password認證插件。可用一種新的caching_sha2_password認證插件。後者可以使用緩存解決連接時的延時問題。
它還支持更多的連接協議,並且不需要與基於RSA密鑰對的密碼交換功能的OpenSSL進行鏈接。
對比可以看出。MySQL8.0中默認新建用戶使用caching_sha2_password,而不是原生的加密策略。這樣客戶端使用原有方式連接就會出現問題。
Windows nivicat客戶端連接問題
Linux 客戶端下連接
這是由於兩邊默認密碼插件不匹配導致無法加解密的原因。有兩種方法解決。一種是服務端降級加密方式,一種是客戶端升級加密方式。
第一種方式以安全代價換便捷。第二種相反。我想服務端應該是有全局參數控制新建用戶使用什麽插件進行加密的。如下:
這樣一來客戶端就能常規方式連接。但是之前創建的用戶依然會報那樣的錯。解決方法是alter 語句修改。
註意的一點5.6的set password 的方式已經徹底被淘汰。且password函數已經被刪除。
默認配置啟動。初始化啟動後,使用生成的密碼登錄不能做任何事,但是可以set命令。
由於密碼強度之強,使得多數情況下的修改validate_password.policy
參數。(這點傷透了我的心,以前是下劃線“_”。有點面向對象的味道)
總結:也就是說加密方式改變導致帳號連接改變。亦可以通過默認恢復到先前方式。
新增角色特性
同Oracle一樣,用來將權限打包。再賦給擁有用戶。
詳見:http://dev.mysql.com/doc/refman/8.0/en/create-role.html
用戶密碼方面
MySQL以前有密碼強度策略,過期時間。現在還維護有關密碼歷史記錄的信息,從而限制重復使用以前的密碼(社會工程學)。
存在mysql.password_history表中。也就是說如果是從老版本升級到8.0.3版本之上。需要同時升級這些系統表(廢話)。
mysql.user 表中多出了幾個關於密碼重用的列。(相關表已確認,未測試功能。)
用戶權限方面
新增多個管理權限。
Ⅱ InnoDB增強
自增列方面
自增列方面。現在自增列計數器會在每次值修改時,將值寫到REDO LOG中,並且在CHECKPOINT時寫到存儲引擎私有的系統表中。
這就消除了以往重啟實例自增列不連續的問題(這也可能形成了一個新的競爭點(蓋國強會上提問InnoDB開發者))。
Btree索引方面
Btree索引被損壞。InnoDB會向REDO LOG中寫入一個損壞標誌。同時也會CHECKPOINT時將內存中損壞頁的數據記錄到存儲引擎私有的系統表中。
這也就促成了恢復時。兩邊一致的情形。索引不可用,並不會造成實例起不來。這很大程度上降低了之前使用innodb_force_recovery和innodb_fast_shutdown的必要。
提升了一致性。(對於一般DBA來說透明,知道有這麽回事就好)
NoSQl操作
InnoDB memcached插件支持多個get操作(在單個memcached查詢中獲取多個鍵/值對)
和範圍查詢。(個人認為這個挺牛逼,有點像NoSQL,不僅僅是NoSQL)。
需要安裝daemon_memcached插件,其中多了一個innodb_memcache schema,這個schema中有幾張表,其中一張containers用來與InnoDB表之間做映射,,
然後通過接口訪問Innodb表。然後會有一個11211的端口打開,用於建立連接。
好處是通過減少客戶端和服務器之間的通信流量,在單個memcached查詢中獲取多個鍵/值對的功能可以提高讀取性能。
對於InnoDB來說,也意味著更少的事務和開放式表操作。
死鎖檢測
新的動態配置選項innodb_deadlock_detect可用於禁用死鎖檢測,默認打開。 在高並發系統上,當大量線程等待相同的鎖時,死鎖檢測會導致速度下降。 有時,在死鎖發生時,
禁用死鎖檢測並依賴innodb_lock_wait_timeout設置進行事務回滾可能更有效。記得之前版本遇到死鎖會自動回滾。以下截圖來自MySQL5.7,與8.0默認相同。
(也就是說即便MySQL5.7也是有死鎖檢測的,並且自動回滾權重較小的事務(套死除外))。
嘗試更改innodb_deadlock_detect參數為OFF。則遇到死鎖時兩個工作線程都會被堵塞。直到innodb_lock_wait_timeout設定的鎖超時。
新的INFORMATION_SCHEMA.INNODB_CACHED_INDEXES
表保存了Innodb索引緩存在Innodb buffer pool中的頁數。
現在,所有InnoDB臨時表都將在共享臨時表空間ibtmp1中創建。
加密特性
支持REDO和UNDO表空間加密。
共享鎖方面
InnoDB在 SELECT ... FOR SHARE
和 SELECT ... FOR UPDATE
鎖定讀語句上
支持不等待( NOWAIT
)和跳過鎖(SKIP LOCKED)的選項。也就是說以往加了共享鎖之後必須手動釋放。
這裏如果沒有鎖就返回結果,如果有就報下面錯誤。
如果是用有鎖就跳過,則無數據。
根據場景使用。反正都是秒回。降低了排查數據庫超時的可能。
與MySQL 5.7使用上的不同。首先初始化的日誌言簡意賅(前三條)
重啟日誌如下:
InnoDB使用自己的MySQL服務層的數據字典,不再保留自己的數據字典。有利於事務的原子性。
MySQL系統表和數據字典表現在創建在MySQL數據目錄中名為mysql.ibd的單個InnoDB表空間文件中。
以前,這些表是在mysql數據庫目錄中的各個InnoDB表空間文件中創建的。
數據字典
現在將表對象信息等數據字典存在內部事務表中。而不是之前的.frm 文件。
mysql schema多出的表:(相比MySQL5.7)
component
default_roles
global_grants
password_history
role_edges
移除的表
Proc
ndb_binlog_index
event
由於存儲引擎層不再保留自己的數據字典。所以表的.frm文件也不存在了。
原子性DDL
聯合上述改變的數據字典更新。實現了DDL的原子性。以前版本中,不具備。
Ⅲ UNDO表空間的改變
(基本上不需要DBA配置關於UNDO表空間的參數了)
在線修改UNDO表空間數量
UNDO表空間數量可以在線修改。或者在實例重啟時使用原本只能初始化之前設定的innodb_undo_tablespaces
參數。
默認值更改
innodb_undo_log_truncate
默認被打開。
innodb_undo_tablespaces
表空間數量默認由0變為2.並且被設置為0已經不被允許。
UNDO默認名有UNDONNN變成UNDO_NNN。
參數改變
innodb_rollback_segments
配置選項定義每個UNDO表空間的回滾段數量。以前,這是一個針對MySQL實例的一個全局設定,單個寫。
這次的改變是,事務寫撤銷日誌時可以並發寫入。innodb_undo_logs
被移除了。該參數代替。
Innodb_available_undo_logs狀態變量被移除。要查看可用回滾段可用SHOW VARIABLES LIKE ‘innodb_rollback_segments‘;
Ⅳ BUFFER POOL的改變
參數默認值改變
innodb_max_dirty_pages_pct_lwm
從0變為10
innodb_max_dirty_pages_pct
從75到90.
控制INNODB BUFFER POOL預寫,刷盤動作參數改變。我想應該是這些年來硬件的提升。
INNODB自增長鎖模式變成2。基於語句對此很敏感,很顯然這是全面基於行的象征。
支持使用 ALTER TABLESPACE ... RENAME TO
語句為通用表空間改名。
自動內存管理
新配置選項innodb_dedicated_server能通過服務器內存總量控制innodb_buffer_pool_size
,
innodb_log_file_size
,
innodb_flush_method
大小和方式。詳見
默認。
打開該參數過後
INFORMATION_SCHEMA.INNODB_TABLESPACES_BRIEF
記錄表空間信息。
當系統不在線時,可以移除或者轉存系統表空間到其他機器上。這對備份恢復又開辟一條路。必須是停機狀態有點差強人意。
提取表空間
SDI(序列化字典信息)存在於除臨時表空間和撤消表空間文件之外的所有InnoDB表空間文件中。 SDI數據的存在提供元數據冗余。
如果數據字典變得不可用,字典對象元數據可能從表空間文件中提取。 使用ibd2sdi工具執行SDI提取。
如下:其中SDI數據以JSON格式存儲。這個工具,在線或者離線都可以使用。回頭看看如何將這個json數據導入(MySQL高版本已經支持JSON)。
Ⅴ REDO方面優化
並行寫入
1、 用戶線程現在可以並發寫入日誌緩沖區,以前是串行寫入。
特性添加
1、 用戶線程現在可以按照relaxed的順序將臟頁添加到flush列表中。
2、 現在專用的日誌線程負責將日誌緩沖區寫入系統緩沖區,將系統緩沖區刷新到磁盤,將寫入和刷新的重做通知用戶線程,維持放寬的清空列表順序所需的延遲,
並寫檢查點。以前就是read,write進程負責後臺讀寫。現在有點想Oracle的DBWR進程。
一些系統變量增加了。控制刷新REDO的CPU等待方式。
innodb_log_wait_for_flush_spin_hwm
innodb_log_spin_cpu_abs_lwm
innodb_log_spin_cpu_pct_hwm
動態修改log buffer
3、 innodb_log_buffer_size配置選項現在是動態的。
Ⅵ 其他關鍵特性
資源管理
MySQL8.0有了資源組(詳情點擊鏈接)的概念。也就是說可以創建並管理一個資源組。
將工作線程分配給特定的組。以便DBA限制,調配資源。目前只針對CPU。
INFORMATION_SCHEMA.RESOURCE_GROUPS
表顯示有關資源定義。Performance
Schema
threads
表顯示了每個線程的資源組分配。
有SQL接口支持資源組管理。這些操作不會被記錄到binlog中,也就是說不會被復制。
字符集
官方建議用utf8mb4代替utf8(utf8現在是utf8mb3的別名)。默認也是utf8mb4
JSON 增強
鑒於沒見到有用,不提及了。
優化器增強
1、 支持不可見索引。優化器不會使用不可用索引。索引默認是可見的。這個在索引優化的時候非常有用。不需要刪除一個索引來增加系統負擔。
2、 MySQL現在支持降序索引:索引定義中的DESC不再被忽略,會導致鍵值以降序存儲。 以前,索引可能會以相反順序掃描,但性能會受到影響。
可以按照順序掃描降序索引,這是更高效的。 降序索引還使得優化器可以在最有效的掃描順序混合某些列的升序和其他列的降序時使用多列索引。
通用表表達式
也就是說可以將很多表的不同列取出來作為新表,然後在做關聯聯合等等操作。個人認為這個對編寫含有大量子查詢的SQL有很大幫助,以及行轉列。
窗口函數
支持大量窗口函數。
類似以下數據。嘗試窗口函數的特性。Oracle有這些特性叫做分析函數等。
聚合函數的窗口函數
AVG()
BIT_AND()
BIT_OR()
BIT_XOR()
COUNT()
MAX()
MIN()
STDDEV_POP(), STDDEV(), STD()
STDDEV_SAMP()
SUM()
VAR_POP(), VARIANCE()
VAR_SAMP()
示例:如果每列包含總利潤,且包含當前行所在國家利潤和。如下結果
如果利用傳統SQL實現.如下,得寫一堆表關聯、聚合。
SELECT t1. YEAR,t1.country,t1.product,t1.profit,t2.total_profit,t3.country_profit FROM ( SELECT YEAR,country,product,profit FROM sales ) t1 LEFT JOIN ( SELECT sum(profit) AS total_profit FROM sales ) t2 ON 1 = 1 LEFT JOIN ( SELECT country,sum(profit) AS country_profit FROM sales GROUP BY country ) t3 ON t1.country = t3.country ORDER BY country,YEAR,product,profit; |
窗口函數實現:
SELECT year, country, product, profit, SUM(profit) OVER() AS total_profit, SUM(profit) OVER(PARTITION BY country) AS country_profit FROM sales ORDER BY country, year, product, profit; |
非聚合函數的窗口函數
CUME_DIST()
DENSE_RANK()
FIRST_VALUE()
LAG()
LAST_VALUE()
LEAD()
NTH_VALUE()
NTILE()
PERCENT_RANK()
RANK()
ROW_NUMBER()
示例:
還有一種比較常見的操作。上述表中,同一個國家的利潤排行。
如下所示:
常規實現需要將每個城市的利潤排序,在union 到一起。過於繁瑣。
窗口函數實現
SELECT YEAR,country,product,profit, ROW_NUMBER () OVER ( PARTITION BY country ORDER BY profit DESC ) AS row_num2 FROM sales; |
正則表達式支持
之前MySQL使用Henry Spencer正則表達式庫來支持正則表達式運算符(REGEXP,RLIKE) ,現在支持強大的正則表達式.
如:函數REGEXP_INSTR,REGEXP_REPLACE和REGEXP_SUBSTR函數可用於查找匹配位置並分別執行子字符串替換和提取。
日誌記錄
除了傳統錯誤日誌外。另外,還有一個可加載的JSON日誌記錄器。
要控制啟用哪些日誌組件,使用 log_error_services
系統變量。更多信息參見錯誤日誌。
備份鎖
一種新的備份鎖允許在線備份期間的DML,同時防止可能導致快照不一致的操作。 新備份鎖由LOCK INSTANCE FOR BACKUP和UNLOCK INSTANCE語法支持。
SET命令增強
類似Oracle,可用改變當前且用於下次重啟生效的SET PERSIST,以及PERSIST_ONLY(更改僅僅應用下次重啟。)不同的是,不像Oracle 記錄到spfile參數文件中。(此特性已經測試)
命令行部分補全功能
比較爽的是,命令支持表補全功能。待補的對象不是所在Schema下的表。而是Schema所對應的
二 MySQL 8.0中棄用的
1、validate_password插件已被重新實現以使用服務器組件基礎結構。
2、 ALTER
TABLESPACE
和 DROP
TABLESPACE
ENGINE
子句被棄用。
3、JSON_MERGE
函數在8.0.3中被棄用,使用 JSON_MERGE_PRESERVE()
代替.
三 MySQL 8.0中移除的
1、以下information Schema中的視圖被改名
Old Name |
New Name |
INNODB_SYS_COLUMNS |
INNODB_COLUMNS |
INNODB_SYS_DATAFILES |
INNODB_DATAFILES |
INNODB_SYS_FIELDS |
INNODB_FIELDS |
INNODB_SYS_FOREIGN |
INNODB_FOREIGN |
INNODB_SYS_FOREIGN_COLS |
INNODB_FOREIGN_COLS |
INNODB_SYS_INDEXES |
INNODB_INDEXES |
INNODB_SYS_TABLES |
INNODB_TABLES |
INNODB_SYS_TABLESPACES |
INNODB_TABLESPACES |
INNODB_SYS_TABLESTATS |
INNODB_TABLESTATS |
INNODB_SYS_VIRTUAL |
INNODB_VIRTUAL |
2
、不能使用grant 語句創建用戶了。只能賦權。Identified
子句移除。
3
、transaction_isolation 和
transaction_read_only
用來替代
tx_isolation
和tx_read_only
4、因為沒有.frm文件了,sync_frm系統變量移除了。 ignore_db_dirs也被移除。
5、have_query_cache
仍然保持棄用狀態, SQL_CACHE和SQL_NO_CACHE子句被棄用,且不起作用。這些在將來版本會被刪除。
6
、log_warnings被移除了,log_error_verbosity代替
7
、加密相關的函數
ENCODE()
和
DECODE()
以及
ENCRYPT()
等都被移除了。
8
、存儲過程的ANALYSE() 語法被移除。
9
、INFORMATION_SCHEMA.
INNODB_LOCKS
和INNODB_LOCK_WAITS表被移除。使用 Performance Schema.
data_locks
和data_lock_waits 的表代替。
10
、InnoDB文件格式相關配置選項已經不存在了。它們是MySQL5.1的產物,現在5.1的產品時代已經終結。
11
、innodb_support_xa系統變量被移除,MySQL總是支持分布式事務。
What's New In MySQL 8.0