MySQLがpt-online-schema-changeを使用する問題
TencentDB for MySQL v5.6以降は、オンラインDDLをサポートしています。5.5バージョンではテーブル構造の変更を行う時に、ロックテーブルによるビジネスへの影響を回避するため、ユーザーがpt-online-schema-changeなどのオープンソースツールを使用してこの操作を完了することをお勧めしていますが、多くのユーザーがCVMによりpt-online-schema-changeを使用してMySQLテーブル構造を変更すると、問題が発生する場合があります。
一般的なエラーメッセージ:
Use of uninitialized value $host in string eq at /usr/local/percona-toolkit-3.0.3/bin/pt-online-schema-change line 4284.
対応するソースコードの表示:
sub _find_slaves_by_processlist {
my ( $self, $dsn_parser, $dbh, $dsn ) = @_;
my @slaves = map {
my $slave = $dsn_parser->parse("h=$_", $dsn);
$slave->{source} = 'processlist';
$slave;
}
grep { $_ }
map {
my ( $host ) = $_->{host} =~ m/^([^:]+):/;
if ( $host eq 'localhost' ) {
$host = '127.0.0.1';
}
$host;
} $self->get_connected_slaves($dbh);
return @slaves;
}
コードが示すように、processlistの方法によりstandbyの情報を探していますが、TencentDBがコピーアカウント関連の情報を処理したため、processlistによりstandbyの情報を取得できません。
ソリューション:
pt-oscを使用する時に以下のパラメーターを追加し、standbyの状態を確認しないようにします。
--recursion-method=none
TencentDBへのデータのインポート中に「Specified key was too long」というエラーメッセージが表示されます
エラーが表示される原因:
クライアントがCVMコマンドラインによりTencentDB for MySQLインスタンスにXXXX.sqlファイルをインポートする時、「Specified key was too long」というエラーメッセージを返します。
エラーメッセージ「ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes」の意味は、「インデックスフィールドが長すぎで、767バイトを超えています」です。
innodbストレージエンジンについては、マルチカラムインデックスの長さは以下のとおり制限されています。
単一列インデクスの長さは767バイトを超えてはならず、すべてのインデックス列を構成する合計長さは3072バイトを超えてはなりません。
myisamストレージエンジンについては、複数列インデックスの長さは以下のとおり制限されています。
各列の長さは1000バイトを超えてはならず、すべてのインデックス列を構成する合計長さは1000バイトを超えてはなりません。
説明:
768/2=384の2バイトまたは767/3=255の3バイトのフィールド(GBKは2バイトで、UTF8は3バイトで、UTF8MB4は4バイト)
MySQL 5.6以上のバージョンは、すべてのmyisamテーブルが自動的にinnodbテーブルに変換されるため、自己構築データベース上には767バイトを超える連結インデックス列がありますが、自己構築データベース上にmyisamストレージエンジンがあるため、同じテーブル作成ステートメントを自己構築データベースで実行しても問題ありませんが、MySQL 5.6以上では問題が発生します。
ソリューション:
1. バックアップファイルにおけるエラー行の連結インデックス列の長さを変更します。
一般的なエラー行:
create table test(test varcahr(255) primary key)charset=utf8;
-- 成功
create table test(test varcahr(256) primary key)charset=utf8;
-- 失敗
ERROR 1071(42000):Specified key was too long; max key length is 767 bytes
2. TencentDB 5.5バージョンを使用すると、myisamエンジンはinnodbに自動変換されません。
「select * from XX into outfile xxxx」のようなエラーが発生した場合はどうなりますか。
プラットフォームの安全性の理由により、file権限をアクティブにすることができず、select into outfile方式でデータをエクスポートすることができません。その他の方法でデータをエクスポートすることをお勧めします。
MySQLデータベースで絵文字を挿入すると文字化けしますが、どうすればいいですか。
MySQLインスタンス内部、クライアント、MySQLインスタンスへの接続の3つの面について、統一して使用していないか、またはutf8mb4文字セットをサポートしているかを調査する必要があります。
絵文字のMySQLインスタンスへの保存を実現するには、MySQLインスタンス内部、クライアント、MySQLインスタンスへの接続の3つの面について、統一して使用するかutf8mb4文字セットをサポートする必要があります。
1. まずMySQLインスタンスは文字セットをutf8mb4に設定する必要があります。コンソールにログインすることによりcharacter_set_serverパラメーターを変更することができます。
説明:
このパラメーターを変更すると、データベースが再起動されます。不要な損失が発生することを回避するため、事前にデータベースをバックアップすることをお勧めします。
2. ユーザーのアプリケーションクライアントは出力する文字列の文字セットがutf8mb4であることを保証する必要があります。
3. アプリケーションプログラムの作成および接続は実行する文字セットを指定する必要があります。例として、一般的なjdbc接続を取り上げます。
jdbc接続については、MySQL Connector/J 5.1.13以上のバージョンを使用する必要があります。サンプルコードは以下の通りです。
String query = “set names utf8mb4”;
stat.execute(query);
一般的なパラメーターの変更および意味
MySQLは既に公式のデフォルト値に基づき最適化を行っていますが、お客様のビジネスシナリオごとに、インスタンスを購入後、自身のビジネスシーンに基づき以下のパラメーターを適切に配置することをお勧めします。
character_set_server
デフォルト値:LATIN1
再起動が必要か:はい
役割:MySQLサーバーのデフォルト文字セットを構成します。MySQLはそれぞれLATIN1、UTF8、GBK、UTF8MB4種類の文字セットを提供し、そのうち、LATIN1は英語文字をサポートし、1文字で1バイトを占めます。UTF8は世界のすべての国で必要な文字を含み、国際的なエンコードで、汎用性が強く、1文字で3バイトを占めます。GBKの文字エンコードは2バイトで表され、即ち日本語、英語の文字とも2バイトで表されます。UTF8MB4はUTF8のスーパーセットとして、完全に下位互換性があり、1文字で4バイトを占め、かつ絵文字をサポートします。
推奨:インスタンスを購入後、ビジネスがサポートする必要のあるデータ形式に基づき適切な文字セットを選択し、文字セットの設定が正しくないことによる文字化けの発生問題および不要な再起動操作を避けるため、クライアントとサーバーに確実に同じ文字セットを設定してください。
lower_case_table_names
デフォルト値:0
再起動が必要か:はい
役割:データベースおよびテーブルを作成時、ストレージとクエリで大文字と小文字を区別するかどうかを設定できます。このパラメーターが設定できる値は0、1で、デフォルトのパラメーター値は0で、データベースおよびテーブル作成時、ストレージとクエリがいずれも大文字と小文字を区別し、それ以外の場合は区別をしないことを表します。
推奨:MySQLはデフォルトで大文字と小文字を区別します。ビジネスのニーズおよび使用の習慣に基づき適切に構成してください。
sql_mode
デフォルト値:
NO_ENGINE_SUBSTITUTION(5.6バージョン),ONLY_FULL_GROUP_BY、STRICT_TRANS_TABLES、NO_ZERO_IN_DATE、NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO、NO_AUTO_CREATE_USER、NO_ENGINE_SUBSTITUTION(5.7バージョン)
再起動が必要か:いいえ
役割:MySQLは様々なsqlモードで実行することができます。sqlモードはmysqlがサポートする必要のあるsql文法、データ検証などを定義します。
このパラメーターの5.6バージョンのデフォルトパラメーター値はNO_ENGINE_SUBSTITUTIONで、使用するストレージエンジンが無効または未コンパイルの場合、エラーがスローされることを表します。5.7バージョンのデフォルトパラメーター値はONLY_FULL_GROUP_BY、STRICT_TRANS_TABLES、NO_ZERO_IN_DATE、NO_ZERO_DATE、ERROR_FOR_DIVISION_BY_ZERO、NO_AUTO_CREATE_USER、NO_ENGINE_SUBSTITUTIONです。
そのうち:
ONLY_FULL_GROUP_BYはGROUP BYの集計操作時に、SELECT中の列、HAVINGまたはORDER BY節の列の場合、GROUP BY中に現れるまたはGROUP BY列に依存する関数列である必要があります。
STRICT_TRANS_TABLESは厳格モードを有効にすることです。NO_ZERO_IN_DATE モードは、年の部分は非ゼロであるが月または日の部分が0である日付をサーバーが許可するかどうかに影響します。
NO_ZERO_DATEデータベースは0の日付を挿入することができず、かつ厳格モードを有効にしたかの影響を受けます。
ERROR_FOR_DIVISION_BY_ZEROは厳格モードにおいて、INSERTまたはUPDATEの過程で、データが0により除算された場合、警告でなくエラーが発生します。非厳格モードではデータが0により除算された場合、MySQLがNULLを戻します。
NO_AUTO_CREATE_USERはGRANTが空のパスワードのユーザーを作成することを禁止します。
NO_ENGINE_SUBSTITUTIONは使用するストレージエンジンが無効または未コンパイルの場合、エラーがスローされます。
推奨:SQLモードごとに異なるSQL文法をサポートしているため、ビジネスシナリオおよび開発習慣に基づき適切な構成を行うことをお勧めします。
long_query_time
デフォルト値:10
再起動が必要か:いいえ
役割:スロークエリの区分時間を指定し、デフォルト値は10sです。特定のクエリ実行時間が10s以上の時、後でスロークエリを分析しやすくするため、このクエリの実行状況はスローログに記録されます。
推奨:ビジネスシナリオおよび性能の感度に基づき、後で性能分析をしやすくするため、適切な値を設定することをお勧めします。