程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> MySQL主從復制資料匯總

MySQL主從復制資料匯總

編輯:MySQL綜合教程

MySQL主從復制資料匯總


1,復制原理

如下圖1.png所示:

\

 

 

該過程的第一部分就是master記錄二進制日志。在每個事務更新數據完成之前,master在二日志記錄這些改變。MySQL將事務串行的寫入二進制日志,即使事務中的語句都是交叉執行的。在事件寫入二進制日志完成後,master通知存儲引擎提交事務。

 

下一步就是slave將master的binary log拷貝到它自己的中繼日志。首先,slave開始一個工作線程——I/O線程。I/O線程在master上打開一個普通的連接,然後開始binlog dump process。Binlog dump process從master的二進制日志中讀取事件,如果已經跟上master,它會睡眠並等待master產生新的事件。I/O線程將這些事件寫入中繼日志。

 

SQLslave thread(SQL從線程)處理該過程的最後一步。SQL線程從中繼日志讀取事件,並重放其中的事件而更新slave的數據,使其與master中的數據一致。只要該線程與I/O線程保持一致,中繼日志通常會位於OS的緩存中,所以中繼日志的開銷很小。

 

此外,在master中也有一個工作線程:和其它MySQL的連接一樣,slave在master中打開一個連接也會使得master開始一個線程。復制 過程有一個很重要的限制——復制在slave上是串行化的,也就是說master上的並行更新操作不能在slave上並行操作。

 

2,mysql主從同步應用場景

(1):數據分布

(2):負載均衡

(3):備份

(4):高可用和容錯

 

3,搭建mysql主從的環境要求

主從系統要保持一致:包括數據庫版本,操作系統版本,磁盤IO磁盤容量,網絡帶寬等。

[root@data02 ~]# cat /etc/redhat-release

CentOS release 6.2 (Final)

[root@data02 ~]#

 

主庫master

從庫slave

OS系統版本

CentOS release 6.2 (Final)

CentOS release 6.2 (Final)

數據庫版本

5.6.12-log

5.6.12-log

磁盤容量

50G

30G

主機ip地址

192.168.52.129

192.168.52.130

端口

3306

3306

內存

1G

1G

服務器類型

虛擬機

虛擬機

 

 

4,開始搭建mysql主從復制

4.1建立復制賬號

 

GRANT REPLICATION SLAVE,RELOAD,SUPER ON *.*TO repl@'192.168.52.130' IDENTIFIED BY 'repl_1234';

建立一個復制賬號,只允許從192.168.52.130上來訪問登錄主庫進行二進制日志傳輸同步。PS:如果mysql版本新舊密碼算法不同,可以設置set password for 'backup'@'10.100.0.200'=old_password('1234'))

 

4.2 手動同步數據

因為當開始搭建的時候,主庫上已經有了數據,所以要先把主庫已經存在的數據先手動同步遷移到從庫上面去。搭建過程中,禁止在主庫從庫上進行任何對數據庫的ddl、dml等數據操作。

這裡可以用mysqldump也可以用xtrabackup導出主庫上面的數據:

(4.2.1):xtrabackup方式

在主庫上192.168.52.129上面進行數據備份,備份命令,要添加--safe-slave-backup參數:

innobackupex --user=backup--password="123456" --host=192.168.52.129 --socket=/tmp/mysql.sock--defaults-file=/etc/my.cnf /data/backups/mysql/repl/backup_slave --parallel=3--safe-slave-backup --no-timestamp

去備份目錄/data/backups/mysql/repl/backup_slave查看備份時候的主庫二進制信息,需要根據這個二進制信息來進行數據同步,如下所示:

[root@data01 test]# cd/data/backups/mysql/repl/backup_slave

[root@data01 backup_slave]# more xtrabackup_binlog_info

mysql-bin.000147 120

[root@data01 backup_slave]#

壓縮備份文件並且傳輸到從庫192.168.52.130上面:

