11
11
12
12
#include "pg_upgrade.h"
13
13
14
+ #include <sys/stat.h>
14
15
#include "catalog/pg_class.h"
15
16
#include "access/transam.h"
16
17
17
18
18
19
static void transfer_single_new_db (FileNameMap * maps , int size , char * old_tablespace );
19
- static void transfer_relfile (FileNameMap * map , const char * suffix );
20
+ static void transfer_relfile (FileNameMap * map , const char * suffix , bool vm_must_add_frozenbit );
20
21
21
22
22
23
/*
@@ -132,6 +133,7 @@ transfer_single_new_db(FileNameMap *maps, int size, char *old_tablespace)
132
133
{
133
134
int mapnum ;
134
135
bool vm_crashsafe_match = true;
136
+ bool vm_must_add_frozenbit = false;
135
137
136
138
/*
137
139
* Do the old and new cluster disagree on the crash-safetiness of the vm
@@ -141,23 +143,30 @@ transfer_single_new_db(FileNameMap *maps, int size, char *old_tablespace)
141
143
new_cluster .controldata .cat_ver >= VISIBILITY_MAP_CRASHSAFE_CAT_VER )
142
144
vm_crashsafe_match = false;
143
145
146
+ /*
147
+ * Do we need to rewrite visibilitymap?
148
+ */
149
+ if (old_cluster .controldata .cat_ver < VISIBILITY_MAP_FROZEN_BIT_CAT_VER &&
150
+ new_cluster .controldata .cat_ver >= VISIBILITY_MAP_FROZEN_BIT_CAT_VER )
151
+ vm_must_add_frozenbit = true;
152
+
144
153
for (mapnum = 0 ; mapnum < size ; mapnum ++ )
145
154
{
146
155
if (old_tablespace == NULL ||
147
156
strcmp (maps [mapnum ].old_tablespace , old_tablespace ) == 0 )
148
157
{
149
158
/* transfer primary file */
150
- transfer_relfile (& maps [mapnum ], "" );
159
+ transfer_relfile (& maps [mapnum ], "" , vm_must_add_frozenbit );
151
160
152
161
/* fsm/vm files added in PG 8.4 */
153
162
if (GET_MAJOR_VERSION (old_cluster .major_version ) >= 804 )
154
163
{
155
164
/*
156
165
* Copy/link any fsm and vm files, if they exist
157
166
*/
158
- transfer_relfile (& maps [mapnum ], "_fsm" );
167
+ transfer_relfile (& maps [mapnum ], "_fsm" , vm_must_add_frozenbit );
159
168
if (vm_crashsafe_match )
160
- transfer_relfile (& maps [mapnum ], "_vm" );
169
+ transfer_relfile (& maps [mapnum ], "_vm" , vm_must_add_frozenbit );
161
170
}
162
171
}
163
172
}
@@ -167,17 +176,19 @@ transfer_single_new_db(FileNameMap *maps, int size, char *old_tablespace)
167
176
/*
168
177
* transfer_relfile()
169
178
*
170
- * Copy or link file from old cluster to new one.
179
+ * Copy or link file from old cluster to new one. If vm_must_add_frozenbit
180
+ * is true, visibility map forks are converted and rewritten, even in link
181
+ * mode.
171
182
*/
172
183
static void
173
- transfer_relfile (FileNameMap * map , const char * type_suffix )
184
+ transfer_relfile (FileNameMap * map , const char * type_suffix , bool vm_must_add_frozenbit )
174
185
{
175
186
const char * msg ;
176
187
char old_file [MAXPGPATH ];
177
188
char new_file [MAXPGPATH ];
178
- int fd ;
179
189
int segno ;
180
190
char extent_suffix [65 ];
191
+ struct stat statbuf ;
181
192
182
193
/*
183
194
* Now copy/link any related segments as well. Remember, PG breaks large
@@ -210,7 +221,7 @@ transfer_relfile(FileNameMap *map, const char *type_suffix)
210
221
if (type_suffix [0 ] != '\0' || segno != 0 )
211
222
{
212
223
/* Did file open fail? */
213
- if (( fd = open ( old_file , O_RDONLY , 0 )) == -1 )
224
+ if (stat ( old_file , & statbuf ) != 0 )
214
225
{
215
226
/* File does not exist? That's OK, just return */
216
227
if (errno == ENOENT )
@@ -220,7 +231,10 @@ transfer_relfile(FileNameMap *map, const char *type_suffix)
220
231
map -> nspname , map -> relname , old_file , new_file ,
221
232
getErrorText ());
222
233
}
223
- close (fd );
234
+
235
+ /* If file is empty, just return */
236
+ if (statbuf .st_size == 0 )
237
+ return ;
224
238
}
225
239
226
240
unlink (new_file );
@@ -232,15 +246,27 @@ transfer_relfile(FileNameMap *map, const char *type_suffix)
232
246
{
233
247
pg_log (PG_VERBOSE , "copying \"%s\" to \"%s\"\n" , old_file , new_file );
234
248
235
- if ((msg = copyFile (old_file , new_file , true)) != NULL )
249
+ /* Rewrite visibility map if needed */
250
+ if (vm_must_add_frozenbit && (strcmp (type_suffix , "_vm" ) == 0 ))
251
+ msg = rewriteVisibilityMap (old_file , new_file , true);
252
+ else
253
+ msg = copyFile (old_file , new_file , true);
254
+
255
+ if (msg )
236
256
pg_fatal ("error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" ,
237
257
map -> nspname , map -> relname , old_file , new_file , msg );
238
258
}
239
259
else
240
260
{
241
261
pg_log (PG_VERBOSE , "linking \"%s\" to \"%s\"\n" , old_file , new_file );
242
262
243
- if ((msg = linkFile (old_file , new_file )) != NULL )
263
+ /* Rewrite visibility map if needed */
264
+ if (vm_must_add_frozenbit && (strcmp (type_suffix , "_vm" ) == 0 ))
265
+ msg = rewriteVisibilityMap (old_file , new_file , true);
266
+ else
267
+ msg = linkFile (old_file , new_file );
268
+
269
+ if (msg )
244
270
pg_fatal ("error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" ,
245
271
map -> nspname , map -> relname , old_file , new_file , msg );
246
272
}
0 commit comments