1.準備兩臺數據庫環境,或者單臺多實例環境,能正常啓動和登陸。html
數據庫的安裝和多實例配置請參考http://www.javashuo.com/article/p-qllacvay-bb.html。mysql
2.配置my.cnf文件linux
[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 = 1sql
注意:更改my.cnf配置,須要重啓服務才生效。數據庫
3.登陸主庫增長用於從庫鏈接主庫同步的帳號,例如rep,並受權replication slave同步權限。bash
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 rep@10.0.0.39 | +------------------------------------------------------------------------------------------------------------------------+ | GRANT REPLICATION SLAVE ON *.* TO 'rep'@'10.0.0.39' IDENTIFIED BY PASSWORD '*4ACFE3202A5FF5CF467898FC58AAB1D615029441' | +------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
說明:有關mysql數據庫建立用戶和受權請參考:http://www.javashuo.com/article/p-tgcxrxmu-km.html異步
4.登陸主庫,整庫鎖表flush table with read lock。(窗口關閉即失效,超時參數到了也失效),而後show master status;查看binlog日誌文件名和位置狀態。(mysql5.1 鎖庫是 flush tables with read lock多個s)ide
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備份請參考:http://www.javashuo.com/article/p-zawaqble-k.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選項