Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita904181

Browse files
committed
Another go-round on making GetRawDatabaseInfo behave as well as it can,
given the fundamental restriction of not looking at transaction commitdata in pg_log. Use code that is actually based on tqual.c rather thanad-hoc tests. Also write the tuple fetch loop using standard accessmacros rather than ad-hoc code.
1 parent8a0c9b1 commita904181

File tree

1 file changed

+67
-34
lines changed

1 file changed

+67
-34
lines changed

‎src/backend/utils/misc/database.c

Lines changed: 67 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,12 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/misc/Attic/database.c,v 1.41 2000/11/1418:37:45 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/misc/Attic/database.c,v 1.42 2001/01/1422:21:05 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
1515
#include"postgres.h"
1616

17-
#include<errno.h>
1817
#include<fcntl.h>
1918
#include<stdlib.h>
2019
#include<string.h>
@@ -28,6 +27,9 @@
2827
#include"utils/syscache.h"
2928

3029

30+
staticboolPhonyHeapTupleSatisfiesNow(HeapTupleHeadertuple);
31+
32+
3133
/*
3234
* ExpandDatabasePath resolves a proposed database path (obtained from
3335
* pg_database.datpath) to a full absolute path for further consumption.
@@ -136,11 +138,9 @@ GetRawDatabaseInfo(const char *name, Oid *db_id, char *path)
136138
{
137139
intdbfd;
138140
intnbytes;
139-
intmax,
140-
i;
141+
intpathlen;
141142
HeapTupleDatatup;
142143
Pagepg;
143-
PageHeaderph;
144144
char*dbfname;
145145
Form_pg_databasetup_db;
146146

@@ -157,7 +157,7 @@ GetRawDatabaseInfo(const char *name, Oid *db_id, char *path)
157157
#endif
158158

159159
if ((dbfd=open(dbfname,O_RDONLY |PG_BINARY,0))<0)
160-
elog(FATAL,"cannot open %s: %s",dbfname,strerror(errno));
160+
elog(FATAL,"cannot open %s: %m",dbfname);
161161

162162
pfree(dbfname);
163163

@@ -179,38 +179,38 @@ GetRawDatabaseInfo(const char *name, Oid *db_id, char *path)
179179
* ----------------
180180
*/
181181
pg= (Page)palloc(BLCKSZ);
182-
ph= (PageHeader)pg;
183182