tar -zcvf backup_slave.tar.gz backup_slave/

scp backup_slave.tar.gz192.168.52.130:/tmp/

(4.2.2)mysqldump方式

在主庫上192.168.52.129上做基於主庫做數據備份

/usr/local/mysql/bin/mysqldump -ubackup--password=123456 --host=192.168.52.129 --single-transaction --flush-logs --master-data=2 --add-drop-table--create-option --quick --extended-insert=false --set-charset --disable-keys -A> /tmp/alldb.sql

壓縮備份文件,傳輸到從庫192.168.52.130上面去。

gzip /tmp/alldb.sql

scp /tmp/alldb.sql.gz 192.168.52.130:/tmp/

4.3 配置master庫(192.168.52.129)

Vim /etc/my.cnf

server-id=129 # Server ID

log-bin =/home/data/mysql/binlog/mysql-bin

binlog-ignore-db=mysql # No sync databases

binlog-ignore-db=test # No sync databases

binlog-ignore-db=information_schema # No sync databases

binlog-ignore-db=performance_schema

binlog-do-db=user_db

 

保存退出,重啟mysql主庫,可以查看主庫的狀態,如下:

mysql> show master status;

+------------------+----------+--------------+--------------------------------------------------+-------------------+

| File | Position | Binlog_Do_DB |Binlog_Ignore_DB | Executed_Gtid_Set |

+------------------+----------+--------------+--------------------------------------------------+-------------------+

| mysql-bin.000151 | 120 | user_db |mysql,test,information_schema,performance_schema | |

+------------------+----------+--------------+--------------------------------------------------+-------------------+

1 row in set (0.00 sec)



mysql>



mysql> show master status\G;

*************************** 1. row***************************

File: mysql-bin.000151

Position: 120

Binlog_Do_DB: user_db

Binlog_Ignore_DB:mysql,test,information_schema,performance_schema

Executed_Gtid_Set:

1 row in set (0.00 sec)

ERROR:

No query specified

mysql>

4.4 配置slave從庫(192.168.52.130)

Slave的配置與master庫類似,如下所示:

Vim /etc/my.cnf

#------------------Master-Slaveconfig-----------------

log-slave-updates=1

replicate-same-server-id=0

server-id=230 # Server ID

log-bin=/home/data/mysql/binlog/mysql-bin.log

relay-log=mysql-relay-bin

master-info-repository=TABLE

relay-log-info-repository=TABLE

binlog-ignore-db=mysql # No sync databases

binlog-ignore-db=test # No sync databases

binlog-ignore-db=information_schema # No sync databases

binlog-ignore-db=performance_schema

binlog-do-db=user_db

expire-logs-days=10

max_binlog_size = 10485760

server_id 是必須的,而且唯一。slave沒有必要開啟二進制日志,但是在一些情況下,必須設置,例如,如果slave為其它slave的master,必須設置 bin_log。在這裡,我們開啟了二進制日志,而且顯示的命名(默認名稱為hostname,但是,如果hostname改變則會出現問題)。

relay_log配置中繼日志,log_slave_updates表示slave將復制事件寫進自己的二進制日志(後面會看到它的用處)。

有些人開啟了slave的二進制日志,卻沒有設置log_slave_updates,然後查看slave的數據是否改變,這是一種錯誤的配置。所以,盡量使用read_only,它防止改變數據(除了特殊的線程)。但是,read_only並是很實用,特別是那些需要在slave上創建表的應用。

配置玩,重啟slave數據庫

mysql> show slave status;

Empty set (0.05 sec)

mysql>

沒有記錄,需要設置一些主從配置。

4.5 設置主從連接復制

生成CHANGE MASTER語句,然後在從上執行,master信息,從備份集合裡面獲取:

xtrabackup備份的話,從xtrabackup_binlog_info裡面獲取,如下所示:

[root@data02 tmp]#tar -xvfbackup_slave.tar.gz

[root@data02 tmp]#cd backup_slave

