Thread: Lazy xid assignment V3

Lazy xid assignment V3

From
"Florian G. Pflug"
Date:
I tried sending this with the actual patch attached - this time,
to pgsql-pacthes, but it seems that my mail didn't get through again.
So it've put up the patch here: http://soc.phlo.org/lazyxidassign.v3.patch

----------------------------------------
Hi

Here is an updated version of my patch. This is pretty much equivalent
to the version V2, apart from the few minor things Tom criticized. The
changes are.

.) elog(ERROR) instead of Assert if there are to-be-deleted files, but
no XID assigned on commit

.) ResourceOwnerId is renamed to VirtualTransactionId.

.) GetOldestXmin() checks GetTopTransactionIdIfAny() first, and only
     reverts to ReadNewTransactionId() if the former returns
     InvalidTransactionId.

Since we didn't really reach an agreement on how xid_age should behave,
I've reverted it back to the original version. So with this patch,
xid_age will just force assignment of a xid. The other proposed ideas
where

.) Use some cached xid value which is kept stable for the duration of
     a transaction.
.) Use RecentGlobalXmin. This makes the notion of xid age consistent with
     VACCUM. The value could change between statements though (for
     read-committed transactions).
.) Use the current snaphot's xmax. This would be the closest possible
     approximation of using ReadNewTransasctionId() that keeps the xid age
     constant during a statement or transaction. (Depending on the xact being
     read-committed or serializable).

greetings, Florian Pflug



Re: Lazy xid assignment V3

From
Alvaro Herrera
Date:
Florian G. Pflug wrote:

> Since we didn't really reach an agreement on how xid_age should behave,
> I've reverted it back to the original version. So with this patch,
> xid_age will just force assignment of a xid.

Is this really a good idea?  I'm repeating myself, but a query like

select age(xmin) from bigtable

could accelerate Xid wraparound.  If the server is running close to the
limit it could cause a shutdown to prevent the actual wraparound.

--
Alvaro Herrera                                http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

Re: Lazy xid assignment V3

From
"Marko Kreen"
Date:
On 9/3/07, Alvaro Herrera <alvherre@commandprompt.com> wrote:
> Florian G. Pflug wrote:
> > Since we didn't really reach an agreement on how xid_age should behave,
> > I've reverted it back to the original version. So with this patch,
> > xid_age will just force assignment of a xid.
>
> Is this really a good idea?  I'm repeating myself, but a query like
>
> select age(xmin) from bigtable
>
> could accelerate Xid wraparound.  If the server is running close to the
> limit it could cause a shutdown to prevent the actual wraparound.

Such query would take only one xid, which should not be a problem?

--
marko

Re: Lazy xid assignment V3

From
"Heikki Linnakangas"
Date:
Florian G. Pflug wrote:
> Here is an updated version of my patch. This is pretty much equivalent
> to the version V2, apart from the few minor things Tom criticized. The
> changes are.

Should there be new a log_line_prefix percent code for virtual
transaction ids? Or should we change the meaning of %x to be virtual
transaction id instead of the real one. As the patch stands, %x will
just print 0 for all transactions with no xid assigned, and the prefix
will change when one is assigned. I believe the main use case for %x is
to distinguish which messages are coming from which transaction, and the
patch as it is makes it mostly useless for that purpose.

The function comment in GetLockConflicts should probably be updated;
it's not returning a linked list anymore, but an array terminated by an
InvalidVirtualTransactionId.

What the worst thing that happens if two sessions are assigned the same
session id? Should be infrequent, but not impossible if you have some
very long-lived connections and other clients connecting/disconnecting
all the time.

A few comment typos:
asigned -> assigned
transcation -> transaction

> .) elog(ERROR) instead of Assert if there are to-be-deleted files, but
> no XID assigned on commit
>
> .) ResourceOwnerId is renamed to VirtualTransactionId.
>
> .) GetOldestXmin() checks GetTopTransactionIdIfAny() first, and only
>     reverts to ReadNewTransactionId() if the former returns
>     InvalidTransactionId.
>
> Since we didn't really reach an agreement on how xid_age should behave,
> I've reverted it back to the original version. So with this patch,
> xid_age will just force assignment of a xid.

Sounds OK to me. It's not going to consume any more xids than it does
now, and I don't think xid_age is called very often. What's it for
anyway? To write scripts to run VACUUM before xid wrap-around?

