Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
c4dcfb60
Commit
c4dcfb60
authored
Apr 26, 2016
by
Sergei Golubchik
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'merge-innodb-5.6' into 10.0
5.6.30
parents
872649c7
f1aae861
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
355 additions
and
130 deletions
+355
-130
storage/innobase/fil/fil0fil.cc
storage/innobase/fil/fil0fil.cc
+25
-12
storage/innobase/fts/fts0fts.cc
storage/innobase/fts/fts0fts.cc
+207
-59
storage/innobase/fts/fts0opt.cc
storage/innobase/fts/fts0opt.cc
+60
-21
storage/innobase/handler/ha_innodb.cc
storage/innobase/handler/ha_innodb.cc
+12
-2
storage/innobase/include/fts0fts.h
storage/innobase/include/fts0fts.h
+17
-7
storage/innobase/include/fts0types.h
storage/innobase/include/fts0types.h
+7
-3
storage/innobase/include/os0sync.h
storage/innobase/include/os0sync.h
+23
-23
storage/innobase/include/univ.i
storage/innobase/include/univ.i
+1
-1
storage/innobase/row/row0merge.cc
storage/innobase/row/row0merge.cc
+3
-2
No files found.
storage/innobase/fil/fil0fil.cc
View file @
c4dcfb60
/*****************************************************************************
/*****************************************************************************
Copyright (c) 1995, 201
5
, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1995, 201
6
, 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
...
@@ -3047,8 +3047,6 @@ fil_create_link_file(
...
@@ -3047,8 +3047,6 @@ fil_create_link_file(
const
char
*
tablename
,
/*!< in: tablename */
const
char
*
tablename
,
/*!< in: tablename */
const
char
*
filepath
)
/*!< in: pathname of tablespace */
const
char
*
filepath
)
/*!< in: pathname of tablespace */
{
{
os_file_t
file
;
ibool
success
;
dberr_t
err
=
DB_SUCCESS
;
dberr_t
err
=
DB_SUCCESS
;
char
*
link_filepath
;
char
*
link_filepath
;
char
*
prev_filepath
=
fil_read_link_file
(
tablename
);
char
*
prev_filepath
=
fil_read_link_file
(
tablename
);
...
@@ -3067,13 +3065,24 @@ fil_create_link_file(
...
@@ -3067,13 +3065,24 @@ fil_create_link_file(
link_filepath
=
fil_make_isl_name
(
tablename
);
link_filepath
=
fil_make_isl_name
(
tablename
);
file
=
os_file_create_simple_no_error_handling
(
/** Check if the file already exists. */
innodb_file_data_key
,
link_filepath
,
FILE
*
file
=
NULL
;
OS_FILE_CREATE
,
OS_FILE_READ_WRITE
,
&
success
);
ibool
exists
;
os_file_type_t
ftype
;
if
(
!
success
)
{
bool
success
=
os_file_status
(
link_filepath
,
&
exists
,
&
ftype
);
/* The following call will print an error message */
ulint
error
=
os_file_get_last_error
(
true
);
ulint
error
=
0
;
if
(
success
&&
!
exists
)
{
file
=
fopen
(
link_filepath
,
"w"
);
if
(
file
==
NULL
)
{
/* This call will print its own error message */
error
=
os_file_get_last_error
(
true
);
}
}
else
{
error
=
OS_FILE_ALREADY_EXISTS
;
}
if
(
error
!=
0
)
{
ut_print_timestamp
(
stderr
);
ut_print_timestamp
(
stderr
);
fputs
(
" InnoDB: Cannot create file "
,
stderr
);
fputs
(
" InnoDB: Cannot create file "
,
stderr
);
...
@@ -3098,13 +3107,17 @@ fil_create_link_file(
...
@@ -3098,13 +3107,17 @@ fil_create_link_file(
return
(
err
);
return
(
err
);
}
}
if
(
!
os_file_write
(
link_filepath
,
file
,
filepath
,
0
,
ulint
rbytes
=
fwrite
(
filepath
,
1
,
strlen
(
filepath
),
file
);
strlen
(
filepath
)))
{
if
(
rbytes
!=
strlen
(
filepath
))
{
os_file_get_last_error
(
true
);
ib_logf
(
IB_LOG_LEVEL_ERROR
,
"cannot write link file "
"%s"
,
filepath
);
err
=
DB_ERROR
;
err
=
DB_ERROR
;
}
}
/* Close the file, we only need it at startup */
/* Close the file, we only need it at startup */
os_file_
close
(
file
);
f
close
(
file
);
mem_free
(
link_filepath
);
mem_free
(
link_filepath
);
...
...
storage/innobase/fts/fts0fts.cc
View file @
c4dcfb60
/*****************************************************************************
/*****************************************************************************
Copyright (c) 2011, 201
5
, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2011, 201
6
, 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
...
@@ -260,16 +260,18 @@ static const char* fts_config_table_insert_values_sql =
...
@@ -260,16 +260,18 @@ static const char* fts_config_table_insert_values_sql =
"INSERT INTO
\"
%s
\"
VALUES ('"
"INSERT INTO
\"
%s
\"
VALUES ('"
FTS_TABLE_STATE
"', '0');
\n
"
;
FTS_TABLE_STATE
"', '0');
\n
"
;
/****************************************************************//**
/** Run SYNC on the table, i.e., write out data from the cache to the
Run SYNC on the table, i.e., write out data from the cache to the
FTS auxiliary INDEX table and clear the cache at the end.
FTS auxiliary INDEX table and clear the cache at the end.
@return DB_SUCCESS if all OK */
@param[in,out] sync sync state
@param[in] unlock_cache whether unlock cache lock when write node
@param[in] wait whether wait when a sync is in progress
@return DB_SUCCESS if all OK */
static
static
dberr_t
dberr_t
fts_sync
(
fts_sync
(
/*=====*/
fts_sync_t
*
sync
,
fts_sync_t
*
sync
)
/*!< in: sync state */
bool
unlock_cache
,
__attribute__
((
nonnull
)
);
bool
wait
);
/****************************************************************//**
/****************************************************************//**
Release all resources help by the words rb tree e.g., the node ilist. */
Release all resources help by the words rb tree e.g., the node ilist. */
...
@@ -653,6 +655,7 @@ fts_cache_create(
...
@@ -653,6 +655,7 @@ fts_cache_create(
mem_heap_zalloc
(
heap
,
sizeof
(
fts_sync_t
)));
mem_heap_zalloc
(
heap
,
sizeof
(
fts_sync_t
)));
cache
->
sync
->
table
=
table
;
cache
->
sync
->
table
=
table
;
cache
->
sync
->
event
=
os_event_create
();
/* Create the index cache vector that will hold the inverted indexes. */
/* Create the index cache vector that will hold the inverted indexes. */
cache
->
indexes
=
ib_vector_create
(
cache
->
indexes
=
ib_vector_create
(
...
@@ -1207,6 +1210,7 @@ fts_cache_destroy(
...
@@ -1207,6 +1210,7 @@ fts_cache_destroy(
mutex_free
(
&
cache
->
optimize_lock
);
mutex_free
(
&
cache
->
optimize_lock
);
mutex_free
(
&
cache
->
deleted_lock
);
mutex_free
(
&
cache
->
deleted_lock
);
mutex_free
(
&
cache
->
doc_id_lock
);
mutex_free
(
&
cache
->
doc_id_lock
);
os_event_free
(
cache
->
sync
->
event
);
if
(
cache
->
stopword_info
.
cached_stopword
)
{
if
(
cache
->
stopword_info
.
cached_stopword
)
{
rbt_free
(
cache
->
stopword_info
.
cached_stopword
);
rbt_free
(
cache
->
stopword_info
.
cached_stopword
);
...
@@ -1435,7 +1439,7 @@ fts_cache_add_doc(
...
@@ -1435,7 +1439,7 @@ fts_cache_add_doc(
ib_vector_last
(
word
->
nodes
));
ib_vector_last
(
word
->
nodes
));
}
}
if
(
fts_node
==
NULL
if
(
fts_node
==
NULL
||
fts_node
->
synced
||
fts_node
->
ilist_size
>
FTS_ILIST_MAX_SIZE
||
fts_node
->
ilist_size
>
FTS_ILIST_MAX_SIZE
||
doc_id
<
fts_node
->
last_doc_id
)
{
||
doc_id
<
fts_node
->
last_doc_id
)
{
...
@@ -2886,35 +2890,28 @@ fts_doc_ids_free(
...
@@ -2886,35 +2890,28 @@ fts_doc_ids_free(
}
}
/*********************************************************************//**
/*********************************************************************//**
Do commit-phase steps necessary for the insertion of a new row.
Do commit-phase steps necessary for the insertion of a new row. */
@return DB_SUCCESS or error code */
void
static
__attribute__
((
nonnull
,
warn_unused_result
))
dberr_t
fts_add
(
fts_add
(
/*====*/
/*====*/
fts_trx_table_t
*
ftt
,
/*!< in: FTS trx table */
fts_trx_table_t
*
ftt
,
/*!< in: FTS trx table */
fts_trx_row_t
*
row
)
/*!< in: row */
fts_trx_row_t
*
row
)
/*!< in: row */
{
{
dict_table_t
*
table
=
ftt
->
table
;
dict_table_t
*
table
=
ftt
->
table
;
dberr_t
error
=
DB_SUCCESS
;
doc_id_t
doc_id
=
row
->
doc_id
;
doc_id_t
doc_id
=
row
->
doc_id
;
ut_a
(
row
->
state
==
FTS_INSERT
||
row
->
state
==
FTS_MODIFY
);
ut_a
(
row
->
state
==
FTS_INSERT
||
row
->
state
==
FTS_MODIFY
);
fts_add_doc_by_id
(
ftt
,
doc_id
,
row
->
fts_indexes
);
fts_add_doc_by_id
(
ftt
,
doc_id
,
row
->
fts_indexes
);
if
(
error
==
DB_SUCCESS
)
{
mutex_enter
(
&
table
->
fts
->
cache
->
deleted_lock
);
mutex_enter
(
&
table
->
fts
->
cache
->
deleted_lock
);
++
table
->
fts
->
cache
->
added
;
++
table
->
fts
->
cache
->
added
;
mutex_exit
(
&
table
->
fts
->
cache
->
deleted_lock
);
mutex_exit
(
&
table
->
fts
->
cache
->
deleted_lock
);
if
(
!
DICT_TF2_FLAG_IS_SET
(
table
,
DICT_TF2_FTS_HAS_DOC_ID
)
if
(
!
DICT_TF2_FLAG_IS_SET
(
table
,
DICT_TF2_FTS_HAS_DOC_ID
)
&&
doc_id
>=
table
->
fts
->
cache
->
next_doc_id
)
{
&&
doc_id
>=
table
->
fts
->
cache
->
next_doc_id
)
{
table
->
fts
->
cache
->
next_doc_id
=
doc_id
+
1
;
table
->
fts
->
cache
->
next_doc_id
=
doc_id
+
1
;
}
}
}
return
(
error
);
}
}
/*********************************************************************//**
/*********************************************************************//**
...
@@ -3025,7 +3022,7 @@ fts_modify(
...
@@ -3025,7 +3022,7 @@ fts_modify(
error
=
fts_delete
(
ftt
,
row
);
error
=
fts_delete
(
ftt
,
row
);
if
(
error
==
DB_SUCCESS
)
{
if
(
error
==
DB_SUCCESS
)
{
error
=
fts_add
(
ftt
,
row
);
fts_add
(
ftt
,
row
);
}
}
return
(
error
);
return
(
error
);
...
@@ -3114,7 +3111,7 @@ fts_commit_table(
...
@@ -3114,7 +3111,7 @@ fts_commit_table(
switch
(
row
->
state
)
{
switch
(
row
->
state
)
{
case
FTS_INSERT
:
case
FTS_INSERT
:
error
=
fts_add
(
ftt
,
row
);
fts_add
(
ftt
,
row
);
break
;
break
;
case
FTS_MODIFY
:
case
FTS_MODIFY
:
...
@@ -3554,16 +3551,34 @@ fts_add_doc_by_id(
...
@@ -3554,16 +3551,34 @@ fts_add_doc_by_id(
get_doc
->
index_cache
,
get_doc
->
index_cache
,
doc_id
,
doc
.
tokens
);
doc_id
,
doc
.
tokens
);
bool
need_sync
=
false
;
if
((
cache
->
total_size
>
fts_max_cache_size
/
10
||
fts_need_sync
)
&&
!
cache
->
sync
->
in_progress
)
{
need_sync
=
true
;
}
rw_lock_x_unlock
(
&
table
->
fts
->
cache
->
lock
);
rw_lock_x_unlock
(
&
table
->
fts
->
cache
->
lock
);
DBUG_EXECUTE_IF
(
DBUG_EXECUTE_IF
(
"fts_instrument_sync"
,
"fts_instrument_sync"
,
fts_sync
(
cache
->
sync
);
fts_optimize_request_sync_table
(
table
);
os_event_wait
(
cache
->
sync
->
event
);
);
DBUG_EXECUTE_IF
(
"fts_instrument_sync_debug"
,
fts_sync
(
cache
->
sync
,
true
,
true
);
);
);
if
(
cache
->
total_size
>
fts_max_cache_size
DEBUG_SYNC_C
(
"fts_instrument_sync_request"
);
||
fts_need_sync
)
{
DBUG_EXECUTE_IF
(
fts_sync
(
cache
->
sync
);
"fts_instrument_sync_request"
,
fts_optimize_request_sync_table
(
table
);
);
if
(
need_sync
)
{
fts_optimize_request_sync_table
(
table
);
}
}
mtr_start
(
&
mtr
);
mtr_start
(
&
mtr
);
...
@@ -3934,16 +3949,17 @@ fts_sync_add_deleted_cache(
...
@@ -3934,16 +3949,17 @@ fts_sync_add_deleted_cache(
return
(
error
);
return
(
error
);
}
}
/*********************************************************************//**
/** Write the words and ilist to disk.
Write the words and ilist to disk.
@param[in,out] trx transaction
@param[in] index_cache index cache
@param[in] unlock_cache whether unlock cache when write node
@return DB_SUCCESS if all went well else error code */
@return DB_SUCCESS if all went well else error code */
static
__attribute__
((
nonnull
,
warn_unused_result
))
static
__attribute__
((
nonnull
,
warn_unused_result
))
dberr_t
dberr_t
fts_sync_write_words
(
fts_sync_write_words
(
/*=================*/
trx_t
*
trx
,
trx_t
*
trx
,
/*!< in: transaction */
fts_index_cache_t
*
index_cache
,
fts_index_cache_t
*
bool
unlock_cache
)
index_cache
)
/*!< in: index cache */
{
{
fts_table_t
fts_table
;
fts_table_t
fts_table
;
ulint
n_nodes
=
0
;
ulint
n_nodes
=
0
;
...
@@ -3951,8 +3967,8 @@ fts_sync_write_words(
...
@@ -3951,8 +3967,8 @@ fts_sync_write_words(
const
ib_rbt_node_t
*
rbt_node
;
const
ib_rbt_node_t
*
rbt_node
;
dberr_t
error
=
DB_SUCCESS
;
dberr_t
error
=
DB_SUCCESS
;
ibool
print_error
=
FALSE
;
ibool
print_error
=
FALSE
;
#ifdef FTS_DOC_STATS_DEBUG
dict_table_t
*
table
=
index_cache
->
index
->
table
;
dict_table_t
*
table
=
index_cache
->
index
->
table
;
#ifdef FTS_DOC_STATS_DEBUG
ulint
n_new_words
=
0
;
ulint
n_new_words
=
0
;
#endif
/* FTS_DOC_STATS_DEBUG */
#endif
/* FTS_DOC_STATS_DEBUG */
...
@@ -3965,7 +3981,7 @@ fts_sync_write_words(
...
@@ -3965,7 +3981,7 @@ fts_sync_write_words(
since we want to free the memory used during caching. */
since we want to free the memory used during caching. */
for
(
rbt_node
=
rbt_first
(
index_cache
->
words
);
for
(
rbt_node
=
rbt_first
(
index_cache
->
words
);
rbt_node
;
rbt_node
;
rbt_node
=
rbt_
first
(
index_cache
->
words
))
{
rbt_node
=
rbt_
next
(
index_cache
->
words
,
rbt_node
))
{
ulint
i
;
ulint
i
;
ulint
selected
;
ulint
selected
;
...
@@ -3998,27 +4014,47 @@ fts_sync_write_words(
...
@@ -3998,27 +4014,47 @@ fts_sync_write_words(
}
}
#endif
/* FTS_DOC_STATS_DEBUG */
#endif
/* FTS_DOC_STATS_DEBUG */
n_nodes
+=
ib_vector_size
(
word
->
nodes
);
/* We iterate over all the nodes even if there was an error */
/* We iterate over all the nodes even if there was an error,
this is to free the memory of the fts_node_t elements. */
for
(
i
=
0
;
i
<
ib_vector_size
(
word
->
nodes
);
++
i
)
{
for
(
i
=
0
;
i
<
ib_vector_size
(
word
->
nodes
);
++
i
)
{
fts_node_t
*
fts_node
=
static_cast
<
fts_node_t
*>
(
fts_node_t
*
fts_node
=
static_cast
<
fts_node_t
*>
(
ib_vector_get
(
word
->
nodes
,
i
));
ib_vector_get
(
word
->
nodes
,
i
));
if
(
fts_node
->
synced
)
{
continue
;
}
else
{
fts_node
->
synced
=
true
;
}
/*FIXME: we need to handle the error properly. */
if
(
error
==
DB_SUCCESS
)
{
if
(
error
==
DB_SUCCESS
)
{
if
(
unlock_cache
)
{
rw_lock_x_unlock
(
&
table
->
fts
->
cache
->
lock
);
}
error
=
fts_write_node
(
error
=
fts_write_node
(
trx
,
trx
,
&
index_cache
->
ins_graph
[
selected
],
&
index_cache
->
ins_graph
[
selected
],
&
fts_table
,
&
word
->
text
,
fts_node
);
&
fts_table
,
&
word
->
text
,
fts_node
);
}
ut_free
(
fts_node
->
ilist
);
DEBUG_SYNC_C
(
"fts_write_node"
);
fts_node
->
ilist
=
NULL
;
DBUG_EXECUTE_IF
(
"fts_write_node_crash"
,
DBUG_SUICIDE
(););
DBUG_EXECUTE_IF
(
"fts_instrument_sync_sleep"
,
os_thread_sleep
(
1000000
);
);
if
(
unlock_cache
)
{
rw_lock_x_lock
(
&
table
->
fts
->
cache
->
lock
);
}
}
}
}
n_nodes
+=
ib_vector_size
(
word
->
nodes
);
if
(
error
!=
DB_SUCCESS
&&
!
print_error
)
{
if
(
error
!=
DB_SUCCESS
&&
!
print_error
)
{
ut_print_timestamp
(
stderr
);
ut_print_timestamp
(
stderr
);
fprintf
(
stderr
,
" InnoDB: Error (%s) writing "
fprintf
(
stderr
,
" InnoDB: Error (%s) writing "
...
@@ -4027,9 +4063,6 @@ fts_sync_write_words(
...
@@ -4027,9 +4063,6 @@ fts_sync_write_words(
print_error
=
TRUE
;
print_error
=
TRUE
;
}
}
/* NOTE: We are responsible for free'ing the node */
ut_free
(
rbt_remove_node
(
index_cache
->
words
,
rbt_node
));
}
}
#ifdef FTS_DOC_STATS_DEBUG
#ifdef FTS_DOC_STATS_DEBUG
...
@@ -4330,7 +4363,7 @@ fts_sync_index(
...
@@ -4330,7 +4363,7 @@ fts_sync_index(
ut_ad
(
rbt_validate
(
index_cache
->
words
));
ut_ad
(
rbt_validate
(
index_cache
->
words
));
error
=
fts_sync_write_words
(
trx
,
index
_cache
);
error
=
fts_sync_write_words
(
sync
->
trx
,
index_cache
,
sync
->
unlock
_cache
);
#ifdef FTS_DOC_STATS_DEBUG
#ifdef FTS_DOC_STATS_DEBUG
/* FTS_RESOLVE: the word counter info in auxiliary table "DOC_ID"
/* FTS_RESOLVE: the word counter info in auxiliary table "DOC_ID"
...
@@ -4346,6 +4379,36 @@ fts_sync_index(
...
@@ -4346,6 +4379,36 @@ fts_sync_index(
return
(
error
);
return
(
error
);
}
}
/** Check if index cache has been synced completely
@param[in,out] sync sync state
@param[in,out] index_cache index cache
@return true if index is synced, otherwise false. */
static
bool
fts_sync_index_check
(
fts_sync_t
*
sync
,
fts_index_cache_t
*
index_cache
)
{
const
ib_rbt_node_t
*
rbt_node
;
for
(
rbt_node
=
rbt_first
(
index_cache
->
words
);
rbt_node
!=
NULL
;
rbt_node
=
rbt_next
(
index_cache
->
words
,
rbt_node
))
{
fts_tokenizer_word_t
*
word
;
word
=
rbt_value
(
fts_tokenizer_word_t
,
rbt_node
);
fts_node_t
*
fts_node
;
fts_node
=
static_cast
<
fts_node_t
*>
(
ib_vector_last
(
word
->
nodes
));
if
(
!
fts_node
->
synced
)
{
return
(
false
);
}
}
return
(
true
);
}
/*********************************************************************//**
/*********************************************************************//**
Commit the SYNC, change state of processed doc ids etc.
Commit the SYNC, change state of processed doc ids etc.
@return DB_SUCCESS if all OK */
@return DB_SUCCESS if all OK */
...
@@ -4422,21 +4485,53 @@ fts_sync_rollback(
...
@@ -4422,21 +4485,53 @@ fts_sync_rollback(
trx_t
*
trx
=
sync
->
trx
;
trx_t
*
trx
=
sync
->
trx
;
fts_cache_t
*
cache
=
sync
->
table
->
fts
->
cache
;
fts_cache_t
*
cache
=
sync
->
table
->
fts
->
cache
;
for
(
ulint
i
=
0
;
i
<
ib_vector_size
(
cache
->
indexes
);
++
i
)
{
ulint
j
;
fts_index_cache_t
*
index_cache
;
index_cache
=
static_cast
<
fts_index_cache_t
*>
(
ib_vector_get
(
cache
->
indexes
,
i
));
for
(
j
=
0
;
fts_index_selector
[
j
].
value
;
++
j
)
{
if
(
index_cache
->
ins_graph
[
j
]
!=
NULL
)
{
fts_que_graph_free_check_lock
(
NULL
,
index_cache
,
index_cache
->
ins_graph
[
j
]);
index_cache
->
ins_graph
[
j
]
=
NULL
;
}
if
(
index_cache
->
sel_graph
[
j
]
!=
NULL
)
{
fts_que_graph_free_check_lock
(
NULL
,
index_cache
,
index_cache
->
sel_graph
[
j
]);
index_cache
->
sel_graph
[
j
]
=
NULL
;
}
}
}
rw_lock_x_unlock
(
&
cache
->
lock
);
rw_lock_x_unlock
(
&
cache
->
lock
);
fts_sql_rollback
(
trx
);
fts_sql_rollback
(
trx
);
trx_free_for_background
(
trx
);
trx_free_for_background
(
trx
);
}
}
/****************************************************************//**
/** Run SYNC on the table, i.e., write out data from the cache to the
Run SYNC on the table, i.e., write out data from the cache to the
FTS auxiliary INDEX table and clear the cache at the end.
FTS auxiliary INDEX table and clear the cache at the end.
@param[in,out] sync sync state
@param[in] unlock_cache whether unlock cache lock when write node
@param[in] wait whether wait when a sync is in progress
@return DB_SUCCESS if all OK */
@return DB_SUCCESS if all OK */
static
static
dberr_t
dberr_t
fts_sync
(
fts_sync
(
/*=====*/
fts_sync_t
*
sync
,
fts_sync_t
*
sync
)
/*!< in: sync state */
bool
unlock_cache
,
bool
wait
)
{
{
ulint
i
;
ulint
i
;
dberr_t
error
=
DB_SUCCESS
;
dberr_t
error
=
DB_SUCCESS
;
...
@@ -4444,8 +4539,35 @@ fts_sync(
...
@@ -4444,8 +4539,35 @@ fts_sync(
rw_lock_x_lock
(
&
cache
->
lock
);
rw_lock_x_lock
(
&
cache
->
lock
);
/* Check if cache is being synced.
Note: we release cache lock in fts_sync_write_words() to
avoid long wait for the lock by other threads. */
while
(
sync
->
in_progress
)
{
rw_lock_x_unlock
(
&
cache
->
lock
);
if
(
wait
)
{
os_event_wait
(
sync
->
event
);
}
else
{
return
(
DB_SUCCESS
);
}
rw_lock_x_lock
(
&
cache
->
lock
);
}
sync
->
unlock_cache
=
unlock_cache
;
sync
->
in_progress
=
true
;
DEBUG_SYNC_C
(
"fts_sync_begin"
);
fts_sync_begin
(
sync
);
fts_sync_begin
(
sync
);
begin_sync:
if
(
cache
->
total_size
>
fts_max_cache_size
)
{
/* Avoid the case: sync never finish when
insert/update keeps comming. */
ut_ad
(
sync
->
unlock_cache
);
sync
->
unlock_cache
=
false
;
}
for
(
i
=
0
;
i
<
ib_vector_size
(
cache
->
indexes
);
++
i
)
{
for
(
i
=
0
;
i
<
ib_vector_size
(
cache
->
indexes
);
++
i
)
{
fts_index_cache_t
*
index_cache
;
fts_index_cache_t
*
index_cache
;
...
@@ -4460,21 +4582,43 @@ fts_sync(
...
@@ -4460,21 +4582,43 @@ fts_sync(
if
(
error
!=
DB_SUCCESS
&&
!
sync
->
interrupted
)
{
if
(
error
!=
DB_SUCCESS
&&
!
sync
->
interrupted
)
{
break
;
goto
end_sync
;
}
}
}
}
DBUG_EXECUTE_IF
(
"fts_instrument_sync_interrupted"
,
DBUG_EXECUTE_IF
(
"fts_instrument_sync_interrupted"
,
sync
->
interrupted
=
true
;
sync
->
interrupted
=
true
;
error
=
DB_INTERRUPTED
;
error
=
DB_INTERRUPTED
;
goto
end_sync
;
);
);
/* Make sure all the caches are synced. */
for
(
i
=
0
;
i
<
ib_vector_size
(
cache
->
indexes
);
++
i
)
{
fts_index_cache_t
*
index_cache
;
index_cache
=
static_cast
<
fts_index_cache_t
*>
(
ib_vector_get
(
cache
->
indexes
,
i
));
if
(
index_cache
->
index
->
to_be_dropped
||
fts_sync_index_check
(
sync
,
index_cache
))
{
continue
;
}
goto
begin_sync
;
}
end_sync:
if
(
error
==
DB_SUCCESS
&&
!
sync
->
interrupted
)
{
if
(
error
==
DB_SUCCESS
&&
!
sync
->
interrupted
)
{
error
=
fts_sync_commit
(
sync
);
error
=
fts_sync_commit
(
sync
);
}
else
{
}
else
{
fts_sync_rollback
(
sync
);
fts_sync_rollback
(
sync
);
}
}
rw_lock_x_lock
(
&
cache
->
lock
);
sync
->
in_progress
=
false
;
os_event_set
(
sync
->
event
);
rw_lock_x_unlock
(
&
cache
->
lock
);
/* We need to check whether an optimize is required, for that
/* We need to check whether an optimize is required, for that
we make copies of the two variables that control the trigger. These
we make copies of the two variables that control the trigger. These
variables can change behind our back and we don't want to hold the
variables can change behind our back and we don't want to hold the
...
@@ -4489,21 +4633,25 @@ fts_sync(
...
@@ -4489,21 +4633,25 @@ fts_sync(
return
(
error
);
return
(
error
);
}
}
/****************************************************************//**
/** Run SYNC on the table, i.e., write out data from the cache to the
Run SYNC on the table, i.e., write out data from the cache to the
FTS auxiliary INDEX table and clear the cache at the end.
FTS auxiliary INDEX table and clear the cache at the end. */
@param[in,out] table fts table
@param[in] unlock_cache whether unlock cache when write node
@param[in] wait whether wait for existing sync to finish
@return DB_SUCCESS on success, error code on failure. */
UNIV_INTERN
UNIV_INTERN
dberr_t
dberr_t
fts_sync_table
(
fts_sync_table
(
/*===========*/
dict_table_t
*
table
,
dict_table_t
*
table
)
/*!< in: table */
bool
unlock_cache
,
bool
wait
)
{
{
dberr_t
err
=
DB_SUCCESS
;
dberr_t
err
=
DB_SUCCESS
;
ut_ad
(
table
->
fts
);
ut_ad
(
table
->
fts
);
if
(
!
dict_table_is_discarded
(
table
)
&&
table
->
fts
->
cache
)
{
if
(
!
dict_table_is_discarded
(
table
)
&&
table
->
fts
->
cache
)
{
err
=
fts_sync
(
table
->
fts
->
cache
->
sync
);
err
=
fts_sync
(
table
->
fts
->
cache
->
sync
,
unlock_cache
,
wait
);
}
}
return
(
err
);
return
(
err
);
...
...
storage/innobase/fts/fts0opt.cc
View file @
c4dcfb60
/*****************************************************************************
/*****************************************************************************
Copyright (c) 2007, 201
5
, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2007, 201
6
, 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
...
@@ -87,6 +87,7 @@ enum fts_msg_type_t {
...
@@ -87,6 +87,7 @@ enum fts_msg_type_t {
FTS_MSG_DEL_TABLE
,
/*!< Remove a table from the optimize
FTS_MSG_DEL_TABLE
,
/*!< Remove a table from the optimize
threads work queue */
threads work queue */
FTS_MSG_SYNC_TABLE
/*!< Sync fts cache of a table */
};
};
/** Compressed list of words that have been read from FTS INDEX
/** Compressed list of words that have been read from FTS INDEX
...
@@ -2652,6 +2653,39 @@ fts_optimize_remove_table(
...
@@ -2652,6 +2653,39 @@ fts_optimize_remove_table(
os_event_free
(
event
);
os_event_free
(
event
);
}
}
/** Send sync fts cache for the table.
@param[in] table table to sync */
UNIV_INTERN
void
fts_optimize_request_sync_table
(
dict_table_t
*
table
)
{
fts_msg_t
*
msg
;
table_id_t
*
table_id
;
/* if the optimize system not yet initialized, return */
if
(
!
fts_optimize_wq
)
{
return
;
}
/* FTS optimizer thread is already exited */
if
(
fts_opt_start_shutdown
)
{
ib_logf
(
IB_LOG_LEVEL_INFO
,
"Try to sync table %s after FTS optimize"
" thread exiting."
,
table
->
name
);
return
;
}
msg
=
fts_optimize_create_msg
(
FTS_MSG_SYNC_TABLE
,
NULL
);
table_id
=
static_cast
<
table_id_t
*>
(
mem_heap_alloc
(
msg
->
heap
,
sizeof
(
table_id_t
)));
*
table_id
=
table
->
id
;
msg
->
ptr
=
table_id
;
ib_wqueue_add
(
fts_optimize_wq
,
msg
,
msg
->
heap
);
}
/**********************************************************************//**
/**********************************************************************//**
Find the slot for a particular table.
Find the slot for a particular table.
@return slot if found else NULL. */
@return slot if found else NULL. */
...
@@ -2932,6 +2966,25 @@ fts_optimize_need_sync(
...
@@ -2932,6 +2966,25 @@ fts_optimize_need_sync(
}
}
#endif
#endif
/** Sync fts cache of a table
@param[in] table_id table id */
void
fts_optimize_sync_table
(
table_id_t
table_id
)
{
dict_table_t
*
table
=
NULL
;
table
=
dict_table_open_on_id
(
table_id
,
FALSE
,
DICT_TABLE_OP_NORMAL
);
if
(
table
)
{
if
(
dict_table_has_fts_index
(
table
)
&&
table
->
fts
->
cache
)
{
fts_sync_table
(
table
,
true
,
false
);
}
dict_table_close
(
table
,
FALSE
,
FALSE
);
}
}
/**********************************************************************//**
/**********************************************************************//**
Optimize all FTS tables.
Optimize all FTS tables.
@return Dummy return */
@return Dummy return */
...
@@ -3053,6 +3106,11 @@ fts_optimize_thread(
...
@@ -3053,6 +3106,11 @@ fts_optimize_thread(
((
fts_msg_del_t
*
)
msg
->
ptr
)
->
event
);
((
fts_msg_del_t
*
)
msg
->
ptr
)
->
event
);
break
;
break
;
case
FTS_MSG_SYNC_TABLE
:
fts_optimize_sync_table
(
*
static_cast
<
table_id_t
*>
(
msg
->
ptr
));
break
;
default:
default:
ut_error
;
ut_error
;
}
}
...
@@ -3079,26 +3137,7 @@ fts_optimize_thread(
...
@@ -3079,26 +3137,7 @@ fts_optimize_thread(
ib_vector_get
(
tables
,
i
));
ib_vector_get
(
tables
,
i
));
if
(
slot
->
state
!=
FTS_STATE_EMPTY
)
{
if
(
slot
->
state
!=
FTS_STATE_EMPTY
)
{
dict_table_t
*
table
=
NULL
;
fts_optimize_sync_table
(
slot
->
table_id
);
/*slot->table may be freed, so we try to open
table by slot->table_id.*/
table
=
dict_table_open_on_id
(
slot
->
table_id
,
FALSE
,
DICT_TABLE_OP_NORMAL
);
if
(
table
)
{
if
(
dict_table_has_fts_index
(
table
))
{
fts_sync_table
(
table
);
}
if
(
table
->
fts
)
{
fts_free
(
table
);
}
dict_table_close
(
table
,
FALSE
,
FALSE
);
}
}
}
}
}
}
}
...
...
storage/innobase/handler/ha_innodb.cc
View file @
c4dcfb60
/*****************************************************************************
/*****************************************************************************
Copyright (c) 2000, 201
5
, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2000, 201
6
, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2012, Facebook Inc.
Copyright (c) 2012, Facebook Inc.
...
@@ -3497,6 +3497,16 @@ innobase_init(
...
@@ -3497,6 +3497,16 @@ innobase_init(
innobase_open_files
=
tc_size
;
innobase_open_files
=
tc_size
;
}
}
}
}
if
(
innobase_open_files
>
(
long
)
open_files_limit
)
{
fprintf
(
stderr
,
"innodb_open_files should not be greater"
" than the open_files_limit.
\n
"
);
if
(
innobase_open_files
>
(
long
)
tc_size
)
{
innobase_open_files
=
tc_size
;
}
}
srv_max_n_open_files
=
(
ulint
)
innobase_open_files
;
srv_max_n_open_files
=
(
ulint
)
innobase_open_files
;
srv_innodb_status
=
(
ibool
)
innobase_create_status_file
;
srv_innodb_status
=
(
ibool
)
innobase_create_status_file
;
...
@@ -11866,7 +11876,7 @@ ha_innobase::optimize(
...
@@ -11866,7 +11876,7 @@ ha_innobase::optimize(
if
(
innodb_optimize_fulltext_only
)
{
if
(
innodb_optimize_fulltext_only
)
{
if
(
prebuilt
->
table
->
fts
&&
prebuilt
->
table
->
fts
->
cache
if
(
prebuilt
->
table
->
fts
&&
prebuilt
->
table
->
fts
->
cache
&&
!
dict_table_is_discarded
(
prebuilt
->
table
))
{
&&
!
dict_table_is_discarded
(
prebuilt
->
table
))
{
fts_sync_table
(
prebuilt
->
table
);
fts_sync_table
(
prebuilt
->
table
,
false
,
true
);
fts_optimize_table
(
prebuilt
->
table
);
fts_optimize_table
(
prebuilt
->
table
);
}
}
return
(
HA_ADMIN_OK
);
return
(
HA_ADMIN_OK
);
...
...
storage/innobase/include/fts0fts.h
View file @
c4dcfb60
/*****************************************************************************
/*****************************************************************************
Copyright (c) 2011, 201
5
, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2011, 201
6
, 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
...
@@ -724,6 +724,13 @@ fts_optimize_remove_table(
...
@@ -724,6 +724,13 @@ fts_optimize_remove_table(
/*======================*/
/*======================*/
dict_table_t
*
table
);
/*!< in: table to remove */
dict_table_t
*
table
);
/*!< in: table to remove */
/** Send sync fts cache for the table.
@param[in] table table to sync */
UNIV_INTERN
void
fts_optimize_request_sync_table
(
dict_table_t
*
table
);
/**********************************************************************//**
/**********************************************************************//**
Signal the optimize thread to prepare for shutdown. */
Signal the optimize thread to prepare for shutdown. */
UNIV_INTERN
UNIV_INTERN
...
@@ -826,15 +833,18 @@ fts_drop_index_split_tables(
...
@@ -826,15 +833,18 @@ fts_drop_index_split_tables(
dict_index_t
*
index
)
/*!< in: fts instance */
dict_index_t
*
index
)
/*!< in: fts instance */
__attribute__
((
nonnull
,
warn_unused_result
));
__attribute__
((
nonnull
,
warn_unused_result
));
/****************************************************************//**
/** Run SYNC on the table, i.e., write out data from the cache to the
Run SYNC on the table, i.e., write out data from the cache to the
FTS auxiliary INDEX table and clear the cache at the end.
FTS auxiliary INDEX table and clear the cache at the end. */
@param[in,out] table fts table
@param[in] unlock_cache whether unlock cache when write node
@param[in] wait whether wait for existing sync to finish
@return DB_SUCCESS on success, error code on failure. */
UNIV_INTERN
UNIV_INTERN
dberr_t
dberr_t
fts_sync_table
(
fts_sync_table
(
/*===========*/
dict_table_t
*
table
,
dict_table_t
*
table
)
/*!< in: table */
bool
unlock_cache
,
__attribute__
((
nonnull
)
);
bool
wait
);
/****************************************************************//**
/****************************************************************//**
Free the query graph but check whether dict_sys->mutex is already
Free the query graph but check whether dict_sys->mutex is already
...
...
storage/innobase/include/fts0types.h
View file @
c4dcfb60
/*****************************************************************************
/*****************************************************************************
Copyright (c) 2007, 201
1
, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2007, 201
6
, 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
...
@@ -122,7 +122,11 @@ struct fts_sync_t {
...
@@ -122,7 +122,11 @@ struct fts_sync_t {
doc_id_t
max_doc_id
;
/*!< The doc id at which the cache was
doc_id_t
max_doc_id
;
/*!< The doc id at which the cache was
noted as being full, we use this to
noted as being full, we use this to
set the upper_limit field */
set the upper_limit field */
ib_time_t
start_time
;
/*!< SYNC start time */
ib_time_t
start_time
;
/*!< SYNC start time */
bool
in_progress
;
/*!< flag whether sync is in progress.*/
bool
unlock_cache
;
/*!< flag whether unlock cache when
write fts node */
os_event_t
event
;
/*!< sync finish event */
};
};
/** The cache for the FTS system. It is a memory-based inverted index
/** The cache for the FTS system. It is a memory-based inverted index
...
@@ -165,7 +169,6 @@ struct fts_cache_t {
...
@@ -165,7 +169,6 @@ struct fts_cache_t {
objects, they are recreated after
objects, they are recreated after
a SYNC is completed */
a SYNC is completed */
ib_alloc_t
*
self_heap
;
/*!< This heap is the heap out of
ib_alloc_t
*
self_heap
;
/*!< This heap is the heap out of
which an instance of the cache itself
which an instance of the cache itself
was created. Objects created using
was created. Objects created using
...
@@ -212,6 +215,7 @@ struct fts_node_t {
...
@@ -212,6 +215,7 @@ struct fts_node_t {
ulint
ilist_size_alloc
;
ulint
ilist_size_alloc
;
/*!< Allocated size of ilist in
/*!< Allocated size of ilist in
bytes */
bytes */
bool
synced
;
/*!< flag whether the node is synced */
};
};
/** A tokenizer word. Contains information about one word. */
/** A tokenizer word. Contains information about one word. */
...
...
storage/innobase/include/os0sync.h
View file @
c4dcfb60
/*****************************************************************************
/*****************************************************************************
Copyright (c) 1995, 201
5
, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1995, 201
6
, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
Portions of this file contain modifications contributed and copyrighted by
...
@@ -466,28 +466,7 @@ amount to decrement. */
...
@@ -466,28 +466,7 @@ amount to decrement. */
# define os_atomic_decrement_uint64(ptr, amount) \
# define os_atomic_decrement_uint64(ptr, amount) \
os_atomic_decrement(ptr, amount)
os_atomic_decrement(ptr, amount)
# if defined(HAVE_IB_GCC_ATOMIC_TEST_AND_SET)
# if defined(IB_STRONG_MEMORY_MODEL)
/** Do an atomic test-and-set.
@param[in,out] ptr Memory location to set to non-zero
@return the previous value */
inline
lock_word_t
os_atomic_test_and_set
(
volatile
lock_word_t
*
ptr
)
{
return
(
__atomic_test_and_set
(
ptr
,
__ATOMIC_ACQUIRE
));
}
/** Do an atomic clear.
@param[in,out] ptr Memory location to set to zero */
inline
void
os_atomic_clear
(
volatile
lock_word_t
*
ptr
)
{
__atomic_clear
(
ptr
,
__ATOMIC_RELEASE
);
}
# elif defined(HAVE_ATOMIC_BUILTINS)
/** Do an atomic test and set.
/** Do an atomic test and set.
@param[in,out] ptr Memory location to set to non-zero
@param[in,out] ptr Memory location to set to non-zero
...
@@ -516,6 +495,27 @@ os_atomic_clear(volatile lock_word_t* ptr)
...
@@ -516,6 +495,27 @@ os_atomic_clear(volatile lock_word_t* ptr)
return
(
__sync_lock_test_and_set
(
ptr
,
0
));
return
(
__sync_lock_test_and_set
(
ptr
,
0
));
}
}
# elif defined(HAVE_IB_GCC_ATOMIC_TEST_AND_SET)
/** Do an atomic test-and-set.
@param[in,out] ptr Memory location to set to non-zero
@return the previous value */
inline
lock_word_t
os_atomic_test_and_set
(
volatile
lock_word_t
*
ptr
)
{
return
(
__atomic_test_and_set
(
ptr
,
__ATOMIC_ACQUIRE
));
}
/** Do an atomic clear.
@param[in,out] ptr Memory location to set to zero */
inline
void
os_atomic_clear
(
volatile
lock_word_t
*
ptr
)
{
__atomic_clear
(
ptr
,
__ATOMIC_RELEASE
);
}
# else
# else
# error "Unsupported platform"
# error "Unsupported platform"
...
...
storage/innobase/include/univ.i
View file @
c4dcfb60
...
@@ -44,7 +44,7 @@ Created 1/20/1994 Heikki Tuuri
...
@@ -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
29
#
define
INNODB_VERSION_BUGFIX
30
/* 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;
...
...
storage/innobase/row/row0merge.cc
View file @
c4dcfb60
/*****************************************************************************
/*****************************************************************************
Copyright (c) 2005, 201
5
, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2005, 201
6
, 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
...
@@ -1986,7 +1986,8 @@ row_merge_read_clustered_index(
...
@@ -1986,7 +1986,8 @@ row_merge_read_clustered_index(
if
(
max_doc_id
&&
err
==
DB_SUCCESS
)
{
if
(
max_doc_id
&&
err
==
DB_SUCCESS
)
{
/* Sync fts cache for other fts indexes to keep all
/* Sync fts cache for other fts indexes to keep all
fts indexes consistent in sync_doc_id. */
fts indexes consistent in sync_doc_id. */
err
=
fts_sync_table
(
const_cast
<
dict_table_t
*>
(
new_table
));
err
=
fts_sync_table
(
const_cast
<
dict_table_t
*>
(
new_table
),
false
,
true
);
if
(
err
==
DB_SUCCESS
)
{
if
(
err
==
DB_SUCCESS
)
{
fts_update_next_doc_id
(
fts_update_next_doc_id
(
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment