【AWS CLI】RDSのメジャーアップグレードに伴うパラメーターグループ移行を簡素化してみた

記事タイトルとURLをコピーする

こんにちは。AWS CLIが好きな福島です。

はじめに

唐突ですが、RDSのメジャーバージョンアップグレードをする際にパラメーターグループ(以降、パラメーターG)の移行が大変かなと存じます。

※ここから、分かりやすいように例として、MySQL5.6からMySQL5.7へ移行する前提で記載します。

まず、パラメーターGは、DBエンジンごとに用意されているため、RDSをMySQL5.6からMySQL5.7に移行する場合、 MySQL5.6で利用していたパラメーターGをそのまま流用することはできません。

代わりにMySQL5.7用のパラメーターGを用意する必要があります。

また、パラメーターGのコピーは、DBエンジンが同じものであればできるのですが、 そうではない場合、コピーができません。

そのため、今回の例で言うと新規にMySQL5.7用のパラメーターGを作成する必要があります。

と、ここで課題があります。

新規にMySQL5.7用のパラメーターGを作成した場合、 MySQL5.6用のパラメーターGのデフォルトから変更された値(以降、カスタム値)が MySQL5.7用のパラメーターGに反映されません。

上記課題を解決するためには、以下の2つを対応する必要があります。

①現パラメーターGでカスタム値を調査。
②新パラメーターGの作成およびカスタム値を反映。
※2つなので簡単そうですが、結構大変な作業かなと思います。

ということで、今回は、上記内容をAWS CLIとLinuxコマンドを使い、対応していきたいと存じます。

※そもそも、デフォルトの現と新のパラメーターG自体にも差分があると思いますので、その点は、別途考慮ください。

①現パラメーターGのカスタム値を調査

まずはこの作業を以下の方法で対応いたします。

①-① デフォルトパラメーターGの値を抽出
①-② 現パラメーターGの値を抽出
①-③ 上記2つを比較し、差分(カスタム値)を確認

①-① デフォルトパラメーターGの値を抽出

デフォルトパラメータGは、利用者によって存在有無が異なるため、今回は、確認したいDBエンジンファミリーのパラメーターGを一時的に作成し、デフォルト値を確認します。

まず、確認したいDBエンジンファミリーを確認します。

aws rds describe-db-engine-versions \
--query "DBEngineVersions[].DBParameterGroupFamily" \
--output yaml | uniq

出力結果例)

- aurora-mysql5.7
- docdb3.6
- docdb4.0
- neptune1
- aurora-postgresql9.6
- aurora-postgresql10
- aurora-postgresql11
- aurora-postgresql12
- mariadb10.2
- mariadb10.3
- mariadb10.4
- mariadb10.5
- mysql5.6
- mysql5.7
- mysql8.0
- oracle-ee-12.1
- oracle-ee-12.2
- oracle-ee-19
- oracle-ee-cdb-19
- oracle-se2-12.1
- oracle-se2-12.2
- oracle-se2-19
- oracle-se2-cdb-19
- aurora5.6
- postgres9.6
- postgres10
- postgres11
- postgres12
- postgres13
- sqlserver-ee-11.0
- sqlserver-ee-12.0
- sqlserver-ee-13.0
- sqlserver-ee-14.0
- sqlserver-ee-15.0
- sqlserver-ex-11.0
- sqlserver-ex-12.0
- sqlserver-ex-13.0
- sqlserver-ex-14.0
- sqlserver-ex-15.0
- sqlserver-se-11.0
- sqlserver-se-12.0
- sqlserver-se-13.0
- sqlserver-se-14.0
- sqlserver-se-15.0
- sqlserver-web-11.0
- sqlserver-web-12.0
- sqlserver-web-13.0
- sqlserver-web-14.0
- sqlserver-web-15.0

上記結果から確認したいパラメーターGのDBエンジンファミリーを変数に定義します。

parameter_group_family="DBエンジンファミリー"

定義したDBエンジンファミリー用のパラメーターGを一時的に作成します。

aws rds create-db-parameter-group \
--db-parameter-group-name tmp-pg \
--db-parameter-group-family ${parameter_group_family} \
--description default.${parameter_group_family}_tmp

作成したパラメーターGの値をファイルに抽出します。
※ファイル名は、「${current_parameter_group}.txt」です。

aws rds describe-db-parameters \
--db-parameter-group-name tmp-pg \
--query "Parameters[].[ParameterName,ParameterValue]" \
--output text > default-${parameter_group_family}.txt

一時的に作成したパラメーターGを削除します。

aws rds delete-db-parameter-group \
--db-parameter-group-name tmp-pg

①-② 現パラメーターGの値を抽出

次に、現パラメーターGの値を抽出します。

まず、RDSの識別子を変数に代入します。

db_instance="RDSの識別子"

以下のコマンドをそのまま実行し、現パラメーターG名を変数に定義します。

