Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
efd6cade
Commit
efd6cade
authored
Jan 15, 2001
by
Tom Lane
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Tweak heap_update/delete so that we do not hold the buffer context lock
on the old tuple's page while we are doing TOAST pushups.
parent
0b5d194a
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
74 additions
and
51 deletions
+74
-51
src/backend/access/heap/heapam.c
src/backend/access/heap/heapam.c
+68
-47
src/backend/access/heap/tuptoaster.c
src/backend/access/heap/tuptoaster.c
+6
-4
No files found.
src/backend/access/heap/heapam.c
View file @
efd6cade
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.10
7 2001/01/12 21:53:54
tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.10
8 2001/01/15 05:29:19
tgl Exp $
*
*
*
*
* INTERFACE ROUTINES
* INTERFACE ROUTINES
...
@@ -1534,18 +1534,20 @@ l1:
...
@@ -1534,18 +1534,20 @@ l1:
}
}
END_CRIT_SECTION
();
END_CRIT_SECTION
();
LockBuffer
(
buffer
,
BUFFER_LOCK_UNLOCK
);
#ifdef TUPLE_TOASTER_ACTIVE
#ifdef TUPLE_TOASTER_ACTIVE
/* ----------
/* ----------
* If the relation has toastable attributes, we need to delete
* If the relation has toastable attributes, we need to delete
* no longer needed items there too.
* no longer needed items there too. We have to do this before
* WriteBuffer because we need to look at the contents of the tuple,
* but it's OK to release the context lock on the buffer first.
* ----------
* ----------
*/
*/
if
(
HeapTupleHasExtended
(
&
tp
))
if
(
HeapTupleHasExtended
(
&
tp
))
heap_tuple_toast_attrs
(
relation
,
NULL
,
&
(
tp
));
heap_tuple_toast_attrs
(
relation
,
NULL
,
&
(
tp
));
#endif
#endif
LockBuffer
(
buffer
,
BUFFER_LOCK_UNLOCK
);
/*
/*
* Mark tuple for invalidation from system caches at next command boundary.
* Mark tuple for invalidation from system caches at next command boundary.
* We have to do this before WriteBuffer because we need to look at the
* We have to do this before WriteBuffer because we need to look at the
...
@@ -1568,7 +1570,10 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
...
@@ -1568,7 +1570,10 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
ItemId
lp
;
ItemId
lp
;
HeapTupleData
oldtup
;
HeapTupleData
oldtup
;
PageHeader
dp
;
PageHeader
dp
;
Buffer
buffer
,
newbuf
;
Buffer
buffer
,
newbuf
;
bool
need_toast
,
already_marked
;
int
result
;
int
result
;
/* increment access statistics */
/* increment access statistics */
...
@@ -1645,7 +1650,7 @@ l2:
...
@@ -1645,7 +1650,7 @@ l2:
return
result
;
return
result
;
}
}
/*
XXX order problems if not atomic assignment ???
*/
/*
Fill in OID and transaction status data for newtup
*/
newtup
->
t_data
->
t_oid
=
oldtup
.
t_data
->
t_oid
;
newtup
->
t_data
->
t_oid
=
oldtup
.
t_data
->
t_oid
;
TransactionIdStore
(
GetCurrentTransactionId
(),
&
(
newtup
->
t_data
->
t_xmin
));
TransactionIdStore
(
GetCurrentTransactionId
(),
&
(
newtup
->
t_data
->
t_xmin
));
newtup
->
t_data
->
t_cmin
=
GetCurrentCommandId
();
newtup
->
t_data
->
t_cmin
=
GetCurrentCommandId
();
...
@@ -1653,69 +1658,84 @@ l2:
...
@@ -1653,69 +1658,84 @@ l2:
newtup
->
t_data
->
t_infomask
&=
~
(
HEAP_XACT_MASK
);
newtup
->
t_data
->
t_infomask
&=
~
(
HEAP_XACT_MASK
);
newtup
->
t_data
->
t_infomask
|=
(
HEAP_XMAX_INVALID
|
HEAP_UPDATED
);
newtup
->
t_data
->
t_infomask
|=
(
HEAP_XMAX_INVALID
|
HEAP_UPDATED
);
#ifdef TUPLE_TOASTER_ACTIVE
/*
/* ----------
* If the toaster needs to be activated, OR if the new tuple will not
* If this relation is enabled for toasting, let the toaster
* fit on the same page as the old, then we need to release the context
* delete any no-longer-needed entries and create new ones to
* lock (but not the pin!) on the old tuple's buffer while we are off
* make the new tuple fit again. Also, if there are already-
* doing TOAST and/or table-file-extension work. We must mark the old
* toasted values from some other relation, the toaster must
* tuple to show that it's already being updated, else other processes
* fix them.
* may try to update it themselves. To avoid second XLOG log record,
* ----------
* we use xact mgr hook to unlock old tuple without reading log if xact
* will abort before update is logged. In the event of crash prio logging,
* TQUAL routines will see HEAP_XMAX_UNLOGGED flag...
*
* NOTE: this trick is useless currently but saved for future
* when we'll implement UNDO and will re-use transaction IDs
* after postmaster startup.
*
* We need to invoke the toaster if there are already any toasted values
* present, or if the new tuple is over-threshold.
*/
*/
if
(
HeapTupleHasExtended
(
&
oldtup
)
||
need_toast
=
(
HeapTupleHasExtended
(
&
oldtup
)
||
HeapTupleHasExtended
(
newtup
)
||
HeapTupleHasExtended
(
newtup
)
||
(
MAXALIGN
(
newtup
->
t_len
)
>
TOAST_TUPLE_THRESHOLD
))
(
MAXALIGN
(
newtup
->
t_len
)
>
TOAST_TUPLE_THRESHOLD
));
heap_tuple_toast_attrs
(
relation
,
newtup
,
&
oldtup
);
#endif
/* Find buffer for new tuple */
if
(
need_toast
||
(
unsigned
)
MAXALIGN
(
newtup
->
t_len
)
>
PageGetFreeSpace
((
Page
)
dp
))
if
((
unsigned
)
MAXALIGN
(
newtup
->
t_len
)
<=
PageGetFreeSpace
((
Page
)
dp
))
newbuf
=
buffer
;
else
{
{
/*
* We have to unlock old tuple buffer before extending table
* file but have to keep lock on the old tuple. To avoid second
* XLOG log record we use xact mngr hook to unlock old tuple
* without reading log if xact will abort before update is logged.
* In the event of crash prio logging, TQUAL routines will see
* HEAP_XMAX_UNLOGGED flag...
*
* NOTE: this trick is useless currently but saved for future
* when we'll implement UNDO and will re-use transaction IDs
* after postmaster startup.
*/
_locked_tuple_
.
node
=
relation
->
rd_node
;
_locked_tuple_
.
node
=
relation
->
rd_node
;
_locked_tuple_
.
tid
=
oldtup
.
t_self
;
_locked_tuple_
.
tid
=
oldtup
.
t_self
;
XactPushRollback
(
_heap_unlock_tuple
,
(
void
*
)
&
_locked_tuple_
);
XactPushRollback
(
_heap_unlock_tuple
,
(
void
*
)
&
_locked_tuple_
);
TransactionIdStore
(
GetCurrentTransactionId
(),
&
(
oldtup
.
t_data
->
t_xmax
));
TransactionIdStore
(
GetCurrentTransactionId
(),
&
(
oldtup
.
t_data
->
t_xmax
));
oldtup
.
t_data
->
t_cmax
=
GetCurrentCommandId
();
oldtup
.
t_data
->
t_cmax
=
GetCurrentCommandId
();
oldtup
.
t_data
->
t_infomask
&=
~
(
HEAP_XMAX_COMMITTED
|
oldtup
.
t_data
->
t_infomask
&=
~
(
HEAP_XMAX_COMMITTED
|
HEAP_XMAX_INVALID
|
HEAP_MARKED_FOR_UPDATE
);
HEAP_XMAX_INVALID
|
HEAP_MARKED_FOR_UPDATE
);
oldtup
.
t_data
->
t_infomask
|=
HEAP_XMAX_UNLOGGED
;
oldtup
.
t_data
->
t_infomask
|=
HEAP_XMAX_UNLOGGED
;
already_marked
=
true
;
LockBuffer
(
buffer
,
BUFFER_LOCK_UNLOCK
);
LockBuffer
(
buffer
,
BUFFER_LOCK_UNLOCK
);
newbuf
=
RelationGetBufferForTuple
(
relation
,
newtup
->
t_len
);
/* Let the toaster do its thing */
if
(
need_toast
)
heap_tuple_toast_attrs
(
relation
,
newtup
,
&
oldtup
);
/* Now, do we need a new page for the tuple, or not? */
if
((
unsigned
)
MAXALIGN
(
newtup
->
t_len
)
<=
PageGetFreeSpace
((
Page
)
dp
))
newbuf
=
buffer
;
else
newbuf
=
RelationGetBufferForTuple
(
relation
,
newtup
->
t_len
);
/* Re-acquire the lock on the old tuple's page. */
/* this seems to be deadlock free... */
/* this seems to be deadlock free... */
LockBuffer
(
buffer
,
BUFFER_LOCK_EXCLUSIVE
);
LockBuffer
(
buffer
,
BUFFER_LOCK_EXCLUSIVE
);
}
}
else
{
/* No TOAST work needed, and it'll fit on same page */
already_marked
=
false
;
newbuf
=
buffer
;
}
/* NO ELOG(ERROR) from here till changes are logged */
/* NO ELOG(ERROR) from here till changes are logged */
START_CRIT_SECTION
();
START_CRIT_SECTION
();
RelationPutHeapTuple
(
relation
,
newbuf
,
newtup
);
/* insert new tuple */
RelationPutHeapTuple
(
relation
,
newbuf
,
newtup
);
/* insert new tuple */
if
(
buffer
==
newbuf
)
if
(
already_marked
)
{
{
TransactionIdStore
(
GetCurrentTransactionId
(),
&
(
oldtup
.
t_data
->
t_xmax
));
oldtup
.
t_data
->
t_infomask
&=
~
HEAP_XMAX_UNLOGGED
;
oldtup
.
t_data
->
t_cmax
=
GetCurrentCommandId
();
XactPopRollback
();
oldtup
.
t_data
->
t_infomask
&=
~
(
HEAP_XMAX_COMMITTED
|
HEAP_XMAX_INVALID
|
HEAP_MARKED_FOR_UPDATE
);
}
}
else
else
{
{
oldtup
.
t_data
->
t_infomask
&=
~
HEAP_XMAX_UNLOGGED
;
TransactionIdStore
(
GetCurrentTransactionId
(),
XactPopRollback
();
&
(
oldtup
.
t_data
->
t_xmax
));
oldtup
.
t_data
->
t_cmax
=
GetCurrentCommandId
();
oldtup
.
t_data
->
t_infomask
&=
~
(
HEAP_XMAX_COMMITTED
|
HEAP_XMAX_INVALID
|
HEAP_MARKED_FOR_UPDATE
);
}
}
/* record address of new tuple in t_ctid of old one */
/* record address of new tuple in t_ctid of old one */
...
@@ -1724,7 +1744,7 @@ l2:
...
@@ -1724,7 +1744,7 @@ l2:
/* XLOG stuff */
/* XLOG stuff */
{
{
XLogRecPtr
recptr
=
log_heap_update
(
relation
,
buffer
,
oldtup
.
t_self
,
XLogRecPtr
recptr
=
log_heap_update
(
relation
,
buffer
,
oldtup
.
t_self
,
newbuf
,
newtup
,
false
);
newbuf
,
newtup
,
false
);
if
(
newbuf
!=
buffer
)
if
(
newbuf
!=
buffer
)
{
{
...
@@ -1734,6 +1754,7 @@ l2:
...
@@ -1734,6 +1754,7 @@ l2:
PageSetLSN
(
BufferGetPage
(
buffer
),
recptr
);
PageSetLSN
(
BufferGetPage
(
buffer
),
recptr
);
PageSetSUI
(
BufferGetPage
(
buffer
),
ThisStartUpID
);
PageSetSUI
(
BufferGetPage
(
buffer
),
ThisStartUpID
);
}
}
END_CRIT_SECTION
();
END_CRIT_SECTION
();
if
(
newbuf
!=
buffer
)
if
(
newbuf
!=
buffer
)
...
...
src/backend/access/heap/tuptoaster.c
View file @
efd6cade
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.1
3 2000/10/23 23:42:04
tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.1
4 2001/01/15 05:29:19
tgl Exp $
*
*
*
*
* INTERFACE ROUTINES
* INTERFACE ROUTINES
...
@@ -197,10 +197,12 @@ toast_delete(Relation rel, HeapTuple oldtup)
...
@@ -197,10 +197,12 @@ toast_delete(Relation rel, HeapTuple oldtup)
*/
*/
for
(
i
=
0
;
i
<
numAttrs
;
i
++
)
for
(
i
=
0
;
i
<
numAttrs
;
i
++
)
{
{
value
=
heap_getattr
(
oldtup
,
i
+
1
,
tupleDesc
,
&
isnull
);
if
(
att
[
i
]
->
attlen
==
-
1
)
if
(
!
isnull
&&
att
[
i
]
->
attlen
==
-
1
)
{
if
(
VARATT_IS_EXTERNAL
(
value
))
value
=
heap_getattr
(
oldtup
,
i
+
1
,
tupleDesc
,
&
isnull
);
if
(
!
isnull
&&
VARATT_IS_EXTERNAL
(
value
))
toast_delete_datum
(
rel
,
value
);
toast_delete_datum
(
rel
,
value
);
}
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment