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
31d63cd0
Commit
31d63cd0
authored
Aug 30, 2007
by
marko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
branches/zip: Merge 1664:1783 from trunk.
parent
94eee936
Changes
18
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
245 additions
and
278 deletions
+245
-278
handler/ha_innodb.cc
handler/ha_innodb.cc
+137
-191
ibuf/ibuf0ibuf.c
ibuf/ibuf0ibuf.c
+0
-5
include/dict0mem.h
include/dict0mem.h
+15
-5
include/mach0data.h
include/mach0data.h
+11
-0
include/mach0data.ic
include/mach0data.ic
+37
-0
include/row0mysql.h
include/row0mysql.h
+8
-5
include/sync0rw.h
include/sync0rw.h
+2
-0
include/sync0rw.ic
include/sync0rw.ic
+1
-1
include/trx0trx.h
include/trx0trx.h
+0
-25
include/ut0mem.h
include/ut0mem.h
+1
-1
lock/lock0lock.c
lock/lock0lock.c
+7
-0
mysql-test/innodb.result
mysql-test/innodb.result
+1
-0
mysql-test/innodb.test
mysql-test/innodb.test
+3
-0
row/row0mysql.c
row/row0mysql.c
+9
-7
row/row0sel.c
row/row0sel.c
+8
-17
sync/sync0rw.c
sync/sync0rw.c
+3
-3
trx/trx0sys.c
trx/trx0sys.c
+2
-0
trx/trx0trx.c
trx/trx0trx.c
+0
-18
No files found.
handler/ha_innodb.cc
View file @
31d63cd0
...
...
@@ -60,12 +60,6 @@ static bool innodb_inited = 0;
*/
static
handlerton
*
innodb_hton_ptr
;
/* Store MySQL definition of 'byte': in Linux it is char while InnoDB
uses unsigned char; the header univ.i which we include next defines
'byte' as a macro which expands to 'unsigned char' */
typedef
uchar
mysql_byte
;
/* Include necessary InnoDB headers */
extern
"C"
{
#include "../storage/innobase/include/univ.i"
...
...
@@ -97,11 +91,15 @@ extern "C" {
#include "../storage/innobase/include/ha_prototypes.h"
}
static
const
long
AUTOINC_OLD_STYLE_LOCKING
=
0
;
static
const
long
AUTOINC_NEW_STYLE_LOCKING
=
1
;
static
const
long
AUTOINC_NO_LOCKING
=
2
;
static
long
innobase_mirrored_log_groups
,
innobase_log_files_in_group
,
innobase_log_buffer_size
,
innobase_additional_mem_pool_size
,
innobase_file_io_threads
,
innobase_lock_wait_timeout
,
innobase_force_recovery
,
innobase_open_files
;
innobase_open_files
,
innobase_autoinc_lock_mode
;
static
long
long
innobase_buffer_pool_size
,
innobase_log_file_size
;
...
...
@@ -147,7 +145,7 @@ static HASH innobase_open_tables;
bool
nw_panic
=
FALSE
;
#endif
static
mysql_byte
*
innobase_get_key
(
INNOBASE_SHARE
*
share
,
size_t
*
length
,
static
uchar
*
innobase_get_key
(
INNOBASE_SHARE
*
share
,
size_t
*
length
,
my_bool
not_used
__attribute__
((
unused
)));
static
INNOBASE_SHARE
*
get_share
(
const
char
*
table_name
);
static
void
free_share
(
INNOBASE_SHARE
*
share
);
...
...
@@ -1928,110 +1926,6 @@ retry:
DBUG_RETURN
(
0
);
}
#if 0
/* TODO: put the
MySQL-4.1 functionality back to 5.0. This is needed to get InnoDB Hot Backup
to work. */
/*********************************************************************
This is called when MySQL writes the binlog entry for the current
transaction. Writes to the InnoDB tablespace info which tells where the
MySQL binlog entry for the current transaction ended. Also commits the
transaction inside InnoDB but does NOT flush InnoDB log files to disk.
To flush you have to call innobase_commit_complete(). We have separated
flushing to eliminate the bottleneck of LOCK_log in log.cc which disabled
InnoDB's group commit capability. */
static
int
innobase_report_binlog_offset_and_commit(
/*=====================================*/
/* out: 0 */
handlerton *hton, /* in: Innodb handlerton */
THD* thd, /* in: user thread */
void* trx_handle, /* in: InnoDB trx handle */
char* log_file_name, /* in: latest binlog file name */
my_off_t end_offset) /* in: the offset in the binlog file
up to which we wrote */
{
trx_t* trx;
trx = (trx_t*)trx_handle;
ut_a(trx != NULL);
trx->mysql_log_file_name = log_file_name;
trx->mysql_log_offset = (ib_longlong)end_offset;
trx->flush_log_later = TRUE;
innobase_commit(hton, thd, TRUE);
trx->flush_log_later = FALSE;
return(0);
}
/***********************************************************************
This function stores the binlog offset and flushes logs. */
static
void
innobase_store_binlog_offset_and_flush_log(
/*=======================================*/
char* binlog_name, /* in: binlog name */
longlong offset) /* in: binlog offset */
{
mtr_t mtr;
assert(binlog_name != NULL);
/* Start a mini-transaction */
mtr_start(&mtr);
/* Update the latest MySQL binlog name and offset info
in trx sys header */
trx_sys_update_mysql_binlog_offset(
binlog_name,
offset,
TRX_SYS_MYSQL_LOG_INFO, &mtr);
/* Commits the mini-transaction */
mtr_commit(&mtr);
/* Synchronous flush of the log buffer to disk */
log_buffer_flush_to_disk();
}
/*********************************************************************
This is called after MySQL has written the binlog entry for the current
transaction. Flushes the InnoDB log files to disk if required. */
static
int
innobase_commit_complete(
/*=====================*/
/* out: 0 */
THD* thd) /* in: user thread */
{
trx_t* trx;
trx = thd_to_trx(thd);
if (trx && trx->active_trans) {
trx->active_trans = 0;
if (UNIV_UNLIKELY(srv_flush_log_at_trx_commit == 0)) {
return(0);
}
trx_commit_complete_for_mysql(trx);
}
return(0);
}
#endif
/*********************************************************************
Rolls back a transaction or the latest SQL statement. */
static
...
...
@@ -2411,7 +2305,7 @@ ha_innobase::open(
upd_and_key_val_buff_len
=
table
->
s
->
reclength
+
table
->
s
->
max_key_length
+
MAX_REF_PARTS
*
3
;
if
(
!
(
mysql_byte
*
)
my_multi_malloc
(
MYF
(
MY_WME
),
if
(
!
(
uchar
*
)
my_multi_malloc
(
MYF
(
MY_WME
),
&
upd_buff
,
upd_and_key_val_buff_len
,
&
key_val_buff
,
upd_and_key_val_buff_len
,
NullS
))
{
...
...
@@ -2846,7 +2740,7 @@ uint
innobase_read_from_2_little_endian
(
/*===============================*/
/* out: value */
const
mysql_byte
*
buf
)
/* in: from where to read */
const
uchar
*
buf
)
/* in: from where to read */
{
return
(
uint
)
((
ulint
)(
buf
[
0
])
+
256
*
((
ulint
)(
buf
[
1
])));
}
...
...
@@ -2862,7 +2756,7 @@ ha_innobase::store_key_val_for_row(
char
*
buff
,
/* in/out: buffer for the key value (in MySQL
format) */
uint
buff_len
,
/* in: buffer length */
const
mysql_byte
*
record
)
/* in: row in MySQL format */
const
uchar
*
record
)
/* in: row in MySQL format */
{
KEY
*
key_info
=
table
->
key_info
+
keynr
;
KEY_PART_INFO
*
key_part
=
key_info
->
key_part
;
...
...
@@ -3059,7 +2953,7 @@ ha_innobase::store_key_val_for_row(
CHARSET_INFO
*
cs
;
ulint
true_len
;
ulint
key_len
;
const
mysql_byte
*
src_start
;
const
uchar
*
src_start
;
int
error
=
0
;
enum_field_types
real_type
;
...
...
@@ -3352,24 +3246,46 @@ ha_innobase::innobase_autoinc_lock(void)
{
ulint
error
=
DB_SUCCESS
;
if
(
thd_sql_command
(
user_thd
)
==
SQLCOM_INSERT
)
{
switch
(
innobase_autoinc_lock_mode
)
{
case
AUTOINC_NO_LOCKING
:
/* Acquire only the AUTOINC mutex. */
dict_table_autoinc_lock
(
prebuilt
->
table
);
break
;
/* We peek at the dict_table_t::auto_inc_lock to check if
another statement has locked it */
if
(
prebuilt
->
trx
->
auto_inc_lock
!=
NULL
)
{
/* Release the mutex to avoid deadlocks */
dict_table_autoinc_unlock
(
prebuilt
->
table
);
case
AUTOINC_NEW_STYLE_LOCKING
:
/* For simple (single/multi) row INSERTs, we fallback to the
old style only if another transaction has already acquired
the AUTOINC lock on behalf of a LOAD FILE or INSERT ... SELECT
etc. type of statement. */
if
(
thd_sql_command
(
user_thd
)
==
SQLCOM_INSERT
)
{
dict_table_t
*
table
=
prebuilt
->
table
;
goto
acquire_auto_inc_lock
;
}
/* Acquire the AUTOINC mutex. */
dict_table_autoinc_lock
(
table
);
/* We need to check that another transaction isn't
already holding the AUTOINC lock on the table. */
if
(
table
->
n_waiting_or_granted_auto_inc_locks
)
{
/* Release the mutex to avoid deadlocks. */
dict_table_autoinc_unlock
(
table
);
}
else
{
acquire_auto_inc_lock:
break
;
}
}
/* Fall through to old style locking. */
case
AUTOINC_OLD_STYLE_LOCKING
:
error
=
row_lock_table_autoinc_for_mysql
(
prebuilt
);
if
(
error
==
DB_SUCCESS
)
{
/* Acquire the AUTOINC mutex. */
dict_table_autoinc_lock
(
prebuilt
->
table
);
}
break
;
default:
ut_error
;
}
return
(
ulong
(
error
));
...
...
@@ -3432,7 +3348,7 @@ int
ha_innobase
::
write_row
(
/*===================*/
/* out: error code */
mysql_byte
*
record
)
/* in: a row in MySQL format */
uchar
*
record
)
/* in: a row in MySQL format */
{
int
error
=
0
;
ibool
auto_inc_used
=
FALSE
;
...
...
@@ -3608,6 +3524,7 @@ no_commit:
if
(
auto_inc
>
prebuilt
->
last_value
)
{
set_max_autoinc:
ut_a
(
prebuilt
->
table
->
autoinc_increment
>
0
);
auto_inc
+=
prebuilt
->
table
->
autoinc_increment
;
innobase_set_max_autoinc
(
auto_inc
);
...
...
@@ -3635,16 +3552,16 @@ calc_row_difference(
/*================*/
/* out: error number or 0 */
upd_t
*
uvect
,
/* in/out: update vector */
mysql_byte
*
old_row
,
/* in: old row in MySQL format */
mysql_byte
*
new_row
,
/* in: new row in MySQL format */
uchar
*
old_row
,
/* in: old row in MySQL format */
uchar
*
new_row
,
/* in: new row in MySQL format */
struct
st_table
*
table
,
/* in: table in MySQL data
dictionary */
mysql_byte
*
upd_buff
,
/* in: buffer to use */
uchar
*
upd_buff
,
/* in: buffer to use */
ulint
buff_len
,
/* in: buffer length */
row_prebuilt_t
*
prebuilt
,
/* in: InnoDB prebuilt struct */
THD
*
thd
)
/* in: user thread */
{
mysql_byte
*
original_upd_buff
=
upd_buff
;
uchar
*
original_upd_buff
=
upd_buff
;
Field
*
field
;
enum_field_types
field_mysql_type
;
uint
n_fields
;
...
...
@@ -3785,8 +3702,8 @@ int
ha_innobase
::
update_row
(
/*====================*/
/* out: error number or 0 */
const
mysql_byte
*
old_row
,
/* in: old row in MySQL format */
mysql_byte
*
new_row
)
/* in: new row in MySQL format */
const
uchar
*
old_row
,
/* in: old row in MySQL format */
uchar
*
new_row
)
/* in: new row in MySQL format */
{
upd_t
*
uvect
;
int
error
=
0
;
...
...
@@ -3808,7 +3725,7 @@ ha_innobase::update_row(
/* Build an update vector from the modified fields in the rows
(uses upd_buff of the handle) */
calc_row_difference
(
uvect
,
(
mysql_byte
*
)
old_row
,
new_row
,
table
,
calc_row_difference
(
uvect
,
(
uchar
*
)
old_row
,
new_row
,
table
,
upd_buff
,
(
ulint
)
upd_and_key_val_buff_len
,
prebuilt
,
user_thd
);
...
...
@@ -3866,7 +3783,7 @@ int
ha_innobase
::
delete_row
(
/*====================*/
/* out: error number or 0 */
const
mysql_byte
*
record
)
/* in: a row in MySQL format */
const
uchar
*
record
)
/* in: a row in MySQL format */
{
int
error
=
0
;
trx_t
*
trx
=
thd_to_trx
(
user_thd
);
...
...
@@ -3879,6 +3796,14 @@ ha_innobase::delete_row(
if
(
table
->
found_next_number_field
&&
record
==
table
->
record
[
0
])
{
ulonglong
dummy
=
0
;
/* First check whether the AUTOINC sub-system has been
initialized using the AUTOINC mutex. If not then we
do it the "proper" way, by acquiring the heavier locks. */
dict_table_autoinc_lock
(
prebuilt
->
table
);
if
(
!
prebuilt
->
table
->
autoinc_inited
)
{
dict_table_autoinc_unlock
(
prebuilt
->
table
);
error
=
innobase_get_auto_increment
(
&
dummy
);
if
(
error
==
DB_SUCCESS
)
{
...
...
@@ -3886,6 +3811,9 @@ ha_innobase::delete_row(
}
else
{
goto
error_exit
;
}
}
else
{
dict_table_autoinc_unlock
(
prebuilt
->
table
);
}
}
if
(
!
prebuilt
->
upd_node
)
{
...
...
@@ -4133,9 +4061,9 @@ ha_innobase::index_read(
/*====================*/
/* out: 0, HA_ERR_KEY_NOT_FOUND,
or error number */
mysql_byte
*
buf
,
/* in/out: buffer for the returned
uchar
*
buf
,
/* in/out: buffer for the returned
row */
const
mysql_byte
*
key_ptr
,
/* in: key value; if this is NULL
const
uchar
*
key_ptr
,
/* in: key value; if this is NULL
we position the cursor at the
start or end of index; this can
also contain an InnoDB row id, in
...
...
@@ -4237,10 +4165,10 @@ ha_innobase::index_read_last(
/*=========================*/
/* out: 0, HA_ERR_KEY_NOT_FOUND, or an
error code */
mysql_byte
*
buf
,
/* out: fetched row */
const
mysql_byte
*
key_ptr
,
/* in: key value, or a prefix of a full
uchar
*
buf
,
/* out: fetched row */
const
uchar
*
key_ptr
,
/* in: key value, or a prefix of a full
key value */
uint
key_len
)
/* in: length of the key val or prefix
uint
key_len
)
/* in: length of the key val or prefix
in bytes */
{
return
(
index_read
(
buf
,
key_ptr
,
key_len
,
HA_READ_PREFIX_LAST
));
...
...
@@ -4339,10 +4267,10 @@ int
ha_innobase
::
index_read_idx
(
/*========================*/
/* out: error number or 0 */
mysql_byte
*
buf
,
/* in/out: buffer for the returned
uchar
*
buf
,
/* in/out: buffer for the returned
row */
uint
keynr
,
/* in: use this index */
const
mysql_byte
*
key
,
/* in: key value; if this is NULL
const
uchar
*
key
,
/* in: key value; if this is NULL
we position the cursor at the
start or end of index */
uint
key_len
,
/* in: key value length */
...
...
@@ -4365,7 +4293,7 @@ ha_innobase::general_fetch(
/*=======================*/
/* out: 0, HA_ERR_END_OF_FILE, or error
number */
mysql_byte
*
buf
,
/* in/out: buffer for next row in MySQL
uchar
*
buf
,
/* in/out: buffer for next row in MySQL
format */
uint
direction
,
/* in: ROW_SEL_NEXT or ROW_SEL_PREV */
uint
match_mode
)
/* in: 0, ROW_SEL_EXACT, or
...
...
@@ -4413,7 +4341,7 @@ ha_innobase::index_next(
/*====================*/
/* out: 0, HA_ERR_END_OF_FILE, or error
number */
mysql_byte
*
buf
)
/* in/out: buffer for next row in MySQL
uchar
*
buf
)
/* in/out: buffer for next row in MySQL
format */
{
ha_statistic_increment
(
&
SSV
::
ha_read_next_count
);
...
...
@@ -4429,8 +4357,8 @@ ha_innobase::index_next_same(
/*=========================*/
/* out: 0, HA_ERR_END_OF_FILE, or error
number */
mysql_byte
*
buf
,
/* in/out: buffer for the row */
const
mysql_byte
*
key
,
/* in: key value */
uchar
*
buf
,
/* in/out: buffer for the row */
const
uchar
*
key
,
/* in: key value */
uint
keylen
)
/* in: key value length */
{
ha_statistic_increment
(
&
SSV
::
ha_read_next_count
);
...
...
@@ -4445,10 +4373,8 @@ positioned using index_read. */
int
ha_innobase
::
index_prev
(
/*====================*/
/* out: 0, HA_ERR_END_OF_FILE, or error
number */
mysql_byte
*
buf
)
/* in/out: buffer for previous row in MySQL
format */
/* out: 0, HA_ERR_END_OF_FILE, or error number */
uchar
*
buf
)
/* in/out: buffer for previous row in MySQL format */
{
ha_statistic_increment
(
&
SSV
::
ha_read_prev_count
);
...
...
@@ -4462,9 +4388,8 @@ corresponding row to buf. */
int
ha_innobase
::
index_first
(
/*=====================*/
/* out: 0, HA_ERR_END_OF_FILE,
or error code */
mysql_byte
*
buf
)
/* in/out: buffer for the row */
/* out: 0, HA_ERR_END_OF_FILE, or error code */
uchar
*
buf
)
/* in/out: buffer for the row */
{
int
error
;
...
...
@@ -4490,7 +4415,7 @@ int
ha_innobase
::
index_last
(
/*====================*/
/* out: 0, HA_ERR_END_OF_FILE, or error code */
mysql_byte
*
buf
)
/* in/out: buffer for the row */
uchar
*
buf
)
/* in/out: buffer for the row */
{
int
error
;
...
...
@@ -4559,7 +4484,7 @@ int
ha_innobase
::
rnd_next
(
/*==================*/
/* out: 0, HA_ERR_END_OF_FILE, or error number */
mysql_byte
*
buf
)
/* in/out: returns the row in this buffer,
uchar
*
buf
)
/* in/out: returns the row in this buffer,
in MySQL format */
{
int
error
;
...
...
@@ -4588,14 +4513,12 @@ Fetches a row from the table based on a row reference. */
int
ha_innobase
::
rnd_pos
(
/*=================*/
/* out: 0, HA_ERR_KEY_NOT_FOUND,
or error code */
mysql_byte
*
buf
,
/* in/out: buffer for the row */
mysql_byte
*
pos
)
/* in: primary key value of the row in the
/* out: 0, HA_ERR_KEY_NOT_FOUND, or error code */
uchar
*
buf
,
/* in/out: buffer for the row */
uchar
*
pos
)
/* in: primary key value of the row in the
MySQL format, or the row id if the clustered
index was internally generated by InnoDB;
the length of data in pos has to be
ref_length */
index was internally generated by InnoDB; the
length of data in pos has to be ref_length */
{
int
error
;
uint
keynr
=
active_index
;
...
...
@@ -4648,7 +4571,7 @@ was positioned the last time. */
void
ha_innobase
::
position
(
/*==================*/
const
mysql_byte
*
record
)
/* in: row in MySQL format */
const
uchar
*
record
)
/* in: row in MySQL format */
{
uint
len
;
...
...
@@ -5561,7 +5484,7 @@ ha_innobase::records_in_range(
{
KEY
*
key
;
dict_index_t
*
index
;
mysql_byte
*
key_val_buff2
=
(
mysql_byte
*
)
my_malloc
(
uchar
*
key_val_buff2
=
(
uchar
*
)
my_malloc
(
table
->
s
->
reclength
+
table
->
s
->
max_key_length
+
100
,
MYF
(
MY_FAE
));
...
...
@@ -5606,7 +5529,7 @@ ha_innobase::records_in_range(
(
ulint
)
upd_and_key_val_buff_len
,
index
,
(
byte
*
)
(
min_key
?
min_key
->
key
:
(
const
mysql_byte
*
)
0
),
(
const
uchar
*
)
0
),
(
ulint
)
(
min_key
?
min_key
->
length
:
0
),
prebuilt
->
trx
);
...
...
@@ -5614,7 +5537,7 @@ ha_innobase::records_in_range(
range_end
,
(
byte
*
)
key_val_buff2
,
buff2_len
,
index
,
(
byte
*
)
(
max_key
?
max_key
->
key
:
(
const
mysql_byte
*
)
0
),
(
const
uchar
*
)
0
),
(
ulint
)
(
max_key
?
max_key
->
length
:
0
),
prebuilt
->
trx
);
...
...
@@ -7024,12 +6947,12 @@ bool innobase_show_status(handlerton *hton, THD* thd,
locking.
****************************************************************************/
static
mysql_byte
*
innobase_get_key
(
INNOBASE_SHARE
*
share
,
size_t
*
length
,
static
uchar
*
innobase_get_key
(
INNOBASE_SHARE
*
share
,
size_t
*
length
,
my_bool
not_used
__attribute__
((
unused
)))
{
*
length
=
share
->
table_name_length
;
return
((
mysql_byte
*
)
share
->
table_name
)
;
return
(
uchar
*
)
share
->
table_name
;
}
static
INNOBASE_SHARE
*
get_share
(
const
char
*
table_name
)
...
...
@@ -7039,7 +6962,7 @@ static INNOBASE_SHARE* get_share(const char* table_name)
uint
length
=
(
uint
)
strlen
(
table_name
);
if
(
!
(
share
=
(
INNOBASE_SHARE
*
)
hash_search
(
&
innobase_open_tables
,
(
mysql_byte
*
)
table_name
,
(
uchar
*
)
table_name
,
length
)))
{
share
=
(
INNOBASE_SHARE
*
)
my_malloc
(
sizeof
(
*
share
)
+
length
+
1
,
...
...
@@ -7050,7 +6973,7 @@ static INNOBASE_SHARE* get_share(const char* table_name)
strmov
(
share
->
table_name
,
table_name
);
if
(
my_hash_insert
(
&
innobase_open_tables
,
(
mysql_byte
*
)
share
))
{
(
uchar
*
)
share
))
{
pthread_mutex_unlock
(
&
innobase_share_mutex
);
my_free
(
share
,
0
);
...
...
@@ -7072,7 +6995,7 @@ static void free_share(INNOBASE_SHARE* share)
pthread_mutex_lock
(
&
innobase_share_mutex
);
if
(
!--
share
->
use_count
)
{
hash_delete
(
&
innobase_open_tables
,
(
mysql_byte
*
)
share
);
hash_delete
(
&
innobase_open_tables
,
(
uchar
*
)
share
);
thr_lock_delete
(
&
share
->
lock
);
pthread_mutex_destroy
(
&
share
->
mutex
);
my_free
(
share
,
MYF
(
0
));
...
...
@@ -7512,13 +7435,24 @@ ha_innobase::get_auto_increment(
*
nb_reserved_values
=
prebuilt
->
trx
->
n_autoinc_rows
;
/* With old style AUTOINC locking we only update the table's
AUTOINC counter after attempting to insert the row. */
if
(
innobase_autoinc_lock_mode
!=
AUTOINC_OLD_STYLE_LOCKING
)
{
/* Compute the last value in the interval */
prebuilt
->
last_value
=
*
first_value
+
(
*
nb_reserved_values
*
increment
);
prebuilt
->
last_value
=
*
first_value
+
(
*
nb_reserved_values
*
increment
);
ut_a
(
prebuilt
->
last_value
>=
*
first_value
);
/* Update the table autoinc variable */
dict_table_autoinc_update
(
prebuilt
->
table
,
prebuilt
->
last_value
);
dict_table_autoinc_update
(
prebuilt
->
table
,
prebuilt
->
last_value
);
}
else
{
/* This will force write_row() into attempting an update
of the table's AUTOINC counter. */
prebuilt
->
last_value
=
0
;
}
/* The increment to be used to increase the AUTOINC value, we use
this in write_row() and update_row() to increase the autoinc counter
...
...
@@ -7573,9 +7507,9 @@ ha_innobase::cmp_ref(
/*=================*/
/* out: < 0 if ref1 < ref2, 0 if equal, else
> 0 */
const
mysql_byte
*
ref1
,
/* in: an (internal) primary key value in the
const
uchar
*
ref1
,
/* in: an (internal) primary key value in the
MySQL key value format */
const
mysql_byte
*
ref2
)
/* in: an (internal) primary key value in the
const
uchar
*
ref2
)
/* in: an (internal) primary key value in the
MySQL key value format */
{
enum_field_types
mysql_type
;
...
...
@@ -9247,6 +9181,17 @@ static MYSQL_SYSVAR_STR(data_file_path, innobase_data_file_path,
"Path to individual files and their sizes."
,
NULL
,
NULL
,
NULL
);
static
MYSQL_SYSVAR_LONG
(
autoinc_lock_mode
,
innobase_autoinc_lock_mode
,
PLUGIN_VAR_RQCMDARG
,
"The AUTOINC lock modes supported by InnoDB:
\n
"
" 0 => Old style AUTOINC locking (for backward compatibility)
\n
"
" 1 => New style AUTOINC locking
\n
"
" 2 => No AUTOINC locking (unsafe for SBR)"
,
NULL
,
NULL
,
AUTOINC_NEW_STYLE_LOCKING
,
/* Default setting */
AUTOINC_OLD_STYLE_LOCKING
,
/* Minimum value */
AUTOINC_NO_LOCKING
,
0
);
/* Maximum value */
static
struct
st_mysql_sys_var
*
innobase_system_variables
[]
=
{
MYSQL_SYSVAR
(
additional_mem_pool_size
),
MYSQL_SYSVAR
(
autoextend_increment
),
...
...
@@ -9285,6 +9230,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR
(
table_locks
),
MYSQL_SYSVAR
(
thread_concurrency
),
MYSQL_SYSVAR
(
thread_sleep_delay
),
MYSQL_SYSVAR
(
autoinc_lock_mode
),
NULL
};
...
...
ibuf/ibuf0ibuf.c
View file @
31d63cd0
...
...
@@ -1189,11 +1189,6 @@ ibuf_dummy_index_free(
dict_mem_table_free
(
table
);
}
void
dict_index_print_low
(
/*=================*/
dict_index_t
*
index
);
/* in: index */
/*************************************************************************
Builds the entry to insert into a non-clustered index when we have the
corresponding record in an ibuf index. */
...
...
include/dict0mem.h
View file @
31d63cd0
...
...
@@ -340,11 +340,11 @@ struct dict_table_struct{
unsigned
n_cols
:
10
;
/* number of columns */
dict_col_t
*
cols
;
/* array of column descriptions */
const
char
*
col_names
;
/*
n_def column names packed in an
"name1\0name2\0...nameN\0"
array. u
ntil
n_def reaches n_cols, this is allocated with
ut_malloc, and the final size array is
allocated through the table's
heap. */
/*
Column names packed in a character string
"name1\0name2\0...nameN\0"
. U
ntil
the string contains n_cols, it will be
allocated from a temporary heap. The final
string will be allocated from table->
heap. */
hash_node_t
name_hash
;
/* hash chain node */
hash_node_t
id_hash
;
/* hash chain node */
UT_LIST_BASE_NODE_T
(
dict_index_t
)
...
...
@@ -444,6 +444,16 @@ struct dict_table_struct{
UT_LIST_BASE_NODE_T
(
row_prebuilt_t
)
prebuilts
;
/* base node for the prebuilts defined
for the table */
ulong
n_waiting_or_granted_auto_inc_locks
;
/* This counter is used to track the number
of granted and pending autoinc locks on this
table. This value is set after acquiring the
kernel mutex but we peek the contents to
determine whether other transactions have
acquired the AUTOINC lock or not. Of course
only one transaction can be granted the
lock but there can be multiple waiters. */
#ifdef UNIV_DEBUG
ulint
magic_n
;
/* magic number */
# define DICT_TABLE_MAGIC_N 76333786
...
...
include/mach0data.h
View file @
31d63cd0
...
...
@@ -364,6 +364,17 @@ mach_write_to_2_little_endian(
byte
*
dest
,
/* in: where to write */
ulint
n
);
/* in: unsigned long int to write */
/*************************************************************
Convert integral type from storage byte order (big endian) to
host byte order. */
UNIV_INLINE
void
mach_read_int_type
(
/*===============*/
byte
*
dest
,
/* out: where to write */
const
byte
*
src
,
/* in: where to read from */
ulint
len
,
/* in: length of src */
ibool
unsigned_type
);
/* in: signed or unsigned flag */
#ifndef UNIV_NONINL
#include "mach0data.ic"
#endif
...
...
include/mach0data.ic
View file @
31d63cd0
...
...
@@ -7,6 +7,8 @@ to the machine format.
Created 11/28/1995 Heikki Tuuri
***********************************************************************/
#include "ut0mem.h"
/***********************************************************
The following function is used to store data in one byte. */
UNIV_INLINE
...
...
@@ -723,3 +725,38 @@ mach_write_to_2_little_endian(
*dest = (byte)(n & 0xFFUL);
}
/*************************************************************
Convert integral type from storage byte order (big endian) to
host byte order. */
UNIV_INLINE
void
mach_read_int_type(
/*===============*/
byte* dest, /* out: where to write */
const byte* src, /* in: where to read from */
ulint len, /* in: length of src */
ibool unsigned_type) /* in: signed or unsigned flag */
{
#ifdef WORDS_BIGENDIAN
memcpy(dest, src, len);
if (!unsigned_type) {
dest[0] ^= 128;
}
#else
byte* ptr;
/* Convert integer data from Innobase to a little-endian format,
sign bit restored to normal. */
for (ptr = dest + len; ptr != dest; ++src) {
--ptr;
*ptr = *src;
}
if (!unsigned_type) {
dest[len - 1] ^= 128;
}
#endif
}
include/row0mysql.h
View file @
31d63cd0
...
...
@@ -340,9 +340,11 @@ row_mysql_unfreeze_data_dictionary(
trx_t
*
trx
);
/* in: transaction */
#ifndef UNIV_HOTBACKUP
/*************************************************************************
Does a table creation operation for MySQL. If the name of the created
table ends to characters INNODB_MONITOR, then this also starts
printing of monitor output by the master thread. */
Drops a table for MySQL. If the name of the table ends in
one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
"innodb_table_monitor", then this will also start the printing of monitor
output by the master thread. If the table name ends in "innodb_mem_validate",
InnoDB will try to invoke mem_validate(). */
int
row_create_table_for_mysql
(
...
...
@@ -420,8 +422,9 @@ row_truncate_table_for_mysql(
dict_table_t
*
table
,
/* in: table handle */
trx_t
*
trx
);
/* in: transaction handle */
/*************************************************************************
Drops a table for MySQL. If the name of the dropped table ends to
characters INNODB_MONITOR, then this also stops printing of monitor
Drops a table for MySQL. If the name of the dropped table ends in
one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
"innodb_table_monitor", then this will also stop the printing of monitor
output by the master thread. */
int
...
...
include/sync0rw.h
View file @
31d63cd0
...
...
@@ -101,6 +101,7 @@ void
rw_lock_free
(
/*=========*/
rw_lock_t
*
lock
);
/* in: rw-lock */
#ifdef UNIV_DEBUG
/**********************************************************************
Checks that the rw-lock has been initialized and that there are no
simultaneous shared and exclusive locks. */
...
...
@@ -109,6 +110,7 @@ ibool
rw_lock_validate
(
/*=============*/
rw_lock_t
*
lock
);
#endif
/* UNIV_DEBUG */
/******************************************************************
NOTE! The following macros should be used in rw s-locking, not the
corresponding function. */
...
...
include/sync0rw.ic
View file @
31d63cd0
...
...
@@ -231,7 +231,7 @@ rw_lock_s_lock_func(
owns an s-lock here, it may end up in a deadlock with another thread
which requests an x-lock here. Therefore, we will forbid recursive
s-locking of a latch: the following assert will warn the programmer
of the possibility of
a tjis kind of
deadlock. If we want to implement
of the possibility of
this kind of a
deadlock. If we want to implement
safe recursive s-locking, we should keep in a list the thread ids of
the threads which have s-locked a latch. This would use some CPU
time. */
...
...
include/trx0trx.h
View file @
31d63cd0
...
...
@@ -510,31 +510,6 @@ struct trx_struct{
ib_longlong
mysql_log_offset
;
/* if MySQL binlog is used, this field
contains the end offset of the binlog
entry */
const
char
*
mysql_master_log_file_name
;
/* if the database server is a MySQL
replication slave, we have here the
master binlog name up to which
replication has processed; otherwise
this is a pointer to a null
character */
ib_longlong
mysql_master_log_pos
;
/* if the database server is a MySQL
replication slave, this is the
position in the log file up to which
replication has processed */
/* A MySQL variable mysql_thd->synchronous_repl tells if we have
to use synchronous replication. See ha_innodb.cc. */
char
*
repl_wait_binlog_name
;
/* NULL, or if synchronous MySQL
replication is used, the binlog name
up to which we must communicate the
binlog to the slave, before returning
from a commit; this is the same as
mysql_log_file_name, but we allocate
and copy the name to a separate buffer
here */
ib_longlong
repl_wait_binlog_pos
;
/* see above at
repl_wait_binlog_name */
os_thread_id_t
mysql_thread_id
;
/* id of the MySQL thread associated
with this transaction object */
ulint
mysql_process_no
;
/* since in Linux, 'top' reports
...
...
include/ut0mem.h
View file @
31d63cd0
...
...
@@ -63,7 +63,7 @@ ut_test_malloc(
/* out: TRUE if succeeded */
ulint
n
);
/* in: try to allocate this many bytes */
/**************************************************************************
Frees a memory blo
o
ck allocated with ut_malloc. */
Frees a memory block allocated with ut_malloc. */
void
ut_free
(
...
...
lock/lock0lock.c
View file @
31d63cd0
...
...
@@ -3544,6 +3544,10 @@ lock_table_create(
ut_ad
(
table
&&
trx
);
ut_ad
(
mutex_own
(
&
kernel_mutex
));
if
((
type_mode
&
LOCK_MODE_MASK
)
==
LOCK_AUTO_INC
)
{
++
table
->
n_waiting_or_granted_auto_inc_locks
;
}
if
(
type_mode
==
LOCK_AUTO_INC
)
{
/* Only one trx can have the lock on the table
at a time: we may use the memory preallocated
...
...
@@ -3594,6 +3598,9 @@ lock_table_remove_low(
if
(
lock
==
trx
->
auto_inc_lock
)
{
trx
->
auto_inc_lock
=
NULL
;
ut_a
(
table
->
n_waiting_or_granted_auto_inc_locks
>
0
);
--
table
->
n_waiting_or_granted_auto_inc_locks
;
}
UT_LIST_REMOVE
(
trx_locks
,
trx
->
trx_locks
,
lock
);
...
...
mysql-test/innodb.result
View file @
31d63cd0
...
...
@@ -479,6 +479,7 @@ passwd varchar(32) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id),
UNIQUE ggid (ggid)
)
ENGINE=innodb;
set global innodb_autoinc_lock_mode = 0;
insert into t1 (ggid,passwd) values ('test1','xxx');
insert into t1 (ggid,passwd) values ('test2','yyy');
insert into t1 (ggid,passwd) values ('test2','this will fail');
...
...
mysql-test/innodb.test
View file @
31d63cd0
...
...
@@ -345,6 +345,9 @@ CREATE TABLE t1 (
UNIQUE
ggid
(
ggid
)
)
ENGINE
=
innodb
;
# Set to old style locking
set
global
innodb_autoinc_lock_mode
=
0
;
insert
into
t1
(
ggid
,
passwd
)
values
(
'test1'
,
'xxx'
);
insert
into
t1
(
ggid
,
passwd
)
values
(
'test2'
,
'yyy'
);
--
error
ER_DUP_ENTRY
...
...
row/row0mysql.c
View file @
31d63cd0
...
...
@@ -1793,10 +1793,11 @@ row_mysql_unlock_data_dictionary(
#ifndef UNIV_HOTBACKUP
/*************************************************************************
Does a table creation operation for MySQL. If the name of the table
to be created is equal with one of the predefined magic table names,
then this also starts printing the corresponding monitor output by
the master thread. */
Drops a table for MySQL. If the name of the table ends in
one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
"innodb_table_monitor", then this will also start the printing of monitor
output by the master thread. If the table name ends in "innodb_mem_validate",
InnoDB will try to invoke mem_validate(). */
int
row_create_table_for_mysql
(
...
...
@@ -3032,9 +3033,10 @@ funct_exit:
}
/*************************************************************************
Drops a table for MySQL. If the name of the table to be dropped is equal
with one of the predefined magic table names, then this also stops printing
the corresponding monitor output by the master thread. */
Drops a table for MySQL. If the name of the dropped table ends in
one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
"innodb_table_monitor", then this will also stop the printing of monitor
output by the master thread. */
int
row_drop_table_for_mysql
(
...
...
row/row0sel.c
View file @
31d63cd0
...
...
@@ -4591,10 +4591,10 @@ row_search_autoinc_read_column(
ibool
unsigned_type
)
/* in: signed or unsigned flag */
{
ulint
len
;
byte
*
ptr
;
const
byte
*
data
;
ib_longlong
value
;
mem_heap_t
*
heap
=
NULL
;
/* Our requirement is that dest should be word aligned. */
byte
dest
[
sizeof
(
value
)];
ulint
offsets_
[
REC_OFFS_NORMAL_SIZE
];
ulint
*
offsets
=
offsets_
;
...
...
@@ -4613,34 +4613,25 @@ row_search_autoinc_read_column(
ut_a
(
len
!=
UNIV_SQL_NULL
);
ut_a
(
len
<=
sizeof
value
);
/* Convert integer data from Innobase to a little-endian format,
sign bit restored to normal */
for
(
ptr
=
dest
+
len
;
ptr
!=
dest
;
++
data
)
{
--
ptr
;
*
ptr
=
*
data
;
}
if
(
!
unsigned_type
)
{
dest
[
len
-
1
]
^=
128
;
}
mach_read_int_type
(
dest
,
data
,
len
,
unsigned_type
);
/* The assumption here is that the AUTOINC value can't be negative.*/
/* The assumption here is that the AUTOINC value can't be negative
and that dest is word aligned. */
switch
(
len
)
{
case
8
:
value
=
*
(
ib_longlong
*
)
ptr
;
value
=
*
(
ib_longlong
*
)
dest
;
break
;
case
4
:
value
=
*
(
ib_uint32_t
*
)
ptr
;
value
=
*
(
ib_uint32_t
*
)
dest
;
break
;
case
2
:
value
=
*
(
uint16
*
)
ptr
;
value
=
*
(
uint16
*
)
dest
;
break
;
case
1
:
value
=
*
ptr
;
value
=
*
dest
;
break
;
default:
...
...
sync/sync0rw.c
View file @
31d63cd0
...
...
@@ -174,9 +174,7 @@ rw_lock_free(
/*=========*/
rw_lock_t
*
lock
)
/* in: rw-lock */
{
#ifdef UNIV_DEBUG
ut_a
(
rw_lock_validate
(
lock
));
#endif
/* UNIV_DEBUG */
ut_ad
(
rw_lock_validate
(
lock
));
ut_a
(
rw_lock_get_writer
(
lock
)
==
RW_LOCK_NOT_LOCKED
);
ut_a
(
rw_lock_get_waiters
(
lock
)
==
0
);
ut_a
(
rw_lock_get_reader_count
(
lock
)
==
0
);
...
...
@@ -199,6 +197,7 @@ rw_lock_free(
mutex_exit
(
&
rw_lock_list_mutex
);
}
#ifdef UNIV_DEBUG
/**********************************************************************
Checks that the rw-lock has been initialized and that there are no
simultaneous shared and exclusive locks. */
...
...
@@ -226,6 +225,7 @@ rw_lock_validate(
return
(
TRUE
);
}
#endif
/* UNIV_DEBUG */
/**********************************************************************
Lock an rw-lock in shared mode for the current thread. If the rw-lock is
...
...
trx/trx0sys.c
View file @
31d63cd0
...
...
@@ -656,6 +656,7 @@ trx_sys_update_mysql_binlog_offset(
MLOG_4BYTES
,
mtr
);
}
#ifdef UNIV_HOTBACKUP
/*********************************************************************
Prints to stderr the MySQL binlog info in the system header if the
magic number shows it valid. */
...
...
@@ -688,6 +689,7 @@ trx_sys_print_mysql_binlog_offset_from_page(
+
TRX_SYS_MYSQL_LOG_NAME
);
}
}
#endif
/* UNIV_HOTBACKUP */
/*********************************************************************
Stores the MySQL binlog offset info in the trx system header if
...
...
trx/trx0trx.c
View file @
31d63cd0
...
...
@@ -112,11 +112,6 @@ trx_create(
trx
->
mysql_log_file_name
=
NULL
;
trx
->
mysql_log_offset
=
0
;
trx
->
mysql_master_log_file_name
=
""
;
trx
->
mysql_master_log_pos
=
0
;
trx
->
repl_wait_binlog_name
=
NULL
;
trx
->
repl_wait_binlog_pos
=
0
;
mutex_create
(
&
trx
->
undo_mutex
,
SYNC_TRX_UNDO
);
...
...
@@ -287,11 +282,6 @@ trx_free(
trx_undo_arr_free
(
trx
->
undo_no_arr
);
}
if
(
trx
->
repl_wait_binlog_name
!=
NULL
)
{
mem_free
(
trx
->
repl_wait_binlog_name
);
}
ut_a
(
UT_LIST_GET_LEN
(
trx
->
signals
)
==
0
);
ut_a
(
UT_LIST_GET_LEN
(
trx
->
reply_signals
)
==
0
);
...
...
@@ -774,14 +764,6 @@ trx_commit_off_kernel(
trx
->
mysql_log_file_name
=
NULL
;
}
if
(
trx
->
mysql_master_log_file_name
[
0
]
!=
'\0'
)
{
/* This database server is a MySQL replication slave */
trx_sys_update_mysql_binlog_offset
(
trx
->
mysql_master_log_file_name
,
trx
->
mysql_master_log_pos
,
TRX_SYS_MYSQL_MASTER_LOG_INFO
,
&
mtr
);
}
/* The following call commits the mini-transaction, making the
whole transaction committed in the file-based world, at this
log sequence number. The transaction becomes 'durable' when
...
...
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