--
  Heikki Linnakangas
  EnterpriseDB   http://www.enterprisedb.com

Re: Lazy xid assignment V3

From
Alvaro Herrera
Date:
Marko Kreen escribió:
> On 9/3/07, Alvaro Herrera <alvherre@commandprompt.com> wrote:
> > Florian G. Pflug wrote:
> > > Since we didn't really reach an agreement on how xid_age should behave,
> > > I've reverted it back to the original version. So with this patch,
> > > xid_age will just force assignment of a xid.
> >
> > Is this really a good idea?  I'm repeating myself, but a query like
> >
> > select age(xmin) from bigtable
> >
> > could accelerate Xid wraparound.  If the server is running close to the
> > limit it could cause a shutdown to prevent the actual wraparound.
>
> Such query would take only one xid, which should not be a problem?

My guess is that it would execute age(xid) once per tuple?  Even if all
the tuples had the same xmin, there's no cache therefore it would
consume as many Xids as there are tuples.

Am I missing something?

--
Alvaro Herrera                                http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.

Re: Lazy xid assignment V3

From
"Marko Kreen"
Date:
On 9/3/07, Alvaro Herrera <alvherre@commandprompt.com> wrote:
> Marko Kreen escribió:
> > On 9/3/07, Alvaro Herrera <alvherre@commandprompt.com> wrote:
> > > Florian G. Pflug wrote:
> > > > Since we didn't really reach an agreement on how xid_age should behave,
> > > > I've reverted it back to the original version. So with this patch,
> > > > xid_age will just force assignment of a xid.
> > >
> > > Is this really a good idea?  I'm repeating myself, but a query like
> > >
> > > select age(xmin) from bigtable
> > >
> > > could accelerate Xid wraparound.  If the server is running close to the
> > > limit it could cause a shutdown to prevent the actual wraparound.
> >
> > Such query would take only one xid, which should not be a problem?
>
> My guess is that it would execute age(xid) once per tuple?  Even if all
> the tuples had the same xmin, there's no cache therefore it would
> consume as many Xids as there are tuples.
>
> Am I missing something?

First age() assigns CurrentXid, rest reuse it.

--
marko

Re: Lazy xid assignment V3

From
Tom Lane
Date:
"Heikki Linnakangas" <heikki@enterprisedb.com> writes:
> Should there be new a log_line_prefix percent code for virtual
> transaction ids? Or should we change the meaning of %x to be virtual
> transaction id instead of the real one.

I think the latter should be sufficient, especially if we also are showing
vxid in pg_locks and pg_stat_activity.

> What the worst thing that happens if two sessions are assigned the same
> session id? Should be infrequent, but not impossible if you have some
> very long-lived connections and other clients connecting/disconnecting
> all the time.

I think this'll be all right.  The only operations we actually do on
vxids is equality comparison.  Even if you had a session that was 4
billion new-connections old, it should also have a pretty darn high
localvxid counter, and so a new session coming in and starting its
counter at 0 is highly unlikely to conflict.  It's not impossible,
I guess, but the odds against seem so high that it's not worth adding
code to prevent it.

>> Since we didn't really reach an agreement on how xid_age should behave,
>> I've reverted it back to the original version. So with this patch,
>> xid_age will just force assignment of a xid.

> Sounds OK to me. It's not going to consume any more xids than it does
> now, and I don't think xid_age is called very often. What's it for
> anyway? To write scripts to run VACUUM before xid wrap-around?

Yeah.  I think xid_age is really just a historical curiosity anyway as
of 8.2 --- there's hardly any real use-case for it.

            regards, tom lane

Re: Lazy xid assignment V3

From
"Florian G. Pflug"
Date:
Tom Lane wrote:
> "Heikki Linnakangas" <heikki@enterprisedb.com> writes:
>> Should there be new a log_line_prefix percent code for virtual
>> transaction ids? Or should we change the meaning of %x to be virtual
>> transaction id instead of the real one.
>
> I think the latter should be sufficient, especially if we also are showing
> vxid in pg_locks and pg_stat_activity.

Hm.. Wouldn't that kind of defeat the idea of a log, if you need the
output of pg_locks to interpret it? Maybe we should just show both
values for %x? Or just the xid if it's set, and the vid otherwise?

BTW, my current patch doesn't show the vid in pg_stat_activity. I
initially wanted to add because, because I believed that the xid
is also shown in pg_stat_activity. But I then realized that the
xid actually *isn't* shown, and the all the other values shown in
pg_stat_activity are directly pulled out of the stats collector.
So it seems quite messy and inconsistent to add the vid.

>> What the worst thing that happens if two sessions are assigned the same
>> session id? Should be infrequent, but not impossible if you have some
>> very long-lived connections and other clients connecting/disconnecting
>> all the time.
>
> I think this'll be all right.  The only operations we actually do on
> vxids is equality comparison.  Even if you had a session that was 4
> billion new-connections old, it should also have a pretty darn high
> localvxid counter, and so a new session coming in and starting its
> counter at 0 is highly unlikely to conflict.  It's not impossible,
> I guess, but the odds against seem so high that it's not worth adding
> code to prevent it.

Even in the case of a conflict, two transactions still wouldn't be
running with the same vid. Rather, the second one would block until
the first exits, because we hold an ExclusiveLock on the vid.

Still, I overlooked the possibility of this, and it does seem a bit
ugly. Maybe we ought to use MyBackendId to disambiguate this? All it
would take would be another field backendId in VirtualTransactionId.

greetings, Florian Pflug

Re: Lazy xid assignment V3

From
Tom Lane
Date:
"Florian G. Pflug" <fgp@phlo.org> writes:
> Tom Lane wrote:
>> "Heikki Linnakangas" <heikki@enterprisedb.com> writes:
>>> Should there be new a log_line_prefix percent code for virtual
>>> transaction ids? Or should we change the meaning of %x to be virtual
>>> transaction id instead of the real one.
>>
>> I think the latter should be sufficient, especially if we also are showing
>> vxid in pg_locks and pg_stat_activity.

> Hm.. Wouldn't that kind of defeat the idea of a log, if you need the
> output of pg_locks to interpret it? Maybe we should just show both
> values for %x? Or just the xid if it's set, and the vid otherwise?

Well, how do you interpret xid in the log today, if not by reference
to those views?  The last option seems quite unworkable, especially
for CSV-based logs.

I suppose there's no great harm in providing %v as an additional
prefix format code ...

> BTW, my current patch doesn't show the vid in pg_stat_activity.

Hmm, actually it looks like the join key for that is supposed to be PID,
so maybe we needn't do anything to it.

> Even in the case of a conflict, two transactions still wouldn't be
> running with the same vid. Rather, the second one would block until
> the first exits, because we hold an ExclusiveLock on the vid.

It's definitely sufficient then ...

            regards, tom lane

Re: Lazy xid assignment V3

From
"Florian G. Pflug"
Date:
Tom Lane wrote:
> "Florian G. Pflug" <fgp@phlo.org> writes:
>> Tom Lane wrote:
>>> "Heikki Linnakangas" <heikki@enterprisedb.com> writes:
>>>> Should there be new a log_line_prefix percent code for virtual
>>>> transaction ids? Or should we change the meaning of %x to be virtual
>>>> transaction id instead of the real one.
>>> I think the latter should be sufficient, especially if we also are showing
>>> vxid in pg_locks and pg_stat_activity.
>
>> Hm.. Wouldn't that kind of defeat the idea of a log, if you need the
>> output of pg_locks to interpret it? Maybe we should just show both
>> values for %x? Or just the xid if it's set, and the vid otherwise?
>
> Well, how do you interpret xid in the log today, if not by reference
> to those views?  The last option seems quite unworkable, especially
> for CSV-based logs.
Someone might match the xid with xids found on disk. If we replace the
xid with the vid, than this is impossible unless you also periodically
snapshot pg_locks.

> I suppose there's no great harm in providing %v as an additional
> prefix format code ...
Ok, I'll do this. Shouldn't be too hard, it seems...

>> BTW, my current patch doesn't show the vid in pg_stat_activity.
>
> Hmm, actually it looks like the join key for that is supposed to be PID,
> so maybe we needn't do anything to it.
Yes, that was my reasoning too. Maybe we want to add both xid and vid
to pg_stat_activity one day, but since this patch might hit 8.3, lets
keep it as minimal as possible...

