archive_command

From: Rui DeSousa <rui(dot)desousa(at)icloud(dot)com>
To: pgsql-hackers(at)postgresql(dot)org
Subject: archive_command
Date: 2018-03-08 01:33:28
Message-ID: 467E3509-0A62-4719-8631-9E92CCB98A10@icloud.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers


Hi,

I’ve been encouraged to submit this code as there has been talk in the past about a simple pgcopy command to use with the archive_command. Currently there is really no good solution in most base systems without having to introduce a dedicated third party Postgres solution. The best base system solution and most commonly used today is rsync which doesn’t fsync the file after completing the transfer leaving no good recommendations.

I not sure what would need to be done to introduce this into a given commitfest. Also, would need to know if the command interface is acceptable and/or other features should be added. It currently is very simple as it just reads from standard input and saves data to the indicated file.

Please let me know how to proceed.

Thanks,
Rui


Example of local compressed archive:

archive_command=“xz -c %p | fwrite /mnt/server/archivedir/%f”

Example of remote archive via a shell script:

#!/usr/bin/env bash

.
.
.

# SSH Command and options
SSH_CMD="ssh -o ServerAliveInterval=20 $ARCH_SERVER"
STS=3

OUTPUT=$(cat $XLOGFILE | $SSH_CMD "(mkdir -p $ARCH_DIR && fwrite $ARCH_DIR/$WALFILE) 2>&1")

echo ${PIPESTATUS[(at)]} | grep -qE '^[0 ]+$'
if [ $? == 0 ]; then
STS=0
fi

exit $STS

fwrite code:

#include <sys/stat.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#define BUFSIZE 131072

int
main(int argc, char *argv[])
{
int fd, r, w;
char *buf;
char *name;
struct stat fstat;

if (argc != 2) {
fprintf(stderr, "usage: fwrite [file]\n");
exit(1);
}

if ((buf = malloc(BUFSIZE)) == NULL)
err(1, "malloc");

++argv;
if ((name = (char *) malloc(strlen(*argv) + 8)) == NULL)
err(1, "malloc");

strcat(strcpy(name, *argv), ".XXXXXX");

if ((fd = mkstemp(name)) < 0)
err(1, "mkstemp");

while ((r = read(STDIN_FILENO, buf, BUFSIZE)) > 0)
if ((w = write(fd, buf, r)) == -1) {
unlink(name);
err(1, "write");
}

if (r < 0)
err(1, "read");

if (lseek(fd, 0, SEEK_CUR) <= 0) {
unlink(name);
errx(1, "zero byte file!");
}

if (fsync(fd) != 0)
err(1, "fsync");

if (close(fd) != 0)
err(1, "close");

if (access(*argv, F_OK) < 0 && errno == ENOENT) {
if (rename(name, *argv) != 0)
err(1, "rename");
} else {
unlink(name);
errx(1, "file exists already!");
}

free(name);
exit(0);
}

Browse pgsql-hackers by date

  From Date Subject
Next Message Peter Geoghegan 2018-03-08 01:40:18 Re: [HACKERS] Parallel tuplesort (for parallel B-Tree index creation)
Previous Message Michael Paquier 2018-03-08 01:18:21 Re: Add default role 'pg_access_server_files'