Обсуждение: CURRENT_DATE and CURRENT_TIME return incorrect values

Поиск
Список
Период
Сортировка

CURRENT_DATE and CURRENT_TIME return incorrect values

От
valerian
Дата:
I have a table with these columns:

   order_date      date                    DEFAULT CURRENT_DATE
   order_time      time with time zone     DEFAULT CURRENT_TIME
   setup_date      date
   last_update     date                    DEFAULT CURRENT_DATE

The order_date and last_update should always be identical because I let
pgsql fill in those fields when a new row is added.  Additionally,
setup_date should be identical as well, because my application just
queries the server time (same exact server as pgsql is running on).

However today I noticed something strange:  a row was added with these
values:

   order_date |     order_time     | setup_date | last_update
   -----------+--------------------+------------+------------
   2003-05-26 | 02:22:00.166015-04 | 2003-05-28 | 2003-05-26

Which is very odd because a few minutes later I ran a manual query that
returned this:

   dev=> SELECT current_date, current_time;
      date    |       timetz
   -----------+--------------------
   2003-05-28 | 13:19:39.189404-04

I also checked my apache log files to make sure that the server hadn't
skipped a few days for some reason...  But that wasn't the case, and my
logs show hits for the 26th, 27th and 28th, as it should be.

I then went back to my application and made it create a new record.  The
following row was created:

   order_date |     order_time     | setup_date | last_update
   -----------+--------------------+------------+------------
   2003-05-28 | 13:25:12.126979-04 | 2003-05-28 |  2003-05-28

What you may find interesting is that my DB had been mostly dormant for
the past several days.  In other words, only a few SELECT queries had
been executed, and no INSERT, UPDATE, DELETE or VACUUM operations had
been run.  I have no idea if this is significant or not...

My environment is:

pgsql 7.3.2
Debian/Linux 3.0 (i386)
/etc/timezone is 'US/Eastern'
libdbi-perl 1.21-2
libdbd-pg-perl 1.01-3

No defaults in postgresql.conf were changed except for
'unix_socket_directory'.  The Locale is set to 'C'.

I noticed that there are several entries in the HISTORY file for pgsql
7.3.3 that deal with dates and times.  Would upgrading fix my problem,
or is this something entirely different?



Re: CURRENT_DATE and CURRENT_TIME return incorrect values

От
DeJuan Jackson
Дата:
Did you create the table on 2003-05-26 by any chance?
It appears that the CURRENT_DATE/CURRENT_TIME in your create table
statement got interpreted, and replaced, so every record that ever gets
inserted will have the same date and time.
use a \d table_name in psql to confirm.
You should be able to alter the table/columns and correct the problem.

valerian wrote:

>I have a table with these columns:
>
>   order_date      date                    DEFAULT CURRENT_DATE
>   order_time      time with time zone     DEFAULT CURRENT_TIME
>   setup_date      date
>   last_update     date                    DEFAULT CURRENT_DATE
>
>The order_date and last_update should always be identical because I let
>pgsql fill in those fields when a new row is added.  Additionally,
>setup_date should be identical as well, because my application just
>queries the server time (same exact server as pgsql is running on).
>
>However today I noticed something strange:  a row was added with these
>values:
>
>   order_date |     order_time     | setup_date | last_update
>   -----------+--------------------+------------+------------
>   2003-05-26 | 02:22:00.166015-04 | 2003-05-28 | 2003-05-26
>
>Which is very odd because a few minutes later I ran a manual query that
>returned this:
>
>   dev=> SELECT current_date, current_time;
>      date    |       timetz
>   -----------+--------------------
>   2003-05-28 | 13:19:39.189404-04
>
>I also checked my apache log files to make sure that the server hadn't
>skipped a few days for some reason...  But that wasn't the case, and my
>logs show hits for the 26th, 27th and 28th, as it should be.
>
>I then went back to my application and made it create a new record.  The
>following row was created:
>
>   order_date |     order_time     | setup_date | last_update
>   -----------+--------------------+------------+------------
>   2003-05-28 | 13:25:12.126979-04 | 2003-05-28 |  2003-05-28
>
>What you may find interesting is that my DB had been mostly dormant for
>the past several days.  In other words, only a few SELECT queries had
>been executed, and no INSERT, UPDATE, DELETE or VACUUM operations had
>been run.  I have no idea if this is significant or not...
>
>My environment is:
>
>pgsql 7.3.2
>Debian/Linux 3.0 (i386)
>/etc/timezone is 'US/Eastern'
>libdbi-perl 1.21-2
>libdbd-pg-perl 1.01-3
>
>No defaults in postgresql.conf were changed except for
>'unix_socket_directory'.  The Locale is set to 'C'.
>
>I noticed that there are several entries in the HISTORY file for pgsql
>7.3.3 that deal with dates and times.  Would upgrading fix my problem,
>or is this something entirely different?
>
>
>
>---------------------------(end of broadcast)---------------------------
>TIP 5: Have you checked our extensive FAQ?
>
>http://www.postgresql.org/docs/faqs/FAQ.html
>
>


