Detaillierte Erläuterung der Fallstricke von DTS, die durch die Zeitstempel- und Datums-/Uhrzeitzonenprobleme in MySQL verursacht werden

Detaillierte Erläuterung der Fallstricke von DTS, die durch die Zeitstempel- und Datums-/Uhrzeitzonenprobleme in MySQL verursacht werden

Wie wird die aktuelle Uhrzeit in MySQL dargestellt?

Tatsächlich gibt es viele Möglichkeiten, dies auszudrücken, die wie folgt zusammengefasst werden können:

Datentyp „Null“-Wert
DATE '0000-00-00'
TIME '00:00:00'
DATETIME '0000-00-00 00:00:00'
TIMESTAMP '0000-00-00 00:00:00'
YEAR 0000

Sowohl der Datums- als auch der Zeitstempeltyp werden verwendet, um Daten im Format JJJJ-MM-TT HH:MM:SS darzustellen, es gibt jedoch einige Unterschiede zwischen den beiden.

abschließend

  • Der Zeitstempel speichert tatsächlich die Anzahl der Sekunden vom 01.01.1970 00:00:00 UTC bis heute und belegt 4 Bytes (mehr Bytes werden verwendet, wenn die Zeitgenauigkeit Millisekunden und Nanosekunden beträgt), sodass er der Zeit mit einer Zeitzone entspricht. Durch Einstellen der Zeitzone der Sitzung wird diese automatisch in die Zeit der eingestellten Zeitzone konvertiert.
  • Datetime speichert eine formatierte Zeichenfolge ähnlich wie „2021-12-05 13:27:53.957033“, die jedoch keine Zeitzoneninformationen enthält. Die in den Zeitzonen UTC und CST abgefragten Ergebnisse sind konsistent. Beispielsweise wird „2021-12-05 13:27:53.957033“ in der Zeitzone CST geschrieben, aber in der Zeitzone UTC abgefragt, lautet dies immer noch „2021-12-05 13:27:53.957033“. Wenn die Zeitzonenkonvertierung nicht durchgeführt wird, entspricht dies einer direkten Zuordnung der CST-Zeit zur UTC-Zeit, aber tatsächlich ist die UTC-Zeit 8 Stunden langsamer als die CST-Zeit.

verifizieren

Umgebungsvorbereitung, kurz gesagt, es gibt eine Tabelle mit Zeitstempelfeld und Datums-/Uhrzeitfeld, und der aktuelle Server befindet sich in der CST-Zeitzone

