Skip to content

Commit

Permalink
[#187] Extract WAL info from backup_label
Browse files Browse the repository at this point in the history
  • Loading branch information
Jubilee101 authored and jesperpedersen committed Mar 4, 2024
1 parent bd64d52 commit 50c3177
Show file tree
Hide file tree
Showing 6 changed files with 356 additions and 9 deletions.
26 changes: 17 additions & 9 deletions src/include/info.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,18 @@ extern "C" {
/* system */
#include <stdlib.h>

#define INFO_STATUS "STATUS"
#define INFO_LABEL "LABEL"
#define INFO_WAL "WAL"
#define INFO_ELAPSED "ELAPSED"
#define INFO_VERSION "VERSION"
#define INFO_KEEP "KEEP"
#define INFO_BACKUP "BACKUP"
#define INFO_RESTORE "RESTORE"
#define INFO_TABLESPACES "TABLESPACES"
#define INFO_STATUS "STATUS"
#define INFO_LABEL "LABEL"
#define INFO_WAL "WAL"
#define INFO_ELAPSED "ELAPSED"
#define INFO_VERSION "VERSION"
#define INFO_KEEP "KEEP"
#define INFO_BACKUP "BACKUP"
#define INFO_RESTORE "RESTORE"
#define INFO_TABLESPACES "TABLESPACES"
#define INFO_START_WALPOS "START_WALPOS"
#define INFO_CHKPT_WALPOS "CHKPT_WALPOS"
#define INFO_START_TIMELINE "START_TIMELINE"

#define VALID_UNKNOWN -1
#define VALID_FALSE 0
Expand All @@ -68,6 +71,11 @@ struct backup
char valid; /**< Is the backup valid */
unsigned long number_of_tablespaces; /**< The number of tablespaces */
char tablespaces[MAX_NUMBER_OF_TABLESPACES][MISC_LENGTH]; /**< The names of the tablespaces */
uint32_t start_lsn_hi32; /**< The high 32 bits of WAL starting position of the backup */
uint32_t start_lsn_lo32; /**< The low 32 bits of WAL starting position of the backup */
uint32_t checkpoint_lsn_hi32; /**< The high 32 bits of WAL checkpoint position of the backup */
uint32_t checkpoint_lsn_lo32; /**< The low 32 bits of WAL checkpoint position of the backup */
uint32_t start_timeline; /**< The starting timeline of the backup */
} __attribute__ ((aligned (64)));

/**
Expand Down
11 changes: 11 additions & 0 deletions src/include/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,17 @@ pgmoneta_read_version(char* directory, char** version);
int
pgmoneta_read_wal(char* directory, char** wal);

/**
* Read the start WAL location and checkpoint WAL location from a backup_label file
* @param directory The base directory
* @param startpos [out] The start WAL position
* @param chkptpos [out] The checkpoint WAL position
* @param start_timeline [out] The timeline this backup starts with
* @return 0 on success, 1 if otherwise
*/
int
pgmoneta_read_wal_info(char* directory, char** startpos, char** chkptpos, uint32_t* start_timeline);

/**
* Get the directory for a server
* @param server The server
Expand Down
12 changes: 12 additions & 0 deletions src/libpgmoneta/info.c
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,18 @@ pgmoneta_get_backup(char* directory, char* label, struct backup** backup)
memcpy(&bck->tablespaces[tbl_idx], &value[0], strlen(&value[0]));
tbl_idx++;
}
else if (pgmoneta_starts_with(&key[0], INFO_START_WALPOS))
{
sscanf(&value[0], "%X/%X", &bck->start_lsn_hi32, &bck->start_lsn_lo32);
}
else if (pgmoneta_starts_with(&key[0], INFO_CHKPT_WALPOS))
{
sscanf(&value[0], "%X/%X", &bck->checkpoint_lsn_hi32, &bck->checkpoint_lsn_lo32);
}
else if (pgmoneta_starts_with(&key[0], INFO_START_TIMELINE))
{
bck->start_timeline = atoi(&value[0]);
}
}
}

Expand Down
224 changes: 224 additions & 0 deletions src/libpgmoneta/prometheus.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,59 @@ home_page(int client_fd)
data = pgmoneta_append(data, " </tbody>\n");
data = pgmoneta_append(data, " </table>\n");
data = pgmoneta_append(data, " <p>\n");
data = pgmoneta_append(data, " <h2>pgmoneta_backup_start_timeline</h2>\n");
data = pgmoneta_append(data, " The starting timeline of a backup for a server\n");
data = pgmoneta_append(data, " <table border=\"1\">\n");
data = pgmoneta_append(data, " <tbody>\n");
data = pgmoneta_append(data, " <tr>\n");
data = pgmoneta_append(data, " <td>name</td>\n");
data = pgmoneta_append(data, " <td>The identifier for the server</td>\n");
data = pgmoneta_append(data, " </tr>\n");
data = pgmoneta_append(data, " <tr>\n");
data = pgmoneta_append(data, " <td>label</td>\n");
data = pgmoneta_append(data, " <td>The backup label</td>\n");
data = pgmoneta_append(data, " </tr>\n");
data = pgmoneta_append(data, " </tbody>\n");
data = pgmoneta_append(data, " </table>\n");
data = pgmoneta_append(data, " <p>\n");
data = pgmoneta_append(data, " <h2>pgmoneta_backup_start_walpos</h2>\n");
data = pgmoneta_append(data, " The starting WAL position of a backup for a server\n");
data = pgmoneta_append(data, " <table border=\"1\">\n");
data = pgmoneta_append(data, " <tbody>\n");
data = pgmoneta_append(data, " <tr>\n");
data = pgmoneta_append(data, " <td>name</td>\n");
data = pgmoneta_append(data, " <td>The identifier for the server</td>\n");
data = pgmoneta_append(data, " </tr>\n");
data = pgmoneta_append(data, " <tr>\n");
data = pgmoneta_append(data, " <td>label</td>\n");
data = pgmoneta_append(data, " <td>The backup label</td>\n");
data = pgmoneta_append(data, " </tr>\n");
data = pgmoneta_append(data, " <tr>\n");
data = pgmoneta_append(data, " <td>walpos</td>\n");
data = pgmoneta_append(data, " <td>The backup starting WAL position</td>\n");
data = pgmoneta_append(data, " </tr>\n");
data = pgmoneta_append(data, " </tbody>\n");
data = pgmoneta_append(data, " </table>\n");
data = pgmoneta_append(data, " <p>\n");
data = pgmoneta_append(data, " <h2>pgmoneta_backup_checkpoint_walpos</h2>\n");
data = pgmoneta_append(data, " The checkpoint WAL pos for a server\n");
data = pgmoneta_append(data, " <table border=\"1\">\n");
data = pgmoneta_append(data, " <tbody>\n");
data = pgmoneta_append(data, " <tr>\n");
data = pgmoneta_append(data, " <td>name</td>\n");
data = pgmoneta_append(data, " <td>The identifier for the server</td>\n");
data = pgmoneta_append(data, " </tr>\n");
data = pgmoneta_append(data, " <tr>\n");
data = pgmoneta_append(data, " <td>label</td>\n");
data = pgmoneta_append(data, " <td>The backup label</td>\n");
data = pgmoneta_append(data, " </tr>\n");
data = pgmoneta_append(data, " <tr>\n");
data = pgmoneta_append(data, " <td>walpos</td>\n");
data = pgmoneta_append(data, " <td>The backup checkpoint WAL position</td>\n");
data = pgmoneta_append(data, " </tr>\n");
data = pgmoneta_append(data, " </tbody>\n");
data = pgmoneta_append(data, " </table>\n");
data = pgmoneta_append(data, " <p>\n");
data = pgmoneta_append(data, " <h2>pgmoneta_restore_newest_size</h2>\n");
data = pgmoneta_append(data, " The size of the newest restore for a server\n");
data = pgmoneta_append(data, " <table border=\"1\">\n");
Expand Down Expand Up @@ -1560,6 +1613,177 @@ backup_information(int client_fd)
}
data = pgmoneta_append(data, "\n");

data = pgmoneta_append(data, "#HELP pgmoneta_backup_start_timeline The starting timeline of a backup for a server\n");
data = pgmoneta_append(data, "#TYPE pgmoneta_backup_start_timeline gauge\n");
for (int i = 0; i < config->number_of_servers; i++)
{
d = pgmoneta_get_server_backup(i);

number_of_backups = 0;
backups = NULL;

pgmoneta_get_backups(d, &number_of_backups, &backups);

if (number_of_backups > 0)
{
for (int j = 0; j < number_of_backups; j++)
{
if (backups[j]->valid == VALID_TRUE)
{
data = pgmoneta_append(data, "pgmoneta_backup_start_timeline{");

data = pgmoneta_append(data, "name=\"");
data = pgmoneta_append(data, config->servers[i].name);
data = pgmoneta_append(data, "\",label=\"");
data = pgmoneta_append(data, backups[j]->label);
data = pgmoneta_append(data, "\"} ");

data = pgmoneta_append_int(data, backups[j]->start_timeline);

data = pgmoneta_append(data, "\n");
}
}
}
else
{
data = pgmoneta_append(data, "pgmoneta_backup_start_timeline{");

data = pgmoneta_append(data, "name=\"");
data = pgmoneta_append(data, config->servers[i].name);
data = pgmoneta_append(data, "\",label=\"0\"} 0");

data = pgmoneta_append(data, "\n");
}

for (int j = 0; j < number_of_backups; j++)
{
free(backups[j]);
}
free(backups);

free(d);
}
data = pgmoneta_append(data, "\n");

data = pgmoneta_append(data, "#HELP pgmoneta_backup_start_walpos The starting WAL position of a backup for a server\n");
data = pgmoneta_append(data, "#TYPE pgmoneta_backup_start_walpos gauge\n");
for (int i = 0; i < config->number_of_servers; i++)
{
d = pgmoneta_get_server_backup(i);

number_of_backups = 0;
backups = NULL;

pgmoneta_get_backups(d, &number_of_backups, &backups);

if (number_of_backups > 0)
{
for (int j = 0; j < number_of_backups; j++)
{
if (backups[j]->valid == VALID_TRUE)
{
char walpos[MISC_LENGTH];
memset(walpos, 0, MISC_LENGTH);
data = pgmoneta_append(data, "pgmoneta_backup_start_walpos{");

data = pgmoneta_append(data, "name=\"");
data = pgmoneta_append(data, config->servers[i].name);
data = pgmoneta_append(data, "\",label=\"");
data = pgmoneta_append(data, backups[j]->label);
data = pgmoneta_append(data, "\", ");

snprintf(walpos, MISC_LENGTH, "%X/%X", backups[j]->start_lsn_hi32, backups[j]->start_lsn_lo32);
data = pgmoneta_append(data, "walpos=\"");
data = pgmoneta_append(data, walpos);
data = pgmoneta_append(data, "\"} ");

data = pgmoneta_append_int(data, 1);

data = pgmoneta_append(data, "\n");
}
}
}
else
{
data = pgmoneta_append(data, "pgmoneta_backup_start_walpos{");

data = pgmoneta_append(data, "name=\"");
data = pgmoneta_append(data, config->servers[i].name);
data = pgmoneta_append(data, "\",label=\"0\", ");
data = pgmoneta_append(data, "walpos=\"0/0\"} 0");

data = pgmoneta_append(data, "\n");
}
for (int j = 0; j < number_of_backups; j++)
{
free(backups[j]);
}
free(backups);

free(d);
}
data = pgmoneta_append(data, "\n");

data = pgmoneta_append(data, "#HELP pgmoneta_backup_checkpoint_walpos The checkpoint WAL position of a backup for a server\n");
data = pgmoneta_append(data, "#TYPE pgmoneta_backup_checkpoint_walpos gauge\n");
for (int i = 0; i < config->number_of_servers; i++)
{
d = pgmoneta_get_server_backup(i);

number_of_backups = 0;
backups = NULL;

pgmoneta_get_backups(d, &number_of_backups, &backups);

if (number_of_backups > 0)
{
for (int j = 0; j < number_of_backups; j++)
{
if (backups[j]->valid == VALID_TRUE)
{
char walpos[MISC_LENGTH];
memset(walpos, 0, MISC_LENGTH);
data = pgmoneta_append(data, "pgmoneta_backup_checkpoint_walpos{");

data = pgmoneta_append(data, "name=\"");
data = pgmoneta_append(data, config->servers[i].name);
data = pgmoneta_append(data, "\",label=\"");
data = pgmoneta_append(data, backups[j]->label);
data = pgmoneta_append(data, "\", ");

snprintf(walpos, MISC_LENGTH, "%X/%X", backups[j]->checkpoint_lsn_hi32, backups[j]->checkpoint_lsn_lo32);
data = pgmoneta_append(data, "walpos=\"");
data = pgmoneta_append(data, walpos);
data = pgmoneta_append(data, "\"} ");

data = pgmoneta_append_int(data, 1);

data = pgmoneta_append(data, "\n");
}
}
}
else
{
data = pgmoneta_append(data, "pgmoneta_backup_checkpoint_walpos{");

data = pgmoneta_append(data, "name=\"");
data = pgmoneta_append(data, config->servers[i].name);
data = pgmoneta_append(data, "\",label=\"0\", ");
data = pgmoneta_append(data, "walpos=\"0/0\"} 0");

data = pgmoneta_append(data, "\n");
}

for (int j = 0; j < number_of_backups; j++)
{
free(backups[j]);
}
free(backups);

free(d);
}
data = pgmoneta_append(data, "\n");

if (data != NULL)
{
send_chunk(client_fd, data);
Expand Down
75 changes: 75 additions & 0 deletions src/libpgmoneta/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -2430,6 +2430,81 @@ pgmoneta_read_wal(char* directory, char** wal)
return 1;
}

int
pgmoneta_read_wal_info(char* directory, char** startpos, char** chkptpos, uint32_t* start_timeline)
{
char label[MAX_PATH];
char buffer[MAX_PATH];
char* start = NULL;
char* chkpt = NULL;
FILE* file = NULL;
uint32_t tli = 0;
int numfields = 0;

start = (char*)malloc(MISC_LENGTH);
chkpt = (char*)malloc(MISC_LENGTH);

memset(start, 0, MISC_LENGTH);
memset(chkpt, 0, MISC_LENGTH);
memset(buffer, 0, sizeof(buffer));
memset(label, 0, MAX_PATH);
snprintf(label, MAX_PATH, "%s/backup_label", directory);

file = fopen(label, "r");
if (file == NULL)
{
pgmoneta_log_error("Unable to open backup_label file: %s", strerror(errno));
goto error;
}
while (fgets(buffer, sizeof(buffer), file) != NULL)
{
if (pgmoneta_starts_with(buffer, "START WAL LOCATION"))
{
numfields = sscanf(buffer, "START WAL LOCATION: %s (file ", start);
if (numfields != 1)
{
pgmoneta_log_error("Error parsing start wal location");
goto error;
}
*startpos = start;
}
else if (pgmoneta_starts_with(buffer, "CHECKPOINT LOCATION"))
{
numfields = sscanf(buffer, "CHECKPOINT LOCATION: %s\n", chkpt);
if (numfields != 1)
{
pgmoneta_log_error("Error parsing checkpoint wal location");
goto error;
}
*chkptpos = chkpt;
}
else if (pgmoneta_starts_with(buffer, "START TIMELINE"))
{
numfields = sscanf(buffer, "START TIMELINE: %u\n", &tli);
if (numfields != 1)
{
pgmoneta_log_error("Error parsing backup start timeline");
goto error;
}
*start_timeline = tli;
}

memset(buffer, 0, sizeof(buffer));
}

fclose(file);
return 0;

error:
if (file != NULL)
{
fclose(file);
}
free(start);
free(chkpt);
return 1;
}

static int
string_compare(const void* a, const void* b)
{
Expand Down

0 comments on commit 50c3177

Please sign in to comment.