手把手教你实现MySQL双机数据同步

 2022-10-27    424  

编者按:很多朋友一开始接触MySQL双机同步需求的时候可能会感到不知道从哪里入手,事实上这是MySQL本身就支持的功能之一。本文提供有关MySQL主从同步的初步思路,供大家参考。

一.需求问题

手把手教你实现MySQL双机数据同步

假设目前有两台 MySQL 数据库服务器,如何实现这两台机器的数据同步问题?即在一台机器上修改数据库后,另一台机器会同步更新所修改的信息。

二.解决方案

查资料发现 MySQL 支持单向,异步复制,复制过程中一个服务器充当主服务器,而另一个或多个其他服务器充当从服务器。

原理是这样的:

主服务器将更新写入二进制日志文件,并维护文件的一个索引来跟踪日志循环。这些日志可以记录发送到从服务器的更新。当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接受从那时起发生的任何更新,然后封锁并等待主服务器通知新的更新。

2.1 测试环境

Master:192.168.7.67(CentOS5.5x86_64)MySQLVersion:5.0.77 
Slave:192.168.56.103(CentOS5.3i386)MySQLVersion:5.0.45

备注:

Master 和 slave 端的 MySQL 版本最好要一样的,或者 Master 端的版本高于 Slave 端

2.2 配置过程

2.2.1 Master 端设置

开启 MySQL 服务并新建一个测试数据库 abc:

root@camlit~:/etc/init.d/mysqldstart 
jian.ma@camlit~:mysql-uroot-p 
Enterpassword:xxxx 
WelcometotheMySQLmonitor.Commandsendwith;or\g. 
YourMySQLconnectionidis3 
Serverversion:5.0.77Sourcedistribution 

Type'help;'or'\h'forhelp.Type'\c'toclearthebuffer. 

mysql>createdatabaseabc; 
QueryOK,1rowaffected(0.31sec) 

###创建一个用来同步的用户,指定只能在192.168.56.103登录 
###REPLICATIONSLAVE:Enablereplicationslavestoreadbinarylogeventsfromthemaster 

mysql>grantreplicationslaveon*.*to'test1'@'192.168.56.103'identifiedby'test1'; 
QueryOK,0rowsaffected(0.16sec)

修改配置文件:

root@camlit~:vi/etc/my.cnf

备注:在修改配置文件之前做好该文件的备份工作。

[mysqld] 
datadir=/var/lib/mysql 
socket=/var/lib/mysql/mysql.sock 
user=mysql 
old_passwords=1 

##增加下面内容 
server_id=1###1表示master,2表示slavebinlog-do-db=abc###需要同步的数据库,如果有多个数据库,每个数据库一行binlog-ignore-db=mysql###不需要同步的数据库log-bin=mysql-bin 
 
[mysqld_safe] 
log-error=/var/log/mysqld.log 
pid-file=/var/run/mysqld/mysqld.pid

重启服务:

root@camlit~:/etc/init.d/mysqldrestart

2.2.2 Slave 端设置

和 master 端一样创建一个相同的数据库: abc

Enterpassword: 
WelcometotheMySQLmonitor.Commandsendwith;or\g. 
YourMySQLconnectionidis5 
Serverversion:5.0.45-logSourcedistribution 
 
Type'help;'or'\h'forhelp.Type'\c'toclearthebuffer. 
 
mysql>createdatabaseabc; 
QueryOK,1rowaffected(0.31sec)

修改配置文件:

root@test2~:vi/etc/my.cnf

[mysqld] 
datadir=/var/lib/mysql 
socket=/var/lib/mysql/mysql.sock 
user=mysql 
old_passwords=1 
 
###增加下面内容 
server_id=2log-bin=mysql-binmaster-host=192.168.7.67master-user=test1master-password=test1master-port=3306master-connect-retry=10###连接次数replicate-do-db=abc###接受的数据库名replicate-ignore-db=mysql###不要接受的数据库 
 
[mysqld_safe] 
log-error=/var/log/mysqld.log 
pid-file=/var/run/mysqld/mysqld.pid

重启服务:

root@test2~:/etc/init.d/mysqldrestart

备注:

配置成功 后会在 mysql 目录(/var/lib/mysql/)下生成 master.info 文件,如果要更改 slave 设置,要先将该文件删除才会起作用。

进入 mysql,输入下面命令:

root@test2~:mysql-uroot-p 
Enterpassword: 
WelcometotheMySQLmonitor.Commandsendwith;or\g. 
YourMySQLconnectionidis4 
Serverversion:5.0.45-logSourcedistribution 
 
Type'help;'or'\h'forhelp.Type'\c'toclearthebuffer. 
 
mysql>slavestart; 
QueryOK,0rowsaffected,1warning(0.00sec) 
###查看同步情况 
mysql>showslavestatus;或showmasterstatus;

2.3 结果测试

在 Master 端进行数据库 abc 的一些操作,如下所示:

jian.ma@camlit~:mysql-uroot-p 
Enterpassword: 
WelcometotheMySQLmonitor.Commandsendwith;or\g. 
YourMySQLconnectionidis3 
Serverversion:5.0.77-logSourcedistribution 
 
Type'help;'or'\h'forhelp.Type'\c'toclearthebuffer. 
 
mysql>useabc; 
Databasechanged 
mysql>createtabletest1(IPVARCHAR(20),USERVARCHAR(100),MAIL 
VARCHAR(100)); 
QueryOK,0rowsaffected(1.20sec) 
mysql>insertintotest1(IP,USER,MAIL)values('192.168.7.66','test','test@test.com.cn'); 
QueryOK,1rowaffected(0.06sec)

在 Slave 端查看是否能够更新:

