記錄一次實踐 MySQL 主從數據庫

前言

以前一直在研究 MySQL 複製問題,因此最近就想動動手將 MySQL 的主從服務器搭一下。MySQL 主從複製是指數據能夠從一個MySQL數據庫服務器主節點複製到一個或多個從節點。MySQL 默認採用異步複製方式,這樣從節點不用一直訪問主服務器來更新本身的數據,數據的更新能夠在遠程鏈接上進行,從節點能夠複製主數據庫中的全部數據庫或者特定的數據庫,或者特定的表。mysql

準備工做

  1. MySQL 5.7
  2. Linux
  3. 準備兩臺服務器兩端口(若是是單機版本準備兩端口)。我這裏是單機版,兩端口是 33063307

實現效果

雙機或單機主從複製,一主一從。linux

步驟

下文我會稱主服務器爲 Master,從服務器爲 Slavesql

下載 MySQL 5.7

  1. 經過 下載地址 下載 MySQL 的安裝包
  2. 解壓安裝包 tail zvxf mysql-5.7.27-linux-glibc2.12-x86_64.tar.gz
  3. 複製兩份,命名爲 MasterSlave
cp -r 解壓後的MySQL文件目錄 ./master

cp -r 解壓後的MySQL文件目錄 ./slave
複製代碼

建立數據目錄

而後咱們建立數據目錄。目前我本身建立的目錄是在 /var/lib/mysql/ 路徑下的,因此咱們在此路徑建立兩個名爲 MasterSlave 的文件夾。數據庫

目前文件夾是爲空的,因此咱們須要進行初始化數據目錄。因此咱們在 Master 和 Slave 的兩個安裝目錄下如下命令後端

## Master
./bin/mysqld --initialize --user=root --datadir=/var/lib/mysql/master/
複製代碼

若是成功執行的狀況之下,你能夠看到一串輸出,裏面包括一句話,上面說明了臨時密碼。這個密碼用於臨時登錄 MySQL,而後再修改密碼的。bash

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 的配置文件。而後咱們編輯 Mastermy.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
複製代碼

而後編輯 Slavemy.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
複製代碼

集中說一下上面配置文件是什麼意思

  1. server-id 是做爲 MySQL 的惟一標識
  2. binlog-ignore-db 是指二進制日誌會忽略掉數據庫
  3. replicate-do-db 發生改變會被複制的數據庫
  4. replicate-ignore-db 發生改變被忽略的數據庫
  5. socket socket 文件,用於通訊
  6. port MySQL 端口
  7. datadir 數據目錄地址
  8. 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 是指被忽略複製的數據庫

如今咱們記住 FilePosition,下面在鏈接 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;
複製代碼

關注我

有興趣的能夠關注我,我會持續發佈關於後端、數據庫、消息隊列中間件、高併發等知識!

相關文章
相關標籤/搜索