如果Master和slave有不同的数据库包含Mysql复制,如何重新同步Mysql DB?

时间:2010-03-02 19:20:46

标签: mysql database database-replication

Mysql Server1正在以 MASTER 的形式运行 Mysql Server2正在运行 SLAVE

现在,数据库复制正在从 MASTER 发生到 SLAVE

Server2已从网络中删除,并在1天后重新连接回来。在此之后,主服务器和从服务器中的数据库不匹配。

如何在恢复从Master到Slave的数据库后再次重新同步数据库也无法解决问题?

14 个答案:

答案 0 :(得分:267)

这是从头开始重新同步主从复制的完整步骤:

在主人:

RESET MASTER;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;

复制最后一个命令的结果值

在不关闭与客户端的连接(因为它会释放读锁定)的情况下发出命令来获取主服务器的转储:

mysqldump -u root -p --all-databases > /a/path/mysqldump.sql

现在您可以释放锁定,即使转储尚未结束。为此,请在MySQL客户端中执行以下命令:

UNLOCK TABLES;

现在使用scp或首选工具将转储文件复制到从属服务器。

在奴隶:

打开与mysql的连接并输入:

STOP SLAVE;

使用此控制台命令加载主数据转储:

mysql -uroot -p < mysqldump.sql

同步从站和主日志:

RESET SLAVE;
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=98;

上述字段的值是您之前复制的字段。

最后,输入:

START SLAVE;

在键入以下内容后检查一切是否正常工作:

SHOW SLAVE STATUS;
你应该看到:

Slave_IO_Running: Yes
Slave_SQL_Running: Yes

就是这样!

答案 1 :(得分:23)

MySQL网站上的文档非常过时,并且充斥着脚枪(例如interactive_timeout)。使用READ LOCK发送FLUSH表作为导出主服务器的一部分通常仅在与存储/文件系统快照(如LVM或zfs)协调时才有意义。

如果您打算使用mysqldump,您应该依赖--master-data选项来防止人为错误并尽快释放主服务器上的锁。

假设master为192.168.100.50,slave为192.168.100.51,每个服务器都配置了不同的server-id,master有二进制登录,slave在my.cnf中只读为1

要使slave能够在导入转储后立即启动复制,请发出CHANGE MASTER命令但省略日志文件名和位置:

slaveserver> CHANGE MASTER TO MASTER_HOST='192.168.100.50', MASTER_USER='replica', MASTER_PASSWORD='asdmk3qwdq1';

在主设备上发出GRANT以供从设备使用:

masterserver> GRANT REPLICATION SLAVE ON *.* TO 'replica'@'192.168.100.51' IDENTIFIED BY 'asdmk3qwdq1';

使用压缩导出主(在屏幕中)并自动捕获正确的二进制日志坐标:

mysqldump --master-data --all-databases --flush-privileges | gzip -1 > replication.sql.gz

将replication.sql.gz文件复制到slave,然后使用zcat将其导入到slave上运行的MySQL实例:

zcat replication.sql.gz | mysql

通过向slave发出命令来启动复制:

slaveserver> START SLAVE;

(可选)更新slave上的/root/.my.cnf以存储与主服务器相同的root密码。

如果您使用的是5.1+,最好先将主人的binlog_format设置为MIXED或ROW。请注意,对于缺少主键的表,行记录事件很慢。这通常比binlog_format = statement(在master上)的备用(和默认)配置更好,因为它不太可能在slave上产生错误的数据。

如果必须(但可能不应该)过滤复制,请使用slave options replicate-wild-do-table = dbname。%或replicate-wild-ignore-table = badDB。%并仅使用binlog_format = row

此过程将在mysqldump命令的持续时间内对主服务器进行全局锁定,但不会影响主服务器。

如果您想使用mysqldump --master-data --all-databases --single-transaction(因为您只使用InnoDB表),使用MySQL Enterprise Backup或称为xtrabackup的开源实现可能会更好(由Percona提供)

答案 2 :(得分:16)

除非您直接写入从属服务器(Server2),否则唯一的问题应该是Server2缺少自断开连接以来发生的任何更新。只需使用“START SLAVE”重新启动从站即可应该让一切恢复正常。

答案 3 :(得分:7)

我认为,Maatkit utilits对您有所帮助!您可以使用mk-table-sync。请参阅此链接:http://www.maatkit.org/doc/mk-table-sync.html

答案 4 :(得分:5)

这是我通常在mysql slave不同步时所做的事情。我看过mk-table-sync,但认为风险部分看起来很恐怖。

On Master:

SHOW MASTER STATUS

输出的列(文件,位置)将对我们有用。

On Slave:

STOP SLAVE

然后转储主数据库并将其导入从数据库。

然后运行以下命令:

CHANGE MASTER TO
  MASTER_LOG_FILE='[File]',
  MASTER_LOG_POS=[Position];
START SLAVE;

其中[File]和[Position]是从上面的“SHOW MASTER STATUS”输出的值。

希望这有帮助!

答案 5 :(得分:5)

跟进大卫的回答......