Re: CURRENT_DATE and CURRENT_TIME return incorrect values

От
valerian
Дата:
On Thu, May 29, 2003 at 07:57:39PM -0500, DeJuan Jackson wrote:
> Did you create the table on 2003-05-26 by any chance?

Nope, that table has been around for about a month or so.  I haven't even
made any recent changes to it.

> It appears that the CURRENT_DATE/CURRENT_TIME in your create table
> statement got interpreted, and replaced, so every record that ever gets
> inserted will have the same date and time.
> use a \d table_name in psql to confirm.
> You should be able to alter the table/columns and correct the problem.

The \d output looks like this:

      Column      |        Type         |                   Modifiers
------------------+---------------------+-----------------------------------------------
 order_date       | date                | default date('now'::text)
 order_time       | time with time zone | default ('now'::text)::time(6) with time zone
 setup_date       | date                |
 last_update      | date                | default date('now'::text)

I think this is correct?  I want pgsql to enter the current date/time in
by default.  It normally seems to work ok, except that one time a couple
days ago when it entered '2003-05-26' instead of '2003-05-28' for some
reason that I don't understand.  Especially considering that it entered
the correct date/time when I added another row just a few minutes later...

It's very strange.  I think it would be difficult to reproduce this
behavior because my DB had been sitting around mostly idle for some
time, and I've never seen this happen before.

I'm fairly certain the problem is related to pgsql because my system
time has been accurate all along.  In other words, the system time
didn't jump from 2003-05-26 to 2003-05-28 in one instant.  My
apache logs show regular hits for that date range, and so do the other
system logs (ie, /var/log/messages has normal, regular entries).

The only thing I can think of is that pgsql cached an old date and time,
for some reason, and used that for the first record, and then actually
queried the system's date/time after that.  But that sounds pretty
weird...

I really need for the order_date to be 100% accurate though, because my
application must do calculations based on that.  So I'm thinking about
having have it grab the date/time directly from the system clock  and
enter it instead of leaving that to pgsql.  Unless anyone can point out
where I made an error.



Re: CURRENT_DATE and CURRENT_TIME return incorrect values

От
"Nigel J. Andrews"
Дата:

The big question is: Can you repeat it?

The next big question is: Can you supply a complete example of how to repeat
it.

The only things that crossed my mind were a) you started a transaction on the
26th and only wrote that record on the 28th or b) which ever system you were
querying the time of to get the 28th had a different time to the database
server.

Is there some reason you are splitting the order time and date into two columns
rather than using a single timestamp one?

--
Nigel Andrews



On Fri, 30 May 2003, valerian wrote:

> On Thu, May 29, 2003 at 07:57:39PM -0500, DeJuan Jackson wrote:
> > Did you create the table on 2003-05-26 by any chance?
>
> Nope, that table has been around for about a month or so.  I haven't even
> made any recent changes to it.
>
> > It appears that the CURRENT_DATE/CURRENT_TIME in your create table
> > statement got interpreted, and replaced, so every record that ever gets
> > inserted will have the same date and time.
> > use a \d table_name in psql to confirm.
> > You should be able to alter the table/columns and correct the problem.
>
> The \d output looks like this:
>
>       Column      |        Type         |                   Modifiers
> ------------------+---------------------+-----------------------------------------------
>  order_date       | date                | default date('now'::text)
>  order_time       | time with time zone | default ('now'::text)::time(6) with time zone
>  setup_date       | date                |
>  last_update      | date                | default date('now'::text)
>
> I think this is correct?  I want pgsql to enter the current date/time in
> by default.  It normally seems to work ok, except that one time a couple
> days ago when it entered '2003-05-26' instead of '2003-05-28' for some
> reason that I don't understand.  Especially considering that it entered
> the correct date/time when I added another row just a few minutes later...
>
> It's very strange.  I think it would be difficult to reproduce this
> behavior because my DB had been sitting around mostly idle for some
> time, and I've never seen this happen before.
>
> I'm fairly certain the problem is related to pgsql because my system
> time has been accurate all along.  In other words, the system time
> didn't jump from 2003-05-26 to 2003-05-28 in one instant.  My
> apache logs show regular hits for that date range, and so do the other
> system logs (ie, /var/log/messages has normal, regular entries).
>
> The only thing I can think of is that pgsql cached an old date and time,
> for some reason, and used that for the first record, and then actually
> queried the system's date/time after that.  But that sounds pretty
> weird...
>
> I really need for the order_date to be 100% accurate though, because my
> application must do calculations based on that.  So I'm thinking about
> having have it grab the date/time directly from the system clock  and
> enter it instead of leaving that to pgsql.  Unless anyone can point out
> where I made an error.
>


