2012-10-16 41 views
4

這種類型的問題已發佈幾次,但提供的解決方案在以下情況下並不理想。在第一個查詢中,我選擇了在執行第一個查詢時存在的表名。然後在遍歷它們的同時,我想查詢選定表格中的記錄數量,但前提是它們仍然存在。問題是,在循環過程中,一些表被另一個腳本丟棄。例如:mysql非本機,僅當表存在時才選擇

SELECT tablename FROM table 
-- returns say 100 tables 

while (%tables){ 
    SELECT COUNT(*) FROM $table 
    -- by the time it gets to the umpteenth table, it's been dropped 
    -- so the SELECT COUNT(*) fails 
} 

而且,我猜是因爲它是由cron運行,它fataly失敗,我得到從cron說明它失敗發送了一封電子郵件。

DBD :: mysql的:: ST執行失敗:表 'XXX' 根本不 /usr/local/lib/perl/5.10.1/Mysql.pm行存在175

腳本正在使用已棄用的Mysql.pm perl模塊。

+0

異常處理??? – Khaleel

+0

新用戶提示:如果您發現它有用,您可以upvote /接受一些答案。你應該包括你的問題涉及的mysql引擎版本。 –

+1

你嘗試使用交易嗎? –

回答

1

很明顯,您需要確保表在執行查詢之前不會被刪除。請記住,如果您以某種表鎖定開始,爲避免可能的丟失 - 從其他位置發出的DROP TABLE查詢將失敗,並出現一些鎖定錯誤,或者至少會等到SELECT完成。刪除表並不是真正經常使用的操作,因此在大多數情況下,架構設計在服務器操作期間仍然存在 - 您觀察到的情況非常罕見。通常,在其他查詢過程中防止表被丟棄是不受支持的,但是,在下面的文檔的註釋中,您可能會發現使用信號量表實現它的一些技巧。

http://dev.mysql.com/doc/refman/5.1/en/lock-tables.html

「表鎖只能預防不當讀取或由其他會話寫道。會話持有鎖,甚至讀鎖,可以執行表級的操作,比如DROP TABLE。截斷操作不事務安全,所以如果會話在活動事務期間或持有表鎖定時嘗試一個錯誤,則會發生錯誤。「 「如果您需要對通常不受讀或寫鎖定支持的表執行操作(如刪除或截斷表),並且您可以配合使用,則可以嘗試以下操作:使用信號量表並創建每個進程有兩個會話在第一個會話中,根據需要在信號量表上獲得一個讀或寫鎖定,在第二個會話中,完成所有其他表的操作。

+0

這聽起來像它正是我需要的。存儲引擎是MyISAM,Mysql版本是:5.0.95。我如何將它鎖定在初始查詢中,然後在完成後解鎖它?我現在會對此進行一些研究。謝謝。 – user1749141

+0

看起來像它可能只適用於本機SQL代碼。我正在使用Mysql perl模塊。 – user1749141

1

你應該能夠通過將它放入eval塊來保護你的perl代碼免於失敗。類似的東西:

eval { 
    # try doing something with DBD::mysql 
}; 
if ([email protected]) { 
    # oops, mysql code failed. 
    # probably need to try it again 
} 

甚至把這個「while」循環

如果你喜歡使用的Postgres更好的服務器,正確的解決方案將封閉一切都變成交易。但是,在MySQL丟棄表中不受事務保護。

+0

它是在while循環中,這是問題,當它循環(每次迭代需要一兩秒鐘)時,表將被另一個腳本刪除。 Innodb引擎的最新版本也支持事務。當我醒來的時候會試試eval。通常使用類似於:if($ dbh-> execute)陷阱錯誤,但cron版本正在死亡。 – user1749141

+0

Eval也沒有接受它。仍然得到cron notifs。 Cron命令是:*/1 * * * * /x.cgi 2>&1>/dev/null – user1749141

+0

您應該能夠將原始選擇的結果與表名稱存儲在數組或散列中。然後遍歷目標表的列表以執行「SELECT count(*)FROM tableN」。但是,當做這個聲明時,把它放入eval塊。這應該肯定工作 - 克朗與否。要進行調試,可以手動將垃圾名稱放到目標表的列表中,以檢查腳本是否在這些表上發出噓聲 – mvp

相關問題