@@ -2607,89 +2607,85 @@ fts_get_next_doc_id(
26072607return (DB_SUCCESS);
26082608}
26092609
2610- /* ********************************************************************/ /* *
2611- This function fetch the Doc ID from CONFIG table, and compare with
2610+ /* * Read the synced document id from the fts configuration table
2611+ @param table fts table
2612+ @param doc_id document id to be read
2613+ @param trx transaction to read from config table
2614+ @return DB_SUCCESS in case of success */
2615+ static
2616+ dberr_t fts_read_synced_doc_id (const dict_table_t *table,
2617+ doc_id_t *doc_id,
2618+ trx_t *trx)
2619+ {
2620+ dberr_t error;
2621+ que_t * graph= NULL ;
2622+ char table_name[MAX_FULL_NAME_LEN];
2623+
2624+ fts_table_t fts_table;
2625+ fts_table.suffix = " CONFIG" ;
2626+ fts_table.table_id = table->id ;
2627+ fts_table.type = FTS_COMMON_TABLE;
2628+ fts_table.table = table;
2629+ ut_a (table->fts ->doc_col != ULINT_UNDEFINED);
2630+
2631+ trx->op_info = " update the next FTS document id" ;
2632+ pars_info_t *info= pars_info_create ();
2633+ pars_info_bind_function (info, " my_func" , fts_fetch_store_doc_id,
2634+ doc_id);
2635+
2636+ fts_get_table_name (&fts_table, table_name);
2637+ pars_info_bind_id (info, " config_table" , table_name);
2638+
2639+ graph= fts_parse_sql (
2640+ &fts_table, info,
2641+ " DECLARE FUNCTION my_func;\n "
2642+ " DECLARE CURSOR c IS SELECT value FROM $config_table"
2643+ " WHERE key = 'synced_doc_id' FOR UPDATE;\n "
2644+ " BEGIN\n "
2645+ " "
2646+ " OPEN c;\n "
2647+ " WHILE 1 = 1 LOOP\n "
2648+ " FETCH c INTO my_func();\n "
2649+ " IF c % NOTFOUND THEN\n "
2650+ " EXIT;\n "
2651+ " END IF;\n "
2652+ " END LOOP;\n "
2653+ " CLOSE c;" );
2654+
2655+ *doc_id = 0 ;
2656+ error = fts_eval_sql (trx, graph);
2657+ fts_que_graph_free_check_lock (&fts_table, NULL , graph);
2658+ return error;
2659+ }
2660+
2661+ /* * This function fetch the Doc ID from CONFIG table, and compare with
26122662the Doc ID supplied. And store the larger one to the CONFIG table.
2663+ @param table fts table
2664+ @param cmp_doc_id Doc ID to compare
2665+ @param doc_id larger document id after comparing "cmp_doc_id" to
2666+ the one stored in CONFIG table
2667+ @param trx transaction
26132668@return DB_SUCCESS if OK */
2614- static MY_ATTRIBUTE ((nonnull))
2669+ static
26152670dberr_t
26162671fts_cmp_set_sync_doc_id (
2617- /* ====================*/
2618- const dict_table_t * table,/* !< in: table */
2619- doc_id_t cmp_doc_id,/* !< in: Doc ID to compare */
2620- ibool read_only,/* !< in: TRUE if read the
2621- synced_doc_id only */
2622- doc_id_t * doc_id)/* !< out: larger document id
2623- after comparing "cmp_doc_id"
2624- to the one stored in CONFIG
2625- table */
2672+ const dict_table_t *table,
2673+ doc_id_t cmp_doc_id,
2674+ doc_id_t *doc_id,
2675+ trx_t *trx=nullptr )
26262676{
2627- trx_t * trx;
2628- pars_info_t * info;
2629- dberr_t error;
2630- fts_table_t fts_table;
2631- que_t * graph = NULL ;
2632- fts_cache_t * cache = table->fts ->cache ;
2633- char table_name[MAX_FULL_NAME_LEN];
2634- retry:
2635- ut_a (table->fts ->doc_col != ULINT_UNDEFINED);
2677+ fts_cache_t * cache= table->fts ->cache ;
2678+ dberr_t error = DB_SUCCESS;
2679+ const trx_t *const caller_trx = trx;
26362680
2637- fts_table.suffix = " CONFIG" ;
2638- fts_table.table_id = table->id ;
2639- fts_table.type = FTS_COMMON_TABLE;
2640- fts_table.table = table;
2641-
2642- trx = trx_create ();
2643- if (srv_read_only_mode) {
2681+ if (trx == nullptr ) {
2682+ trx = trx_create ();
26442683trx_start_internal_read_only (trx);
2645- } else {
2646- trx_start_internal (trx);
2647- }
2648-
2649- trx->op_info = " update the next FTS document id" ;
2650-
2651- info = pars_info_create ();
2652-
2653- pars_info_bind_function (
2654- info, " my_func" , fts_fetch_store_doc_id, doc_id);
2655-
2656- fts_get_table_name (&fts_table, table_name);
2657- pars_info_bind_id (info, " config_table" , table_name);
2658-
2659- graph = fts_parse_sql (
2660- &fts_table, info,
2661- " DECLARE FUNCTION my_func;\n "
2662- " DECLARE CURSOR c IS SELECT value FROM $config_table"
2663- " WHERE key = 'synced_doc_id' FOR UPDATE;\n "
2664- " BEGIN\n "
2665- " "
2666- " OPEN c;\n "
2667- " WHILE 1 = 1 LOOP\n "
2668- " FETCH c INTO my_func();\n "
2669- " IF c % NOTFOUND THEN\n "
2670- " EXIT;\n "
2671- " END IF;\n "
2672- " END LOOP;\n "
2673- " CLOSE c;" );
2674-
2675- *doc_id = 0 ;
2676-
2677- error = fts_eval_sql (trx, graph);
2678-
2679- fts_que_graph_free_check_lock (&fts_table, NULL , graph);
2680-
2681- // FIXME: We need to retry deadlock errors
2682- if (error != DB_SUCCESS) {
2683- goto func_exit;
26842684}
2685+ retry:
2686+ error = fts_read_synced_doc_id (table, doc_id, trx);
26852687
2686- if (read_only) {
2687- /* InnoDB stores actual synced_doc_id value + 1 in
2688- FTS_CONFIG table. Reduce the value by 1 while reading
2689- after startup. */
2690- if (*doc_id) *doc_id -= 1 ;
2691- goto func_exit;
2692- }
2688+ if (error != DB_SUCCESS) goto func_exit;
26932689
26942690if (cmp_doc_id == 0 && *doc_id) {
26952691cache->synced_doc_id = *doc_id - 1 ;
@@ -2714,13 +2710,18 @@ fts_cmp_set_sync_doc_id(
27142710
27152711func_exit:
27162712
2713+ if (caller_trx) {
2714+ return error;
2715+ }
2716+
27172717if (UNIV_LIKELY (error == DB_SUCCESS)) {
27182718fts_sql_commit (trx);
27192719} else {
27202720*doc_id = 0 ;
27212721
27222722ib::error () << " (" << error << " ) while getting next doc id "
27232723" for table " << table->name ;
2724+
27242725fts_sql_rollback (trx);
27252726
27262727if (error == DB_DEADLOCK) {
@@ -4201,8 +4202,8 @@ fts_sync_commit(
42014202
42024203/* After each Sync, update the CONFIG table about the max doc id
42034204we just sync-ed to index table */
4204- error = fts_cmp_set_sync_doc_id (sync->table , sync->max_doc_id , FALSE ,
4205- &last_doc_id);
4205+ error = fts_cmp_set_sync_doc_id (sync->table , sync->max_doc_id ,
4206+ &last_doc_id, trx );
42064207
42074208/* Get the list of deleted documents that are either in the
42084209cache or were headed there but were deleted before the add
@@ -4228,6 +4229,7 @@ fts_sync_commit(
42284229rw_lock_x_unlock (&cache->lock );
42294230
42304231if (UNIV_LIKELY (error == DB_SUCCESS)) {
4232+ DEBUG_SYNC_C (" fts_crash_before_commit_sync" );
42314233fts_sql_commit (trx);
42324234} else {
42334235fts_sql_rollback (trx);
@@ -4901,7 +4903,7 @@ fts_init_doc_id(
49014903
49024904/* Then compare this value with the ID value stored in the CONFIG
49034905table. The larger one will be our new initial Doc ID */
4904- fts_cmp_set_sync_doc_id (table, 0 , FALSE , &max_doc_id);
4906+ fts_cmp_set_sync_doc_id (table, 0 , &max_doc_id);
49054907
49064908/* If DICT_TF2_FTS_ADD_DOC_ID is set, we are in the process of
49074909creating index (and add doc id column. No need to recovery
@@ -6376,7 +6378,17 @@ fts_init_index(
63766378start_doc = cache->synced_doc_id ;
63776379
63786380if (!start_doc) {
6379- fts_cmp_set_sync_doc_id (table, 0 , TRUE , &start_doc);
6381+ trx_t *trx = trx_create ();
6382+ trx_start_internal_read_only (trx);
6383+ dberr_t err= fts_read_synced_doc_id (table, &start_doc, trx);
6384+ fts_sql_commit (trx);
6385+ trx->free ();
6386+ if (err != DB_SUCCESS) {
6387+ goto func_exit;
6388+ }
6389+ if (start_doc) {
6390+ start_doc--;
6391+ }
63806392cache->synced_doc_id = start_doc;
63816393}
63826394
0 commit comments