記錄一次實踐 MySQL 主從資料庫
前言
之前一直在研究 MySQL 複製問題,所以最近就想動動手將 MySQL 的主從伺服器搭一下。MySQL 主從複製是指資料可以從一個MySQL資料庫伺服器主節點複製到一個或多個從節點。MySQL 預設採用非同步複製方式,這樣從節點不用一直訪問主伺服器來更新自己的資料,資料的更新可以在遠端連線上進行,從節點可以複製主資料庫中的所有資料庫或者特定的資料庫,或者特定的表。
準備工作
MySQL 5.7
Linux
- 準備兩臺伺服器兩埠(如果是單機版本準備兩埠)。我這裡是單機版,兩埠是
3306
、3307
實現效果
雙機或單機主從複製,一主一從。
步驟
下文我會稱主伺服器為 Master
,從伺服器為 Slave
下載 MySQL 5.7
- 通過 下載地址 下載 MySQL 的安裝包
- 解壓安裝包
tail zvxf mysql-5.7.27-linux-glibc2.12-x86_64.tar.gz
- 複製兩份,命名為
Master
和Slave
cp -r 解壓後的MySQL檔案目錄 ./master
cp -r 解壓後的MySQL檔案目錄 ./slave
複製程式碼
建立資料目錄
然後我們建立資料目錄。目前我自己建立的目錄是在 /var/lib/mysql/
路徑下的,所以我們在此路徑建立兩個名為 Master
和 Slave
的資料夾。
目前資料夾是為空的,所以我們需要進行初始化資料目錄。所以我們在 Master 和 Slave 的兩個安裝目錄下以下命令
## Master
./bin/mysqld --initialize --user=root --datadir=/var/lib/mysql/master/
複製程式碼
如果成功執行的情況之下,你可以看到一串輸出,裡麵包括一句話,上面說明瞭臨時密碼。這個密碼用於臨時登陸 MySQL,然後再修改密碼的。
2019-11-12T08:43:49.391486Z 1 [Note] A temporary password is generated for root@localhost: %Cx0w5aWACrf
複製程式碼
接下來執行的是 Slave 的資料目錄初始化
## Slave
./bin/mysqld --initialize --user=root --datadir=/var/lib/mysql/slave/
複製程式碼
初始化完畢之後,我們可以走到下一步了
建立配置檔案 my.cnf 並編輯
有人可能不知道 my.cnf
檔案是什麼。其實 my.cnf
就是一個配置檔案,主要配置 MySQL
的服務端,客戶端等配置資訊。
所以我們需要分別為 Master(主) 和 Slave(從) 複製兩份放進各自 MySQL
資料夾,這個是為了區別開各個 MySQL
的配置檔案。然後我們編輯 Master
的 my.cnf
檔案,填入以下內容(需要特別注意的是我們應該核對好主從資料庫的資料目錄)
my.cnf
[mysqld]
server-id=1
log-bin=binlog_name
binlog-ignore-db=information_schema
binlog-ignore-db=mysql
replicate-ignore-db=information_schema
replicate-ignore-db=mysql
replicate-do-db=test
log-slave-updates
slave-skip-errors=all
slave-net-timeout=60
user=root
port=3307
datadir=/var/lib/mysql/master
socket=/var/lib/mysql/master/mysql.sock
[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid
[client]
default-character-set=utf8
port=3306
socket=/var/lib/mysql/master/mysql.sock
[mysql]
default-character-set=utf8
socket=/var/lib/mysql/master/mysql.sock
複製程式碼
然後編輯 Slave
的 my.cnf
[mysqld]
server-id=2
binlog-ignore-db=information_schema
binlog-ignore-db=mysql
replicate-do-db=test
replicate-ignore-db=mysql
log-slave-updates
slave-skip-errors=all
slave-net-timeout=60
user=root
port=3307
datadir=/var/lib/mysql/slave
socket=/var/lib/mysql/slave/mysql.sock
[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid
[client]
default-character-set=utf8
port=3306
socket=/var/lib/mysql/slave/mysql.sock
[mysql]
default-character-set=utf8
socket=/var/lib/mysql/slave/mysql.sock
複製程式碼
集中說一下上面配置檔案是什麼意思
-
server-id
是作為 MySQL 的唯一標識 -
binlog-ignore-db
是指二進位制日誌會忽略掉資料庫 -
replicate-do-db
發生改變會被複制的資料庫 -
replicate-ignore-db
發生改變被忽略的資料庫 -
socket
socket 檔案,用於通訊 -
port
MySQL 埠 -
datadir
資料目錄地址 -
log-bin
開啟了二進位制日誌
啟動 MySQL
因為我們是單機版主從資料庫搭建,所以我們需要指定 my.cnf 來啟動 MySQL。下面是啟動的命令列,++我們需要分別在 Master 和 Slave 安裝目錄下執行這句命令++
Master
./bin/mysqld --defaults-file=my.cnf -uroot
複製程式碼
Slave
./bin/mysqld --defaults-file=my.cnf -uroot
複製程式碼
配置 MySQL 的主從資訊
連線 Master 服務端
❤️ 還記得上面的臨時密碼嗎?現在服務端已經啟動好了,現在我們需要拿來登陸服務端。
./bin/mysqld --defaults-file=my.cnf -uroot -p臨時密碼
複製程式碼
登陸成功後,我們首要的事情是修改密碼,因為在臨時登陸情況下服務端不允許進行任何操作。
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('new_password');
複製程式碼
首先我們通過命令列或者客戶端連線上 Master 的 MySQL 伺服器,然後檢視是否開啟了 binlog 二進位制日誌。
show master status;
複製程式碼
如果開啟狀態的話會有以下結果
+--------------------+----------+--------------+--------------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+--------------------+----------+--------------+--------------------------+-------------------+
| binlog_name.000005 | 154 | | information_schema,mysql | |
+--------------------+----------+--------------+--------------------------+-------------------+
1 row in set (0.00 sec)
複製程式碼
關於上面的結果我解釋一下
-
File
指的是當前二進位制日誌記錄的檔名 -
Position
指的是二進位制日誌記錄的位置 -
Binlog_Do_DB
是指需要被複制的資料庫 -
Binlog_Ignore_DB
是指被忽略複製的資料庫
現在我們記住 File
和 Position
,下面在連線 Slave 的時候我們要配置 Master 和 Slave 的資訊對稱問題。
❤️ 然後我們建立一個 test
資料庫,再建立一個 sys_account
表,用於測試主從資訊同步的表。
CREATE TABLE `test`.`sys_account` (
`id` int(11) NOT NULL,`username` varchar(255) NULL,PRIMARY KEY (`id`)
);
複製程式碼
❤️ 最後我們需要建立一個賬號,因為主從資料庫的實質++是 Slave 通過特定的賬號登陸 Master 獲取二進位制日誌檔案,然後通過記錄同步到 Slave 資料庫當中++。
// 建立一個使用者名稱為 slave_user,密碼是 slave_pass ,伺服器地址為 slave_host 的賬號,
create user 'slave_user'@'slave_host' identified by 'slave_pass';
// 然後授予所有資料庫的複製許可權給新建的賬號
GRANT REPLICATION SLAVE ON *.* TO 'slave_user'@'slave_host';
複製程式碼
至此 Master 的所有操作已經結束了。
連線 Slave 服務端
❤️ 同樣,現在我們需要臨時密碼登陸服務端,然後修改密碼。
❤️ 因為 Slave 只是拿來單純的同步來自於 Master 的資訊,資料庫裡邊是空的,所以我們先要對其和 Master 進行一個資料結構和資料的同步,保證在開始的時候,它們是處於資訊對稱的狀態。我們可以通過 navicat 或者命令列進行同步,這個我就不在這裡展開。
❤️ 現在我們要設定 Slave 資料庫的主伺服器,所以你們需要根據實際情況填寫命令的資訊
CHANGE MASTER TO MASTER_HOST='127.0.0.1',MASTER_USER='slave_user',MASTER_PORT=3306,MASTER_PASSWORD='slave_pass',MASTER_LOG_FILE='binlog_name.000005',MASTER_LOG_POS=154
複製程式碼
引數說明
-
MASTER_HOST
指的是主資料庫的 IP 地址 -
MASTER_USER
指的是剛剛在上面 Master 為 Slave 建立的賬號名 -
MASTER_PORT
指的是主資料庫監聽的埠 -
MASTER_PASSWORD
指的是剛剛在上面 Master 為 Slave 建立的賬號密碼 -
MASTER_LOG_FILE
指的是主伺服器當前二進位制的檔名 -
MASTER_LOG_POS
指的是主伺服器當前二進位制的記錄的位置
常見問題
無法登陸 MySQL
如果新裝的 MySQL 無法登陸,例如提示以下資訊
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
複製程式碼
那麼我們先修改 my.cnf,加上下面這句話
[mysqld]
skip-grant-tables
複製程式碼
然後我們可以直接無賬號密碼登陸 MySQL 服務端,然後我們通過 SQL 命令列修改命令
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('new_password');
複製程式碼
修改完後我們就可以將上面新增的 skip-grant-tables
註釋掉,重新使用新密碼登陸。
遠端登陸問題
有可能你們在遠端伺服器進行搭建的,所以新建的 MySQL 需要開啟遠端連線的選項
# 使所有遠端使用者都可以使用 root 賬號 root 密碼登陸 mysql
grant all privileges on *.* to 'root'@'%' identified by 'root' with grant option;
flush privileges;
複製程式碼
關注我
有興趣的可以關注我,我會持續釋出關於後端、資料庫、訊息佇列中介軟體、高併發等知識!