@@ -239,3 +239,144 @@ def test_retention_window_pinning(self):
239
239
240
240
# Clean after yourself
241
241
self .del_test_dir (module_name , fname )
242
+
243
+ # @unittest.skip("skip")
244
+ def test_wal_retention_and_pinning (self ):
245
+ """
246
+ B1---B2---P---B3--->
247
+ wal-depth=2
248
+ P - pinned backup
249
+
250
+ expected result after WAL purge:
251
+ B1 B2---P---B3--->
252
+
253
+ """
254
+ fname = self .id ().split ('.' )[3 ]
255
+ node = self .make_simple_node (
256
+ base_dir = os .path .join (module_name , fname , 'node' ),
257
+ initdb_params = ['--data-checksums' ])
258
+
259
+ backup_dir = os .path .join (self .tmp_path , module_name , fname , 'backup' )
260
+ self .init_pb (backup_dir )
261
+ self .add_instance (backup_dir , 'node' , node )
262
+ self .set_archiving (backup_dir , 'node' , node )
263
+ node .slow_start ()
264
+
265
+ # take FULL BACKUP
266
+ self .backup_node (
267
+ backup_dir , 'node' , node , options = ['--stream' ])
268
+
269
+ node .pgbench_init (scale = 1 )
270
+
271
+ # Take PAGE BACKUP
272
+ self .backup_node (
273
+ backup_dir , 'node' , node ,
274
+ backup_type = 'page' , options = ['--stream' ])
275
+
276
+ node .pgbench_init (scale = 1 )
277
+
278
+ # Take DELTA BACKUP and pin it
279
+ expire_time = "{:%Y-%m-%d %H:%M:%S}" .format (
280
+ datetime .now () + timedelta (days = 6 ))
281
+ backup_id_pinned = self .backup_node (
282
+ backup_dir , 'node' , node ,
283
+ backup_type = 'delta' ,
284
+ options = [
285
+ '--stream' ,
286
+ '--expire-time={0}' .format (expire_time )])
287
+
288
+ node .pgbench_init (scale = 1 )
289
+
290
+ # Take second PAGE BACKUP
291
+ self .backup_node (
292
+ backup_dir , 'node' , node , backup_type = 'delta' , options = ['--stream' ])
293
+
294
+ node .pgbench_init (scale = 1 )
295
+
296
+ # Purge backups
297
+ out = self .delete_expired (
298
+ backup_dir , 'node' ,
299
+ options = [
300
+ '--log-level-console=LOG' ,
301
+ '--delete-wal' , '--wal-depth=2' ])
302
+
303
+ # print(out)
304
+ self .assertIn (
305
+ 'Pinned backup {0} is ignored for the '
306
+ 'purpose of WAL retention' .format (backup_id_pinned ),
307
+ out )
308
+
309
+ for instance in self .show_archive (backup_dir ):
310
+ timelines = instance ['timelines' ]
311
+
312
+ # sanity
313
+ for timeline in timelines :
314
+ self .assertEqual (timeline ['min-segno' ], '0000000000000004' )
315
+ self .assertEqual (timeline ['status' ], 'OK' )
316
+
317
+ # Clean after yourself
318
+ self .del_test_dir (module_name , fname )
319
+
320
+ # @unittest.skip("skip")
321
+ def test_wal_retention_and_pinning_1 (self ):
322
+ """
323
+ P---B1--->
324
+ wal-depth=2
325
+ P - pinned backup
326
+
327
+ expected result after WAL purge:
328
+ P---B1--->
329
+
330
+ """
331
+ fname = self .id ().split ('.' )[3 ]
332
+ node = self .make_simple_node (
333
+ base_dir = os .path .join (module_name , fname , 'node' ),
334
+ initdb_params = ['--data-checksums' ])
335
+
336
+ backup_dir = os .path .join (self .tmp_path , module_name , fname , 'backup' )
337
+ self .init_pb (backup_dir )
338
+ self .add_instance (backup_dir , 'node' , node )
339
+ self .set_archiving (backup_dir , 'node' , node )
340
+ node .slow_start ()
341
+
342
+ expire_time = "{:%Y-%m-%d %H:%M:%S}" .format (
343
+ datetime .now () + timedelta (days = 6 ))
344
+
345
+ # take FULL BACKUP
346
+ backup_id_pinned = self .backup_node (
347
+ backup_dir , 'node' , node ,
348
+ options = ['--expire-time={0}' .format (expire_time )])
349
+
350
+ node .pgbench_init (scale = 2 )
351
+
352
+ # Take second PAGE BACKUP
353
+ self .backup_node (
354
+ backup_dir , 'node' , node , backup_type = 'delta' )
355
+
356
+ node .pgbench_init (scale = 2 )
357
+
358
+ # Purge backups
359
+ out = self .delete_expired (
360
+ backup_dir , 'node' ,
361
+ options = [
362
+ '--log-level-console=verbose' ,
363
+ '--delete-wal' , '--wal-depth=2' ])
364
+
365
+ print (out )
366
+ self .assertIn (
367
+ 'Pinned backup {0} is ignored for the '
368
+ 'purpose of WAL retention' .format (backup_id_pinned ),
369
+ out )
370
+
371
+ for instance in self .show_archive (backup_dir ):
372
+ timelines = instance ['timelines' ]
373
+
374
+ # sanity
375
+ for timeline in timelines :
376
+ self .assertEqual (timeline ['min-segno' ], '0000000000000002' )
377
+ self .assertEqual (timeline ['status' ], 'OK' )
378
+
379
+ self .validate_pb (backup_dir )
380
+
381
+ # Clean after yourself
382
+ self .del_test_dir (module_name , fname )
0 commit comments