使用SHOW SLAVE STATUS\G将提供人类可读的输出。

答案 6 :(得分:5)

我对这个问题已经很晚了,但是我确实遇到了这个问题,经过多次搜索后,我从布莱恩·肯尼迪那里得到了这些信息:http://plusbryan.com/mysql-replication-without-downtime

On Master请像这样备份:
mysqldump --skip-lock-tables --single-transaction --flush-logs --hex-blob --master-data = 2 -A&gt; 〜/ dump.sql

现在,检查文件的头部并记下MASTER_LOG_FILE和MASTER_LOG_POS的值。你以后会需要它们: head dump.sql -n80 | grep&#34; MASTER_LOG&#34;

复制&#34; dump.sql&#34;将文件传递给Slave并恢复它: mysql -u mysql-user -p&lt; 〜/ dump.sql

连接到Slave mysql并运行如下命令: CHANGE MASTER TO MASTER_HOST =&#39; master-server-ip&#39;,MASTER_USER =&#39; replication-user&#39;,MASTER_PASSWORD =&#39; slave-server-password&#39;,MASTER_LOG_FILE =&#39;来自上面的值&#39;,MASTER_LOG_POS =来自上面的值; START SLAVE;

检查奴隶的进度: 显示失败状态;

如果一切正常,Last_Error将为空,Slave_IO_State将报告“等待主发送事件”。 寻找Seconds_Behind_Master,它表明它背后有多远。 因人而异。 :)

答案 7 :(得分:4)

有时你只需要给奴隶踢一脚

stop slave;    
reset slave;    
start slave;    
show slave status;
很多时候,奴隶,他们只是被卡住的家伙:)

答案 8 :(得分:2)

这是一个完整的答案,希望有助于其他人......


我想使用master和slave设置mysql复制,因为我唯一知道的是它使用日志文件进行同步,如果奴隶脱机并且不同步,理论上它应该只需要连接回其主服务器并继续从它停止的位置读取日志文件,如用户malonso所述。

以下是配置主站和从站后的测试结果:http://dev.mysql.com/doc/refman/5.0/en/replication-howto.html ...

如果您使用推荐的主/从配置并且不写入从站,则他和我在哪里(就mysql-server 5.x而言)。我甚至不需要使用“START SLAVE;”,它只是赶上它的主人。但是有一个默认的88000每60秒重试一次,所以我想如果你筋疲力尽你可能不得不启动或重启奴隶。无论如何,对于像我这样想知道是否让一个奴隶脱机并再次备份的人需要人工干预..不,它没有。

也许原始海报在日志文件中有损坏?但最有可能的不仅仅是服务器脱机了一天。


从/usr/share/doc/mysql-server-5.1/README.Debian.gz中提取,这对非debian服务器也有意义:

* FURTHER NOTES ON REPLICATION
===============================
If the MySQL server is acting as a replication slave, you should not
set --tmpdir to point to a directory on a memory-based filesystem or to
a directory that is cleared when the server host restarts. A replication
slave needs some of its temporary files to survive a machine restart so
that it can replicate temporary tables or LOAD DATA INFILE operations. If
files in the temporary file directory are lost when the server restarts,
replication fails.

你可以使用像sql这样的东西:显示像'tmpdir'; 这样的变量来查找。

答案 9 :(得分:2)

添加常用答案以包含此错误:

"ERROR 1200 (HY000): The server is not configured as slave; fix in config file or with CHANGE MASTER TO",

一次性从奴隶复制:

在一个终端窗口中:

mysql -h <Master_IP_Address> -uroot -p

连接后,

RESET MASTER;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;

状态显示如下:请注意位置编号各不相同!

+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 |      98  | your_DB      |                  |
+------------------+----------+--------------+------------------+

导出转储类似于他描述的“使用其他终端”!

退出并连接到您自己的数据库(从属设备):

mysql -u root -p

以下命令的类型:

STOP SLAVE;

如上所述导入转储(当然是在另一个终端!)并输入以下命令:

RESET SLAVE;
CHANGE MASTER TO 
  MASTER_HOST = 'Master_IP_Address', 
  MASTER_USER = 'your_Master_user', // usually the "root" user
  MASTER_PASSWORD = 'Your_MasterDB_Password', 
  MASTER_PORT = 3306, 
  MASTER_LOG_FILE = 'mysql-bin.000001', 
  MASTER_LOG_POS = 98; // In this case

记录后,设置server_id参数(通常,对于新的/未复制的DB,默认情况下不设置),

set global server_id=4000;

现在,启动奴隶。

START SLAVE;
SHOW SLAVE STATUS\G;

输出应与他描述的相同。

  Slave_IO_Running: Yes
  Slave_SQL_Running: Yes

注意:一旦复制,主服务器和从服务器共享相同的密码!

答案 10 :(得分:0)

我用脚本创建了一个GitHub repo来快速解决这个问题。只需更改几个变量并运行它(首先,脚本会创建数据库的备份)。

我希望这能帮到你(以及其他人)。

How to Reset (Re-Sync) MySQL Master-Slave Replication