mysql> show create table test_time\G;
*************************** 1. Reihe ***************************
Tabelle: test_time
Tabelle erstellen: CREATE TABLE `test_time` (
  `id` int NICHT NULL AUTO_INCREMENT,
  `ts` Zeitstempel(6) NULL DEFAULT CURRENT_TIMESTAMP(6) BEI UPDATE CURRENT_TIMESTAMP(6),
  `dt` datetime(6) DEFAULT CURRENT_TIMESTAMP(6) BEI UPDATE CURRENT_TIMESTAMP(6),
  PRIMÄRSCHLÜSSEL (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 Zeile im Satz (0,00 Sek.)

mysql> Variablen wie „%time_zone%“ anzeigen;
+------------------+--------+
| Variablenname | Wert |
+------------------+--------+
| Systemzeitzone | CST |
| Zeitzone | SYSTEM |
+------------------+--------+
2 Zeilen im Satz (0,01 Sek.)

Fügen Sie ein Datenelement ein. Die Ergebnisse von ts und dt sind in der aktuellen CST-Zeitzone gleich.

mysql> wähle * aus Testzeit;
Leerer Satz (0,00 Sek.)

mysql> in test_time() Werte einfügen();
Abfrage OK, 1 Zeile betroffen (0,00 Sek.)

mysql> wähle * aus Testzeit;
+----+----------------------------+----------------------------+
| id | ts | dt |
+----+----------------------------+----------------------------+
| 3 | 05.12.2021 15:04:13.293949 | 05.12.2021 15:04:13.293949 |
+----+----------------------------+----------------------------+
1 Zeile im Satz (0,00 Sek.)

Stellen Sie die Zeitzone der Sitzung auf UTC ein und führen Sie die Abfrage erneut durch. Das Ergebnis der ts-Abfrage ist 8 Stunden langsamer als zuvor, da die Zeitzone von CST auf UTC geändert wird. Da dt keine Zeitzoneninformationen überträgt, bleibt das Ergebnis unverändert.

mysql> setze Zeitzone='+00:00';
Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)

mysql> wähle * aus Testzeit;
+----+----------------------------+----------------------------+
| id | ts | dt |
+----+----------------------------+----------------------------+
| 3 | 05.12.2021 07:04:13.293949 | 05.12.2021 15:04:13.293949 |
+----+----------------------------+----------------------------+
1 Zeile im Satz (0,01 Sek.)

Dies spiegelt sich auch im Binärprotokoll wider, das durch den Einfügevorgang generiert wird. ts wird im Binärprotokoll als Zeitstempel gespeichert (die Anzahl der Sekunden vom 01.01.1970 00:00:00 UTC bis heute), was den UTC-Zeitzoneninformationen entspricht. dt ist ohne die Zeitzoneninformationen. Das Ergebnis ist die formatierte Zeichenfolge 2021-12-05 15:04:13.293949. Konzentrieren Sie sich auf die vierte und fünfte Zeile von unten. @2=1638687853.293949 stellt den Wert des ts-Felds dar und @3='2021-12-05 15:04:13.293949' stellt den Wert des dt-Felds dar.

[mysql %] mysqlbinlog -v --base64-output=Zeilen dekodieren ./mysqlbin.000012
... ...
SETZEN @@SESSION.GTID_NEXT= '1cf4493a-dafd-11eb-944c-4016af29c14c:1416767'/*!*/;
# bei 14220
#211205 15:04:13 Server-ID 1 End-Log-Pos 14308 CRC32 0x1fd913a3 Abfrage Thread-ID = 137 Exec-Zeit = 0 Fehlercode = 0
ZEITSTEMPEL FESTLEGEN=1638687853.293949/*!*/;
BEGINNEN
/*!*/;
# bei 14308
#211205 15:04:13 Server-ID 1 end_log_pos 14368 CRC32 0xbb8937fb Table_map: `testa`.`test_time` zugeordnet zur Nummer 121
# bei 14368
#211205 15:04:13 Server-ID 1 end_log_pos 14423 CRC32 0x2e0a3baa Write_rows: Tabellen-ID 121 Flags: STMT_END_F
### INSERT INTO `testa`.`test_time`
### SATZ
### @1=3
### @2=1638687853.293949
### @3='2021-12-05 15:04:13.293949'
# bei 14423
#211205 15:04:13 Server-ID 1 end_log_pos 14454 CRC32 0x68cee280 Xid = 1416
BEGEHEN /*!*/;

Grube

  • Wenn Sie ein Open-Source-Tool zum Analysen von MySQL Binlog verwenden, wenn Sie DTS-bezogene Projekte wie Github.com/go-mysql-org/go-mysql durchführen, und konfigurieren Sie Parsetime = true, das Timestamp-Typ wird als lokaler Zeit analysiert, und das Timing-Tim-Tim-Tim-Tim-Tim-Tim-Tim-Tim-Tim-Tim-Time-Tim-Time-Tim-Tim-Tim-Tim-Tim-Zeitpunkt, und das Timing-Time-Tim-Tim-Tim-Time-Time-Time-Time-Time-Time-Time-Time-Time-Time-Time-Time-Time-Time-Time-Time-Time-Time-Tim-Time-Tim-Time-Tim-Time-Tim-Time-Tim-Tim-Tim-Tim-Tim. Die native Zeichenfolge in Binlog. -05 07: 04: 13.293949 Um korrekt zu sein.
  • Wenn aus geschäftlichen Gründen ein Vergleich zwischen der durch time.Now() erhaltenen Ortszeit und einem Feld vom Typ „datetime“ erforderlich ist, müssen Sie das Zeitzonenproblem beachten oder die Zeitzone aus der Zeit entfernen und sie zum Vergleich in eine formatierte Zeichenfolge konvertieren.
  • Da Datum und Uhrzeit selbst keine Zeitzoneninformationen enthalten, gibt es keine bessere Wahl als die Umrechnung in die UTC-Zeit. Dies stellt also eine Falle dar!

Damit ist dieser Artikel abgeschlossen, in dem die Fallstricke von DTS, die durch die Zeitzonenprobleme von Zeitstempel und Datum/Uhrzeit in MySQL verursacht werden, ausführlich erläutert werden. Weitere Informationen zu den Fallstricken von MySQL-Zeitstempel und Datum/Uhrzeit finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen!

Das könnte Sie auch interessieren:
  • Der Unterschied und die Wahl zwischen Datum und Uhrzeit und Zeitstempel in MySQL
  • In der MySQL-Datenbank werden datetime, bigint und timestamp zur Darstellung der Zeitauswahl verwendet. Welches davon ist für die Zeitspeicherung am effizientesten?
  • Der Unterschied und die Verwendung von Datum/Uhrzeit und Zeitstempel in MySQL
  • Datums-/Uhrzeit- und Zeitstempelvergleich in MySQL
  • Zusammenfassung der Verwendung von Datetime und Timestamp in MySQL

<<:  Die Bedeutung der 5 Leerzeichenarten in HTML

>>:  So verhindern Sie, dass Benutzer Webseiteninhalte mit reinem CSS kopieren

Artikel empfehlen

Lösen Sie das Problem des IDEA-Konfigurations-Tomcat-Startfehlers

Beim Konfigurieren unterschiedlicher Servlet-Pfad...

Verwenden Sie thead, tfoot und tbody, um eine Tabelle zu erstellen

Manche Leute verwenden diese drei Tags auf pervers...

Lösen Sie das Docker.Socket-Berechtigungsproblem des VSCode-Docker-Plugins

Lösung: Beenden Sie alle mit .vscode in Zusammenh...

MySQL-Update-Fall Update-Feldwert ist keine feste Operation

Wenn bei der Verarbeitung von Batch-Updates besti...

Detaillierte Erklärung langsamer MySQL-Abfragen

Informationen zu MySQL-Vorgängen abfragen Status ...

Verwenden von CSS3 zum Erzielen von Übergangs- und Animationseffekten

Warum sollten wir CSS-Animationen anstelle von JS...

Implementierungsschritte zum Erstellen eines lokalen Webservers auf Centos8

1 Übersicht System CentOS8, verwenden Sie httpd, ...

So verwenden Sie Nginx zum Proxy mehrerer Anwendungssites in Docker

Vorwort Was ist die Rolle eines Agenten? - Mehrer...

Verwenden Sie die mail()-Funktion von PHP zum Senden von E-Mails

Senden von E-Mails mit der Mail-Funktion von PHP ...