search
LoginSignup
2

More than 1 year has passed since last update.

Organization

MySQLのタイムゾーンを日本時間に修正する(Herokuも対応できるのか?)

問題

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で使われるテキストエディタの一種です。

/usr/local/etc/my.cnf
[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

最後に

もし上記のようにやってもうまくいかなかったり、ご指摘あればぜひコメントください。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
2