diff --git a/src/backend/access/rmgrdesc/dbasedesc.c b/src/backend/access/rmgrdesc/dbasedesc.c index c7d60ce10d..d08c575872 100644 *** a/src/backend/access/rmgrdesc/dbasedesc.c --- b/src/backend/access/rmgrdesc/dbasedesc.c *************** *** 35,43 **** dbase_desc(StringInfo buf, XLogReaderState *record) else if (info == XLOG_DBASE_DROP) { xl_dbase_drop_rec *xlrec = (xl_dbase_drop_rec *) rec; ! appendStringInfo(buf, "dir %u/%u", ! xlrec->tablespace_id, xlrec->db_id); } } --- 35,46 ---- else if (info == XLOG_DBASE_DROP) { xl_dbase_drop_rec *xlrec = (xl_dbase_drop_rec *) rec; + int i; ! appendStringInfo(buf, "dir"); ! for (i = 0; i < xlrec->ntablespaces; i++) ! appendStringInfo(buf, " %u/%u", ! xlrec->tablespace_ids[i], xlrec->db_id); } } diff --git a/src/backend/commands/dbcommands.cindex 01d66212e9..643a539efe 100644 *** a/src/backend/commands/dbcommands.c --- b/src/backend/commands/dbcommands.c *************** *** 1404,1413 **** movedb(const char *dbname, const char *tblspcname) xl_dbase_drop_rec xlrec; xlrec.db_id = db_id; ! xlrec.tablespace_id = src_tblspcoid; XLogBeginInsert(); XLogRegisterData((char *) &xlrec, sizeof(xl_dbase_drop_rec)); (void) XLogInsert(RM_DBASE_ID, XLOG_DBASE_DROP | XLR_SPECIAL_REL_UPDATE); --- 1404,1414 ---- xl_dbase_drop_rec xlrec; xlrec.db_id = db_id; ! xlrec.ntablespaces = 1; XLogBeginInsert(); XLogRegisterData((char *) &xlrec, sizeof(xl_dbase_drop_rec)); + XLogRegisterData((char *) &src_tblspcoid, sizeof(Oid)); (void) XLogInsert(RM_DBASE_ID, XLOG_DBASE_DROP | XLR_SPECIAL_REL_UPDATE); *************** *** 1915,1920 **** remove_dbtablespaces(Oid db_id) --- 1916,1926 ---- Relation rel; TableScanDesc scan; HeapTuple tuple; + List *ltblspc = NIL; + ListCell *cell; + int ntblspc; + int i; + Oid *tablespace_ids; rel = table_open(TableSpaceRelationId, AccessShareLock); scan = table_beginscan_catalog(rel, 0, NULL); *************** *** 1943,1965 **** remove_dbtablespaces(Oid db_id) (errmsg("some useless files may be left behind in old database directory \"%s\"", dstpath))); ! /* Record the filesystem change in XLOG */ ! { ! xl_dbase_drop_rec xlrec; ! xlrec.db_id = db_id; ! xlrec.tablespace_id = dsttablespace; ! XLogBeginInsert(); ! XLogRegisterData((char *) &xlrec, sizeof(xl_dbase_drop_rec)); ! (void) XLogInsert(RM_DBASE_ID, ! XLOG_DBASE_DROP | XLR_SPECIAL_REL_UPDATE); ! } ! pfree(dstpath); } table_endscan(scan); table_close(rel, AccessShareLock); } --- 1949,1989 ---- (errmsg("some useless files may be left behind in old database directory \"%s\"", dstpath))); ! ltblspc = lappend_oid(ltblspc, dsttablespace); ! pfree(dstpath); ! } ! ntblspc = list_length(ltblspc); ! if (ntblspc == 0) ! { ! table_endscan(scan); ! table_close(rel, AccessShareLock); ! return; ! } ! tablespace_ids = (Oid *) palloc(ntblspc * sizeof(Oid)); ! i = 0; ! foreach(cell, ltblspc) ! tablespace_ids[i++] = lfirst_oid(cell); ! /* Record the filesystem change in XLOG */ ! { ! xl_dbase_drop_rec xlrec; ! xlrec.db_id = db_id; ! xlrec.ntablespaces = ntblspc; ! ! XLogBeginInsert(); ! XLogRegisterData((char *) &xlrec, MinSizeOfDbaseDropRec); ! XLogRegisterData((char *) tablespace_ids, ntblspc * sizeof(Oid)); ! ! (void) XLogInsert(RM_DBASE_ID, ! XLOG_DBASE_DROP | XLR_SPECIAL_REL_UPDATE); } + list_free(ltblspc); + pfree(tablespace_ids); + table_endscan(scan); table_close(rel, AccessShareLock); } *************** *** 2166,2173 **** dbase_redo(XLogReaderState *record) { xl_dbase_drop_rec *xlrec = (xl_dbase_drop_rec *) XLogRecGetData(record); char *dst_path; ! ! dst_path = GetDatabasePath(xlrec->db_id, xlrec->tablespace_id); if (InHotStandby) { --- 2190,2196 ---- { xl_dbase_drop_rec *xlrec = (xl_dbase_drop_rec *) XLogRecGetData(record); char *dst_path; ! int i; if (InHotStandby) { *************** *** 2197,2207 **** dbase_redo(XLogReaderState *record) /* Clean out the xlog relcache too */ XLogDropDatabase(xlrec->db_id); ! /* And remove the physical files */ ! if (!rmtree(dst_path, true)) ! ereport(WARNING, ! (errmsg("some useless files may be left behind in old database directory \"%s\"", ! dst_path))); if (InHotStandby) { --- 2220,2236 ---- /* Clean out the xlog relcache too */ XLogDropDatabase(xlrec->db_id); ! for (i = 0; i < xlrec->ntablespaces; i++) ! { ! dst_path = GetDatabasePath(xlrec->db_id, xlrec->tablespace_ids[i]); ! ! /* And remove the physical files */ ! if (!rmtree(dst_path, true)) ! ereport(WARNING, ! (errmsg("some useless files may be left behind in old database directory \"%s\"", ! dst_path))); ! pfree(dst_path); ! } if (InHotStandby) { diff --git a/src/include/commands/dbcommindex 46be8a615a..4e8a442c89 100644 *** a/src/include/commands/dbcommands_xlog.h --- b/src/include/commands/dbcommands_xlog.h *************** *** 32,41 **** typedef struct xl_dbase_create_rec typedef struct xl_dbase_drop_rec { - /* Records dropping of a single subdirectory incl. contents */ Oid db_id; ! Oid tablespace_id; } xl_dbase_drop_rec; extern void dbase_redo(XLogReaderState *rptr); extern void dbase_desc(StringInfo buf, XLogReaderState *rptr); --- 32,42 ---- typedef struct xl_dbase_drop_rec { Oid db_id; ! int ntablespaces; /* number of tablespace IDs */ ! Oid tablespace_ids[FLEXIBLE_ARRAY_MEMBER]; } xl_dbase_drop_rec; + #define MinSizeOfDbaseDropRec offsetof(xl_dbase_drop_rec, tablespace_ids) extern void dbase_redo(XLogReaderState *rptr); extern void dbase_desc(StringInfo buf, XLogReaderState *rptr);