<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ## 背景 你是否曾為`Error on rename of './test/#sql-78fd_780371' to './test/t2' (errno: 150)`這樣的錯誤而不解,如stackoverflow上的這個[問題](http://stackoverflow.com/questions/4080611/1025-error-on-rename-of-database-sql-2e0f-1254ba7-to-database-table)? 下面我們來復現下: ~~~ drop table t2; drop table t1; create table t1(c1 int primary key, c2 int); create table t2(c1 int primary key, c2 int , constraint fk foreign key (c2) references t1(c1)) engine=innodb; //刪外鍵所引用的列 alter table t2 drop c2; //刪不存在的外鍵 alter table t2 drop foreign key idx1; ~~~ 5.5的表現 ~~~ mysql> alter table t2 drop c2; ERROR 1025 (HY000): Error on rename of './test/#sql-78fd_780371' to './test/t2' (errno: 150) mysql> alter table t2 drop foreign key idx1; ERROR 1025 (HY000): Error on rename of './test/t2' to './test/#sql2-78fd-780371' (errno: 152) ~~~ 5.6的表現 ~~~ mysql> alter table t2 drop c2; ERROR 1553 (HY000): Cannot drop index 'fk': needed in a foreign key constraint mysql> alter table t2 drop foreign key idx1; ERROR 1091 (42000): Can't DROP 'idx1'; check that column/key exists ~~~ 很明顯5.6的報錯信息更精確些,5.5的報錯太不人性化了,容易造成誤解。 它們差別在于5.6的報錯處理在語義分析階段,精準的定位了錯誤信息。 ~~~ mysql_alter_table |=>mysql_inplace_alter_table |==>ha_innobase::prepare_inplace_alter_table |===>innobase_check_foreign_key_index ~~~ 而5.5的報錯處理在執行階段。 我們先來看看5.5的執行流程: ~~~ mysql_alter_table |=>mysql_create_table_no_lock //創建臨時表tmp_table1,其結構和原表類似,但不包括外鍵信息 |==>rea_create_table |=>copy_data_between_tables //將原表數據copy到tmp_table1 |=>mysql_rename_table //將原表重命名tmp_table2,但不重命名外鍵涉及的表信息 |==> row_rename_table_for_mysql //修改字典表 |=>mysql_rename_table //將臨時表tmp_table1重命名回原表 |==>row_rename_table_for_mysql //修改字典表 |===>dict_load_foreigns //這里通過從數據字段加載外鍵信息來檢查外鍵索引是否存在,外鍵索引列是否一致. ~~~ `dict_load_foreigns`:這個函數由于承擔的責任太多,只要發現錯誤,就籠統的拋出`Error on rename of 'xxxx' to 'xxxx' (errno: xxx)`的錯誤. ## 外鍵bug 我們來看一個外鍵相關的[bug77467](https://bugs.mysql.com/bug.php?id=77467)。 ~~~ Alter table reply change blogId topicId int(11) NOT NULL, drop index userId, drop foreign key reply_ibfk_2; ~~~ bug中這個DDL雖然執行失敗了,但實際上foreign key reply_ibfk_2被刪除了。這個bug在單機環境下影響不大,但在主備環境下由于DDL執行失敗并沒有記binlog,從而導致主備表結構不一致。這個bug只出現在5.6以前的版本中,5.6是OK的 ## bug分析 我們來看看5.5的流程: ~~~ mysql_alter_table |=>mysql_create_table_no_lock //創建臨時表tmp_table1,其結構和原表類似,但不包括外鍵信息 |==>rea_create_table |=>copy_data_between_tables //將原表數據copy到tmp_table1 |=>mysql_rename_table //將原表重命名tmp_table2,但不重命名外鍵涉及的表信息,同時刪除原表的外鍵reply_ibfk_2 |==> row_rename_table_for_mysql //修改字典表 |=>mysql_rename_table //將臨時表tmp_table1重命名回原表 |==>row_rename_table_for_mysql //修改字典表 |===>dict_load_foreigns //這里通過從數據字段加載外鍵信息來檢查外鍵索引是否存在,外鍵索引列是否一致.檢查發現index userId不存在,出現錯誤 |===>trx_rollback_to_savepoint //出現錯誤回滾之前的修改 ~~~ 出錯回滾之前的修改,預期是回滾刪除外鍵reply_ibfk_2,但是刪除外鍵reply_ibfk_2操作在第一次`mysql_rename_table`中,屬于一個事務,而回滾操作在第二次`mysql_rename_table`中,屬于另一個事務,因此回滾沒有成功。 那么5.6為什么沒有出現這種錯誤呢?5.6在語義分析的時候就發現錯誤,還沒來得及刪外鍵就已經報錯返回了。 ## bug修復 5.5修復方法,將刪外鍵的操作放到第二次`mysql_rename_table`中進行,如果出現錯誤就可以順利的回滾了。當然,還是5.6的做法比較好。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看