Обновление часовых поясов для mysql на сервере FreeBSD

#0. Резюме

Помимо основной базы системных зон часовых поясов на сервере, некоторые службы, такие как mysql, могут использовать свои собственные зоны часовых поясов. В итоге можно наблюдать картину, когда время в mysql отстаёт или опережает системное.

# mysql -uadmin -p -e "select current_timestamp();"
Enter password: 
+---------------------+
| current_timestamp() |
+---------------------+
| 2014-11-20 14:58:22 | 
+---------------------+
# echo "System Time: " ; date "+%d.%m.%Y %H:%M"
System Time: 
20.11.2014 13:59

Как видим, системное время и время в mysql различаются. Чтобы этого избежать, помимо обновления системных часовых поясов, требуется отдельно обновлять time_zone (zoneinfo) для mysql (php, postgresql, java и т.п.).

СУБД MySQL может использовать системные зоны часовых поясов, а может использовать свои собственные. В первую очередь нужно проверить какую таймзону использует СУБД для отображения времени.

# mysql -uadmin -p -e "SHOW VARIABLES LIKE '%time_zone%';"
Enter password: 
+------------------+---------------+
| Variable_name    | Value         |
+------------------+---------------+
| system_time_zone | MSK           | 
| time_zone        | Europe/Moscow | 
+------------------+---------------+

Временная зона Europe/Moscow, а время системное и в субд различается. Похоже, что ранее были загружены на текущий момент устаревшие зоны. Выхода два: обновить временные зоны mysql или указать использовать системные временные зоны.

#1. Обновление зон часовых поясов для mysql через mysql_tzinfo_to_sql

Загружаем в mysql новые системные временные зоны и перезапускаем mysqld.

# mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -uadmin mysql -p
# /usr/local/etc/rc.d/mysql-server restart

Зоны обновлены, можно проверять время.

# mysql -uadmin -p -e "select current_timestamp();;"
Enter password: 
+---------------------+
| current_timestamp() |
+---------------------+
| 2014-11-20 14:30:13 | 
+---------------------+
# echo "System Time: " ; date "+%d.%m.%Y %H:%M"
System Time: 
20.11.2014 14:30

Время системное и время СУБД совпадают. Profit!

#2. Использовать для mysql системные временные зоны

Чтобы не морочиться с периодическим обновлением временных зон для mysql, можно указать СУБД использовать временные зоны системы. Заходим в mysql.

# mysql -uadmin -p
mysql> SET GLOBAL time_zone = 'SYSTEM';
Query OK, 0 rows affected (0.02 sec)
mysql> SET time_zone = 'SYSTEM';
Query OK, 0 rows affected (0.00 sec)

Теперь проверяем время на соответствие с системным.

# mysql -uadmin -p -e "select current_timestamp();;"
Enter password: 
+---------------------+
| current_timestamp() |
+---------------------+
| 2014-11-20 14:47:23 | 
+---------------------+
# echo "System Time: " ; date "+%d.%m.%Y %H:%M"
System Time: 
20.11.2014 14:47

Время системное и время СУБД совпадают. Profit!

#3. Post Scriptum

Таким же образом можно вместо SYSTEM назначать конкретные зоны, предварительно загрузив их через mysql_tzinfo_to_sql.

# mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -uadmin mysql -p
# /usr/local/etc/rc.d/mysql-server restart
# mysql -uadmin -p
mysql> SET GLOBAL time_zone = 'Europe/Moscow';
Query OK, 0 rows affected (0.00 sec)
mysql> SET time_zone = 'Europe/Moscow';
Query OK, 0 rows affected (0.01 sec)