3287{
3289
3290 /* Backup blocks are not used in dbase records */
3292
3294 {
3297 char *src_path;
3298 char *dst_path;
3299 char *parent_path;
3301
3304
3305 /*
3306 * Our theory for replaying a CREATE is to forcibly drop the target
3307 * subdirectory if present, then re-copy the source data. This may be
3308 * more work than needed, but it is simple to implement.
3309 */
3310 if (
stat(dst_path, &st) == 0 &&
S_ISDIR(st.st_mode))
3311 {
3312 if (!
rmtree(dst_path,
true))
3313 /* If this failed, copydir() below is going to error. */
3315 (
errmsg(
"some useless files may be left behind in old database directory \"%s\"",
3316 dst_path)));
3317 }
3318
3319 /*
3320 * If the parent of the target path doesn't exist, create it now. This
3321 * enables us to create the target underneath later.
3322 */
3323 parent_path =
pstrdup(dst_path);
3325 if (
stat(parent_path, &st) < 0)
3326 {
3327 if (errno != ENOENT)
3329 errmsg(
"could not stat directory \"%s\": %m",
3330 dst_path));
3331
3332 /* create the parent directory if needed and valid */
3334 }
3336
3337 /*
3338 * There's a case where the copy source directory is missing for the
3339 * same reason above. Create the empty source directory so that
3340 * copydir below doesn't fail. The directory will be dropped soon by
3341 * recovery.
3342 */
3343 if (
stat(src_path, &st) < 0 && errno == ENOENT)
3345
3346 /*
3347 * Force dirty buffers out to disk, to ensure source database is
3348 * up-to-date for the copy.
3349 */
3351
3352 /* Close all smgr fds in all backends. */
3354
3355 /*
3356 * Copy this subdirectory to the new location
3357 *
3358 * We don't need to copy subdirectories
3359 */
3360 copydir(src_path, dst_path,
false);
3361
3364 }
3366 {
3369 char *dbpath;
3370 char *parent_path;
3371
3373
3374 /* create the parent directory if needed and valid */
3375 parent_path =
pstrdup(dbpath);
3378
3379 /* Create the database directory with the version file. */
3381 true);
3383 }
3385 {
3387 char *dst_path;
3389
3391 {
3392 /*
3393 * Lock database while we resolve conflicts to ensure that
3394 * InitPostgres() cannot fully re-execute concurrently. This
3395 * avoids backends re-connecting automatically to same database,
3396 * which can happen in some cases.
3397 *
3398 * This will lock out walsenders trying to connect to db-specific
3399 * slots for logical decoding too, so it's safe for us to drop
3400 * slots.
3401 */
3404 }
3405
3406 /* Drop any database-specific replication slots */
3408
3409 /* Drop pages for this database that are in the shared buffer cache */
3411
3412 /* Also, clean out any fsync requests that might be pending in md.c */
3414
3415 /* Clean out the xlog relcache too */
3417
3418 /* Close all smgr fds in all backends. */
3420
3422 {
3424
3425 /* And remove the physical files */
3426 if (!
rmtree(dst_path,
true))
3428 (
errmsg(
"some useless files may be left behind in old database directory \"%s\"",
3429 dst_path)));
3431 }
3432
3434 {
3435 /*
3436 * Release locks prior to commit. XXX There is a race condition
3437 * here that may allow backends to reconnect, but the window for
3438 * this is small because the gap between here and commit is mostly
3439 * fairly small and it is unlikely that people will be dropping
3440 * databases that we are trying to connect to anyway.
3441 */
3443 }
3444 }
3445 else
3446 elog(
PANIC,
"dbase_redo: unknown op code %u", info);
3447}
void DropDatabaseBuffers(Oid dbid)
void FlushDatabaseBuffers(Oid dbid)
void copydir(const char *fromdir, const char *todir, bool recurse)
static void CreateDirAndVersionFile(char *dbpath, Oid dbid, Oid tsid, bool isRedo)
static void recovery_create_dbdir(char *path, bool only_tblspc)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
Assert(PointerIsAligned(start, uint64))
void UnlockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
void LockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
#define AccessExclusiveLock
char * pstrdup(const char *in)
void pfree(void *pointer)
void ForgetDatabaseSyncRequests(Oid dbid)
void get_parent_directory(char *path)
void WaitForProcSignalBarrier(uint64 generation)
uint64 EmitProcSignalBarrier(ProcSignalBarrierType type)
@ PROCSIGNAL_BARRIER_SMGRRELEASE
char * GetDatabasePath(Oid dbOid, Oid spcOid)
bool rmtree(const char *path, bool rmtopdir)
void ReplicationSlotsDropDBSlots(Oid dboid)
void ResolveRecoveryConflictWithDatabase(Oid dbid)
#define XLogRecHasAnyBlockRefs(decoder)
void XLogDropDatabase(Oid dbid)