From 963d2d432b7d0e627b49fff934760a8bab204b51 Mon Sep 17 00:00:00 2001 From: Satya B Date: Thu, 8 Oct 2009 18:22:21 +0530 Subject: [PATCH] Applying InnoDB Plugin 1.0.5 snapshot, part 6 From revision r5748 to r5783 Detailed revision comments: r5748 | marko | 2009-09-03 06:05:44 -0500 (Thu, 03 Sep 2009) | 1 line branches/zip: MLOG_MULTI_REC_END: Correct the comment. r5751 | marko | 2009-09-03 09:36:15 -0500 (Thu, 03 Sep 2009) | 7 lines branches/zip: row_merge(): Remove a bogus debug assertion that was triggered when creating an index on an empty table. row_merge_sort(): Add debug assertions and comments that justify the loop termination condition. The bogus assertion ut_ad(ihalf > 0) was reported by Michael. r5752 | marko | 2009-09-03 09:55:51 -0500 (Thu, 03 Sep 2009) | 10 lines branches/zip: recv_recover_page_func(): Write the log sequence number to the compressed page, if there is one. Previously, the function only wrote the LSN to the uncompressed page. It is not clear why recv_recover_page_func() is updating FIL_PAGE_LSN in the buffer pool. The log sequence number will be stamped on the page when it is flushed to disk, in buf_flush_init_for_writing(). I noticed this inconsistency when analyzing Issue #313, but this patch does not fix it. That is no surprise, since FIL_PAGE_LSN should only matter on disk files, not in the buffer pool. r5775 | calvin | 2009-09-07 16:15:05 -0500 (Mon, 07 Sep 2009) | 13 lines branches/zip: Build InnoDB on Windows with UNIV_HOTBACKUP The changes are non-functional changes for normal InnoDB, but needed for building the Hot Backup on Windows (with UNIV_HOTBACKUP defined). - Define os_aio_use_native_aio for HB. - Do not acquire seek mutexes for backup since HB is single threaded. - Do not use srv_flush_log_at_trx_commit for HB build rb://155 Approved by: Marko r5777 | marko | 2009-09-08 10:50:25 -0500 (Tue, 08 Sep 2009) | 2 lines branches/zip: Remove BUF_LRU_INITIAL_RATIO, which should have been removed together with buf_LRU_get_recent_limit(). r5779 | marko | 2009-09-09 01:17:19 -0500 (Wed, 09 Sep 2009) | 2 lines branches/zip: buf_page_peek_if_too_old(): Make the bitmasking work when buf_pool->freed_page_clock is wider than 32 bits. r5780 | marko | 2009-09-09 01:50:50 -0500 (Wed, 09 Sep 2009) | 1 line branches/zip: ut_time_ms(): Return ulint, not uint. r5782 | marko | 2009-09-09 02:00:59 -0500 (Wed, 09 Sep 2009) | 2 lines branches/zip: buf_page_peek_if_too_old(): Silence a compiler warning that was introduced in r5779 on 32-bit systems. r5783 | marko | 2009-09-09 02:25:00 -0500 (Wed, 09 Sep 2009) | 1 line branches/zip: buf_page_is_accessed(): Correct the function comment. --- storage/innodb_plugin/buf/buf0lru.c | 5 --- storage/innodb_plugin/include/buf0buf.h | 4 +- storage/innodb_plugin/include/buf0buf.ic | 6 +-- storage/innodb_plugin/include/mtr0mtr.h | 2 +- storage/innodb_plugin/include/ut0ut.h | 2 +- storage/innodb_plugin/log/log0recv.c | 30 ++++++++++---- storage/innodb_plugin/os/os0file.c | 52 ++++++++++++++++++++---- storage/innodb_plugin/row/row0merge.c | 9 +++- storage/innodb_plugin/ut/ut0ut.c | 4 +- 9 files changed, 82 insertions(+), 32 deletions(-) diff --git a/storage/innodb_plugin/buf/buf0lru.c b/storage/innodb_plugin/buf/buf0lru.c index 223746e0d01..e7cf852e200 100644 --- a/storage/innodb_plugin/buf/buf0lru.c +++ b/storage/innodb_plugin/buf/buf0lru.c @@ -66,11 +66,6 @@ allowed to point to either end of the LRU list. */ # error "BUF_LRU_NON_OLD_MIN_LEN >= BUF_LRU_OLD_MIN_LEN" #endif -/** The whole LRU list length is divided by this number to determine an -initial segment in buf_LRU_get_recent_limit */ - -#define BUF_LRU_INITIAL_RATIO 8 - /** When dropping the search hash index entries before deleting an ibd file, we build a local array of pages belonging to that tablespace in the buffer pool. Following is the size of that array. */ diff --git a/storage/innodb_plugin/include/buf0buf.h b/storage/innodb_plugin/include/buf0buf.h index 299312e5d10..db95aa7ce21 100644 --- a/storage/innodb_plugin/include/buf0buf.h +++ b/storage/innodb_plugin/include/buf0buf.h @@ -807,8 +807,8 @@ buf_page_set_old( buf_page_t* bpage, /*!< in/out: control block */ ibool old); /*!< in: old */ /*********************************************************************//** -Determine the time of last access a block in the buffer pool. -@return ut_time_ms() at the time of last access, 0 if not accessed */ +Determine the time of first access of a block in the buffer pool. +@return ut_time_ms() at the time of first access, 0 if not accessed */ UNIV_INLINE unsigned buf_page_is_accessed( diff --git a/storage/innodb_plugin/include/buf0buf.ic b/storage/innodb_plugin/include/buf0buf.ic index 409d339aa16..18ee4551eb4 100644 --- a/storage/innodb_plugin/include/buf0buf.ic +++ b/storage/innodb_plugin/include/buf0buf.ic @@ -84,7 +84,7 @@ buf_page_peek_if_too_old( return(FALSE); } else { /* FIXME: bpage->freed_page_clock is 31 bits */ - return((buf_pool->freed_page_clock & ~(1 << 31)) + return((buf_pool->freed_page_clock & ((1UL << 31) - 1)) > bpage->freed_page_clock + (buf_pool->curr_size * (BUF_LRU_OLD_RATIO_DIV - buf_LRU_old_ratio) @@ -471,8 +471,8 @@ buf_page_set_old( } /*********************************************************************//** -Determine the time of last access a block in the buffer pool. -@return ut_time_ms() at the time of last access, 0 if not accessed */ +Determine the time of first access of a block in the buffer pool. +@return ut_time_ms() at the time of first access, 0 if not accessed */ UNIV_INLINE unsigned buf_page_is_accessed( diff --git a/storage/innodb_plugin/include/mtr0mtr.h b/storage/innodb_plugin/include/mtr0mtr.h index 69a2c03f4cb..44bba43b1ab 100644 --- a/storage/innodb_plugin/include/mtr0mtr.h +++ b/storage/innodb_plugin/include/mtr0mtr.h @@ -118,7 +118,7 @@ For 1 - 8 bytes, the flag value must give the length also! @{ */ #define MLOG_WRITE_STRING ((byte)30) /*!< write a string to a page */ #define MLOG_MULTI_REC_END ((byte)31) /*!< if a single mtr writes - log records for several pages, + several log records, this log record ends the sequence of these records */ #define MLOG_DUMMY_RECORD ((byte)32) /*!< dummy log record used to diff --git a/storage/innodb_plugin/include/ut0ut.h b/storage/innodb_plugin/include/ut0ut.h index 94a93dff6c7..6655d522c18 100644 --- a/storage/innodb_plugin/include/ut0ut.h +++ b/storage/innodb_plugin/include/ut0ut.h @@ -246,7 +246,7 @@ value may wrap around. It should only be used for heuristic purposes. @return ms since epoch */ UNIV_INTERN -uint +ulint ut_time_ms(void); /*============*/ #endif /* !UNIV_HOTBACKUP */ diff --git a/storage/innodb_plugin/log/log0recv.c b/storage/innodb_plugin/log/log0recv.c index 3b40925f079..971c5600d39 100644 --- a/storage/innodb_plugin/log/log0recv.c +++ b/storage/innodb_plugin/log/log0recv.c @@ -1327,6 +1327,7 @@ recv_recover_page_func( buf_block_t* block) /*!< in/out: buffer block */ { page_t* page; + page_zip_des_t* page_zip; recv_addr_t* recv_addr; recv_t* recv; byte* buf; @@ -1376,6 +1377,7 @@ recv_recover_page_func( mtr_set_log_mode(&mtr, MTR_LOG_NONE); page = block->frame; + page_zip = buf_block_get_page_zip(block); #ifndef UNIV_HOTBACKUP if (just_read_in) { @@ -1436,13 +1438,19 @@ recv_recover_page_func( if (recv->type == MLOG_INIT_FILE_PAGE) { page_lsn = page_newest_lsn; - mach_write_ull(page + UNIV_PAGE_SIZE - - FIL_PAGE_END_LSN_OLD_CHKSUM, 0); - mach_write_ull(page + FIL_PAGE_LSN, 0); + memset(FIL_PAGE_LSN + page, 0, 8); + memset(UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM + + page, 0, 8); + + if (page_zip) { + memset(FIL_PAGE_LSN + page_zip->data, 0, 8); + } } if (recv->start_lsn >= page_lsn) { + ib_uint64_t end_lsn; + if (!modification_to_page) { modification_to_page = TRUE; @@ -1464,11 +1472,17 @@ recv_recover_page_func( recv_parse_or_apply_log_rec_body(recv->type, buf, buf + recv->len, block, &mtr); - mach_write_ull(page + UNIV_PAGE_SIZE - - FIL_PAGE_END_LSN_OLD_CHKSUM, - recv->start_lsn + recv->len); - mach_write_ull(page + FIL_PAGE_LSN, - recv->start_lsn + recv->len); + + end_lsn = recv->start_lsn + recv->len; + mach_write_ull(FIL_PAGE_LSN + page, end_lsn); + mach_write_ull(UNIV_PAGE_SIZE + - FIL_PAGE_END_LSN_OLD_CHKSUM + + page, end_lsn); + + if (page_zip) { + mach_write_ull(FIL_PAGE_LSN + + page_zip->data, end_lsn); + } } if (recv->len > RECV_DATA_BLOCK_SIZE) { diff --git a/storage/innodb_plugin/os/os0file.c b/storage/innodb_plugin/os/os0file.c index dc25d55f818..50612282f69 100644 --- a/storage/innodb_plugin/os/os0file.c +++ b/storage/innodb_plugin/os/os0file.c @@ -88,7 +88,9 @@ UNIV_INTERN ibool os_do_not_call_flush_at_each_write = FALSE; /* We do not call os_file_flush in every os_file_write. */ #endif /* UNIV_DO_FLUSH */ -#ifndef UNIV_HOTBACKUP +#ifdef UNIV_HOTBACKUP +# define os_aio_use_native_aio FALSE +#else /* UNIV_HOTBACKUP */ /* We use these mutexes to protect lseek + file i/o operation, if the OS does not provide an atomic pread or pwrite, or similar */ #define OS_FILE_N_SEEK_MUTEXES 16 @@ -198,7 +200,7 @@ static ulint os_aio_n_segments = ULINT_UNDEFINED; /** If the following is TRUE, read i/o handler threads try to wait until a batch of new read requests have been posted */ static ibool os_aio_recommend_sleep_for_read_threads = FALSE; -#endif /* !UNIV_HOTBACKUP */ +#endif /* UNIV_HOTBACKUP */ UNIV_INTERN ulint os_n_file_reads = 0; UNIV_INTERN ulint os_bytes_read_since_printout = 0; @@ -1245,6 +1247,7 @@ try_again: } #endif #ifdef UNIV_NON_BUFFERED_IO +# ifndef UNIV_HOTBACKUP if (type == OS_LOG_FILE && srv_flush_log_at_trx_commit == 2) { /* Do not use unbuffered i/o to log files because value 2 denotes that we do not flush the log at every @@ -1253,10 +1256,14 @@ try_again: == SRV_WIN_IO_UNBUFFERED) { attributes = attributes | FILE_FLAG_NO_BUFFERING; } -#endif +# else /* !UNIV_HOTBACKUP */ + attributes = attributes | FILE_FLAG_NO_BUFFERING; +# endif /* !UNIV_HOTBACKUP */ +#endif /* UNIV_NON_BUFFERED_IO */ } else if (purpose == OS_FILE_NORMAL) { attributes = 0; #ifdef UNIV_NON_BUFFERED_IO +# ifndef UNIV_HOTBACKUP if (type == OS_LOG_FILE && srv_flush_log_at_trx_commit == 2) { /* Do not use unbuffered i/o to log files because value 2 denotes that we do not flush the log at every @@ -1265,7 +1272,10 @@ try_again: == SRV_WIN_IO_UNBUFFERED) { attributes = attributes | FILE_FLAG_NO_BUFFERING; } -#endif +# else /* !UNIV_HOTBACKUP */ + attributes = attributes | FILE_FLAG_NO_BUFFERING; +# endif /* !UNIV_HOTBACKUP */ +#endif /* UNIV_NON_BUFFERED_IO */ } else { attributes = 0; ut_error; @@ -2227,7 +2237,9 @@ os_file_read( DWORD low; DWORD high; ibool retry; +#ifndef UNIV_HOTBACKUP ulint i; +#endif /* !UNIV_HOTBACKUP */ ut_a((offset & 0xFFFFFFFFUL) == offset); @@ -2246,16 +2258,20 @@ try_again: os_n_pending_reads++; os_mutex_exit(os_file_count_mutex); +#ifndef UNIV_HOTBACKUP /* Protect the seek / read operation with a mutex */ i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES; os_mutex_enter(os_file_seek_mutexes[i]); +#endif /* !UNIV_HOTBACKUP */ ret2 = SetFilePointer(file, low, &high, FILE_BEGIN); if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) { +#ifndef UNIV_HOTBACKUP os_mutex_exit(os_file_seek_mutexes[i]); +#endif /* !UNIV_HOTBACKUP */ os_mutex_enter(os_file_count_mutex); os_n_pending_reads--; @@ -2266,7 +2282,9 @@ try_again: ret = ReadFile(file, buf, (DWORD) n, &len, NULL); +#ifndef UNIV_HOTBACKUP os_mutex_exit(os_file_seek_mutexes[i]); +#endif /* !UNIV_HOTBACKUP */ os_mutex_enter(os_file_count_mutex); os_n_pending_reads--; @@ -2275,7 +2293,7 @@ try_again: if (ret && len == n) { return(TRUE); } -#else +#else /* __WIN__ */ ibool retry; ssize_t ret; @@ -2294,7 +2312,7 @@ try_again: "InnoDB: Was only able to read %ld.\n", (ulong)n, (ulong)offset_high, (ulong)offset, (long)ret); -#endif +#endif /* __WIN__ */ #ifdef __WIN__ error_handling: #endif @@ -2343,7 +2361,9 @@ os_file_read_no_error_handling( DWORD low; DWORD high; ibool retry; +#ifndef UNIV_HOTBACKUP ulint i; +#endif /* !UNIV_HOTBACKUP */ ut_a((offset & 0xFFFFFFFFUL) == offset); @@ -2362,16 +2382,20 @@ try_again: os_n_pending_reads++; os_mutex_exit(os_file_count_mutex); +#ifndef UNIV_HOTBACKUP /* Protect the seek / read operation with a mutex */ i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES; os_mutex_enter(os_file_seek_mutexes[i]); +#endif /* !UNIV_HOTBACKUP */ ret2 = SetFilePointer(file, low, &high, FILE_BEGIN); if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) { +#ifndef UNIV_HOTBACKUP os_mutex_exit(os_file_seek_mutexes[i]); +#endif /* !UNIV_HOTBACKUP */ os_mutex_enter(os_file_count_mutex); os_n_pending_reads--; @@ -2382,7 +2406,9 @@ try_again: ret = ReadFile(file, buf, (DWORD) n, &len, NULL); +#ifndef UNIV_HOTBACKUP os_mutex_exit(os_file_seek_mutexes[i]); +#endif /* !UNIV_HOTBACKUP */ os_mutex_enter(os_file_count_mutex); os_n_pending_reads--; @@ -2391,7 +2417,7 @@ try_again: if (ret && len == n) { return(TRUE); } -#else +#else /* __WIN__ */ ibool retry; ssize_t ret; @@ -2404,7 +2430,7 @@ try_again: return(TRUE); } -#endif +#endif /* __WIN__ */ #ifdef __WIN__ error_handling: #endif @@ -2463,9 +2489,11 @@ os_file_write( DWORD ret2; DWORD low; DWORD high; - ulint i; ulint n_retries = 0; ulint err; +#ifndef UNIV_HOTBACKUP + ulint i; +#endif /* !UNIV_HOTBACKUP */ ut_a((offset & 0xFFFFFFFF) == offset); @@ -2482,16 +2510,20 @@ retry: os_n_pending_writes++; os_mutex_exit(os_file_count_mutex); +#ifndef UNIV_HOTBACKUP /* Protect the seek / write operation with a mutex */ i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES; os_mutex_enter(os_file_seek_mutexes[i]); +#endif /* !UNIV_HOTBACKUP */ ret2 = SetFilePointer(file, low, &high, FILE_BEGIN); if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) { +#ifndef UNIV_HOTBACKUP os_mutex_exit(os_file_seek_mutexes[i]); +#endif /* !UNIV_HOTBACKUP */ os_mutex_enter(os_file_count_mutex); os_n_pending_writes--; @@ -2525,7 +2557,9 @@ retry: } # endif /* UNIV_DO_FLUSH */ +#ifndef UNIV_HOTBACKUP os_mutex_exit(os_file_seek_mutexes[i]); +#endif /* !UNIV_HOTBACKUP */ os_mutex_enter(os_file_count_mutex); os_n_pending_writes--; diff --git a/storage/innodb_plugin/row/row0merge.c b/storage/innodb_plugin/row/row0merge.c index 9a51221732b..a968fe80864 100644 --- a/storage/innodb_plugin/row/row0merge.c +++ b/storage/innodb_plugin/row/row0merge.c @@ -1576,7 +1576,6 @@ row_merge( ulint ohalf; /*!< half the output file */ UNIV_MEM_ASSERT_W(block[0], 3 * sizeof block[0]); - ut_ad(ihalf > 0); ut_ad(ihalf < file->offset); of.fd = *tmpfd; @@ -1665,6 +1664,10 @@ row_merge_sort( { ulint half = file->offset / 2; + /* The file should always contain at least one byte (the end + of file marker). Thus, it must be at least one block. */ + ut_ad(file->offset > 0); + do { ulint error; @@ -1673,6 +1676,10 @@ row_merge_sort( if (error != DB_SUCCESS) { return(error); } + + /* half > 0 should hold except when the file consists + of one block. No need to merge further then. */ + ut_ad(half > 0 || file->offset == 1); } while (half < file->offset && half > 0); return(DB_SUCCESS); diff --git a/storage/innodb_plugin/ut/ut0ut.c b/storage/innodb_plugin/ut/ut0ut.c index 5857c9bdef4..498873e290a 100644 --- a/storage/innodb_plugin/ut/ut0ut.c +++ b/storage/innodb_plugin/ut/ut0ut.c @@ -206,7 +206,7 @@ value may wrap around. It should only be used for heuristic purposes. @return ms since epoch */ UNIV_INTERN -uint +ulint ut_time_ms(void) /*============*/ { @@ -214,7 +214,7 @@ ut_time_ms(void) ut_gettimeofday(&tv, NULL); - return((uint) tv.tv_sec * 1000 + tv.tv_usec / 1000); + return((ulint) tv.tv_sec * 1000 + tv.tv_usec / 1000); } #endif /* !UNIV_HOTBACKUP */