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
0e28bb07
Commit
0e28bb07
authored
Dec 27, 2004
by
heikki@hundin.mysql.fi
Browse files
Options
Browse Files
Download
Plain Diff
Merge heikki@bk-internal.mysql.com:/home/bk/mysql-4.1
into hundin.mysql.fi:/home/heikki/mysql-4.1
parents
8f602f2a
7ad5e204
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
321 additions
and
104 deletions
+321
-104
innobase/buf/buf0rea.c
innobase/buf/buf0rea.c
+1
-1
innobase/dict/dict0load.c
innobase/dict/dict0load.c
+25
-5
innobase/fil/fil0fil.c
innobase/fil/fil0fil.c
+78
-15
innobase/include/dict0load.h
innobase/include/dict0load.h
+6
-4
innobase/include/fil0fil.h
innobase/include/fil0fil.h
+19
-9
innobase/include/row0mysql.h
innobase/include/row0mysql.h
+1
-19
innobase/include/trx0trx.h
innobase/include/trx0trx.h
+13
-0
innobase/row/row0ins.c
innobase/row/row0ins.c
+2
-2
innobase/row/row0mysql.c
innobase/row/row0mysql.c
+119
-22
innobase/row/row0sel.c
innobase/row/row0sel.c
+16
-2
innobase/srv/srv0start.c
innobase/srv/srv0start.c
+32
-11
innobase/trx/trx0trx.c
innobase/trx/trx0trx.c
+8
-0
sql/ha_innodb.cc
sql/ha_innodb.cc
+1
-14
No files found.
innobase/buf/buf0rea.c
View file @
0e28bb07
...
@@ -326,7 +326,7 @@ buf_read_page(
...
@@ -326,7 +326,7 @@ buf_read_page(
if
(
err
==
DB_TABLESPACE_DELETED
)
{
if
(
err
==
DB_TABLESPACE_DELETED
)
{
ut_print_timestamp
(
stderr
);
ut_print_timestamp
(
stderr
);
fprintf
(
stderr
,
fprintf
(
stderr
,
" InnoDB:
e
rror: trying to access tablespace %lu page no. %lu,
\n
"
" InnoDB:
E
rror: trying to access tablespace %lu page no. %lu,
\n
"
"InnoDB: but the tablespace does not exist or is just being dropped.
\n
"
,
"InnoDB: but the tablespace does not exist or is just being dropped.
\n
"
,
(
ulong
)
space
,
(
ulong
)
offset
);
(
ulong
)
space
,
(
ulong
)
offset
);
}
}
...
...
innobase/dict/dict0load.c
View file @
0e28bb07
...
@@ -205,12 +205,14 @@ dict_print(void)
...
@@ -205,12 +205,14 @@ dict_print(void)
In a crash recovery we already have all the tablespace objects created.
In a crash recovery we already have all the tablespace objects created.
This function compares the space id information in the InnoDB data dictionary
This function compares the space id information in the InnoDB data dictionary
to what we already read with fil_load_single_table_tablespaces().
to what we already read with fil_load_single_table_tablespaces().
In a normal startup we just scan the biggest space id, and store it to
fil_system. */
In a normal startup, we create the tablespace objects for every table in
InnoDB's data dictionary, if the corresponding .ibd file exists.
We also scan the biggest space id, and store it to fil_system. */
void
void
dict_check_tablespaces_
or
_store_max_id
(
dict_check_tablespaces_
and
_store_max_id
(
/*===================================*/
/*===================================
=
*/
ibool
in_crash_recovery
)
/* in: are we doing a crash recovery */
ibool
in_crash_recovery
)
/* in: are we doing a crash recovery */
{
{
dict_table_t
*
sys_tables
;
dict_table_t
*
sys_tables
;
...
@@ -280,6 +282,14 @@ dict_check_tablespaces_or_store_max_id(
...
@@ -280,6 +282,14 @@ dict_check_tablespaces_or_store_max_id(
FALSE
,
TRUE
,
TRUE
);
FALSE
,
TRUE
,
TRUE
);
}
}
if
(
space_id
!=
0
&&
!
in_crash_recovery
)
{
/* It is a normal database startup: create the space
object and check that the .ibd file exists. */
fil_open_single_table_tablespace
(
FALSE
,
space_id
,
name
);
}
mem_free
(
name
);
mem_free
(
name
);
if
(
space_id
>
max_space_id
)
{
if
(
space_id
>
max_space_id
)
{
...
@@ -796,8 +806,18 @@ dict_load_table(
...
@@ -796,8 +806,18 @@ dict_load_table(
/* Ok; (if we did a crash recovery then the tablespace
/* Ok; (if we did a crash recovery then the tablespace
can already be in the memory cache) */
can already be in the memory cache) */
}
else
{
}
else
{
/* In >= 4.1.9, InnoDB scans the data dictionary also
at a normal mysqld startup. It is an error if the
space object does not exist in memory. */
ut_print_timestamp
(
stderr
);
fprintf
(
stderr
,
" InnoDB: error: space object of table %s,
\n
"
"InnoDB: space id %lu did not exist in memory. Retrying an open.
\n
"
,
name
,
(
ulong
)
space
);
/* Try to open the tablespace */
/* Try to open the tablespace */
if
(
!
fil_open_single_table_tablespace
(
space
,
name
))
{
if
(
!
fil_open_single_table_tablespace
(
TRUE
,
space
,
name
))
{
/* We failed to find a sensible tablespace
/* We failed to find a sensible tablespace
file */
file */
...
...
innobase/fil/fil0fil.c
View file @
0e28bb07
...
@@ -466,6 +466,10 @@ fil_node_open_file(
...
@@ -466,6 +466,10 @@ fil_node_open_file(
ulint
size_low
;
ulint
size_low
;
ulint
size_high
;
ulint
size_high
;
ibool
ret
;
ibool
ret
;
byte
*
buf2
;
byte
*
page
;
ibool
success
;
ulint
space_id
;
#ifdef UNIV_SYNC_DEBUG
#ifdef UNIV_SYNC_DEBUG
ut_ad
(
mutex_own
(
&
(
system
->
mutex
)));
ut_ad
(
mutex_own
(
&
(
system
->
mutex
)));
...
@@ -494,6 +498,8 @@ fil_node_open_file(
...
@@ -494,6 +498,8 @@ fil_node_open_file(
system
->
n_open
++
;
system
->
n_open
++
;
if
(
node
->
size
==
0
)
{
if
(
node
->
size
==
0
)
{
ut_a
(
space
->
purpose
!=
FIL_LOG
);
os_file_get_size
(
node
->
handle
,
&
size_low
,
&
size_high
);
os_file_get_size
(
node
->
handle
,
&
size_low
,
&
size_high
);
size_bytes
=
(((
ib_longlong
)
size_high
)
<<
32
)
size_bytes
=
(((
ib_longlong
)
size_high
)
<<
32
)
...
@@ -507,6 +513,46 @@ fil_node_open_file(
...
@@ -507,6 +513,46 @@ fil_node_open_file(
ut_a
(
space
->
id
!=
0
);
ut_a
(
space
->
id
!=
0
);
if
(
size_bytes
<
FIL_IBD_FILE_INITIAL_SIZE
*
UNIV_PAGE_SIZE
)
{
fprintf
(
stderr
,
"InnoDB: Error: the size of single-table tablespace file %s
\n
"
"InnoDB: is only %lu %lu, should be at least %lu!"
,
node
->
name
,
(
ulong
)
size_high
,
(
ulong
)
size_low
,
(
ulong
)
(
4
*
UNIV_PAGE_SIZE
));
ut_a
(
0
);
}
/* Read the first page of the tablespace */
buf2
=
ut_malloc
(
2
*
UNIV_PAGE_SIZE
);
/* Align the memory for file i/o if we might have O_DIRECT
set */
page
=
ut_align
(
buf2
,
UNIV_PAGE_SIZE
);
success
=
os_file_read
(
node
->
handle
,
page
,
0
,
0
,
UNIV_PAGE_SIZE
);
space_id
=
fsp_header_get_space_id
(
page
);
ut_free
(
buf2
);
if
(
space_id
==
ULINT_UNDEFINED
||
space_id
==
0
)
{
fprintf
(
stderr
,
"InnoDB: Error: tablespace id %lu in file %s is not sensible
\n
"
,
(
ulong
)
space_id
,
node
->
name
);
ut_a
(
0
);
}
if
(
space_id
!=
space
->
id
)
{
fprintf
(
stderr
,
"InnoDB: Error: tablespace id is %lu in the data dictionary
\n
"
"InnoDB: but in file %s it is %lu!
\n
"
,
space
->
id
,
node
->
name
,
space_id
);
ut_a
(
0
);
}
if
(
size_bytes
>=
FSP_EXTENT_SIZE
*
UNIV_PAGE_SIZE
)
{
if
(
size_bytes
>=
FSP_EXTENT_SIZE
*
UNIV_PAGE_SIZE
)
{
node
->
size
=
(
ulint
)
((
size_bytes
/
(
1024
*
1024
))
node
->
size
=
(
ulint
)
((
size_bytes
/
(
1024
*
1024
))
*
((
1024
*
1024
)
/
UNIV_PAGE_SIZE
));
*
((
1024
*
1024
)
/
UNIV_PAGE_SIZE
));
...
@@ -2487,21 +2533,29 @@ fil_reset_too_high_lsns(
...
@@ -2487,21 +2533,29 @@ fil_reset_too_high_lsns(
}
}
/************************************************************************
/************************************************************************
Tries to open a single-table tablespace and checks the space id is right in
Tries to open a single-table tablespace and optionally checks the space id is
it. If does not succeed, prints an error message to the .err log. This
right in it. If does not succeed, prints an error message to the .err log. This
function is used to open the tablespace when we load a table definition
function is used to open a tablespace when we start up mysqld, and also in
to the dictionary cache. NOTE that we assume this operation is used under the
IMPORT TABLESPACE.
protection of the dictionary mutex, so that two users cannot race here. This
NOTE that we assume this operation is used either at the database startup
operation does not leave the file associated with the tablespace open, but
or under the protection of the dictionary mutex, so that two users cannot
closes it after we have looked at the space id in it. */
race here. This operation does not leave the file associated with the
tablespace open, but closes it after we have looked at the space id in it. */
ibool
ibool
fil_open_single_table_tablespace
(
fil_open_single_table_tablespace
(
/*=============================*/
/*=============================*/
/* out: TRUE if success */
/* out: TRUE if success */
ulint
id
,
/* in: space id */
ibool
check_space_id
,
/* in: should we check that the space
const
char
*
name
)
/* in: table name in the
id in the file is right; we assume
databasename/tablename format */
that this function runs much faster
if no check is made, since accessing
the file inode probably is much
faster (the OS caches them) than
accessing the first page of the file */
ulint
id
,
/* in: space id */
const
char
*
name
)
/* in: table name in the
databasename/tablename format */
{
{
os_file_t
file
;
os_file_t
file
;
char
*
filepath
;
char
*
filepath
;
...
@@ -2540,6 +2594,12 @@ fil_open_single_table_tablespace(
...
@@ -2540,6 +2594,12 @@ fil_open_single_table_tablespace(
return
(
FALSE
);
return
(
FALSE
);
}
}
if
(
!
check_space_id
)
{
space_id
=
id
;
goto
skip_check
;
}
/* Read the first page of the tablespace */
/* Read the first page of the tablespace */
buf2
=
ut_malloc
(
2
*
UNIV_PAGE_SIZE
);
buf2
=
ut_malloc
(
2
*
UNIV_PAGE_SIZE
);
...
@@ -2552,6 +2612,8 @@ fil_open_single_table_tablespace(
...
@@ -2552,6 +2612,8 @@ fil_open_single_table_tablespace(
space_id
=
fsp_header_get_space_id
(
page
);
space_id
=
fsp_header_get_space_id
(
page
);
ut_free
(
buf2
);
if
(
space_id
!=
id
)
{
if
(
space_id
!=
id
)
{
ut_print_timestamp
(
stderr
);
ut_print_timestamp
(
stderr
);
...
@@ -2572,6 +2634,7 @@ fil_open_single_table_tablespace(
...
@@ -2572,6 +2634,7 @@ fil_open_single_table_tablespace(
goto
func_exit
;
goto
func_exit
;
}
}
skip_check:
success
=
fil_space_create
(
filepath
,
space_id
,
FIL_TABLESPACE
);
success
=
fil_space_create
(
filepath
,
space_id
,
FIL_TABLESPACE
);
if
(
!
success
)
{
if
(
!
success
)
{
...
@@ -2584,7 +2647,6 @@ fil_open_single_table_tablespace(
...
@@ -2584,7 +2647,6 @@ fil_open_single_table_tablespace(
fil_node_create
(
filepath
,
0
,
space_id
,
FALSE
);
fil_node_create
(
filepath
,
0
,
space_id
,
FALSE
);
func_exit:
func_exit:
os_file_close
(
file
);
os_file_close
(
file
);
ut_free
(
buf2
);
mem_free
(
filepath
);
mem_free
(
filepath
);
return
(
ret
);
return
(
ret
);
...
@@ -2651,7 +2713,7 @@ fil_load_single_table_tablespace(
...
@@ -2651,7 +2713,7 @@ fil_load_single_table_tablespace(
fprintf
(
stderr
,
fprintf
(
stderr
,
"InnoDB: Error: could not open single-table tablespace file
\n
"
"InnoDB: Error: could not open single-table tablespace file
\n
"
"InnoDB: %s!
\n
"
"InnoDB: %s!
\n
"
"InnoDB: We do not continue
crash recovery, because the table will
become
\n
"
"InnoDB: We do not continue
the crash recovery, because the table may
become
\n
"
"InnoDB: corrupt if we cannot apply the log records in the InnoDB log to it.
\n
"
"InnoDB: corrupt if we cannot apply the log records in the InnoDB log to it.
\n
"
"InnoDB: To fix the problem and start mysqld:
\n
"
"InnoDB: To fix the problem and start mysqld:
\n
"
"InnoDB: 1) If there is a permission problem in the file and mysqld cannot
\n
"
"InnoDB: 1) If there is a permission problem in the file and mysqld cannot
\n
"
...
@@ -2822,8 +2884,9 @@ fil_load_single_table_tablespace(
...
@@ -2822,8 +2884,9 @@ fil_load_single_table_tablespace(
goto
func_exit
;
goto
func_exit
;
}
}
/* We do not measure the size of the file, that is why we pass the 0
/* We do not use the size information we have about the file, because
below */
the rounding formulat for extents and pages is somewhat complex; we
let fil_node_open() do that task. */
fil_node_create
(
filepath
,
0
,
space_id
,
FALSE
);
fil_node_create
(
filepath
,
0
,
space_id
,
FALSE
);
func_exit:
func_exit:
...
...
innobase/include/dict0load.h
View file @
0e28bb07
...
@@ -18,12 +18,14 @@ Created 4/24/1996 Heikki Tuuri
...
@@ -18,12 +18,14 @@ Created 4/24/1996 Heikki Tuuri
In a crash recovery we already have all the tablespace objects created.
In a crash recovery we already have all the tablespace objects created.
This function compares the space id information in the InnoDB data dictionary
This function compares the space id information in the InnoDB data dictionary
to what we already read with fil_load_single_table_tablespaces().
to what we already read with fil_load_single_table_tablespaces().
In a normal startup we just scan the biggest space id, and store it to
fil_system. */
In a normal startup, we create the tablespace objects for every table in
InnoDB's data dictionary, if the corresponding .ibd file exists.
We also scan the biggest space id, and store it to fil_system. */
void
void
dict_check_tablespaces_
or
_store_max_id
(
dict_check_tablespaces_
and
_store_max_id
(
/*===================================*/
/*===================================
=
*/
ibool
in_crash_recovery
);
/* in: are we doing a crash recovery */
ibool
in_crash_recovery
);
/* in: are we doing a crash recovery */
/************************************************************************
/************************************************************************
Finds the first table name in the given database. */
Finds the first table name in the given database. */
...
...
innobase/include/fil0fil.h
View file @
0e28bb07
...
@@ -364,19 +364,29 @@ fil_create_new_single_table_tablespace(
...
@@ -364,19 +364,29 @@ fil_create_new_single_table_tablespace(
tablespace file in pages,
tablespace file in pages,
must be >= FIL_IBD_FILE_INITIAL_SIZE */
must be >= FIL_IBD_FILE_INITIAL_SIZE */
/************************************************************************
/************************************************************************
Tries to open a single-table tablespace and checks the space id is right in
Tries to open a single-table tablespace and optionally checks the space id is
it. If does not succeed, prints an error message to the .err log. This
right in it. If does not succeed, prints an error message to the .err log. This
function is used to open the tablespace when we load a table definition
function is used to open a tablespace when we start up mysqld, and also in
to the dictionary cache. NOTE that we assume this operation is used under the
IMPORT TABLESPACE.
protection of the dictionary mutex, so that two users cannot race here. */
NOTE that we assume this operation is used either at the database startup
or under the protection of the dictionary mutex, so that two users cannot
race here. This operation does not leave the file associated with the
tablespace open, but closes it after we have looked at the space id in it. */
ibool
ibool
fil_open_single_table_tablespace
(
fil_open_single_table_tablespace
(
/*=============================*/
/*=============================*/
/* out: TRUE if success */
/* out: TRUE if success */
ulint
id
,
/* in: space id */
ibool
check_space_id
,
/* in: should we check that the space
const
char
*
name
);
/* in: table name in the
id in the file is right; we assume
databasename/tablename format */
that this function runs much faster
if no check is made, since accessing
the file inode probably is much
faster (the OS caches them) than
accessing the first page of the file */
ulint
id
,
/* in: space id */
const
char
*
name
);
/* in: table name in the
databasename/tablename format */
/************************************************************************
/************************************************************************
It is possible, though very improbable, that the lsn's in the tablespace to be
It is possible, though very improbable, that the lsn's in the tablespace to be
imported have risen above the current system lsn, if a lengthy purge, ibuf
imported have risen above the current system lsn, if a lengthy purge, ibuf
...
...
innobase/include/row0mysql.h
View file @
0e28bb07
...
@@ -367,25 +367,7 @@ row_drop_table_for_mysql(
...
@@ -367,25 +367,7 @@ row_drop_table_for_mysql(
/*************************************************************************
/*************************************************************************
Discards the tablespace of a table which stored in an .ibd file. Discarding
Discards the tablespace of a table which stored in an .ibd file. Discarding
means that this function deletes the .ibd file and assigns a new table id for
means that this function deletes the .ibd file and assigns a new table id for
the table. Also the flag table->ibd_file_missing is set TRUE.
the table. Also the flag table->ibd_file_missing is set TRUE. */
How do we prevent crashes caused by ongoing operations on the table? Old
operations could try to access non-existent pages.
1) SQL queries, INSERT, SELECT, ...: we must get an exclusive MySQL table lock
on the table before we can do DISCARD TABLESPACE. Then there are no running
queries on the table.
2) Purge and rollback: we assign a new table id for the table. Since purge and
rollback look for the table based on the table id, they see the table as
'dropped' and discard their operations.
3) Insert buffer: we remove all entries for the tablespace in the insert
buffer tree; as long as the tablespace mem object does not exist, ongoing
insert buffer page merges are discarded in buf0rea.c. If we recreate the
tablespace mem object with IMPORT TABLESPACE later, then the tablespace will
have the same id, but the tablespace_version field in the mem object is
different, and ongoing old insert buffer page merges get discarded.
4) Linear readahead and random readahead: we use the same method as in 3) to
discard ongoing operations. */
int
int
row_discard_tablespace_for_mysql
(
row_discard_tablespace_for_mysql
(
...
...
innobase/include/trx0trx.h
View file @
0e28bb07
...
@@ -378,6 +378,19 @@ struct trx_struct{
...
@@ -378,6 +378,19 @@ struct trx_struct{
replication slave, this is the
replication slave, this is the
position in the log file up to which
position in the log file up to which
replication has processed */
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
os_thread_id_t
mysql_thread_id
;
/* id of the MySQL thread associated
with this transaction object */
with this transaction object */
ulint
mysql_process_no
;
/* since in Linux, 'top' reports
ulint
mysql_process_no
;
/* since in Linux, 'top' reports
...
...
innobase/row/row0ins.c
View file @
0e28bb07
...
@@ -1173,7 +1173,7 @@ row_ins_check_foreign_constraint(
...
@@ -1173,7 +1173,7 @@ row_ins_check_foreign_constraint(
check_index
=
foreign
->
foreign_index
;
check_index
=
foreign
->
foreign_index
;
}
}
if
(
check_table
==
NULL
)
{
if
(
check_table
==
NULL
||
check_table
->
ibd_file_missing
)
{
if
(
check_ref
)
{
if
(
check_ref
)
{
FILE
*
ef
=
dict_foreign_err_file
;
FILE
*
ef
=
dict_foreign_err_file
;
mutex_enter
(
&
dict_foreign_err_mutex
);
mutex_enter
(
&
dict_foreign_err_mutex
);
...
@@ -1192,7 +1192,7 @@ row_ins_check_foreign_constraint(
...
@@ -1192,7 +1192,7 @@ row_ins_check_foreign_constraint(
dtuple_print
(
ef
,
entry
);
dtuple_print
(
ef
,
entry
);
fputs
(
"
\n
But the parent table "
,
ef
);
fputs
(
"
\n
But the parent table "
,
ef
);
ut_print_name
(
ef
,
trx
,
foreign
->
referenced_table_name
);
ut_print_name
(
ef
,
trx
,
foreign
->
referenced_table_name
);
fputs
(
"
does not currently exist!
\n
"
,
ef
);
fputs
(
"
\n
or its .ind file
does not currently exist!
\n
"
,
ef
);
mutex_exit
(
&
dict_foreign_err_mutex
);
mutex_exit
(
&
dict_foreign_err_mutex
);
return
(
DB_NO_REFERENCED_ROW
);
return
(
DB_NO_REFERENCED_ROW
);
...
...
innobase/row/row0mysql.c
View file @
0e28bb07
...
@@ -869,7 +869,21 @@ row_insert_for_mysql(
...
@@ -869,7 +869,21 @@ row_insert_for_mysql(
ut_ad
(
trx
);
ut_ad
(
trx
);
ut_ad
(
trx
->
mysql_thread_id
==
os_thread_get_curr_id
());
ut_ad
(
trx
->
mysql_thread_id
==
os_thread_get_curr_id
());
if
(
prebuilt
->
table
->
ibd_file_missing
)
{
ut_print_timestamp
(
stderr
);
fprintf
(
stderr
,
" InnoDB: Error:
\n
"
"InnoDB: MySQL is trying to use a table handle but the .ibd file for
\n
"
"InnoDB: table %s does not exist.
\n
"
"InnoDB: Have you deleted the .ibd file from the database directory under
\n
"
"InnoDB: the MySQL datadir, or have you used DISCARD TABLESPACE?
\n
"
"InnoDB: Look from
\n
"
"http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html
\n
"
"InnoDB: how you can resolve the problem.
\n
"
,
prebuilt
->
table
->
name
);
return
(
DB_ERROR
);
}
if
(
prebuilt
->
magic_n
!=
ROW_PREBUILT_ALLOCATED
)
{
if
(
prebuilt
->
magic_n
!=
ROW_PREBUILT_ALLOCATED
)
{
fprintf
(
stderr
,
fprintf
(
stderr
,
"InnoDB: Error: trying to free a corrupt
\n
"
"InnoDB: Error: trying to free a corrupt
\n
"
...
@@ -1087,6 +1101,20 @@ row_update_for_mysql(
...
@@ -1087,6 +1101,20 @@ row_update_for_mysql(
ut_ad
(
trx
->
mysql_thread_id
==
os_thread_get_curr_id
());
ut_ad
(
trx
->
mysql_thread_id
==
os_thread_get_curr_id
());
UT_NOT_USED
(
mysql_rec
);
UT_NOT_USED
(
mysql_rec
);
if
(
prebuilt
->
table
->
ibd_file_missing
)
{
ut_print_timestamp
(
stderr
);
fprintf
(
stderr
,
" InnoDB: Error:
\n
"
"InnoDB: MySQL is trying to use a table handle but the .ibd file for
\n
"
"InnoDB: table %s does not exist.
\n
"
"InnoDB: Have you deleted the .ibd file from the database directory under
\n
"
"InnoDB: the MySQL datadir, or have you used DISCARD TABLESPACE?
\n
"
"InnoDB: Look from
\n
"
"http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html
\n
"
"InnoDB: how you can resolve the problem.
\n
"
,
prebuilt
->
table
->
name
);
return
(
DB_ERROR
);
}
if
(
prebuilt
->
magic_n
!=
ROW_PREBUILT_ALLOCATED
)
{
if
(
prebuilt
->
magic_n
!=
ROW_PREBUILT_ALLOCATED
)
{
fprintf
(
stderr
,
fprintf
(
stderr
,
"InnoDB: Error: trying to free a corrupt
\n
"
"InnoDB: Error: trying to free a corrupt
\n
"
...
@@ -1966,9 +1994,25 @@ row_add_table_to_background_drop_list(
...
@@ -1966,9 +1994,25 @@ row_add_table_to_background_drop_list(
/*************************************************************************
/*************************************************************************
Discards the tablespace of a table which stored in an .ibd file. Discarding
Discards the tablespace of a table which stored in an .ibd file. Discarding
means that this function deletes the .ibd file and assigns a new table id for
means that this function deletes the .ibd file and assigns a new table id for
the table. Also the flag table->ibd_file_missing is set TRUE.
the table. Also the flag table->ibd_file_missing is set TRUE.
*/
How do we prevent crashes caused by ongoing operations on the table? Old
int
row_discard_tablespace_for_mysql
(
/*=============================*/
/* out: error code or DB_SUCCESS */
const
char
*
name
,
/* in: table name */
trx_t
*
trx
)
/* in: transaction handle */
{
dict_foreign_t
*
foreign
;
dulint
new_id
;
dict_table_t
*
table
;
que_thr_t
*
thr
;
que_t
*
graph
=
NULL
;
ibool
success
;
ulint
err
;
char
*
buf
;
/* How do we prevent crashes caused by ongoing operations on the table? Old
operations could try to access non-existent pages.
operations could try to access non-existent pages.
1) SQL queries, INSERT, SELECT, ...: we must get an exclusive MySQL table lock
1) SQL queries, INSERT, SELECT, ...: we must get an exclusive MySQL table lock
...
@@ -1984,22 +2028,9 @@ tablespace mem object with IMPORT TABLESPACE later, then the tablespace will
...
@@ -1984,22 +2028,9 @@ tablespace mem object with IMPORT TABLESPACE later, then the tablespace will
have the same id, but the tablespace_version field in the mem object is
have the same id, but the tablespace_version field in the mem object is
different, and ongoing old insert buffer page merges get discarded.
different, and ongoing old insert buffer page merges get discarded.
4) Linear readahead and random readahead: we use the same method as in 3) to
4) Linear readahead and random readahead: we use the same method as in 3) to
discard ongoing operations. */
discard ongoing operations.
5) FOREIGN KEY operations: if table->n_foreign_key_checks_running > 0, we
int
do not allow the discard. We also reserve the data dictionary latch. */
row_discard_tablespace_for_mysql
(
/*=============================*/
/* out: error code or DB_SUCCESS */
const
char
*
name
,
/* in: table name */
trx_t
*
trx
)
/* in: transaction handle */
{
dulint
new_id
;
dict_table_t
*
table
;
que_thr_t
*
thr
;
que_t
*
graph
=
NULL
;
ibool
success
;
ulint
err
;
char
*
buf
;
static
const
char
discard_tablespace_proc1
[]
=
static
const
char
discard_tablespace_proc1
[]
=
"PROCEDURE DISCARD_TABLESPACE_PROC () IS
\n
"
"PROCEDURE DISCARD_TABLESPACE_PROC () IS
\n
"
...
@@ -2060,6 +2091,54 @@ row_discard_tablespace_for_mysql(
...
@@ -2060,6 +2091,54 @@ row_discard_tablespace_for_mysql(
goto
funct_exit
;
goto
funct_exit
;
}
}
if
(
table
->
n_foreign_key_checks_running
>
0
)
{
ut_print_timestamp
(
stderr
);
fputs
(
" InnoDB: You are trying to DISCARD table "
,
stderr
);
ut_print_name
(
stderr
,
trx
,
table
->
name
);
fputs
(
"
\n
"
"InnoDB: though there is a foreign key check running on it.
\n
"
"InnoDB: Cannot discard the table.
\n
"
,
stderr
);
err
=
DB_ERROR
;
goto
funct_exit
;
}
/* Check if the table is referenced by foreign key constraints from
some other table (not the table itself) */
foreign
=
UT_LIST_GET_FIRST
(
table
->
referenced_list
);
while
(
foreign
&&
foreign
->
foreign_table
==
table
)
{
foreign
=
UT_LIST_GET_NEXT
(
referenced_list
,
foreign
);
}
if
(
foreign
&&
trx
->
check_foreigns
)
{
FILE
*
ef
=
dict_foreign_err_file
;
/* We only allow discarding a referenced table if
FOREIGN_KEY_CHECKS is set to 0 */
err
=
DB_CANNOT_DROP_CONSTRAINT
;
mutex_enter
(
&
dict_foreign_err_mutex
);
rewind
(
ef
);
ut_print_timestamp
(
ef
);
fputs
(
" Cannot drop table "
,
ef
);
ut_print_name
(
ef
,
trx
,
name
);
fputs
(
"
\n
"
"because it is referenced by "
,
ef
);
ut_print_name
(
ef
,
trx
,
foreign
->
foreign_table_name
);
putc
(
'\n'
,
ef
);
mutex_exit
(
&
dict_foreign_err_mutex
);
goto
funct_exit
;
}
new_id
=
dict_hdr_get_new_id
(
DICT_HDR_TABLE_ID
);
new_id
=
dict_hdr_get_new_id
(
DICT_HDR_TABLE_ID
);
buf
=
mem_alloc
((
sizeof
discard_tablespace_proc1
)
+
buf
=
mem_alloc
((
sizeof
discard_tablespace_proc1
)
+
...
@@ -2077,6 +2156,10 @@ row_discard_tablespace_for_mysql(
...
@@ -2077,6 +2156,10 @@ row_discard_tablespace_for_mysql(
ut_a
(
graph
);
ut_a
(
graph
);
/* Remove any locks there are on the table or its records */
lock_reset_all_on_table
(
table
);
graph
->
trx
=
trx
;
graph
->
trx
=
trx
;
trx
->
graph
=
NULL
;
trx
->
graph
=
NULL
;
...
@@ -2227,8 +2310,8 @@ row_import_tablespace_for_mysql(
...
@@ -2227,8 +2310,8 @@ row_import_tablespace_for_mysql(
ibuf_delete_for_discarded_space
(
table
->
space
);
ibuf_delete_for_discarded_space
(
table
->
space
);
success
=
fil_open_single_table_tablespace
(
table
->
space
,
table
->
name
);
success
=
fil_open_single_table_tablespace
(
TRUE
,
table
->
space
,
table
->
name
);
if
(
success
)
{
if
(
success
)
{
table
->
ibd_file_missing
=
FALSE
;
table
->
ibd_file_missing
=
FALSE
;
table
->
tablespace_discarded
=
FALSE
;
table
->
tablespace_discarded
=
FALSE
;
...
@@ -2236,7 +2319,7 @@ row_import_tablespace_for_mysql(
...
@@ -2236,7 +2319,7 @@ row_import_tablespace_for_mysql(
if
(
table
->
ibd_file_missing
)
{
if
(
table
->
ibd_file_missing
)
{
ut_print_timestamp
(
stderr
);
ut_print_timestamp
(
stderr
);
fputs
(
fputs
(
" InnoDB: cannot find o
f
open in the database directory the .ibd file of
\n
"
" InnoDB: cannot find o
r
open in the database directory the .ibd file of
\n
"
"InnoDB: table "
,
stderr
);
"InnoDB: table "
,
stderr
);
ut_print_name
(
stderr
,
trx
,
name
);
ut_print_name
(
stderr
,
trx
,
name
);
fputs
(
"
\n
"
fputs
(
"
\n
"
...
@@ -3284,6 +3367,20 @@ row_check_table_for_mysql(
...
@@ -3284,6 +3367,20 @@ row_check_table_for_mysql(
ulint
ret
=
DB_SUCCESS
;
ulint
ret
=
DB_SUCCESS
;
ulint
old_isolation_level
;
ulint
old_isolation_level
;
if
(
prebuilt
->
table
->
ibd_file_missing
)
{
ut_print_timestamp
(
stderr
);
fprintf
(
stderr
,
" InnoDB: Error:
\n
"
"InnoDB: MySQL is trying to use a table handle but the .ibd file for
\n
"
"InnoDB: table %s does not exist.
\n
"
"InnoDB: Have you deleted the .ibd file from the database directory under
\n
"
"InnoDB: the MySQL datadir, or have you used DISCARD TABLESPACE?
\n
"
"InnoDB: Look from
\n
"
"http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html
\n
"
"InnoDB: how you can resolve the problem.
\n
"
,
prebuilt
->
table
->
name
);
return
(
DB_ERROR
);
}
prebuilt
->
trx
->
op_info
=
"checking table"
;
prebuilt
->
trx
->
op_info
=
"checking table"
;
old_isolation_level
=
prebuilt
->
trx
->
isolation_level
;
old_isolation_level
=
prebuilt
->
trx
->
isolation_level
;
...
...
innobase/row/row0sel.c
View file @
0e28bb07
...
@@ -2776,7 +2776,7 @@ row_search_for_mysql(
...
@@ -2776,7 +2776,7 @@ row_search_for_mysql(
/* out: DB_SUCCESS,
/* out: DB_SUCCESS,
DB_RECORD_NOT_FOUND,
DB_RECORD_NOT_FOUND,
DB_END_OF_INDEX, DB_DEADLOCK,
DB_END_OF_INDEX, DB_DEADLOCK,
DB_LOCK_TABLE_FULL,
DB_LOCK_TABLE_FULL,
DB_CORRUPTION,
or DB_TOO_BIG_RECORD */
or DB_TOO_BIG_RECORD */
byte
*
buf
,
/* in/out: buffer for the fetched
byte
*
buf
,
/* in/out: buffer for the fetched
row in the MySQL format */
row in the MySQL format */
...
@@ -2828,7 +2828,21 @@ row_search_for_mysql(
...
@@ -2828,7 +2828,21 @@ row_search_for_mysql(
ut_ad
(
index
&&
pcur
&&
search_tuple
);
ut_ad
(
index
&&
pcur
&&
search_tuple
);
ut_ad
(
trx
->
mysql_thread_id
==
os_thread_get_curr_id
());
ut_ad
(
trx
->
mysql_thread_id
==
os_thread_get_curr_id
());
if
(
prebuilt
->
table
->
ibd_file_missing
)
{
ut_print_timestamp
(
stderr
);
fprintf
(
stderr
,
" InnoDB: Error:
\n
"
"InnoDB: MySQL is trying to use a table handle but the .ibd file for
\n
"
"InnoDB: table %s does not exist.
\n
"
"InnoDB: Have you deleted the .ibd file from the database directory under
\n
"
"InnoDB: the MySQL datadir, or have you used DISCARD TABLESPACE?
\n
"
"InnoDB: Look from
\n
"
"http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html
\n
"
"InnoDB: how you can resolve the problem.
\n
"
,
prebuilt
->
table
->
name
);
return
(
DB_ERROR
);
}
if
(
prebuilt
->
magic_n
!=
ROW_PREBUILT_ALLOCATED
)
{
if
(
prebuilt
->
magic_n
!=
ROW_PREBUILT_ALLOCATED
)
{
fprintf
(
stderr
,
fprintf
(
stderr
,
"InnoDB: Error: trying to free a corrupt
\n
"
"InnoDB: Error: trying to free a corrupt
\n
"
...
...
innobase/srv/srv0start.c
View file @
0e28bb07
...
@@ -1378,14 +1378,39 @@ NetWare. */
...
@@ -1378,14 +1378,39 @@ NetWare. */
return
(
DB_ERROR
);
return
(
DB_ERROR
);
}
}
/* Since ibuf init is in dict_boot, and ibuf is needed
/* Since the insert buffer init is in dict_boot, and the
in any disk i/o, first call dict_boot */
insert buffer is needed in any disk i/o, first we call
dict_boot(). Note that trx_sys_init_at_db_start() only needs
to access space 0, and the insert buffer at this stage already
works for space 0. */
dict_boot
();
dict_boot
();
trx_sys_init_at_db_start
();
trx_sys_init_at_db_start
();
/* The following needs trx lists which are initialized in
if
(
srv_force_recovery
<
SRV_FORCE_NO_IBUF_MERGE
)
{
trx_sys_init_at_db_start */
/* The following call is necessary for the insert
buffer to work with multiple tablespaces. We must
know the mapping between space id's and .ibd file
names.
In a crash recovery, we check that the info in data
dictionary is consistent with what we already know
about space id's from the call of
fil_load_single_table_tablespaces().
In a normal startup, we create the space objects for
every table in the InnoDB data dictionary that has
an .ibd file.
We also determine the maximum tablespace id used.
TODO: We may have incomplete transactions in the
data dictionary tables. Does that harm the scanning of
the data dictionary below? */
dict_check_tablespaces_and_store_max_id
(
recv_needed_recovery
);
}
srv_startup_is_before_trx_rollback_phase
=
FALSE
;
srv_startup_is_before_trx_rollback_phase
=
FALSE
;
...
@@ -1393,6 +1418,9 @@ NetWare. */
...
@@ -1393,6 +1418,9 @@ NetWare. */
system */
system */
fsp_header_get_free_limit
(
0
);
fsp_header_get_free_limit
(
0
);
/* recv_recovery_from_checkpoint_finish needs trx lists which
are initialized in trx_sys_init_at_db_start(). */
recv_recovery_from_checkpoint_finish
();
recv_recovery_from_checkpoint_finish
();
}
}
...
@@ -1433,13 +1461,6 @@ NetWare. */
...
@@ -1433,13 +1461,6 @@ NetWare. */
}
}
}
}
#endif
/* UNIV_LOG_ARCHIVE */
#endif
/* UNIV_LOG_ARCHIVE */
if
(
!
create_new_db
&&
srv_force_recovery
==
0
)
{
/* After a crash recovery we only check that the info in data
dictionary is consistent with what we already know about space
id's from the call of fil_load_single_table_tablespaces(). */
dict_check_tablespaces_or_store_max_id
(
recv_needed_recovery
);
}
if
(
srv_measure_contention
)
{
if
(
srv_measure_contention
)
{
/* os_thread_create(&test_measure_cont, NULL, thread_ids +
/* os_thread_create(&test_measure_cont, NULL, thread_ids +
...
...
innobase/trx/trx0trx.c
View file @
0e28bb07
...
@@ -109,6 +109,9 @@ trx_create(
...
@@ -109,6 +109,9 @@ trx_create(
trx
->
mysql_log_offset
=
0
;
trx
->
mysql_log_offset
=
0
;
trx
->
mysql_master_log_file_name
=
""
;
trx
->
mysql_master_log_file_name
=
""
;
trx
->
mysql_master_log_pos
=
0
;
trx
->
mysql_master_log_pos
=
0
;
trx
->
repl_wait_binlog_name
=
NULL
;
trx
->
repl_wait_binlog_pos
=
0
;
mutex_create
(
&
(
trx
->
undo_mutex
));
mutex_create
(
&
(
trx
->
undo_mutex
));
mutex_set_level
(
&
(
trx
->
undo_mutex
),
SYNC_TRX_UNDO
);
mutex_set_level
(
&
(
trx
->
undo_mutex
),
SYNC_TRX_UNDO
);
...
@@ -271,6 +274,11 @@ trx_free(
...
@@ -271,6 +274,11 @@ trx_free(
trx_undo_arr_free
(
trx
->
undo_no_arr
);
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
->
signals
)
==
0
);
ut_a
(
UT_LIST_GET_LEN
(
trx
->
reply_signals
)
==
0
);
ut_a
(
UT_LIST_GET_LEN
(
trx
->
reply_signals
)
==
0
);
...
...
sql/ha_innodb.cc
View file @
0e28bb07
...
@@ -4977,7 +4977,7 @@ the SQL statement in case of an error. */
...
@@ -4977,7 +4977,7 @@ the SQL statement in case of an error. */
int
int
ha_innobase
::
external_lock
(
ha_innobase
::
external_lock
(
/*=======================*/
/*=======================*/
/* out: 0 */
/* out: 0
or HA_ERR_CRASHED
*/
THD
*
thd
,
/* in: handle to the user thread */
THD
*
thd
,
/* in: handle to the user thread */
int
lock_type
)
/* in: lock type */
int
lock_type
)
/* in: lock type */
{
{
...
@@ -4989,19 +4989,6 @@ ha_innobase::external_lock(
...
@@ -4989,19 +4989,6 @@ ha_innobase::external_lock(
update_thd
(
thd
);
update_thd
(
thd
);
if
(
prebuilt
->
table
->
ibd_file_missing
&&
!
current_thd
->
tablespace_op
)
{
ut_print_timestamp
(
stderr
);
fprintf
(
stderr
,
" InnoDB error:
\n
"
"MySQL is trying to use a table handle but the .ibd file for
\n
"
"table %s does not exist.
\n
"
"Have you deleted the .ibd file from the database directory under
\n
"
"the MySQL datadir, or have you used DISCARD TABLESPACE?
\n
"
"Look from section 15.1 of http://www.innodb.com/ibman.html
\n
"
"how you can resolve the problem.
\n
"
,
prebuilt
->
table
->
name
);
DBUG_RETURN
(
HA_ERR_CRASHED
);
}
trx
=
prebuilt
->
trx
;
trx
=
prebuilt
->
trx
;
prebuilt
->
sql_stat_start
=
TRUE
;
prebuilt
->
sql_stat_start
=
TRUE
;
...
...
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