From b7dffc73ee9d83b9d696e1123922ca56ba410ee1 Mon Sep 17 00:00:00 2001 From: Artem Gavrilov Date: Fri, 2 Aug 2024 15:39:00 +0200 Subject: [PATCH] PG-934 Fix old telemetry files loading on startup (#10) * PG-934 Fix old telemetry files loading on startup * PG-934 Fix build for PG12 * PG-934 Fix codestyle * PG-934 Fix --- percona_pg_telemetry.c | 70 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 61 insertions(+), 9 deletions(-) diff --git a/percona_pg_telemetry.c b/percona_pg_telemetry.c index 84fc644..db5298f 100644 --- a/percona_pg_telemetry.c +++ b/percona_pg_telemetry.c @@ -74,10 +74,16 @@ static shmem_request_hook_type prev_shmem_request_hook = NULL; static BgwHandleStatus setup_background_worker(const char *bgw_function_name, const char *bgw_name, const char *bgw_type, Oid datid, pid_t bgw_notify_pid); static void start_leader(void); static long server_uptime(void); -static void cleaup_telemetry_dir(void); +static void load_telemery_files(void); static char *generate_filename(char *filename); static bool validate_dir(char *folder_path); +#if PG_VERSION_NUM >= 130000 +static int compare_file_names(const ListCell *a, const ListCell *b); +#else +static int compare_file_names(const void *a, const void *b); +#endif + /* Database information collection and writing to file */ static void write_pg_settings(void); static List *get_database_list(void); @@ -198,12 +204,17 @@ telemetry_file_is_valid(void) } /* - * + * Adds a new filename to the next position in the circular buffer. If position already has a filename + * (i.e. we made full circle), then it will try to remove this file from filesystem. + * Returns the previous filename that was in the position. */ static char * telemetry_file_next(char *filename) { - char *curr_oldest = telemetry_curr_filename(); + /* Get current file that will become previous */ + char *previous = telemetry_curr_filename(); + + /* Increment the index. We are using a circular buffer. */ ptss->curr_file_index = (ptss->curr_file_index + 1) % files_to_keep; /* Remove the existing file on this location if valid */ @@ -212,21 +223,26 @@ telemetry_file_next(char *filename) PathNameDeleteTemporaryFile(ptss->telemetry_filenames[ptss->curr_file_index], false); } + /* Add new file to the new current position */ telemetry_add_filename(filename); - return (*curr_oldest) ? curr_oldest : NULL; + /* Return previous file */ + return (*previous) ? previous : NULL; } /* - * + * Load all telemetry files from the telemetry directory. */ static void -cleaup_telemetry_dir(void) +load_telemery_files(void) { DIR *d; struct dirent *de; uint64 system_id = GetSystemIdentifier(); char json_file_id[MAXPGPATH]; + char full_path[MAXPGPATH]; + List *files_list = NIL; + ListCell *lc = NULL; int file_id_len; validate_dir(ptss->telemetry_path); @@ -248,13 +264,49 @@ cleaup_telemetry_dir(void) { if (strncmp(json_file_id, de->d_name, file_id_len) == 0) { - telemetry_file_next(de->d_name); + /* Construct the file full path */ + snprintf(full_path, sizeof(full_path), "%s/%s", ptss->telemetry_path, de->d_name); + + files_list = lappend(files_list, pstrdup(full_path)); } } +#if PG_VERSION_NUM >= 130000 + list_sort(files_list, compare_file_names); +#else + files_list = list_qsort(files_list, compare_file_names); +#endif + + foreach(lc, files_list) + { + char *file_path = lfirst(lc); + telemetry_file_next(file_path); + } + + list_free_deep(files_list); FreeDir(d); } + +#if PG_VERSION_NUM >= 130000 +static int +compare_file_names(const ListCell *a, const ListCell *b) +{ + char *fna = (char *) lfirst(a); + char *fnb = (char *) lfirst(b); + return strcmp(fna, fnb); +} + +#else +static int +compare_file_names(const void *a, const void *b) +{ + char *fna = (char *) lfirst(*(ListCell **) a); + char *fnb = (char *) lfirst(*(ListCell **) b); + return strcmp(fna, fnb); +} +#endif + /* * telemetry_path */ @@ -850,8 +902,8 @@ percona_pg_telemetry_main(Datum main_arg) /* Initialize shmem */ pt_shmem_init(); - /* Cleanup the directory */ - cleaup_telemetry_dir(); + /* Load existing telemetry files */ + load_telemery_files(); /* Set up connection */ BackgroundWorkerInitializeConnectionByOid(InvalidOid, InvalidOid, 0);