Thread

  1. Re: Bug #613: Sequence values fall back to previously chec

    Vadim Mikheev <vmikheev@sectorbase.com> — 2002-03-15T00:17:39Z

    > > This isn't an issue for a SELECT nextval() standing on
    > > its own AFAIK the result will not be transmitted to the
    > > client until after the commit happens. But it would be
    > > an issue for a select executed inside a transaction
    > > block (begin/commit).
    > 
    > The behavior of SELECT nextval() should not be conditional
    > on being in or out of a transaction block.
    
    And it's not. But behaviour of application *must* be
    conditional on was transaction committed or not.
    
    What's the problem for application that need nextval() for
    external (out-of-database) purposes to use sequence values
    only after transaction commit? What's *wrong* for such application
    to behave the same way as when dealing with other database objects
    which are under transaction control (eg only after commit you can
    report to user that $100 was successfully added to his/her account)?
    
    ---
    
    I agree that if nextval-s were only "write" actions in transaction
    and they made some XLogInsert-s then WAL must be flushed at commit
    time. But that's it. Was this fixed? Very easy.
    
    Vadim
    
    
  2. Re: Bug #613: Sequence values fall back to previously chec

    Ben Grimm <bgrimm@zaeon.com> — 2002-03-15T01:55:23Z

    On Thu, 14 Mar 2002, Mikheev, Vadim wrote:
    
    > And it's not. But behaviour of application *must* be
    > conditional on was transaction committed or not.
    > 
    > What's the problem for application that need nextval() for
    > external (out-of-database) purposes to use sequence values
    > only after transaction commit? What's *wrong* for such application
    > to behave the same way as when dealing with other database objects
    > which are under transaction control (eg only after commit you can
    > report to user that $100 was successfully added to his/her account)?
    
    But sequences should not be under transaction control.  Can you 
    safely rollback a sequence?  No!  The only way to ensure that would
    be to lock the sequence for the duration of the transaction.  If 
    you want an ACID compliant sequential value, you implement it using
    a transaction safe method (e.g. a table with rows you can lock for
    the duration of a transaction).  If you want a number that is 
    guaranteed to always move in one direction, return the next value
    without requiring locks, and may have gaps in the numbers returned,
    you choose a sequence.
    
    Placing a restriction on an application that says it must treat 
    the values returned from a sequence as if they might not be committed
    is absurd.  What about applications that don't use explicit 
    transactions?  As soon as a result comes back it should be considered
    'live', on disk, never think about it again. 
     
    > I agree that if nextval-s were only "write" actions in transaction
    > and they made some XLogInsert-s then WAL must be flushed at commit
    > time. But that's it. Was this fixed? Very easy.
    
    But aren't the nextval's always going to be the only write actions
    in their transactions since the nextval isn't really a part of the 
    transaction that called it?  If it were, then it could be rolled 
    back along with that transaction.  This is why you can, right now, 
    insert data into a table with a serial column, committing after
    each row, crash the database and STILL have the sequence fall back
    to its initial state.  The XLogInserts that occur from the table
    inserts must not happen in the same xact as the nextval's 
    XLogInserts.  I can demonstrate the behavior quite easilly, and 
    Bruce posted results that confirmed it.
    
    -- Ben
    
    
  3. Re: Bug #613: Sequence values fall back to previously chec

    Vadim Mikheev <vmikheev@sectorbase.com> — 2002-03-15T09:05:33Z

    > But sequences should not be under transaction control.  Can you
    > safely rollback a sequence?  No!  The only way to ensure that would
    ...
    > Placing a restriction on an application that says it must treat the values
    > returned from a sequence as if they might not be committed is absurd.
    
    Why? The fact that you are not able to rollback sequences does not
    necessary mean that you are not required to perform commit to ensure
    permanent storage of changes made to database.
    
    And isn't it absurd to do more XLogFlush-es for non-transactional objects
    than we do for transactional ones? And why? Just for convenience of
    << 1% applications which need to use sequences in their own,
    non-database, external objects? We are not required to care about those
    objects, but we'd better care about performance of our operations over our
    objects.
    
    > > I agree that if nextval-s were only "write" actions in transaction
    > > and they made some XLogInsert-s then WAL must be flushed at commit
    > > time. But that's it. Was this fixed? Very easy.
    >
    > But aren't the nextval's always going to be the only write actions
    > in their transactions since the nextval isn't really a part of the
    > transaction that called it?  If it were, then it could be rolled
    
    There are no nextval' transactions. See how XLOG_NO_TRAN flag
    is used in XLogInsert and you'll see why there is no XLogFlush
    after transaction-with-nextval-only (which causes N1 reported problem).
    
    > back along with that transaction.  This is why you can, right now,
    > insert data into a table with a serial column, committing after
    > each row, crash the database and STILL have the sequence fall back
    > to its initial state.  The XLogInserts that occur from the table
    > inserts must not happen in the same xact as the nextval's
    > XLogInserts.  I can demonstrate the behavior quite easilly, and
    > Bruce posted results that confirmed it.
    
    Just wait until Tom adds check for system RedoRecPtr in nextval()
    and try to reproduce this behaviour (N2 reported problem)
    after that.
    
    Vadim
    
    
    
    
  4. Re: Bug #613: Sequence values fall back to previously chec

    Ben Grimm <bgrimm@zaeon.com> — 2002-03-15T13:23:58Z

    On Fri, 15 Mar 2002, Vadim Mikheev wrote:
    
    > > But sequences should not be under transaction control.  Can you
    > > safely rollback a sequence?  No!  The only way to ensure that would
    > ...
    > > Placing a restriction on an application that says it must treat the values
    > > returned from a sequence as if they might not be committed is absurd.
    > 
    > Why? The fact that you are not able to rollback sequences does not
    > necessary mean that you are not required to perform commit to ensure
    > permanent storage of changes made to database.
    
    I'm not sure I agree, but I'll wait to see the behavior of the db after
    the changes are made.
    
    > And isn't it absurd to do more XLogFlush-es for non-transactional objects
    > than we do for transactional ones? And why? Just for convenience of
    > << 1% applications which need to use sequences in their own,
    > non-database, external objects? We are not required to care about those
    > objects, but we'd better care about performance of our operations over our
    > objects.
    
    Yes, absolutely - if there's a better way, which apparently there is, 
    then sure, eliminate the calls to XLogFlush.  It's a workaround, a hack.
    I am much more concerned with getting the behavior correct than I am 
    about getting some code with my name on it into a release.  My workarounds 
    only served to point out flaws in the design, even if I didn't quite
    understand at the time why they worked :-)
    
    > There are no nextval' transactions. See how XLOG_NO_TRAN flag
    > is used in XLogInsert and you'll see why there is no XLogFlush
    > after transaction-with-nextval-only (which causes N1 reported problem).
    > 
    > Just wait until Tom adds check for system RedoRecPtr in nextval()
    > and try to reproduce this behaviour (N2 reported problem)
    > after that.
    > 
    
    Thank you!  I think I have much better understanding of how this works 
    now. 
    
    When these bugs are fixed there is still the issue of bug #3 that I 
    came across.  The one that I work around by resetting log_cnt to 0 when a 
    backend initializes a sequence.  It's this third bug that made the other 
    two so apparent.  Fixing them does not obviate the need to fix this one.
    
    Is there a way to intercept writes or reads such that when a sequnce is
    going to or from disk that we can force log_cnt = 0?  Right now that's 
    worked around by my 'reset_logcnt' flag in the patch, but I know that it 
    may not be an ideal solution.  But, since sequences are just tuples like 
    everything else I don't see an obvious way to prevent it.  
    
    -- Ben
    
    
  5. Re: Bug #613: Sequence values fall back to previously chec

    Tom Lane <tgl@sss.pgh.pa.us> — 2002-03-15T14:34:36Z

    "'Ben Grimm'" <bgrimm@zaeon.com> writes:
    > When these bugs are fixed there is still the issue of bug #3 that I 
    > came across.  The one that I work around by resetting log_cnt to 0 when a 
    > backend initializes a sequence.  It's this third bug that made the other 
    > two so apparent.  Fixing them does not obviate the need to fix this one.
    
    What's bug #3?  I don't recall a third issue.
    
    			regards, tom lane
    
    
  6. Re: Bug #613: Sequence values fall back to previously chec

    Tom Lane <tgl@sss.pgh.pa.us> — 2002-03-15T14:39:04Z

    Attached is a patch against current CVS that fixes both of the known
    problems with sequences: failure to flush XLOG after a transaction
    that only does "SELECT nextval()", and failure to force a new WAL
    record to be written on the first nextval after a checkpoint.
    (The latter uses Vadim's idea of looking at the sequence page LSN.)
    I haven't tested it really extensively, but it seems to cure the
    reported problems.
    
    Some notes:
    
    1. I found what I believe is another bug in the sequence logic:
    		fetch = log = fetch - log + SEQ_LOG_VALS;
    should be
    		fetch = log = fetch + SEQ_LOG_VALS;
    I can't see any reason to reduce the number of values prefetched
    by the number formerly prefetched.  Also, if the sequence's "cache"
    setting is large (more than SEQ_LOG_VALS), the original code could
    easily fail to fetch as many values as it was supposed to cache,
    let alone additional ones to be prefetched and logged.
    
    2. I renamed XLogCtl->RedoRecPtr to SavedRedoRecPtr, and renamed
    the associated routines to SetSavedRedoRecPtr/GetSavedRedoRecPtr,
    in hopes of reducing confusion.
    
    3. I believe it'd now be possible to remove SavedRedoRecPtr and
    SetSavedRedoRecPtr/GetSavedRedoRecPtr entirely, in favor of letting
    the postmaster fetch the updated pointer with GetRedoRecPtr just
    like a backend would.  This would be cleaner and less code ... but
    someone might object that it introduces a risk of postmaster hangup,
    if some backend crashes whilst holding info_lck.  I consider that
    risk minuscule given the short intervals in which info_lck is held,
    but it can't be denied that the risk is not zero.  Thoughts?
    
    Comments?  Unless I hear objections I will patch this in current
    and the 7.2 branch.  (If we agree to remove SavedRedoRecPtr,
    though, I don't think we should back-patch that change.)
    
    			regards, tom lane
    
    
  7. Re: [HACKERS] Bug #613: Sequence values fall back to previously

    Bruce Momjian <pgman@candle.pha.pa.us> — 2002-03-15T15:43:25Z

    Tom Lane wrote:
    > Attached is a patch against current CVS that fixes both of the known
    > problems with sequences: failure to flush XLOG after a transaction
    > that only does "SELECT nextval()", and failure to force a new WAL
    > record to be written on the first nextval after a checkpoint.
    > (The latter uses Vadim's idea of looking at the sequence page LSN.)
    > I haven't tested it really extensively, but it seems to cure the
    > reported problems.
    
    I can confirm that the patch fixes the problem shown in my simple test:
    
    test=> create table test (x serial, y varchar(255));
    NOTICE:  CREATE TABLE will create implicit sequence 'test_x_seq' for SERIAL column 'test.x'
    NOTICE:  CREATE TABLE / UNIQUE will create implicit index 'test_x_key' for table 'test'
    CREATE
    test=> insert into test (y) values ('lkjasdflkja sdfl;kj asdfl;kjasdf');
    INSERT 16561 1
    test=> insert into test (y) values ('lkjasdflkja sdfl;kj asdfl;kjasdf');
    INSERT 16562 1
    test=> insert into test (y) values ('lkjasdflkja sdfl;kj asdfl;kjasdf');
    INSERT 16563 1
    ...
    
    test=> select nextval('test_x_seq');
     nextval 
    ---------
          22
    (1 row)
    
    test=> checkpoint;
    CHECKPOINT
    test=> insert into test (y) values ('lkjasdflkja sdfl;kj asdfl;kjasdf');
    INSERT 16582 1
    test=> insert into test (y) values ('lkjasdflkja sdfl;kj asdfl;kjasdf');
    INSERT 16583 1
    test=> insert into test (y) values ('lkjasdflkja sdfl;kj asdfl;kjasdf');
    INSERT 16584 1
    
    [ kill -9 to backend ]
    
    #$ sql test
    Welcome to psql, the PostgreSQL interactive terminal.
    
    Type:  \copyright for distribution terms
           \h for help with SQL commands
           \? for help on internal slash commands
           \g or terminate with semicolon to execute query
           \q to quit
    
    test=> select nextval('test_x_seq');
     nextval 
    ---------
          56
    (1 row)
    
    
    -- 
      Bruce Momjian                        |  http://candle.pha.pa.us
      pgman@candle.pha.pa.us               |  (610) 853-3000
      +  If your life is a hard drive,     |  830 Blythe Avenue
      +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
    
    
  8. Re: [HACKERS] Bug #613: Sequence values fall back to previously

    Bruce Momjian <pgman@candle.pha.pa.us> — 2002-03-15T15:44:16Z

    Tom Lane wrote:
    > 2. I renamed XLogCtl->RedoRecPtr to SavedRedoRecPtr, and renamed
    > the associated routines to SetSavedRedoRecPtr/GetSavedRedoRecPtr,
    > in hopes of reducing confusion.
    
    Good.
    
    > 3. I believe it'd now be possible to remove SavedRedoRecPtr and
    > SetSavedRedoRecPtr/GetSavedRedoRecPtr entirely, in favor of letting
    > the postmaster fetch the updated pointer with GetRedoRecPtr just
    > like a backend would.  This would be cleaner and less code ... but
    > someone might object that it introduces a risk of postmaster hangup,
    > if some backend crashes whilst holding info_lck.  I consider that
    > risk minuscule given the short intervals in which info_lck is held,
    > but it can't be denied that the risk is not zero.  Thoughts?
    
    The change sounds good to me.
    
    > Comments?  Unless I hear objections I will patch this in current
    > and the 7.2 branch.  (If we agree to remove SavedRedoRecPtr,
    > though, I don't think we should back-patch that change.)
    
    Totally agree.
    
    -- 
      Bruce Momjian                        |  http://candle.pha.pa.us
      pgman@candle.pha.pa.us               |  (610) 853-3000
      +  If your life is a hard drive,     |  830 Blythe Avenue
      +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
    
    
  9. Re: Bug #613: Sequence values fall back to previously chec

    Ben Grimm <bgrimm@zaeon.com> — 2002-03-15T15:44:35Z

    On Fri, 15 Mar 2002, Tom Lane wrote:
    
    > "'Ben Grimm'" <bgrimm@zaeon.com> writes:
    > > When these bugs are fixed there is still the issue of bug #3 that I 
    > > came across.  The one that I work around by resetting log_cnt to 0 when a 
    > > backend initializes a sequence.  It's this third bug that made the other 
    > > two so apparent.  Fixing them does not obviate the need to fix this one.
    > 
    > What's bug #3?  I don't recall a third issue.
    > 
    
    The problem I was seeing before is that when the postmaster was shutdown 
    properly, log_cnt in the sequence record was saved with whatever value it 
    had at the time.  So when it loaded from disk it would have a value greater 
    than zero resulting in no XLogInsert until you'd exceded log_cnt calls to
    nextval.  
    
    AFAICT, your patch fixes this problem, as I can't reproduce it now.  
    
    Thanks!
    
    -- Ben
    
    
  10. Re: Bug #613: Sequence values fall back to previously chec

    Tom Lane <tgl@sss.pgh.pa.us> — 2002-03-15T16:03:50Z

    "'Ben Grimm'" <bgrimm@zaeon.com> writes:
    > On Fri, 15 Mar 2002, Tom Lane wrote:
    >> What's bug #3?  I don't recall a third issue.
    
    > The problem I was seeing before is that when the postmaster was shutdown 
    > properly, log_cnt in the sequence record was saved with whatever value it 
    > had at the time.
    
    Right, it's supposed to do that.
    
    > So when it loaded from disk it would have a value greater 
    > than zero resulting in no XLogInsert until you'd exceded log_cnt calls to
    > nextval.  
    
    This is the same as the post-checkpoint issue: we fix it by forcing an
    XLogInsert on the first nextval after a checkpoint (or system startup).
    
    			regards, tom lane
    
    
  11. Re: [BUGS] Bug #613: Sequence values fall back to previously chec

    Clark C. Evans <cce@clarkevans.com> — 2002-03-16T01:54:02Z

    (userland comment)
    
    On Fri, Mar 15, 2002 at 01:05:33AM -0800, Vadim Mikheev wrote:
    | > But sequences should not be under transaction control.  Can you
    | > safely rollback a sequence?  No!  The only way to ensure that would
    | ...
    | > Placing a restriction on an application that says it must treat the values
    | > returned from a sequence as if they might not be committed is absurd.
    | 
    | Why? The fact that you are not able to rollback sequences does not
    | necessary mean that you are not required to perform commit to ensure
    | permanent storage of changes made to database.
    
    I use sequences to generate message identifiers for a simple
    external-to-database message passing system.   I also use
    them for file upload identifiers.  In both cases, if the
    external action (message or file upload) succeeds, I commit; 
    otherwise I roll-back.  I assume that the datbase won't give
    me a duplicate sequence... otherwise I'd have to find some
    other way go get sequences or I'd have duplicate messages
    or non-unique file identifiers.
    
    With these changes is this assumption no longer valid?  If
    so, this change will break alot of user programs.
    
    | And why? Just for convenience of << 1% applications which need
    | to use sequences in their own, non-database, external objects?
    
    I think you may be underestimating the amount of "external resources"
    which may be associated with a datbase object.  Regardless, may of the
    database features in PostgreSQL are there for 1% or less of the
    user base... 
    
    Best,
    
    Clark
    
    -- 
    Clark C. Evans                   Axista, Inc.
    http://www.axista.com            800.926.5525
    XCOLLA Collaborative Project Management Software
    
    
  12. Re: [BUGS] Bug #613: Sequence values fall back to previously chec

    Rod Taylor <rbt@zort.ca> — 2002-03-16T02:02:25Z

    I do basically the same thing for files.  Except I md5 a 4 character
    random string, and the sequence ID just incase I get the same one
    twice -- as it's never been written in stone that I wouldn't -- not to
    mention the high number of requests for returning a sequence ID back
    to the pool on a rollback.
    
    Anyway, you might try using the OID rather than a sequence ID but if
    you rollback the database commit due to failure of an action
    externally, shouldn't you be cleaning up that useless external stuff
    as well?
    --
    Rod Taylor
    
    This message represents the official view of the voices in my head
    
    ----- Original Message -----
    From: "Clark C . Evans" <cce@clarkevans.com>
    To: "Vadim Mikheev" <vmikheev@sectorbase.com>
    Cc: <pgsql-hackers@postgresql.org>
    Sent: Friday, March 15, 2002 8:54 PM
    Subject: Re: [HACKERS] [BUGS] Bug #613: Sequence values fall back to
    previously chec
    
    
    > (userland comment)
    >
    > On Fri, Mar 15, 2002 at 01:05:33AM -0800, Vadim Mikheev wrote:
    > | > But sequences should not be under transaction control.  Can you
    > | > safely rollback a sequence?  No!  The only way to ensure that
    would
    > | ...
    > | > Placing a restriction on an application that says it must treat
    the values
    > | > returned from a sequence as if they might not be committed is
    absurd.
    > |
    > | Why? The fact that you are not able to rollback sequences does not
    > | necessary mean that you are not required to perform commit to
    ensure
    > | permanent storage of changes made to database.
    >
    > I use sequences to generate message identifiers for a simple
    > external-to-database message passing system.   I also use
    > them for file upload identifiers.  In both cases, if the
    > external action (message or file upload) succeeds, I commit;
    > otherwise I roll-back.  I assume that the datbase won't give
    > me a duplicate sequence... otherwise I'd have to find some
    > other way go get sequences or I'd have duplicate messages
    > or non-unique file identifiers.
    >
    > With these changes is this assumption no longer valid?  If
    > so, this change will break alot of user programs.
    >
    > | And why? Just for convenience of << 1% applications which need
    > | to use sequences in their own, non-database, external objects?
    >
    > I think you may be underestimating the amount of "external
    resources"
    > which may be associated with a datbase object.  Regardless, may of
    the
    > database features in PostgreSQL are there for 1% or less of the
    > user base...
    >
    > Best,
    >
    > Clark
    >
    > --
    > Clark C. Evans                   Axista, Inc.
    > http://www.axista.com            800.926.5525
    > XCOLLA Collaborative Project Management Software
    >
    > ---------------------------(end of
    broadcast)---------------------------
    > TIP 1: subscribe and unsubscribe commands go to
    majordomo@postgresql.org
    >
    
    
    
  13. Re: [BUGS] Bug #613: Sequence values fall back to previously chec

    Vadim Mikheev <vmikheev@sectorbase.com> — 2002-03-16T06:04:09Z

    > | > Placing a restriction on an application that says it must treat the
    values
    > | > returned from a sequence as if they might not be committed is absurd.
    > |
    > | Why? The fact that you are not able to rollback sequences does not
    > | necessary mean that you are not required to perform commit to ensure
    > | permanent storage of changes made to database.
    >
    > I use sequences to generate message identifiers for a simple
    > external-to-database message passing system.   I also use
    > them for file upload identifiers.  In both cases, if the
    > external action (message or file upload) succeeds, I commit;
    > otherwise I roll-back.  I assume that the datbase won't give
    > me a duplicate sequence... otherwise I'd have to find some
    
    So can you do "select nextval()" in *separate* (committed)
    transaction *before* external action and "real" transaction where
    you store information (with sequence number) about external
    action in database?
    
    BEGIN;
    SELECT NEXTVAL();
    COMMIT;
    BEGIN;
    -- Do external actions and store info in DB --
    COMMIT/ROLLBACK;
    
    Is this totally unacceptable? Is it really *required* to call nextval()
    in *the same* transaction where you store info in DB? Why?
    
    > other way go get sequences or I'd have duplicate messages
    > or non-unique file identifiers.
    >
    > With these changes is this assumption no longer valid?  If
    
    1. It's not valid to assume that sequences will not return duplicate
        numbers if there was no commit after nextval.
    2. It doesn't matter when sequence numbers are stored in
       database objects only.
    3. But if you're going to use sequence numbers in external objects
        you must (pre)fetch those numbers in separate committed
        transaction.
    
    (Can we have this in FAQ?)
    
    > so, this change will break alot of user programs.
    >
    > | And why? Just for convenience of << 1% applications which need
    > | to use sequences in their own, non-database, external objects?
    >
    > I think you may be underestimating the amount of "external resources"
    > which may be associated with a datbase object.  Regardless, may of the
    > database features in PostgreSQL are there for 1% or less of the
    > user base...
    
    Please note that I was talking about some *inconvenience*, not about
    *inability* of using sequence numbers externally (seems my words were
    too short). Above is how to do this. And though I agreed that it's not
    very convenient/handy/cosy to *take care* and fetch numbers in
    separate committed transaction, but it's required only in those special
    cases and I think it's better than do fsync() per each nextval() call what
    would affect other users/applications where storing sequence numbers
    outside of database is not required.
    
    Vadim