TIME_ZONE MariaDB

Аналогічна проблема, як і в mysqldump - mariadb-dump змінює час полів timestamp...

Взагалі-то че фіча... для переносу дампів між серверами на різних часових поясах, але в мене і прод-сервери і локальний сервер працюють на одному часовому поясі, але це виглядає як проблема, бо час постйно зсуваєтся...

У MariaDB для mariadb-dump логіка така сама, як і для mysqldump: за замовчуванням утиліта вмикає --tz-utc, через що в дамп додаються рядки виду:

/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
...
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

і TIMESTAMP конвертується в UTC.

Щоб цього не було, потрібно вимкнути tz-utc саме для клієнта mariadb-dump.

Правильний варіант — додати в конфіг:

Файл (якщо нема - створити):

/etc/mysql/conf.d/mariadb-dump.cnf

або (може бути)

/etc/my.cnf.d/mariadb-dump.cnf

Вміст:

[mariadb-dump]
tz-utc=0

Або можна універсально (не пробував):

[client]
tz-utc=0

Після цього:

  • рядки SET TIME_ZONE=... з дампу зникнуть

  • TIMESTAMP буде вивантажуватись без конвертації в UTC

  • час залишиться таким самим, як у таблиці

Перевірити, що опція підхопилась, можна так:

Там має з’явитися --tz-utc=0.

Якщо не спрацює — подивись, які конфіги реально читаються:

Це покаже список файлів, з яких воно бере налаштування.


Різниця поведінки TIMESTAMP vs DATETIME у цьому контексті

Різниця принципова, і саме через неї виникають ці проблеми з дампами.

1. TIMESTAMP

TIMESTAMP зберігається всередині в UTC, але:

  • при записі → значення конвертується з поточної time_zone сесії в UTC

  • при читанні → з UTC конвертується назад у time_zone сесії

Тобто сервер завжди "крутить" час через часовий пояс сесії.

Що робить dump

За замовчуванням mariadb-dump вмикає:

і тоді:

  • значення читаються з сервера як UTC

  • в дамп записується UTC-час

  • при відновленні все знову працює правильно

Це зроблено для переносимості між серверами з різними timezone.

Якщо вимкнути tz-utc

Тоді:

  • dump читає значення в поточному timezone

  • в SQL пишеться саме той текст, який ти бачиш в SELECT

  • ніякої конвертації не відбувається

Але якщо ти відновиш дамп на сервері з іншим time_zone, значення можуть "поїхати".


2. DATETIME

DATETIME:

  • зберігається буквально як число

  • не має жодної прив’язки до timezone

  • сервер його ніколи не конвертує

Тобто:

завжди буде саме цим значенням, незалежно від налаштувань сервера.

Dump для DATETIME нічого не змінює — tz-utc на нього не впливає.


3. Приклад, щоб було зрозуміло

Припустимо:

Ти вставляєш:

Якщо поле TIMESTAMP

В БД реально зберігається:

При SELECT ти знову побачиш 15:00.

Якщо dump ставить TIME_ZONE='+00:00', то в дамп піде:


Якщо поле DATETIME

В БД зберігається буквально:

І дамп завжди міститиме саме це.


4. Коли що використовувати

Використовуй TIMESTAMP якщо:

  • це реальний момент часу (подія, лог, created_at)

  • сервери можуть бути в різних timezone

  • важлива абсолютна точка в часі

Використовуй DATETIME якщо:

  • це "локальний" час (наприклад, "прийом о 09:00")

  • час не повинен змінюватись при міграції

  • ти хочеш повністю контролювати timezone на рівні застосунку


5. Чому у тебе змінювався час

Бо:

  1. TIMESTAMP зберігається в UTC

  2. dump ставив SET TIME_ZONE='+00:00'

  3. ти бачив різницю між тим, що в SELECT, і тим, що в дампі

Це не помилка — це механізм захисту від зміни часу при переносі.


Якщо ти працюєш із серверами сам і timezone у тебе стабільний — можна сміливо вимикати tz-utc.

Якщо ж база може переїжджати — краще залишати його увімкненим.

Якщо хочеш — можу показати практичний сценарій, де вимкнений tz-utc реально ламає продакшн.

Last updated