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
b43a345c
Commit
b43a345c
authored
Jan 14, 2005
by
unknown
Browse files
Options
Browse Files
Download
Plain Diff
Merge gbichot@bk-internal.mysql.com:/home/bk/mysql-5.0
into mysql.com:/home/mysql_src/mysql-5.0-clean
parents
6468de3d
4db9aaee
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
486 additions
and
38 deletions
+486
-38
innobase/dict/dict0boot.c
innobase/dict/dict0boot.c
+19
-15
innobase/dict/dict0crea.c
innobase/dict/dict0crea.c
+102
-7
innobase/dict/dict0dict.c
innobase/dict/dict0dict.c
+6
-7
innobase/dict/dict0load.c
innobase/dict/dict0load.c
+1
-3
innobase/ibuf/ibuf0ibuf.c
innobase/ibuf/ibuf0ibuf.c
+1
-3
innobase/include/dict0boot.h
innobase/include/dict0boot.h
+1
-0
innobase/include/dict0crea.h
innobase/include/dict0crea.h
+12
-0
innobase/include/dict0dict.h
innobase/include/dict0dict.h
+4
-2
innobase/include/dict0mem.h
innobase/include/dict0mem.h
+0
-1
innobase/include/row0mysql.h
innobase/include/row0mysql.h
+9
-0
innobase/row/row0mysql.c
innobase/row/row0mysql.c
+288
-0
sql/ha_innodb.cc
sql/ha_innodb.cc
+42
-0
sql/ha_innodb.h
sql/ha_innodb.h
+1
-0
No files found.
innobase/dict/dict0boot.c
View file @
b43a345c
...
...
@@ -223,6 +223,7 @@ dict_boot(void)
dict_index_t
*
index
;
dict_hdr_t
*
dict_hdr
;
mtr_t
mtr
;
ibool
success
;
mtr_start
(
&
mtr
);
...
...
@@ -275,20 +276,20 @@ dict_boot(void)
dict_mem_index_add_field
(
index
,
"NAME"
,
0
,
0
);
index
->
page_no
=
mtr_read_ulint
(
dict_hdr
+
DICT_HDR_TABLES
,
MLOG_4BYTES
,
&
mtr
);
index
->
id
=
DICT_TABLES_ID
;
ut_a
(
dict_index_add_to_cache
(
table
,
index
));
success
=
dict_index_add_to_cache
(
table
,
index
,
mtr_read_ulint
(
dict_hdr
+
DICT_HDR_TABLES
,
MLOG_4BYTES
,
&
mtr
));
ut_a
(
success
);
/*-------------------------*/
index
=
dict_mem_index_create
(
"SYS_TABLES"
,
"ID_IND"
,
DICT_HDR_SPACE
,
DICT_UNIQUE
,
1
);
dict_mem_index_add_field
(
index
,
"ID"
,
0
,
0
);
index
->
page_no
=
mtr_read_ulint
(
dict_hdr
+
DICT_HDR_TABLE_IDS
,
MLOG_4BYTES
,
&
mtr
);
index
->
id
=
DICT_TABLE_IDS_ID
;
ut_a
(
dict_index_add_to_cache
(
table
,
index
));
success
=
dict_index_add_to_cache
(
table
,
index
,
mtr_read_ulint
(
dict_hdr
+
DICT_HDR_TABLE_IDS
,
MLOG_4BYTES
,
&
mtr
));
ut_a
(
success
);
/*-------------------------*/
table
=
dict_mem_table_create
(
"SYS_COLUMNS"
,
DICT_HDR_SPACE
,
7
,
FALSE
);
...
...
@@ -311,10 +312,10 @@ dict_boot(void)
dict_mem_index_add_field
(
index
,
"TABLE_ID"
,
0
,
0
);
dict_mem_index_add_field
(
index
,
"POS"
,
0
,
0
);
index
->
page_no
=
mtr_read_ulint
(
dict_hdr
+
DICT_HDR_COLUMNS
,
MLOG_4BYTES
,
&
mtr
);
index
->
id
=
DICT_COLUMNS_ID
;
ut_a
(
dict_index_add_to_cache
(
table
,
index
));
success
=
dict_index_add_to_cache
(
table
,
index
,
mtr_read_ulint
(
dict_hdr
+
DICT_HDR_COLUMNS
,
MLOG_4BYTES
,
&
mtr
));
ut_a
(
success
);
/*-------------------------*/
table
=
dict_mem_table_create
(
"SYS_INDEXES"
,
DICT_HDR_SPACE
,
7
,
FALSE
);
...
...
@@ -332,6 +333,9 @@ dict_boot(void)
#endif
#if DICT_SYS_INDEXES_SPACE_NO_FIELD != 5 + 2
#error "DICT_SYS_INDEXES_SPACE_NO_FIELD != 5 + 2"
#endif
#if DICT_SYS_INDEXES_TYPE_FIELD != 4 + 2
#error "DICT_SYS_INDEXES_TYPE_FIELD != 4 + 2"
#endif
table
->
id
=
DICT_INDEXES_ID
;
...
...
@@ -344,10 +348,10 @@ dict_boot(void)
dict_mem_index_add_field
(
index
,
"TABLE_ID"
,
0
,
0
);
dict_mem_index_add_field
(
index
,
"ID"
,
0
,
0
);
index
->
page_no
=
mtr_read_ulint
(
dict_hdr
+
DICT_HDR_INDEXES
,
MLOG_4BYTES
,
&
mtr
);
index
->
id
=
DICT_INDEXES_ID
;
ut_a
(
dict_index_add_to_cache
(
table
,
index
));
success
=
dict_index_add_to_cache
(
table
,
index
,
mtr_read_ulint
(
dict_hdr
+
DICT_HDR_INDEXES
,
MLOG_4BYTES
,
&
mtr
));
ut_a
(
success
);
/*-------------------------*/
table
=
dict_mem_table_create
(
"SYS_FIELDS"
,
DICT_HDR_SPACE
,
3
,
FALSE
);
...
...
@@ -365,10 +369,10 @@ dict_boot(void)
dict_mem_index_add_field
(
index
,
"INDEX_ID"
,
0
,
0
);
dict_mem_index_add_field
(
index
,
"POS"
,
0
,
0
);
index
->
page_no
=
mtr_read_ulint
(
dict_hdr
+
DICT_HDR_FIELDS
,
MLOG_4BYTES
,
&
mtr
);
index
->
id
=
DICT_FIELDS_ID
;
ut_a
(
dict_index_add_to_cache
(
table
,
index
));
success
=
dict_index_add_to_cache
(
table
,
index
,
mtr_read_ulint
(
dict_hdr
+
DICT_HDR_FIELDS
,
MLOG_4BYTES
,
&
mtr
));
ut_a
(
success
);
mtr_commit
(
&
mtr
);
/*-------------------------*/
...
...
innobase/dict/dict0crea.c
View file @
b43a345c
...
...
@@ -544,9 +544,7 @@ dict_build_index_def_step(
table in the same tablespace */
index
->
space
=
table
->
space
;
index
->
page_no
=
FIL_NULL
;
node
->
page_no
=
FIL_NULL
;
row
=
dict_create_sys_indexes_tuple
(
index
,
node
->
heap
);
node
->
ind_row
=
row
;
...
...
@@ -624,18 +622,18 @@ dict_create_index_tree_step(
btr_pcur_move_to_next_user_rec
(
&
pcur
,
&
mtr
);
index
->
page_no
=
btr_create
(
index
->
type
,
index
->
space
,
index
->
id
,
node
->
page_no
=
btr_create
(
index
->
type
,
index
->
space
,
index
->
id
,
table
->
comp
,
&
mtr
);
/* printf("Created a new index tree in space %lu root page %lu\n",
index->space, index->page_no); */
page_rec_write_index_page_no
(
btr_pcur_get_rec
(
&
pcur
),
DICT_SYS_INDEXES_PAGE_NO_FIELD
,
index
->
page_no
,
&
mtr
);
node
->
page_no
,
&
mtr
);
btr_pcur_close
(
&
pcur
);
mtr_commit
(
&
mtr
);
if
(
index
->
page_no
==
FIL_NULL
)
{
if
(
node
->
page_no
==
FIL_NULL
)
{
return
(
DB_OUT_OF_FILE_SPACE
);
}
...
...
@@ -706,6 +704,101 @@ dict_drop_index_tree(
DICT_SYS_INDEXES_PAGE_NO_FIELD
,
FIL_NULL
,
mtr
);
}
/***********************************************************************
Truncates the index tree associated with a row in SYS_INDEXES table. */
void
dict_truncate_index_tree
(
/*=====================*/
dict_table_t
*
table
,
/* in: the table the index belongs to */
rec_t
*
rec
,
/* in: record in the clustered index of
SYS_INDEXES table */
mtr_t
*
mtr
)
/* in: mtr having the latch
on the record page */
{
ulint
root_page_no
;
ulint
space
;
ulint
type
;
dulint
index_id
;
byte
*
ptr
;
ulint
len
;
ibool
comp
;
dict_index_t
*
index
;
#ifdef UNIV_SYNC_DEBUG
ut_ad
(
mutex_own
(
&
(
dict_sys
->
mutex
)));
#endif
/* UNIV_SYNC_DEBUG */
ut_a
(
!
dict_sys
->
sys_indexes
->
comp
);
ptr
=
rec_get_nth_field_old
(
rec
,
DICT_SYS_INDEXES_PAGE_NO_FIELD
,
&
len
);
ut_ad
(
len
==
4
);
root_page_no
=
mtr_read_ulint
(
ptr
,
MLOG_4BYTES
,
mtr
);
if
(
root_page_no
==
FIL_NULL
)
{
/* The tree has been freed. */
return
;
}
ptr
=
rec_get_nth_field_old
(
rec
,
DICT_SYS_INDEXES_SPACE_NO_FIELD
,
&
len
);
ut_ad
(
len
==
4
);
space
=
mtr_read_ulint
(
ptr
,
MLOG_4BYTES
,
mtr
);
if
(
!
fil_tablespace_exists_in_mem
(
space
))
{
/* It is a single table tablespace and the .ibd file is
missing: do nothing */
return
;
}
ptr
=
rec_get_nth_field_old
(
rec
,
DICT_SYS_INDEXES_TYPE_FIELD
,
&
len
);
ut_ad
(
len
==
4
);
type
=
mach_read_from_4
(
ptr
);
ptr
=
rec_get_nth_field_old
(
rec
,
1
,
&
len
);
ut_ad
(
len
==
8
);
index_id
=
mach_read_from_8
(
ptr
);
/* We free all the pages but the root page first; this operation
may span several mini-transactions */
btr_free_but_not_root
(
space
,
root_page_no
);
/* Then we free the root page in the same mini-transaction where
we create the b-tree and write its new root page number to the
appropriate field in the SYS_INDEXES record: this mini-transaction
marks the B-tree totally truncated */
comp
=
page_is_comp
(
btr_page_get
(
space
,
root_page_no
,
RW_X_LATCH
,
mtr
));
btr_free_root
(
space
,
root_page_no
,
mtr
);
/* Find the index corresponding to this SYS_INDEXES record. */
for
(
index
=
UT_LIST_GET_FIRST
(
table
->
indexes
);
index
;
index
=
UT_LIST_GET_NEXT
(
indexes
,
index
))
{
if
(
!
ut_dulint_cmp
(
index
->
id
,
index_id
))
{
break
;
}
}
root_page_no
=
btr_create
(
type
,
space
,
index_id
,
comp
,
mtr
);
if
(
index
)
{
index
->
tree
->
page
=
root_page_no
;
}
page_rec_write_index_page_no
(
rec
,
DICT_SYS_INDEXES_PAGE_NO_FIELD
,
root_page_no
,
mtr
);
}
/*************************************************************************
Creates a table create graph. */
...
...
@@ -762,6 +855,7 @@ ind_create_graph_create(
node
->
index
=
index
;
node
->
state
=
INDEX_BUILD_INDEX_DEF
;
node
->
page_no
=
FIL_NULL
;
node
->
heap
=
mem_heap_create
(
256
);
node
->
ind_def
=
ins_node_create
(
INS_DIRECT
,
...
...
@@ -981,7 +1075,8 @@ dict_create_index_step(
if
(
node
->
state
==
INDEX_ADD_TO_CACHE
)
{
success
=
dict_index_add_to_cache
(
node
->
table
,
node
->
index
);
success
=
dict_index_add_to_cache
(
node
->
table
,
node
->
index
,
node
->
page_no
);
ut_a
(
success
);
...
...
innobase/dict/dict0dict.c
View file @
b43a345c
...
...
@@ -1374,8 +1374,9 @@ dict_index_add_to_cache(
/*====================*/
/* out: TRUE if success */
dict_table_t
*
table
,
/* in: table on which the index is */
dict_index_t
*
index
)
/* in, own: index; NOTE! The index memory
dict_index_t
*
index
,
/* in, own: index; NOTE! The index memory
object is freed in this function! */
ulint
page_no
)
/* in: root page number of the index */
{
dict_index_t
*
new_index
;
dict_tree_t
*
tree
;
...
...
@@ -1461,10 +1462,9 @@ dict_index_add_to_cache(
tree
=
dict_index_get_tree
(
UT_LIST_GET_FIRST
(
cluster
->
indexes
));
new_index
->
tree
=
tree
;
new_index
->
page_no
=
tree
->
page
;
}
else
{
/* Create an index tree memory object for the index */
tree
=
dict_tree_create
(
new_index
);
tree
=
dict_tree_create
(
new_index
,
page_no
);
ut_ad
(
tree
);
new_index
->
tree
=
tree
;
...
...
@@ -1749,7 +1749,6 @@ dict_index_build_internal_clust(
new_index
->
n_user_defined_cols
=
index
->
n_fields
;
new_index
->
id
=
index
->
id
;
new_index
->
page_no
=
index
->
page_no
;
if
(
table
->
type
!=
DICT_TABLE_ORDINARY
)
{
/* The index is mixed: copy common key prefix fields */
...
...
@@ -1928,7 +1927,6 @@ dict_index_build_internal_non_clust(
new_index
->
n_user_defined_cols
=
index
->
n_fields
;
new_index
->
id
=
index
->
id
;
new_index
->
page_no
=
index
->
page_no
;
/* Copy fields from index to new_index */
dict_index_copy
(
new_index
,
index
,
0
,
index
->
n_fields
);
...
...
@@ -3565,9 +3563,10 @@ dict_tree_t*
dict_tree_create
(
/*=============*/
/* out, own: created tree */
dict_index_t
*
index
)
/* in: the index for which to create: in the
dict_index_t
*
index
,
/* in: the index for which to create: in the
case of a mixed tree, this should be the
index of the cluster object */
ulint
page_no
)
/* in: root page number of the index */
{
dict_tree_t
*
tree
;
...
...
@@ -3577,7 +3576,7 @@ dict_tree_create(
tree
->
type
=
index
->
type
;
tree
->
space
=
index
->
space
;
tree
->
page
=
index
->
page_no
;
tree
->
page
=
page_no
;
tree
->
id
=
index
->
id
;
...
...
innobase/dict/dict0load.c
View file @
b43a345c
...
...
@@ -681,12 +681,10 @@ dict_load_indexes(
}
else
{
index
=
dict_mem_index_create
(
table
->
name
,
name_buf
,
space
,
type
,
n_fields
);
index
->
page_no
=
page_no
;
index
->
id
=
id
;
dict_load_fields
(
table
,
index
,
heap
);
dict_index_add_to_cache
(
table
,
index
);
dict_index_add_to_cache
(
table
,
index
,
page_no
);
}
btr_pcur_move_to_next_user_rec
(
&
pcur
,
&
mtr
);
...
...
innobase/ibuf/ibuf0ibuf.c
View file @
b43a345c
...
...
@@ -548,11 +548,9 @@ ibuf_data_init_for_space(
dict_mem_index_add_field
(
index
,
"PAGE_NO"
,
0
,
0
);
dict_mem_index_add_field
(
index
,
"TYPES"
,
0
,
0
);
index
->
page_no
=
FSP_IBUF_TREE_ROOT_PAGE_NO
;
index
->
id
=
ut_dulint_add
(
DICT_IBUF_ID_MIN
,
space
);
dict_index_add_to_cache
(
table
,
index
);
dict_index_add_to_cache
(
table
,
index
,
FSP_IBUF_TREE_ROOT_PAGE_NO
);
data
->
index
=
dict_table_get_first_index
(
table
);
...
...
innobase/include/dict0boot.h
View file @
b43a345c
...
...
@@ -119,6 +119,7 @@ dict_create(void);
clustered index */
#define DICT_SYS_INDEXES_PAGE_NO_FIELD 8
#define DICT_SYS_INDEXES_SPACE_NO_FIELD 7
#define DICT_SYS_INDEXES_TYPE_FIELD 6
/* When a row id which is zero modulo this number (which must be a power of
two) is assigned, the field DICT_HDR_ROW_ID on the dictionary header page is
...
...
innobase/include/dict0crea.h
View file @
b43a345c
...
...
@@ -54,6 +54,17 @@ dict_create_index_step(
/* out: query thread to run next or NULL */
que_thr_t
*
thr
);
/* in: query thread */
/***********************************************************************
Truncates the index tree associated with a row in SYS_INDEXES table. */
void
dict_truncate_index_tree
(
/*=====================*/
dict_table_t
*
table
,
/* in: the table the index belongs to */
rec_t
*
rec
,
/* in: record in the clustered index of
SYS_INDEXES table */
mtr_t
*
mtr
);
/* in: mtr having the latch
on the record page */
/***********************************************************************
Drops the index tree associated with a row in SYS_INDEXES table. */
void
...
...
@@ -142,6 +153,7 @@ struct ind_node_struct{
/*----------------------*/
/* Local storage for this graph node */
ulint
state
;
/* node execution state */
ulint
page_no
;
/* root page number of the index */
dict_table_t
*
table
;
/* table which owns the index */
dtuple_t
*
ind_row
;
/* index definition row built */
ulint
field_no
;
/* next field definition to insert */
...
...
innobase/include/dict0dict.h
View file @
b43a345c
...
...
@@ -508,8 +508,9 @@ dict_index_add_to_cache(
/*====================*/
/* out: TRUE if success */
dict_table_t
*
table
,
/* in: table on which the index is */
dict_index_t
*
index
);
/* in, own: index; NOTE! The index memory
dict_index_t
*
index
,
/* in, own: index; NOTE! The index memory
object is freed in this function! */
ulint
page_no
);
/* in: root page number of the index */
/************************************************************************
Gets the number of fields in the internal representation of an index,
including fields added by the dictionary system. */
...
...
@@ -686,9 +687,10 @@ dict_tree_t*
dict_tree_create
(
/*=============*/
/* out, own: created tree */
dict_index_t
*
index
);
/* in: the index for which to create: in the
dict_index_t
*
index
,
/* in: the index for which to create: in the
case of a mixed tree, this should be the
index of the cluster object */
ulint
page_no
);
/* in: root page number of the index */
/**************************************************************************
Frees an index tree struct. */
...
...
innobase/include/dict0mem.h
View file @
b43a345c
...
...
@@ -218,7 +218,6 @@ struct dict_index_struct{
const
char
*
table_name
;
/* table name */
dict_table_t
*
table
;
/* back pointer to table */
ulint
space
;
/* space where the index tree is placed */
ulint
page_no
;
/* page number of the index tree root */
ulint
trx_id_offset
;
/* position of the the trx id column
in a clustered index record, if the fields
before it are known to be of a fixed size,
...
...
innobase/include/row0mysql.h
View file @
b43a345c
...
...
@@ -363,6 +363,15 @@ row_get_background_drop_list_len_low(void);
/*======================================*/
/* out: how many tables in list */
/*************************************************************************
Truncates a table for MySQL. */
int
row_truncate_table_for_mysql
(
/*=========================*/
/* out: error code or DB_SUCCESS */
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
output by the master thread. */
...
...
innobase/row/row0mysql.c
View file @
b43a345c
...
...
@@ -2421,6 +2421,294 @@ funct_exit:
return
((
int
)
err
);
}
/*************************************************************************
Truncates a table for MySQL. */
int
row_truncate_table_for_mysql
(
/*=========================*/
/* out: error code or DB_SUCCESS */
dict_table_t
*
table
,
/* in: table handle */
trx_t
*
trx
)
/* in: transaction handle */
{
dict_foreign_t
*
foreign
;
ulint
err
;
ibool
locked_dictionary
=
FALSE
;
mem_heap_t
*
heap
;
byte
*
buf
;
dtuple_t
*
tuple
;
dfield_t
*
dfield
;
dict_index_t
*
sys_index
;
btr_pcur_t
pcur
;
mtr_t
mtr
;
dulint
new_id
;
char
*
sql
;
que_thr_t
*
thr
;
que_t
*
graph
=
NULL
;
/* 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 TRUNCATE TABLE. 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: TRUNCATE TABLE is analogous to DROP TABLE, so we do not
have to remove insert buffer records, as the insert buffer works at a low
level. If a freed page is later reallocated, the allocator will remove
the ibuf entries for it.
TODO: when we truncate *.ibd files (analogous to DISCARD TABLESPACE), we
will have to remove we remove all entries for the table in the insert
buffer tree!
4) Linear readahead and random readahead: we use the same method as in 3) to
discard ongoing operations. (This will only be relevant for TRUNCATE TABLE
by DISCARD TABLESPACE.)
5) FOREIGN KEY operations: if table->n_foreign_key_checks_running > 0, we
do not allow the TRUNCATE. We also reserve the data dictionary latch. */
static
const
char
renumber_tablespace_proc
[]
=
"PROCEDURE RENUMBER_TABLESPACE_PROC () IS
\n
"
"old_id CHAR;
\n
"
"new_id CHAR;
\n
"
"old_id_low INT;
\n
"
"old_id_high INT;
\n
"
"new_id_low INT;
\n
"
"new_id_high INT;
\n
"
"BEGIN
\n
"
"old_id_high := %lu;
\n
"
"old_id_low := %lu;
\n
"
"new_id_high := %lu;
\n
"
"new_id_low := %lu;
\n
"
"old_id := CONCAT(TO_BINARY(old_id_high, 4), TO_BINARY(old_id_low, 4));
\n
"
"new_id := CONCAT(TO_BINARY(new_id_high, 4), TO_BINARY(new_id_low, 4));
\n
"
"UPDATE SYS_TABLES SET ID = new_id
\n
"
"WHERE ID = old_id;
\n
"
"UPDATE SYS_COLUMNS SET TABLE_ID = new_id
\n
"
"WHERE TABLE_ID = old_id;
\n
"
"UPDATE SYS_INDEXES SET TABLE_ID = new_id
\n
"
"WHERE TABLE_ID = old_id;
\n
"
"COMMIT WORK;
\n
"
"END;
\n
"
;
ut_ad
(
trx
->
mysql_thread_id
==
os_thread_get_curr_id
());
ut_ad
(
table
);
if
(
srv_created_new_raw
)
{
fputs
(
"InnoDB: A new raw disk partition was initialized or
\n
"
"InnoDB: innodb_force_recovery is on: we do not allow
\n
"
"InnoDB: database modifications by the user. Shut down
\n
"
"InnoDB: mysqld and edit my.cnf so that newraw is replaced
\n
"
"InnoDB: with raw, and innodb_force_... is removed.
\n
"
,
stderr
);
return
(
DB_ERROR
);
}
trx
->
op_info
=
"truncating table"
;
trx_start_if_not_started
(
trx
);
/* Serialize data dictionary operations with dictionary mutex:
no deadlocks can occur then in these operations */
if
(
trx
->
dict_operation_lock_mode
!=
RW_X_LATCH
)
{
/* Prevent foreign key checks etc. while we are truncating the
table */
row_mysql_lock_data_dictionary
(
trx
);
locked_dictionary
=
TRUE
;
}
#ifdef UNIV_SYNC_DEBUG
ut_ad
(
mutex_own
(
&
(
dict_sys
->
mutex
)));
ut_ad
(
rw_lock_own
(
&
dict_operation_lock
,
RW_LOCK_EX
));
#endif
/* UNIV_SYNC_DEBUG */
/* 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 truncating a referenced table if
FOREIGN_KEY_CHECKS is set to 0 */
mutex_enter
(
&
dict_foreign_err_mutex
);
rewind
(
ef
);
ut_print_timestamp
(
ef
);
fputs
(
" Cannot truncate table "
,
ef
);
ut_print_name
(
ef
,
trx
,
table
->
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
);
err
=
DB_ERROR
;
goto
funct_exit
;
}
if
(
table
->
n_mysql_handles_opened
>
1
)
{
ut_print_timestamp
(
stderr
);
fputs
(
" InnoDB: Warning: MySQL is trying to truncate table "
,
stderr
);
ut_print_name
(
stderr
,
trx
,
table
->
name
);
fputs
(
"
\n
"
"InnoDB: though there are still open handles to it.
\n
"
,
stderr
);
err
=
DB_ERROR
;
goto
funct_exit
;
}
/* TODO: could we replace the counter n_foreign_key_checks_running
with lock checks on the table? Acquire here an exclusive lock on the
table, and rewrite lock0lock.c and the lock wait in srv0srv.c so that
they can cope with the table having been truncated here? Foreign key
checks take an IS or IX lock on the table. */
if
(
table
->
n_foreign_key_checks_running
>
0
)
{
ut_print_timestamp
(
stderr
);
fputs
(
" InnoDB: You are trying to truncate table "
,
stderr
);
ut_print_name
(
stderr
,
trx
,
table
->
name
);
fputs
(
"
\n
"
"InnoDB: though there is a foreign key check running on it.
\n
"
,
stderr
);
err
=
DB_ERROR
;
goto
funct_exit
;
}
/* Remove any locks there are on the table or its records */
lock_reset_all_on_table
(
table
);
trx
->
dict_operation
=
TRUE
;
trx
->
table_id
=
table
->
id
;
/* scan SYS_INDEXES for all indexes of the table */
heap
=
mem_heap_create
(
800
);
tuple
=
dtuple_create
(
heap
,
1
);
dfield
=
dtuple_get_nth_field
(
tuple
,
0
);
buf
=
mem_heap_alloc
(
heap
,
8
);
mach_write_to_8
(
buf
,
table
->
id
);
dfield_set_data
(
dfield
,
buf
,
8
);
sys_index
=
dict_table_get_first_index
(
dict_sys
->
sys_indexes
);
dict_index_copy_types
(
tuple
,
sys_index
,
1
);
mtr_start
(
&
mtr
);
btr_pcur_open_on_user_rec
(
sys_index
,
tuple
,
PAGE_CUR_GE
,
BTR_MODIFY_LEAF
,
&
pcur
,
&
mtr
);
for
(;;)
{
rec_t
*
rec
;
const
byte
*
field
;
ulint
len
;
if
(
!
btr_pcur_is_on_user_rec
(
&
pcur
,
&
mtr
))
{
/* The end of SYS_INDEXES has been reached. */
break
;
}
rec
=
btr_pcur_get_rec
(
&
pcur
);
field
=
rec_get_nth_field_old
(
rec
,
0
,
&
len
);
ut_ad
(
len
==
8
);
if
(
memcmp
(
buf
,
field
,
len
)
!=
0
)
{
/* End of indexes for the table (TABLE_ID mismatch). */
break
;
}
if
(
rec_get_deleted_flag
(
rec
,
FALSE
))
{
/* The index has been dropped. */
continue
;
}
dict_truncate_index_tree
(
table
,
rec
,
&
mtr
);
btr_pcur_move_to_next_user_rec
(
&
pcur
,
&
mtr
);
}
btr_pcur_close
(
&
pcur
);
mtr_commit
(
&
mtr
);
new_id
=
dict_hdr_get_new_id
(
DICT_HDR_TABLE_ID
);
mem_heap_empty
(
heap
);
sql
=
mem_heap_alloc
(
heap
,
(
sizeof
renumber_tablespace_proc
)
+
40
);
sprintf
(
sql
,
renumber_tablespace_proc
,
(
ulong
)
ut_dulint_get_high
(
table
->
id
),
(
ulong
)
ut_dulint_get_low
(
table
->
id
),
(
ulong
)
ut_dulint_get_high
(
new_id
),
(
ulong
)
ut_dulint_get_low
(
new_id
));
graph
=
pars_sql
(
sql
);
ut_a
(
graph
);
mem_heap_free
(
heap
);
graph
->
trx
=
trx
;
trx
->
graph
=
NULL
;
graph
->
fork_type
=
QUE_FORK_MYSQL_INTERFACE
;
thr
=
que_fork_start_command
(
graph
);
ut_a
(
thr
);
que_run_threads
(
thr
);
que_graph_free
(
graph
);
err
=
trx
->
error_state
;
if
(
err
!=
DB_SUCCESS
)
{
trx
->
error_state
=
DB_SUCCESS
;
trx_general_rollback_for_mysql
(
trx
,
FALSE
,
NULL
);
trx
->
error_state
=
DB_SUCCESS
;
ut_print_timestamp
(
stderr
);
fputs
(
" InnoDB: Unable to assign a new identifier to table "
,
stderr
);
ut_print_name
(
stderr
,
trx
,
table
->
name
);
fputs
(
"
\n
"
"InnoDB: after truncating it. Background processes may corrupt the table!
\n
"
,
stderr
);
err
=
DB_ERROR
;
}
else
{
dict_table_change_id_in_cache
(
table
,
new_id
);
}
dict_table_autoinc_initialize
(
table
,
0
);
dict_update_statistics
(
table
);
trx_commit_for_mysql
(
trx
);
funct_exit:
if
(
locked_dictionary
)
{
row_mysql_unlock_data_dictionary
(
trx
);
}
trx
->
op_info
=
""
;
srv_wake_master_thread
();
return
((
int
)
err
);
}
/*************************************************************************
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
...
...
sql/ha_innodb.cc
View file @
b43a345c
...
...
@@ -4091,6 +4091,48 @@ ha_innobase::discard_or_import_tablespace(
DBUG_RETURN
(
err
);
}
/*********************************************************************
Deletes all rows of an InnoDB table. */
int
ha_innobase
::
delete_all_rows
(
void
)
/*==============================*/
/* out: error number */
{
row_prebuilt_t
*
prebuilt
=
(
row_prebuilt_t
*
)
innobase_prebuilt
;
int
error
;
trx_t
*
trx
;
THD
*
thd
=
current_thd
;
DBUG_ENTER
(
"ha_innobase::delete_all_rows"
);
if
(
thd
->
lex
->
sql_command
!=
SQLCOM_TRUNCATE
)
{
fallback:
/* We only handle TRUNCATE TABLE t as a special case.
DELETE FROM t will have to use ha_innobase::delete_row(). */
DBUG_RETURN
(
my_errno
=
HA_ERR_WRONG_COMMAND
);
}
/* Get the transaction associated with the current thd, or create one
if not yet created */
trx
=
check_trx_exists
(
thd
);
/* Truncate the table in InnoDB */
error
=
row_truncate_table_for_mysql
(
prebuilt
->
table
,
trx
);
if
(
error
==
DB_ERROR
)
{
/* Cannot truncate; resort to ha_innobase::delete_row() */
goto
fallback
;
}
innobase_commit_low
(
trx
);
error
=
convert_error_code_to_mysql
(
error
,
NULL
);
DBUG_RETURN
(
error
);
}
/*********************************************************************
Drops a table from an InnoDB database. Before calling this function,
MySQL calls innobase_commit to commit the transaction of the current user.
...
...
sql/ha_innodb.h
View file @
b43a345c
...
...
@@ -159,6 +159,7 @@ class ha_innobase: public handler
int
create
(
const
char
*
name
,
register
TABLE
*
form
,
HA_CREATE_INFO
*
create_info
);
int
delete_all_rows
();
int
delete_table
(
const
char
*
name
);
int
rename_table
(
const
char
*
from
,
const
char
*
to
);
int
check
(
THD
*
thd
,
HA_CHECK_OPT
*
check_opt
);
...
...
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