Re: CURRENT_DATE and CURRENT_TIME return incorrect values

От
Tom Lane
Дата:
valerian <valerian2@hotpop.com> writes:
> The only thing I can think of is that pgsql cached an old date and time,
> for some reason, and used that for the first record, and then actually
> queried the system's date/time after that.

Is it possible that the entry was made from a transaction that had been
sitting open for two days?  now() and related functions return
transaction start time.

            regards, tom lane

Re: CURRENT_DATE and CURRENT_TIME return incorrect values

От
valerian
Дата:
Nigel J. Andrews wrote:
> The big question is: Can you repeat it?

I doubt it, because I never noticed this before.  And I tend to check
all the data very closely because I'm doing developement work (gotta
catch all those bugs).

> The next big question is: Can you supply a complete example of how to repeat
> it.

Alas no. :(  I tried to reproduce the oddity by letting my system sit
mostly idle for the past 24 hours, to see if the same thing would
happen.  I then added a new record, but the date/time was correct.

> Is there some reason you are splitting the order time and date into two columns
> rather than using a single timestamp one?

Yes, the order_time is sort of an 'extra' field.  I don't currently use
it, and it might even disapear in the future.  I only do calculations on
the order_date and setup_date fields.  That's why I didn't use a
timestamp.

> The only things that crossed my mind were a) you started a transaction on the
> 26th and only wrote that record on the 28th or b) which ever system you were
> querying the time of to get the 28th had a different time to the database
> server.

Tom Lane wrote:
> Is it possible that the entry was made from a transaction that had been
> sitting open for two days?  now() and related functions return
> transaction start time.

Aha!  You may be on to something there.  First, to clarify:  I only have
one server, and all processes (pgsql, apache, etc.) are running on it
and query that server's system clock.

When I run 'ps auxww |grep postgres' it shows:

postgres  4770  0.0  0.2  7068 3076 pts/3    S    Apr27   0:11 /usr/local/pgsql/bin/postmaster
postgres 12525  0.0  0.2  8060 3024 pts/3    S    Apr27   0:00 postgres: stats buffer process
postgres  5850  0.0  0.2  7116 3080 pts/3    S    Apr27   0:00 postgres: stats collector process
postgres 20284  0.0  0.8 10556 8748 pts/3    S    May02   2:11 postgres: dev dev [local] idle
postgres  8572  0.0  0.4  7484 4772 pts/3    S    May29   0:00 postgres: dev dev [local] idle in transaction
postgres 20062  0.0  0.4  7484 4680 pts/3    S    May29   0:00 postgres: dev dev [local] idle in transaction
postgres 18226  0.0  0.4  7484 4680 pts/3    S    May29   0:00 postgres: dev dev [local] idle in transaction
postgres 16750  0.0  0.4  7484 4680 pts/3    S    May29   0:00 postgres: dev dev [local] idle in transaction
postgres 25970  0.0  0.4  7484 4676 pts/3    S    May29   0:00 postgres: dev dev [local] idle in transaction
postgres 21388  0.0  0.4  7484 4676 pts/3    S    05:56   0:00 postgres: dev dev [local] idle in transaction

PID 20284 is an instance of psql, that I always keep open in 'screen',
so that's why it's been running since May 02.

All the other children processes are managed by mod_perl, using
Apache::DBI to get persistent connections.  My application was
completely dormant during the 'ps' snapshot above.  But it does seem
that Apache::DBI starts a transaction (one for each mod_perl process)
and waits...

I'm thinking that by some freaky occurence, one of those transactions
got started on the 26th and didn't get used at all (not even for SELECT
queries) during those few days, until the 28th when it was handed the
INSERT for the row in question.  Does that sound possible?  It seems
strange because my application has to run a good half-dozen SELECT
queries before even getting to the point of adding a record, and there
were a few (but only a few) other queries done during those days as well.

I imagine that this situation shouldn't happen in a real environment where
the DB is actually used on a daily basis, but there is still a chance
for the dates to be wrong if a transaction starts a little before midnight
but doesn't commit until the next day.  And chances are the times may
often tend to be off by a little?

If this is true, then it sounds like a very bad idea to use columns with
'default CURRENT_DATE' and 'default CURRENT_TIME' with Apache::DBI...