答案 11 :(得分:0)

使用LVM重建奴隶

这是我们用于使用Linux LVM重建MySQL从属的方法。这样可以保证一致的快照,同时确保主服务器的停机时间非常短。

在主MySQL服务器上将innodb max脏页百分比设置为零。这将迫使MySQL将所有页面写入磁盘,这将显着加快重启速度。

set global innodb_max_dirty_pages_pct = 0;

要监视运行命令的脏页数

mysqladmin ext -i10 | grep dirty

一旦数字停止减少,您就可以继续了。接下来重置主服务器以清除旧的bin日志/中继日志:

RESET MASTER;

执行lvdisplay以获取LV路径

lvdisplay

输出将如下所示

--- Logical volume ---
LV Path                /dev/vg_mysql/lv_data
LV Name                lv_data
VG Name                vg_mysql

使用命令

关闭master数据库
service mysql stop

接下来拍一个快照,mysql_snapshot将是新的逻辑卷名。如果在操作系统驱动器上放置了binlog,那么也需要快照。

lvcreate --size 10G --snapshot --name mysql_snapshot /dev/vg_mysql/lv_data

使用命令

再次启动主控
service mysql start

将脏页面设置恢复为默认值

set global innodb_max_dirty_pages_pct = 75;

再次运行lvdisplay以确保快照在那里并且可见

lvdisplay

输出:

--- Logical volume ---
LV Path                /dev/vg_mysql/mysql_snapshot
LV Name                mysql_snapshot
VG Name                vg_mysql

挂载快照

mkdir /mnt/mysql_snapshot
mount /dev/vg_mysql/mysql_snapshot /mnt/mysql_snapshot

如果你有一个现有的MySQL奴隶运行,你需要停止它

service mysql stop

接下来你需要清除MySQL数据文件夹

cd /var/lib/mysql
rm -fr *

回到主人。现在rsync快照到MySQL从属

rsync --progress -harz /mnt/mysql_snapshot/ targethostname:/var/lib/mysql/

rsync完成后,您可以卸载并删除快照

umount /mnt/mysql_snapshot
lvremove -f /dev/vg_mysql/mysql_snapshot

如果旧复制用户不存在或密码未知,则在主服务器上创建复制用户

GRANT REPLICATION SLAVE on *.* to 'replication'@'[SLAVE IP]' identified by 'YourPass';

验证/ var / lib / mysql数据文件是否为mysql用户所有,如果是,则可以省略以下命令:

chown -R mysql:mysql /var/lib/mysql

接下来记录binlog位置

ls -laF | grep mysql-bin

您会看到类似

的内容
..
-rw-rw----     1 mysql mysql  1073750329 Aug 28 03:33 mysql-bin.000017
-rw-rw----     1 mysql mysql  1073741932 Aug 28 08:32 mysql-bin.000018
-rw-rw----     1 mysql mysql   963333441 Aug 28 15:37 mysql-bin.000019
-rw-rw----     1 mysql mysql    65657162 Aug 28 16:44 mysql-bin.000020

此处主日志文件是序列中最高的文件编号,bin日志位置是文件大小。记录这些值:

master_log_file=mysql-bin.000020
master_log_post=65657162

接下来启动奴隶MySQL

service mysql start

执行以下操作,对从站执行change master命令:

CHANGE MASTER TO 
master_host="10.0.0.12", 
master_user="replication", 
master_password="YourPass", 
master_log_file="mysql-bin.000020", 
master_log_pos=65657162; 

最后启动奴隶

SLAVE START;

检查奴隶状态:

SHOW SLAVE STATUS;

确保Slave IO正在运行且没有连接错误。祝你好运!

BR,Juha Vehnia

我最近在我的博客上写了这个...这里有更多细节,但故事是一样的。

http://www.juhavehnia.com/2015/05/rebuilding-mysql-slave-using-linux-lvm.html

答案 12 :(得分:0)

我们正在使用MySQL的master-master复制技术,如果一台MySQL服务器说1从网络中删除,它会在恢复连接并在服务器2中提交的所有记录恢复后重新连接自身。网络被传送到恢复后失去连接的服务器1。 默认情况下,每60秒,MySQL中的从属线程将重试以连接到其主服务器。可以将此属性更改为MySQL,并带有“ master_connect_retry = 5”标志,其中5以秒为单位。这意味着我们希望每5秒重试一次。

但是您需要确保丢失连接的服务器显示在您重复时不会对数据库进行任何提交。关键错误错误代码:1062

答案 13 :(得分:0)

大师

mysqldump -u root -p --all-databases --master-data | gzip > /tmp/dump.sql.gz  

scp master:/tmp/dump.sql.gz slave:/tmp/将转储文件移至从属服务器

从站:

STOP SLAVE;

zcat /tmp/dump.sql.gz | mysql -u root -p

START SLAVE;
SHOW SLAVE STATUS;  

注意
在主服务器上,您可以运行SET GLOBAL expire_logs_days = 3来将二进制日志保留3天,以防从属服务器出现问题。