Thanks to visit codestin.com
Credit goes to github.com

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

Lines changed: 5 additions & 2 deletions
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

Lines changed: 48 additions & 19 deletions
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

Lines changed: 3 additions & 2 deletions
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)