2009-05-08 12 views
0

私は2つのテーブルがあります。MySQLテーブルを交換してauto_incrementをアトミックに変更するにはどうすればよいですか?

CREATE TABLE table_a (
    id SERIAL 
); 
CREATE TABLE table_b (
    id SERIAL 
); 

私はテーブルを交換し、MAX(ID)に新しいtable_aのAUTO_INCREMENTを設定したい+1 table_bのを。例えば。

SELECT @A:=MAX(id) FROM table_a; 
SET @qry = CONCAT('ALTER TABLE table_b AUTO_INCREMENT =', @A+1); 
PREPARE stmt FROM @qry; 
EXECUTE stmt; 
RENAME TABLE table_a TO table_b_tmp, table_b TO table_a, table_b_tmp TO table_a; 

残念ながら、私はテーブルをロックもRENAME TABLEは、ロックされたテーブル上で動作し、暗黙的にコミットするALTER TABLEをしないようトランザクションでこれを行うことはできません。

idsの重複を避けるために私が考えることができる唯一の解決策は、auto_increment + 50を設定することですが、このプロセスが頻繁に起こっているので、私のIDには穴がたくさんありません。

アイデア?

+0

あなたはより良いスタックオーバーフローよりもthedailywtfするために提出される可能性があります、定期的にこのようにテーブルの上にスワップしている場合、私は思います。 .. – Greg

+0

ありがとうございますが、これは私たちのライブサイトに影響を与えずに効率的にダンプすることができない巨大なテーブルなので、それを交換する必要があります。私を信じて、私はここに到着する前にすべての可能なルートをダウンしてきました。 –

+0

なぜこのようなテーブルをダンピングしていますか?あなたは、複製されたスレーブデータベースをセットアップし、常にauto_incrementの位置をmuckingすることでデータの整合性を損なうことなく、ダンプを取ることをお勧めします。 – zombat

答えて

0

限り、サーバはMS Windowsのバージョンではなく、あなたが非トランザクションテーブルに固執するとして、あなたはテーブルロックとALTER TABLEtable_nameRENAME TOnew_table_nameステートメントを使用することができるはずです。

LOCK TABLES table_a WRITE, table_b WRITE; 
SELECT @A:=MAX(id)+1 FROM table_a; 
ALTER TABLE table_a RENAME TO table_a_tmp; 
LOCK TABLES table_b WRITE, table_a_tmp WRITE; 
PREPARE stmt FROM 'ALTER TABLE table_b RENAME TO table_a, AUTO_INCREMENT = ?'; 
EXECUTE stmt USING @A; 
ALTER TABLE table_a_tmp RENAME TO table_b; 
UNLOCK TABLES; 

2番目のロックは私を心配します。保留中の他のセッションがある場合、ロック前のテーブルにチャンスがありますか?私も上記の作業について簡単に間違っている可能性があります。私は、ロック、トランザクション、およびALTERステートメントについて、上記のページに基づいています。

私の他の考えは、挿入のためのMERGEテーブルを作成して、マージメソッドをFIRSTまたはLASTに更新することで、テーブルをスワップする代わりに(?)それは働くだろうか?

+0

返事をありがとう。残念ながら、ALTER TABLE ... RENAME TOは暗黙的にロックを解除するので、これは機能しません。 しかし、私はMERGEテーブルの考え方を考慮していませんでした。私はこれがうまくいくと思う。私はそれを試し、結果を投稿します。提案していただきありがとうございます。 –

+0

ALTER TABLEはトランザクションテーブルのロックを解除します。 MyISAMテーブルで動作するはずです。だから私は以前にテーブルタイプについて尋ねました(そしてMS Windowsについての警告を含んでいました)。 – outis

関連する問題