主從同步
第一篇文章說過,初始版本的系統(tǒng)一直單庫(kù)運(yùn)行,所有的讀、寫,以及數(shù)據(jù)存儲(chǔ)都放在了同一臺(tái)dbserver中。出現(xiàn)問題,哭都沒地方...于是...增加多個(gè)dbserver,單主庫(kù)多從庫(kù),避免出現(xiàn)單庫(kù)數(shù)據(jù)文件問題導(dǎo)致的數(shù)據(jù)損失...
修改數(shù)據(jù)文件的存儲(chǔ)位置
mysql默認(rèn)的數(shù)據(jù)庫(kù)文件是放在安裝目錄下的(/var/lib/mysql),先把這個(gè)路徑設(shè)定到阿里云數(shù)據(jù)盤,防止系統(tǒng)更新或者其他問題時(shí)造成數(shù)據(jù)文件損壞。
使用root用戶或具有root權(quán)限的用戶,在目標(biāo)路徑下新建一個(gè)目錄,比如叫做mysqldata,并修改其權(quán)限
mkdir /alidata1/mysqldata
chown -R mysql:mysql /alidata1/mysqldata/ ← 改變數(shù)據(jù)庫(kù)的歸屬為mysql把MySQL服務(wù)進(jìn)程停掉(一開始就做了,或者半夜干吧...):
mysqladmin -u root -p shutdown把/var/lib/mysql整個(gè)目錄移到/alidata1/mysqldata
mv /var/lib/mysql /alidata1/mysqldata找到my.cnf配置文件,如果/etc/目錄下沒有my.cnf配置文件,請(qǐng)到/usr/share/mysql/下找到*.cnf文件,拷貝其中一個(gè)到/etc/并改名為my.cnf)中。命令如下:
cp /usr/share/mysql/my-medium.cnf /etc/my.cnf-
編輯MySQL的配置文件/etc/my.cnf,為保證MySQL能夠正常工作,需要指明mysql.sock文件的產(chǎn)生位置。修改socket=/var/lib/mysql/mysql.sock一行中等號(hào)右邊的值為:/alidata1/mysqldata/mysql.sock 。操作如下:
vi my.cnf (用vi工具編輯my.cnf文件,找到下列數(shù)據(jù)修改之)
# The MySQL server[mysqld] port = 3306
#socket = /var/lib/mysql/mysql.sock(原內(nèi)容,為了更穩(wěn)妥用“#”注釋此行)
socket = /alidata1/mysqldata/mysql.sock?。由洗诵校?/p>// 為了防止binlog日志擠爆硬盤,加入另外的配置: expire_logs_days = 10 (表示binlog日志過期時(shí)間,單位為天,注意這個(gè)配置是在每次切換新的log文件時(shí)才會(huì)清除對(duì)應(yīng)的log文件的。也可以在mysql運(yùn)行期間命令行執(zhí)行 set global expire_log_days=10) 修改MySQL啟動(dòng)腳本/etc/init.d/mysql,把其中datadir=/var/lib/mysql一行中,等號(hào)右邊的路徑改成你現(xiàn)在的實(shí)際存放路徑:/alidata1/mysqldata
vi /etc/init.d/mysql
#datadir=/var/lib/mysql(注釋此行)
datadir=/alidata1/mysqldata (加上此行)
如果是CentOS還要改 /usr/bin/mysqld_safe 相關(guān)文件位置;最后 做一個(gè)mysql.sock 鏈接:
ln -s /home/data/mysql/mysql.sock /var/lib/mysql/mysql.sock重新啟動(dòng)MySQL服務(wù)
/etc/init.d/mysqld start
主庫(kù)設(shè)置成功后,其他的從庫(kù)也全都按照同樣的步驟來操作。
導(dǎo)出及導(dǎo)入數(shù)據(jù)
- 在主庫(kù)服務(wù)器中執(zhí)行以下命令,用于導(dǎo)出對(duì)應(yīng)的數(shù)據(jù)庫(kù)
mysqldump -u mysqlsuperuser -p dbname> dbname.sql - 在從庫(kù)中先建立同名數(shù)據(jù)庫(kù)
mysql -u mysqlsuperuser -p
create database dbname - 使用scp或者別的命令將dbname.sql拷貝到對(duì)應(yīng)的從庫(kù)服務(wù)器(們),并導(dǎo)入:
mysql -u mysqlsuperuser -p
source /path/dbname.sql
在主從庫(kù)中創(chuàng)建用于同步的數(shù)據(jù)庫(kù)用戶
- 創(chuàng)建用戶
create user 'dbcopy'@'%' identified by '****' - 賦相應(yīng)的權(quán)限
- 主庫(kù)
grant replication slave,replication client on . to 'dbcopy'@'%' identified by '****'; - 從庫(kù)
grant replication slave,replication client on . to 'dbcopy'@'%' identified by '****';
......
- 主庫(kù)
配置同步選項(xiàng)
修改主庫(kù)的my.cnf文件
log_bin = mysql-bin
server_id = 21013 (必須明確地指定一個(gè)唯一的服務(wù)器ID 此處取服務(wù)器Ip的最后兩個(gè)段).
如果之前沒有在mysql 的配置文件中指定log_bin 就需要重新啟動(dòng)Mysql。 為了確認(rèn)二進(jìn)制日志文件是否已經(jīng)在主庫(kù)上創(chuàng)建,使用以下命令查看
show master status;修改各從庫(kù)的my.cnf文件
備庫(kù)上也需要做同樣的配置,并重啟數(shù)據(jù)庫(kù)
log_bin = mysql-bin
server_id = 208246
relay_log = /var/lib/mysql/mysql-relay-bin (指定中繼日志的位置和命名)
log_slave_updates = 1 (允許備庫(kù)將其重放的事件也記錄到自身的二進(jìn)制日志)
read_only = 1(只讀模式,防止多端同時(shí)寫數(shù)據(jù)造成各個(gè)點(diǎn)的數(shù)據(jù)不同步)開啟復(fù)制
在從庫(kù)中執(zhí)行以下命令
CHANGE MASTER TO MASTER_HOST='masterIP',
MASTER_USER='dbcopy',
MASTER_PASSWORD='****',
MASTER_LOG_FILE = 'mysql-bin.000002',
MASTER_LOG_POS=0;
其中master_log_file和master_log_pos的值都是在主庫(kù)中使用show master status來取到的。剛開始配置時(shí),pos位置可以指定為0常用命令
SHOW SLAVE STATUS; //查看配置信息。
START SLAVE;//開啟復(fù)制。
STOP SLAVE; //停止復(fù)制-
其他配置
- 推薦的復(fù)制配置
在主庫(kù)上二進(jìn)制日志最重要的選項(xiàng)是:
sync_binlog =1
如果開啟該選項(xiàng),mysql每次在提交事物請(qǐng)會(huì)將二進(jìn)制日志同步到磁盤上,保證在服務(wù)器崩潰的時(shí)候不會(huì)丟失事件。 - 如果使用InnoDB 強(qiáng)烈推薦設(shè)置如下選項(xiàng):
innodb_flush_logs_at_trx_commit
innodb_support_xa=1
innodb_safe_binlog
- 推薦的復(fù)制配置
如果正在使用mysql 5.5 ,最好設(shè)置以下選項(xiàng):
sync_master_info=1
sync_replay_log = 1
sync_relay_long_info =1
出現(xiàn)數(shù)據(jù)不同步時(shí)的處理方案
當(dāng)出現(xiàn)數(shù)據(jù)不同步時(shí),一般執(zhí)行 show slave status;會(huì)有以下結(jié)果:

Slave_IO_Running:連接到主庫(kù),并讀取主庫(kù)的日志到本地,生成本地日志文件
Slave_SQL_Running:讀取本地日志文件,并執(zhí)行日志里的SQL命令。
一般是出現(xiàn)同步錯(cuò)誤或者master_log的info出現(xiàn)了變化,相應(yīng)的解決方案如下:
- 同步錯(cuò)誤解決方案:
slave stop;
set GLOBAL SQL_SLAVE_SKIP_COUNTER=1; //值為1表示跳過一個(gè)錯(cuò)誤,可以設(shè)置為N。不過跳過去的數(shù)據(jù)就跟主庫(kù)不同步了,要手動(dòng)處理
slave start;
show slave status; // 查看同步狀態(tài)是否恢復(fù)正常了
- 主庫(kù)日志信息變更導(dǎo)致的錯(cuò)誤解決方案
查看主庫(kù)
show master status; //記錄下File,Position字段,假設(shè)為‘mysql-bin.000004’,98;
在從庫(kù)中執(zhí)行以下命令:
stop slave;
change master to master_log_file='mysql-bin.000004',master_log_pos=98;
start slave;
show slave status; //查看同步狀態(tài)