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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
f841b4ae
Commit
f841b4ae
authored
Apr 16, 2003
by
heikki@hundin.mysql.fi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Many files:
Merge InnoDB-4.0.13; DROP FOREIGN KEY now works
parent
cde0099e
Changes
17
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
999 additions
and
205 deletions
+999
-205
innobase/buf/buf0flu.c
innobase/buf/buf0flu.c
+9
-3
innobase/dict/dict0crea.c
innobase/dict/dict0crea.c
+8
-0
innobase/dict/dict0dict.c
innobase/dict/dict0dict.c
+574
-100
innobase/dict/dict0load.c
innobase/dict/dict0load.c
+33
-6
innobase/ibuf/ibuf0ibuf.c
innobase/ibuf/ibuf0ibuf.c
+9
-4
innobase/include/db0err.h
innobase/include/db0err.h
+2
-0
innobase/include/dict0dict.h
innobase/include/dict0dict.h
+35
-0
innobase/include/row0ins.h
innobase/include/row0ins.h
+0
-1
innobase/lock/lock0lock.c
innobase/lock/lock0lock.c
+26
-16
innobase/os/os0file.c
innobase/os/os0file.c
+16
-6
innobase/row/row0ins.c
innobase/row/row0ins.c
+154
-6
innobase/row/row0mysql.c
innobase/row/row0mysql.c
+83
-38
innobase/row/row0sel.c
innobase/row/row0sel.c
+18
-17
innobase/row/row0upd.c
innobase/row/row0upd.c
+1
-1
innobase/srv/srv0srv.c
innobase/srv/srv0srv.c
+16
-6
innobase/ut/ut0ut.c
innobase/ut/ut0ut.c
+1
-1
sql/ha_innodb.cc
sql/ha_innodb.cc
+14
-0
No files found.
innobase/buf/buf0flu.c
View file @
f841b4ae
...
...
@@ -106,7 +106,7 @@ buf_flush_ready_for_replace(
BUF_BLOCK_FILE_PAGE and in the LRU list*/
{
ut_ad
(
mutex_own
(
&
(
buf_pool
->
mutex
)));
ut_a
d
(
block
->
state
==
BUF_BLOCK_FILE_PAGE
);
ut_a
(
block
->
state
==
BUF_BLOCK_FILE_PAGE
);
if
((
ut_dulint_cmp
(
block
->
oldest_modification
,
ut_dulint_zero
)
>
0
)
||
(
block
->
buf_fix_count
!=
0
)
...
...
@@ -227,7 +227,9 @@ buf_flush_buffered_writes(void)
}
for
(
i
=
0
;
i
<
trx_doublewrite
->
first_free
;
i
++
)
{
block
=
trx_doublewrite
->
buf_block_arr
[
i
];
ut_a
(
block
->
state
==
BUF_BLOCK_FILE_PAGE
);
if
(
block
->
check_index_page_at_flush
&&
!
page_simple_validate
(
block
->
frame
))
{
...
...
@@ -236,10 +238,12 @@ buf_flush_buffered_writes(void)
ut_print_timestamp
(
stderr
);
fprintf
(
stderr
,
" InnoDB: Apparent corruption of an index page
\n
"
" InnoDB: Apparent corruption of an index page
n:o %lu in space %lu
\n
"
"InnoDB: to be written to data file. We intentionally crash server
\n
"
"InnoDB: to prevent corrupt data from ending up in data
\n
"
"InnoDB: files.
\n
"
);
"InnoDB: files.
\n
"
,
block
->
offset
,
block
->
space
);
ut_a
(
0
);
}
}
...
...
@@ -432,6 +436,8 @@ buf_flush_try_page(
block
=
buf_page_hash_get
(
space
,
offset
);
ut_a
(
block
->
state
==
BUF_BLOCK_FILE_PAGE
);
if
(
flush_type
==
BUF_FLUSH_LIST
&&
block
&&
buf_flush_ready_for_flush
(
block
,
flush_type
))
{
...
...
innobase/dict/dict0crea.c
View file @
f841b4ae
...
...
@@ -1173,6 +1173,7 @@ dict_create_add_foreigns_to_dictionary(
if
(
NULL
==
dict_table_get_low
((
char
*
)
"SYS_FOREIGN"
))
{
fprintf
(
stderr
,
"InnoDB: table SYS_FOREIGN not found from internal data dictionary
\n
"
);
return
(
DB_ERROR
);
}
...
...
@@ -1259,6 +1260,13 @@ dict_create_add_foreigns_to_dictionary(
"InnoDB: at http://www.innodb.com/ibman.html
\n
"
);
}
mutex_enter
(
&
dict_foreign_err_mutex
);
ut_sprintf_timestamp
(
buf
);
sprintf
(
buf
+
strlen
(
buf
),
" Internal error in foreign key constraint creation for table %.500s.
\n
"
"See the MySQL .err log in the datadir for more information.
\n
"
,
table
->
name
);
mutex_exit
(
&
dict_foreign_err_mutex
);
return
(
error
);
}
...
...
innobase/dict/dict0dict.c
View file @
f841b4ae
This diff is collapsed.
Click to expand it.
innobase/dict/dict0load.c
View file @
f841b4ae
...
...
@@ -456,7 +456,7 @@ dict_load_indexes(
ut_ad
(
len
==
8
);
id
=
mach_read_from_8
(
field
);
ut_a
(
0
==
ut_strcmp
(
"NAME"
,
ut_a
(
0
==
ut_strcmp
(
(
char
*
)
"NAME"
,
dict_field_get_col
(
dict_index_get_nth_field
(
dict_table_get_first_index
(
sys_indexes
),
4
))
->
name
));
...
...
@@ -515,7 +515,7 @@ dict_load_indexes(
&&
((
type
&
DICT_CLUSTERED
)
||
((
table
==
dict_sys
->
sys_tables
)
&&
(
name_len
==
ut_strlen
(
"ID_IND"
))
&&
(
0
==
ut_memcmp
(
name_buf
,
"ID_IND"
,
&&
(
0
==
ut_memcmp
(
name_buf
,
(
char
*
)
"ID_IND"
,
name_len
)))))
{
/* The index was created in memory already in
...
...
@@ -566,6 +566,7 @@ dict_load_table(
char
*
buf
;
ulint
space
;
ulint
n_cols
;
ulint
err
;
mtr_t
mtr
;
ut_ad
(
mutex_own
(
&
(
dict_sys
->
mutex
)));
...
...
@@ -674,8 +675,25 @@ dict_load_table(
dict_load_indexes
(
table
,
heap
);
ut_a
(
DB_SUCCESS
==
dict_load_foreigns
(
table
->
name
));
err
=
dict_load_foreigns
(
table
->
name
);
/*
if (err != DB_SUCCESS) {
mutex_enter(&dict_foreign_err_mutex);
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Error: could not make a foreign key definition to match\n"
"InnoDB: the foreign key table or the referenced table!\n"
"InnoDB: The data dictionary of InnoDB is corrupt. You may need to drop\n"
"InnoDB: and recreate the foreign key table or the referenced table.\n"
"InnoDB: Send a detailed bug report to mysql@lists.mysql.com\n"
"InnoDB: Latest foreign key error printout:\n%s\n", dict_foreign_err_buf);
mutex_exit(&dict_foreign_err_mutex);
}
*/
mem_heap_free
(
heap
);
return
(
table
);
...
...
@@ -978,8 +996,8 @@ dict_load_foreign(
field
=
rec_get_nth_field
(
rec
,
4
,
&
len
);
foreign
->
referenced_table_name
=
mem_heap_alloc
(
foreign
->
heap
,
1
+
len
);
foreign
->
referenced_table_name
=
mem_heap_alloc
(
foreign
->
heap
,
1
+
len
);
ut_memcpy
(
foreign
->
referenced_table_name
,
field
,
len
);
foreign
->
referenced_table_name
[
len
]
=
'\0'
;
...
...
@@ -988,10 +1006,19 @@ dict_load_foreign(
dict_load_foreign_cols
(
id
,
foreign
);
/* If the foreign table is not yet in the dictionary cache, we
have to load it so that we are able to make type comparisons
in the next function call. */
dict_table_get_low
(
foreign
->
foreign_table_name
);
/* Note that there may already be a foreign constraint object in
the dictionary cache for this constraint: then the following
call only sets the pointers in it to point to the appropriate table
and index objects and frees the newly created object foreign. */
and index objects and frees the newly created object foreign.
Adding to the cache should always succeed since we are not creating
a new foreign key constraint but loading one from the data
dictionary. */
err
=
dict_foreign_add_to_cache
(
foreign
);
...
...
innobase/ibuf/ibuf0ibuf.c
View file @
f841b4ae
...
...
@@ -2420,17 +2420,22 @@ ibuf_delete_rec(
fprintf
(
stderr
,
"InnoDB: ibuf cursor restoration fails!
\n
"
);
fprintf
(
stderr
,
"InnoDB: ibuf record inserted to page %lu
\n
"
,
page_no
);
fflush
(
stderr
);
rec_print
(
btr_pcur_get_rec
(
pcur
));
rec_print
(
pcur
->
old_rec
);
dtuple_print
(
search_tuple
);
rec_print
(
page_rec_get_next
(
btr_pcur_get_rec
(
pcur
)));
fflush
(
stdout
);
mtr_commit
(
mtr
);
fprintf
(
stderr
,
"InnoDB: Validating insert buffer tree:
\n
"
);
ut_a
(
btr_validate_tree
(
ibuf_data
->
index
->
tree
));
fprintf
(
stderr
,
"InnoDB: Ibuf tree ok
\n
"
);
fprintf
(
stderr
,
"InnoDB: ibuf tree ok
\n
"
);
fflush
(
stderr
);
}
ut_a
(
success
);
...
...
innobase/include/db0err.h
View file @
f841b4ae
...
...
@@ -44,6 +44,8 @@ Created 5/24/1996 Heikki Tuuri
#define DB_CORRUPTION 39
/* data structure corruption noticed */
#define DB_COL_APPEARS_TWICE_IN_INDEX 40
/* InnoDB cannot handle an index
where same column appears twice */
#define DB_CANNOT_DROP_CONSTRAINT 40
/* dropping a foreign key constraint
from a table failed */
/* The following are partial failure codes */
#define DB_FAIL 1000
...
...
innobase/include/dict0dict.h
View file @
f841b4ae
...
...
@@ -219,6 +219,24 @@ dict_create_foreign_constraints(
char
*
name
);
/* in: table full name in the normalized form
database_name/table_name */
/**************************************************************************
Parses the CONSTRAINT id's to be dropped in an ALTER TABLE statement. */
ulint
dict_foreign_parse_drop_constraints
(
/*================================*/
/* out: DB_SUCCESS or
DB_CANNOT_DROP_CONSTRAINT if
syntax error or the constraint
id does not match */
mem_heap_t
*
heap
,
/* in: heap from which we can
allocate memory */
trx_t
*
trx
,
/* in: transaction */
dict_table_t
*
table
,
/* in: table */
ulint
*
n
,
/* out: number of constraints
to drop */
char
***
constraints_to_drop
);
/* out: id's of the
constraints to drop */
/**************************************************************************
Returns a table object and memoryfixes it. NOTE! This is a high-level
function to be used mainly from outside the 'dict' directory. Inside this
directory dict_table_get_low is usually the appropriate function. */
...
...
@@ -333,6 +351,16 @@ dict_print_info_on_foreign_keys(
char
*
str
,
/* in/out: pointer to a string */
ulint
len
,
/* in: space in str available for info */
dict_table_t
*
table
);
/* in: table */
/**************************************************************************
Sprintfs to a string info on a foreign key of a table in a format suitable
for CREATE TABLE. */
char
*
dict_print_info_on_foreign_key_in_create_format
(
/*============================================*/
/* out: how far in buf we printed */
dict_foreign_t
*
foreign
,
/* in: foreign key constraint */
char
*
buf
);
/* in: buffer of at least 5000 bytes */
/************************************************************************
Gets the first index on the table (the clustered index). */
UNIV_INLINE
...
...
@@ -808,6 +836,13 @@ void
dict_mutex_exit_for_mysql
(
void
);
/*===========================*/
/* The following len must be at least 10000 bytes! */
#define DICT_FOREIGN_ERR_BUF_LEN 10000
/* Buffer for storing detailed information about the latest foreig key
error */
extern
char
*
dict_foreign_err_buf
;
extern
mutex_t
dict_foreign_err_mutex
;
/* mutex protecting the buffer */
extern
dict_sys_t
*
dict_sys
;
/* the dictionary system */
extern
rw_lock_t
dict_operation_lock
;
...
...
innobase/include/row0ins.h
View file @
f841b4ae
...
...
@@ -35,7 +35,6 @@ row_ins_check_foreign_constraint(
dictionary cache if they exist at all */
dict_table_t
*
table
,
/* in: if check_ref is TRUE, then the foreign
table, else the referenced table */
dict_index_t
*
index
,
/* in: index in table */
dtuple_t
*
entry
,
/* in: index entry for index */
que_thr_t
*
thr
);
/* in: query thread */
/*************************************************************************
...
...
innobase/lock/lock0lock.c
View file @
f841b4ae
...
...
@@ -3092,8 +3092,7 @@ lock_deadlock_recursive(
err_buf
+=
strlen
(
err_buf
);
err_buf
+=
sprintf
(
err_buf
,
" LATEST DETECTED DEADLOCK:
\n
"
"*** (1) TRANSACTION:
\n
"
);
"
\n
*** (1) TRANSACTION:
\n
"
);
trx_print
(
err_buf
,
wait_lock
->
trx
);
err_buf
+=
strlen
(
err_buf
);
...
...
@@ -3935,24 +3934,15 @@ lock_print_info(
return
;
}
buf
+=
sprintf
(
buf
,
"Trx id counter %lu %lu
\n
"
,
ut_dulint_get_high
(
trx_sys
->
max_trx_id
),
ut_dulint_get_low
(
trx_sys
->
max_trx_id
));
buf
+=
sprintf
(
buf
,
"Purge done for trx's n:o < %lu %lu undo n:o < %lu %lu
\n
"
,
ut_dulint_get_high
(
purge_sys
->
purge_trx_no
),
ut_dulint_get_low
(
purge_sys
->
purge_trx_no
),
ut_dulint_get_high
(
purge_sys
->
purge_undo_no
),
ut_dulint_get_low
(
purge_sys
->
purge_undo_no
));
lock_mutex_enter_kernel
();
buf
+=
sprintf
(
buf
,
"Total number of lock structs in row lock hash table %lu
\n
"
,
lock_get_n_rec_locks
());
if
(
lock_deadlock_found
)
{
buf
+=
sprintf
(
buf
,
"------------------------
\n
"
"LATEST DETECTED DEADLOCK
\n
"
"------------------------
\n
"
);
if
((
ulint
)(
buf_end
-
buf
)
<
100
+
strlen
(
lock_latest_err_buf
))
{
...
...
@@ -3972,6 +3962,26 @@ lock_print_info(
return
;
}
buf
+=
sprintf
(
buf
,
"------------
\n
"
"TRANSACTIONS
\n
"
"------------
\n
"
);
buf
+=
sprintf
(
buf
,
"Trx id counter %lu %lu
\n
"
,
ut_dulint_get_high
(
trx_sys
->
max_trx_id
),
ut_dulint_get_low
(
trx_sys
->
max_trx_id
));
buf
+=
sprintf
(
buf
,
"Purge done for trx's n:o < %lu %lu undo n:o < %lu %lu
\n
"
,
ut_dulint_get_high
(
purge_sys
->
purge_trx_no
),
ut_dulint_get_low
(
purge_sys
->
purge_trx_no
),
ut_dulint_get_high
(
purge_sys
->
purge_undo_no
),
ut_dulint_get_low
(
purge_sys
->
purge_undo_no
));
buf
+=
sprintf
(
buf
,
"Total number of lock structs in row lock hash table %lu
\n
"
,
lock_get_n_rec_locks
());
buf
+=
sprintf
(
buf
,
"LIST OF TRANSACTIONS FOR EACH SESSION:
\n
"
);
/* First print info on non-active transactions */
...
...
innobase/os/os0file.c
View file @
f841b4ae
...
...
@@ -214,9 +214,14 @@ os_file_get_last_error(void)
"InnoDB: the directory. It may also be you have created a subdirectory
\n
"
"InnoDB: of the same name as a data file.
\n
"
);
}
else
{
if
(
strerror
((
int
)
err
)
!=
NULL
)
{
fprintf
(
stderr
,
"InnoDB: Look from section 13.2 at http://www.innodb.com/ibman.html
\n
"
"InnoDB: what the error number means.
\n
"
);
"InnoDB: Error number %lu means '%s'.
\n
"
,
err
,
strerror
((
int
)
err
));
}
fprintf
(
stderr
,
"InnoDB: See also section 13.2 at http://www.innodb.com/ibman.html
\n
"
"InnoDB: about operating system error numbers.
\n
"
);
}
}
...
...
@@ -252,9 +257,14 @@ os_file_get_last_error(void)
"InnoDB: The error means mysqld does not have the access rights to
\n
"
"InnoDB: the directory.
\n
"
);
}
else
{
if
(
strerror
((
int
)
err
)
!=
NULL
)
{
fprintf
(
stderr
,
"InnoDB: Error number %lu means '%s'.
\n
"
,
err
,
strerror
((
int
)
err
));
}
fprintf
(
stderr
,
"InnoDB:
Look from
section 13.2 at http://www.innodb.com/ibman.html
\n
"
"InnoDB:
what the error number means or use the perror program of MySQL
.
\n
"
);
"InnoDB:
See also
section 13.2 at http://www.innodb.com/ibman.html
\n
"
"InnoDB:
about operating system error numbers
.
\n
"
);
}
}
...
...
innobase/row/row0ins.c
View file @
f841b4ae
...
...
@@ -437,6 +437,111 @@ row_ins_cascade_calc_update_vec(
return
(
n_fields_updated
);
}
/*************************************************************************
Reports a foreign key error associated with an update or a delete of a
parent table index entry. */
static
void
row_ins_foreign_report_err
(
/*=======================*/
char
*
errstr
,
/* in: error string from the viewpoint
of the parent table */
que_thr_t
*
thr
,
/* in: query thread whose run_node
is an update node */
dict_foreign_t
*
foreign
,
/* in: foreign key constraint */
rec_t
*
rec
,
/* in: a matching index record in the
child table */
dtuple_t
*
entry
)
/* in: index entry in the parent
table */
{
char
*
buf
=
dict_foreign_err_buf
;
mutex_enter
(
&
dict_foreign_err_mutex
);
ut_sprintf_timestamp
(
buf
);
sprintf
(
buf
+
strlen
(
buf
),
" Transaction:
\n
"
);
trx_print
(
buf
+
strlen
(
buf
),
thr_get_trx
(
thr
));
sprintf
(
buf
+
strlen
(
buf
),
"Foreign key constraint fails for table %.500s:
\n
"
,
foreign
->
foreign_table_name
);
dict_print_info_on_foreign_key_in_create_format
(
foreign
,
buf
+
strlen
(
buf
));
sprintf
(
buf
+
strlen
(
buf
),
"
\n
%s"
,
errstr
);
sprintf
(
buf
+
strlen
(
buf
),
" in parent table, in index %.500s tuple:
\n
"
,
foreign
->
referenced_index
->
name
);
if
(
entry
)
{
dtuple_sprintf
(
buf
+
strlen
(
buf
),
1000
,
entry
);
}
sprintf
(
buf
+
strlen
(
buf
),
"
\n
But in child table %.500s, in index %.500s, there is a record:
\n
"
,
foreign
->
foreign_table_name
,
foreign
->
foreign_index
->
name
);
if
(
rec
)
{
rec_sprintf
(
buf
+
strlen
(
buf
),
1000
,
rec
);
}
sprintf
(
buf
+
strlen
(
buf
),
"
\n
"
);
ut_a
(
strlen
(
buf
)
<
DICT_FOREIGN_ERR_BUF_LEN
);
mutex_exit
(
&
dict_foreign_err_mutex
);
}
/*************************************************************************
Reports a foreign key error to dict_foreign_err_buf when we are trying
to add an index entry to a child table. Note that the adding may be the result
of an update, too. */
static
void
row_ins_foreign_report_add_err
(
/*===========================*/
que_thr_t
*
thr
,
/* in: query thread whose run_node
is an insert node */
dict_foreign_t
*
foreign
,
/* in: foreign key constraint */
rec_t
*
rec
,
/* in: a record in the parent table:
it does not match entry because we
have an error! */
dtuple_t
*
entry
)
/* in: index entry to insert in the
child table */
{
char
*
buf
=
dict_foreign_err_buf
;
mutex_enter
(
&
dict_foreign_err_mutex
);
ut_sprintf_timestamp
(
buf
);
sprintf
(
buf
+
strlen
(
buf
),
" Transaction:
\n
"
);
trx_print
(
buf
+
strlen
(
buf
),
thr_get_trx
(
thr
));
sprintf
(
buf
+
strlen
(
buf
),
"Foreign key constraint fails for table %.500s:
\n
"
,
foreign
->
foreign_table_name
);
dict_print_info_on_foreign_key_in_create_format
(
foreign
,
buf
+
strlen
(
buf
));
sprintf
(
buf
+
strlen
(
buf
),
"
\n
Trying to add in child table, in index %.500s tuple:
\n
"
,
foreign
->
foreign_index
->
name
);
if
(
entry
)
{
dtuple_sprintf
(
buf
+
strlen
(
buf
),
1000
,
entry
);
}
sprintf
(
buf
+
strlen
(
buf
),
"
\n
But in parent table %.500s, in index %.500s,
\n
"
"the closest match we can find is record:
\n
"
,
foreign
->
referenced_table_name
,
foreign
->
referenced_index
->
name
);
if
(
rec
&&
page_rec_is_supremum
(
rec
))
{
/* If the cursor ended on a supremum record, it is better
to report the previous record in the error message, so that
the user gets a more descriptive error message. */
rec
=
page_rec_get_prev
(
rec
);
}
if
(
rec
)
{
rec_sprintf
(
buf
+
strlen
(
buf
),
1000
,
rec
);
}
sprintf
(
buf
+
strlen
(
buf
),
"
\n
"
);
ut_a
(
strlen
(
buf
)
<
DICT_FOREIGN_ERR_BUF_LEN
);
mutex_exit
(
&
dict_foreign_err_mutex
);
}
/*************************************************************************
Perform referential actions or checks when a parent row is deleted or updated
and the constraint had an ON DELETE or ON UPDATE condition which was not
...
...
@@ -453,6 +558,8 @@ row_ins_foreign_check_on_constraint(
type is != 0 */
btr_pcur_t
*
pcur
,
/* in: cursor placed on a matching
index record in the child table */
dtuple_t
*
entry
,
/* in: index entry in the parent
table */
mtr_t
*
mtr
)
/* in: mtr holding the latch of pcur
page */
{
...
...
@@ -506,6 +613,10 @@ row_ins_foreign_check_on_constraint(
return
(
DB_SUCCESS
);
}
row_ins_foreign_report_err
((
char
*
)
"Trying to delete"
,
thr
,
foreign
,
btr_pcur_get_rec
(
pcur
),
entry
);
return
(
DB_ROW_IS_REFERENCED
);
}
...
...
@@ -523,6 +634,10 @@ row_ins_foreign_check_on_constraint(
return
(
DB_SUCCESS
);
}
row_ins_foreign_report_err
((
char
*
)
"Trying to update"
,
thr
,
foreign
,
btr_pcur_get_rec
(
pcur
),
entry
);
return
(
DB_ROW_IS_REFERENCED
);
}
...
...
@@ -580,6 +695,10 @@ row_ins_foreign_check_on_constraint(
err
=
DB_ROW_IS_REFERENCED
;
row_ins_foreign_report_err
(
(
char
*
)
"Trying an update, possibly causing a cyclic cascaded update
\n
"
"in the child table,"
,
thr
,
foreign
,
btr_pcur_get_rec
(
pcur
),
entry
);
goto
nonstandard_exit_func
;
}
...
...
@@ -809,7 +928,6 @@ row_ins_check_foreign_constraint(
dictionary cache if they exist at all */
dict_table_t
*
table
,
/* in: if check_ref is TRUE, then the foreign
table, else the referenced table */
dict_index_t
*
index
__attribute__
((
unused
)),
/* in: index in table */
dtuple_t
*
entry
,
/* in: index entry for index */
que_thr_t
*
thr
)
/* in: query thread */
{
...
...
@@ -824,6 +942,7 @@ row_ins_check_foreign_constraint(
int
cmp
;
ulint
err
;
ulint
i
;
char
*
buf
=
dict_foreign_err_buf
;
mtr_t
mtr
;
run_again:
...
...
@@ -884,6 +1003,25 @@ row_ins_check_foreign_constraint(
if
(
check_table
==
NULL
)
{
if
(
check_ref
)
{
mutex_enter
(
&
dict_foreign_err_mutex
);
ut_sprintf_timestamp
(
buf
);
sprintf
(
buf
+
strlen
(
buf
),
" Transaction:
\n
"
);
trx_print
(
buf
+
strlen
(
buf
),
thr_get_trx
(
thr
));
sprintf
(
buf
+
strlen
(
buf
),
"Foreign key constraint fails for table %.500s:
\n
"
,
foreign
->
foreign_table_name
);
dict_print_info_on_foreign_key_in_create_format
(
foreign
,
buf
+
strlen
(
buf
));
sprintf
(
buf
+
strlen
(
buf
),
"
\n
Trying to add to index %.500s tuple:
\n
"
,
foreign
->
foreign_index
->
name
);
dtuple_sprintf
(
buf
+
strlen
(
buf
),
1000
,
entry
);
sprintf
(
buf
+
strlen
(
buf
),
"
\n
But the parent table %.500s does not currently exist!
\n
"
,
foreign
->
referenced_table_name
);
ut_a
(
strlen
(
buf
)
<
DICT_FOREIGN_ERR_BUF_LEN
);
mutex_exit
(
&
dict_foreign_err_mutex
);
return
(
DB_NO_REFERENCED_ROW
);
}
...
...
@@ -949,7 +1087,8 @@ row_ins_check_foreign_constraint(
if
(
cmp
==
0
)
{
if
(
rec_get_deleted_flag
(
rec
))
{
err
=
row_ins_set_shared_rec_lock
(
LOCK_ORDINARY
,
err
=
row_ins_set_shared_rec_lock
(
LOCK_ORDINARY
,
rec
,
check_index
,
thr
);
if
(
err
!=
DB_SUCCESS
)
{
...
...
@@ -989,13 +1128,17 @@ row_ins_check_foreign_constraint(
err
=
row_ins_foreign_check_on_constraint
(
thr
,
foreign
,
&
pcur
,
&
mtr
);
thr
,
foreign
,
&
pcur
,
entry
,
&
mtr
);
if
(
err
!=
DB_SUCCESS
)
{
break
;
}
}
else
{
row_ins_foreign_report_err
(
(
char
*
)
"Trying to delete or update"
,
thr
,
foreign
,
rec
,
entry
);
err
=
DB_ROW_IS_REFERENCED
;
break
;
}
...
...
@@ -1012,6 +1155,8 @@ row_ins_check_foreign_constraint(
if
(
check_ref
)
{
err
=
DB_NO_REFERENCED_ROW
;
row_ins_foreign_report_add_err
(
thr
,
foreign
,
rec
,
entry
);
}
else
{
err
=
DB_SUCCESS
;
}
...
...
@@ -1025,6 +1170,9 @@ row_ins_check_foreign_constraint(
if
(
!
moved
)
{
if
(
check_ref
)
{
rec
=
btr_pcur_get_rec
(
&
pcur
);
row_ins_foreign_report_add_err
(
thr
,
foreign
,
rec
,
entry
);
err
=
DB_NO_REFERENCED_ROW
;
}
else
{
err
=
DB_SUCCESS
;
...
...
@@ -1100,7 +1248,7 @@ row_ins_check_foreign_constraints(
}
err
=
row_ins_check_foreign_constraint
(
TRUE
,
foreign
,
table
,
index
,
entry
,
thr
);
table
,
entry
,
thr
);
if
(
got_s_lock
)
{
row_mysql_unfreeze_data_dictionary
(
trx
);
}
...
...
innobase/row/row0mysql.c
View file @
f841b4ae
...
...
@@ -1156,7 +1156,7 @@ row_mysql_recover_tmp_table(
return
(
DB_ERROR
);
}
if
(
0
==
ut_memcmp
(
ptr
,
"/rsql"
,
5
))
{
if
(
0
==
ut_memcmp
(
ptr
,
(
char
*
)
"/rsql"
,
5
))
{
ptr
++
;
*
ptr
=
'#'
;
...
...
@@ -1281,9 +1281,9 @@ row_create_table_for_mysql(
trx
->
op_info
=
(
char
*
)
"creating table"
;
if
(
0
==
ut_strcmp
(
table
->
name
,
"mysql/host"
)
||
0
==
ut_strcmp
(
table
->
name
,
"mysql/user"
)
||
0
==
ut_strcmp
(
table
->
name
,
"mysql/db"
))
{
if
(
0
==
ut_strcmp
(
table
->
name
,
(
char
*
)
"mysql/host"
)
||
0
==
ut_strcmp
(
table
->
name
,
(
char
*
)
"mysql/user"
)
||
0
==
ut_strcmp
(
table
->
name
,
(
char
*
)
"mysql/db"
))
{
fprintf
(
stderr
,
"InnoDB: Error: trying to create a MySQL system table %s of type InnoDB.
\n
"
...
...
@@ -1303,7 +1303,7 @@ row_create_table_for_mysql(
if
(
namelen
>=
keywordlen
&&
0
==
ut_memcmp
(
table
->
name
+
namelen
-
keywordlen
,
"_recover_innodb_tmp_table"
,
keywordlen
))
{
(
char
*
)
"_recover_innodb_tmp_table"
,
keywordlen
))
{
/* MySQL prevents accessing of tables whose name begins
with #sql, that is temporary tables. If mysqld crashes in
...
...
@@ -1371,7 +1371,7 @@ row_create_table_for_mysql(
if
(
namelen
>=
keywordlen
&&
0
==
ut_memcmp
(
table
->
name
+
namelen
-
keywordlen
,
"innodb_mem_validate"
,
keywordlen
))
{
(
char
*
)
"innodb_mem_validate"
,
keywordlen
))
{
/* We define here a debugging feature intended for
developers */
...
...
@@ -1481,7 +1481,7 @@ row_create_index_for_mysql(
if
(
namelen
>=
keywordlen
&&
0
==
ut_memcmp
(
index
->
table_name
+
namelen
-
keywordlen
,
"_recover_innodb_tmp_table"
,
keywordlen
))
{
(
char
*
)
"_recover_innodb_tmp_table"
,
keywordlen
))
{
return
(
DB_SUCCESS
);
}
...
...
@@ -1586,7 +1586,7 @@ row_table_add_foreign_constraints(
if
(
namelen
>=
keywordlen
&&
0
==
ut_memcmp
(
name
+
namelen
-
keywordlen
,
"_recover_innodb_tmp_table"
,
keywordlen
))
{
(
char
*
)
"_recover_innodb_tmp_table"
,
keywordlen
))
{
return
(
DB_SUCCESS
);
}
...
...
@@ -1808,7 +1808,6 @@ row_drop_table_for_mysql(
ulint
len
;
ulint
namelen
;
ulint
keywordlen
;
ulint
rounds
=
0
;
ibool
locked_dictionary
=
FALSE
;
char
buf
[
10000
];
...
...
@@ -2155,7 +2154,7 @@ row_is_mysql_tmp_table_name(
ulint
i
;
for
(
i
=
0
;
i
<=
ut_strlen
(
name
)
-
5
;
i
++
)
{
if
(
ut_memcmp
(
name
+
i
,
"/#sql"
,
5
)
==
0
)
{
if
(
ut_memcmp
(
name
+
i
,
(
char
*
)
"/#sql"
,
5
)
==
0
)
{
return
(
TRUE
);
}
...
...
@@ -2177,12 +2176,16 @@ row_rename_table_for_mysql(
{
dict_table_t
*
table
;
que_thr_t
*
thr
;
que_t
*
graph
;
que_t
*
graph
=
NULL
;
ulint
err
;
char
*
str1
;
char
*
str2
;
char
*
str3
;
mem_heap_t
*
heap
=
NULL
;
char
**
constraints_to_drop
=
NULL
;
ulint
n_constraints_to_drop
=
0
;
ulint
len
;
ulint
i
;
char
buf
[
10000
];
ut_ad
(
trx
->
mysql_thread_id
==
os_thread_get_curr_id
());
...
...
@@ -2201,9 +2204,9 @@ row_rename_table_for_mysql(
return
(
DB_ERROR
);
}
if
(
0
==
ut_strcmp
(
new_name
,
"mysql/host"
)
||
0
==
ut_strcmp
(
new_name
,
"mysql/user"
)
||
0
==
ut_strcmp
(
new_name
,
"mysql/db"
))
{
if
(
0
==
ut_strcmp
(
new_name
,
(
char
*
)
"mysql/host"
)
||
0
==
ut_strcmp
(
new_name
,
(
char
*
)
"mysql/user"
)
||
0
==
ut_strcmp
(
new_name
,
(
char
*
)
"mysql/db"
))
{
fprintf
(
stderr
,
"InnoDB: Error: trying to create a MySQL system table %s of type InnoDB.
\n
"
...
...
@@ -2217,6 +2220,19 @@ row_rename_table_for_mysql(
trx
->
op_info
=
(
char
*
)
"renaming table"
;
trx_start_if_not_started
(
trx
);
/* Serialize data dictionary operations with dictionary mutex:
no deadlocks can occur then in these operations */
row_mysql_lock_data_dictionary
(
trx
);
table
=
dict_table_get_low
(
old_name
);
if
(
!
table
)
{
err
=
DB_TABLE_NOT_FOUND
;
goto
funct_exit
;
}
str1
=
(
char
*
)
"PROCEDURE RENAME_TABLE_PROC () IS
\n
"
"new_table_name CHAR;
\n
"
...
...
@@ -2229,14 +2245,43 @@ row_rename_table_for_mysql(
if
(
row_is_mysql_tmp_table_name
(
new_name
))
{
/* We want to preserve the original foreign key
constraint definitions despite the name change */
/* MySQL is doing an ALTER TABLE command and it renames the
original table to a temporary table name. We want to preserve
the original foreign key constraint definitions despite the
name change. An exception is those constraints for which
the ALTER TABLE contained DROP FOREIGN KEY <foreign key id>.*/
str3
=
(
char
*
)
heap
=
mem_heap_create
(
100
);
err
=
dict_foreign_parse_drop_constraints
(
heap
,
trx
,
table
,
&
n_constraints_to_drop
,
&
constraints_to_drop
);
if
(
err
!=
DB_SUCCESS
)
{
goto
funct_exit
;
}
str3
=
mem_heap_alloc
(
heap
,
1000
+
500
*
n_constraints_to_drop
);
*
str3
=
'\0'
;
sprintf
(
str3
,
"';
\n
"
"UPDATE SYS_TABLES SET NAME = new_table_name
\n
"
"WHERE NAME = old_table_name;
\n
"
"END;
\n
"
;
"WHERE NAME = old_table_name;
\n
"
);
for
(
i
=
0
;
i
<
n_constraints_to_drop
;
i
++
)
{
sprintf
(
str3
+
strlen
(
str3
),
"DELETE FROM SYS_FOREIGN_COLS WHERE ID = '%s';
\n
"
"DELETE FROM SYS_FOREIGN WHERE ID = '%s';
\n
"
,
constraints_to_drop
[
i
],
constraints_to_drop
[
i
]);
}
sprintf
(
str3
+
strlen
(
str3
),
"END;
\n
"
);
ut_a
(
strlen
(
str3
)
<
1000
+
500
*
n_constraints_to_drop
);
}
else
{
str3
=
(
char
*
)
"';
\n
"
...
...
@@ -2267,13 +2312,6 @@ row_rename_table_for_mysql(
ut_memcpy
(
buf
+
len
,
str3
,
ut_strlen
(
str3
)
+
1
);
/* Serialize data dictionary operations with dictionary mutex:
no deadlocks can occur then in these operations */
row_mysql_lock_data_dictionary
(
trx
);
table
=
dict_table_get_low
(
old_name
);
graph
=
pars_sql
(
buf
);
ut_a
(
graph
);
...
...
@@ -2283,12 +2321,6 @@ row_rename_table_for_mysql(
graph
->
fork_type
=
QUE_FORK_MYSQL_INTERFACE
;
if
(
!
table
)
{
err
=
DB_TABLE_NOT_FOUND
;
goto
funct_exit
;
}
ut_a
(
thr
=
que_fork_start_command
(
graph
,
SESS_COMM_EXECUTE
,
0
));
que_run_threads
(
thr
);
...
...
@@ -2329,6 +2361,13 @@ row_rename_table_for_mysql(
if
(
row_is_mysql_tmp_table_name
(
old_name
))
{
/* MySQL is doing an ALTER TABLE command and it
renames the created temporary table to the name
of the original table. In the ALTER TABLE we maybe
created some FOREIGN KEY constraints for the temporary
table. But we want to load also the foreign key
constraint definitions for the original table name. */
err
=
dict_load_foreigns
(
new_name
);
if
(
err
!=
DB_SUCCESS
)
{
...
...
@@ -2354,7 +2393,13 @@ row_rename_table_for_mysql(
funct_exit:
row_mysql_unlock_data_dictionary
(
trx
);
if
(
graph
)
{
que_graph_free
(
graph
);
}
if
(
heap
)
{
mem_heap_free
(
heap
);
}
trx_commit_for_mysql
(
trx
);
...
...
innobase/row/row0sel.c
View file @
f841b4ae
...
...
@@ -2601,6 +2601,24 @@ row_search_for_mysql(
printf("N tables locked %lu\n", trx->mysql_n_tables_locked);
*/
/*-------------------------------------------------------------*/
/* PHASE 0: Release a possible s-latch we are holding on the
adaptive hash index latch if there is someone waiting behind */
if
(
trx
->
has_search_latch
&&
btr_search_latch
.
writer
!=
RW_LOCK_NOT_LOCKED
)
{
/* There is an x-latch request on the adaptive hash index:
release the s-latch to reduce starvation and wait for
BTR_SEA_TIMEOUT rounds before trying to keep it again over
calls from MySQL */
rw_lock_s_unlock
(
&
btr_search_latch
);
trx
->
has_search_latch
=
FALSE
;
trx
->
search_latch_timeout
=
BTR_SEA_TIMEOUT
;
}
/*-------------------------------------------------------------*/
/* PHASE 1: Try to pop the row from the prefetch cache */
...
...
@@ -2737,22 +2755,6 @@ row_search_for_mysql(
and if we try that, we can deadlock on the adaptive
hash index semaphore! */
if
(
btr_search_latch
.
writer
!=
RW_LOCK_NOT_LOCKED
)
{
/* There is an x-latch request: release
a possible s-latch to reduce starvation
and wait for BTR_SEA_TIMEOUT rounds before
trying to keep it again over calls from
MySQL */
if
(
trx
->
has_search_latch
)
{
rw_lock_s_unlock
(
&
btr_search_latch
);
trx
->
has_search_latch
=
FALSE
;
}
trx
->
search_latch_timeout
=
BTR_SEA_TIMEOUT
;
goto
no_shortcut
;
}
#ifndef UNIV_SEARCH_DEBUG
if
(
!
trx
->
has_search_latch
)
{
rw_lock_s_lock
(
&
btr_search_latch
);
...
...
@@ -2810,7 +2812,6 @@ row_search_for_mysql(
}
}
no_shortcut:
/*-------------------------------------------------------------*/
/* PHASE 3: Open or restore index cursor position */
...
...
innobase/row/row0upd.c
View file @
f841b4ae
...
...
@@ -218,7 +218,7 @@ row_upd_check_references_constraints(
being dropped while the check is running. */
err
=
row_ins_check_foreign_constraint
(
FALSE
,
foreign
,
table
,
index
,
entry
,
thr
);
table
,
entry
,
thr
);
if
(
foreign
->
foreign_table
)
{
mutex_enter
(
&
(
dict_sys
->
mutex
));
...
...
innobase/srv/srv0srv.c
View file @
f841b4ae
...
...
@@ -1869,11 +1869,11 @@ srv_conc_enter_innodb(
/* Go to wait for the event; when a thread leaves InnoDB it will
release this thread */
trx
->
op_info
=
"waiting in InnoDB queue"
;
trx
->
op_info
=
(
char
*
)
"waiting in InnoDB queue"
;
os_event_wait
(
slot
->
event
);
trx
->
op_info
=
""
;
trx
->
op_info
=
(
char
*
)
""
;
os_fast_mutex_lock
(
&
srv_conc_mutex
);
...
...
@@ -2346,9 +2346,19 @@ srv_sprintf_innodb_monitor(
buf
=
buf
+
strlen
(
buf
);
ut_a
(
buf
<
buf_end
+
1500
);
buf
+=
sprintf
(
buf
,
"------------
\n
"
"TRANSACTIONS
\n
"
"------------
\n
"
);
if
(
*
dict_foreign_err_buf
!=
'\0'
)
{
buf
+=
sprintf
(
buf
,
"------------------------
\n
"
"LATEST FOREIGN KEY ERROR
\n
"
"------------------------
\n
"
);
if
(
buf_end
-
buf
>
6000
)
{
buf
+=
sprintf
(
buf
,
"%.4000s"
,
dict_foreign_err_buf
);
}
}
ut_a
(
buf
<
buf_end
+
1500
);
lock_print_info
(
buf
,
buf_end
);
buf
=
buf
+
strlen
(
buf
);
...
...
innobase/ut/ut0ut.c
View file @
f841b4ae
...
...
@@ -204,7 +204,7 @@ ut_get_year_month_day(
cal_tm_ptr
=
localtime
(
&
tm
);
*
year
=
(
ulint
)
cal_tm_ptr
->
tm_year
;
*
year
=
(
ulint
)
cal_tm_ptr
->
tm_year
+
1900
;
*
month
=
(
ulint
)
cal_tm_ptr
->
tm_mon
+
1
;
*
day
=
(
ulint
)
cal_tm_ptr
->
tm_mday
;
#endif
...
...
sql/ha_innodb.cc
View file @
f841b4ae
...
...
@@ -242,6 +242,10 @@ convert_error_code_to_mysql(
return
(
HA_ERR_CANNOT_ADD_FOREIGN
);
}
else
if
(
error
==
(
int
)
DB_CANNOT_DROP_CONSTRAINT
)
{
return
(
HA_WRONG_CREATE_OPTION
);
}
else
if
(
error
==
(
int
)
DB_COL_APPEARS_TWICE_IN_INDEX
)
{
return
(
HA_ERR_CRASHED
);
...
...
@@ -3049,6 +3053,9 @@ ha_innobase::create(
trx
=
trx_allocate_for_mysql
();
trx
->
mysql_thd
=
thd
;
trx
->
mysql_query_str
=
&
((
*
thd
).
query
);
if
(
thd
->
options
&
OPTION_NO_FOREIGN_KEY_CHECKS
)
{
trx
->
check_foreigns
=
FALSE
;
}
...
...
@@ -3231,6 +3238,9 @@ ha_innobase::delete_table(
trx
=
trx_allocate_for_mysql
();
trx
->
mysql_thd
=
current_thd
;
trx
->
mysql_query_str
=
&
((
*
current_thd
).
query
);
name_len
=
strlen
(
name
);
assert
(
name_len
<
1000
);
...
...
@@ -3309,6 +3319,8 @@ innobase_drop_database(
casedn_str
(
namebuf
);
#endif
trx
=
trx_allocate_for_mysql
();
trx
->
mysql_thd
=
current_thd
;
trx
->
mysql_query_str
=
&
((
*
current_thd
).
query
);
error
=
row_drop_database_for_mysql
(
namebuf
,
trx
);
...
...
@@ -3368,6 +3380,8 @@ ha_innobase::rename_table(
}
trx
=
trx_allocate_for_mysql
();
trx
->
mysql_thd
=
current_thd
;
trx
->
mysql_query_str
=
&
((
*
current_thd
).
query
);
name_len1
=
strlen
(
from
);
name_len2
=
strlen
(
to
);
...
...
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