current_parameter_group=$(aws rds describe-db-instances \
--db-instance-identifier $db_instance \
--query "DBInstances[].[DBParameterGroups[0].DBParameterGroupName]" \
--output text)

そしたら先ほどと同様に現パラメーターGの値を抽出します。
※ファイル名は、「${current_parameter_group}.txt」です。

aws rds describe-db-parameters \
--db-parameter-group-name  ${current_parameter_group} \
--query "Parameters[].[ParameterName,ParameterValue]" \
--output text > ${current_parameter_group}.txt

①-③ 上記2つを比較し、差分を確認

①-①、①-②で取得したファイルの差分を以下のコマンドをそのまま実行し、確認します。

sdiff -s default-${parameter_group_family}.txt ${current_parameter_group}.txt

実行結果例)

character_set_client    None                                  | character_set_client    utf8
character_set_connection        None                          | character_set_connection        utf8
character_set_database  None                                  | character_set_database  utf8
character_set_filesystem        None                          | character_set_filesystem        utf8
character_set_results   None                                  | character_set_results   utf8
character_set_server    None                                  | character_set_server    utf8
timed_mutexes   None                                          | timed_mutexes   0

この差分が現パラメータGのカスタム値となります。 ※上記、実行結果例の場合、character_set系とtimed_mutexesに差分があることが分かります。

②新パラメーターGの作成およびカスタム値を反映

②-①新パラメーターGの作成

まず、新パラメーターGを作成します。 CLIで実行できますが、手順がややこしくなるため、 以下のドキュメントを見て、マネージメントコンソールから作っていただければと思います。

◆DB パラメータグループを作成する https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_WorkingWithParamGroups.html#USER_WorkingWithParamGroups.Creating

②-②新パラメーターGの値を出力

作成した新パラメーターG名を変数に定義します。

new_parameter_group="新パラメーターG名"

新パラメーターGの現在の値(作成したばかりなので、デフォルト値)を取得します。
※ファイル名は、「${new_parameter_group}-default.txt」になります。

aws rds describe-db-parameters \
--db-parameter-group-name  ${new_parameter_group} \
--query "Parameters[].[ParameterName,ParameterValue]" \
--output text > ${new_parameter_group}-default.txt

②-③カスタム値を新パラメーターGへ反映

後は、以下のコマンドを実行します。
※現パラメータGで利用できていたパラメーターが新パラメーターGで使えなくなっている場合もあります。 その場合、エラーになりますが、新規に作成した新パラメーターGであれば、どのRDSでも利用していないので、気にしなくていいと思います。

sdiff -s default-${parameter_group_family}.txt ${current_parameter_group}.txt | while read line
do
   pname=$(echo $line | awk '{print $1}')
   pvalue=$(echo $line | awk '{print $5}')
   aws rds modify-db-parameter-group \
   --db-parameter-group-name ${new_parameter_group} \
   --parameters ParameterName=$pname,ParameterValue=$pvalue,ApplyMethod=immediate
done

実行結果例)

{
    "DBParameterGroupName": "fk-mysql57"
}

中略

{
    "DBParameterGroupName": "fk-mysql57"
}

An error occurred (InvalidParameterValue) when calling the ModifyDBParameterGroup operation: Could not find parameter with name: timed_mutexes

上記実行結果例の場合、「timed_mutexes」がエラーになっているので、 mysql5.7ではこのパラメーターがなくなっていることが分かります。

③設定確認

カスタム値を本当に変更できているか気になりますよね。 以下の方法で解決します。

③-①現パラメーターGのカスタム値を出力
③-②新パラメーターGのカスタム値を出力
③-③上記二つの差分を比較。(設定が正しく反映されていれば、差分がなくなるはずです。)

③-①現パラメーターGのカスタム値を出力

sdiff -s default-${parameter_group_family}.txt ${current_parameter_group}.txt > current-diff.txt

③-②新パラメーターグルプのカスタム値を出力

まずは、カスタム値を反映した新パラメーターGの値を取得します。

aws rds describe-db-parameters \
--db-parameter-group-name  ${new_parameter_group} \
--query "Parameters[].[ParameterName,ParameterValue]" \
--output text > ${new_parameter_group}-after.txt
sdiff -s ${new_parameter_group}-default.txt ${new_parameter_group}-after.txt > new-diff.txt

③-③上記二つの差分を比較。

diff current-diff.txt new-diff.txt

実行結果例)

7d6
< timed_mutexes None                                          | timed_mutexes   0

 →差分があると上記の通り、値が出力されます。
  何も表示がなければ、差分がなく正しくカスタム値を反映できていることが分かります。

終わりに

今回は、RDSのメジャーアップグレードに伴うパラメーターG移行を簡素化してみました。
どなたかのお役に立てれば幸いです。

福島 和弥 (記事一覧)

2019/10 入社

AWS CLIが好きです。