Re: Zeit und Zeitzonen richtig konfigurieren

From: Andreas Seltenreich <andreas+pg(at)gate450(dot)dyndns(dot)org>
To: pgsql-de-allgemein(at)postgresql(dot)org
Subject: Re: Zeit und Zeitzonen richtig konfigurieren
Date: 2006-04-04 04:14:23
Message-ID: 87vetqrn8g.fsf@gate450.dyndns.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-de-allgemein

Ich versuche mal, auf die noch offenen Fragen einzugehen...

Johannes Brügmann schrob:

> ich habe folgendes System am Start und wüßte gerne, wie ich es am
> besten konfiguriere, damit alle beteiligten Clients (drei Gruppen) die
> jeweils korrespondierenden Zeitstempel erhalten und damit alle
> beteiligten möglichst effizient arbeiten können:
>
> (a) mehrere Clients populieren eine Tabelle der Datenbank mit Tupeln
> der Form (timestamptz, id1, id2, id3, data ...). Dabei bilden
> timestamptz, id1, id2, id3 den Primärschlüssel. (id1, id2, id3) ist
> ein referenzierter Fremdschlüssel. Jeder dieser Clients hatte bislang
> (bis zum "rumspielen" an der Konfiguration heute) die
> Umgebungsvariable PGTZ=CET und erhält Daten aus der Standardeingabe,
> die allesamt Winterzeit referenzieren. Jeder dieser Clients erhält
> seine Zeit als Argument z.B. -t '03.04.2006 12:00:00'. Den Wert
> dieses

D.h., die Stempel sind immer UTC+01, auch im Sommer? In diesem Fall
wäre "CET" die falsche Wahl, denn bei der Verwendung als
Session-Zeitzone bezeichnet "CET" die Zeitzone als Ort, und nicht als
Offset. PGTZ=CET verhält sich wahrscheinlich fast identisch zu
PGTZ=Europe/Berlin.

Damit würde '01.01.2006 12:00:00' zu '01.01.2006 12:00:00 UTC+01'
und '01.04.2006 12:00:00' zu '01.04.2006 12:00:00 UTC+02'
...und dahin ist die Bedeutungstreue.

> Arguments (string, libpqxx) verwendet der Client beim Einfügen in die
> Datenbank. Die Tabelle enthält mittlerweile Daten mit mehr als
> 100GB. Im Endstadium schätze ich das Volumen auf 200GB.
>
> (b) andere Clients starten zu einem beliebigen Zeitpunkt und setzen
> ihre Uhr auf localtime abgerundet auf die volle Minute weniger ein
> paar gewollten Verzögerungsminuten. Aufgabe dieser Clients ist es, die
> jeweils ihrer Zeit entsprechenden neuesten Daten zu erfragen und
> korrespondierende Rechenergebnisse zurückzuschreiben. In der
> Sommerzeit (CEST) wollen sie die Daten mit ihrem Zeitstempel - 1h; in
> der Winterzeit - 0h. Auch diese Clients haben PGTZ=CET bzw. jetzt
> PGTZ=+01.

Wozu hier die Unterscheidung der DST? Ein Vergleich mit
"date_trunc('minute', now()) - verzögerung" sollte unabhängig von DST
und Session-Zeitzone die selben Tupel liefern. Vorausgesetzt, die
Stempel wurden in (a) auch konsistent eingepflegt.

> (c) die letzte Gruppe von Clients will nur die stets aktuellsten
> Rechenergebnisse der vorherigen Gruppe (b). Auch diese Clients
> verwenden die leicht modifizierte localtime(0) wie oben bei der
> Datenbankanfrage. Sie besitzen die Umgebungsvariable PGTZ=-0000. Die
> Tabelle, deren Daten sie abfragen, hat die Form (timestamptz,
> (Fremdschlüssel), data ...). Dieser Fremdschlüssel ist nicht identisch
> mit (a). Die Tabelle enthält zwar nur jeweils die letzten 24- oder
> eventuell auch weniger Stunden, jedoch sind das auch in etwa
> 1240-Datensätze pro Minute.
>
> Die Systemzeit war bis gestern Europe/Berlin, seit heute
> UTC.

