Skip to content

Commit 5f06a23

Browse files
committed
fix bug in pm_buf_read that read the NULL list even though TOID_IS_NULL() return not null
1 parent f7b2d3f commit 5f06a23

File tree

3 files changed

+91
-55
lines changed

3 files changed

+91
-55
lines changed

storage/innobase/include/my_pmemobj.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,8 @@ struct __pmem_buf_bucket_stat {
363363
uint64_t n_writes;/*number of writes on the bucket*/
364364
uint64_t n_overwrites;/*number of overwrites on the bucket*/
365365
uint64_t n_reads;/*number of reads on the list (both flushing and normal)*/
366-
uint64_t n_reads_flushing;/*number of reads on the on-flushing list*/
366+
uint64_t n_reads_hit;/*number of reads successful on PMEM buffer*/
367+
uint64_t n_reads_flushing;/*number of reads on the on-flushing list, n_reads_flushing < n_reads_hit < n_reads*/
367368
uint64_t max_linked_lists;
368369
uint64_t n_flushed_lists; /*number of of flushes on the bucket*/
369370
};

storage/innobase/log/log0recv.cc

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2705,7 +2705,6 @@ recv_apply_hashed_log_recs(
27052705
mutex_exit(&(recv_sys->mutex));
27062706

27072707
if (buf_page_peek(page_id)) {
2708-
//tdnguyen test
27092708
buf_block_t* block;
27102709

27112710
mtr_start(&mtr);
@@ -2720,13 +2719,7 @@ recv_apply_hashed_log_recs(
27202719
recv_recover_page(FALSE, block);
27212720
mtr_commit(&mtr);
27222721
} else {
2723-
//printf("i = %zu case 2: space_no %zu page_no %zu start...", i, page_id.space(), page_id.page_no());
2724-
//if (i == 9628) {
2725-
// ulint test_break = 1;
2726-
//}
2727-
//printf("recv_read_in_area run space_no %zu page_no %zu...", page_id.space(), page_id.page_no());
27282722
recv_read_in_area(page_id);
2729-
//printf(" case2 ended \n");
27302723
}
27312724

27322725
mutex_enter(&(recv_sys->mutex));

storage/innobase/pmem/pmem0buf.cc

Lines changed: 89 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ static uint64_t PMEM_N_FLUSH_THREADS;
3737
static uint64_t PMEM_N_BUCKET_BITS = 8;
3838
static uint64_t PMEM_N_SPACE_BITS = 5;
3939
static uint64_t PMEM_PAGE_PER_BUCKET_BITS=10;
40+
// 1 < this_value < flusher->size
41+
static uint64_t PMEM_FLUSHER_WAKE_THRESHOLD=5;
4042

4143
static FILE* debug_file = fopen("part_debug.txt","w");
4244

@@ -190,35 +192,35 @@ pm_wrapper_buf_alloc_or_open(
190192
pmw->pbuf->cur_free_param = 0; //start with the 0
191193

192194
//Open file
193-
pmw->pbuf->deb_file = fopen("part_debug.txt","w");
195+
pmw->pbuf->deb_file = fopen("pmem_debug.txt","w");
194196

195-
////test for recovery
196-
printf("========== > Test for recovery\n");
197-
TOID(PMEM_BUF_BLOCK_LIST) cur_list;
198-
PMEM_BUF_BLOCK_LIST* pcurlist;
199-
200-
printf("The bucket ====\n");
201-
for (i = 0; i < PMEM_N_BUCKETS; i++) {
202-
TOID_ASSIGN(cur_list, (D_RW(pmw->pbuf->buckets)[i]).oid);
203-
plist = D_RW(cur_list);
204-
printf("list %zu is_flush %d cur_pages %zu max_pages %zu\n",plist->list_id, plist->is_flush, plist->cur_pages, plist->max_pages );
205-
206-
TOID_ASSIGN(cur_list, (D_RW(cur_list)->next_list).oid);
207-
printf("\t[next list \n");
208-
while( !TOID_IS_NULL(cur_list)) {
209-
plist = D_RW(cur_list);
210-
printf("\t\t next list %zu is_flush %d cur_pages %zu max_pages %zu\n",plist->list_id, plist->is_flush, plist->cur_pages, plist->max_pages );
211-
TOID_ASSIGN(cur_list, (D_RW(cur_list)->next_list).oid);
212-
}
213-
printf("\t end next list] \n");
214-
215-
//print the linked-list
216-
217-
}
218-
printf("The free pool ====\n");
219-
PMEM_BUF_FREE_POOL* pfree_pool = D_RW(pmw->pbuf->free_pool);
220-
printf("cur_lists = %zu max_lists=%zu\n",
221-
pfree_pool->cur_lists, pfree_pool->max_lists);
197+
// ////test for recovery
198+
// printf("========== > Test for recovery\n");
199+
// TOID(PMEM_BUF_BLOCK_LIST) cur_list;
200+
// PMEM_BUF_BLOCK_LIST* pcurlist;
201+
//
202+
// printf("The bucket ====\n");
203+
// for (i = 0; i < PMEM_N_BUCKETS; i++) {
204+
// TOID_ASSIGN(cur_list, (D_RW(pmw->pbuf->buckets)[i]).oid);
205+
// plist = D_RW(cur_list);
206+
// printf("list %zu is_flush %d cur_pages %zu max_pages %zu\n",plist->list_id, plist->is_flush, plist->cur_pages, plist->max_pages );
207+
//
208+
// TOID_ASSIGN(cur_list, (D_RW(cur_list)->next_list).oid);
209+
// printf("\t[next list \n");
210+
// while( !TOID_IS_NULL(cur_list)) {
211+
// plist = D_RW(cur_list);
212+
// printf("\t\t next list %zu is_flush %d cur_pages %zu max_pages %zu\n",plist->list_id, plist->is_flush, plist->cur_pages, plist->max_pages );
213+
// TOID_ASSIGN(cur_list, (D_RW(cur_list)->next_list).oid);
214+
// }
215+
// printf("\t end next list] \n");
216+
//
217+
// //print the linked-list
218+
//
219+
// }
220+
// printf("The free pool ====\n");
221+
// PMEM_BUF_FREE_POOL* pfree_pool = D_RW(pmw->pbuf->free_pool);
222+
// printf("cur_lists = %zu max_lists=%zu\n",
223+
// pfree_pool->cur_lists, pfree_pool->max_lists);
222224

223225
}
224226

@@ -1238,9 +1240,10 @@ pm_buf_write_with_flusher(
12381240
pm_buf_handle_full_hashed_list(pop, buf, hashed);
12391241
goto retry;
12401242
}
1241-
1242-
//printf("\n wait for list %zu cur_pages = %zu max_pages= %zu flushing....",
1243-
//phashlist->list_id, phashlist->cur_pages, phashlist->max_pages);
1243+
#if defined (UNIV_PMEMOBJ_BUF_RECOVERY_DEBUG)
1244+
printf("\n wait for list %zu cur_pages = %zu max_pages= %zu flushing....",
1245+
phashlist->list_id, phashlist->cur_pages, phashlist->max_pages);
1246+
#endif
12441247

12451248
pmemobj_rwlock_unlock(pop, &phashlist->lock);
12461249
os_event_wait(buf->flush_events[hashed]);
@@ -1360,6 +1363,10 @@ pm_buf_write_with_flusher(
13601363
//block upcomming writes into this bucket
13611364
os_event_reset(buf->flush_events[hashed]);
13621365

1366+
#if defined (UNIV_PMEMOBJ_BUF_STAT)
1367+
++buf->bucket_stats[hashed].n_flushed_lists;
1368+
#endif
1369+
13631370
pmemobj_rwlock_unlock(pop, &phashlist->lock);
13641371
pm_buf_handle_full_hashed_list(pop, buf, hashed);
13651372

@@ -2034,6 +2041,11 @@ pm_buf_read(
20342041
#endif
20352042

20362043
TOID_ASSIGN(cur_list, (D_RO(buf->buckets)[hashed]).oid);
2044+
2045+
#if defined(UNIV_PMEMOBJ_BUF_STAT)
2046+
++buf->bucket_stats[hashed].n_reads;
2047+
#endif
2048+
20372049
if ( TOID_IS_NULL(cur_list)) {
20382050
//assert(!TOID_IS_NULL(cur_list));
20392051
printf("PMEM_ERROR error in get hashded list, but return NULL, check again! \n");
@@ -2045,11 +2057,15 @@ pm_buf_read(
20452057
//pblock = NULL;
20462058
//found = -1;
20472059

2048-
while ( !TOID_IS_NULL(cur_list) ) {
2060+
while ( !TOID_IS_NULL(cur_list) && (D_RO(cur_list) != NULL) ) {
20492061
//plist = D_RW(cur_list);
20502062
//pmemobj_rwlock_rdlock(pop, &plist->lock);
20512063
//Scan in this list
20522064
//for (i = 0; i < D_RO(cur_list)->max_pages; i++) {
2065+
if (D_RO(cur_list) == NULL) {
2066+
printf("===> ERROR read NULL list \n");
2067+
assert(0);
2068+
}
20532069
for (i = 0; i < D_RO(cur_list)->cur_pages; i++) {
20542070
//accepted states: PMEM_IN_USED_BLOCK, PMEM_IN_FLUSH_BLOCK
20552071
//if ( D_RO(D_RO(plist->arr)[i])->state != PMEM_FREE_BLOCK &&
@@ -2060,30 +2076,21 @@ pm_buf_read(
20602076
//if(is_lock_on_read)
20612077
pmemobj_rwlock_rdlock(pop, &pblock->lock);
20622078

2063-
//if (!pblock->size.equals_to(size)) {
2064-
// printf("PMEM_ERROR size not equal!!!\n");
2065-
// assert(0);
2066-
//}
2067-
//found = i;
20682079
pdata = buf->p_align;
20692080

2070-
//UNIV_MEM_ASSERT_RW(data, pblock->size.physical());
2071-
//pmemobj_memcpy_persist(pop, data, pdata + pblock->pmemaddr, pblock->size.physical());
2072-
//memcpy(data, pdata + D_RO(D_RO(D_RO(cur_list)->arr)[i])->pmemaddr, D_RO(D_RO(D_RO(cur_list)->arr)[i])->size.physical());
20732081
memcpy(data, pdata + pblock->pmemaddr, pblock->size.physical());
20742082
//bytes_read = pblock->size.physical();
20752083
#if defined (UNIV_PMEMOBJ_DEBUG)
20762084
assert( pm_check_io(pdata + pblock->pmemaddr, pblock->id) ) ;
20772085
#endif
20782086
#if defined(UNIV_PMEMOBJ_BUF_STAT)
2079-
++buf->bucket_stats[hashed].n_reads;
2087+
++buf->bucket_stats[hashed].n_reads_hit;
20802088
if (D_RO(cur_list)->is_flush)
20812089
++buf->bucket_stats[hashed].n_reads_flushing;
20822090
#endif
20832091
//if(is_lock_on_read)
20842092
pmemobj_rwlock_unlock(pop, &pblock->lock);
20852093

2086-
//return bytes_read;
20872094
//return pblock;
20882095
return D_RO(D_RO(D_RO(cur_list)->arr)[i]);
20892096
}
@@ -2093,6 +2100,9 @@ pm_buf_read(
20932100
if ( TOID_IS_NULL(D_RO(cur_list)->next_list))
20942101
break;
20952102
TOID_ASSIGN(cur_list, (D_RO(cur_list)->next_list).oid);
2103+
if (TOID_IS_NULL(cur_list) || D_RO(cur_list) == NULL)
2104+
break;
2105+
20962106
#if defined(UNIV_PMEMOBJ_BUF_STAT)
20972107
cur_level++;
20982108
if (buf->bucket_stats[hashed].max_linked_lists < cur_level)
@@ -2341,11 +2351,11 @@ pm_buf_handle_full_hashed_list(
23412351

23422352
/*(1) Handle flusher */
23432353
#if defined (UNIV_PMEMOBJ_BUF_RECOVERY_DEBUG)
2344-
printf("\n[ begin handle assign flusher list %zu hashed %zu ===> ", phashlist->list_id, hashed);
2354+
printf("\n[(1) begin handle assign flusher list %zu hashed %zu ===> ", phashlist->list_id, hashed);
23452355
#endif
23462356
pm_buf_assign_flusher(buf, phashlist);
23472357
#if defined (UNIV_PMEMOBJ_BUF_RECOVERY_DEBUG)
2348-
printf("end handle assign flusher list %zu]\n", phashlist->list_id);
2358+
printf("(1) end handle assign flusher list %zu]\n", phashlist->list_id);
23492359
#endif
23502360

23512361

@@ -2359,6 +2369,9 @@ pm_buf_handle_full_hashed_list(
23592369

23602370
/* (2) Handle free list*/
23612371
get_free_list:
2372+
#if defined (UNIV_PMEMOBJ_BUF_RECOVERY_DEBUG)
2373+
printf("\n (2) begin get_free_list to replace full list %zu ==>", phashlist->list_id);
2374+
#endif
23622375
//Get a free list from the free pool
23632376
pmemobj_rwlock_wrlock(pop, &(D_RW(buf->free_pool)->lock));
23642377

@@ -2393,6 +2406,9 @@ pm_buf_handle_full_hashed_list(
23932406
TOID_ASSIGN( D_RW(first_list)->next_list, hash_list.oid);
23942407
TOID_ASSIGN( D_RW(hash_list)->prev_list, first_list.oid);
23952408

2409+
#if defined (UNIV_PMEMOBJ_BUF_RECOVERY_DEBUG)
2410+
printf("\n (2) end get_free_list %zu to replace full list %zu ==>", D_RW(first_list)->list_id, phashlist->list_id);
2411+
#endif
23962412

23972413
#if defined (UNIV_PMEMOBJ_BUF_STAT)
23982414
if ( !TOID_IS_NULL( D_RW(hash_list)->next_list ))
@@ -2437,7 +2453,8 @@ pm_buf_assign_flusher(
24372453
++flusher->n_requested;
24382454
//delay calling flush up to a threshold
24392455
//printf("trigger worker...\n");
2440-
if (flusher->n_requested == flusher->size - 2) {
2456+
//if (flusher->n_requested == flusher->size - 2) {
2457+
if (flusher->n_requested == PMEM_FLUSHER_WAKE_THRESHOLD) {
24412458
os_event_set(flusher->is_req_not_empty);
24422459
}
24432460

@@ -2508,7 +2525,7 @@ pm_filemap_init(
25082525
#define PMEM_BUF_BUCKET_STAT_PRINT(pb, index) do {\
25092526
assert (0 <= index && index <= PMEM_N_BUCKETS);\
25102527
PMEM_BUCKET_STAT* p = &pb->bucket_stats[index];\
2511-
printf("bucket %d [n_writes %zu,\t n_overwrites %zu,\t n_reads %zu, n_reads_flushing %zu \tmax_linked_lists %zu, \tn_flushed_lists %zu] \n ",index, p->n_writes, p->n_overwrites, p->n_reads, p->n_reads_flushing, p->max_linked_lists, p->n_flushed_lists); \
2528+
printf("bucket %zu [n_writes %zu,\t n_overwrites %zu,\t n_reads %zu, n_reads_hit %zu, n_reads_flushing %zu \tmax_linked_lists %zu, \tn_flushed_lists %zu] \n ",index, p->n_writes, p->n_overwrites, p->n_reads, p->n_reads_hit, p->n_reads_flushing, p->max_linked_lists, p->n_flushed_lists); \
25122529
}while (0)
25132530

25142531

@@ -2520,7 +2537,7 @@ void pm_buf_bucket_stat_init(PMEM_BUF* pbuf) {
25202537

25212538
for (i = 0; i < PMEM_N_BUCKETS; i++) {
25222539
arr[i].n_writes = arr[i].n_overwrites =
2523-
arr[i].n_reads = arr[i].n_reads_flushing = arr[i].max_linked_lists =
2540+
arr[i].n_reads = arr[i].n_reads_hit = arr[i].n_reads_flushing = arr[i].max_linked_lists =
25242541
arr[i].n_flushed_lists = 0;
25252542
}
25262543
pbuf->bucket_stats = arr;
@@ -2529,10 +2546,35 @@ void pm_buf_bucket_stat_init(PMEM_BUF* pbuf) {
25292546
void pm_buf_stat_print_all(PMEM_BUF* pbuf) {
25302547
ulint i;
25312548
PMEM_BUCKET_STAT* arr = pbuf->bucket_stats;
2549+
PMEM_BUCKET_STAT sumstat;
2550+
2551+
sumstat.n_writes = sumstat.n_overwrites =
2552+
sumstat.n_reads = sumstat.n_reads_hit = sumstat.n_reads_flushing = sumstat.max_linked_lists = sumstat.n_flushed_lists = 0;
2553+
25322554

25332555
for (i = 0; i < PMEM_N_BUCKETS; i++) {
2556+
sumstat.n_writes += arr[i].n_writes;
2557+
sumstat.n_overwrites += arr[i].n_overwrites;
2558+
sumstat.n_reads += arr[i].n_reads;
2559+
sumstat.n_reads_hit += arr[i].n_reads_hit;
2560+
sumstat.n_reads_flushing += arr[i].n_reads_flushing;
2561+
sumstat.n_flushed_lists += arr[i].n_flushed_lists;
2562+
2563+
if (sumstat.max_linked_lists < arr[i].max_linked_lists) {
2564+
sumstat.max_linked_lists = arr[i].max_linked_lists;
2565+
}
2566+
25342567
PMEM_BUF_BUCKET_STAT_PRINT(pbuf, i);
25352568
}
2569+
2570+
printf("\n==========\n Statistic info:\n n_writes\t n_overwrites \t n_reads \t n_reads_hit \t n_reads_flushing \t max_linked_lists \t n_flushed_lists \n %zu \t %zu \t %zu \t %zu \t %zu \t %zu \t %zu \n",
2571+
sumstat.n_writes, sumstat.n_overwrites, sumstat.n_reads, sumstat.n_reads_hit, sumstat.n_reads_flushing, sumstat.max_linked_lists, sumstat.n_flushed_lists);
2572+
printf("\n==========\n");
2573+
2574+
fprintf(pbuf->deb_file, "\n==========\n Statistic info:\n n_writes\t n_overwrites \t n_reads \t n_reads_hit \t n_reads_flushing \t max_linked_lists \t n_flushed_lists \n %zu \t %zu \t %zu \t %zu \t %zu \t %zu \t %zu \n",
2575+
sumstat.n_writes, sumstat.n_overwrites, sumstat.n_reads, sumstat.n_reads_hit, sumstat.n_reads_flushing, sumstat.max_linked_lists, sumstat.n_flushed_lists);
2576+
fprintf(pbuf->deb_file, "\n==========\n");
2577+
25362578
}
25372579

25382580
#endif //UNIV_PMEMOBJ_STAT

0 commit comments

Comments
 (0)