1. 程式人生 > >CentOS8.1操作系下使用通用二進位制包安裝MySQL8.0(實踐整理自MySQL官方)

CentOS8.1操作系下使用通用二進位制包安裝MySQL8.0(實踐整理自MySQL官方)

  寫在前的的話: 在IT技術日新月異的今天,老司機也可能在看似熟悉的道路上翻車,甚至是大型翻車現場!自己一個人開車過去翻個車不可怕,可怕的是帶著整個團隊甚至是整個公司一起翻車山崖下,解決辦法就是:新出現的道路自己先過一遍,留好坑位標記,將來帶隊過去時不再翻車!!!

 

  最近剛好在進行許可權系統的微服務化改造,要重新搭一套開發伺服器環境。今天搭的是MySQL資料庫伺服器,MySQL 8.0出來也有些年月了,現在(2020)大多數公司還沒在生產上用上,於是乎就想嚐個鮮,選擇了在CentOS8.1上進行MySQL8.0伺服器的搭建。當前來說CentOS8.1也算比較新了!

 

  老樣子,先裝一個全新的CentOS8.1虛擬機器,選擇裝配基本的Server軟體包,網路模式選擇【橋接模式(自動)】(主要為了讓宿主機和虛擬機器的網路處於等級),IP地址相關資訊切記選擇手工配置,不能用DHCP進行動態分配(有DNS伺服器輔助除外),為什麼呢?因為你是在配伺服器,IP地址要固定下來,不然每次啟動後的IP都不同,那就很尷尬了!

 

  伺服器作業系統準備好後該去下載MySQL8.0了,去哪裡下呢?當然是MySQL8.0社群版官網!可是跑到網官一看,估計有些同學就一臉懵逼,純英文的不說,安裝包還各樣種樣的!怎麼選呢?

  首先要選定作業系統平臺,我這邊是CentOS8.1 x86_64位架構,那我要選Linux版本的,最好是CentOS專用的!結果找了一圈暫時還沒有CentOS專用的版本(RedHat專用版本到是有,其實我們知道CentOS是就源自RedHat)...為了保險起見,我們選Linux通用版(Linux-Generic),結果出來的列表也不少!這麼多都是些啥,見圖示解吧:

 

  我選擇【64位通用二進位制最小安裝壓縮包(不含除錯元件及調式符號)】,理由:

  1. 我的目標作業系統是64位的CentOS;
  2. 我不需要做MySQL的除錯;
  3. CentOS8.1上帶有專用的解壓安裝工具tar;
  4. 小包從官網下載和上傳到伺服器都快(MySQL資料庫功能也完整,別看小了那麼多!);

  點選Download後出現的介面中會建議你登入你的Oracle Web賬號,不用登入(當然你有賬號也可以登入),直接點下面的一小行字——“No thanks,just start my download.”

 

  將目標包(mysql-8.0.20-linux-x86_64-minimal.tar.xz)下載好後,使用SecureCRT上傳到伺服器 /opt 目錄下!(Linux眾多目錄的作用)

  接下來開始正式安裝MySQL8.0,記住我們的前提是:全新的、乾淨的CentOS8.1作業系統,之前沒有裝過MySQL的!如果之前裝過MySQL是要先把相關目錄和配置檔案刪除乾淨才能再裝的!謹記!謹記!謹記!

  第一步:使用yum包管理器檢查並安裝非同步IO依賴包 libaio ,如果沒裝這個包,資料目錄初始化和後續伺服器的啟動都將失敗,如果檢查發現沒裝,要將它裝上:

# yum search libaio 
# yum -y install libaio 

  第二步:由於CentOS是源自RedHat的,而RedHat系列的作業系統中沒有MySQL通用二進位制安裝包(不管有沒有壓縮)中的MySQL客戶端(bin/mysql)元件所需要的 /lib64/libtinfo.so.5 檔案,為了解決這個問題,需要安裝一個含有該檔案的 ncurses-compat-libs 包(截圖是已經裝過一次的結果):

# yum -y install ncurses-compat-libs

  第三步:轉到 mysql-8.0.20-linux-x86_64-minimal.tar.xz 壓縮包存放目錄 /opt ,使用 tar 命令進行解壓(直接解壓到當前目錄):

