Временной сдвиг в phpMyAdmin
версия для печатиПродолжаю тему "временных аномалий" в MySQL :) У меня с хостером разные часовые пояса: у него - GMT+3:00, а на моих сайтах GMT+8:00 (об этом на сайтах скрипты заботятся). Добавлять новости на сайт это не мешает, т.к. время пишется через mysql-функцию now() (текущее значение времени). Проблема появляется, когда мне нужна синхронизация записей с локальной копией БД. Делаю следующее: через phpMyAdmin экспортирую БД в файл - dump.sql, потом загружаю его на своем (местном) сервере MySQL. После такой синхронизации я получаю разницу во времени в 5 часов в каждой записи, где вообще есть время. Покопался и нашел причину! :)
Отступление: согласно документации MySQL, при записи времени в базу его значение сначала переводится в абсолютное UTC-значение (timestamp), потом пишется. Об этом написано где-то здесь (eng). Такой подход ко времени позволяет обойти разногласия часовых поясов при записи. Другими словами, когда я использую функцию now(), то в БД пишется текущее время по Гринвичу (GMT 0:00) в формате timestamp, не зависимо от того, какой часовой пояс у mysql-сессии/сервера.
Итак, проблема.. При экспорте phpMyAdmin сочиняет sql-файл, читая записи в БД:
Файл dump.sql-- phpMyAdmin SQL Dump -- version 3.2.3 ... -- Дамп данных таблицы `table` REPLACE INTO `table` VALUES(38, '2011-08-05 19:11:59', 1, NULL, 'La peau de chagrin' ...); REPLACE INTO `table` VALUES(39, '2011-08-12 03:41:15', 1, NULL, 'Blitz'...);
В этом файле в полях времени стоят уже конкретные форматированные дата/время, а не их UTC-значение. И они сдвинуты на GMT+3:00 часа! Это происходит потому, что при чтении из БД UTC-значение времени преобразуется в читабельную дату/время с учетом часового пояса mysql-сессии/сервера (см. тот же мануал по MySQL). Все даже еще интереснее: в БД по-прежнему хранится точное UTC-время записи, но в дамп оно не попадает, т.к. файл собирается на основании SELECT-запросов, в которые (заботами MySQL) пишется дата со сдвигом, вместо точного timestamp-числа. В итоге, при запуске такого sql-дампа на локальном сервере я получаю сдвиг по времени на -5 часов от настоящего времени записи! Еще круче получится, если я попытаюсь таким же способом (генерацией sql-файла), залить данные обратно на сервер хостера. Вообщем временные сдвиги и UTC-преобразования убивают синхронизацию.
Решение 1: в начале dump-файла добавить запрос с установкой временной зоны, такой же как на сервере хостера. Подробнее об этом читайте здесь: "Работа со временем в PHP/MySQL". В моем случае запрос выглядит так:
Подправленный файл dump.sqlSET SESSION time_zone = 'Europe/Moscow'; -- Далее, собственно дамп экспортируемой таблицы. REPLACE INTO `table` VALUES(38, '2011-08-05 19:11:59', 1, NULL, 'La peau de chagrin' ...); REPLACE INTO `table` VALUES(39, '2011-08-12 03:41:15', 1, NULL, 'Blitz'...);
Решение 2: написать свой инструмент sql-дампа. Допустим, тот же php-скрипт, выполняемый в переменных окружения сайта. Тогда в дамп пойдет время с учетом сдвига, определенного на сайте (совпадающего с "местным" временем), т.е. "правильное" время записи. В крайнем случае, можно в такой дамп-файл так же в начале писать запрос на смену часового пояса для сессии. Теоретически, код будет не сложный :) Но пока это все на уровне идеи.
Есть и другое решение, наверно: отказаться от phpMyAdmin и подключаться к БД другими клиентами. Но мой хостер дал мне доступ к БД только через phpMyAdmin. Цитирую "Доступ извне к базам данных по умолчанию запрещен. Но, если у вас статический ip-адрес и Вы укажете для чего Вам нужен доступ к БД извне, то вопрос будет рассмотрен и, в случае положительного его решения, доступ к базам данных Вам откроют."
[update: 26 августа 2011] Сделал свой Dumper! =) Все отлично работает в обе стороны. Перед сборкой дамп-файла для хостера сначала устанавливаю часовой пояс сессии, все запросы в скрипте выполняются с его учетом. Тогда не нужен лишний запрос в самом файле :)
[1oo%, EoF]Похожие материалы: Работа со временем в PHP/MySQL
Понравилась статья? Расскажите о ней друзьям: