/* * transfer_single_new_db() * * create links for mappings stored in "maps" array. */ static void transfer_single_new_db(pageCnvCtx *pageConverter, FileNameMap *maps, int size) { char old_dir[MAXPGPATH]; struct dirent **namelist = NULL; int numFiles = 0; int mapnum; int fileno; old_dir[0] = '\0'; for (mapnum = 0; mapnum < size; mapnum++) { char old_file[MAXPGPATH]; char new_file[MAXPGPATH]; /* Changed tablespaces? Need a new directory scan? */ if (strcmp(maps[mapnum].old_dir, old_dir) != 0) { if (numFiles > 0) { for (fileno = 0; fileno < numFiles; fileno++) pg_free(namelist[fileno]); pg_free(namelist); } snprintf(old_dir, sizeof(old_dir), "%s", maps[mapnum].old_dir); numFiles = pg_scandir(old_dir, &namelist, NULL); } /* Copying files might take some time, so give feedback. */ snprintf(old_file, sizeof(old_file), "%s/%u", maps[mapnum].old_dir, maps[mapnum].old_relfilenode); snprintf(new_file, sizeof(new_file), "%s/%u", maps[mapnum].new_dir, maps[mapnum].new_relfilenode); pg_log(PG_REPORT, OVERWRITE_MESSAGE, old_file); /* * Copy/link the relation file to the new cluster */ unlink(new_file); transfer_relfile(pageConverter, old_file, new_file, maps[mapnum].nspname, maps[mapnum].relname); /* fsm/vm files added in PG 8.4 */ if (GET_MAJOR_VERSION(old_cluster.major_version) >= 804) { /* * Copy/link any fsm and vm files, if they exist */ snprintf(scandir_file_pattern, sizeof(scandir_file_pattern), "%u_", maps[mapnum].old_relfilenode); for (fileno = 0; fileno < numFiles; fileno++) { if (strncmp(namelist[fileno]->d_name, scandir_file_pattern, strlen(scandir_file_pattern)) == 0) { snprintf(old_file, sizeof(old_file), "%s/%s", maps[mapnum].old_dir, namelist[fileno]->d_name); snprintf(new_file, sizeof(new_file), "%s/%u%s", maps[mapnum].new_dir, maps[mapnum].new_relfilenode, strchr(namelist[fileno]->d_name, '_')); unlink(new_file); transfer_relfile(pageConverter, old_file, new_file, maps[mapnum].nspname, maps[mapnum].relname); } } } /* * Now copy/link any related segments as well. Remember, PG breaks * large files into 1GB segments, the first segment has no extension, * subsequent segments are named relfilenode.1, relfilenode.2, * relfilenode.3, ... 'fsm' and 'vm' files use underscores so are not * copied. */ snprintf(scandir_file_pattern, sizeof(scandir_file_pattern), "%u.", maps[mapnum].old_relfilenode); for (fileno = 0; fileno < numFiles; fileno++) { if (strncmp(namelist[fileno]->d_name, scandir_file_pattern, strlen(scandir_file_pattern)) == 0) { snprintf(old_file, sizeof(old_file), "%s/%s", maps[mapnum].old_dir, namelist[fileno]->d_name); snprintf(new_file, sizeof(new_file), "%s/%u%s", maps[mapnum].new_dir, maps[mapnum].new_relfilenode, strchr(namelist[fileno]->d_name, '.')); unlink(new_file); transfer_relfile(pageConverter, old_file, new_file, maps[mapnum].nspname, maps[mapnum].relname); } } } if (numFiles > 0) { for (fileno = 0; fileno < numFiles; fileno++) pg_free(namelist[fileno]); pg_free(namelist); } }
/* * transfer_single_new_db() * * create links for mappings stored in "maps" array. */ static void transfer_single_new_db(pageCnvCtx *pageConverter, FileNameMap *maps, int size) { char old_dir[MAXPGPATH]; struct dirent **namelist = NULL; int numFiles = 0; int mapnum; int fileno; bool vm_crashsafe_change = false; old_dir[0] = '\0'; /* Do not copy non-crashsafe vm files for binaries that assume crashsafety */ if (old_cluster.controldata.cat_ver < VISIBILITY_MAP_CRASHSAFE_CAT_VER && new_cluster.controldata.cat_ver >= VISIBILITY_MAP_CRASHSAFE_CAT_VER) vm_crashsafe_change = true; for (mapnum = 0; mapnum < size; mapnum++) { char old_file[MAXPGPATH]; char new_file[MAXPGPATH]; /* Changed tablespaces? Need a new directory scan? */ if (strcmp(maps[mapnum].old_dir, old_dir) != 0) { if (numFiles > 0) { for (fileno = 0; fileno < numFiles; fileno++) pg_free(namelist[fileno]); pg_free(namelist); } snprintf(old_dir, sizeof(old_dir), "%s", maps[mapnum].old_dir); numFiles = pg_scandir(old_dir, &namelist, NULL); } /* Copying files might take some time, so give feedback. */ snprintf(old_file, sizeof(old_file), "%s/%u", maps[mapnum].old_dir, maps[mapnum].old_relfilenode); snprintf(new_file, sizeof(new_file), "%s/%u", maps[mapnum].new_dir, maps[mapnum].new_relfilenode); pg_log(PG_REPORT, OVERWRITE_MESSAGE, old_file); /* * Copy/link the relation file to the new cluster */ unlink(new_file); transfer_relfile(pageConverter, old_file, new_file, maps[mapnum].nspname, maps[mapnum].relname); /* fsm/vm files added in PG 8.4 */ if (GET_MAJOR_VERSION(old_cluster.major_version) >= 804) { /* * Copy/link any fsm and vm files, if they exist */ snprintf(scandir_file_pattern, sizeof(scandir_file_pattern), "%u_", maps[mapnum].old_relfilenode); for (fileno = 0; fileno < numFiles; fileno++) { char *vm_offset = strstr(namelist[fileno]->d_name, "_vm"); bool is_vm_file = false; /* Is a visibility map file? (name ends with _vm) */ if (vm_offset && strlen(vm_offset) == strlen("_vm")) is_vm_file = true; if (strncmp(namelist[fileno]->d_name, scandir_file_pattern, strlen(scandir_file_pattern)) == 0 && (!is_vm_file || !vm_crashsafe_change)) { snprintf(old_file, sizeof(old_file), "%s/%s", maps[mapnum].old_dir, namelist[fileno]->d_name); snprintf(new_file, sizeof(new_file), "%s/%u%s", maps[mapnum].new_dir, maps[mapnum].new_relfilenode, strchr(namelist[fileno]->d_name, '_')); unlink(new_file); transfer_relfile(pageConverter, old_file, new_file, maps[mapnum].nspname, maps[mapnum].relname); } } } /* * Now copy/link any related segments as well. Remember, PG breaks * large files into 1GB segments, the first segment has no extension, * subsequent segments are named relfilenode.1, relfilenode.2, * relfilenode.3, ... 'fsm' and 'vm' files use underscores so are not * copied. */ snprintf(scandir_file_pattern, sizeof(scandir_file_pattern), "%u.", maps[mapnum].old_relfilenode); for (fileno = 0; fileno < numFiles; fileno++) { if (strncmp(namelist[fileno]->d_name, scandir_file_pattern, strlen(scandir_file_pattern)) == 0) { snprintf(old_file, sizeof(old_file), "%s/%s", maps[mapnum].old_dir, namelist[fileno]->d_name); snprintf(new_file, sizeof(new_file), "%s/%u%s", maps[mapnum].new_dir, maps[mapnum].new_relfilenode, strchr(namelist[fileno]->d_name, '.')); unlink(new_file); transfer_relfile(pageConverter, old_file, new_file, maps[mapnum].nspname, maps[mapnum].relname); } } } if (numFiles > 0) { for (fileno = 0; fileno < numFiles; fileno++) pg_free(namelist[fileno]); pg_free(namelist); } }