启动从属时出现 MySQL 错误 1062-重复条目的原因是什么?

启动从属时出现 MySQL 错误 1062-重复条目的原因是什么?
  • MySQL 主版本:5.5.16-1
  • MySQL 从版本:5.5.18-1

主快照由以下方式创建:

mysql> FLUSH TABLES WITH READ LOCK;
shell> mysqldump --all-databases --master-data > dbname_`date +%F`.sql

这个转储文件被导入到从属服务器(使用选项启动--skip-slave-start)上,没有出现错误:

shell> pv dbname_`date +%F`.sql | mysql -u root -p

但是我在执行时出现以下错误mysql> start slave;

    Last_SQL_Errno: 1062
    Last_SQL_Error: Error 'Duplicate entry '115846' for key
'PRIMARY'' on query. Default database: 'db'. Query: 'INSERT INTO
request_posted (id, user_id, channel, message, link, picture, name, ...

主服务器上只有一条 ID 为 115846 的记录:

mysql> select count(*) from request_posted where id=115846;
Current database: db

+----------+
| count(*) |
+----------+
|        1 |
+----------+
1 row in set (0.01 sec)

尝试跳过一些查询:

mysql> STOP SLAVE; 
mysql> SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; 
mysql> START SLAVE;

没有帮助。我不想通过添加以下内容来跳过这些错误:

slave-skip-errors = 1062

因为my.cnf它可能会带来从属不一致。

造成该错误的原因可能是什么?


更新

这不是我通常设置 mySQL 复制的方式

您认为我没有遵循文档的哪些步骤?

我想知道如果您设置整个配置而不是传递 mysqldump 命令,您是否会遇到同样的问题。

不,如果我也将主控更改为相应的坐标,它就可以正常工作。

我会尝试删除从服务器上的数据库,确保 binlog 清晰,然后重新启动。同时检查主服务器上有问题的表,以确保索引没有错误。

删除(移动)所有数据目录就够了吗?我这样做了,得到了相同的结果。


回复 @Dmytro Leonenko

在从服务器上执行“show slave status\G”以确保其配置正确,MASTER_LOG_POS 为 0

只有在导入之后但在启动slave之前执行“show slave statug\G”才能给我们答案

我备份了数据目录,全部删除并运行mysql_install_db,导入转储文件,执行change master to,结果如下:

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: 
                  Master_Host: x.x.x.x
                  Master_User: xx
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: 
          Read_Master_Log_Pos: 4
               Relay_Log_File: mysqld-relay-bin.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: 
             Slave_IO_Running: No
            Slave_SQL_Running: No
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 0
              Relay_Log_Space: 106
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
1 row in set (0.00 sec)

我想知道为什么 Master_Log_Pos 是 4?

答案1

尝试修复您的问题的方法:

  1. 您应该首先删除从属上的 master.info,然后重新启动 mysql
  2. 发出 CHANGE MASTER TO MASTER_HOST='XX.XX.XX.XX', MASTER_USER='repl', MASTER_PASSWORD='slavepass';
  3. 在主服务器上使用 mysqldump '--flush-logs' 选项
  4. 从属设备上的‘mysql -u user -p < dump.sql’
  5. 在从服务器上执行“show slave status\G”以确保其配置正确,MASTER_LOG_POS 为 0
  6. '启动奴隶;' 在奴隶身上。

还需检查什么:

  • Binlog格式:MIXED
  • 主服务器和从服务器上的 server_id 不同

答案2

问题是由于在执行转储之前在正在运行的生产服务器上设置主服务器而导致的(据我所知)。因此,master_log 中写入的查询已在从服务器上的数据上执行。我从未在 mysql 网站或邮件列表上看到过解决方案。因此,我想出了以下解决方案来解决我的问题。

在奴隶身上:

mysql> STOP SLAVE;
mysql> FLUSH PRIVILEGES;  # dump likly included users too

在 master 上:

mysql> RESET MASTER;

在奴隶身上:

mysql> RESET SLAVE;
mysql> START SLAVE;

顺便说一下,我在从属服务器上运行了以下命令:

mysqldump -uROOTUSER -pROOTPASSWORD -hMYSQLMASTER.EXAMPLE.COM --all-databases --delete-master-logs | mysql -uROOTUSER -pROOTPASSWORD

我希望这对其他人有帮助。

http://dev.mysql.com/doc/refman/5.0/en/reset-master.html

http://dev.mysql.com/doc/refman/5.0/en/reset-slave.html

答案3

如果你不想重做整个过程,一个好的解决方法是使用

STOP SLAVE;    
SET GLOBAL sql_slave_skip_counter=1;
START SLAVE;

如果此类错误太多,一个好主意是使用 bash 脚本自动执行该操作。

参考: 修复重复输入错误

答案4

就我而言,这个问题可以通过以下命令解决

通过以下步骤

STOP SLAVE;
RESET SLAVE;
START SLAVE;

相关内容