Was war die Motivation? Was ist mit Systemzeit gemeint? Die Zeitzone
des Betriebssystems? Letztere hat AFAIK lediglich Auswirkungen auf den
Defaultwert der Session-Zeitzone, welchen du ja überall zu
überschreiben scheinst.

> Phänomen:
>
> Es sei 03.04.2006 09:00:00 UTC. Ein (a)-Client hat Daten mit
> '03.04.2006 10:00:00 +01' und schreibt diese in die Datenbank. Eine
> spätere Anfrage mittels PGTZ=UTC psql liefert keine Daten mit
> '03.04.2006 09:00:00'. Die Daten erhalte ich nur mit '03.04.2006
> 08:00:00'.

Wenn meine Vermutung bei (a) stimmt, dann könnte man das so erklären:

Tatsächlicher Eingabestempel: '03.04.2006 09:00:00 UTC'

Client (a) bekommt '03.04.2006 10:00:00'

Mit PGTZ=CET landet dadurch das falsche '03.04.2006 8:00:00 UTC' auf
der Platte, was man dann mit PGTZ=UTC auch so zu sehen bekommt.

> Mittlerweile habe ich die (a)-Clients umgestellt auf
> PGTZ=UTC und erhalte nun die entsprechenden Daten mit '03.04.2006
> 10:00:00'.

Wenn die Stempel immer in UTC+01 vorliegen, schröbe ein Client (a) mit
PGTZ='+01' die Korrekte Zeit in die Datanbank.

> Fragen:
>
> 1. Wie können die Daten aus (a) unter CET bzw. UTC +01 gespeichert
> werden?

Genaugenommen gar nicht. Die Timestamp-Typen speichern keine
Zeitzoneninformation. Im Falle von timestamptz wird nur
sichergestellt, daß auf der Platte immer UTC liegt. Die Konvertierung
erfolgt unter Beachtung der Session-Zeitzone, und eventuell
vorhandener Offsetangaben im String selbst.

> Muss ich Daten seit der Umstellung auf CEST mittels UPDATE
> aktualisieren?

Auf der Platte liegt nur UTC, ein Update einer timestamptz-Spalte
macht also nur Sinn, wenn man PostgreSQL einmal über die verwendete
Zeitzone getäuscht hat, und UTC deswegen nicht UTC ist.

> 2. Welche PGTZ-Einstellung benötigen die Clients aus (b), damit sie
> die entsprechenden Daten erhalten? Benötigen diese Clients eventuell
> oder unbedingt eine besondere Zeitstempelkonvertierung?

S.o., das sollte bei korrektem Import in (a) einklich tun.

> 3. Welche PGTZ-Einstellung ist für die (c)-Clients am sinnvollsten?

Ich lese in der Beschreibung zu (c) nichts, was eine spezielle
Zeitzone erforden würde.

> 4. Was bedeutet integer_datetimes = off aus den
> show-all-Einstellungen?

<http://www.postgresql.org/docs/8.0/static/datatype-datetime.html>

--8<---------------cut here---------------start------------->8---
*Note*

When `timestamp' values are stored as double precision
floating-point numbers (currently the default), the effective
limit of precision may be less than 6. `timestamp' values are
stored as seconds before or after midnight 2000-01-01. Microsecond
precision is achieved for dates within a few years of 2000-01-01,
but the precision degrades for dates further away. When
`timestamp' values are stored as eight-byte integers (a
compile-time option), microsecond precision is available over the
full range of values. However eight-byte integer timestamps have a
more limited range of dates than shown above: from 4713 BC up to
294276 AD. The same compile-time option also determines whether
`time' and `interval' values are stored as floating-point or
eight-byte integers. In the floating-point case, large `interval'
values degrade in precision as the size of the interval increases.
--8<---------------cut here---------------end--------------->8---

HTH
Andreas

In response to

Responses

Browse pgsql-de-allgemein by date

  From Date Subject
Next Message Johannes Brgmann 2006-04-04 07:05:05 Re: Zeit und Zeitzonen richtig konfigurieren
Previous Message A. Kretschmer 2006-04-03 17:54:50 Re: Zeit und Zeitzonen richtig konfigurieren