archive_command - Mailing list pgsql-hackers

From Rui DeSousa
Subject archive_command
Date
Msg-id 467E3509-0A62-4719-8631-9E92CCB98A10@icloud.com
Whole thread Raw
List 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[@]} | 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);
}

pgsql-hackers by date:

Previous
From: Michael Paquier
Date:
Subject: Re: Add default role 'pg_access_server_files'
Next
From: Peter Geoghegan
Date:
Subject: Re: [HACKERS] Parallel tuplesort (for parallel B-Tree index creation)