@@ -306,13 +306,42 @@ static void unpin_by_checkpoint_callback(FT ft, void *extra) {
306
306
}
307
307
308
308
// maps to cf->note_unpin_by_checkpoint
309
- // Must be protected by ydb lock.
310
- // Called by end_checkpoint, which grabs ydb lock around note_unpin
309
+ // Must be protected by ydb lock.
310
+ // Called by end_checkpoint, which grabs ydb lock around note_unpin
311
311
static void ft_note_unpin_by_checkpoint (CACHEFILE UU (cachefile), void *header_v) {
312
312
FT ft = (FT) header_v;
313
313
toku_ft_remove_reference (ft, false , ZERO_LSN, unpin_by_checkpoint_callback, NULL );
314
314
}
315
315
316
+
317
+ // maps to cf->note_pin_by_backup
318
+ // Must be protected by ydb lock.
319
+ // Is only called by backup begin, which holds it
320
+ static void ft_note_pin_by_backup (CACHEFILE UU (cachefile), void *header_v) {
321
+ // Note: open_close lock is held by checkpoint begin
322
+ FT ft = (FT) header_v;
323
+ toku_ft_grab_reflock (ft);
324
+ assert (toku_ft_needed_unlocked (ft));
325
+ ft->num_backups ++;
326
+ toku_ft_release_reflock (ft);
327
+ }
328
+
329
+ // Requires: the reflock is held.
330
+ static void unpin_by_backup_callback (FT ft, void *extra) {
331
+ invariant (extra == NULL );
332
+ invariant (ft->num_backups > 0 );
333
+ ft->num_backups --;
334
+ }
335
+
336
+ // maps to cf->note_unpin_by_backup
337
+ // Must be protected by ydb lock.
338
+ // Called by end_backup, which grabs ydb lock around note_unpin
339
+ static void ft_note_unpin_by_backup (CACHEFILE UU (cachefile), void *header_v) {
340
+ FT ft = (FT) header_v;
341
+ toku_ft_remove_reference (ft, false , ZERO_LSN, unpin_by_backup_callback, NULL );
342
+ }
343
+
344
+
316
345
//
317
346
// End of Functions that are callbacks to the cachefile
318
347
// ///////////////////////////////////////////////////////////////////////
@@ -332,38 +361,33 @@ static void setup_initial_ft_root_node(FT ft, BLOCKNUM blocknum) {
332
361
}
333
362
334
363
static void ft_init (FT ft, FT_OPTIONS options, CACHEFILE cf) {
335
- // fake, prevent unnecessary upgrade logic
336
- ft->layout_version_read_from_disk = FT_LAYOUT_VERSION;
337
- ft->checkpoint_header = NULL ;
364
+ // fake, prevent unnecessary upgrade logic
365
+ ft->layout_version_read_from_disk = FT_LAYOUT_VERSION;
366
+ ft->checkpoint_header = NULL ;
338
367
339
- toku_list_init (&ft->live_ft_handles );
368
+ toku_list_init (&ft->live_ft_handles );
340
369
341
- // intuitively, the comparator points to the FT's cmp descriptor
342
- ft->cmp .create (options->compare_fun , &ft->cmp_descriptor , options->memcmp_magic );
343
- ft->update_fun = options->update_fun ;
370
+ // intuitively, the comparator points to the FT's cmp descriptor
371
+ ft->cmp .create (options->compare_fun , &ft->cmp_descriptor ,
372
+ options->memcmp_magic );
373
+ ft->update_fun = options->update_fun ;
344
374
345
- if (ft->cf != NULL ) {
346
- assert (ft->cf == cf);
347
- }
348
- ft->cf = cf;
349
- ft->in_memory_stats = ZEROSTATS;
375
+ if (ft->cf != NULL ) {
376
+ assert (ft->cf == cf);
377
+ }
378
+ ft->cf = cf;
379
+ ft->in_memory_stats = ZEROSTATS;
350
380
351
- setup_initial_ft_root_node (ft, ft->h ->root_blocknum );
352
- toku_cachefile_set_userdata (ft->cf ,
353
- ft,
354
- ft_log_fassociate_during_checkpoint,
355
- ft_close,
356
- ft_free,
357
- ft_checkpoint,
358
- ft_begin_checkpoint,
359
- ft_end_checkpoint,
360
- ft_note_pin_by_checkpoint,
361
- ft_note_unpin_by_checkpoint);
381
+ setup_initial_ft_root_node (ft, ft->h ->root_blocknum );
382
+ toku_cachefile_set_userdata (
383
+ ft->cf , ft, ft_log_fassociate_during_checkpoint, ft_close, ft_free,
384
+ ft_checkpoint, ft_begin_checkpoint, ft_end_checkpoint,
385
+ ft_note_pin_by_checkpoint, ft_note_unpin_by_checkpoint,
386
+ ft_note_pin_by_backup, ft_note_unpin_by_backup);
362
387
363
- ft->blocktable .verify_no_free_blocknums ();
388
+ ft->blocktable .verify_no_free_blocknums ();
364
389
}
365
390
366
-
367
391
static FT_HEADER
368
392
ft_header_create (FT_OPTIONS options, BLOCKNUM root_blocknum, TXNID root_xid_that_created)
369
393
{
@@ -455,7 +479,9 @@ int toku_read_ft_and_store_in_cachefile (FT_HANDLE ft_handle, CACHEFILE cf, LSN
455
479
ft_begin_checkpoint,
456
480
ft_end_checkpoint,
457
481
ft_note_pin_by_checkpoint,
458
- ft_note_unpin_by_checkpoint);
482
+ ft_note_unpin_by_checkpoint,
483
+ ft_note_pin_by_backup,
484
+ ft_note_unpin_by_backup);
459
485
*header = ft;
460
486
return 0 ;
461
487
}
@@ -475,7 +501,7 @@ static int
475
501
ft_get_reference_count (FT ft) {
476
502
uint32_t pinned_by_checkpoint = ft->pinned_by_checkpoint ? 1 : 0 ;
477
503
int num_handles = toku_list_num_elements_est (&ft->live_ft_handles );
478
- return pinned_by_checkpoint + ft->num_txns + num_handles;
504
+ return pinned_by_checkpoint + ft->num_txns + ft-> num_backups + num_handles;
479
505
}
480
506
481
507
// a ft is needed in memory iff its reference count is non-zero
0 commit comments