一、複製準備
(1)定義機器角色:
主庫 192.168.11.34 port 3306
[root@master ~]# cat /etc/sysconfig/network
HOSTNAME=master
從庫 192.168.11.35 port 3306
[root@slave ~]#cat /etc/sysconfig/network
HOSTNAME=slave
提示:一般做主從,主從服務器在不同的機器上,監聽端口爲3306。可以根據實際情況進行修改。
(2)主庫上執行操作
設置server-id值並開啓binlog設置
根據mysql的同步原理,我們知道複製的關鍵因素就是binlog日誌。
執行[root@master ~]# vim /etc/my.cnf,編輯my.cnf配置文件,添加兩個參數
[mysqld]
server_id = 34
log_bin =/usr/local/data/mysql-bin
注意:上述兩個參數必須放在my.cnf配置文件[mysqld]中,否則報錯。
server_id = 34可以是服務器IP後以爲,避免重複。
修改配置文件後需要重啓mysql。
[root@master data]# grep -E "server-id|log-bin" /etc/my.cnf 檢查配置結果
server-id = 34
log-bin = /usr/local/data/mysql-bin
(3)建立用於從庫複製的賬號tangbo
mysql> grant replication slave on *.* to 'tangbo'@'192.168.11.%' identified by '111111';
Query OK, 0 rows affected (0.00 sec)
mysql>replication slave 爲mysql同步必須權限,此處不要授權all。*.*表示所有庫所有表。
查看已經創建的用戶
mysql> select user,host from mysql.user;
+--------+---------------+
| user | host |
+--------+---------------+
| root | 127.0.0.1 |
| tangbo | 192.168.11.%
(4)鎖表只讀(當前窗口不要關掉)
生產環境執行鎖表操作時,會影響業務。 需申請停機時間
mysql> flush tables with read lock;
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> create database test1;
ERROR 1223 (HY000): Can't execute the query because you have a conflicting read lock 創建不了庫,鎖表成功
mysql> select * from renchuan.caiwu; 執行查詢無任何問題
+----+--------+------+----------+------+------------+
| id | name | ages | job | pay | time |
+----+--------+------+----------+------+------------+
| 1 | tangbo | 27 | wangguan | 3000 | 2015-12-20 |
+----+--------+------+----------+------+------------+
1 row in set (0.00 sec)
mysql>
提示:這個鎖表命令的時間,在不同引擎的情況,有可鞥受如下參數的控制。鎖表時,如果超過設置時間不操作會自動解鎖。
interactive_timeout = 60
wait_timeout = 60
默認時常爲:
mysql> show variables like '%timeout%';
+-----------------------------+----------+
| Variable_name | Value |
+-----------------------------+----------+
| connect_timeout | 10 |
| delayed_insert_timeout | 300 |
| innodb_flush_log_at_timeout | 1 |
| innodb_lock_wait_timeout | 50 |
| innodb_rollback_on_timeout | OFF |
| interactive_timeout | 28800 |
| lock_wait_timeout | 31536000 |
| net_read_timeout | 30 |
| net_write_timeout | 60 |
| rpl_stop_slave_timeout | 31536000 |
| slave_net_timeout | 3600 |
| wait_timeout | 28800 |
+-----------------------------+----------+
12 rows in set (0.00 sec)
mysql>
(5)查看主庫狀態 即查看當前日誌文件名和二進制偏移量
mysql> show master status;命令顯示的信息要記錄下來,後面從庫的複製是從這個位置開始的。
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000013 | 331 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
mysql>
(6)新開窗口,導出數據庫數據,如果量很大(+100G),且可以停機,直接打包數據遷移。
[root@master data]# mkdir /server/backup/ -p 創建備份目錄
[root@master /]# mysqldump -uroot -ptangbo -A -B|gzip > /server/backup/mysql.bak.$(date +%F).sql.gz
執行備份命令, -A表示備份所有庫,-B表示增加use 數據庫名和drop等(導庫時會直接覆蓋原有的)。
導爲了確保導庫期間,數據庫沒有數據插入,可以再檢查下主庫狀態信息。
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000013 | 331 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
提示:無特殊情況,binlog文件及文件點事保持不變的。
mysql>
(7)導庫完成後,解鎖主庫,恢復可寫。
mysql> unlock table;
二、開始遷移數據
(1)把主庫備份的mysql數據遷移到從庫,通常可以使用scp,rsync
[root@master backup]# scp mysql.bak.2015-12-22.sql.gz [email protected]:/tmp
[email protected]'s password:
mysql.bak.2015-12-22.sql.gz 100% 164KB 163.9KB/s 00:00
[root@master backup]#
三、主庫設置完畢,可以開始操作從庫;
(1)設置server-id值並關閉binlog設置
[mysqld]
server_id = 34
#log_bin =/usr/local/data/mysql-bin
注意:上述兩個參數必須放在my.cnf配置文件[mysqld]中,否則報錯
server_id = 34可以是服務器IP後以爲,避免重複。
修改配置文件後需要重啓mysql
(2)檢查配置文件
[root@master data]# grep -E "server-id|log-bin" /etc/my.cnf 檢查配置結果
[root@slave tmp]# grep -E "server-id|log-bin" /etc/my.cnf
server-id = 35
#log-bin =/usr/local/data/mysql-bin
[root@slave tmp]#
(3)還原主庫導出的數據庫到從庫
[root@slave tmp]# gzip -d mysql.bak.2015-12-22.sql.gz 解壓
[root@slave tmp]# mysql -uroot -ptangbo <mysql.bak.2015-12-22.sql 恢復數據導從庫
下面可以去檢查下恢復的數據是否成功。
mysql> desc caiwu;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(30) | NO | PRI | NULL | auto_increment |
| name | varchar(60) | NO | | NULL | |
| ages | varchar(60) | YES | | NULL | |
| job | varchar(30) | YES | | NULL | |
| pay | float | YES | | NULL | |
| time | date | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)
mysql>
(4)登陸從庫配置同步參數:或不登陸數據庫,在命令行快速執行change master的語句(適合在腳本中批量創建slave庫用)
登陸數據庫執行:
change master to #連接master庫
master_host='192.168.11.34', #主庫的IP
master_port=3306, #這裏是主庫的端口,從庫端口可以和主庫不同
master_user='tangbo', #主庫上建立的用於複製的用戶名
master_password='111111', ##主庫上建立的用於複製的密碼
master_log_file='mysql-bin.000013', #show master status時看到的查看二進制日誌文件名稱,不能多出空格來
master_log_pos=331; #show master status時看到的二進制日誌的偏移量,不能多出空格來
下面這個可以直接複製:
change master to
master_host='192.168.11.34',
master_port=3306,
master_user='tangbo',
master_password='111111',
master_log_file='mysql-bin.000013',
master_log_pos=331;
腳本下寫法:
cat | mysql -uroot -ptangbo << EOF
change master to
master_host='192.168.11.34',
master_port=3306,
master_user='tangbo',
master_password='111111',
master_log_file='mysql-bin.000013',
master_log_pos=331;
EOF
四、啓動從庫同步開關
啓動從庫同步開關,並查看同步狀態
登陸數據庫後執行: start slave
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.11.34 #當前mysql master服務器主機
Master_User: tangbo
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000013
Read_Master_Log_Pos: 634818
Relay_Log_File: slave-relay-bin.000002
Relay_Log_Pos: 634770
Relay_Master_Log_File: mysql-bin.000013
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: 634818
Relay_Log_Space: 634943
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: 34
Master_UUID: 3a53cf38-9a9f-11e5-bdc9-52540055b912
Master_Info_File: /usr/local/data/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
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
1 row in set (0.00 sec)
判斷是否搭建成功就看IO和SQL兩個線程是否顯示爲yes狀態。
Slave_IO_Running: Yes #負責從庫去主庫讀取BINLOG日誌,並寫入從庫的中繼日誌中
Slave_SQL_Running: Yes #負責讀取並執行中繼日誌的binlog,轉換SQL語句後應用到數據庫彙總
提示:有關show master status 查看mysql手冊
測試複製結果
五、相關mysql技術技巧概覽
(1)配置忽略權限庫同步參數
binlog-ignore-db=information_schema
binlog-ignore-db=mysql
(2)主從複製故障解決
show slave status;
有報錯:Error xxxx desn't exist
且 mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_Running: Yes
Slave_SQL_Running: No
Seconds_Behind_Master: NULL
解決辦法:
stop slave;
set global sql_slave_skip_counter =1; #=n表示忽略執行N個更新
start slave;
這樣,Slave就會和Master去同步:主要看點:
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_Running: Yes
Slave_SQL_Running: YES
Seconds_Behind_Master: 0 #0表示已經同步狀態
(3)讓mysql slave 記錄binlog方法
在從庫my.cnf中加入如下參數
log-slave-updates
log-bin=mysql13307-bin
expire logs days = 7
應用場景:級聯複製或從庫做數據備份
(4)嚴格設置從庫只讀
read-only的妙用,詳情出查看文檔
(5)生產環境確保從庫只讀?
1.mysql從服務器中加入 read-only參數
。 2.忽略mysql庫已經information_schema庫同步
3.授權從庫用戶時僅僅授權selesct權限。
(6)生產環境主庫用戶的授權;
grant select,insert,update,delete on bbpay.* to 'test'@'localhost' identified by '111111';
(7)生產環境從庫用戶的授權
1.grant select on bbpay.* to 'test'@'localhost' identified by '111111';
2.在my.cnf中添加read-only參數
六、生產環境主從庫注意事項:
(1)第一次做從庫如何做?
假如你的服務器只有主庫,而且跑了應用了,現在由於業務需要第一個做從庫,此時可能需要申請停機維護世界,;可以再
用戶訪問量最小,且不影響內部其他業務運轉的時間點來停機配置主從複製,一般都在凌晨進行。
當然,也可以不申請,在定時任務備份時,每天夜裏定時備份時做一些任務。
(2)不加班工作時間從容配置從庫
當然了,也可以不申請,在定時任務備份時,每天的夜裏服務器壓力小時定時備份時做一些措施即可。
1.鎖表備份全備一份
2.鎖表前後取得show master status值記錄到日誌裏。
這樣就可以再白天從容的實現主從同步了,這個腳本還是比較簡單:如
[root@master tmp]# cat mysql_bak.sh
#!/bin/bash
##############################
#scripts by tangbo
#qq 79313760
##############################
mkdir -p /server/backup
MYUSER=root
MYPASS="tangbo"
MAIN_PATH=/server/backup
DATA_PATH=/server/backup
LOG_FILE=${DATA_PATH}/mysqllogs_`date +%F`.log
DATA_FILE=${DATA_PATH}/mysql_backup_`date +%F`.sql.gz
MYSQL_PATH=/usr/local/mysql/bin
MYSQL_CMD="$MYSQL_PATH/mysql -u$MYUSER -p$MYPASS"
MYSQL_DUMP="$MYSQL_PATH/mysqldump -u$MYUSER -p$MYPASS -A -B --flush-logs --single-transaction -e"
$MYSQL_CMD -e "flush tables with read lock;"
echo "----------show master status result----------" >> $LOG_FILE
$MYSQL_CMD -e "show master status;" >> $LOG_FILE
${MYSQL_DUMP} | gzip > $DATA_FILE
$MYSQL_CMD -e "unlock tables;"
mail -s "mysql slave log" [email protected] < $LOG_FILE
[root@master tmp]#
提示:腳本實際上就是把主從製作的過程自動化。
執行過程與結果:
[root@master tmp]# ls -l /server/backup/
total 336
-rw-r--r--. 1 root root 170596 Dec 22 21:32 mysql_backup_2015-12-22.sql.gz
-rw-r--r--. 1 root root 167799 Dec 22 00:52 mysql.bak.2015-12-22.sql.gz
-rw-r--r--. 1 root root 135 Dec 22 21:32 mysqllogs_2015-12-22.log
[root@master tmp]#
[root@master tmp]# cat /server/backup/mysqllogs_2015-12-22.log
----------show master status result----------
File Position Binlog_Do_DB Binlog_Ignore_DB Executed_Gtid_Set
mysql-bin.000013 634818
[root@master tmp]#
(3)有了主庫備份文件和mysql-bin.000013內容做從庫就很簡單了。
下面開始不停主庫一鍵批量創建從庫;首先,把mysql_backup_2015-12-22.sql.gz發佈到想做從庫的機器上,也許N臺。
開始製作批量做從庫腳本,一鍵完成多臺從庫的製作:
[root@master tmp]# cat mysql_slave.sh
#!/bin/bash
##############################
#scripts by tangbo
#qq 79313760
##############################
MYUSER=root
MYPASS="tangbo"
MAIN_PATH=/server/backup
DATA_PATH=/server/backup
LOG_FILE=${DATA_PATH}/mysqllogs_`date +%F`.log
DATA_FILE=${DATA_PATH}/mysql_backup_`date +%F`.sql.gz
MYSQL_PATH=/usr/local/mysql/bin
MYSQL_CMD="$MYSQL_PATH/mysql -u$MYUSER -p$MYPASS"
#reconver
cd ${DATA_PATH}
gzip -d mysql_backup_`date +%F`.sql.gz
$MYSQL_CMD < mysql_backup_`date +%F`.sql.gz
#config slave
cat | $MYSQL_CMD << EOF
change master to
master_host='192.168.11.34',
master_port=3306,
master_user='tangbo',
master_password='111111',
master_log_file='mysql-bin.000013',
master_log_pos=331;
EOF
echo "----------show master status result----------" >> $LOG_FILE
$MYSQL_CMD -e "show slave status\G" |grep "IO_Running|SQL_Running" >> $LOG_FILE
mail -s "mysql slave log" [email protected] < $LOG_FILE
[root@master tmp]#
注意:上面腳本中change master 參數要根據mysqllogs_2015-12-22.log修改。
(4)主從庫給開發人員讀寫分離用戶的設置:
如: 主庫(提供寫服務): blog tangbo123 ip=192.168.111.1 port=3306
從庫(僅僅提供讀服務): blog tangbo123 ip=192.168.111.2 port=3306