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

Commitfd42262

Browse files
committed
Add code to apply some simple sanity checks to the header fields of a
page when it's read in, per pghackers discussion around 17-Feb. Add aGUC variable zero_damaged_pages that causes the response to be a WARNINGfollowed by zeroing the page, rather than the normal ERROR; this is perHiroshi's suggestion that there needs to be a way to get at the datain the rest of the table.
1 parentbb3c00e commitfd42262

File tree

8 files changed

+104
-73
lines changed

8 files changed

+104
-73
lines changed

‎doc/src/sgml/runtime.sgml

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.174 2003/03/25 16:15:38 petere Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.175 2003/03/28 20:17:13 tgl Exp $
33
-->
44

55
<Chapter Id="runtime">
@@ -1599,7 +1599,7 @@ dynamic_library_path = '/usr/local/lib/postgresql:/home/my_project/lib:$libdir'
15991599

16001600
<para>
16011601
It should be noted that the performance penalty of having
1602-
<varname>fsync</> on considerably less in
1602+
<varname>fsync</> onisconsiderably less in
16031603
<productname>PostgreSQL</> version 7.1 and later. If you
16041604
previously suppressed <function>fsync</> for performance
16051605
reasons, you may wish to reconsider your choice.
@@ -2174,6 +2174,24 @@ dynamic_library_path = '/usr/local/lib/postgresql:/home/my_project/lib:$libdir'
21742174
</listitem>
21752175
</varlistentry>
21762176

2177+
<varlistentry>
2178+
<term><varname>ZERO_DAMAGED_PAGES</varname> (<type>boolean</type>)</term>
2179+
<listitem>
2180+
<para>
2181+
Detection of a damaged page header normally causes
2182+
<productname>PostgreSQL</> to report an error, aborting the current
2183+
transaction. Setting <varname>zero_damaged_pages</> to true causes
2184+
the system to instead report a warning, zero out the damaged page,
2185+
and continue processing. This behavior <emphasis>will lose data</>,
2186+
namely all the rows on the damaged page. But it allows you to get
2187+
past the error and retrieve rows from any undamaged pages that may
2188+
be present in the table. So it is useful for recovering data if
2189+
corruption has occurred due to hardware or software error. The
2190+
default setting is off, and it can only be changed by a superuser.
2191+
</para>
2192+
</listitem>
2193+
</varlistentry>
2194+
21772195
</variablelist>
21782196
</sect2>
21792197

‎src/backend/storage/buffer/bufmgr.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.134 2003/02/13 05:35:11 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.135 2003/03/28 20:17:13 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -49,6 +49,7 @@
4949
#include"miscadmin.h"
5050
#include"storage/buf_internals.h"
5151
#include"storage/bufmgr.h"
52+
#include"storage/bufpage.h"
5253
#include"storage/proc.h"
5354
#include"storage/smgr.h"
5455
#include"utils/relcache.h"
@@ -59,6 +60,10 @@
5960
(*((XLogRecPtr*) MAKE_PTR((bufHdr)->data)))
6061

6162

63+
/* GUC variable */
64+
boolzero_damaged_pages= false;
65+
66+
6267
staticvoidWaitIO(BufferDesc*buf);
6368
staticvoidStartBufferIO(BufferDesc*buf,boolforInput);
6469
staticvoidTerminateBufferIO(BufferDesc*buf);
@@ -217,6 +222,20 @@ ReadBufferInternal(Relation reln, BlockNumber blockNum,
217222
{
218223
status=smgrread(DEFAULT_SMGR,reln,blockNum,
219224
(char*)MAKE_PTR(bufHdr->data));
225+
/* check for garbage data */
226+
if (status==SM_SUCCESS&&
227+
!PageHeaderIsValid((PageHeader)MAKE_PTR(bufHdr->data)))
228+
{
229+
if (zero_damaged_pages)
230+
{
231+
elog(WARNING,"Invalid page header in block %u of %s; zeroing out page",
232+
blockNum,RelationGetRelationName(reln));
233+
MemSet((char*)MAKE_PTR(bufHdr->data),0,BLCKSZ);
234+
}
235+
else
236+
elog(ERROR,"Invalid page header in block %u of %s",
237+
blockNum,RelationGetRelationName(reln));
238+
}
220239
}
221240

222241
if (isLocalBuf)

‎src/backend/storage/page/bufpage.c

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,12 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/storage/page/bufpage.c,v 1.51 2003/01/11 05:01:03 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/storage/page/bufpage.c,v 1.52 2003/03/28 20:17:13 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
1515
#include"postgres.h"
1616

17-
#include<sys/file.h>
18-
1917
#include"storage/bufpage.h"
2018

2119

@@ -48,6 +46,51 @@ PageInit(Page page, Size pageSize, Size specialSize)
4846
}
4947