root@test2~:mysql-uroot-p 
Enterpassword: 
WelcometotheMySQLmonitor.Commandsendwith;or\g. 
YourMySQLconnectionidis6 
Serverversion:5.0.45-logSourcedistribution 
 
Type'help;'or'\h'forhelp.Type'\c'toclearthebuffer. 
 
mysql>showdatabases; 
+--------------------+ 
|Database| 
+--------------------+ 
|information_schema| 
|foo| 
|mysql| 
|test| 
|abc| 
+--------------------+ 
5rowsinset(0.00sec) 
mysql>useabc; 
Readingtableinformationforcompletionoftableandcolumnnames 
Youcanturnoffthisfeaturetogetaquickerstartupwith-A 
Databasechanged 
mysql>showtables; 
+---------------+ 
|Tables_in_abc| 
+---------------+ 
|test1| 
+---------------+ 
1rowinset(0.03sec) 
mysql>select*fromtest1; 
+--------------+------+------------------+ 
|IP|USER|MAIL| 
+--------------+------+------------------+ 
|192.168.7.66|test|test@test.com.cn| 
+--------------+------+------------------+ 
1rowinset(0.00sec)

从上面的结果可以看到 Master 端的数据可以同步到 Slave 端里面。说明此时主从数据库的同步问题已经成功解决。

#p#

三.补充资料

关于如何连接到远程 MySQL 问题,可以采取下面的步骤:

首先先登录到远程机器:

jian.ma@camlit~:sshroot@192.168.56.103 
password:xxx 
root@test2~:

编辑配置文件:

root@test2~:vi/etc/my.cnf

增加下面一行内容:

[mysqld] 
datadir=/var/lib/mysql 
socket=/var/lib/mysql/mysql.sock 
user=mysql 
old_passwords=1 
bind-address=192.168.56.103###此IP地址为MySQL本机的IP地址 
[mysqld_safe] 
log-error=/var/log/mysqld.log 
pid-file=/var/run/mysqld/mysqld.pi

重启服务:

root@test2~:/etc/init.d/mysqldrestart

创建测试数据库:

root@test2~:mysql-uroot-p 
Enterpassword: 
WelcometotheMySQLmonitor.Commandsendwith;or\g. 
YourMySQLconnectionidis2 
Serverversion:5.0.45Sourcedistribution 
 
Type'help;'or'\h'forhelp.Type'\c'toclearthebuffer. 
 
mysql>createdatabasefoo; 
QueryOK,1rowaffected(0.00sec) 
###增加用户test123从任何主机登录到MySQL 
mysql>grantallprivilegeson*.*to'test123'@'%'identifiedby'test123'withgrantoption; 
QueryOK,0rowsaffected(0.00sec) 
###增加用户test1从192.168.7.67主机登录到MySQL 
mysql>grantallprivilegesonfoo.*to'test1'@'192.168.7.67'identifiedby'test1'withgrantoption; 
QueryOK,0rowsaffected(0.00sec)

如果有防火墙的设置的话,可以如下设置:

root@test2~:iptables-AINPUT-ieth0-s192.168.7.67-ptcp--dport3306-jACCEPT 
root@test2~:/etc/init.d/iptalessave

最后在客户端就可以输入下面命令来远程进入 MySQL 数据库:

jian.ma@camlit~:mysql-utest1-h192.168.56.103-p 
Enterpassword: 
WelcometotheMySQLmonitor.Commandsendwith;or\g. 
YourMySQLconnectionidis13 
Serverversion:5.0.45Sourcedistribution 
Type'help;'or'\h'forhelp.Type'\c'toclearthebuffer.

mysqld.pl内容如下:

#!/usr/bin/perl

#Thisscriptisusedtocheckifthemysqlreplicationisok

usestrict;
useDBI;
usePOSIX"strftime";

my$host="192.168.56.103";
my$user="test1";
my$passwd="test1";
my$port="3306";
my$max_behind="120";
my$check_log="./mysql_check.log";


#Openthelogfile
open(FH,">>$check_log")ordie$!;

#Connectthemysqlserver
my$dbh=&MysqlConnect($host,$port,$user,$passwd);


#Getslavesqlstatus
my$slave_status=&MysqlQuery($dbh,'showslavestatus');
printFH"Error:SQLQueryError:".$dbh->errstr;


my$slave_IO=$slave_status->{Slave_IO_Running};
my$slave_SQL=$slave_status->{Slave_SQL_Running};
my$seconds_behind_master=$slave_status->{Seconds_Behind_Master};
my$now_time=POSIX::strftime("[%Y-%m-%d%H:%M:%S]",localtime);


print"ChecktheSlaveMySQLstauts....\n";
print"_"x50,"\n";
print"Time:\t\t\t$now_time\n";
print"SlaveIORunning:\t\t$slave_IO\n";
print"SlaveSQLRunning::\t\t$slave_SQL\n";
print"BehindMasterSeconds:\t\t$seconds_behind_master\n";


if($seconds_behind_master>$max_behind){
print"SlaveSQLServerisfarbehindmaster";
}


#---Functions----#
subMysqlConnect{

my($host,$port,$user,$passwd)=@_;
my$dsn="DBI:mysql:host=$host;port=$port";
returnDBI->connect($dsn,$user,$passwd,{RaiseError=>1});
}


subMysqlQuery{

my($dbh,$query)=@_;
my$sth=$dbh->prepare($query);
my$res=$sth->execute;
returnundefunless$res;
my$row=$sth->fetchrow_hashref;
$sth->finish;
return$row;
}

  •  标签:  
  • MySQL
  •  

原文链接:https://77isp.com/post/4259.html

=========================================

https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。