>> Even in the case of a conflict, two transactions still wouldn't be
>> running with the same vid. Rather, the second one would block until
>> the first exits, because we hold an ExclusiveLock on the vid.
>
> It's definitely sufficient then ...
This implies that connecting and the immediately starting a transaction
(which will then get "1" as it's localTransactionId) which you keep
open *will* block some other transaction after 4 billion other connects.

I'm not saying that this is unacceptable, I just wanted to clearly state
the consequences.

greetings, Florian Pflug



Re: Lazy xid assignment V3

From
"Heikki Linnakangas"
Date:
Tom Lane wrote:
> "Florian G. Pflug" <fgp@phlo.org> writes:
>> Tom Lane wrote:
>>> "Heikki Linnakangas" <heikki@enterprisedb.com> writes:
>>>> Should there be new a log_line_prefix percent code for virtual
>>>> transaction ids? Or should we change the meaning of %x to be virtual
>>>> transaction id instead of the real one.
>>> I think the latter should be sufficient, especially if we also are showing
>>> vxid in pg_locks and pg_stat_activity.
>
>> Hm.. Wouldn't that kind of defeat the idea of a log, if you need the
>> output of pg_locks to interpret it? Maybe we should just show both
>> values for %x? Or just the xid if it's set, and the vid otherwise?
>
> Well, how do you interpret xid in the log today, if not by reference
> to those views?  The last option seems quite unworkable, especially
> for CSV-based logs.

I don't think people usually interpret the xid in logs in any way. It's
just a handy unique (unique enough, ignoring xid wraparound) identifier
for the transaction that you can use to figure out what each separate
transaction is doing. For that purpose, it doesn't matter if it doesn't
match the normal on-disk xid, using vid instead of xid works just fine.

Hmm. Or is it unique enough after all? Do we reuse session ids after a
server restart?

For debugging PostgreSQL bugs, though, having the real xid in the logs
is really nice. You can then compare the logs against the tuples on the
disk.

>> Even in the case of a conflict, two transactions still wouldn't be
>> running with the same vid. Rather, the second one would block until
>> the first exits, because we hold an ExclusiveLock on the vid.
>
> It's definitely sufficient then ...

Yeah. If we did want to do something more, we could acquire the lock on
vid conditionally, and use another vid if acquiring the lock fails. But
I don't think it's necessary.

--
  Heikki Linnakangas
  EnterpriseDB   http://www.enterprisedb.com

Re: Lazy xid assignment V3

From
"Florian G. Pflug"
Date:
Heikki Linnakangas wrote:
> Tom Lane wrote:
>> "Florian G. Pflug" <fgp@phlo.org> writes:
>>> Tom Lane wrote:
>>>> "Heikki Linnakangas" <heikki@enterprisedb.com> writes:
>>>>> Should there be new a log_line_prefix percent code for virtual
>>>>> transaction ids? Or should we change the meaning of %x to be virtual
>>>>> transaction id instead of the real one.
>>>> I think the latter should be sufficient, especially if we also are showing
>>>> vxid in pg_locks and pg_stat_activity.
>>> Hm.. Wouldn't that kind of defeat the idea of a log, if you need the
>>> output of pg_locks to interpret it? Maybe we should just show both
>>> values for %x? Or just the xid if it's set, and the vid otherwise?
>> Well, how do you interpret xid in the log today, if not by reference
>> to those views?  The last option seems quite unworkable, especially
>> for CSV-based logs.
>
> I don't think people usually interpret the xid in logs in any way. It's
> just a handy unique (unique enough, ignoring xid wraparound) identifier
> for the transaction that you can use to figure out what each separate
> transaction is doing. For that purpose, it doesn't matter if it doesn't
> match the normal on-disk xid, using vid instead of xid works just fine.
>
> Hmm. Or is it unique enough after all? Do we reuse session ids after a
> server restart?
Yes - the sessionIs is just a counter in shared memory, so we start "1"
after a restart again.

> For debugging PostgreSQL bugs, though, having the real xid in the logs
> is really nice. You can then compare the logs against the tuples on the
> disk.
I take this as a vote for having both "%x" and "%v" for xid and virtual xid
respectively.

greetings, Florian Pflug

Re: Lazy xid assignment V3

From
Tom Lane
Date:
"Heikki Linnakangas" <heikki@enterprisedb.com> writes:
> Yeah. If we did want to do something more, we could acquire the lock on
> vid conditionally, and use another vid if acquiring the lock fails. But
> I don't think it's necessary.

I was thinking more along the lines of looking through the ProcArray at
backend startup to ensure the sessionID we've chosen is unique, and
choosing another one if not.  But this would expend cycles with the
ProcArray locked, for something that seems exceedingly unlikely to
happen,

            regards, tom lane