[MySQL] 8.0 replica
最近剛好需要幫公司的資料庫做 replica, 但由於之前的資料庫沒有開啟 binlog,
所以研究了一下該怎麼操作。
如果是剛開始建立服務,建議 binlog 的設定要記得打開,如果沒有打開的話,變成要實作 replica 就需要先將資料備份出來,然後在備份出來的 master 資料還原給 slave,之後再去開啟 master 的 binlog,與建立要給 slave 同步用的帳號。
稍微解釋一下主從式架構,主要是由 master 來執行讀與寫,然後每個操作會記錄在 binlog 中,master 會透過 REPLICATION 這個權限讓 slave 可以去取回 binlog 的操作,藉由非同步的方式同步資料。
預先提醒,如果 slave 是由 master 透過複製虛擬機出來的,如果遇到
Last_IO_Error: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server UUIDs; these UUIDs must be different for replication to work
這個錯誤,就是代表 MySQL Server 的 UUID 重複,這時候只需要把 slave 的
/var/lib/mysql/auto.cnf 這個檔案刪除,之後執行
service mysql restart
就可以解決問題囉!
Master
1. 以 Ubuntu 20.10 為例,MySQL 設定 replica 的設定檔在/etc/mysql/mysql.conf.d/mysqld.cnf
在該檔案中加入
binlog_do_db = 指定的資料庫
bind-address = 0.0.0.0
server_id = 1
log_bin = /var/lib/mysql/mysql-bin.log
log-slave-updates = 0
expire_logs_days = 10
# 如果開始 sync_binlog = 1 與innodb_flush_log_at_trx_commit
# 一致性會是最好,但會影響效能。
sync_binlog = 0
innodb_flush_log_at_trx_commit = 0
# innodb_buffer_pool_size 建議是整個主機記憶體的 80%
innodb_buffer_pool_size = 2G
存擋之後執行
service mysql restart
讓設定檔生效
之後建立一個 replication 的 mysql 用戶,讓 slave 可以抓取 binlog
先透過 mysql-client-cli:
mysql -uroot -p
mysql > create user 'replication'@'%' IDENTIFIED by '指定的密碼';mysql > ALTER USER 'replication'@'%' IDENTIFIED WITH mysql_native_password BY '指定的密碼';mysql > GRANT REPLICATION SLAVE ON *.* TO 'replication'@'%';
mysql > FLUSH PRIVILEGES;
接下來要記 File & Positionmysql > SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 | 550 | 指定的資料庫 | | |
+------------------+----------+--------------+------------------+-------------------+
在這邊就是記住 mysql-bin.000002 與 550
Slave
1. 以 Ubuntu 20.10 為例,MySQL 設定 replica 的設定檔在/etc/mysql/mysql.conf.d/mysqld.cnf
在該檔案中加入
# server_id 必須跟 master 不同,如果有多台 slave,id 都需要不同。
server_id = 2
log_bin = /var/lib/mysql/mysql-bin.log
relay-log = /var/log/mysql/mysql-relay-bin.log
log-slave-updates = 0
expire_logs_days = 10
sync_binlog = 0
innodb_flush_log_at_trx_commit = 0
innodb_buffer_pool_size = 2G
# 加入 read_only = 1 是防止程式端對 slave 寫入,造成不一致,也可不用。
read_only = 1
接著一樣
# mysql -uroot -p
如果 slave 已經有執行的話,先停止 slave
mysql > STOP SLAVE;
接下來
mysql > CHANGE MASTER TO MASTER_HOST='master的 IP',MASTER_USER='replication', MASTER_PASSWORD='指定的密碼', MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS= 550;
mysql > START SLAVE;
要看有沒有成功:
mysql > SHOW SLAVE STATUS;
如果有看到
Waiting for master to send event
那就是成功了!
備註:
MySQL 5.7 建立用戶是
create user 'neil'@'%' IDENTIFIED by '指定的密碼';
GRANT ALL privileges on 指定的資料庫名稱.* to neil@'%'identified by '指定的密碼';
但這樣會造成使用 mysql gui client 連線不上(MySQL 8.0)所以如果資料庫是 8.0 以上的版本
create user 'neil'@'%' IDENTIFIED by '指定的密碼';GRANT ALL PRIVILEGES ON *.* TO 'neil'@'%' WITH GRANT OPTION;ALTER USER 'neil'@'%' IDENTIFIED WITH mysql_native_password BY '指定的密碼';
Ref:
留言
張貼留言