• MySQL 服務器端的錯誤處理太弱了!

    0
    MySQL SQL C/C++ Go 10702 次瀏覽

    沒有一種合適的方式來捕捉和診斷 MySQL 服務器端的錯誤,因此想知道什么地方出錯了基本上是不可能的。

    我們使用下面這樣一個查詢來證明這個結論:

    INSERT INTO my_table (my_column) VALUES (300);

    這個查詢可能發生什么錯誤?

    • 違反 UNIQUE KEY 約束
    • 違反 FOREIGN KEY 約束
    • my_column 字段類型可能是 TINYINT UNSIGNED, 而嚴格的 sql_mode 導致數值越界
    • 后者字段類型可能是某個枚舉,如 ENUM (2,3,5,8)

    還有可能是這樣一些錯誤:

    • my_table 可能是一個只讀的 MyISAM
    • 我們對 my_table 進行了鎖表操作 LOCK TABLES my_table READ -- 違反了鎖
    • 或者可能是一個 InnoDB 表,而 INSERT 可能導致死鎖
    • 配置了 read_only=1 只讀
    • 或者用戶沒法訪問該表的權限
    • 或者表不存在
    • 也有可能是字段不存在

    而且我還確定還可能有更多的錯誤原因存在。

    現在,如果我寫了一個 Java 程序,可能用了 Hibernate,那么我將會通過 SQLException 得到一個描述比較清晰的異常信息,我可以得知錯誤碼和錯誤信息。

    但在 MySQL 的服務器端,例如是存儲過程呢?則不行!

    再看看下面的代碼:
    CREATE PROCEDURE some_procedure ()
    BEGIN
      DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET @error_found = 1;
      INSERT INTO my_table (my_column) VALUES (300);
      IF @error_found THEN -- Any what error exactly is this? What's the message? END IF;
    END;

    如果我們希望為指定的錯誤執行相應的動作,我們需要:

      DECLARE CONTINUE HANDLER FOR 1146 SET @error_found = 1146;
      DECLARE CONTINUE HANDLER FOR 1147 SET @error_found = 1147;
      DECLARE CONTINUE HANDLER FOR 1148 SET @error_found = 1148;
      DECLARE CONTINUE HANDLER FOR 1149 SET @error_found = 1149;
      ...

    但如果我們比知道將會發生什么錯誤,但仍希望記錄這個錯誤,這樣我們可能需要定義成百上千的 HANDLERs,盡管如此還是無法覆蓋所有的錯誤情況。

    5.5 版本不是引入了 SINGAL 和 RESIGNAL 了嗎?

    是的,的確是引入了,但對你毫無幫助,你可以重新 RESIGNAL 一個錯誤,但并不意味著錯誤實際發生時你能知曉。

    那么,問題是什么呢?

    我想在服務器端做很多事情,而不是通過外部腳本如 Python/Perl/Java/Ruby/Shell 等,例如 event scheduler: 我的意思是有什么意義呢?如果在服務器端很多事情你沒法做的話,那將是無用的。你不能夠組織錯誤,不能得到足夠的錯誤描述信息,這只不過是你想執行好工作的一小部分而已。

    common_schema/QueryScript 中我提供了一些腳本,但錯誤處理該怎么辦呢?我編寫了一個完全不同的錯誤處理方法(尚未發布),但一旦在服務器端運行 common_schema , 因為服務器的限制導致其功能是有限的,也就是說用處的確很小。

    本來不錯

    這是 error_count 連接會話變量,實際上也沒有任何用途,有了下面兩個變量就會好很多:

    • last_error_code
    • last_error_message

    如果一個查詢導致了多個錯誤,請選擇其中一個。

    或者使用其他方法來在服務器端解析 SHOW 命令(參考 這里). 如果我可以解析 SHOW ERRORS 命令,那么所有事情都能得以解決。

    MySQL 5.0 引入了 INFORMATION_SCHEMA, 雖然并不完整。很快 SHOW 命令被排除在服務器端游標之外。因為太多的功能缺失,所以我提交了一個 bug report/feature request. 你支持我嗎?

    譯者注:后面內容翻譯的很糟糕,完全不知道在說什么,如果費勁請看英文原文或者共同翻譯下。

    相似問題

    相關經驗

    相關資訊

    相關文檔

  • sesese色