Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit e6d8069

Browse files
committed
Make DROP DATABASE command generate less WAL records.
Previously DROP DATABASE generated as many XLOG_DBASE_DROP WAL records as the number of tablespaces that the database to drop uses. This caused the scans of shared_buffers as many times as the number of the tablespaces during recovery because WAL replay of one XLOG_DBASE_DROP record needs that full scan. This could make the recovery time longer especially when shared_buffers is large. This commit changes DROP DATABASE so that it generates only one XLOG_DBASE_DROP record, and registers the information of all the tablespaces into it. Then, WAL replay of XLOG_DBASE_DROP record needs full scan of shared_buffers only once, and which may improve the recovery performance. Author: Fujii Masao Reviewed-by: Kirk Jamison, Simon Riggs Discussion: https://postgr.es/m/CAHGQGwF8YwNH0ZaL+2wjZPkj+ji9UhC+Z4ScnG97WKtVY5L9iw@mail.gmail.com
1 parent 30840c9 commit e6d8069

File tree

3 files changed

+56
-23
lines changed

3 files changed

+56
-23
lines changed

src/backend/access/rmgrdesc/dbasedesc.c

+5-2
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,12 @@ dbase_desc(StringInfo buf, XLogReaderState *record)
3535
else if (info == XLOG_DBASE_DROP)
3636
{
3737
xl_dbase_drop_rec *xlrec = (xl_dbase_drop_rec *) rec;
38+
int i;
3839

39-
appendStringInfo(buf, "dir %u/%u",
40-
xlrec->tablespace_id, xlrec->db_id);
40+
appendStringInfo(buf, "dir");
41+
for (i = 0; i < xlrec->ntablespaces; i++)
42+
appendStringInfo(buf, " %u/%u",
43+
xlrec->tablespace_ids[i], xlrec->db_id);
4144
}
4245
}
4346

src/backend/commands/dbcommands.c

+48-19
Original file line numberDiff line numberDiff line change
@@ -1411,10 +1411,11 @@ movedb(const char *dbname, const char *tblspcname)
14111411
xl_dbase_drop_rec xlrec;
14121412

14131413
xlrec.db_id = db_id;
1414-
xlrec.tablespace_id = src_tblspcoid;
1414+
xlrec.ntablespaces = 1;
14151415

14161416
XLogBeginInsert();
14171417
XLogRegisterData((char *) &xlrec, sizeof(xl_dbase_drop_rec));
1418+
XLogRegisterData((char *) &src_tblspcoid, sizeof(Oid));
14181419

14191420
(void) XLogInsert(RM_DBASE_ID,
14201421
XLOG_DBASE_DROP | XLR_SPECIAL_REL_UPDATE);
@@ -1946,6 +1947,11 @@ remove_dbtablespaces(Oid db_id)
19461947
Relation rel;
19471948
TableScanDesc scan;
19481949
HeapTuple tuple;
1950+
List *ltblspc = NIL;
1951+
ListCell *cell;
1952+
int ntblspc;
1953+
int i;
1954+
Oid *tablespace_ids;
19491955

19501956
rel = table_open(TableSpaceRelationId, AccessShareLock);
19511957
scan = table_beginscan_catalog(rel, 0, NULL);
@@ -1974,23 +1980,41 @@ remove_dbtablespaces(Oid db_id)
19741980
(errmsg("some useless files may be left behind in old database directory \"%s\"",
19751981
dstpath)));
19761982

1977-
/* Record the filesystem change in XLOG */
1978-
{
1979-
xl_dbase_drop_rec xlrec;
1983+
ltblspc = lappend_oid(ltblspc, dsttablespace);
1984+
pfree(dstpath);
1985+
}
19801986

1981-
xlrec.db_id = db_id;
1982-
xlrec.tablespace_id = dsttablespace;
1987+
ntblspc = list_length(ltblspc);
1988+
if (ntblspc == 0)
1989+
{
1990+
table_endscan(scan);
1991+
table_close(rel, AccessShareLock);
1992+
return;
1993+
}
19831994

