mysql 環境毎にDBスキーマが異なってるかどうかを調べる

Webアプリケーションの開発などでは、開発環境・ステージング環境・プロダクション環境など複数の環境が準備されて、運用が行なわれます。ソースコードの管理は、svnやgitから自動デプロイを行なうようになっていれば、svnやgitで管理されているコードと実際に動作しているコードが同一であることが保証できます。しかし、いろんな理由で、DBのスキーマ情報には、ずれが生じてしまうことが多いと思います。

  • プロダクション環境でしか発生しないバグに緊急対応したため、スキーマ変更が他環境に反映されなかった。
  • 性能改善のためのインデックス付加などのスキーマ変更が、プロダクション環境だけに適応される。
  • 調査のために、ステージング環境だけで付加したインデックスが残ったままになる。

などなど、根本的には、別の方法を考えた方がいいんだろうけど、ずれてしまったものは仕方がない。今、どれだけの差異があるのかを調べるのは結構骨が折れる作業だと思うので、スクリプトを書いて検査する方法を取ってみた。

diffを取りやすい形でテーブルの情報を出力するスクリプトを用意する

#!/usr/bin/perl
use strict;
use warnings;
use utf8;
 
sub options {
    die "usage: $0 <user> <password> <host> <database>\n" if scalar(@ARGV) != 4;
 
    return {
        user => $ARGV[0],
        password => $ARGV[1],
        host => $ARGV[2],
        database => $ARGV[3],
    };
}
sub mysql_command {
    my $options = shift;
    my $command = "mysql -u $options->{user} ";
    $command .= "-p$options->{password} " if $options->{password};
    $command .= "-h $options->{host} " if $options->{host};
    $command .= "$options->{database}";
    return $command;
}
my $options = options();
 
my $command = "echo show tables | " . mysql_command($options);
my @tables = split(/\s/, `$command`);
for my $t (@tables) {
    print "=== $t ===\n";
    my $command = "echo show columns from $t | " . mysql_command($options);
    my @columns = split(/\n/, `$command`);
    for my $line (@columns) {
        print "$t\t$line\n";
    }
    print "\n";
}

データの採取

$ ./dump_schema_mysql.pl hogehoge **** db_dev_server db_name > schema_dev.txt
$ ./dump_schema_mysql.pl hogehoge **** db_production_server db_name > schema_productoin.txt

比較

diffの結果を一番見易く表示してくれるのは、もちろんvim!

$ vimdiff schema_dev.txt schema_production.txt

実行結果

gvim の colorscheme morningを使うと見易いです。

:colorscheme morning

3件のコメント

  • 良い記事でした!

  • ありがとうございますー

  • Mansoor, ever state has to deal with a myriad of problems, that doesn’t mean there is a conspiracy against it.

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です


The reCAPTCHA verification period has expired. Please reload the page.

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください