diff options
author | unknown <bell@desktop.sanja.is.com.ua> | 2008-01-12 02:32:00 +0200 |
---|---|---|
committer | unknown <bell@desktop.sanja.is.com.ua> | 2008-01-12 02:32:00 +0200 |
commit | ade002151fb308a02ef6ef3deed6b8be4f5316bd (patch) | |
tree | f30250c43558c8ede34e566d81f709734a60ca9b /storage | |
parent | e689fbc4582de1b5f81cb69d98f5fe54b7064db1 (diff) | |
parent | c2b840bec33cc59d3f56829eaab9c9d9eff34913 (diff) | |
download | mariadb-git-ade002151fb308a02ef6ef3deed6b8be4f5316bd.tar.gz |
Merge desktop.sanja.is.com.ua:/home/bell/mysql/bk/mysql-maria
into desktop.sanja.is.com.ua:/home/bell/mysql/bk/work-maria-pin
storage/maria/ma_loghandler.c:
Auto merged
storage/maria/ma_recovery.c:
Auto merged
Diffstat (limited to 'storage')
-rw-r--r-- | storage/maria/ma_loghandler.c | 209 | ||||
-rw-r--r-- | storage/maria/ma_recovery.c | 12 |
2 files changed, 146 insertions, 75 deletions
diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c index 5b91ca9fa4a..7654fb735d7 100644 --- a/storage/maria/ma_loghandler.c +++ b/storage/maria/ma_loghandler.c @@ -1589,10 +1589,12 @@ static void translog_new_page_header(TRANSLOG_ADDRESS *horizon, cursor->buffer->size+= len; } cursor->ptr= ptr; - DBUG_PRINT("info", ("NewP buffer #%u: 0x%lx chaser: %d Size: %lu (%lu)", + DBUG_PRINT("info", ("NewP buffer #%u: 0x%lx chaser: %d Size: %lu (%lu) " + "Horizon: (%lu,0x%lu)", (uint) cursor->buffer->buffer_no, (ulong) cursor->buffer, cursor->chaser, (ulong) cursor->buffer->size, - (ulong) (cursor->ptr - cursor->buffer->buffer))); + (ulong) (cursor->ptr - cursor->buffer->buffer), + LSN_IN_PARTS(*horizon))); translog_check_cursor(cursor); DBUG_VOID_RETURN; } @@ -2025,10 +2027,12 @@ static void translog_set_sent_to_disk(LSN lsn, TRANSLOG_ADDRESS in_buffers) DBUG_ENTER("translog_set_sent_to_disk"); pthread_mutex_lock(&log_descriptor.sent_to_disk_lock); DBUG_PRINT("enter", ("lsn: (%lu,0x%lx) in_buffers: (%lu,0x%lx) " - "in_buffers_only: (%lu,0x%lx)", + "in_buffers_only: (%lu,0x%lx) " + "sent_to_disk: (%lu,0x%lx)", LSN_IN_PARTS(lsn), LSN_IN_PARTS(in_buffers), - LSN_IN_PARTS(log_descriptor.in_buffers_only))); + LSN_IN_PARTS(log_descriptor.in_buffers_only), + LSN_IN_PARTS(log_descriptor.sent_to_disk))); DBUG_ASSERT(cmp_translog_addr(lsn, log_descriptor.sent_to_disk) >= 0); log_descriptor.sent_to_disk= lsn; /* LSN_IMPOSSIBLE == 0 => it will work for very first time */ @@ -2405,7 +2409,7 @@ static my_bool translog_buffer_flush(struct st_translog_buffer *buffer) { DBUG_PRINT("error", ("Can't write page (%lu,0x%lx) to pagecache, error: %d", - (ulong) buffer->file, + (ulong) buffer->file->number, (ulong) (LSN_OFFSET(buffer->offset)+ i), my_errno)); translog_stop_writing(); @@ -3740,7 +3744,10 @@ my_bool translog_init_with_table(const char *directory, if (readonly) log_descriptor.horizon= last_lsn; else if (translog_truncate_log(last_lsn)) + { + translog_free_record_header(&rec); DBUG_RETURN(1); + } } else { @@ -3762,10 +3769,14 @@ my_bool translog_init_with_table(const char *directory, if (readonly) log_descriptor.horizon= last_lsn; else if (translog_truncate_log(last_lsn)) + { + translog_free_record_header(&rec); DBUG_RETURN(1); + } } } } + translog_free_record_header(&rec); } } @@ -4148,6 +4159,36 @@ static void translog_buffer_decrease_writers(struct st_translog_buffer *buffer) } +/** + @brief Skip to the next page for chaser (thread which advanced horizon + pointer and now feeling the buffer) + + @param horizon \ Pointers on file position and buffer + @param cursor / + + @retval 1 OK + @retval 0 Error +*/ + +static my_bool translog_chaser_page_next(TRANSLOG_ADDRESS *horizon, + struct st_buffer_cursor *cursor) +{ + struct st_translog_buffer *buffer_to_flush; + my_bool rc; + DBUG_ENTER("translog_chaser_page_next"); + DBUG_ASSERT(cursor->chaser); + rc= translog_page_next(horizon, cursor, &buffer_to_flush); + if (buffer_to_flush != NULL) + { + translog_buffer_lock(buffer_to_flush); + translog_buffer_decrease_writers(buffer_to_flush); + if (!rc) + rc= translog_buffer_flush(buffer_to_flush); + translog_buffer_unlock(buffer_to_flush); + } + DBUG_RETURN(rc); +} + /* Put chunk 2 from new page beginning @@ -4167,22 +4208,11 @@ translog_write_variable_record_chunk2_page(struct st_translog_parts *parts, TRANSLOG_ADDRESS *horizon, struct st_buffer_cursor *cursor) { - struct st_translog_buffer *buffer_to_flush; - int rc; uchar chunk2_header[1]; DBUG_ENTER("translog_write_variable_record_chunk2_page"); chunk2_header[0]= TRANSLOG_CHUNK_NOHDR; - rc= translog_page_next(horizon, cursor, &buffer_to_flush); - if (buffer_to_flush != NULL) - { - translog_buffer_lock(buffer_to_flush); - translog_buffer_decrease_writers(buffer_to_flush); - if (!rc) - rc= translog_buffer_flush(buffer_to_flush); - translog_buffer_unlock(buffer_to_flush); - } - if (rc) + if (translog_chaser_page_next(horizon, cursor)) DBUG_RETURN(1); /* Puts chunk type */ @@ -4215,23 +4245,13 @@ translog_write_variable_record_chunk3_page(struct st_translog_parts *parts, TRANSLOG_ADDRESS *horizon, struct st_buffer_cursor *cursor) { - struct st_translog_buffer *buffer_to_flush; LEX_STRING *part; - int rc; uchar chunk3_header[1 + 2]; DBUG_ENTER("translog_write_variable_record_chunk3_page"); - rc= translog_page_next(horizon, cursor, &buffer_to_flush); - if (buffer_to_flush != NULL) - { - translog_buffer_lock(buffer_to_flush); - translog_buffer_decrease_writers(buffer_to_flush); - if (!rc) - rc= translog_buffer_flush(buffer_to_flush); - translog_buffer_unlock(buffer_to_flush); - } - if (rc) + if (translog_chaser_page_next(horizon, cursor)) DBUG_RETURN(1); + if (length == 0) { /* It was call to write page header only (no data for chunk 3) */ @@ -4541,7 +4561,7 @@ translog_write_variable_record_1group(LSN *lsn, *lsn= horizon= log_descriptor.horizon; if (translog_set_lsn_for_files(LSN_FILE_NO(*lsn), LSN_FILE_NO(*lsn), - *lsn, TRUE) || + *lsn, TRUE) || (log_record_type_descriptor[type].inwrite_hook && (*log_record_type_descriptor[type].inwrite_hook)(type, trn, tbl_info, lsn, hook_arg))) @@ -5045,6 +5065,7 @@ translog_write_variable_record_mgroup(LSN *lsn, uint header_fixed_part= header_length + 2; uint groups_per_page= (page_capacity - header_fixed_part) / (7 + 1); uint file_of_the_first_group; + int pages_to_skip; DBUG_ENTER("translog_write_variable_record_mgroup"); translog_lock_assert_owner(); @@ -5119,7 +5140,6 @@ translog_write_variable_record_mgroup(LSN *lsn, if (buffer_to_flush != NULL) { - translog_buffer_lock(buffer_to_flush); translog_buffer_decrease_writers(buffer_to_flush); if (!rc) rc= translog_buffer_flush(buffer_to_flush); @@ -5158,18 +5178,7 @@ translog_write_variable_record_mgroup(LSN *lsn, done+= (first_page - 1 + buffer_rest); - /* TODO: make separate function for following */ - rc= translog_page_next(&horizon, &cursor, &buffer_to_flush); - if (buffer_to_flush != NULL) - { - translog_buffer_lock(buffer_to_flush); - translog_buffer_decrease_writers(buffer_to_flush); - if (!rc) - rc= translog_buffer_flush(buffer_to_flush); - translog_buffer_unlock(buffer_to_flush); - buffer_to_flush= NULL; - } - if (rc) + if (translog_chaser_page_next(&horizon, &cursor)) { DBUG_PRINT("error", ("flush of unlock buffer failed")); goto err; @@ -5180,9 +5189,18 @@ translog_write_variable_record_mgroup(LSN *lsn, translog_lock(); + /* Check that we have place for chunk type 2 */ first_page= translog_get_current_page_rest(); + if (first_page <= 1) + { + if (translog_page_next(&log_descriptor.horizon, &log_descriptor.bc, + &buffer_to_flush)) + goto err_unlock; + first_page= translog_get_current_page_rest(); + } buffer_rest= translog_get_current_group_size(); - } while (first_page + buffer_rest < (uint) (parts->record_length - done)); + } while ((translog_size_t)(first_page + buffer_rest) < + (translog_size_t)(parts->record_length - done)); group.addr= horizon= log_descriptor.horizon; cursor= log_descriptor.bc; @@ -5195,19 +5213,39 @@ translog_write_variable_record_mgroup(LSN *lsn, } record_rest= parts->record_length - done; DBUG_PRINT("info", ("Record rest: %lu", (ulong) record_rest)); - if (first_page <= record_rest + 1) + if (first_page > record_rest + 1) { + /* + We have not so much data to fill all first page + (no speaking about full pages) + so it will be: + <chunk0 <data>> + or + <chunk0>...<chunk0><chunk0 <data>> + or + <chunk3 <data>><chunk0>...<chunk0><chunk0 <possible data of 1 byte>> + */ + chunk2_page= full_pages= 0; + last_page_capacity= first_page; + pages_to_skip= -1; + } + else + { + /* + We will have: + <chunk2 <data>>...<chunk2 <data>><chunk0 <data>> + or + <chunk2 <data>>...<chunk2 <data>><chunk0>...<chunk0><chunk0 <data>> + or + <chunk3 <data>><chunk0>...<chunk0><chunk0 <possible data of 1 byte>> + */ chunk2_page= 1; record_rest-= (first_page - 1); - full_pages= record_rest / log_descriptor.page_capacity_chunk_2; + pages_to_skip= full_pages= + record_rest / log_descriptor.page_capacity_chunk_2; record_rest= (record_rest % log_descriptor.page_capacity_chunk_2); last_page_capacity= page_capacity; } - else - { - chunk2_page= full_pages= 0; - last_page_capacity= first_page; - } chunk3_size= 0; chunk3_pages= 0; if (last_page_capacity > record_rest + 1 && record_rest != 0) @@ -5220,6 +5258,7 @@ translog_write_variable_record_mgroup(LSN *lsn, } else { + pages_to_skip++; chunk3_pages= 1; if (record_rest + 2 == last_page_capacity) { @@ -5255,16 +5294,28 @@ translog_write_variable_record_mgroup(LSN *lsn, (ulong) full_pages * log_descriptor.page_capacity_chunk_2, chunk3_pages, (uint) chunk3_size, (uint) record_rest)); - rc= translog_advance_pointer((int)(full_pages + chunk3_pages + - (chunk0_pages - 1)) + - (full_pages + chunk3_pages + chunk0_pages + - chunk2_page == 1? -1 : 0), + rc= translog_advance_pointer(pages_to_skip + (int)(chunk0_pages - 1), record_rest + header_fixed_part + (groups.elements - ((page_capacity - header_fixed_part) / (7 + 1)) * (chunk0_pages - 1)) * (7 + 1)); translog_unlock(); + + if (buffer_to_flush != NULL) + { + translog_buffer_decrease_writers(buffer_to_flush); + if (!rc) + rc= translog_buffer_flush(buffer_to_flush); + translog_buffer_unlock(buffer_to_flush); + buffer_to_flush= NULL; + } + if (rc) + { + DBUG_PRINT("error", ("flush of unlock buffer failed")); + goto err; + } + if (rc) goto err; @@ -5334,23 +5385,11 @@ translog_write_variable_record_mgroup(LSN *lsn, do { int limit; - if (new_page_before_chunk0) + if (new_page_before_chunk0 && + translog_chaser_page_next(&horizon, &cursor)) { - rc= translog_page_next(&horizon, &cursor, &buffer_to_flush); - if (buffer_to_flush != NULL) - { - translog_buffer_lock(buffer_to_flush); - translog_buffer_decrease_writers(buffer_to_flush); - if (!rc) - rc= translog_buffer_flush(buffer_to_flush); - translog_buffer_unlock(buffer_to_flush); - buffer_to_flush= NULL; - } - if (rc) - { - DBUG_PRINT("error", ("flush of unlock buffer failed")); - goto err; - } + DBUG_PRINT("error", ("flush of unlock buffer failed")); + goto err; } new_page_before_chunk0= 1; @@ -5431,6 +5470,16 @@ err_unlock: translog_unlock(); err: + if (buffer_to_flush != NULL) + { + /* This is to prevent locking buffer forever in case of error */ + translog_buffer_decrease_writers(buffer_to_flush); + if (!rc) + rc= translog_buffer_flush(buffer_to_flush); + translog_buffer_unlock(buffer_to_flush); + buffer_to_flush= NULL; + } + translog_mark_file_finished(file_of_the_first_group); @@ -6294,6 +6343,7 @@ translog_variable_length_header(uchar *page, translog_size_t page_offset, uint16 length= desc->read_header_len; uint16 buffer_length= length; uint16 body_len; + int rc; TRANSLOG_SCANNER_DATA internal_scanner; DBUG_ENTER("translog_variable_length_header"); @@ -6378,19 +6428,24 @@ translog_variable_length_header(uchar *page, translog_size_t page_offset, DBUG_PRINT("info", ("use internal scanner for header reading")); scanner= &internal_scanner; if (translog_scanner_init(buff->lsn, 1, scanner, 0)) - DBUG_RETURN(RECHEADER_READ_ERROR); + { + rc= RECHEADER_READ_ERROR; + goto exit_and_free; + } } if (translog_get_next_chunk(scanner)) { if (scanner == &internal_scanner) translog_destroy_scanner(scanner); - DBUG_RETURN(RECHEADER_READ_ERROR); + rc= RECHEADER_READ_ERROR; + goto exit_and_free; } if (scanner->page == END_OF_LOG) { if (scanner == &internal_scanner) translog_destroy_scanner(scanner); - DBUG_RETURN(RECHEADER_READ_EOF); + rc= RECHEADER_READ_EOF; + goto exit_and_free; } page= scanner->page; page_offset= scanner->page_offset; @@ -6447,6 +6502,11 @@ translog_variable_length_header(uchar *page, translog_size_t page_offset, buff->non_header_data_start_offset, buff->non_header_data_len, buffer_length)); DBUG_RETURN(buffer_length); + +exit_and_free: + my_free(buff->groups, MYF(0)); + buff->groups_no= 0; /* prevent try to use of buff->groups */ + DBUG_RETURN(rc); } @@ -6810,6 +6870,7 @@ static my_bool translog_init_reader_data(LSN lsn, static void translog_destroy_reader_data(TRANSLOG_READER_DATA *data) { translog_destroy_scanner(&data->scanner); + translog_free_record_header(&data->header); } diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c index 8170d393434..e9a39f23025 100644 --- a/storage/maria/ma_recovery.c +++ b/storage/maria/ma_recovery.c @@ -2335,6 +2335,8 @@ static int run_redo_phase(LSN lsn, enum maria_apply_log_way apply) { tprint(tracef, "Cannot read record's body: read %u of" " %u bytes\n", read_len, rec2.record_length); + translog_destroy_scanner(&scanner2); + translog_free_record_header(&rec2); goto err; } } @@ -2342,23 +2344,27 @@ static int run_redo_phase(LSN lsn, enum maria_apply_log_way apply) display_and_apply_record(log_desc2, &rec2)) { translog_destroy_scanner(&scanner2); + translog_free_record_header(&rec2); goto err; } } + translog_free_record_header(&rec2); len= translog_read_next_record_header(&scanner2, &rec2); if (len < 0) /* EOF or error */ { tprint(tracef, "Cannot find record where it should be\n"); + translog_destroy_scanner(&scanner2); + translog_free_record_header(&rec2); goto err; } } while (rec2.lsn < rec.lsn); - translog_free_record_header(&rec2); /* group finished */ all_active_trans[sid].group_start_lsn= LSN_IMPOSSIBLE; current_group_end_lsn= LSN_IMPOSSIBLE; /* for debugging */ display_record_position(log_desc, &rec, 0); translog_destroy_scanner(&scanner2); + translog_free_record_header(&rec2); } } if (apply == MARIA_LOG_APPLY && @@ -2377,6 +2383,7 @@ static int run_redo_phase(LSN lsn, enum maria_apply_log_way apply) all_active_trans[sid].group_start_lsn= rec.lsn; } } + translog_free_record_header(&rec); len= translog_read_next_record_header(&scanner, &rec); if (len < 0) { @@ -2403,6 +2410,7 @@ static int run_redo_phase(LSN lsn, enum maria_apply_log_way apply) err: translog_destroy_scanner(&scanner); + translog_free_record_header(&rec); return 1; } @@ -2559,8 +2567,10 @@ static int run_undo_phase(uint uncommitted) { eprint(tracef, "Got error %d when executing undo %s", my_errno, log_desc->name); + translog_free_record_header(&rec); DBUG_RETURN(1); } + translog_free_record_header(&rec); } if (trnman_rollback_trn(trn)) |