@@ -265,13 +265,15 @@ FTS auxiliary INDEX table and clear the cache at the end.
265
265
@param[in,out] sync sync state
266
266
@param[in] unlock_cache whether unlock cache lock when write node
267
267
@param[in] wait whether wait when a sync is in progress
268
+ @param[in] has_dict whether has dict operation lock
268
269
@return DB_SUCCESS if all OK */
269
270
static
270
271
dberr_t
271
272
fts_sync (
272
273
fts_sync_t * sync,
273
274
bool unlock_cache,
274
- bool wait);
275
+ bool wait,
276
+ bool has_dict);
275
277
276
278
/* ***************************************************************/ /* *
277
279
Release all resources help by the words rb tree e.g., the node ilist. */
@@ -3567,7 +3569,7 @@ fts_add_doc_by_id(
3567
3569
3568
3570
DBUG_EXECUTE_IF (
3569
3571
" fts_instrument_sync_debug" ,
3570
- fts_sync (cache->sync , true , true );
3572
+ fts_sync (cache->sync , true , true , false );
3571
3573
);
3572
3574
3573
3575
DEBUG_SYNC_C (" fts_instrument_sync_request" );
@@ -4379,13 +4381,11 @@ fts_sync_index(
4379
4381
}
4380
4382
4381
4383
/* * Check if index cache has been synced completely
4382
- @param[in,out] sync sync state
4383
4384
@param[in,out] index_cache index cache
4384
4385
@return true if index is synced, otherwise false. */
4385
4386
static
4386
4387
bool
4387
4388
fts_sync_index_check (
4388
- fts_sync_t * sync,
4389
4389
fts_index_cache_t * index_cache)
4390
4390
{
4391
4391
const ib_rbt_node_t * rbt_node;
@@ -4408,14 +4408,36 @@ fts_sync_index_check(
4408
4408
return (true );
4409
4409
}
4410
4410
4411
- /* ********************************************************************/ /* *
4412
- Commit the SYNC, change state of processed doc ids etc.
4411
+ /* * Reset synced flag in index cache when rollback
4412
+ @param[in,out] index_cache index cache */
4413
+ static
4414
+ void
4415
+ fts_sync_index_reset (
4416
+ fts_index_cache_t * index_cache)
4417
+ {
4418
+ const ib_rbt_node_t * rbt_node;
4419
+
4420
+ for (rbt_node = rbt_first (index_cache->words );
4421
+ rbt_node != NULL ;
4422
+ rbt_node = rbt_next (index_cache->words , rbt_node)) {
4423
+
4424
+ fts_tokenizer_word_t * word;
4425
+ word = rbt_value (fts_tokenizer_word_t , rbt_node);
4426
+
4427
+ fts_node_t * fts_node;
4428
+ fts_node = static_cast <fts_node_t *>(ib_vector_last (word->nodes ));
4429
+
4430
+ fts_node->synced = false ;
4431
+ }
4432
+ }
4433
+
4434
+ /* * Commit the SYNC, change state of processed doc ids etc.
4435
+ @param[in,out] sync sync state
4413
4436
@return DB_SUCCESS if all OK */
4414
4437
static MY_ATTRIBUTE ((nonnull, warn_unused_result))
4415
4438
dberr_t
4416
4439
fts_sync_commit(
4417
- /* ============*/
4418
- fts_sync_t * sync) /* !< in: sync state */
4440
+ fts_sync_t * sync)
4419
4441
{
4420
4442
dberr_t error;
4421
4443
trx_t * trx = sync->trx ;
@@ -4468,6 +4490,8 @@ fts_sync_commit(
4468
4490
(double ) n_nodes/ (double ) elapsed_time);
4469
4491
}
4470
4492
4493
+ /* Avoid assertion in trx_free(). */
4494
+ trx->dict_operation_lock_mode = 0 ;
4471
4495
trx_free_for_background (trx);
4472
4496
4473
4497
return (error);
@@ -4490,6 +4514,10 @@ fts_sync_rollback(
4490
4514
index_cache = static_cast <fts_index_cache_t *>(
4491
4515
ib_vector_get (cache->indexes , i));
4492
4516
4517
+ /* Reset synced flag so nodes will not be skipped
4518
+ in the next sync, see fts_sync_write_words(). */
4519
+ fts_sync_index_reset (index_cache);
4520
+
4493
4521
for (j = 0 ; fts_index_selector[j].value ; ++j) {
4494
4522
4495
4523
if (index_cache->ins_graph [j] != NULL ) {
@@ -4515,6 +4543,9 @@ fts_sync_rollback(
4515
4543
rw_lock_x_unlock (&cache->lock );
4516
4544
4517
4545
fts_sql_rollback (trx);
4546
+
4547
+ /* Avoid assertion in trx_free(). */
4548
+ trx->dict_operation_lock_mode = 0 ;
4518
4549
trx_free_for_background (trx);
4519
4550
}
4520
4551
@@ -4523,13 +4554,15 @@ FTS auxiliary INDEX table and clear the cache at the end.
4523
4554
@param[in,out] sync sync state
4524
4555
@param[in] unlock_cache whether unlock cache lock when write node
4525
4556
@param[in] wait whether wait when a sync is in progress
4557
+ @param[in] has_dict whether has dict operation lock
4526
4558
@return DB_SUCCESS if all OK */
4527
4559
static
4528
4560
dberr_t
4529
4561
fts_sync (
4530
4562
fts_sync_t * sync,
4531
4563
bool unlock_cache,
4532
- bool wait)
4564
+ bool wait,
4565
+ bool has_dict)
4533
4566
{
4534
4567
ulint i;
4535
4568
dberr_t error = DB_SUCCESS;
@@ -4558,6 +4591,12 @@ fts_sync(
4558
4591
DEBUG_SYNC_C (" fts_sync_begin" );
4559
4592
fts_sync_begin (sync);
4560
4593
4594
+ /* When sync in background, we hold dict operation lock
4595
+ to prevent DDL like DROP INDEX, etc. */
4596
+ if (has_dict) {
4597
+ sync->trx ->dict_operation_lock_mode = RW_S_LATCH;
4598
+ }
4599
+
4561
4600
begin_sync:
4562
4601
if (cache->total_size > fts_max_cache_size) {
4563
4602
/* Avoid the case: sync never finish when
@@ -4598,7 +4637,7 @@ fts_sync(
4598
4637
ib_vector_get (cache->indexes , i));
4599
4638
4600
4639
if (index_cache->index ->to_be_dropped
4601
- || fts_sync_index_check (sync, index_cache)) {
4640
+ || fts_sync_index_check (index_cache)) {
4602
4641
continue ;
4603
4642
}
4604
4643
@@ -4613,6 +4652,7 @@ fts_sync(
4613
4652
}
4614
4653
4615
4654
rw_lock_x_lock (&cache->lock );
4655
+ sync->interrupted = false ;
4616
4656
sync->in_progress = false ;
4617
4657
os_event_set (sync->event );
4618
4658
rw_lock_x_unlock (&cache->lock );
@@ -4636,20 +4676,23 @@ FTS auxiliary INDEX table and clear the cache at the end.
4636
4676
@param[in,out] table fts table
4637
4677
@param[in] unlock_cache whether unlock cache when write node
4638
4678
@param[in] wait whether wait for existing sync to finish
4679
+ @param[in] has_dict whether has dict operation lock
4639
4680
@return DB_SUCCESS on success, error code on failure. */
4640
4681
UNIV_INTERN
4641
4682
dberr_t
4642
4683
fts_sync_table (
4643
4684
dict_table_t * table,
4644
4685
bool unlock_cache,
4645
- bool wait)
4686
+ bool wait,
4687
+ bool has_dict)
4646
4688
{
4647
4689
dberr_t err = DB_SUCCESS;
4648
4690
4649
4691
ut_ad (table->fts );
4650
4692
4651
4693
if (!dict_table_is_discarded (table) && table->fts ->cache ) {
4652
- err = fts_sync (table->fts ->cache ->sync , unlock_cache, wait);
4694
+ err = fts_sync (table->fts ->cache ->sync ,
4695
+ unlock_cache, wait, has_dict);
4653
4696
}
4654
4697
4655
4698
return (err);
0 commit comments