[root@data02 backup_slave]# morextrabackup_binlog_info

mysql-bin.000141 120

[root@data02 backup_slave]#

Mysqldump的啊,從sql文件的頭幾列獲取,如下所示:

[root@data02 tmp]#cd /tmp/

[root@data02 tmp]#gunzip alldb.sql.gz

[root@data02 tmp]# more alldb.sql |grep"CHANGE MASTER TO MASTER_LOG_FILE" |grep "MASTER_LOG_POS"|more

-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000141',MASTER_LOG_POS=120;

生成changemaster語句,如下:

CHANGE MASTER TO MASTER_HOST='192.168.52.129',

MASTER_USER='repl',

MASTER_PASSWORD='repl_1234',

MASTER_LOG_FILE='mysql-bin.000141',

MASTER_LOG_POS=120;

有報錯信息:

mysql> CHANGE MASTER TO MASTER_HOST='192.168.52.129',

-> MASTER_USER='repl',

-> MASTER_PASSWORD='repl_1234',

-> MASTER_LOG_FILE='mysql-bin.000141',

-> MASTER_LOG_POS=120;

ERROR 1794 (HY000): Slave is not configuredor failed to initialize properly. You must at least set --server-id to enableeither a master or a slave. Additional error messages can be found in the MySQLerror log.

mysql>

具體原因目前不詳,網上查找到的資料:數據庫打開這幾張表的默認引擎為MyISAM,但是這幾張表在建表時的引擎為INNODB

但是能確定的,這幾張表確實是在mysql5.6中新入的

innodb_index_stats,

innodb_tables_stats,

slave_master_info,

slave_relay_log_info,

slave_worker_info

解決方法:

登錄數據庫,進入mysql庫,執行如下SQL刪除5張表

記住,一定要是drop table if exists

drop table if exists innodb_index_stats;

drop table if exists innodb_table_stats;

drop table if exists slave_master_info;

drop table if exists slave_relay_log_info;

drop table if exists slave_worker_info;

執行完後,可以用show tables查看一下,看表的數據是否已經比刪除之前減少了,如果減少了,說明你成功了!

[root@data02 test] cd/home/data/mysql/data/mysql

[root@data02 mysql]# ll *.ibd

-rw-rw----. 1 mysql mysql 98304 1? 9 02:08 innodb_index_stats.ibd

-rw-rw----. 1 mysql mysql 98304 1? 9 02:08 innodb_table_stats.ibd

-rw-rw----. 1 mysql mysql 98304 1? 9 02:08 slave_master_info.ibd

-rw-rw----. 1 mysql mysql 98304 1? 9 02:08 slave_relay_log_info.ibd

-rw-rw----. 1 mysql mysql 98304 1? 9 02:08 slave_worker_info.ibd

[root@data02 mysql]#

強行刪除ibd文件:

[root@data02 mysql]# rm -f *.ibd

重啟數據庫,登錄mysql

source/usr/test/mysql/share/mysql_system_tables.sql

show tables;

發現表已經回來了,表數據大概總數量為28個。

 

之後執行change master to,OK,搞定,如下所示:

mysql> stop slave;

Query OK, 0 rows affected, 1 warning (0.03sec)

 

mysql> CHANGE MASTER TOMASTER_HOST='192.168.52.129',MASTER_USER='repl',MASTER_PASSWORD='repl_1234',MASTER_LOG_FILE='mysql-bin.000141',MASTER_LOG_POS=120;

Query OK, 0 rows affected, 2 warnings (0.07sec)

mysql>

啟動slave

mysql> start slave;

Query OK, 0 rows affected (0.02 sec)

 

mysql>

 

4.6 驗證主從復制狀態

在slave服務器上查看slave狀態:

mysql> show slave status\G

*************************** 1. row***************************

Slave_IO_State: Waiting formaster to send event

Master_Host: 192.168.52.129

Master_User: repl

Master_Port: 3306

Connect_Retry: 60

Master_Log_File: mysql-bin.000151

Read_Master_Log_Pos: 346

Relay_Log_File:mysql-relay-bin.000018

Relay_Log_Pos: 509

Relay_Master_Log_File: mysql-bin.000151

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

Replicate_Do_DB:business_db,user_db,plocc_system

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: 346

Relay_Log_Space: 845

Until_Condition: None

這裡主要看:

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

Seconds_Behind_Master: 0

IO和SQL線程都是Yes以及Seconds_Behind_Master是0就表示從庫正常運行了。

在master服務器上查看:

mysql> show full processlist;

+----+-----------------+----------------------+------+-------------+------+-----------------------------------------------------------------------+-----------------------+

| Id | User | Host | db | Command | Time | State |Info |

+----+-----------------+----------------------+------+-------------+------+-----------------------------------------------------------------------+-----------------------+

| 1| event_scheduler | localhost | NULL | Daemon | 5874 |Waiting on empty queue | NULL |

| 21 | root | localhost | NULL | Query | 0 | init | show full processlist |

| 24 | repl | 192.168.52.130:45665 | NULL |Binlog Dump | 88 | Master has sent allbinlog to slave; waiting for binlog to be updated | NULL |

+----+-----------------+----------------------+------+-------------+------+-----------------------------------------------------------------------+-----------------------+

3 rows in set (0.03 sec)

mysql>

看到有192.168.52.130:45665的線程在同步二進制數據

4.7 master添加數據驗證

去master(192.168.52.129)上操作,添加表記錄:

mysql> create table master_test select 1as a,'a' as b;

Query OK, 1 row affected (0.72 sec)

Records: 1 Duplicates: 0 Warnings: 0

mysql>

去slave(192.168.52.130)上查詢下,看表數據是否同步過來,看到數據已經同步過來了,如下所示:

mysql> select * fromuser_db.master_test;

+---+---+

| a | b |

+---+---+

| 1 | a |

+---+---+

1 row in set (0.06 sec)

mysql>

5,如何添加新的slave服務器總結

如果master運行很久了,需要添加新的slave服務器,那麼搭建新的slave,此時,有幾種方法可以使slave從另一個服務開始,例如,從master拷貝數據,從另一個slave克隆,從最近的備份開始一個slave。Slave與master同步時,需要三樣東西:

(1)master的某個時刻的數據快照;

(2)master當前的日志文件、以及生成快照時的字節偏移。這兩個值可以叫做日志文件坐標(log file coordinate),因為它們確定了一個二進制日志的位置,你可以用SHOW MASTER STATUS命令找到日志文件的坐標;

(3)master的二進制日志文件。

也可以通過以下幾中方法來克隆一個slave:

(1) 冷拷貝(cold copy)

停止master,將master的文件拷貝到slave;然後重啟master。缺點很明顯。

(2) 熱拷貝(warm copy)

如果你僅使用MyISAM表,你可以使用mysqlhotcopy拷貝,即使服務器正在運行。

如果有myisam和innodb表,可以在業務低峰期用tar包的方式來熱拷貝。

(3) 使用mysqldump

使用mysqldump來得到一個數據快照可分為以下幾步:

<3.a>鎖表:如果你還沒有鎖表,你應該對表加鎖,防止其它連接修改數據庫,否則,你得到的數據可以是不一致的。如下:

mysql> FLUSH TABLES WITH READ LOCK;

<3.b>在另一個連接用mysqldump創建一個你想進行復制的數據庫的轉儲:

見4.2.1小節

<3.c>對表釋放鎖。

mysql> UNLOCK TABLES;

(4) 使用xtrabackup

使用xtrabackup得到數據快照,見4.2.2小節

6,如何實現MSS

當設置log_slave_updates時,你可以讓slave扮演其它slave的master。此時,slave把SQL線程執行的事件寫進行自己的二進制日志(binary log),然後,它的slave可以獲取這些事件並執行它。如下圖6.png所示:

