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

Ind*_*rma 134 mysql database database-replication

Mysql Server1作为MASTER运行.
Mysql Server2作为SLAVE运行.

现在,DB复制正在从MASTER发生到SLAVE.

Server2从网络中删除并在1天后重新连接.在此之后,主站和从站中的数据库不匹配.

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

Dav*_*art 279

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

在主人:

RESET MASTER;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;
Run Code Online (Sandbox Code Playgroud)

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

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

mysqldump -u root -p --all-databases > /a/path/mysqldump.sql
Run Code Online (Sandbox Code Playgroud)

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

UNLOCK TABLES;
Run Code Online (Sandbox Code Playgroud)

现在使用scp或首选工具将转储文件复制到从站.

在奴隶:

打开与mysql的连接并输入:

STOP SLAVE;
Run Code Online (Sandbox Code Playgroud)

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

mysql -uroot -p < mysqldump.sql
Run Code Online (Sandbox Code Playgroud)

同步从站和主日志:

RESET SLAVE;
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=98;
Run Code Online (Sandbox Code Playgroud)

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

最后,键入:

START SLAVE;
Run Code Online (Sandbox Code Playgroud)

要在输入后检查一切是否正常工作:

SHOW SLAVE STATUS;
Run Code Online (Sandbox Code Playgroud)

你应该看到:

Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Run Code Online (Sandbox Code Playgroud)

而已!

  • 如果在主服务器上调用mysqldump时使用--master-data标志,则将CHANGE MASTER TO命令写入转储文件,从而在将转储文件导入从服务器后保存执行该步骤. (22认同)
  • 使用INNODB类型的dabatase和其他复杂的列类型(如BLOB和DATE定义),我建议使用以下开关:`--opt --single-transaction --comments --hex-blob --dump-date --no-autocommit - - 全databases` (7认同)
  • 是否需要"RESET_SLAVE"?请注意,这些指令会重置复制用户和密码,因此您必须重新输入"CHANGE MASTER TO ..." (4认同)
  • 不锁定主机(不需要Percona)http://plusbryan.com/mysql-replication-without-downtime这样做的另一个好处是SQL转储还带有必要的"CHANGE MASTER"行(注释掉) (3认同)
  • 有没有办法实现自动化? (2认同)
  • 我认为你应该小心来自这个转储“mysqldump -uroot -p --all-databases &gt; /a/path/mysqldump.sql”的“mysql -uroot -p &lt; mysqldump.sql”它可能最终覆盖系统数据库就像 information_schema 一样,我不得不艰难地学习它。 (2认同)
  • 既然你已经完成了RESET MASTER;在主服务器上,它将重复 GTID。所以你还必须运行RESET MASTER;在导入转储之前在 _SLAVE_ 服务器上执行此操作,以便从属服务器的 gtid_executed 集为空。否则,从站将忽略任何与旧 GTID 匹配的新事务。 (2认同)

Out*_*ted 25

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

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

slaveserver> CHANGE MASTER TO MASTER_HOST='192.168.100.50', MASTER_USER='replica', MASTER_PASSWORD='asdmk3qwdq1';
Run Code Online (Sandbox Code Playgroud)

在主服务器上发出GRANT以供从服务器使用:

masterserver> GRANT REPLICATION SLAVE ON *.* TO 'replica'@'192.168.100.51' IDENTIFIED BY 'asdmk3qwdq1';
Run Code Online (Sandbox Code Playgroud)

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

mysqldump --master-data --all-databases --flush-privileges | gzip -1 > replication.sql.gz
Run Code Online (Sandbox Code Playgroud)

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

zcat replication.sql.gz | mysql
Run Code Online (Sandbox Code Playgroud)

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

slaveserver> START SLAVE;
Run Code Online (Sandbox Code Playgroud)

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

如果您使用的是5.1+,最好先将master的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的)

  • 如果您只想重建现有的从站,可以按照上述过程,跳过几个步骤:GRANT和手动CHANGE MASTER命令 (3认同)

mal*_*nso 17

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

  • 您可以检查 bin 日志,看看它们是否涵盖了系统不同步的时间段。如果您错过了几天,这可能是一个更大的问题,需要您进行完整转储以恢复丢失的数据。 (3认同)

Min*_*nor 7

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


小智 6

我这个问题已经很晚了,但是我确实遇到了这个问题,经过多次搜索,我从Bryan Kennedy那里得到了这些信息:http: //plusbryan.com/mysql-replication-without-downtime

在Master上进行如下备份:
mysqldump --skip-lock-tables --single-transaction --flush-logs --hex-blob --master-data = 2 -A>〜/ dump.sql

现在,检查文件的头部并记下MASTER_LOG_FILE和MASTER_LOG_POS的值.稍后您将需要它们: head dump.sql -n80 | grep"MASTER_LOG"

将"dump.sql"文件复制到Slave并恢复它: mysql -u mysql-user -p <〜/ dump.sql

连接到从MySQL和运行这样的命令: CHANGE MASTER TO MASTER_HOST ="主服务器IP",MASTER_USER ="复制用户",MASTER_PASSWORD ="从属服务器口令",MASTER_LOG_FILE ="值从上面", MASTER_LOG_POS =上面的值; 开始离开;

检查奴隶的进展: SHOW SLAVE STATUS;

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

  • 这样做,如果奴隶已经设置并且只是不同步,你不需要运行CHANGE MASTER; 只需指定`--master-data = 1`(或只是`--master-data`). (3认同)

Bry*_*son 5

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

在大师:

SHOW MASTER STATUS
Run Code Online (Sandbox Code Playgroud)

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

在奴隶:

STOP SLAVE
Run Code Online (Sandbox Code Playgroud)

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

然后运行以下命令:

CHANGE MASTER TO
  MASTER_LOG_FILE='[File]',
  MASTER_LOG_POS=[Position];
START SLAVE;
Run Code Online (Sandbox Code Playgroud)

其中[File]和[Position]是从上面运行的"SHOW MASTER STATUS"输出的值.

希望这可以帮助!

  • 这看起来很糟糕,因为显然你没有`刷读了LOCK;`在你`SHOW MASTER STATUS`之前并转储master数据库.我认为这可能会导致例如奴隶上的重复键错误,因为您有效地将主状态设置为转储之前的某个时间点,因此您将重放已包含在转储中的历史记录.(如果按照您描述的顺序执行操作.) (5认同)

小智 5

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

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


Mo *_*ami 5

掌握

mysqldump -u root -p --all-databases --master-data | gzip > /tmp/dump.sql.gz  
Run Code Online (Sandbox Code Playgroud)

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

奴隶:

STOP SLAVE;
Run Code Online (Sandbox Code Playgroud)

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

START SLAVE;
SHOW SLAVE STATUS;  
Run Code Online (Sandbox Code Playgroud)

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