Skip to content

Commit

Permalink
[pgmoneta#22] Initial pgmoneta_ext_full_backup()
Browse files Browse the repository at this point in the history
  • Loading branch information
GuChad369 committed Sep 14, 2024
1 parent dc7fea7 commit 47a4eef
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 2 deletions.
8 changes: 6 additions & 2 deletions sql/pgmoneta_ext--0.1.0.sql
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@ CREATE FUNCTION pgmoneta_ext_get_oids() RETURNS SETOF RECORD
AS 'MODULE_PATHNAME'
LANGUAGE C;

CREATE FUNCTION pgmoneta_ext_get_file(file_path TEXT) RETURNS TEXT
CREATE FUNCTION pgmoneta_ext_get_file(file_path text) RETURNS text
AS 'MODULE_PATHNAME'
LANGUAGE C STRICT;

CREATE OR REPLACE FUNCTION pgmoneta_ext_get_files(file_path TEXT) RETURNS text[]
CREATE FUNCTION pgmoneta_ext_get_files(file_path text) RETURNS text[]
AS 'MODULE_PATHNAME'
LANGUAGE C STRICT;

CREATE FUNCTION pgmoneta_ext_full_backup() RETURNS text
AS 'MODULE_PATHNAME'
LANGUAGE C STRICT;
135 changes: 135 additions & 0 deletions src/pgmoneta_ext/lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include <catalog/pg_type.h>
#include <common/base64.h>
#include <commands/dbcommands.h>
#include <executor/spi.h>
#include <fmgr.h>
#include <funcapi.h>
#include <lib/stringinfo.h>
Expand All @@ -66,8 +67,17 @@ PG_MODULE_MAGIC;

#define PGMONETA_EXT_CHUNK_SIZE 8192

struct backup_info
{
char* backup_label;
XLogRecPtr start_lsn;
XLogRecPtr stop_lsn;
} __attribute__ ((aligned (64)));

static text* encode_bytea_to_base64(bytea* data);
static void list_files(const char* name, ArrayBuildState* astate);
static int start_backup(struct backup_info* info);
static int stop_backup(struct backup_info* info);

PG_FUNCTION_INFO_V1(pgmoneta_ext_version);
PG_FUNCTION_INFO_V1(pgmoneta_ext_switch_wal);
Expand All @@ -76,6 +86,7 @@ PG_FUNCTION_INFO_V1(pgmoneta_ext_get_oid);
PG_FUNCTION_INFO_V1(pgmoneta_ext_get_oids);
PG_FUNCTION_INFO_V1(pgmoneta_ext_get_file);
PG_FUNCTION_INFO_V1(pgmoneta_ext_get_files);
PG_FUNCTION_INFO_V1(pgmoneta_ext_full_backup);

Datum
pgmoneta_ext_version(PG_FUNCTION_ARGS)
Expand Down Expand Up @@ -395,6 +406,46 @@ pgmoneta_ext_get_files(PG_FUNCTION_ARGS)
}
}

Datum
pgmoneta_ext_full_backup(PG_FUNCTION_ARGS)
{
struct backup_info* info;
char backup_label[] = "test_backup";

info = (struct backup_info*) malloc(sizeof(struct backup_info));
memset(info, 0, sizeof(struct backup_info));
info->backup_label = (char*) malloc(strlen(backup_label) + 1);
strcpy(info->backup_label, backup_label);

if (start_backup(info) != 0)
{
ereport(ERROR, errmsg_internal("pgmoneta_ext_full_backup: start_backup failed"));
free(info->backup_label);
free(info);
PG_RETURN_TEXT_P(cstring_to_text("Backup fail"));
}

// Perform backup ...

if (stop_backup(info) != 0)
{
ereport(ERROR, errmsg_internal("pgmoneta_ext_full_backup: stop_backup failed"));
free(info->backup_label);
free(info);
PG_RETURN_TEXT_P(cstring_to_text("Backup fail"));
}

ereport(LOG, errmsg_internal("Final Backup Info - Label: %s, Start LSN: %X/%X, Stop LSN: %X/%X",
info->backup_label,
(uint32) (info->start_lsn >> 32), (uint32) info->start_lsn,
(uint32) (info->stop_lsn >> 32), (uint32) info->stop_lsn));

free(info->backup_label);
free(info);

PG_RETURN_TEXT_P(cstring_to_text("Backup success"));
}

static text*
encode_bytea_to_base64(bytea* data)
{
Expand Down Expand Up @@ -449,3 +500,87 @@ list_files(const char* name, ArrayBuildState* astate)
}
closedir(dir);
}

static int
start_backup(struct backup_info* info)
{
char* query;
int spi_result;

if (info == NULL)
{
ereport(ERROR, errmsg_internal("start_backup: backup_info is not allocated"));
return 1;
}

#if PG_VERSION_NUM >= 150000
query = psprintf("SELECT pg_backup_start('%s')", info->backup_label);
#else
query = psprintf("SELECT pg_start_backup('%s')", info->backup_label);
#endif

if (SPI_connect() != SPI_OK_CONNECT)
{
ereport(ERROR, (errmsg_internal("start_backup: unable to connect to SPI")));
pfree(query);
return 1;
}

spi_result = SPI_execute(query, true, 0);
if (spi_result != SPI_OK_SELECT)
{
ereport(ERROR, (errmsg_internal("start_backup: SPI_execute failed with code %d", spi_result)));
SPI_finish();
pfree(query);
return 1;
}

SPI_finish();

info->start_lsn = GetXLogWriteRecPtr();

pfree(query);
return 0;
}

static int
stop_backup(struct backup_info* info)
{
char* query;
int spi_result;

if (info == NULL)
{
ereport(ERROR, errmsg_internal("stop_backup: backup_info is not allocated"));
return 1;
}

#if PG_VERSION_NUM >= 150000
query = psprintf("SELECT pg_backup_stop()");
#else
query = psprintf("SELECT pg_stop_backup()");
#endif

if (SPI_connect() != SPI_OK_CONNECT)
{
ereport(ERROR, (errmsg_internal("stop_backup: unable to connect to SPI")));
pfree(query);
return 1;
}

spi_result = SPI_execute(query, true, 0);
if (spi_result != SPI_OK_SELECT)
{
ereport(ERROR, (errmsg_internal("stop_backup: SPI_execute failed with code %d", spi_result)));
SPI_finish();
pfree(query);
return 1;
}

SPI_finish();

info->stop_lsn = GetXLogWriteRecPtr();

pfree(query);
return 0;
}

0 comments on commit 47a4eef

Please sign in to comment.