5048

49+
/*
50+
* PageHeaderIsValid
51+
*Check that the header fields of a page appear valid.
52+
*
53+
* This is called when a page has just been read in from disk. The idea is
54+
* to cheaply detect trashed pages before we go nuts following bogus item
55+
* pointers, testing invalid transaction identifiers, etc.
56+
*
57+
* It turns out to be necessary to allow zeroed pages here too. Even though
58+
* this routine is *not* called when deliberately adding a page to a relation,
59+
* there are scenarios in which a zeroed page might be found in a table.
60+
* (Example: a backend extends a relation, then crashes before it can write
61+
* any WAL entry about the new page. The kernel will already have the
62+
* zeroed page in the file, and it will stay that way after restart.) So we
63+
* allow zeroed pages here, and are careful that the page access macros
64+
* treat such a page as empty and without free space. Eventually, VACUUM
65+
* will clean up such a page and make it usable.
66+
*/
67+
bool
68+
PageHeaderIsValid(PageHeaderpage)
69+
{
70+
char*pagebytes;
71+
inti;
72+
73+
/* Check normal case */
74+
if (PageGetPageSize(page)==BLCKSZ&&
75+
PageGetPageLayoutVersion(page)==PG_PAGE_LAYOUT_VERSION&&
76+
page->pd_lower >=SizeOfPageHeaderData&&
77+
page->pd_lower <=page->pd_upper&&
78+
page->pd_upper <=page->pd_special&&
79+
page->pd_special <=BLCKSZ&&
80+
page->pd_special==MAXALIGN(page->pd_special))
81+
return true;
82+
83+
/* Check all-zeroes case */
84+
pagebytes= (char*)page;
85+
for (i=0;i<BLCKSZ;i++)
86+
{
87+
if (pagebytes[i]!=0)
88+
return false;
89+
}
90+
return true;
91+
}
92+
93+
5194
/* ----------------
5295
*PageAddItem
5396
*

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* command, configuration file, and command line options.
66
* See src/backend/utils/misc/README for more information.
77
*
8-
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.117 2003/03/20 04:51:44 momjian Exp $
8+
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.118 2003/03/28 20:17:13 tgl Exp $
99
*
1010
* Copyright 2000 by PostgreSQL Global Development Group
1111
* Written by Peter Eisentraut <peter_e@gmx.net>.
@@ -357,6 +357,10 @@ static struct config_bool
357357
{"fsync",PGC_SIGHUP},&enableFsync,
358358
true,NULL,NULL
359359
},
360+
{
361+
{"zero_damaged_pages",PGC_SUSET},&zero_damaged_pages,
362+
false,NULL,NULL
363+
},
360364
{
361365
{"silent_mode",PGC_POSTMASTER},&SilentMode,
362366
false,NULL,NULL

‎src/backend/utils/misc/postgresql.conf.sample

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,6 @@
213213
#sql_inheritance = true
214214
#transform_null_equals = false
215215
#statement_timeout = 0# 0 is disabled, in milliseconds
216+
#zero_damaged_pages = false # set this true only for disaster recovery
216217
#db_user_namespace = false
217218
#preload_libraries = ''
218-

‎src/include/storage/bufmgr.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: bufmgr.h,v 1.66 2002/10/22 20:00:48 petere Exp $
10+
* $Id: bufmgr.h,v 1.67 2003/03/28 20:17:13 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -25,6 +25,9 @@ typedef void *Block;
2525
/* in globals.c ... this duplicates miscadmin.h */
2626
externDLLIMPORTintNBuffers;
2727

28+
/* in bufmgr.c */
29+
externboolzero_damaged_pages;
30+
2831
/* in buf_init.c */
2932
externDLLIMPORTBlock*BufferBlockPointers;
3033
externlong*PrivateRefCount;

‎src/include/storage/bufpage.h

Lines changed: 8 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: bufpage.h,v 1.53 2002/09/04 20:31:45 momjian Exp $
10+
* $Id: bufpage.h,v 1.54 2003/03/28 20:17:13 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -19,7 +19,6 @@
1919
#include"storage/item.h"
2020
#include"storage/itemid.h"
2121
#include"storage/off.h"
22-
#include"storage/page.h"
2322
#include"access/xlog.h"
2423

