Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
15b4441d
Commit
15b4441d
authored
Jan 22, 2014
by
Sergei Golubchik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Percona-Server-5.5.35-rel33.0.tar.gz
parent
667f381a
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
405 additions
and
136 deletions
+405
-136
btr/btr0cur.c
btr/btr0cur.c
+22
-9
btr/btr0pcur.c
btr/btr0pcur.c
+19
-27
buf/buf0buf.c
buf/buf0buf.c
+5
-1
buf/buf0flu.c
buf/buf0flu.c
+10
-0
dict/dict0dict.c
dict/dict0dict.c
+13
-0
fil/fil0fil.c
fil/fil0fil.c
+2
-1
handler/ha_innodb.cc
handler/ha_innodb.cc
+49
-31
handler/i_s.cc
handler/i_s.cc
+4
-0
ibuf/ibuf0ibuf.c
ibuf/ibuf0ibuf.c
+24
-5
include/btr0cur.h
include/btr0cur.h
+15
-0
include/btr0pcur.h
include/btr0pcur.h
+24
-20
include/btr0pcur.ic
include/btr0pcur.ic
+2
-2
include/btr0sea.h
include/btr0sea.h
+0
-2
include/dict0types.h
include/dict0types.h
+5
-0
include/ibuf0ibuf.h
include/ibuf0ibuf.h
+0
-5
include/log0log.h
include/log0log.h
+2
-0
include/univ.i
include/univ.i
+1
-1
log/log0log.c
log/log0log.c
+109
-1
log/log0online.c
log/log0online.c
+16
-3
row/row0sel.c
row/row0sel.c
+75
-28
trx/trx0trx.c
trx/trx0trx.c
+8
-0
No files found.
btr/btr0cur.c
View file @
15b4441d
...
...
@@ -61,6 +61,7 @@ Created 10/16/1994 Heikki Tuuri
#include "row0upd.h"
#include "trx0rec.h"
#include "trx0roll.h"
/* trx_is_recv() */
#include "trx0undo.h"
#include "que0que.h"
#include "row0row.h"
#include "srv0srv.h"
...
...
@@ -1757,7 +1758,7 @@ btr_cur_upd_lock_and_undo(
/***********************************************************//**
Writes a redo log record of updating a record in-place. */
UNIV_IN
LINE
UNIV_IN
TERN
void
btr_cur_update_in_place_log
(
/*========================*/
...
...
@@ -1785,18 +1786,30 @@ btr_cur_update_in_place_log(
return
;
}
/*
The code below assumes index is a clustered index: change index to
t
he clustered index if we are updating a secondary index record (or we
could as well skip writing the sys col values to the log in this case
because they are not needed for a secondary index record update) */
index
=
dict_table_get_first_index
(
index
->
table
);
/*
For secondary indexes, we could skip writing the dummy system fields
t
o the redo log but we have to change redo log parsing of
MLOG_REC_UPDATE_IN_PLACE/MLOG_COMP_REC_UPDATE_IN_PLACE or we have to add
new redo log record. For now, just write dummy sys fields to the redo
log if we are updating a secondary index record.
*/
mach_write_to_1
(
log_ptr
,
flags
);
log_ptr
++
;
log_ptr
=
row_upd_write_sys_vals_to_log
(
index
,
trx
,
roll_ptr
,
log_ptr
,
mtr
);
if
(
dict_index_is_clust
(
index
))
{
log_ptr
=
row_upd_write_sys_vals_to_log
(
index
,
trx
,
roll_ptr
,
log_ptr
,
mtr
);
}
else
{
/* Dummy system fields for a secondary index */
/* TRX_ID Position */
log_ptr
+=
mach_write_compressed
(
log_ptr
,
0
);
/* ROLL_PTR */
trx_write_roll_ptr
(
log_ptr
,
0
);
log_ptr
+=
DATA_ROLL_PTR_LEN
;
/* TRX_ID */
log_ptr
+=
mach_ull_write_compressed
(
log_ptr
,
0
);
}
mach_write_to_2
(
log_ptr
,
page_offset
(
rec
));
log_ptr
+=
2
;
...
...
btr/btr0pcur.c
View file @
15b4441d
/*****************************************************************************
Copyright (c) 1996, 201
2
, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1996, 201
3
, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
...
...
@@ -111,7 +111,7 @@ btr_pcur_store_position(
page_t
*
page
;
ulint
offs
;
ut_a
(
cursor
->
pos_state
==
BTR_PCUR_IS_POSITIONED
);
ut_a
d
(
cursor
->
pos_state
==
BTR_PCUR_IS_POSITIONED
);
ut_ad
(
cursor
->
latch_mode
!=
BTR_NO_LATCHES
);
block
=
btr_pcur_get_block
(
cursor
);
...
...
@@ -128,7 +128,6 @@ btr_pcur_store_position(
ut_ad
(
mtr_memo_contains
(
mtr
,
block
,
MTR_MEMO_PAGE_S_FIX
)
||
mtr_memo_contains
(
mtr
,
block
,
MTR_MEMO_PAGE_X_FIX
));
ut_a
(
cursor
->
latch_mode
!=
BTR_NO_LATCHES
);
if
(
UNIV_UNLIKELY
(
page_get_n_recs
(
page
)
==
0
))
{
/* It must be an empty index tree; NOTE that in this case
...
...
@@ -239,21 +238,12 @@ btr_pcur_restore_position_func(
ut_ad
(
mtr
);
ut_ad
(
mtr
->
state
==
MTR_ACTIVE
);
ut_ad
(
cursor
->
old_stored
==
BTR_PCUR_OLD_STORED
);
ut_ad
(
cursor
->
pos_state
==
BTR_PCUR_WAS_POSITIONED
||
cursor
->
pos_state
==
BTR_PCUR_IS_POSITIONED
);
index
=
btr_cur_get_index
(
btr_pcur_get_btr_cur
(
cursor
));
if
(
UNIV_UNLIKELY
(
cursor
->
old_stored
!=
BTR_PCUR_OLD_STORED
)
||
UNIV_UNLIKELY
(
cursor
->
pos_state
!=
BTR_PCUR_WAS_POSITIONED
&&
cursor
->
pos_state
!=
BTR_PCUR_IS_POSITIONED
))
{
ut_print_buf
(
stderr
,
cursor
,
sizeof
(
btr_pcur_t
));
putc
(
'\n'
,
stderr
);
if
(
cursor
->
trx_if_known
)
{
trx_print
(
stderr
,
cursor
->
trx_if_known
,
0
);
}
ut_error
;
}
if
(
UNIV_UNLIKELY
(
cursor
->
rel_pos
==
BTR_PCUR_AFTER_LAST_IN_TREE
||
cursor
->
rel_pos
==
BTR_PCUR_BEFORE_FIRST_IN_TREE
))
{
...
...
@@ -277,14 +267,14 @@ btr_pcur_restore_position_func(
if
(
UNIV_LIKELY
(
latch_mode
==
BTR_SEARCH_LEAF
)
||
UNIV_LIKELY
(
latch_mode
==
BTR_MODIFY_LEAF
))
{
/* Try optimistic restoration */
/* Try optimistic restoration
.
*/
if
(
UNIV_LIKELY
(
buf_page_optimistic_get
(
latch_mode
,
cursor
->
block_when_stored
,
cursor
->
modify_clock
,
file
,
line
,
mtr
)))
{
if
(
buf_page_optimistic_get
(
latch_mode
,
cursor
->
block_when_stored
,
cursor
->
modify_clock
,
file
,
line
,
mtr
))
{
cursor
->
pos_state
=
BTR_PCUR_IS_POSITIONED
;
cursor
->
latch_mode
=
latch_mode
;
buf_block_dbg_add_level
(
btr_pcur_get_block
(
cursor
),
...
...
@@ -296,9 +286,6 @@ btr_pcur_restore_position_func(
const
rec_t
*
rec
;
const
ulint
*
offsets1
;
const
ulint
*
offsets2
;
#endif
/* UNIV_DEBUG */
cursor
->
latch_mode
=
latch_mode
;
#ifdef UNIV_DEBUG
rec
=
btr_pcur_get_rec
(
cursor
);
heap
=
mem_heap_create
(
256
);
...
...
@@ -316,7 +303,13 @@ btr_pcur_restore_position_func(
#endif
/* UNIV_DEBUG */
return
(
TRUE
);
}
/* This is the same record as stored,
may need to be adjusted for BTR_PCUR_BEFORE/AFTER,
depending on search mode and direction. */
if
(
btr_pcur_is_on_user_rec
(
cursor
))
{
cursor
->
pos_state
=
BTR_PCUR_IS_POSITIONED_OPTIMISTIC
;
}
return
(
FALSE
);
}
}
...
...
@@ -418,7 +411,7 @@ btr_pcur_move_to_next_page(
buf_block_t
*
next_block
;
page_t
*
next_page
;
ut_a
(
cursor
->
pos_state
==
BTR_PCUR_IS_POSITIONED
);
ut_a
d
(
cursor
->
pos_state
==
BTR_PCUR_IS_POSITIONED
);
ut_ad
(
cursor
->
latch_mode
!=
BTR_NO_LATCHES
);
ut_ad
(
btr_pcur_is_after_last_on_page
(
cursor
));
...
...
@@ -484,7 +477,6 @@ btr_pcur_move_backward_from_page(
ulint
latch_mode
;
ulint
latch_mode2
;
ut_a
(
cursor
->
pos_state
==
BTR_PCUR_IS_POSITIONED
);
ut_ad
(
cursor
->
latch_mode
!=
BTR_NO_LATCHES
);
ut_ad
(
btr_pcur_is_before_first_on_page
(
cursor
));
ut_ad
(
!
btr_pcur_is_before_first_in_tree
(
cursor
,
mtr
));
...
...
buf/buf0buf.c
View file @
15b4441d
...
...
@@ -4754,12 +4754,16 @@ buf_get_latched_pages_number_instance(
case
BUF_BLOCK_FILE_PAGE
:
/* uncompressed page */
break
;
case
BUF_BLOCK_REMOVE_HASH
:
/* We hold flush list but not LRU list mutex here.
Thus encountering BUF_BLOCK_REMOVE_HASH pages is
possible. */
break
;
case
BUF_BLOCK_ZIP_FREE
:
case
BUF_BLOCK_ZIP_PAGE
:
case
BUF_BLOCK_NOT_USED
:
case
BUF_BLOCK_READY_FOR_USE
:
case
BUF_BLOCK_MEMORY
:
case
BUF_BLOCK_REMOVE_HASH
:
ut_error
;
break
;
}
...
...
buf/buf0flu.c
View file @
15b4441d
...
...
@@ -1605,6 +1605,16 @@ buf_flush_page_and_try_neighbors(
ut_ad
(
block_mutex
);
}
if
(
UNIV_UNLIKELY
(
buf_page_get_state
(
bpage
)
==
BUF_BLOCK_REMOVE_HASH
))
{
/* In case we don't hold the LRU list mutex, we may see a page
that is about to be relocated on the flush list. Do not
attempt to flush it. */
ut_ad
(
flush_type
==
BUF_FLUSH_LIST
);
return
(
flushed
);
}
ut_a
(
buf_page_in_file
(
bpage
));
if
(
buf_flush_ready_for_flush
(
bpage
,
flush_type
))
{
...
...
dict/dict0dict.c
View file @
15b4441d
...
...
@@ -36,6 +36,11 @@ UNIV_INTERN dict_index_t* dict_ind_redundant;
/** dummy index for ROW_FORMAT=COMPACT supremum and infimum records */
UNIV_INTERN
dict_index_t
*
dict_ind_compact
;
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
/** Flag to control insert buffer debugging. */
UNIV_INTERN
uint
ibuf_debug
;
#endif
/* UNIV_DEBUG || UNIV_IBUF_DEBUG */
#ifndef UNIV_HOTBACKUP
#include "buf0buf.h"
#include "data0type.h"
...
...
@@ -4855,6 +4860,8 @@ dict_update_statistics(
dict_index_t
*
index
;
ulint
sum_of_index_sizes
=
0
;
DBUG_EXECUTE_IF
(
"skip_innodb_statistics"
,
return
;);
if
(
table
->
ibd_file_missing
)
{
ut_print_timestamp
(
stderr
);
fprintf
(
stderr
,
...
...
@@ -4916,6 +4923,12 @@ dict_update_statistics(
continue
;
}
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
if
(
ibuf_debug
&&
!
dict_index_is_clust
(
index
))
{
goto
fake_statistics
;
}
#endif
/* UNIV_DEBUG || UNIV_IBUF_DEBUG */
if
(
UNIV_LIKELY
(
srv_force_recovery
<
SRV_FORCE_NO_IBUF_MERGE
||
(
srv_force_recovery
<
SRV_FORCE_NO_LOG_REDO
...
...
fil/fil0fil.c
View file @
15b4441d
...
...
@@ -4369,7 +4369,7 @@ fil_load_single_table_tablespace(
if
(
check_msg
)
{
fprintf
(
stderr
,
"InnoDB: Error: %s in file %s"
,
"InnoDB: Error: %s in file %s
\n
"
,
check_msg
,
filepath
);
goto
func_exit
;
}
...
...
@@ -4967,6 +4967,7 @@ fil_extend_space_to_desired_size(
space
->
size
+=
(
size_after_extend
-
start_page_no
);
os_has_said_disk_full
=
FALSE
;
}
fil_node_complete_io
(
node
,
fil_system
,
OS_FILE_READ
);
goto
complete_io
;
}
#endif
...
...
handler/ha_innodb.cc
View file @
15b4441d
...
...
@@ -55,6 +55,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
#include <mysql/innodb_priv.h>
#include <mysql/psi/psi.h>
#include <my_sys.h>
#include <my_check_opt.h>
#ifdef MYSQL_SERVER
#include <rpl_mi.h>
...
...
@@ -8810,6 +8811,10 @@ ha_innobase::records_in_range(
/* There exists possibility of not being able to find requested
index due to inconsistency between MySQL and InoDB dictionary info.
Necessary message should have been printed in innobase_get_index() */
if
(
prebuilt
->
table
->
ibd_file_missing
)
{
n_rows
=
HA_POS_ERROR
;
goto
func_exit
;
}
if
(
UNIV_UNLIKELY
(
!
index
))
{
n_rows
=
HA_POS_ERROR
;
goto
func_exit
;
...
...
@@ -9533,8 +9538,7 @@ int
ha_innobase
::
check
(
/*===============*/
THD
*
thd
,
/*!< in: user thread handle */
HA_CHECK_OPT
*
check_opt
)
/*!< in: check options, currently
ignored */
HA_CHECK_OPT
*
check_opt
)
/*!< in: check options */
{
dict_index_t
*
index
;
ulint
n_rows
;
...
...
@@ -9591,11 +9595,6 @@ ha_innobase::check(
do additional check */
prebuilt
->
table
->
corrupted
=
FALSE
;
/* Enlarge the fatal lock wait timeout during CHECK TABLE. */
mutex_enter
(
&
kernel_mutex
);
srv_fatal_semaphore_wait_threshold
+=
SRV_SEMAPHORE_WAIT_EXTENSION
;
mutex_exit
(
&
kernel_mutex
);
for
(
index
=
dict_table_get_first_index
(
prebuilt
->
table
);
index
!=
NULL
;
index
=
dict_table_get_next_index
(
index
))
{
...
...
@@ -9608,20 +9607,41 @@ ha_innobase::check(
/* If this is an index being created, break */
if
(
*
index
->
name
==
TEMP_INDEX_PREFIX
)
{
break
;
}
else
if
(
!
btr_validate_index
(
index
,
prebuilt
->
trx
))
{
is_ok
=
FALSE
;
continue
;
}
if
(
!
(
check_opt
->
flags
&
T_QUICK
))
{
/* Enlarge the fatal lock wait timeout during
CHECK TABLE. */
mutex_enter
(
&
kernel_mutex
);
srv_fatal_semaphore_wait_threshold
+=
SRV_SEMAPHORE_WAIT_EXTENSION
;
mutex_exit
(
&
kernel_mutex
);
ibool
valid
=
TRUE
;
valid
=
btr_validate_index
(
index
,
prebuilt
->
trx
);
/* Restore the fatal lock wait timeout after
CHECK TABLE. */
mutex_enter
(
&
kernel_mutex
);
srv_fatal_semaphore_wait_threshold
-=
SRV_SEMAPHORE_WAIT_EXTENSION
;
mutex_exit
(
&
kernel_mutex
);
if
(
!
valid
)
{
is_ok
=
FALSE
;
innobase_format_name
(
index_name
,
sizeof
index_name
,
prebuilt
->
index
->
name
,
TRUE
);
innobase_format_name
(
index_name
,
sizeof
index_name
,
index
->
name
,
TRUE
);
push_warning_printf
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_NOT_KEYFILE
,
"InnoDB: The B-tree of"
" index %s is corrupted."
,
index_name
);
push_warning_printf
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_NOT_KEYFILE
,
"InnoDB: The B-tree of"
" index %s is corrupted."
,
index_name
);
continue
;
continue
;
}
}
/* Instead of invoking change_active_index(), set up
...
...
@@ -9725,21 +9745,17 @@ ha_innobase::check(
/* Restore the original isolation level */
prebuilt
->
trx
->
isolation_level
=
old_isolation_level
;
/* We validate also the whole adaptive hash index for all tables
at every CHECK TABLE */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
/* We validate the whole adaptive hash index for all tables
at every CHECK TABLE only when QUICK flag is not present. */
if
(
!
btr_search_validate
())
{
if
(
!
(
check_opt
->
flags
&
T_QUICK
)
&&
!
btr_search_validate
())
{
push_warning
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_NOT_KEYFILE
,
"InnoDB: The adaptive hash index is corrupted."
);
is_ok
=
FALSE
;
}
/* Restore the fatal lock wait timeout after CHECK TABLE. */
mutex_enter
(
&
kernel_mutex
);
srv_fatal_semaphore_wait_threshold
-=
SRV_SEMAPHORE_WAIT_EXTENSION
;
mutex_exit
(
&
kernel_mutex
);
#endif
/* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
prebuilt
->
trx
->
op_info
=
""
;
if
(
thd_killed
(
user_thd
))
{
my_error
(
ER_QUERY_INTERRUPTED
,
MYF
(
0
));
...
...
@@ -10623,6 +10639,7 @@ innodb_show_status(
const
long
MAX_STATUS_SIZE
=
1048576
;
ulint
trx_list_start
=
ULINT_UNDEFINED
;
ulint
trx_list_end
=
ULINT_UNDEFINED
;
bool
ret_val
;
DBUG_ENTER
(
"innodb_show_status"
);
DBUG_ASSERT
(
hton
==
innodb_hton_ptr
);
...
...
@@ -10687,12 +10704,13 @@ innodb_show_status(
mutex_exit
(
&
srv_monitor_file_mutex
);
stat_print
(
thd
,
innobase_hton_name
,
(
uint
)
strlen
(
innobase_hton_name
),
STRING_WITH_LEN
(
""
),
str
,
flen
);
ret_val
=
stat_print
(
thd
,
innobase_hton_name
,
(
uint
)
strlen
(
innobase_hton_name
),
STRING_WITH_LEN
(
""
),
str
,
flen
);
my_free
(
str
);
DBUG_RETURN
(
FALSE
);
DBUG_RETURN
(
ret_val
);
}
/************************************************************************//**
...
...
handler/i_s.cc
View file @
15b4441d
...
...
@@ -48,14 +48,18 @@ extern "C" {
#include "btr0types.h"
#include "buf0buddy.h"
#include "buf0buf.h"
#include "buf0lru.h"
#include "ibuf0ibuf.h"
#include "dict0mem.h"
#include "dict0types.h"
#include "dict0boot.h"
#include "dict0load.h"
#include "ha_prototypes.h"
#include "srv0start.h"
#include "srv0srv.h"
#include "trx0i_s.h"
#include "trx0rseg.h"
#include "trx0trx.h"
#include "trx0undo.h"
#include "log0online.h"
#include "btr0btr.h"
...
...
ibuf/ibuf0ibuf.c
View file @
15b4441d
...
...
@@ -194,11 +194,6 @@ access order rules. */
/** Operations that can currently be buffered. */
UNIV_INTERN
ibuf_use_t
ibuf_use
=
IBUF_USE_ALL
;
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
/** Flag to control insert buffer debugging. */
UNIV_INTERN
uint
ibuf_debug
;
#endif
/* UNIV_DEBUG || UNIV_IBUF_DEBUG */
/** The insert buffer control structure */
UNIV_INTERN
ibuf_t
*
ibuf
=
NULL
;
...
...
@@ -2693,6 +2688,12 @@ ibuf_contract_ext(
return
(
0
);
}
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
if
(
ibuf_debug
)
{
return
(
0
);
}
#endif
/* UNIV_DEBUG || UNIV_IBUF_DEBUG */
ibuf_mtr_start
(
&
mtr
);
/* Open a cursor to a randomly chosen leaf of the tree, at a random
...
...
@@ -4066,6 +4067,24 @@ updated_in_place:
to btr_cur_update_in_place(). */
row_upd_rec_in_place
(
rec
,
index
,
offsets
,
update
,
page_zip
);
/* Log the update in place operation. During recovery
MLOG_COMP_REC_UPDATE_IN_PLACE/MLOG_REC_UPDATE_IN_PLACE
expects trx_id, roll_ptr for secondary indexes. So we
just write dummy trx_id(0), roll_ptr(0) */
btr_cur_update_in_place_log
(
BTR_KEEP_SYS_FLAG
,
rec
,
index
,
update
,
NULL
,
0
,
mtr
);
DBUG_EXECUTE_IF
(
"crash_after_log_ibuf_upd_inplace"
,
log_buffer_flush_to_disk
();
fprintf
(
stderr
,
"InnoDB: Wrote log record for ibuf "
"update in place operation
\n
"
);
DBUG_SUICIDE
();
);
goto
updated_in_place
;
}
...
...
include/btr0cur.h
View file @
15b4441d
...
...
@@ -637,6 +637,21 @@ btr_cur_set_deleted_flag_for_ibuf(
uncompressed */
ibool
val
,
/*!< in: value to set */
mtr_t
*
mtr
);
/*!< in/out: mini-transaction */
/***********************************************************//**
Writes a redo log record of updating a record in-place. */
UNIV_INTERN
void
btr_cur_update_in_place_log
(
/*========================*/
ulint
flags
,
/*!< in: flags */
rec_t
*
rec
,
/*!< in: record */
dict_index_t
*
index
,
/*!< in: index where cursor positioned */
const
upd_t
*
update
,
/*!< in: update vector */
trx_t
*
trx
,
/*!< in: transaction */
roll_ptr_t
roll_ptr
,
/*!< in: roll ptr */
mtr_t
*
mtr
);
/*!< in: mtr */
/*######################################################################*/
/** In the pessimistic delete, if the page data size drops below this
...
...
include/btr0pcur.h
View file @
15b4441d
/*****************************************************************************
Copyright (c) 1996, 201
1
, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1996, 201
3
, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
...
...
@@ -447,6 +447,27 @@ btr_pcur_move_to_prev_on_page(
/*==========================*/
btr_pcur_t
*
cursor
);
/*!< in/out: persistent cursor */
/** Position state of persistent B-tree cursor. */
enum
pcur_pos_t
{
/** The persistent cursor is not positioned. */
BTR_PCUR_NOT_POSITIONED
=
0
,
/** The persistent cursor was previously positioned.
TODO: currently, the state can be BTR_PCUR_IS_POSITIONED,
though it really should be BTR_PCUR_WAS_POSITIONED,
because we have no obligation to commit the cursor with
mtr; similarly latch_mode may be out of date. This can
lead to problems if btr_pcur is not used the right way;
all current code should be ok. */
BTR_PCUR_WAS_POSITIONED
,
/** The persistent cursor is positioned by optimistic get to the same
record as it was positioned at. Not used for rel_pos == BTR_PCUR_ON.
It may need adjustment depending on previous/current search direction
and rel_pos. */
BTR_PCUR_IS_POSITIONED_OPTIMISTIC
,
/** The persistent cursor is positioned by index search.
Or optimistic get for rel_pos == BTR_PCUR_ON. */
BTR_PCUR_IS_POSITIONED
};
/* The persistent B-tree cursor structure. This is used mainly for SQL
selects, updates, and deletes. */
...
...
@@ -480,10 +501,8 @@ struct btr_pcur_struct{
ib_uint64_t
modify_clock
;
/*!< the modify clock value of the
buffer block when the cursor position
was stored */
ulint
pos_state
;
/*!< see TODO note below!
BTR_PCUR_IS_POSITIONED,
BTR_PCUR_WAS_POSITIONED,
BTR_PCUR_NOT_POSITIONED */
enum
pcur_pos_t
pos_state
;
/*!< btr_pcur_store_position() and
btr_pcur_restore_position() state. */
ulint
search_mode
;
/*!< PAGE_CUR_G, ... */
trx_t
*
trx_if_known
;
/*!< the transaction, if we know it;
otherwise this field is not defined;
...
...
@@ -499,21 +518,6 @@ struct btr_pcur_struct{
is not NULL */
};
#define BTR_PCUR_IS_POSITIONED 1997660512
/* TODO: currently, the state
can be BTR_PCUR_IS_POSITIONED,
though it really should be
BTR_PCUR_WAS_POSITIONED,
because we have no obligation
to commit the cursor with
mtr; similarly latch_mode may
be out of date. This can
lead to problems if btr_pcur
is not used the right way;
all current code should be
ok. */
#define BTR_PCUR_WAS_POSITIONED 1187549791
#define BTR_PCUR_NOT_POSITIONED 1328997689
#define BTR_PCUR_OLD_STORED 908467085
#define BTR_PCUR_OLD_NOT_STORED 122766467
...
...
include/btr0pcur.ic
View file @
15b4441d
/*****************************************************************************
Copyright (c) 1996, 201
1
, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1996, 201
3
, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
...
...
@@ -379,7 +379,7 @@ btr_pcur_commit_specify_mtr(
btr_pcur_t* pcur, /*!< in: persistent cursor */
mtr_t* mtr) /*!< in: mtr to commit */
{
ut_a(pcur->pos_state == BTR_PCUR_IS_POSITIONED);
ut_a
d
(pcur->pos_state == BTR_PCUR_IS_POSITIONED);
pcur->latch_mode = BTR_NO_LATCHES;
...
...
include/btr0sea.h
View file @
15b4441d
...
...
@@ -196,8 +196,6 @@ UNIV_INTERN
ibool
btr_search_validate
(
void
);
/*======================*/
#else
# define btr_search_validate() TRUE
#endif
/* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
/********************************************************************//**
...
...
include/dict0types.h
View file @
15b4441d
...
...
@@ -63,4 +63,9 @@ typedef enum dict_err_ignore dict_err_ignore_t;
#define TEMP_TABLE_PREFIX "#sql"
#define TEMP_TABLE_PATH_PREFIX "/" TEMP_TABLE_PREFIX
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
/** Flag to control insert buffer debugging. */
extern
uint
ibuf_debug
;
#endif
/* UNIV_DEBUG || UNIV_IBUF_DEBUG */
#endif
include/ibuf0ibuf.h
View file @
15b4441d
...
...
@@ -63,11 +63,6 @@ typedef enum {
/** Operations that can currently be buffered. */
extern
ibuf_use_t
ibuf_use
;
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
/** Flag to control insert buffer debugging. */
extern
uint
ibuf_debug
;
#endif
/* UNIV_DEBUG || UNIV_IBUF_DEBUG */
/** The insert buffer control structure */
extern
ibuf_t
*
ibuf
;
...
...
include/log0log.h
View file @
15b4441d
...
...
@@ -822,6 +822,8 @@ struct log_struct{
later; this is advanced when a flush
operation is completed to all the log
groups */
volatile
ibool
is_extending
;
/*!< this is set to true during extend
the log buffer size */
ib_uint64_t
written_to_some_lsn
;
/*!< first log sequence number not yet
written to any log group; for this to
...
...
include/univ.i
View file @
15b4441d
...
...
@@ -64,7 +64,7 @@ component, i.e. we show M.N.P as M.N */
(
INNODB_VERSION_MAJOR
<<
8
|
INNODB_VERSION_MINOR
)
#
ifndef
PERCONA_INNODB_VERSION
#
define
PERCONA_INNODB_VERSION
29.3
#
define
PERCONA_INNODB_VERSION
33.0
#
endif
#
define
INNODB_VERSION_STR
MYSQL_SERVER_VERSION
"-"
IB_TO_STR
(
PERCONA_INNODB_VERSION
)
...
...
log/log0log.c
View file @
15b4441d
...
...
@@ -262,6 +262,85 @@ log_check_tracking_margin(
return
tracked_lsn_age
+
lsn_advance
>
log_sys
->
max_checkpoint_age
;
}
/** Extends the log buffer.
@param[in] len requested minimum size in bytes */
static
void
log_buffer_extend
(
ulint
len
)
{
ulint
move_start
;
ulint
move_end
;
byte
tmp_buf
[
OS_FILE_LOG_BLOCK_SIZE
];
mutex_enter
(
&
(
log_sys
->
mutex
));
while
(
log_sys
->
is_extending
)
{
/* Another thread is trying to extend already.
Needs to wait for. */
mutex_exit
(
&
(
log_sys
->
mutex
));
log_buffer_flush_to_disk
();
mutex_enter
(
&
(
log_sys
->
mutex
));
if
(
srv_log_buffer_size
>
len
/
UNIV_PAGE_SIZE
)
{
/* Already extended enough by the others */
mutex_exit
(
&
(
log_sys
->
mutex
));
return
;
}
}
log_sys
->
is_extending
=
TRUE
;
while
(
log_sys
->
n_pending_writes
!=
0
||
ut_calc_align_down
(
log_sys
->
buf_free
,
OS_FILE_LOG_BLOCK_SIZE
)
!=
ut_calc_align_down
(
log_sys
->
buf_next_to_write
,
OS_FILE_LOG_BLOCK_SIZE
))
{
/* Buffer might have >1 blocks to write still. */
mutex_exit
(
&
(
log_sys
->
mutex
));
log_buffer_flush_to_disk
();
mutex_enter
(
&
(
log_sys
->
mutex
));
}
move_start
=
ut_calc_align_down
(
log_sys
->
buf_free
,
OS_FILE_LOG_BLOCK_SIZE
);
move_end
=
log_sys
->
buf_free
;
/* store the last log block in buffer */
ut_memcpy
(
tmp_buf
,
log_sys
->
buf
+
move_start
,
move_end
-
move_start
);
log_sys
->
buf_free
-=
move_start
;
log_sys
->
buf_next_to_write
-=
move_start
;
/* reallocate log buffer */
srv_log_buffer_size
=
len
/
UNIV_PAGE_SIZE
+
1
;
mem_free
(
log_sys
->
buf_ptr
);
log_sys
->
buf_ptr
=
mem_alloc
(
LOG_BUFFER_SIZE
+
OS_FILE_LOG_BLOCK_SIZE
);
log_sys
->
buf
=
ut_align
(
log_sys
->
buf_ptr
,
OS_FILE_LOG_BLOCK_SIZE
);
log_sys
->
buf_size
=
LOG_BUFFER_SIZE
;
memset
(
log_sys
->
buf
,
'\0'
,
LOG_BUFFER_SIZE
);
log_sys
->
max_buf_free
=
log_sys
->
buf_size
/
LOG_BUF_FLUSH_RATIO
-
LOG_BUF_FLUSH_MARGIN
;
/* restore the last log block */
ut_memcpy
(
log_sys
->
buf
,
tmp_buf
,
move_end
-
move_start
);
ut_ad
(
log_sys
->
is_extending
);
log_sys
->
is_extending
=
FALSE
;
mutex_exit
(
&
(
log_sys
->
mutex
));
fprintf
(
stderr
,
"InnoDB: innodb_log_buffer_size was extended to %lu.
\n
"
,
LOG_BUFFER_SIZE
);
}
/************************************************************//**
Opens the log for log_write_low. The log must be closed with log_close.
@return start lsn of the log record */
...
...
@@ -279,10 +358,38 @@ log_open(
#endif
/* UNIV_LOG_ARCHIVE */
ulint
count
=
0
;
ut_a
(
len
<
log
->
buf_size
/
2
);
if
(
len
>=
log
->
buf_size
/
2
)
{
DBUG_EXECUTE_IF
(
"ib_log_buffer_is_short_crash"
,
DBUG_SUICIDE
(););
/* log_buffer is too small. try to extend instead of crash. */
ut_print_timestamp
(
stderr
);
fprintf
(
stderr
,
" InnoDB: Warning: "
"The transaction log size is too large"
" for innodb_log_buffer_size (%lu >= %lu / 2). "
"Trying to extend it.
\n
"
,
len
,
LOG_BUFFER_SIZE
);
log_buffer_extend
((
len
+
1
)
*
2
);
}
loop:
ut_ad
(
!
recv_no_log_write
);
if
(
log
->
is_extending
)
{
mutex_exit
(
&
(
log
->
mutex
));
/* Log buffer size is extending. Writing up to the next block
should wait for the extending finished. */
os_thread_sleep
(
100000
);
ut_ad
(
++
count
<
50
);
goto
loop
;
}
/* Calculate an upper limit for the space the string may take in the
log buffer */
...
...
@@ -899,6 +1006,7 @@ log_init(void)
log_sys
->
buf
=
ut_align
(
log_sys
->
buf_ptr
,
OS_FILE_LOG_BLOCK_SIZE
);
log_sys
->
buf_size
=
LOG_BUFFER_SIZE
;
log_sys
->
is_extending
=
FALSE
;
memset
(
log_sys
->
buf
,
'\0'
,
LOG_BUFFER_SIZE
);
...
...
log/log0online.c
View file @
15b4441d
...
...
@@ -1790,7 +1790,8 @@ log_online_purge_changed_page_bitmaps(
mutex_enter
(
&
log_bmp_sys
->
mutex
);
}
if
(
!
log_online_setup_bitmap_file_range
(
&
bitmap_files
,
0
,
lsn
))
{
if
(
!
log_online_setup_bitmap_file_range
(
&
bitmap_files
,
0
,
IB_ULONGLONG_MAX
))
{
if
(
srv_track_changed_pages
)
{
mutex_exit
(
&
log_bmp_sys
->
mutex
);
}
...
...
@@ -1805,8 +1806,20 @@ log_online_purge_changed_page_bitmaps(
}
for
(
i
=
0
;
i
<
bitmap_files
.
count
;
i
++
)
{
if
(
bitmap_files
.
files
[
i
].
seq_num
==
0
||
bitmap_files
.
files
[
i
].
start_lsn
>=
lsn
)
{
/* We consider the end LSN of the current bitmap, derived from
the start LSN of the subsequent bitmap file, to determine
whether to remove the current bitmap. Note that bitmap_files
does not contain an entry for the bitmap past the given LSN so
we must check the boundary conditions as well. For example,
consider 1_0.xdb and 2_10.xdb and querying LSN 5. bitmap_files
will only contain 1_0.xdb and we must not delete it since it
represents LSNs 0-9. */
if
((
i
+
1
==
bitmap_files
.
count
||
bitmap_files
.
files
[
i
+
1
].
seq_num
==
0
||
bitmap_files
.
files
[
i
+
1
].
start_lsn
>
lsn
)
&&
(
lsn
!=
IB_ULONGLONG_MAX
))
{
break
;
}
if
(
!
os_file_delete_if_exists
(
bitmap_files
.
files
[
i
].
name
))
{
...
...
row/row0sel.c
View file @
15b4441d
...
...
@@ -3099,48 +3099,78 @@ sel_restore_position_for_mysql(
mtr_t
*
mtr
)
/*!< in: mtr; CAUTION: may commit
mtr temporarily! */
{
ibool
success
;
ulint
relative_position
;
relative_position
=
pcur
->
rel_pos
;
ibool
success
;
success
=
btr_pcur_restore_position
(
latch_mode
,
pcur
,
mtr
);
*
same_user_rec
=
success
;
if
(
relative_position
==
BTR_PCUR_ON
)
{
if
(
success
)
{
return
(
FALSE
);
}
if
(
moves_up
)
{
btr_pcur_move_to_next
(
pcur
,
mtr
);
}
return
(
TRUE
);
ut_ad
(
!
success
||
pcur
->
rel_pos
==
BTR_PCUR_ON
);
#ifdef UNIV_DEBUG
if
(
pcur
->
pos_state
==
BTR_PCUR_IS_POSITIONED_OPTIMISTIC
)
{
ut_ad
(
pcur
->
rel_pos
==
BTR_PCUR_BEFORE
||
pcur
->
rel_pos
==
BTR_PCUR_AFTER
);
}
else
{
ut_ad
(
pcur
->
pos_state
==
BTR_PCUR_IS_POSITIONED
);
ut_ad
((
pcur
->
rel_pos
==
BTR_PCUR_ON
)
==
btr_pcur_is_on_user_rec
(
pcur
));
}
#endif
if
(
relative_position
==
BTR_PCUR_AFTER
||
relative_position
==
BTR_PCUR_AFTER_LAST_IN_TREE
)
{
/* The position may need be adjusted for rel_pos and moves_up. */
if
(
moves_up
)
{
switch
(
pcur
->
rel_pos
)
{
case
BTR_PCUR_ON
:
if
(
!
success
&&
moves_up
)
{
next:
btr_pcur_move_to_next
(
pcur
,
mtr
);
return
(
TRUE
);
}
if
(
btr_pcur_is_on_user_rec
(
pcur
))
{
return
(
!
success
);
case
BTR_PCUR_AFTER_LAST_IN_TREE
:
case
BTR_PCUR_BEFORE_FIRST_IN_TREE
:
return
(
TRUE
);
case
BTR_PCUR_AFTER
:
/* positioned to record after pcur->old_rec. */
pcur
->
pos_state
=
BTR_PCUR_IS_POSITIONED
;
prev:
if
(
btr_pcur_is_on_user_rec
(
pcur
)
&&
!
moves_up
)
{
btr_pcur_move_to_prev
(
pcur
,
mtr
);
}
return
(
TRUE
);
case
BTR_PCUR_BEFORE
:
/* For non optimistic restoration:
The position is now set to the record before pcur->old_rec.
For optimistic restoration:
The position also needs to take the previous search_mode into
consideration. */
switch
(
pcur
->
pos_state
)
{
case
BTR_PCUR_IS_POSITIONED_OPTIMISTIC
:
pcur
->
pos_state
=
BTR_PCUR_IS_POSITIONED
;
if
(
pcur
->
search_mode
==
PAGE_CUR_GE
)
{
/* Positioned during Greater or Equal search
with BTR_PCUR_BEFORE. Optimistic restore to
the same record. If scanning for lower then
we must move to previous record.
This can happen with:
HANDLER READ idx a = (const);
HANDLER READ idx PREV; */
goto
prev
;
}
return
(
TRUE
);
case
BTR_PCUR_IS_POSITIONED
:
if
(
moves_up
&&
btr_pcur_is_on_user_rec
(
pcur
))
{
goto
next
;
}
return
(
TRUE
);
case
BTR_PCUR_WAS_POSITIONED
:
case
BTR_PCUR_NOT_POSITIONED
:
break
;
}
}
ut_ad
(
relative_position
==
BTR_PCUR_BEFORE
||
relative_position
==
BTR_PCUR_BEFORE_FIRST_IN_TREE
);
if
(
moves_up
&&
btr_pcur_is_on_user_rec
(
pcur
))
{
btr_pcur_move_to_next
(
pcur
,
mtr
);
}
ut_ad
(
0
);
return
(
TRUE
);
}
...
...
@@ -4141,6 +4171,14 @@ wrong_offs:
btr_pcur_store_position
(
pcur
,
&
mtr
);
/* The found record was not a match, but may be used
as NEXT record (index_next). Set the relative position
to BTR_PCUR_BEFORE, to reflect that the position of
the persistent cursor is before the found/stored row
(pcur->old_rec). */
ut_ad
(
pcur
->
rel_pos
==
BTR_PCUR_ON
);
pcur
->
rel_pos
=
BTR_PCUR_BEFORE
;
err
=
DB_RECORD_NOT_FOUND
;
/* ut_print_name(stderr, index->name);
fputs(" record not found 3\n", stderr); */
...
...
@@ -4180,6 +4218,14 @@ wrong_offs:
btr_pcur_store_position
(
pcur
,
&
mtr
);
/* The found record was not a match, but may be used
as NEXT record (index_next). Set the relative position
to BTR_PCUR_BEFORE, to reflect that the position of
the persistent cursor is before the found/stored row
(pcur->old_rec). */
ut_ad
(
pcur
->
rel_pos
==
BTR_PCUR_ON
);
pcur
->
rel_pos
=
BTR_PCUR_BEFORE
;
err
=
DB_RECORD_NOT_FOUND
;
/* ut_print_name(stderr, index->name);
fputs(" record not found 4\n", stderr); */
...
...
@@ -4757,6 +4803,7 @@ normal_return:
if
(
prebuilt
->
n_fetch_cached
>
0
)
{
row_sel_pop_cached_row_for_mysql
(
buf
,
prebuilt
);
DEBUG_SYNC_C
(
"row_search_cached_row"
);
err
=
DB_SUCCESS
;
}
...
...
trx/trx0trx.c
View file @
15b4441d
...
...
@@ -1306,7 +1306,15 @@ trx_cleanup_at_db_startup(
}
trx
->
state
=
TRX_NOT_STARTED
;
/* This code is executed in a single threaded context, but we acquire
kernel_mutex to satisfy a debug assertion in
trx_release_descriptor(). */
mutex_enter
(
&
kernel_mutex
);
trx_release_descriptor
(
trx
);
mutex_exit
(
&
kernel_mutex
);
trx
->
rseg
=
NULL
;
trx
->
undo_no
=
0
;
trx
->
last_sql_stat_start
.
least_undo_no
=
0
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment