

本番運用中のMySQLのデフォルト文字コードが以前と変わってしまってることが発覚して  
その間に作られたテーブルの文字コードを修正したいです

ほとんどのテーブルは修正できたのですが

ユニークカラム user_id をもっていて頻繁に更新されるテーブルに

[code]

    ALTER TABLE user_states DEFAULT CHARACTER SET utf8
    
[/code]

実行しようとしたところ  
`Error Code: 1062. Duplicate entry`xxxxxxxx` for key
'index_user_states_on_user_id'  
というエラーが出てしまいます

当然ユニーク制約がついてるためレコードは１つしかないです

文字コード変更中に書き込みされて文字列の比較がうまくいかなくて  
変なことが起こってるのかなと推測していますが  
どうにか更新を行う方法はないでしょうか

要件としては  
このテーブル自体は多少（数秒程度なら）欠損がでても問題ないですが  
書き込んでる API 側や MySQL 全体を停止したりネットワークから切り離すのはNGです

SQLで明示的にテーブル単位でロックがとれれば

[code]

    LOCK;
    ALTER TABLE user_states DEFAULT CHARACTER SET utf8;
    UNLOCK;
    
[/code]

みたいな感じで数秒だけ書き込みを抑制して文字コード変更が完了できると思うんですが…  
そういうことってできないでしょうか

追記：

Rails のマイグレーションエラー全文

[code]

    execute("ALTER TABLE user_states DEFAULT CHARACTER SET utf8")
    rake stderr: rake aborted!
    StandardError: An error has occurred, all later migrations canceled:
    Mysql2::Error: Duplicate entry 'xxxxxxxxxxxxxxxxxxx' for key 'index_user_states_on_user_id': ALTER TABLE user_states DEFAULT CHARACTER SET utf8
    
[/code]

xxxxxxxxxxxxxxx  
は実行するたびに変わっていてそのユーザのデータが直前に更新されているので  
文字コード変更とINSERTが重なっておかしなことになってると推測しました  
もちろんユニーク制約があるので重複データは存在しません

[code]

    INSERT INTO user_states (user_id, state) VALUES(xxxxxx, xxx)
    ON DUPLICATEKEY UPDATE state = state 
    
[/code]

同時に大量に飛んでくる更新クエリはこんな感じです


CC BY-SA 4.0
2019-11-07T10:41:54.067
60327
2020-07-19T14:01:35.213
2019-11-12T06:43:50.453
question
mysql
常に更新があるテーブルの MySQL テーブル文字コードの変更


MySQL でテーブルをロックするには `LOCK TABLES` を使用します。  
<https://dev.mysql.com/doc/refman/5.6/ja/lock-tables.html>


CC BY-SA 4.0
2019-11-16T09:26:08.327
60581
2019-11-16T09:26:08.327
3249
60327
answer