Подтвердить что ты не робот

Настройка для настройки часовой пояс по умолчанию для RDS

Недавно мы переключились на экземпляр RDS и заметили, что куча задач нашей базы данных запускалась на 4 часа раньше, чем нужно. При дальнейшем исследовании проблема возникает из-за установки часового пояса по умолчанию (UTC) на экземпляре RDS. Поскольку этот параметр не может быть изменен, мы хотели бы исправить проблему на уровне кода глобально во всех наших приложениях, используя этот экземпляр базы данных. Я попытался установить временную зону на экземпляре db, который я создаю, на "US/Eastern", используя

set GLOBAL time_zone = 'US/Eastern'" OR
set time_zone = 'US/Eastern'"

Но это порождает ошибку "Ошибка базы данных: неизвестный или неправильный часовой пояс:" US/Eastern "

Как вы думаете, что я здесь делаю неправильно? Кто-нибудь использовал какие-либо другие решения?

4b9b3361

Ответ 1

К сожалению, невозможно установить default_timezone в группах параметров RDS DB, чтобы ваша попытка была в правильном направлении уже.

$ rds-describe-db-parameters default | grep "time_zone"
DBPARAMETER  default_time_zone                                                                   engine-default  string   static   false

Чтобы установить глобальное значение через SET GLOBAL, вам необходимо иметь привилегию SUPER, которая не предоставляется вам как пользователю RDS.

Единственный способ установить time_zone - для каждого соединения.

mysql> SET time_zone = timezone;

На моих машинах я успешно пробовал US/Eastern, но у меня было довольно старое поколение.

Чтобы определить часовые пояса, которые доступны в вашем логе,

mysql -h yourboxhost.rds.amazonaws.com -u <youruser> -p

и введите

mysql> SELECT * FROM mysql.time_zone_name;

Вы должны получить список установленных и действительных имен часовых поясов, которые вы можете установить в своем экземпляре

+----------------------------------------+--------------+
| Name                                   | Time_zone_id |
+----------------------------------------+--------------+
| Africa/Abidjan                         |            1 |
| Africa/Accra                           |            2 |
| Africa/Addis_Ababa                     |            3 |
| Africa/Algiers                         |            4 |
| Africa/Asmara                          |            5 |
| Africa/Asmera                          |            6 |
| Africa/Bamako                          |            7 |
| Africa/Bangui                          |            8 |
| Africa/Banjul                          |            9 |
| Africa/Bissau                          |           10 |
| Africa/Blantyre                        |           11 |
| Africa/Brazzaville                     |           12 |
| Africa/Bujumbura                       |           13 |
| Africa/Cairo                           |           14 |
etc...

Вы должны установить time_zone каждый раз, когда вы подключаетесь к серверу базы данных

Например, если вы используете расширение php Mysqli, вы можете сделать это

$mysqli = mysqli_init();
mysqli_options($mysqli,MYSQLI_INIT_COMMAND,"SET time_zone = 'Africa/Brazzaville'" );
mysqli_real_connect($mysqli,$host, $user, $pass,$dbName) or die ('Unable to connect');

В противном случае просто вручную (с точки зрения использования этого соединителя базы данных) выполните запрос SET time_zone = '<YOUR_DESIRED_TIMEZONE>' Query после того, как вы подключились к своей базе данных

Ответ 3

TL;DR;

Создайте "общую" схему, к которой все ваши пользователи имеют доступ EXECUTE, создайте SPROC, который изменяет часовой пояс сеанса и модифицирует параметр init_connect MySQL для его вызова.


Как сказал Райан Вейр в своем превосходном ответе в двухтомном вопросе, этого следует, по возможности, избежать. Если, однако, вы похожи на меня и хотите реализовать его ради удобства и здравомыслия, я принял решение Райана и внес несколько изменений.

Если у вас есть несколько пользователей, настроенных в MySQL с разными разрешениями, то простое включение sproc в схему mysql может иметь проблемы. Чтобы решить эту проблему, я создал новую схему под названием "shared" и дал всем моим пользователям EXECUTE доступ к этой схеме. Затем я создал следующую хранимую процедуру.

DROP PROCEDURE IF EXISTS shared.store_time_zone;
CREATE PROCEDURE shared.`store_time_zone`()
IF NOT (POSITION('[email protected]' IN CURRENT_USER()) = 1) THEN     
    SET SESSION time_zone = 'US/Pacific';  
END IF;

Я предпочитаю устанавливать "US/Pacific" для обработки летнего времени, но вы должны проверить это, чтобы убедиться, что ваш экземпляр MySQL распознает его в первую очередь. Просто выполните следующий запрос SET SESSION time_zone = 'US/Pacific';, чтобы убедиться, что он работает. Чтобы просмотреть свой часовой пояс, выполните SELECT * FROM mysql.time_zone_name;

В этот момент я рекомендую проверить разрешения перед тем, как вы измените группу параметров и потенциально сломаете все. Просто подключитесь к БД (желательно с пользователем с разрешениями низкого уровня и/или обычно используемыми) и выполните следующие запросы.

CALL shared.store_time_zone;
select now();

Надеюсь, у вас не возникло никаких ошибок и появилось правильное время.

Далее вам нужно будет изменить параметр init_connect в группе параметров базы данных DB, которую использует ваш экземпляр RDS. Вы можете сделать это в веб-консоли RDS через API или утилиту командной строки. Если вы используете командную строку, это будет выглядеть так:

$ rds-modify-db-parameter-group PARAMGROUP --parameters "name=init_connect, value='CALL shared.store_time_zone', method=immediate"

Если вы делаете это через веб-консоль, вам просто нужно изменить значение init_connect.

CALL shared.store_time_zone

Вернитесь к экземпляру RDS в веб-консоли и прокрутите панель сведений до группы параметров DB. Он должен сказать что-то вроде (применение) или (синхронно). После того, как он (в синхронизации), пройдите все, чтобы убедиться, что проблем нет.

Если в этот момент у вас возникают проблемы и вам нужно отбросить файлы, я рекомендую установить значение init_connect на что-то безвредное, например:

SET SESSION time_zone = '-00:00';

Отключить его до пустого с веб-консоли невозможно. См. Эту тему для получения более подробной информации о том, почему один не может восстановить пустое значение для параметра DB

Ответ 4

@Решение Thomas Paine работает для меня, за исключением того, что я использовал для пользователя user() вместо current_user(), как внутри контекста init_connect current_user() возвращает главного пользователя RDS. (Посредством мастера я не имею в виду rdsadmin, который является реальным пользователем root, но пользователь, созданный с экземпляром DB с большинством привилегий.)

Ответ 5

Я сделал следующие шаги, чтобы изменить часовой пояс

  • войдите в RDS и создайте новую группу параметров.

  • Отредактируйте вновь созданную группу параметров

  • Установить time_zone Ex: Азия/Калькутта и сохранить изменения

  • Измените экземпляр RDS, измените группу параметров DB на вновь созданную группу параметров

  • Сохранить и перезагрузить экземпляр RDS