問題描述:
DROP INDEX index_name on table_name時,如果table_name是大寫,則會導致後續information_schema.statistics 表的訪問問題。
環境:MYSQL 5.1.46 win32版本。
問題樣本:
use test;
CREATE TABLE IF NOT EXISTS TCI_INST
(
FCIID
INT UNSIGNED,
FCIDVER
INT UNSIGNED,
FCINAME
VARCHAR(256)
);
CREATE INDEX IND_TCI_FCIID ON TCI_INST(FCIID,FCIDVER);
SELECT * FROM information_schema.statistics where table_name='TCI_INST' and index_name='IND_TCI_FCIID';
應該輸出兩條記錄。實際輸出兩條記錄,正確!
SELECT count(*) FROM information_schema.statistics where table_name='TCI_INST' and index_name='IND_TCI_FCIID';
應該輸出2。實際輸出2,正確!
DROP INDEX IND_TCI_FCIID ON TCI_INST; (注意這裡TCI_INST為大寫)
SELECT * FROM information_schema.statistics where table_name='TCI_INST' and index_name='IND_TCI_FCIID';
應該輸出0條記錄。正確!
SELECT count(*) FROM information_schema.statistics where table_name='TCI_INST' and index_name='IND_TCI_FCIID';
應該輸出0 但卻輸出2!錯誤!!!
SELECT table_name,index_name FROM information_schema.statistics where table_name='TCI_INST' and index_name='IND_TCI_FCIID';
居然也能輸出兩條記錄!錯誤!!!
如果DROP INDEX IND_TCI_FCIID ON tci_inst; (這裡改為小寫)
則一切正常。
來源:
今天研究了一下關於DROP INDEX IF EXISTS的問題,在研究這個問題的時候發現這個問題。
由於MYSQL不支援DROP INDEX IF EXISTS,那麼在寫安裝/升級指令碼的時候會比較麻煩,
於是寫了一個預存程序來判斷和刪除。
通過判斷information_schema.statistics的table_name和index_name來判斷索引是否存在。
如果存在,就刪除索引。
但是由於建立表時,均為大寫表名,因此調用此預存程序時也採用大寫表名,
第一次執行正確,再次執行時應該判斷表索引不存在,但是由於此bug,卻誤判為存在。
restart mysql後方能正確
改進:
在研究mysql過程中,也許表名字應該全部規定為小寫?
先暫訂mysql編程中表名字一律用小寫?