LCOV - differential code coverage report
Current view: top level - src/bin/pg_upgrade - relfilenumber.c (source / functions) Coverage Total Hit UNC UIC GIC GNC
Current: Differential Code Coverage HEAD vs 15 Lines: 68.3 % 82 56 5 21 55 1
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 4 4 4
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (180,240] days: 100.0 % 2 2 2
Legend: Lines: hit not hit (240..) days: 67.5 % 80 54 5 21 53 1
Function coverage date bins:
(240..) days: 100.0 % 4 4 4

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*
                                  2                 :  *  relfilenumber.c
                                  3                 :  *
                                  4                 :  *  relfilenumber functions
                                  5                 :  *
                                  6                 :  *  Copyright (c) 2010-2023, PostgreSQL Global Development Group
                                  7                 :  *  src/bin/pg_upgrade/relfilenumber.c
                                  8                 :  */
                                  9                 : 
                                 10                 : #include "postgres_fe.h"
                                 11                 : 
                                 12                 : #include <sys/stat.h>
                                 13                 : 
                                 14                 : #include "access/transam.h"
                                 15                 : #include "catalog/pg_class_d.h"
                                 16                 : #include "pg_upgrade.h"
                                 17                 : 
                                 18                 : static void transfer_single_new_db(FileNameMap *maps, int size, char *old_tablespace);
                                 19                 : static void transfer_relfile(FileNameMap *map, const char *type_suffix, bool vm_must_add_frozenbit);
                                 20                 : 
                                 21                 : 
                                 22                 : /*
                                 23                 :  * transfer_all_new_tablespaces()
                                 24                 :  *
                                 25                 :  * Responsible for upgrading all database. invokes routines to generate mappings and then
                                 26                 :  * physically link the databases.
                                 27                 :  */
                                 28                 : void
 3742 bruce                      29 GIC           1 : transfer_all_new_tablespaces(DbInfoArr *old_db_arr, DbInfoArr *new_db_arr,
                                 30                 :                              char *old_pgdata, char *new_pgdata)
                                 31                 : {
 1614 peter_e                    32               1 :     switch (user_opts.transfer_mode)
                                 33                 :     {
 1614 peter_e                    34 UIC           0 :         case TRANSFER_MODE_CLONE:
  412 andres                     35               0 :             prep_status_progress("Cloning user relation files");
 1614 peter_e                    36               0 :             break;
 1614 peter_e                    37 GIC           1 :         case TRANSFER_MODE_COPY:
  412 andres                     38               1 :             prep_status_progress("Copying user relation files");
 1614 peter_e                    39               1 :             break;
 1614 peter_e                    40 UIC           0 :         case TRANSFER_MODE_LINK:
  412 andres                     41               0 :             prep_status_progress("Linking user relation files");
 1614 peter_e                    42               0 :             break;
                                 43                 :     }
                                 44                 : 
                                 45                 :     /*
                                 46                 :      * Transferring files by tablespace is tricky because a single database
                                 47                 :      * can use multiple tablespaces.  For non-parallel mode, we just pass a
                                 48                 :      * NULL tablespace path, which matches all tablespaces.  In parallel mode,
                                 49                 :      * we pass the default tablespace and all user-created tablespaces and let
                                 50                 :      * those operations happen in parallel.
                                 51                 :      */
 3742 bruce                      52 GIC           1 :     if (user_opts.jobs <= 1)
                                 53               1 :         parallel_transfer_all_new_dbs(old_db_arr, new_db_arr, old_pgdata,
                                 54                 :                                       new_pgdata, NULL);
                                 55                 :     else
                                 56                 :     {
                                 57                 :         int         tblnum;
                                 58                 : 
                                 59                 :         /* transfer default tablespace */
 3742 bruce                      60 UIC           0 :         parallel_transfer_all_new_dbs(old_db_arr, new_db_arr, old_pgdata,
                                 61                 :                                       new_pgdata, old_pgdata);
                                 62                 : 
                                 63               0 :         for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
 3599 sfrost                     64               0 :             parallel_transfer_all_new_dbs(old_db_arr,
                                 65                 :                                           new_db_arr,
                                 66                 :                                           old_pgdata,
                                 67                 :                                           new_pgdata,
                                 68               0 :                                           os_info.old_tablespaces[tblnum]);
                                 69                 :         /* reap all children */
 3742 bruce                      70               0 :         while (reap_child(true) == true)
                                 71                 :             ;
                                 72                 :     }
                                 73                 : 
 3742 bruce                      74 GIC           1 :     end_progress_output();
                                 75               1 :     check_ok();
                                 76               1 : }
                                 77                 : 
                                 78                 : 
                                 79                 : /*
                                 80                 :  * transfer_all_new_dbs()
                                 81                 :  *
                                 82                 :  * Responsible for upgrading all database. invokes routines to generate mappings and then
                                 83                 :  * physically link the databases.
                                 84                 :  */
                                 85                 : void
                                 86               1 : transfer_all_new_dbs(DbInfoArr *old_db_arr, DbInfoArr *new_db_arr,
                                 87                 :                      char *old_pgdata, char *new_pgdata, char *old_tablespace)
                                 88                 : {
                                 89                 :     int         old_dbnum,
                                 90                 :                 new_dbnum;
                                 91                 : 
                                 92                 :     /* Scan the old cluster databases and transfer their files */
 4177                            93               1 :     for (old_dbnum = new_dbnum = 0;
 4175                            94               7 :          old_dbnum < old_db_arr->ndbs;
 4177                            95               6 :          old_dbnum++, new_dbnum++)
                                 96                 :     {
 3955                            97               6 :         DbInfo     *old_db = &old_db_arr->dbs[old_dbnum],
                                 98               6 :                    *new_db = NULL;
                                 99                 :         FileNameMap *mappings;
                                100                 :         int         n_maps;
                                101                 : 
                                102                 :         /*
                                103                 :          * Advance past any databases that exist in the new cluster but not in
                                104                 :          * the old, e.g. "postgres".  (The user might have removed the
                                105                 :          * 'postgres' database from the old cluster.)
                                106                 :          */
 4175                           107               6 :         for (; new_dbnum < new_db_arr->ndbs; new_dbnum++)
                                108                 :         {
                                109               6 :             new_db = &new_db_arr->dbs[new_dbnum];
                                110               6 :             if (strcmp(old_db->db_name, new_db->db_name) == 0)
                                111               6 :                 break;
                                112                 :         }
                                113                 : 
                                114               6 :         if (new_dbnum >= new_db_arr->ndbs)
  271 tgl                       115 UNC           0 :             pg_fatal("old database \"%s\" not found in the new cluster",
                                116                 :                      old_db->db_name);
                                117                 : 
 4555 bruce                     118 GIC           6 :         mappings = gen_db_file_maps(old_db, new_db, &n_maps, old_pgdata,
                                119                 :                                     new_pgdata);
 4715                           120               6 :         if (n_maps)
                                121                 :         {
 2588 rhaas                     122               6 :             transfer_single_new_db(mappings, n_maps, old_tablespace);
                                123                 :         }
                                124                 :         /* We allocate something even for n_maps == 0 */
 3012 bruce                     125               6 :         pg_free(mappings);
                                126                 :     }
 4715                           127               1 : }
                                128                 : 
                                129                 : /*
                                130                 :  * transfer_single_new_db()
                                131                 :  *
                                132                 :  * create links for mappings stored in "maps" array.
                                133                 :  */
                                134                 : static void
 2588 rhaas                     135               6 : transfer_single_new_db(FileNameMap *maps, int size, char *old_tablespace)
                                136                 : {
                                137                 :     int         mapnum;
 2585                           138               6 :     bool        vm_must_add_frozenbit = false;
                                139                 : 
                                140                 :     /*
                                141                 :      * Do we need to rewrite visibilitymap?
                                142                 :      */
                                143               6 :     if (old_cluster.controldata.cat_ver < VISIBILITY_MAP_FROZEN_BIT_CAT_VER &&
 2585 rhaas                     144 UIC           0 :         new_cluster.controldata.cat_ver >= VISIBILITY_MAP_FROZEN_BIT_CAT_VER)
                                145               0 :         vm_must_add_frozenbit = true;
                                146                 : 
 4715 bruce                     147 GIC        1264 :     for (mapnum = 0; mapnum < size; mapnum++)
                                148                 :     {
 3742                           149            1258 :         if (old_tablespace == NULL ||
 3742 bruce                     150 UIC           0 :             strcmp(maps[mapnum].old_tablespace, old_tablespace) == 0)
                                151                 :         {
                                152                 :             /* transfer primary file */
 2585 rhaas                     153 GIC        1258 :             transfer_relfile(&maps[mapnum], "", vm_must_add_frozenbit);
                                154                 : 
                                155                 :             /*
                                156                 :              * Copy/link any fsm and vm files, if they exist
                                157                 :              */
  915 bruce                     158            1258 :             transfer_relfile(&maps[mapnum], "_fsm", vm_must_add_frozenbit);
  481 tgl                       159            1258 :             transfer_relfile(&maps[mapnum], "_vm", vm_must_add_frozenbit);
                                160                 :         }
                                161                 :     }
 4715 bruce                     162               6 : }
                                163                 : 
                                164                 : 
                                165                 : /*
                                166                 :  * transfer_relfile()
                                167                 :  *
                                168                 :  * Copy or link file from old cluster to new one.  If vm_must_add_frozenbit
                                169                 :  * is true, visibility map forks are converted and rewritten, even in link
                                170                 :  * mode.
                                171                 :  */
                                172                 : static void
 2585 rhaas                     173            3774 : transfer_relfile(FileNameMap *map, const char *type_suffix, bool vm_must_add_frozenbit)
                                174                 : {
                                175                 :     char        old_file[MAXPGPATH];
                                176                 :     char        new_file[MAXPGPATH];
                                177                 :     int         segno;
                                178                 :     char        extent_suffix[65];
                                179                 :     struct stat statbuf;
                                180                 : 
                                181                 :     /*
                                182                 :      * Now copy/link any related segments as well. Remember, PG breaks large
                                183                 :      * files into 1GB segments, the first segment has no extension, subsequent
                                184                 :      * segments are named relfilenumber.1, relfilenumber.2, relfilenumber.3.
                                185                 :      */
 3798 bruce                     186            5335 :     for (segno = 0;; segno++)
                                187                 :     {
                                188            5335 :         if (segno == 0)
                                189            3774 :             extent_suffix[0] = '\0';
                                190                 :         else
                                191            1561 :             snprintf(extent_suffix, sizeof(extent_suffix), ".%d", segno);
                                192                 : 
  193 rhaas                     193            5335 :         snprintf(old_file, sizeof(old_file), "%s%s/%u/%u%s%s",
                                194                 :                  map->old_tablespace,
                                195                 :                  map->old_tablespace_suffix,
                                196                 :                  map->db_oid,
                                197                 :                  map->relfilenumber,
                                198                 :                  type_suffix,
                                199                 :                  extent_suffix);
                                200            5335 :         snprintf(new_file, sizeof(new_file), "%s%s/%u/%u%s%s",
                                201                 :                  map->new_tablespace,
                                202                 :                  map->new_tablespace_suffix,
                                203                 :                  map->db_oid,
                                204                 :                  map->relfilenumber,
                                205                 :                  type_suffix,
                                206                 :                  extent_suffix);
                                207                 : 
                                208                 :         /* Is it an extent, fsm, or vm file? */
 3798 bruce                     209            5335 :         if (type_suffix[0] != '\0' || segno != 0)
                                210                 :         {
                                211                 :             /* Did file open fail? */
 2585 rhaas                     212            4077 :             if (stat(old_file, &statbuf) != 0)
                                213                 :             {
                                214                 :                 /* File does not exist?  That's OK, just return */
 3798 bruce                     215            3773 :                 if (errno == ENOENT)
                                216            3773 :                     return;
                                217                 :                 else
  271 tgl                       218 UNC           0 :                     pg_fatal("error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s",
                                219                 :                              map->nspname, map->relname, old_file, new_file,
 2382 tgl                       220 UIC           0 :                              strerror(errno));
                                221                 :             }
                                222                 : 
                                223                 :             /* If file is empty, just return */
 2585 rhaas                     224 GIC         304 :             if (statbuf.st_size == 0)
                                225               1 :                 return;
                                226                 :         }
                                227                 : 
 3798 bruce                     228            1561 :         unlink(new_file);
                                229                 : 
                                230                 :         /* Copying files might take some time, so give feedback. */
 3775                           231            1561 :         pg_log(PG_STATUS, "%s", old_file);
                                232                 : 
 2382 tgl                       233            1561 :         if (vm_must_add_frozenbit && strcmp(type_suffix, "_vm") == 0)
                                234                 :         {
                                235                 :             /* Need to rewrite visibility map format */
  271 tgl                       236 UNC           0 :             pg_log(PG_VERBOSE, "rewriting \"%s\" to \"%s\"",
                                237                 :                    old_file, new_file);
 2382 tgl                       238 UIC           0 :             rewriteVisibilityMap(old_file, new_file, map->nspname, map->relname);
                                239                 :         }
                                240                 :         else
 1614 peter_e                   241 GIC        1561 :             switch (user_opts.transfer_mode)
                                242                 :             {
 1614 peter_e                   243 UIC           0 :                 case TRANSFER_MODE_CLONE:
  271 tgl                       244 UNC           0 :                     pg_log(PG_VERBOSE, "cloning \"%s\" to \"%s\"",
                                245                 :                            old_file, new_file);
 1614 peter_e                   246 UIC           0 :                     cloneFile(old_file, new_file, map->nspname, map->relname);
                                247               0 :                     break;
 1614 peter_e                   248 GIC        1561 :                 case TRANSFER_MODE_COPY:
  271 tgl                       249 GNC        1561 :                     pg_log(PG_VERBOSE, "copying \"%s\" to \"%s\"",
                                250                 :                            old_file, new_file);
 1614 peter_e                   251 GIC        1561 :                     copyFile(old_file, new_file, map->nspname, map->relname);
                                252            1561 :                     break;
 1614 peter_e                   253 UIC           0 :                 case TRANSFER_MODE_LINK:
  271 tgl                       254 UNC           0 :                     pg_log(PG_VERBOSE, "linking \"%s\" to \"%s\"",
                                255                 :                            old_file, new_file);
 1614 peter_e                   256 UIC           0 :                     linkFile(old_file, new_file, map->nspname, map->relname);
                                257                 :             }
                                258                 :     }
                                259                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a