一.设置步骤
1.首先设置Master端
修改my.ini,必须设置的就两个地方:
[mysqld]
log-bin=mysql-bin
server-id=1
我们也会为从机设定log-bin,这是因为默认的log-bin文件是根据主机名命名的,一旦机器更改主机名就会出问题,再者保持主从机的配制一致也方便做主从机切换!
主机可选的配置项:(用于配置主机哪些库会做二进制日志用以Replicate)
binlog-do-db
binlog-ignore-db
从机可选的配置项:(用于配置从机会Replicate哪些库和表)
replicate-do-db, replicate-ignore-db
replicate-do-table, replicate-ignore-table
replicate-wild-do-table
replicate-wild-ignore-table
注意:一条建议是不要my.ini中配制master_host等选项,而应该使用CHANGE MASTER TO命令来动态设置!
对于Master端,我只需简单地设置server_id和log_bin两项即可,对于Slave端其实只需要设置server_id。
从服务器的配置:
# SLAVE-END replication-related configuration.
# The only required option for slave-end is server_id.
# The other options are recommanded on P 349 of《Hight Performance MySql》
server_id=2
log_bin=mysql_bin//开启二进制日志
relay_log = mysql_relay_bin//配置中继日志
log_slave_updates = 1//表示slave将复制事件写进自己的二进制日志
read_only = 1 //防止改变数据(除了特殊的线程)。
#下面参数根据实际情况配置,可以全库同步,可以个别表同步。这两个参数可出现多次。replicate-do-db = 要同步的库1
replicate-do-db = 要同步的库2
replicate-do-table = 某库.要同步的表1
replicate-do-table = 某库.要同步的表2
2.在主服务器创建备份账号
账号为slave,密码为0487521,且只能在IP为192.168.23.145上登录。具有replication slave和replication client权限。
GRANT REPLICATION SLAVE ,REPLICATION CLIENT ON *.* TO 'slave'@'192.168.23.145' IDENTIFIED BY '0487521';
3.拷贝数据
(假如是你完全新安装mysql主从服务器,这个一步就不需要。因为新安装的master和slave有相同的数据)关停Master服务器,将Master中的数据拷贝到B服务器中,使得Master和slave中的数据同步,并且确保在全部设置操作结束前,禁止在Master和slave服务器中进行写操作,使得两数据库中的数据一定要相同!
4..连接从服务器至主服务器进行Replicate
通过在从服务器上输入CHANGE MASTER TO命令可以使从服务连接到某个主服务器上进行replication.
CHANGE MASTER TO MASTER_HOST='192.168.23.119',MASTER_USER='slave',MASTER_PASSWORD='0487521',MASTER_LOG_FILE='mysql-bin.000027',
MASTER_LOG_POS=120;
MASTER_LOG_POS的值为0,因为它是日志的开始位置。
其中的:
MASTER_LOG_POS=0;
MASTER_LOG_FILE='mysql-bin.000001',
从show master status可以获取。
Master_Log_File和Read_Master_Log_Pos。Master_Log_File代表主机上用于主备同步的日志文件名,Read_Master_Log_Pos代表上一次成功同步到的日志文件中的位置。
如果这两项与先前在主服务器上看到的File及Position的值不相符,则无法正确进行同步。
输入上述命令后即完成了全部配置工作,通过:
start slave;启动从服务的replication工作,这样主从服务器就开始同步了。
你可以通过:
SHOW SLAVE STATUS;命令来查看从服务器的状态,如果是Slave_IO_State一项显示:Waiting for master to send event,表示所有工作已经就绪。
二.常见错误:
1.Slave_SQL_Running: No(主-从) 。
mysql服务器为主-从配置时,发现从MySQL Slave未和主机同步,查看Slave状态:
mysql> show slave statusG
Slave_IO_Running: Yes
Slave_SQL_Running: No
Last_Errno: 1062
….
Seconds_Behind_Master:NULL
原因:
1.程序可能在slave上进行了写操作
2.也可能是slave机器重起后,事务回滚造成的.
解决办法I:
1.首先停掉Slave服务:slave stop
2.到主服务器上使用show master status查看主机状态:记录File和Position对应的值。
3.到slave服务器上执行手动同步:
CHANGE MASTER TO MASTER_HOST='192.168.0.246',MASTER_USER='slave',
MASTER_PASSWORD='0487521',MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=0;
4.再次查看slave状态发现:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
…
Seconds_Behind_Master: 0
注:这种办法可能会导致从服务器上的数据不完整,如从服务器一直出错,但主服务器日志文件一直在增加,过好长时间,再直接从主服务器上取日志位置,可能会造成错误期间的数据无法更新到从服务器中.这里建议采用下面的这种办法(将错误语句直接跳过).
解决办法II:
mysql> slave stop;
mysql> set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
mysql> slave start;
2.error:'Duplicate entry
错误日志提示如下:
Error 'Duplicate entry '1' for key 1' on query. Default database: 'movivi1'. Query: 'INSERT INTO `v1vid0_user_samename` VALUES(null,1,'123','11','4545','123')'
Slave status;
显示:Slave_SQL_Running 为 NO
解决方法I:
stop slave;
set global sql_slave_skip_counter =1 ;
start slave;
3.UUIDS相同
错误日志文档提示:The slave I/O thread stops because master and slave have equal MySQL server UUIDs
拷贝整个data目录,把auto.cnf文件也拷贝过来了,里面记录了数据库的uuid,每个库的uuid应该是不一样的。
[auto]
server-uuid=6dcee5be-8cdb-11e2-9408-90e2ba2e2ea6
解决办法,按照这个16进制格式,随便改下,重启mysql即可。
4.Slave_IO_Running: No(主-从)
修改配置没见my.ini,记得把从服务器中的server-id = 1注释掉。
三.添加新slave服务器
假如master已经运行很久了,想对新安装的slave进行数据同步,甚至它没有master的数据。
此时,有几种方法可以使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拷贝,即使服务器正在运行。
(3) 使用mysqldump
使用mysqldump来得到一个数据快照可分为以下几步:
<1>锁表:如果你还没有锁表,你应该对表加锁,防止其它连接修改数据库,否则,你得到的数据可以是不一致的。如下:
mysql> FLUSH TABLES WITH READ LOCK;
<2>在另一个连接用mysqldump创建一个你想进行复制的数据库的转储:
shell> mysqldump --all-databases --lock-all-tables >dbdump.db
<3>对表释放锁。
mysql> UNLOCK TABLES;
四.常见状态
1. Master 同步线程状态
以下列出了master的 Binlog Dump 线程 State 字段中最常见的几种状态。如果在master上没有 Binlog Dump 线程,那么同步就没有在运行。也就是说,没有slave连接上来。
Sending binlog event to slave
事件是由二进制日志构成,一个事件通常由更新语句加上其他信息。线程读取到一个事件并正发送到slave上。
Finished reading one binlog; switching to next binlog
读取完了一个二进制日志,正切换到下一个。
Has sent all binlog to slave; waiting for binlog to be updated
已经读取完全部未完成更新日志,并且全部都发送到slave了。它处于空闲状态,正等待在master上执行新的更新操作以在二进制日志中产生新的事件,然后读取它们。
Waiting to finalize termination
当前线程停止了,这个时间很短
2. Slave的I/O线程状态
以下列出了slave的I/O线程 State 字段中最常见的几种状态。从MySQL 4.1.1开始,这个状态在执行 SHOW SLAVE STATUS 语句结果的 Slave_IO_State 字段也会出现。这意味着可以只执行 SHOW SLAVE STATUS 语句就能了解到更多的信息。
Connecting to master
该线程证尝试连接到master上。
Checking master version
确定连接到master后出现的一个短暂的状态。
Registering slave on master
确定连接到master后出现的一个短暂的状态。
Requesting binlog dump
确定连接到master后出现的一个短暂的状态。该线程向master发送一个请求,告诉它要请求的二进制文件以及开始位置。
Waiting to reconnect after a failed binlog dump request
如果二进制日志转储(binary log dump)请求失败了(由于连接断开),该线程在休眠时进入这个状态,并定期重连。重连的时间间隔由
--master-connect-retry 选项来指定。
Reconnecting after a failed binlog dump request
该线程正尝试重连到master。
Waiting for master to send event
已经连接到master,正等待它发送二进制日志。如果master闲置时,这个状态可能会持续较长时间,如果它等待超过 slave_read_timeout 秒,就会发生超时。这时,它就会考虑断开连接,然后尝试重连。
Queueing master event to the relay log
已经读取到一个事件,正把它拷贝到中继日志中以备SQL线程处理。
Waiting to reconnect after a failed master event read
读日志时发生错误(由于连接断开)。该线程在重连之前休眠 master-connect-retry 秒。
Reconnecting after a failed master event read
正尝试重连到master。当连接确定后,状态就变成 Waiting for master to send event。
Waiting for the slave SQL thread to free enough relay log space
relay_log_space_limit 的值非零,中继日志的大小总和超过这个值了。I/O线程等待SQL线程先处理中继日志然后删除它们以释放足够的空间。
Waiting for slave mutex on exit
当前线程停止了,这个时间很短。
3. Slave的SQL线程状态
以下列出了slave的SQL线程 State 字段中最常见的几种状态:
Reading event from the relay log
从中继日志里读到一个事件以备执行。
Has read all relay log; waiting for the slave I/O thread to update it
已经处理完中继日志中的全部事件了,正等待I/O线程写入更新的日志。
Waiting for slave mutex on exit
当前线程停止了,这个时间很短。
SQL线程的 State 字段有时候也可能是一个SQL语句。这意味着它从中继日志中读取到一个事件了,从中提取出SQL语句,并执行它。