技術分享 | 如何優雅地在 Windows 上從 MySQL 5.6 升級到 5.7

做者:趙黎明
愛可生 MySQL DBA 團隊成員,Oracle 10g OCM,MySQL 5.7 OCP,擅長數據庫性能問題診斷、事務與鎖問題的分析等,負責處理客戶 MySQL 及我司自研 DMP 平臺平常運維中的問題,對開源數據庫相關技術很是感興趣。
本文來源:原創投稿
*愛可生開源社區出品,原創內容未經受權不得隨意使用,轉載請聯繫小編並註明來源。

本文關鍵字:升級、Windows、帳號管理

背景

最近有去某客戶那裏支持 MySQL 實例升級,他們的實例版本比較多,有 5.五、5.六、5.7,外加各類小版本,平臺也不少,有 Linux、Windows。對於 Unix/Linux 平臺的 MySQL 版本升級,你們可能再熟悉不過了,但對於 windows 平臺的,可能接觸地較少。因爲項目上有需求,本身也在 Windows 環境上測試了一把,有了些心得,想跟你們分享一些經驗,因而有了本文。這裏主要是針對比較常見的 5.6 到 5.7 的升級。html

限制

  • MySQL 官方提供了 2 種介質的升級方式:一種是 MySQL Installer 的方式(須要下載 MSI 可執行程序,進行圖形化安裝),另外一種則是 noinstall zip 包的方式(就是咱們熟悉的綠色軟件,解壓即用的那種,固然 MySQL 做爲數據庫軟件,也沒傻瓜到那種程度,仍是須要一些額外操做的),推薦使用第 2 種方式,系統侵入性小,方便快捷。
  • 連續大版本的升級(5.6 to 5.7)不能用 MySQL Installer,這種場景只支持 zip 方式。
  • 社區版和企業版之間,也不能用 MySQL Installer 升級,須要用 zip 方式。
  • 除了介質,升級的方法也有 2 種:一種是 IN-PLACE 方式(適用於數據量較大、小版本或連續版本的升級),另外一種是邏輯方式(適用於數據量小、跨越大版本的升級)。
  • 對於大數據庫,即使是採用 IN-PLACE 方式升級,也可能會花費較長時間,由於執行 mysql_upgrade 時,默認也會對業務表進行數據轉換和修復(這個問題在客戶那兒也遇到了,300G 左右的庫,有大量 MyISAM 表,最大的單表有 40G。修復過程實際上是經過建立臨時表進行重建,而他們的磁盤性能又很差,跑了好久都沒有結束,後來經過 -s 參數跳過對業務表的修復)。
  • 若是是 Milestone 版和 GA 版之間的升級,也只能經過邏輯方式進行。

環境準備

雖然是在講升級,這裏也稍微提一下 Windows 上安裝實例的方法。首先,準備一臺 Windows 主機(我這裏用的是 Windows 10),去官網下載好 5.6.x,5.7.x for Windows 的 zip 包,我選擇了社區版的 5.6.30 和 5.7.30(最新 GA)的包。 
解壓完的 zip包 是這樣的,有點像 Linux 上的二進制包:
1.png
2.pngmysql

安裝 5.6 環境

安裝很簡單,最小化配置只須要把 my-default 參數中示例的幾個參數前的註釋符號去掉,並配置上相應的值,就能夠啓動了,固然,若是是生產環境,確定會自定義一堆參數,此處略過。 redis

3.png

改完後以下,而後就能夠用這個參數文件去初始化實例了: sql

4.png

初始化實例後,再啓動實例,接着建立並配置 Windows 服務,之後就能夠經過啓停服務對 MySQL 實例進行管理。升級 5.6 至 5.7這裏不討論詳細的升級步驟,與安裝實例其實差很少,主要說一下升級時要注意的點(本次測試採用 IN-PLACE 方式)。數據庫

  • 首次安裝完 5.7(zip 方式)後,出於安全性考慮,須要設置 skip-grant-tables 進入實例,修改 root 密碼,刪除空帳號(先執行 flush privileges;)。
  • 服務的建立、刪除都要用管理員身份運行 cmd 後再執行執行,示例:mysqld install mysql5630 / mysqld remove mysql5630。
  • 若是啓動實例是用 mysqld --console 執行的,會在屏幕輸出實例啓動的一些 error 日誌,一旦退出這個窗口,實例就會終止(所以,建議僅在首次測試實例可否正常啓動時使用)。
  • 5.7 的 zip 包解壓後沒有 data 目錄和 my.ini 配置文件,能夠將 5.6 中的 data 目錄和 my.ini 拷貝過來(拷 data 前要停實例),若是原本就已經指定在 basedir 以外的地方,也能夠直接用,而後修改 5.7 配置文件的 datadir 與原來 5.6 的位置一致。
  • 若是 5.6 是 zip 安裝,5.7 也是 zip 安裝,而且 5.7 解壓到 5.6 的目錄以外,建議修改環境變量後先執行 mysql -V,檢查其是否被正確地配置了(官方推薦解壓到同一個目錄中,這樣能夠不用修改環境變量)。
  • 儘可能不要使用舊版的 my.cnf,而且用 mysqld --print-defaults 檢查默認參數。
  • 升級到 5.7 後,當執行 mysqld install mysql5730 時(添加 5.7 實例的服務),若是報找不到 dll 動態庫連接文件 MSVCR120.dll、MSVCP120.dll,則須要下載並安裝相應版本的的 Visual C++ 程序)。 
