153

MysqlServer1作为MASTER运行。
MysqlServer2作为SLAVE运行。

现在数据库复制正在从MASTERSLAVE发生。

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

如何在将数据库从主服务器恢复到从服务器后再次重新同步数据库也不能解决问题?

4

14 回答 14

309

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

在大师:

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;

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

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

而已!

于 2010-07-12T15:08:00.400 回答
34

MySQL 站点上的相关文档严重过时,并且充斥着各种措辞(例如 interactive_timeout)。发出带有读锁的 FLUSH TABLES 作为您导出主服务器的一部分通常只有在与存储/文件系统快照(如 LVM 或 zfs)协调时才有意义。

如果你打算使用 mysqldump,你应该改用 --master-data 选项来防止人为错误并尽快释放 master 上的锁。

假设 master 是 192.168.100.50,slave 是 192.168.100.51,每台服务器都配置了不同的 server-id,master 有二进制登录,slave 在 my.cnf 中有 read-only=1

要在导入转储后立即启动从属服务器以启动复制,请发出 CHANGE MASTER 命令但省略日志文件名和位置:

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

在 master 上发出 GRANT 以供 slave 使用:

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

通过向从属设备发出命令开始复制:

slaveserver> START SLAVE;

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

如果你是5.1+,最好先把master的binlog_format设置为MIXED或者ROW。请注意,对于缺少主键的表,行记录的事件很慢。这通常比 binlog_format=statement(在主服务器上)的替代(和默认)配置更好,因为它不太可能在从服务器上产生错误数据。

如果您必须(但可能不应该)过滤复制,请使用从属选项 replicate-wild-do-table=dbname.% 或 replicate-wild-ignore-table=badDB.% 并仅使用 binlog_format=row

此进程将在 mysqldump 命令执行期间保持对 master 的全局锁定,但不会影响 master。

如果您想使用 mysqldump --master-data --all-databases --single-transaction (因为您只使用 InnoDB 表),那么使用 MySQL Enterprise Backup 或名为 xtrabackup 的开源实现可能会更好(由佩尔科纳)

于 2013-10-29T17:22:06.157 回答
18

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

于 2010-03-08T22:14:48.193 回答
8

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

于 2010-03-02T19:45:53.390 回答
8

我对这个问题很晚了,但是我确实遇到了这个问题,经过大量搜索,我从 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

连接到 Slave mysql 并运行如下命令: CHANGE MASTER TO MASTER_HOST='master-server-ip', MASTER_USER='replication-user', MASTER_PASSWORD='slave-server-password', MASTER_LOG_FILE='value from above', MASTER_LOG_POS=上面的值;启动奴隶;

查看 Slave 的进度: SHOW SLAVE STATUS;

如果一切正常,Last_Error 将为空,Slave_IO_State 将报告“Waiting for master to send event”。查找 Seconds_Behind_Master,它表明它落后了多远。YMMV。:)

于 2016-01-20T19:13:48.960 回答
6

这是当 mysql 从站不同步时我通常会做的事情。我看过 mk-table-sync 但认为风险部分看起来很吓人。

在大师:

SHOW MASTER STATUS

输出的列(文件、位置)稍后会对我们有用。

在奴隶上:

STOP SLAVE

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

然后运行以下命令:

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

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

希望这可以帮助!

于 2010-03-19T17:30:35.117 回答
5

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

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

于 2013-04-22T14:07:28.880 回答
2

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


我想使用master和slave设置mysql复制,因为我唯一知道的是它使用日志文件进行同步,如果slave离线并且不同步,理论上它应该只需要连接回来正如用户 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 服务器也有意义:

* 关于复制的进一步说明
================================
如果 MySQL 服务器充当复制从属服务器,则不应
设置 --tmpdir 指向基于内存的文件系统上的目录或
服务器主机重新启动时清除的目录。复制
从机需要一些临时文件才能在机器重启后存活,所以
它可以复制临时表或 LOAD DATA INFILE 操作。如果
服务器重启时临时文件目录中的文件丢失,
复制失败。

您可以使用类似 sql 的东西:显示变量,如 'tmpdir';找出答案。

于 2011-10-05T02:07:47.803 回答
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 参数(通常,对于新的/非复制的数据库,默认情况下不设置),

set global server_id=4000;

现在,启动从站。

START SLAVE;
SHOW SLAVE STATUS\G;

输出应该和他描述的一样。

  Slave_IO_Running: Yes
  Slave_SQL_Running: Yes

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

于 2013-05-22T04:44:44.627 回答
2

大师

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;  

注意
在 master 上,您可以运行SET GLOBAL expire_logs_days = 3以将 binlogs 保留 3 天以防从属问题。

于 2019-10-10T13:13:38.490 回答
1

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

尝试

stop slave;    
reset slave;    
start slave;    
show slave status;

很多时候,奴隶,他们只是被困住了:)

于 2014-10-15T16:07:24.707 回答
1

使用 LVM 重建从站

这是我们使用 Linux LVM 重建 MySQL 从站的方法。这保证了一致的快照,同时在您的主服务器上需要非常短的停机时间。

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

set global innodb_max_dirty_pages_pct = 0;

要监控脏页的数量,请运行命令

mysqladmin ext -i10 | grep dirty

一旦数量停止减少,您就可以继续。接下来重置master以清除旧的bin日志/中继日志:

RESET MASTER;

执行 lvdisplay 获取 LV Path

lvdisplay

输出将如下所示

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

使用命令关闭主数据库

service mysql stop

接下来拍摄快照,mysql_snapshot 将是新的逻辑卷名。如果二进制日志放置在操作系统驱动器上,则也需要进行快照。

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

使用命令再次启动master

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 slave 正在运行,你需要停止它

service mysql stop

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

cd /var/lib/mysql
rm -fr *

回到大师。现在将快照同步到 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

接下来启动slave MySQL

service mysql start

通过执行以下命令在从站上执行更改主命令:

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

SLAVE START;

检查从属状态:

SHOW SLAVE STATUS;

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

我最近在我的博客上写了这篇文章,可以在这里找到......那里有更多细节,但故事是一样的。

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

于 2015-05-21T20:06:27.573 回答
0

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

我希望这对您(以及其他人)有所帮助。

如何重置(重新同步)MySQL 主从复制

于 2015-03-02T18:12:43.890 回答
0

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

但是您需要确保丢失连接的服务器显示没有在数据库中进行任何提交,因为您收到重复的密钥错误错误代码:1062

于 2018-09-15T07:46:13.480 回答