When will /usr/my.cnf be created?

先日、my.cnfに設定したsql_modeが効かなくて困った話をアップしました。

その作業中に、DBサーバによって/usr/my.cnfがあったりなかったりすることを発見しました(しかもMySQLのバージョンは同一)。

この怪奇現象を突き止めるためには、/usr/my.cnfを作成しているmysql_install_dbがいつ実行されているのか突き止める必要があります。

調べたところ、mysqldのinitスクリプトでmysql_install_dbを叩いていました。具体的にはstart()の中で叩かれていました。以下がmysql_install_dbの実行されていたブロックです。

if [ ! -d "$datadir/mysql" ] ; then
    # First, make sure $datadir is there with correct permissions
    if [ ! -d "$datadir" -a ! -h "$datadir" -a "x$(dirname "$datadir")" = "x/var/lib" ]; then
        install -d -m0755 -omysql -gmysql "$datadir" || exit 1
    fi
    if [ ! -h "$datadir" -a "x$(dirname "$datadir")" = "x/var/lib" ]; then
        chown mysql:mysql "$datadir"
        chmod 0755 "$datadir"
    fi
    if [ -x /sbin/restorecon ]; then
        /sbin/restorecon "$datadir"
        for dir in /var/lib/mysql-files ; do
            if [ -x /usr/sbin/semanage -a -d /var/lib/mysql -a -d $dir ] ; then
                /usr/sbin/semanage fcontext -a -e /var/lib/mysql $dir >/dev/null 2>&1
                /sbin/restorecon $dir
            fi
        done
    fi
    # Now create the database
    action $"Initializing MySQL database: " /usr/bin/mysql_install_db --rpm --datadir="$datadir" --user=mysql
    ret=$?
    if [ $ret -ne 0 ] ; then
        return $ret
    fi
fi

おお、$datadir/mysql(= /var/lib/mysqlなど)が存在しない場合、ディレクトリの作成と、mysql_install_dbを使ってデータベースの初期化を行っていることがわかりました。

さて、今回DBサーバによって/usr/my.cnfがあったりなかったりする現象に混乱してしまったわけですが、これで原因がわかりました。

DBサーバのリプレースのために、/var/lib/mysql以下を丸ごとコピーして(もうちょっと複雑な手順ですが)リプレースを行ったことが過去にあり、その場合は**/var/lib/mysqlが既にあるので、mysqldをstartしてもmysql_install_dbが実行されず**(if [ ! -d "$datadir/mysql" ] ; thenブロック内が実行されないので)、それによって**/usr/my.cnfが作られなかった**のです。

そしてリプレースではなく新規に作成したDBサーバでは、mysqldをstartした時点でまだ/var/lib/mysqlが存在しないのでmysql_install_dbが実行され、/usr/my.cnfが作成されていたというわけでした。

ややこしい…。

感想

スッキリした! ✨

だけどわかるかこんなもん!!!!!!!!!!!!!!!!

勉強になりました…。

参考

  • 先輩