psql connection being reset during function?

Поиск
Список
Период
Сортировка
От Randall Skelton
Тема psql connection being reset during function?
Дата
Msg-id Pine.LNX.4.33.0108142031540.10412-100000@mulligan.atm.ox.ac.uk
обсуждение исходный текст
Ответы Re: psql connection being reset during function?
Список pgsql-sql
Hi all,

I am running 7.1.2 and I have the unenviable task of cleaning up a
database which has columns:

sgmty  integer,   -- YEAR
sgmtmo integer,   -- MONTH
sgmtd  integer,   -- DAY
sgmth  integer,   -- HOUR
sgmtm  integer,   -- MINUTE
sgmts  float,     -- SECOND
+ 190 other floats per row

The data is basically an atmospheric model dump at 1 frame per second. Why
exactly time is stored like this remains a mystery... The values for
seconds resemble a 16 bit float output directly inserted (via libpq) into
the database:
 0.999992423414 1.999986999391 3.000021808504 ... 4.00001638448158.00000869548259.00000327145959.999997847437...

My first thought was simply to add a new column called gmt_timestamp
and write a simple function in plpgsql to update each record.

My first-cut function:

CREATE FUNCTION mydatetime() RETURNS text AS'  DECLARE      -- defines a record and text variable      rec    RECORD;
  date_time TEXT;
 
  BEGIN      -- loop over all entries in path      FOR rec IN SELECT * FROM path LOOP        date_time:= ''UPDATE path
SETsgmt_timestamp = '' ||                   quote_literal(                   rec.sgmty   || ''-'' ||
rec.sgmtmo || ''-'' ||                   rec.sgmtd   || '' '' ||                   rec.sgmth   || '':'' ||
    rec.sgmtm   || '':'' ||                   cast(rec.sgmts as integer)                   )                   || ''
WHERE''||                   '' sgmty      = '' || quote_literal(rec.sgmty) ||                   '' AND sgmtmo = '' ||
quote_literal(rec.sgmtmo)||                   '' AND sgmtd  = '' || quote_literal(rec.sgmtd) ||                   ''
ANDsgmth  = '' || quote_literal(rec.sgmth) ||                   '' AND sgmtm  = '' || quote_literal(rec.sgmtm) ||
           '' AND sgmts  = '' || quote_literal(rec.sgmts)                   || '';'';        EXECUTE date_time;     END
LOOP;
      --return date_time;      return ''done'';
  END;  ' LANGUAGE 'plpgsql';

Surely this can be improved upon, but it leads to problem #1.  In the case
of sgmts = 59.999997847437 my explicit cast of, 'cast(rec.sgmts as
integer)' creates a problem in that I make a timestamp with '60' in the
seconds column.  A time stamp of this sort is not handled by the postgres
timestamp type and the function falls over.

My revised function explicitly propogates 60 seconds to be a minute, 60
minutes to be an hour, 24 hours to be a day and so on.

CREATE FUNCTION mydatetime() RETURNS text AS'  DECLARE      -- defines a record and text variable      rec    RECORD;
  year   INTEGER;      month  INTEGER;      day    INTEGER;      hour   INTEGER;      minute INTEGER;      second
INTEGER;     addone INTEGER;      date_time     TEXT;      date_time_two TEXT;
 
  BEGIN      -- loop over all entries in atlas3_path      FOR rec IN SELECT * FROM atlas3_path LOOP        /* THIS IS A
DIRTYHACK!!! Should never have excluded a time stamp;         * casting allows the seconds to be 60 which is causes
   * problems for the timestamp postgres type.         * Emperically checked to ensure month does not flip for this
   * dataset (i.e. 1996-01-31 23:59:60 does not occur)         * Original code has now been modified to         *
includea proper timestamp calculation.         */
 
        day := 0;        hour := 0;        minute := 0;        second := 0;
        IF cast(rec.sgmts as integer) > 59 THEN           second := cast(rec.sgmts as integer) - 60;           minute
:=1;        ELSE           second := cast(rec.sgmts as integer);        END IF;
 
        IF minute + rec.sgmtm > 59 THEN           minute := minute + rec.sgmtm - 60;           hour := 1;        ELSE
       minute := minute + rec.sgmtm;        END IF;
 
        IF hour + rec.sgmth > 23 THEN           hour := hour + rec.sgmth - 24;           day := 1;        ELSE
