Skip to content

Commit fcfebd0

Browse files
committed
With this change we also move the wal to new location if --wal-dir location is changed
1 parent 56fa48d commit fcfebd0

File tree

1 file changed

+79
-0
lines changed

1 file changed

+79
-0
lines changed

internal/postgresql/postgresql.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,10 +299,89 @@ func (p *Manager) StartTmpMerged() error {
299299
return p.start("-c", fmt.Sprintf("config_file=%s", tmpPostgresConfPath))
300300
}
301301

302+
func (p *Manager) moveWal() (err error) {
303+
var curPath string
304+
var desiredPath string
305+
var tmpPath string
306+
symlinkPath := filepath.Join(p.dataDir, "pg_wal")
307+
if curPath, err = filepath.EvalSymlinks(symlinkPath); err != nil {
308+
log.Errorf("could not evaluate symlink %s: %e", symlinkPath, err)
309+
return err
310+
}
311+
if p.walDir == "" {
312+
desiredPath = symlinkPath
313+
tmpPath = filepath.Join(p.dataDir, "pg_wal_new")
314+
} else {
315+
desiredPath = p.walDir
316+
tmpPath = p.walDir
317+
}
318+
if curPath == desiredPath {
319+
return nil
320+
}
321+
if p.walDir == "" {
322+
log.Infof("moving wal from %s to %s first and then to %s", curPath, tmpPath, desiredPath)
323+
} else {
324+
log.Infof("moving wal from PGDATA/pg_wal (%s) to new location %s", curPath, desiredPath)
325+
}
326+
// We use tmpPath here first and (if needed) mv tmpPath to desiredPath when all is copied.
327+
// This allows stolon-keeper to re-read symlink dest and continue should stolon-keeper be restarted while copying.
328+
log.Debugf("creating %s", tmpPath)
329+
if err = os.MkdirAll(tmpPath, 0700); err != nil && ! os.IsExist(err) {
330+
log.Errorf("could not create new dest folder %s: %e", tmpPath, err)
331+
return err
332+
}
333+
log.Debugf("moving wal from %s to %s", curPath, tmpPath)
334+
if entries, err := ioutil.ReadDir(curPath); err != nil {
335+
log.Errorf("could not read contents of folder %s: %e", curPath, err)
336+
return err
337+
} else {
338+
for _, entry := range entries {
339+
srcEntry := filepath.Join(curPath, entry.Name())
340+
dstEntry := filepath.Join(tmpPath, entry.Name())
341+
log.Infof("moving %s to %s", srcEntry, dstEntry)
342+
os.Rename(srcEntry, dstEntry)
343+
}
344+
}
345+
346+
if symlinkStat, err := os.Lstat(symlinkPath); err != nil {
347+
log.Errorf("could not get info on current pg_wal folder/symlink %s: %e", symlinkPath, err)
348+
return err
349+
} else if symlinkStat.Mode() & os.ModeSymlink != 0 {
350+
if err = os.Remove(symlinkPath); err != nil {
351+
log.Errorf("could not remove current pg_wal symlink %s: %e", symlinkPath, err)
352+
return err
353+
}
354+
} else if symlinkStat.IsDir() {
355+
if err := syscall.Rmdir(symlinkPath); err != nil {
356+
log.Errorf("could not remove current folder %s: %e", symlinkPath, err)
357+
return err
358+
}
359+
} else {
360+
err := fmt.Errorf("location %s is no symlink and no dir, so please check and resolve by hand", symlinkPath)
361+
log.Error(err)
362+
return err
363+
}
364+
if p.walDir == "" {
365+
// So we were moving wal files back into PGDATA. Let's rename the tmpDir now holding all wal files and use that
366+
// as PGDATA/pg_wal
367+
os.Rename(tmpPath, desiredPath)
368+
// Ah, so we were copying WAL files from PGDATA (or another location) to a location outside of PGDATA.
369+
// Then we need to point the symlink in the right direction.
370+
} else if err = os.Symlink(desiredPath, symlinkPath); err != nil {
371+
log.Errorf("could not create symlink %s to %s: %e", symlinkPath, desiredPath, err)
372+
return err
373+
}
374+
log.Debugf("finished moving pg_wal from %s to %s", curPath, desiredPath)
375+
return nil
376+
}
377+
302378
func (p *Manager) Start() error {
303379
if err := p.writeConfs(false); err != nil {
304380
return err
305381
}
382+
if err := p.moveWal(); err != nil {
383+
return err
384+
}
306385
return p.start()
307386
}
308387

0 commit comments

Comments
 (0)