mirror of
https://github.com/MariaDB/server.git
synced 2025-12-09 08:01:34 +03:00
branches/zip: Merge revisions 465:532 from trunk.
This commit is contained in:
106
Makefile.am
106
Makefile.am
@@ -26,57 +26,65 @@ SUBDIRS = os ut btr buf data dict dyn eval fil fsp fut \
|
||||
ha ibuf lock log mach mem mtr page \
|
||||
pars que read rem row srv sync thr trx usr
|
||||
|
||||
EXTRA_DIST = include/btr0btr.h include/btr0btr.ic include/btr0cur.h include/btr0cur.ic \
|
||||
include/btr0pcur.h include/btr0pcur.ic include/btr0sea.h include/btr0sea.ic \
|
||||
include/btr0types.h \
|
||||
include/buf0buf.h include/buf0buf.ic include/buf0flu.h include/buf0flu.ic \
|
||||
include/buf0lru.h include/buf0lru.ic include/buf0rea.h include/buf0types.h \
|
||||
include/data0data.h include/data0data.ic include/data0type.h include/data0type.ic \
|
||||
include/data0types.h include/db0err.h \
|
||||
include/dict0boot.h include/dict0boot.ic include/dict0crea.h include/dict0crea.ic \
|
||||
include/dict0dict.h include/dict0dict.ic include/dict0load.h include/dict0load.ic \
|
||||
include/dict0mem.h include/dict0mem.ic include/dict0types.h \
|
||||
include/dyn0dyn.h include/dyn0dyn.ic \
|
||||
include/eval0eval.h include/eval0eval.ic include/eval0proc.h include/eval0proc.ic \
|
||||
include/fil0fil.h include/fsp0fsp.h include/fsp0fsp.ic \
|
||||
include/fut0fut.h include/fut0fut.ic include/fut0lst.h include/fut0lst.ic \
|
||||
include/ha0ha.h include/ha0ha.ic include/hash0hash.h include/hash0hash.ic \
|
||||
EXTRA_DIST = include/btr0btr.h include/btr0btr.ic include/btr0cur.h \
|
||||
include/btr0cur.ic include/btr0pcur.h include/btr0pcur.ic \
|
||||
include/btr0sea.h include/btr0sea.ic include/btr0types.h \
|
||||
include/buf0buf.h include/buf0buf.ic include/buf0flu.h \
|
||||
include/buf0flu.ic include/buf0lru.h include/buf0lru.ic \
|
||||
include/buf0rea.h include/buf0types.h include/data0data.h \
|
||||
include/data0data.ic include/data0type.h include/data0type.ic \
|
||||
include/data0types.h include/db0err.h include/dict0boot.h \
|
||||
include/dict0boot.ic include/dict0crea.h include/dict0crea.ic \
|
||||
include/dict0dict.h include/dict0dict.ic include/dict0load.h \
|
||||
include/dict0load.ic include/dict0mem.h include/dict0mem.ic \
|
||||
include/dict0types.h include/dyn0dyn.h include/dyn0dyn.ic \
|
||||
include/eval0eval.h include/eval0eval.ic include/eval0proc.h \
|
||||
include/eval0proc.ic include/fil0fil.h include/fsp0fsp.h \
|
||||
include/fsp0fsp.ic include/fut0fut.h include/fut0fut.ic \
|
||||
include/fut0lst.h include/fut0lst.ic include/ha0ha.h \
|
||||
include/ha0ha.ic include/hash0hash.h include/hash0hash.ic \
|
||||
include/ibuf0ibuf.h include/ibuf0ibuf.ic include/ibuf0types.h \
|
||||
include/lock0lock.h include/lock0lock.ic include/lock0types.h \
|
||||
include/log0log.h include/log0log.ic include/log0recv.h include/log0recv.ic \
|
||||
include/mach0data.h include/mach0data.ic include/mem0dbg.h include/mem0dbg.ic \
|
||||
include/mem0mem.h include/mem0mem.ic include/mem0pool.h include/mem0pool.ic \
|
||||
include/mtr0log.h include/mtr0log.ic include/mtr0mtr.h include/mtr0mtr.ic \
|
||||
include/mtr0types.h include/os0file.h \
|
||||
include/os0proc.h include/os0proc.ic include/os0sync.h include/os0sync.ic \
|
||||
include/os0thread.h include/os0thread.ic \
|
||||
include/page0cur.h include/page0cur.ic include/page0page.h include/page0page.ic \
|
||||
include/page0types.h \
|
||||
include/pars0grm.h include/pars0opt.h include/pars0opt.ic \
|
||||
include/pars0pars.h include/pars0pars.ic include/pars0sym.h include/pars0sym.ic \
|
||||
include/pars0types.h \
|
||||
include/que0que.h include/que0que.ic include/que0types.h \
|
||||
include/read0read.h include/read0read.ic include/read0types.h \
|
||||
include/rem0cmp.h include/rem0cmp.ic include/rem0rec.h include/rem0rec.ic \
|
||||
include/rem0types.h \
|
||||
include/row0ins.h include/row0ins.ic include/row0mysql.h include/row0mysql.ic \
|
||||
include/row0purge.h include/row0purge.ic include/row0row.h include/row0row.ic \
|
||||
include/row0sel.h include/row0sel.ic include/row0types.h \
|
||||
include/row0uins.h include/row0uins.ic include/row0umod.h include/row0umod.ic \
|
||||
include/row0undo.h include/row0undo.ic include/row0upd.h include/row0upd.ic \
|
||||
include/row0vers.h include/row0vers.ic \
|
||||
include/srv0que.h include/srv0srv.h include/srv0srv.ic include/srv0start.h \
|
||||
include/sync0arr.h include/sync0arr.ic include/sync0rw.h include/sync0rw.ic \
|
||||
include/sync0sync.h include/sync0sync.ic include/sync0types.h \
|
||||
include/thr0loc.h include/thr0loc.ic \
|
||||
include/trx0purge.h include/trx0purge.ic include/trx0rec.h include/trx0rec.ic \
|
||||
include/trx0roll.h include/trx0roll.ic include/trx0rseg.h include/trx0rseg.ic \
|
||||
include/trx0sys.h include/trx0sys.ic include/trx0trx.h include/trx0trx.ic \
|
||||
include/trx0types.h include/trx0undo.h include/trx0undo.ic include/trx0xa.h \
|
||||
include/univ.i include/usr0sess.h include/usr0sess.ic include/usr0types.h \
|
||||
include/ut0byte.h include/ut0byte.ic include/ut0dbg.h include/ut0lst.h \
|
||||
include/ut0mem.h include/ut0mem.ic include/ut0rnd.h include/ut0rnd.ic \
|
||||
include/ut0sort.h include/ut0ut.h include/ut0ut.ic include/ut0vec.h include/ut0vec.ic
|
||||
include/log0log.h include/log0log.ic include/log0recv.h \
|
||||
include/log0recv.ic include/mach0data.h include/mach0data.ic \
|
||||
include/mem0dbg.h include/mem0dbg.ic include/mem0mem.h \
|
||||
include/mem0mem.ic include/mem0pool.h include/mem0pool.ic \
|
||||
include/mtr0log.h include/mtr0log.ic include/mtr0mtr.h \
|
||||
include/mtr0mtr.ic include/mtr0types.h include/os0file.h \
|
||||
include/os0proc.h include/os0proc.ic include/os0sync.h \
|
||||
include/os0sync.ic include/os0thread.h include/os0thread.ic \
|
||||
include/page0cur.h include/page0cur.ic include/page0page.h \
|
||||
include/page0page.ic include/page0types.h include/pars0grm.h \
|
||||
include/pars0opt.h include/pars0opt.ic include/pars0pars.h \
|
||||
include/pars0pars.ic include/pars0sym.h include/pars0sym.ic \
|
||||
include/pars0types.h include/que0que.h include/que0que.ic \
|
||||
include/que0types.h include/read0read.h include/read0read.ic \
|
||||
include/read0types.h include/rem0cmp.h include/rem0cmp.ic \
|
||||
include/rem0rec.h include/rem0rec.ic include/rem0types.h \
|
||||
include/row0ins.h include/row0ins.ic include/row0mysql.h \
|
||||
include/row0mysql.ic include/row0purge.h include/row0purge.ic \
|
||||
include/row0row.h include/row0row.ic include/row0sel.h \
|
||||
include/row0sel.ic include/row0types.h include/row0uins.h \
|
||||
include/row0uins.ic include/row0umod.h include/row0umod.ic \
|
||||
include/row0undo.h include/row0undo.ic include/row0upd.h \
|
||||
include/row0upd.ic include/row0vers.h include/row0vers.ic \
|
||||
include/srv0que.h include/srv0srv.h include/srv0srv.ic \
|
||||
include/srv0start.h include/sync0arr.h include/sync0arr.ic \
|
||||
include/sync0rw.h include/sync0rw.ic include/sync0sync.h \
|
||||
include/sync0sync.ic include/sync0types.h include/thr0loc.h \
|
||||
include/thr0loc.ic include/trx0purge.h include/trx0purge.ic \
|
||||
include/trx0rec.h include/trx0rec.ic include/trx0roll.h \
|
||||
include/trx0roll.ic include/trx0rseg.h include/trx0rseg.ic \
|
||||
include/trx0sys.h include/trx0sys.ic include/trx0trx.h \
|
||||
include/trx0trx.ic include/trx0types.h include/trx0undo.h \
|
||||
include/trx0undo.ic include/trx0xa.h include/univ.i \
|
||||
include/usr0sess.h include/usr0sess.ic include/usr0types.h \
|
||||
include/ut0byte.h include/ut0byte.ic include/ut0dbg.h \
|
||||
include/ut0lst.h include/ut0mem.h include/ut0mem.ic \
|
||||
include/ut0rnd.h include/ut0rnd.ic include/ut0sort.h \
|
||||
include/ut0ut.h include/ut0ut.ic include/ut0vec.h \
|
||||
include/ut0vec.ic include/ut0list.h include/ut0list.ic \
|
||||
include/ut0wqueue.h cmakelists.txt
|
||||
|
||||
# Don't update the files from bitkeeper
|
||||
%::SCCS/s.%
|
||||
|
||||
@@ -136,13 +136,12 @@ btr_search_sys_create(
|
||||
|
||||
btr_search_latch_temp = mem_alloc(sizeof(rw_lock_t));
|
||||
|
||||
rw_lock_create(&btr_search_latch);
|
||||
rw_lock_create(&btr_search_latch, SYNC_SEARCH_SYS);
|
||||
|
||||
btr_search_sys = mem_alloc(sizeof(btr_search_sys_t));
|
||||
|
||||
btr_search_sys->hash_index = ha_create(TRUE, hash_size, 0, 0);
|
||||
|
||||
rw_lock_set_level(&btr_search_latch, SYNC_SEARCH_SYS);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
|
||||
@@ -612,12 +612,11 @@ buf_block_init(
|
||||
|
||||
page_zip_des_init(&block->page_zip);
|
||||
|
||||
rw_lock_create(&(block->lock));
|
||||
rw_lock_create(&block->lock, SYNC_LEVEL_VARYING);
|
||||
ut_ad(rw_lock_validate(&(block->lock)));
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
rw_lock_create(&(block->debug_latch));
|
||||
rw_lock_set_level(&(block->debug_latch), SYNC_NO_ORDER_CHECK);
|
||||
rw_lock_create(&block->debug_latch, SYNC_NO_ORDER_CHECK);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
}
|
||||
|
||||
@@ -660,8 +659,7 @@ buf_pool_init(
|
||||
|
||||
/* 1. Initialize general fields
|
||||
------------------------------- */
|
||||
mutex_create(&(buf_pool->mutex));
|
||||
mutex_set_level(&(buf_pool->mutex), SYNC_BUF_POOL);
|
||||
mutex_create(&buf_pool->mutex, SYNC_BUF_POOL);
|
||||
|
||||
mutex_enter(&(buf_pool->mutex));
|
||||
|
||||
@@ -1953,7 +1951,6 @@ buf_page_io_complete(
|
||||
buf_block_t* block) /* in: pointer to the block in question */
|
||||
{
|
||||
ulint io_type;
|
||||
ulint read_page_no;
|
||||
|
||||
ut_ad(block);
|
||||
|
||||
@@ -1978,16 +1975,36 @@ buf_page_io_complete(
|
||||
}
|
||||
|
||||
/* If this page is not uninitialized and not in the
|
||||
doublewrite buffer, then the page number should be the
|
||||
same as in block */
|
||||
|
||||
read_page_no = mach_read_from_4((block->frame)
|
||||
doublewrite buffer, then the page number and space id
|
||||
should be the same as in block. */
|
||||
ulint read_page_no = mach_read_from_4((block->frame)
|
||||
+ FIL_PAGE_OFFSET);
|
||||
if (read_page_no && read_page_no != block->offset) {
|
||||
ulint read_space_id = mach_read_from_4((block->frame)
|
||||
+ FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
|
||||
|
||||
if (!block->space && trx_doublewrite_page_inside(
|
||||
block->offset)) {
|
||||
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error: page n:o stored in the page read in is %lu, should be %lu!\n",
|
||||
(ulong) read_page_no, (ulong) block->offset);
|
||||
" InnoDB: Error: reading page %lu\n"
|
||||
"InnoDB: which is in the doublewrite buffer!\n",
|
||||
(ulong) block->offset);
|
||||
} else if (!read_space_id && !read_page_no) {
|
||||
/* This is likely an uninitialized page. */
|
||||
} else if ((block->space && block->space != read_space_id)
|
||||
|| block->offset != read_page_no) {
|
||||
/* We did not compare space_id to read_space_id
|
||||
if block->space == 0, because the field on the
|
||||
page may contain garbage in MySQL < 4.1.1,
|
||||
which only supported block->space == 0. */
|
||||
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
" InnoDB: Error: space id and page n:o stored in the page\n"
|
||||
"InnoDB: read in are %lu:%lu, should be %lu:%lu!\n",
|
||||
(ulong) read_space_id, (ulong) read_page_no,
|
||||
(ulong) block->space, (ulong) block->offset);
|
||||
}
|
||||
|
||||
/* From version 3.23.38 up we store the page checksum
|
||||
@@ -2345,7 +2362,8 @@ buf_get_latched_pages_number(void)
|
||||
}
|
||||
|
||||
mutex_exit(&(buf_pool->mutex));
|
||||
return fixed_pages_number;
|
||||
|
||||
return(fixed_pages_number);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
||||
@@ -27,7 +27,7 @@ Created 11/11/1995 Heikki Tuuri
|
||||
#include "trx0sys.h"
|
||||
#include "srv0srv.h"
|
||||
|
||||
/* When flushed, dirty blocks are searched in neigborhoods of this size, and
|
||||
/* When flushed, dirty blocks are searched in neighborhoods of this size, and
|
||||
flushed along with the original page. */
|
||||
|
||||
#define BUF_FLUSH_AREA ut_min(BUF_READ_AHEAD_AREA,\
|
||||
|
||||
@@ -32,4 +32,4 @@ ADD_LIBRARY(innobase btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
|
||||
thr/thr0loc.c
|
||||
trx/trx0purge.c trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c
|
||||
usr/usr0sess.c
|
||||
ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c)
|
||||
ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c ut/ut0list.c ut/ut0wqueue.c)
|
||||
|
||||
@@ -1139,11 +1139,8 @@ dict_create_or_check_foreign_constraint_tables(void)
|
||||
{
|
||||
dict_table_t* table1;
|
||||
dict_table_t* table2;
|
||||
que_thr_t* thr;
|
||||
que_t* graph;
|
||||
ulint error;
|
||||
trx_t* trx;
|
||||
const char* str;
|
||||
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
|
||||
@@ -1195,7 +1192,7 @@ dict_create_or_check_foreign_constraint_tables(void)
|
||||
VARBINARY, like in other InnoDB system tables, to get a clean
|
||||
design. */
|
||||
|
||||
str =
|
||||
error = que_eval_sql(NULL,
|
||||
"PROCEDURE CREATE_FOREIGN_SYS_TABLES_PROC () IS\n"
|
||||
"BEGIN\n"
|
||||
"CREATE TABLE\n"
|
||||
@@ -1207,22 +1204,8 @@ dict_create_or_check_foreign_constraint_tables(void)
|
||||
"SYS_FOREIGN_COLS(ID CHAR, POS INT, FOR_COL_NAME CHAR, REF_COL_NAME CHAR);\n"
|
||||
"CREATE UNIQUE CLUSTERED INDEX ID_IND ON SYS_FOREIGN_COLS (ID, POS);\n"
|
||||
"COMMIT WORK;\n"
|
||||
"END;\n";
|
||||
|
||||
graph = pars_sql(NULL, str);
|
||||
|
||||
ut_a(graph);
|
||||
|
||||
graph->trx = trx;
|
||||
trx->graph = NULL;
|
||||
|
||||
graph->fork_type = QUE_FORK_MYSQL_INTERFACE;
|
||||
|
||||
ut_a(thr = que_fork_start_command(graph));
|
||||
|
||||
que_run_threads(thr);
|
||||
|
||||
error = trx->error_state;
|
||||
"END;\n"
|
||||
, trx);
|
||||
|
||||
if (error != DB_SUCCESS) {
|
||||
fprintf(stderr, "InnoDB: error %lu in creation\n",
|
||||
@@ -1241,8 +1224,6 @@ dict_create_or_check_foreign_constraint_tables(void)
|
||||
error = DB_MUST_GET_MORE_FILE_SPACE;
|
||||
}
|
||||
|
||||
que_graph_free(graph);
|
||||
|
||||
trx->op_info = "";
|
||||
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
|
||||
@@ -235,11 +235,10 @@ dict_remove_db_name(
|
||||
const char* name) /* in: table name in the form
|
||||
dbname '/' tablename */
|
||||
{
|
||||
const char* s;
|
||||
s = strchr(name, '/');
|
||||
const char* s = strchr(name, '/');
|
||||
ut_a(s);
|
||||
if (s) s++;
|
||||
return(s);
|
||||
|
||||
return(s + 1);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
@@ -600,7 +599,7 @@ dict_index_get_nth_field_pos(
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Returns a table object, based on table id, and memoryfixes it. */
|
||||
Returns a table object based on table id. */
|
||||
|
||||
dict_table_t*
|
||||
dict_table_get_on_id(
|
||||
@@ -622,12 +621,12 @@ dict_table_get_on_id(
|
||||
ut_ad(mutex_own(&(dict_sys->mutex)));
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
return(dict_table_get_on_id_low(table_id, trx));
|
||||
return(dict_table_get_on_id_low(table_id));
|
||||
}
|
||||
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
|
||||
table = dict_table_get_on_id_low(table_id, trx);
|
||||
table = dict_table_get_on_id_low(table_id);
|
||||
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
|
||||
@@ -709,8 +708,7 @@ dict_init(void)
|
||||
{
|
||||
dict_sys = mem_alloc(sizeof(dict_sys_t));
|
||||
|
||||
mutex_create(&(dict_sys->mutex));
|
||||
mutex_set_level(&(dict_sys->mutex), SYNC_DICT);
|
||||
mutex_create(&dict_sys->mutex, SYNC_DICT);
|
||||
|
||||
dict_sys->table_hash = hash_create(buf_pool_get_max_size() /
|
||||
(DICT_POOL_PER_TABLE_HASH *
|
||||
@@ -725,32 +723,28 @@ dict_init(void)
|
||||
|
||||
UT_LIST_INIT(dict_sys->table_LRU);
|
||||
|
||||
rw_lock_create(&dict_operation_lock);
|
||||
rw_lock_set_level(&dict_operation_lock, SYNC_DICT_OPERATION);
|
||||
rw_lock_create(&dict_operation_lock, SYNC_DICT_OPERATION);
|
||||
|
||||
dict_foreign_err_file = os_file_create_tmpfile();
|
||||
ut_a(dict_foreign_err_file);
|
||||
mutex_create(&dict_foreign_err_mutex);
|
||||
mutex_set_level(&dict_foreign_err_mutex, SYNC_ANY_LATCH);
|
||||
|
||||
mutex_create(&dict_foreign_err_mutex, SYNC_ANY_LATCH);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
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. */
|
||||
Returns a table object. 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. */
|
||||
|
||||
dict_table_t*
|
||||
dict_table_get(
|
||||
/*===========*/
|
||||
/* out: table, NULL if
|
||||
does not exist */
|
||||
const char* table_name, /* in: table name */
|
||||
trx_t* trx) /* in: transaction handle or NULL */
|
||||
const char* table_name) /* in: table name */
|
||||
{
|
||||
dict_table_t* table;
|
||||
|
||||
UT_NOT_USED(trx);
|
||||
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
|
||||
table = dict_table_get_low(table_name);
|
||||
@@ -774,13 +768,10 @@ dict_table_get_and_increment_handle_count(
|
||||
/*======================================*/
|
||||
/* out: table, NULL if
|
||||
does not exist */
|
||||
const char* table_name, /* in: table name */
|
||||
trx_t* trx) /* in: transaction handle or NULL */
|
||||
const char* table_name) /* in: table name */
|
||||
{
|
||||
dict_table_t* table;
|
||||
|
||||
UT_NOT_USED(trx);
|
||||
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
|
||||
table = dict_table_get_low(table_name);
|
||||
@@ -890,10 +881,7 @@ dict_table_add_to_cache(
|
||||
/* Add table to LRU list of tables */
|
||||
UT_LIST_ADD_FIRST(table_LRU, dict_sys->table_LRU, table);
|
||||
|
||||
/* If the dictionary cache grows too big, trim the table LRU list */
|
||||
|
||||
dict_sys->size += mem_heap_get_size(table->heap);
|
||||
/* dict_table_LRU_trim(); */
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
@@ -1258,38 +1246,6 @@ dict_table_remove_from_cache(
|
||||
dict_mem_table_free(table);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Frees tables from the end of table_LRU if the dictionary cache occupies
|
||||
too much space. Currently not used! */
|
||||
|
||||
void
|
||||
dict_table_LRU_trim(void)
|
||||
/*=====================*/
|
||||
{
|
||||
dict_table_t* table;
|
||||
dict_table_t* prev_table;
|
||||
|
||||
ut_error;
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
ut_ad(mutex_own(&(dict_sys->mutex)));
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
table = UT_LIST_GET_LAST(dict_sys->table_LRU);
|
||||
|
||||
while (table && (dict_sys->size >
|
||||
buf_pool_get_max_size() / DICT_POOL_PER_VARYING)) {
|
||||
|
||||
prev_table = UT_LIST_GET_PREV(table_LRU, table);
|
||||
|
||||
if (table->mem_fix == 0) {
|
||||
dict_table_remove_from_cache(table);
|
||||
}
|
||||
|
||||
table = prev_table;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Adds a column to the data dictionary hash table. */
|
||||
static
|
||||
@@ -1519,10 +1475,7 @@ dict_index_add_to_cache(
|
||||
/* Add the index to the list of indexes stored in the tree */
|
||||
tree->tree_index = new_index;
|
||||
|
||||
/* If the dictionary cache grows too big, trim the table LRU list */
|
||||
|
||||
dict_sys->size += mem_heap_get_size(new_index->heap);
|
||||
/* dict_table_LRU_trim(); */
|
||||
|
||||
dict_mem_index_free(index);
|
||||
|
||||
@@ -2994,7 +2947,8 @@ loop:
|
||||
if so, immediately reject the command if the table is a
|
||||
temporary one. For now, this kludge will work. */
|
||||
if (reject_fks && (UT_LIST_GET_LEN(table->foreign_list) > 0)) {
|
||||
return DB_CANNOT_ADD_CONSTRAINT;
|
||||
|
||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
}
|
||||
|
||||
/**********************************************************/
|
||||
@@ -3664,9 +3618,7 @@ dict_tree_create(
|
||||
|
||||
tree->magic_n = DICT_TREE_MAGIC_N;
|
||||
|
||||
rw_lock_create(&(tree->lock));
|
||||
|
||||
rw_lock_set_level(&(tree->lock), SYNC_INDEX_TREE);
|
||||
rw_lock_create(&tree->lock, SYNC_INDEX_TREE);
|
||||
|
||||
return(tree);
|
||||
}
|
||||
|
||||
@@ -660,7 +660,7 @@ dict_load_indexes(
|
||||
break;
|
||||
}
|
||||
|
||||
if (rec_get_deleted_flag(rec, dict_table_is_comp(table))) {
|
||||
if (rec_get_deleted_flag(rec, 0)) {
|
||||
dict_load_report_deleted_index(table->name,
|
||||
ULINT_UNDEFINED);
|
||||
|
||||
|
||||
@@ -57,7 +57,6 @@ dict_mem_table_create(
|
||||
table->tablespace_discarded = FALSE;
|
||||
table->n_def = 0;
|
||||
table->n_cols = n_cols + DATA_N_SYS_COLS;
|
||||
table->mem_fix = 0;
|
||||
|
||||
table->n_mysql_handles_opened = 0;
|
||||
table->n_foreign_key_checks_running = 0;
|
||||
@@ -82,8 +81,7 @@ dict_mem_table_create(
|
||||
|
||||
table->stat_modified_counter = 0;
|
||||
|
||||
mutex_create(&(table->autoinc_mutex));
|
||||
mutex_set_level(&(table->autoinc_mutex), SYNC_DICT_AUTOINC_MUTEX);
|
||||
mutex_create(&table->autoinc_mutex, SYNC_DICT_AUTOINC_MUTEX);
|
||||
|
||||
table->autoinc_inited = FALSE;
|
||||
|
||||
|
||||
37
export.sh
37
export.sh
@@ -1,19 +1,29 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# export current working directory in a format suitable for sending to
|
||||
# MySQL as a snapshot.
|
||||
# export current working directory in a format suitable for sending to MySQL
|
||||
# as a snapshot. also generates the actual snapshot and sends it to MySQL.
|
||||
|
||||
set -eu
|
||||
|
||||
if [ $# -ne 1 ] ; then
|
||||
echo "Usage: export.sh revision-number-of-last-snapshot"
|
||||
die () {
|
||||
echo $*
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ $# -ne 2 ] ; then
|
||||
die "Usage: export.sh revision-number-of-last-snapshot current-revision-number"
|
||||
fi
|
||||
|
||||
set +u
|
||||
if test -z $EDITOR; then
|
||||
die "\$EDITOR is not set"
|
||||
fi
|
||||
set -u
|
||||
|
||||
rm -rf to-mysql
|
||||
mkdir -p to-mysql/storage/
|
||||
svn log -v -r "$1:BASE" > to-mysql/log
|
||||
svn export . to-mysql/storage/innobase
|
||||
svn log -v -r "$(($1 + 1)):BASE" > to-mysql/log
|
||||
svn export -q . to-mysql/storage/innobase
|
||||
cd to-mysql
|
||||
|
||||
mkdir -p sql mysql-test/t mysql-test/r mysql-test/include
|
||||
@@ -27,5 +37,18 @@ mv mysql-test/*.result ../../mysql-test/r
|
||||
mv mysql-test/*.inc ../../mysql-test/include
|
||||
rmdir mysql-test
|
||||
|
||||
rm setup.sh export.sh compile-innodb-debug
|
||||
rm setup.sh export.sh revert_gen.sh compile-innodb-debug compile-innodb
|
||||
|
||||
cd ../..
|
||||
$EDITOR log
|
||||
cd ..
|
||||
|
||||
fname="innodb-5.1-ss$2.tar.gz"
|
||||
|
||||
rm -f $fname
|
||||
tar czf $fname to-mysql
|
||||
scp $fname mysql:snapshots
|
||||
rm $fname
|
||||
rm -rf to-mysql
|
||||
|
||||
echo "Sent $fname to MySQL"
|
||||
|
||||
@@ -1067,8 +1067,7 @@ try_again:
|
||||
|
||||
space->ibuf_data = NULL;
|
||||
|
||||
rw_lock_create(&(space->latch));
|
||||
rw_lock_set_level(&(space->latch), SYNC_FSP);
|
||||
rw_lock_create(&space->latch, SYNC_FSP);
|
||||
|
||||
HASH_INSERT(fil_space_t, hash, system->spaces, id, space);
|
||||
|
||||
@@ -1362,9 +1361,7 @@ fil_system_create(
|
||||
|
||||
system = mem_alloc(sizeof(fil_system_t));
|
||||
|
||||
mutex_create(&(system->mutex));
|
||||
|
||||
mutex_set_level(&(system->mutex), SYNC_ANY_LATCH);
|
||||
mutex_create(&system->mutex, SYNC_ANY_LATCH);
|
||||
|
||||
system->spaces = hash_create(hash_size);
|
||||
system->name_hash = hash_create(hash_size);
|
||||
|
||||
@@ -144,9 +144,7 @@ hash_create_mutexes(
|
||||
table->mutexes = mem_alloc(n_mutexes * sizeof(mutex_t));
|
||||
|
||||
for (i = 0; i < n_mutexes; i++) {
|
||||
mutex_create(table->mutexes + i);
|
||||
|
||||
mutex_set_level(table->mutexes + i, sync_level);
|
||||
mutex_create(table->mutexes + i, sync_level);
|
||||
}
|
||||
|
||||
table->n_mutexes = n_mutexes;
|
||||
|
||||
@@ -238,7 +238,8 @@ handlerton innobase_hton = {
|
||||
NULL, /* Fill FILES table */
|
||||
HTON_NO_FLAGS,
|
||||
NULL, /* binlog_func */
|
||||
NULL /* binlog_log_query */
|
||||
NULL, /* binlog_log_query */
|
||||
innobase_release_temporary_latches
|
||||
};
|
||||
|
||||
|
||||
@@ -1768,25 +1769,6 @@ innobase_report_binlog_offset_and_commit(
|
||||
trx->mysql_log_file_name = log_file_name;
|
||||
trx->mysql_log_offset = (ib_longlong)end_offset;
|
||||
|
||||
#ifdef HAVE_REPLICATION
|
||||
if (thd->variables.sync_replication) {
|
||||
/* Let us store the binlog file name and the position, so that
|
||||
we know how long to wait for the binlog to the replicated to
|
||||
the slave in synchronous replication. */
|
||||
|
||||
if (trx->repl_wait_binlog_name == NULL) {
|
||||
|
||||
trx->repl_wait_binlog_name =
|
||||
(char*)mem_alloc_noninline(FN_REFLEN + 100);
|
||||
}
|
||||
|
||||
ut_a(strlen(log_file_name) < FN_REFLEN + 100);
|
||||
|
||||
strcpy(trx->repl_wait_binlog_name, log_file_name);
|
||||
|
||||
trx->repl_wait_binlog_pos = (ib_longlong)end_offset;
|
||||
}
|
||||
#endif /* HAVE_REPLICATION */
|
||||
trx->flush_log_later = TRUE;
|
||||
|
||||
innobase_commit(thd, TRUE);
|
||||
@@ -1855,224 +1837,9 @@ innobase_commit_complete(
|
||||
trx_commit_complete_for_mysql(trx);
|
||||
}
|
||||
|
||||
#ifdef HAVE_REPLICATION
|
||||
if (thd->variables.sync_replication
|
||||
&& trx->repl_wait_binlog_name
|
||||
&& innobase_repl_state != 0) {
|
||||
|
||||
struct timespec abstime;
|
||||
int cmp;
|
||||
int ret;
|
||||
|
||||
/* In synchronous replication, let us wait until the MySQL
|
||||
replication has sent the relevant binlog segment to the
|
||||
replication slave. */
|
||||
|
||||
pthread_mutex_lock(&innobase_repl_cond_mutex);
|
||||
try_again:
|
||||
if (innobase_repl_state == 0) {
|
||||
|
||||
pthread_mutex_unlock(&innobase_repl_cond_mutex);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
cmp = strcmp(innobase_repl_file_name,
|
||||
trx->repl_wait_binlog_name);
|
||||
if (cmp > 0
|
||||
|| (cmp == 0 && innobase_repl_pos
|
||||
>= (my_off_t)trx->repl_wait_binlog_pos)) {
|
||||
/* We have already sent the relevant binlog to the
|
||||
slave: no need to wait here */
|
||||
|
||||
pthread_mutex_unlock(&innobase_repl_cond_mutex);
|
||||
|
||||
/* printf("Binlog now sent\n"); */
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Let us update the info about the minimum binlog position
|
||||
of waiting threads in the innobase_repl_... variables */
|
||||
|
||||
if (innobase_repl_wait_file_name_inited != 0) {
|
||||
cmp = strcmp(trx->repl_wait_binlog_name,
|
||||
innobase_repl_wait_file_name);
|
||||
if (cmp < 0
|
||||
|| (cmp == 0
|
||||
&& (my_off_t)trx->repl_wait_binlog_pos
|
||||
<= innobase_repl_wait_pos)) {
|
||||
/* This thd has an even lower position, let
|
||||
us update the minimum info */
|
||||
|
||||
strcpy(innobase_repl_wait_file_name,
|
||||
trx->repl_wait_binlog_name);
|
||||
|
||||
innobase_repl_wait_pos =
|
||||
trx->repl_wait_binlog_pos;
|
||||
}
|
||||
} else {
|
||||
strcpy(innobase_repl_wait_file_name,
|
||||
trx->repl_wait_binlog_name);
|
||||
|
||||
innobase_repl_wait_pos = trx->repl_wait_binlog_pos;
|
||||
|
||||
innobase_repl_wait_file_name_inited = 1;
|
||||
}
|
||||
set_timespec(abstime, thd->variables.sync_replication_timeout);
|
||||
|
||||
/* Let us suspend this thread to wait on the condition;
|
||||
when replication has progressed far enough, we will release
|
||||
these waiting threads. The following call
|
||||
pthread_cond_timedwait also atomically unlocks
|
||||
innobase_repl_cond_mutex. */
|
||||
|
||||
innobase_repl_n_wait_threads++;
|
||||
|
||||
/* printf("Waiting for binlog to be sent\n"); */
|
||||
|
||||
ret = pthread_cond_timedwait(&innobase_repl_cond,
|
||||
&innobase_repl_cond_mutex, &abstime);
|
||||
innobase_repl_n_wait_threads--;
|
||||
|
||||
if (ret != 0) {
|
||||
ut_print_timestamp(stderr);
|
||||
|
||||
sql_print_error("MySQL synchronous replication was "
|
||||
"not able to send the binlog to the "
|
||||
"slave within the timeout %lu. We "
|
||||
"assume that the slave has become "
|
||||
"inaccessible, and switch off "
|
||||
"synchronous replication until the "
|
||||
"communication to the slave works "
|
||||
"again. MySQL synchronous replication "
|
||||
"has sent binlog to the slave up to "
|
||||
"file %s, position %lu. This "
|
||||
"transaction needs it to be sent up "
|
||||
"to file %s, position %lu.",
|
||||
thd->variables.sync_replication_timeout,
|
||||
innobase_repl_file_name,
|
||||
(ulong) innobase_repl_pos,
|
||||
trx->repl_wait_binlog_name,
|
||||
(ulong) trx->repl_wait_binlog_pos);
|
||||
|
||||
innobase_repl_state = 0;
|
||||
|
||||
pthread_mutex_unlock(&innobase_repl_cond_mutex);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
goto try_again;
|
||||
}
|
||||
#endif // HAVE_REPLICATION
|
||||
return(0);
|
||||
}
|
||||
|
||||
#ifdef HAVE_REPLICATION
|
||||
/*********************************************************************
|
||||
In synchronous replication, reports to InnoDB up to which binlog position
|
||||
we have sent the binlog to the slave. Note that replication is synchronous
|
||||
for one slave only. For other slaves, we do nothing in this function. This
|
||||
function is used in a replication master. */
|
||||
|
||||
int
|
||||
innobase_repl_report_sent_binlog(
|
||||
/*=============================*/
|
||||
/* out: 0 */
|
||||
THD* thd, /* in: thread doing the binlog communication to
|
||||
the slave */
|
||||
char* log_file_name, /* in: binlog file name */
|
||||
my_off_t end_offset) /* in: the offset in the binlog file up to
|
||||
which we sent the contents to the slave */
|
||||
{
|
||||
int cmp;
|
||||
ibool can_release_threads = 0;
|
||||
|
||||
if (!innodb_inited) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If synchronous replication is not switched on, or this thd is
|
||||
sending binlog to a slave where we do not need synchronous replication,
|
||||
then return immediately */
|
||||
|
||||
if (thd->server_id != thd->variables.sync_replication_slave_id) {
|
||||
|
||||
/* Do nothing */
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&innobase_repl_cond_mutex);
|
||||
|
||||
if (innobase_repl_state == 0) {
|
||||
|
||||
ut_print_timestamp(stderr);
|
||||
sql_print_warning("Switching MySQL synchronous replication on "
|
||||
"again at binlog file %s, position %lu",
|
||||
log_file_name, (ulong) end_offset);
|
||||
|
||||
innobase_repl_state = 1;
|
||||
}
|
||||
|
||||
/* The position should increase monotonically, since just one thread
|
||||
is sending the binlog to the slave for which we want synchronous
|
||||
replication. Let us check this, and print an error to the .err log
|
||||
if that is not the case. */
|
||||
|
||||
if (innobase_repl_file_name_inited) {
|
||||
cmp = strcmp(log_file_name, innobase_repl_file_name);
|
||||
|
||||
if (cmp < 0
|
||||
|| (cmp == 0 && end_offset < innobase_repl_pos)) {
|
||||
|
||||
ut_print_timestamp(stderr);
|
||||
sql_print_error("MySQL synchronous replication has "
|
||||
"sent binlog to the slave up to file "
|
||||
"%s, position %lu, but now MySQL "
|
||||
"reports that it sent the binlog only "
|
||||
"up to file %s, position %lu",
|
||||
innobase_repl_file_name,
|
||||
(ulong) innobase_repl_pos,
|
||||
log_file_name, (ulong) end_offset);
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(innobase_repl_file_name, log_file_name);
|
||||
innobase_repl_pos = end_offset;
|
||||
innobase_repl_file_name_inited = 1;
|
||||
|
||||
if (innobase_repl_n_wait_threads > 0) {
|
||||
/* Let us check if some of the waiting threads doing a trx
|
||||
commit can now proceed */
|
||||
|
||||
cmp = strcmp(innobase_repl_file_name,
|
||||
innobase_repl_wait_file_name);
|
||||
if (cmp > 0
|
||||
|| (cmp == 0 && innobase_repl_pos
|
||||
>= innobase_repl_wait_pos)) {
|
||||
|
||||
/* Yes, at least one waiting thread can now proceed:
|
||||
let us release all waiting threads with a broadcast */
|
||||
|
||||
can_release_threads = 1;
|
||||
|
||||
innobase_repl_wait_file_name_inited = 0;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&innobase_repl_cond_mutex);
|
||||
|
||||
if (can_release_threads) {
|
||||
|
||||
pthread_cond_broadcast(&innobase_repl_cond);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
#endif /* HAVE_REPLICATION */
|
||||
|
||||
/*********************************************************************
|
||||
Rolls back a transaction or the latest SQL statement. */
|
||||
@@ -2444,8 +2211,7 @@ ha_innobase::open(
|
||||
|
||||
/* Get pointer to a table object in InnoDB dictionary cache */
|
||||
|
||||
ib_table = dict_table_get_and_increment_handle_count(
|
||||
norm_name, NULL);
|
||||
ib_table = dict_table_get_and_increment_handle_count(norm_name);
|
||||
|
||||
if (NULL == ib_table) {
|
||||
ut_print_timestamp(stderr);
|
||||
@@ -5026,7 +4792,7 @@ ha_innobase::create(
|
||||
|
||||
log_buffer_flush_to_disk();
|
||||
|
||||
innobase_table = dict_table_get(norm_name, NULL);
|
||||
innobase_table = dict_table_get(norm_name);
|
||||
|
||||
DBUG_ASSERT(innobase_table != 0);
|
||||
|
||||
|
||||
@@ -316,9 +316,6 @@ int innobase_rollback_by_xid(
|
||||
XID *xid); /* in : X/Open XA Transaction Identification */
|
||||
|
||||
|
||||
int innobase_repl_report_sent_binlog(THD *thd, char *log_file_name,
|
||||
my_off_t end_offset);
|
||||
|
||||
/***********************************************************************
|
||||
Create a consistent view for a cursor based on current transaction
|
||||
which is created if the corresponding MySQL thread still lacks one.
|
||||
|
||||
@@ -144,6 +144,7 @@ static ulint ibuf_rnd = 986058871;
|
||||
|
||||
ulint ibuf_flush_count = 0;
|
||||
|
||||
#ifdef UNIV_IBUF_DEBUG
|
||||
/* Dimensions for the ibuf_count array */
|
||||
#define IBUF_COUNT_N_SPACES 500
|
||||
#define IBUF_COUNT_N_PAGES 2000
|
||||
@@ -152,6 +153,7 @@ ulint ibuf_flush_count = 0;
|
||||
static ulint* ibuf_counts[IBUF_COUNT_N_SPACES];
|
||||
|
||||
static ibool ibuf_counts_inited = FALSE;
|
||||
#endif
|
||||
|
||||
/* The start address for an insert buffer bitmap page bitmap */
|
||||
#define IBUF_BITMAP PAGE_DATA
|
||||
@@ -314,6 +316,7 @@ ibuf_tree_root_get(
|
||||
return(page);
|
||||
}
|
||||
|
||||
#ifdef UNIV_IBUF_DEBUG
|
||||
/**********************************************************************
|
||||
Gets the ibuf count for a given page. */
|
||||
|
||||
@@ -338,7 +341,6 @@ ibuf_count_get(
|
||||
|
||||
/**********************************************************************
|
||||
Sets the ibuf count for a given page. */
|
||||
#ifdef UNIV_IBUF_DEBUG
|
||||
static
|
||||
void
|
||||
ibuf_count_set(
|
||||
@@ -389,23 +391,18 @@ ibuf_init_at_db_start(void)
|
||||
ibuf_count_set(i, j, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
mutex_create(&ibuf_pessimistic_insert_mutex);
|
||||
|
||||
mutex_set_level(&ibuf_pessimistic_insert_mutex,
|
||||
SYNC_IBUF_PESS_INSERT_MUTEX);
|
||||
mutex_create(&ibuf_mutex);
|
||||
|
||||
mutex_set_level(&ibuf_mutex, SYNC_IBUF_MUTEX);
|
||||
|
||||
mutex_create(&ibuf_bitmap_mutex);
|
||||
|
||||
mutex_set_level(&ibuf_bitmap_mutex, SYNC_IBUF_BITMAP_MUTEX);
|
||||
|
||||
fil_ibuf_init_at_db_start();
|
||||
|
||||
ibuf_counts_inited = TRUE;
|
||||
}
|
||||
#endif
|
||||
mutex_create(&ibuf_pessimistic_insert_mutex,
|
||||
SYNC_IBUF_PESS_INSERT_MUTEX);
|
||||
|
||||
mutex_create(&ibuf_mutex, SYNC_IBUF_MUTEX);
|
||||
|
||||
mutex_create(&ibuf_bitmap_mutex, SYNC_IBUF_BITMAP_MUTEX);
|
||||
|
||||
fil_ibuf_init_at_db_start();
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
@@ -265,17 +265,16 @@ dict_foreign_parse_drop_constraints(
|
||||
const 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. */
|
||||
Returns a table object. 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. */
|
||||
|
||||
dict_table_t*
|
||||
dict_table_get(
|
||||
/*===========*/
|
||||
/* out: table, NULL if
|
||||
does not exist */
|
||||
const char* table_name, /* in: table name */
|
||||
trx_t* trx); /* in: transaction handle */
|
||||
const char* table_name); /* in: table name */
|
||||
/**************************************************************************
|
||||
Returns a table object and increments MySQL open handle count on the table.
|
||||
*/
|
||||
@@ -285,10 +284,9 @@ dict_table_get_and_increment_handle_count(
|
||||
/*======================================*/
|
||||
/* out: table, NULL if
|
||||
does not exist */
|
||||
const char* table_name, /* in: table name */
|
||||
trx_t* trx); /* in: transaction handle or NULL */
|
||||
const char* table_name); /* in: table name */
|
||||
/**************************************************************************
|
||||
Returns a table object, based on table id, and memoryfixes it. */
|
||||
Returns a table object based on table id. */
|
||||
|
||||
dict_table_t*
|
||||
dict_table_get_on_id(
|
||||
@@ -297,21 +295,13 @@ dict_table_get_on_id(
|
||||
dulint table_id, /* in: table id */
|
||||
trx_t* trx); /* in: transaction handle */
|
||||
/**************************************************************************
|
||||
Returns a table object, based on table id, and memoryfixes it. */
|
||||
Returns a table object based on table id. */
|
||||
UNIV_INLINE
|
||||
dict_table_t*
|
||||
dict_table_get_on_id_low(
|
||||
/*=====================*/
|
||||
/* out: table, NULL if does not exist */
|
||||
dulint table_id, /* in: table id */
|
||||
trx_t* trx); /* in: transaction handle */
|
||||
/**************************************************************************
|
||||
Releases a table from being memoryfixed. Currently this has no relevance. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
dict_table_release(
|
||||
/*===============*/
|
||||
dict_table_t* table); /* in: table to be released */
|
||||
dulint table_id); /* in: table id */
|
||||
/**************************************************************************
|
||||
Checks if a table is in the dictionary cache. */
|
||||
UNIV_INLINE
|
||||
|
||||
@@ -577,14 +577,13 @@ dict_table_get_low(
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Returns a table object, based on table id, and memoryfixes it. */
|
||||
Returns a table object based on table id. */
|
||||
UNIV_INLINE
|
||||
dict_table_t*
|
||||
dict_table_get_on_id_low(
|
||||
/*=====================*/
|
||||
/* out: table, NULL if does not exist */
|
||||
dulint table_id, /* in: table id */
|
||||
trx_t* trx) /* in: transaction handle */
|
||||
dulint table_id) /* in: table id */
|
||||
{
|
||||
dict_table_t* table;
|
||||
ulint fold;
|
||||
@@ -592,7 +591,6 @@ dict_table_get_on_id_low(
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
ut_ad(mutex_own(&(dict_sys->mutex)));
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
UT_NOT_USED(trx);
|
||||
|
||||
/* Look for the table name in the hash table */
|
||||
fold = ut_fold_dulint(table_id);
|
||||
@@ -603,32 +601,11 @@ dict_table_get_on_id_low(
|
||||
table = dict_load_table_on_id(table_id);
|
||||
}
|
||||
|
||||
if (table != NULL) {
|
||||
table->mem_fix++;
|
||||
|
||||
/* lock_push(trx, table, LOCK_DICT_MEM_FIX) */
|
||||
}
|
||||
|
||||
/* TODO: should get the type information from MySQL */
|
||||
|
||||
return(table);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Releases a table from being memoryfixed. Currently this has no relevance. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
dict_table_release(
|
||||
/*===============*/
|
||||
dict_table_t* table) /* in: table to be released */
|
||||
{
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
|
||||
table->mem_fix--;
|
||||
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Returns an index object. */
|
||||
UNIV_INLINE
|
||||
|
||||
@@ -172,10 +172,6 @@ struct dict_tree_struct{
|
||||
the same memory cache line */
|
||||
rw_lock_t lock; /* read-write lock protecting the upper levels
|
||||
of the index tree */
|
||||
ulint mem_fix;/* count of how many times this tree
|
||||
struct has been memoryfixed (by mini-
|
||||
transactions wanting to access the index
|
||||
tree) */
|
||||
dict_index_t* tree_index; /* the index stored in the
|
||||
index tree */
|
||||
ulint magic_n;/* magic number */
|
||||
@@ -318,9 +314,6 @@ struct dict_table_struct{
|
||||
which refer to this table */
|
||||
UT_LIST_NODE_T(dict_table_t)
|
||||
table_LRU; /* node of the LRU list of tables */
|
||||
ulint mem_fix;/* count of how many times the table
|
||||
and its indexes has been fixed in memory;
|
||||
currently NOT used */
|
||||
ulint n_mysql_handles_opened;
|
||||
/* count of how many handles MySQL has opened
|
||||
to this table; dropping of the table is
|
||||
|
||||
@@ -369,24 +369,28 @@ description takes less than 1 byte; a descriptor page is repeated every
|
||||
this many file pages */
|
||||
#define XDES_DESCRIBED_PER_PAGE UNIV_PAGE_SIZE
|
||||
|
||||
/* The space low address page map, and also offsets for extent descriptor and
|
||||
bitmap pages which are repeated always after XDES_DESCRIBED_PER_PAGE more
|
||||
pages: */
|
||||
/* The space low address page map */
|
||||
/*--------------------------------------*/
|
||||
#define FSP_XDES_OFFSET 0
|
||||
#define FSP_IBUF_BITMAP_OFFSET 1
|
||||
/* The following two pages are repeated
|
||||
every XDES_DESCRIBED_PER_PAGE pages in
|
||||
every tablespace. */
|
||||
#define FSP_XDES_OFFSET 0 /* extent descriptor */
|
||||
#define FSP_IBUF_BITMAP_OFFSET 1 /* insert buffer bitmap */
|
||||
/* The ibuf bitmap pages are the ones whose
|
||||
page number is the number above plus a
|
||||
multiple of XDES_DESCRIBED_PER_PAGE */
|
||||
#define FSP_FIRST_INODE_PAGE_NO 2
|
||||
#define FSP_IBUF_HEADER_PAGE_NO 3
|
||||
#define FSP_IBUF_TREE_ROOT_PAGE_NO 4
|
||||
|
||||
#define FSP_FIRST_INODE_PAGE_NO 2 /* in every tablespace */
|
||||
/* The following pages exist
|
||||
in the system tablespace (space 0). */
|
||||
#define FSP_IBUF_HEADER_PAGE_NO 3 /* in tablespace 0 */
|
||||
#define FSP_IBUF_TREE_ROOT_PAGE_NO 4 /* in tablespace 0 */
|
||||
/* The ibuf tree root page number in
|
||||
tablespace 0; its fseg inode is on the page
|
||||
number FSP_FIRST_INODE_PAGE_NO */
|
||||
#define FSP_TRX_SYS_PAGE_NO 5
|
||||
#define FSP_FIRST_RSEG_PAGE_NO 6
|
||||
#define FSP_DICT_HDR_PAGE_NO 7
|
||||
#define FSP_TRX_SYS_PAGE_NO 5 /* in tablespace 0 */
|
||||
#define FSP_FIRST_RSEG_PAGE_NO 6 /* in tablespace 0 */
|
||||
#define FSP_DICT_HDR_PAGE_NO 7 /* in tablespace 0 */
|
||||
/*--------------------------------------*/
|
||||
|
||||
#ifndef UNIV_NONINL
|
||||
|
||||
@@ -267,6 +267,7 @@ ibuf_parse_bitmap_init(
|
||||
byte* end_ptr,/* in: buffer end */
|
||||
page_t* page, /* in: page or NULL */
|
||||
mtr_t* mtr); /* in: mtr or NULL */
|
||||
#ifdef UNIV_IBUF_DEBUG
|
||||
/**********************************************************************
|
||||
Gets the ibuf count for a given page. */
|
||||
|
||||
@@ -277,6 +278,7 @@ ibuf_count_get(
|
||||
currently buffered for this page */
|
||||
ulint space, /* in: space id */
|
||||
ulint page_no);/* in: page number */
|
||||
#endif
|
||||
/**********************************************************************
|
||||
Looks if the insert buffer is empty. */
|
||||
|
||||
|
||||
@@ -311,6 +311,28 @@ mem_heap_strdupl(
|
||||
const char* str, /* in: string to be copied */
|
||||
ulint len); /* in: length of str, in bytes */
|
||||
|
||||
/**************************************************************************
|
||||
Concatenate two strings and return the result, using a memory heap. */
|
||||
|
||||
char*
|
||||
mem_heap_strcat(
|
||||
/*============*/
|
||||
/* out, own: the result */
|
||||
mem_heap_t* heap, /* in: memory heap where string is allocated */
|
||||
const char* s1, /* in: string 1 */
|
||||
const char* s2); /* in: string 2 */
|
||||
|
||||
/**************************************************************************
|
||||
Duplicate a block of data, allocated from a memory heap. */
|
||||
|
||||
void*
|
||||
mem_heap_dup(
|
||||
/*=========*/
|
||||
/* out, own: a copy of the data */
|
||||
mem_heap_t* heap, /* in: memory heap where copy is allocated */
|
||||
const void* data, /* in: data to be copied */
|
||||
ulint len); /* in: length of data, in bytes */
|
||||
|
||||
#ifdef MEM_PERIODIC_CHECK
|
||||
/**********************************************************************
|
||||
Goes through the list of all allocated mem blocks, checks their magic
|
||||
|
||||
@@ -77,7 +77,7 @@ os_thread_create(
|
||||
void* arg, /* in: argument to start
|
||||
function */
|
||||
os_thread_id_t* thread_id); /* out: id of the created
|
||||
thread */
|
||||
thread, or NULL */
|
||||
int
|
||||
os_thread_join(
|
||||
/*===========*/
|
||||
|
||||
@@ -531,6 +531,16 @@ pars_info_add_function(
|
||||
pars_user_func_cb_t func, /* in: function address */
|
||||
void* arg); /* in: user-supplied argument */
|
||||
|
||||
/********************************************************************
|
||||
Add bound id. */
|
||||
|
||||
void
|
||||
pars_info_add_id(
|
||||
/*=============*/
|
||||
pars_info_t* info, /* in: info struct */
|
||||
const char* name, /* in: name */
|
||||
const char* id); /* in: id */
|
||||
|
||||
/********************************************************************
|
||||
Get user function with the given name.*/
|
||||
|
||||
@@ -553,6 +563,17 @@ pars_info_get_bound_lit(
|
||||
pars_info_t* info, /* in: info struct */
|
||||
const char* name); /* in: bound literal name to find */
|
||||
|
||||
/********************************************************************
|
||||
Get bound id with the given name.*/
|
||||
|
||||
pars_bound_id_t*
|
||||
pars_info_get_bound_id(
|
||||
/*===================*/
|
||||
/* out: bound id, or NULL if not
|
||||
found */
|
||||
pars_info_t* info, /* in: info struct */
|
||||
const char* name); /* in: bound id name to find */
|
||||
|
||||
|
||||
/* Extra information supplied for pars_sql(). */
|
||||
struct pars_info_struct {
|
||||
@@ -562,6 +583,8 @@ struct pars_info_struct {
|
||||
(pars_user_func_t*) */
|
||||
ib_vector_t* bound_lits; /* bound literals, or NULL
|
||||
(pars_bound_lit_t*) */
|
||||
ib_vector_t* bound_ids; /* bound ids, or NULL
|
||||
(pars_bound_id_t*) */
|
||||
|
||||
ibool graph_owns_us; /* if TRUE (which is the default),
|
||||
que_graph_free() will free us */
|
||||
@@ -583,6 +606,12 @@ struct pars_bound_lit_struct {
|
||||
ulint prtype; /* precise type, e.g. DATA_UNSIGNED */
|
||||
};
|
||||
|
||||
/* Bound id. */
|
||||
struct pars_bound_id_struct {
|
||||
const char* name; /* name */
|
||||
const char* id; /* id */
|
||||
};
|
||||
|
||||
/* Struct used to denote a reserved word in a parsing tree */
|
||||
struct pars_res_word_struct{
|
||||
int code; /* the token code for the reserved word from
|
||||
|
||||
@@ -82,6 +82,16 @@ sym_tab_add_id(
|
||||
byte* name, /* in: identifier name */
|
||||
ulint len); /* in: identifier length */
|
||||
|
||||
/**********************************************************************
|
||||
Add a bound identifier to a symbol table. */
|
||||
|
||||
sym_node_t*
|
||||
sym_tab_add_bound_id(
|
||||
/*===========*/
|
||||
/* out: symbol table node */
|
||||
sym_tab_t* sym_tab, /* in: symbol table */
|
||||
const char* name); /* in: name of bound id */
|
||||
|
||||
#define SYM_CLUST_FIELD_NO 0
|
||||
#define SYM_SEC_FIELD_NO 1
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ Created 1/11/1998 Heikki Tuuri
|
||||
typedef struct pars_info_struct pars_info_t;
|
||||
typedef struct pars_user_func_struct pars_user_func_t;
|
||||
typedef struct pars_bound_lit_struct pars_bound_lit_t;
|
||||
typedef struct pars_bound_id_struct pars_bound_id_t;
|
||||
typedef struct sym_node_struct sym_node_t;
|
||||
typedef struct sym_tab_struct sym_tab_t;
|
||||
typedef struct pars_res_word_struct pars_res_word_t;
|
||||
|
||||
@@ -56,9 +56,7 @@ struct purge_node_struct{
|
||||
determined by ref was found in the clustered
|
||||
index, and we were able to position pcur on
|
||||
it */
|
||||
dict_table_t* table; /* table where purge is done; NOTE that the
|
||||
table has to be released explicitly with
|
||||
dict_table_release */
|
||||
dict_table_t* table; /* table where purge is done */
|
||||
ulint cmpl_info;/* compiler analysis info of an update */
|
||||
upd_t* update; /* update vector for a clustered index record */
|
||||
dtuple_t* ref; /* NULL, or row reference to the next row to
|
||||
|
||||
@@ -84,9 +84,7 @@ struct undo_node_struct{
|
||||
record */
|
||||
btr_pcur_t pcur; /* persistent cursor used in searching the
|
||||
clustered index record */
|
||||
dict_table_t* table; /* table where undo is done; NOTE that the
|
||||
table has to be released explicitly with
|
||||
dict_table_release */
|
||||
dict_table_t* table; /* table where undo is done */
|
||||
ulint cmpl_info;/* compiler analysis of an update */
|
||||
upd_t* update; /* update vector for a clustered index record */
|
||||
dtuple_t* ref; /* row reference to the next row to handle */
|
||||
|
||||
@@ -157,33 +157,12 @@ extern ulint srv_pool_size;
|
||||
extern ulint srv_mem_pool_size;
|
||||
extern ulint srv_lock_table_size;
|
||||
|
||||
extern ulint srv_sim_disk_wait_pct;
|
||||
extern ulint srv_sim_disk_wait_len;
|
||||
extern ibool srv_sim_disk_wait_by_yield;
|
||||
extern ibool srv_sim_disk_wait_by_wait;
|
||||
|
||||
extern ibool srv_measure_contention;
|
||||
extern ibool srv_measure_by_spin;
|
||||
|
||||
extern ibool srv_print_thread_releases;
|
||||
extern ibool srv_print_lock_waits;
|
||||
extern ibool srv_print_buf_io;
|
||||
extern ibool srv_print_log_io;
|
||||
extern ibool srv_print_parsed_sql;
|
||||
extern ibool srv_print_latch_waits;
|
||||
|
||||
extern ibool srv_test_nocache;
|
||||
extern ibool srv_test_cache_evict;
|
||||
|
||||
extern ibool srv_test_extra_mutexes;
|
||||
extern ibool srv_test_sync;
|
||||
extern ulint srv_test_n_threads;
|
||||
extern ulint srv_test_n_loops;
|
||||
extern ulint srv_test_n_free_rnds;
|
||||
extern ulint srv_test_n_reserved_rnds;
|
||||
extern ulint srv_test_n_mutexes;
|
||||
extern ulint srv_test_array_size;
|
||||
|
||||
extern ulint srv_activity_count;
|
||||
extern ulint srv_fatal_semaphore_wait_threshold;
|
||||
extern ulint srv_dml_needed_delay;
|
||||
@@ -365,11 +344,7 @@ srv_release_threads(
|
||||
/*************************************************************************
|
||||
The master thread controlling the server. */
|
||||
|
||||
#ifndef __WIN__
|
||||
void*
|
||||
#else
|
||||
ulint
|
||||
#endif
|
||||
os_thread_ret_t
|
||||
srv_master_thread(
|
||||
/*==============*/
|
||||
/* out: a dummy parameter */
|
||||
@@ -451,11 +426,7 @@ srv_release_mysql_thread_if_suspended(
|
||||
A thread which wakes up threads whose lock wait may have lasted too long.
|
||||
This also prints the info output by various InnoDB monitors. */
|
||||
|
||||
#ifndef __WIN__
|
||||
void*
|
||||
#else
|
||||
ulint
|
||||
#endif
|
||||
os_thread_ret_t
|
||||
srv_lock_timeout_and_monitor_thread(
|
||||
/*================================*/
|
||||
/* out: a dummy parameter */
|
||||
@@ -465,11 +436,7 @@ srv_lock_timeout_and_monitor_thread(
|
||||
A thread which prints warnings about semaphore waits which have lasted
|
||||
too long. These can be used to track bugs which cause hangs. */
|
||||
|
||||
#ifndef __WIN__
|
||||
void*
|
||||
#else
|
||||
ulint
|
||||
#endif
|
||||
os_thread_ret_t
|
||||
srv_error_monitor_thread(
|
||||
/*=====================*/
|
||||
/* out: a dummy parameter */
|
||||
@@ -567,9 +534,6 @@ struct export_var_struct{
|
||||
|
||||
/* The server system struct */
|
||||
struct srv_sys_struct{
|
||||
os_event_t operational; /* created threads must wait for the
|
||||
server to become operational by
|
||||
waiting for this event */
|
||||
srv_table_t* threads; /* server thread table */
|
||||
UT_LIST_BASE_NODE_T(que_thr_t)
|
||||
tasks; /* task queue */
|
||||
|
||||
@@ -61,7 +61,7 @@ Creates, or rather, initializes an rw-lock object in a specified memory
|
||||
location (which must be appropriately aligned). The rw-lock is initialized
|
||||
to the non-locked state. Explicit freeing of the rw-lock with rw_lock_free
|
||||
is necessary only if the memory block containing it is freed. */
|
||||
#define rw_lock_create(L) rw_lock_create_func((L), __FILE__, __LINE__, #L)
|
||||
#define rw_lock_create(L, level) rw_lock_create_func((L), (level), __FILE__, __LINE__, #L)
|
||||
|
||||
/*=====================*/
|
||||
/**********************************************************************
|
||||
@@ -74,6 +74,7 @@ void
|
||||
rw_lock_create_func(
|
||||
/*================*/
|
||||
rw_lock_t* lock, /* in: pointer to memory */
|
||||
ulint level, /* in: level */
|
||||
const char* cfile_name, /* in: file name where created */
|
||||
ulint cline, /* in: file line where created */
|
||||
const char* cmutex_name); /* in: mutex name */
|
||||
@@ -299,14 +300,6 @@ rw_lock_x_unlock_direct(
|
||||
/*====================*/
|
||||
rw_lock_t* lock); /* in: rw-lock */
|
||||
/**********************************************************************
|
||||
Sets the rw-lock latching level field. */
|
||||
|
||||
void
|
||||
rw_lock_set_level(
|
||||
/*==============*/
|
||||
rw_lock_t* lock, /* in: rw-lock */
|
||||
ulint level); /* in: level */
|
||||
/**********************************************************************
|
||||
Returns the value of writer_count for the lock. Does not reserve the lock
|
||||
mutex, so the caller must be sure it is not changed during the call. */
|
||||
UNIV_INLINE
|
||||
@@ -448,8 +441,8 @@ struct rw_lock_struct {
|
||||
/* In the debug version: pointer to the debug
|
||||
info list of the lock */
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
ulint level; /* Level in the global latching
|
||||
order; default SYNC_LEVEL_NONE */
|
||||
|
||||
ulint level; /* Level in the global latching order. */
|
||||
const char* cfile_name;/* File name where lock created */
|
||||
ulint cline; /* Line where created */
|
||||
const char* last_s_file_name;/* File name where last s-locked */
|
||||
|
||||
@@ -39,7 +39,7 @@ location (which must be appropriately aligned). The mutex is initialized
|
||||
in the reset state. Explicit freeing of the mutex with mutex_free is
|
||||
necessary only if the memory block containing it is freed. */
|
||||
|
||||
#define mutex_create(M) mutex_create_func((M), __FILE__, __LINE__, #M)
|
||||
#define mutex_create(M, level) mutex_create_func((M), (level), __FILE__, __LINE__, #M)
|
||||
/*===================*/
|
||||
/**********************************************************************
|
||||
Creates, or rather, initializes a mutex object in a specified memory
|
||||
@@ -51,6 +51,7 @@ void
|
||||
mutex_create_func(
|
||||
/*==============*/
|
||||
mutex_t* mutex, /* in: pointer to memory */
|
||||
ulint level, /* in: level */
|
||||
const char* cfile_name, /* in: file name where created */
|
||||
ulint cline, /* in: file line where created */
|
||||
const char* cmutex_name); /* in: mutex name */
|
||||
@@ -155,14 +156,6 @@ mutex_validate(
|
||||
/*===========*/
|
||||
mutex_t* mutex);
|
||||
/**********************************************************************
|
||||
Sets the mutex latching level field. */
|
||||
|
||||
void
|
||||
mutex_set_level(
|
||||
/*============*/
|
||||
mutex_t* mutex, /* in: mutex */
|
||||
ulint level); /* in: level */
|
||||
/**********************************************************************
|
||||
Adds a latch and its level in the thread level array. Allocates the memory
|
||||
for the array if called first time for this OS thread. Makes the checks
|
||||
against other latch levels stored in the array for this thread. */
|
||||
@@ -171,8 +164,8 @@ void
|
||||
sync_thread_add_level(
|
||||
/*==================*/
|
||||
void* latch, /* in: pointer to a mutex or an rw-lock */
|
||||
ulint level); /* in: level in the latching order; if SYNC_LEVEL_NONE,
|
||||
nothing is done */
|
||||
ulint level); /* in: level in the latching order; if
|
||||
SYNC_LEVEL_VARYING, nothing is done */
|
||||
/**********************************************************************
|
||||
Removes a latch from the thread level array if it is found there. */
|
||||
|
||||
@@ -383,7 +376,12 @@ or row lock! */
|
||||
#define SYNC_USER_TRX_LOCK 9999
|
||||
#define SYNC_NO_ORDER_CHECK 3000 /* this can be used to suppress
|
||||
latching order checking */
|
||||
#define SYNC_LEVEL_NONE 2000 /* default: level not defined */
|
||||
#define SYNC_LEVEL_VARYING 2000 /* Level is varying. Only used with
|
||||
buffer pool page locks, which do not
|
||||
have a fixed level, but instead have
|
||||
their level set after the page is
|
||||
locked; see e.g.
|
||||
ibuf_bitmap_get_map_page(). */
|
||||
#define SYNC_DICT_OPERATION 1001 /* table create, drop, etc. reserve
|
||||
this in X-mode, implicit or backround
|
||||
operations purge, rollback, foreign
|
||||
@@ -426,6 +424,7 @@ or row lock! */
|
||||
#define SYNC_TRX_SYS_HEADER 290
|
||||
#define SYNC_LOG 170
|
||||
#define SYNC_RECV 168
|
||||
#define SYNC_WORK_QUEUE 161
|
||||
#define SYNC_SEARCH_SYS 160 /* NOTE that if we have a memory
|
||||
heap that can be extended to the
|
||||
buffer pool, its logical level is
|
||||
@@ -472,8 +471,7 @@ struct mutex_struct {
|
||||
os_thread_id_t thread_id; /* Debug version: The thread id of the
|
||||
thread which locked the mutex. */
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
ulint level; /* Level in the global latching
|
||||
order; default SYNC_LEVEL_NONE */
|
||||
ulint level; /* Level in the global latching order */
|
||||
const char* cfile_name;/* File name where mutex created */
|
||||
ulint cline; /* Line where created */
|
||||
ulint magic_n;
|
||||
|
||||
@@ -107,11 +107,7 @@ transaction already was committed, then we clean up a possible insert
|
||||
undo log. If the transaction was not yet committed, then we roll it back.
|
||||
Note: this is done in a background thread. */
|
||||
|
||||
#ifndef __WIN__
|
||||
void*
|
||||
#else
|
||||
ulint
|
||||
#endif
|
||||
os_thread_ret_t
|
||||
trx_rollback_or_clean_all_without_sess(
|
||||
/*===================================*/
|
||||
/* out: a dummy parameter */
|
||||
|
||||
@@ -75,6 +75,15 @@ multiple tablespace format. */
|
||||
void
|
||||
trx_sys_mark_upgraded_to_multiple_tablespaces(void);
|
||||
/*===============================================*/
|
||||
/********************************************************************
|
||||
Determines if a page number is located inside the doublewrite buffer. */
|
||||
|
||||
ibool
|
||||
trx_doublewrite_page_inside(
|
||||
/*========================*/
|
||||
/* out: TRUE if the location is inside
|
||||
the two blocks of the doublewrite buffer */
|
||||
ulint page_no); /* in: page number */
|
||||
/*******************************************************************
|
||||
Checks if a page address is the trx sys header page. */
|
||||
UNIV_INLINE
|
||||
|
||||
@@ -82,17 +82,18 @@ memory is read outside the allocated blocks. */
|
||||
|
||||
/* Make a non-inline debug version */
|
||||
|
||||
#if 0
|
||||
#define UNIV_DEBUG
|
||||
/*
|
||||
#define UNIV_MEM_DEBUG
|
||||
#define UNIV_IBUF_DEBUG
|
||||
#define UNIV_SYNC_DEBUG
|
||||
#define UNIV_SEARCH_DEBUG
|
||||
#define UNIV_SYNC_PERF_STAT
|
||||
#define UNIV_SEARCH_PERF_STAT
|
||||
#define UNIV_SRV_PRINT_LATCH_WAITS;
|
||||
#define UNIV_SRV_PRINT_LATCH_WAITS
|
||||
#define UNIV_ZIP_DEBUG
|
||||
*/
|
||||
#endif
|
||||
|
||||
#define UNIV_LIGHT_MEM_DEBUG
|
||||
|
||||
#define YYDEBUG 1
|
||||
@@ -274,6 +275,18 @@ it is read or written. */
|
||||
/* Compile-time constant of the given array's size. */
|
||||
#define UT_ARR_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
|
||||
/* The return type from a thread's start function differs between Unix and
|
||||
Windows, so define a typedef for it and a macro to use at the end of such
|
||||
functions. */
|
||||
|
||||
#ifdef __WIN__
|
||||
typedef ulint os_thread_ret_t;
|
||||
#define OS_THREAD_DUMMY_RETURN return(0)
|
||||
#else
|
||||
typedef void* os_thread_ret_t;
|
||||
#define OS_THREAD_DUMMY_RETURN return(NULL)
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "ut0dbg.h"
|
||||
#include "ut0ut.h"
|
||||
|
||||
134
include/ut0list.h
Normal file
134
include/ut0list.h
Normal file
@@ -0,0 +1,134 @@
|
||||
/***********************************************************************
|
||||
A double-linked list. This differs from the one in ut0lst.h in that in this
|
||||
one, each list node contains a pointer to the data, whereas the one in
|
||||
ut0lst.h uses a strategy where the list pointers are embedded in the data
|
||||
items themselves.
|
||||
|
||||
Use this one when you need to store arbitrary data in the list where you
|
||||
can't embed the list pointers in the data, if a data item needs to be
|
||||
stored in multiple lists, etc.
|
||||
|
||||
Note about the memory management: ib_list_t is a fixed-size struct whose
|
||||
allocation/deallocation is done through ib_list_create/ib_list_free, but the
|
||||
memory for the list nodes is allocated through a user-given memory heap,
|
||||
which can either be the same for all nodes or vary per node. Most users will
|
||||
probably want to create a memory heap to store the item-specific data, and
|
||||
pass in this same heap to the list node creation functions, thus
|
||||
automatically freeing the list node when the item's heap is freed.
|
||||
|
||||
************************************************************************/
|
||||
|
||||
|
||||
#ifndef IB_LIST_H
|
||||
#define IB_LIST_H
|
||||
|
||||
#include "mem0mem.h"
|
||||
|
||||
typedef struct ib_list_struct ib_list_t;
|
||||
typedef struct ib_list_node_struct ib_list_node_t;
|
||||
typedef struct ib_list_helper_struct ib_list_helper_t;
|
||||
|
||||
/********************************************************************
|
||||
Create a new list. */
|
||||
|
||||
ib_list_t*
|
||||
ib_list_create(void);
|
||||
/*=================*/
|
||||
/* out: list */
|
||||
|
||||
/********************************************************************
|
||||
Free a list. */
|
||||
|
||||
void
|
||||
ib_list_free(
|
||||
/*=========*/
|
||||
ib_list_t* list); /* in: list */
|
||||
|
||||
/********************************************************************
|
||||
Add the data to the start of the list. */
|
||||
|
||||
ib_list_node_t*
|
||||
ib_list_add_first(
|
||||
/*==============*/
|
||||
/* out: new list node*/
|
||||
ib_list_t* list, /* in: list */
|
||||
void* data, /* in: data */
|
||||
mem_heap_t* heap); /* in: memory heap to use */
|
||||
|
||||
/********************************************************************
|
||||
Add the data to the end of the list. */
|
||||
|
||||
ib_list_node_t*
|
||||
ib_list_add_last(
|
||||
/*=============*/
|
||||
/* out: new list node*/
|
||||
ib_list_t* list, /* in: list */
|
||||
void* data, /* in: data */
|
||||
mem_heap_t* heap); /* in: memory heap to use */
|
||||
|
||||
/********************************************************************
|
||||
Add the data after the indicated node. */
|
||||
|
||||
ib_list_node_t*
|
||||
ib_list_add_after(
|
||||
/*==============*/
|
||||
/* out: new list node*/
|
||||
ib_list_t* list, /* in: list */
|
||||
ib_list_node_t* prev_node, /* in: node preceding new node (can
|
||||
be NULL) */
|
||||
void* data, /* in: data */
|
||||
mem_heap_t* heap); /* in: memory heap to use */
|
||||
|
||||
/********************************************************************
|
||||
Remove the node from the list. */
|
||||
|
||||
void
|
||||
ib_list_remove(
|
||||
/*===========*/
|
||||
ib_list_t* list, /* in: list */
|
||||
ib_list_node_t* node); /* in: node to remove */
|
||||
|
||||
/********************************************************************
|
||||
Get the first node in the list. */
|
||||
UNIV_INLINE
|
||||
ib_list_node_t*
|
||||
ib_list_get_first(
|
||||
/*==============*/
|
||||
/* out: first node, or NULL */
|
||||
ib_list_t* list); /* in: list */
|
||||
|
||||
/********************************************************************
|
||||
Get the last node in the list. */
|
||||
UNIV_INLINE
|
||||
ib_list_node_t*
|
||||
ib_list_get_last(
|
||||
/*=============*/
|
||||
/* out: last node, or NULL */
|
||||
ib_list_t* list); /* in: list */
|
||||
|
||||
/* List. */
|
||||
struct ib_list_struct {
|
||||
ib_list_node_t* first; /* first node */
|
||||
ib_list_node_t* last; /* last node */
|
||||
};
|
||||
|
||||
/* A list node. */
|
||||
struct ib_list_node_struct {
|
||||
ib_list_node_t* prev; /* previous node */
|
||||
ib_list_node_t* next; /* next node */
|
||||
void* data; /* user data */
|
||||
};
|
||||
|
||||
/* Quite often, the only additional piece of data you need is the per-item
|
||||
memory heap, so we have this generic struct available to use in those
|
||||
cases. */
|
||||
struct ib_list_helper_struct {
|
||||
mem_heap_t* heap; /* memory heap */
|
||||
void* data; /* user data */
|
||||
};
|
||||
|
||||
#ifndef UNIV_NONINL
|
||||
#include "ut0list.ic"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
23
include/ut0list.ic
Normal file
23
include/ut0list.ic
Normal file
@@ -0,0 +1,23 @@
|
||||
/********************************************************************
|
||||
Get the first node in the list. */
|
||||
UNIV_INLINE
|
||||
ib_list_node_t*
|
||||
ib_list_get_first(
|
||||
/*==============*/
|
||||
/* out: first node, or NULL */
|
||||
ib_list_t* list) /* in: list */
|
||||
{
|
||||
return(list->first);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Get the last node in the list. */
|
||||
UNIV_INLINE
|
||||
ib_list_node_t*
|
||||
ib_list_get_last(
|
||||
/*=============*/
|
||||
/* out: last node, or NULL */
|
||||
ib_list_t* list) /* in: list */
|
||||
{
|
||||
return(list->last);
|
||||
}
|
||||
60
include/ut0wqueue.h
Normal file
60
include/ut0wqueue.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/***********************************************************************
|
||||
A Work queue. Threads can add work items to the queue and other threads can
|
||||
wait for work items to be available and take them off the queue for
|
||||
processing.
|
||||
|
||||
************************************************************************/
|
||||
|
||||
#ifndef IB_WORK_QUEUE_H
|
||||
#define IB_WORK_QUEUE_H
|
||||
|
||||
#include "ut0list.h"
|
||||
#include "mem0mem.h"
|
||||
#include "os0sync.h"
|
||||
#include "sync0types.h"
|
||||
|
||||
typedef struct ib_wqueue_struct ib_wqueue_t;
|
||||
|
||||
/********************************************************************
|
||||
Create a new work queue. */
|
||||
|
||||
ib_wqueue_t*
|
||||
ib_wqueue_create(void);
|
||||
/*===================*/
|
||||
/* out: work queue */
|
||||
|
||||
/********************************************************************
|
||||
Free a work queue. */
|
||||
|
||||
void
|
||||
ib_wqueue_free(
|
||||
/*===========*/
|
||||
ib_wqueue_t* wq); /* in: work queue */
|
||||
|
||||
/********************************************************************
|
||||
Add a work item to the queue. */
|
||||
|
||||
void
|
||||
ib_wqueue_add(
|
||||
/*==========*/
|
||||
ib_wqueue_t* wq, /* in: work queue */
|
||||
void* item, /* in: work item */
|
||||
mem_heap_t* heap); /* in: memory heap to use for allocating the
|
||||
list node */
|
||||
|
||||
/********************************************************************
|
||||
Wait for a work item to appear in the queue. */
|
||||
|
||||
void*
|
||||
ib_wqueue_wait(
|
||||
/* out: work item */
|
||||
ib_wqueue_t* wq); /* in: work queue */
|
||||
|
||||
/* Work queue. */
|
||||
struct ib_wqueue_struct {
|
||||
mutex_t mutex; /* mutex protecting everything */
|
||||
ib_list_t* items; /* work item list */
|
||||
os_event_t event; /* event we use to signal additions to list */
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -741,8 +741,7 @@ log_init(void)
|
||||
|
||||
log_sys = mem_alloc(sizeof(log_t));
|
||||
|
||||
mutex_create(&(log_sys->mutex));
|
||||
mutex_set_level(&(log_sys->mutex), SYNC_LOG);
|
||||
mutex_create(&log_sys->mutex, SYNC_LOG);
|
||||
|
||||
mutex_enter(&(log_sys->mutex));
|
||||
|
||||
@@ -798,8 +797,7 @@ log_init(void)
|
||||
log_sys->last_checkpoint_lsn = log_sys->lsn;
|
||||
log_sys->n_pending_checkpoint_writes = 0;
|
||||
|
||||
rw_lock_create(&(log_sys->checkpoint_lock));
|
||||
rw_lock_set_level(&(log_sys->checkpoint_lock), SYNC_NO_ORDER_CHECK);
|
||||
rw_lock_create(&log_sys->checkpoint_lock, SYNC_NO_ORDER_CHECK);
|
||||
|
||||
log_sys->checkpoint_buf = ut_align(
|
||||
mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE),
|
||||
@@ -815,8 +813,7 @@ log_init(void)
|
||||
|
||||
log_sys->n_pending_archive_ios = 0;
|
||||
|
||||
rw_lock_create(&(log_sys->archive_lock));
|
||||
rw_lock_set_level(&(log_sys->archive_lock), SYNC_NO_ORDER_CHECK);
|
||||
rw_lock_create(&log_sys->archive_lock, SYNC_NO_ORDER_CHECK);
|
||||
|
||||
log_sys->archive_buf = NULL;
|
||||
|
||||
|
||||
@@ -113,8 +113,7 @@ recv_sys_create(void)
|
||||
|
||||
recv_sys = mem_alloc(sizeof(recv_sys_t));
|
||||
|
||||
mutex_create(&(recv_sys->mutex));
|
||||
mutex_set_level(&(recv_sys->mutex), SYNC_RECV);
|
||||
mutex_create(&recv_sys->mutex, SYNC_RECV);
|
||||
|
||||
recv_sys->heap = NULL;
|
||||
recv_sys->addr_hash = NULL;
|
||||
@@ -2969,7 +2968,6 @@ recv_recovery_from_checkpoint_finish(void)
|
||||
/*======================================*/
|
||||
{
|
||||
int i;
|
||||
os_thread_id_t recovery_thread_id;
|
||||
|
||||
/* Apply the hashed log records to the respective file pages */
|
||||
|
||||
@@ -3013,7 +3011,7 @@ recv_recovery_from_checkpoint_finish(void)
|
||||
session */
|
||||
|
||||
os_thread_create(trx_rollback_or_clean_all_without_sess,
|
||||
(void *)&i, &recovery_thread_id);
|
||||
(void *)&i, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -122,8 +122,7 @@ mem_init(
|
||||
/* Initialize the hash table */
|
||||
ut_a(FALSE == mem_hash_initialized);
|
||||
|
||||
mutex_create(&mem_hash_mutex);
|
||||
mutex_set_level(&mem_hash_mutex, SYNC_MEM_HASH);
|
||||
mutex_create(&mem_hash_mutex, SYNC_MEM_HASH);
|
||||
|
||||
for (i = 0; i < MEM_HASH_SIZE; i++) {
|
||||
UT_LIST_INIT(*mem_hash_get_nth_cell(i));
|
||||
|
||||
@@ -110,8 +110,46 @@ mem_heap_strdup(
|
||||
mem_heap_t* heap, /* in: memory heap where string is allocated */
|
||||
const char* str) /* in: string to be copied */
|
||||
{
|
||||
ulint len = strlen(str) + 1;
|
||||
return(memcpy(mem_heap_alloc(heap, len), str, len));
|
||||
return(mem_heap_dup(heap, str, strlen(str) + 1));
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Duplicate a block of data, allocated from a memory heap. */
|
||||
|
||||
void*
|
||||
mem_heap_dup(
|
||||
/*=========*/
|
||||
/* out, own: a copy of the data */
|
||||
mem_heap_t* heap, /* in: memory heap where copy is allocated */
|
||||
const void* data, /* in: data to be copied */
|
||||
ulint len) /* in: length of data, in bytes */
|
||||
{
|
||||
return(memcpy(mem_heap_alloc(heap, len), data, len));
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Concatenate two strings and return the result, using a memory heap. */
|
||||
|
||||
char*
|
||||
mem_heap_strcat(
|
||||
/*============*/
|
||||
/* out, own: the result */
|
||||
mem_heap_t* heap, /* in: memory heap where string is allocated */
|
||||
const char* s1, /* in: string 1 */
|
||||
const char* s2) /* in: string 2 */
|
||||
{
|
||||
char* s;
|
||||
ulint s1_len = strlen(s1);
|
||||
ulint s2_len = strlen(s2);
|
||||
|
||||
s = mem_heap_alloc(heap, s1_len + s2_len + 1);
|
||||
|
||||
memcpy(s, s1, s1_len);
|
||||
memcpy(s + s1_len, s2, s2_len);
|
||||
|
||||
s[s1_len + s2_len] = '\0';
|
||||
|
||||
return(s);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
|
||||
@@ -204,8 +204,7 @@ mem_pool_create(
|
||||
pool->buf = ut_malloc_low(size, FALSE, TRUE);
|
||||
pool->size = size;
|
||||
|
||||
mutex_create(&(pool->mutex));
|
||||
mutex_set_level(&(pool->mutex), SYNC_MEM_POOL);
|
||||
mutex_create(&pool->mutex, SYNC_MEM_POOL);
|
||||
|
||||
/* Initialize the free lists */
|
||||
|
||||
|
||||
@@ -1632,6 +1632,30 @@ t2 CREATE TABLE `t2` (
|
||||
CONSTRAINT `t2_ibfk_2` FOREIGN KEY (`b`) REFERENCES `t1` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
drop table t2, t1;
|
||||
flush status;
|
||||
show status like "binlog_cache_use";
|
||||
Variable_name Value
|
||||
Binlog_cache_use 0
|
||||
show status like "binlog_cache_disk_use";
|
||||
Variable_name Value
|
||||
Binlog_cache_disk_use 0
|
||||
create table t1 (a int) engine=innodb;
|
||||
show status like "binlog_cache_use";
|
||||
Variable_name Value
|
||||
Binlog_cache_use 1
|
||||
show status like "binlog_cache_disk_use";
|
||||
Variable_name Value
|
||||
Binlog_cache_disk_use 1
|
||||
begin;
|
||||
delete from t1;
|
||||
commit;
|
||||
show status like "binlog_cache_use";
|
||||
Variable_name Value
|
||||
Binlog_cache_use 2
|
||||
show status like "binlog_cache_disk_use";
|
||||
Variable_name Value
|
||||
Binlog_cache_disk_use 1
|
||||
drop table t1;
|
||||
create table t1 (c char(10), index (c,c)) engine=innodb;
|
||||
ERROR 42S21: Duplicate column name 'c'
|
||||
create table t1 (c1 char(10), c2 char(10), index (c1,c2,c1)) engine=innodb;
|
||||
@@ -3125,9 +3149,7 @@ SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
KEY `t2_ibfk_0` (`a`),
|
||||
CONSTRAINT `t2_ibfk_0` FOREIGN KEY (`a`) REFERENCES `t1` (`a`),
|
||||
CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`)
|
||||
KEY `t2_ibfk_0` (`a`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
DROP TABLE t2,t1;
|
||||
create table t1(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
|
||||
@@ -3206,6 +3228,46 @@ UPDATE t1 SET field1 = 'other' WHERE field2 = 'somevalu';
|
||||
ERROR 23000: Upholding foreign key constraints for table 't1', entry 'other-somevalu', key 1 would lead to a duplicate entry
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t1;
|
||||
create table t1 (
|
||||
c1 bigint not null,
|
||||
c2 bigint not null,
|
||||
primary key (c1),
|
||||
unique key (c2)
|
||||
) engine=innodb;
|
||||
create table t2 (
|
||||
c1 bigint not null,
|
||||
primary key (c1)
|
||||
) engine=innodb;
|
||||
alter table t1 add constraint c2_fk foreign key (c2)
|
||||
references t2(c1) on delete cascade;
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c1` bigint(20) NOT NULL,
|
||||
`c2` bigint(20) NOT NULL,
|
||||
PRIMARY KEY (`c1`),
|
||||
UNIQUE KEY `c2` (`c2`),
|
||||
CONSTRAINT `c2_fk` FOREIGN KEY (`c2`) REFERENCES `t2` (`c1`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
alter table t1 drop foreign key c2_fk;
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c1` bigint(20) NOT NULL,
|
||||
`c2` bigint(20) NOT NULL,
|
||||
PRIMARY KEY (`c1`),
|
||||
UNIQUE KEY `c2` (`c2`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
drop table t1, t2;
|
||||
create table t1(a date) engine=innodb;
|
||||
create table t2(a date, key(a)) engine=innodb;
|
||||
insert into t1 values('2005-10-01');
|
||||
insert into t2 values('2005-10-01');
|
||||
select * from t1, t2
|
||||
where t2.a between t1.a - interval 2 day and t1.a + interval 2 day;
|
||||
a a
|
||||
2005-10-01 2005-10-01
|
||||
drop table t1, t2;
|
||||
create table t1 (id int not null, f_id int not null, f int not null,
|
||||
primary key(f_id, id)) engine=innodb;
|
||||
create table t2 (id int not null,s_id int not null,s varchar(200),
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
#######################################################################
|
||||
# #
|
||||
# Please, DO NOT TOUCH this file as well as the innodb.result file. #
|
||||
# These files are to be modified ONLY BY INNOBASE guys. #
|
||||
# #
|
||||
# Use innodb_mysql.[test|result] files instead. #
|
||||
# #
|
||||
# If nevertheless you need to make some changes here, please, forward #
|
||||
# your commit message To: dev@innodb.com Cc: dev-innodb@mysql.com #
|
||||
# (otherwise your changes may be erased). #
|
||||
# #
|
||||
#######################################################################
|
||||
|
||||
-- source include/have_innodb.inc
|
||||
|
||||
#
|
||||
@@ -1133,6 +1146,41 @@ show create table t2;
|
||||
drop table t2, t1;
|
||||
|
||||
|
||||
#
|
||||
# Let us test binlog_cache_use and binlog_cache_disk_use status vars.
|
||||
# Actually this test has nothing to do with innodb per se, it just requires
|
||||
# transactional table.
|
||||
#
|
||||
flush status;
|
||||
show status like "binlog_cache_use";
|
||||
show status like "binlog_cache_disk_use";
|
||||
|
||||
create table t1 (a int) engine=innodb;
|
||||
|
||||
# Now we are going to create transaction which is long enough so its
|
||||
# transaction binlog will be flushed to disk...
|
||||
let $1=2000;
|
||||
disable_query_log;
|
||||
begin;
|
||||
while ($1)
|
||||
{
|
||||
eval insert into t1 values( $1 );
|
||||
dec $1;
|
||||
}
|
||||
commit;
|
||||
enable_query_log;
|
||||
show status like "binlog_cache_use";
|
||||
show status like "binlog_cache_disk_use";
|
||||
|
||||
# Transaction which should not be flushed to disk and so should not
|
||||
# increase binlog_cache_disk_use.
|
||||
begin;
|
||||
delete from t1;
|
||||
commit;
|
||||
show status like "binlog_cache_use";
|
||||
show status like "binlog_cache_disk_use";
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug #6126: Duplicate columns in keys gives misleading error message
|
||||
#
|
||||
@@ -2106,6 +2154,42 @@ UPDATE t1 SET field1 = 'other' WHERE field2 = 'somevalu';
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug#18477 - MySQL/InnoDB Ignoring Foreign Keys in ALTER TABLE
|
||||
#
|
||||
create table t1 (
|
||||
c1 bigint not null,
|
||||
c2 bigint not null,
|
||||
primary key (c1),
|
||||
unique key (c2)
|
||||
) engine=innodb;
|
||||
#
|
||||
create table t2 (
|
||||
c1 bigint not null,
|
||||
primary key (c1)
|
||||
) engine=innodb;
|
||||
#
|
||||
alter table t1 add constraint c2_fk foreign key (c2)
|
||||
references t2(c1) on delete cascade;
|
||||
show create table t1;
|
||||
#
|
||||
alter table t1 drop foreign key c2_fk;
|
||||
show create table t1;
|
||||
#
|
||||
drop table t1, t2;
|
||||
|
||||
#
|
||||
# Bug #14360: problem with intervals
|
||||
#
|
||||
|
||||
create table t1(a date) engine=innodb;
|
||||
create table t2(a date, key(a)) engine=innodb;
|
||||
insert into t1 values('2005-10-01');
|
||||
insert into t2 values('2005-10-01');
|
||||
select * from t1, t2
|
||||
where t2.a between t1.a - interval 2 day and t1.a + interval 2 day;
|
||||
drop table t1, t2;
|
||||
|
||||
create table t1 (id int not null, f_id int not null, f int not null,
|
||||
primary key(f_id, id)) engine=innodb;
|
||||
create table t2 (id int not null,s_id int not null,s varchar(200),
|
||||
|
||||
1
mysql-test/innodb_mysql.result
Normal file
1
mysql-test/innodb_mysql.result
Normal file
@@ -0,0 +1 @@
|
||||
drop table if exists t1;
|
||||
5
mysql-test/innodb_mysql.test
Normal file
5
mysql-test/innodb_mysql.test
Normal file
@@ -0,0 +1,5 @@
|
||||
-- source include/have_innodb.inc
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
--enable_warnings
|
||||
61
os/os0file.c
61
os/os0file.c
@@ -3679,6 +3679,37 @@ os_aio_posix_handle(
|
||||
}
|
||||
#endif
|
||||
|
||||
/**************************************************************************
|
||||
Do a 'last millisecond' check that the end of an uncompressed page is sensible;
|
||||
reported page checksum errors from Linux seem to wipe over the page end. */
|
||||
static
|
||||
void
|
||||
os_file_check_page_trailers(
|
||||
/*========================*/
|
||||
byte* combined_buf, /* in: combined write buffer */
|
||||
ulint total_len) /* in: size of combined_buf, in bytes
|
||||
(a multiple of UNIV_PAGE_SIZE) */
|
||||
{
|
||||
ulint len;
|
||||
|
||||
for (len = 0; len + UNIV_PAGE_SIZE <= total_len;
|
||||
len += UNIV_PAGE_SIZE) {
|
||||
byte* buf = combined_buf + len;
|
||||
|
||||
if (memcmp(buf + (FIL_PAGE_LSN + 4), buf + (UNIV_PAGE_SIZE
|
||||
- FIL_PAGE_END_LSN_OLD_CHKSUM + 4), 4)) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
" InnoDB: ERROR: The page to be written seems corrupt!\n"
|
||||
"InnoDB: Writing a block of %lu bytes, currently at offset %lu\n",
|
||||
(ulong)total_len, (ulong)len);
|
||||
buf_page_print(buf, 0);
|
||||
fprintf(stderr,
|
||||
"InnoDB: ERROR: The page to be written seems corrupt!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Does simulated aio. This function should be called by an i/o-handler
|
||||
thread. */
|
||||
@@ -3716,7 +3747,6 @@ os_aio_simulated_handle(
|
||||
ibool ret;
|
||||
ulint n;
|
||||
ulint i;
|
||||
ulint len2;
|
||||
|
||||
segment = os_aio_get_array_and_local_segment(&array, global_segment);
|
||||
|
||||
@@ -3924,34 +3954,15 @@ consecutive_loop:
|
||||
ut_error;
|
||||
}
|
||||
|
||||
/* Do a 'last millisecond' check that the page end
|
||||
is sensible; reported page checksum errors from
|
||||
Linux seem to wipe over the page end */
|
||||
|
||||
/* TODO: disable this for compressed pages */
|
||||
|
||||
for (len2 = 0; len2 + UNIV_PAGE_SIZE <= total_len;
|
||||
len2 += UNIV_PAGE_SIZE) {
|
||||
if (mach_read_from_4(combined_buf + len2
|
||||
+ FIL_PAGE_LSN + 4)
|
||||
!= mach_read_from_4(combined_buf + len2
|
||||
+ UNIV_PAGE_SIZE
|
||||
- FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
" InnoDB: ERROR: The page to be written seems corrupt!\n");
|
||||
fprintf(stderr,
|
||||
"InnoDB: Writing a block of %lu bytes, currently writing at offset %lu\n",
|
||||
(ulong)total_len, (ulong)len2);
|
||||
buf_page_print(combined_buf + len2, 0);
|
||||
fprintf(stderr,
|
||||
"InnoDB: ERROR: The page to be written seems corrupt!\n");
|
||||
}
|
||||
}
|
||||
os_file_check_page_trailers(combined_buf, total_len);
|
||||
}
|
||||
|
||||
ret = os_file_write(slot->name, slot->file, combined_buf,
|
||||
slot->offset, slot->offset_high, total_len);
|
||||
|
||||
if (array == os_aio_write_array) {
|
||||
os_file_check_page_trailers(combined_buf, total_len);
|
||||
}
|
||||
} else {
|
||||
ret = os_file_read(slot->file, combined_buf,
|
||||
slot->offset, slot->offset_high, total_len);
|
||||
|
||||
@@ -96,7 +96,7 @@ os_thread_create(
|
||||
void* arg, /* in: argument to start
|
||||
function */
|
||||
os_thread_id_t* thread_id) /* out: id of the created
|
||||
thread */
|
||||
thread, or NULL */
|
||||
{
|
||||
#ifdef __WIN__
|
||||
os_thread_t thread;
|
||||
@@ -122,7 +122,9 @@ os_thread_create(
|
||||
ut_a(SetThreadPriority(thread, srv_query_thread_priority));
|
||||
}
|
||||
|
||||
if (thread_id) {
|
||||
*thread_id = win_thread_id;
|
||||
}
|
||||
|
||||
return(thread);
|
||||
#else
|
||||
@@ -180,7 +182,9 @@ os_thread_create(
|
||||
my_pthread_setprio(pthread, srv_query_thread_priority);
|
||||
}
|
||||
|
||||
if (thread_id) {
|
||||
*thread_id = pthread;
|
||||
}
|
||||
|
||||
return(pthread);
|
||||
#endif
|
||||
@@ -216,7 +220,7 @@ os_thread_join(
|
||||
/*===========*/
|
||||
os_thread_id_t thread_id) /* in: id of the thread to join */
|
||||
{
|
||||
return pthread_join(thread_id, NULL);
|
||||
return(pthread_join(thread_id, NULL));
|
||||
}
|
||||
#endif
|
||||
/*********************************************************************
|
||||
|
||||
952
pars/lexyy.c
952
pars/lexyy.c
File diff suppressed because it is too large
Load Diff
@@ -84,6 +84,7 @@ string_append(
|
||||
DIGIT [0-9]
|
||||
ID [a-z_A-Z][a-z_A-Z0-9]*
|
||||
BOUND_LIT \:[a-z_A-Z0-9]+
|
||||
BOUND_ID \$[a-z_A-Z0-9]+
|
||||
|
||||
%x comment
|
||||
%x quoted
|
||||
@@ -111,6 +112,13 @@ BOUND_LIT \:[a-z_A-Z0-9]+
|
||||
return(type);
|
||||
}
|
||||
|
||||
{BOUND_ID} {
|
||||
yylval = sym_tab_add_bound_id(pars_sym_tab_global,
|
||||
yytext + 1);
|
||||
|
||||
return(PARS_ID_TOKEN);
|
||||
}
|
||||
|
||||
"'" {
|
||||
/* Quoted character string literals are handled in an explicit
|
||||
start state 'quoted'. This state is entered and the buffer for
|
||||
|
||||
@@ -1931,6 +1931,7 @@ pars_info_create(void)
|
||||
info->heap = heap;
|
||||
info->funcs = NULL;
|
||||
info->bound_lits = NULL;
|
||||
info->bound_ids = NULL;
|
||||
info->graph_owns_us = TRUE;
|
||||
|
||||
return(info);
|
||||
@@ -1963,6 +1964,8 @@ pars_info_add_literal(
|
||||
{
|
||||
pars_bound_lit_t* pbl;
|
||||
|
||||
ut_ad(!pars_info_get_bound_lit(info, name));
|
||||
|
||||
pbl = mem_heap_alloc(info->heap, sizeof(*pbl));
|
||||
|
||||
pbl->name = name;
|
||||
@@ -2053,6 +2056,8 @@ pars_info_add_function(
|
||||
{
|
||||
pars_user_func_t* puf;
|
||||
|
||||
ut_ad(!pars_info_get_user_func(info, name));
|
||||
|
||||
puf = mem_heap_alloc(info->heap, sizeof(*puf));
|
||||
|
||||
puf->name = name;
|
||||
@@ -2066,6 +2071,32 @@ pars_info_add_function(
|
||||
ib_vector_push(info->funcs, puf);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Add bound id. */
|
||||
|
||||
void
|
||||
pars_info_add_id(
|
||||
/*=============*/
|
||||
pars_info_t* info, /* in: info struct */
|
||||
const char* name, /* in: name */
|
||||
const char* id) /* in: id */
|
||||
{
|
||||
pars_bound_id_t* bid;
|
||||
|
||||
ut_ad(!pars_info_get_bound_id(info, name));
|
||||
|
||||
bid = mem_heap_alloc(info->heap, sizeof(*bid));
|
||||
|
||||
bid->name = name;
|
||||
bid->id = id;
|
||||
|
||||
if (!info->bound_ids) {
|
||||
info->bound_ids = ib_vector_create(info->heap, 8);
|
||||
}
|
||||
|
||||
ib_vector_push(info->bound_ids, bid);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Get user function with the given name.*/
|
||||
|
||||
@@ -2127,3 +2158,34 @@ pars_info_get_bound_lit(
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Get bound id with the given name.*/
|
||||
|
||||
pars_bound_id_t*
|
||||
pars_info_get_bound_id(
|
||||
/*===================*/
|
||||
/* out: bound id, or NULL if not
|
||||
found */
|
||||
pars_info_t* info, /* in: info struct */
|
||||
const char* name) /* in: bound id name to find */
|
||||
{
|
||||
ulint i;
|
||||
ib_vector_t* vec;
|
||||
|
||||
if (!info || !info->bound_ids) {
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
vec = info->bound_ids;
|
||||
|
||||
for (i = 0; i < ib_vector_size(vec); i++) {
|
||||
pars_bound_id_t* bid = ib_vector_get(vec, i);
|
||||
|
||||
if (strcmp(bid->name, name) == 0) {
|
||||
return(bid);
|
||||
}
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
@@ -304,3 +304,42 @@ sym_tab_add_id(
|
||||
|
||||
return(node);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
Add a bound identifier to a symbol table. */
|
||||
|
||||
sym_node_t*
|
||||
sym_tab_add_bound_id(
|
||||
/*===========*/
|
||||
/* out: symbol table node */
|
||||
sym_tab_t* sym_tab, /* in: symbol table */
|
||||
const char* name) /* in: name of bound id */
|
||||
{
|
||||
sym_node_t* node;
|
||||
pars_bound_id_t* bid;
|
||||
|
||||
bid = pars_info_get_bound_id(sym_tab->info, name);
|
||||
ut_a(bid);
|
||||
|
||||
node = mem_heap_alloc(sym_tab->heap, sizeof(sym_node_t));
|
||||
|
||||
node->common.type = QUE_NODE_SYMBOL;
|
||||
|
||||
node->resolved = FALSE;
|
||||
node->indirection = NULL;
|
||||
|
||||
node->name = mem_heap_strdup(sym_tab->heap, bid->id);
|
||||
node->name_len = strlen(node->name);
|
||||
|
||||
UT_LIST_ADD_LAST(sym_list, sym_tab->sym_list, node);
|
||||
|
||||
dfield_set_data(&(node->common.val), NULL, UNIV_SQL_NULL);
|
||||
|
||||
node->common.val_buf_size = 0;
|
||||
node->prefetch_buf = NULL;
|
||||
node->cursor_def = NULL;
|
||||
|
||||
node->sym_table = sym_tab;
|
||||
|
||||
return(node);
|
||||
}
|
||||
|
||||
@@ -1340,14 +1340,6 @@ loop:
|
||||
next_thr = que_thr_step(thr);
|
||||
/*-------------------------*/
|
||||
|
||||
/* Test the effect on performance of adding extra mutex
|
||||
reservations */
|
||||
|
||||
/* if (srv_test_extra_mutexes) {
|
||||
mutex_enter(&kernel_mutex);
|
||||
mutex_exit(&kernel_mutex);
|
||||
}
|
||||
*/
|
||||
loop_count++;
|
||||
|
||||
if (next_thr != thr) {
|
||||
|
||||
@@ -1519,8 +1519,7 @@ row_ins_check_foreign_constraints(
|
||||
if (foreign->foreign_index == index) {
|
||||
|
||||
if (foreign->referenced_table == NULL) {
|
||||
dict_table_get(foreign->referenced_table_name,
|
||||
trx);
|
||||
dict_table_get(foreign->referenced_table_name);
|
||||
}
|
||||
|
||||
if (0 == trx->dict_operation_lock_mode) {
|
||||
|
||||
676
row/row0mysql.c
676
row/row0mysql.c
@@ -2384,11 +2384,9 @@ row_discard_tablespace_for_mysql(
|
||||
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;
|
||||
pars_info_t* info = NULL;
|
||||
|
||||
/* How do we prevent crashes caused by ongoing operations on the table? Old
|
||||
operations could try to access non-existent pages.
|
||||
@@ -2410,36 +2408,6 @@ discard ongoing operations.
|
||||
5) FOREIGN KEY operations: if table->n_foreign_key_checks_running > 0, we
|
||||
do not allow the discard. We also reserve the data dictionary latch. */
|
||||
|
||||
static const char discard_tablespace_proc1[] =
|
||||
"PROCEDURE DISCARD_TABLESPACE_PROC () IS\n"
|
||||
"old_id CHAR;\n"
|
||||
"new_id CHAR;\n"
|
||||
"new_id_low INT;\n"
|
||||
"new_id_high INT;\n"
|
||||
"table_name CHAR;\n"
|
||||
"BEGIN\n"
|
||||
"table_name := '";
|
||||
static const char discard_tablespace_proc2[] =
|
||||
"';\n"
|
||||
"new_id_high := %lu;\n"
|
||||
"new_id_low := %lu;\n"
|
||||
"new_id := CONCAT(TO_BINARY(new_id_high, 4), TO_BINARY(new_id_low, 4));\n"
|
||||
"SELECT ID INTO old_id\n"
|
||||
"FROM SYS_TABLES\n"
|
||||
"WHERE NAME = table_name;\n"
|
||||
"IF (SQL %% NOTFOUND) THEN\n"
|
||||
" COMMIT WORK;\n"
|
||||
" RETURN;\n"
|
||||
"END IF;\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());
|
||||
|
||||
trx->op_info = "discarding tablespace";
|
||||
@@ -2519,35 +2487,34 @@ do not allow the discard. We also reserve the data dictionary latch. */
|
||||
|
||||
new_id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID);
|
||||
|
||||
buf = mem_alloc((sizeof discard_tablespace_proc1) +
|
||||
(sizeof discard_tablespace_proc2) +
|
||||
20 + ut_strlenq(name, '\''));
|
||||
|
||||
memcpy(buf, discard_tablespace_proc1, sizeof discard_tablespace_proc1);
|
||||
sprintf(ut_strcpyq(buf + (sizeof discard_tablespace_proc1 - 1),
|
||||
'\'', name),
|
||||
discard_tablespace_proc2,
|
||||
(ulong) ut_dulint_get_high(new_id),
|
||||
(ulong) ut_dulint_get_low(new_id));
|
||||
|
||||
graph = pars_sql(NULL, buf);
|
||||
|
||||
ut_a(graph);
|
||||
|
||||
/* Remove any locks there are on the table or its records */
|
||||
|
||||
lock_reset_all_on_table(table);
|
||||
|
||||
graph->trx = trx;
|
||||
trx->graph = NULL;
|
||||
info = pars_info_create();
|
||||
|
||||
graph->fork_type = QUE_FORK_MYSQL_INTERFACE;
|
||||
pars_info_add_str_literal(info, "table_name", name);
|
||||
pars_info_add_dulint_literal(info, "new_id", new_id);
|
||||
|
||||
ut_a(thr = que_fork_start_command(graph));
|
||||
|
||||
que_run_threads(thr);
|
||||
|
||||
err = trx->error_state;
|
||||
err = que_eval_sql(info,
|
||||
"PROCEDURE DISCARD_TABLESPACE_PROC () IS\n"
|
||||
"old_id CHAR;\n"
|
||||
"BEGIN\n"
|
||||
"SELECT ID INTO old_id\n"
|
||||
"FROM SYS_TABLES\n"
|
||||
"WHERE NAME = :table_name;\n"
|
||||
"IF (SQL % NOTFOUND) THEN\n"
|
||||
" COMMIT WORK;\n"
|
||||
" RETURN;\n"
|
||||
"END IF;\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"
|
||||
, trx);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
trx->error_state = DB_SUCCESS;
|
||||
@@ -2571,13 +2538,10 @@ do not allow the discard. We also reserve the data dictionary latch. */
|
||||
table->ibd_file_missing = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
funct_exit:
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
|
||||
if (graph) {
|
||||
que_graph_free(graph);
|
||||
}
|
||||
|
||||
trx_commit_for_mysql(trx);
|
||||
|
||||
trx->op_info = "";
|
||||
@@ -2738,9 +2702,7 @@ row_truncate_table_for_mysql(
|
||||
btr_pcur_t pcur;
|
||||
mtr_t mtr;
|
||||
dulint new_id;
|
||||
char* sql;
|
||||
que_thr_t* thr;
|
||||
que_t* graph = NULL;
|
||||
pars_info_t* info = NULL;
|
||||
|
||||
/* How do we prevent crashes caused by ongoing operations on the table? Old
|
||||
operations could try to access non-existent pages.
|
||||
@@ -2768,30 +2730,6 @@ 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);
|
||||
|
||||
@@ -2952,35 +2890,27 @@ do not allow the TRUNCATE. We also reserve the data dictionary latch. */
|
||||
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(NULL, sql);
|
||||
|
||||
ut_a(graph);
|
||||
|
||||
mem_heap_free(heap);
|
||||
|
||||
graph->trx = trx;
|
||||
trx->graph = NULL;
|
||||
new_id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID);
|
||||
|
||||
graph->fork_type = QUE_FORK_MYSQL_INTERFACE;
|
||||
info = pars_info_create();
|
||||
|
||||
thr = que_fork_start_command(graph);
|
||||
ut_a(thr);
|
||||
pars_info_add_dulint_literal(info, "old_id", table->id);
|
||||
pars_info_add_dulint_literal(info, "new_id", new_id);
|
||||
|
||||
que_run_threads(thr);
|
||||
|
||||
que_graph_free(graph);
|
||||
|
||||
err = trx->error_state;
|
||||
err = que_eval_sql(info,
|
||||
"PROCEDURE RENUMBER_TABLESPACE_PROC () IS\n"
|
||||
"BEGIN\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"
|
||||
, trx);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
trx->error_state = DB_SUCCESS;
|
||||
@@ -3030,83 +2960,13 @@ row_drop_table_for_mysql(
|
||||
dict_foreign_t* foreign;
|
||||
dict_table_t* table;
|
||||
ulint space_id;
|
||||
que_thr_t* thr;
|
||||
que_t* graph;
|
||||
ulint err;
|
||||
const char* table_name;
|
||||
ulint namelen;
|
||||
char* dir_path_of_temp_table = NULL;
|
||||
ibool success;
|
||||
ibool locked_dictionary = FALSE;
|
||||
char* quoted_name;
|
||||
char* sql;
|
||||
|
||||
/* We use the private SQL parser of Innobase to generate the
|
||||
query graphs needed in deleting the dictionary data from system
|
||||
tables in Innobase. Deleting a row from SYS_INDEXES table also
|
||||
frees the file segments of the B-tree associated with the index. */
|
||||
|
||||
static const char str1[] =
|
||||
"PROCEDURE DROP_TABLE_PROC () IS\n"
|
||||
"table_name CHAR;\n"
|
||||
"sys_foreign_id CHAR;\n"
|
||||
"table_id CHAR;\n"
|
||||
"index_id CHAR;\n"
|
||||
"foreign_id CHAR;\n"
|
||||
"found INT;\n"
|
||||
"BEGIN\n"
|
||||
"table_name := ";
|
||||
static const char str2[] =
|
||||
";\n"
|
||||
"SELECT ID INTO table_id\n"
|
||||
"FROM SYS_TABLES\n"
|
||||
"WHERE NAME = table_name;\n"
|
||||
"IF (SQL % NOTFOUND) THEN\n"
|
||||
" COMMIT WORK;\n"
|
||||
" RETURN;\n"
|
||||
"END IF;\n"
|
||||
"found := 1;\n"
|
||||
"SELECT ID INTO sys_foreign_id\n"
|
||||
"FROM SYS_TABLES\n"
|
||||
"WHERE NAME = 'SYS_FOREIGN';\n"
|
||||
"IF (SQL % NOTFOUND) THEN\n"
|
||||
" found := 0;\n"
|
||||
"END IF;\n"
|
||||
"IF (table_name = 'SYS_FOREIGN') THEN\n"
|
||||
" found := 0;\n"
|
||||
"END IF;\n"
|
||||
"IF (table_name = 'SYS_FOREIGN_COLS') THEN\n"
|
||||
" found := 0;\n"
|
||||
"END IF;\n"
|
||||
"WHILE found = 1 LOOP\n"
|
||||
" SELECT ID INTO foreign_id\n"
|
||||
" FROM SYS_FOREIGN\n"
|
||||
" WHERE FOR_NAME = table_name\n"
|
||||
" AND TO_BINARY(FOR_NAME) = TO_BINARY(table_name);\n"
|
||||
" IF (SQL % NOTFOUND) THEN\n"
|
||||
" found := 0;\n"
|
||||
" ELSE"
|
||||
" DELETE FROM SYS_FOREIGN_COLS WHERE ID = foreign_id;\n"
|
||||
" DELETE FROM SYS_FOREIGN WHERE ID = foreign_id;\n"
|
||||
" END IF;\n"
|
||||
"END LOOP;\n"
|
||||
"found := 1;\n"
|
||||
"WHILE found = 1 LOOP\n"
|
||||
" SELECT ID INTO index_id\n"
|
||||
" FROM SYS_INDEXES\n"
|
||||
" WHERE TABLE_ID = table_id;\n"
|
||||
" IF (SQL % NOTFOUND) THEN\n"
|
||||
" found := 0;\n"
|
||||
" ELSE"
|
||||
" DELETE FROM SYS_FIELDS WHERE INDEX_ID = index_id;\n"
|
||||
" DELETE FROM SYS_INDEXES WHERE ID = index_id\n"
|
||||
" AND TABLE_ID = table_id;\n"
|
||||
" END IF;\n"
|
||||
"END LOOP;\n"
|
||||
"DELETE FROM SYS_COLUMNS WHERE TABLE_ID = table_id;\n"
|
||||
"DELETE FROM SYS_TABLES WHERE ID = table_id;\n"
|
||||
"COMMIT WORK;\n"
|
||||
"END;\n";
|
||||
pars_info_t* info = NULL;
|
||||
|
||||
ut_a(name != NULL);
|
||||
|
||||
@@ -3161,14 +3021,6 @@ row_drop_table_for_mysql(
|
||||
srv_print_innodb_table_monitor = FALSE;
|
||||
}
|
||||
|
||||
quoted_name = mem_strdupq(name, '\'');
|
||||
namelen = strlen(quoted_name);
|
||||
sql = mem_alloc((sizeof str1) + (sizeof str2) - 2 + 1 + namelen);
|
||||
memcpy(sql, str1, (sizeof str1) - 1);
|
||||
memcpy(sql + (sizeof str1) - 1, quoted_name, namelen);
|
||||
memcpy(sql + (sizeof str1) - 1 + namelen, str2, sizeof str2);
|
||||
mem_free(quoted_name);
|
||||
|
||||
/* Serialize data dictionary operations with dictionary mutex:
|
||||
no deadlocks can occur then in these operations */
|
||||
|
||||
@@ -3186,16 +3038,6 @@ row_drop_table_for_mysql(
|
||||
ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX));
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
graph = pars_sql(NULL, sql);
|
||||
|
||||
ut_a(graph);
|
||||
mem_free(sql);
|
||||
|
||||
graph->trx = trx;
|
||||
trx->graph = NULL;
|
||||
|
||||
graph->fork_type = QUE_FORK_MYSQL_INTERFACE;
|
||||
|
||||
table = dict_table_get_low(name);
|
||||
|
||||
if (!table) {
|
||||
@@ -3319,18 +3161,80 @@ fputs(" InnoDB: You are trying to drop table ", stderr);
|
||||
trx->dict_operation = TRUE;
|
||||
trx->table_id = table->id;
|
||||
|
||||
ut_a(thr = que_fork_start_command(graph));
|
||||
/* We use the private SQL parser of Innobase to generate the
|
||||
query graphs needed in deleting the dictionary data from system
|
||||
tables in Innobase. Deleting a row from SYS_INDEXES table also
|
||||
frees the file segments of the B-tree associated with the index. */
|
||||
|
||||
que_run_threads(thr);
|
||||
info = pars_info_create();
|
||||
|
||||
err = trx->error_state;
|
||||
pars_info_add_str_literal(info, "table_name", name);
|
||||
|
||||
err = que_eval_sql(info,
|
||||
"PROCEDURE DROP_TABLE_PROC () IS\n"
|
||||
"sys_foreign_id CHAR;\n"
|
||||
"table_id CHAR;\n"
|
||||
"index_id CHAR;\n"
|
||||
"foreign_id CHAR;\n"
|
||||
"found INT;\n"
|
||||
"BEGIN\n"
|
||||
"SELECT ID INTO table_id\n"
|
||||
"FROM SYS_TABLES\n"
|
||||
"WHERE NAME = :table_name;\n"
|
||||
"IF (SQL % NOTFOUND) THEN\n"
|
||||
" COMMIT WORK;\n"
|
||||
" RETURN;\n"
|
||||
"END IF;\n"
|
||||
"found := 1;\n"
|
||||
"SELECT ID INTO sys_foreign_id\n"
|
||||
"FROM SYS_TABLES\n"
|
||||
"WHERE NAME = 'SYS_FOREIGN';\n"
|
||||
"IF (SQL % NOTFOUND) THEN\n"
|
||||
" found := 0;\n"
|
||||
"END IF;\n"
|
||||
"IF (:table_name = 'SYS_FOREIGN') THEN\n"
|
||||
" found := 0;\n"
|
||||
"END IF;\n"
|
||||
"IF (:table_name = 'SYS_FOREIGN_COLS') THEN\n"
|
||||
" found := 0;\n"
|
||||
"END IF;\n"
|
||||
"WHILE found = 1 LOOP\n"
|
||||
" SELECT ID INTO foreign_id\n"
|
||||
" FROM SYS_FOREIGN\n"
|
||||
" WHERE FOR_NAME = :table_name\n"
|
||||
" AND TO_BINARY(FOR_NAME) = TO_BINARY(:table_name);\n"
|
||||
" IF (SQL % NOTFOUND) THEN\n"
|
||||
" found := 0;\n"
|
||||
" ELSE"
|
||||
" DELETE FROM SYS_FOREIGN_COLS WHERE ID = foreign_id;\n"
|
||||
" DELETE FROM SYS_FOREIGN WHERE ID = foreign_id;\n"
|
||||
" END IF;\n"
|
||||
"END LOOP;\n"
|
||||
"found := 1;\n"
|
||||
"WHILE found = 1 LOOP\n"
|
||||
" SELECT ID INTO index_id\n"
|
||||
" FROM SYS_INDEXES\n"
|
||||
" WHERE TABLE_ID = table_id;\n"
|
||||
" IF (SQL % NOTFOUND) THEN\n"
|
||||
" found := 0;\n"
|
||||
" ELSE"
|
||||
" DELETE FROM SYS_FIELDS WHERE INDEX_ID = index_id;\n"
|
||||
" DELETE FROM SYS_INDEXES WHERE ID = index_id\n"
|
||||
" AND TABLE_ID = table_id;\n"
|
||||
" END IF;\n"
|
||||
"END LOOP;\n"
|
||||
"DELETE FROM SYS_COLUMNS WHERE TABLE_ID = table_id;\n"
|
||||
"DELETE FROM SYS_TABLES WHERE ID = table_id;\n"
|
||||
"COMMIT WORK;\n"
|
||||
"END;\n"
|
||||
, trx);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
ut_a(err == DB_OUT_OF_FILE_SPACE);
|
||||
|
||||
err = DB_MUST_GET_MORE_FILE_SPACE;
|
||||
|
||||
row_mysql_handle_errors(&err, trx, thr, NULL);
|
||||
row_mysql_handle_errors(&err, trx, NULL, NULL);
|
||||
|
||||
ut_error;
|
||||
} else {
|
||||
@@ -3408,8 +3312,6 @@ funct_exit:
|
||||
mem_free(dir_path_of_temp_table);
|
||||
}
|
||||
|
||||
que_graph_free(graph);
|
||||
|
||||
trx_commit_for_mysql(trx);
|
||||
|
||||
trx->op_info = "";
|
||||
@@ -3514,6 +3416,62 @@ row_is_mysql_tmp_table_name(
|
||||
return(strstr(name, "/@0023sql") != NULL);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Delete a single constraint. */
|
||||
static
|
||||
int
|
||||
row_delete_constraint_low(
|
||||
/*======================*/
|
||||
/* out: error code or DB_SUCCESS */
|
||||
const char* id, /* in: constraint id */
|
||||
trx_t* trx) /* in: transaction handle */
|
||||
{
|
||||
pars_info_t* info = pars_info_create();
|
||||
|
||||
pars_info_add_str_literal(info, "id", id);
|
||||
|
||||
return(que_eval_sql(info,
|
||||
"PROCEDURE DELETE_CONSTRAINT () IS\n"
|
||||
"BEGIN\n"
|
||||
"DELETE FROM SYS_FOREIGN_COLS WHERE ID = :id;\n"
|
||||
"DELETE FROM SYS_FOREIGN WHERE ID = :id;\n"
|
||||
"END;\n"
|
||||
, trx));
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Delete a single constraint. */
|
||||
static
|
||||
int
|
||||
row_delete_constraint(
|
||||
/*==================*/
|
||||
/* out: error code or DB_SUCCESS */
|
||||
const char* id, /* in: constraint id */
|
||||
const char* database_name, /* in: database name, with the
|
||||
trailing '/' */
|
||||
mem_heap_t* heap, /* in: memory heap */
|
||||
trx_t* trx) /* in: transaction handle */
|
||||
{
|
||||
ulint err;
|
||||
|
||||
/* New format constraints have ids <databasename>/<constraintname>. */
|
||||
err = row_delete_constraint_low(
|
||||
mem_heap_strcat(heap, database_name, id), trx);
|
||||
|
||||
if ((err == DB_SUCCESS) && !strchr(id, '/')) {
|
||||
/* Old format < 4.0.18 constraints have constraint ids
|
||||
<number>_<number>. We only try deleting them if the
|
||||
constraint name does not contain a '/' character, otherwise
|
||||
deleting a new format constraint named 'foo/bar' from
|
||||
database 'baz' would remove constraint 'bar' from database
|
||||
'foo', if it existed. */
|
||||
|
||||
err = row_delete_constraint_low(id, trx);
|
||||
}
|
||||
|
||||
return(err);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Renames a table for MySQL. */
|
||||
|
||||
@@ -3526,100 +3484,13 @@ row_rename_table_for_mysql(
|
||||
trx_t* trx) /* in: transaction handle */
|
||||
{
|
||||
dict_table_t* table;
|
||||
que_thr_t* thr;
|
||||
que_t* graph = NULL;
|
||||
ulint err;
|
||||
/* We use the private SQL parser of Innobase to generate the
|
||||
query graphs needed in deleting the dictionary data from system
|
||||
tables in Innobase. Deleting a row from SYS_INDEXES table also
|
||||
frees the file segments of the B-tree associated with the index. */
|
||||
static const char str1[] =
|
||||
"PROCEDURE RENAME_TABLE_PROC () IS\n"
|
||||
"new_table_name CHAR;\n"
|
||||
"old_table_name CHAR;\n"
|
||||
"gen_constr_prefix CHAR;\n"
|
||||
"new_db_name CHAR;\n"
|
||||
"foreign_id CHAR;\n"
|
||||
"new_foreign_id CHAR;\n"
|
||||
"old_db_name_len INT;\n"
|
||||
"old_t_name_len INT;\n"
|
||||
"new_db_name_len INT;\n"
|
||||
"id_len INT;\n"
|
||||
"found INT;\n"
|
||||
"BEGIN\n"
|
||||
"new_table_name := '";
|
||||
static const char str2[] =
|
||||
"';\nold_table_name := '";
|
||||
static const char str3[] =
|
||||
"';\n"
|
||||
"UPDATE SYS_TABLES SET NAME = new_table_name\n"
|
||||
"WHERE NAME = old_table_name;\n";
|
||||
static const char str4a1[] = /* drop some constraints of tmp tables */
|
||||
"DELETE FROM SYS_FOREIGN_COLS WHERE ID = '";
|
||||
static const char str4a2[] = "';\n"
|
||||
"DELETE FROM SYS_FOREIGN WHERE ID = '";
|
||||
static const char str4a3[] = "';\n";
|
||||
static const char str4b[] = /* rename all constraints */
|
||||
"found := 1;\n"
|
||||
"old_db_name_len := INSTR(old_table_name, '/') - 1;\n"
|
||||
"new_db_name_len := INSTR(new_table_name, '/') - 1;\n"
|
||||
"new_db_name := SUBSTR(new_table_name, 0, new_db_name_len);\n"
|
||||
"old_t_name_len := LENGTH(old_table_name);\n"
|
||||
"gen_constr_prefix := CONCAT(old_table_name, '_ibfk_');\n"
|
||||
"WHILE found = 1 LOOP\n"
|
||||
" SELECT ID INTO foreign_id\n"
|
||||
" FROM SYS_FOREIGN\n"
|
||||
" WHERE FOR_NAME = old_table_name\n"
|
||||
" AND TO_BINARY(FOR_NAME) = TO_BINARY(old_table_name);\n"
|
||||
" IF (SQL % NOTFOUND) THEN\n"
|
||||
" found := 0;\n"
|
||||
" ELSE\n"
|
||||
" UPDATE SYS_FOREIGN\n"
|
||||
" SET FOR_NAME = new_table_name\n"
|
||||
" WHERE ID = foreign_id;\n"
|
||||
" id_len := LENGTH(foreign_id);\n"
|
||||
" IF (INSTR(foreign_id, '/') > 0) THEN\n"
|
||||
" IF (INSTR(foreign_id,\n"
|
||||
" gen_constr_prefix) > 0)\n"
|
||||
" THEN\n"
|
||||
" new_foreign_id :=\n"
|
||||
" CONCAT(new_table_name,\n"
|
||||
" SUBSTR(foreign_id, old_t_name_len,\n"
|
||||
" id_len - old_t_name_len));\n"
|
||||
" ELSE\n"
|
||||
" new_foreign_id :=\n"
|
||||
" CONCAT(new_db_name,\n"
|
||||
" SUBSTR(foreign_id,\n"
|
||||
" old_db_name_len,\n"
|
||||
" id_len - old_db_name_len));\n"
|
||||
" END IF;\n"
|
||||
" UPDATE SYS_FOREIGN\n"
|
||||
" SET ID = new_foreign_id\n"
|
||||
" WHERE ID = foreign_id;\n"
|
||||
" UPDATE SYS_FOREIGN_COLS\n"
|
||||
" SET ID = new_foreign_id\n"
|
||||
" WHERE ID = foreign_id;\n"
|
||||
" END IF;\n"
|
||||
" END IF;\n"
|
||||
"END LOOP;\n"
|
||||
"UPDATE SYS_FOREIGN SET REF_NAME = new_table_name\n"
|
||||
"WHERE REF_NAME = old_table_name\n"
|
||||
" AND TO_BINARY(REF_NAME) = TO_BINARY(old_table_name);\n";
|
||||
static const char str5[] =
|
||||
"END;\n";
|
||||
|
||||
mem_heap_t* heap = NULL;
|
||||
const char** constraints_to_drop = NULL;
|
||||
ulint n_constraints_to_drop = 0;
|
||||
ibool recovering_temp_table = FALSE;
|
||||
ibool old_is_tmp, new_is_tmp;
|
||||
ulint len;
|
||||
ulint i;
|
||||
ibool success;
|
||||
/* length of database name; 0 if not renaming to a temporary table */
|
||||
ulint db_name_len;
|
||||
char* sql;
|
||||
char* sqlend;
|
||||
pars_info_t* info = NULL;
|
||||
|
||||
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
|
||||
ut_a(old_name != NULL);
|
||||
@@ -3697,13 +3568,7 @@ row_rename_table_for_mysql(
|
||||
goto funct_exit;
|
||||
}
|
||||
|
||||
/* calculate the length of the SQL string */
|
||||
len = (sizeof str1) + (sizeof str2) + (sizeof str3) + (sizeof str5) - 4
|
||||
+ ut_strlenq(new_name, '\'') + ut_strlenq(old_name, '\'');
|
||||
|
||||
if (new_is_tmp) {
|
||||
db_name_len = dict_get_db_name_len(old_name) + 1;
|
||||
|
||||
/* 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
|
||||
@@ -3713,110 +3578,124 @@ row_rename_table_for_mysql(
|
||||
heap = mem_heap_create(100);
|
||||
|
||||
err = dict_foreign_parse_drop_constraints(heap, trx,
|
||||
table,
|
||||
&n_constraints_to_drop,
|
||||
&constraints_to_drop);
|
||||
table, &n_constraints_to_drop, &constraints_to_drop);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
goto funct_exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* reserve space for all database names */
|
||||
len += 2 * n_constraints_to_drop
|
||||
* (ut_strlenq(old_name, '\'')
|
||||
- ut_strlenq(old_name + db_name_len, '\''));
|
||||
/* We use the private SQL parser of Innobase to generate the query
|
||||
graphs needed in deleting the dictionary data from system tables in
|
||||
Innobase. Deleting a row from SYS_INDEXES table also frees the file
|
||||
segments of the B-tree associated with the index. */
|
||||
|
||||
info = pars_info_create();
|
||||
|
||||
pars_info_add_str_literal(info, "new_table_name", new_name);
|
||||
pars_info_add_str_literal(info, "old_table_name", old_name);
|
||||
|
||||
err = que_eval_sql(info,
|
||||
"PROCEDURE RENAME_TABLE () IS\n"
|
||||
"BEGIN\n"
|
||||
"UPDATE SYS_TABLES SET NAME = :new_table_name\n"
|
||||
" WHERE NAME = :old_table_name;\n"
|
||||
"END;\n"
|
||||
, trx);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!new_is_tmp) {
|
||||
/* Rename all constraints. */
|
||||
|
||||
info = pars_info_create();
|
||||
|
||||
pars_info_add_str_literal(info, "new_table_name", new_name);
|
||||
pars_info_add_str_literal(info, "old_table_name", old_name);
|
||||
|
||||
err = que_eval_sql(info,
|
||||
"PROCEDURE RENAME_CONSTRAINT_IDS () IS\n"
|
||||
"gen_constr_prefix CHAR;\n"
|
||||
"new_db_name CHAR;\n"
|
||||
"foreign_id CHAR;\n"
|
||||
"new_foreign_id CHAR;\n"
|
||||
"old_db_name_len INT;\n"
|
||||
"old_t_name_len INT;\n"
|
||||
"new_db_name_len INT;\n"
|
||||
"id_len INT;\n"
|
||||
"found INT;\n"
|
||||
"BEGIN\n"
|
||||
"found := 1;\n"
|
||||
"old_db_name_len := INSTR(:old_table_name, '/') - 1;\n"
|
||||
"new_db_name_len := INSTR(:new_table_name, '/') - 1;\n"
|
||||
"new_db_name := SUBSTR(:new_table_name, 0, new_db_name_len);\n"
|
||||
"old_t_name_len := LENGTH(:old_table_name);\n"
|
||||
"gen_constr_prefix := CONCAT(:old_table_name, '_ibfk_');\n"
|
||||
"WHILE found = 1 LOOP\n"
|
||||
" SELECT ID INTO foreign_id\n"
|
||||
" FROM SYS_FOREIGN\n"
|
||||
" WHERE FOR_NAME = :old_table_name\n"
|
||||
" AND TO_BINARY(FOR_NAME) = TO_BINARY(:old_table_name);\n"
|
||||
" IF (SQL % NOTFOUND) THEN\n"
|
||||
" found := 0;\n"
|
||||
" ELSE\n"
|
||||
" UPDATE SYS_FOREIGN\n"
|
||||
" SET FOR_NAME = :new_table_name\n"
|
||||
" WHERE ID = foreign_id;\n"
|
||||
" id_len := LENGTH(foreign_id);\n"
|
||||
" IF (INSTR(foreign_id, '/') > 0) THEN\n"
|
||||
" IF (INSTR(foreign_id,\n"
|
||||
" gen_constr_prefix) > 0)\n"
|
||||
" THEN\n"
|
||||
" new_foreign_id :=\n"
|
||||
" CONCAT(:new_table_name,\n"
|
||||
" SUBSTR(foreign_id, old_t_name_len,\n"
|
||||
" id_len - old_t_name_len));\n"
|
||||
" ELSE\n"
|
||||
" new_foreign_id :=\n"
|
||||
" CONCAT(new_db_name,\n"
|
||||
" SUBSTR(foreign_id,\n"
|
||||
" old_db_name_len,\n"
|
||||
" id_len - old_db_name_len));\n"
|
||||
" END IF;\n"
|
||||
" UPDATE SYS_FOREIGN\n"
|
||||
" SET ID = new_foreign_id\n"
|
||||
" WHERE ID = foreign_id;\n"
|
||||
" UPDATE SYS_FOREIGN_COLS\n"
|
||||
" SET ID = new_foreign_id\n"
|
||||
" WHERE ID = foreign_id;\n"
|
||||
" END IF;\n"
|
||||
" END IF;\n"
|
||||
"END LOOP;\n"
|
||||
"UPDATE SYS_FOREIGN SET REF_NAME = :new_table_name\n"
|
||||
"WHERE REF_NAME = :old_table_name\n"
|
||||
" AND TO_BINARY(REF_NAME) = TO_BINARY(:old_table_name);\n"
|
||||
"END;\n"
|
||||
, trx);
|
||||
|
||||
} else if (n_constraints_to_drop > 0) {
|
||||
/* Drop some constraints of tmp tables. */
|
||||
|
||||
ulint db_name_len = dict_get_db_name_len(old_name) + 1;
|
||||
char* db_name = mem_heap_strdupl(heap, old_name,
|
||||
db_name_len);
|
||||
ulint i;
|
||||
|
||||
for (i = 0; i < n_constraints_to_drop; i++) {
|
||||
ulint addlen
|
||||
= 2 * ut_strlenq(constraints_to_drop[i], '\'')
|
||||
+ ((sizeof str4a1) + (sizeof str4a2)
|
||||
+ (sizeof str4a3) - 3);
|
||||
if (!strchr(constraints_to_drop[i], '/')) {
|
||||
addlen *= 2;
|
||||
}
|
||||
len += addlen;
|
||||
}
|
||||
} else {
|
||||
db_name_len = 0;
|
||||
len += (sizeof str4b) - 1;
|
||||
}
|
||||
err = row_delete_constraint(constraints_to_drop[i],
|
||||
db_name, heap, trx);
|
||||
|
||||
sql = sqlend = mem_alloc(len + 1);
|
||||
memcpy(sql, str1, (sizeof str1) - 1);
|
||||
sqlend += (sizeof str1) - 1;
|
||||
sqlend = ut_strcpyq(sqlend, '\'', new_name);
|
||||
memcpy(sqlend, str2, (sizeof str2) - 1);
|
||||
sqlend += (sizeof str2) - 1;
|
||||
sqlend = ut_strcpyq(sqlend, '\'', old_name);
|
||||
memcpy(sqlend, str3, (sizeof str3) - 1);
|
||||
sqlend += (sizeof str3) - 1;
|
||||
|
||||
if (db_name_len) {
|
||||
/* Internally, old format < 4.0.18 constraints have as the
|
||||
constraint id <number>_<number>, while new format constraints
|
||||
have <databasename>/<constraintname>. */
|
||||
|
||||
for (i = 0; i < n_constraints_to_drop; i++) {
|
||||
memcpy(sqlend, str4a1, (sizeof str4a1) - 1);
|
||||
sqlend += (sizeof str4a1) - 1;
|
||||
sqlend = ut_memcpyq(sqlend, '\'',
|
||||
old_name, db_name_len);
|
||||
sqlend = ut_strcpyq(sqlend, '\'',
|
||||
constraints_to_drop[i]);
|
||||
memcpy(sqlend, str4a2, (sizeof str4a2) - 1);
|
||||
sqlend += (sizeof str4a2) - 1;
|
||||
sqlend = ut_memcpyq(sqlend, '\'',
|
||||
old_name, db_name_len);
|
||||
sqlend = ut_strcpyq(sqlend, '\'',
|
||||
constraints_to_drop[i]);
|
||||
memcpy(sqlend, str4a3, (sizeof str4a3) - 1);
|
||||
sqlend += (sizeof str4a3) - 1;
|
||||
|
||||
if (!strchr(constraints_to_drop[i], '/')) {
|
||||
/* If this happens to be an old format
|
||||
constraint, let us delete it. Since all new
|
||||
format constraints contain '/', it does no
|
||||
harm to run these DELETEs anyway. */
|
||||
|
||||
memcpy(sqlend, str4a1, (sizeof str4a1) - 1);
|
||||
sqlend += (sizeof str4a1) - 1;
|
||||
sqlend = ut_strcpyq(sqlend, '\'',
|
||||
constraints_to_drop[i]);
|
||||
memcpy(sqlend, str4a2, (sizeof str4a2) - 1);
|
||||
sqlend += (sizeof str4a2) - 1;
|
||||
sqlend = ut_strcpyq(sqlend, '\'',
|
||||
constraints_to_drop[i]);
|
||||
memcpy(sqlend, str4a3, (sizeof str4a3) - 1);
|
||||
sqlend += (sizeof str4a3) - 1;
|
||||
if (err != DB_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
memcpy(sqlend, str4b, (sizeof str4b) - 1);
|
||||
sqlend += (sizeof str4b) - 1;
|
||||
}
|
||||
|
||||
memcpy(sqlend, str5, sizeof str5);
|
||||
sqlend += sizeof str5;
|
||||
|
||||
ut_a(sqlend == sql + len + 1);
|
||||
|
||||
graph = pars_sql(NULL, sql);
|
||||
|
||||
ut_a(graph);
|
||||
mem_free(sql);
|
||||
|
||||
graph->trx = trx;
|
||||
trx->graph = NULL;
|
||||
|
||||
graph->fork_type = QUE_FORK_MYSQL_INTERFACE;
|
||||
|
||||
ut_a(thr = que_fork_start_command(graph));
|
||||
|
||||
que_run_threads(thr);
|
||||
|
||||
err = trx->error_state;
|
||||
|
||||
end:
|
||||
if (err != DB_SUCCESS) {
|
||||
if (err == DB_DUPLICATE_KEY) {
|
||||
ut_print_timestamp(stderr);
|
||||
@@ -3853,8 +3732,9 @@ row_rename_table_for_mysql(
|
||||
/* The following call will also rename the .ibd data file if
|
||||
the table is stored in a single-table tablespace */
|
||||
|
||||
success = dict_table_rename_in_cache(table, new_name,
|
||||
ibool success = dict_table_rename_in_cache(table, new_name,
|
||||
!new_is_tmp);
|
||||
|
||||
if (!success) {
|
||||
trx->error_state = DB_SUCCESS;
|
||||
trx_general_rollback_for_mysql(trx, FALSE, NULL);
|
||||
@@ -3902,20 +3782,16 @@ row_rename_table_for_mysql(
|
||||
ut_a(dict_table_rename_in_cache(table,
|
||||
old_name, FALSE));
|
||||
trx->error_state = DB_SUCCESS;
|
||||
trx_general_rollback_for_mysql(trx, FALSE,
|
||||
NULL);
|
||||
trx_general_rollback_for_mysql(trx, FALSE, NULL);
|
||||
trx->error_state = DB_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
funct_exit:
|
||||
if (!recovering_temp_table) {
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
}
|
||||
|
||||
if (graph) {
|
||||
que_graph_free(graph);
|
||||
}
|
||||
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
|
||||
@@ -521,7 +521,7 @@ row_purge_parse_undo_rec(
|
||||
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
|
||||
node->table = dict_table_get_on_id_low(table_id, trx);
|
||||
node->table = dict_table_get_on_id_low(table_id);
|
||||
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
|
||||
|
||||
@@ -2036,8 +2036,13 @@ row_fetch_print(
|
||||
dtype_print(type);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
if (dfield_get_len(dfield) != UNIV_SQL_NULL) {
|
||||
ut_print_buf(stderr, dfield_get_data(dfield),
|
||||
dfield_get_len(dfield));
|
||||
} else {
|
||||
fprintf(stderr, " <NULL>;");
|
||||
}
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
exp = que_node_get_next(exp);
|
||||
@@ -4401,7 +4406,7 @@ row_search_check_if_query_cache_permitted(
|
||||
dict_table_t* table;
|
||||
ibool ret = FALSE;
|
||||
|
||||
table = dict_table_get(norm_name, trx);
|
||||
table = dict_table_get(norm_name);
|
||||
|
||||
if (table == NULL) {
|
||||
|
||||
|
||||
@@ -202,8 +202,7 @@ row_upd_check_references_constraints(
|
||||
foreign->n_fields))) {
|
||||
|
||||
if (foreign->foreign_table == NULL) {
|
||||
dict_table_get(foreign->foreign_table_name,
|
||||
trx);
|
||||
dict_table_get(foreign->foreign_table_name);
|
||||
}
|
||||
|
||||
if (foreign->foreign_table) {
|
||||
|
||||
@@ -362,30 +362,6 @@ ibool srv_print_innodb_lock_monitor = FALSE;
|
||||
ibool srv_print_innodb_tablespace_monitor = FALSE;
|
||||
ibool srv_print_innodb_table_monitor = FALSE;
|
||||
|
||||
/* The parameters below are obsolete: */
|
||||
|
||||
ibool srv_print_parsed_sql = FALSE;
|
||||
|
||||
ulint srv_sim_disk_wait_pct = ULINT_MAX;
|
||||
ulint srv_sim_disk_wait_len = ULINT_MAX;
|
||||
ibool srv_sim_disk_wait_by_yield = FALSE;
|
||||
ibool srv_sim_disk_wait_by_wait = FALSE;
|
||||
|
||||
ibool srv_measure_contention = FALSE;
|
||||
ibool srv_measure_by_spin = FALSE;
|
||||
|
||||
ibool srv_test_extra_mutexes = FALSE;
|
||||
ibool srv_test_nocache = FALSE;
|
||||
ibool srv_test_cache_evict = FALSE;
|
||||
|
||||
ibool srv_test_sync = FALSE;
|
||||
ulint srv_test_n_threads = ULINT_MAX;
|
||||
ulint srv_test_n_loops = ULINT_MAX;
|
||||
ulint srv_test_n_free_rnds = ULINT_MAX;
|
||||
ulint srv_test_n_reserved_rnds = ULINT_MAX;
|
||||
ulint srv_test_array_size = ULINT_MAX;
|
||||
ulint srv_test_n_mutexes = ULINT_MAX;
|
||||
|
||||
/* Array of English strings describing the current state of an
|
||||
i/o handler thread */
|
||||
|
||||
@@ -873,11 +849,9 @@ srv_init(void)
|
||||
srv_sys = mem_alloc(sizeof(srv_sys_t));
|
||||
|
||||
kernel_mutex_temp = mem_alloc(sizeof(mutex_t));
|
||||
mutex_create(&kernel_mutex);
|
||||
mutex_set_level(&kernel_mutex, SYNC_KERNEL);
|
||||
mutex_create(&kernel_mutex, SYNC_KERNEL);
|
||||
|
||||
mutex_create(&srv_innodb_monitor_mutex);
|
||||
mutex_set_level(&srv_innodb_monitor_mutex, SYNC_NO_ORDER_CHECK);
|
||||
mutex_create(&srv_innodb_monitor_mutex, SYNC_NO_ORDER_CHECK);
|
||||
|
||||
srv_sys->threads = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t));
|
||||
|
||||
@@ -911,10 +885,6 @@ srv_init(void)
|
||||
srv_meter_foreground[i] = 250;
|
||||
}
|
||||
|
||||
srv_sys->operational = os_event_create(NULL);
|
||||
|
||||
ut_a(srv_sys->operational);
|
||||
|
||||
UT_LIST_INIT(srv_sys->tasks);
|
||||
|
||||
/* create dummy table and index for old-style infimum and supremum */
|
||||
@@ -1847,11 +1817,7 @@ srv_export_innodb_status(void)
|
||||
A thread which wakes up threads whose lock wait may have lasted too long.
|
||||
This also prints the info output by various InnoDB monitors. */
|
||||
|
||||
#ifndef __WIN__
|
||||
void*
|
||||
#else
|
||||
ulint
|
||||
#endif
|
||||
os_thread_ret_t
|
||||
srv_lock_timeout_and_monitor_thread(
|
||||
/*================================*/
|
||||
/* out: a dummy parameter */
|
||||
@@ -2023,22 +1989,15 @@ exit_func:
|
||||
thread should always use that to exit and not use return() to exit. */
|
||||
|
||||
os_thread_exit(NULL);
|
||||
#ifndef __WIN__
|
||||
return(NULL);
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
|
||||
OS_THREAD_DUMMY_RETURN;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
A thread which prints warnings about semaphore waits which have lasted
|
||||
too long. These can be used to track bugs which cause hangs. */
|
||||
|
||||
#ifndef __WIN__
|
||||
void*
|
||||
#else
|
||||
ulint
|
||||
#endif
|
||||
os_thread_ret_t
|
||||
srv_error_monitor_thread(
|
||||
/*=====================*/
|
||||
/* out: a dummy parameter */
|
||||
@@ -2120,11 +2079,7 @@ loop:
|
||||
|
||||
os_thread_exit(NULL);
|
||||
|
||||
#ifndef __WIN__
|
||||
return(NULL);
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
OS_THREAD_DUMMY_RETURN;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -2169,11 +2124,7 @@ srv_wake_master_thread(void)
|
||||
/*************************************************************************
|
||||
The master thread controlling the server. */
|
||||
|
||||
#ifndef __WIN__
|
||||
void*
|
||||
#else
|
||||
ulint
|
||||
#endif
|
||||
os_thread_ret_t
|
||||
srv_master_thread(
|
||||
/*==============*/
|
||||
/* out: a dummy parameter */
|
||||
@@ -2212,7 +2163,6 @@ srv_master_thread(
|
||||
|
||||
mutex_exit(&kernel_mutex);
|
||||
|
||||
os_event_set(srv_sys->operational);
|
||||
loop:
|
||||
/*****************************************************************/
|
||||
/* ---- When there is database activity by users, we cycle in this
|
||||
@@ -2607,22 +2557,9 @@ suspend_thread:
|
||||
os_thread_exit(NULL);
|
||||
}
|
||||
|
||||
/* When there is user activity, InnoDB will set the event and the main
|
||||
thread goes back to loop: */
|
||||
/* When there is user activity, InnoDB will set the event and the
|
||||
main thread goes back to loop. */
|
||||
|
||||
goto loop;
|
||||
|
||||
/* We count the number of threads in os_thread_exit(). A created
|
||||
thread should always use that to exit and not use return() to exit.
|
||||
The thread actually never comes here because it is exited in an
|
||||
os_event_wait(). */
|
||||
|
||||
os_thread_exit(NULL);
|
||||
|
||||
#ifndef __WIN__
|
||||
return(NULL); /* Not reached */
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
@@ -108,8 +108,10 @@ static char* srv_monitor_file_name;
|
||||
static int inno_bcmp(register const char *s1, register const char *s2,
|
||||
register uint len)
|
||||
{
|
||||
while (len-- != 0 && *s1++ == *s2++) ;
|
||||
return len+1;
|
||||
while ((len-- != 0) && (*s1++ == *s2++))
|
||||
;
|
||||
|
||||
return(len + 1);
|
||||
}
|
||||
#define memcmp(A,B,C) inno_bcmp((A),(B),(C))
|
||||
#endif
|
||||
@@ -426,11 +428,7 @@ srv_parse_log_group_home_dirs(
|
||||
I/o-handler thread function. */
|
||||
static
|
||||
|
||||
#ifndef __WIN__
|
||||
void*
|
||||
#else
|
||||
ulint
|
||||
#endif
|
||||
os_thread_ret_t
|
||||
io_handler_thread(
|
||||
/*==============*/
|
||||
void* arg)
|
||||
@@ -459,11 +457,7 @@ io_handler_thread(
|
||||
|
||||
os_thread_exit(NULL);
|
||||
|
||||
#ifndef __WIN__
|
||||
return(NULL); /* Not reached */
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
OS_THREAD_DUMMY_RETURN;
|
||||
}
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
@@ -942,8 +936,7 @@ skip_size_check:
|
||||
|
||||
ios = 0;
|
||||
|
||||
mutex_create(&ios_mutex);
|
||||
mutex_set_level(&ios_mutex, SYNC_NO_ORDER_CHECK);
|
||||
mutex_create(&ios_mutex, SYNC_NO_ORDER_CHECK);
|
||||
|
||||
return(DB_SUCCESS);
|
||||
}
|
||||
@@ -1175,8 +1168,8 @@ NetWare. */
|
||||
return((int) err);
|
||||
}
|
||||
|
||||
mutex_create(&srv_monitor_file_mutex);
|
||||
mutex_set_level(&srv_monitor_file_mutex, SYNC_NO_ORDER_CHECK);
|
||||
mutex_create(&srv_monitor_file_mutex, SYNC_NO_ORDER_CHECK);
|
||||
|
||||
if (srv_innodb_status) {
|
||||
srv_monitor_file_name = mem_alloc(
|
||||
strlen(fil_path_to_mysql_datadir) +
|
||||
@@ -1197,15 +1190,15 @@ NetWare. */
|
||||
}
|
||||
}
|
||||
|
||||
mutex_create(&srv_dict_tmpfile_mutex);
|
||||
mutex_set_level(&srv_dict_tmpfile_mutex, SYNC_DICT_OPERATION);
|
||||
mutex_create(&srv_dict_tmpfile_mutex, SYNC_DICT_OPERATION);
|
||||
|
||||
srv_dict_tmpfile = os_file_create_tmpfile();
|
||||
if (!srv_dict_tmpfile) {
|
||||
return(DB_ERROR);
|
||||
}
|
||||
|
||||
mutex_create(&srv_misc_tmpfile_mutex);
|
||||
mutex_set_level(&srv_misc_tmpfile_mutex, SYNC_ANY_LATCH);
|
||||
mutex_create(&srv_misc_tmpfile_mutex, SYNC_ANY_LATCH);
|
||||
|
||||
srv_misc_tmpfile = os_file_create_tmpfile();
|
||||
if (!srv_misc_tmpfile) {
|
||||
return(DB_ERROR);
|
||||
@@ -1539,11 +1532,6 @@ NetWare. */
|
||||
}
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
|
||||
if (srv_measure_contention) {
|
||||
/* os_thread_create(&test_measure_cont, NULL, thread_ids +
|
||||
SRV_MAX_N_IO_THREADS); */
|
||||
}
|
||||
|
||||
/* fprintf(stderr, "Max allowed record size %lu\n",
|
||||
page_get_free_space_of_empty() / 2); */
|
||||
|
||||
|
||||
@@ -213,8 +213,7 @@ sync_array_create(
|
||||
if (protection == SYNC_ARRAY_OS_MUTEX) {
|
||||
arr->os_mutex = os_mutex_create(NULL);
|
||||
} else if (protection == SYNC_ARRAY_MUTEX) {
|
||||
mutex_create(&(arr->mutex));
|
||||
mutex_set_level(&(arr->mutex), SYNC_NO_ORDER_CHECK);
|
||||
mutex_create(&arr->mutex, SYNC_NO_ORDER_CHECK);
|
||||
} else {
|
||||
ut_error;
|
||||
}
|
||||
|
||||
@@ -89,19 +89,19 @@ void
|
||||
rw_lock_create_func(
|
||||
/*================*/
|
||||
rw_lock_t* lock, /* in: pointer to memory */
|
||||
ulint level, /* in: level */
|
||||
const char* cfile_name, /* in: file name where created */
|
||||
ulint cline, /* in: file line where created */
|
||||
const char* cmutex_name) /* in: mutex name */
|
||||
{
|
||||
/* If this is the very first time a synchronization
|
||||
object is created, then the following call initializes
|
||||
the sync system. */
|
||||
/* If this is the very first time a synchronization object is
|
||||
created, then the following call initializes the sync system. */
|
||||
|
||||
mutex_create(rw_lock_get_mutex(lock));
|
||||
mutex_set_level(rw_lock_get_mutex(lock), SYNC_NO_ORDER_CHECK);
|
||||
mutex_create(rw_lock_get_mutex(lock), SYNC_NO_ORDER_CHECK);
|
||||
|
||||
lock->mutex.cfile_name = cfile_name;
|
||||
lock->mutex.cline = cline;
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
lock->mutex.cmutex_name = cmutex_name;
|
||||
lock->mutex.mutex_type = 1;
|
||||
@@ -116,9 +116,10 @@ rw_lock_create_func(
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
UT_LIST_INIT(lock->debug_list);
|
||||
|
||||
lock->level = SYNC_LEVEL_NONE;
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
lock->level = level;
|
||||
|
||||
lock->magic_n = RW_LOCK_MAGIC_N;
|
||||
|
||||
lock->cfile_name = cfile_name;
|
||||
@@ -669,18 +670,6 @@ rw_lock_remove_debug_info(
|
||||
}
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
/**********************************************************************
|
||||
Sets the rw-lock latching level field. */
|
||||
|
||||
void
|
||||
rw_lock_set_level(
|
||||
/*==============*/
|
||||
rw_lock_t* lock, /* in: rw-lock */
|
||||
ulint level) /* in: level */
|
||||
{
|
||||
lock->level = level;
|
||||
}
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
/**********************************************************************
|
||||
Checks if the thread has locked the rw-lock in the specified mode, with
|
||||
|
||||
@@ -202,6 +202,7 @@ void
|
||||
mutex_create_func(
|
||||
/*==============*/
|
||||
mutex_t* mutex, /* in: pointer to memory */
|
||||
ulint level, /* in: level */
|
||||
const char* cfile_name, /* in: file name where created */
|
||||
ulint cline, /* in: file line where created */
|
||||
const char* cmutex_name) /* in: mutex name */
|
||||
@@ -218,7 +219,7 @@ mutex_create_func(
|
||||
mutex->line = 0;
|
||||
mutex->file_name = "not yet reserved";
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
mutex->level = SYNC_LEVEL_NONE;
|
||||
mutex->level = level;
|
||||
mutex->cfile_name = cfile_name;
|
||||
mutex->cline = cline;
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
@@ -598,19 +599,6 @@ mutex_get_debug_info(
|
||||
}
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
/**********************************************************************
|
||||
Sets the mutex latching level field. */
|
||||
|
||||
void
|
||||
mutex_set_level(
|
||||
/*============*/
|
||||
mutex_t* mutex, /* in: mutex */
|
||||
ulint level) /* in: level */
|
||||
{
|
||||
mutex->level = level;
|
||||
}
|
||||
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
/**********************************************************************
|
||||
Checks that the current thread owns the mutex. Works only in the debug
|
||||
@@ -979,8 +967,8 @@ void
|
||||
sync_thread_add_level(
|
||||
/*==================*/
|
||||
void* latch, /* in: pointer to a mutex or an rw-lock */
|
||||
ulint level) /* in: level in the latching order; if SYNC_LEVEL_NONE,
|
||||
nothing is done */
|
||||
ulint level) /* in: level in the latching order; if
|
||||
SYNC_LEVEL_VARYING, nothing is done */
|
||||
{
|
||||
sync_level_t* array;
|
||||
sync_level_t* slot;
|
||||
@@ -1002,7 +990,7 @@ sync_thread_add_level(
|
||||
return;
|
||||
}
|
||||
|
||||
if (level == SYNC_LEVEL_NONE) {
|
||||
if (level == SYNC_LEVEL_VARYING) {
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1050,6 +1038,9 @@ sync_thread_add_level(
|
||||
case SYNC_RECV:
|
||||
ut_a(sync_thread_levels_g(array, SYNC_RECV));
|
||||
break;
|
||||
case SYNC_WORK_QUEUE:
|
||||
ut_a(sync_thread_levels_g(array, SYNC_WORK_QUEUE));
|
||||
break;
|
||||
case SYNC_LOG:
|
||||
ut_a(sync_thread_levels_g(array, SYNC_LOG));
|
||||
break;
|
||||
@@ -1290,21 +1281,17 @@ sync_init(void)
|
||||
/* Init the mutex list and create the mutex to protect it. */
|
||||
|
||||
UT_LIST_INIT(mutex_list);
|
||||
mutex_create(&mutex_list_mutex);
|
||||
mutex_set_level(&mutex_list_mutex, SYNC_NO_ORDER_CHECK);
|
||||
mutex_create(&mutex_list_mutex, SYNC_NO_ORDER_CHECK);
|
||||
|
||||
mutex_create(&sync_thread_mutex);
|
||||
mutex_set_level(&sync_thread_mutex, SYNC_NO_ORDER_CHECK);
|
||||
mutex_create(&sync_thread_mutex, SYNC_NO_ORDER_CHECK);
|
||||
|
||||
/* Init the rw-lock list and create the mutex to protect it. */
|
||||
|
||||
UT_LIST_INIT(rw_lock_list);
|
||||
mutex_create(&rw_lock_list_mutex);
|
||||
mutex_set_level(&rw_lock_list_mutex, SYNC_NO_ORDER_CHECK);
|
||||
mutex_create(&rw_lock_list_mutex, SYNC_NO_ORDER_CHECK);
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
mutex_create(&rw_lock_debug_mutex);
|
||||
mutex_set_level(&rw_lock_debug_mutex, SYNC_NO_ORDER_CHECK);
|
||||
mutex_create(&rw_lock_debug_mutex, SYNC_NO_ORDER_CHECK);
|
||||
|
||||
rw_lock_debug_event = os_event_create(NULL);
|
||||
rw_lock_debug_waiters = FALSE;
|
||||
|
||||
@@ -226,6 +226,5 @@ thr_local_init(void)
|
||||
|
||||
thr_local_hash = hash_create(OS_THREAD_MAX_N + 100);
|
||||
|
||||
mutex_create(&thr_local_mutex);
|
||||
mutex_set_level(&thr_local_mutex, SYNC_THR_LOCAL);
|
||||
mutex_create(&thr_local_mutex, SYNC_THR_LOCAL);
|
||||
}
|
||||
|
||||
@@ -211,11 +211,9 @@ trx_purge_sys_create(void)
|
||||
purge_sys->purge_undo_no = ut_dulint_zero;
|
||||
purge_sys->next_stored = FALSE;
|
||||
|
||||
rw_lock_create(&(purge_sys->latch));
|
||||
rw_lock_set_level(&(purge_sys->latch), SYNC_PURGE_LATCH);
|
||||
rw_lock_create(&purge_sys->latch, SYNC_PURGE_LATCH);
|
||||
|
||||
mutex_create(&(purge_sys->mutex));
|
||||
mutex_set_level(&(purge_sys->mutex), SYNC_PURGE_SYS);
|
||||
mutex_create(&purge_sys->mutex, SYNC_PURGE_SYS);
|
||||
|
||||
purge_sys->heap = mem_heap_create(256);
|
||||
|
||||
|
||||
@@ -391,11 +391,7 @@ transaction already was committed, then we clean up a possible insert
|
||||
undo log. If the transaction was not yet committed, then we roll it back.
|
||||
Note: this is done in a background thread. */
|
||||
|
||||
#ifndef __WIN__
|
||||
void*
|
||||
#else
|
||||
ulint
|
||||
#endif
|
||||
os_thread_ret_t
|
||||
trx_rollback_or_clean_all_without_sess(
|
||||
/*===================================*/
|
||||
/* out: a dummy parameter */
|
||||
@@ -544,7 +540,7 @@ loop:
|
||||
(ulong) ut_dulint_get_high(trx->table_id),
|
||||
(ulong) ut_dulint_get_low(trx->table_id));
|
||||
|
||||
table = dict_table_get_on_id_low(trx->table_id, trx);
|
||||
table = dict_table_get_on_id_low(trx->table_id);
|
||||
|
||||
if (table) {
|
||||
fputs("InnoDB: Table found: dropping table ", stderr);
|
||||
@@ -576,13 +572,7 @@ leave_function:
|
||||
|
||||
os_thread_exit(NULL);
|
||||
|
||||
/* The following is dummy code to keep the compiler happy: */
|
||||
|
||||
#ifndef __WIN__
|
||||
return(NULL);
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
OS_THREAD_DUMMY_RETURN;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
||||
@@ -147,8 +147,7 @@ trx_rseg_mem_create(
|
||||
rseg->space = space;
|
||||
rseg->page_no = page_no;
|
||||
|
||||
mutex_create(&(rseg->mutex));
|
||||
mutex_set_level(&(rseg->mutex), SYNC_RSEG);
|
||||
mutex_create(&rseg->mutex, SYNC_RSEG);
|
||||
|
||||
UT_LIST_ADD_LAST(rseg_list, trx_sys->rseg_list, rseg);
|
||||
|
||||
|
||||
@@ -54,6 +54,36 @@ char trx_sys_mysql_bin_log_name[TRX_SYS_MYSQL_LOG_NAME_LEN];
|
||||
ib_longlong trx_sys_mysql_bin_log_pos = -1;
|
||||
|
||||
|
||||
/********************************************************************
|
||||
Determines if a page number is located inside the doublewrite buffer. */
|
||||
|
||||
ibool
|
||||
trx_doublewrite_page_inside(
|
||||
/*========================*/
|
||||
/* out: TRUE if the location is inside
|
||||
the two blocks of the doublewrite buffer */
|
||||
ulint page_no) /* in: page number */
|
||||
{
|
||||
if (trx_doublewrite == NULL) {
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
if (page_no >= trx_doublewrite->block1
|
||||
&& page_no < trx_doublewrite->block1
|
||||
+ TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) {
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
if (page_no >= trx_doublewrite->block2
|
||||
&& page_no < trx_doublewrite->block2
|
||||
+ TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) {
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Creates or initialializes the doublewrite buffer at a database start. */
|
||||
static
|
||||
@@ -71,8 +101,7 @@ trx_doublewrite_init(
|
||||
os_do_not_call_flush_at_each_write = TRUE;
|
||||
#endif /* UNIV_DO_FLUSH */
|
||||
|
||||
mutex_create(&(trx_doublewrite->mutex));
|
||||
mutex_set_level(&(trx_doublewrite->mutex), SYNC_DOUBLEWRITE);
|
||||
mutex_create(&trx_doublewrite->mutex, SYNC_DOUBLEWRITE);
|
||||
|
||||
trx_doublewrite->first_free = 0;
|
||||
|
||||
|
||||
@@ -144,8 +144,7 @@ trx_create(
|
||||
trx->repl_wait_binlog_name = NULL;
|
||||
trx->repl_wait_binlog_pos = 0;
|
||||
|
||||
mutex_create(&(trx->undo_mutex));
|
||||
mutex_set_level(&(trx->undo_mutex), SYNC_TRX_UNDO);
|
||||
mutex_create(&trx->undo_mutex, SYNC_TRX_UNDO);
|
||||
|
||||
trx->rseg = NULL;
|
||||
|
||||
|
||||
@@ -19,6 +19,6 @@ include ../include/Makefile.i
|
||||
|
||||
noinst_LIBRARIES = libut.a
|
||||
|
||||
libut_a_SOURCES = ut0byte.c ut0dbg.c ut0mem.c ut0rnd.c ut0ut.c ut0vec.c
|
||||
libut_a_SOURCES = ut0byte.c ut0dbg.c ut0mem.c ut0rnd.c ut0ut.c ut0vec.c ut0list.c ut0wqueue.c
|
||||
|
||||
EXTRA_PROGRAMS =
|
||||
|
||||
147
ut/ut0list.c
Normal file
147
ut/ut0list.c
Normal file
@@ -0,0 +1,147 @@
|
||||
#include "ut0list.h"
|
||||
#ifdef UNIV_NONINL
|
||||
#include "ut0list.ic"
|
||||
#endif
|
||||
|
||||
/********************************************************************
|
||||
Create a new list. */
|
||||
|
||||
ib_list_t*
|
||||
ib_list_create(void)
|
||||
/*=================*/
|
||||
/* out: list */
|
||||
{
|
||||
ib_list_t* list = mem_alloc(sizeof(ib_list_t));
|
||||
|
||||
list->first = NULL;
|
||||
list->last = NULL;
|
||||
|
||||
return(list);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Free a list. */
|
||||
|
||||
void
|
||||
ib_list_free(
|
||||
/*=========*/
|
||||
ib_list_t* list) /* in: list */
|
||||
{
|
||||
/* We don't check that the list is empty because it's entirely valid
|
||||
to e.g. have all the nodes allocated from a single heap that is then
|
||||
freed after the list itself is freed. */
|
||||
|
||||
mem_free(list);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Add the data to the start of the list. */
|
||||
|
||||
ib_list_node_t*
|
||||
ib_list_add_first(
|
||||
/*==============*/
|
||||
/* out: new list node*/
|
||||
ib_list_t* list, /* in: list */
|
||||
void* data, /* in: data */
|
||||
mem_heap_t* heap) /* in: memory heap to use */
|
||||
{
|
||||
return(ib_list_add_after(list, ib_list_get_first(list), data, heap));
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Add the data to the end of the list. */
|
||||
|
||||
ib_list_node_t*
|
||||
ib_list_add_last(
|
||||
/*=============*/
|
||||
/* out: new list node*/
|
||||
ib_list_t* list, /* in: list */
|
||||
void* data, /* in: data */
|
||||
mem_heap_t* heap) /* in: memory heap to use */
|
||||
{
|
||||
return(ib_list_add_after(list, ib_list_get_last(list), data, heap));
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Add the data after the indicated node. */
|
||||
|
||||
ib_list_node_t*
|
||||
ib_list_add_after(
|
||||
/*==============*/
|
||||
/* out: new list node*/
|
||||
ib_list_t* list, /* in: list */
|
||||
ib_list_node_t* prev_node, /* in: node preceding new node (can
|
||||
be NULL) */
|
||||
void* data, /* in: data */
|
||||
mem_heap_t* heap) /* in: memory heap to use */
|
||||
{
|
||||
ib_list_node_t* node = mem_heap_alloc(heap, sizeof(ib_list_node_t));
|
||||
|
||||
node->data = data;
|
||||
|
||||
if (!list->first) {
|
||||
/* Empty list. */
|
||||
|
||||
ut_a(!prev_node);
|
||||
|
||||
node->prev = NULL;
|
||||
node->next = NULL;
|
||||
|
||||
list->first = node;
|
||||
list->last = node;
|
||||
} else if (!prev_node) {
|
||||
/* Start of list. */
|
||||
|
||||
node->prev = NULL;
|
||||
node->next = list->first;
|
||||
|
||||
list->first->prev = node;
|
||||
|
||||
list->first = node;
|
||||
} else {
|
||||
/* Middle or end of list. */
|
||||
|
||||
node->prev = prev_node;
|
||||
node->next = prev_node->next;
|
||||
|
||||
prev_node->next = node;
|
||||
|
||||
if (node->next) {
|
||||
node->next->prev = node;
|
||||
} else {
|
||||
list->last = node;
|
||||
}
|
||||
}
|
||||
|
||||
return(node);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Remove the node from the list. */
|
||||
|
||||
void
|
||||
ib_list_remove(
|
||||
/*===========*/
|
||||
ib_list_t* list, /* in: list */
|
||||
ib_list_node_t* node) /* in: node to remove */
|
||||
{
|
||||
if (node->prev) {
|
||||
node->prev->next = node->next;
|
||||
} else {
|
||||
/* First item in list. */
|
||||
|
||||
ut_ad(list->first == node);
|
||||
|
||||
list->first = node->next;
|
||||
}
|
||||
|
||||
if (node->next) {
|
||||
node->next->prev = node->prev;
|
||||
} else {
|
||||
/* Last item in list. */
|
||||
|
||||
ut_ad(list->last == node);
|
||||
|
||||
list->last = node->prev;
|
||||
}
|
||||
}
|
||||
92
ut/ut0wqueue.c
Normal file
92
ut/ut0wqueue.c
Normal file
@@ -0,0 +1,92 @@
|
||||
#include "ut0wqueue.h"
|
||||
|
||||
/********************************************************************
|
||||
Create a new work queue. */
|
||||
|
||||
ib_wqueue_t*
|
||||
ib_wqueue_create(void)
|
||||
/*===================*/
|
||||
/* out: work queue */
|
||||
{
|
||||
ib_wqueue_t* wq = mem_alloc(sizeof(ib_wqueue_t));
|
||||
|
||||
mutex_create(&wq->mutex, SYNC_WORK_QUEUE);
|
||||
|
||||
wq->items = ib_list_create();
|
||||
wq->event = os_event_create(NULL);
|
||||
|
||||
return(wq);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Free a work queue. */
|
||||
|
||||
void
|
||||
ib_wqueue_free(
|
||||
/*===========*/
|
||||
ib_wqueue_t* wq) /* in: work queue */
|
||||
{
|
||||
ut_a(!ib_list_get_first(wq->items));
|
||||
|
||||
mutex_free(&wq->mutex);
|
||||
ib_list_free(wq->items);
|
||||
os_event_free(wq->event);
|
||||
|
||||
mem_free(wq);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Add a work item to the queue. */
|
||||
|
||||
void
|
||||
ib_wqueue_add(
|
||||
/*==========*/
|
||||
ib_wqueue_t* wq, /* in: work queue */
|
||||
void* item, /* in: work item */
|
||||
mem_heap_t* heap) /* in: memory heap to use for allocating the
|
||||
list node */
|
||||
{
|
||||
mutex_enter(&wq->mutex);
|
||||
|
||||
ib_list_add_last(wq->items, item, heap);
|
||||
os_event_set(wq->event);
|
||||
|
||||
mutex_exit(&wq->mutex);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Wait for a work item to appear in the queue. */
|
||||
|
||||
void*
|
||||
ib_wqueue_wait(
|
||||
/* out: work item */
|
||||
ib_wqueue_t* wq) /* in: work queue */
|
||||
{
|
||||
ib_list_node_t* node;
|
||||
|
||||
for (;;) {
|
||||
os_event_wait(wq->event);
|
||||
|
||||
mutex_enter(&wq->mutex);
|
||||
|
||||
node = ib_list_get_first(wq->items);
|
||||
|
||||
if (node) {
|
||||
ib_list_remove(wq->items, node);
|
||||
|
||||
if (!ib_list_get_first(wq->items)) {
|
||||
/* We must reset the event when the list
|
||||
gets emptied. */
|
||||
os_event_reset(wq->event);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
mutex_exit(&wq->mutex);
|
||||
}
|
||||
|
||||
mutex_exit(&wq->mutex);
|
||||
|
||||
return(node->data);
|
||||
}
|
||||
Reference in New Issue
Block a user