2012-12-30 22 views
0

我們在維基網站上遇到問題(使用mysql 5.5.9)。有一個text表和一個revision表,其中revision.rev_text_idtext.old_id的外鍵(不存在新問題,請問維基媒體)。插入的行消失

有一個INSERT INTO text...,然後INSERT INTO revision...它使用從先前的查詢收到的新的old_id/rev_text_id

第二個查詢起作用,第一個 - 我不確定。事情是在整個事情經過(有幾十個查詢)之後,revision行在那裏,在它的rev_text_id列中有一個新的新值。

但是,text行不存在。有趣的事情 - text表自動增量提前,因爲下一個動作跳過它的值爲old_id,缺失值與我們在revision表中匹配。

雖然行未實際插入,但第一個查詢是否有可能使自動遞增索引提前?這是什麼原因?

ADDTITION

當我複製從日誌的INSERT INTO text查詢並運行它的服務器上 - 它執行罰款(行加入表)

編輯

完整查詢是:

INSERT INTO text (old_id,old_text,old_flags) VALUES (NULL,'{text input by user}','utf8'); 
INSERT INTO `revision` (rev_id,rev_page,rev_text_id,rev_comment,rev_minor_edit,rev_user,rev_user_text,rev_timestamp,rev_deleted,rev_len,rev_parent_id,rev_sha1) VALUES (NULL,'{pageId}','{textId}','{comment}','{isMinor}','{userId}','{userName}','{TS}','{isDeleted}','{length}','{parentRevision}','{HASH}')" 

另外,如果r elevant,text表正在運行InnoDB,而revision是MyISAM。

編輯

從日誌的詳細信息:

壞請求

BEGIN 
INSERT INTO `text` 
INSERT INTO `revision` 
UPDATE `page` SET page_latest 
INSERT INTO `recentchanges` 
INSERT INTO `cu_changes` 
SELECT wl_user FROM `watchlist` 
SELECT user_id FROM `user` 
SELECT user_id,user_name,user_real_name,user_password,user_newpassword,user_newpass_time,user_email,user_touched,use 
SELECT ug_group FROM `user_groups` 
SELECT up_property,up_value FROM `user_properties` 
SELECT user_id,user_name,user_real_name,user_password,user_newpassword,user_newpass_time,user_email,user_touched,use 
SELECT ug_group FROM `user_groups` 
SELECT up_property,up_value FROM `user_properties` 
SELECT lc_value FROM `l10n_cache` 
SELECT lc_value FROM `l10n_cache` 
... 

再過SELECT秒。活動暫停2秒,然後日誌中有來自新用戶的命令,不再有來自該用戶的查詢(在同一線程上)。

由同一用戶的編輯到不同的頁面,進展順利:

BEGIN 
INSERT INTO `text` 
INSERT INTO `revision` 
UPDATE `page` SET page_latest 
INSERT INTO `recentchanges` 
INSERT INTO `cu_changes` 
SELECT wl_user FROM `watchlist` 
COMMIT 
BEGIN 
UPDATE `watchlist` SET wl_notificationtimestamp 
COMMIT 
BEGIN 
SELECT user_id FROM `user` 
SELECT user_id,user_name,user_real_name,user_password,user_newpasswo 
SELECT ug_group FROM `user_groups` 
SELECT up_property,up_value FROM `user_properties` 
SELECT * FROM `user` 
SELECT up_property,up_value FROM `user_properties` 
INSERT INTO `logging` 
UPDATE `user` SET user_editcount=user_editcount+1 
SELECT 1 FROM `user` 
UPDATE `user` SET user_touched = '20121227211743' 
COMMIT 

+0

需要查看這兩個查詢。 –

+0

有沒有機會第一次查詢使自動增量索引提前行,雖然行未實際插入?這是什麼原因? 是的,當然可能是發生了什麼事情。但你能告訴我你在用什麼引擎? –

+0

@mamdouhalramadan - 有趣的是,'text'表是InnoDB,而其他的則是MyISAM。可能是我們改變了自己,而不是原來的配置。 – JNF

回答

1

有機會第一次查詢,使自動增量指標提前儘管該行ISN實際上插入?這是什麼原因?

是的,當您嘗試插入一個表中的一行AUTO_INCREMENT列,則插入會失敗,但AUTO_INCREMENT值將由1

如果你決定將錶轉換爲遞增InnoDB,我建議你使用交易。這樣,如果一個查詢失敗,它們都不會被插入。

+0

我明白'LAST_INSERT_ID()'會採取相應的行動(雖然沒有真正的插入) – JNF

+0

實際上有一個'BEGIN'開始之前,我找不到匹配日誌中的COMMIT – JNF

+0

事務僅適用於某些存儲引擎,但它們不適用於MyISAM。 http://dev.mysql.com/doc/refman/5.0/en/ansi-diff-transactions.html – PachinSV