1984-
XLogBeginInsert();
1985-
XLogRegisterData((char *) &xlrec, sizeof(xl_dbase_drop_rec));
1995+
tablespace_ids = (Oid *) palloc(ntblspc * sizeof(Oid));
1996+
i = 0;
1997+
foreach(cell, ltblspc)
1998+
tablespace_ids[i++] = lfirst_oid(cell);
19861999

1987-
(void) XLogInsert(RM_DBASE_ID,
1988-
XLOG_DBASE_DROP | XLR_SPECIAL_REL_UPDATE);
1989-
}
2000+
/* Record the filesystem change in XLOG */
2001+
{
2002+
xl_dbase_drop_rec xlrec;
19902003

1991-
pfree(dstpath);
2004+
xlrec.db_id = db_id;
2005+
xlrec.ntablespaces = ntblspc;
2006+
2007+
XLogBeginInsert();
2008+
XLogRegisterData((char *) &xlrec, MinSizeOfDbaseDropRec);
2009+
XLogRegisterData((char *) tablespace_ids, ntblspc * sizeof(Oid));
2010+
2011+
(void) XLogInsert(RM_DBASE_ID,
2012+
XLOG_DBASE_DROP | XLR_SPECIAL_REL_UPDATE);
19922013
}
19932014

2015+
list_free(ltblspc);
2016+
pfree(tablespace_ids);
2017+
19942018
table_endscan(scan);
19952019
table_close(rel, AccessShareLock);
19962020
}
@@ -2197,8 +2221,7 @@ dbase_redo(XLogReaderState *record)
21972221
{
21982222
xl_dbase_drop_rec *xlrec = (xl_dbase_drop_rec *) XLogRecGetData(record);
21992223
char *dst_path;
2200-
2201-
dst_path = GetDatabasePath(xlrec->db_id, xlrec->tablespace_id);
2224+
int i;
22022225

22032226
if (InHotStandby)
22042227
{
@@ -2228,11 +2251,17 @@ dbase_redo(XLogReaderState *record)
22282251
/* Clean out the xlog relcache too */
22292252
XLogDropDatabase(xlrec->db_id);
22302253

2231-
/* And remove the physical files */
2232-
if (!rmtree(dst_path, true))
2233-
ereport(WARNING,
2234-
(errmsg("some useless files may be left behind in old database directory \"%s\"",
2235-
dst_path)));
2254+
for (i = 0; i < xlrec->ntablespaces; i++)
2255+
{
2256+
dst_path = GetDatabasePath(xlrec->db_id, xlrec->tablespace_ids[i]);
2257+
2258+
/* And remove the physical files */
2259+
if (!rmtree(dst_path, true))
2260+
ereport(WARNING,
2261+
(errmsg("some useless files may be left behind in old database directory \"%s\"",
2262+
dst_path)));
2263+
pfree(dst_path);
2264+
}
22362265

22372266
if (InHotStandby)
22382267
{

src/include/commands/dbcommands_xlog.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,11 @@ typedef struct xl_dbase_create_rec
3232

3333
typedef struct xl_dbase_drop_rec
3434
{
35-
/* Records dropping of a single subdirectory incl. contents */
3635
Oid db_id;
37-
Oid tablespace_id;
36+
int ntablespaces; /* number of tablespace IDs */
37+
Oid tablespace_ids[FLEXIBLE_ARRAY_MEMBER];
3838
} xl_dbase_drop_rec;
39+
#define MinSizeOfDbaseDropRec offsetof(xl_dbase_drop_rec, tablespace_ids)
3940

4041
extern void dbase_redo(XLogReaderState *rptr);
4142
extern void dbase_desc(StringInfo buf, XLogReaderState *rptr);

0 commit comments

Comments
 (0)