184183
while ((nbytes=read(dbfd,pg,BLCKSZ))==BLCKSZ)
185184
{
186-
max=PageGetMaxOffsetNumber(pg);
185+
OffsetNumbermax=PageGetMaxOffsetNumber(pg);
186+
OffsetNumberlineoff;
187187

188188
/* look at each tuple on the page */
189-
for (i=0;i<max;i++)
189+
for (lineoff=FirstOffsetNumber;lineoff <=max;lineoff++)
190190
{
191-
intoffset;
191+
ItemIdlpp=PageGetItemId(pg,lineoff);
192192

193193
/* if it's a freed tuple, ignore it */
194-
if (!(ph->pd_linp[i].lp_flags&LP_USED))
194+
if (!ItemIdIsUsed(lpp))
195195
continue;
196196

197197
/* get a pointer to the tuple itself */
198-
offset= (int)ph->pd_linp[i].lp_off;
199198
tup.t_datamcxt=NULL;
200-
tup.t_data= (HeapTupleHeader)(((char*)pg)+offset);
199+
tup.t_data= (HeapTupleHeader)PageGetItem(pg,lpp);
201200

202-
/*
203-
* if the tuple has been deleted (the database was destroyed),
204-
* skip this tuple. XXX warning, will robinson: violation of
205-
* transaction semantics happens right here. we should check
206-
* to be sure that the xact that deleted this tuple actually
207-
* committed. Only way to do that at init time is to paw over
208-
* the log relation by hand, too. Instead we take the
209-
* conservative assumption that if someone tried to delete it,
210-
* it's gone. The other side of the coin is that we might
211-
* accept a tuple that was stored and never committed.All in
212-
* all, this code is pretty shaky.We will cross-check our
213-
* result in ReverifyMyDatabase() in postinit.c.
201+
/*--------------------
202+
* Check to see if tuple is valid (committed).
203+
*
204+
* XXX warning, will robinson: violation of transaction semantics
205+
* happens right here. We cannot really determine if the tuple
206+
* is valid without checking transaction commit status, and the
207+
* only way to do that at init time is to paw over pg_log by hand,
208+
* too. Instead of checking, we assume that the inserting
209+
* transaction committed, and that any deleting transaction did
210+
* also, unless shown otherwise by on-row commit status bits.
211+
*
212+
* All in all, this code is pretty shaky. We will cross-check
213+
* our result in ReverifyMyDatabase() in postinit.c.
214214
*
215215
* NOTE: if a bogus tuple in pg_database prevents connection to a
216216
* valid database, a fix is to connect to another database and
@@ -220,12 +220,10 @@ GetRawDatabaseInfo(const char *name, Oid *db_id, char *path)
220220
* XXX wouldn't it be better to let new backends read the
221221
* database OID from a flat file, handled the same way we
222222
* handle the password relation?
223+
*--------------------
223224
*/
224-
if (tup.t_data->t_infomask&HEAP_XMIN_INVALID)
225-
continue;/* inserting xact known aborted */
226-
if (TransactionIdIsValid((TransactionId)tup.t_data->t_xmax)&&
227-
!(tup.t_data->t_infomask&HEAP_XMAX_INVALID))
228-
continue;/* deleting xact happened, not known aborted */
225+
if (!PhonyHeapTupleSatisfiesNow(tup.t_data))
226+
continue;
229227

230228
/*
231229
* Okay, see if this is the one we want.
@@ -236,9 +234,11 @@ GetRawDatabaseInfo(const char *name, Oid *db_id, char *path)
236234
{
237235
/* Found it; extract the OID and the database path. */
238236
*db_id=tup.t_data->t_oid;
239-
strncpy(path,VARDATA(&(tup_db->datpath)),
240-
(VARSIZE(&(tup_db->datpath))-VARHDRSZ));
241-
*(path+VARSIZE(&(tup_db->datpath))-VARHDRSZ)='\0';
237+
pathlen=VARSIZE(&(tup_db->datpath))-VARHDRSZ;
238+
if (pathlen >=MAXPGPATH)
239+
pathlen=MAXPGPATH-1;/* pure paranoia */
240+
strncpy(path,VARDATA(&(tup_db->datpath)),pathlen);
241+
path[pathlen]='\0';
242242
gotodone;
243243
}
244244
}
@@ -251,4 +251,37 @@ GetRawDatabaseInfo(const char *name, Oid *db_id, char *path)
251251
done:
252252
close(dbfd);
253253
pfree(pg);
254-
}/* GetRawDatabaseInfo() */
254+
}
255+
256+
/*
257+
* PhonyHeapTupleSatisfiesNow --- cut-down tuple time qual test
258+
*
259+
* This is a simplified version of HeapTupleSatisfiesNow() that does not
260+
* depend on having transaction commit info available. Any transaction
261+
* that touched the tuple is assumed committed unless later marked invalid.
262+
* (While we could think about more complex rules, this seems appropriate
263+
* for examining pg_database, since both CREATE DATABASE and DROP DATABASE
264+
* are non-roll-back-able.)
265+
*/
266+
staticbool
267+
PhonyHeapTupleSatisfiesNow(HeapTupleHeadertuple)
268+
{
269+
if (!(tuple->t_infomask&HEAP_XMIN_COMMITTED))
270+
{
271+
if (tuple->t_infomask&HEAP_XMIN_INVALID)
272+
return false;
273+
274+
if (tuple->t_infomask&HEAP_MOVED_OFF)
275+
return false;
276+
/* else assume committed */
277+
}
278+
279+
if (tuple->t_infomask&HEAP_XMAX_INVALID)/* xid invalid or aborted */
280+
return true;
281+
282+
/* assume xmax transaction committed */
283+
if (tuple->t_infomask&HEAP_MARKED_FOR_UPDATE)
284+
return true;
285+
286+
return false;
287+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp