#問題
HerokuにデプロイしたWebアプリ、MySQLのDBの時間がどうも日本時間と9時間ずれている...問題はここの設定のようです↓
mysql> show variables like "%time_zone%";
+------------------+--------+
| Variable_name | Value |
+------------------+--------+
| system_time_zone | UTC |
| time_zone | SYSTEM |
+------------------+--------+
###本記事の読み方
結論から言うと、HerokuではClearDBのようなAdd-onのDBのタイムゾーンは直せないみたいです。詳細は後述します。
ただし、MySQL自体のタイムゾーンは変更できました。まず私が解決できた方法をシェアし、次にうまくいかなかった方法もメモしておきます。
この問題の解決に関して、またしても**YouTube万屋エンジニアチャンネル様**の協力をいただきました。いつもありがとうございます。
###環境
MySQL, Heroku, ClearDB MySQL, MacOS
#私の解決方法
公式ドキュメントを読むと、タイムゾーンテーブルのロードが必要で、そのためにmysql_tzinfo_to_sqlプログラムを使用するべきかな?と推測し下記コマンドを実行。
MySQL のインストール手順では、mysql データベース内にタイムゾーンテーブルを作成しますが、これらをロードしません。次の手順を使用して、手動でこれを行う必要があります。
(「10.6 MySQL Server でのタイムゾーンのサポート」より抜粋)
$ mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql
Warning: Unable to load '/usr/share/zoneinfo/+VERSION' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/iso3166.tab' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/leapseconds' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/zone.tab' as time zone. Skipping it.
↑Warningが出ている。/usr/share/zoneinfoのディレクトリには変化なし...でもOKらしい。
↓MySQLにrootユーザーでログインし、mysql.time_zoneテーブルを呼び込むと縦長にどかっとNだらけのテーブルが出てきます。これがタイムゾーンテーブルのデータらしいです。
$ mysql -u root
(中略)
mysql> select * from mysql.time_zone;
+--------------+------------------+
| Time_zone_id | Use_leap_seconds |
+--------------+------------------+
| 1 | N |
| 2 | N |
| 3 | N |
| 4 | N |
中略
| 593 | N |
| 594 | N |
| 595 | N |
| 596 | N |
+--------------+------------------+
596 rows in set (0.03 sec)
文字コードの設定の時と同様、MySQLの設定ファイル(/usr/local/etc/my.cnf)を編集します。MySQL設定ファイルに関しては、その記事の中で詳しく書いたのでよろしければご参照ください→#MySQLの設定ファイルを探せ!
$ vi /usr/local/etc/my.cnf
でファイルを開き、i
で編集開始、下記のように[mysqld]の箇所に追記。終了後、escボタン
> :wq(保存して終了)
>Enterボタン
。
ちなみにvi
とはUNIX系OSで使われるテキストエディタの一種です。
[mysqld]
default-time-zone = 'Asia/Tokyo'
↓MySQLを再起動。sudoはなくてもいいのかもです。(sudo = superuser do, substitute user doという意味のコマンド。ログインしているユーザーが別の管理者権限で実行すること)
$ sudo mysql.server stop
Password:→パスワード入力
Shutting down MySQL
.. SUCCESS!
$ sudo mysql.server start
Starting MySQL
.. SUCCESS!
↓これでもう一度rootユーザーでログインして設定を確認すると...
mysql> show variables like "%time_zone%";
+------------------+------------+
| Variable_name | Value |
+------------------+------------+
| system_time_zone | JST |
| time_zone | Asia/Tokyo |
+------------------+------------+
↑きちんと設定が変更されています!しかしながら、HerokuのMySQL(ClearDB)は変わってませんでした。
#HerokuのClearDB MySQLは変更できず
文字コードの設定の時は、ClearDB MySQLもきちんと設定が変わったのですが、タイムゾーンは直りませんでした。
ひょっとしたら、先にタイムゾーンテーブルのロードをした時にrootと指定しているからか?と思い、rootをClearDBのDB_USERNAMEに変更したり、-pオプション、-hオプションを加えたりしてトライしましたがダメでした。
$ mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u 私のDB_USERNAME mysql
Warning: Unable to load '/usr/share/zoneinfo/+VERSION' as time zone. Skipping it.
ERROR 1045 (28000): Access denied for user '私のDB_USERNAME'@'localhost' (using password: NO)
$ mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u 私のDB_USERNAME -p mysql
Warning: Unable to load '/usr/share/zoneinfo/+VERSION' as time zone. Skipping it.
Enter password:
ERROR 1045 (28000): Access denied for user '私のDB_USERNAME'@'localhost' (using password: YES)
$ mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u 私のDB_USERNAME -h 私のDB_HOST -p mysql
Warning: Unable to load '/usr/share/zoneinfo/+VERSION' as time zone. Skipping it.
Enter password:
ERROR 1044 (42000): Access denied for user '私のDB_USERNAME'@'%' to database 'mysql'
どうしても時間を直さないといけない場合は、プログラムの方でなんとかする方が良いみたいです。
#うまくいかなかった方法、やらなくてもよかったこと
ここからは自分用のメモという意味合いが強いです。
タイムゾーンの変更の仕方をネット上で探すと下記コマンドがよく提示されていますが、私の場合はやってもエラーになり、やる必要もありませんでした。
$ /usr/bin/mysql_tzinfo_to_sql /usr/share/zoneinfo > ~/timezone.sql
$ mysql -u root -p -Dmysql < ~/timezone.sql
一行目のコマンドでダメでした...↓
$ /usr/bin/mysql_tzinfo_to_sql /usr/share/zoneinfo > ~/timezone.sql
-bash: /usr/bin/mysql_tzinfo_to_sql: No such file or directory
それもそのはず指定したディレクトリにそんなファイルはなかったです↓
$ cat /usr/bin/mysql_tzinfo_to_sql
cat: mysql_tzinfo_to_sql: No such file or directory
ご参考にzoneinfoの様子↓
$ ls /usr/share/zoneinfo
+VERSION Australia EET Factory Greenwich Jamaica Mexico Poland US leapseconds
Africa Brazil EST GB HST Japan NZ Portugal UTC posixrules
America CET EST5EDT GB-Eire Hongkong Kwajalein NZ-CHAT ROC Universal zone.tab
Antarctica CST6CDT Egypt GMT Iceland Libya Navajo ROK W-SU
Arctic Canada Eire GMT+0 Indian MET PRC Singapore WET
Asia Chile Etc GMT-0 Iran MST PST8PDT Turkey Zulu
Atlantic Cuba Europe GMT0 Israel MST7MDT Pacific UCT iso3166.tab
こちらはファイルがあったが中身は空↓
$ cat timezone.sql
そういや以前別件MySQLの中を漁っていたとき、mysql_tzinfo_to_sqlというファイルがここにありました↓
9 10 19:01 mysql_tzinfo_to_sql -> ../Cellar/mysql/8.0.21_1/bin/mysql_tzinfo_to_sql
9 10 19:01 mysql_tzinfo_to_sql -> ../Cellar/mysql/8.0.21_1/bin/mysql_tzinfo_to_sql
cd /usr/local/Cellar/mysql/8.0.21_1
#最後に
もし上記のようにやってもうまくいかなかったり、ご指摘あればぜひコメントください。