# cd /opt
# tar -xvf mysql-8.0.20-linux-x86_64-minimal.tar.xz

  解壓得到一個新目錄:/opt/mysql-8.0.20-linux-x86_64-minimal ,該目錄即為MySQL的真實安裝目錄;

  第四步:建立用於執行MySQL的組和普通使用者(非作業系統使用者):

# groupadd mysql
# useradd -r -g mysql -s /bin/false mysql

  第五步:在使用者手動安裝軟體推薦安裝目錄 /usr/local 中建立MySQL的真實安裝目錄的軟連結目錄(軟連結目錄不能是已經存在的目錄,相當於Windows快捷方式):

# cd /usr/local
# ln -s /opt/mysql-8.0.20-linux-x86_64-minimal mysql

  第六步:在mysql軟連結目錄中建立匯入匯出操作安全目錄(該目錄用於使具有FILE許可權的使用者可以安全地執行匯入匯出操作):

# cd /usr/local/mysql
# mkdir mysql-files
# chown mysql:mysql mysql-files
# chmod 750 mysql-files

  (其實,第六步做完後就已經有辦法可以臨時點亮MySQL伺服器了,這裡不講,因為我們要配的是一個長期執行的MySQL資料庫伺服器)

  第七步:在mysql軟連結目錄下建立資料目錄:

# cd /usr/local/mysql
# mkdir data
# chown mysql:mysql data
# chmod 750 data

  第八步:建立MySQL服務啟動需要用到的靜態配置檔案(如果目錄下已經有了同名檔案,則需要換一個名字,之前沒裝過MySQL一般是不會有的!):

# cd /etc
# touch my.cnf
# chown root:root my.cnf
# chmod 644 my.cnf

  第九步:使用vi或vim開啟第八步建立的配置檔案 /etc/my.cnf ,加入MySQL服務的配置資訊

[mysqld]
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
port=3306
log-error=/usr/local/mysql/data/mysqldb.xgclassroom.err
user=mysql
secure_file_priv=/usr/local/mysql/mysql-files
local_infile=OFF

  注意:配置中log-error的值一般中根據你安裝作業系統時設定的Host名稱相關,大家的不一樣,當然你也可以直接指定新名字!

  另外,如果要InnoDB的相關配置項,那麼只能在資料目錄初始化(第十步)之前在my.cnf中進行配置,主要有 innodb_data_home_dir,innodb_data_file_path,,innodb_log_file_size,innodb_log_group_home_dir 和 innodb_page_size 這幾項,未配置的情況下,它們都使用預設值。

  第十步:初始化第七步建立的資料目錄(因為要用到第八和第九步建立的配置檔案)

# cd /usr/local/mysql
# bin/mysqld --defaults-file=/etc/my.cnf --initialize

  注意:資料目錄初始化成功後,會在第九步所設定的log-error日誌檔案(我的是 /usr/local/mysql/data/mysqldb.xgclassroom.err)中生成 root@localhost 的初始密碼(賬號冒號後面的QdbB=9e!lT6=就是,要記住這個初始密碼,後面登入root賬號是要它來修改初始密碼),類似下面的資訊(可以使用cat命令檢視):

...省略...
A temporary password is generated for root@localhost: yi5w%J*hws6E
...省略...

  現在我們還缺了最最最重要的一項配置——讓MySQL服務隨作業系統的啟動自動啟動!繼續配置ing!

  在Linux系統中目前系統服務主要以 systemd 服務單元的形式存在(類似windows平臺的services.msc下管理的各個服務),Linux系統下一切皆檔案,systemd 服務單元也是由一個個systemd 服務單元配置檔案組成,systemd 服務單元配置檔案 = systemd 服務單元!配置檔名就是服務單元名!所有服務單元的配置檔案統一放在 /usr/lib/systemd/system 目錄下。

  第十一步:在系統服務單元配置檔案存放目下建立MySQL的服務單元配置檔案:

# cd /usr/lib/systemd/system
# touch mysqld.service
# chmod 644 mysqld.service

  第十二步:使用vi或vim開啟第十一步建立的MySQL服務單元配置檔案 /usr/lib/systemd/system/mysqld.service,並加入MySQL服務單元配置資訊:

[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target

[Install]
WantedBy=multi-user.target

[Service]
User=mysql
Group=mysql

# Have mysqld write its state to the systemd notify socket
Type=notify

# Disable service start and stop timeout logic of systemd for mysqld service.
TimeoutSec=0

# Start main service
ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf $MYSQLD_OPTS 

# Use this to switch malloc implementation
EnvironmentFile=-/etc/sysconfig/mysql

# Sets open_files_limit
LimitNOFILE = 10000

Restart=on-failure

RestartPreventExitStatus=1

# Set environment variable MYSQLD_PARENT_PID. This is required for restart.
Environment=MYSQLD_PARENT_PID=1

PrivateTmp=false

  第十三步:啟用MySQL服務單元配置

# systemctl enable mysqld.service

  經過上面的一系列安裝和配置步驟後,此時我們已經可以通過systemctl工具手工管理MySQL服務了:

# systemctl {start|stop|restart|status} mysqld

  第十四步:啟動MySQL服務,並檢視MySQL服務狀態:

# systemctl start mysqld
# systemctl status mysqld

  第十五步:重啟伺服器,檢驗MySQL服務是否隨伺服器一起啟動了:

# reboot

  ...重啟系統中...

# systemctl status mysqld

  如果最終MySQL服務狀態正常,那麼CentOS8.1上MySQL8.0的安裝就算是完成了,但是不要高興的太早了!還有好多事要做:

  1、將伺服器上的MySQL客戶端(bin/mysql)配置到系統環境變數PATH中:

  如果不將MySQL客戶端(bin/mysql)配到環境變數中,你會發現即使MySQL服務在正常執行,但直接在系統終端輸入mysql是找不到該命令的:

[root@mysqldb /]# mysql
-bash: mysql: command not found

  當然,你用完整MySQL客戶端(bin/mysql)命令路徑是可以執行該命令的(雖然報錯,但那是正常的識別命令使用了):

[root@mysqldb /]# /usr/local/mysql/bin/mysql
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

  系統環境變數PATH在環境變數配置檔案 /etc/profile 中配置:

# vim /etc/profile

在檔案的最後新起一行,插入:

export PATH=$PATH:/usr/local/mysql/bin

儲存退出後,使用下面的命令手動使修改生效:

# source /etc/profile

  現在你可以直接在任意目錄下執行mysql命令了:

[root@mysqldb /]# mysql
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

  

  2、root賬號初始密碼修改:

  使用root初始密碼(記錄在第九步所設定的log-error日誌檔案)登入MySQL,並修改密碼:

[root@mysqldb /]# mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 8.0.20

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>alter user 'root'@'localhost' identified by '1qaz@WSX';

 Query OK, 0 rows affected (0.00 sec)

 

  3、進行root賬號的伺服器本機登入測試:

  修改完root的預設密碼後,退出MySQL並使用新密碼重新嘗試登入:

mysql> exit
Bye
[root@mysqldb /]# mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 8.0.20 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> 

 

  4、對MySQL使用的埠號進行防火牆例外設定:

  先用root賬號登入MySQL,檢查一下當前正在使用的埠號:

mysql> show global variables like 'port';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| port          | 3306  |
+---------------+-------+
1 row in set (0.01 sec)

  將目標埠號(例中為3306)新增到防火牆例外列表,並重新載入防火牆:

# firewall-cmd --zone=public --add-port=3306/tcp --permanent
success
# firewall-cmd --reload
success

  注意1:一定要帶上--permanent 引數才能永遠生效,否則系統重啟後丟失,另外 --zone 、--add-port 和 --permanent引數前面是兩個-;

  注意2:一定要重新載入防火牆,讓設定生效;

 

  5、建立遠端登入和使用MySQL的普通使用者(因為安全起見,root賬號一般不要設定成可以遠端登入,要設定也儘量設定成只可在固定的某個IP遠端登入):

  以root賬號登入MySQL,使用以下SQL命令建立一個可以任意網路互通的點登入的賬號xurm 密碼 1qaz@WSX

create user xurm IDENTIFIED with mysql_native_password by '1qaz@WSX' account unlock;
select host,user from user;
grant all on *.* to xurm WITH GRANT OPTION;
FLUSH PRIVILEGES;

 

  認認真真按上邊的步驟和細節進行安裝和配置後,現在可以從開發機的客戶端,用普通賬號登入遠端MySQL伺服器,愉快的玩耍了:

 

  以下記錄一次手賤導致的翻車現場:

  使用 # systemctl stop mysqld.service 成功關閉mysql服務後,嘗試直接使用 /usr/local/mysql/bin/mysqld 嘗試啟動mysql造成的後果:bin/mysqld 嘗試啟動時覆蓋並破壞了第十步資料目錄初始生成的有關檔案,導至MySQL無法啟動,這時嘗試使用 # systemctl start mysqld.service也無法再啟動MySQL服務~~~

....
2020-06-06T04:38:39.614356Z 1 [ERROR] [MY-012574] [InnoDB] Unable to lock ./ibdata1 error: 11
2020-06-06T04:38:40.618323Z 1 [ERROR] [MY-012574] [InnoDB] Unable to lock ./ibdata1 error: 11
2020-06-06T04:38:41.619650Z 1 [ERROR] [MY-012574] [InnoDB] Unable to lock ./ibdata1 error: 11
2020-06-06T04:38:41.620710Z 1 [ERROR] [MY-012592] [InnoDB] Operating system error number 11 in a file operation.
2020-06-06T04:38:41.621045Z 1 [ERROR] [MY-012596] [InnoDB] Error number 11 means 'Resource temporarily unavailable'
2020-06-06T04:38:41.621712Z 1 [ERROR] [MY-012215] [InnoDB] Cannot open datafile './ibdata1'
2020-06-06T04:38:41.622047Z 1 [ERROR] [MY-012959] [InnoDB] Could not open or create the system tablespace. 
If you tried to add new data files to the system tablespace, and it failed here, you should now edit innodb_data_file_path in my.cnf back to
what it was, and remove the new ibdata files InnoDB created in this failed attempt. InnoDB only wrote those files full of zeros, but did not
yet use them in any way. But be careful: do not remove old data files which contain your precious data! 2020-06-06T04:38:41.622372Z 1 [ERROR] [MY-012930] [InnoDB] Plugin initialization aborted with error Cannot open a file. 2020-06-06T04:38:42.119489Z 1 [ERROR] [MY-010334] [Server] Failed to initialize DD Storage Engine 2020-06-06T04:38:42.122437Z 0 [ERROR] [MY-010020] [Server] Data Dictionary initialization failed. 2020-06-06T04:38:42.127147Z 0 [ERROR] [MY-010119] [Server] Aborting 2020-06-06T04:38:42.127857Z 0 [System] [MY-010910] [Server] /usr/local/mysql/bin/mysqld: Shutdown complete (mysqld 8.0.20) MySQL Community Server - GPL.

  提示資訊中讓我在/etc/my.cnf配置檔案中將 innodb_data_file_path 配置項的值改回原來的去,實際上我並沒有在/etc/my.cnf配置檔案配置該項,而是一直使用著預設的 innodb_data_file_path 配置;

  提示資訊讓我刪除啟動失敗的嘗試中InnoDB生成的新ibdata相關檔案,講真的,因為一開始沒有對比過data/目錄中的檔案,現在我都不知道哪些是InnoDB生成的新ibdata相關檔案;

  最後想了一下,我是剛剛安裝的資料庫系統,也還沒有重要資料在上邊,現在data/目錄遭到破壞,那最快的辦法就是清空data/目錄,並重新初始化它,應該就能解決問題了(已經運行了段時間的生產資料庫千萬不要這麼玩,要備份好所有資料檔案,否則會死得很難看!!!最好另尋它法,最最最好就不要讓這樣的車禍出現!):

  • 清空data/目錄:
#  rm -rf /usr/local/mysql/data/*

 

  • 使用第十步中的命令重新初始化資料目錄:
# cd /usr/local/mysql
# bin/mysqld --defaults-file=/etc/my.cnf --initialize

注意:資料目錄重新初始化成功後,會在第九步所設定的log-error日誌檔案(我的是 /usr/local/mysql/data/mysqldb.xgclassroom.err)中生成新的 root@localhost 的初始密碼

 

  • 重啟嘗試啟動MySQL服務:
# systemctl start mysqld
Job for mysqld.service failed because the control process exited with error code.
See "systemctl status mysqld.service" and "journalctl -xe" for details.

  哦呵...又雙叒叕翻車了,重啟失敗!!! 慌得一逼!繼續...

 

  • 檢視一下日誌檔案/usr/local/mysql/data/mysqldb.xgclassroom.err
# cat mysqldb.xgclassroom.err 
2020-06-06T05:31:31.249888Z 0 [System] [MY-013169] [Server] /opt/mysql-8.0.20-linux-x86_64-minimal/bin/mysqld (mysqld 8.0.20) initializing of server in progress as process 2662
2020-06-06T05:31:31.256260Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2020-06-06T05:31:31.509465Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2020-06-06T05:31:31.995068Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: iqaaJCdnj3&e
2020-06-06T05:33:09.978908Z 0 [System] [MY-010116] [Server] /usr/local/mysql/bin/mysqld (mysqld 8.0.20) starting as process 2714
2020-06-06T05:33:09.987836Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2020-06-06T05:33:10.212686Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2020-06-06T05:33:11.314035Z 0 [ERROR] [MY-011292] [Server] Plugin mysqlx reported: 'Preparation of I/O interfaces failed, X Protocol won't be accessible'
2020-06-06T05:33:11.314175Z 0 [ERROR] [MY-011300] [Server] Plugin mysqlx reported: 'Setup of bind-address: '*' port: 33060 failed, `bind()` 
failed with error: Address already in use (98). Do you already have another mysqld server running with Mysqlx ?' 2020-06-06T05:33:11.314342Z 0 [ERROR] [MY-011300] [Server] Plugin mysqlx reported: 'Setup of socket: '/tmp/mysqlx.sock' failed,
another process with PID 1734 is using UNIX socket file' 2020-06-06T05:33:11.413373Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed. 2020-06-06T05:33:11.414505Z 0 [ERROR] [MY-010262] [Server] Can't start server: Bind on TCP/IP port: Address already in use 2020-06-06T05:33:11.414625Z 0 [ERROR] [MY-010257] [Server] Do you already have another mysqld server running on port: 3306 ? 2020-06-06T05:33:11.414918Z 0 [ERROR] [MY-010119] [Server] Aborting 2020-06-06T05:33:12.939872Z 0 [System] [MY-010910] [Server] /usr/local/mysql/bin/mysqld: Shutdown complete (mysqld 8.0.20) MySQL Community Server - GPL.

  有個PID為1734的程序在佔用3306和33060埠?而且還可能是另一個mysqld server,我造,不會是真的吧!使用# systemctl status mysqld 都查過了,沒有服務了~

 

  • 檢視一下3306埠的佔用情況先:
# netstat -anp | grep 3306
tcp6       0      0 :::33060                :::*                    LISTEN      1734/mysqld         
tcp6       0      0 :::3306                 :::*                    LISTEN      1734/mysqld 

  竟然真的有個mysqld程序(PID=1734)以tpc6的協議模式佔著3306和33060埠~

 

  • 檢視一下這個mysqld程序的詳情,看看它是是哪裡來的:
# ps -aux | grep mysqld
mysql      1734  0.5 19.0 1773244 352616 ?      Sl   12:12   0:29 /usr/local/mysql/bin/mysqld
root       2786  0.0  0.0  12108  1080 pts/1    S+   13:45   0:00 grep --color=auto mysqld

  果然是手賤作的孽,直接通過/usr/local/mysql/bin/mysqld手動啟動的服務沒關徹底...

 

  • 幹掉佔用3306和33060埠的無效mysqld程序:
# kill -9 1734

 

  • 再次使用# systemctl start mysqld 命令啟動mysql:
# systemctl start mysqld
# systemctl status mysqld
● mysqld.service - MySQL Server
   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
   Active: active (running) since Sat 2020-06-06 13:47:15 CST; 20s ago
     Docs: man:mysqld(8)
           http://dev.mysql.com/doc/refman/en/using-systemd.html
 Main PID: 2795 (mysqld)
   Status: "Server is operational"
    Tasks: 39 (limit: 11337)
   Memory: 327.7M
   CGroup: /system.slice/mysqld.service
           └─2795 /usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf

Jun 06 13:47:14 mysqldb.xgclassroom systemd[1]: Starting MySQL Server...
Jun 06 13:47:15 mysqldb.xgclassroom systemd[1]: Started MySQL Server.

 

  終於開回正路來了!!!使用日誌檔案/usr/local/mysql/data/mysqldb.xgclassroom.err中記錄的新的初始密碼登入mysql並修改初始化密碼就可以了!