2012-08-22 12 views
8

私はtbl_jobsというテーブルを持っています。このテーブルには、アプリケーションで実行中のバックグラウンドジョブのメタデータが格納されています。スキーマは次のようである:mysqlのキー 'PRIMARY'の重複エントリ

CREATE TABLE `tbl_jobs` (
    `type` varchar(30) NOT NULL DEFAULT '', 
    `last_run_on` datetime NOT NULL, 
    `records_updated` text, 
    PRIMARY KEY (`type`,`last_run_on`), 
    UNIQUE KEY `index2` (`type`,`last_run_on`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1$$ 

仕事は、それは異なるジョブの一意の識別子、その実行中run timerecords updatedあるtypeとテーブルにエントリを作成し実行しますたび。 MAILER_UNLOCKED_REWARDSMAILER_ALMOST_UNLOCKED

はタイプで同時に実行二つの異なるジョブがあります。

これらのジョブが同じタイムスタンプでエントリを挿入しようとすると、そのうちの1つだけが挿入され、もう1つは重複エントリエラーをスローします。例えば

は、2つのジョブには、以下を実行しました:正常に実行されたが、2番目のジョブがINSERTコマンド

INSERT INTO tbl_jobs 
      (type, 
      last_run_on, 
      records_updated) 
VALUES  ('MAILER_UNLOCKED_REWARDS', 
      '2012-08-22 19:10:00', 
      '8a003e8934c07f040134c30959c40009:59bcc21b33a0466e8e5dc50443beb945') 

を実行したときにそれがエラーを投げた

INSERT INTO tbl_jobs 
      (type, 
      last_run_on, 
      records_updated) 
VALUES  ('MAILER_ALMOST_UNLOCKED', 
      '2012-08-22 19:10:00', 
      'f8a35230fb214989ac75bf11c085aa28:b591426df4f340ecbce5a63c2a5a0174') 

Duplicate entry 'M-2012-08-22 19:10:00' for key 'PRIMARY' 

主キーはtypeとの組み合わせです10列。

最初のジョブのエントリを削除すると、挿入が成功します。つまり、timestampだけが一意であることを要求しています。

しかし、同じtimestampの競合は、これらの2つのジョブ間でのみ発生します。同じtimestampのために挿入される他のジョブがあります。

問題が発生する可能性のあるアイデアはありますか?

+1

あなたは 'show create table tbl_jobs'を表示できますか – jcho360

+0

コメントだけですが、私はサロゲートキーの使用をお勧めします。毎秒複数のエントリが発生している可能性があります。 – Kermit

+1

主キーは必然的に一意であるため、スクリプトのUNIQUE KEY行を削除する必要があります。 – sp00m

答えて

4

インデックスに「タイプ」フィールド全体を使用していますか?または最初の文字のみ? MySQLは不満されたキーが代わりにMAILER _...

てみランニングの

M-2012-08-22 19:10:00 

ですので:

SHOW INDEXES FROM tbl_jobs; 

それはのようなものを与える必要があります。

+----------+------------+----------+--------------+-------------+-----------+-------------+ ----------+--------+------+------------+---------+---------------+ 
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | 
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 
| tbl_jobs |   0 | PRIMARY |   1 | type  | A   |   0 |  NULL | NULL |  | BTREE  |   |    | 
| tbl_jobs |   0 | PRIMARY |   2 | last_run_on | A   |   0 |  NULL | NULL |  | BTREE  |   |    | 

を.. 。

とIそれはPRIMARYインデックスのSub_part欄に「1」の代わりに表示されます疑う:

+----------+------------+----------+--------------+-------------+-----------+-------------+ ----------+--------+------+------------+---------+---------------+ 
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | 
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 
| tbl_jobs |   0 | PRIMARY |   1 | type  | A   |   0 |  1 | NULL |  | BTREE  |   |    | 
| tbl_jobs |   0 | PRIMARY |   2 | last_run_on | A   |   0 |  NULL | NULL |  | BTREE  |   |    | 

...

ところで、主キーは常にユニークであるので、あなたが宣言する2番目のインデックスindex2冗長です。

+0

私はタイプキー全体を使用しています。 Mさんが何をしているのか分からない。 – mickeymoon

+0

@mickeymoon、PRIMARYについて報告されたエラーは結果と矛盾します。定義に何か問題があります。私はSHOW INDEXESが助けになると信じています( "sub_part"列をチェックしてください)。 – LSerni

+0

@Iserni:あなたから指摘されているように、 'sub_part'は実際には' type'カラムの** 1 **です。それにはどのような意味がありますか?それを解決するにはどうすればいいですか? – mickeymoon

0

最初のこと:PRIMARY KEYにAUTO_INCREMENTが設定されていることを確認する必要があります。 2番目のこと:自動インクリメントを有効にするだけです: ALTER TABLE [テーブル名] AUTO_INCREMENT = 1 3つ目のこと:挿入コマンドを実行すると、このキーをスキップする必要があります。

+0

主キー(この場合)は英数字ですので、 'AUTO_INCREMENT'設定は適用できません。 – fusion3k

0

システムのシャットダウンまたはネットワークに問題がある場合は、このエラーが発生しています。あなたは本当にあなたのデータベースに重複がありません。これはMySQLのdbエラーです。挿入する場合はtrueではなく、挿入するテーブルの列のいずれかをvarcharからtextまたはbigintに変更してから、挿入をやり直してください。それが問題を解決します。

If(!$insert) 
{  
$alter=Mysql_query("alter table  

`table_name` change `table_name` 

`table_name` bigint(255) not null");  

If($alter){ 

//you then redo your insertion.  

} 


} 
関連する問題