亞馬遜的 RDS 沒有辦法直接設 my.cnf 就能設時區,也沒辦法改其 host 上面的時區,導致每個 timestamp 查出來的時間都差了八小時,要確認可以直接 SELECT NOW() 就知道問題了~
mysql 的 my.cnf 對應到 RDS 上稱呼為 DB Parameter Groups,就是一系列的參數供管理者設定,就只能透過這些參數來想辦法解決 timezone 的問題。
在建立 instance 時都要指定一個 Parameter Groups(PG),然後就可以針對這個 PG 做設定來影響 instance 了,只是每次的 PG 修改要套用似乎都要幫 instance 重開機。
要改 timezone 靠的是 init_connect,這個 Parameter 可以指定每次 client 連線時可以執行一句 SQL。搭配 MySQL 的 procedure 建立一個可以修改時區的函式,就能解決這個問題。
所以要先學一些 procedure 的語法,查詢所有存在的 procedure ,rds 內建有一大堆。
show procedure status
也可以查某個 procedure 的定義
show create procedure mysql.rds_kill
呼叫 procedure 則是直接用 call
call mysql.rds_kill
然後要建立一個可以改時區的 procedure 為下,意思為呼叫該 procedure 時該如果連線者不是 rdsadmin 則每次 query 時區都會自動 +8 (台北)
delimiter // CREATE PROCEDURE mysql.store_time_zone() IF NOT (POSITION('rdsadmin@' IN CURRENT_USER()) = 1) THEN SET SESSION time_zone = '+8:00'; END IF // delimiter
如果錯了或者要刪掉
DROP PROCEDURE mysql.store_time_zone
改好後可以測測看,以下語法有沒有確實影響查出來的時間
CALL mysql.store_time_zone; select now()
確認沒問題以後再去 RDS PG 裡面把 init_connect 加上 CALL mysql.store_time_zone,再重開 RDS 就能確定之後的查詢時間都沒錯囉。如果發現改完一直沒辦法連進 mysql query,則是有可能 procedure 沒建立成功,但卻也不能把 init_connect 隨便從 RDS 設定上改成空白,可能要先改掉 instance 的 PG,所以最好確定沒問題以後再設。
千金難買早知道
成功成為 +8 -8 心算專家