\

7,復制過濾

復制過濾可以讓你只復制服務器中的一部分數據,有兩種復制過濾:在master上過濾二進制日志中的事件;在slave上過濾中繼日志中的事件。如下圖7.png所示:

 

\

8,常用的mysql主從拓撲結構

復制的體系結構有以下一些基本原則:

(1) 每個slave只能有一個master;

(2) 每個slave只能有一個唯一的服務器ID;

(3) 每個master可以有很多slave;

(4) 如果你設置log_slave_updates,slave可以是其它slave的master,從而擴散master的更新。

MySQL不支持多主服務器復制(MultimasterReplication)——即一個slave可以有多個master。但是,通過一些簡單的組合,我們卻可以建立靈活而強大的復制體系結構。

9,mysql主從同步之間的管理

介紹一下基本的mysql主從的管理操作命令:

9.1 停止mysql從服務

STOP SLAVE IO_THREAD; #停止IO進程

STOP SLAVE SQL_THREAD; #停止SQL進程

STOP SLAVE; #停止IO和SQL進程

9.2 開啟mysql主從同步服務

START SLAVE IO_THREAD; #啟動IO進程

START SLAVE SQL_THREAD; #啟動SQL進程

START SLAVE; #啟動IO進程和SQL進程

9.3 重置mysql主從同步

RESET SLAVE;

#用於讓從屬服務器忘記其在主服務器的二進制日志中的復制位置, 它會刪除master.info和relay-log.info文件,以及所有的中繼日志,並啟動一個新的中繼日志,當你不需要主從的時候可以在從上執行這個操作。不然以後還會同步,可能會覆蓋掉你的數據庫。

9.4 查看主從同步狀態

SHOW SLAVE STATUS;

#這個命令主要查看Slave_IO_Running、Slave_SQL_Running、Seconds_Behind_Master、Last_IO_Error、Last_SQL_Error這些值來把握復制的狀態。

9.5 臨時跳過MYSQL同步錯誤

#經常會朋友mysql主從同步遇到錯誤的時候,比如一個主鍵沖突等,那麼我就需要在確保那一行數據一致的情況下臨時的跳過這個錯誤,那就需要使用SQL_SLAVE_SKIP_COUNTER = n命令了,n是表示跳過後面的n個事件,比如我跳過一個事件的操作如下:

STOP SLAVE;

SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;

START SLAVE;

9.6 從指定位置重新同步數據

#有的時候主從同步有問題了以後,需要從log位置的下一個位置進行同步,相當於跳過那個錯誤,這時候也可以使用CHANGE MASTER命令來處理,只要找到對應的LOG位置就可以,比如:

CHANGE MASTER TOMASTER_HOST='10.1.1.75',MASTER_USER='replication',MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000006',MASTER_LOG_POS=106;

START SLAVE;

PS:生產環境中這種操作盡量能避免就避免。

10,線上維護mysql主從需要注意的事項

1. 不要亂使用SQL_SLAVE_SKIP_COUNTER命令。

這個命令跳過之後很可能會導致你的主從數據不一致,一定要先將指定的錯誤記錄下來,然後再去檢查數據是否一致,尤其是核心的業務數據。

2. 結合percona-toolkit工具pt-table-checksum定期查看數據是否一致。

這個是DBA必須要定期做的事情,呵呵,有合適的工具何樂而不為呢?另外percona-toolkit還提供了對數據庫不一致的解決方案,可以采用pt-table-sync,這個工具不會更改主的數據。還可以使用pt-heartbeat來查看從服務器的復制落後情況。

3. 使用replicate-wild-ignore-table選項而不要使用replicate-do-db或者replicate-ignore-db。

原因已經在上面做了說明。

4. 將主服務器的日志模式調整成mixed。

5. 每個表都加上主鍵,主鍵對數據庫的同步會有影響尤其是居於ROW復制模式。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved