
主庫配置log-bin和server-id參數,從庫配置server-id,不能和主庫相同以及其他從庫相同,一般不開啟log-bin功能。除非從庫級聯要開啟log-bin,從庫級聯除了開啟log-bin 還需要開啟log-slave-updates = 1
注意:更改my.cnf配置,需要重新開機服務才生效。
1.準備兩台資料庫環境,或者單台多執行個體環境,能正常啟動和登入。
資料庫的安裝和多執行個體配置請參考https://www.cnblogs.com/qiuhom-1874/p/9757061.html。
2.配置my.cnf檔案
[root@qiuhom 3306]# egrep "log-bin|log_slave_update|server-id" ../3306/my.cnf
log-bin = /mysql_multi_case/3306/mysqld-bin
server-id = 1
[root@qiuhom 3306]# egrep "log-bin|log_slave_update|server-id" ../3307/my.cnf
log-bin = /mysql_multi_case/3307/mysqld-bin
log_slave_updates = 1
server-id = 2
[root@qiuhom 3306]# egrep "log-bin|log_slave_update|server-id" ../3308/my.cnf
#log-bin = /mysql_multi_case/3308/mysqld-bin
server-id = 3
主庫配置log-bin和server-id參數,從庫配置server-id,不能和主庫相同以及其他從庫相同,一般不開啟log-bin功能。除非從庫級聯要開啟log-bin,從庫級聯除了開啟log-bin 還需要開啟log-slave-updates = 1
3.登入主庫增加用于從庫連接配接主庫同步的賬号,例如rep,并授權replication slave同步權限。
mysql> grant replication slave on *.* to 'rep'@'10.0.0.39' identified by 'admin';
Query OK, 0 rows affected (0.00 sec)
mysql> select user,host,password from mysql.user where user='rep';
+------+-----------+-------------------------------------------+
| user | host | password |
+------+-----------+-------------------------------------------+
| rep | 10.0.0.39 | *4ACFE3202A5FF5CF467898FC58AAB1D615029441 |
+------+-----------+-------------------------------------------+
1 row in set (0.00 sec)
mysql> show grants for rep@'10.0.0.39';
+------------------------------------------------------------------------------------------------------------------------+
| Grants for [email protected] |
+------------------------------------------------------------------------------------------------------------------------+
| GRANT REPLICATION SLAVE ON *.* TO 'rep'@'10.0.0.39' IDENTIFIED BY PASSWORD '*4ACFE3202A5FF5CF467898FC58AAB1D615029441' |
+------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
說明:有關mysql資料庫建立使用者和授權請參考:https://www.cnblogs.com/qiuhom-1874/p/9741166.html
4.登入主庫,整庫鎖表flush table with read lock。(視窗關閉即失效,逾時參數到了也失效),然後show master status;檢視binlog日志檔案名和位置狀态。(mysql5.1 鎖庫是 flush tables with read lock多個s)
mysql> flush table with read lock;
Query OK, 0 rows affected (0.00 sec)
mysql> show master status;
+-------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| mysqld-bin.000001 | 653 | | |
+-------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
說明:鎖表的目的是防止我們檢視binlog日志檔案和位置點時,資料還在往庫裡寫。鎖表能更好的,更準确的記錄binlog日志檔案和位置點。同時為備份做好了準備,鎖表能準确的記錄備份時binlog的檔案和位置點。這裡還是要說下binlog二進制日志檔案,這個檔案主要記錄着對mysql資料庫的資料有更新的操作的語句(增删改),千萬記住查詢它不記錄,是以我們鎖表的目的就在這裡,防止我們在檢視binlog日志檔案和位置點時,寫入資料導緻我們找到檔案和位置點和實際的不同。
5.新開視窗,Linux 指令行備份和導出原有的資料庫資料
[root@qiuhom ~]# mysqldump -uroot -padmin -S /mysql_multi_case/3306/mysql.sock -A --events > /work/bak/all.sql
說明:有關mysql備份請參考:https://www.cnblogs.com/qiuhom-1874/p/9747219.html 這裡要說下 --master-data=1 這個選項的主要作用是我們備份的時候在備份sql語句裡記錄binlog日志檔案和位置點,這個選項有個很好的好處就是我們不用鎖表就能準确的拿到備份是的binlog日志檔案名和位置點,同時我們在做主從的時候從庫不需要指定binlog日志檔案和位置的,因為備份出來sql語句有告訴從庫binlog日志和位置點。--master-data=2 這個和等于1的選項隻有一個差別就是等于2是把binlog日志和位置點的語句給注釋了的,等于1的是沒有注釋的,推薦備份使用這個選項。
如果資料量很大,我們建議申請停機備份時間,直接打包資料檔案。
6.解鎖主庫,unlock tables;
mysql> unlock table;
Query OK, 0 rows affected (0.00 sec)
提示:如果備份用--master-data選項鎖表和解鎖這兩步都可以省略。
7.把主庫導出的原有資料恢複到從庫。
[root@qiuhom ~]# mysql -uroot -padmin -S /mysql_multi_case/3307/mysql.sock </work/bak/all.sql
提示:因為是全備 所有不需要指定庫。
8.根具主庫的show master status;檢視binlog的位置狀态,在從庫執行change master to ...語句
CHANGE MASTER TO
MASTER_HOST='10.0.0.39',
MASTER_PORT=3306,
MASTER_USER='rep',
MASTER_PASSWORD='admin',
MASTER_LOG_FILE='mysqld-bin.000001',
MASTER_LOG_POS=653;
提示:如果全備是有給定選項--master-data=1 那麼我們在從庫可以不用寫MASTER_LOG_FILE='mysqld-bin.000001',和MASTER_LOG_POS=653;這兩參數。
9.從庫開啟同步開關,start slave;
mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)
10.從庫檢查同步狀态,并在主庫進行更新測試。show slave status\G;
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.0.0.39
Master_User: rep
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysqld-bin.000001
Read_Master_Log_Pos: 653
Relay_Log_File: relay-bin.000002
Relay_Log_Pos: 647
Relay_Master_Log_File: mysqld-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB: mysql
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: 653
Relay_Log_Space: 797
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: 3
1 row in set (0.00 sec)
提示:我們可以從傳回的資訊看到Slave_IO_Running: Yes和Slave_SQL_Running: Yes。io和sql線程已經啟動了,說明主從已經配置好了。當然我們也可以看線程狀況。
mysql> show processlist;
+----+-------------+-----------+------+---------+-------+-----------------------------------------------------------------------------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+-------------+-----------+------+---------+-------+-----------------------------------------------------------------------------+------------------+
| 4 | system user | | NULL | Connect | 29932 | Waiting for master to send event | NULL |
| 5 | system user | | NULL | Connect | 2584 | Slave has read all relay log; waiting for the slave I/O thread to update it | NULL |
| 11 | root | localhost | NULL | Query | 0 | NULL | show processlist |
+----+-------------+-----------+------+---------+-------+-----------------------------------------------------------------------------+------------------+
3 rows in set (0.00 sec)
我們可以看到目前兩個線程的狀态。
mysql> show processlist;
+----+----------+-----------------+------+-------------+-------+-----------------------------------------------------------------------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+----------+-----------------+------+-------------+-------+-----------------------------------------------------------------------+------------------+
| 5 | rep | 10.0.0.39:36750 | NULL | Binlog Dump | 30068 | Master has sent all binlog to slave; waiting for binlog to be updated | NULL |
| 23 | root | localhost | NULL | Query | 0 | NULL | show processlist |
+----+----------+-----------------+------+-------------+-------+-----------------------------------------------------------------------+------------------+
2 rows in set (0.00 sec)
在主庫上看有個我們建立的使用者連到主庫上,也可看到目前io線程的狀态。
接下來我們就可以在主庫上測試建立庫,看在從庫上是否同步成功
[root@qiuhom ~]# mysql -uroot -padmin -S /mysql_multi_case/3306/mysql.sock -e "show databases;"
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
+--------------------+
[root@qiuhom ~]# mysql -uroot -padmin -S /mysql_multi_case/3307/mysql.sock -e "show databases;"
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
+--------------------+
[root@qiuhom ~]# mysql -uroot -padmin -S /mysql_multi_case/3306/mysql.sock -e "create database abcd;use abcd;create table test(id int);"
[root@qiuhom ~]# mysql -uroot -padmin -S /mysql_multi_case/3306/mysql.sock -e "show databases;"
+--------------------+
| Database |
+--------------------+
| information_schema |
| abcd |
| mysql |
| performance_schema |
+--------------------+
[root@qiuhom ~]# mysql -uroot -padmin -S /mysql_multi_case/3307/mysql.sock -e "show databases;"
+--------------------+
| Database |
+--------------------+
| information_schema |
| abcd |
| mysql |
| performance_schema |
+--------------------+
[root@qiuhom ~]# mysql -uroot -padmin -S /mysql_multi_case/3307/mysql.sock -e "use abcd;show tables;"
+----------------+
| Tables_in_abcd |
+----------------+
| test |
+----------------+
可以看出我們在主庫上建立庫表能及時的同步到從庫上,說明主從複制是配置成功的。說下原理吧,主從複制首先它是異步處理的過程,怎麼說呢,從上面我們檢視線程list可以看出主庫上有一個io線程,從庫上有一個io線程和sql線程,首先從庫會對master-info裡的使用者名和密碼并向向主庫發送連接配接同步認證,主庫主程序收到認證消息,它就把這個任務直接轉交給主庫的io線程,認證成功後從庫的io線程就會去讀master-info裡的記錄的binlog檔案名和對應的位置點發給主庫的io線程,主庫收到這個資訊後就把對應的日志檔案和位置點以下的内容發給從庫的io線程,從庫io線程收到資料後就把收到的資料寫進中繼日志檔案relay-log,同時也會更新master-info裡的binlog檔案名和位置點,到此從庫的io就不管了,它主要的作用就是把主庫io線程發過來的binlog日志寫進中繼日志和更新master-info。接下來sql線程就來讀中繼日志relay-log裡的内容,sql線程它會做兩個事情,一是把讀到的sql語句在本地執行并生成資料檔案。第二件事就是他會把它執行的sql語句位置點記錄到relay-info的檔案,relay-info記錄sql線程把binlog應用到本地資料庫裡的位置點,sql線程會不斷的去讀relay-info裡記錄的binlog檔案名和位置點,并拿着這些資訊去relay-log裡找對應的位置的sql語句,并把這些sql語句執行生成資料檔案。sql線程每讀一次relay-log,它就會往relay-info裡記錄它讀到什麼位置,然後執行sql語句生成資料檔案。
mysql主從複制的原理大概主要有以下幾點:
1.異步方式同步。(slave端的io線程不會等sql線程把語句執行了後再向master端發送binlog位置點,slave端的io線程會不斷的讀master-info裡的binlog檔案名和位置點發送給master端,至于sql線程他們倆不是同步處理的)
2.邏輯同步模式。多種模式,預設是通過sql語句執行。
3.主庫通過記錄binlog實作對從庫的同步。binlog記錄資料庫更新語句(增删改)。
4.主庫1個線程,從庫2個線程來完成的。(主io,從io,sql)
5.從庫關鍵檔案master.info(記錄change master 資訊) ,relay-log(中繼日志,記錄主庫io線程發過來的binlog日志),relay-info(記錄sql線程把binlog應用到本地資料庫裡的位置點)功能。
6.如果從庫級聯,需要打開log-bin和log-slave-updates選項
作者:Linux-1874
出處:https://www.cnblogs.com/qiuhom-1874/
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利.