From 7f7211073ceec9d35947ec5c9286878cfa4d3d78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 13 May 2019 08:48:22 +0300 Subject: [PATCH 1/5] MDEV-19441 Typo in error message "InnoDB: FTS Doc ID must be large than" row_insert_for_mysql(): Correct the grammar error, and display the table name in both messages. --- storage/innobase/handler/ha_innodb.cc | 2 +- storage/innobase/row/row0mysql.cc | 15 +++++++-------- storage/xtradb/handler/ha_innodb.cc | 2 +- storage/xtradb/row/row0mysql.cc | 15 +++++++-------- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 025df01adc7..8b007bb0b38 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -13520,7 +13520,7 @@ innodb_rec_per_key( } /* If the number of NULL values is the same as or - large than that of the distinct values, we could + larger than that of the distinct values, we could consider that the table consists mostly of NULL value. Set rec_per_key to 1. */ if (n_diff <= n_null) { diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 21a5f6d9f09..966448b502c 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -1490,8 +1490,9 @@ error_exit: doc_id = fts_get_doc_id_from_row(table, node->row); if (doc_id <= 0) { - fprintf(stderr, - "InnoDB: FTS Doc ID must be large than 0 \n"); + ib_logf(IB_LOG_LEVEL_ERROR, + "FTS_DOC_ID must be larger than 0" + " for table %s", table->name); err = DB_FTS_INVALID_DOCID; trx->error_state = DB_FTS_INVALID_DOCID; goto error_exit; @@ -1502,12 +1503,10 @@ error_exit: = table->fts->cache->next_doc_id; if (doc_id < next_doc_id) { - fprintf(stderr, - "InnoDB: FTS Doc ID must be large than" - " " UINT64PF " for table", - next_doc_id - 1); - ut_print_name(stderr, trx, TRUE, table->name); - putc('\n', stderr); + ib_logf(IB_LOG_LEVEL_ERROR, + "FTS_DOC_ID must be larger than " + UINT64PF " for table %s", + next_doc_id - 1, table->name); err = DB_FTS_INVALID_DOCID; trx->error_state = DB_FTS_INVALID_DOCID; diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index fb29a10466b..df925327c1c 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -14107,7 +14107,7 @@ innodb_rec_per_key( } /* If the number of NULL values is the same as or - large than that of the distinct values, we could + larger than that of the distinct values, we could consider that the table consists mostly of NULL value. Set rec_per_key to 1. */ if (n_diff <= n_null) { diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc index 111ee70f1af..a5192dcad8f 100644 --- a/storage/xtradb/row/row0mysql.cc +++ b/storage/xtradb/row/row0mysql.cc @@ -1476,8 +1476,9 @@ error_exit: doc_id = fts_get_doc_id_from_row(table, node->row); if (doc_id <= 0) { - fprintf(stderr, - "InnoDB: FTS Doc ID must be large than 0 \n"); + ib_logf(IB_LOG_LEVEL_ERROR, + "FTS_DOC_ID must be larger than 0" + " for table %s", table->name); err = DB_FTS_INVALID_DOCID; trx->error_state = DB_FTS_INVALID_DOCID; goto error_exit; @@ -1488,12 +1489,10 @@ error_exit: = table->fts->cache->next_doc_id; if (doc_id < next_doc_id) { - fprintf(stderr, - "InnoDB: FTS Doc ID must be large than" - " " UINT64PF " for table", - next_doc_id - 1); - ut_print_name(stderr, trx, TRUE, table->name); - putc('\n', stderr); + ib_logf(IB_LOG_LEVEL_ERROR, + "FTS_DOC_ID must be larger than " + UINT64PF " for table %s", + next_doc_id - 1, table->name); err = DB_FTS_INVALID_DOCID; trx->error_state = DB_FTS_INVALID_DOCID; From c7c54ce606b645fc1bee1ec2b04e491dab89a7ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 13 May 2019 11:32:20 +0300 Subject: [PATCH 2/5] fts_doc_ids_free(): Define inline --- storage/innobase/fts/fts0fts.cc | 16 ---------------- storage/innobase/include/fts0fts.h | 14 ++++++-------- storage/xtradb/fts/fts0fts.cc | 16 ---------------- storage/xtradb/include/fts0fts.h | 14 ++++++-------- 4 files changed, 12 insertions(+), 48 deletions(-) diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index f78d0bd43b9..bfb469b1e2d 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -2889,22 +2889,6 @@ fts_doc_ids_create(void) return(fts_doc_ids); } -/*********************************************************************//** -Free a fts_doc_ids_t. */ - -void -fts_doc_ids_free( -/*=============*/ - fts_doc_ids_t* fts_doc_ids) -{ - mem_heap_t* heap = static_cast( - fts_doc_ids->self_heap->arg); - - memset(fts_doc_ids, 0, sizeof(*fts_doc_ids)); - - mem_heap_free(heap); -} - /*********************************************************************//** Do commit-phase steps necessary for the insertion of a new row. */ void diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h index ac27094aa30..19a1058dc0c 100644 --- a/storage/innobase/include/fts0fts.h +++ b/storage/innobase/include/fts0fts.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2017, MariaDB Corporation. +Copyright (c) 2016, 2019, MariaDB Corporation. 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 @@ -429,13 +429,11 @@ fts_doc_ids_t* fts_doc_ids_create(void); /*=====================*/ -/******************************************************************//** -Free a fts_doc_ids_t. */ -UNIV_INTERN -void -fts_doc_ids_free( -/*=============*/ - fts_doc_ids_t* doc_ids); /*!< in: doc_ids to free */ +/** Free fts_doc_ids_t */ +inline void fts_doc_ids_free(fts_doc_ids_t* doc_ids) +{ + mem_heap_free(static_cast(doc_ids->self_heap->arg)); +} /******************************************************************//** Notify the FTS system about an operation on an FTS-indexed table. */ diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc index f78d0bd43b9..bfb469b1e2d 100644 --- a/storage/xtradb/fts/fts0fts.cc +++ b/storage/xtradb/fts/fts0fts.cc @@ -2889,22 +2889,6 @@ fts_doc_ids_create(void) return(fts_doc_ids); } -/*********************************************************************//** -Free a fts_doc_ids_t. */ - -void -fts_doc_ids_free( -/*=============*/ - fts_doc_ids_t* fts_doc_ids) -{ - mem_heap_t* heap = static_cast( - fts_doc_ids->self_heap->arg); - - memset(fts_doc_ids, 0, sizeof(*fts_doc_ids)); - - mem_heap_free(heap); -} - /*********************************************************************//** Do commit-phase steps necessary for the insertion of a new row. */ void diff --git a/storage/xtradb/include/fts0fts.h b/storage/xtradb/include/fts0fts.h index ac27094aa30..19a1058dc0c 100644 --- a/storage/xtradb/include/fts0fts.h +++ b/storage/xtradb/include/fts0fts.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2017, MariaDB Corporation. +Copyright (c) 2016, 2019, MariaDB Corporation. 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 @@ -429,13 +429,11 @@ fts_doc_ids_t* fts_doc_ids_create(void); /*=====================*/ -/******************************************************************//** -Free a fts_doc_ids_t. */ -UNIV_INTERN -void -fts_doc_ids_free( -/*=============*/ - fts_doc_ids_t* doc_ids); /*!< in: doc_ids to free */ +/** Free fts_doc_ids_t */ +inline void fts_doc_ids_free(fts_doc_ids_t* doc_ids) +{ + mem_heap_free(static_cast(doc_ids->self_heap->arg)); +} /******************************************************************//** Notify the FTS system about an operation on an FTS-indexed table. */ From 1c97e07f8f30a968521054d658b8075f2ab2a8d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 13 May 2019 17:07:13 +0300 Subject: [PATCH 3/5] fts_optimize_words(): Remove stray output With SET GLOBAL innodb_optimize_fulltext_only=1 in effect, OPTIMIZE TABLE would output words from the fulltext index to the server error log, even in non-debug builds. fts_optimize_words(): Remove the unwanted output. --- storage/innobase/fts/fts0opt.cc | 2 -- storage/xtradb/fts/fts0opt.cc | 2 -- 2 files changed, 4 deletions(-) diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc index 625218244f4..881b106f570 100644 --- a/storage/innobase/fts/fts0opt.cc +++ b/storage/innobase/fts/fts0opt.cc @@ -1799,8 +1799,6 @@ fts_optimize_words( fetch.read_arg = optim->words; fetch.read_record = fts_optimize_index_fetch_node; - fprintf(stderr, "%.*s\n", (int) word->f_len, word->f_str); - while(!optim->done) { dberr_t error; trx_t* trx = optim->trx; diff --git a/storage/xtradb/fts/fts0opt.cc b/storage/xtradb/fts/fts0opt.cc index 625218244f4..881b106f570 100644 --- a/storage/xtradb/fts/fts0opt.cc +++ b/storage/xtradb/fts/fts0opt.cc @@ -1799,8 +1799,6 @@ fts_optimize_words( fetch.read_arg = optim->words; fetch.read_record = fts_optimize_index_fetch_node; - fprintf(stderr, "%.*s\n", (int) word->f_len, word->f_str); - while(!optim->done) { dberr_t error; trx_t* trx = optim->trx; From 2647fd101db922b1e6c7363124adfc03e81ab8a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 13 May 2019 17:16:42 +0300 Subject: [PATCH 4/5] MDEV-19445 heap-use-after-free related to innodb_ft_aux_table Try to fix the race conditions between SET GLOBAL innodb_ft_aux_table = ...; and access to the INFORMATION_SCHEMA tables that depend on this variable. innodb_ft_aux_table: Replaces fts_internal_tbl_name,fts_internal_tbl_name2. Just store the user-specified parameter as is. innodb_ft_aux_table_id: The table_id corresponding to SET GLOBAL innodb_ft_aux_table, or 0 if the table does not exist or does not contain FULLTEXT INDEX. If the table is renamed later, the INFORMATION_SCHEMA tables will continue to refer to the table. If the table is dropped or rebuilt, the INFORMATION_SCHEMA tables will not find the table. --- .../r/innodb_skip_innodb_is_tables.result | 10 ++ .../innodb_fts/r/innodb_ft_aux_table.result | 116 +++++++++++++++++ .../innodb_fts/t/innodb_ft_aux_table.opt | 6 + .../innodb_fts/t/innodb_ft_aux_table.test | 43 +++++++ storage/innobase/fts/fts0fts.cc | 5 - storage/innobase/handler/ha_innodb.cc | 119 +++++------------- storage/innobase/handler/i_s.cc | 105 ++++++++-------- storage/innobase/handler/i_s.h | 6 +- storage/innobase/include/fts0fts.h | 5 - storage/xtradb/fts/fts0fts.cc | 5 - storage/xtradb/handler/ha_innodb.cc | 119 +++++------------- storage/xtradb/handler/i_s.cc | 105 ++++++++-------- storage/xtradb/handler/i_s.h | 6 +- storage/xtradb/include/fts0fts.h | 5 - 14 files changed, 339 insertions(+), 316 deletions(-) create mode 100644 mysql-test/suite/innodb_fts/r/innodb_ft_aux_table.result create mode 100644 mysql-test/suite/innodb_fts/t/innodb_ft_aux_table.opt create mode 100644 mysql-test/suite/innodb_fts/t/innodb_ft_aux_table.test diff --git a/mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result b/mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result index 65e063979c4..285c1a35709 100644 --- a/mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result +++ b/mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result @@ -319,14 +319,24 @@ the www select * from information_schema.innodb_ft_deleted; DOC_ID +Warnings: +Warning 1012 InnoDB: SELECTing from INFORMATION_SCHEMA.innodb_ft_deleted but the InnoDB storage engine is not installed select * from information_schema.innodb_ft_being_deleted; DOC_ID +Warnings: +Warning 1012 InnoDB: SELECTing from INFORMATION_SCHEMA.innodb_ft_being_deleted but the InnoDB storage engine is not installed select * from information_schema.innodb_ft_index_cache; WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +Warnings: +Warning 1012 InnoDB: SELECTing from INFORMATION_SCHEMA.innodb_ft_index_cache but the InnoDB storage engine is not installed select * from information_schema.innodb_ft_index_table; WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +Warnings: +Warning 1012 InnoDB: SELECTing from INFORMATION_SCHEMA.innodb_ft_index_table but the InnoDB storage engine is not installed select * from information_schema.innodb_ft_config; KEY VALUE +Warnings: +Warning 1012 InnoDB: SELECTing from INFORMATION_SCHEMA.innodb_ft_config but the InnoDB storage engine is not installed select * from information_schema.innodb_buffer_page; POOL_ID BLOCK_ID SPACE PAGE_NUMBER PAGE_TYPE FLUSH_TYPE FIX_COUNT IS_HASHED NEWEST_MODIFICATION OLDEST_MODIFICATION ACCESS_TIME TABLE_NAME INDEX_NAME NUMBER_RECORDS DATA_SIZE COMPRESSED_SIZE PAGE_STATE IO_FIX IS_OLD FREE_PAGE_CLOCK Warnings: diff --git a/mysql-test/suite/innodb_fts/r/innodb_ft_aux_table.result b/mysql-test/suite/innodb_fts/r/innodb_ft_aux_table.result new file mode 100644 index 00000000000..cb233a466a5 --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/innodb_ft_aux_table.result @@ -0,0 +1,116 @@ +CREATE TABLE t1 (v VARCHAR(100), FULLTEXT INDEX (v)) ENGINE=InnoDB; +insert into t1 VALUES('First record'),('Second record'),('Third record'); +SET @save_ft_aux_table = @@GLOBAL.innodb_ft_aux_table; +SET GLOBAL innodb_ft_aux_table = 'test/t0'; +ERROR 42000: Variable 'innodb_ft_aux_table' can't be set to the value of 'test/t0' +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DEFAULT_STOPWORD; +value +a +about +an +are +as +at +be +by +com +de +en +for +from +how +i +in +is +it +la +of +on +or +that +the +this +to +was +what +when +where +who +will +with +und +the +www +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DELETED; +DOC_ID +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_BEING_DELETED; +DOC_ID +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_CONFIG; +KEY VALUE +SET GLOBAL innodb_ft_aux_table = 'test/t1'; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DELETED; +DOC_ID +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_BEING_DELETED; +DOC_ID +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +first 1 1 1 1 0 +record 1 3 3 1 6 +record 1 3 3 2 7 +record 1 3 3 3 6 +second 2 2 1 2 0 +third 3 3 1 3 0 +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_CONFIG; +KEY VALUE +optimize_checkpoint_limit 180 +synced_doc_id 0 +stopword_table_name +use_stopword 1 +SELECT @@GLOBAL.innodb_ft_aux_table; +@@GLOBAL.innodb_ft_aux_table +test/t1 +RENAME TABLE t1 TO t2; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DELETED; +DOC_ID +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_BEING_DELETED; +DOC_ID +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +first 1 1 1 1 0 +record 1 3 3 1 6 +record 1 3 3 2 7 +record 1 3 3 3 6 +second 2 2 1 2 0 +third 3 3 1 3 0 +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_CONFIG; +KEY VALUE +optimize_checkpoint_limit 180 +synced_doc_id 0 +stopword_table_name +use_stopword 1 +SELECT @@GLOBAL.innodb_ft_aux_table; +@@GLOBAL.innodb_ft_aux_table +test/t1 +DROP TABLE t2; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DELETED; +DOC_ID +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_BEING_DELETED; +DOC_ID +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_CONFIG; +KEY VALUE +SELECT @@GLOBAL.innodb_ft_aux_table; +@@GLOBAL.innodb_ft_aux_table +test/t1 +SET GLOBAL innodb_ft_aux_table = @save_ft_aux_table; diff --git a/mysql-test/suite/innodb_fts/t/innodb_ft_aux_table.opt b/mysql-test/suite/innodb_fts/t/innodb_ft_aux_table.opt new file mode 100644 index 00000000000..f85581275ed --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/innodb_ft_aux_table.opt @@ -0,0 +1,6 @@ +--innodb_ft_default_stopword +--innodb_ft_deleted +--innodb_ft_being_deleted +--innodb_ft_index_cache +--innodb_ft_index_table +--innodb_ft_config diff --git a/mysql-test/suite/innodb_fts/t/innodb_ft_aux_table.test b/mysql-test/suite/innodb_fts/t/innodb_ft_aux_table.test new file mode 100644 index 00000000000..48964aef4fd --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/innodb_ft_aux_table.test @@ -0,0 +1,43 @@ +--source include/have_innodb.inc + +CREATE TABLE t1 (v VARCHAR(100), FULLTEXT INDEX (v)) ENGINE=InnoDB; + +insert into t1 VALUES('First record'),('Second record'),('Third record'); + +SET @save_ft_aux_table = @@GLOBAL.innodb_ft_aux_table; + +connect (con1,localhost,root,,); +--error ER_WRONG_VALUE_FOR_VAR +SET GLOBAL innodb_ft_aux_table = 'test/t0'; +connection default; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DEFAULT_STOPWORD; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DELETED; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_BEING_DELETED; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_CONFIG; +connection con1; +SET GLOBAL innodb_ft_aux_table = 'test/t1'; +disconnect con1; +connection default; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DELETED; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_BEING_DELETED; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_CONFIG; +SELECT @@GLOBAL.innodb_ft_aux_table; +RENAME TABLE t1 TO t2; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DELETED; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_BEING_DELETED; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_CONFIG; +SELECT @@GLOBAL.innodb_ft_aux_table; +DROP TABLE t2; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DELETED; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_BEING_DELETED; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_CONFIG; +SELECT @@GLOBAL.innodb_ft_aux_table; +SET GLOBAL innodb_ft_aux_table = @save_ft_aux_table; diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index bfb469b1e2d..beed1b99d6c 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -107,11 +107,6 @@ UNIV_INTERN mysql_pfs_key_t fts_doc_id_mutex_key; UNIV_INTERN mysql_pfs_key_t fts_pll_tokenize_mutex_key; #endif /* UNIV_PFS_MUTEX */ -/** variable to record innodb_fts_internal_tbl_name for information -schema table INNODB_FTS_INSERTED etc. */ -UNIV_INTERN char* fts_internal_tbl_name = NULL; -UNIV_INTERN char* fts_internal_tbl_name2 = NULL; - /** InnoDB default stopword list: There are different versions of stopwords, the stop words listed below comes from "Google Stopword" list. Reference: diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 8b007bb0b38..cb6ec20e0d6 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -17118,98 +17118,36 @@ innodb_stopword_table_validate( return(ret); } -/*************************************************************//** -Check whether valid argument given to "innodb_fts_internal_tbl_name" -This function is registered as a callback with MySQL. -@return 0 for valid stopword table */ -static -int -innodb_internal_table_validate( -/*===========================*/ - THD* thd, /*!< in: thread handle */ - struct st_mysql_sys_var* var, /*!< in: pointer to system - variable */ - void* save, /*!< out: immediate result - for update function */ - struct st_mysql_value* value) /*!< in: incoming string */ +/** The latest assigned innodb_ft_aux_table name */ +static char* innodb_ft_aux_table; + +/** Update innodb_ft_aux_table_id on SET GLOBAL innodb_ft_aux_table. +@param[out] save new value of innodb_ft_aux_table +@param[in] value user-specified value */ +static int innodb_ft_aux_table_validate(THD*, st_mysql_sys_var*, + void* save, st_mysql_value* value) { - const char* table_name; - char buff[STRING_BUFFER_USUAL_SIZE]; - int len = sizeof(buff); - int ret = 1; - dict_table_t* user_table; + char buf[STRING_BUFFER_USUAL_SIZE]; + int len = sizeof buf; - ut_a(save != NULL); - ut_a(value != NULL); - - table_name = value->val_str(value, buff, &len); - - if (!table_name) { - *static_cast(save) = NULL; - return(0); - } - - user_table = dict_table_open_on_name( - table_name, FALSE, TRUE, DICT_ERR_IGNORE_NONE); - - if (user_table) { - if (dict_table_has_fts_index(user_table)) { - *static_cast(save) = table_name; - ret = 0; + if (const char* table_name = value->val_str(value, buf, &len)) { + if (dict_table_t* table = dict_table_open_on_name( + table_name, FALSE, TRUE, DICT_ERR_IGNORE_NONE)) { + const table_id_t id = dict_table_has_fts_index(table) + ? table->id : 0; + dict_table_close(table, FALSE, FALSE); + if (id) { + innodb_ft_aux_table_id = id; + *static_cast(save) = table_name; + return 0; + } } - dict_table_close(user_table, FALSE, TRUE); - - DBUG_EXECUTE_IF("innodb_evict_autoinc_table", - mutex_enter(&dict_sys->mutex); - dict_table_remove_from_cache_low(user_table, TRUE); - mutex_exit(&dict_sys->mutex); - ); - } - - return(ret); -} - -/****************************************************************//** -Update global variable "fts_internal_tbl_name" with the "saved" -stopword table name value. This function is registered as a callback -with MySQL. */ -static -void -innodb_internal_table_update( -/*=========================*/ - THD* thd, /*!< in: thread handle */ - struct st_mysql_sys_var* var, /*!< in: pointer to - system variable */ - void* var_ptr,/*!< out: where the - formal string goes */ - const void* save) /*!< in: immediate result - from check function */ -{ - const char* table_name; - char* old; - - ut_a(save != NULL); - ut_a(var_ptr != NULL); - - table_name = *static_cast(save); - old = *(char**) var_ptr; - - if (table_name) { - *(char**) var_ptr = my_strdup(table_name, MYF(0)); + return 1; } else { - *(char**) var_ptr = NULL; - } - - if (old) { - my_free(old); - } - - fts_internal_tbl_name2 = *(char**) var_ptr; - if (fts_internal_tbl_name2 == NULL) { - fts_internal_tbl_name = const_cast("default"); - } else { - fts_internal_tbl_name = fts_internal_tbl_name2; + *static_cast(save) = NULL; + innodb_ft_aux_table_id = 0; + return 0; } } @@ -19476,11 +19414,10 @@ static MYSQL_SYSVAR_BOOL(disable_sort_file_cache, srv_disable_sort_file_cache, "Whether to disable OS system file cache for sort I/O", NULL, NULL, FALSE); -static MYSQL_SYSVAR_STR(ft_aux_table, fts_internal_tbl_name2, - PLUGIN_VAR_NOCMDARG, +static MYSQL_SYSVAR_STR(ft_aux_table, innodb_ft_aux_table, + PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_MEMALLOC, "FTS internal auxiliary table to be checked", - innodb_internal_table_validate, - innodb_internal_table_update, NULL); + innodb_ft_aux_table_validate, NULL, NULL); static MYSQL_SYSVAR_ULONG(ft_cache_size, fts_max_cache_size, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index 9eae8ded633..2729a755570 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -64,6 +64,9 @@ Modified Dec 29, 2014 Jan Lindström (Added sys_semaphore_waits) #include "fil0fil.h" #include "fil0crypt.h" +/** The latest successfully looked up innodb_fts_aux_table */ +UNIV_INTERN table_id_t innodb_ft_aux_table_id; + /** structure associates a name string with a file page type and/or buffer page state. */ struct buf_page_desc_t{ @@ -2934,25 +2937,21 @@ i_s_fts_deleted_generic_fill( DBUG_RETURN(0); } - if (!fts_internal_tbl_name) { - DBUG_RETURN(0); - } + RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name); - /* Prevent DDL to drop fts aux tables. */ + /* Prevent DROP of the internal tables for fulltext indexes. + FIXME: acquire DDL-blocking MDL on the user table name! */ rw_lock_s_lock(&dict_operation_lock); - user_table = dict_table_open_on_name( - fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE); + user_table = dict_table_open_on_id( + innodb_ft_aux_table_id, FALSE, DICT_TABLE_OP_NORMAL); if (!user_table) { rw_lock_s_unlock(&dict_operation_lock); - DBUG_RETURN(0); } else if (!dict_table_has_fts_index(user_table)) { dict_table_close(user_table, FALSE, FALSE); - rw_lock_s_unlock(&dict_operation_lock); - DBUG_RETURN(0); } @@ -2967,6 +2966,12 @@ i_s_fts_deleted_generic_fill( fts_table_fetch_doc_ids(trx, &fts_table, deleted); + dict_table_close(user_table, FALSE, FALSE); + + rw_lock_s_unlock(&dict_operation_lock); + + trx_free_for_background(trx); + fields = table->field; int ret = 0; @@ -2981,14 +2986,8 @@ i_s_fts_deleted_generic_fill( BREAK_IF(ret = schema_table_store_record(thd, table)); } - trx_free_for_background(trx); - fts_doc_ids_free(deleted); - dict_table_close(user_table, FALSE, FALSE); - - rw_lock_s_unlock(&dict_operation_lock); - DBUG_RETURN(ret); } @@ -3348,32 +3347,33 @@ i_s_fts_index_cache_fill( DBUG_RETURN(0); } - if (!fts_internal_tbl_name) { - DBUG_RETURN(0); - } + RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name); - user_table = dict_table_open_on_name( - fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE); + /* Prevent DROP of the internal tables for fulltext indexes. + FIXME: acquire DDL-blocking MDL on the user table name! */ + rw_lock_s_lock(&dict_operation_lock); + + user_table = dict_table_open_on_id( + innodb_ft_aux_table_id, FALSE, DICT_TABLE_OP_NORMAL); if (!user_table) { +no_fts: + rw_lock_s_unlock(&dict_operation_lock); DBUG_RETURN(0); } - if (user_table->fts == NULL || user_table->fts->cache == NULL) { + if (!user_table->fts || !user_table->fts->cache) { dict_table_close(user_table, FALSE, FALSE); - - DBUG_RETURN(0); + goto no_fts; } cache = user_table->fts->cache; - ut_a(cache); - int ret = 0; fts_string_t conv_str; - conv_str.f_len = system_charset_info->mbmaxlen - * FTS_MAX_WORD_LEN_IN_CHAR; - conv_str.f_str = static_cast(ut_malloc(conv_str.f_len)); + byte word[HA_FT_MAXBYTELEN + 1]; + conv_str.f_len = sizeof word; + conv_str.f_str = word; for (ulint i = 0; i < ib_vector_size(cache->indexes); i++) { fts_index_cache_t* index_cache; @@ -3385,9 +3385,8 @@ i_s_fts_index_cache_fill( index_cache, thd, &conv_str, tables)); } - ut_free(conv_str.f_str); - dict_table_close(user_table, FALSE, FALSE); + rw_lock_s_unlock(&dict_operation_lock); DBUG_RETURN(ret); } @@ -3801,19 +3800,17 @@ i_s_fts_index_table_fill( DBUG_RETURN(0); } - if (!fts_internal_tbl_name) { - DBUG_RETURN(0); - } + RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name); - /* Prevent DDL to drop fts aux tables. */ + /* Prevent DROP of the internal tables for fulltext indexes. + FIXME: acquire DDL-blocking MDL on the user table name! */ rw_lock_s_lock(&dict_operation_lock); - user_table = dict_table_open_on_name( - fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE); + user_table = dict_table_open_on_id( + innodb_ft_aux_table_id, FALSE, DICT_TABLE_OP_NORMAL); if (!user_table) { rw_lock_s_unlock(&dict_operation_lock); - DBUG_RETURN(0); } @@ -3966,32 +3963,28 @@ i_s_fts_config_fill( DBUG_RETURN(0); } - if (!fts_internal_tbl_name) { - DBUG_RETURN(0); - } + RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name); - DEBUG_SYNC_C("i_s_fts_config_fille_check"); - - fields = table->field; - - /* Prevent DDL to drop fts aux tables. */ + /* Prevent DROP of the internal tables for fulltext indexes. + FIXME: acquire DDL-blocking MDL on the user table name! */ rw_lock_s_lock(&dict_operation_lock); - user_table = dict_table_open_on_name( - fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE); + user_table = dict_table_open_on_id( + innodb_ft_aux_table_id, FALSE, DICT_TABLE_OP_NORMAL); if (!user_table) { +no_fts: rw_lock_s_unlock(&dict_operation_lock); - - DBUG_RETURN(0); - } else if (!dict_table_has_fts_index(user_table)) { - dict_table_close(user_table, FALSE, FALSE); - - rw_lock_s_unlock(&dict_operation_lock); - DBUG_RETURN(0); } + if (!dict_table_has_fts_index(user_table)) { + dict_table_close(user_table, FALSE, FALSE); + goto no_fts; + } + + fields = table->field; + trx = trx_allocate_for_background(); trx->op_info = "Select for FTS CONFIG TABLE"; @@ -4043,12 +4036,12 @@ i_s_fts_config_fill( fts_sql_commit(trx); - trx_free_for_background(trx); - dict_table_close(user_table, FALSE, FALSE); rw_lock_s_unlock(&dict_operation_lock); + trx_free_for_background(trx); + DBUG_RETURN(ret); } diff --git a/storage/innobase/handler/i_s.h b/storage/innobase/handler/i_s.h index 596774a0b50..9dc025fa649 100644 --- a/storage/innobase/handler/i_s.h +++ b/storage/innobase/handler/i_s.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2007, 2013, Oracle and/or its affiliates. All Rights Reserved. -Copyrigth (c) 2014, 2017, MariaDB Corporation. +Copyrigth (c) 2014, 2019, MariaDB Corporation. 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 @@ -27,6 +27,7 @@ Modified Dec 29, 2014 Jan Lindström #ifndef i_s_h #define i_s_h +#include "dict0types.h" const char plugin_author[] = "Oracle Corporation"; const char maria_plugin_author[] = "MariaDB Corporation"; @@ -64,6 +65,9 @@ extern struct st_maria_plugin i_s_innodb_tablespaces_encryption; extern struct st_maria_plugin i_s_innodb_tablespaces_scrubbing; extern struct st_maria_plugin i_s_innodb_sys_semaphore_waits; +/** The latest successfully looked up innodb_fts_aux_table */ +extern table_id_t innodb_ft_aux_table_id; + /** maximum number of buffer page info we would cache. */ #define MAX_BUF_INFO_CACHED 10000 diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h index 19a1058dc0c..a1fab659732 100644 --- a/storage/innobase/include/fts0fts.h +++ b/storage/innobase/include/fts0fts.h @@ -367,11 +367,6 @@ extern bool fts_need_sync; /** Maximum possible Fulltext word length (in characters) */ #define FTS_MAX_WORD_LEN_IN_CHAR HA_FT_MAXCHARLEN -/** Variable specifying the table that has Fulltext index to display its -content through information schema table */ -extern char* fts_internal_tbl_name; -extern char* fts_internal_tbl_name2; - #define fts_que_graph_free(graph) \ do { \ mutex_enter(&dict_sys->mutex); \ diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc index bfb469b1e2d..beed1b99d6c 100644 --- a/storage/xtradb/fts/fts0fts.cc +++ b/storage/xtradb/fts/fts0fts.cc @@ -107,11 +107,6 @@ UNIV_INTERN mysql_pfs_key_t fts_doc_id_mutex_key; UNIV_INTERN mysql_pfs_key_t fts_pll_tokenize_mutex_key; #endif /* UNIV_PFS_MUTEX */ -/** variable to record innodb_fts_internal_tbl_name for information -schema table INNODB_FTS_INSERTED etc. */ -UNIV_INTERN char* fts_internal_tbl_name = NULL; -UNIV_INTERN char* fts_internal_tbl_name2 = NULL; - /** InnoDB default stopword list: There are different versions of stopwords, the stop words listed below comes from "Google Stopword" list. Reference: diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index df925327c1c..aa17eb6a5ea 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -17839,98 +17839,36 @@ innodb_stopword_table_validate( return(ret); } -/*************************************************************//** -Check whether valid argument given to "innodb_fts_internal_tbl_name" -This function is registered as a callback with MySQL. -@return 0 for valid stopword table */ -static -int -innodb_internal_table_validate( -/*===========================*/ - THD* thd, /*!< in: thread handle */ - struct st_mysql_sys_var* var, /*!< in: pointer to system - variable */ - void* save, /*!< out: immediate result - for update function */ - struct st_mysql_value* value) /*!< in: incoming string */ +/** The latest assigned innodb_ft_aux_table name */ +static char* innodb_ft_aux_table; + +/** Update innodb_ft_aux_table_id on SET GLOBAL innodb_ft_aux_table. +@param[out] save new value of innodb_ft_aux_table +@param[in] value user-specified value */ +static int innodb_ft_aux_table_validate(THD*, st_mysql_sys_var*, + void* save, st_mysql_value* value) { - const char* table_name; - char buff[STRING_BUFFER_USUAL_SIZE]; - int len = sizeof(buff); - int ret = 1; - dict_table_t* user_table; + char buf[STRING_BUFFER_USUAL_SIZE]; + int len = sizeof buf; - ut_a(save != NULL); - ut_a(value != NULL); - - table_name = value->val_str(value, buff, &len); - - if (!table_name) { - *static_cast(save) = NULL; - return(0); - } - - user_table = dict_table_open_on_name( - table_name, FALSE, TRUE, DICT_ERR_IGNORE_NONE); - - if (user_table) { - if (dict_table_has_fts_index(user_table)) { - *static_cast(save) = table_name; - ret = 0; + if (const char* table_name = value->val_str(value, buf, &len)) { + if (dict_table_t* table = dict_table_open_on_name( + table_name, FALSE, TRUE, DICT_ERR_IGNORE_NONE)) { + const table_id_t id = dict_table_has_fts_index(table) + ? table->id : 0; + dict_table_close(table, FALSE, FALSE); + if (id) { + innodb_ft_aux_table_id = id; + *static_cast(save) = table_name; + return 0; + } } - dict_table_close(user_table, FALSE, TRUE); - - DBUG_EXECUTE_IF("innodb_evict_autoinc_table", - mutex_enter(&dict_sys->mutex); - dict_table_remove_from_cache_low(user_table, TRUE); - mutex_exit(&dict_sys->mutex); - ); - } - - return(ret); -} - -/****************************************************************//** -Update global variable "fts_internal_tbl_name" with the "saved" -stopword table name value. This function is registered as a callback -with MySQL. */ -static -void -innodb_internal_table_update( -/*=========================*/ - THD* thd, /*!< in: thread handle */ - struct st_mysql_sys_var* var, /*!< in: pointer to - system variable */ - void* var_ptr,/*!< out: where the - formal string goes */ - const void* save) /*!< in: immediate result - from check function */ -{ - const char* table_name; - char* old; - - ut_a(save != NULL); - ut_a(var_ptr != NULL); - - table_name = *static_cast(save); - old = *(char**) var_ptr; - - if (table_name) { - *(char**) var_ptr = my_strdup(table_name, MYF(0)); + return 1; } else { - *(char**) var_ptr = NULL; - } - - if (old) { - my_free(old); - } - - fts_internal_tbl_name2 = *(char**) var_ptr; - if (fts_internal_tbl_name2 == NULL) { - fts_internal_tbl_name = const_cast("default"); - } else { - fts_internal_tbl_name = fts_internal_tbl_name2; + *static_cast(save) = NULL; + innodb_ft_aux_table_id = 0; + return 0; } } @@ -20693,11 +20631,10 @@ static MYSQL_SYSVAR_BOOL(disable_sort_file_cache, srv_disable_sort_file_cache, "Whether to disable OS system file cache for sort I/O", NULL, NULL, FALSE); -static MYSQL_SYSVAR_STR(ft_aux_table, fts_internal_tbl_name2, - PLUGIN_VAR_NOCMDARG, +static MYSQL_SYSVAR_STR(ft_aux_table, innodb_ft_aux_table, + PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_MEMALLOC, "FTS internal auxiliary table to be checked", - innodb_internal_table_validate, - innodb_internal_table_update, NULL); + innodb_ft_aux_table_validate, NULL, NULL); static MYSQL_SYSVAR_ULONG(ft_cache_size, fts_max_cache_size, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc index e1b5b1b700f..8eb53502da8 100644 --- a/storage/xtradb/handler/i_s.cc +++ b/storage/xtradb/handler/i_s.cc @@ -75,6 +75,9 @@ Modified Dec 29, 2014 Jan Lindström (Added sys_semaphore_waits) #include "fil0fil.h" #include "fil0crypt.h" +/** The latest successfully looked up innodb_fts_aux_table */ +UNIV_INTERN table_id_t innodb_ft_aux_table_id; + /** structure associates a name string with a file page type and/or buffer page state. */ struct buf_page_desc_t{ @@ -2928,25 +2931,21 @@ i_s_fts_deleted_generic_fill( DBUG_RETURN(0); } - if (!fts_internal_tbl_name) { - DBUG_RETURN(0); - } + RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name); - /* Prevent DDL to drop fts aux tables. */ + /* Prevent DROP of the internal tables for fulltext indexes. + FIXME: acquire DDL-blocking MDL on the user table name! */ rw_lock_s_lock(&dict_operation_lock); - user_table = dict_table_open_on_name( - fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE); + user_table = dict_table_open_on_id( + innodb_ft_aux_table_id, FALSE, DICT_TABLE_OP_NORMAL); if (!user_table) { rw_lock_s_unlock(&dict_operation_lock); - DBUG_RETURN(0); } else if (!dict_table_has_fts_index(user_table)) { dict_table_close(user_table, FALSE, FALSE); - rw_lock_s_unlock(&dict_operation_lock); - DBUG_RETURN(0); } @@ -2961,6 +2960,12 @@ i_s_fts_deleted_generic_fill( fts_table_fetch_doc_ids(trx, &fts_table, deleted); + dict_table_close(user_table, FALSE, FALSE); + + rw_lock_s_unlock(&dict_operation_lock); + + trx_free_for_background(trx); + fields = table->field; int ret = 0; @@ -2975,14 +2980,8 @@ i_s_fts_deleted_generic_fill( BREAK_IF(ret = schema_table_store_record(thd, table)); } - trx_free_for_background(trx); - fts_doc_ids_free(deleted); - dict_table_close(user_table, FALSE, FALSE); - - rw_lock_s_unlock(&dict_operation_lock); - DBUG_RETURN(ret); } @@ -3340,32 +3339,33 @@ i_s_fts_index_cache_fill( DBUG_RETURN(0); } - if (!fts_internal_tbl_name) { - DBUG_RETURN(0); - } + RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name); - user_table = dict_table_open_on_name( - fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE); + /* Prevent DROP of the internal tables for fulltext indexes. + FIXME: acquire DDL-blocking MDL on the user table name! */ + rw_lock_s_lock(&dict_operation_lock); + + user_table = dict_table_open_on_id( + innodb_ft_aux_table_id, FALSE, DICT_TABLE_OP_NORMAL); if (!user_table) { +no_fts: + rw_lock_s_unlock(&dict_operation_lock); DBUG_RETURN(0); } - if (user_table->fts == NULL || user_table->fts->cache == NULL) { + if (!user_table->fts || !user_table->fts->cache) { dict_table_close(user_table, FALSE, FALSE); - - DBUG_RETURN(0); + goto no_fts; } cache = user_table->fts->cache; - ut_a(cache); - int ret = 0; fts_string_t conv_str; - conv_str.f_len = system_charset_info->mbmaxlen - * FTS_MAX_WORD_LEN_IN_CHAR; - conv_str.f_str = static_cast(ut_malloc(conv_str.f_len)); + byte word[HA_FT_MAXBYTELEN + 1]; + conv_str.f_len = sizeof word; + conv_str.f_str = word; for (ulint i = 0; i < ib_vector_size(cache->indexes); i++) { fts_index_cache_t* index_cache; @@ -3377,9 +3377,8 @@ i_s_fts_index_cache_fill( index_cache, thd, &conv_str, tables)); } - ut_free(conv_str.f_str); - dict_table_close(user_table, FALSE, FALSE); + rw_lock_s_unlock(&dict_operation_lock); DBUG_RETURN(ret); } @@ -3792,19 +3791,17 @@ i_s_fts_index_table_fill( DBUG_RETURN(0); } - if (!fts_internal_tbl_name) { - DBUG_RETURN(0); - } + RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name); - /* Prevent DDL to drop fts aux tables. */ + /* Prevent DROP of the internal tables for fulltext indexes. + FIXME: acquire DDL-blocking MDL on the user table name! */ rw_lock_s_lock(&dict_operation_lock); - user_table = dict_table_open_on_name( - fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE); + user_table = dict_table_open_on_id( + innodb_ft_aux_table_id, FALSE, DICT_TABLE_OP_NORMAL); if (!user_table) { rw_lock_s_unlock(&dict_operation_lock); - DBUG_RETURN(0); } @@ -3956,32 +3953,28 @@ i_s_fts_config_fill( DBUG_RETURN(0); } - if (!fts_internal_tbl_name) { - DBUG_RETURN(0); - } + RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name); - DEBUG_SYNC_C("i_s_fts_config_fille_check"); - - fields = table->field; - - /* Prevent DDL to drop fts aux tables. */ + /* Prevent DROP of the internal tables for fulltext indexes. + FIXME: acquire DDL-blocking MDL on the user table name! */ rw_lock_s_lock(&dict_operation_lock); - user_table = dict_table_open_on_name( - fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE); + user_table = dict_table_open_on_id( + innodb_ft_aux_table_id, FALSE, DICT_TABLE_OP_NORMAL); if (!user_table) { +no_fts: rw_lock_s_unlock(&dict_operation_lock); - - DBUG_RETURN(0); - } else if (!dict_table_has_fts_index(user_table)) { - dict_table_close(user_table, FALSE, FALSE); - - rw_lock_s_unlock(&dict_operation_lock); - DBUG_RETURN(0); } + if (!dict_table_has_fts_index(user_table)) { + dict_table_close(user_table, FALSE, FALSE); + goto no_fts; + } + + fields = table->field; + trx = trx_allocate_for_background(); trx->op_info = "Select for FTS CONFIG TABLE"; @@ -4033,12 +4026,12 @@ i_s_fts_config_fill( fts_sql_commit(trx); - trx_free_for_background(trx); - dict_table_close(user_table, FALSE, FALSE); rw_lock_s_unlock(&dict_operation_lock); + trx_free_for_background(trx); + DBUG_RETURN(ret); } diff --git a/storage/xtradb/handler/i_s.h b/storage/xtradb/handler/i_s.h index 0353e426365..81d6977954d 100644 --- a/storage/xtradb/handler/i_s.h +++ b/storage/xtradb/handler/i_s.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2007, 2013, Oracle and/or its affiliates. All Rights Reserved. -Copyrigth (c) 2014, 2017, MariaDB Corporation. +Copyrigth (c) 2014, 2019, MariaDB Corporation. 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 @@ -27,6 +27,7 @@ Modified Dec 29, 2014 Jan Lindström #ifndef i_s_h #define i_s_h +#include "dict0types.h" const char plugin_author[] = "Oracle Corporation"; const char maria_plugin_author[] = "MariaDB Corporation"; @@ -69,6 +70,9 @@ extern struct st_maria_plugin i_s_innodb_tablespaces_scrubbing; extern struct st_mysql_plugin i_s_innodb_sys_semaphore_waits; extern struct st_mysql_plugin i_s_innodb_changed_page_bitmaps; +/** The latest successfully looked up innodb_fts_aux_table */ +extern table_id_t innodb_ft_aux_table_id; + /** maximum number of buffer page info we would cache. */ #define MAX_BUF_INFO_CACHED 10000 diff --git a/storage/xtradb/include/fts0fts.h b/storage/xtradb/include/fts0fts.h index 19a1058dc0c..a1fab659732 100644 --- a/storage/xtradb/include/fts0fts.h +++ b/storage/xtradb/include/fts0fts.h @@ -367,11 +367,6 @@ extern bool fts_need_sync; /** Maximum possible Fulltext word length (in characters) */ #define FTS_MAX_WORD_LEN_IN_CHAR HA_FT_MAXCHARLEN -/** Variable specifying the table that has Fulltext index to display its -content through information schema table */ -extern char* fts_internal_tbl_name; -extern char* fts_internal_tbl_name2; - #define fts_que_graph_free(graph) \ do { \ mutex_enter(&dict_sys->mutex); \ From b93ecea65cc33969cf561b941f00a7ac10d3e29a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 13 May 2019 18:26:59 +0300 Subject: [PATCH 5/5] Remove unnecessary pointer indirection for rw_lock_t In MySQL 5.7.8 an extra level of pointer indirection was added to dict_operation_lock and some other rw_lock_t without solid justification, in mysql/mysql-server@52720f1772f9f424bf3dd62fa9c214dd608cd036. Let us revert that change and remove the rather useless rw_lock_t constructor and destructor and the magic_n field. In this way, some unnecessary pointer dereferences and heap allocation will be avoided and debugging might be a little easier. --- storage/innobase/dict/dict0crea.cc | 4 +-- storage/innobase/dict/dict0defrag_bg.cc | 10 +++--- storage/innobase/dict/dict0dict.cc | 32 +++++++---------- storage/innobase/dict/dict0load.cc | 10 +++--- storage/innobase/dict/dict0stats.cc | 42 +++++++++++------------ storage/innobase/fil/fil0fil.cc | 2 +- storage/innobase/handler/ha_innodb.cc | 2 +- storage/innobase/handler/handler0alter.cc | 16 ++++----- storage/innobase/handler/i_s.cc | 34 ++++++++---------- storage/innobase/include/dict0dict.h | 2 +- storage/innobase/include/sync0rw.h | 22 +----------- storage/innobase/row/row0import.cc | 8 ++--- storage/innobase/row/row0ins.cc | 2 +- storage/innobase/row/row0log.cc | 4 +-- storage/innobase/row/row0merge.cc | 6 ++-- storage/innobase/row/row0mysql.cc | 14 ++++---- storage/innobase/row/row0purge.cc | 14 ++++---- storage/innobase/row/row0trunc.cc | 2 +- storage/innobase/row/row0umod.cc | 4 +-- storage/innobase/srv/srv0srv.cc | 4 +-- storage/innobase/sync/sync0rw.cc | 12 +------ storage/innobase/trx/trx0i_s.cc | 30 +++++++--------- storage/innobase/trx/trx0purge.cc | 4 --- 23 files changed, 115 insertions(+), 165 deletions(-) diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc index 342bafab92c..86038a3710a 100644 --- a/storage/innobase/dict/dict0crea.cc +++ b/storage/innobase/dict/dict0crea.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2019, MariaDB Corporation. 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 @@ -2471,7 +2471,7 @@ dict_delete_tablespace_and_datafiles( { dberr_t err = DB_SUCCESS; - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); ut_ad(mutex_own(&dict_sys->mutex)); ut_ad(srv_sys_tablespaces_open); diff --git a/storage/innobase/dict/dict0defrag_bg.cc b/storage/innobase/dict/dict0defrag_bg.cc index 25175c7deb5..f1ea8ae30d2 100644 --- a/storage/innobase/dict/dict0defrag_bg.cc +++ b/storage/innobase/dict/dict0defrag_bg.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2016, 2018, MariaDB Corporation. +Copyright (c) 2016, 2019, MariaDB Corporation. 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 @@ -244,7 +244,7 @@ dict_stats_save_defrag_summary( return DB_SUCCESS; } - rw_lock_x_lock(dict_operation_lock); + rw_lock_x_lock(&dict_operation_lock); mutex_enter(&dict_sys->mutex); ret = dict_stats_save_index_stat(index, now, "n_pages_freed", @@ -255,7 +255,7 @@ dict_stats_save_defrag_summary( NULL); mutex_exit(&dict_sys->mutex); - rw_lock_x_unlock(dict_operation_lock); + rw_lock_x_unlock(&dict_operation_lock); return (ret); } @@ -295,7 +295,7 @@ dict_stats_save_defrag_stats( return DB_SUCCESS; } - rw_lock_x_lock(dict_operation_lock); + rw_lock_x_lock(&dict_operation_lock); mutex_enter(&dict_sys->mutex); ret = dict_stats_save_index_stat(index, now, "n_page_split", @@ -328,7 +328,7 @@ dict_stats_save_defrag_stats( end: mutex_exit(&dict_sys->mutex); - rw_lock_x_unlock(dict_operation_lock); + rw_lock_x_unlock(&dict_operation_lock); return (ret); } diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 0919b212c5b..51d3db39e16 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -95,7 +95,7 @@ in S-mode; we cannot trust that MySQL protects implicit or background operations a table drop since MySQL does not know of them; therefore we need this; NOTE: a transaction which reserves this must keep book on the mode in trx_t::dict_operation_lock_mode */ -rw_lock_t* dict_operation_lock; +rw_lock_t dict_operation_lock; /** Percentage of compression failures that are allowed in a single round */ @@ -554,7 +554,7 @@ dict_table_close_and_drop( dberr_t err = DB_SUCCESS; ut_ad(mutex_own(&dict_sys->mutex)); - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); ut_ad(trx->dict_operation != TRX_DICT_OP_NONE); ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE)); @@ -1081,9 +1081,6 @@ void dict_init(void) /*===========*/ { - dict_operation_lock = static_cast( - ut_zalloc_nokey(sizeof(*dict_operation_lock))); - dict_sys = static_cast(ut_zalloc_nokey(sizeof(*dict_sys))); UT_LIST_INIT(dict_sys->table_LRU, &dict_table_t::table_LRU); @@ -1100,7 +1097,7 @@ dict_init(void) / (DICT_POOL_PER_TABLE_HASH * UNIV_WORD_SIZE)); rw_lock_create(dict_operation_lock_key, - dict_operation_lock, SYNC_DICT_OPERATION); + &dict_operation_lock, SYNC_DICT_OPERATION); if (!srv_read_only_mode) { dict_foreign_err_file = os_file_create_tmpfile(NULL); @@ -1349,7 +1346,7 @@ dict_table_can_be_evicted( dict_table_t* table) /*!< in: table to test */ { ut_ad(mutex_own(&dict_sys->mutex)); - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); ut_a(table->can_be_evicted); ut_a(table->foreign_set.empty()); @@ -1417,7 +1414,7 @@ dict_make_room_in_cache( ut_a(pct_check > 0); ut_a(pct_check <= 100); ut_ad(mutex_own(&dict_sys->mutex)); - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); ut_ad(dict_lru_validate()); i = len = UT_LIST_GET_LEN(dict_sys->table_LRU); @@ -2076,7 +2073,7 @@ dict_table_remove_from_cache_low( trx_t* trx = trx_allocate_for_background(); ut_ad(mutex_own(&dict_sys->mutex)); - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); /* Mimic row_mysql_lock_data_dictionary(). */ trx->dict_operation_lock_mode = RW_X_LATCH; @@ -6068,7 +6065,7 @@ dict_index_set_merge_threshold( ut_ad(!dict_table_is_comp(dict_sys->sys_tables)); ut_ad(!dict_table_is_comp(dict_sys->sys_indexes)); - rw_lock_x_lock(dict_operation_lock); + rw_lock_x_lock(&dict_operation_lock); mutex_enter(&(dict_sys->mutex)); heap = mem_heap_create(sizeof(dtuple_t) + 2 * (sizeof(dfield_t) @@ -6118,7 +6115,7 @@ dict_index_set_merge_threshold( mem_heap_free(heap); mutex_exit(&(dict_sys->mutex)); - rw_lock_x_unlock(dict_operation_lock); + rw_lock_x_unlock(&dict_operation_lock); } #ifdef UNIV_DEBUG @@ -6713,10 +6710,7 @@ dict_close(void) mutex_free(&dict_sys->mutex); - rw_lock_free(dict_operation_lock); - - ut_free(dict_operation_lock); - dict_operation_lock = NULL; + rw_lock_free(&dict_operation_lock); mutex_free(&dict_foreign_err_mutex); @@ -7122,7 +7116,7 @@ dict_space_is_empty( mtr_t mtr; bool found = false; - rw_lock_x_lock(dict_operation_lock); + rw_lock_x_lock(&dict_operation_lock); mutex_enter(&dict_sys->mutex); mtr_start(&mtr); @@ -7145,7 +7139,7 @@ dict_space_is_empty( mtr_commit(&mtr); mutex_exit(&dict_sys->mutex); - rw_lock_x_unlock(dict_operation_lock); + rw_lock_x_unlock(&dict_operation_lock); return(!found); } @@ -7163,7 +7157,7 @@ dict_space_get_id( ulint name_len = strlen(name); ulint id = ULINT_UNDEFINED; - rw_lock_x_lock(dict_operation_lock); + rw_lock_x_lock(&dict_operation_lock); mutex_enter(&dict_sys->mutex); mtr_start(&mtr); @@ -7194,7 +7188,7 @@ dict_space_get_id( mtr_commit(&mtr); mutex_exit(&dict_sys->mutex); - rw_lock_x_unlock(dict_operation_lock); + rw_lock_x_unlock(&dict_operation_lock); return(id); } diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc index ca0ee95dbf3..ae5bbac9118 100644 --- a/storage/innobase/dict/dict0load.cc +++ b/storage/innobase/dict/dict0load.cc @@ -903,7 +903,7 @@ dict_update_filepath( dberr_t err = DB_SUCCESS; trx_t* trx; - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); ut_ad(mutex_own(&dict_sys->mutex)); trx = trx_allocate_for_background(); @@ -971,7 +971,7 @@ dict_replace_tablespace_and_filepath( DBUG_EXECUTE_IF("innodb_fail_to_update_tablespace_dict", return(DB_INTERRUPTED);); - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); ut_ad(mutex_own(&dict_sys->mutex)); ut_ad(filepath); @@ -1371,7 +1371,7 @@ static ulint dict_check_sys_tables() DBUG_ENTER("dict_check_sys_tables"); - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); ut_ad(mutex_own(&dict_sys->mutex)); mtr_start(&mtr); @@ -1516,7 +1516,7 @@ void dict_check_tablespaces_and_store_max_id() DBUG_ENTER("dict_check_tablespaces_and_store_max_id"); - rw_lock_x_lock(dict_operation_lock); + rw_lock_x_lock(&dict_operation_lock); mutex_enter(&dict_sys->mutex); /* Initialize the max space_id from sys header */ @@ -1535,7 +1535,7 @@ void dict_check_tablespaces_and_store_max_id() fil_set_max_space_id_if_bigger(max_space_id); mutex_exit(&dict_sys->mutex); - rw_lock_x_unlock(dict_operation_lock); + rw_lock_x_unlock(&dict_operation_lock); DBUG_VOID_RETURN; } diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index 3f9e981f5f7..1df016d9301 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2009, 2019, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2015, 2018, MariaDB Corporation. +Copyright (c) 2015, 2019, MariaDB Corporation. 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 @@ -283,7 +283,7 @@ dict_stats_exec_sql( dberr_t err; bool trx_started = false; - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); ut_ad(mutex_own(&dict_sys->mutex)); if (!dict_stats_persistent_storage_check(true)) { @@ -2311,7 +2311,7 @@ dict_stats_save_index_stat( char table_utf8[MAX_TABLE_UTF8_LEN]; ut_ad(!trx || trx->internal || trx->in_mysql_trx_list); - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); ut_ad(mutex_own(&dict_sys->mutex)); dict_fs2utf8(index->table->name.m_name, db_utf8, sizeof(db_utf8), @@ -2447,7 +2447,7 @@ dict_stats_save( table_utf8, sizeof(table_utf8)); now = ut_time(); - rw_lock_x_lock(dict_operation_lock); + rw_lock_x_lock(&dict_operation_lock); mutex_enter(&dict_sys->mutex); pinfo = pars_info_create(); @@ -2488,7 +2488,7 @@ dict_stats_save( << table->name << ": " << ut_strerr(ret); mutex_exit(&dict_sys->mutex); - rw_lock_x_unlock(dict_operation_lock); + rw_lock_x_unlock(&dict_operation_lock); dict_stats_snapshot_free(table); @@ -2595,7 +2595,7 @@ end: trx_free_for_background(trx); mutex_exit(&dict_sys->mutex); - rw_lock_x_unlock(dict_operation_lock); + rw_lock_x_unlock(&dict_operation_lock); dict_stats_snapshot_free(table); @@ -3406,7 +3406,7 @@ dict_stats_drop_index( pars_info_add_str_literal(pinfo, "index_name", iname); - rw_lock_x_lock(dict_operation_lock); + rw_lock_x_lock(&dict_operation_lock); mutex_enter(&dict_sys->mutex); ret = dict_stats_exec_sql( @@ -3420,7 +3420,7 @@ dict_stats_drop_index( "END;\n", NULL); mutex_exit(&dict_sys->mutex); - rw_lock_x_unlock(dict_operation_lock); + rw_lock_x_unlock(&dict_operation_lock); if (ret == DB_STATS_DO_NOT_EXIST) { ret = DB_SUCCESS; @@ -3468,7 +3468,7 @@ dict_stats_delete_from_table_stats( pars_info_t* pinfo; dberr_t ret; - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); ut_ad(mutex_own(&dict_sys->mutex)); pinfo = pars_info_create(); @@ -3504,7 +3504,7 @@ dict_stats_delete_from_index_stats( pars_info_t* pinfo; dberr_t ret; - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); ut_ad(mutex_own(&dict_sys->mutex)); pinfo = pars_info_create(); @@ -3541,7 +3541,7 @@ dict_stats_drop_table( char table_utf8[MAX_TABLE_UTF8_LEN]; dberr_t ret; - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); ut_ad(mutex_own(&dict_sys->mutex)); /* skip tables that do not contain a database name @@ -3617,7 +3617,7 @@ dict_stats_rename_table_in_table_stats( pars_info_t* pinfo; dberr_t ret; - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); ut_ad(mutex_own(&dict_sys->mutex)); pinfo = pars_info_create(); @@ -3661,7 +3661,7 @@ dict_stats_rename_table_in_index_stats( pars_info_t* pinfo; dberr_t ret; - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); ut_ad(mutex_own(&dict_sys->mutex)); pinfo = pars_info_create(); @@ -3705,7 +3705,7 @@ dict_stats_rename_table( char new_table_utf8[MAX_TABLE_UTF8_LEN]; dberr_t ret; - ut_ad(!rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(!rw_lock_own(&dict_operation_lock, RW_LOCK_X)); ut_ad(!mutex_own(&dict_sys->mutex)); /* skip innodb_table_stats and innodb_index_stats themselves */ @@ -3723,7 +3723,7 @@ dict_stats_rename_table( dict_fs2utf8(new_name, new_db_utf8, sizeof(new_db_utf8), new_table_utf8, sizeof(new_table_utf8)); - rw_lock_x_lock(dict_operation_lock); + rw_lock_x_lock(&dict_operation_lock); mutex_enter(&dict_sys->mutex); ulint n_attempts = 0; @@ -3745,9 +3745,9 @@ dict_stats_rename_table( if (ret != DB_SUCCESS) { mutex_exit(&dict_sys->mutex); - rw_lock_x_unlock(dict_operation_lock); + rw_lock_x_unlock(&dict_operation_lock); os_thread_sleep(200000 /* 0.2 sec */); - rw_lock_x_lock(dict_operation_lock); + rw_lock_x_lock(&dict_operation_lock); mutex_enter(&dict_sys->mutex); } } while ((ret == DB_DEADLOCK @@ -3777,7 +3777,7 @@ dict_stats_rename_table( new_db_utf8, new_table_utf8, old_db_utf8, old_table_utf8); mutex_exit(&dict_sys->mutex); - rw_lock_x_unlock(dict_operation_lock); + rw_lock_x_unlock(&dict_operation_lock); return(ret); } /* else */ @@ -3801,9 +3801,9 @@ dict_stats_rename_table( if (ret != DB_SUCCESS) { mutex_exit(&dict_sys->mutex); - rw_lock_x_unlock(dict_operation_lock); + rw_lock_x_unlock(&dict_operation_lock); os_thread_sleep(200000 /* 0.2 sec */); - rw_lock_x_lock(dict_operation_lock); + rw_lock_x_lock(&dict_operation_lock); mutex_enter(&dict_sys->mutex); } } while ((ret == DB_DEADLOCK @@ -3812,7 +3812,7 @@ dict_stats_rename_table( && n_attempts < 5); mutex_exit(&dict_sys->mutex); - rw_lock_x_unlock(dict_operation_lock); + rw_lock_x_unlock(&dict_operation_lock); if (ret != DB_SUCCESS) { snprintf(errstr, errstr_sz, diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 39921c9a67c..595f9c3e729 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -3821,7 +3821,7 @@ fil_ibd_open( ulint tablespaces_found = 0; ulint valid_tablespaces_found = 0; - ut_ad(!fix_dict || rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(!fix_dict || rw_lock_own(&dict_operation_lock, RW_LOCK_X)); ut_ad(!fix_dict || mutex_own(&dict_sys->mutex)); ut_ad(!fix_dict || !srv_read_only_mode); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index a5a6b274049..f55fa6c4fc5 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -21566,7 +21566,7 @@ static TABLE* innodb_find_table_for_vc(THD* thd, dict_table_t* table) /* Purge thread acquires dict_operation_lock while processing undo log record. Release the dict_operation_lock before acquiring MDL on the table. */ - rw_lock_s_unlock(dict_operation_lock); + rw_lock_s_unlock(&dict_operation_lock); return innodb_acquire_mdl(thd, table); } else { if (table->vc_templ->mysql_table_query_id diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index af41e517dc5..c0c002e3042 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -3440,7 +3440,7 @@ innobase_update_gis_column_type( DBUG_ASSERT(trx_get_dict_operation(trx) == TRX_DICT_OP_INDEX); ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); ut_ad(mutex_own(&dict_sys->mutex)); - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); info = pars_info_create(); @@ -4970,7 +4970,7 @@ op_ok: #endif /* UNIV_DEBUG */ ut_ad(ctx->trx->dict_operation_lock_mode == RW_X_LATCH); ut_ad(mutex_own(&dict_sys->mutex)); - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); DICT_TF2_FLAG_SET(ctx->new_table, DICT_TF2_FTS); if (new_clustered) { @@ -6157,8 +6157,8 @@ ha_innobase::inplace_alter_table( DBUG_ASSERT(!srv_read_only_mode); ut_ad(!sync_check_iterate(sync_check())); - ut_ad(!rw_lock_own(dict_operation_lock, RW_LOCK_X)); - ut_ad(!rw_lock_own(dict_operation_lock, RW_LOCK_S)); + ut_ad(!rw_lock_own_flagged(&dict_operation_lock, + RW_LOCK_FLAG_X | RW_LOCK_FLAG_S)); DEBUG_SYNC(m_user_thd, "innodb_inplace_alter_table_enter"); @@ -6369,7 +6369,7 @@ innobase_online_rebuild_log_free( dict_index_t* clust_index = dict_table_get_first_index(table); ut_ad(mutex_own(&dict_sys->mutex)); - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); rw_lock_x_lock(&clust_index->lock); @@ -6643,7 +6643,7 @@ innobase_drop_foreign_try( DBUG_ASSERT(trx_get_dict_operation(trx) == TRX_DICT_OP_INDEX); ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); ut_ad(mutex_own(&dict_sys->mutex)); - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); /* Drop the constraint from the data dictionary. */ static const char sql[] = @@ -6706,7 +6706,7 @@ innobase_rename_column_try( DBUG_ASSERT(trx_get_dict_operation(trx) == TRX_DICT_OP_INDEX); ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); ut_ad(mutex_own(&dict_sys->mutex)); - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); if (new_clustered) { goto rename_foreign; @@ -6988,7 +6988,7 @@ innobase_enlarge_column_try( DBUG_ASSERT(trx_get_dict_operation(trx) == TRX_DICT_OP_INDEX); ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); ut_ad(mutex_own(&dict_sys->mutex)); - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); if (is_v) { v_col = dict_table_get_nth_v_col(user_table, nth_col); diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index 9a15c44aa1f..1cc9857c42e 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -2890,20 +2890,17 @@ i_s_fts_deleted_generic_fill( } /* Prevent DDL to drop fts aux tables. */ - rw_lock_s_lock(dict_operation_lock); + rw_lock_s_lock(&dict_operation_lock); user_table = dict_table_open_on_name( fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE); if (!user_table) { - rw_lock_s_unlock(dict_operation_lock); - + rw_lock_s_unlock(&dict_operation_lock); DBUG_RETURN(0); } else if (!dict_table_has_fts_index(user_table)) { dict_table_close(user_table, FALSE, FALSE); - - rw_lock_s_unlock(dict_operation_lock); - + rw_lock_s_unlock(&dict_operation_lock); DBUG_RETURN(0); } @@ -2938,7 +2935,7 @@ i_s_fts_deleted_generic_fill( dict_table_close(user_table, FALSE, FALSE); - rw_lock_s_unlock(dict_operation_lock); + rw_lock_s_unlock(&dict_operation_lock); DBUG_RETURN(ret); } @@ -3751,14 +3748,13 @@ i_s_fts_index_table_fill( } /* Prevent DDL to drop fts aux tables. */ - rw_lock_s_lock(dict_operation_lock); + rw_lock_s_lock(&dict_operation_lock); user_table = dict_table_open_on_name( fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE); if (!user_table) { - rw_lock_s_unlock(dict_operation_lock); - + rw_lock_s_unlock(&dict_operation_lock); DBUG_RETURN(0); } @@ -3778,7 +3774,7 @@ i_s_fts_index_table_fill( dict_table_close(user_table, FALSE, FALSE); - rw_lock_s_unlock(dict_operation_lock); + rw_lock_s_unlock(&dict_operation_lock); ut_free(conv_str.f_str); @@ -3920,19 +3916,19 @@ i_s_fts_config_fill( fields = table->field; /* Prevent DDL to drop fts aux tables. */ - rw_lock_s_lock(dict_operation_lock); + rw_lock_s_lock(&dict_operation_lock); user_table = dict_table_open_on_name( fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE); if (!user_table) { - rw_lock_s_unlock(dict_operation_lock); + rw_lock_s_unlock(&dict_operation_lock); DBUG_RETURN(0); } else if (!dict_table_has_fts_index(user_table)) { dict_table_close(user_table, FALSE, FALSE); - rw_lock_s_unlock(dict_operation_lock); + rw_lock_s_unlock(&dict_operation_lock); DBUG_RETURN(0); } @@ -3992,7 +3988,7 @@ i_s_fts_config_fill( dict_table_close(user_table, FALSE, FALSE); - rw_lock_s_unlock(dict_operation_lock); + rw_lock_s_unlock(&dict_operation_lock); DBUG_RETURN(ret); } @@ -6388,7 +6384,7 @@ i_s_sys_tables_fill_table_stats( } heap = mem_heap_create(1000); - rw_lock_s_lock(dict_operation_lock); + rw_lock_s_lock(&dict_operation_lock); mutex_enter(&dict_sys->mutex); mtr_start(&mtr); @@ -6423,11 +6419,11 @@ i_s_sys_tables_fill_table_stats( err_msg); } - rw_lock_s_unlock(dict_operation_lock); + rw_lock_s_unlock(&dict_operation_lock); mem_heap_empty(heap); /* Get the next record */ - rw_lock_s_lock(dict_operation_lock); + rw_lock_s_lock(&dict_operation_lock); mutex_enter(&dict_sys->mutex); mtr_start(&mtr); @@ -6436,7 +6432,7 @@ i_s_sys_tables_fill_table_stats( mtr_commit(&mtr); mutex_exit(&dict_sys->mutex); - rw_lock_s_unlock(dict_operation_lock); + rw_lock_s_unlock(&dict_operation_lock); mem_heap_free(heap); DBUG_RETURN(0); diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 4acdae31ee8..cdcdef75917 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -1676,7 +1676,7 @@ extern ib_mutex_t dict_foreign_err_mutex; /* mutex protecting the /** the dictionary system */ extern dict_sys_t* dict_sys; /** the data dictionary rw-latch protecting dict_sys */ -extern rw_lock_t* dict_operation_lock; +extern rw_lock_t dict_operation_lock; /* Dictionary system struct */ struct dict_sys_t{ diff --git a/storage/innobase/include/sync0rw.h b/storage/innobase/include/sync0rw.h index 7ced4a0e9e0..e0451d66de1 100644 --- a/storage/innobase/include/sync0rw.h +++ b/storage/innobase/include/sync0rw.h @@ -2,7 +2,7 @@ Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. -Copyright (c) 2017, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2017, 2019, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -631,34 +631,14 @@ struct rw_lock_t #endif /* UNIV_PFS_RWLOCK */ #ifdef UNIV_DEBUG -/** Value of rw_lock_t::magic_n */ -# define RW_LOCK_MAGIC_N 22643 - - /** Constructor */ - rw_lock_t() - { - magic_n = RW_LOCK_MAGIC_N; - } - - /** Destructor */ - virtual ~rw_lock_t() - { - ut_ad(magic_n == RW_LOCK_MAGIC_N); - magic_n = 0; - } - virtual std::string to_string() const; virtual std::string locked_from() const; - /** For checking memory corruption. */ - ulint magic_n; - /** In the debug version: pointer to the debug info list of the lock */ UT_LIST_BASE_NODE_T(rw_lock_debug_t) debug_list; /** Level in the global latching order. */ latch_level_t level; - #endif /* UNIV_DEBUG */ }; diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index 16694d751a1..036b657e36c 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -3819,7 +3819,7 @@ row_import_for_mysql( /* Prevent DDL operations while we are checking. */ - rw_lock_s_lock_func(dict_operation_lock, 0, __FILE__, __LINE__); + rw_lock_s_lock_func(&dict_operation_lock, 0, __FILE__, __LINE__); row_import cfg; @@ -3844,14 +3844,14 @@ row_import_for_mysql( autoinc = cfg.m_autoinc; } - rw_lock_s_unlock_gen(dict_operation_lock, 0); + rw_lock_s_unlock_gen(&dict_operation_lock, 0); DBUG_EXECUTE_IF("ib_import_set_index_root_failure", err = DB_TOO_MANY_CONCURRENT_TRXS;); } else if (cfg.m_missing) { - rw_lock_s_unlock_gen(dict_operation_lock, 0); + rw_lock_s_unlock_gen(&dict_operation_lock, 0); /* We don't have a schema file, we will have to discover the index root pages from the .ibd file and skip the schema @@ -3883,7 +3883,7 @@ row_import_for_mysql( space_flags = fetchIndexRootPages.get_space_flags(); } else { - rw_lock_s_unlock_gen(dict_operation_lock, 0); + rw_lock_s_unlock_gen(&dict_operation_lock, 0); } if (err != DB_SUCCESS) { diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index f3e6cf093a0..b081f15b279 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -1574,7 +1574,7 @@ row_ins_check_foreign_constraint( upd_node= NULL; #endif /* WITH_WSREP */ - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_S)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_S)); err = DB_SUCCESS; diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index 262beeb37c2..0013fabd98e 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2019, MariaDB Corporation. 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 @@ -2902,7 +2902,7 @@ row_log_table_apply( stage->begin_phase_log_table(); - ut_ad(!rw_lock_own(dict_operation_lock, RW_LOCK_S)); + ut_ad(!rw_lock_own(&dict_operation_lock, RW_LOCK_S)); clust_index = dict_table_get_first_index(old_table); rw_lock_x_lock(dict_index_get_lock(clust_index)); diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index dc4c8b72785..3dd7ba233b2 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -3614,7 +3614,7 @@ row_merge_drop_index_dict( ut_ad(mutex_own(&dict_sys->mutex)); ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); ut_ad(trx_get_dict_operation(trx) == TRX_DICT_OP_INDEX); - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); info = pars_info_create(); pars_info_add_ull_literal(info, "indexid", index_id); @@ -3677,7 +3677,7 @@ row_merge_drop_indexes_dict( ut_ad(mutex_own(&dict_sys->mutex)); ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); ut_ad(trx_get_dict_operation(trx) == TRX_DICT_OP_INDEX); - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); /* It is possible that table->n_ref_count > 1 when locked=TRUE. In this case, all code that should have an open @@ -3727,7 +3727,7 @@ row_merge_drop_indexes( ut_ad(mutex_own(&dict_sys->mutex)); ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); ut_ad(trx_get_dict_operation(trx) == TRX_DICT_OP_INDEX); - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); index = dict_table_get_first_index(table); ut_ad(dict_index_is_clust(index)); diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 6d5c79859b8..b8e5a7e9c65 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -2062,7 +2062,7 @@ row_mysql_freeze_data_dictionary_func( { ut_a(trx->dict_operation_lock_mode == 0); - rw_lock_s_lock_inline(dict_operation_lock, 0, file, line); + rw_lock_s_lock_inline(&dict_operation_lock, 0, file, line); trx->dict_operation_lock_mode = RW_S_LATCH; } @@ -2078,7 +2078,7 @@ row_mysql_unfreeze_data_dictionary( ut_a(trx->dict_operation_lock_mode == RW_S_LATCH); - rw_lock_s_unlock(dict_operation_lock); + rw_lock_s_unlock(&dict_operation_lock); trx->dict_operation_lock_mode = 0; } @@ -2183,7 +2183,7 @@ row_mysql_lock_data_dictionary_func( /* Serialize data dictionary operations with dictionary mutex: no deadlocks or lock waits can occur then in these operations */ - rw_lock_x_lock_inline(dict_operation_lock, 0, file, line); + rw_lock_x_lock_inline(&dict_operation_lock, 0, file, line); trx->dict_operation_lock_mode = RW_X_LATCH; mutex_enter(&dict_sys->mutex); @@ -2204,7 +2204,7 @@ row_mysql_unlock_data_dictionary( no deadlocks can occur then in these operations */ mutex_exit(&dict_sys->mutex); - rw_lock_x_unlock(dict_operation_lock); + rw_lock_x_unlock(&dict_operation_lock); trx->dict_operation_lock_mode = 0; } @@ -2228,7 +2228,7 @@ row_create_table_for_mysql( que_thr_t* thr; dberr_t err; - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); ut_ad(mutex_own(&dict_sys->mutex)); ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); @@ -2392,7 +2392,7 @@ row_create_index_for_mysql( is_fts = (index->type == DICT_FTS); - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); ut_ad(mutex_own(&dict_sys->mutex)); table = dict_table_open_on_name(table_name, TRUE, TRUE, @@ -3300,7 +3300,7 @@ row_drop_table_for_mysql( } ut_ad(mutex_own(&dict_sys->mutex)); - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); table = dict_table_open_on_name( name, TRUE, FALSE, diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc index b039834748d..560315af499 100644 --- a/storage/innobase/row/row0purge.cc +++ b/storage/innobase/row/row0purge.cc @@ -111,7 +111,7 @@ row_purge_remove_clust_if_poss_low( ulint offsets_[REC_OFFS_NORMAL_SIZE]; rec_offs_init(offsets_); - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_S) + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_S) || node->vcol_info.is_used()); index = dict_table_get_first_index(node->table); @@ -796,7 +796,7 @@ row_purge_upd_exist_or_extern_func( { mem_heap_t* heap; - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_S) + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_S) || node->vcol_info.is_used()); ut_ad(!node->table->skip_alter_undo); @@ -979,7 +979,7 @@ skip: for this row */ try_again: - rw_lock_s_lock_inline(dict_operation_lock, 0, __FILE__, __LINE__); + rw_lock_s_lock_inline(&dict_operation_lock, 0, __FILE__, __LINE__); node->table = dict_table_open_on_id( table_id, FALSE, DICT_TABLE_OP_NORMAL); @@ -1003,7 +1003,7 @@ try_again: if (!mysqld_server_started) { dict_table_close(node->table, FALSE, FALSE); - rw_lock_s_unlock(dict_operation_lock); + rw_lock_s_unlock(&dict_operation_lock); if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { return(false); } @@ -1033,7 +1033,7 @@ close_exit: dict_table_close(node->table, FALSE, FALSE); node->table = NULL; err_exit: - rw_lock_s_unlock(dict_operation_lock); + rw_lock_s_unlock(&dict_operation_lock); if (table_id) { node->skip(table_id, trx_id); } @@ -1162,10 +1162,10 @@ row_purge( node, undo_rec, thr, updated_extern); if (!node->vcol_info.is_used()) { - rw_lock_s_unlock(dict_operation_lock); + rw_lock_s_unlock(&dict_operation_lock); } - ut_ad(!rw_lock_own(dict_operation_lock, RW_LOCK_S)); + ut_ad(!rw_lock_own(&dict_operation_lock, RW_LOCK_S)); if (purged || srv_shutdown_state != SRV_SHUTDOWN_NONE diff --git a/storage/innobase/row/row0trunc.cc b/storage/innobase/row/row0trunc.cc index 934295f501e..50f88cc857e 100644 --- a/storage/innobase/row/row0trunc.cc +++ b/storage/innobase/row/row0trunc.cc @@ -1788,7 +1788,7 @@ dberr_t row_truncate_table_for_mysql(dict_table_t* table, trx_t* trx) ut_a(trx->dict_operation_lock_mode == 0); row_mysql_lock_data_dictionary(trx); ut_ad(mutex_own(&dict_sys->mutex)); - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_X)); /* Step-4: Stop all the background process associated with table. */ dict_stats_wait_bg_to_stop_using_table(table, trx); diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc index 7d56b0cee3f..3d4065cbab6 100644 --- a/storage/innobase/row/row0umod.cc +++ b/storage/innobase/row/row0umod.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. +Copyright (c) 2017, 2019, MariaDB Corporation. 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 @@ -263,7 +263,7 @@ row_undo_mod_clust( ut_ad(thr_get_trx(thr) == node->trx); ut_ad(node->trx->dict_operation_lock_mode); ut_ad(node->trx->in_rollback); - ut_ad(rw_lock_own_flagged(dict_operation_lock, + ut_ad(rw_lock_own_flagged(&dict_operation_lock, RW_LOCK_FLAG_X | RW_LOCK_FLAG_S)); log_free_check(); diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index 3d7e3e3814c..a6ada6067fd 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -2066,7 +2066,7 @@ srv_master_evict_from_table_cache( { ulint n_tables_evicted = 0; - rw_lock_x_lock(dict_operation_lock); + rw_lock_x_lock(&dict_operation_lock); dict_mutex_enter_for_mysql(); @@ -2075,7 +2075,7 @@ srv_master_evict_from_table_cache( dict_mutex_exit_for_mysql(); - rw_lock_x_unlock(dict_operation_lock); + rw_lock_x_unlock(&dict_operation_lock); return(n_tables_evicted); } diff --git a/storage/innobase/sync/sync0rw.cc b/storage/innobase/sync/sync0rw.cc index acfddff4b6b..2c3407ba56a 100644 --- a/storage/innobase/sync/sync0rw.cc +++ b/storage/innobase/sync/sync0rw.cc @@ -2,7 +2,7 @@ Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2019, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -241,9 +241,6 @@ rw_lock_create_func( mutex_enter(&rw_lock_list_mutex); - ut_ad(UT_LIST_GET_FIRST(rw_lock_list) == NULL - || UT_LIST_GET_FIRST(rw_lock_list)->magic_n == RW_LOCK_MAGIC_N); - UT_LIST_ADD_FIRST(rw_lock_list, lock); mutex_exit(&rw_lock_list_mutex); @@ -270,12 +267,6 @@ rw_lock_free_func( UT_LIST_REMOVE(rw_lock_list, lock); mutex_exit(&rw_lock_list_mutex); - - /* We did an in-place new in rw_lock_create_func() */ - ut_d(lock->~rw_lock_t()); - /* Sometimes (maybe when compiled with GCC -O3) the above call - to rw_lock_t::~rw_lock_t() will not actually assign magic_n=0. */ - ut_d(lock->magic_n = 0); } /******************************************************************//** @@ -870,7 +861,6 @@ rw_lock_validate( lock_word = lock->lock_word; - ut_ad(lock->magic_n == RW_LOCK_MAGIC_N); ut_ad(lock->waiters < 2); ut_ad(lock_word > -(2 * X_LOCK_DECR)); ut_ad(lock_word <= X_LOCK_DECR); diff --git a/storage/innobase/trx/trx0i_s.cc b/storage/innobase/trx/trx0i_s.cc index e37aecde9ee..3c23ed91a33 100644 --- a/storage/innobase/trx/trx0i_s.cc +++ b/storage/innobase/trx/trx0i_s.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2007, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2019, MariaDB Corporation. 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 @@ -138,7 +138,7 @@ struct i_s_table_cache_t { /** This structure describes the intermediate buffer */ struct trx_i_s_cache_t { - rw_lock_t* rw_lock; /*!< read-write lock protecting + rw_lock_t rw_lock; /*!< read-write lock protecting the rest of this structure */ uintmax_t last_read; /*!< last time the cache was read; measured in microseconds since @@ -1206,7 +1206,7 @@ can_cache_be_updated( So it is not possible for last_read to be updated while we are reading it. */ - ut_ad(rw_lock_own(cache->rw_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&cache->rw_lock, RW_LOCK_X)); now = ut_time_us(NULL); if (now - cache->last_read > CACHE_MIN_IDLE_TIME_US) { @@ -1393,10 +1393,7 @@ trx_i_s_cache_init( release trx_i_s_cache_t::last_read_mutex release trx_i_s_cache_t::rw_lock */ - cache->rw_lock = static_cast( - ut_malloc_nokey(sizeof(*cache->rw_lock))); - - rw_lock_create(trx_i_s_cache_lock_key, cache->rw_lock, + rw_lock_create(trx_i_s_cache_lock_key, &cache->rw_lock, SYNC_TRX_I_S_RWLOCK); cache->last_read = 0; @@ -1425,10 +1422,7 @@ trx_i_s_cache_free( /*===============*/ trx_i_s_cache_t* cache) /*!< in, own: cache to free */ { - rw_lock_free(cache->rw_lock); - ut_free(cache->rw_lock); - cache->rw_lock = NULL; - + rw_lock_free(&cache->rw_lock); mutex_free(&cache->last_read_mutex); hash_table_free(cache->locks_hash); @@ -1445,7 +1439,7 @@ trx_i_s_cache_start_read( /*=====================*/ trx_i_s_cache_t* cache) /*!< in: cache */ { - rw_lock_s_lock(cache->rw_lock); + rw_lock_s_lock(&cache->rw_lock); } /*******************************************************************//** @@ -1457,7 +1451,7 @@ trx_i_s_cache_end_read( { uintmax_t now; - ut_ad(rw_lock_own(cache->rw_lock, RW_LOCK_S)); + ut_ad(rw_lock_own(&cache->rw_lock, RW_LOCK_S)); /* update cache last read time */ now = ut_time_us(NULL); @@ -1465,7 +1459,7 @@ trx_i_s_cache_end_read( cache->last_read = now; mutex_exit(&cache->last_read_mutex); - rw_lock_s_unlock(cache->rw_lock); + rw_lock_s_unlock(&cache->rw_lock); } /*******************************************************************//** @@ -1475,7 +1469,7 @@ trx_i_s_cache_start_write( /*======================*/ trx_i_s_cache_t* cache) /*!< in: cache */ { - rw_lock_x_lock(cache->rw_lock); + rw_lock_x_lock(&cache->rw_lock); } /*******************************************************************//** @@ -1485,9 +1479,9 @@ trx_i_s_cache_end_write( /*====================*/ trx_i_s_cache_t* cache) /*!< in: cache */ { - ut_ad(rw_lock_own(cache->rw_lock, RW_LOCK_X)); + ut_ad(rw_lock_own(&cache->rw_lock, RW_LOCK_X)); - rw_lock_x_unlock(cache->rw_lock); + rw_lock_x_unlock(&cache->rw_lock); } /*******************************************************************//** @@ -1500,7 +1494,7 @@ cache_select_table( trx_i_s_cache_t* cache, /*!< in: whole cache */ enum i_s_table table) /*!< in: which table */ { - ut_ad(rw_lock_own_flagged(cache->rw_lock, + ut_ad(rw_lock_own_flagged(&cache->rw_lock, RW_LOCK_FLAG_X | RW_LOCK_FLAG_S)); switch (table) { diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc index d2e286be81f..2b57b5ef15f 100644 --- a/storage/innobase/trx/trx0purge.cc +++ b/storage/innobase/trx/trx0purge.cc @@ -221,10 +221,6 @@ purge_sys_t::~purge_sys_t() trx_free_for_background(trx); view.close(); rw_lock_free(&latch); - /* rw_lock_free() already called latch.~rw_lock_t(); tame the - debug assertions when the destructor will be called once more. */ - ut_ad(latch.magic_n == 0); - ut_d(latch.magic_n = RW_LOCK_MAGIC_N); mutex_free(&pq_mutex); os_event_destroy(event); }