主從複製常見的用途:
1.數據分佈
Mysql複製通常不會對帶寬造成很大壓力,但在5.1版本引入的基於行復制會比傳統基於複製模式的帶寬壓力更大。可以隨意停止或開始複製,並在不同的的地理位置來分佈數據。
2.負載均衡
通過將MySql複製可以將讀操作分佈到多個服務器上,實現對讀密集型應用的優化。簡單的代碼修改可以實現基本的負載均衡。
3.備份
可以作爲備份的技術補充,但複製不是備份也不能取代備份。
4.高可用性和故障切換
當某個節點數據庫崩潰時,可以切換系統數據庫節點。
5.mysql升級
比如要升級某個數據庫可以先嚐試性升級某個節點數據庫進行測試。
主從工作原理:
1.主庫將數據更改記錄二進制日誌(Binary Log)
2.備庫將主庫的日誌複製到自己的中繼日誌(Relay Log)
3.備庫讀取中繼日誌中的事件,將其重放到備庫數據上。
I/O線程跟主庫建立一個連接,然後再主庫上啓動一個特殊的二進制轉儲(binlog dump) 線程這個線程會讀取二進制日誌中事件,但並不會對事件進行輪訓,如果線程追趕上了主庫,它將進入睡眠狀態直到主庫發送信號通知有新的事件產生纔會備喚醒。從庫SQL線程讀取中繼日誌並在備庫中執行。所以在Mysql4.0之後複製是總共啓動了三個線程,在者之前Mysql 複製功能是沒有使用中繼日誌。
注:
1.MySql支持兩種複製方式:基本航的複製和基於語句的複製。
2.MySql複製大部分是向後兼容,新版本服務器可以作爲老版本服務器的備庫,但是反過來,將老版本作爲新版本的備庫通常情況下是不行的。因爲老版本的庫可能無法解析新版本所採用的新特性或語法。所使用的二進制文件格式也可能不相同。
3.複製通常不會增加主庫開銷,主要是啓用二進制日誌帶來的開銷。當備庫讀取日誌文件時候,可能會造成更高的I/O開銷,另外鎖的競爭也可能阻礙事務的提交。(5000或更高TPS主庫複製到多個備庫,喚醒多個線程發送事件開銷將會累加)
4.MySql 4.0之前的主從複製跟之後版本變化很大。例如mysql 複製功能並沒有使用中繼日誌,複製只用到2個線程。二不是現在三個線程。
5.主備份配置 sync_binlog=1 如果開啓此項Mysql每次會在提交事務之前會將二進制文件同步到磁盤上,保證服務器崩潰時不會丟失數據事件,如果禁用服務器崩潰會損壞或者丟失信息,建議在不是主備份上該項可以不設置減少性能開銷
語句複製(邏輯複製)在MySql 3.23版本就存在。行的複製通過主庫上記錄二進制日誌,在備庫重放日誌方式實現異步數據複製。(同一時間備庫上的數據可能與主庫上的數據存在不一致問題,無法保證主備之間的延遲)。
在設計這塊通常讀操作指向備庫,寫操作指向主庫,否則並不適合通過複製來擴展寫操作。所以主庫多備架構中,寫操作會被多次執行,這個時候整個系統性能取決寫入最慢的那個部分。
缺點就是:1臺服務數據N臺數據備庫。那麼這N臺服務器都存在相同數據,所以這個不是一種經濟的方式。
實戰主從複製
1.創建複製賬號
GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO repl@'內網地址.%' IDENTIFIED BY '密碼';
主庫和備庫都需要建立賬號
2.開啓主服務器binLog
主庫在my.conf 中添加server_id可以由自己來決定取值,但是id是服務器唯一ID。修改完畢重啓mysql
log_bin = mysql-bin
server_id = 10
輸入看看是否開啓
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 154 | | | |
+------------------+----------+--------------+------------------+-------------------+
備庫也需要在my.conf中增加類似配置
log_bin = mysql-bin
server_id=2
#中繼日誌路徑
relay_log = D:\mysql-5.7.32-winx64\realay_log
#允許備庫將其重放的事件記錄也到自身的二進制日誌中
log_slave_updates = 1
#阻止任何沒有特權的線程修改數據(所以最好不要給與用戶超過需要的權限)
read_only = 1
3.啓動複製
這一步告訴備庫如何連接到主庫並重放其二進制日誌 MASTER_LOG_POS=0 因爲日誌要從頭開始執行
CHANGE MASTER TO MASTER_HOST='主庫地址', MASTER_USER='repl', MASTER_PASSWORD='密碼' ,MASTER_LOG_FILE='主庫binlog', MASTER_LOG_POS=0;
mysql> show slave status;
+----------------+-----------------+-------------+-------------+---------------+------------------+---------------------+----------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+-------------+-----------------------------------------+-----------+---------------------+-------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+
| Slave_IO_State | Master_Host | Master_User | Master_Port | Connect_Retry | Master_Log_File | Read_Master_Log_Pos | Relay_Log_File | Relay_Log_Pos | Relay_Master_Log_File | Slave_IO_Running | Slave_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Master_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Master_SSL_Allowed | Master_SSL_CA_File | Master_SSL_CA_Path | Master_SSL_Cert | Master_SSL_Cipher | Master_SSL_Key | Seconds_Behind_Master | Master_SSL_Verify_Server_Cert | Last_IO_Errno | Last_IO_Error | Last_SQL_Errno | Last_SQL_Error | Replicate_Ignore_Server_Ids | Master_Server_Id | Master_UUID | Master_Info_File | SQL_Delay | SQL_Remaining_Delay | Slave_SQL_Running_State | Master_Retry_Count | Master_Bind | Last_IO_Error_Timestamp | Last_SQL_Error_Timestamp | Master_SSL_Crl | Master_SSL_Crlpath | Retrieved_Gtid_Set | Executed_Gtid_Set | Auto_Position | Replicate_Rewrite_DB | Channel_Name | Master_TLS_Version |
+----------------+-----------------+-------------+-------------+---------------+------------------+---------------------+----------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+-------------+-----------------------------------------+-----------+---------------------+-------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+
| | 192.168.200.221 | root | 3306 | 60 | mysql-bin.000001 | 4 | mysql-5.7 | 4 | mysql-bin.000001 | No | No | | | | | | | 0 | | 0 | 4 | 154 | None | | 0 | No | | | | | | NULL | No | 0 | | 0 | | | 0 | | D:\mysql-5.7.32-winx64\data\master.info | 0 | NULL | | 86400 | | | | | | | | 0 | | | |
+----------------+-----------------+-------------+-------------+---------------+------------------+---------------------+----------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+-------------+-----------------------------------------+-----------+---------------------+-------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+
可以看到 Slave_IO_State, Slave_IO_Running,Slave_SQL_Running 顯示當前備庫複製尚未運行。Read_Master_Log_Pos 已經是4而不是0 因爲0不是日誌真正開始的位置 它僅僅意味 在日誌文件頭 MySql第一個事件是從文件第4位開始的(真正的日誌起始位置是98,一旦備庫開始連接主庫就開始工作,但是現在尚未發生)
4.開始複製命令
mysql> start slave;
查看從庫狀態
mysql> show slave status;
+----------------------------------+-----------------+-------------+-------------+---------------+------------------+---------------------+----------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+----------------------------------------------+-----------+---------------------+--------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+
| Slave_IO_State | Master_Host | Master_User | Master_Port | Connect_Retry | Master_Log_File | Read_Master_Log_Pos | Relay_Log_File | Relay_Log_Pos | Relay_Master_Log_File | Slave_IO_Running | Slave_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Master_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Master_SSL_Allowed | Master_SSL_CA_File | Master_SSL_CA_Path | Master_SSL_Cert | Master_SSL_Cipher | Master_SSL_Key | Seconds_Behind_Master | Master_SSL_Verify_Server_Cert | Last_IO_Errno | Last_IO_Error | Last_SQL_Errno | Last_SQL_Error | Replicate_Ignore_Server_Ids | Master_Server_Id | Master_UUID | Master_Info_File | SQL_Delay | SQL_Remaining_Delay | Slave_SQL_Running_State | Master_Retry_Count | Master_Bind | Last_IO_Error_Timestamp | Last_SQL_Error_Timestamp | Master_SSL_Crl | Master_SSL_Crlpath | Retrieved_Gtid_Set | Executed_Gtid_Set | Auto_Position | Replicate_Rewrite_DB | Channel_Name | Master_TLS_Version |
+----------------------------------+-----------------+-------------+-------------+---------------+------------------+---------------------+----------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+----------------------------------------------+-----------+---------------------+--------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+
| Waiting for master to send event | 192.168.200.221 | root | 3306 | 60 | mysql-bin.000001 | 844 | mysql-5.7 | 1200 | mysql-bin.000001 | Yes | Yes | | | | | | | 0 | | 0 | 844 | 1200 | None | | 0 | No | | | | | | 0 | No | 0 | | 0 | | |
10 | cbef984a-9fc3-11ec-87a3-000c29467e7e | D:\mysql-5.7.32-winx64\mysqlData\master.info | 0 | NULL | Slave has read all relay log; waiting for more updates | 86400 | | | | | | | | 0 | | | |
+----------------------------------+-----------------+-------------+-------------+---------------+------------------+---------------------+----------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+----------------------------------------------+-----------+---------------------+--------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+
可以看到 Slave_IO_Running,Slave_SQL_Running 已經執行成功了