mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
InnoDB 5.6.20
This commit is contained in:
commit
75796d9ecb
51 changed files with 1027 additions and 659 deletions
|
@ -1,7 +1,7 @@
|
||||||
FLUSH TABLES WITH READ LOCK AND DISABLE CHECKPOINT;
|
FLUSH TABLES WITH READ LOCK AND DISABLE CHECKPOINT;
|
||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
CREATE TABLE t1 ( m MEDIUMTEXT ) ENGINE=InnoDB;
|
CREATE TABLE t1 ( m MEDIUMTEXT ) ENGINE=InnoDB;
|
||||||
INSERT INTO t1 VALUES ( REPEAT('i',1048576) );
|
INSERT INTO t1 VALUES ( REPEAT('i',65535) );
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
ERROR 42000: Row size too large (> ####). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.
|
||||||
f4 f8
|
f4 f8
|
||||||
xxx zzz
|
|
||||||
f4 f8
|
f4 f8
|
||||||
xxx zzz
|
|
||||||
|
|
|
@ -1,31 +1,32 @@
|
||||||
--source include/have_innodb.inc
|
|
||||||
#
|
#
|
||||||
# Bug#34300 Tinyblob & tinytext fields currupted after export/import and alter in 5.1
|
# Bug#34300 Tinyblob & tinytext fields currupted after export/import and alter in 5.1
|
||||||
# http://bugs.mysql.com/34300
|
# http://bugs.mysql.com/34300
|
||||||
#
|
#
|
||||||
|
|
||||||
|
-- source include/have_innodb.inc
|
||||||
|
|
||||||
-- disable_query_log
|
-- disable_query_log
|
||||||
-- disable_result_log
|
-- disable_result_log
|
||||||
|
|
||||||
call mtr.add_suppression("InnoDB: Warning: a long semaphore wait:");
|
call mtr.add_suppression("InnoDB: The total blob data length");
|
||||||
call mtr.add_suppression("the age of the last checkpoint is");
|
|
||||||
|
|
||||||
# set packet size and reconnect
|
# set packet size and reconnect
|
||||||
let $max_packet=`select @@global.max_allowed_packet`;
|
let $max_packet=`select @@global.max_allowed_packet`;
|
||||||
SET @@global.max_allowed_packet=16777216;
|
SET @@global.max_allowed_packet=16777216;
|
||||||
--connect (newconn, localhost, root,,)
|
--connect (newconn, localhost, root,,)
|
||||||
|
|
||||||
DROP TABLE IF EXISTS bug34300;
|
--enable_result_log
|
||||||
|
|
||||||
CREATE TABLE bug34300 (
|
CREATE TABLE bug34300 (
|
||||||
f4 TINYTEXT,
|
f4 TINYTEXT,
|
||||||
f6 MEDIUMTEXT,
|
f6 MEDIUMTEXT,
|
||||||
f8 TINYBLOB
|
f8 TINYBLOB
|
||||||
) ENGINE=InnoDB;
|
) ENGINE=InnoDB;
|
||||||
|
|
||||||
|
--replace_regex /\(> [0-9]*\)/(> ####)/
|
||||||
|
--error ER_TOO_BIG_ROWSIZE
|
||||||
INSERT INTO bug34300 VALUES ('xxx', repeat('a', 8459264), 'zzz');
|
INSERT INTO bug34300 VALUES ('xxx', repeat('a', 8459264), 'zzz');
|
||||||
|
|
||||||
-- enable_result_log
|
|
||||||
|
|
||||||
SELECT f4, f8 FROM bug34300;
|
SELECT f4, f8 FROM bug34300;
|
||||||
|
|
||||||
ALTER TABLE bug34300 ADD COLUMN (f10 INT);
|
ALTER TABLE bug34300 ADD COLUMN (f10 INT);
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
FLUSH TABLES WITH READ LOCK AND DISABLE CHECKPOINT;
|
FLUSH TABLES WITH READ LOCK AND DISABLE CHECKPOINT;
|
||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
CREATE TABLE t1 ( m MEDIUMTEXT ) ENGINE=InnoDB;
|
CREATE TABLE t1 ( m MEDIUMTEXT ) ENGINE=InnoDB;
|
||||||
INSERT INTO t1 VALUES ( REPEAT('i',1048576) );
|
INSERT INTO t1 VALUES ( REPEAT('i',65535) );
|
||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,6 @@ IF(NOT CMAKE_CROSSCOMPILING)
|
||||||
long x;
|
long x;
|
||||||
long y;
|
long y;
|
||||||
long res;
|
long res;
|
||||||
char c;
|
|
||||||
|
|
||||||
x = 10;
|
x = 10;
|
||||||
y = 123;
|
y = 123;
|
||||||
|
@ -93,6 +92,16 @@ IF(NOT CMAKE_CROSSCOMPILING)
|
||||||
if (res != 123 + 10 || x != 123 + 10) {
|
if (res != 123 + 10 || x != 123 + 10) {
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
return(0);
|
||||||
|
}"
|
||||||
|
HAVE_IB_GCC_ATOMIC_BUILTINS
|
||||||
|
)
|
||||||
|
CHECK_C_SOURCE_RUNS(
|
||||||
|
"
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
long res;
|
||||||
|
char c;
|
||||||
|
|
||||||
c = 10;
|
c = 10;
|
||||||
res = __sync_lock_test_and_set(&c, 123);
|
res = __sync_lock_test_and_set(&c, 123);
|
||||||
|
@ -101,7 +110,7 @@ IF(NOT CMAKE_CROSSCOMPILING)
|
||||||
}
|
}
|
||||||
return(0);
|
return(0);
|
||||||
}"
|
}"
|
||||||
HAVE_IB_GCC_ATOMIC_BUILTINS
|
HAVE_IB_GCC_ATOMIC_BUILTINS_BYTE
|
||||||
)
|
)
|
||||||
CHECK_C_SOURCE_RUNS(
|
CHECK_C_SOURCE_RUNS(
|
||||||
"#include<stdint.h>
|
"#include<stdint.h>
|
||||||
|
@ -148,6 +157,10 @@ IF(HAVE_IB_GCC_ATOMIC_BUILTINS)
|
||||||
ADD_DEFINITIONS(-DHAVE_IB_GCC_ATOMIC_BUILTINS=1)
|
ADD_DEFINITIONS(-DHAVE_IB_GCC_ATOMIC_BUILTINS=1)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
IF(HAVE_IB_GCC_ATOMIC_BUILTINS_BYTE)
|
||||||
|
ADD_DEFINITIONS(-DHAVE_IB_GCC_ATOMIC_BUILTINS_BYTE=1)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
IF(HAVE_IB_GCC_ATOMIC_BUILTINS_64)
|
IF(HAVE_IB_GCC_ATOMIC_BUILTINS_64)
|
||||||
ADD_DEFINITIONS(-DHAVE_IB_GCC_ATOMIC_BUILTINS_64=1)
|
ADD_DEFINITIONS(-DHAVE_IB_GCC_ATOMIC_BUILTINS_64=1)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 2008, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 2008, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
@ -2044,6 +2044,8 @@ ib_cursor_delete_row(
|
||||||
const rec_t* rec;
|
const rec_t* rec;
|
||||||
ib_bool_t page_format;
|
ib_bool_t page_format;
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
|
rec_t* copy = NULL;
|
||||||
|
byte ptr[UNIV_PAGE_SIZE_MAX];
|
||||||
|
|
||||||
page_format = static_cast<ib_bool_t>(
|
page_format = static_cast<ib_bool_t>(
|
||||||
dict_table_is_comp(index->table));
|
dict_table_is_comp(index->table));
|
||||||
|
@ -2052,16 +2054,27 @@ ib_cursor_delete_row(
|
||||||
|
|
||||||
if (btr_pcur_restore_position(
|
if (btr_pcur_restore_position(
|
||||||
BTR_SEARCH_LEAF, pcur, &mtr)) {
|
BTR_SEARCH_LEAF, pcur, &mtr)) {
|
||||||
|
mem_heap_t* heap = NULL;
|
||||||
|
ulint offsets_[REC_OFFS_NORMAL_SIZE];
|
||||||
|
ulint* offsets = offsets_;
|
||||||
|
|
||||||
|
rec_offs_init(offsets_);
|
||||||
|
|
||||||
rec = btr_pcur_get_rec(pcur);
|
rec = btr_pcur_get_rec(pcur);
|
||||||
} else {
|
|
||||||
rec = NULL;
|
/* Since mtr will be commited, the rec
|
||||||
|
will not be protected. Make a copy of
|
||||||
|
the rec. */
|
||||||
|
offsets = rec_get_offsets(
|
||||||
|
rec, index, offsets, ULINT_UNDEFINED, &heap);
|
||||||
|
ut_ad(rec_offs_size(offsets) < UNIV_PAGE_SIZE_MAX);
|
||||||
|
copy = rec_copy(ptr, rec, offsets);
|
||||||
}
|
}
|
||||||
|
|
||||||
mtr_commit(&mtr);
|
mtr_commit(&mtr);
|
||||||
|
|
||||||
if (rec && !rec_get_deleted_flag(rec, page_format)) {
|
if (copy && !rec_get_deleted_flag(copy, page_format)) {
|
||||||
err = ib_delete_row(cursor, pcur, rec);
|
err = ib_delete_row(cursor, pcur, copy);
|
||||||
} else {
|
} else {
|
||||||
err = DB_RECORD_NOT_FOUND;
|
err = DB_RECORD_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2557,6 +2557,31 @@ make_external:
|
||||||
ut_ad(flags & BTR_KEEP_POS_FLAG);
|
ut_ad(flags & BTR_KEEP_POS_FLAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (big_rec_vec) {
|
||||||
|
const ulint redo_10p = srv_log_file_size * UNIV_PAGE_SIZE / 10;
|
||||||
|
ulint total_blob_len = 0;
|
||||||
|
|
||||||
|
/* Calculate the total number of bytes for blob data */
|
||||||
|
for (ulint i = 0; i < big_rec_vec->n_fields; i++) {
|
||||||
|
total_blob_len += big_rec_vec->fields[i].len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (total_blob_len > redo_10p) {
|
||||||
|
ib_logf(IB_LOG_LEVEL_ERROR, "The total blob data"
|
||||||
|
" length (" ULINTPF ") is greater than"
|
||||||
|
" 10%% of the redo log file size (" UINT64PF
|
||||||
|
"). Please increase innodb_log_file_size.",
|
||||||
|
total_blob_len, srv_log_file_size);
|
||||||
|
if (n_reserved > 0) {
|
||||||
|
fil_space_release_free_extents(
|
||||||
|
index->space, n_reserved);
|
||||||
|
}
|
||||||
|
|
||||||
|
err = DB_TOO_BIG_RECORD;
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Store state of explicit locks on rec on the page infimum record,
|
/* Store state of explicit locks on rec on the page infimum record,
|
||||||
before deleting rec. The page infimum acts as a dummy carrier of the
|
before deleting rec. The page infimum acts as a dummy carrier of the
|
||||||
locks, taking care also of lock releases, before we can move the locks
|
locks, taking care also of lock releases, before we can move the locks
|
||||||
|
@ -4378,6 +4403,7 @@ btr_store_big_rec_extern_fields(
|
||||||
buf_block_t** freed_pages = NULL;
|
buf_block_t** freed_pages = NULL;
|
||||||
ulint n_freed_pages = 0;
|
ulint n_freed_pages = 0;
|
||||||
dberr_t error = DB_SUCCESS;
|
dberr_t error = DB_SUCCESS;
|
||||||
|
ulint total_blob_len = 0;
|
||||||
|
|
||||||
ut_ad(rec_offs_validate(rec, index, offsets));
|
ut_ad(rec_offs_validate(rec, index, offsets));
|
||||||
ut_ad(rec_offs_any_extern(offsets));
|
ut_ad(rec_offs_any_extern(offsets));
|
||||||
|
@ -4397,6 +4423,23 @@ btr_store_big_rec_extern_fields(
|
||||||
rec_page_no = buf_block_get_page_no(rec_block);
|
rec_page_no = buf_block_get_page_no(rec_block);
|
||||||
ut_a(fil_page_get_type(page_align(rec)) == FIL_PAGE_INDEX);
|
ut_a(fil_page_get_type(page_align(rec)) == FIL_PAGE_INDEX);
|
||||||
|
|
||||||
|
const ulint redo_10p = (srv_log_file_size * UNIV_PAGE_SIZE / 10);
|
||||||
|
|
||||||
|
/* Calculate the total number of bytes for blob data */
|
||||||
|
for (ulint i = 0; i < big_rec_vec->n_fields; i++) {
|
||||||
|
total_blob_len += big_rec_vec->fields[i].len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (total_blob_len > redo_10p) {
|
||||||
|
ut_ad(op == BTR_STORE_INSERT);
|
||||||
|
ib_logf(IB_LOG_LEVEL_ERROR, "The total blob data length"
|
||||||
|
" (" ULINTPF ") is greater than 10%% of the"
|
||||||
|
" redo log file size (" UINT64PF "). Please"
|
||||||
|
" increase innodb_log_file_size.",
|
||||||
|
total_blob_len, srv_log_file_size);
|
||||||
|
return(DB_TOO_BIG_RECORD);
|
||||||
|
}
|
||||||
|
|
||||||
if (page_zip) {
|
if (page_zip) {
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
|
|
@ -2882,12 +2882,6 @@ got_block:
|
||||||
|
|
||||||
ut_ad(buf_block_get_state(fix_block) == BUF_BLOCK_FILE_PAGE);
|
ut_ad(buf_block_get_state(fix_block) == BUF_BLOCK_FILE_PAGE);
|
||||||
|
|
||||||
#if UNIV_WORD_SIZE == 4
|
|
||||||
/* On 32-bit systems, there is no padding in buf_page_t. On
|
|
||||||
other systems, Valgrind could complain about uninitialized pad
|
|
||||||
bytes. */
|
|
||||||
UNIV_MEM_ASSERT_RW(&fix_block->page, sizeof(fix_block->page));
|
|
||||||
#endif
|
|
||||||
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
|
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
|
||||||
|
|
||||||
if ((mode == BUF_GET_IF_IN_POOL || mode == BUF_GET_IF_IN_POOL_OR_WATCH)
|
if ((mode == BUF_GET_IF_IN_POOL || mode == BUF_GET_IF_IN_POOL_OR_WATCH)
|
||||||
|
@ -5401,7 +5395,7 @@ buf_get_free_list_len(void)
|
||||||
|
|
||||||
#else /* !UNIV_HOTBACKUP */
|
#else /* !UNIV_HOTBACKUP */
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
Inits a page to the buffer buf_pool, for use in ibbackup --restore. */
|
Inits a page to the buffer buf_pool, for use in mysqlbackup --restore. */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
void
|
void
|
||||||
buf_page_init_for_backup_restore(
|
buf_page_init_for_backup_restore(
|
||||||
|
|
|
@ -1818,13 +1818,6 @@ buf_LRU_free_page(
|
||||||
rw_lock_x_lock(hash_lock);
|
rw_lock_x_lock(hash_lock);
|
||||||
mutex_enter(block_mutex);
|
mutex_enter(block_mutex);
|
||||||
|
|
||||||
#if UNIV_WORD_SIZE == 4
|
|
||||||
/* On 32-bit systems, there is no padding in buf_page_t. On
|
|
||||||
other systems, Valgrind could complain about uninitialized pad
|
|
||||||
bytes. */
|
|
||||||
UNIV_MEM_ASSERT_RW(bpage, sizeof *bpage);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!buf_page_can_relocate(bpage)) {
|
if (!buf_page_can_relocate(bpage)) {
|
||||||
|
|
||||||
/* Do not free buffer fixed or I/O-fixed blocks. */
|
/* Do not free buffer fixed or I/O-fixed blocks. */
|
||||||
|
@ -1862,12 +1855,6 @@ func_exit:
|
||||||
ut_ad(buf_page_in_file(bpage));
|
ut_ad(buf_page_in_file(bpage));
|
||||||
ut_ad(bpage->in_LRU_list);
|
ut_ad(bpage->in_LRU_list);
|
||||||
ut_ad(!bpage->in_flush_list == !bpage->oldest_modification);
|
ut_ad(!bpage->in_flush_list == !bpage->oldest_modification);
|
||||||
#if UNIV_WORD_SIZE == 4
|
|
||||||
/* On 32-bit systems, there is no padding in buf_page_t. On
|
|
||||||
other systems, Valgrind could complain about uninitialized pad
|
|
||||||
bytes. */
|
|
||||||
UNIV_MEM_ASSERT_RW(bpage, sizeof *bpage);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNIV_DEBUG
|
#ifdef UNIV_DEBUG
|
||||||
if (buf_debug_prints) {
|
if (buf_debug_prints) {
|
||||||
|
@ -1940,13 +1927,6 @@ func_exit:
|
||||||
|
|
||||||
ut_ad(prev_b->in_LRU_list);
|
ut_ad(prev_b->in_LRU_list);
|
||||||
ut_ad(buf_page_in_file(prev_b));
|
ut_ad(buf_page_in_file(prev_b));
|
||||||
#if UNIV_WORD_SIZE == 4
|
|
||||||
/* On 32-bit systems, there is no
|
|
||||||
padding in buf_page_t. On other
|
|
||||||
systems, Valgrind could complain about
|
|
||||||
uninitialized pad bytes. */
|
|
||||||
UNIV_MEM_ASSERT_RW(prev_b, sizeof *prev_b);
|
|
||||||
#endif
|
|
||||||
UT_LIST_INSERT_AFTER(LRU, buf_pool->LRU,
|
UT_LIST_INSERT_AFTER(LRU, buf_pool->LRU,
|
||||||
prev_b, b);
|
prev_b, b);
|
||||||
|
|
||||||
|
@ -2172,13 +2152,6 @@ buf_LRU_block_remove_hashed(
|
||||||
ut_a(buf_page_get_io_fix(bpage) == BUF_IO_NONE);
|
ut_a(buf_page_get_io_fix(bpage) == BUF_IO_NONE);
|
||||||
ut_a(bpage->buf_fix_count == 0);
|
ut_a(bpage->buf_fix_count == 0);
|
||||||
|
|
||||||
#if UNIV_WORD_SIZE == 4
|
|
||||||
/* On 32-bit systems, there is no padding in
|
|
||||||
buf_page_t. On other systems, Valgrind could complain
|
|
||||||
about uninitialized pad bytes. */
|
|
||||||
UNIV_MEM_ASSERT_RW(bpage, sizeof *bpage);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
buf_LRU_remove_block(bpage);
|
buf_LRU_remove_block(bpage);
|
||||||
|
|
||||||
buf_pool->freed_page_clock += 1;
|
buf_pool->freed_page_clock += 1;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
@ -1611,26 +1611,25 @@ dict_create_add_foreign_to_dictionary(
|
||||||
return(error);
|
return(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************//**
|
/** Adds the given set of foreign key objects to the dictionary tables
|
||||||
Adds foreign key definitions to data dictionary tables in the database.
|
in the database. This function does not modify the dictionary cache. The
|
||||||
@return error code or DB_SUCCESS */
|
caller must ensure that all foreign key objects contain a valid constraint
|
||||||
|
name in foreign->id.
|
||||||
|
@param[in] local_fk_set set of foreign key objects, to be added to
|
||||||
|
the dictionary tables
|
||||||
|
@param[in] table table to which the foreign key objects in
|
||||||
|
local_fk_set belong to
|
||||||
|
@param[in,out] trx transaction
|
||||||
|
@return error code or DB_SUCCESS */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
dberr_t
|
dberr_t
|
||||||
dict_create_add_foreigns_to_dictionary(
|
dict_create_add_foreigns_to_dictionary(
|
||||||
/*===================================*/
|
/*===================================*/
|
||||||
ulint start_id,/*!< in: if we are actually doing ALTER TABLE
|
const dict_foreign_set& local_fk_set,
|
||||||
ADD CONSTRAINT, we want to generate constraint
|
const dict_table_t* table,
|
||||||
numbers which are bigger than in the table so
|
trx_t* trx)
|
||||||
far; we number the constraints from
|
|
||||||
start_id + 1 up; start_id should be set to 0 if
|
|
||||||
we are creating a new table, or if the table
|
|
||||||
so far has no constraints for which the name
|
|
||||||
was generated here */
|
|
||||||
dict_table_t* table, /*!< in: table */
|
|
||||||
trx_t* trx) /*!< in: transaction */
|
|
||||||
{
|
{
|
||||||
dict_foreign_t* foreign;
|
dict_foreign_t* foreign;
|
||||||
ulint number = start_id + 1;
|
|
||||||
dberr_t error;
|
dberr_t error;
|
||||||
|
|
||||||
ut_ad(mutex_own(&(dict_sys->mutex)));
|
ut_ad(mutex_own(&(dict_sys->mutex)));
|
||||||
|
@ -1643,17 +1642,12 @@ dict_create_add_foreigns_to_dictionary(
|
||||||
return(DB_ERROR);
|
return(DB_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (foreign = UT_LIST_GET_FIRST(table->foreign_list);
|
for (dict_foreign_set::const_iterator it = local_fk_set.begin();
|
||||||
foreign;
|
it != local_fk_set.end();
|
||||||
foreign = UT_LIST_GET_NEXT(foreign_list, foreign)) {
|
++it) {
|
||||||
|
|
||||||
error = dict_create_add_foreign_id(&number, table->name,
|
foreign = *it;
|
||||||
foreign);
|
ut_ad(foreign->id != NULL);
|
||||||
|
|
||||||
if (error != DB_SUCCESS) {
|
|
||||||
|
|
||||||
return(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
error = dict_create_add_foreign_to_dictionary(table->name,
|
error = dict_create_add_foreign_to_dictionary(table->name,
|
||||||
foreign, trx);
|
foreign, trx);
|
||||||
|
|
|
@ -27,6 +27,7 @@ Created 1/8/1996 Heikki Tuuri
|
||||||
#include "dict0dict.h"
|
#include "dict0dict.h"
|
||||||
#include "fts0fts.h"
|
#include "fts0fts.h"
|
||||||
#include "fil0fil.h"
|
#include "fil0fil.h"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#ifdef UNIV_NONINL
|
#ifdef UNIV_NONINL
|
||||||
#include "dict0dict.ic"
|
#include "dict0dict.ic"
|
||||||
|
@ -1251,8 +1252,8 @@ dict_table_can_be_evicted(
|
||||||
#endif /* UNIV_SYNC_DEBUG */
|
#endif /* UNIV_SYNC_DEBUG */
|
||||||
|
|
||||||
ut_a(table->can_be_evicted);
|
ut_a(table->can_be_evicted);
|
||||||
ut_a(UT_LIST_GET_LEN(table->foreign_list) == 0);
|
ut_a(table->foreign_set.empty());
|
||||||
ut_a(UT_LIST_GET_LEN(table->referenced_list) == 0);
|
ut_a(table->referenced_set.empty());
|
||||||
|
|
||||||
if (table->n_ref_count == 0) {
|
if (table->n_ref_count == 0) {
|
||||||
dict_index_t* index;
|
dict_index_t* index;
|
||||||
|
@ -1468,6 +1469,22 @@ dict_index_find_on_id_low(
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Function object to remove a foreign key constraint from the
|
||||||
|
referenced_set of the referenced table. The foreign key object is
|
||||||
|
also removed from the dictionary cache. The foreign key constraint
|
||||||
|
is not removed from the foreign_set of the table containing the
|
||||||
|
constraint. */
|
||||||
|
struct dict_foreign_remove_partial
|
||||||
|
{
|
||||||
|
void operator()(dict_foreign_t* foreign) {
|
||||||
|
dict_table_t* table = foreign->referenced_table;
|
||||||
|
if (table != NULL) {
|
||||||
|
table->referenced_set.erase(foreign);
|
||||||
|
}
|
||||||
|
dict_foreign_free(foreign);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**********************************************************************//**
|
/**********************************************************************//**
|
||||||
Renames a table object.
|
Renames a table object.
|
||||||
@return TRUE if success */
|
@return TRUE if success */
|
||||||
|
@ -1642,27 +1659,25 @@ dict_table_rename_in_cache(
|
||||||
system tables through a call of dict_load_foreigns. */
|
system tables through a call of dict_load_foreigns. */
|
||||||
|
|
||||||
/* Remove the foreign constraints from the cache */
|
/* Remove the foreign constraints from the cache */
|
||||||
foreign = UT_LIST_GET_LAST(table->foreign_list);
|
std::for_each(table->foreign_set.begin(),
|
||||||
|
table->foreign_set.end(),
|
||||||
while (foreign != NULL) {
|
dict_foreign_remove_partial());
|
||||||
dict_foreign_remove_from_cache(foreign);
|
table->foreign_set.clear();
|
||||||
foreign = UT_LIST_GET_LAST(table->foreign_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reset table field in referencing constraints */
|
/* Reset table field in referencing constraints */
|
||||||
|
for (dict_foreign_set::iterator it
|
||||||
|
= table->referenced_set.begin();
|
||||||
|
it != table->referenced_set.end();
|
||||||
|
++it) {
|
||||||
|
|
||||||
foreign = UT_LIST_GET_FIRST(table->referenced_list);
|
foreign = *it;
|
||||||
|
|
||||||
while (foreign != NULL) {
|
|
||||||
foreign->referenced_table = NULL;
|
foreign->referenced_table = NULL;
|
||||||
foreign->referenced_index = NULL;
|
foreign->referenced_index = NULL;
|
||||||
|
|
||||||
foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make the list of referencing constraints empty */
|
/* Make the set of referencing constraints empty */
|
||||||
|
table->referenced_set.clear();
|
||||||
UT_LIST_INIT(table->referenced_list);
|
|
||||||
|
|
||||||
return(DB_SUCCESS);
|
return(DB_SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -1671,9 +1686,19 @@ dict_table_rename_in_cache(
|
||||||
the constraint id of new format >= 4.0.18 constraints. Note that at
|
the constraint id of new format >= 4.0.18 constraints. Note that at
|
||||||
this point we have already changed table->name to the new name. */
|
this point we have already changed table->name to the new name. */
|
||||||
|
|
||||||
foreign = UT_LIST_GET_FIRST(table->foreign_list);
|
dict_foreign_set fk_set;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
|
||||||
|
dict_foreign_set::iterator it
|
||||||
|
= table->foreign_set.begin();
|
||||||
|
|
||||||
|
if (it == table->foreign_set.end()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreign = *it;
|
||||||
|
|
||||||
while (foreign != NULL) {
|
|
||||||
if (ut_strlen(foreign->foreign_table_name)
|
if (ut_strlen(foreign->foreign_table_name)
|
||||||
< ut_strlen(table->name)) {
|
< ut_strlen(table->name)) {
|
||||||
/* Allocate a longer name buffer;
|
/* Allocate a longer name buffer;
|
||||||
|
@ -1823,12 +1848,18 @@ dict_table_rename_in_cache(
|
||||||
mem_free(old_id);
|
mem_free(old_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
|
table->foreign_set.erase(it);
|
||||||
|
fk_set.insert(foreign);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (foreign = UT_LIST_GET_FIRST(table->referenced_list);
|
ut_a(table->foreign_set.empty());
|
||||||
foreign != NULL;
|
table->foreign_set.swap(fk_set);
|
||||||
foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) {
|
|
||||||
|
for (dict_foreign_set::iterator it = table->referenced_set.begin();
|
||||||
|
it != table->referenced_set.end();
|
||||||
|
++it) {
|
||||||
|
|
||||||
|
foreign = *it;
|
||||||
|
|
||||||
if (ut_strlen(foreign->referenced_table_name)
|
if (ut_strlen(foreign->referenced_table_name)
|
||||||
< ut_strlen(table->name)) {
|
< ut_strlen(table->name)) {
|
||||||
|
@ -1898,27 +1929,17 @@ dict_table_remove_from_cache_low(
|
||||||
ut_ad(mutex_own(&(dict_sys->mutex)));
|
ut_ad(mutex_own(&(dict_sys->mutex)));
|
||||||
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
|
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
|
||||||
|
|
||||||
#if 0
|
|
||||||
fputs("Removing table ", stderr);
|
|
||||||
ut_print_name(stderr, table->name, ULINT_UNDEFINED);
|
|
||||||
fputs(" from dictionary cache\n", stderr);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Remove the foreign constraints from the cache */
|
/* Remove the foreign constraints from the cache */
|
||||||
|
std::for_each(table->foreign_set.begin(), table->foreign_set.end(),
|
||||||
for (foreign = UT_LIST_GET_LAST(table->foreign_list);
|
dict_foreign_remove_partial());
|
||||||
foreign != NULL;
|
table->foreign_set.clear();
|
||||||
foreign = UT_LIST_GET_LAST(table->foreign_list)) {
|
|
||||||
|
|
||||||
dict_foreign_remove_from_cache(foreign);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reset table field in referencing constraints */
|
/* Reset table field in referencing constraints */
|
||||||
|
for (dict_foreign_set::iterator it = table->referenced_set.begin();
|
||||||
|
it != table->referenced_set.end();
|
||||||
|
++it) {
|
||||||
|
|
||||||
for (foreign = UT_LIST_GET_FIRST(table->referenced_list);
|
foreign = *it;
|
||||||
foreign != NULL;
|
|
||||||
foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) {
|
|
||||||
|
|
||||||
foreign->referenced_table = NULL;
|
foreign->referenced_table = NULL;
|
||||||
foreign->referenced_index = NULL;
|
foreign->referenced_index = NULL;
|
||||||
}
|
}
|
||||||
|
@ -3134,7 +3155,7 @@ dict_table_is_referenced_by_foreign_key(
|
||||||
/*====================================*/
|
/*====================================*/
|
||||||
const dict_table_t* table) /*!< in: InnoDB table */
|
const dict_table_t* table) /*!< in: InnoDB table */
|
||||||
{
|
{
|
||||||
return(UT_LIST_GET_LEN(table->referenced_list) > 0);
|
return(!table->referenced_set.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
|
@ -3154,9 +3175,11 @@ dict_table_get_referenced_constraint(
|
||||||
ut_ad(index != NULL);
|
ut_ad(index != NULL);
|
||||||
ut_ad(table != NULL);
|
ut_ad(table != NULL);
|
||||||
|
|
||||||
for (foreign = UT_LIST_GET_FIRST(table->referenced_list);
|
for (dict_foreign_set::iterator it = table->referenced_set.begin();
|
||||||
foreign;
|
it != table->referenced_set.end();
|
||||||
foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) {
|
++it) {
|
||||||
|
|
||||||
|
foreign = *it;
|
||||||
|
|
||||||
if (foreign->referenced_index == index) {
|
if (foreign->referenced_index == index) {
|
||||||
|
|
||||||
|
@ -3185,9 +3208,11 @@ dict_table_get_foreign_constraint(
|
||||||
ut_ad(index != NULL);
|
ut_ad(index != NULL);
|
||||||
ut_ad(table != NULL);
|
ut_ad(table != NULL);
|
||||||
|
|
||||||
for (foreign = UT_LIST_GET_FIRST(table->foreign_list);
|
for (dict_foreign_set::iterator it = table->foreign_set.begin();
|
||||||
foreign;
|
it != table->foreign_set.end();
|
||||||
foreign = UT_LIST_GET_NEXT(foreign_list, foreign)) {
|
++it) {
|
||||||
|
|
||||||
|
foreign = *it;
|
||||||
|
|
||||||
if (foreign->foreign_index == index) {
|
if (foreign->foreign_index == index) {
|
||||||
|
|
||||||
|
@ -3198,17 +3223,6 @@ dict_table_get_foreign_constraint(
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
|
||||||
Frees a foreign key struct. */
|
|
||||||
UNIV_INTERN
|
|
||||||
void
|
|
||||||
dict_foreign_free(
|
|
||||||
/*==============*/
|
|
||||||
dict_foreign_t* foreign) /*!< in, own: foreign key struct */
|
|
||||||
{
|
|
||||||
mem_heap_free(foreign->heap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************//**
|
/**********************************************************************//**
|
||||||
Removes a foreign constraint struct from the dictionary cache. */
|
Removes a foreign constraint struct from the dictionary cache. */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
|
@ -3220,16 +3234,12 @@ dict_foreign_remove_from_cache(
|
||||||
ut_ad(mutex_own(&(dict_sys->mutex)));
|
ut_ad(mutex_own(&(dict_sys->mutex)));
|
||||||
ut_a(foreign);
|
ut_a(foreign);
|
||||||
|
|
||||||
if (foreign->referenced_table) {
|
if (foreign->referenced_table != NULL) {
|
||||||
UT_LIST_REMOVE(referenced_list,
|
foreign->referenced_table->referenced_set.erase(foreign);
|
||||||
foreign->referenced_table->referenced_list,
|
|
||||||
foreign);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foreign->foreign_table) {
|
if (foreign->foreign_table != NULL) {
|
||||||
UT_LIST_REMOVE(foreign_list,
|
foreign->foreign_table->foreign_set.erase(foreign);
|
||||||
foreign->foreign_table->foreign_list,
|
|
||||||
foreign);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dict_foreign_free(foreign);
|
dict_foreign_free(foreign);
|
||||||
|
@ -3243,33 +3253,21 @@ static
|
||||||
dict_foreign_t*
|
dict_foreign_t*
|
||||||
dict_foreign_find(
|
dict_foreign_find(
|
||||||
/*==============*/
|
/*==============*/
|
||||||
dict_table_t* table, /*!< in: table object */
|
dict_table_t* table, /*!< in: table object */
|
||||||
const char* id) /*!< in: foreign constraint id */
|
dict_foreign_t* foreign) /*!< in: foreign constraint */
|
||||||
{
|
{
|
||||||
dict_foreign_t* foreign;
|
|
||||||
|
|
||||||
ut_ad(mutex_own(&(dict_sys->mutex)));
|
ut_ad(mutex_own(&(dict_sys->mutex)));
|
||||||
|
|
||||||
foreign = UT_LIST_GET_FIRST(table->foreign_list);
|
dict_foreign_set::iterator it = table->foreign_set.find(foreign);
|
||||||
|
|
||||||
while (foreign) {
|
if (it != table->foreign_set.end()) {
|
||||||
if (ut_strcmp(id, foreign->id) == 0) {
|
return(*it);
|
||||||
|
|
||||||
return(foreign);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreign = UT_LIST_GET_FIRST(table->referenced_list);
|
it = table->referenced_set.find(foreign);
|
||||||
|
|
||||||
while (foreign) {
|
if (it != table->referenced_set.end()) {
|
||||||
if (ut_strcmp(id, foreign->id) == 0) {
|
return(*it);
|
||||||
|
|
||||||
return(foreign);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return(NULL);
|
return(NULL);
|
||||||
|
@ -3407,11 +3405,11 @@ dict_foreign_add_to_cache(
|
||||||
ut_a(for_table || ref_table);
|
ut_a(for_table || ref_table);
|
||||||
|
|
||||||
if (for_table) {
|
if (for_table) {
|
||||||
for_in_cache = dict_foreign_find(for_table, foreign->id);
|
for_in_cache = dict_foreign_find(for_table, foreign);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!for_in_cache && ref_table) {
|
if (!for_in_cache && ref_table) {
|
||||||
for_in_cache = dict_foreign_find(ref_table, foreign->id);
|
for_in_cache = dict_foreign_find(ref_table, foreign);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (for_in_cache) {
|
if (for_in_cache) {
|
||||||
|
@ -3448,9 +3446,12 @@ dict_foreign_add_to_cache(
|
||||||
|
|
||||||
for_in_cache->referenced_table = ref_table;
|
for_in_cache->referenced_table = ref_table;
|
||||||
for_in_cache->referenced_index = index;
|
for_in_cache->referenced_index = index;
|
||||||
UT_LIST_ADD_LAST(referenced_list,
|
|
||||||
ref_table->referenced_list,
|
std::pair<dict_foreign_set::iterator, bool> ret
|
||||||
for_in_cache);
|
= ref_table->referenced_set.insert(for_in_cache);
|
||||||
|
|
||||||
|
ut_a(ret.second); /* second is true if the insertion
|
||||||
|
took place */
|
||||||
added_to_referenced_list = TRUE;
|
added_to_referenced_list = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3479,10 +3480,13 @@ dict_foreign_add_to_cache(
|
||||||
|
|
||||||
if (for_in_cache == foreign) {
|
if (for_in_cache == foreign) {
|
||||||
if (added_to_referenced_list) {
|
if (added_to_referenced_list) {
|
||||||
UT_LIST_REMOVE(
|
const dict_foreign_set::size_type n
|
||||||
referenced_list,
|
= ref_table->referenced_set
|
||||||
ref_table->referenced_list,
|
.erase(for_in_cache);
|
||||||
for_in_cache);
|
|
||||||
|
ut_a(n == 1); /* the number of
|
||||||
|
elements removed must
|
||||||
|
be one */
|
||||||
}
|
}
|
||||||
|
|
||||||
mem_heap_free(foreign->heap);
|
mem_heap_free(foreign->heap);
|
||||||
|
@ -3493,9 +3497,11 @@ dict_foreign_add_to_cache(
|
||||||
|
|
||||||
for_in_cache->foreign_table = for_table;
|
for_in_cache->foreign_table = for_table;
|
||||||
for_in_cache->foreign_index = index;
|
for_in_cache->foreign_index = index;
|
||||||
UT_LIST_ADD_LAST(foreign_list,
|
std::pair<dict_foreign_set::iterator, bool> ret
|
||||||
for_table->foreign_list,
|
= for_table->foreign_set.insert(for_in_cache);
|
||||||
for_in_cache);
|
|
||||||
|
ut_a(ret.second); /* second is true if the insertion
|
||||||
|
took place */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We need to move the table to the non-LRU end of the table LRU
|
/* We need to move the table to the non-LRU end of the table LRU
|
||||||
|
@ -4073,9 +4079,12 @@ dict_table_get_highest_foreign_id(
|
||||||
ut_a(table);
|
ut_a(table);
|
||||||
|
|
||||||
len = ut_strlen(table->name);
|
len = ut_strlen(table->name);
|
||||||
foreign = UT_LIST_GET_FIRST(table->foreign_list);
|
|
||||||
|
|
||||||
while (foreign) {
|
for (dict_foreign_set::iterator it = table->foreign_set.begin();
|
||||||
|
it != table->foreign_set.end();
|
||||||
|
++it) {
|
||||||
|
foreign = *it;
|
||||||
|
|
||||||
if (ut_strlen(foreign->id) > ((sizeof dict_ibfk) - 1) + len
|
if (ut_strlen(foreign->id) > ((sizeof dict_ibfk) - 1) + len
|
||||||
&& 0 == ut_memcmp(foreign->id, table->name, len)
|
&& 0 == ut_memcmp(foreign->id, table->name, len)
|
||||||
&& 0 == ut_memcmp(foreign->id + len,
|
&& 0 == ut_memcmp(foreign->id + len,
|
||||||
|
@ -4094,8 +4103,6 @@ dict_table_get_highest_foreign_id(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return(biggest_id);
|
return(biggest_id);
|
||||||
|
@ -4156,6 +4163,7 @@ dict_create_foreign_constraints_low(
|
||||||
dict_table_t* referenced_table;
|
dict_table_t* referenced_table;
|
||||||
dict_table_t* table_to_alter;
|
dict_table_t* table_to_alter;
|
||||||
ulint highest_id_so_far = 0;
|
ulint highest_id_so_far = 0;
|
||||||
|
ulint number = 1;
|
||||||
dict_index_t* index;
|
dict_index_t* index;
|
||||||
dict_foreign_t* foreign;
|
dict_foreign_t* foreign;
|
||||||
const char* ptr = sql_string;
|
const char* ptr = sql_string;
|
||||||
|
@ -4174,6 +4182,8 @@ dict_create_foreign_constraints_low(
|
||||||
const dict_col_t*columns[500];
|
const dict_col_t*columns[500];
|
||||||
const char* column_names[500];
|
const char* column_names[500];
|
||||||
const char* referenced_table_name;
|
const char* referenced_table_name;
|
||||||
|
dict_foreign_set local_fk_set;
|
||||||
|
dict_foreign_set_free local_fk_set_free(local_fk_set);
|
||||||
|
|
||||||
ut_ad(!srv_read_only_mode);
|
ut_ad(!srv_read_only_mode);
|
||||||
ut_ad(mutex_own(&(dict_sys->mutex)));
|
ut_ad(mutex_own(&(dict_sys->mutex)));
|
||||||
|
@ -4238,6 +4248,7 @@ dict_create_foreign_constraints_low(
|
||||||
table_to_alter);
|
table_to_alter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
number = highest_id_so_far + 1;
|
||||||
/* Scan for foreign key declarations in a loop */
|
/* Scan for foreign key declarations in a loop */
|
||||||
loop:
|
loop:
|
||||||
/* Scan either to "CONSTRAINT" or "FOREIGN", whichever is closer */
|
/* Scan either to "CONSTRAINT" or "FOREIGN", whichever is closer */
|
||||||
|
@ -4282,7 +4293,7 @@ loop:
|
||||||
command, determine if there are any foreign keys, and
|
command, determine if there are any foreign keys, and
|
||||||
if so, immediately reject the command if the table is a
|
if so, immediately reject the command if the table is a
|
||||||
temporary one. For now, this kludge will work. */
|
temporary one. For now, this kludge will work. */
|
||||||
if (reject_fks && (UT_LIST_GET_LEN(table->foreign_list) > 0)) {
|
if (reject_fks && !local_fk_set.empty()) {
|
||||||
|
|
||||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||||
}
|
}
|
||||||
|
@ -4292,7 +4303,17 @@ loop:
|
||||||
to the data dictionary system tables on disk */
|
to the data dictionary system tables on disk */
|
||||||
|
|
||||||
error = dict_create_add_foreigns_to_dictionary(
|
error = dict_create_add_foreigns_to_dictionary(
|
||||||
highest_id_so_far, table, trx);
|
local_fk_set, table, trx);
|
||||||
|
|
||||||
|
if (error == DB_SUCCESS) {
|
||||||
|
|
||||||
|
table->foreign_set.insert(local_fk_set.begin(),
|
||||||
|
local_fk_set.end());
|
||||||
|
std::for_each(local_fk_set.begin(),
|
||||||
|
local_fk_set.end(),
|
||||||
|
dict_foreign_add_to_referenced_table());
|
||||||
|
local_fk_set.clear();
|
||||||
|
}
|
||||||
return(error);
|
return(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4451,6 +4472,24 @@ col_loop1:
|
||||||
strcpy(foreign->id + db_len + 1, constraint_name);
|
strcpy(foreign->id + db_len + 1, constraint_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (foreign->id == NULL) {
|
||||||
|
error = dict_create_add_foreign_id(&number,
|
||||||
|
table->name, foreign);
|
||||||
|
if (error != DB_SUCCESS) {
|
||||||
|
dict_foreign_free(foreign);
|
||||||
|
return(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<dict_foreign_set::iterator, bool> ret
|
||||||
|
= local_fk_set.insert(foreign);
|
||||||
|
|
||||||
|
if (!ret.second) {
|
||||||
|
/* A duplicate foreign key name has been found */
|
||||||
|
dict_foreign_free(foreign);
|
||||||
|
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||||
|
}
|
||||||
|
|
||||||
foreign->foreign_table = table;
|
foreign->foreign_table = table;
|
||||||
foreign->foreign_table_name = mem_heap_strdup(
|
foreign->foreign_table_name = mem_heap_strdup(
|
||||||
foreign->heap, table->name);
|
foreign->heap, table->name);
|
||||||
|
@ -4476,8 +4515,6 @@ col_loop1:
|
||||||
checking of foreign key constraints! */
|
checking of foreign key constraints! */
|
||||||
|
|
||||||
if (!success || (!referenced_table && trx->check_foreigns)) {
|
if (!success || (!referenced_table && trx->check_foreigns)) {
|
||||||
dict_foreign_free(foreign);
|
|
||||||
|
|
||||||
mutex_enter(&dict_foreign_err_mutex);
|
mutex_enter(&dict_foreign_err_mutex);
|
||||||
dict_foreign_error_report_low(ef, name);
|
dict_foreign_error_report_low(ef, name);
|
||||||
fprintf(ef, "%s:\nCannot resolve table name close to:\n"
|
fprintf(ef, "%s:\nCannot resolve table name close to:\n"
|
||||||
|
@ -4491,7 +4528,6 @@ col_loop1:
|
||||||
ptr = dict_accept(cs, ptr, "(", &success);
|
ptr = dict_accept(cs, ptr, "(", &success);
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
dict_foreign_free(foreign);
|
|
||||||
dict_foreign_report_syntax_err(name, start_of_latest_foreign,
|
dict_foreign_report_syntax_err(name, start_of_latest_foreign,
|
||||||
ptr);
|
ptr);
|
||||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||||
|
@ -4506,7 +4542,6 @@ col_loop2:
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
dict_foreign_free(foreign);
|
|
||||||
|
|
||||||
mutex_enter(&dict_foreign_err_mutex);
|
mutex_enter(&dict_foreign_err_mutex);
|
||||||
dict_foreign_error_report_low(ef, name);
|
dict_foreign_error_report_low(ef, name);
|
||||||
|
@ -4527,7 +4562,6 @@ col_loop2:
|
||||||
ptr = dict_accept(cs, ptr, ")", &success);
|
ptr = dict_accept(cs, ptr, ")", &success);
|
||||||
|
|
||||||
if (!success || foreign->n_fields != i) {
|
if (!success || foreign->n_fields != i) {
|
||||||
dict_foreign_free(foreign);
|
|
||||||
|
|
||||||
dict_foreign_report_syntax_err(name, start_of_latest_foreign,
|
dict_foreign_report_syntax_err(name, start_of_latest_foreign,
|
||||||
ptr);
|
ptr);
|
||||||
|
@ -4553,7 +4587,6 @@ scan_on_conditions:
|
||||||
ptr = dict_accept(cs, ptr, "UPDATE", &success);
|
ptr = dict_accept(cs, ptr, "UPDATE", &success);
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
dict_foreign_free(foreign);
|
|
||||||
|
|
||||||
dict_foreign_report_syntax_err(
|
dict_foreign_report_syntax_err(
|
||||||
name, start_of_latest_foreign, ptr);
|
name, start_of_latest_foreign, ptr);
|
||||||
|
@ -4591,7 +4624,6 @@ scan_on_conditions:
|
||||||
ptr = dict_accept(cs, ptr, "ACTION", &success);
|
ptr = dict_accept(cs, ptr, "ACTION", &success);
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
dict_foreign_free(foreign);
|
|
||||||
dict_foreign_report_syntax_err(
|
dict_foreign_report_syntax_err(
|
||||||
name, start_of_latest_foreign, ptr);
|
name, start_of_latest_foreign, ptr);
|
||||||
|
|
||||||
|
@ -4610,7 +4642,6 @@ scan_on_conditions:
|
||||||
ptr = dict_accept(cs, ptr, "SET", &success);
|
ptr = dict_accept(cs, ptr, "SET", &success);
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
dict_foreign_free(foreign);
|
|
||||||
dict_foreign_report_syntax_err(name, start_of_latest_foreign,
|
dict_foreign_report_syntax_err(name, start_of_latest_foreign,
|
||||||
ptr);
|
ptr);
|
||||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||||
|
@ -4619,7 +4650,6 @@ scan_on_conditions:
|
||||||
ptr = dict_accept(cs, ptr, "NULL", &success);
|
ptr = dict_accept(cs, ptr, "NULL", &success);
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
dict_foreign_free(foreign);
|
|
||||||
dict_foreign_report_syntax_err(name, start_of_latest_foreign,
|
dict_foreign_report_syntax_err(name, start_of_latest_foreign,
|
||||||
ptr);
|
ptr);
|
||||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||||
|
@ -4632,8 +4662,6 @@ scan_on_conditions:
|
||||||
/* It is not sensible to define SET NULL
|
/* It is not sensible to define SET NULL
|
||||||
if the column is not allowed to be NULL! */
|
if the column is not allowed to be NULL! */
|
||||||
|
|
||||||
dict_foreign_free(foreign);
|
|
||||||
|
|
||||||
mutex_enter(&dict_foreign_err_mutex);
|
mutex_enter(&dict_foreign_err_mutex);
|
||||||
dict_foreign_error_report_low(ef, name);
|
dict_foreign_error_report_low(ef, name);
|
||||||
fprintf(ef, "%s:\n"
|
fprintf(ef, "%s:\n"
|
||||||
|
@ -4659,8 +4687,6 @@ try_find_index:
|
||||||
if (n_on_deletes > 1 || n_on_updates > 1) {
|
if (n_on_deletes > 1 || n_on_updates > 1) {
|
||||||
/* It is an error to define more than 1 action */
|
/* It is an error to define more than 1 action */
|
||||||
|
|
||||||
dict_foreign_free(foreign);
|
|
||||||
|
|
||||||
mutex_enter(&dict_foreign_err_mutex);
|
mutex_enter(&dict_foreign_err_mutex);
|
||||||
dict_foreign_error_report_low(ef, name);
|
dict_foreign_error_report_low(ef, name);
|
||||||
fprintf(ef, "%s:\n"
|
fprintf(ef, "%s:\n"
|
||||||
|
@ -4682,7 +4708,6 @@ try_find_index:
|
||||||
foreign->foreign_index,
|
foreign->foreign_index,
|
||||||
TRUE, FALSE);
|
TRUE, FALSE);
|
||||||
if (!index) {
|
if (!index) {
|
||||||
dict_foreign_free(foreign);
|
|
||||||
mutex_enter(&dict_foreign_err_mutex);
|
mutex_enter(&dict_foreign_err_mutex);
|
||||||
dict_foreign_error_report_low(ef, name);
|
dict_foreign_error_report_low(ef, name);
|
||||||
fprintf(ef, "%s:\n"
|
fprintf(ef, "%s:\n"
|
||||||
|
@ -4726,16 +4751,6 @@ try_find_index:
|
||||||
= mem_heap_strdup(foreign->heap, column_names[i]);
|
= mem_heap_strdup(foreign->heap, column_names[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We found an ok constraint definition: add to the lists */
|
|
||||||
|
|
||||||
UT_LIST_ADD_LAST(foreign_list, table->foreign_list, foreign);
|
|
||||||
|
|
||||||
if (referenced_table) {
|
|
||||||
UT_LIST_ADD_LAST(referenced_list,
|
|
||||||
referenced_table->referenced_list,
|
|
||||||
foreign);
|
|
||||||
}
|
|
||||||
|
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -4821,7 +4836,6 @@ dict_foreign_parse_drop_constraints(
|
||||||
const char*** constraints_to_drop) /*!< out: id's of the
|
const char*** constraints_to_drop) /*!< out: id's of the
|
||||||
constraints to drop */
|
constraints to drop */
|
||||||
{
|
{
|
||||||
dict_foreign_t* foreign;
|
|
||||||
ibool success;
|
ibool success;
|
||||||
char* str;
|
char* str;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
@ -4898,25 +4912,10 @@ loop:
|
||||||
(*constraints_to_drop)[*n] = id;
|
(*constraints_to_drop)[*n] = id;
|
||||||
(*n)++;
|
(*n)++;
|
||||||
|
|
||||||
/* Look for the given constraint id */
|
if (std::find_if(table->foreign_set.begin(),
|
||||||
|
table->foreign_set.end(),
|
||||||
foreign = UT_LIST_GET_FIRST(table->foreign_list);
|
dict_foreign_matches_id(id))
|
||||||
|
== table->foreign_set.end()) {
|
||||||
while (foreign != NULL) {
|
|
||||||
if (0 == innobase_strcasecmp(foreign->id, id)
|
|
||||||
|| (strchr(foreign->id, '/')
|
|
||||||
&& 0 == innobase_strcasecmp(
|
|
||||||
id,
|
|
||||||
dict_remove_db_name(foreign->id)))) {
|
|
||||||
/* Found */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (foreign == NULL) {
|
|
||||||
|
|
||||||
if (!srv_read_only_mode) {
|
if (!srv_read_only_mode) {
|
||||||
FILE* ef = dict_foreign_err_file;
|
FILE* ef = dict_foreign_err_file;
|
||||||
|
@ -5243,7 +5242,6 @@ dict_table_print(
|
||||||
dict_table_t* table) /*!< in: table */
|
dict_table_t* table) /*!< in: table */
|
||||||
{
|
{
|
||||||
dict_index_t* index;
|
dict_index_t* index;
|
||||||
dict_foreign_t* foreign;
|
|
||||||
ulint i;
|
ulint i;
|
||||||
|
|
||||||
ut_ad(mutex_own(&(dict_sys->mutex)));
|
ut_ad(mutex_own(&(dict_sys->mutex)));
|
||||||
|
@ -5282,19 +5280,13 @@ dict_table_print(
|
||||||
|
|
||||||
dict_table_stats_unlock(table, RW_X_LATCH);
|
dict_table_stats_unlock(table, RW_X_LATCH);
|
||||||
|
|
||||||
foreign = UT_LIST_GET_FIRST(table->foreign_list);
|
std::for_each(table->foreign_set.begin(),
|
||||||
|
table->foreign_set.end(),
|
||||||
|
dict_foreign_print_low);
|
||||||
|
|
||||||
while (foreign != NULL) {
|
std::for_each(table->referenced_set.begin(),
|
||||||
dict_foreign_print_low(foreign);
|
table->referenced_set.end(),
|
||||||
foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
|
dict_foreign_print_low);
|
||||||
}
|
|
||||||
|
|
||||||
foreign = UT_LIST_GET_FIRST(table->referenced_list);
|
|
||||||
|
|
||||||
while (foreign != NULL) {
|
|
||||||
dict_foreign_print_low(foreign);
|
|
||||||
foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************//**
|
/**********************************************************************//**
|
||||||
|
@ -5502,15 +5494,12 @@ dict_print_info_on_foreign_keys(
|
||||||
|
|
||||||
mutex_enter(&(dict_sys->mutex));
|
mutex_enter(&(dict_sys->mutex));
|
||||||
|
|
||||||
foreign = UT_LIST_GET_FIRST(table->foreign_list);
|
for (dict_foreign_set::iterator it = table->foreign_set.begin();
|
||||||
|
it != table->foreign_set.end();
|
||||||
|
++it) {
|
||||||
|
|
||||||
if (foreign == NULL) {
|
foreign = *it;
|
||||||
mutex_exit(&(dict_sys->mutex));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (foreign != NULL) {
|
|
||||||
if (create_table_format) {
|
if (create_table_format) {
|
||||||
dict_print_info_on_foreign_key_in_create_format(
|
dict_print_info_on_foreign_key_in_create_format(
|
||||||
file, trx, foreign, TRUE);
|
file, trx, foreign, TRUE);
|
||||||
|
@ -5567,8 +5556,6 @@ dict_print_info_on_foreign_keys(
|
||||||
fputs(" ON UPDATE NO ACTION", file);
|
fputs(" ON UPDATE NO ACTION", file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_exit(&(dict_sys->mutex));
|
mutex_exit(&(dict_sys->mutex));
|
||||||
|
@ -5900,10 +5887,11 @@ dict_foreign_replace_index(
|
||||||
ut_ad(index->to_be_dropped);
|
ut_ad(index->to_be_dropped);
|
||||||
ut_ad(index->table == table);
|
ut_ad(index->table == table);
|
||||||
|
|
||||||
for (foreign = UT_LIST_GET_FIRST(table->foreign_list);
|
for (dict_foreign_set::iterator it = table->foreign_set.begin();
|
||||||
foreign;
|
it != table->foreign_set.end();
|
||||||
foreign = UT_LIST_GET_NEXT(foreign_list, foreign)) {
|
++it) {
|
||||||
|
|
||||||
|
foreign = *it;
|
||||||
if (foreign->foreign_index == index) {
|
if (foreign->foreign_index == index) {
|
||||||
ut_ad(foreign->foreign_table == index->table);
|
ut_ad(foreign->foreign_table == index->table);
|
||||||
|
|
||||||
|
@ -5923,10 +5911,11 @@ dict_foreign_replace_index(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (foreign = UT_LIST_GET_FIRST(table->referenced_list);
|
for (dict_foreign_set::iterator it = table->referenced_set.begin();
|
||||||
foreign;
|
it != table->referenced_set.end();
|
||||||
foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) {
|
++it) {
|
||||||
|
|
||||||
|
foreign = *it;
|
||||||
if (foreign->referenced_index == index) {
|
if (foreign->referenced_index == index) {
|
||||||
ut_ad(foreign->referenced_table == index->table);
|
ut_ad(foreign->referenced_table == index->table);
|
||||||
|
|
||||||
|
@ -6246,24 +6235,24 @@ dict_table_schema_check(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req_schema->n_foreign != UT_LIST_GET_LEN(table->foreign_list)) {
|
if (req_schema->n_foreign != table->foreign_set.size()) {
|
||||||
ut_snprintf(
|
ut_snprintf(
|
||||||
errstr, errstr_sz,
|
errstr, errstr_sz,
|
||||||
"Table %s has %lu foreign key(s) pointing to other "
|
"Table %s has " ULINTPF " foreign key(s) pointing"
|
||||||
"tables, but it must have %lu.",
|
" to other tables, but it must have %lu.",
|
||||||
ut_format_name(req_schema->table_name,
|
ut_format_name(req_schema->table_name,
|
||||||
TRUE, buf, sizeof(buf)),
|
TRUE, buf, sizeof(buf)),
|
||||||
UT_LIST_GET_LEN(table->foreign_list),
|
static_cast<ulint>(table->foreign_set.size()),
|
||||||
req_schema->n_foreign);
|
req_schema->n_foreign);
|
||||||
return(DB_ERROR);
|
return(DB_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req_schema->n_referenced != UT_LIST_GET_LEN(table->referenced_list)) {
|
if (req_schema->n_referenced != table->referenced_set.size()) {
|
||||||
ut_snprintf(
|
ut_snprintf(
|
||||||
errstr, errstr_sz,
|
errstr, errstr_sz,
|
||||||
"There are %lu foreign key(s) pointing to %s, "
|
"There are " ULINTPF " foreign key(s) pointing to %s, "
|
||||||
"but there must be %lu.",
|
"but there must be %lu.",
|
||||||
UT_LIST_GET_LEN(table->referenced_list),
|
static_cast<ulint>(table->referenced_set.size()),
|
||||||
ut_format_name(req_schema->table_name,
|
ut_format_name(req_schema->table_name,
|
||||||
TRUE, buf, sizeof(buf)),
|
TRUE, buf, sizeof(buf)),
|
||||||
req_schema->n_referenced);
|
req_schema->n_referenced);
|
||||||
|
|
|
@ -124,6 +124,9 @@ dict_mem_table_create(
|
||||||
}
|
}
|
||||||
#endif /* !UNIV_HOTBACKUP */
|
#endif /* !UNIV_HOTBACKUP */
|
||||||
|
|
||||||
|
new(&table->foreign_set) dict_foreign_set();
|
||||||
|
new(&table->referenced_set) dict_foreign_set();
|
||||||
|
|
||||||
return(table);
|
return(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,6 +159,9 @@ dict_mem_table_free(
|
||||||
|
|
||||||
dict_table_stats_latch_destroy(table);
|
dict_table_stats_latch_destroy(table);
|
||||||
|
|
||||||
|
table->foreign_set.~dict_foreign_set();
|
||||||
|
table->referenced_set.~dict_foreign_set();
|
||||||
|
|
||||||
ut_free(table->name);
|
ut_free(table->name);
|
||||||
mem_heap_free(table->heap);
|
mem_heap_free(table->heap);
|
||||||
}
|
}
|
||||||
|
@ -326,10 +332,15 @@ dict_mem_table_col_rename_low(
|
||||||
table->col_names = col_names;
|
table->col_names = col_names;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dict_foreign_t* foreign;
|
||||||
|
|
||||||
/* Replace the field names in every foreign key constraint. */
|
/* Replace the field names in every foreign key constraint. */
|
||||||
for (dict_foreign_t* foreign = UT_LIST_GET_FIRST(table->foreign_list);
|
for (dict_foreign_set::iterator it = table->foreign_set.begin();
|
||||||
foreign != NULL;
|
it != table->foreign_set.end();
|
||||||
foreign = UT_LIST_GET_NEXT(foreign_list, foreign)) {
|
++it) {
|
||||||
|
|
||||||
|
foreign = *it;
|
||||||
|
|
||||||
for (unsigned f = 0; f < foreign->n_fields; f++) {
|
for (unsigned f = 0; f < foreign->n_fields; f++) {
|
||||||
/* These can point straight to
|
/* These can point straight to
|
||||||
table->col_names, because the foreign key
|
table->col_names, because the foreign key
|
||||||
|
@ -341,10 +352,12 @@ dict_mem_table_col_rename_low(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (dict_foreign_t* foreign = UT_LIST_GET_FIRST(
|
for (dict_foreign_set::iterator it = table->referenced_set.begin();
|
||||||
table->referenced_list);
|
it != table->referenced_set.end();
|
||||||
foreign != NULL;
|
++it) {
|
||||||
foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) {
|
|
||||||
|
foreign = *it;
|
||||||
|
|
||||||
for (unsigned f = 0; f < foreign->n_fields; f++) {
|
for (unsigned f = 0; f < foreign->n_fields; f++) {
|
||||||
/* foreign->referenced_col_names[] need to be
|
/* foreign->referenced_col_names[] need to be
|
||||||
copies, because the constraint may become
|
copies, because the constraint may become
|
||||||
|
|
|
@ -112,7 +112,7 @@ completes, we decrement the count and return the file node to the LRU-list if
|
||||||
the count drops to zero. */
|
the count drops to zero. */
|
||||||
|
|
||||||
/** When mysqld is run, the default directory "." is the mysqld datadir,
|
/** When mysqld is run, the default directory "." is the mysqld datadir,
|
||||||
but in the MySQL Embedded Server Library and ibbackup it is not the default
|
but in the MySQL Embedded Server Library and mysqlbackup it is not the default
|
||||||
directory, and we must set the base file path explicitly */
|
directory, and we must set the base file path explicitly */
|
||||||
UNIV_INTERN const char* fil_path_to_mysql_datadir = ".";
|
UNIV_INTERN const char* fil_path_to_mysql_datadir = ".";
|
||||||
|
|
||||||
|
@ -2017,8 +2017,8 @@ fil_check_first_page(
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************//**
|
/*******************************************************************//**
|
||||||
Reads the flushed lsn, arch no, and tablespace flag fields from a data
|
Reads the flushed lsn, arch no, space_id and tablespace flag fields from
|
||||||
file at database startup.
|
the first page of a data file at database startup.
|
||||||
@retval NULL on success, or if innodb_force_recovery is set
|
@retval NULL on success, or if innodb_force_recovery is set
|
||||||
@return pointer to an error message string */
|
@return pointer to an error message string */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
|
@ -2055,16 +2055,19 @@ fil_read_first_page(
|
||||||
|
|
||||||
os_file_read(data_file, page, 0, UNIV_PAGE_SIZE);
|
os_file_read(data_file, page, 0, UNIV_PAGE_SIZE);
|
||||||
|
|
||||||
*flags = fsp_header_get_flags(page);
|
/* The FSP_HEADER on page 0 is only valid for the first file
|
||||||
|
in a tablespace. So if this is not the first datafile, leave
|
||||||
*space_id = fsp_header_get_space_id(page);
|
*flags and *space_id as they were read from the first file and
|
||||||
|
do not validate the first page. */
|
||||||
flushed_lsn = mach_read_from_8(page + FIL_PAGE_FILE_FLUSH_LSN);
|
|
||||||
|
|
||||||
if (!one_read_already) {
|
if (!one_read_already) {
|
||||||
|
*flags = fsp_header_get_flags(page);
|
||||||
|
*space_id = fsp_header_get_space_id(page);
|
||||||
|
|
||||||
check_msg = fil_check_first_page(page);
|
check_msg = fil_check_first_page(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flushed_lsn = mach_read_from_8(page + FIL_PAGE_FILE_FLUSH_LSN);
|
||||||
|
|
||||||
ut_free(buf);
|
ut_free(buf);
|
||||||
|
|
||||||
if (check_msg) {
|
if (check_msg) {
|
||||||
|
@ -2272,13 +2275,13 @@ exists and the space id in it matches. Replays the create operation if a file
|
||||||
at that path does not exist yet. If the database directory for the file to be
|
at that path does not exist yet. If the database directory for the file to be
|
||||||
created does not exist, then we create the directory, too.
|
created does not exist, then we create the directory, too.
|
||||||
|
|
||||||
Note that ibbackup --apply-log sets fil_path_to_mysql_datadir to point to the
|
Note that mysqlbackup --apply-log sets fil_path_to_mysql_datadir to point to
|
||||||
datadir that we should use in replaying the file operations.
|
the datadir that we should use in replaying the file operations.
|
||||||
|
|
||||||
InnoDB recovery does not replay these fully since it always sets the space id
|
InnoDB recovery does not replay these fully since it always sets the space id
|
||||||
to zero. But ibbackup does replay them. TODO: If remote tablespaces are used,
|
to zero. But mysqlbackup does replay them. TODO: If remote tablespaces are
|
||||||
ibbackup will only create tables in the default directory since MLOG_FILE_CREATE
|
used, mysqlbackup will only create tables in the default directory since
|
||||||
and MLOG_FILE_CREATE2 only know the tablename, not the path.
|
MLOG_FILE_CREATE and MLOG_FILE_CREATE2 only know the tablename, not the path.
|
||||||
|
|
||||||
@return end of log record, or NULL if the record was not completely
|
@return end of log record, or NULL if the record was not completely
|
||||||
contained between ptr and end_ptr */
|
contained between ptr and end_ptr */
|
||||||
|
@ -2365,11 +2368,11 @@ fil_op_log_parse_or_replay(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Let us try to perform the file operation, if sensible. Note that
|
/* Let us try to perform the file operation, if sensible. Note that
|
||||||
ibbackup has at this stage already read in all space id info to the
|
mysqlbackup has at this stage already read in all space id info to the
|
||||||
fil0fil.cc data structures.
|
fil0fil.cc data structures.
|
||||||
|
|
||||||
NOTE that our algorithm is not guaranteed to work correctly if there
|
NOTE that our algorithm is not guaranteed to work correctly if there
|
||||||
were renames of tables during the backup. See ibbackup code for more
|
were renames of tables during the backup. See mysqlbackup code for more
|
||||||
on the problem. */
|
on the problem. */
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -2784,12 +2787,12 @@ fil_delete_tablespace(
|
||||||
if (err == DB_SUCCESS) {
|
if (err == DB_SUCCESS) {
|
||||||
#ifndef UNIV_HOTBACKUP
|
#ifndef UNIV_HOTBACKUP
|
||||||
/* Write a log record about the deletion of the .ibd
|
/* Write a log record about the deletion of the .ibd
|
||||||
file, so that ibbackup can replay it in the
|
file, so that mysqlbackup can replay it in the
|
||||||
--apply-log phase. We use a dummy mtr and the familiar
|
--apply-log phase. We use a dummy mtr and the familiar
|
||||||
log write mechanism. */
|
log write mechanism. */
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
|
|
||||||
/* When replaying the operation in ibbackup, do not try
|
/* When replaying the operation in mysqlbackup, do not try
|
||||||
to write any log record */
|
to write any log record */
|
||||||
mtr_start(&mtr);
|
mtr_start(&mtr);
|
||||||
|
|
||||||
|
@ -4463,7 +4466,7 @@ will_not_choose:
|
||||||
" (< 4 pages 16 kB each),\n"
|
" (< 4 pages 16 kB each),\n"
|
||||||
"InnoDB: or the space id in the file header"
|
"InnoDB: or the space id in the file header"
|
||||||
" is not sensible.\n"
|
" is not sensible.\n"
|
||||||
"InnoDB: This can happen in an ibbackup run,"
|
"InnoDB: This can happen in an mysqlbackup run,"
|
||||||
" and is not dangerous.\n",
|
" and is not dangerous.\n",
|
||||||
fsp->filepath, fsp->id, fsp->filepath, size);
|
fsp->filepath, fsp->id, fsp->filepath, size);
|
||||||
os_file_close(fsp->file);
|
os_file_close(fsp->file);
|
||||||
|
@ -4500,7 +4503,7 @@ will_not_choose:
|
||||||
"InnoDB: because space %s with the same id\n"
|
"InnoDB: because space %s with the same id\n"
|
||||||
"InnoDB: was scanned earlier. This can happen"
|
"InnoDB: was scanned earlier. This can happen"
|
||||||
" if you have renamed tables\n"
|
" if you have renamed tables\n"
|
||||||
"InnoDB: during an ibbackup run.\n",
|
"InnoDB: during an mysqlbackup run.\n",
|
||||||
fsp->filepath, fsp->id, fsp->filepath,
|
fsp->filepath, fsp->id, fsp->filepath,
|
||||||
space->name);
|
space->name);
|
||||||
os_file_close(fsp->file);
|
os_file_close(fsp->file);
|
||||||
|
@ -5213,9 +5216,9 @@ file_extended:
|
||||||
#ifdef UNIV_HOTBACKUP
|
#ifdef UNIV_HOTBACKUP
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
Extends all tablespaces to the size stored in the space header. During the
|
Extends all tablespaces to the size stored in the space header. During the
|
||||||
ibbackup --apply-log phase we extended the spaces on-demand so that log records
|
mysqlbackup --apply-log phase we extended the spaces on-demand so that log
|
||||||
could be applied, but that may have left spaces still too small compared to
|
records could be applied, but that may have left spaces still too small
|
||||||
the size stored in the space header. */
|
compared to the size stored in the space header. */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
void
|
void
|
||||||
fil_extend_tablespaces_to_stored_len(void)
|
fil_extend_tablespaces_to_stored_len(void)
|
||||||
|
@ -5712,7 +5715,7 @@ fil_io(
|
||||||
ut_a((len % OS_FILE_LOG_BLOCK_SIZE) == 0);
|
ut_a((len % OS_FILE_LOG_BLOCK_SIZE) == 0);
|
||||||
|
|
||||||
#ifdef UNIV_HOTBACKUP
|
#ifdef UNIV_HOTBACKUP
|
||||||
/* In ibbackup do normal i/o, not aio */
|
/* In mysqlbackup do normal i/o, not aio */
|
||||||
if (type == OS_FILE_READ) {
|
if (type == OS_FILE_READ) {
|
||||||
ret = os_file_read(node->handle, buf, offset, len);
|
ret = os_file_read(node->handle, buf, offset, len);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 2007, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 2007, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
@ -83,11 +83,11 @@ UNIV_INTERN
|
||||||
fts_ast_node_t*
|
fts_ast_node_t*
|
||||||
fts_ast_create_node_term(
|
fts_ast_create_node_term(
|
||||||
/*=====================*/
|
/*=====================*/
|
||||||
void* arg, /*!< in: ast state instance */
|
void* arg, /*!< in: ast state instance */
|
||||||
const char* ptr) /*!< in: ast term string */
|
const fts_ast_string_t* ptr) /*!< in: ast term string */
|
||||||
{
|
{
|
||||||
fts_ast_state_t* state = static_cast<fts_ast_state_t*>(arg);
|
fts_ast_state_t* state = static_cast<fts_ast_state_t*>(arg);
|
||||||
ulint len = strlen(ptr);
|
ulint len = ptr->len;
|
||||||
ulint cur_pos = 0;
|
ulint cur_pos = 0;
|
||||||
fts_ast_node_t* node = NULL;
|
fts_ast_node_t* node = NULL;
|
||||||
fts_ast_node_t* node_list = NULL;
|
fts_ast_node_t* node_list = NULL;
|
||||||
|
@ -101,8 +101,9 @@ fts_ast_create_node_term(
|
||||||
|
|
||||||
cur_len = innobase_mysql_fts_get_token(
|
cur_len = innobase_mysql_fts_get_token(
|
||||||
state->charset,
|
state->charset,
|
||||||
reinterpret_cast<const byte*>(ptr) + cur_pos,
|
reinterpret_cast<const byte*>(ptr->str) + cur_pos,
|
||||||
reinterpret_cast<const byte*>(ptr) + len, &str, &offset);
|
reinterpret_cast<const byte*>(ptr->str) + len,
|
||||||
|
&str, &offset);
|
||||||
|
|
||||||
if (cur_len == 0) {
|
if (cur_len == 0) {
|
||||||
break;
|
break;
|
||||||
|
@ -124,10 +125,8 @@ fts_ast_create_node_term(
|
||||||
|
|
||||||
node->type = FTS_AST_TERM;
|
node->type = FTS_AST_TERM;
|
||||||
|
|
||||||
node->term.ptr = static_cast<byte*>(ut_malloc(
|
node->term.ptr = fts_ast_string_create(
|
||||||
str.f_len + 1));
|
str.f_str, str.f_len);
|
||||||
memcpy(node->term.ptr, str.f_str, str.f_len);
|
|
||||||
node->term.ptr[str.f_len] = '\0';
|
|
||||||
|
|
||||||
fts_ast_state_add_node(
|
fts_ast_state_add_node(
|
||||||
static_cast<fts_ast_state_t*>(arg), node);
|
static_cast<fts_ast_state_t*>(arg), node);
|
||||||
|
@ -160,25 +159,21 @@ UNIV_INTERN
|
||||||
fts_ast_node_t*
|
fts_ast_node_t*
|
||||||
fts_ast_create_node_text(
|
fts_ast_create_node_text(
|
||||||
/*=====================*/
|
/*=====================*/
|
||||||
void* arg, /*!< in: ast state instance */
|
void* arg, /*!< in: ast state instance */
|
||||||
const char* ptr) /*!< in: ast text string */
|
const fts_ast_string_t* ptr) /*!< in: ast text string */
|
||||||
{
|
{
|
||||||
ulint len = strlen(ptr);
|
ulint len = ptr->len;
|
||||||
fts_ast_node_t* node = NULL;
|
fts_ast_node_t* node = NULL;
|
||||||
|
|
||||||
|
/* Once we come here, the string must have at least 2 quotes ""
|
||||||
|
around the query string, which could be empty. Also the query
|
||||||
|
string may contain 0x00 in it, we don't treat it as null-terminated. */
|
||||||
|
ut_ad(len >= 2);
|
||||||
|
ut_ad(ptr->str[0] == '\"' && ptr->str[len - 1] == '\"');
|
||||||
|
|
||||||
ut_ad(len >= 1);
|
if (len == 2) {
|
||||||
|
/* If the query string contains nothing except quotes,
|
||||||
if (len <= 2) {
|
it's obviously an invalid query. */
|
||||||
/* There is a way to directly supply null terminator
|
|
||||||
in the query string (by using 0x220022) and get here,
|
|
||||||
and certainly it would not make a valid query text */
|
|
||||||
ut_ad(ptr[0] == '\"');
|
|
||||||
|
|
||||||
if (len == 2) {
|
|
||||||
ut_ad(ptr[1] == '\"');
|
|
||||||
}
|
|
||||||
|
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,11 +183,9 @@ fts_ast_create_node_text(
|
||||||
len -= 2;
|
len -= 2;
|
||||||
|
|
||||||
node->type = FTS_AST_TEXT;
|
node->type = FTS_AST_TEXT;
|
||||||
node->text.ptr = static_cast<byte*>(ut_malloc(len + 1));
|
|
||||||
|
|
||||||
/*!< Skip copying the first quote */
|
/*!< Skip copying the first quote */
|
||||||
memcpy(node->text.ptr, ptr + 1, len);
|
node->text.ptr = fts_ast_string_create(
|
||||||
node->text.ptr[len] = 0;
|
reinterpret_cast<const byte*>(ptr->str + 1), len);
|
||||||
node->text.distance = ULINT_UNDEFINED;
|
node->text.distance = ULINT_UNDEFINED;
|
||||||
|
|
||||||
fts_ast_state_add_node((fts_ast_state_t*) arg, node);
|
fts_ast_state_add_node((fts_ast_state_t*) arg, node);
|
||||||
|
@ -275,14 +268,14 @@ fts_ast_free_node(
|
||||||
switch (node->type) {
|
switch (node->type) {
|
||||||
case FTS_AST_TEXT:
|
case FTS_AST_TEXT:
|
||||||
if (node->text.ptr) {
|
if (node->text.ptr) {
|
||||||
ut_free(node->text.ptr);
|
fts_ast_string_free(node->text.ptr);
|
||||||
node->text.ptr = NULL;
|
node->text.ptr = NULL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FTS_AST_TERM:
|
case FTS_AST_TERM:
|
||||||
if (node->term.ptr) {
|
if (node->term.ptr) {
|
||||||
ut_free(node->term.ptr);
|
fts_ast_string_free(node->term.ptr);
|
||||||
node->term.ptr = NULL;
|
node->term.ptr = NULL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -421,10 +414,10 @@ fts_ast_state_free(
|
||||||
fts_ast_node_t* next = node->next_alloc;
|
fts_ast_node_t* next = node->next_alloc;
|
||||||
|
|
||||||
if (node->type == FTS_AST_TEXT && node->text.ptr) {
|
if (node->type == FTS_AST_TEXT && node->text.ptr) {
|
||||||
ut_free(node->text.ptr);
|
fts_ast_string_free(node->text.ptr);
|
||||||
node->text.ptr = NULL;
|
node->text.ptr = NULL;
|
||||||
} else if (node->type == FTS_AST_TERM && node->term.ptr) {
|
} else if (node->type == FTS_AST_TERM && node->term.ptr) {
|
||||||
ut_free(node->term.ptr);
|
fts_ast_string_free(node->term.ptr);
|
||||||
node->term.ptr = NULL;
|
node->term.ptr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,11 +438,13 @@ fts_ast_node_print(
|
||||||
{
|
{
|
||||||
switch (node->type) {
|
switch (node->type) {
|
||||||
case FTS_AST_TEXT:
|
case FTS_AST_TEXT:
|
||||||
printf("TEXT: %s\n", node->text.ptr);
|
printf("TEXT: ");
|
||||||
|
fts_ast_string_print(node->text.ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FTS_AST_TERM:
|
case FTS_AST_TERM:
|
||||||
printf("TERM: %s\n", node->term.ptr);
|
printf("TERM: ");
|
||||||
|
fts_ast_string_print(node->term.ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FTS_AST_LIST:
|
case FTS_AST_LIST:
|
||||||
|
@ -628,3 +623,74 @@ fts_ast_visit(
|
||||||
|
|
||||||
return(error);
|
return(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Create an ast string object, with NUL-terminator, so the string
|
||||||
|
has one more byte than len
|
||||||
|
@param[in] str pointer to string
|
||||||
|
@param[in] len length of the string
|
||||||
|
@return ast string with NUL-terminator */
|
||||||
|
UNIV_INTERN
|
||||||
|
fts_ast_string_t*
|
||||||
|
fts_ast_string_create(
|
||||||
|
const byte* str,
|
||||||
|
ulint len)
|
||||||
|
{
|
||||||
|
fts_ast_string_t* ast_str;
|
||||||
|
|
||||||
|
ut_ad(len > 0);
|
||||||
|
|
||||||
|
ast_str = static_cast<fts_ast_string_t*>
|
||||||
|
(ut_malloc(sizeof(fts_ast_string_t)));
|
||||||
|
ast_str->str = static_cast<byte*>(ut_malloc(len + 1));
|
||||||
|
|
||||||
|
ast_str->len = len;
|
||||||
|
memcpy(ast_str->str, str, len);
|
||||||
|
ast_str->str[len] = '\0';
|
||||||
|
|
||||||
|
return(ast_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Free an ast string instance
|
||||||
|
@param[in,out] ast_str string to free */
|
||||||
|
UNIV_INTERN
|
||||||
|
void
|
||||||
|
fts_ast_string_free(
|
||||||
|
fts_ast_string_t* ast_str)
|
||||||
|
{
|
||||||
|
if (ast_str != NULL) {
|
||||||
|
ut_free(ast_str->str);
|
||||||
|
ut_free(ast_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Translate ast string of type FTS_AST_NUMB to unsigned long by strtoul
|
||||||
|
@param[in] str string to translate
|
||||||
|
@param[in] base the base
|
||||||
|
@return translated number */
|
||||||
|
UNIV_INTERN
|
||||||
|
ulint
|
||||||
|
fts_ast_string_to_ul(
|
||||||
|
const fts_ast_string_t* ast_str,
|
||||||
|
int base)
|
||||||
|
{
|
||||||
|
return(strtoul(reinterpret_cast<const char*>(ast_str->str),
|
||||||
|
NULL, base));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Print the ast string
|
||||||
|
@param[in] str string to print */
|
||||||
|
UNIV_INTERN
|
||||||
|
void
|
||||||
|
fts_ast_string_print(
|
||||||
|
const fts_ast_string_t* ast_str)
|
||||||
|
{
|
||||||
|
for (ulint i = 0; i < ast_str->len; ++i) {
|
||||||
|
printf("%c", ast_str->str[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
|
@ -451,7 +451,7 @@ static yyconst flex_int16_t yy_chk[32] =
|
||||||
#line 1 "fts0blex.l"
|
#line 1 "fts0blex.l"
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 2007, 2011, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 2007, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
@ -806,7 +806,7 @@ case 3:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 53 "fts0blex.l"
|
#line 53 "fts0blex.l"
|
||||||
{
|
{
|
||||||
val->token = strdup(fts0bget_text(yyscanner));
|
val->token = fts_ast_string_create(reinterpret_cast<const byte*>(fts0bget_text(yyscanner)), fts0bget_leng(yyscanner));
|
||||||
|
|
||||||
return(FTS_NUMB);
|
return(FTS_NUMB);
|
||||||
}
|
}
|
||||||
|
@ -815,7 +815,7 @@ case 4:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 59 "fts0blex.l"
|
#line 59 "fts0blex.l"
|
||||||
{
|
{
|
||||||
val->token = strdup(fts0bget_text(yyscanner));
|
val->token = fts_ast_string_create(reinterpret_cast<const byte*>(fts0bget_text(yyscanner)), fts0bget_leng(yyscanner));
|
||||||
|
|
||||||
return(FTS_TERM);
|
return(FTS_TERM);
|
||||||
}
|
}
|
||||||
|
@ -824,7 +824,7 @@ case 5:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 65 "fts0blex.l"
|
#line 65 "fts0blex.l"
|
||||||
{
|
{
|
||||||
val->token = strdup(fts0bget_text(yyscanner));
|
val->token = fts_ast_string_create(reinterpret_cast<const byte*>(fts0bget_text(yyscanner)), fts0bget_leng(yyscanner));
|
||||||
|
|
||||||
return(FTS_TEXT);
|
return(FTS_TEXT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 2007, 2011, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 2007, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
@ -51,19 +51,19 @@ this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
}
|
}
|
||||||
|
|
||||||
[0-9]+ {
|
[0-9]+ {
|
||||||
val->token = strdup(fts0bget_text(yyscanner));
|
val->token = fts_ast_string_create(reinterpret_cast<const byte*>(fts0bget_text(yyscanner)), fts0bget_leng(yyscanner));
|
||||||
|
|
||||||
return(FTS_NUMB);
|
return(FTS_NUMB);
|
||||||
}
|
}
|
||||||
|
|
||||||
[^" \n*()+\-<>~@%]* {
|
[^" \n*()+\-<>~@%]* {
|
||||||
val->token = strdup(fts0bget_text(yyscanner));
|
val->token = fts_ast_string_create(reinterpret_cast<const byte*>(fts0bget_text(yyscanner)), fts0bget_leng(yyscanner));
|
||||||
|
|
||||||
return(FTS_TERM);
|
return(FTS_TERM);
|
||||||
}
|
}
|
||||||
|
|
||||||
\"[^\"\n]*\" {
|
\"[^\"\n]*\" {
|
||||||
val->token = strdup(fts0bget_text(yyscanner));
|
val->token = fts_ast_string_create(reinterpret_cast<const byte*>(fts0bget_text(yyscanner)), fts0bget_leng(yyscanner));
|
||||||
|
|
||||||
return(FTS_TEXT);
|
return(FTS_TEXT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -608,8 +608,10 @@ fts_cache_init(
|
||||||
|
|
||||||
cache->total_size = 0;
|
cache->total_size = 0;
|
||||||
|
|
||||||
|
mutex_enter((ib_mutex_t*) &cache->deleted_lock);
|
||||||
cache->deleted_doc_ids = ib_vector_create(
|
cache->deleted_doc_ids = ib_vector_create(
|
||||||
cache->sync_heap, sizeof(fts_update_t), 4);
|
cache->sync_heap, sizeof(fts_update_t), 4);
|
||||||
|
mutex_exit((ib_mutex_t*) &cache->deleted_lock);
|
||||||
|
|
||||||
/* Reset the cache data for all the FTS indexes. */
|
/* Reset the cache data for all the FTS indexes. */
|
||||||
for (i = 0; i < ib_vector_size(cache->indexes); ++i) {
|
for (i = 0; i < ib_vector_size(cache->indexes); ++i) {
|
||||||
|
@ -1137,7 +1139,10 @@ fts_cache_clear(
|
||||||
cache->sync_heap->arg = NULL;
|
cache->sync_heap->arg = NULL;
|
||||||
|
|
||||||
cache->total_size = 0;
|
cache->total_size = 0;
|
||||||
|
|
||||||
|
mutex_enter((ib_mutex_t*) &cache->deleted_lock);
|
||||||
cache->deleted_doc_ids = NULL;
|
cache->deleted_doc_ids = NULL;
|
||||||
|
mutex_exit((ib_mutex_t*) &cache->deleted_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
|
@ -1954,10 +1959,15 @@ fts_create_one_index_table(
|
||||||
char* table_name = fts_get_table_name(fts_table);
|
char* table_name = fts_get_table_name(fts_table);
|
||||||
dberr_t error;
|
dberr_t error;
|
||||||
CHARSET_INFO* charset;
|
CHARSET_INFO* charset;
|
||||||
|
ulint flags2 = 0;
|
||||||
|
|
||||||
ut_ad(index->type & DICT_FTS);
|
ut_ad(index->type & DICT_FTS);
|
||||||
|
|
||||||
new_table = dict_mem_table_create(table_name, 0, 5, 1, 0);
|
if (srv_file_per_table) {
|
||||||
|
flags2 = DICT_TF2_USE_TABLESPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_table = dict_mem_table_create(table_name, 0, 5, 1, flags2);
|
||||||
|
|
||||||
field = dict_index_get_nth_field(index, 0);
|
field = dict_index_get_nth_field(index, 0);
|
||||||
charset = innobase_get_fts_charset(
|
charset = innobase_get_fts_charset(
|
||||||
|
@ -1986,7 +1996,7 @@ fts_create_one_index_table(
|
||||||
dict_mem_table_add_col(new_table, heap, "ilist", DATA_BLOB,
|
dict_mem_table_add_col(new_table, heap, "ilist", DATA_BLOB,
|
||||||
4130048, 0);
|
4130048, 0);
|
||||||
|
|
||||||
error = row_create_table_for_mysql(new_table, trx, true);
|
error = row_create_table_for_mysql(new_table, trx, false);
|
||||||
|
|
||||||
if (error != DB_SUCCESS) {
|
if (error != DB_SUCCESS) {
|
||||||
trx->error_state = error;
|
trx->error_state = error;
|
||||||
|
@ -2251,11 +2261,15 @@ static
|
||||||
fts_trx_t*
|
fts_trx_t*
|
||||||
fts_trx_create(
|
fts_trx_create(
|
||||||
/*===========*/
|
/*===========*/
|
||||||
trx_t* trx) /*!< in: InnoDB transaction */
|
trx_t* trx) /*!< in/out: InnoDB
|
||||||
|
transaction */
|
||||||
{
|
{
|
||||||
fts_trx_t* ftt;
|
fts_trx_t* ftt;
|
||||||
ib_alloc_t* heap_alloc;
|
ib_alloc_t* heap_alloc;
|
||||||
mem_heap_t* heap = mem_heap_create(1024);
|
mem_heap_t* heap = mem_heap_create(1024);
|
||||||
|
trx_named_savept_t* savep;
|
||||||
|
|
||||||
|
ut_a(trx->fts_trx == NULL);
|
||||||
|
|
||||||
ftt = static_cast<fts_trx_t*>(mem_heap_alloc(heap, sizeof(fts_trx_t)));
|
ftt = static_cast<fts_trx_t*>(mem_heap_alloc(heap, sizeof(fts_trx_t)));
|
||||||
ftt->trx = trx;
|
ftt->trx = trx;
|
||||||
|
@ -2273,6 +2287,14 @@ fts_trx_create(
|
||||||
fts_savepoint_create(ftt->savepoints, NULL, NULL);
|
fts_savepoint_create(ftt->savepoints, NULL, NULL);
|
||||||
fts_savepoint_create(ftt->last_stmt, NULL, NULL);
|
fts_savepoint_create(ftt->last_stmt, NULL, NULL);
|
||||||
|
|
||||||
|
/* Copy savepoints that already set before. */
|
||||||
|
for (savep = UT_LIST_GET_FIRST(trx->trx_savepoints);
|
||||||
|
savep != NULL;
|
||||||
|
savep = UT_LIST_GET_NEXT(trx_savepoints, savep)) {
|
||||||
|
|
||||||
|
fts_savepoint_take(trx, ftt, savep->name);
|
||||||
|
}
|
||||||
|
|
||||||
return(ftt);
|
return(ftt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4366,6 +4388,7 @@ fts_sync_commit(
|
||||||
/* We need to do this within the deleted lock since fts_delete() can
|
/* We need to do this within the deleted lock since fts_delete() can
|
||||||
attempt to add a deleted doc id to the cache deleted id array. */
|
attempt to add a deleted doc id to the cache deleted id array. */
|
||||||
fts_cache_clear(cache);
|
fts_cache_clear(cache);
|
||||||
|
DEBUG_SYNC_C("fts_deleted_doc_ids_clear");
|
||||||
fts_cache_init(cache);
|
fts_cache_init(cache);
|
||||||
rw_lock_x_unlock(&cache->lock);
|
rw_lock_x_unlock(&cache->lock);
|
||||||
|
|
||||||
|
@ -5167,6 +5190,12 @@ fts_cache_append_deleted_doc_ids(
|
||||||
|
|
||||||
mutex_enter((ib_mutex_t*) &cache->deleted_lock);
|
mutex_enter((ib_mutex_t*) &cache->deleted_lock);
|
||||||
|
|
||||||
|
if (cache->deleted_doc_ids == NULL) {
|
||||||
|
mutex_exit((ib_mutex_t*) &cache->deleted_lock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
for (i = 0; i < ib_vector_size(cache->deleted_doc_ids); ++i) {
|
for (i = 0; i < ib_vector_size(cache->deleted_doc_ids); ++i) {
|
||||||
fts_update_t* update;
|
fts_update_t* update;
|
||||||
|
|
||||||
|
@ -5452,16 +5481,15 @@ void
|
||||||
fts_savepoint_take(
|
fts_savepoint_take(
|
||||||
/*===============*/
|
/*===============*/
|
||||||
trx_t* trx, /*!< in: transaction */
|
trx_t* trx, /*!< in: transaction */
|
||||||
|
fts_trx_t* fts_trx, /*!< in: fts transaction */
|
||||||
const char* name) /*!< in: savepoint name */
|
const char* name) /*!< in: savepoint name */
|
||||||
{
|
{
|
||||||
mem_heap_t* heap;
|
mem_heap_t* heap;
|
||||||
fts_trx_t* fts_trx;
|
|
||||||
fts_savepoint_t* savepoint;
|
fts_savepoint_t* savepoint;
|
||||||
fts_savepoint_t* last_savepoint;
|
fts_savepoint_t* last_savepoint;
|
||||||
|
|
||||||
ut_a(name != NULL);
|
ut_a(name != NULL);
|
||||||
|
|
||||||
fts_trx = trx->fts_trx;
|
|
||||||
heap = fts_trx->heap;
|
heap = fts_trx->heap;
|
||||||
|
|
||||||
/* The implied savepoint must exist. */
|
/* The implied savepoint must exist. */
|
||||||
|
@ -5778,7 +5806,7 @@ fts_savepoint_rollback(
|
||||||
ut_a(ib_vector_size(savepoints) > 0);
|
ut_a(ib_vector_size(savepoints) > 0);
|
||||||
|
|
||||||
/* Restore the savepoint. */
|
/* Restore the savepoint. */
|
||||||
fts_savepoint_take(trx, name);
|
fts_savepoint_take(trx, trx->fts_trx, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,8 @@ extern int ftserror(const char* p);
|
||||||
#define YYPARSE_PARAM state
|
#define YYPARSE_PARAM state
|
||||||
#define YYLEX_PARAM ((fts_ast_state_t*) state)->lexer
|
#define YYLEX_PARAM ((fts_ast_state_t*) state)->lexer
|
||||||
|
|
||||||
|
#define YYTOKENFREE(token) fts_ast_string_free((token))
|
||||||
|
|
||||||
typedef int (*fts_scanner_alt)(YYSTYPE* val, yyscan_t yyscanner);
|
typedef int (*fts_scanner_alt)(YYSTYPE* val, yyscan_t yyscanner);
|
||||||
typedef int (*fts_scanner)();
|
typedef int (*fts_scanner)();
|
||||||
|
|
||||||
|
@ -154,9 +156,9 @@ typedef union YYSTYPE
|
||||||
/* Line 293 of yacc.c */
|
/* Line 293 of yacc.c */
|
||||||
#line 61 "fts0pars.y"
|
#line 61 "fts0pars.y"
|
||||||
|
|
||||||
int oper;
|
int oper;
|
||||||
char* token;
|
fts_ast_string_t* token;
|
||||||
fts_ast_node_t* node;
|
fts_ast_node_t* node;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -632,6 +634,19 @@ while (YYID (0))
|
||||||
#define YYTERROR 1
|
#define YYTERROR 1
|
||||||
#define YYERRCODE 256
|
#define YYERRCODE 256
|
||||||
|
|
||||||
|
#define YYERRCLEANUP \
|
||||||
|
do \
|
||||||
|
switch (yylastchar) \
|
||||||
|
{ \
|
||||||
|
case FTS_NUMB: \
|
||||||
|
case FTS_TEXT: \
|
||||||
|
case FTS_TERM: \
|
||||||
|
YYTOKENFREE(yylval.token); \
|
||||||
|
break; \
|
||||||
|
default: \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
while (YYID (0))
|
||||||
|
|
||||||
/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
|
/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
|
||||||
If N is 0, then set CURRENT to the empty location which ends
|
If N is 0, then set CURRENT to the empty location which ends
|
||||||
|
@ -1169,6 +1184,8 @@ yyparse ()
|
||||||
{
|
{
|
||||||
/* The lookahead symbol. */
|
/* The lookahead symbol. */
|
||||||
int yychar;
|
int yychar;
|
||||||
|
/* The backup of yychar when there is an error and we're in yyerrlab. */
|
||||||
|
int yylastchar;
|
||||||
|
|
||||||
/* The semantic value of the lookahead symbol. */
|
/* The semantic value of the lookahead symbol. */
|
||||||
YYSTYPE yylval;
|
YYSTYPE yylval;
|
||||||
|
@ -1524,8 +1541,8 @@ yyreduce:
|
||||||
/* Line 1806 of yacc.c */
|
/* Line 1806 of yacc.c */
|
||||||
#line 141 "fts0pars.y"
|
#line 141 "fts0pars.y"
|
||||||
{
|
{
|
||||||
fts_ast_term_set_distance((yyvsp[(1) - (3)].node), strtoul((yyvsp[(3) - (3)].token), NULL, 10));
|
fts_ast_term_set_distance((yyvsp[(1) - (3)].node), fts_ast_string_to_ul((yyvsp[(3) - (3)].token), 10));
|
||||||
free((yyvsp[(3) - (3)].token));
|
fts_ast_string_free((yyvsp[(3) - (3)].token));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1557,8 +1574,8 @@ yyreduce:
|
||||||
{
|
{
|
||||||
(yyval.node) = fts_ast_create_node_list(state, (yyvsp[(1) - (4)].node));
|
(yyval.node) = fts_ast_create_node_list(state, (yyvsp[(1) - (4)].node));
|
||||||
fts_ast_add_node((yyval.node), (yyvsp[(2) - (4)].node));
|
fts_ast_add_node((yyval.node), (yyvsp[(2) - (4)].node));
|
||||||
fts_ast_term_set_distance((yyvsp[(2) - (4)].node), strtoul((yyvsp[(4) - (4)].token), NULL, 10));
|
fts_ast_term_set_distance((yyvsp[(2) - (4)].node), fts_ast_string_to_ul((yyvsp[(4) - (4)].token), 10));
|
||||||
free((yyvsp[(4) - (4)].token));
|
fts_ast_string_free((yyvsp[(4) - (4)].token));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1623,7 +1640,7 @@ yyreduce:
|
||||||
#line 191 "fts0pars.y"
|
#line 191 "fts0pars.y"
|
||||||
{
|
{
|
||||||
(yyval.node) = fts_ast_create_node_term(state, (yyvsp[(1) - (1)].token));
|
(yyval.node) = fts_ast_create_node_term(state, (yyvsp[(1) - (1)].token));
|
||||||
free((yyvsp[(1) - (1)].token));
|
fts_ast_string_free((yyvsp[(1) - (1)].token));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1633,7 +1650,7 @@ yyreduce:
|
||||||
#line 196 "fts0pars.y"
|
#line 196 "fts0pars.y"
|
||||||
{
|
{
|
||||||
(yyval.node) = fts_ast_create_node_term(state, (yyvsp[(1) - (1)].token));
|
(yyval.node) = fts_ast_create_node_term(state, (yyvsp[(1) - (1)].token));
|
||||||
free((yyvsp[(1) - (1)].token));
|
fts_ast_string_free((yyvsp[(1) - (1)].token));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1652,7 +1669,7 @@ yyreduce:
|
||||||
#line 207 "fts0pars.y"
|
#line 207 "fts0pars.y"
|
||||||
{
|
{
|
||||||
(yyval.node) = fts_ast_create_node_text(state, (yyvsp[(1) - (1)].token));
|
(yyval.node) = fts_ast_create_node_text(state, (yyvsp[(1) - (1)].token));
|
||||||
free((yyvsp[(1) - (1)].token));
|
fts_ast_string_free((yyvsp[(1) - (1)].token));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1700,6 +1717,8 @@ yyreduce:
|
||||||
| yyerrlab -- here on detecting error |
|
| yyerrlab -- here on detecting error |
|
||||||
`------------------------------------*/
|
`------------------------------------*/
|
||||||
yyerrlab:
|
yyerrlab:
|
||||||
|
/* Backup yychar, in case we would change it. */
|
||||||
|
yylastchar = yychar;
|
||||||
/* Make sure we have latest lookahead translation. See comments at
|
/* Make sure we have latest lookahead translation. See comments at
|
||||||
user semantic actions for why this is necessary. */
|
user semantic actions for why this is necessary. */
|
||||||
yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
|
yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
|
||||||
|
@ -1755,7 +1774,11 @@ yyerrlab:
|
||||||
{
|
{
|
||||||
/* Return failure if at end of input. */
|
/* Return failure if at end of input. */
|
||||||
if (yychar == YYEOF)
|
if (yychar == YYEOF)
|
||||||
YYABORT;
|
{
|
||||||
|
/* Since we don't need the token, we have to free it first. */
|
||||||
|
YYERRCLEANUP;
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1812,7 +1835,11 @@ yyerrlab1:
|
||||||
|
|
||||||
/* Pop the current state because it cannot handle the error token. */
|
/* Pop the current state because it cannot handle the error token. */
|
||||||
if (yyssp == yyss)
|
if (yyssp == yyss)
|
||||||
YYABORT;
|
{
|
||||||
|
/* Since we don't need the error token, we have to free it first. */
|
||||||
|
YYERRCLEANUP;
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
yydestruct ("Error: popping",
|
yydestruct ("Error: popping",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 2007, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 2007, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
@ -59,9 +59,9 @@ struct fts_lexer_struct {
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%union {
|
%union {
|
||||||
int oper;
|
int oper;
|
||||||
char* token;
|
fts_ast_string_t* token;
|
||||||
fts_ast_node_t* node;
|
fts_ast_node_t* node;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Enable re-entrant parser */
|
/* Enable re-entrant parser */
|
||||||
|
@ -139,8 +139,8 @@ expr : term {
|
||||||
}
|
}
|
||||||
|
|
||||||
| text '@' FTS_NUMB {
|
| text '@' FTS_NUMB {
|
||||||
fts_ast_term_set_distance($1, strtoul($3, NULL, 10));
|
fts_ast_term_set_distance($1, fts_ast_string_to_ul($3, 10));
|
||||||
free($3);
|
fts_ast_string_free($3);
|
||||||
}
|
}
|
||||||
|
|
||||||
| prefix term '*' {
|
| prefix term '*' {
|
||||||
|
@ -157,8 +157,8 @@ expr : term {
|
||||||
| prefix text '@' FTS_NUMB {
|
| prefix text '@' FTS_NUMB {
|
||||||
$$ = fts_ast_create_node_list(state, $1);
|
$$ = fts_ast_create_node_list(state, $1);
|
||||||
fts_ast_add_node($$, $2);
|
fts_ast_add_node($$, $2);
|
||||||
fts_ast_term_set_distance($2, strtoul($4, NULL, 10));
|
fts_ast_term_set_distance($2, fts_ast_string_to_ul($4, 10));
|
||||||
free($4);
|
fts_ast_string_free($4);
|
||||||
}
|
}
|
||||||
|
|
||||||
| prefix text {
|
| prefix text {
|
||||||
|
@ -190,12 +190,12 @@ prefix : '-' {
|
||||||
|
|
||||||
term : FTS_TERM {
|
term : FTS_TERM {
|
||||||
$$ = fts_ast_create_node_term(state, $1);
|
$$ = fts_ast_create_node_term(state, $1);
|
||||||
free($1);
|
fts_ast_string_free($1);
|
||||||
}
|
}
|
||||||
|
|
||||||
| FTS_NUMB {
|
| FTS_NUMB {
|
||||||
$$ = fts_ast_create_node_term(state, $1);
|
$$ = fts_ast_create_node_term(state, $1);
|
||||||
free($1);
|
fts_ast_string_free($1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ignore leading '*' */
|
/* Ignore leading '*' */
|
||||||
|
@ -206,7 +206,7 @@ term : FTS_TERM {
|
||||||
|
|
||||||
text : FTS_TEXT {
|
text : FTS_TEXT {
|
||||||
$$ = fts_ast_create_node_text(state, $1);
|
$$ = fts_ast_create_node_text(state, $1);
|
||||||
free($1);
|
fts_ast_string_free($1);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
%%
|
%%
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 2007, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 2007, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
@ -2800,20 +2800,19 @@ fts_query_get_token(
|
||||||
ulint str_len;
|
ulint str_len;
|
||||||
byte* new_ptr = NULL;
|
byte* new_ptr = NULL;
|
||||||
|
|
||||||
str_len = ut_strlen((char*) node->term.ptr);
|
str_len = node->term.ptr->len;
|
||||||
|
|
||||||
ut_a(node->type == FTS_AST_TERM);
|
ut_a(node->type == FTS_AST_TERM);
|
||||||
|
|
||||||
token->f_len = str_len;
|
token->f_len = str_len;
|
||||||
token->f_str = node->term.ptr;
|
token->f_str = node->term.ptr->str;
|
||||||
|
|
||||||
if (node->term.wildcard) {
|
if (node->term.wildcard) {
|
||||||
|
|
||||||
token->f_str = static_cast<byte*>(ut_malloc(str_len + 2));
|
token->f_str = static_cast<byte*>(ut_malloc(str_len + 2));
|
||||||
token->f_len = str_len + 1;
|
token->f_len = str_len + 1;
|
||||||
|
|
||||||
/* Need to copy the NUL character too. */
|
memcpy(token->f_str, node->term.ptr->str, str_len);
|
||||||
memcpy(token->f_str, node->term.ptr, str_len + 1);
|
|
||||||
|
|
||||||
token->f_str[str_len] = '%';
|
token->f_str[str_len] = '%';
|
||||||
token->f_str[token->f_len] = 0;
|
token->f_str[token->f_len] = 0;
|
||||||
|
@ -2848,8 +2847,8 @@ fts_query_visitor(
|
||||||
|
|
||||||
switch (node->type) {
|
switch (node->type) {
|
||||||
case FTS_AST_TEXT:
|
case FTS_AST_TEXT:
|
||||||
token.f_str = node->text.ptr;
|
token.f_str = node->text.ptr->str;
|
||||||
token.f_len = ut_strlen((char*) token.f_str);
|
token.f_len = node->text.ptr->len;
|
||||||
|
|
||||||
if (query->oper == FTS_EXIST) {
|
if (query->oper == FTS_EXIST) {
|
||||||
ut_ad(query->intersection == NULL);
|
ut_ad(query->intersection == NULL);
|
||||||
|
@ -2878,8 +2877,8 @@ fts_query_visitor(
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FTS_AST_TERM:
|
case FTS_AST_TERM:
|
||||||
token.f_str = node->term.ptr;
|
token.f_str = node->term.ptr->str;
|
||||||
token.f_len = ut_strlen(reinterpret_cast<char*>(token.f_str));
|
token.f_len = node->term.ptr->len;
|
||||||
|
|
||||||
/* Add the word to our RB tree that will be used to
|
/* Add the word to our RB tree that will be used to
|
||||||
calculate this terms per document frequency. */
|
calculate this terms per document frequency. */
|
||||||
|
@ -3191,13 +3190,9 @@ fts_query_read_node(
|
||||||
to assign the frequency on search string behalf. */
|
to assign the frequency on search string behalf. */
|
||||||
if (query->cur_node->type == FTS_AST_TERM
|
if (query->cur_node->type == FTS_AST_TERM
|
||||||
&& query->cur_node->term.wildcard) {
|
&& query->cur_node->term.wildcard) {
|
||||||
|
term.f_len = query->cur_node->term.ptr->len;
|
||||||
/* These cast are safe since we only care about the
|
|
||||||
terminating NUL character as an end of string marker. */
|
|
||||||
term.f_len = ut_strlen(reinterpret_cast<char*>
|
|
||||||
(query->cur_node->term.ptr));
|
|
||||||
ut_ad(FTS_MAX_WORD_LEN >= term.f_len);
|
ut_ad(FTS_MAX_WORD_LEN >= term.f_len);
|
||||||
memcpy(term.f_str, query->cur_node->term.ptr, term.f_len);
|
memcpy(term.f_str, query->cur_node->term.ptr->str, term.f_len);
|
||||||
} else {
|
} else {
|
||||||
term.f_len = word->f_len;
|
term.f_len = word->f_len;
|
||||||
ut_ad(FTS_MAX_WORD_LEN >= word->f_len);
|
ut_ad(FTS_MAX_WORD_LEN >= word->f_len);
|
||||||
|
@ -3507,14 +3502,15 @@ fts_query_prepare_result(
|
||||||
doc_freq = rbt_value(fts_doc_freq_t, node);
|
doc_freq = rbt_value(fts_doc_freq_t, node);
|
||||||
|
|
||||||
/* Don't put deleted docs into result */
|
/* Don't put deleted docs into result */
|
||||||
if (fts_bsearch(array, 0, static_cast<int>(size), doc_freq->doc_id)
|
if (fts_bsearch(array, 0, static_cast<int>(size),
|
||||||
>= 0) {
|
doc_freq->doc_id) >= 0) {
|
||||||
|
/* one less matching doc count */
|
||||||
|
--word_freq->doc_count;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ranking.doc_id = doc_freq->doc_id;
|
ranking.doc_id = doc_freq->doc_id;
|
||||||
ranking.rank = static_cast<fts_rank_t>(
|
ranking.rank = static_cast<fts_rank_t>(doc_freq->freq);
|
||||||
doc_freq->freq * word_freq->idf * word_freq->idf);
|
|
||||||
ranking.words = NULL;
|
ranking.words = NULL;
|
||||||
|
|
||||||
fts_query_add_ranking(query, result->rankings_by_id,
|
fts_query_add_ranking(query, result->rankings_by_id,
|
||||||
|
@ -3527,6 +3523,25 @@ fts_query_prepare_result(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Calculate IDF only after we exclude the deleted items */
|
||||||
|
fts_query_calculate_idf(query);
|
||||||
|
|
||||||
|
node = rbt_first(query->word_freqs);
|
||||||
|
word_freq = rbt_value(fts_word_freq_t, node);
|
||||||
|
|
||||||
|
/* Calculate the ranking for each doc */
|
||||||
|
for (node = rbt_first(result->rankings_by_id);
|
||||||
|
node != NULL;
|
||||||
|
node = rbt_next(result->rankings_by_id, node)) {
|
||||||
|
|
||||||
|
fts_ranking_t* ranking;
|
||||||
|
|
||||||
|
ranking = rbt_value(fts_ranking_t, node);
|
||||||
|
|
||||||
|
ranking->rank = static_cast<fts_rank_t>(
|
||||||
|
ranking->rank * word_freq->idf * word_freq->idf);
|
||||||
|
}
|
||||||
|
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3900,6 +3915,7 @@ fts_query(
|
||||||
/* Get the deleted doc ids that are in the cache. */
|
/* Get the deleted doc ids that are in the cache. */
|
||||||
fts_cache_append_deleted_doc_ids(
|
fts_cache_append_deleted_doc_ids(
|
||||||
index->table->fts->cache, query.deleted->doc_ids);
|
index->table->fts->cache, query.deleted->doc_ids);
|
||||||
|
DEBUG_SYNC_C("fts_deleted_doc_ids_append");
|
||||||
|
|
||||||
/* Sort the vector so that we can do a binary search over the ids. */
|
/* Sort the vector so that we can do a binary search over the ids. */
|
||||||
ib_vector_sort(query.deleted->doc_ids, fts_update_doc_id_cmp);
|
ib_vector_sort(query.deleted->doc_ids, fts_update_doc_id_cmp);
|
||||||
|
@ -3956,7 +3972,8 @@ fts_query(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate the inverse document frequency of the terms. */
|
/* Calculate the inverse document frequency of the terms. */
|
||||||
if (query.error == DB_SUCCESS) {
|
if (query.error == DB_SUCCESS
|
||||||
|
&& query.flags != FTS_OPT_RANKING) {
|
||||||
fts_query_calculate_idf(&query);
|
fts_query_calculate_idf(&query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -447,7 +447,7 @@ static yyconst flex_int16_t yy_chk[29] =
|
||||||
#line 1 "fts0tlex.l"
|
#line 1 "fts0tlex.l"
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 2007, 2011, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 2007, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
@ -802,7 +802,7 @@ case 3:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 54 "fts0tlex.l"
|
#line 54 "fts0tlex.l"
|
||||||
{
|
{
|
||||||
val->token = strdup(fts0tget_text(yyscanner));
|
val->token = fts_ast_string_create(reinterpret_cast<const byte*>(fts0tget_text(yyscanner)), fts0tget_leng(yyscanner));
|
||||||
|
|
||||||
return(FTS_TEXT);
|
return(FTS_TEXT);
|
||||||
}
|
}
|
||||||
|
@ -811,7 +811,7 @@ case 4:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 60 "fts0tlex.l"
|
#line 60 "fts0tlex.l"
|
||||||
{
|
{
|
||||||
val->token = strdup(fts0tget_text(yyscanner));
|
val->token = fts_ast_string_create(reinterpret_cast<const byte*>(fts0tget_text(yyscanner)), fts0tget_leng(yyscanner));
|
||||||
|
|
||||||
return(FTS_TERM);
|
return(FTS_TERM);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 2007, 2011, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 2007, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
@ -52,13 +52,13 @@ this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
}
|
}
|
||||||
|
|
||||||
\"[^\"\n]*\" {
|
\"[^\"\n]*\" {
|
||||||
val->token = strdup(fts0tget_text(yyscanner));
|
val->token = fts_ast_string_create(reinterpret_cast<const byte*>(fts0tget_text(yyscanner)), fts0tget_leng(yyscanner));
|
||||||
|
|
||||||
return(FTS_TEXT);
|
return(FTS_TEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
[^" \n\%]* {
|
[^" \n\%]* {
|
||||||
val->token = strdup(fts0tget_text(yyscanner));
|
val->token = fts_ast_string_create(reinterpret_cast<const byte*>(fts0tget_text(yyscanner)), fts0tget_leng(yyscanner));
|
||||||
|
|
||||||
return(FTS_TERM);
|
return(FTS_TERM);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3572,7 +3572,7 @@ innobase_commit_ordered_2(
|
||||||
{
|
{
|
||||||
DBUG_ENTER("innobase_commit_ordered_2");
|
DBUG_ENTER("innobase_commit_ordered_2");
|
||||||
|
|
||||||
/* We need current binlog position for ibbackup to work.
|
/* We need current binlog position for mysqlbackup to work.
|
||||||
Note, the position is current because commit_ordered is guaranteed
|
Note, the position is current because commit_ordered is guaranteed
|
||||||
to be called in same sequenece as writing to binlog. */
|
to be called in same sequenece as writing to binlog. */
|
||||||
|
|
||||||
|
@ -4144,7 +4144,7 @@ innobase_savepoint(
|
||||||
error = trx_savepoint_for_mysql(trx, name, (ib_int64_t)0);
|
error = trx_savepoint_for_mysql(trx, name, (ib_int64_t)0);
|
||||||
|
|
||||||
if (error == DB_SUCCESS && trx->fts_trx != NULL) {
|
if (error == DB_SUCCESS && trx->fts_trx != NULL) {
|
||||||
fts_savepoint_take(trx, name);
|
fts_savepoint_take(trx, trx->fts_trx, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_RETURN(convert_error_code_to_mysql(error, 0, NULL));
|
DBUG_RETURN(convert_error_code_to_mysql(error, 0, NULL));
|
||||||
|
@ -12169,9 +12169,13 @@ ha_innobase::get_foreign_key_list(
|
||||||
|
|
||||||
mutex_enter(&(dict_sys->mutex));
|
mutex_enter(&(dict_sys->mutex));
|
||||||
|
|
||||||
for (foreign = UT_LIST_GET_FIRST(prebuilt->table->foreign_list);
|
for (dict_foreign_set::iterator it
|
||||||
foreign != NULL;
|
= prebuilt->table->foreign_set.begin();
|
||||||
foreign = UT_LIST_GET_NEXT(foreign_list, foreign)) {
|
it != prebuilt->table->foreign_set.end();
|
||||||
|
++it) {
|
||||||
|
|
||||||
|
foreign = *it;
|
||||||
|
|
||||||
pf_key_info = get_foreign_key_info(thd, foreign);
|
pf_key_info = get_foreign_key_info(thd, foreign);
|
||||||
if (pf_key_info) {
|
if (pf_key_info) {
|
||||||
f_key_list->push_back(pf_key_info);
|
f_key_list->push_back(pf_key_info);
|
||||||
|
@ -12207,9 +12211,13 @@ ha_innobase::get_parent_foreign_key_list(
|
||||||
|
|
||||||
mutex_enter(&(dict_sys->mutex));
|
mutex_enter(&(dict_sys->mutex));
|
||||||
|
|
||||||
for (foreign = UT_LIST_GET_FIRST(prebuilt->table->referenced_list);
|
for (dict_foreign_set::iterator it
|
||||||
foreign != NULL;
|
= prebuilt->table->referenced_set.begin();
|
||||||
foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) {
|
it != prebuilt->table->referenced_set.end();
|
||||||
|
++it) {
|
||||||
|
|
||||||
|
foreign = *it;
|
||||||
|
|
||||||
pf_key_info = get_foreign_key_info(thd, foreign);
|
pf_key_info = get_foreign_key_info(thd, foreign);
|
||||||
if (pf_key_info) {
|
if (pf_key_info) {
|
||||||
f_key_list->push_back(pf_key_info);
|
f_key_list->push_back(pf_key_info);
|
||||||
|
@ -12242,8 +12250,8 @@ ha_innobase::can_switch_engines(void)
|
||||||
"determining if there are foreign key constraints";
|
"determining if there are foreign key constraints";
|
||||||
row_mysql_freeze_data_dictionary(prebuilt->trx);
|
row_mysql_freeze_data_dictionary(prebuilt->trx);
|
||||||
|
|
||||||
can_switch = !UT_LIST_GET_FIRST(prebuilt->table->referenced_list)
|
can_switch = prebuilt->table->referenced_set.empty()
|
||||||
&& !UT_LIST_GET_FIRST(prebuilt->table->foreign_list);
|
&& prebuilt->table->foreign_set.empty();
|
||||||
|
|
||||||
row_mysql_unfreeze_data_dictionary(prebuilt->trx);
|
row_mysql_unfreeze_data_dictionary(prebuilt->trx);
|
||||||
prebuilt->trx->op_info = "";
|
prebuilt->trx->op_info = "";
|
||||||
|
|
|
@ -590,15 +590,9 @@ innobase_init_foreign(
|
||||||
/* Check if any existing foreign key has the same id,
|
/* Check if any existing foreign key has the same id,
|
||||||
this is needed only if user supplies the constraint name */
|
this is needed only if user supplies the constraint name */
|
||||||
|
|
||||||
for (const dict_foreign_t* existing_foreign
|
if (table->foreign_set.find(foreign)
|
||||||
= UT_LIST_GET_FIRST(table->foreign_list);
|
!= table->foreign_set.end()) {
|
||||||
existing_foreign != 0;
|
return(false);
|
||||||
existing_foreign = UT_LIST_GET_NEXT(
|
|
||||||
foreign_list, existing_foreign)) {
|
|
||||||
|
|
||||||
if (ut_strcmp(existing_foreign->id, foreign->id) == 0) {
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2236,14 +2230,18 @@ innobase_check_foreigns_low(
|
||||||
const char* col_name,
|
const char* col_name,
|
||||||
bool drop)
|
bool drop)
|
||||||
{
|
{
|
||||||
|
dict_foreign_t* foreign;
|
||||||
ut_ad(mutex_own(&dict_sys->mutex));
|
ut_ad(mutex_own(&dict_sys->mutex));
|
||||||
|
|
||||||
/* Check if any FOREIGN KEY constraints are defined on this
|
/* Check if any FOREIGN KEY constraints are defined on this
|
||||||
column. */
|
column. */
|
||||||
for (const dict_foreign_t* foreign = UT_LIST_GET_FIRST(
|
|
||||||
user_table->foreign_list);
|
for (dict_foreign_set::iterator it = user_table->foreign_set.begin();
|
||||||
foreign;
|
it != user_table->foreign_set.end();
|
||||||
foreign = UT_LIST_GET_NEXT(foreign_list, foreign)) {
|
++it) {
|
||||||
|
|
||||||
|
foreign = *it;
|
||||||
|
|
||||||
if (!drop && !(foreign->type
|
if (!drop && !(foreign->type
|
||||||
& (DICT_FOREIGN_ON_DELETE_SET_NULL
|
& (DICT_FOREIGN_ON_DELETE_SET_NULL
|
||||||
| DICT_FOREIGN_ON_UPDATE_SET_NULL))) {
|
| DICT_FOREIGN_ON_UPDATE_SET_NULL))) {
|
||||||
|
@ -2275,10 +2273,13 @@ innobase_check_foreigns_low(
|
||||||
|
|
||||||
/* Check if any FOREIGN KEY constraints in other tables are
|
/* Check if any FOREIGN KEY constraints in other tables are
|
||||||
referring to the column that is being dropped. */
|
referring to the column that is being dropped. */
|
||||||
for (const dict_foreign_t* foreign = UT_LIST_GET_FIRST(
|
for (dict_foreign_set::iterator it
|
||||||
user_table->referenced_list);
|
= user_table->referenced_set.begin();
|
||||||
foreign;
|
it != user_table->referenced_set.end();
|
||||||
foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) {
|
++it) {
|
||||||
|
|
||||||
|
foreign = *it;
|
||||||
|
|
||||||
if (innobase_dropping_foreign(foreign, drop_fk, n_drop_fk)) {
|
if (innobase_dropping_foreign(foreign, drop_fk, n_drop_fk)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -3598,11 +3599,12 @@ check_if_ok_to_rename:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (dict_foreign_t* foreign = UT_LIST_GET_FIRST(
|
for (dict_foreign_set::iterator it
|
||||||
prebuilt->table->foreign_list);
|
= prebuilt->table->foreign_set.begin();
|
||||||
foreign != NULL;
|
it != prebuilt->table->foreign_set.end();
|
||||||
foreign = UT_LIST_GET_NEXT(
|
++it) {
|
||||||
foreign_list, foreign)) {
|
|
||||||
|
dict_foreign_t* foreign = *it;
|
||||||
const char* fid = strchr(foreign->id, '/');
|
const char* fid = strchr(foreign->id, '/');
|
||||||
|
|
||||||
DBUG_ASSERT(fid);
|
DBUG_ASSERT(fid);
|
||||||
|
@ -4443,10 +4445,12 @@ err_exit:
|
||||||
rename_foreign:
|
rename_foreign:
|
||||||
trx->op_info = "renaming column in SYS_FOREIGN_COLS";
|
trx->op_info = "renaming column in SYS_FOREIGN_COLS";
|
||||||
|
|
||||||
for (const dict_foreign_t* foreign = UT_LIST_GET_FIRST(
|
for (dict_foreign_set::iterator it = user_table->foreign_set.begin();
|
||||||
user_table->foreign_list);
|
it != user_table->foreign_set.end();
|
||||||
foreign != NULL;
|
++it) {
|
||||||
foreign = UT_LIST_GET_NEXT(foreign_list, foreign)) {
|
|
||||||
|
dict_foreign_t* foreign = *it;
|
||||||
|
|
||||||
for (unsigned i = 0; i < foreign->n_fields; i++) {
|
for (unsigned i = 0; i < foreign->n_fields; i++) {
|
||||||
if (strcmp(foreign->foreign_col_names[i], from)) {
|
if (strcmp(foreign->foreign_col_names[i], from)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -4476,10 +4480,12 @@ rename_foreign:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const dict_foreign_t* foreign = UT_LIST_GET_FIRST(
|
for (dict_foreign_set::iterator it
|
||||||
user_table->referenced_list);
|
= user_table->referenced_set.begin();
|
||||||
foreign != NULL;
|
it != user_table->referenced_set.end();
|
||||||
foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) {
|
++it) {
|
||||||
|
|
||||||
|
dict_foreign_t* foreign = *it;
|
||||||
for (unsigned i = 0; i < foreign->n_fields; i++) {
|
for (unsigned i = 0; i < foreign->n_fields; i++) {
|
||||||
if (strcmp(foreign->referenced_col_names[i], from)) {
|
if (strcmp(foreign->referenced_col_names[i], from)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -4803,8 +4809,8 @@ innobase_update_foreign_cache(
|
||||||
column names. No need to pass col_names or to drop
|
column names. No need to pass col_names or to drop
|
||||||
constraints from the data dictionary cache. */
|
constraints from the data dictionary cache. */
|
||||||
DBUG_ASSERT(!ctx->col_names);
|
DBUG_ASSERT(!ctx->col_names);
|
||||||
DBUG_ASSERT(UT_LIST_GET_LEN(user_table->foreign_list) == 0);
|
DBUG_ASSERT(user_table->foreign_set.empty());
|
||||||
DBUG_ASSERT(UT_LIST_GET_LEN(user_table->referenced_list) == 0);
|
DBUG_ASSERT(user_table->referenced_set.empty());
|
||||||
user_table = ctx->new_table;
|
user_table = ctx->new_table;
|
||||||
} else {
|
} else {
|
||||||
/* Drop the foreign key constraints if the
|
/* Drop the foreign key constraints if the
|
||||||
|
|
|
@ -447,7 +447,7 @@ buf_page_create(
|
||||||
mtr_t* mtr); /*!< in: mini-transaction handle */
|
mtr_t* mtr); /*!< in: mini-transaction handle */
|
||||||
#else /* !UNIV_HOTBACKUP */
|
#else /* !UNIV_HOTBACKUP */
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
Inits a page to the buffer buf_pool, for use in ibbackup --restore. */
|
Inits a page to the buffer buf_pool, for use in mysqlbackup --restore. */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
void
|
void
|
||||||
buf_page_init_for_backup_restore(
|
buf_page_init_for_backup_restore(
|
||||||
|
|
|
@ -1160,12 +1160,6 @@ buf_page_hash_get_low(
|
||||||
ut_a(buf_page_in_file(bpage));
|
ut_a(buf_page_in_file(bpage));
|
||||||
ut_ad(bpage->in_page_hash);
|
ut_ad(bpage->in_page_hash);
|
||||||
ut_ad(!bpage->in_zip_hash);
|
ut_ad(!bpage->in_zip_hash);
|
||||||
#if UNIV_WORD_SIZE == 4
|
|
||||||
/* On 32-bit systems, there is no padding in
|
|
||||||
buf_page_t. On other systems, Valgrind could complain
|
|
||||||
about uninitialized pad bytes. */
|
|
||||||
UNIV_MEM_ASSERT_RW(bpage, sizeof *bpage);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return(bpage);
|
return(bpage);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
@ -124,28 +124,24 @@ dict_create_add_foreign_id(
|
||||||
const char* name, /*!< in: table name */
|
const char* name, /*!< in: table name */
|
||||||
dict_foreign_t* foreign)/*!< in/out: foreign key */
|
dict_foreign_t* foreign)/*!< in/out: foreign key */
|
||||||
__attribute__((nonnull));
|
__attribute__((nonnull));
|
||||||
/********************************************************************//**
|
|
||||||
Adds foreign key definitions to data dictionary tables in the database. We
|
/** Adds the given set of foreign key objects to the dictionary tables
|
||||||
look at table->foreign_list, and also generate names to constraints that were
|
in the database. This function does not modify the dictionary cache. The
|
||||||
not named by the user. A generated constraint has a name of the format
|
caller must ensure that all foreign key objects contain a valid constraint
|
||||||
databasename/tablename_ibfk_NUMBER, where the numbers start from 1, and are
|
name in foreign->id.
|
||||||
given locally for this table, that is, the number is not global, as in the
|
@param[in] local_fk_set set of foreign key objects, to be added to
|
||||||
old format constraints < 4.0.18 it used to be.
|
the dictionary tables
|
||||||
@return error code or DB_SUCCESS */
|
@param[in] table table to which the foreign key objects in
|
||||||
|
local_fk_set belong to
|
||||||
|
@param[in,out] trx transaction
|
||||||
|
@return error code or DB_SUCCESS */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
dberr_t
|
dberr_t
|
||||||
dict_create_add_foreigns_to_dictionary(
|
dict_create_add_foreigns_to_dictionary(
|
||||||
/*===================================*/
|
/*===================================*/
|
||||||
ulint start_id,/*!< in: if we are actually doing ALTER TABLE
|
const dict_foreign_set& local_fk_set,
|
||||||
ADD CONSTRAINT, we want to generate constraint
|
const dict_table_t* table,
|
||||||
numbers which are bigger than in the table so
|
trx_t* trx)
|
||||||
far; we number the constraints from
|
|
||||||
start_id + 1 up; start_id should be set to 0 if
|
|
||||||
we are creating a new table, or if the table
|
|
||||||
so far has no constraints for which the name
|
|
||||||
was generated here */
|
|
||||||
dict_table_t* table, /*!< in: table */
|
|
||||||
trx_t* trx) /*!< in: transaction */
|
|
||||||
__attribute__((nonnull, warn_unused_result));
|
__attribute__((nonnull, warn_unused_result));
|
||||||
/****************************************************************//**
|
/****************************************************************//**
|
||||||
Creates the tablespaces and datafiles system tables inside InnoDB
|
Creates the tablespaces and datafiles system tables inside InnoDB
|
||||||
|
|
|
@ -47,6 +47,8 @@ Created 1/8/1996 Heikki Tuuri
|
||||||
#include "trx0types.h"
|
#include "trx0types.h"
|
||||||
#include "fts0fts.h"
|
#include "fts0fts.h"
|
||||||
#include "os0once.h"
|
#include "os0once.h"
|
||||||
|
#include <set>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
/* Forward declaration. */
|
/* Forward declaration. */
|
||||||
struct ib_rbt_t;
|
struct ib_rbt_t;
|
||||||
|
@ -706,12 +708,106 @@ struct dict_foreign_t{
|
||||||
does not generate new indexes
|
does not generate new indexes
|
||||||
implicitly */
|
implicitly */
|
||||||
dict_index_t* referenced_index;/*!< referenced index */
|
dict_index_t* referenced_index;/*!< referenced index */
|
||||||
UT_LIST_NODE_T(dict_foreign_t)
|
};
|
||||||
foreign_list; /*!< list node for foreign keys of the
|
|
||||||
table */
|
/** Compare two dict_foreign_t objects using their ids. Used in the ordering
|
||||||
UT_LIST_NODE_T(dict_foreign_t)
|
of dict_table_t::foreign_set and dict_table_t::referenced_set. It returns
|
||||||
referenced_list;/*!< list node for referenced
|
true if the first argument is considered to go before the second in the
|
||||||
keys of the table */
|
strict weak ordering it defines, and false otherwise. */
|
||||||
|
struct dict_foreign_compare {
|
||||||
|
|
||||||
|
bool operator()(
|
||||||
|
const dict_foreign_t* lhs,
|
||||||
|
const dict_foreign_t* rhs) const
|
||||||
|
{
|
||||||
|
return(ut_strcmp(lhs->id, rhs->id) < 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** A function object to find a foreign key with the given index as the
|
||||||
|
referenced index. Return the foreign key with matching criteria or NULL */
|
||||||
|
struct dict_foreign_with_index {
|
||||||
|
|
||||||
|
dict_foreign_with_index(const dict_index_t* index)
|
||||||
|
: m_index(index)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool operator()(const dict_foreign_t* foreign) const
|
||||||
|
{
|
||||||
|
return(foreign->referenced_index == m_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
const dict_index_t* m_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A function object to check if the foreign constraint is between different
|
||||||
|
tables. Returns true if foreign key constraint is between different tables,
|
||||||
|
false otherwise. */
|
||||||
|
struct dict_foreign_different_tables {
|
||||||
|
|
||||||
|
bool operator()(const dict_foreign_t* foreign) const
|
||||||
|
{
|
||||||
|
return(foreign->foreign_table != foreign->referenced_table);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** A function object to check if the foreign key constraint has the same
|
||||||
|
name as given. If the full name of the foreign key constraint doesn't match,
|
||||||
|
then, check if removing the database name from the foreign key constraint
|
||||||
|
matches. Return true if it matches, false otherwise. */
|
||||||
|
struct dict_foreign_matches_id {
|
||||||
|
|
||||||
|
dict_foreign_matches_id(const char* id)
|
||||||
|
: m_id(id)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool operator()(const dict_foreign_t* foreign) const
|
||||||
|
{
|
||||||
|
if (0 == innobase_strcasecmp(foreign->id, m_id)) {
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
if (const char* pos = strchr(foreign->id, '/')) {
|
||||||
|
if (0 == innobase_strcasecmp(m_id, pos + 1)) {
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* m_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::set<dict_foreign_t*, dict_foreign_compare> dict_foreign_set;
|
||||||
|
|
||||||
|
/*********************************************************************//**
|
||||||
|
Frees a foreign key struct. */
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
dict_foreign_free(
|
||||||
|
/*==============*/
|
||||||
|
dict_foreign_t* foreign) /*!< in, own: foreign key struct */
|
||||||
|
{
|
||||||
|
mem_heap_free(foreign->heap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The destructor will free all the foreign key constraints in the set
|
||||||
|
by calling dict_foreign_free() on each of the foreign key constraints.
|
||||||
|
This is used to free the allocated memory when a local set goes out
|
||||||
|
of scope. */
|
||||||
|
struct dict_foreign_set_free {
|
||||||
|
|
||||||
|
dict_foreign_set_free(const dict_foreign_set& foreign_set)
|
||||||
|
: m_foreign_set(foreign_set)
|
||||||
|
{}
|
||||||
|
|
||||||
|
~dict_foreign_set_free()
|
||||||
|
{
|
||||||
|
std::for_each(m_foreign_set.begin(),
|
||||||
|
m_foreign_set.end(),
|
||||||
|
dict_foreign_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
const dict_foreign_set& m_foreign_set;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** The flags for ON_UPDATE and ON_DELETE can be ORed; the default is that
|
/** The flags for ON_UPDATE and ON_DELETE can be ORed; the default is that
|
||||||
|
@ -733,6 +829,8 @@ the table, DML from memcached will be blocked. */
|
||||||
/** Data structure for a database table. Most fields will be
|
/** Data structure for a database table. Most fields will be
|
||||||
initialized to 0, NULL or FALSE in dict_mem_table_create(). */
|
initialized to 0, NULL or FALSE in dict_mem_table_create(). */
|
||||||
struct dict_table_t{
|
struct dict_table_t{
|
||||||
|
|
||||||
|
|
||||||
table_id_t id; /*!< id of the table */
|
table_id_t id; /*!< id of the table */
|
||||||
mem_heap_t* heap; /*!< memory heap */
|
mem_heap_t* heap; /*!< memory heap */
|
||||||
char* name; /*!< table name */
|
char* name; /*!< table name */
|
||||||
|
@ -787,13 +885,16 @@ struct dict_table_t{
|
||||||
hash_node_t id_hash; /*!< hash chain node */
|
hash_node_t id_hash; /*!< hash chain node */
|
||||||
UT_LIST_BASE_NODE_T(dict_index_t)
|
UT_LIST_BASE_NODE_T(dict_index_t)
|
||||||
indexes; /*!< list of indexes of the table */
|
indexes; /*!< list of indexes of the table */
|
||||||
UT_LIST_BASE_NODE_T(dict_foreign_t)
|
|
||||||
foreign_list;/*!< list of foreign key constraints
|
dict_foreign_set foreign_set;
|
||||||
|
/*!< set of foreign key constraints
|
||||||
in the table; these refer to columns
|
in the table; these refer to columns
|
||||||
in other tables */
|
in other tables */
|
||||||
UT_LIST_BASE_NODE_T(dict_foreign_t)
|
|
||||||
referenced_list;/*!< list of foreign key constraints
|
dict_foreign_set referenced_set;
|
||||||
|
/*!< list of foreign key constraints
|
||||||
which refer to this table */
|
which refer to this table */
|
||||||
|
|
||||||
UT_LIST_NODE_T(dict_table_t)
|
UT_LIST_NODE_T(dict_table_t)
|
||||||
table_LRU; /*!< node of the LRU list of tables */
|
table_LRU; /*!< node of the LRU list of tables */
|
||||||
unsigned fk_max_recusive_level:8;
|
unsigned fk_max_recusive_level:8;
|
||||||
|
@ -1035,6 +1136,19 @@ struct dict_table_t{
|
||||||
#endif /* UNIV_DEBUG */
|
#endif /* UNIV_DEBUG */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** A function object to add the foreign key constraint to the referenced set
|
||||||
|
of the referenced table, if it exists in the dictionary cache. */
|
||||||
|
struct dict_foreign_add_to_referenced_table {
|
||||||
|
void operator()(dict_foreign_t* foreign) const
|
||||||
|
{
|
||||||
|
if (dict_table_t* table = foreign->referenced_table) {
|
||||||
|
std::pair<dict_foreign_set::iterator, bool> ret
|
||||||
|
= table->referenced_set.insert(foreign);
|
||||||
|
ut_a(ret.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#ifndef UNIV_NONINL
|
#ifndef UNIV_NONINL
|
||||||
#include "dict0mem.ic"
|
#include "dict0mem.ic"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -48,7 +48,7 @@ struct fil_space_t;
|
||||||
typedef std::list<const char*> space_name_list_t;
|
typedef std::list<const char*> space_name_list_t;
|
||||||
|
|
||||||
/** When mysqld is run, the default directory "." is the mysqld datadir,
|
/** When mysqld is run, the default directory "." is the mysqld datadir,
|
||||||
but in the MySQL Embedded Server Library and ibbackup it is not the default
|
but in the MySQL Embedded Server Library and mysqlbackup it is not the default
|
||||||
directory, and we must set the base file path explicitly */
|
directory, and we must set the base file path explicitly */
|
||||||
extern const char* fil_path_to_mysql_datadir;
|
extern const char* fil_path_to_mysql_datadir;
|
||||||
|
|
||||||
|
@ -426,8 +426,8 @@ exists and the space id in it matches. Replays the create operation if a file
|
||||||
at that path does not exist yet. If the database directory for the file to be
|
at that path does not exist yet. If the database directory for the file to be
|
||||||
created does not exist, then we create the directory, too.
|
created does not exist, then we create the directory, too.
|
||||||
|
|
||||||
Note that ibbackup --apply-log sets fil_path_to_mysql_datadir to point to the
|
Note that mysqlbackup --apply-log sets fil_path_to_mysql_datadir to point to
|
||||||
datadir that we should use in replaying the file operations.
|
the datadir that we should use in replaying the file operations.
|
||||||
@return end of log record, or NULL if the record was not completely
|
@return end of log record, or NULL if the record was not completely
|
||||||
contained between ptr and end_ptr */
|
contained between ptr and end_ptr */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
|
@ -680,9 +680,9 @@ fil_space_for_table_exists_in_mem(
|
||||||
#else /* !UNIV_HOTBACKUP */
|
#else /* !UNIV_HOTBACKUP */
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
Extends all tablespaces to the size stored in the space header. During the
|
Extends all tablespaces to the size stored in the space header. During the
|
||||||
ibbackup --apply-log phase we extended the spaces on-demand so that log records
|
mysqlbackup --apply-log phase we extended the spaces on-demand so that log
|
||||||
could be appllied, but that may have left spaces still too small compared to
|
records could be appllied, but that may have left spaces still too small
|
||||||
the size stored in the space header. */
|
compared to the size stored in the space header. */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
void
|
void
|
||||||
fil_extend_tablespaces_to_stored_len(void);
|
fil_extend_tablespaces_to_stored_len(void);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 2007, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 2007, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
@ -76,6 +76,7 @@ enum fts_ast_oper_t {
|
||||||
struct fts_lexer_t;
|
struct fts_lexer_t;
|
||||||
struct fts_ast_node_t;
|
struct fts_ast_node_t;
|
||||||
struct fts_ast_state_t;
|
struct fts_ast_state_t;
|
||||||
|
struct fts_ast_string_t;
|
||||||
|
|
||||||
typedef dberr_t (*fts_ast_callback)(fts_ast_oper_t, fts_ast_node_t*, void*);
|
typedef dberr_t (*fts_ast_callback)(fts_ast_oper_t, fts_ast_node_t*, void*);
|
||||||
|
|
||||||
|
@ -101,16 +102,16 @@ extern
|
||||||
fts_ast_node_t*
|
fts_ast_node_t*
|
||||||
fts_ast_create_node_term(
|
fts_ast_create_node_term(
|
||||||
/*=====================*/
|
/*=====================*/
|
||||||
void* arg, /*!< in: ast state */
|
void* arg, /*!< in: ast state */
|
||||||
const char* ptr); /*!< in: term string */
|
const fts_ast_string_t* ptr); /*!< in: term string */
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
Create an AST text node */
|
Create an AST text node */
|
||||||
extern
|
extern
|
||||||
fts_ast_node_t*
|
fts_ast_node_t*
|
||||||
fts_ast_create_node_text(
|
fts_ast_create_node_text(
|
||||||
/*=====================*/
|
/*=====================*/
|
||||||
void* arg, /*!< in: ast state */
|
void* arg, /*!< in: ast state */
|
||||||
const char* ptr); /*!< in: text string */
|
const fts_ast_string_t* ptr); /*!< in: text string */
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
Create an AST expr list node */
|
Create an AST expr list node */
|
||||||
extern
|
extern
|
||||||
|
@ -233,16 +234,66 @@ fts_lexer_free(
|
||||||
free */
|
free */
|
||||||
__attribute__((nonnull));
|
__attribute__((nonnull));
|
||||||
|
|
||||||
|
/**
|
||||||
|
Create an ast string object, with NUL-terminator, so the string
|
||||||
|
has one more byte than len
|
||||||
|
@param[in] str pointer to string
|
||||||
|
@param[in] len length of the string
|
||||||
|
@return ast string with NUL-terminator */
|
||||||
|
UNIV_INTERN
|
||||||
|
fts_ast_string_t*
|
||||||
|
fts_ast_string_create(
|
||||||
|
const byte* str,
|
||||||
|
ulint len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Free an ast string instance
|
||||||
|
@param[in,out] ast_str string to free */
|
||||||
|
UNIV_INTERN
|
||||||
|
void
|
||||||
|
fts_ast_string_free(
|
||||||
|
fts_ast_string_t* ast_str);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Translate ast string of type FTS_AST_NUMB to unsigned long by strtoul
|
||||||
|
@param[in] str string to translate
|
||||||
|
@param[in] base the base
|
||||||
|
@return translated number */
|
||||||
|
UNIV_INTERN
|
||||||
|
ulint
|
||||||
|
fts_ast_string_to_ul(
|
||||||
|
const fts_ast_string_t* ast_str,
|
||||||
|
int base);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Print the ast string
|
||||||
|
@param[in] str string to print */
|
||||||
|
UNIV_INTERN
|
||||||
|
void
|
||||||
|
fts_ast_string_print(
|
||||||
|
const fts_ast_string_t* ast_str);
|
||||||
|
|
||||||
|
/* String of length len.
|
||||||
|
We always store the string of length len with a terminating '\0',
|
||||||
|
regardless of there is any 0x00 in the string itself */
|
||||||
|
struct fts_ast_string_t {
|
||||||
|
/*!< Pointer to string. */
|
||||||
|
byte* str;
|
||||||
|
|
||||||
|
/*!< Length of the string. */
|
||||||
|
ulint len;
|
||||||
|
};
|
||||||
|
|
||||||
/* Query term type */
|
/* Query term type */
|
||||||
struct fts_ast_term_t {
|
struct fts_ast_term_t {
|
||||||
byte* ptr; /*!< Pointer to term string.*/
|
fts_ast_string_t* ptr; /*!< Pointer to term string.*/
|
||||||
ibool wildcard; /*!< TRUE if wild card set.*/
|
ibool wildcard; /*!< TRUE if wild card set.*/
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Query text type */
|
/* Query text type */
|
||||||
struct fts_ast_text_t {
|
struct fts_ast_text_t {
|
||||||
byte* ptr; /*!< Pointer to term string.*/
|
fts_ast_string_t* ptr; /*!< Pointer to text string.*/
|
||||||
ulint distance; /*!< > 0 if proximity distance
|
ulint distance; /*!< > 0 if proximity distance
|
||||||
set */
|
set */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -745,6 +745,7 @@ void
|
||||||
fts_savepoint_take(
|
fts_savepoint_take(
|
||||||
/*===============*/
|
/*===============*/
|
||||||
trx_t* trx, /*!< in: transaction */
|
trx_t* trx, /*!< in: transaction */
|
||||||
|
fts_trx_t* fts_trx, /*!< in: fts transaction */
|
||||||
const char* name) /*!< in: savepoint name */
|
const char* name) /*!< in: savepoint name */
|
||||||
__attribute__((nonnull));
|
__attribute__((nonnull));
|
||||||
/**********************************************************************//**
|
/**********************************************************************//**
|
||||||
|
|
|
@ -53,9 +53,9 @@ typedef union YYSTYPE
|
||||||
/* Line 2068 of yacc.c */
|
/* Line 2068 of yacc.c */
|
||||||
#line 61 "fts0pars.y"
|
#line 61 "fts0pars.y"
|
||||||
|
|
||||||
int oper;
|
int oper;
|
||||||
char* token;
|
fts_ast_string_t* token;
|
||||||
fts_ast_node_t* node;
|
fts_ast_node_t* node;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -656,13 +656,13 @@ extern log_t* log_sys;
|
||||||
megabyte.
|
megabyte.
|
||||||
|
|
||||||
This information might have been used
|
This information might have been used
|
||||||
since ibbackup version 0.35 but
|
since mysqlbackup version 0.35 but
|
||||||
before 1.41 to decide if unused ends of
|
before 1.41 to decide if unused ends of
|
||||||
non-auto-extending data files
|
non-auto-extending data files
|
||||||
in space 0 can be truncated.
|
in space 0 can be truncated.
|
||||||
|
|
||||||
This information was made obsolete
|
This information was made obsolete
|
||||||
by ibbackup --compress. */
|
by mysqlbackup --compress. */
|
||||||
#define LOG_CHECKPOINT_FSP_MAGIC_N (12 + LOG_CHECKPOINT_ARRAY_END)
|
#define LOG_CHECKPOINT_FSP_MAGIC_N (12 + LOG_CHECKPOINT_ARRAY_END)
|
||||||
/*!< Not used (0);
|
/*!< Not used (0);
|
||||||
This magic number tells if the
|
This magic number tells if the
|
||||||
|
@ -691,7 +691,7 @@ extern log_t* log_sys;
|
||||||
/* a 32-byte field which contains
|
/* a 32-byte field which contains
|
||||||
the string 'ibbackup' and the
|
the string 'ibbackup' and the
|
||||||
creation time if the log file was
|
creation time if the log file was
|
||||||
created by ibbackup --restore;
|
created by mysqlbackup --restore;
|
||||||
when mysqld is first time started
|
when mysqld is first time started
|
||||||
on the restored database, it can
|
on the restored database, it can
|
||||||
print helpful info for the user */
|
print helpful info for the user */
|
||||||
|
|
|
@ -126,7 +126,7 @@ enum os_file_create_t {
|
||||||
|
|
||||||
#define OS_FILE_READ_ONLY 333
|
#define OS_FILE_READ_ONLY 333
|
||||||
#define OS_FILE_READ_WRITE 444
|
#define OS_FILE_READ_WRITE 444
|
||||||
#define OS_FILE_READ_ALLOW_DELETE 555 /* for ibbackup */
|
#define OS_FILE_READ_ALLOW_DELETE 555 /* for mysqlbackup */
|
||||||
|
|
||||||
/* Options for file_create */
|
/* Options for file_create */
|
||||||
#define OS_FILE_AIO 61
|
#define OS_FILE_AIO 61
|
||||||
|
|
|
@ -357,6 +357,10 @@ Atomic compare-and-swap and increment for InnoDB. */
|
||||||
|
|
||||||
# define HAVE_ATOMIC_BUILTINS
|
# define HAVE_ATOMIC_BUILTINS
|
||||||
|
|
||||||
|
# ifdef HAVE_IB_GCC_ATOMIC_BUILTINS_BYTE
|
||||||
|
# define HAVE_ATOMIC_BUILTINS_BYTE
|
||||||
|
# endif
|
||||||
|
|
||||||
# ifdef HAVE_IB_GCC_ATOMIC_BUILTINS_64
|
# ifdef HAVE_IB_GCC_ATOMIC_BUILTINS_64
|
||||||
# define HAVE_ATOMIC_BUILTINS_64
|
# define HAVE_ATOMIC_BUILTINS_64
|
||||||
# endif
|
# endif
|
||||||
|
@ -440,6 +444,7 @@ Returns the old value of *ptr, atomically sets *ptr to new_val */
|
||||||
#elif defined(HAVE_IB_SOLARIS_ATOMICS)
|
#elif defined(HAVE_IB_SOLARIS_ATOMICS)
|
||||||
|
|
||||||
# define HAVE_ATOMIC_BUILTINS
|
# define HAVE_ATOMIC_BUILTINS
|
||||||
|
# define HAVE_ATOMIC_BUILTINS_BYTE
|
||||||
# define HAVE_ATOMIC_BUILTINS_64
|
# define HAVE_ATOMIC_BUILTINS_64
|
||||||
|
|
||||||
/* If not compiling with GCC or GCC doesn't support the atomic
|
/* If not compiling with GCC or GCC doesn't support the atomic
|
||||||
|
@ -524,6 +529,7 @@ Returns the old value of *ptr, atomically sets *ptr to new_val */
|
||||||
#elif defined(HAVE_WINDOWS_ATOMICS)
|
#elif defined(HAVE_WINDOWS_ATOMICS)
|
||||||
|
|
||||||
# define HAVE_ATOMIC_BUILTINS
|
# define HAVE_ATOMIC_BUILTINS
|
||||||
|
# define HAVE_ATOMIC_BUILTINS_BYTE
|
||||||
|
|
||||||
# ifndef _WIN32
|
# ifndef _WIN32
|
||||||
# define HAVE_ATOMIC_BUILTINS_64
|
# define HAVE_ATOMIC_BUILTINS_64
|
||||||
|
@ -695,7 +701,15 @@ for synchronization */
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
/** barrier definitions for memory ordering */
|
/** barrier definitions for memory ordering */
|
||||||
#ifdef HAVE_IB_GCC_ATOMIC_THREAD_FENCE
|
#if defined __i386__ || defined __x86_64__ || defined _M_IX86 || defined _M_X64 || defined __WIN__
|
||||||
|
/* Performance regression was observed at some conditions for Intel
|
||||||
|
architecture. Disable memory barrier for Intel architecture for now. */
|
||||||
|
# define os_rmb do { } while(0)
|
||||||
|
# define os_wmb do { } while(0)
|
||||||
|
# define os_isync do { } while(0)
|
||||||
|
# define IB_MEMORY_BARRIER_STARTUP_MSG \
|
||||||
|
"Memory barrier is not used"
|
||||||
|
#elif defined(HAVE_IB_GCC_ATOMIC_THREAD_FENCE)
|
||||||
# define HAVE_MEMORY_BARRIER
|
# define HAVE_MEMORY_BARRIER
|
||||||
# define os_rmb __atomic_thread_fence(__ATOMIC_ACQUIRE)
|
# define os_rmb __atomic_thread_fence(__ATOMIC_ACQUIRE)
|
||||||
# define os_wmb __atomic_thread_fence(__ATOMIC_RELEASE)
|
# define os_wmb __atomic_thread_fence(__ATOMIC_RELEASE)
|
||||||
|
@ -723,7 +737,7 @@ for synchronization */
|
||||||
# define os_wmb __machine_w_barrier()
|
# define os_wmb __machine_w_barrier()
|
||||||
# define os_isync os_rmb; os_wmb
|
# define os_isync os_rmb; os_wmb
|
||||||
# define IB_MEMORY_BARRIER_STARTUP_MSG \
|
# define IB_MEMORY_BARRIER_STARTUP_MSG \
|
||||||
"Soralis memory ordering functions are used for memory barrier"
|
"Solaris memory ordering functions are used for memory barrier"
|
||||||
|
|
||||||
#elif defined(HAVE_WINDOWS_MM_FENCE)
|
#elif defined(HAVE_WINDOWS_MM_FENCE)
|
||||||
# define HAVE_MEMORY_BARRIER
|
# define HAVE_MEMORY_BARRIER
|
||||||
|
|
|
@ -93,6 +93,7 @@ rw_lock_set_waiter_flag(
|
||||||
(void) os_compare_and_swap_ulint(&lock->waiters, 0, 1);
|
(void) os_compare_and_swap_ulint(&lock->waiters, 0, 1);
|
||||||
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
|
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
|
||||||
lock->waiters = 1;
|
lock->waiters = 1;
|
||||||
|
os_wmb;
|
||||||
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
|
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,6 +111,7 @@ rw_lock_reset_waiter_flag(
|
||||||
(void) os_compare_and_swap_ulint(&lock->waiters, 1, 0);
|
(void) os_compare_and_swap_ulint(&lock->waiters, 1, 0);
|
||||||
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
|
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
|
||||||
lock->waiters = 0;
|
lock->waiters = 0;
|
||||||
|
os_wmb;
|
||||||
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
|
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,13 +202,16 @@ rw_lock_lock_word_decr(
|
||||||
{
|
{
|
||||||
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
|
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
|
||||||
lint local_lock_word;
|
lint local_lock_word;
|
||||||
os_rmb;
|
|
||||||
while ((local_lock_word= lock->lock_word) > 0) {
|
os_rmb;
|
||||||
|
local_lock_word = lock->lock_word;
|
||||||
|
while (local_lock_word > 0) {
|
||||||
if (os_compare_and_swap_lint(&lock->lock_word,
|
if (os_compare_and_swap_lint(&lock->lock_word,
|
||||||
local_lock_word,
|
local_lock_word,
|
||||||
local_lock_word - amount)) {
|
local_lock_word - amount)) {
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
local_lock_word = lock->lock_word;
|
||||||
}
|
}
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
|
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
|
||||||
|
|
|
@ -49,6 +49,8 @@ extern "C" my_bool timed_mutexes;
|
||||||
#ifdef HAVE_WINDOWS_ATOMICS
|
#ifdef HAVE_WINDOWS_ATOMICS
|
||||||
typedef LONG lock_word_t; /*!< On Windows, InterlockedExchange operates
|
typedef LONG lock_word_t; /*!< On Windows, InterlockedExchange operates
|
||||||
on LONG variable */
|
on LONG variable */
|
||||||
|
#elif defined(HAVE_ATOMIC_BUILTINS) && !defined(HAVE_ATOMIC_BUILTINS_BYTE)
|
||||||
|
typedef ulint lock_word_t;
|
||||||
#else
|
#else
|
||||||
typedef byte lock_word_t;
|
typedef byte lock_word_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -80,7 +80,11 @@ ib_mutex_test_and_set(
|
||||||
ib_mutex_t* mutex) /*!< in: mutex */
|
ib_mutex_t* mutex) /*!< in: mutex */
|
||||||
{
|
{
|
||||||
#if defined(HAVE_ATOMIC_BUILTINS)
|
#if defined(HAVE_ATOMIC_BUILTINS)
|
||||||
|
# if defined(HAVE_ATOMIC_BUILTINS_BYTE)
|
||||||
return(os_atomic_test_and_set_byte(&mutex->lock_word, 1));
|
return(os_atomic_test_and_set_byte(&mutex->lock_word, 1));
|
||||||
|
# else
|
||||||
|
return(os_atomic_test_and_set_ulint(&mutex->lock_word, 1));
|
||||||
|
# endif
|
||||||
#else
|
#else
|
||||||
ibool ret;
|
ibool ret;
|
||||||
|
|
||||||
|
@ -92,7 +96,7 @@ ib_mutex_test_and_set(
|
||||||
ut_a(mutex->lock_word == 0);
|
ut_a(mutex->lock_word == 0);
|
||||||
|
|
||||||
mutex->lock_word = 1;
|
mutex->lock_word = 1;
|
||||||
os_wmb;
|
os_wmb;
|
||||||
}
|
}
|
||||||
|
|
||||||
return((byte) ret);
|
return((byte) ret);
|
||||||
|
|
|
@ -44,7 +44,7 @@ Created 1/20/1994 Heikki Tuuri
|
||||||
|
|
||||||
#define INNODB_VERSION_MAJOR 5
|
#define INNODB_VERSION_MAJOR 5
|
||||||
#define INNODB_VERSION_MINOR 6
|
#define INNODB_VERSION_MINOR 6
|
||||||
#define INNODB_VERSION_BUGFIX 19
|
#define INNODB_VERSION_BUGFIX 20
|
||||||
|
|
||||||
/* The following is the InnoDB version as shown in
|
/* The following is the InnoDB version as shown in
|
||||||
SELECT plugin_version FROM information_schema.plugins;
|
SELECT plugin_version FROM information_schema.plugins;
|
||||||
|
|
|
@ -1249,7 +1249,7 @@ log_group_file_header_flush(
|
||||||
mach_write_to_4(buf + LOG_GROUP_ID, group->id);
|
mach_write_to_4(buf + LOG_GROUP_ID, group->id);
|
||||||
mach_write_to_8(buf + LOG_FILE_START_LSN, start_lsn);
|
mach_write_to_8(buf + LOG_FILE_START_LSN, start_lsn);
|
||||||
|
|
||||||
/* Wipe over possible label of ibbackup --restore */
|
/* Wipe over possible label of mysqlbackup --restore */
|
||||||
memcpy(buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, " ", 4);
|
memcpy(buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, " ", 4);
|
||||||
|
|
||||||
dest_offset = nth_file * group->file_size;
|
dest_offset = nth_file * group->file_size;
|
||||||
|
@ -1996,7 +1996,7 @@ log_reset_first_header_and_checkpoint(
|
||||||
|
|
||||||
lsn = start + LOG_BLOCK_HDR_SIZE;
|
lsn = start + LOG_BLOCK_HDR_SIZE;
|
||||||
|
|
||||||
/* Write the label of ibbackup --restore */
|
/* Write the label of mysqlbackup --restore */
|
||||||
strcpy((char*) hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP,
|
strcpy((char*) hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP,
|
||||||
"ibbackup ");
|
"ibbackup ");
|
||||||
ut_sprintf_timestamp((char*) hdr_buf
|
ut_sprintf_timestamp((char*) hdr_buf
|
||||||
|
|
|
@ -59,7 +59,7 @@ Created 9/20/1997 Heikki Tuuri
|
||||||
|
|
||||||
|
|
||||||
/** This is set to FALSE if the backup was originally taken with the
|
/** This is set to FALSE if the backup was originally taken with the
|
||||||
ibbackup --include regexp option: then we do not want to create tables in
|
mysqlbackup --include regexp option: then we do not want to create tables in
|
||||||
directories which were not included */
|
directories which were not included */
|
||||||
UNIV_INTERN ibool recv_replay_file_ops = TRUE;
|
UNIV_INTERN ibool recv_replay_file_ops = TRUE;
|
||||||
#endif /* !UNIV_HOTBACKUP */
|
#endif /* !UNIV_HOTBACKUP */
|
||||||
|
@ -2056,7 +2056,7 @@ recv_apply_log_recs_for_backup(void)
|
||||||
|
|
||||||
/* Extend the tablespace's last file if the page_no
|
/* Extend the tablespace's last file if the page_no
|
||||||
does not fall inside its bounds; we assume the last
|
does not fall inside its bounds; we assume the last
|
||||||
file is auto-extending, and ibbackup copied the file
|
file is auto-extending, and mysqlbackup copied the file
|
||||||
when it still was smaller */
|
when it still was smaller */
|
||||||
|
|
||||||
success = fil_extend_space_to_desired_size(
|
success = fil_extend_space_to_desired_size(
|
||||||
|
@ -2427,10 +2427,10 @@ loop:
|
||||||
#ifdef UNIV_HOTBACKUP
|
#ifdef UNIV_HOTBACKUP
|
||||||
if (recv_replay_file_ops) {
|
if (recv_replay_file_ops) {
|
||||||
|
|
||||||
/* In ibbackup --apply-log, replay an .ibd file
|
/* In mysqlbackup --apply-log, replay an .ibd
|
||||||
operation, if possible; note that
|
file operation, if possible; note that
|
||||||
fil_path_to_mysql_datadir is set in ibbackup to
|
fil_path_to_mysql_datadir is set in mysqlbackup
|
||||||
point to the datadir we should use there */
|
to point to the datadir we should use there */
|
||||||
|
|
||||||
if (NULL == fil_op_log_parse_or_replay(
|
if (NULL == fil_op_log_parse_or_replay(
|
||||||
body, end_ptr, type,
|
body, end_ptr, type,
|
||||||
|
@ -3090,17 +3090,17 @@ recv_recovery_from_checkpoint_start_func(
|
||||||
if (srv_read_only_mode) {
|
if (srv_read_only_mode) {
|
||||||
|
|
||||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||||
"Cannot restore from ibbackup, InnoDB running "
|
"Cannot restore from mysqlbackup, InnoDB "
|
||||||
"in read-only mode!");
|
"running in read-only mode!");
|
||||||
|
|
||||||
return(DB_ERROR);
|
return(DB_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This log file was created by ibbackup --restore: print
|
/* This log file was created by mysqlbackup --restore: print
|
||||||
a note to the user about it */
|
a note to the user about it */
|
||||||
|
|
||||||
ib_logf(IB_LOG_LEVEL_INFO,
|
ib_logf(IB_LOG_LEVEL_INFO,
|
||||||
"The log file was created by ibbackup --apply-log "
|
"The log file was created by mysqlbackup --apply-log "
|
||||||
"at %s. The following crash recovery is part of a "
|
"at %s. The following crash recovery is part of a "
|
||||||
"normal restore.",
|
"normal restore.",
|
||||||
log_hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP);
|
log_hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP);
|
||||||
|
|
|
@ -1816,7 +1816,7 @@ os_file_delete_if_exists_func(
|
||||||
bool ret;
|
bool ret;
|
||||||
ulint count = 0;
|
ulint count = 0;
|
||||||
loop:
|
loop:
|
||||||
/* In Windows, deleting an .ibd file may fail if ibbackup is copying
|
/* In Windows, deleting an .ibd file may fail if mysqlbackup is copying
|
||||||
it */
|
it */
|
||||||
|
|
||||||
ret = DeleteFile((LPCTSTR) name);
|
ret = DeleteFile((LPCTSTR) name);
|
||||||
|
@ -1841,7 +1841,7 @@ loop:
|
||||||
ib_logf(IB_LOG_LEVEL_WARN, "Delete of file %s failed.", name);
|
ib_logf(IB_LOG_LEVEL_WARN, "Delete of file %s failed.", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
os_thread_sleep(1000000); /* sleep for a second */
|
os_thread_sleep(500000); /* sleep for 0.5 second */
|
||||||
|
|
||||||
if (count > 2000) {
|
if (count > 2000) {
|
||||||
|
|
||||||
|
@ -1878,7 +1878,7 @@ os_file_delete_func(
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
ulint count = 0;
|
ulint count = 0;
|
||||||
loop:
|
loop:
|
||||||
/* In Windows, deleting an .ibd file may fail if ibbackup is copying
|
/* In Windows, deleting an .ibd file may fail if mysqlbackup is copying
|
||||||
it */
|
it */
|
||||||
|
|
||||||
ret = DeleteFile((LPCTSTR) name);
|
ret = DeleteFile((LPCTSTR) name);
|
||||||
|
@ -1901,7 +1901,7 @@ loop:
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"InnoDB: Warning: cannot delete file %s\n"
|
"InnoDB: Warning: cannot delete file %s\n"
|
||||||
"InnoDB: Are you running ibbackup"
|
"InnoDB: Are you running mysqlbackup"
|
||||||
" to back up the file?\n", name);
|
" to back up the file?\n", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3278,24 +3278,8 @@ page_zip_validate_low(
|
||||||
temp_page_buf = static_cast<byte*>(ut_malloc(2 * UNIV_PAGE_SIZE));
|
temp_page_buf = static_cast<byte*>(ut_malloc(2 * UNIV_PAGE_SIZE));
|
||||||
temp_page = static_cast<byte*>(ut_align(temp_page_buf, UNIV_PAGE_SIZE));
|
temp_page = static_cast<byte*>(ut_align(temp_page_buf, UNIV_PAGE_SIZE));
|
||||||
|
|
||||||
#ifdef UNIV_DEBUG_VALGRIND
|
|
||||||
/* Get detailed information on the valid bits in case the
|
|
||||||
UNIV_MEM_ASSERT_RW() checks fail. The v-bits of page[],
|
|
||||||
page_zip->data[] or page_zip could be viewed at temp_page[] or
|
|
||||||
temp_page_zip in a debugger when running valgrind --db-attach. */
|
|
||||||
(void) VALGRIND_GET_VBITS(page, temp_page, UNIV_PAGE_SIZE);
|
|
||||||
UNIV_MEM_ASSERT_RW(page, UNIV_PAGE_SIZE);
|
UNIV_MEM_ASSERT_RW(page, UNIV_PAGE_SIZE);
|
||||||
# if UNIV_WORD_SIZE == 4
|
|
||||||
VALGRIND_GET_VBITS(page_zip, &temp_page_zip, sizeof temp_page_zip);
|
|
||||||
/* On 32-bit systems, there is no padding in page_zip_des_t.
|
|
||||||
On other systems, Valgrind could complain about uninitialized
|
|
||||||
pad bytes. */
|
|
||||||
UNIV_MEM_ASSERT_RW(page_zip, sizeof *page_zip);
|
|
||||||
# endif
|
|
||||||
(void) VALGRIND_GET_VBITS(page_zip->data, temp_page,
|
|
||||||
page_zip_get_size(page_zip));
|
|
||||||
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
|
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
|
||||||
#endif /* UNIV_DEBUG_VALGRIND */
|
|
||||||
|
|
||||||
temp_page_zip = *page_zip;
|
temp_page_zip = *page_zip;
|
||||||
valid = page_zip_decompress(&temp_page_zip, temp_page, TRUE);
|
valid = page_zip_decompress(&temp_page_zip, temp_page, TRUE);
|
||||||
|
|
|
@ -1711,12 +1711,11 @@ do_possible_lock_wait:
|
||||||
table case (check_ref == 0), since MDL lock will prevent
|
table case (check_ref == 0), since MDL lock will prevent
|
||||||
concurrent DDL and DML on the same table */
|
concurrent DDL and DML on the same table */
|
||||||
if (!check_ref) {
|
if (!check_ref) {
|
||||||
for (const dict_foreign_t* check_foreign
|
for (dict_foreign_set::iterator it
|
||||||
= UT_LIST_GET_FIRST( table->referenced_list);
|
= table->referenced_set.begin();
|
||||||
check_foreign;
|
it != table->referenced_set.end();
|
||||||
check_foreign = UT_LIST_GET_NEXT(
|
++it) {
|
||||||
referenced_list, check_foreign)) {
|
if (*it == foreign) {
|
||||||
if (check_foreign == foreign) {
|
|
||||||
verified = true;
|
verified = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1764,12 +1763,15 @@ row_ins_check_foreign_constraints(
|
||||||
|
|
||||||
trx = thr_get_trx(thr);
|
trx = thr_get_trx(thr);
|
||||||
|
|
||||||
foreign = UT_LIST_GET_FIRST(table->foreign_list);
|
|
||||||
|
|
||||||
DEBUG_SYNC_C_IF_THD(thr_get_trx(thr)->mysql_thd,
|
DEBUG_SYNC_C_IF_THD(thr_get_trx(thr)->mysql_thd,
|
||||||
"foreign_constraint_check_for_ins");
|
"foreign_constraint_check_for_ins");
|
||||||
|
|
||||||
while (foreign) {
|
for (dict_foreign_set::iterator it = table->foreign_set.begin();
|
||||||
|
it != table->foreign_set.end();
|
||||||
|
++it) {
|
||||||
|
|
||||||
|
foreign = *it;
|
||||||
|
|
||||||
if (foreign->foreign_index == index) {
|
if (foreign->foreign_index == index) {
|
||||||
dict_table_t* ref_table = NULL;
|
dict_table_t* ref_table = NULL;
|
||||||
dict_table_t* foreign_table = foreign->foreign_table;
|
dict_table_t* foreign_table = foreign->foreign_table;
|
||||||
|
@ -1825,8 +1827,6 @@ row_ins_check_foreign_constraints(
|
||||||
return(err);
|
return(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return(DB_SUCCESS);
|
return(DB_SUCCESS);
|
||||||
|
@ -2858,7 +2858,7 @@ row_ins_clust_index_entry(
|
||||||
dberr_t err;
|
dberr_t err;
|
||||||
ulint n_uniq;
|
ulint n_uniq;
|
||||||
|
|
||||||
if (UT_LIST_GET_FIRST(index->table->foreign_list)) {
|
if (!index->table->foreign_set.empty()) {
|
||||||
err = row_ins_check_foreign_constraints(
|
err = row_ins_check_foreign_constraints(
|
||||||
index->table, index, entry, thr);
|
index->table, index, entry, thr);
|
||||||
if (err != DB_SUCCESS) {
|
if (err != DB_SUCCESS) {
|
||||||
|
@ -2916,7 +2916,7 @@ row_ins_sec_index_entry(
|
||||||
mem_heap_t* offsets_heap;
|
mem_heap_t* offsets_heap;
|
||||||
mem_heap_t* heap;
|
mem_heap_t* heap;
|
||||||
|
|
||||||
if (UT_LIST_GET_FIRST(index->table->foreign_list)) {
|
if (!index->table->foreign_set.empty()) {
|
||||||
err = row_ins_check_foreign_constraints(index->table, index,
|
err = row_ins_check_foreign_constraints(index->table, index,
|
||||||
entry, thr);
|
entry, thr);
|
||||||
if (err != DB_SUCCESS) {
|
if (err != DB_SUCCESS) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 2000, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
@ -63,6 +63,7 @@ Created 9/17/2000 Heikki Tuuri
|
||||||
#include "m_string.h"
|
#include "m_string.h"
|
||||||
#include "my_sys.h"
|
#include "my_sys.h"
|
||||||
#include "ha_prototypes.h"
|
#include "ha_prototypes.h"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
/** Provide optional 4.x backwards compatibility for 5.0 and above */
|
/** Provide optional 4.x backwards compatibility for 5.0 and above */
|
||||||
UNIV_INTERN ibool row_rollback_on_timeout = FALSE;
|
UNIV_INTERN ibool row_rollback_on_timeout = FALSE;
|
||||||
|
@ -1573,8 +1574,6 @@ init_fts_doc_id_for_ref(
|
||||||
{
|
{
|
||||||
dict_foreign_t* foreign;
|
dict_foreign_t* foreign;
|
||||||
|
|
||||||
foreign = UT_LIST_GET_FIRST(table->referenced_list);
|
|
||||||
|
|
||||||
table->fk_max_recusive_level = 0;
|
table->fk_max_recusive_level = 0;
|
||||||
|
|
||||||
(*depth)++;
|
(*depth)++;
|
||||||
|
@ -1586,17 +1585,25 @@ init_fts_doc_id_for_ref(
|
||||||
|
|
||||||
/* Loop through this table's referenced list and also
|
/* Loop through this table's referenced list and also
|
||||||
recursively traverse each table's foreign table list */
|
recursively traverse each table's foreign table list */
|
||||||
while (foreign && foreign->foreign_table) {
|
for (dict_foreign_set::iterator it = table->referenced_set.begin();
|
||||||
if (foreign->foreign_table->fts) {
|
it != table->referenced_set.end();
|
||||||
|
++it) {
|
||||||
|
|
||||||
|
foreign = *it;
|
||||||
|
|
||||||
|
if (foreign->foreign_table == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (foreign->foreign_table->fts != NULL) {
|
||||||
fts_init_doc_id(foreign->foreign_table);
|
fts_init_doc_id(foreign->foreign_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UT_LIST_GET_LEN(foreign->foreign_table->referenced_list)
|
if (!foreign->foreign_table->referenced_set.empty()
|
||||||
> 0 && foreign->foreign_table != table) {
|
&& foreign->foreign_table != table) {
|
||||||
init_fts_doc_id_for_ref(foreign->foreign_table, depth);
|
init_fts_doc_id_for_ref(
|
||||||
|
foreign->foreign_table, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2825,43 +2832,47 @@ row_discard_tablespace_foreign_key_checks(
|
||||||
const trx_t* trx, /*!< in: transaction handle */
|
const trx_t* trx, /*!< in: transaction handle */
|
||||||
const dict_table_t* table) /*!< in: table to be discarded */
|
const dict_table_t* table) /*!< in: table to be discarded */
|
||||||
{
|
{
|
||||||
const dict_foreign_t* foreign;
|
|
||||||
|
if (srv_read_only_mode || !trx->check_foreigns) {
|
||||||
|
return(DB_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if the table is referenced by foreign key constraints from
|
/* Check if the table is referenced by foreign key constraints from
|
||||||
some other table (not the table itself) */
|
some other table (not the table itself) */
|
||||||
|
dict_foreign_set::iterator it
|
||||||
|
= std::find_if(table->referenced_set.begin(),
|
||||||
|
table->referenced_set.end(),
|
||||||
|
dict_foreign_different_tables());
|
||||||
|
|
||||||
for (foreign = UT_LIST_GET_FIRST(table->referenced_list);
|
if (it == table->referenced_set.end()) {
|
||||||
foreign && foreign->foreign_table == table;
|
return(DB_SUCCESS);
|
||||||
foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!srv_read_only_mode && foreign && trx->check_foreigns) {
|
const dict_foreign_t* foreign = *it;
|
||||||
|
FILE* ef = dict_foreign_err_file;
|
||||||
|
|
||||||
FILE* ef = dict_foreign_err_file;
|
ut_ad(foreign->foreign_table != table);
|
||||||
|
ut_ad(foreign->referenced_table == table);
|
||||||
|
|
||||||
/* We only allow discarding a referenced table if
|
/* We only allow discarding a referenced table if
|
||||||
FOREIGN_KEY_CHECKS is set to 0 */
|
FOREIGN_KEY_CHECKS is set to 0 */
|
||||||
|
|
||||||
mutex_enter(&dict_foreign_err_mutex);
|
mutex_enter(&dict_foreign_err_mutex);
|
||||||
|
|
||||||
rewind(ef);
|
rewind(ef);
|
||||||
|
|
||||||
ut_print_timestamp(ef);
|
ut_print_timestamp(ef);
|
||||||
|
|
||||||
fputs(" Cannot DISCARD table ", ef);
|
fputs(" Cannot DISCARD table ", ef);
|
||||||
ut_print_name(stderr, trx, TRUE, table->name);
|
ut_print_name(stderr, trx, TRUE, table->name);
|
||||||
fputs("\n"
|
fputs("\n"
|
||||||
"because it is referenced by ", ef);
|
"because it is referenced by ", ef);
|
||||||
ut_print_name(stderr, trx, TRUE, foreign->foreign_table_name);
|
ut_print_name(stderr, trx, TRUE, foreign->foreign_table_name);
|
||||||
putc('\n', ef);
|
putc('\n', ef);
|
||||||
|
|
||||||
mutex_exit(&dict_foreign_err_mutex);
|
mutex_exit(&dict_foreign_err_mutex);
|
||||||
|
|
||||||
return(DB_CANNOT_DROP_CONSTRAINT);
|
return(DB_CANNOT_DROP_CONSTRAINT);
|
||||||
}
|
|
||||||
|
|
||||||
return(DB_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
|
@ -3164,7 +3175,6 @@ row_truncate_table_for_mysql(
|
||||||
dict_table_t* table, /*!< in: table handle */
|
dict_table_t* table, /*!< in: table handle */
|
||||||
trx_t* trx) /*!< in: transaction handle */
|
trx_t* trx) /*!< in: transaction handle */
|
||||||
{
|
{
|
||||||
dict_foreign_t* foreign;
|
|
||||||
dberr_t err;
|
dberr_t err;
|
||||||
mem_heap_t* heap;
|
mem_heap_t* heap;
|
||||||
byte* buf;
|
byte* buf;
|
||||||
|
@ -3256,18 +3266,17 @@ row_truncate_table_for_mysql(
|
||||||
/* Check if the table is referenced by foreign key constraints from
|
/* Check if the table is referenced by foreign key constraints from
|
||||||
some other table (not the table itself) */
|
some other table (not the table itself) */
|
||||||
|
|
||||||
for (foreign = UT_LIST_GET_FIRST(table->referenced_list);
|
dict_foreign_set::iterator it
|
||||||
foreign != 0 && foreign->foreign_table == table;
|
= std::find_if(table->referenced_set.begin(),
|
||||||
foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) {
|
table->referenced_set.end(),
|
||||||
|
dict_foreign_different_tables());
|
||||||
/* Do nothing. */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!srv_read_only_mode
|
if (!srv_read_only_mode
|
||||||
&& foreign
|
&& it != table->referenced_set.end()
|
||||||
&& trx->check_foreigns) {
|
&& trx->check_foreigns) {
|
||||||
|
|
||||||
FILE* ef = dict_foreign_err_file;
|
FILE* ef = dict_foreign_err_file;
|
||||||
|
dict_foreign_t* foreign = *it;
|
||||||
|
|
||||||
/* We only allow truncating a referenced table if
|
/* We only allow truncating a referenced table if
|
||||||
FOREIGN_KEY_CHECKS is set to 0 */
|
FOREIGN_KEY_CHECKS is set to 0 */
|
||||||
|
@ -3868,42 +3877,45 @@ row_drop_table_for_mysql(
|
||||||
/* Check if the table is referenced by foreign key constraints from
|
/* Check if the table is referenced by foreign key constraints from
|
||||||
some other table (not the table itself) */
|
some other table (not the table itself) */
|
||||||
|
|
||||||
foreign = UT_LIST_GET_FIRST(table->referenced_list);
|
if (!srv_read_only_mode && trx->check_foreigns) {
|
||||||
|
|
||||||
while (foreign && foreign->foreign_table == table) {
|
for (dict_foreign_set::iterator it
|
||||||
check_next_foreign:
|
= table->referenced_set.begin();
|
||||||
foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
|
it != table->referenced_set.end();
|
||||||
}
|
++it) {
|
||||||
|
|
||||||
if (!srv_read_only_mode
|
foreign = *it;
|
||||||
&& foreign
|
|
||||||
&& trx->check_foreigns
|
|
||||||
&& !(drop_db && dict_tables_have_same_db(
|
|
||||||
name, foreign->foreign_table_name_lookup))) {
|
|
||||||
FILE* ef = dict_foreign_err_file;
|
|
||||||
|
|
||||||
/* We only allow dropping a referenced table if
|
const bool ref_ok = drop_db
|
||||||
FOREIGN_KEY_CHECKS is set to 0 */
|
&& dict_tables_have_same_db(
|
||||||
|
name,
|
||||||
|
foreign->foreign_table_name_lookup);
|
||||||
|
|
||||||
err = DB_CANNOT_DROP_CONSTRAINT;
|
if (foreign->foreign_table != table && !ref_ok) {
|
||||||
|
|
||||||
mutex_enter(&dict_foreign_err_mutex);
|
FILE* ef = dict_foreign_err_file;
|
||||||
rewind(ef);
|
|
||||||
ut_print_timestamp(ef);
|
|
||||||
|
|
||||||
fputs(" Cannot drop table ", ef);
|
/* We only allow dropping a referenced table
|
||||||
ut_print_name(ef, trx, TRUE, name);
|
if FOREIGN_KEY_CHECKS is set to 0 */
|
||||||
fputs("\n"
|
|
||||||
"because it is referenced by ", ef);
|
|
||||||
ut_print_name(ef, trx, TRUE, foreign->foreign_table_name);
|
|
||||||
putc('\n', ef);
|
|
||||||
mutex_exit(&dict_foreign_err_mutex);
|
|
||||||
|
|
||||||
goto funct_exit;
|
err = DB_CANNOT_DROP_CONSTRAINT;
|
||||||
}
|
|
||||||
|
|
||||||
if (foreign && trx->check_foreigns) {
|
mutex_enter(&dict_foreign_err_mutex);
|
||||||
goto check_next_foreign;
|
rewind(ef);
|
||||||
|
ut_print_timestamp(ef);
|
||||||
|
|
||||||
|
fputs(" Cannot drop table ", ef);
|
||||||
|
ut_print_name(ef, trx, TRUE, name);
|
||||||
|
fputs("\n"
|
||||||
|
"because it is referenced by ", ef);
|
||||||
|
ut_print_name(ef, trx, TRUE,
|
||||||
|
foreign->foreign_table_name);
|
||||||
|
putc('\n', ef);
|
||||||
|
mutex_exit(&dict_foreign_err_mutex);
|
||||||
|
|
||||||
|
goto funct_exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: could we replace the counter n_foreign_key_checks_running
|
/* TODO: could we replace the counter n_foreign_key_checks_running
|
||||||
|
|
|
@ -51,7 +51,7 @@ Created 12/27/1996 Heikki Tuuri
|
||||||
#include "pars0sym.h"
|
#include "pars0sym.h"
|
||||||
#include "eval0eval.h"
|
#include "eval0eval.h"
|
||||||
#include "buf0lru.h"
|
#include "buf0lru.h"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
/* What kind of latch and lock can we assume when the control comes to
|
/* What kind of latch and lock can we assume when the control comes to
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
|
@ -136,12 +136,10 @@ row_upd_index_is_referenced(
|
||||||
trx_t* trx) /*!< in: transaction */
|
trx_t* trx) /*!< in: transaction */
|
||||||
{
|
{
|
||||||
dict_table_t* table = index->table;
|
dict_table_t* table = index->table;
|
||||||
dict_foreign_t* foreign;
|
|
||||||
ibool froze_data_dict = FALSE;
|
ibool froze_data_dict = FALSE;
|
||||||
ibool is_referenced = FALSE;
|
ibool is_referenced = FALSE;
|
||||||
|
|
||||||
if (!UT_LIST_GET_FIRST(table->referenced_list)) {
|
if (table->referenced_set.empty()) {
|
||||||
|
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,19 +148,13 @@ row_upd_index_is_referenced(
|
||||||
froze_data_dict = TRUE;
|
froze_data_dict = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreign = UT_LIST_GET_FIRST(table->referenced_list);
|
dict_foreign_set::iterator it
|
||||||
|
= std::find_if(table->referenced_set.begin(),
|
||||||
|
table->referenced_set.end(),
|
||||||
|
dict_foreign_with_index(index));
|
||||||
|
|
||||||
while (foreign) {
|
is_referenced = (it != table->referenced_set.end());
|
||||||
if (foreign->referenced_index == index) {
|
|
||||||
|
|
||||||
is_referenced = TRUE;
|
|
||||||
goto func_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
|
|
||||||
}
|
|
||||||
|
|
||||||
func_exit:
|
|
||||||
if (froze_data_dict) {
|
if (froze_data_dict) {
|
||||||
row_mysql_unfreeze_data_dictionary(trx);
|
row_mysql_unfreeze_data_dictionary(trx);
|
||||||
}
|
}
|
||||||
|
@ -200,7 +192,7 @@ row_upd_check_references_constraints(
|
||||||
dberr_t err;
|
dberr_t err;
|
||||||
ibool got_s_lock = FALSE;
|
ibool got_s_lock = FALSE;
|
||||||
|
|
||||||
if (UT_LIST_GET_FIRST(table->referenced_list) == NULL) {
|
if (table->referenced_set.empty()) {
|
||||||
|
|
||||||
return(DB_SUCCESS);
|
return(DB_SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -227,9 +219,13 @@ row_upd_check_references_constraints(
|
||||||
}
|
}
|
||||||
|
|
||||||
run_again:
|
run_again:
|
||||||
foreign = UT_LIST_GET_FIRST(table->referenced_list);
|
|
||||||
|
|
||||||
while (foreign) {
|
for (dict_foreign_set::iterator it = table->referenced_set.begin();
|
||||||
|
it != table->referenced_set.end();
|
||||||
|
++it) {
|
||||||
|
|
||||||
|
foreign = *it;
|
||||||
|
|
||||||
/* Note that we may have an update which updates the index
|
/* Note that we may have an update which updates the index
|
||||||
record, but does NOT update the first fields which are
|
record, but does NOT update the first fields which are
|
||||||
referenced in a foreign key constraint. Then the update does
|
referenced in a foreign key constraint. Then the update does
|
||||||
|
@ -282,8 +278,6 @@ run_again:
|
||||||
goto func_exit;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = DB_SUCCESS;
|
err = DB_SUCCESS;
|
||||||
|
|
|
@ -1647,6 +1647,19 @@ innobase_start_or_create_for_mysql(void)
|
||||||
ib_logf(IB_LOG_LEVEL_INFO,
|
ib_logf(IB_LOG_LEVEL_INFO,
|
||||||
"" IB_ATOMICS_STARTUP_MSG "");
|
"" IB_ATOMICS_STARTUP_MSG "");
|
||||||
|
|
||||||
|
ib_logf(IB_LOG_LEVEL_INFO,
|
||||||
|
"" IB_MEMORY_BARRIER_STARTUP_MSG "");
|
||||||
|
|
||||||
|
#ifndef HAVE_MEMORY_BARRIER
|
||||||
|
#if defined __i386__ || defined __x86_64__ || defined _M_IX86 || defined _M_X64 || defined __WIN__
|
||||||
|
#else
|
||||||
|
ib_logf(IB_LOG_LEVEL_WARN,
|
||||||
|
"MySQL was built without a memory barrier capability on this"
|
||||||
|
" architecture, which might allow a mutex/rw_lock violation"
|
||||||
|
" under high thread concurrency. This may cause a hang.");
|
||||||
|
#endif /* IA32 or AMD64 */
|
||||||
|
#endif /* HAVE_MEMORY_BARRIER */
|
||||||
|
|
||||||
ib_logf(IB_LOG_LEVEL_INFO,
|
ib_logf(IB_LOG_LEVEL_INFO,
|
||||||
"Compressed tables use zlib " ZLIB_VERSION
|
"Compressed tables use zlib " ZLIB_VERSION
|
||||||
#ifdef UNIV_ZIP_DEBUG
|
#ifdef UNIV_ZIP_DEBUG
|
||||||
|
@ -2631,13 +2644,6 @@ files_checked:
|
||||||
srv_undo_logs = ULONG_UNDEFINED;
|
srv_undo_logs = ULONG_UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flush the changes made to TRX_SYS_PAGE by trx_sys_create_rsegs()*/
|
|
||||||
if (!srv_force_recovery && !srv_read_only_mode) {
|
|
||||||
bool success = buf_flush_list(ULINT_MAX, LSN_MAX, NULL);
|
|
||||||
ut_a(success);
|
|
||||||
buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!srv_read_only_mode) {
|
if (!srv_read_only_mode) {
|
||||||
/* Create the thread which watches the timeouts
|
/* Create the thread which watches the timeouts
|
||||||
for lock waits */
|
for lock waits */
|
||||||
|
|
|
@ -749,6 +749,7 @@ sync_arr_cell_can_wake_up(
|
||||||
|
|
||||||
mutex = static_cast<ib_mutex_t*>(cell->wait_object);
|
mutex = static_cast<ib_mutex_t*>(cell->wait_object);
|
||||||
|
|
||||||
|
os_rmb;
|
||||||
if (mutex_get_lock_word(mutex) == 0) {
|
if (mutex_get_lock_word(mutex) == 0) {
|
||||||
|
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
|
@ -758,7 +759,7 @@ sync_arr_cell_can_wake_up(
|
||||||
|
|
||||||
lock = static_cast<rw_lock_t*>(cell->wait_object);
|
lock = static_cast<rw_lock_t*>(cell->wait_object);
|
||||||
|
|
||||||
os_rmb;
|
os_rmb;
|
||||||
if (lock->lock_word > 0) {
|
if (lock->lock_word > 0) {
|
||||||
/* Either unlocked or only read locked. */
|
/* Either unlocked or only read locked. */
|
||||||
|
|
||||||
|
@ -770,7 +771,7 @@ sync_arr_cell_can_wake_up(
|
||||||
lock = static_cast<rw_lock_t*>(cell->wait_object);
|
lock = static_cast<rw_lock_t*>(cell->wait_object);
|
||||||
|
|
||||||
/* lock_word == 0 means all readers have left */
|
/* lock_word == 0 means all readers have left */
|
||||||
os_rmb;
|
os_rmb;
|
||||||
if (lock->lock_word == 0) {
|
if (lock->lock_word == 0) {
|
||||||
|
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
|
@ -779,7 +780,7 @@ sync_arr_cell_can_wake_up(
|
||||||
lock = static_cast<rw_lock_t*>(cell->wait_object);
|
lock = static_cast<rw_lock_t*>(cell->wait_object);
|
||||||
|
|
||||||
/* lock_word > 0 means no writer or reserved writer */
|
/* lock_word > 0 means no writer or reserved writer */
|
||||||
os_rmb;
|
os_rmb;
|
||||||
if (lock->lock_word > 0) {
|
if (lock->lock_word > 0) {
|
||||||
|
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
|
|
|
@ -388,7 +388,7 @@ lock_loop:
|
||||||
}
|
}
|
||||||
|
|
||||||
HMT_medium();
|
HMT_medium();
|
||||||
if (lock->lock_word <= 0) {
|
if (i >= SYNC_SPIN_ROUNDS) {
|
||||||
os_thread_yield();
|
os_thread_yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -475,9 +475,9 @@ rw_lock_x_lock_wait(
|
||||||
|
|
||||||
counter_index = (size_t) os_thread_get_curr_id();
|
counter_index = (size_t) os_thread_get_curr_id();
|
||||||
|
|
||||||
|
os_rmb;
|
||||||
ut_ad(lock->lock_word <= 0);
|
ut_ad(lock->lock_word <= 0);
|
||||||
|
|
||||||
os_rmb;
|
|
||||||
HMT_low();
|
HMT_low();
|
||||||
while (lock->lock_word < 0) {
|
while (lock->lock_word < 0) {
|
||||||
if (srv_spin_wait_delay) {
|
if (srv_spin_wait_delay) {
|
||||||
|
@ -564,8 +564,11 @@ rw_lock_x_lock_low(
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
os_thread_id_t thread_id = os_thread_get_curr_id();
|
os_thread_id_t thread_id = os_thread_get_curr_id();
|
||||||
if (!pass)
|
|
||||||
|
if (!pass) {
|
||||||
os_rmb;
|
os_rmb;
|
||||||
|
}
|
||||||
|
|
||||||
/* Decrement failed: relock or failed lock */
|
/* Decrement failed: relock or failed lock */
|
||||||
if (!pass && lock->recursive
|
if (!pass && lock->recursive
|
||||||
&& os_thread_eq(lock->writer_thread, thread_id)) {
|
&& os_thread_eq(lock->writer_thread, thread_id)) {
|
||||||
|
@ -657,7 +660,7 @@ lock_loop:
|
||||||
os_rmb;
|
os_rmb;
|
||||||
}
|
}
|
||||||
HMT_medium();
|
HMT_medium();
|
||||||
if (i == SYNC_SPIN_ROUNDS) {
|
if (i >= SYNC_SPIN_ROUNDS) {
|
||||||
os_thread_yield();
|
os_thread_yield();
|
||||||
} else {
|
} else {
|
||||||
goto lock_loop;
|
goto lock_loop;
|
||||||
|
|
|
@ -127,7 +127,7 @@ it and did not see the waiters byte set to 1, a case which would lead the
|
||||||
other thread to an infinite wait.
|
other thread to an infinite wait.
|
||||||
|
|
||||||
LEMMA 1: After a thread resets the event of a mutex (or rw_lock), some
|
LEMMA 1: After a thread resets the event of a mutex (or rw_lock), some
|
||||||
=======
|
======
|
||||||
thread will eventually call os_event_set() on that particular event.
|
thread will eventually call os_event_set() on that particular event.
|
||||||
Thus no infinite wait is possible in this case.
|
Thus no infinite wait is possible in this case.
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ os_event_set() with the mutex as an argument.
|
||||||
Q.E.D.
|
Q.E.D.
|
||||||
|
|
||||||
LEMMA 2: If an os_event_set() call is made after some thread has called
|
LEMMA 2: If an os_event_set() call is made after some thread has called
|
||||||
=======
|
======
|
||||||
the os_event_reset() and before it starts wait on that event, the call
|
the os_event_reset() and before it starts wait on that event, the call
|
||||||
will not be lost to the second thread. This is true even if there is an
|
will not be lost to the second thread. This is true even if there is an
|
||||||
intervening call to os_event_reset() by another thread.
|
intervening call to os_event_reset() by another thread.
|
||||||
|
@ -504,16 +504,16 @@ mutex_loop:
|
||||||
spin_loop:
|
spin_loop:
|
||||||
|
|
||||||
HMT_low();
|
HMT_low();
|
||||||
|
os_rmb;
|
||||||
while (mutex_get_lock_word(mutex) != 0 && i < SYNC_SPIN_ROUNDS) {
|
while (mutex_get_lock_word(mutex) != 0 && i < SYNC_SPIN_ROUNDS) {
|
||||||
if (srv_spin_wait_delay) {
|
if (srv_spin_wait_delay) {
|
||||||
ut_delay(ut_rnd_interval(0, srv_spin_wait_delay));
|
ut_delay(ut_rnd_interval(0, srv_spin_wait_delay));
|
||||||
}
|
}
|
||||||
os_rmb; // Ensure future reads sees new values
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
HMT_medium();
|
HMT_medium();
|
||||||
|
|
||||||
if (i == SYNC_SPIN_ROUNDS) {
|
if (i >= SYNC_SPIN_ROUNDS) {
|
||||||
os_thread_yield();
|
os_thread_yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -952,7 +952,7 @@ trx_sys_print_mysql_binlog_offset_from_page(
|
||||||
== TRX_SYS_MYSQL_LOG_MAGIC_N) {
|
== TRX_SYS_MYSQL_LOG_MAGIC_N) {
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"ibbackup: Last MySQL binlog file position %lu %lu,"
|
"mysqlbackup: Last MySQL binlog file position %lu %lu,"
|
||||||
" file name %s\n",
|
" file name %s\n",
|
||||||
(ulong) mach_read_from_4(
|
(ulong) mach_read_from_4(
|
||||||
sys_header + TRX_SYS_MYSQL_LOG_INFO
|
sys_header + TRX_SYS_MYSQL_LOG_INFO
|
||||||
|
@ -1003,9 +1003,9 @@ trx_sys_read_file_format_id(
|
||||||
ut_print_timestamp(stderr);
|
ut_print_timestamp(stderr);
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
" ibbackup: Error: trying to read system tablespace "
|
" mysqlbackup: Error: trying to read system "
|
||||||
"file format,\n"
|
"tablespace file format,\n"
|
||||||
" ibbackup: but could not open the tablespace "
|
" mysqlbackup: but could not open the tablespace "
|
||||||
"file %s!\n", pathname);
|
"file %s!\n", pathname);
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
@ -1022,9 +1022,9 @@ trx_sys_read_file_format_id(
|
||||||
ut_print_timestamp(stderr);
|
ut_print_timestamp(stderr);
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
" ibbackup: Error: trying to read system tablespace "
|
" mysqlbackup: Error: trying to read system "
|
||||||
"file format,\n"
|
"tablespace file format,\n"
|
||||||
" ibbackup: but failed to read the tablespace "
|
" mysqlbackup: but failed to read the tablespace "
|
||||||
"file %s!\n", pathname);
|
"file %s!\n", pathname);
|
||||||
|
|
||||||
os_file_close(file);
|
os_file_close(file);
|
||||||
|
@ -1083,9 +1083,9 @@ trx_sys_read_pertable_file_format_id(
|
||||||
ut_print_timestamp(stderr);
|
ut_print_timestamp(stderr);
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
" ibbackup: Error: trying to read per-table "
|
" mysqlbackup: Error: trying to read per-table "
|
||||||
"tablespace format,\n"
|
"tablespace format,\n"
|
||||||
" ibbackup: but could not open the tablespace "
|
" mysqlbackup: but could not open the tablespace "
|
||||||
"file %s!\n", pathname);
|
"file %s!\n", pathname);
|
||||||
|
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
|
@ -1102,9 +1102,9 @@ trx_sys_read_pertable_file_format_id(
|
||||||
ut_print_timestamp(stderr);
|
ut_print_timestamp(stderr);
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
" ibbackup: Error: trying to per-table data file "
|
" mysqlbackup: Error: trying to per-table data file "
|
||||||
"format,\n"
|
"format,\n"
|
||||||
" ibbackup: but failed to read the tablespace "
|
" mysqlbackup: but failed to read the tablespace "
|
||||||
"file %s!\n", pathname);
|
"file %s!\n", pathname);
|
||||||
|
|
||||||
os_file_close(file);
|
os_file_close(file);
|
||||||
|
|
Loading…
Reference in a new issue