2524
/*
@@ -74,11 +73,7 @@
7473
* fields.
7574
*/
7675

77-
/*
78-
* PageIsValid
79-
*True iff page is valid.
80-
*/
81-
#definePageIsValid(page) PointerIsValid(page)
76+
typedefPointerPage;
8277

8378

8479
/*
@@ -141,22 +136,12 @@ typedef PageHeaderData *PageHeader;
141136
*page support macros
142137
* ----------------------------------------------------------------
143138
*/
144-
/*
145-
* PageIsValid -- This is defined in page.h.
146-
*/
147139

148140
/*
149-
* PageIsUsed
150-
*True iff the page size is used.
151-
*
152-
* Note:
153-
*Assumes page is valid.
141+
* PageIsValid
142+
*True iff page is valid.
154143
*/
155-
#definePageIsUsed(page) \
156-
( \
157-
AssertMacro(PageIsValid(page)), \
158-
((bool) (((PageHeader) (page))->pd_lower != 0)) \
159-
)
144+
#definePageIsValid(page) PointerIsValid(page)
160145

161146
/*
162147
* line pointer does not count as part of header
@@ -172,9 +157,8 @@ typedef PageHeaderData *PageHeader;
172157

173158
/*
174159
* PageIsNew
175-
*returns true iff pageis not initialized (by PageInit)
160+
*returns true iff pagehas not been initialized (by PageInit)
176161
*/
177-
178162
#definePageIsNew(page) (((PageHeader) (page))->pd_upper == 0)
179163

180164
/*
@@ -199,12 +183,6 @@ typedef PageHeaderData *PageHeader;
199183
/*
200184
* PageSizeIsValid
201185
*True iff the page size is valid.
202-
*
203-
* XXX currently all page sizes are "valid" but we only actually
204-
* use BLCKSZ.
205-
*
206-
* 01/06/98 Now does something useful.darrenk
207-
*
208186
*/
209187
#definePageSizeIsValid(pageSize) ((pageSize) == BLCKSZ)
210188

@@ -214,18 +192,14 @@ typedef PageHeaderData *PageHeader;
214192
*
215193
* this can only be called on a formatted page (unlike
216194
* BufferGetPageSize, which can be called on an unformatted page).
217-
* however, it can be called on a pagefor which there is no buffer.
195+
* however, it can be called on a pagethat is not stored in a buffer.
218196
*/
219197
#definePageGetPageSize(page) \
220198
((Size) (((PageHeader) (page))->pd_pagesize_version & (uint16) 0xFF00))
221199

222200
/*
223201
* PageGetPageLayoutVersion
224202
*Returns the page layout version of a page.
225-
*
226-
* this can only be called on a formatted page (unlike
227-
* BufferGetPageSize, which can be called on an unformatted page).
228-
* however, it can be called on a page for which there is no buffer.
229203
*/
230204
#definePageGetPageLayoutVersion(page) \
231205
(((PageHeader) (page))->pd_pagesize_version & 0x00FF)
@@ -251,19 +225,13 @@ typedef PageHeaderData *PageHeader;
251225
/*
252226
* PageGetSpecialSize
253227
*Returns size of special space on a page.
254-
*
255-
* Note:
256-
*Assumes page is locked.
257228
*/
258229
#definePageGetSpecialSize(page) \
259230
((uint16) (PageGetPageSize(page) - ((PageHeader)(page))->pd_special))
260231

261232
/*
262233
* PageGetSpecialPointer
263234
*Returns pointer to special space on a page.
264-
*
265-
* Note:
266-
*Assumes page is locked.
267235
*/
268236
#definePageGetSpecialPointer(page) \
269237
( \
@@ -339,6 +307,7 @@ typedef PageHeaderData *PageHeader;
339307
*/
340308

341309
externvoidPageInit(Pagepage,SizepageSize,SizespecialSize);
310+
externboolPageHeaderIsValid(PageHeaderpage);
342311
externOffsetNumberPageAddItem(Pagepage,Itemitem,Sizesize,
343312
OffsetNumberoffsetNumber,ItemIdFlagsflags);
344313
externPagePageGetTempPage(Pagepage,SizespecialSize);

‎src/include/storage/page.h

Lines changed: 0 additions & 25 deletions
This file was deleted.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp