mirror of
https://github.com/postgres/postgres.git
synced 2026-04-23 07:07:22 -04:00
as per recent discussions. Invent SubTransactionIds that are managed like CommandIds (ie, counter is reset at start of each top transaction), and use these instead of TransactionIds to keep track of subtransaction status in those modules that need it. This means that a subtransaction does not need an XID unless it actually inserts/modifies rows in the database. Accordingly, don't assign it an XID nor take a lock on the XID until it tries to do that. This saves a lot of overhead for subtransactions that are only used for error recovery (eg plpgsql exceptions). Also, arrange to release a subtransaction's XID lock as soon as the subtransaction exits, in both the commit and abort cases. This avoids holding many unique locks after a long series of subtransactions. The price is some additional overhead in XactLockTableWait, but that seems acceptable. Finally, restructure the state machine in xact.c to have a more orthogonal set of states for subtransactions.
77 lines
2.7 KiB
C
77 lines
2.7 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* large_object.h
|
|
* Declarations for PostgreSQL large objects. POSTGRES 4.2 supported
|
|
* zillions of large objects (internal, external, jaquith, inversion).
|
|
* Now we only support inversion.
|
|
*
|
|
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
* $PostgreSQL: pgsql/src/include/storage/large_object.h,v 1.30 2004/09/16 16:58:42 tgl Exp $
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#ifndef LARGE_OBJECT_H
|
|
#define LARGE_OBJECT_H
|
|
|
|
|
|
/*----------
|
|
* Data about a currently-open large object.
|
|
*
|
|
* id is the logical OID of the large object
|
|
* subid is the subtransaction that opened the LO (or currently owns it)
|
|
* offset is the current seek offset within the LO
|
|
* flags contains some flag bits
|
|
*
|
|
* NOTE: before 7.1, we also had to store references to the separate table
|
|
* and index of a specific large object. Now they all live in pg_largeobject
|
|
* and are accessed via a common relation descriptor.
|
|
*----------
|
|
*/
|
|
typedef struct LargeObjectDesc
|
|
{
|
|
Oid id; /* LO's identifier */
|
|
SubTransactionId subid; /* owning subtransaction ID */
|
|
uint32 offset; /* current seek pointer */
|
|
int flags; /* locking info, etc */
|
|
|
|
/* flag bits: */
|
|
#define IFS_RDLOCK (1 << 0)
|
|
#define IFS_WRLOCK (1 << 1)
|
|
} LargeObjectDesc;
|
|
|
|
|
|
/*
|
|
* Each "page" (tuple) of a large object can hold this much data
|
|
*
|
|
* We could set this as high as BLCKSZ less some overhead, but it seems
|
|
* better to make it a smaller value, so that not as much space is used
|
|
* up when a page-tuple is updated. Note that the value is deliberately
|
|
* chosen large enough to trigger the tuple toaster, so that we will
|
|
* attempt to compress page tuples in-line. (But they won't be moved off
|
|
* unless the user creates a toast-table for pg_largeobject...)
|
|
*
|
|
* Also, it seems to be a smart move to make the page size be a power of 2,
|
|
* since clients will often be written to send data in power-of-2 blocks.
|
|
* This avoids unnecessary tuple updates caused by partial-page writes.
|
|
*/
|
|
#define LOBLKSIZE (BLCKSZ / 4)
|
|
|
|
|
|
/*
|
|
* Function definitions...
|
|
*/
|
|
|
|
/* inversion stuff in inv_api.c */
|
|
extern void close_lo_relation(bool isCommit);
|
|
extern LargeObjectDesc *inv_create(int flags);
|
|
extern LargeObjectDesc *inv_open(Oid lobjId, int flags);
|
|
extern void inv_close(LargeObjectDesc *obj_desc);
|
|
extern int inv_drop(Oid lobjId);
|
|
extern int inv_seek(LargeObjectDesc *obj_desc, int offset, int whence);
|
|
extern int inv_tell(LargeObjectDesc *obj_desc);
|
|
extern int inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes);
|
|
extern int inv_write(LargeObjectDesc *obj_desc, char *buf, int nbytes);
|
|
|
|
#endif /* LARGE_OBJECT_H */
|