web-dev-qa-db-ja.com

列を型「int」から型「bigint(20)unsigned」に変換できませんか?

私は、Percona MySQLクラスターを使用しており、マスターといくつかのスレーブがあります。それぞれがMySQLの「Ver 14.14 Distrib 5.5.40-36.1」を実行しています。レプリケーションは行ベースです。

スレーブのテーブルの1つだけに対して変更クエリを実行しました。マスターでテーブルをロックする余裕がないため、すべてのスレーブでこのクエリを実行してからマスター切り替えを行う計画です。

クエリは次のとおりです。

ALTER TABLE order_item_units 
MODIFY parent_id BIGINT(20) unsigned ;

そして、show slave statusを使用してスレーブをチェックしたときにこれを投稿すると、次のエラーでレプリケーションが壊れていることがわかります。

テーブル 'database_name.order_item_units'の列3は、タイプ 'int'からタイプ 'bigint(20)unsigned'に変換できません

そして、私がカラムをチェックしたとき、それはBIGINTに変換しました。

そして今、私はこれを修正することができません。私は奴隷を止めて、奴隷を始めました、助けませんでした。スレーブを停止してMySQLを再起動しましたが、役に立ちませんでした。スキップカウンターをやった、どちらも助けにはならなかった。

列が変換されていないはずである場合、エラーは正しいはずですが、エラーはまったく発生していない可能性があります。

そして、列が変換された場合、なぜエラーが発生しますか?

ここで何が欠けているか手掛かりはありますか?

4
Gautam Somani

なぜそのエラーが発生するのかわかりません。 2つの解決策があります。データが本当に符号なしbigintに変換できない場合、ソリューションはエラーを出します。

ALTER TABLE `order_item_units` ADD COLUMN `parent_id2` BIGINT(255) UNSIGNED AFTER `parent_id`;
UPDATE `order_item_units` SET `parent_id2` = `parent_id`;
SELECT * FROM `order_item_units` WHERE `parent_id2` != `parent_id` OR `parent_id` IS NULL;

3番目のクエリのデータを確認します。データが適切に配置されたら、古い列を削除します。次に、新しい列の名前を古い列の名前に変更します。ドロップする前にデータを検証することが不可欠です。

ALTER TABLE `order_item_units` DROP COLUMN `parent_id`;
ALTER TABLE `order_item_units` CHANGE `parent_id2` `parent_id` BIGINT(255) UNSIGNED;

新しい列に制約を追加することを忘れないでください。

一時テーブルを使用して同じプロセスを実行することもできますOR新しい列定義を使用して新しいテーブルを作成します。次に、古いテーブルを選択します。データを確認します。元のテーブルの名前を「 _old "に変更します。次に、修正したテーブルの名前を元のテーブル名に変更します

1
Nathan

特定のケースでは、「slave_conversion_type = ALL_NON_LOSSY」の設定が役立ちます。スレーブで実行:

STOP SLAVE; SET GLOBAL SLAVE_TYPE_CONVERSIONS=ALL_NON_LOSSY; START SLAVE; SHOW SLAVE STATUS\G

詳細については、こちらをお読みください: https://dev.mysql.com/doc/mysql-replication-excerpt/5.5/en/replication-features-different-data-types.html

0
Nopius