參考連接:
https://www.groovypost.com/ho...
https://answers.microsoft.com...

各個 dll 文件對應的 Visual C++ 版本: windows

5.png

安裝完之後,能夠查看 dll 動態庫連接文件與對應 Visual C++ 版本之間的關係: 安全

6.png

個人環境中要正常運行 5.7.30 實例,須要安裝 Visual C++ 20十二、Visual C++ 2013,以後就能夠正常建立服務。服務器

升級排錯案例

安裝完 5.7.30 實例後,建立並啓動 windows 服務: session

7.png

經過 SC 啓動服務後卻當即中止了:運維

8.png

用 NET 命令也沒法啓動,error 日誌也沒有輸出:

9.png

嘗試刪除服務再從新添加:

10.png

此時服務尚未被建立:

11.png

經過 SC 再次啓動後,服務有了,但仍然是已中止狀態:

12.png

再次刪除服務後直接啓動 mysqld,在登陸客戶端後發現了端倪,原來是用 5.6.30 的 mysqld 命令啓動了:

13.png

當即檢查 my.ini 參數,發現參數中果真是用了 5.6.30 的路徑:

14.png

中止進程,修改參數並從新啓動 5.7.30 進程和服務:

15.png

msyql5730 服務恢復正常,不會再自動中止了:

16.png

服務端(mysqld)和客戶端(mysql)進程也運行正常:

17.png

檢查數據庫(注意,此時仍然是沒有 sys 庫的,由於是把 5.6 的 data 目錄直接拿來啓動實例的):

18.png

執行 mysql_upgrade,重建系統庫:

19.png

至此,完成 5.6.30 to 5.7.30 的升級(是否是 so easy?)。 

20.png

要注意,執行完 mysql_upgrade 後須要重啓實例,不然會報如下錯誤:

21.png

重啓實例後,能夠正常使用了:

22.png

一個有趣的登錄測試

  • 配置了 3 個 root 帳號,來源分別爲 ::1,127.0.0.1',localhost。
  • 在帳號密碼都不輸入的狀況下,Windows 默認會用 ODBC@localhost 這個用戶鏈接。
  • 在加上 -uroot 後,會優先使用 root@'::1' 這個帳號來鏈接,用戶仍然使用的是 root@localhost。
  • 把 root@'::1' 帳號刪除後,會使用 root@localhost 的帳號鏈接。
  • 把 root@localhost 帳號也刪除後,默認不會使用 root@127.0.0.1 的帳號鏈接,除非指定了 -h127.0.0.1。
  • 在 Windows 中,不管是 ::一、localhost 仍是 127.0.0.1,哪怕是使用 -S 進行鏈接,也都是 TCP/IP 鏈接。
mysql> select user,host from mysql.user;
+---------------+-------------+
| user | host |
+---------------+-------------+
| root | 10.186.64.% |
| root | 127.0.0.1 |
| root | ::1 |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+---------------+-------------+
6 rows in set (0.00 sec)

mysql> exit
Bye
C:\Users\Administrator>mysql
ERROR 1045 (28000): Access denied for user 'ODBC'@'localhost' (using password: NO)

C:\Users\Administrator>mysql -uroot
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

C:\Users\Administrator>mysql -uroot -p
Enter password: ********
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.7.30-log MySQL Community Server (GPL)

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> select current_user(),user();
+----------------+----------------+
| current_user() | user() |
+----------------+----------------+
| root@::1 | root@localhost |
+----------------+----------------+
1 row in set (0.00 sec)

mysql> drop user root@'::1';
Query OK, 0 rows affected (0.06 sec)

mysql> exit
Bye
C:\Users\Administrator>mysql -uroot -p
Enter password: ********
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 5.7.30-log MySQL Community Server (GPL)

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> select current_user(),user();
+----------------+----------------+
| current_user() | user() |
+----------------+----------------+
| root@localhost | root@localhost |
+----------------+----------------+
1 row in set (0.02 sec)

mysql> drop user root@localhost;
Query OK, 0 rows affected (0.03 sec)

mysql> exit
Bye
C:\Users\Administrator>mysql -uroot -p
Enter password: ********
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

C:\Users\Administrator>mysql -uroot -p -h127.0.0.1
Enter password: ********
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 5.7.30-log MySQL Community Server (GPL)

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> select current_user(),user();
+----------------+----------------+
| current_user() | user() |
+----------------+----------------+
| root@127.0.0.1 | root@localhost |
+----------------+----------------+
1 row in set (0.00 sec)

