38 #include "fts0types.ic"
46 static const ulint FTS_MAX_DELETE_DOC_IDS = 1000;
49 static const ulint FTS_QUEUE_WAIT_IN_USECS = 5000000;
52 static const ulint FTS_OPTIMIZE_INTERVAL_IN_SECS = 300;
55 static bool fts_opt_start_shutdown =
false;
63 static ulint fts_optimize_sync_iterator = 0;
133 que_t* read_nodes_graph;
238 static ulint FTS_ZIP_BLOCK_SIZE = 1024;
241 static ib_time_t fts_optimize_time_limit = 0;
244 static const char* fts_init_delete_sql =
247 "INSERT INTO %s_BEING_DELETED\n"
248 "SELECT doc_id FROM \"%s_DELETED\";\n"
250 "INSERT INTO %s_BEING_DELETED_CACHE\n"
251 "SELECT doc_id FROM \"%s_DELETED_CACHE\";\n";
253 static const char* fts_delete_doc_ids_sql =
256 "DELETE FROM \"%s_DELETED\" WHERE doc_id = :doc_id1;\n"
257 "DELETE FROM \"%s_DELETED_CACHE\" WHERE doc_id = :doc_id2;\n";
259 static const char* fts_end_delete_sql =
262 "DELETE FROM \"%s_BEING_DELETED\";\n"
263 "DELETE FROM \"%s_BEING_DELETED_CACHE\";\n";
283 ib_vector_reset(zip->
blocks);
285 memset(zip->
zp, 0,
sizeof(*zip->
zp));
308 zip->
heap_alloc = ib_heap_allocator_create(heap);
329 memset(zip->
zp, 0,
sizeof(*zip->
zp));
348 memset(word, 0,
sizeof(*word));
357 word->
heap_alloc = ib_heap_allocator_create(heap);
359 word->
nodes = ib_vector_create(
370 fts_optimize_read_node(
377 ib_vector_push(word->
nodes, NULL));
383 byte* data =
static_cast<byte*
>(
384 dfield_get_data(dfield));
387 ut_a(len != UNIV_SQL_NULL);
406 memcpy(node->
ilist, data, len);
436 void* data = dfield_get_data(dfield);
441 if (ib_vector_size(words) == 0) {
443 word =
static_cast<fts_word_t*
>(ib_vector_push(words, NULL));
447 word =
static_cast<fts_word_t*
>(ib_vector_last(words));
450 || memcmp(word->
text.
f_str, data, dfield_len)) {
452 word =
static_cast<fts_word_t*
>(ib_vector_push(words, NULL));
478 trx->
op_info =
"fetching FTS index nodes";
481 info = (*graph)->info;
502 "DECLARE FUNCTION my_func;\n"
503 "DECLARE CURSOR c IS"
504 " SELECT word, doc_count, first_doc_id, last_doc_id, "
507 " WHERE word LIKE :word\n"
508 " ORDER BY first_doc_id;\n"
513 " FETCH c INTO my_func();\n"
514 " IF c % NOTFOUND THEN\n"
524 if (error == DB_SUCCESS) {
534 fprintf(stderr,
" InnoDB: Warning: lock wait "
535 "timeout reading FTS index. "
540 fprintf(stderr,
" InnoDB: Error: (%s) "
541 "while reading FTS index.\n",
566 byte* ptr = word->
f_str;
567 int flush = Z_NO_FLUSH;
570 if (zip->
status != Z_OK) {
574 zip->
zp->next_out = &len;
575 zip->
zp->avail_out =
sizeof(len);
577 while (zip->
status == Z_OK && zip->
zp->avail_out > 0) {
580 if (zip->
zp->avail_in == 0) {
584 ulint prev = zip->
pos - 1;
593 if (zip->
pos < ib_vector_size(zip->
blocks)) {
595 zip->
zp->next_in =
static_cast<byte*
>(
612 switch (zip->
status = inflate(zip->
zp, flush)) {
614 if (zip->
zp->avail_out == 0 && len > 0) {
619 zip->
zp->next_out = ptr;
620 zip->
zp->avail_out = len;
640 if (zip->
status != Z_OK) {
641 for (i = 0; i < ib_vector_size(zip->
blocks); ++
i) {
642 if (ib_vector_getp(zip->
blocks, i)) {
654 return(zip->
status == Z_OK || zip->
status == Z_STREAM_END ? ptr : NULL);
663 fts_fetch_index_words(
673 void* data = dfield_get_data(dfield);
686 ut_a(zip->
zp->avail_in == 0);
687 ut_a(zip->
zp->next_in == NULL);
690 zip->
zp->next_in = &len;
691 zip->
zp->avail_in =
sizeof(len);
694 while (zip->
zp->avail_in > 0) {
697 if (zip->
zp->avail_out == 0) {
701 ib_vector_push(zip->
blocks, &block);
707 switch (zip->
status = deflate(zip->
zp, Z_NO_FLUSH)) {
709 if (zip->
zp->avail_in == 0) {
710 zip->
zp->next_in =
static_cast<byte*
>(data);
711 zip->
zp->avail_in = len;
727 ut_a(zip->
zp->avail_in == 0);
728 zip->
zp->next_in = NULL;
743 ut_a(zip->
zp->avail_in == 0);
744 ut_a(zip->
zp->next_in == NULL);
746 zip->
status = deflate(zip->
zp, Z_FINISH);
752 while (zip->
status == Z_OK) {
755 ut_a(zip->
zp->avail_out == 0);
758 ib_vector_push(zip->
blocks, &block);
763 zip->
status = deflate(zip->
zp, Z_FINISH);
772 memset(zip->
zp, 0,
sizeof(*zip->
zp));
779 static __attribute__((nonnull, warn_unused_result))
781 fts_index_fetch_words(
794 ibool inited = FALSE;
796 optim->trx->op_info =
"fetching FTS index words";
798 if (optim->zip == NULL) {
799 optim->zip = fts_zip_create(heap, FTS_ZIP_BLOCK_SIZE, n_words);
801 fts_zip_initialize(optim->zip);
805 optim->fts_index_table.charset, word->f_str, word->f_len);
812 if (optim->fts_index_table.suffix == NULL) {
813 return(DB_TABLE_NOT_FOUND);
819 info,
"my_func", fts_fetch_index_words, optim->zip);
822 info,
"word", word->f_str, word->f_len);
825 &optim->fts_index_table,
827 "DECLARE FUNCTION my_func;\n"
828 "DECLARE CURSOR c IS"
831 " WHERE word > :word\n"
837 " FETCH c INTO my_func();\n"
838 " IF c % NOTFOUND THEN\n"
849 if (!inited && ((err = deflateInit(zip->
zp, 9))
853 " InnoDB: Error: ZLib deflateInit() "
854 "failed: %d\n", err);
863 if (error == DB_SUCCESS) {
872 fprintf(stderr,
" InnoDB: "
873 "Warning: lock wait "
874 "timeout reading document. "
882 optim->trx->error_state = DB_SUCCESS;
884 fprintf(stderr,
" InnoDB: Error: (%s) "
885 "while reading document.\n",
893 fts_que_graph_free(graph);
896 if (optim->zip->n_words >= n_words) {
901 if (error == DB_SUCCESS && zip->
status == Z_OK && zip->
n_words > 0) {
904 ut_a(zip->
zp->avail_in == 0);
906 fts_zip_deflate_end(zip);
929 ib_vector_push(fts_doc_ids->
doc_ids, NULL));
936 void* data = dfield_get_data(dfield);
939 ut_a(len != UNIV_SQL_NULL);
946 static_cast<byte*>(data));
971 ibool alloc_bk_trx = FALSE;
981 trx->
op_info =
"fetching FTS doc ids";
988 "DECLARE FUNCTION my_func;\n"
989 "DECLARE CURSOR c IS"
990 " SELECT doc_id FROM \"%s\";\n"
995 " FETCH c INTO my_func();\n"
996 " IF c % NOTFOUND THEN\n"
1008 if (error == DB_SUCCESS) {
1036 int orig_size = upper;
1042 while (lower < upper) {
1043 int i = (lower + upper) >> 1;
1045 if (doc_id > array[i].doc_id) {
1047 }
else if (doc_id < array[i].doc_id) {
1055 if (lower == upper && lower < orig_size) {
1056 if (doc_id == array[lower].doc_id) {
1058 }
else if (lower == 0) {
1064 return( (lower == 0) ? -1 : -lower);
1074 fts_optimize_lookup(
1082 int upper = ib_vector_size(doc_ids);
1085 pos =
fts_bsearch(array, lower, upper, first_doc_id);
1087 ut_a(abs(pos) <= upper + 1);
1096 if (i == 1 && array[0].doc_id <= last_doc_id
1097 && first_doc_id < array[0].doc_id) {
1099 }
else if (i < upper && array[i].doc_id <= last_doc_id) {
1113 static __attribute__((nonnull))
1115 fts_optimize_encode_node(
1126 byte* src = enc->src_ilist_ptr;
1128 if (node->first_doc_id == 0) {
1129 ut_a(node->last_doc_id == 0);
1131 node->first_doc_id = doc_id;
1135 doc_id_delta = doc_id - node->last_doc_id;
1147 pos_enc_len = src - enc->src_ilist_ptr;
1150 enc_len += pos_enc_len;
1157 ut_a(node->ilist_size == 0);
1162 node->ilist =
static_cast<byte*
>(
ut_malloc(new_size));
1163 node->ilist_size_alloc = new_size;
1165 }
else if ((node->ilist_size + enc_len) > node->ilist_size_alloc) {
1166 ulint new_size = node->ilist_size + enc_len;
1167 byte* ilist =
static_cast<byte*
>(
ut_malloc(new_size));
1169 memcpy(ilist, node->ilist, node->ilist_size);
1173 node->ilist = ilist;
1174 node->ilist_size_alloc = new_size;
1177 src = enc->src_ilist_ptr;
1178 dst = node->ilist + node->ilist_size;
1185 memcpy(dst, src, pos_enc_len);
1187 node->last_doc_id = doc_id;
1190 node->ilist_size += enc_len;
1191 enc->src_ilist_ptr += pos_enc_len;
1193 ut_a(node->ilist_size <= node->ilist_size_alloc);
1201 static __attribute__((nonnull))
1213 doc_id_t doc_id = enc->src_last_doc_id;
1215 if (!enc->src_ilist_ptr) {
1216 enc->src_ilist_ptr = src_node->ilist;
1219 copied = enc->src_ilist_ptr - src_node->ilist;
1223 while (copied < src_node->ilist_size
1236 if (*del_pos >= 0 && *del_pos < (
int) ib_vector_size(del_vec)) {
1242 del_doc_id = update->
doc_id;
1245 if (enc->src_ilist_ptr == src_node->ilist && doc_id == 0) {
1246 ut_a(delta == src_node->first_doc_id);
1251 if (del_doc_id > 0 && doc_id == del_doc_id) {
1256 while (*enc->src_ilist_ptr) {
1261 ++enc->src_ilist_ptr;
1267 if (del_doc_id > 0 && doc_id > del_doc_id) {
1276 fts_optimize_encode_node(dst_node, doc_id, enc);
1278 ++dst_node->doc_count;
1280 ut_a(dst_node->last_doc_id == doc_id);
1284 copied = enc->src_ilist_ptr - src_node->ilist;
1287 if (copied >= src_node->ilist_size) {
1288 ut_a(doc_id == src_node->last_doc_id);
1291 enc->src_last_doc_id = doc_id;
1299 static __attribute__((nonnull, warn_unused_result))
1301 fts_optimize_deleted_pos(
1315 if (ib_vector_size(del_vec) > 0) {
1319 ulint
size = ib_vector_size(word->nodes);
1327 ut_a(first_id <= last_id);
1329 del_pos = fts_optimize_lookup(
1330 del_vec, optim->del_pos, first_id, last_id);
1339 #define FTS_DEBUG_PRINT
1357 ulint size = ib_vector_size(word->
nodes);
1359 del_pos = fts_optimize_deleted_pos(optim, word);
1360 nodes = ib_vector_create(word->
heap_alloc,
sizeof(*dst_node), 128);
1367 fprintf(stderr,
"FTS_OPTIMIZE: optimize \"%s\"\n",
1380 ib_vector_push(nodes, NULL));
1381 memset(dst_node, 0,
sizeof(*dst_node));
1385 fts_optimize_node(del_vec, &del_pos, dst_node, src_node, &enc);
1393 ut_a(copied <= src_node->ilist_size);
1403 src_node->
ilist = NULL;
1418 ut_a(dst_node == NULL);
1427 static __attribute__((nonnull, warn_unused_result))
1429 fts_optimize_write_word(
1445 ut_ad(fts_table->charset);
1448 fprintf(stderr,
"FTS_OPTIMIZE: processed \"%s\"\n",
1453 info,
"word", word->f_str, word->f_len);
1456 word->f_str, word->f_len);
1463 "BEGIN DELETE FROM \"%s\" WHERE word = :word;");
1467 if (error != DB_SUCCESS) {
1469 fprintf(stderr,
" InnoDB: Error: (%s) during optimize, "
1470 "when deleting a word from the FTS index.\n",
1474 fts_que_graph_free(graph);
1481 for (i = 0; i < ib_vector_size(nodes); ++
i) {
1485 if (error == DB_SUCCESS) {
1487 trx, &graph, fts_table, word, node);
1489 if (error != DB_SUCCESS) {
1491 fprintf(stderr,
" InnoDB: Error: (%s) "
1492 "during optimize, while adding a "
1493 "word to the FTS index.\n",
1503 if (graph != NULL) {
1504 fts_que_graph_free(graph);
1521 memset(word, 0,
sizeof(*word));
1530 static __attribute__((nonnull, warn_unused_result))
1532 fts_optimize_compact(
1540 ulint size = ib_vector_size(optim->words);
1542 for (i = 0; i < size && error == DB_SUCCESS && !optim->done; ++
i) {
1545 trx_t* trx = optim->trx;
1552 nodes = fts_optimize_word(optim, word);
1555 error = fts_optimize_write_word(
1556 trx, &optim->fts_index_table, &word->
text, nodes);
1558 if (error == DB_SUCCESS) {
1569 if (fts_optimize_time_limit > 0
1570 && (
ut_time() - start_time) > fts_optimize_time_limit) {
1584 fts_optimize_create(
1593 optim->
self_heap = ib_heap_allocator_create(heap);
1597 optim->
words = ib_vector_create(
1604 optim->fts_common_table.
parent = table->
name;
1605 optim->fts_common_table.
table_id = table->
id;
1614 &optim->fts_common_table);
1619 #ifdef FTS_OPTIMIZE_DEBUG
1623 static __attribute__((nonnull, warn_unused_result))
1625 fts_optimize_get_index_start_time(
1633 (ulint*) start_time));
1639 static __attribute__((nonnull, warn_unused_result))
1641 fts_optimize_set_index_start_time(
1649 (ulint) start_time));
1655 static __attribute__((nonnull, warn_unused_result))
1657 fts_optimize_get_index_end_time(
1670 static __attribute__((nonnull, warn_unused_result))
1672 fts_optimize_set_index_end_time(
1687 fts_optimize_graph_free(
1707 if (graph->read_nodes_graph) {
1709 graph->read_nodes_graph = NULL;
1726 fts_optimize_graph_free(&optim->
graph);
1739 fts_optimize_get_time_limit(
1750 return(time_limit * 1000);
1767 que_t* graph = NULL;
1773 fts_optimize_time_limit = fts_optimize_get_time_limit(
1774 optim->
trx, &optim->fts_common_table);
1782 fprintf(stderr,
"%.*s\n", (
int) word->
f_len, word->
f_str);
1784 while(!optim->
done) {
1789 ut_a(ib_vector_size(optim->
words) == 0);
1798 if (error == DB_SUCCESS) {
1804 error = fts_optimize_compact(optim, index, start_time);
1806 if (error == DB_SUCCESS) {
1813 ib_vector_reset(optim->
words);
1815 if (error == DB_SUCCESS) {
1817 if (!fts_zip_read_word(optim->
zip, word)) {
1821 charset, word->
f_str,
1824 fts_que_graph_free(graph);
1829 fprintf(stderr,
"InnoDB: Warning: lock wait timeout "
1830 "during optimize. Retrying!\n");
1833 }
else if (error == DB_DEADLOCK) {
1834 fprintf(stderr,
"InnoDB: Warning: deadlock "
1835 "during optimize. Retrying!\n");
1843 if (graph != NULL) {
1844 fts_que_graph_free(graph);
1853 fts_optimize_set_next_word(
1874 ut_a(value <= 0xff);
1878 *word->
f_str = (byte) value;
1888 static __attribute__((nonnull, warn_unused_result))
1890 fts_optimize_index_completed(
1897 byte
buf[
sizeof(ulint)];
1898 #ifdef FTS_OPTIMIZE_DEBUG
1901 error = fts_optimize_set_index_end_time(optim->trx, index, end_time);
1914 if (error != DB_SUCCESS) {
1916 fprintf(stderr,
"InnoDB: Error: (%s) while "
1917 "updating last optimized word!\n",
ut_strerr(error));
1928 static __attribute__((nonnull, warn_unused_result))
1930 fts_optimize_index_read_words(
1938 if (optim->del_list_regenerated) {
1949 if (error == DB_RECORD_NOT_FOUND) {
1954 while (error == DB_SUCCESS) {
1956 error = fts_index_fetch_words(
1959 if (error == DB_SUCCESS) {
1963 if (optim->zip->n_words > 0) {
1967 fts_optimize_set_next_word(
1968 optim->fts_index_table.charset,
1971 if (word->f_len == 0) {
1985 static __attribute__((nonnull, warn_unused_result))
1997 optim->fts_index_table.index_id = index->id;
2000 optim->done = FALSE;
2008 word.
f_len =
sizeof(str) - 1;
2013 error = fts_optimize_index_read_words(optim, index, &word);
2015 if (error == DB_SUCCESS) {
2018 ut_a(optim->zip->pos == 0);
2019 ut_a(optim->zip->zp->total_in == 0);
2020 ut_a(optim->zip->zp->total_out == 0);
2022 zip_error = inflateInit(optim->zip->zp);
2023 ut_a(zip_error == Z_OK);
2029 if (!fts_zip_read_word(optim->zip, &word)) {
2033 fts_optimize_words(optim, index, &word);
2040 if (error == DB_SUCCESS && optim->zip->n_words == 0) {
2042 error = fts_optimize_index_completed(optim, index);
2044 if (error == DB_SUCCESS) {
2045 ++optim->n_completed;
2056 static __attribute__((nonnull, warn_unused_result))
2058 fts_optimize_purge_deleted_doc_ids(
2072 ut_a(ib_vector_size(optim->to_delete->doc_ids) > 0);
2088 fts_delete_doc_ids_sql,
"%s", optim->name_prefix);
2095 for (i = 0; i < ib_vector_size(optim->to_delete->doc_ids); ++
i) {
2098 optim->to_delete->doc_ids, i));
2110 if (error != DB_SUCCESS) {
2117 fts_que_graph_free(graph);
2125 static __attribute__((nonnull, warn_unused_result))
2127 fts_optimize_purge_deleted_doc_id_snapshot(
2137 sql_str =
ut_strreplace(fts_end_delete_sql,
"%s", optim->name_prefix);
2146 fts_que_graph_free(graph);
2158 fts_optimize_being_deleted_count(
2175 static __attribute__((nonnull, warn_unused_result))
2177 fts_optimize_create_deleted_doc_id_snapshot(
2187 sql_str =
ut_strreplace(fts_init_delete_sql,
"%s", optim->name_prefix);
2196 fts_que_graph_free(graph);
2198 if (error != DB_SUCCESS) {
2204 optim->del_list_regenerated = TRUE;
2213 static __attribute__((nonnull, warn_unused_result))
2215 fts_optimize_read_deleted_doc_id_snapshot(
2221 optim->fts_common_table.suffix =
"BEING_DELETED";
2225 optim->trx, &optim->fts_common_table, optim->to_delete);
2227 if (error == DB_SUCCESS) {
2229 optim->fts_common_table.suffix =
"BEING_DELETED_CACHE";
2233 optim->trx, &optim->fts_common_table, optim->to_delete);
2236 if (error != DB_SUCCESS) {
2239 optim->to_delete = NULL;
2250 static __attribute__((nonnull, warn_unused_result))
2252 fts_optimize_indexes(
2258 fts_t* fts = optim->table->fts;
2261 for (i = 0; i < ib_vector_size(fts->
indexes); ++
i) {
2264 #ifdef FTS_OPTIMIZE_DEBUG
2269 error = fts_optimize_get_index_start_time(
2270 optim->trx, index, &start_time);
2272 if (error != DB_SUCCESS) {
2276 error = fts_optimize_get_index_end_time(
2277 optim->trx, index, &end_time);
2279 if (error != DB_SUCCESS) {
2285 if (start_time == 0) {
2288 error = fts_optimize_set_index_start_time(
2289 optim->trx, index, start_time);
2294 error = fts_optimize_index(optim, index);
2296 if (error != DB_SUCCESS) {
2300 ++optim->n_completed;
2304 ib_vector_getp(fts->
indexes, i));
2305 error = fts_optimize_index(optim, index);
2308 if (error == DB_SUCCESS) {
2320 static __attribute__((nonnull, warn_unused_result))
2322 fts_optimize_purge_snapshot(
2330 error = fts_optimize_purge_deleted_doc_ids(optim);
2332 if (error == DB_SUCCESS) {
2334 error = fts_optimize_purge_deleted_doc_id_snapshot(optim);
2337 if (error == DB_SUCCESS) {
2349 static __attribute__((nonnull, warn_unused_result))
2351 fts_optimize_reset_start_time(
2356 #ifdef FTS_OPTIMIZE_DEBUG
2357 fts_t* fts = optim->table->fts;
2360 ut_a(optim->n_completed == ib_vector_size(fts->
indexes));
2362 for (uint i = 0; i < ib_vector_size(fts->
indexes); ++
i) {
2368 error = fts_optimize_set_index_start_time(
2369 optim->trx, index, start_time);
2372 ib_vector_getp(fts->
indexes, i));
2376 if (error == DB_SUCCESS) {
2388 static __attribute__((nonnull))
2390 fts_optimize_table_bk(
2396 fts_t* fts = table->fts;
2399 if (slot->last_run > 0
2400 && (
ut_time() - slot->last_run) < slot->interval_time) {
2404 }
else if (fts && fts->
cache
2409 if (error == DB_SUCCESS) {
2410 slot->state = FTS_STATE_DONE;
2434 fts_t* fts = table->fts;
2437 fprintf(stderr,
" InnoDB: FTS start optimize %s\n", table->
name);
2439 optim = fts_optimize_create(table);
2445 if (fts_optimize_being_deleted_count(optim) == 0) {
2448 error = fts_optimize_create_deleted_doc_id_snapshot(optim);
2454 if (error == DB_DUPLICATE_KEY) {
2458 if (error == DB_SUCCESS) {
2463 error = fts_optimize_read_deleted_doc_id_snapshot(optim);
2465 if (error == DB_SUCCESS) {
2474 error = fts_optimize_indexes(optim);
2484 if (error == DB_SUCCESS
2488 fprintf(stderr,
"FTS_OPTIMIZE: Completed "
2489 "Optimize, cleanup DELETED "
2498 error = fts_optimize_purge_snapshot(optim);
2501 if (error == DB_SUCCESS) {
2504 error = fts_optimize_reset_start_time(optim);
2509 fts_optimize_free(optim);
2512 fprintf(stderr,
" InnoDB: FTS end optimize %s\n", table->
name);
2522 fts_optimize_create_msg(
2550 if (!fts_optimize_wq) {
2575 if (!fts_optimize_wq) {
2598 if (!fts_optimize_wq) {
2603 if (fts_opt_start_shutdown) {
2605 "Try to remove table %s after FTS optimize"
2606 " thread exiting.", table->
name);
2619 remove->event = event;
2624 os_event_wait(event);
2634 fts_optimize_find_slot(
2641 for (i = 0; i < ib_vector_size(tables); ++
i) {
2658 fts_optimize_start_table(
2665 slot = fts_optimize_find_slot(tables, table);
2669 fprintf(stderr,
" InnoDB: Error: table %s not registered "
2670 "with the optimize thread.\n", table->
name);
2681 fts_optimize_new_table(
2688 ulint empty_slot = ULINT_UNDEFINED;
2691 for (i = 0; i < ib_vector_size(tables); ++
i) {
2696 if (slot->
state == FTS_STATE_EMPTY) {
2698 }
else if (slot->
table->
id == table->
id) {
2705 if (empty_slot != ULINT_UNDEFINED) {
2714 slot =
static_cast<fts_slot_t*
>(ib_vector_push(tables, NULL));
2717 memset(slot, 0x0,
sizeof(*slot));
2720 slot->
state = FTS_STATE_LOADED;
2730 fts_optimize_del_table(
2738 for (i = 0; i < ib_vector_size(tables); ++
i) {
2744 if (slot->
state != FTS_STATE_EMPTY
2748 fprintf(stderr,
" InnoDB: FTS Optimize Removing "
2749 "table %s\n", table->
name);
2752 slot->
state = FTS_STATE_EMPTY;
2766 fts_optimize_how_many(
2778 for (i = 0; i < ib_vector_size(tables); ++
i) {
2782 ib_vector_get_const(tables, i));
2784 switch (slot->
state) {
2785 case FTS_STATE_DONE:
2786 case FTS_STATE_LOADED:
2797 case FTS_STATE_RUNNING:
2800 delta = current_time - slot->
last_run;
2809 case FTS_STATE_EMPTY:
2810 case FTS_STATE_SUSPENDED:
2829 ulint total_memory = 0;
2830 double time_diff = difftime(
ut_time(), last_check_sync_time);
2836 last_check_sync_time =
ut_time();
2838 for (ulint i = 0; i < ib_vector_size(tables); ++
i) {
2842 ib_vector_get_const(tables, i));
2861 fts_optimize_need_sync(
2867 ulint num_table = ib_vector_size(tables);
2873 if (fts_optimize_sync_iterator >= num_table) {
2874 fts_optimize_sync_iterator = 0;
2878 table = slot->
table;
2886 if (table->fts->
cache) {
2890 >= fts_optimize_add_threshold) {
2892 }
else if (deleted >= fts_optimize_delete_threshold) {
2901 fts_optimize_sync_iterator++;
2912 fts_optimize_thread(
2923 ulint n_optimize = 0;
2929 heap_alloc = ib_heap_allocator_create(heap);
2931 tables = ib_vector_create(heap_alloc,
sizeof(
fts_slot_t), 4);
2939 && ib_wqueue_is_empty(wq)
2941 && n_optimize > 0) {
2945 ut_a(ib_vector_size(tables) > 0);
2951 if (slot->
state != FTS_STATE_EMPTY) {
2953 slot->
state = FTS_STATE_RUNNING;
2955 fts_optimize_table_bk(slot);
2961 if (current >= ib_vector_size(tables)) {
2962 n_optimize = fts_optimize_how_many(tables);
2967 }
else if (n_optimize == 0 || !ib_wqueue_is_empty(wq)) {
2971 ib_wqueue_timedwait(wq,
2972 FTS_QUEUE_WAIT_IN_USECS));
2976 if (fts_is_sync_needed(tables)) {
2983 switch (msg->
type) {
2997 if (fts_optimize_new_table(
2999 static_cast<dict_table_t*>(
3007 fts_optimize_start_table(
3009 static_cast<dict_table_t*>(
3015 if (fts_optimize_del_table(
3016 tables, static_cast<fts_msg_del_t*>(
3034 n_optimize = fts_optimize_how_many(tables);
3046 for (i = 0; i < ib_vector_size(tables); i++) {
3052 if (slot->
state != FTS_STATE_EMPTY) {
3075 ib_vector_free(tables);
3077 ib_logf(IB_LOG_LEVEL_INFO,
"FTS optimize thread exiting.");
3085 OS_THREAD_DUMMY_RETURN;
3098 ut_a(fts_optimize_wq == NULL);
3101 ut_a(fts_optimize_wq != NULL);
3102 last_check_sync_time =
ut_time();
3104 os_thread_create(fts_optimize_thread, fts_optimize_wq, NULL);
3115 return(fts_optimize_wq != NULL);
3137 fts_opt_start_shutdown =
true;
3150 os_event_wait(event);
3168 fts_optimize_wq = NULL;