Mysql

表錯誤的密鑰文件不正確。如何將 MySQL 臨時文件夾的位置更改為具有更多磁碟空間的驅動器的另一部分?

  • April 13, 2021

我在 Mac Pro OSX Mavericks 上使用 MySQL 和 Sequel Pro,並嘗試執行儲存過程的程式碼,以便向表中添加兩個新列。該過程對來自兩個不同表的列進行數學運算,其中一個是與目標/輸出表“starting_pitcher_stats”相同的表。

當我呼叫該過程時,我不斷收到以下錯誤:

表 ‘/var/folders/zz/zyxvpxvq6csfxvn_n000009800002_/T/#sql43_1_82.MYI’ 的密鑰文件不正確;嘗試修復它

這是該過程的程式碼:

DROP PROCEDURE IF EXISTS starting_pitcher_std_wRC;
   DELIMITER $$
   CREATE PROCEDURE starting_pitcher_std_wRC()
   BEGIN
       DECLARE pit_id CHAR(10);
       DECLARE gdate DATE;
       DECLARE seq INT;
       DECLARE YEARID INT;
       DECLARE wOBAsc VARCHAR (255);
       DECLARE stdwOBA DOUBLE;
       DECLARE wOBAgame DOUBLE;
       DECLARE lgwOBAgame DOUBLE;
       DECLARE lgstdwOBA DOUBLE;
       DECLARE lgRoverPAg DOUBLE;
       DECLARE stdlgRoverPA DOUBLE;
       DECLARE stdwRC DOUBLE;
       DECLARE wRCg DOUBLE;
       DECLARE prev_year YEAR(4);
       DECLARE end_of_cursor BOOLEAN;

       DECLARE no_table CONDITION FOR SQLSTATE '42S02';

       DECLARE c1 CURSOR FOR
         SELECT s.Starting_Pitcher, s.Game_Date, s.Game_Number, s.YEAR_ID,
                s.wOBAScale, s.std_wOBA, s.wOBA_game, l.lg_wOBA_game,
                l.lg_std_wOBA, l.lg_RoverPA_g, l.std_lg_RoverPA,
                s.wRC_g, s.std_wRC 
           FROM starting_pitcher_stats AS s,
                lg_starting_pitcher_game_log AS l
          ORDER BY s.Starting_Pitcher, s.Game_Date, s.Game_Number;

       DECLARE CONTINUE HANDLER FOR NOT FOUND
         SET end_of_cursor := TRUE;

       SET end_of_cursor := FALSE;  -- reset
       SET prev_year := 0;          -- reset control-break

       OPEN c1;

       fetch_loop: LOOP
         FETCH c1 INTO pit_id, gdate, seq, YEARID, wOBAsc, stdwOBA,
               wOBAgame, lgwOBAgame, lgstdwOBA, lgRoverPAg, stdlgRoverPA,
               wRCg, stdwRC;
         IF end_of_cursor THEN
           LEAVE fetch_loop;
         END IF;

         -- check control-break conditions
         IF YEAR(gdate) != prev_year THEN
           SET stdwRC := 0;
           SET wRCg := 0;
           SET prev_year := YEAR(gdate);
         END IF;

           SET wRCg := (((wOBAgame - lgwOBAgame)/wOBASc)+(lgRoverPAg))*BFPgame;
           SET stdwRC := (((stdwOBA - lgstdwOBA)/wOBASc)+(stdlgRoverPA))*stdBFP;

         UPDATE starting_pitcher_stats
           SET s.std_wRC =stdwRC,
           s.wRC_g =wRCg
             WHERE s.YEAR_ID=YEARID
             AND s.Game_date=gdate
             AND s.Game_Number=seq
             AND s.Starting_Pitcher = pit_id;

       END LOOP;
       CLOSE c1;
     END
     $$

 DELIMITER ;

出現錯誤後,我在嘗試創建的兩個新列中獲得了所有 Null 值。

我確實看到了對具有類似錯誤的類似文章的回复,每個文章都解決了導致錯誤的不同可能原因,但不清楚是哪種問題類型引發了我的錯誤。

我希望我只需要將 MySQL 的臨時文件夾的位置更改為具有更多空間的位置,正如一個人在以下執行緒中推薦的那樣。他們說我需要在 MySQL 的配置文件中更改它,但不知道該怎麼做:

https://stackoverflow.com/questions/2428738/how-do-you-fix-a-mysql-incorrect-key-file-error-when-you-cant-repair-the-tabl

這是我試圖呼叫的儲存過程的目標表的表結構的螢幕截圖:

在此處輸入圖像描述

有人可以指出我如何修復文件夾或解決問題的正確方向嗎?如果您需要更多資訊,請告訴我,以便我提供。

先感謝您。

更新:當我執行 df -h 來確定整個掛載文件系統中使用的大小和磁碟空間時,如果磁碟空間是一個問題,因為以前的文章經常建議是我得到的錯誤的來源,結果如下:

Filesystem      Size   Used  Avail Capacity  iused     ifree %iused  Mounted on
/dev/disk2s2   298Gi  200Gi   97Gi    68% 52622616  25436210   67%   /
devfs          187Ki  187Ki    0Bi   100%      646         0  100%   /dev
/dev/disk0s2   149Gi  288Mi  148Gi     1%    73766  38914980    0%   /Volumes/Disk 2                       
map -hosts       0Bi    0Bi    0Bi   100%        0         0  100%   /net
map auto_home    0Bi    0Bi    0Bi   100%        0         0  100%   /home
/dev/disk1s2   931Gi  254Gi  677Gi    28% 66541860 177564806   27%   /Volumes/DATASTORE_Z

當我使用錯誤中列出的路徑執行相同的命令時(不包括 .MYI 文件,因為當我包含它時它說訪問被拒絕)它表明有問題的文件夾(目錄?)佔用了 68% 的空間:

df -h /var/folders/zz/zyxvpxvq6csfxvn_n000009800002_/T/:

Filesystem     Size   Used  Avail Capacity  iused    ifree %iused  Mounted on
/dev/disk2s2  298Gi  201Gi   97Gi    68% 52624601 25434225   67%   /

如果在執行我的上述儲存過程時產生的臨時文件確實超過了可用空間量,那麼將 /var/folders/zz/zyxvpxvq6csfxvn_n000009800002_/T/ 移動到另一個文件系統是否有意義,例如 /dev/disk1s2 ?

如果是這樣,它會像使用 mv 那樣簡單嗎?我在這裡很謹慎,因為我不想這樣做造成更多問題,因為這裡的問題可能不是我想的那樣。

預先感謝您對上述內容的任何回饋以及我應該採取哪些措施來解決問題。

改變tmpdir;見http://dev.mysql.com/doc/refman/5.7/en/temporary-files.html

你應該從 MyISAM 遷移到 InnoDB。

您可能可以在單個“多表更新”語句中完成整個儲存過程。(游標效率不高。)

但是,也許最重要的是,切換FROM a,bFROM a JOIN b ON ...此時您會意識到您有一個“交叉連接”,因為ON缺少條件。這可能會導致一個巨大的臨時表。如果每個表有 10K 行長,則 tmp 表將有 100M 行!

引用自:https://dba.stackexchange.com/questions/142936