mysql> \s
--------------
mysql Ver 14.14 Distrib 5.7.30, for Win64 (x86_64)

Connection id: 10
Current database:
Current user: root@localhost
SSL: Cipher in use is ECDHE-RSA-AES128-GCM-SHA256
Using delimiter: ;
Server version: 5.7.30-log MySQL Community Server (GPL)
Protocol version: 10
Connection: 127.0.0.1 via TCP/IP
Server characterset: latin1
Db characterset: latin1
Client characterset: gbk
Conn. characterset: gbk
TCP port: 3306
Uptime: 6 hours 41 min 40 sec

Threads: 1 Questions: 26 Slow queries: 0 Opens: 123 Flush tables: 1 Open tables: 116 Queries per second avg: 0.001
--------------

mysql> show variables like 'socket';
+-----------------------------------------+-------+
| Variable_name | Value |
+-----------------------------------------+-------+
| socket | MySQL |
+-----------------------------------------+-------+
3 rows in set, 1 warning (0.01 sec)

mysql> exit
Bye
C:\Users\Administrator>mysql -uroot -p -S MySQL

Enter password: ********
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 16
Server version: 5.7.30-log MySQL Community Server (GPL)

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> \s
--------------
mysql Ver 14.14 Distrib 5.7.30, for Win64 (x86_64)

Connection id: 16
Current database:
Current user: root@localhost
SSL: Cipher in use is ECDHE-RSA-AES128-GCM-SHA256
Using delimiter: ;
Server version: 5.7.30-log MySQL Community Server (GPL)
Protocol version: 10
Connection: localhost via TCP/IP
Server characterset: latin1
Db characterset: latin1
Client characterset: gbk
Conn. characterset: gbk
TCP port: 3306
Uptime: 7 hours 6 min 23 sec

Threads: 1 Questions: 63 Slow queries: 0 Opens: 137 Flush tables: 1 Open tables: 130 Queries per second avg: 0.002
--------------

升級步驟彙總

最後,再把升級的各個步驟羅列一遍:
1. 下載 5.7.30 的 zip 包並解壓到新的目錄。
2. 安裝 Visual C++ 2012/2013(或更多版本)。
3. 停應用,中止 5.6 實例(能夠經過停服務來操做,中止服務前建議記錄一下 GTID 或 binlog file 和 position 位置),刪除服務。
4. 備份一份 5.6 實例的 datadir,包括 binlog(整個目錄 copy 到別的目錄存放)。
5. 拷貝 5.6 實例的 datadir 和 my.ini 到 5.7 實例 basedir 目錄,調整並優化參數值(注意要確保路徑一致,確認已開啓 5.7 新特性相關參數,如加強半同步、MTS 等)。
6. 修改系統環境變量,把可執行路徑指向 5.7 實例的 basedir/bin。
7. 啓動 5.7 實例,建立服務並啓動。
8. 驗證服務端、客戶端版本是否正確。
9. 確認無誤後,執行 mysql_upgrade 升級數據字典(會升級系統庫:mysql,ps,sys,沒有會重建)。
10. 重啓實例。
11. 再次校驗 5.7 的參數,儘可能保持與 5.6 的兼容,尤爲要注意 sql_mode 的默認值對業務的影響。
12. 清理 5.6 實例的 basedir 和 datadir 目錄(可選)。
13. 若是是主從環境,還要考慮 slave_net_timeout 參數默認值改變帶來的影響(主庫 error 日誌中出現 「ER_RPL_ZOMBIE_ENCOUNTERED」 的報錯)。在 5.7.7 之前,該參數默認是 3600s,以後改成了 60s,須要從新執行 change master to 語句,而且顯式指定 master_heartbeat_period=xx,由於從 5.7.4 開始,只有執行 reset slave 才能將其重置爲默認值(slave_net_timeout 值的一半)。另外提一句,也是從 5.7.4 開始,執行 change master to 語句時,能夠不用先中止複製線程了。 

參考連接:
https://dev.mysql.com/doc/ref...
https://dev.mysql.com/doc/ref...
https://dev.mysql.com/doc/ref...

總結

本文主要闡述瞭如何優雅地經過 ZIP&IN-PLACE 方式在 Windows 服務器上將 MySQL 5.6 實例升級到 5.7。對 MySQL 官方提供的一些升級方式和相關限制作了說明。經過一個實際的升級案例來展現如何在升級過程當中排查錯誤。演示了一個關於帳號登錄的小測試,要注意區分帳號的來源部分、current_user(),user() 之間的差異,前者是 mysql.user 表中建立的帳號,後者是當前操做系統的登陸用戶。最後對整個升級步驟作了總結,羅列了一些升級時的注意點。

參考連接: 
https://dev.mysql.com/doc/ref...
https://dev.mysql.com/doc/ref...
相關文章
相關標籤/搜索