0

wiki サイトで問題が発生しています (mysql 5.5.9 を使用)。テーブルと、外部キーtextとなるrevisionテーブルがあります(新しいテーブルはありません。wikimedia に問い合わせてください)。revision.rev_text_idtext.old_id

がありINSERT INTO text...、前のクエリから受け取っINSERT INTO revision...た新しいold_id/を使用します。rev_text_id

2番目のクエリは機能しますが、最初のクエリは機能します-よくわかりません。問題は、すべてが完了した後 (さらに数十回のクエリを実行)、revision行がそこにあり、その列に新しい新しい値が含まれていることrev_text_idです。

ただし、text列はありません。面白いことに、textテーブルの自動インクリメントが進み、次のアクションが の値をスキップします。old_id欠落している値は、テーブルにあるものと一致しrevisionます。

行が実際に挿入されていなくても、最初のクエリで自動インクリメント インデックスが進む可能性はありますか? これは何が原因ですか?

追記

ログからクエリをコピーし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}')"

また、関連する場合、textテーブルは InnoDB を実行しており、revisionMyISAM です。

編集

ログからの詳細情報:

要求の形式が正しくありません

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

4

1 に答える 1

1

行が実際に挿入されていなくても、最初のクエリで自動インクリメント インデックスが進む可能性はありますか? これは何が原因ですか?

はい、auto_increment 列を含むテーブルに行を挿入しようとすると、挿入は失敗しますが、auto_increment 値は 1 増加します。

テーブルを InnoDB に変換する場合は、トランザクションを使用することをお勧めします。このようにして、クエリが失敗した場合、それらのどれも挿入されません。

于 2012-12-31T07:27:44.583 に答える