hour := hour + rec.sgmth;        END IF;
 
        day :=  day + rec.sgmtd;
        date_time:= ''UPDATE atlas3_path SET sgmt_timestamp = '' ||                   quote_literal(
rec.sgmty  || ''-'' ||                   rec.sgmtmo  || ''-'' ||                   day         || '' '' ||
    hour        || '':'' ||                   minute      || '':'' ||                   second                   )
            || '' WHERE'' ||                   '' sgmty   = '' || quote_literal(rec.sgmty) ||                   '' AND
sgmtmo = '' || quote_literal(rec.sgmtmo) ||                   '' AND sgmtd    = '' || quote_literal(rec.sgmtd) ||
           '' AND sgmth   = '' || quote_literal(rec.sgmth) ||                   '' AND sgmtm = '' ||
quote_literal(rec.sgmtm)||                   '' AND sgmts = '' || quote_literal(rec.sgmts)                   || '';'';
     EXECUTE date_time;     END LOOP;
 
      --return date_time;      return ''done'';
  END;  ' LANGUAGE 'plpgsql';

Again this is rather verbose and unelegant.  Nevertheless it leads to
problem #2: While this works perfectly for a small table of 10 entries, it
crashes the database connection when I try to update 311537 rows using
psql and 'select mydatetime()'.

pqReadData() -- backend closed the channel unexpectedly.       This probably means the backend terminated abnormally
  before or while processing the request.
 
The connection to the server was lost. Attempting reset: Failed.

My logs read:

...
DEBUG:  XLogWrite: new log file created - consider increasing WAL_FILES
DEBUG:  XLogWrite: new log file created - consider increasing WAL_FILES
DEBUG:  XLogWrite: new log file created - consider increasing WAL_FILES
DEBUG:  MoveOfflineLogs: remove 000000000000006C
DEBUG:  XLogWrite: new log file created - consider increasing WAL_FILES
DEBUG:  XLogWrite: new log file created - consider increasing WAL_FILES
DEBUG:  XLogWrite: new log file created - consider increasing WAL_FILES
DEBUG:  XLogWrite: new log file created - consider increasing WAL_FILES
DEBUG:  XLogWrite: new log file created - consider increasing WAL_FILES
DEBUG:  XLogWrite: new log file created - consider increasing WAL_FILES
DEBUG:  XLogWrite: new log file created - consider increasing WAL_FILES
DEBUG:  XLogWrite: new log file created - consider increasing WAL_FILES
DEBUG:  XLogWrite: new log file created - consider increasing WAL_FILES
DEBUG:  XLogWrite: new log file created - consider increasing WAL_FILES
DEBUG:  XLogWrite: new log file created - consider increasing WAL_FILES
DEBUG:  XLogWrite: new log file created - consider increasing WAL_FILES
DEBUG:  XLogWrite: new log file created - consider increasing WAL_FILES
Server process (pid 10219) exited with status 9 at Tue Aug 14 19:34:41 2001
Terminating any active server processes...
Server processes were terminated at Tue Aug 14 19:34:42 2001
Reinitializing shared memory and semaphores
The Data Base System is starting up
DEBUG:  database system was interrupted at 2001-08-14 19:33:51 BST
DEBUG:  CheckPoint record at (0, 2081443972)
DEBUG:  Redo record at (0, 2080561900); Undo record at (0, 1828733240);
Shutdown
FALSE
DEBUG:  NextTransactionId: 5627; NextOid: 15659730
DEBUG:  database system was not properly shut down; automatic recovery in progress...
DEBUG:  redo starts at (0, 2080561900)
DEBUG:  open(logfile 0 seg 126) failed: No such file or directory
DEBUG:  redo done at (0, 2113927744)
DEBUG:  database system is in production state

Any and all thoughts are greatly appreciated!

Cheers,
Randall




В списке pgsql-sql по дате отправления:

Предыдущее
От: Jan Wieck
Дата:
Сообщение: Re: Date: the day before yesterday.
Следующее
От: Tom Lane
Дата:
Сообщение: Re: Deadlocks? What happened to MVCC?