Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
P
postgres-lambda-diff
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Jakob Huber
postgres-lambda-diff
Commits
2a44383a
Commit
2a44383a
authored
May 31, 1999
by
Tom Lane
Browse files
Options
Downloads
Patches
Plain Diff
Clean up memory leaks in LO operations by freeing LO's private
memory context at transaction commit or abort.
parent
81ced1e0
No related branches found
No related tags found
No related merge requests found
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
src/backend/access/transam/xact.c
+3
-4
3 additions, 4 deletions
src/backend/access/transam/xact.c
src/backend/libpq/be-fsstubs.c
+78
-22
78 additions, 22 deletions
src/backend/libpq/be-fsstubs.c
src/include/libpq/be-fsstubs.h
+2
-2
2 additions, 2 deletions
src/include/libpq/be-fsstubs.h
with
83 additions
and
28 deletions
src/backend/access/transam/xact.c
+
3
−
4
View file @
2a44383a
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.3
6
1999/05/
25 16:07:50 momjian
Exp $
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.3
7
1999/05/
31 22:53:59 tgl
Exp $
*
*
* NOTES
* NOTES
* Transaction aborts can now occur two ways:
* Transaction aborts can now occur two ways:
...
@@ -156,8 +156,6 @@
...
@@ -156,8 +156,6 @@
#include
<miscadmin.h>
#include
<miscadmin.h>
#include
<commands/async.h>
#include
<commands/async.h>
#include
<commands/sequence.h>
#include
<commands/sequence.h>
/* included for _lo_commit [PA, 7/17/98] */
#include
<libpq/be-fsstubs.h>
#include
<libpq/be-fsstubs.h>
static
void
AbortTransaction
(
void
);
static
void
AbortTransaction
(
void
);
...
@@ -938,7 +936,7 @@ CommitTransaction()
...
@@ -938,7 +936,7 @@ CommitTransaction()
*/
*/
/* handle commit for large objects [ PA, 7/17/98 ] */
/* handle commit for large objects [ PA, 7/17/98 ] */
_
lo_commit
();
lo_commit
(
true
);
/* NOTIFY commit must also come before lower-level cleanup */
/* NOTIFY commit must also come before lower-level cleanup */
AtCommit_Notify
();
AtCommit_Notify
();
...
@@ -1012,6 +1010,7 @@ AbortTransaction()
...
@@ -1012,6 +1010,7 @@ AbortTransaction()
* do abort processing
* do abort processing
* ----------------
* ----------------
*/
*/
lo_commit
(
false
);
/* 'false' means it's abort */
UnlockBuffers
();
UnlockBuffers
();
AtAbort_Notify
();
AtAbort_Notify
();
CloseSequences
();
CloseSequences
();
...
...
...
...
This diff is collapsed.
Click to expand it.
src/backend/libpq/be-fsstubs.c
+
78
−
22
View file @
2a44383a
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/libpq/be-fsstubs.c,v 1.3
3
1999/05/
25 16:08:57 momjian
Exp $
* $Header: /cvsroot/pgsql/src/backend/libpq/be-fsstubs.c,v 1.3
4
1999/05/
31 22:53:57 tgl
Exp $
*
*
* NOTES
* NOTES
* This should be moved to a more appropriate place. It is here
* This should be moved to a more appropriate place. It is here
...
@@ -15,10 +15,17 @@
...
@@ -15,10 +15,17 @@
*
*
* Builtin functions for open/close/read/write operations on large objects.
* Builtin functions for open/close/read/write operations on large objects.
*
*
* These functions operate in the current portal variable context, which
* These functions operate in a private GlobalMemoryContext, which means
* means the large object descriptors hang around between transactions and
* that large object descriptors hang around until we destroy the context.
* are not deallocated until explicitly closed, or until the portal is
* That happens in lo_commit(). It'd be possible to prolong the lifetime
* closed.
* of the context so that LO FDs are good across transactions (for example,
* we could release the context only if we see that no FDs remain open).
* But we'd need additional state in order to do the right thing at the
* end of an aborted transaction. FDs opened during an aborted xact would
* still need to be closed, since they might not be pointing at valid
* relations at all. For now, we'll stick with the existing documented
* semantics of LO FDs: they're only good within a transaction.
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -37,6 +44,7 @@
...
@@ -37,6 +44,7 @@
#include
<utils/memutils.h>
#include
<utils/memutils.h>
#include
<lib/fstack.h>
#include
<lib/fstack.h>
#include
<utils/mcxt.h>
#include
<utils/mcxt.h>
#include
<catalog/pg_shadow.h>
/* for superuser() */
#include
<storage/fd.h>
/* for O_ */
#include
<storage/fd.h>
/* for O_ */
#include
<storage/large_object.h>
#include
<storage/large_object.h>
#include
<libpq/be-fsstubs.h>
#include
<libpq/be-fsstubs.h>
...
@@ -91,6 +99,11 @@ lo_open(Oid lobjId, int mode)
...
@@ -91,6 +99,11 @@ lo_open(Oid lobjId, int mode)
/* switch context back to orig. */
/* switch context back to orig. */
MemoryContextSwitchTo
(
currentContext
);
MemoryContextSwitchTo
(
currentContext
);
#if FSDB
if
(
fd
<
0
)
/* newLOfd couldn't find a slot */
elog
(
NOTICE
,
"Out of space for large object FDs"
);
#endif
return
fd
;
return
fd
;
}
}
...
@@ -144,6 +157,8 @@ lo_read(int fd, char *buf, int len)
...
@@ -144,6 +157,8 @@ lo_read(int fd, char *buf, int len)
elog
(
ERROR
,
"lo_read: invalid large obj descriptor (%d)"
,
fd
);
elog
(
ERROR
,
"lo_read: invalid large obj descriptor (%d)"
,
fd
);
return
-
3
;
return
-
3
;
}
}
Assert
(
fscxt
!=
NULL
);
currentContext
=
MemoryContextSwitchTo
((
MemoryContext
)
fscxt
);
currentContext
=
MemoryContextSwitchTo
((
MemoryContext
)
fscxt
);
status
=
inv_read
(
cookies
[
fd
],
buf
,
len
);
status
=
inv_read
(
cookies
[
fd
],
buf
,
len
);
...
@@ -168,6 +183,8 @@ lo_write(int fd, char *buf, int len)
...
@@ -168,6 +183,8 @@ lo_write(int fd, char *buf, int len)
elog
(
ERROR
,
"lo_write: invalid large obj descriptor (%d)"
,
fd
);
elog
(
ERROR
,
"lo_write: invalid large obj descriptor (%d)"
,
fd
);
return
-
3
;
return
-
3
;
}
}
Assert
(
fscxt
!=
NULL
);
currentContext
=
MemoryContextSwitchTo
((
MemoryContext
)
fscxt
);
currentContext
=
MemoryContextSwitchTo
((
MemoryContext
)
fscxt
);
status
=
inv_write
(
cookies
[
fd
],
buf
,
len
);
status
=
inv_write
(
cookies
[
fd
],
buf
,
len
);
...
@@ -181,7 +198,7 @@ int
...
@@ -181,7 +198,7 @@ int
lo_lseek
(
int
fd
,
int
offset
,
int
whence
)
lo_lseek
(
int
fd
,
int
offset
,
int
whence
)
{
{
MemoryContext
currentContext
;
MemoryContext
currentContext
;
int
ret
;
int
status
;
if
(
fd
<
0
||
fd
>=
MAX_LOBJ_FDS
)
if
(
fd
<
0
||
fd
>=
MAX_LOBJ_FDS
)
{
{
...
@@ -194,13 +211,14 @@ lo_lseek(int fd, int offset, int whence)
...
@@ -194,13 +211,14 @@ lo_lseek(int fd, int offset, int whence)
return
-
3
;
return
-
3
;
}
}
Assert
(
fscxt
!=
NULL
);
currentContext
=
MemoryContextSwitchTo
((
MemoryContext
)
fscxt
);
currentContext
=
MemoryContextSwitchTo
((
MemoryContext
)
fscxt
);
ret
=
inv_seek
(
cookies
[
fd
],
offset
,
whence
);
status
=
inv_seek
(
cookies
[
fd
],
offset
,
whence
);
MemoryContextSwitchTo
(
currentContext
);
MemoryContextSwitchTo
(
currentContext
);
return
ret
;
return
status
;
}
}
Oid
Oid
...
@@ -246,12 +264,26 @@ lo_tell(int fd)
...
@@ -246,12 +264,26 @@ lo_tell(int fd)
elog
(
ERROR
,
"lo_tell: invalid large object descriptor (%d)"
,
fd
);
elog
(
ERROR
,
"lo_tell: invalid large object descriptor (%d)"
,
fd
);
return
-
3
;
return
-
3
;
}
}
/*
* We assume we do not need to switch contexts for inv_tell.
* That is true for now, but is probably more than this module
* ought to assume...
*/
return
inv_tell
(
cookies
[
fd
]);
return
inv_tell
(
cookies
[
fd
]);
}
}
int
int
lo_unlink
(
Oid
lobjId
)
lo_unlink
(
Oid
lobjId
)
{
{
/*
* inv_destroy does not need a context switch, indeed it doesn't
* touch any LO-specific data structures at all. (Again, that's
* probably more than this module ought to be assuming.)
*
* XXX there ought to be some code to clean up any open LOs that
* reference the specified relation... as is, they remain "open".
*/
return
inv_destroy
(
lobjId
);
return
inv_destroy
(
lobjId
);
}
}
...
@@ -297,16 +329,23 @@ lo_import(text *filename)
...
@@ -297,16 +329,23 @@ lo_import(text *filename)
File
fd
;
File
fd
;
int
nbytes
,
int
nbytes
,
tmp
;
tmp
;
char
buf
[
BUFSIZE
];
char
buf
[
BUFSIZE
];
char
fnamebuf
[
FNAME_BUFSIZE
];
char
fnamebuf
[
FNAME_BUFSIZE
];
LargeObjectDesc
*
lobj
;
LargeObjectDesc
*
lobj
;
Oid
lobjOid
;
Oid
lobjOid
;
if
(
!
superuser
())
elog
(
ERROR
,
"You must have Postgres superuser privilege to use "
"server-side lo_import().
\n\t
Anyone can use the "
"client-side lo_import() provided by libpq."
);
/*
/*
* open the file to be read in
* open the file to be read in
*/
*/
StrNCpy
(
fnamebuf
,
VARDATA
(
filename
),
VARSIZE
(
filename
)
-
VARHDRSZ
+
1
);
nbytes
=
VARSIZE
(
filename
)
-
VARHDRSZ
+
1
;
if
(
nbytes
>
FNAME_BUFSIZE
)
nbytes
=
FNAME_BUFSIZE
;
StrNCpy
(
fnamebuf
,
VARDATA
(
filename
),
nbytes
);
#ifndef __CYGWIN32__
#ifndef __CYGWIN32__
fd
=
PathNameOpenFile
(
fnamebuf
,
O_RDONLY
,
0666
);
fd
=
PathNameOpenFile
(
fnamebuf
,
O_RDONLY
,
0666
);
#else
#else
...
@@ -314,7 +353,7 @@ lo_import(text *filename)
...
@@ -314,7 +353,7 @@ lo_import(text *filename)
#endif
#endif
if
(
fd
<
0
)
if
(
fd
<
0
)
{
/* error */
{
/* error */
elog
(
ERROR
,
"
be_
lo_import: can't open unix file
\"
%s
\"
\n
"
,
elog
(
ERROR
,
"lo_import: can't open unix file
\"
%s
\"
: %m
"
,
fnamebuf
);
fnamebuf
);
}
}
...
@@ -341,11 +380,9 @@ lo_import(text *filename)
...
@@ -341,11 +380,9 @@ lo_import(text *filename)
{
{
tmp
=
inv_write
(
lobj
,
buf
,
nbytes
);
tmp
=
inv_write
(
lobj
,
buf
,
nbytes
);
if
(
tmp
<
nbytes
)
if
(
tmp
<
nbytes
)
{
elog
(
ERROR
,
"lo_import: error while reading
\"
%s
\"
"
,
elog
(
ERROR
,
"lo_import: error while reading
\"
%s
\"
"
,
fnamebuf
);
fnamebuf
);
}
}
}
FileClose
(
fd
);
FileClose
(
fd
);
inv_close
(
lobj
);
inv_close
(
lobj
);
...
@@ -363,12 +400,16 @@ lo_export(Oid lobjId, text *filename)
...
@@ -363,12 +400,16 @@ lo_export(Oid lobjId, text *filename)
File
fd
;
File
fd
;
int
nbytes
,
int
nbytes
,
tmp
;
tmp
;
char
buf
[
BUFSIZE
];
char
buf
[
BUFSIZE
];
char
fnamebuf
[
FNAME_BUFSIZE
];
char
fnamebuf
[
FNAME_BUFSIZE
];
LargeObjectDesc
*
lobj
;
LargeObjectDesc
*
lobj
;
mode_t
oumask
;
mode_t
oumask
;
if
(
!
superuser
())
elog
(
ERROR
,
"You must have Postgres superuser privilege to use "
"server-side lo_export().
\n\t
Anyone can use the "
"client-side lo_export() provided by libpq."
);
/*
/*
* open the inversion "object"
* open the inversion "object"
*/
*/
...
@@ -378,9 +419,16 @@ lo_export(Oid lobjId, text *filename)
...
@@ -378,9 +419,16 @@ lo_export(Oid lobjId, text *filename)
/*
/*
* open the file to be written to
* open the file to be written to
*
* Note: we reduce backend's normal 077 umask to the slightly
* friendlier 022. This code used to drop it all the way to 0,
* but creating world-writable export files doesn't seem wise.
*/
*/
StrNCpy
(
fnamebuf
,
VARDATA
(
filename
),
VARSIZE
(
filename
)
-
VARHDRSZ
+
1
);
nbytes
=
VARSIZE
(
filename
)
-
VARHDRSZ
+
1
;
oumask
=
umask
((
mode_t
)
0
);
if
(
nbytes
>
FNAME_BUFSIZE
)
nbytes
=
FNAME_BUFSIZE
;
StrNCpy
(
fnamebuf
,
VARDATA
(
filename
),
nbytes
);
oumask
=
umask
((
mode_t
)
0022
);
#ifndef __CYGWIN32__
#ifndef __CYGWIN32__
fd
=
PathNameOpenFile
(
fnamebuf
,
O_CREAT
|
O_WRONLY
|
O_TRUNC
,
0666
);
fd
=
PathNameOpenFile
(
fnamebuf
,
O_CREAT
|
O_WRONLY
|
O_TRUNC
,
0666
);
#else
#else
...
@@ -389,7 +437,7 @@ lo_export(Oid lobjId, text *filename)
...
@@ -389,7 +437,7 @@ lo_export(Oid lobjId, text *filename)
umask
(
oumask
);
umask
(
oumask
);
if
(
fd
<
0
)
if
(
fd
<
0
)
{
/* error */
{
/* error */
elog
(
ERROR
,
"lo_export: can't open unix file
\"
%s
\"
"
,
elog
(
ERROR
,
"lo_export: can't open unix file
\"
%s
\"
: %m
"
,
fnamebuf
);
fnamebuf
);
}
}
...
@@ -400,11 +448,9 @@ lo_export(Oid lobjId, text *filename)
...
@@ -400,11 +448,9 @@ lo_export(Oid lobjId, text *filename)
{
{
tmp
=
FileWrite
(
fd
,
buf
,
nbytes
);
tmp
=
FileWrite
(
fd
,
buf
,
nbytes
);
if
(
tmp
<
nbytes
)
if
(
tmp
<
nbytes
)
{
elog
(
ERROR
,
"lo_export: error while writing
\"
%s
\"
"
,
elog
(
ERROR
,
"lo_export: error while writing
\"
%s
\"
"
,
fnamebuf
);
fnamebuf
);
}
}
}
inv_close
(
lobj
);
inv_close
(
lobj
);
FileClose
(
fd
);
FileClose
(
fd
);
...
@@ -417,24 +463,34 @@ lo_export(Oid lobjId, text *filename)
...
@@ -417,24 +463,34 @@ lo_export(Oid lobjId, text *filename)
* prepares large objects for transaction commit [PA, 7/17/98]
* prepares large objects for transaction commit [PA, 7/17/98]
*/
*/
void
void
_
lo_commit
(
void
)
lo_commit
(
bool
isCommit
)
{
{
int
i
;
int
i
;
MemoryContext
currentContext
;
MemoryContext
currentContext
;
if
(
fscxt
==
NULL
)
if
(
fscxt
==
NULL
)
return
;
return
;
/* no LO operations in this xact */
currentContext
=
MemoryContextSwitchTo
((
MemoryContext
)
fscxt
);
currentContext
=
MemoryContextSwitchTo
((
MemoryContext
)
fscxt
);
/* Clean out still-open index scans (not necessary if aborting)
* and clear cookies array so that LO fds are no longer good.
*/
for
(
i
=
0
;
i
<
MAX_LOBJ_FDS
;
i
++
)
for
(
i
=
0
;
i
<
MAX_LOBJ_FDS
;
i
++
)
{
{
if
(
cookies
[
i
]
!=
NULL
)
if
(
cookies
[
i
]
!=
NULL
)
{
if
(
isCommit
)
inv_cleanindex
(
cookies
[
i
]);
inv_cleanindex
(
cookies
[
i
]);
cookies
[
i
]
=
NULL
;
}
}
}
MemoryContextSwitchTo
(
currentContext
);
MemoryContextSwitchTo
(
currentContext
);
/* Release the LO memory context to prevent permanent memory leaks. */
GlobalMemoryDestroy
(
fscxt
);
fscxt
=
NULL
;
}
}
...
...
...
...
This diff is collapsed.
Click to expand it.
src/include/libpq/be-fsstubs.h
+
2
−
2
View file @
2a44383a
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
*
*
* Copyright (c) 1994, Regents of the University of California
* Copyright (c) 1994, Regents of the University of California
*
*
* $Id: be-fsstubs.h,v 1.
8
1999/0
2/13 23:21:34 momjian
Exp $
* $Id: be-fsstubs.h,v 1.
9
1999/0
5/31 22:53:58 tgl
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -40,6 +40,6 @@ extern int lowrite(int fd, struct varlena * wbuf);
...
@@ -40,6 +40,6 @@ extern int lowrite(int fd, struct varlena * wbuf);
/*
/*
* Added for buffer leak prevention [ Pascal Andr <andre@via.ecp.fr> ]
* Added for buffer leak prevention [ Pascal Andr <andre@via.ecp.fr> ]
*/
*/
extern
void
_
lo_commit
(
void
);
extern
void
lo_commit
(
bool
isCommit
);
#endif
/* BE_FSSTUBS_H */
#endif
/* BE_FSSTUBS_H */
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment