Commit 37a5a54a authored by Sergei Golubchik's avatar Sergei Golubchik

Percona-Server-5.5.28-rel29.3

parent b1b939f4
......@@ -239,6 +239,7 @@ btr_cur_latch_leaves(
mtr_t* mtr) /*!< in: mtr */
{
ulint mode;
ulint sibling_mode;
ulint left_page_no;
ulint right_page_no;
buf_block_t* get_block;
......@@ -261,14 +262,21 @@ btr_cur_latch_leaves(
#endif /* UNIV_BTR_DEBUG */
get_block->check_index_page_at_flush = TRUE;
return;
case BTR_SEARCH_TREE:
case BTR_MODIFY_TREE:
/* x-latch also brothers from left to right */
if (UNIV_UNLIKELY(latch_mode == BTR_SEARCH_TREE)) {
mode = RW_S_LATCH;
sibling_mode = RW_NO_LATCH;
} else {
mode = sibling_mode = RW_X_LATCH;
}
/* Fetch and possibly latch also brothers from left to right */
left_page_no = btr_page_get_prev(page, mtr);
if (left_page_no != FIL_NULL) {
get_block = btr_block_get(
space, zip_size, left_page_no,
RW_X_LATCH, cursor->index, mtr);
sibling_mode, cursor->index, mtr);
if (srv_pass_corrupt_table && !get_block) {
return;
......@@ -280,12 +288,21 @@ btr_cur_latch_leaves(
ut_a(btr_page_get_next(get_block->frame, mtr)
== page_get_page_no(page));
#endif /* UNIV_BTR_DEBUG */
get_block->check_index_page_at_flush = TRUE;
if (sibling_mode == RW_NO_LATCH) {
/* btr_block_get() called with RW_NO_LATCH will
fix the read block in the buffer. This serves
no purpose for the fake changes prefetching,
thus we unfix the sibling blocks immediately.*/
mtr_memo_release(mtr, get_block,
MTR_MEMO_BUF_FIX);
} else {
get_block->check_index_page_at_flush = TRUE;
}
}
get_block = btr_block_get(
space, zip_size, page_no,
RW_X_LATCH, cursor->index, mtr);
mode, cursor->index, mtr);
if (srv_pass_corrupt_table && !get_block) {
return;
......@@ -301,7 +318,7 @@ btr_cur_latch_leaves(
if (right_page_no != FIL_NULL) {
get_block = btr_block_get(
space, zip_size, right_page_no,
RW_X_LATCH, cursor->index, mtr);
sibling_mode, cursor->index, mtr);
if (srv_pass_corrupt_table && !get_block) {
return;
......@@ -313,7 +330,12 @@ btr_cur_latch_leaves(
ut_a(btr_page_get_prev(get_block->frame, mtr)
== page_get_page_no(page));
#endif /* UNIV_BTR_DEBUG */
get_block->check_index_page_at_flush = TRUE;
if (sibling_mode == RW_NO_LATCH) {
mtr_memo_release(mtr, get_block,
MTR_MEMO_BUF_FIX);
} else {
get_block->check_index_page_at_flush = TRUE;
}
}
return;
......@@ -1566,6 +1588,9 @@ btr_cur_pessimistic_insert(
}
if (!(flags & BTR_NO_UNDO_LOG_FLAG)) {
ut_a(cursor->tree_height != ULINT_UNDEFINED);
/* First reserve enough free space for the file segments
of the index tree, so that the insert will not fail because
of lack of space */
......@@ -1860,7 +1885,8 @@ btr_cur_update_alloc_zip(
ulint length, /*!< in: size needed */
ibool create, /*!< in: TRUE=delete-and-insert,
FALSE=update-in-place */
mtr_t* mtr) /*!< in: mini-transaction */
mtr_t* mtr, /*!< in: mini-transaction */
trx_t* trx) /*!< in: NULL or transaction */
{
ut_a(page_zip == buf_block_get_page_zip(block));
ut_ad(page_zip);
......@@ -1877,6 +1903,14 @@ btr_cur_update_alloc_zip(
return(FALSE);
}
if (trx && trx->fake_changes) {
/* Don't call page_zip_compress_write_log_no_data as that has
assert which would fail. Assume there won't be a compression
failure. */
return TRUE;
}
if (!page_zip_compress(page_zip, buf_block_get_frame(block),
index, mtr)) {
/* Unable to compress the page */
......@@ -1960,7 +1994,8 @@ btr_cur_update_in_place(
/* Check that enough space is available on the compressed page. */
if (page_zip
&& !btr_cur_update_alloc_zip(page_zip, block, index,
rec_offs_size(offsets), FALSE, mtr)) {
rec_offs_size(offsets), FALSE, mtr,
trx)) {
return(DB_ZIP_OVERFLOW);
}
......@@ -2159,7 +2194,8 @@ any_extern:
if (page_zip
&& !btr_cur_update_alloc_zip(page_zip, block, index,
new_rec_size, TRUE, mtr)) {
new_rec_size, TRUE, mtr,
thr_get_trx(thr))) {
err = DB_ZIP_OVERFLOW;
goto err_exit;
}
......@@ -2402,7 +2438,15 @@ btr_cur_pessimistic_update(
of the index tree, so that the update will not fail because
of lack of space */
n_extents = cursor->tree_height / 16 + 3;
if (UNIV_UNLIKELY(cursor->tree_height == ULINT_UNDEFINED)) {
/* When the tree height is uninitialized due to fake
changes, reserve some hardcoded number of extents. */
ut_a(thr && thr_get_trx(thr)->fake_changes);
n_extents = 3;
}
else {
n_extents = cursor->tree_height / 16 + 3;
}
if (flags & BTR_NO_UNDO_LOG_FLAG) {
reserve_flag = FSP_CLEANING;
......@@ -2439,7 +2483,7 @@ btr_cur_pessimistic_update(
itself. Thus the following call is safe. */
row_upd_index_replace_new_col_vals_index_pos(new_entry, index, update,
FALSE, *heap);
if (!(flags & BTR_KEEP_SYS_FLAG)) {
if (!(flags & BTR_KEEP_SYS_FLAG) && !trx->fake_changes) {
row_upd_index_entry_sys_field(new_entry, index, DATA_ROLL_PTR,
roll_ptr);
row_upd_index_entry_sys_field(new_entry, index, DATA_TRX_ID,
......@@ -3210,6 +3254,8 @@ btr_cur_pessimistic_delete(
of the index tree, so that the node pointer updates will
not fail because of lack of space */
ut_a(cursor->tree_height != ULINT_UNDEFINED);
n_extents = cursor->tree_height / 32 + 1;
success = fsp_reserve_free_extents(&n_reserved,
......
......@@ -47,6 +47,7 @@ btr_pcur_create_for_mysql(void)
pcur->btr_cur.index = NULL;
btr_pcur_init(pcur);
pcur->btr_cur.tree_height = ULINT_UNDEFINED;
return(pcur);
}
......
......@@ -239,9 +239,11 @@ buf_LRU_drop_page_hash_batch(
When doing a DROP TABLE/DISCARD TABLESPACE we have to drop all page
hash index entries belonging to that table. This function tries to
do that in batch. Note that this is a 'best effort' attempt and does
not guarantee that ALL hash entries will be removed. */
not guarantee that ALL hash entries will be removed.
@return number of hashed pages found*/
static
void
ulint
buf_LRU_drop_page_hash_for_tablespace(
/*==================================*/
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
......@@ -251,13 +253,14 @@ buf_LRU_drop_page_hash_for_tablespace(
ulint* page_arr;
ulint num_entries;
ulint zip_size;
ulint num_found = 0;
zip_size = fil_space_get_zip_size(id);
if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
/* Somehow, the tablespace does not exist. Nothing to drop. */
ut_ad(0);
return;
return num_found;
}
page_arr = ut_malloc(
......@@ -315,6 +318,7 @@ next_page:
ut_a(num_entries < BUF_LRU_DROP_SEARCH_SIZE);
++num_entries;
++num_found;
if (num_entries < BUF_LRU_DROP_SEARCH_SIZE) {
goto next_page;
......@@ -370,6 +374,8 @@ next_page:
/* Drop any remaining batch of search hashed pages. */
buf_LRU_drop_page_hash_batch(id, zip_size, page_arr, num_entries);
ut_free(page_arr);
return num_found;
}
/******************************************************************//**
......@@ -814,8 +820,6 @@ buf_LRU_mark_space_was_deleted(
for (i = 0; i < srv_buf_pool_instances; i++) {
buf_pool_t* buf_pool;
buf_page_t* bpage;
buf_chunk_t* chunk;
ulint j, k;
buf_pool = buf_pool_from_array(i);
......@@ -832,28 +836,10 @@ buf_LRU_mark_space_was_deleted(
mutex_exit(&buf_pool->LRU_list_mutex);
btr_search_s_lock_all();
chunk = buf_pool->chunks;
for (j = buf_pool->n_chunks; j--; chunk++) {
buf_block_t* block = chunk->blocks;
for (k = chunk->size; k--; block++) {
if (buf_block_get_state(block)
!= BUF_BLOCK_FILE_PAGE
|| !block->index
|| buf_page_get_space(&block->page) != id) {
continue;
}
btr_search_s_unlock_all();
rw_lock_x_lock(&block->lock);
btr_search_drop_page_hash_index(block);
rw_lock_x_unlock(&block->lock);
btr_search_s_lock_all();
}
}
btr_search_s_unlock_all();
/* The AHI entries for the tablespace being deleted should be
removed by now. */
ut_ad(buf_LRU_drop_page_hash_for_tablespace(buf_pool, id)
== 0);
}
}
......
......@@ -3034,7 +3034,11 @@ try_again:
some of them will contain extent descriptor pages, and therefore
will not be free extents */
n_free_up = (size - free_limit) / FSP_EXTENT_SIZE;
if (size <= free_limit) {
n_free_up = 0;
} else {
n_free_up = (size - free_limit) / FSP_EXTENT_SIZE;
}
if (n_free_up > 0) {
n_free_up--;
......
......@@ -1050,6 +1050,13 @@ thd_to_trx(
return(*(trx_t**) thd_ha_data(thd, innodb_hton_ptr));
}
my_bool
ha_innobase::is_fake_change_enabled(THD* thd)
{
trx_t* trx = thd_to_trx(thd);
return(trx && trx->fake_changes);
}
/********************************************************************//**
Call this function when mysqld passes control to the client. That is to
avoid deadlocks on the adaptive hash S-latch possibly held by thd. For more
......@@ -3057,6 +3064,14 @@ innobase_change_buffering_inited_ok:
srv_use_checksums = (ibool) innobase_use_checksums;
srv_fast_checksum = (ibool) innobase_fast_checksum;
if (innobase_fast_checksum) {
fprintf(stderr,
"InnoDB: Warning: innodb_fast_checksum is DEPRECATED "
"and *WILL* be removed in Percona Server 5.6. Please "
"consult the Percona Server 5.6 documentation for "
"help in upgrading.\n");
}
srv_blocking_lru_restore = (ibool) innobase_blocking_lru_restore;
#ifdef HAVE_LARGE_PAGES
......@@ -5991,7 +6006,9 @@ no_commit:
error = row_insert_for_mysql((byte*) record, prebuilt);
#ifdef EXTENDED_FOR_USERSTAT
if (error == DB_SUCCESS) rows_changed++;
if (UNIV_LIKELY(error == DB_SUCCESS && !trx->fake_changes)) {
rows_changed++;
}
#endif
/* Handle duplicate key errors */
......@@ -6355,7 +6372,9 @@ ha_innobase::update_row(
}
#ifdef EXTENDED_FOR_USERSTAT
if (error == DB_SUCCESS) rows_changed++;
if (UNIV_LIKELY(error == DB_SUCCESS && !trx->fake_changes)) {
rows_changed++;
}
#endif
innodb_srv_conc_exit_innodb(trx);
......@@ -6420,7 +6439,9 @@ ha_innobase::delete_row(
error = row_update_for_mysql((byte*) record, prebuilt);
#ifdef EXTENDED_FOR_USERSTAT
if (error == DB_SUCCESS) rows_changed++;
if (UNIV_LIKELY(error == DB_SUCCESS && !trx->fake_changes)) {
rows_changed++;
}
#endif
innodb_srv_conc_exit_innodb(trx);
......@@ -12351,6 +12372,8 @@ static MYSQL_SYSVAR_BOOL(checksums, innobase_use_checksums,
static MYSQL_SYSVAR_BOOL(fast_checksum, innobase_fast_checksum,
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
"DEPRECATED. #### WARNING #### : This feature is DEPRECATED and WILL "
"be removed in Percona Server 5.6. "
"Change the algorithm of checksum for the whole of datapage to 4-bytes word based. "
"The original checksum is checked after the new one. It may be slow for reading page"
" which has orginal checksum. Overwrite the page or recreate the InnoDB database, "
......@@ -12785,6 +12808,11 @@ static MYSQL_SYSVAR_BOOL(track_changed_pages, srv_track_changed_pages,
"Track the redo log for changed pages and output a changed page bitmap",
NULL, NULL, FALSE);
static MYSQL_SYSVAR_ULONGLONG(max_bitmap_file_size, srv_max_bitmap_file_size,
PLUGIN_VAR_RQCMDARG,
"The maximum size of changed page bitmap files",
NULL, NULL, 100*1024*1024ULL, 4096ULL, ULONGLONG_MAX, 0);
static MYSQL_SYSVAR_ULONGLONG(changed_pages_limit, srv_changed_pages_limit,
PLUGIN_VAR_RQCMDARG,
"The maximum number of rows for "
......@@ -12987,6 +13015,13 @@ static MYSQL_SYSVAR_ULONG(lazy_drop_table, srv_lazy_drop_table,
"e.g. for http://bugs.mysql.com/51325",
NULL, NULL, 0, 0, 1, 0);
static MYSQL_SYSVAR_BOOL(locking_fake_changes, srv_fake_changes_locks,
PLUGIN_VAR_NOCMDARG,
"###EXPERIMENTAL### if enabled, transactions will get S row locks instead "
"of X locks for fake changes. If disabled, fake change transactions will "
"not take any locks at all.",
NULL, NULL, TRUE);
static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(page_size),
MYSQL_SYSVAR(log_block_size),
......@@ -13078,6 +13113,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(use_native_aio),
MYSQL_SYSVAR(change_buffering),
MYSQL_SYSVAR(track_changed_pages),
MYSQL_SYSVAR(max_bitmap_file_size),
MYSQL_SYSVAR(changed_pages_limit),
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
MYSQL_SYSVAR(change_buffering_debug),
......@@ -13096,6 +13132,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(corrupt_table_action),
MYSQL_SYSVAR(lazy_drop_table),
MYSQL_SYSVAR(fake_changes),
MYSQL_SYSVAR(locking_fake_changes),
MYSQL_SYSVAR(merge_sort_block_size),
NULL
};
......
......@@ -138,6 +138,7 @@ class ha_innobase: public handler
int close(void);
double scan_time();
double read_time(uint index, uint ranges, ha_rows rows);
my_bool is_fake_change_enabled(THD *thd);
bool is_corrupt() const;
int write_row(uchar * buf);
......
This diff is collapsed.
......@@ -4044,7 +4044,7 @@ updated_in_place:
update)
&& (!page_zip || btr_cur_update_alloc_zip(
page_zip, block, index,
rec_offs_size(offsets), FALSE, mtr))) {
rec_offs_size(offsets), FALSE, mtr, NULL))) {
/* This is the easy case. Do something similar
to btr_cur_update_in_place(). */
row_upd_rec_in_place(rec, index, offsets,
......
......@@ -65,7 +65,10 @@ enum btr_latch_mode {
/** Search the previous record. */
BTR_SEARCH_PREV = 35,
/** Modify the previous record. */
BTR_MODIFY_PREV = 36
BTR_MODIFY_PREV = 36,
/** Weaker BTR_MODIFY_TREE that does not lock the leaf page siblings,
used for fake changes. */
BTR_SEARCH_TREE = 37 /* BTR_MODIFY_TREE | 4 */
};
/* BTR_INSERT, BTR_DELETE and BTR_DELETE_MARK are mutually exclusive. */
......
......@@ -259,8 +259,9 @@ btr_cur_update_alloc_zip(
ulint length, /*!< in: size needed */
ibool create, /*!< in: TRUE=delete-and-insert,
FALSE=update-in-place */
mtr_t* mtr) /*!< in: mini-transaction */
__attribute__((nonnull, warn_unused_result));
mtr_t* mtr, /*!< in: mini-transaction */
trx_t* trx) /*!< in: NULL or transaction */
__attribute__((nonnull (1, 2, 3, 6), warn_unused_result));
/*************************************************************//**
Updates a record when the update causes no size changes in its fields.
@return DB_SUCCESS or error number */
......
......@@ -27,6 +27,16 @@ Online database log parsing for changed page tracking
#include "univ.i"
#include "os0file.h"
/** Single bitmap file information */
typedef struct log_online_bitmap_file_struct log_online_bitmap_file_t;
/** A set of bitmap files containing some LSN range */
typedef struct log_online_bitmap_file_range_struct
log_online_bitmap_file_range_t;
/** An iterator over changed page info */
typedef struct log_bitmap_iterator_struct log_bitmap_iterator_t;
/*********************************************************************//**
Initializes the online log following subsytem. */
UNIV_INTERN
......@@ -49,45 +59,32 @@ void
log_online_follow_redo_log();
/*=========================*/
/** The iterator through all bits of changed pages bitmap blocks */
struct log_bitmap_iterator_struct
{
char in_name[FN_REFLEN]; /*!< the file name for bitmap
input */
os_file_t in; /*!< the bitmap input file */
ib_uint64_t in_offset; /*!< the next write position in the
bitmap output file */
ib_uint32_t bit_offset; /*!< bit offset inside of bitmap
block*/
ib_uint64_t start_lsn; /*!< Start lsn of the block */
ib_uint64_t end_lsn; /*!< End lsn of the block */
ib_uint32_t space_id; /*!< Block space id */
ib_uint32_t first_page_id; /*!< First block page id */
ibool changed; /*!< true if current page was changed */
byte* page; /*!< Bitmap block */
};
typedef struct log_bitmap_iterator_struct log_bitmap_iterator_t;
#define LOG_BITMAP_ITERATOR_START_LSN(i) \
((i).start_lsn)
((i).start_lsn)
#define LOG_BITMAP_ITERATOR_END_LSN(i) \
((i).end_lsn)
((i).end_lsn)
#define LOG_BITMAP_ITERATOR_SPACE_ID(i) \
((i).space_id)
((i).space_id)
#define LOG_BITMAP_ITERATOR_PAGE_NUM(i) \
((i).first_page_id + (i).bit_offset)
((i).first_page_id + (i).bit_offset)
#define LOG_BITMAP_ITERATOR_PAGE_CHANGED(i) \
((i).changed)
((i).changed)
/*********************************************************************//**
Initializes log bitmap iterator.
Initializes log bitmap iterator. The minimum LSN is used for finding the
correct starting file with records and it there may be records returned by
the iterator that have LSN less than start_lsn.
@return TRUE if the iterator is initialized OK, FALSE otherwise. */
UNIV_INTERN
ibool
log_online_bitmap_iterator_init(
/*============================*/
log_bitmap_iterator_t *i); /*!<in/out: iterator */
log_bitmap_iterator_t *i, /*!<in/out: iterator */
ib_uint64_t min_lsn, /*!<in: start LSN for the
iterator */
ib_uint64_t max_lsn); /*!<in: end LSN for the
iterator */
/*********************************************************************//**
Releases log bitmap iterator. */
......@@ -108,4 +105,57 @@ log_online_bitmap_iterator_next(
/*============================*/
log_bitmap_iterator_t *i); /*!<in/out: iterator */
/** Struct for single bitmap file information */
struct log_online_bitmap_file_struct {
char name[FN_REFLEN]; /*!< Name with full path */
os_file_t file; /*!< Handle to opened file */
ib_uint64_t size; /*!< Size of the file */
ib_uint64_t offset; /*!< Offset of the next read,
or count of already-read bytes
*/
};
/** Struct for a set of bitmap files containing some LSN range */
struct log_online_bitmap_file_range_struct {
size_t count; /*!< Number of files */
/*!< Dynamically-allocated array of info about individual files */
struct {
char name[FN_REFLEN]; /*!< Name of a file */
ib_uint64_t start_lsn; /*!< Starting LSN of
data in this file */
ulong seq_num; /*!< Sequence number of
this file */
} *files;
};
/** Struct for an iterator through all bits of changed pages bitmap blocks */
struct log_bitmap_iterator_struct
{
log_online_bitmap_file_range_t in_files; /*!< The bitmap files
for this iterator */
size_t in_i; /*!< Currently read
file index in in_files
*/
log_online_bitmap_file_t in; /*!< Currently read
file */
ib_uint32_t bit_offset; /*!< bit offset inside
the current bitmap
block */
ib_uint64_t start_lsn; /*!< Start LSN of the
current bitmap block */
ib_uint64_t end_lsn; /*!< End LSN of the
current bitmap block */
ib_uint32_t space_id; /*!< Current block
space id */
ib_uint32_t first_page_id; /*!< Id of the first
page in the current
block */
ibool last_page_in_run;/*!< "Last page in
run" flag value for the
current block */
ibool changed; /*!< true if current
page was changed */
byte* page; /*!< Bitmap block */
};
#endif
......@@ -141,7 +141,8 @@ extern char* srv_doublewrite_file;
extern ibool srv_recovery_stats;
extern my_bool srv_track_changed_pages;
extern my_bool srv_track_changed_pages;
extern ib_uint64_t srv_max_bitmap_file_size;
extern
ulonglong srv_changed_pages_limit;
......@@ -392,6 +393,10 @@ extern uint srv_auto_lru_dump;
/** Whether startup should be blocked until buffer pool is fully restored */
extern ibool srv_blocking_lru_restore;
/** When TRUE, fake change transcations take S rather than X row locks.
When FALSE, row locks are not taken at all. */
extern my_bool srv_fake_changes_locks;
/** Status variables to be passed to MySQL */
typedef struct export_var_struct export_struc;
......
......@@ -54,7 +54,7 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_BUGFIX 8
#ifndef PERCONA_INNODB_VERSION
#define PERCONA_INNODB_VERSION 29.0
#define PERCONA_INNODB_VERSION 29.3
#endif
......
......@@ -122,6 +122,15 @@ ut_max(
/*===*/
ulint n1, /*!< in: first number */
ulint n2); /*!< in: second number */
/******************************************************//**
Calculates the maximum of two ib_uint64_t values.
@return the maximum */
UNIV_INLINE
ib_uint64_t
ut_max_uint64(
/*==========*/
ib_uint64_t n1, /*!< in: first number */
ib_uint64_t n2); /*!< in: second number */
/****************************************************************//**
Calculates minimum of two ulint-pairs. */
UNIV_INLINE
......
......@@ -49,6 +49,19 @@ ut_max(
return((n1 <= n2) ? n2 : n1);
}
/******************************************************//**
Calculates the maximum of two ib_uint64_t values.
@return the maximum */
UNIV_INLINE
ib_uint64_t
ut_max_uint64(
/*==========*/
ib_uint64_t n1, /*!< in: first number */
ib_uint64_t n2) /*!< in: second number */
{
return((n1 <= n2) ? n2 : n1);
}
/****************************************************************//**
Calculates minimum of two ulint-pairs. */
UNIV_INLINE
......
......@@ -5481,8 +5481,13 @@ lock_sec_rec_read_check_and_lock(
return(DB_SUCCESS);
}
if (thr && thr_get_trx(thr)->fake_changes && mode == LOCK_X) {
mode = LOCK_S;
if (UNIV_UNLIKELY((thr && thr_get_trx(thr)->fake_changes))) {
if (!srv_fake_changes_locks) {
return(DB_SUCCESS);
}
if (mode == LOCK_X) {
mode = LOCK_S;
}
}
heap_no = page_rec_get_heap_no(rec);
......@@ -5561,8 +5566,13 @@ lock_clust_rec_read_check_and_lock(
return(DB_SUCCESS);
}
if (thr && thr_get_trx(thr)->fake_changes && mode == LOCK_X) {
mode = LOCK_S;
if (UNIV_UNLIKELY((thr && thr_get_trx(thr)->fake_changes))) {
if (!srv_fake_changes_locks) {
return(DB_SUCCESS);
}
if (mode == LOCK_X) {
mode = LOCK_S;
}
}
heap_no = page_rec_get_heap_no(rec);
......
......@@ -246,7 +246,7 @@ log_check_tracking_margin(
checked for the already-written log. */
{
ib_uint64_t tracked_lsn;
ulint tracked_lsn_age;
ib_uint64_t tracked_lsn_age;
if (!srv_track_changed_pages) {
return FALSE;
......@@ -458,7 +458,7 @@ log_close(void)
ib_uint64_t oldest_lsn;
ib_uint64_t lsn;
ib_uint64_t tracked_lsn;
ulint tracked_lsn_age;
ib_uint64_t tracked_lsn_age;
log_t* log = log_sys;
ib_uint64_t checkpoint_age;
......
This diff is collapsed.
......@@ -2057,8 +2057,10 @@ os_file_set_eof_at(
ib_uint64_t new_len)/*!< in: new file length */
{
#ifdef __WIN__
/* TODO: untested! */
return(!_chsize_s(file, new_len));
LARGE_INTEGER li, li2;
li.QuadPart = new_len;
return(SetFilePointerEx(file, li, &li2,FILE_BEGIN)
&& SetEndOfFile(file));
#else
/* TODO: works only with -D_FILE_OFFSET_BITS=64 ? */
return(!ftruncate(file, new_len));
......
......@@ -2012,7 +2012,10 @@ row_ins_index_entry_low(
the function will return in both low_match and up_match of the
cursor sensible values */
if (dict_index_is_clust(index)) {
if (UNIV_UNLIKELY(thr_get_trx(thr)->fake_changes)) {
search_mode = (mode & BTR_MODIFY_TREE)
? BTR_SEARCH_TREE : BTR_SEARCH_LEAF;
} else if (dict_index_is_clust(index)) {
search_mode = mode;
} else if (!(thr_get_trx(thr)->check_unique_secondary)) {
search_mode = mode | BTR_INSERT | BTR_IGNORE_SEC_UNIQUE;
......@@ -2021,7 +2024,7 @@ row_ins_index_entry_low(
}
btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE,
thr_get_trx(thr)->fake_changes ? BTR_SEARCH_LEAF : search_mode,
search_mode,
&cursor, 0, __FILE__, __LINE__, &mtr);
if (cursor.flag == BTR_CUR_INSERT_TO_IBUF) {
......
......@@ -1276,17 +1276,19 @@ run_again:
que_thr_stop_for_mysql_no_error(thr, trx);
prebuilt->table->stat_n_rows++;
if (UNIV_LIKELY(!(trx->fake_changes))) {
srv_n_rows_inserted++;
prebuilt->table->stat_n_rows++;
if (prebuilt->table->stat_n_rows == 0) {
/* Avoid wrap-over */
prebuilt->table->stat_n_rows--;
if (prebuilt->table->stat_n_rows == 0) {
/* Avoid wrap-over */
prebuilt->table->stat_n_rows--;
}
srv_n_rows_inserted++;
row_update_statistics_if_needed(prebuilt->table);
}
if (!(trx->fake_changes))
row_update_statistics_if_needed(prebuilt->table);
trx->op_info = "";
return((int) err);
......@@ -1533,6 +1535,11 @@ run_again:
que_thr_stop_for_mysql_no_error(thr, trx);
if (UNIV_UNLIKELY(trx->fake_changes)) {
trx->op_info = "";
return((int) err);
}
if (node->is_delete) {
if (prebuilt->table->stat_n_rows > 0) {
prebuilt->table->stat_n_rows--;
......@@ -1547,7 +1554,6 @@ run_again:
that changes indexed columns, UPDATEs that change only non-indexed
columns would not affect statistics. */
if (node->is_delete || !(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {
if (!(trx->fake_changes))
row_update_statistics_if_needed(prebuilt->table);
}
......@@ -1755,6 +1761,11 @@ run_again:
return(err);
}
if (UNIV_UNLIKELY((trx->fake_changes))) {
return(err);
}
if (node->is_delete) {
if (table->stat_n_rows > 0) {
table->stat_n_rows--;
......@@ -1765,7 +1776,6 @@ run_again:
srv_n_rows_updated++;
}
if (!(trx->fake_changes))
row_update_statistics_if_needed(table);
return(err);
......
......@@ -2018,7 +2018,8 @@ row_upd_clust_rec(
the same transaction do not modify the record in the meantime.
Therefore we can assert that the restoration of the cursor succeeds. */
ut_a(btr_pcur_restore_position(thr_get_trx(thr)->fake_changes ? BTR_SEARCH_LEAF : BTR_MODIFY_TREE,
ut_a(btr_pcur_restore_position(thr_get_trx(thr)->fake_changes
? BTR_SEARCH_TREE : BTR_MODIFY_TREE,
pcur, mtr));
ut_ad(!rec_get_deleted_flag(btr_pcur_get_rec(pcur),
......
......@@ -179,8 +179,14 @@ UNIV_INTERN ibool srv_recovery_stats = FALSE;
UNIV_INTERN my_bool srv_track_changed_pages = TRUE;
UNIV_INTERN ib_uint64_t srv_max_bitmap_file_size = 100 * 1024 * 1024;
UNIV_INTERN ulonglong srv_changed_pages_limit = 0;
/** When TRUE, fake change transcations take S rather than X row locks.
When FALSE, row locks are not taken at all. */
UNIV_INTERN my_bool srv_fake_changes_locks = TRUE;
/* if TRUE, then we auto-extend the last data file */
UNIV_INTERN ibool srv_auto_extend_last_data_file = FALSE;
/* if != 0, this tells the max size auto-extending may increase the
......
......@@ -1148,6 +1148,24 @@ skip_size_check:
return(DB_SUCCESS);
}
/*********************************************************************//**
Initializes the log tracking subsystem and starts its thread. */
static
void
init_log_online(void)
/*=================*/
{
if (srv_track_changed_pages) {
log_online_read_init();
/* Create the thread that follows the redo log to output the
changed page bitmap */
os_thread_create(&srv_redo_log_follow_thread, NULL,
thread_ids + 5 + SRV_MAX_N_IO_THREADS);
}
}
/********************************************************************
Starts InnoDB and creates a new database if database files
are not found and the user wants.
......@@ -1791,6 +1809,8 @@ innobase_start_or_create_for_mysql(void)
trx_sys_file_format_init();
if (create_new_db) {
init_log_online();
mtr_start(&mtr);
fsp_header_init(0, sum_of_new_sizes, &mtr);
......@@ -1890,6 +1910,8 @@ innobase_start_or_create_for_mysql(void)
return(DB_ERROR);
}
init_log_online();
/* Since the insert buffer init is in dict_boot, and the
insert buffer is needed in any disk i/o, first we call
dict_boot(). Note that trx_sys_init_at_db_start() only needs
......@@ -2037,19 +2059,6 @@ innobase_start_or_create_for_mysql(void)
if (srv_auto_lru_dump && srv_blocking_lru_restore)
buf_LRU_file_restore();
if (srv_track_changed_pages) {
/* Initialize the log tracking subsystem here to block
server startup until it's completed due to the potential
need to re-read previous server run's log. */
log_online_read_init();
/* Create the thread that follows the redo log to output the
changed page bitmap */
os_thread_create(&srv_redo_log_follow_thread, NULL,
thread_ids + 6 + SRV_MAX_N_IO_THREADS);
}
srv_is_being_started = FALSE;
err = dict_create_or_check_foreign_constraint_tables();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment