• ADADADADAD

    【MySQL】重放binlog故障一则 ERROR 1050 (42S01) : Table '' already exists[ mysql数据库 ]

    mysql数据库 时间:2024-12-03 12:12:02

    作者:文/会员上传

    简介:

    〇现象:
    在通过binlog增量恢复数据时,报错1050。
    〇 版本:
    MySQL 5.5.x 及以下 ,低版本的MySQL 5.6.x (在5.6的高版本中测试,无法复现,疑似被修复)
    〇 原因:
    binlog记录了执行出错的

    以下为本文的正文内容,内容仅供参考!本站为公益性网站,复制本文以及下载DOC文档全部免费。


    〇现象:
    在通过binlog增量恢复数据时,报错1050。
    〇 版本:
    MySQL 5.5.x 及以下 ,低版本的MySQL 5.6.x (在5.6的高版本中测试,无法复现,疑似被修复)
    〇 原因:
    binlog记录了执行出错的DDL语句,此处,具体DDL是CREATE VIEW $view_name AS ...

    有点奇怪,难道执行错误了的DDL也会被记录到binlog中么?

    〇 复现:

      [17:52:45] root@localhost [a]> FLUSH LOGS;
      Query OK, 0 rows affected (0.01 sec)

      [17:52:47] root@localhost [a]> SHOW BINLOG EVENTS IN 'mysql55-bin.000006';
      +--------------------+-----+-------------+-----------+-------------+---------------------------------------+
      | Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
      +--------------------+-----+-------------+-----------+-------------+---------------------------------------+
      | mysql55-bin.000006 | 4 | Format_desc | 55 | 107 | Server ver: 5.5.57-log, Binlog ver: 4 |
      +--------------------+-----+-------------+-----------+-------------+---------------------------------------+
      1 row in set (0.00 sec)

      [17:53:13] root@localhost [a]> CREATE TABLE t(id int);
      Query OK, 0 rows affected (0.01 sec)

      [17:53:18] root@localhost [a]> CREATE VIEW v_t AS SELECT * from t;
      Query OK, 0 rows affected (0.00 sec)

      [17:53:21] root@localhost [a]> CREATE VIEW v_t AS SELECT * from t;
      ERROR 1050 (42S01): Table 'v_t' already exists

    此时,再次检查binlog:
      [17:53:24] root@localhost [a]> SHOW BINLOG EVENTS IN 'mysql55-bin.000006'\G
      *************************** 1. row ***************************
      Log_name: mysql55-bin.000006
      Pos: 4
      Event_type: Format_desc
      Server_id: 55
      End_log_pos: 107
      Info: Server ver: 5.5.57-log, Binlog ver: 4
      *************************** 2. row ***************************
      Log_name: mysql55-bin.000006
      Pos: 107
      Event_type: Query
      Server_id: 55
      End_log_pos: 189
      Info: use `a`; CREATE TABLE t(id int)
      *************************** 3. row ***************************
      Log_name: mysql55-bin.000006
      Pos: 189
      Event_type: Query
      Server_id: 55
      End_log_pos: 369
      Info: use `a`; CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_t` AS SELECT * from t
      *************************** 4. row ***************************
      Log_name: mysql55-bin.000006
      Pos: 369
      Event_type: Query
      Server_id: 55
      End_log_pos: 549
      Info: use `a`; CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_t` AS SELECT * from t
      4 rows in set (0.00 sec)

    可以发现,第二次执行CREATE VIEW,即便在mysql client执行时报错,也被记录到binlog中。
    自然,在通过mysqlbinlog重放binlog时,也会报错。

    但在复制结构中,从实例不会重放该events,故从库不会报错。

    重新通过mysqlbinlog解析日志得到:
      # at 107
      #180206 17:53:18 server id 55end_log_pos 189Query thread_id=13exec_time=0 error_code=0
      use `a`/*!*/;
      SET TIMESTAMP=1517910798/*!*/;
      SET @@session.pseudo_thread_id=13/*!*/;
      SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
      SET @@session.sql_mode=0/*!*/;
      SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
      /*!\C utf8 *//*!*/;
      SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=8/*!*/;
      SET @@session.lc_time_names=0/*!*/;
      SET @@session.collation_database=DEFAULT/*!*/;
      CREATE TABLE t(id int)
      /*!*/;
      # at 189
      #180206 17:53:21 server id 55end_log_pos 369Query thread_id=13exec_time=0 error_code=0
      SET TIMESTAMP=1517910801/*!*/;
      CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_t` AS SELECT * from t
      /*!*/;
      # at 369
      #180206 17:53:22 server id 55end_log_pos 549Query thread_id=13exec_time=0 error_code=1050SET TIMESTAMP=1517910802/*!*/;
      CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_t` AS SELECT * from t
      /*!*/;
    可以发现第二次报错的语句,虽然被记录到binlog中,但error_code标识为1050

    至于为何从库不报错,大概是因为sql thread会特殊处理这种error_code,不会执行。
    而mysqlbinlog mysql-binlog.00000x | mysql -u -p -S 重放binlog的方式会报错。——大概是因为mysql这个client工具没有做对mysqlbinlog解析出来的error_code的特殊处理吧。

    暂时不知道是否为bug,但高版本的MySQL5.6.x已经修正了该问题,5.7也如此。

    因此,在可能出现问题的版本,通过binlog增量恢复数据时,可能需要特殊处理。



    热门标签: 故障42S01