簡單搭建MySQL主從複製

小松聊PHP进阶發表於2024-03-07

個人認為,90%的公司的資料體量和併發量壓根用不上從伺服器,結合Redis,一臺效能強勁的雲MySQL伺服器,做好日常備份。足夠了。

概念

一個MySQL主(Master)伺服器上的資料自動複製到至少一個的MySQL從(Slave)伺服器的過程,利用bin log,主伺服器上的資料更改會被自動地同步到從伺服器,以保持至少兩個伺服器上資料的一致性。
注意:客戶端請求MySQL Server,寫主還是寫從,讀主還是讀從,決定權在客戶端。

解決了什麼問題?

  • 負載均衡:一臺機器讀寫可能扛不住,多個伺服器過來幫忙,主負責寫,從負責讀。
  • 讀寫分離:起到了資料備份的作用,雞蛋不要放到一個籃子裡。
  • 高可用性:一臺伺服器當機,可切換到另一臺伺服器上,提供繼續服務的能力。

缺點

  • 增加運維複雜度。
  • 無法保證主從實時通訊,可能出現資料不一致的情況。

主從通訊推還是拉?

拉,透過從機上配置主機的IP就能看出來,如果是推,則是主機上配置從機IP。
主伺服器主動請求從伺服器或推送,這是推。
從伺服器主動請求主伺服器,這是拉。

配置一主一從

mysql有大量的可選主從的配置,很多不一定能用上,具體可檢視MySQL官網:https://dev.mysql.com/doc/refman/8.0/en/replication-configuration.html
最好先ping對方的伺服器,能互相ping通,說明可通訊。
防火牆開啟3306埠:
firewall-cmd --zone=public --add-port=3306/tcp --permanent && systemctl restart firewalld

主伺服器配置
#主伺服器id
server-id=180
#bin log日誌名稱
log-bin=mysql-bin
#需要從機複製的資料庫名
binlog-do-db=test


從伺服器配置
#從伺服器id
server-id=181
#設定只讀
read-only=1


mysql5.7及以下版本,在主伺服器上執行一下MySQL指令
grant replication slave on *.* to '從伺服器使用者名稱'@'從伺服器IP' identified by '從伺服器密碼';

mysql8,在主伺服器上執行一下MySQL指令
create user '從機使用者名稱'@'%' identified by '從機密碼';
grant replication slave on *.* to '從機使用者名稱'@'%';
alter user '從機使用者名稱'@'%' identified with mysql_native_password by '從機密碼';
flush privileges;

主機執行
show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000032 |      157 | test         |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

在從機執行
change master to master_host='主機IP',master_user='主機建立的從機使用者名稱',master_password='主機建立的從機密碼',master_log_file='主機執行show master status的bin log名稱',master_log_pos=主機執行show master status的position值;

在從機執行
start slave;

在從機執行:
show slave status;只要發現Slave_IO_Running : Yes和Slave_SQL_Running : Yes;就說明配置完成。
*************************** 1. row ***************************
               Slave_IO_State: Waiting for source to send event
                  Master_Host: 192.168.3.180
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000032
          Read_Master_Log_Pos: 157
               Relay_Log_File: lnmp-relay-bin.000002
                Relay_Log_Pos: 326
        Relay_Master_Log_File: mysql-bin.000032
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 157
              Relay_Log_Space: 535
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 180
                  Master_UUID: fbdac062-db17-11ee-9a5f-000c29d1c19b
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
            Network_Namespace: 
1 row in set, 1 warning (0.00 sec)

值得一提的是,在主機的配置上,有一個binlog_format的屬性,用於指定二進位制日誌檔案中記錄的事件格式

  • statement:如執行now()這種函式時,從機會照搬複製主機的資料。
  • row:預設值。 如執行now()這種函式時,從機會獲取自身的資料,能夠避免由於不確定性造成的錯誤。但可能生成更大的二進位制日誌檔案,因為它記錄了每一行資料的變化。
  • mixed:中庸策略,在某些情況下,它會記錄 SQL 語句,而在另一些情況下會記錄資料行更改。

相關文章