是什么导致MySQL错误1062-启动从属服务器时出现重复条目​​?


11
  • MySQL主版本:5.5.16-1
  • MySQL Slave版本:5.5.18-1

主机的快照是通过以下方式创建的:

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

此转储文件已导入从站(以--skip-slave-startoption 开头),没有错误:

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命令是否会遇到相同的问题。

不,如果我也将母版更改为相应的坐标,则它可以正常工作。

我会尝试将数据库拖放到从属服务器上,确保二进制日志已清除,然后重新启动。还要检查主服务器上有问题的表,以确保索引没有错误。

删除(移动)所有数据目录是否足够?我做到了,得到了相同的结果。


回复@Dmytro Leonenko

从站上的'show slave status \ G'以确保已正确配置,MASTER_LOG_POS为0

在导入之后但在“启动从站”之前仅“显示从站状态\ G”;可以给我们答案

我备份了datadir,删除所有并运行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
只能有一个具有该ID的记录,因此该错误将永远不会被写入。当您发出问题时SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1,引起错误的查询变化最少吗?从站二进制日志位置设置正确吗?
thinice 2011年

每次我跳过计数器时,它都会更改为另一个ID。该--master-data选项已将二进制日志坐标写入转储文件。我只需要将master更改为master_host,master_user,master_password。
量子

这不是我通常设置mySQL复制的方式(我通常在此处按URL设置复制:dev.mysql.com/doc/refman/5.0/en/replication-howto.html)但是,通读mysqldump选项,没有任何理由为什么它不起作用。我想知道如果要设置整个配置而不是传递mysqldump命令是否会遇到相同的问题。
Rilindo 2011年

您是说我--master-data在创建数据快照时不应该使用该选项吗?如果在使用--lock-all-tablesoption和时仍然发生这种情况change master to master_log_file='', master_log_pos='', ...,可能是什么原因?
量子

不,我不是这个意思。正如我所暗示的那样,您应该做的事情应该如预期的那样-据我所知,该选项没有现有的错误。但是,这并不意味着没有,因此作为隔离步骤,我将首先通过该URL遵循mySQL提供的约定。t。如果这样可以解决问题,至少您应指导开始进行故障排除。如果那还不行,那么,我们有另一个问题。:)
Rilindo '12

Answers:


7

尝试解决问题的方法:

  1. 你应该先删除slave上的master.info并重启mysql
  2. 发出CHANGE MASTER TO MASTER_HOST ='XX.XX.XX.XX',MASTER_USER ='repl',MASTER_PASSWORD ='slavepass';
  3. 使用master上的“ --flush-logs”选项执行mysqldump
  4. 从站上的'mysql -u user -p <dump.sql'
  5. 从站上的'show slave status \ G'以确保已正确配置,MASTER_LOG_POS为0
  6. “开始奴隶;” 在奴隶上。

还需要检查什么:

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

发出整个更改主字符串(包括日志名称和位置编号)实际上可以解决该问题,但目前,我认为核心问题是,为什么Quanta必须重新输入日志名称和位置编号,否则它已经存在了。转储文件。
Rilindo 2011年

在导入之后但在“启动从站”之前仅“显示从站状态\ G”;可以给我们答案
Dmytro Leonenko 2011年

将要求的信息附加到我的原始帖子中。
量子

您如何在不发出“ CHANGE MASTER ...”的情况下以“ Master_Host:xxxx Master_User:xx”结束。还是您只是没有在回答中提及它?您是否检查了binlog格式以及mysqldump的命令行是什么?
Dmytro Leonenko 2011年

我已经在我的文章“ 导入转储文件,执行change master to ”中提到过。我正在使用基于MIXED的日志记录。我已经使用MySQL 5.0.77(基于语句)进行了测试,它也会导致此错误。完整的mysqldump是mysqldump -u root -p --all-databases --master-data --flush-logs > alldb_$(date +%F).sql
量化

2

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

在奴隶上:

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

在主人上:

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


编辑为包括冲洗特权;我又一次错误地意识到,即使我的用户已随转储导入,他们的特权仍未激活。
2013年

RESET MASTER应在从机运行,而不是在主,见percona.com/blog/2013/02/08/...
乔恩·

1

如果您不希望REDO完成整个过程,则最好使用

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

如果有太多这样的错误,一个好主意是使用bash脚本将其自动化。

参考: 修复重复输入错误


1

我遇到了确切的问题,Ut xd的链接提供了帮助。但是该链接中的命令语法错误,这是对我有用的版本:

while [ 1 ]; do if [ `mysql -uroot -ppassword -e"show slave status \G;" | grep "Duplicate entry" | wc -l` -eq 2 ] ; then mysql -uroot -ppassword -e"stop slave; set global sql_slave_skip_counter=1; start slave;"; fi; sleep 1; mysql -uroot -ppassword -e"show slave status\G"; done

它基本上检查是否存在重复的输入错误,并从主机跳过此事件。并循环执行。


1
如果您要解释该代码的功能并将其格式化以提高可读性,那么这将是一个更好的答案。
卡巴斯德(Kasperd)'17年

0

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

通过以下步骤

STOP SLAVE;
RESET SLAVE;
START SLAVE;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.