diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-06-05 20:36:43 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-06-05 20:36:43 +0300 |
commit | 6877ef9a7c9c7ee55d67e4baaf4e8f7b874c9f89 (patch) | |
tree | ade4c0b2e50538438e70dc49581541de94098625 | |
parent | 374f94c5a749ec6af83824c1f55f0f49029a9714 (diff) | |
parent | 68d9d512e933a1d40670add50f205e5266bc5507 (diff) | |
download | mariadb-git-6877ef9a7c9c7ee55d67e4baaf4e8f7b874c9f89.tar.gz |
Merge 10.4 into 10.5
61 files changed, 841 insertions, 477 deletions
diff --git a/include/my_compiler.h b/include/my_compiler.h index 8e37f8bcd19..d35a9104c50 100644 --- a/include/my_compiler.h +++ b/include/my_compiler.h @@ -2,6 +2,7 @@ #define MY_COMPILER_INCLUDED /* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2017, 2020, 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 @@ -156,6 +157,7 @@ struct my_aligned_storage #ifdef __GNUC__ # define ATTRIBUTE_NORETURN __attribute__((noreturn)) +# define ATTRIBUTE_NOINLINE __attribute__((noinline)) # if MY_GNUC_PREREQ(4,3) /** Starting with GCC 4.3, the "cold" attribute is used to inform the compiler that a function is unlikely executed. The function is @@ -169,8 +171,10 @@ rarely invoked function for size instead for speed. */ # endif #elif defined _MSC_VER # define ATTRIBUTE_NORETURN __declspec(noreturn) +# define ATTRIBUTE_NOINLINE __declspec(noinline) #else # define ATTRIBUTE_NORETURN /* empty */ +# define ATTRIBUTE_NOINLINE /* empty */ #endif #ifndef ATTRIBUTE_COLD diff --git a/mysql-test/main/opt_trace.result b/mysql-test/main/opt_trace.result index 2e4cfb9acb7..ad7bce44445 100644 --- a/mysql-test/main/opt_trace.result +++ b/mysql-test/main/opt_trace.result @@ -441,6 +441,7 @@ select * from v2 { }, "rows_for_plan": 1, "cost_for_plan": 2.404394531, + "cost_for_sorting": 1, "estimated_join_cardinality": 1 } ] @@ -765,6 +766,7 @@ explain select * from v1 { }, "rows_for_plan": 10, "cost_for_plan": 4.021972656, + "cost_for_sorting": 10, "estimated_join_cardinality": 10 } ] @@ -1452,6 +1454,7 @@ EXPLAIN SELECT MIN(d) FROM t1 where b=2 and c=3 group by a { }, "rows_for_plan": 8, "cost_for_plan": 3.8, + "cost_for_sorting": 8, "estimated_join_cardinality": 8 } ] @@ -1645,6 +1648,7 @@ EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104e0 GROUP BY id { }, "rows_for_plan": 9, "cost_for_plan": 4.15, + "cost_for_sorting": 9, "estimated_join_cardinality": 9 } ] @@ -1827,6 +1831,7 @@ EXPLAIN SELECT * FROM t1 WHERE a = 20010104e0 GROUP BY id { }, "rows_for_plan": 9, "cost_for_plan": 4.15, + "cost_for_sorting": 9, "estimated_join_cardinality": 9 } ] @@ -8258,6 +8263,174 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.range_scan_alternatives')) ] ] drop table t1; +# +# MDEV-21626: Optimizer misses the details about the picked join order +# +CREATE TABLE t1(a INT, b INT, key(a)); +INSERT INTO t1 SELECT seq, seq from seq_1_to_10; +CREATE TABLE t2(a INT, b INT, key(a)); +INSERT INTO t2 SELECT seq, seq from seq_1_to_100; +SET OPTIMIZER_TRACE=1; +EXPLAIN SELECT * FROM t1, t2 WHERE t1.a=t2.a ORDER BY t2.b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL a NULL NULL NULL 10 Using where; Using temporary; Using filesort +1 SIMPLE t2 ref a a 5 test.t1.a 1 +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) +[ + + [ + + { + "plan_prefix": + [ + ], + "table": "t1", + "best_access_path": + { + "considered_access_paths": + [ + + { + "access_type": "scan", + "resulting_rows": 10, + "cost": 2.021972656, + "chosen": true + } + ], + "chosen_access_method": + { + "type": "scan", + "records": 10, + "cost": 2.021972656, + "uses_join_buffering": false + } + }, + "rows_for_plan": 10, + "cost_for_plan": 4.021972656, + "rest_of_plan": + [ + + { + "plan_prefix": + [ + "t1" + ], + "table": "t2", + "best_access_path": + { + "considered_access_paths": + [ + + { + "access_type": "ref", + "index": "a", + "used_range_estimates": false, + "cause": "not available", + "rows": 1, + "cost": 20.00585794, + "chosen": true + }, + + { + "access_type": "scan", + "resulting_rows": 100, + "cost": 2.219726562, + "chosen": false + } + ], + "chosen_access_method": + { + "type": "ref", + "records": 1, + "cost": 20.00585794, + "uses_join_buffering": false + } + }, + "rows_for_plan": 10, + "cost_for_plan": 26.0278306, + "cost_for_sorting": 10, + "estimated_join_cardinality": 10 + } + ] + }, + + { + "plan_prefix": + [ + ], + "table": "t2", + "best_access_path": + { + "considered_access_paths": + [ + + { + "access_type": "scan", + "resulting_rows": 100, + "cost": 2.219726562, + "chosen": true, + "use_tmp_table": true + } + ], + "chosen_access_method": + { + "type": "scan", + "records": 100, + "cost": 2.219726562, + "uses_join_buffering": false + } + }, + "rows_for_plan": 100, + "cost_for_plan": 22.21972656, + "rest_of_plan": + [ + + { + "plan_prefix": + [ + "t2" + ], + "table": "t1", + "best_access_path": + { + "considered_access_paths": + [ + + { + "access_type": "ref", + "index": "a", + "used_range_estimates": false, + "cause": "not available", + "rows": 1, + "cost": 200.0585794, + "chosen": true + }, + + { + "access_type": "scan", + "resulting_rows": 10, + "cost": 2.021972656, + "chosen": true + } + ], + "chosen_access_method": + { + "type": "scan", + "records": 10, + "cost": 2.021972656, + "uses_join_buffering": true + } + }, + "rows_for_plan": 1000, + "cost_for_plan": 224.2416992, + "pruned_by_cost": true + } + ] + } + ] +] +DROP TABLE t1,t2; # End of 10.4 tests # # Test many rows to see output of big cost numbers diff --git a/mysql-test/main/opt_trace.test b/mysql-test/main/opt_trace.test index 2839dbad9e6..f2d7b67983d 100644 --- a/mysql-test/main/opt_trace.test +++ b/mysql-test/main/opt_trace.test @@ -580,6 +580,20 @@ select * from t1 force index(kp1) where (kp1=2 and kp2 >=4); select JSON_DETAILED(JSON_EXTRACT(trace, '$**.range_scan_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE; drop table t1; +--echo # +--echo # MDEV-21626: Optimizer misses the details about the picked join order +--echo # + +CREATE TABLE t1(a INT, b INT, key(a)); +INSERT INTO t1 SELECT seq, seq from seq_1_to_10; +CREATE TABLE t2(a INT, b INT, key(a)); +INSERT INTO t2 SELECT seq, seq from seq_1_to_100; + +SET OPTIMIZER_TRACE=1; +EXPLAIN SELECT * FROM t1, t2 WHERE t1.a=t2.a ORDER BY t2.b; +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE; +DROP TABLE t1,t2; + --echo # End of 10.4 tests diff --git a/mysql-test/main/win.result b/mysql-test/main/win.result index 8324a065b93..74322abd661 100644 --- a/mysql-test/main/win.result +++ b/mysql-test/main/win.result @@ -3742,6 +3742,53 @@ a ROW_NUMBER() OVER v2 1 1 drop table t0; # +# MDEV-16230:Server crashes when Analyze format=json is run with a window function with +# empty PARTITION BY and ORDER BY clauses +# +CREATE TABLE t1(a INT, b INT); +INSERT INTO t1 VALUES (1,1),(2,2),(3,3); +ANALYZE FORMAT=JSON SELECT row_number() OVER() FROM t1; +ANALYZE +{ + "query_block": { + "select_id": 1, + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "window_functions_computation": { + "sorts": { + "filesort": { + "sort_key": "`row_number() OVER()`", + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "r_used_priority_queue": false, + "r_output_rows": 3, + "r_buffer_size": "REPLACED", + "r_sort_mode": "sort_key,rowid" + } + }, + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "r_loops": 1, + "rows": 3, + "r_rows": 3, + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 100, + "r_filtered": 100 + } + } + } + } +} +SELECT row_number() OVER() FROM t1; +row_number() OVER() +1 +2 +3 +DROP TABLE t1; +# # End of 10.2 tests # # diff --git a/mysql-test/main/win.test b/mysql-test/main/win.test index 272404e712d..b741461083f 100644 --- a/mysql-test/main/win.test +++ b/mysql-test/main/win.test @@ -2446,6 +2446,19 @@ WINDOW v2 AS ( PARTITION BY a ORDER BY a DESC ); drop table t0; --echo # +--echo # MDEV-16230:Server crashes when Analyze format=json is run with a window function with +--echo # empty PARTITION BY and ORDER BY clauses +--echo # + +CREATE TABLE t1(a INT, b INT); +INSERT INTO t1 VALUES (1,1),(2,2),(3,3); + +--source include/analyze-format.inc +ANALYZE FORMAT=JSON SELECT row_number() OVER() FROM t1; +SELECT row_number() OVER() FROM t1; +DROP TABLE t1; + +--echo # --echo # End of 10.2 tests --echo # diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index ec13e011dae..5401c5478be 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -201,6 +201,7 @@ my @DEFAULT_SUITES= qw( plugins- roles- rpl- + stress- sys_vars- sql_sequence- unit- diff --git a/mysql-test/suite/innodb/r/xa_recovery.result b/mysql-test/suite/innodb/r/xa_recovery.result index b559de388e2..ed9f19b7eb3 100644 --- a/mysql-test/suite/innodb/r/xa_recovery.result +++ b/mysql-test/suite/innodb/r/xa_recovery.result @@ -5,12 +5,20 @@ XA START 'x'; UPDATE t1 set a=2; XA END 'x'; XA PREPARE 'x'; +connect con2,localhost,root; +CREATE TABLE t2 (a INT) ENGINE=InnoDB; +XA START 'y'; +INSERT INTO t2 VALUES (1); +XA END 'y'; +XA PREPARE 'y'; connection default; # restart: --innodb-force-recovery=2 disconnect con1; +disconnect con2; connect con1,localhost,root; SELECT * FROM t1 LOCK IN SHARE MODE; connection default; +DROP TABLE t2; # restart disconnect con1; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; @@ -22,3 +30,6 @@ SELECT * FROM t1; a 1 DROP TABLE t1; +SET GLOBAL innodb_fast_shutdown=0; +# restart +XA ROLLBACK 'y'; diff --git a/mysql-test/suite/innodb/t/leaf_page_corrupted_during_recovery.test b/mysql-test/suite/innodb/t/leaf_page_corrupted_during_recovery.test index f20f17f869d..b7fff30dca2 100644 --- a/mysql-test/suite/innodb/t/leaf_page_corrupted_during_recovery.test +++ b/mysql-test/suite/innodb/t/leaf_page_corrupted_during_recovery.test @@ -9,7 +9,7 @@ call mtr.add_suppression("\\[ERROR\\] InnoDB: Plugin initialization aborted at s call mtr.add_suppression("\\[ERROR\\] Plugin 'InnoDB' (init function|registration)"); call mtr.add_suppression("\\[ERROR\\] InnoDB: We detected index corruption"); call mtr.add_suppression("\\[ERROR\\] (mysqld|mariadbd).*: Index for table 't1' is corrupt; try to repair it"); -call mtr.add_suppression("InnoDB: Error code: [0-9][0-9][0-9]* btr_pcur_open_low level: 0 called from file: "); +call mtr.add_suppression("InnoDB: btr_pcur_open_low level: 0 called from file: "); --enable_query_log CREATE TABLE t1 (pk INT PRIMARY KEY, c CHAR(255))ENGINE=InnoDB STATS_PERSISTENT=0; diff --git a/mysql-test/suite/innodb/t/xa_recovery.test b/mysql-test/suite/innodb/t/xa_recovery.test index 20bb52c22f2..bb8e3316860 100644 --- a/mysql-test/suite/innodb/t/xa_recovery.test +++ b/mysql-test/suite/innodb/t/xa_recovery.test @@ -5,7 +5,7 @@ # MDEV-8841 - close tables opened by previous tests, # so they don't get marked crashed when the server gets crashed --disable_query_log -call mtr.add_suppression("Found 1 prepared XA transactions"); +call mtr.add_suppression("Found [12] prepared XA transactions"); FLUSH TABLES; --enable_query_log @@ -13,6 +13,9 @@ CREATE TABLE t1 (a INT) ENGINE=InnoDB; INSERT INTO t1 VALUES (1); connect (con1,localhost,root); XA START 'x'; UPDATE t1 set a=2; XA END 'x'; XA PREPARE 'x'; +connect (con2,localhost,root); +CREATE TABLE t2 (a INT) ENGINE=InnoDB; +XA START 'y'; INSERT INTO t2 VALUES (1); XA END 'y'; XA PREPARE 'y'; connection default; # innodb_force_recovery=2 prevents the purge and tests that the fix of @@ -25,6 +28,7 @@ connection default; --let $shutdown_timeout= disconnect con1; +disconnect con2; connect (con1,localhost,root); --send SELECT * FROM t1 LOCK IN SHARE MODE @@ -35,6 +39,8 @@ let $wait_condition= info = 'SELECT * FROM t1 LOCK IN SHARE MODE'; --source include/wait_condition.inc +DROP TABLE t2; + --source include/restart_mysqld.inc disconnect con1; @@ -45,3 +51,8 @@ XA ROLLBACK 'x'; SELECT * FROM t1; DROP TABLE t1; + +SET GLOBAL innodb_fast_shutdown=0; +--source include/restart_mysqld.inc + +XA ROLLBACK 'y'; diff --git a/mysql-test/suite/stress/r/misc.result b/mysql-test/suite/stress/r/misc.result new file mode 100644 index 00000000000..6d0a3ea5050 --- /dev/null +++ b/mysql-test/suite/stress/r/misc.result @@ -0,0 +1,9 @@ +# +# MDEV-22339 - Assertion `str_length < len' failed in +# Binary_string::realloc_raw +# +CREATE TABLE t1(a INT) ENGINE=MyISAM; +connect con1, localhost, root; +disconnect con1; +connection default; +DROP TABLE t1; diff --git a/mysql-test/suite/stress/t/misc.test b/mysql-test/suite/stress/t/misc.test new file mode 100644 index 00000000000..e8255cb3a81 --- /dev/null +++ b/mysql-test/suite/stress/t/misc.test @@ -0,0 +1,32 @@ +--echo # +--echo # MDEV-22339 - Assertion `str_length < len' failed in +--echo # Binary_string::realloc_raw +--echo # +CREATE TABLE t1(a INT) ENGINE=MyISAM; +connect con1, localhost, root; +let $i=1000; +disable_query_log; +disable_result_log; +while ($i) +{ + connection default; + HANDLER t1 OPEN; + send SELECT * FROM t1, t1 t1a1over8, t1 t1a2over8, t1 t1a3over8, t1 t1a4over8, t1 t1a5over8, t1 t1a6over8; + + connection con1; + send REPAIR TABLE t1; + + connection default; + reap; + HANDLER t1 CLOSE; + + connection con1; + reap; + dec $i; +} +enable_query_log; +enable_result_log; +disconnect con1; + +connection default; +DROP TABLE t1; diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index b357ae390af..b945ca4fb5b 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -1068,6 +1068,16 @@ delete from v1; ERROR HY000: Table 't1' was locked with a READ lock and can't be updated drop view v1; drop table t1; +# +# MDEV-22112 Assertion `tab_part_info->part_type == RANGE_PARTITION || tab_part_info->part_type == LIST_PARTITION' failed in prep_alter_part_table +# +create table t1 (a int) with system versioning partition by system_time; +drop table t1; +create table t1 (a int) with system versioning partition by system_time +(partition p1 history, partition pn current); +alter table t1 add partition (partition p2); +ERROR HY000: Wrong partitioning type, expected type: `SYSTEM_TIME` +drop table t1; # End of 10.3 tests # # MDEV-22283 Server crashes in key_copy or unexpected error 156: The table already existed in the storage engine diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test index c6b89a23abd..507e8d40256 100644 --- a/mysql-test/suite/versioning/t/partition.test +++ b/mysql-test/suite/versioning/t/partition.test @@ -905,6 +905,21 @@ delete from v1; drop view v1; drop table t1; +--echo # +--echo # MDEV-22112 Assertion `tab_part_info->part_type == RANGE_PARTITION || tab_part_info->part_type == LIST_PARTITION' failed in prep_alter_part_table +--echo # + +create table t1 (a int) with system versioning partition by system_time; +drop table t1; + +create table t1 (a int) with system versioning partition by system_time +(partition p1 history, partition pn current); +--error ER_PARTITION_WRONG_TYPE +alter table t1 add partition (partition p2); + +# Cleanup +drop table t1; + --echo # End of 10.3 tests --echo # diff --git a/sql/partition_info.cc b/sql/partition_info.cc index e9dbf2b49c3..10f82242bca 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -415,6 +415,8 @@ bool partition_info::set_up_default_partitions(THD *thd, handler *file, const char *error_string; if (part_type == RANGE_PARTITION) error_string= "RANGE"; + else if (part_type == VERSIONING_PARTITION) + error_string= "SYSTEM_TIME"; else error_string= "LIST"; my_error(ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0), error_string); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 8dd85d3de24..1567df7d537 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1765,6 +1765,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx) { table= best_table; table->query_id= thd->query_id; + table->init(thd, table_list); DBUG_PRINT("info",("Using locked table")); #ifdef WITH_PARTITION_STORAGE_ENGINE part_names_error= set_partitions_as_used(table_list, table); @@ -2086,12 +2087,13 @@ retry_share: } table->mdl_ticket= mdl_ticket; + table->reginfo.lock_type=TL_READ; /* Assume read */ + + table->init(thd, table_list); table->next= thd->open_tables; /* Link into simple list */ thd->set_open_tables(table); - table->reginfo.lock_type=TL_READ; /* Assume read */ - reset: /* Check that there is no reference to a condition from an earlier query @@ -2123,16 +2125,15 @@ retry_share: my_error(ER_NOT_SEQUENCE, MYF(0), table_list->db.str, table_list->alias.str); DBUG_RETURN(true); } - table->init(thd, table_list); - DBUG_ASSERT(thd->locked_tables_mode || table->file->row_logging == 0); - DBUG_RETURN(FALSE); + DBUG_ASSERT(thd->locked_tables_mode || table->file->row_logging == 0); + DBUG_RETURN(false); err_lock: tdc_release_share(share); DBUG_PRINT("exit", ("failed")); - DBUG_RETURN(TRUE); + DBUG_RETURN(true); } diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 34e4d6e8ea7..9051484b6b8 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -5034,7 +5034,8 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0), "LIST", "IN"); } - else if (thd->work_part_info->part_type == VERSIONING_PARTITION) + else if (thd->work_part_info->part_type == VERSIONING_PARTITION || + tab_part_info->part_type == VERSIONING_PARTITION) { my_error(ER_PARTITION_WRONG_TYPE, MYF(0), "SYSTEM_TIME"); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 2347162ff84..bf192faad77 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -9654,12 +9654,15 @@ best_extension_by_limited_search(JOIN *join, if (join->sort_by_table && join->sort_by_table != join->positions[join->const_tables].table->table) + { /* We may have to make a temp table, note that this is only a heuristic since we cannot know for sure at this point. Hence it may be wrong. */ + trace_one_table.add("cost_for_sorting", current_record_count); current_read_time= COST_ADD(current_read_time, current_record_count); + } trace_one_table.add("estimated_join_cardinality", partial_join_cardinality); if (current_read_time < join->best_read) diff --git a/sql/sql_window.cc b/sql/sql_window.cc index 9e6ef6468e0..68a783341f3 100644 --- a/sql/sql_window.cc +++ b/sql/sql_window.cc @@ -3066,7 +3066,8 @@ bool Window_funcs_sort::setup(THD *thd, SQL_SELECT *sel, */ ORDER *order= (ORDER *)alloc_root(thd->mem_root, sizeof(ORDER)); memset(order, 0, sizeof(*order)); - Item *item= new (thd->mem_root) Item_field(thd, join_tab->table->field[0]); + Item *item= new (thd->mem_root) Item_temptable_field(thd, + join_tab->table->field[0]); order->item= (Item **)alloc_root(thd->mem_root, 2 * sizeof(Item *)); order->item[1]= NULL; order->item[0]= item; diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index 119f16dd667..9a29cc1036a 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -7039,13 +7039,12 @@ static void btr_blob_free(buf_block_t *block, bool all, mtr_t *mtr) mtr->commit(); mutex_enter(&buf_pool.mutex); - /* Free the block if it is still allocated to the same file page. */ - if (block->page.state() == BUF_BLOCK_FILE_PAGE && - block->page.id() == page_id && - !buf_LRU_free_page(&block->page, all) && all && block->page.zip.data) - /* Attempt to deallocate the redundant copy of the uncompressed page - if the whole ROW_FORMAT=COMPRESSED block cannot be deallocted. */ - buf_LRU_free_page(&block->page, false); + + if (buf_page_t *bpage= buf_pool.page_hash_get_low(page_id)) + if(!buf_LRU_free_page(bpage, all) && all && bpage->zip.data) + /* Attempt to deallocate the redundant copy of the uncompressed page + if the whole ROW_FORMAT=COMPRESSED block cannot be deallocted. */ + buf_LRU_free_page(bpage, false); mutex_exit(&buf_pool.mutex); } diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc index ba646dd738a..90afaaccf13 100644 --- a/storage/innobase/btr/btr0sea.cc +++ b/storage/innobase/btr/btr0sea.cc @@ -191,28 +191,32 @@ static void btr_search_check_free_space_in_heap(const dict_index_t* index) { - hash_table_t* table = btr_get_search_table(index); - mem_heap_t* heap = table->heap; - /* Note that we peek the value of heap->free_block without reserving the latch: this is ok, because we will not guarantee that there will be enough free space in the hash table. */ - if (heap->free_block == NULL) { - buf_block_t* block = buf_block_alloc(); - rw_lock_t* ahi_latch = btr_get_search_latch(index); + buf_block_t* block = buf_block_alloc(); + rw_lock_t* latch = btr_get_search_latch(index); + hash_table_t* table; + mem_heap_t* heap; - rw_lock_x_lock(ahi_latch); + rw_lock_x_lock(latch); - if (btr_search_enabled - && heap->free_block == NULL) { - heap->free_block = block; - } else { - buf_block_free(block); - } + if (!btr_search_enabled) { + goto func_exit; + } - rw_lock_x_unlock(ahi_latch); + table = btr_get_search_table(index); + heap = table->heap; + + if (heap->free_block == NULL) { + heap->free_block = block; + } else { +func_exit: + buf_block_free(block); } + + rw_lock_x_unlock(latch); } /** Creates and initializes the adaptive search system at a database start. @@ -240,90 +244,47 @@ void btr_search_sys_create(ulint hash_size) btr_search_sys = reinterpret_cast<btr_search_sys_t*>( ut_malloc(sizeof(btr_search_sys_t), mem_key_ahi)); - btr_search_sys->hash_tables = reinterpret_cast<hash_table_t**>( - ut_malloc(sizeof(hash_table_t*) * btr_ahi_parts, mem_key_ahi)); - - for (ulint i = 0; i < btr_ahi_parts; ++i) { - - btr_search_sys->hash_tables[i] = - ib_create((hash_size / btr_ahi_parts), - LATCH_ID_HASH_TABLE_MUTEX, - 0, MEM_HEAP_FOR_BTR_SEARCH); - -#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG - btr_search_sys->hash_tables[i]->adaptive = TRUE; -#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ - } -} - -/** Resize hash index hash table. -@param[in] hash_size hash index hash table size */ -void btr_search_sys_resize(ulint hash_size) -{ - /* Step-1: Lock all search latches in exclusive mode. */ - btr_search_x_lock_all(); + btr_search_sys->hash_tables = NULL; if (btr_search_enabled) { - - btr_search_x_unlock_all(); - - ib::error() << "btr_search_sys_resize failed because" - " hash index hash table is not empty."; - ut_ad(0); - return; - } - - /* Step-2: Recreate hash tables with new size. */ - for (ulint i = 0; i < btr_ahi_parts; ++i) { - - mem_heap_free(btr_search_sys->hash_tables[i]->heap); - hash_table_free(btr_search_sys->hash_tables[i]); - - btr_search_sys->hash_tables[i] = - ib_create((hash_size / btr_ahi_parts), - LATCH_ID_HASH_TABLE_MUTEX, - 0, MEM_HEAP_FOR_BTR_SEARCH); - -#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG - btr_search_sys->hash_tables[i]->adaptive = TRUE; -#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ + btr_search_enable(); } - - /* Step-3: Unlock all search latches from exclusive mode. */ - btr_search_x_unlock_all(); } /** Frees the adaptive search system at a database shutdown. */ void btr_search_sys_free() { - if (!btr_search_sys) { - ut_ad(!btr_search_latches); - return; - } - - ut_ad(btr_search_latches); + if (!btr_search_sys) + { + ut_ad(!btr_search_latches); + return; + } - /* Step-1: Release the hash tables. */ - for (ulint i = 0; i < btr_ahi_parts; ++i) { + ut_ad(btr_search_sys); + ut_ad(btr_search_latches); - mem_heap_free(btr_search_sys->hash_tables[i]->heap); - hash_table_free(btr_search_sys->hash_tables[i]); - - } + if (btr_search_sys->hash_tables) + { + for (ulint i= 0; i < btr_ahi_parts; ++i) + { + mem_heap_free(btr_search_sys->hash_tables[i]->heap); + hash_table_free(btr_search_sys->hash_tables[i]); + } + ut_free(btr_search_sys->hash_tables); + } - ut_free(btr_search_sys->hash_tables); - ut_free(btr_search_sys); - btr_search_sys = NULL; + ut_free(btr_search_sys); + btr_search_sys= nullptr; - /* Step-2: Release all allocates latches. */ - for (ulint i = 0; i < btr_ahi_parts; ++i) { - - rw_lock_free(btr_search_latches[i]); - ut_free(btr_search_latches[i]); - } + /* Free all latches. */ + for (ulint i= 0; i < btr_ahi_parts; ++i) + { + rw_lock_free(btr_search_latches[i]); + ut_free(btr_search_latches[i]); + } - ut_free(btr_search_latches); - btr_search_latches = NULL; + ut_free(btr_search_latches); + btr_search_latches= nullptr; } /** Set index->ref_count = 0 on all indexes of a table. @@ -353,24 +314,17 @@ ATTRIBUTE_COLD static void btr_search_lazy_free(dict_index_t *index) } } -/** Disable the adaptive hash search system and empty the index. -@param[in] need_mutex need to acquire dict_sys.mutex */ -void btr_search_disable(bool need_mutex) +/** Disable the adaptive hash search system and empty the index. */ +void btr_search_disable() { dict_table_t* table; - if (need_mutex) { - mutex_enter(&dict_sys.mutex); - } + mutex_enter(&dict_sys.mutex); - ut_ad(mutex_own(&dict_sys.mutex)); btr_search_x_lock_all(); if (!btr_search_enabled) { - if (need_mutex) { - mutex_exit(&dict_sys.mutex); - } - + mutex_exit(&dict_sys.mutex); btr_search_x_unlock_all(); return; } @@ -391,33 +345,56 @@ void btr_search_disable(bool need_mutex) btr_search_disable_ref_count(table); } - if (need_mutex) { - mutex_exit(&dict_sys.mutex); - } + mutex_exit(&dict_sys.mutex); /* Set all block->index = NULL. */ buf_pool.clear_hash_index(); /* Clear the adaptive hash index. */ for (ulint i = 0; i < btr_ahi_parts; ++i) { - hash_table_clear(btr_search_sys->hash_tables[i]); - mem_heap_empty(btr_search_sys->hash_tables[i]->heap); + mem_heap_free(btr_search_sys->hash_tables[i]->heap); + hash_table_free(btr_search_sys->hash_tables[i]); } + ut_free(btr_search_sys->hash_tables); + btr_search_sys->hash_tables = NULL; btr_search_x_unlock_all(); } -/** Enable the adaptive hash search system. */ -void btr_search_enable() +/** Enable the adaptive hash search system. +@param resize whether buf_pool_t::resize() is the caller */ +void btr_search_enable(bool resize) { - mutex_enter(&buf_pool.mutex); - if (srv_buf_pool_old_size != srv_buf_pool_size) { + if (!resize) { + mutex_enter(&buf_pool.mutex); + bool changed = srv_buf_pool_old_size != srv_buf_pool_size; mutex_exit(&buf_pool.mutex); - return; + if (changed) { + return; + } } - mutex_exit(&buf_pool.mutex); btr_search_x_lock_all(); + ulint hash_size = buf_pool_get_curr_size() / sizeof(void *) / 64; + + if (btr_search_sys->hash_tables) { + ut_ad(btr_search_enabled); + btr_search_x_unlock_all(); + return; + } + + btr_search_sys->hash_tables = reinterpret_cast<hash_table_t**>( + ut_malloc(sizeof(hash_table_t*) * btr_ahi_parts, mem_key_ahi)); + for (ulint i = 0; i < btr_ahi_parts; ++i) { + btr_search_sys->hash_tables[i] = + ib_create((hash_size / btr_ahi_parts), + LATCH_ID_HASH_TABLE_MUTEX, + 0, MEM_HEAP_FOR_BTR_SEARCH); +#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG + btr_search_sys->hash_tables[i]->adaptive = TRUE; +#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ + } + btr_search_enabled = true; btr_search_x_unlock_all(); } @@ -641,7 +618,8 @@ btr_search_update_hash_ref( if (block->index && (block->curr_n_fields == info->n_fields) && (block->curr_n_bytes == info->n_bytes) - && (block->curr_left_side == info->left_side)) { + && (block->curr_left_side == info->left_side) + && btr_search_enabled) { mem_heap_t* heap = NULL; rec_offs offsets_[REC_OFFS_NORMAL_SIZE]; rec_offs_init(offsets_); @@ -1054,7 +1032,6 @@ got_no_latch: buf_block_dbg_add_level(block, SYNC_TREE_NODE_FROM_HASH); if (UNIV_UNLIKELY(fail)) { - btr_search_drop_page_hash_index(block); goto fail_and_release_page; } } else if (UNIV_UNLIKELY(index != block->index @@ -1203,7 +1180,7 @@ retry: rw_lock_s_lock(latch); assert_block_ahi_valid(block); - if (!block->index) { + if (!block->index || !btr_search_enabled) { rw_lock_s_unlock(latch); return; } @@ -1441,13 +1418,18 @@ btr_search_build_page_hash_index( rw_lock_s_lock(ahi_latch); - const bool rebuild = block->index + const bool enabled = btr_search_enabled; + const bool rebuild = enabled && block->index && (block->curr_n_fields != n_fields || block->curr_n_bytes != n_bytes || block->curr_left_side != left_side); rw_lock_s_unlock(ahi_latch); + if (!enabled) { + return; + } + if (rebuild) { btr_search_drop_page_hash_index(block); } @@ -1555,6 +1537,7 @@ btr_search_build_page_hash_index( goto exit_func; } + table = btr_get_search_table(index); if (block->index && ((block->curr_n_fields != n_fields) || (block->curr_n_bytes != n_bytes) || (block->curr_left_side != left_side))) { @@ -1715,7 +1698,6 @@ btr_search_move_or_delete_hash_entries( using btr_cur_search_, the record is not yet deleted.*/ void btr_search_update_hash_on_delete(btr_cur_t* cursor) { - hash_table_t* table; buf_block_t* block; const rec_t* rec; ulint fold; @@ -1750,8 +1732,6 @@ void btr_search_update_hash_on_delete(btr_cur_t* cursor) ut_a(block->curr_n_fields > 0 || block->curr_n_bytes > 0); ut_ad(!dict_index_is_ibuf(index)); - table = btr_get_search_table(index); - rec = btr_cur_get_rec(cursor); fold = rec_fold(rec, rec_get_offsets(rec, index, offsets_, true, @@ -1761,22 +1741,24 @@ void btr_search_update_hash_on_delete(btr_cur_t* cursor) mem_heap_free(heap); } - rw_lock_t* ahi_latch = btr_get_search_latch(index); + rw_lock_t* ahi_latch = btr_get_search_latch(index); rw_lock_x_lock(ahi_latch); assert_block_ahi_valid(block); - if (block->index) { - ut_a(block->index == index); + if (btr_search_enabled) { + hash_table_t* table = btr_get_search_table(index); + if (block->index) { + ut_a(block->index == index); - if (ha_search_and_delete_if_found(table, fold, rec)) { - MONITOR_INC(MONITOR_ADAPTIVE_HASH_ROW_REMOVED); - } else { - MONITOR_INC( - MONITOR_ADAPTIVE_HASH_ROW_REMOVE_NOT_FOUND); - } + if (ha_search_and_delete_if_found(table, fold, rec)) { + MONITOR_INC(MONITOR_ADAPTIVE_HASH_ROW_REMOVED); + } else { + MONITOR_INC(MONITOR_ADAPTIVE_HASH_ROW_REMOVE_NOT_FOUND); + } - assert_block_ahi_valid(block); + assert_block_ahi_valid(block); + } } rw_lock_x_unlock(ahi_latch); @@ -1822,7 +1804,7 @@ btr_search_update_hash_node_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch) ut_ad(!dict_index_is_ibuf(index)); rw_lock_x_lock(ahi_latch); - if (!block->index) { + if (!block->index || !btr_search_enabled) { goto func_exit; } @@ -1903,8 +1885,6 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch) ut_ad(block->page.id().space() == index->table->space_id); btr_search_check_free_space_in_heap(index); - table = btr_get_search_table(index); - rec = btr_cur_get_rec(cursor); #ifdef MYSQL_INDEX_DISABLE_AHI @@ -1944,10 +1924,11 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch) locked = true; rw_lock_x_lock(ahi_latch); - if (!btr_search_enabled) { + if (!btr_search_enabled || !block->index) { goto function_exit; } + table = btr_get_search_table(index); ha_insert_for_fold(table, ins_fold, block, ins_rec); } @@ -1960,9 +1941,10 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch) locked = true; rw_lock_x_lock(ahi_latch); - if (!btr_search_enabled) { + if (!btr_search_enabled || !block->index) { goto function_exit; } + table = btr_get_search_table(index); } if (!left_side) { @@ -1980,9 +1962,10 @@ check_next_rec: locked = true; rw_lock_x_lock(ahi_latch); - if (!btr_search_enabled) { + if (!btr_search_enabled || !block->index) { goto function_exit; } + table = btr_get_search_table(index); } ha_insert_for_fold(table, ins_fold, block, ins_rec); @@ -1996,9 +1979,10 @@ check_next_rec: locked = true; rw_lock_x_lock(ahi_latch); - if (!btr_search_enabled) { + if (!btr_search_enabled || !block->index) { goto function_exit; } + table = btr_get_search_table(index); } if (!left_side) { @@ -2035,7 +2019,9 @@ btr_search_hash_table_validate(ulint hash_table_id) rec_offs offsets_[REC_OFFS_NORMAL_SIZE]; rec_offs* offsets = offsets_; + btr_search_x_lock_all(); if (!btr_search_enabled) { + btr_search_x_unlock_all(); return(TRUE); } @@ -2045,7 +2031,6 @@ btr_search_hash_table_validate(ulint hash_table_id) rec_offs_init(offsets_); - btr_search_x_lock_all(); mutex_enter(&buf_pool.mutex); cell_count = hash_get_n_cells( @@ -2062,6 +2047,12 @@ btr_search_hash_table_validate(ulint hash_table_id) os_thread_yield(); btr_search_x_lock_all(); + + if (!btr_search_enabled) { + ok = true; + goto func_exit; + } + mutex_enter(&buf_pool.mutex); ulint curr_cell_count = hash_get_n_cells( @@ -2174,6 +2165,12 @@ btr_search_hash_table_validate(ulint hash_table_id) os_thread_yield(); btr_search_x_lock_all(); + + if (!btr_search_enabled) { + ok = true; + goto func_exit; + } + mutex_enter(&buf_pool.mutex); ulint curr_cell_count = hash_get_n_cells( @@ -2198,6 +2195,7 @@ btr_search_hash_table_validate(ulint hash_table_id) } mutex_exit(&buf_pool.mutex); +func_exit: btr_search_x_unlock_all(); if (UNIV_LIKELY_NULL(heap)) { diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 9baf9a361e4..0a685a3e1ab 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -2041,7 +2041,7 @@ inline void buf_pool_t::resize() btr_search_s_unlock_all(); } - btr_search_disable(true); + btr_search_disable(); if (btr_search_disabled) { ib::info() << "disabled adaptive hash index."; @@ -2329,15 +2329,9 @@ calc_buf_pool_size: buf_resize_status("Resizing also other hash tables."); - /* normalize lock_sys */ srv_lock_table_size = 5 * (srv_buf_pool_size >> srv_page_size_shift); lock_sys.resize(srv_lock_table_size); - - /* normalize btr_search_sys */ - btr_search_sys_resize( - buf_pool_get_curr_size() / sizeof(void*) / 64); - dict_sys.resize(); ib::info() << "Resized hash tables at lock_sys," @@ -2361,7 +2355,7 @@ calc_buf_pool_size: #ifdef BTR_CUR_HASH_ADAPT /* enable AHI if needed */ if (btr_search_disabled) { - btr_search_enable(); + btr_search_enable(true); ib::info() << "Re-enabled adaptive hash index."; } #endif /* BTR_CUR_HASH_ADAPT */ @@ -2686,9 +2680,9 @@ lookup: ut_ad(!hash_lock); dberr_t err = buf_read_page(page_id, zip_size); - if (err != DB_SUCCESS) { + if (UNIV_UNLIKELY(err != DB_SUCCESS)) { ib::error() << "Reading compressed page " << page_id - << " failed with error: " << ut_strerr(err); + << " failed with error: " << err; goto err_exit; } @@ -2907,6 +2901,46 @@ buf_wait_for_read( } } +#ifdef BTR_CUR_HASH_ADAPT +/** If a stale adaptive hash index exists on the block, drop it. +Multiple executions of btr_search_drop_page_hash_index() on the +same block must be prevented by exclusive page latch. */ +ATTRIBUTE_COLD +static void buf_defer_drop_ahi(buf_block_t *block, mtr_memo_type_t fix_type) +{ + switch (fix_type) { + case MTR_MEMO_BUF_FIX: + /* We do not drop the adaptive hash index, because safely doing + so would require acquiring block->lock, and that is not safe + to acquire in some RW_NO_LATCH access paths. Those code paths + should have no business accessing the adaptive hash index anyway. */ + break; + case MTR_MEMO_PAGE_S_FIX: + /* Temporarily release our S-latch. */ + rw_lock_s_unlock(&block->lock); + rw_lock_x_lock(&block->lock); + if (dict_index_t *index= block->index) + if (index->freed()) + btr_search_drop_page_hash_index(block); + rw_lock_x_unlock(&block->lock); + rw_lock_s_lock(&block->lock); + break; + case MTR_MEMO_PAGE_SX_FIX: + rw_lock_sx_unlock(&block->lock); + rw_lock_x_lock(&block->lock); + if (dict_index_t *index= block->index) + if (index->freed()) + btr_search_drop_page_hash_index(block); + rw_lock_x_unlock(&block->lock); + rw_lock_sx_lock(&block->lock); + break; + default: + ut_ad(fix_type == MTR_MEMO_PAGE_X_FIX); + btr_search_drop_page_hash_index(block); + } +} +#endif /* BTR_CUR_HASH_ADAPT */ + /** Lock the page with the given latch type. @param[in,out] block block to be locked @param[in] rw_latch RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH @@ -2945,7 +2979,7 @@ static buf_block_t* buf_page_mtr_lock(buf_block_t *block, { dict_index_t *index= block->index; if (index && index->freed()) - btr_search_drop_page_hash_index(block); + buf_defer_drop_ahi(block, fix_type); } #endif /* BTR_CUR_HASH_ADAPT */ diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index 6a2d7fe4f12..3f8fc7b75a8 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -544,11 +544,11 @@ buf_dblwr_process() page_id, zip_size, 0, physical_size, read_buf, NULL); - if (fio.err != DB_SUCCESS) { + if (UNIV_UNLIKELY(fio.err != DB_SUCCESS)) { ib::warn() << "Double write buffer recovery: " << page_id << " read failed with " - << "error: " << ut_strerr(fio.err); + << "error: " << fio.err; } if (fio.node) { diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc index 04340ed79f8..6d6388149d2 100644 --- a/storage/innobase/buf/buf0flu.cc +++ b/storage/innobase/buf/buf0flu.cc @@ -2541,7 +2541,7 @@ static os_thread_ret_t DECLARE_THREAD(buf_flush_page_cleaner)(void*) ulint last_activity = srv_get_activity_count(); ulint last_pages = 0; - while (srv_shutdown_state == SRV_SHUTDOWN_NONE) { + while (srv_shutdown_state <= SRV_SHUTDOWN_INITIATED) { ulint curr_time = ut_time_ms(); /* The page_cleaner skips sleep if the server is @@ -2558,7 +2558,7 @@ static os_thread_ret_t DECLARE_THREAD(buf_flush_page_cleaner)(void*) ret_sleep = 0; } - if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { + if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) { break; } @@ -2727,7 +2727,7 @@ static os_thread_ret_t DECLARE_THREAD(buf_flush_page_cleaner)(void*) ut_d(buf_flush_page_cleaner_disabled_loop()); } - ut_ad(srv_shutdown_state > 0); + ut_ad(srv_shutdown_state > SRV_SHUTDOWN_INITIATED); if (srv_fast_shutdown == 2 || srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) { /* In very fast shutdown or when innodb failed to start, we diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc index 4a2212d1c41..e00e59f79c4 100644 --- a/storage/innobase/dict/dict0crea.cc +++ b/storage/innobase/dict/dict0crea.cc @@ -1491,10 +1491,9 @@ dict_create_or_check_foreign_constraint_tables(void) "END;\n", FALSE, trx); - if (err != DB_SUCCESS) { - + if (UNIV_UNLIKELY(err != DB_SUCCESS)) { ib::error() << "Creation of SYS_FOREIGN and SYS_FOREIGN_COLS" - " failed: " << ut_strerr(err) << ". Tablespace is" + " failed: " << err << ". Tablespace is" " full. Dropping incompletely created tables."; ut_ad(err == DB_OUT_OF_FILE_SPACE @@ -1593,10 +1592,9 @@ dict_create_or_check_sys_virtual() "END;\n", FALSE, trx); - if (err != DB_SUCCESS) { - + if (UNIV_UNLIKELY(err != DB_SUCCESS)) { ib::error() << "Creation of SYS_VIRTUAL" - " failed: " << ut_strerr(err) << ". Tablespace is" + " failed: " << err << ". Tablespace is" " full or too many transactions." " Dropping incompletely created tables."; @@ -1674,9 +1672,9 @@ dict_foreign_eval_sql( return(error); } - if (error != DB_SUCCESS) { + if (UNIV_UNLIKELY(error != DB_SUCCESS)) { ib::error() << "Foreign key constraint creation failed: " - << ut_strerr(error); + << error; mutex_enter(&dict_foreign_err_mutex); ut_print_timestamp(ef); @@ -2127,10 +2125,9 @@ dict_create_or_check_sys_tablespace(void) "END;\n", FALSE, trx); - if (err != DB_SUCCESS) { - + if (UNIV_UNLIKELY(err != DB_SUCCESS)) { ib::error() << "Creation of SYS_TABLESPACES and SYS_DATAFILES" - " has failed with error " << ut_strerr(err) + " has failed with error " << err << ". Dropping incompletely created tables."; ut_a(err == DB_OUT_OF_FILE_SPACE diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc index 7f933cde0f6..c837c6a9d9a 100644 --- a/storage/innobase/dict/dict0load.cc +++ b/storage/innobase/dict/dict0load.cc @@ -899,7 +899,7 @@ dict_update_filepath( trx->dict_operation_lock_mode = 0; trx_free(trx); - if (err == DB_SUCCESS) { + if (UNIV_LIKELY(err == DB_SUCCESS)) { /* We just updated SYS_DATAFILES due to the contents in a link file. Make a note that we did this. */ ib::info() << "The InnoDB data dictionary table SYS_DATAFILES" @@ -909,7 +909,7 @@ dict_update_filepath( ib::warn() << "Error occurred while updating InnoDB data" " dictionary table SYS_DATAFILES for tablespace ID " << space_id << " to file " << filepath << ": " - << ut_strerr(err) << "."; + << err << "."; } return(err); @@ -1354,6 +1354,7 @@ static ulint dict_check_sys_tables() for (rec = dict_startscan_system(&pcur, &mtr, SYS_TABLES); rec != NULL; + mtr.commit(), mtr.start(), rec = dict_getnext_system(&pcur, &mtr)) { const byte* field; ulint len; diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index 1111bcb1cf0..82da06c6b27 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -2349,14 +2349,14 @@ dict_stats_save_index_stat( ");\n" "END;", trx); - if (ret != DB_SUCCESS) { + if (UNIV_UNLIKELY(ret != DB_SUCCESS)) { if (innodb_index_stats_not_found == false && index->stats_error_printed == false) { ib::error() << "Cannot save index statistics for table " << index->table->name << ", index " << index->name << ", stat name \"" << stat_name << "\": " - << ut_strerr(ret); + << ret; index->stats_error_printed = true; } } @@ -2466,9 +2466,9 @@ dict_stats_save( ");\n" "END;", NULL); - if (ret != DB_SUCCESS) { + if (UNIV_UNLIKELY(ret != DB_SUCCESS)) { ib::error() << "Cannot save table statistics for table " - << table->name << ": " << ut_strerr(ret); + << table->name << ": " << ret; func_exit: dict_sys_unlock(); dict_stats_snapshot_free(table); @@ -3314,7 +3314,7 @@ dict_stats_update( " for table " << table->name << " from " TABLE_STATS_NAME_PRINT " and " - INDEX_STATS_NAME_PRINT ": " << ut_strerr(err) + INDEX_STATS_NAME_PRINT ": " << err << ". Using transient stats method instead."; } diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index 0e62cff0ea1..c08f1eedc33 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -288,14 +288,9 @@ fil_space_crypt_t* fil_space_read_crypt_data(ulint zip_size, const byte* page) type == CRYPT_SCHEME_1) || iv_length != sizeof crypt_data->iv) { ib::error() << "Found non sensible crypt scheme: " - << type << "," << iv_length << " for space: " - << page_get_space_id(page) << " offset: " - << offset << " bytes: [" - << page[offset + 2 + MAGIC_SZ] - << page[offset + 3 + MAGIC_SZ] - << page[offset + 4 + MAGIC_SZ] - << page[offset + 5 + MAGIC_SZ] - << "]."; + << type << "," << iv_length + << " for space: " + << page_get_space_id(page); return NULL; } @@ -784,8 +779,10 @@ static bool fil_space_decrypt_for_non_full_checksum( } ib::fatal() << "Unable to decrypt data-block " - << " src: " << src << "srclen: " - << srclen << " buf: " << dst << "buflen: " + << " src: " << static_cast<const void*>(src) + << "srclen: " + << srclen << " buf: " + << static_cast<const void*>(dst) << "buflen: " << dstlen << " return-code: " << rc << " Can't continue!"; } @@ -1163,6 +1160,7 @@ struct rotate_thread_t { case SRV_SHUTDOWN_EXIT_THREADS: /* srv_init_abort() must have been invoked */ case SRV_SHUTDOWN_CLEANUP: + case SRV_SHUTDOWN_INITIATED: return true; case SRV_SHUTDOWN_FLUSH_PHASE: case SRV_SHUTDOWN_LAST_PHASE: diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index b627e7826a5..75e49d24ad2 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -4007,8 +4007,7 @@ write_completed: recv_sys.found_corrupt_fs= true; ib::error() << "Failed to read page " << id.page_no() - << " from file '" << node->name << "': " - << ut_strerr(err); + << " from file '" << node->name << "': " << err; } mutex_enter(&fil_system.mutex); diff --git a/storage/innobase/fsp/fsp0file.cc b/storage/innobase/fsp/fsp0file.cc index 6f133b8db78..198d69206ec 100644 --- a/storage/innobase/fsp/fsp0file.cc +++ b/storage/innobase/fsp/fsp0file.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2013, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2019, MariaDB Corporation. +Copyright (c) 2017, 2020, 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 @@ -328,7 +328,7 @@ Datafile::read_first_page(bool read_only_mode) ib::error() << "Cannot read first page of '" << m_filepath << "' " - << ut_strerr(err); + << err; break; } } diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc index 323cd2e35a2..b473efccfee 100644 --- a/storage/innobase/fsp/fsp0fsp.cc +++ b/storage/innobase/fsp/fsp0fsp.cc @@ -1180,7 +1180,7 @@ fsp_alloc_free_page( ut_a(!is_system_tablespace(space_id)); if (page_no >= FSP_EXTENT_SIZE) { ib::error() << "Trying to extend a single-table" - " tablespace " << space << " , by single" + " tablespace " << space->name << " , by single" " page(s) though the space size " << space_size << ". Page no " << page_no << "."; return(NULL); diff --git a/storage/innobase/fts/fts0config.cc b/storage/innobase/fts/fts0config.cc index 410d60a5f4e..8ae10c2465d 100644 --- a/storage/innobase/fts/fts0config.cc +++ b/storage/innobase/fts/fts0config.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2019, MariaDB Corporation. +Copyright (c) 2017, 2020, 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 @@ -317,9 +317,7 @@ fts_config_get_index_ulint( error = fts_config_get_index_value(trx, index, name, &value); if (UNIV_UNLIKELY(error != DB_SUCCESS)) { - - ib::error() << "(" << ut_strerr(error) << ") reading `" - << name << "'"; + ib::error() << "(" << error << ") reading `" << name << "'"; } else { *int_value = strtoul((char*) value.f_str, NULL, 10); } @@ -357,9 +355,7 @@ fts_config_set_index_ulint( error = fts_config_set_index_value(trx, index, name, &value); if (UNIV_UNLIKELY(error != DB_SUCCESS)) { - - ib::error() << "(" << ut_strerr(error) << ") writing `" - << name << "'"; + ib::error() << "(" << error << ") writing `" << name << "'"; } ut_free(value.f_str); @@ -391,8 +387,7 @@ fts_config_get_ulint( error = fts_config_get_value(trx, fts_table, name, &value); if (UNIV_UNLIKELY(error != DB_SUCCESS)) { - ib::error() << "(" << ut_strerr(error) << ") reading `" - << name << "'"; + ib::error() << "(" << error << ") reading `" << name << "'"; } else { *int_value = strtoul((char*) value.f_str, NULL, 10); } @@ -430,8 +425,7 @@ fts_config_set_ulint( error = fts_config_set_value(trx, fts_table, name, &value); if (UNIV_UNLIKELY(error != DB_SUCCESS)) { - ib::error() << "(" << ut_strerr(error) << ") writing `" - << name << "'"; + ib::error() << "(" << error << ") writing `" << name << "'"; } ut_free(value.f_str); diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 7691e19a33a..7f89a0b6f42 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -509,7 +509,7 @@ cleanup: for (;;) { dberr_t error = fts_eval_sql(trx, graph); - if (error == DB_SUCCESS) { + if (UNIV_LIKELY(error == DB_SUCCESS)) { fts_sql_commit(trx); stopword_info->status = STOPWORD_USER_TABLE; break; @@ -522,7 +522,7 @@ cleanup: trx->error_state = DB_SUCCESS; } else { - ib::error() << "Error '" << ut_strerr(error) + ib::error() << "Error '" << error << "' while reading user stopword" " table."; ret = FALSE; @@ -1435,9 +1435,9 @@ fts_drop_table( error = row_drop_table_for_mysql(table_name, trx, SQLCOM_DROP_DB, false, false); - if (error != DB_SUCCESS) { + if (UNIV_UNLIKELY(error != DB_SUCCESS)) { ib::error() << "Unable to drop FTS index aux table " - << table_name << ": " << ut_strerr(error); + << table_name << ": " << error; } } else { error = DB_FAIL; @@ -2490,8 +2490,7 @@ fts_get_max_cache_size( error = fts_config_get_value( trx, fts_table, FTS_MAX_CACHE_SIZE_IN_MB, &value); - if (error == DB_SUCCESS) { - + if (UNIV_LIKELY(error == DB_SUCCESS)) { value.f_str[value.f_len] = 0; cache_size_in_mb = strtoul((char*) value.f_str, NULL, 10); @@ -2521,7 +2520,7 @@ fts_get_max_cache_size( cache_size_in_mb = FTS_CACHE_SIZE_LOWER_LIMIT_IN_MB; } } else { - ib::error() << "(" << ut_strerr(error) << ") reading max" + ib::error() << "(" << error << ") reading max" " cache config value from config table"; } @@ -2690,13 +2689,12 @@ retry: func_exit: - if (error == DB_SUCCESS) { + if (UNIV_LIKELY(error == DB_SUCCESS)) { fts_sql_commit(trx); } else { *doc_id = 0; - ib::error() << "(" << ut_strerr(error) << ") while getting" - " next doc id."; + ib::error() << "(" << error << ") while getting next doc id."; fts_sql_rollback(trx); if (error == DB_DEADLOCK) { @@ -2771,12 +2769,11 @@ fts_update_sync_doc_id( fts_que_graph_free_check_lock(&fts_table, NULL, graph); if (local_trx) { - if (error == DB_SUCCESS) { + if (UNIV_LIKELY(error == DB_SUCCESS)) { fts_sql_commit(trx); cache->synced_doc_id = doc_id; } else { - - ib::error() << "(" << ut_strerr(error) << ") while" + ib::error() << "(" << error << ") while" " updating last doc id."; fts_sql_rollback(trx); @@ -4000,14 +3997,14 @@ fts_sync_write_words( n_nodes += ib_vector_size(word->nodes); - if (error != DB_SUCCESS && !print_error) { - ib::error() << "(" << ut_strerr(error) << ") writing" + if (UNIV_UNLIKELY(error != DB_SUCCESS) && !print_error) { + ib::error() << "(" << error << ") writing" " word node to FTS auxiliary index table."; print_error = TRUE; } } - if (fts_enable_diag_print) { + if (UNIV_UNLIKELY(fts_enable_diag_print)) { printf("Avg number of nodes: %lf\n", (double) n_nodes / (double) (n_words > 1 ? n_words : 1)); } @@ -4033,7 +4030,7 @@ fts_sync_begin( sync->trx = trx_create(); trx_start_internal(sync->trx); - if (fts_enable_diag_print) { + if (UNIV_UNLIKELY(fts_enable_diag_print)) { ib::info() << "FTS SYNC for table " << sync->table->name << ", deleted count: " << ib_vector_size(cache->deleted_doc_ids) @@ -4056,7 +4053,7 @@ fts_sync_index( trx->op_info = "doing SYNC index"; - if (fts_enable_diag_print) { + if (UNIV_UNLIKELY(fts_enable_diag_print)) { ib::info() << "SYNC words: " << rbt_size(index_cache->words); } @@ -4153,18 +4150,14 @@ fts_sync_commit( fts_cache_init(cache); rw_lock_x_unlock(&cache->lock); - if (error == DB_SUCCESS) { - + if (UNIV_LIKELY(error == DB_SUCCESS)) { fts_sql_commit(trx); - - } else if (error != DB_SUCCESS) { - + } else { fts_sql_rollback(trx); - - ib::error() << "(" << ut_strerr(error) << ") during SYNC."; + ib::error() << "(" << error << ") during SYNC."; } - if (fts_enable_diag_print && elapsed_time) { + if (UNIV_UNLIKELY(fts_enable_diag_print) && elapsed_time) { ib::info() << "SYNC for table " << sync->table->name << ": SYNC time: " << (time(NULL) - sync->start_time) @@ -4910,7 +4903,7 @@ fts_get_rows_count( for (;;) { error = fts_eval_sql(trx, graph); - if (error == DB_SUCCESS) { + if (UNIV_LIKELY(error == DB_SUCCESS)) { fts_sql_commit(trx); break; /* Exit the loop. */ @@ -4923,7 +4916,7 @@ fts_get_rows_count( trx->error_state = DB_SUCCESS; } else { - ib::error() << "(" << ut_strerr(error) + ib::error() << "(" << error << ") while reading FTS table."; break; /* Exit the loop. */ @@ -6946,7 +6939,7 @@ fts_drop_orphaned_tables(void) for (;;) { dberr_t error = fts_eval_sql(trx, graph); - if (error == DB_SUCCESS) { + if (UNIV_LIKELY(error == DB_SUCCESS)) { fts_check_and_drop_orphaned_tables(trx, tables); break; /* Exit the loop. */ } else { @@ -6960,7 +6953,7 @@ fts_drop_orphaned_tables(void) trx->error_state = DB_SUCCESS; } else { - ib::error() << "(" << ut_strerr(error) + ib::error() << "(" << error << ") while reading SYS_TABLES."; break; /* Exit the loop. */ diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc index 8dcaa05ef06..490cbcd4546 100644 --- a/storage/innobase/fts/fts0opt.cc +++ b/storage/innobase/fts/fts0opt.cc @@ -531,7 +531,7 @@ fts_index_fetch_nodes( for (;;) { error = fts_eval_sql(trx, *graph); - if (error == DB_SUCCESS) { + if (UNIV_LIKELY(error == DB_SUCCESS)) { fts_sql_commit(trx); break; /* Exit the loop. */ @@ -544,7 +544,7 @@ fts_index_fetch_nodes( trx->error_state = DB_SUCCESS; } else { - ib::error() << "(" << ut_strerr(error) + ib::error() << "(" << error << ") while reading FTS index."; break; /* Exit the loop. */ @@ -866,7 +866,7 @@ fts_index_fetch_words( error = fts_eval_sql(optim->trx, graph); } - if (error == DB_SUCCESS) { + if (UNIV_LIKELY(error == DB_SUCCESS)) { //FIXME fts_sql_commit(optim->trx); break; } else { @@ -883,7 +883,7 @@ fts_index_fetch_words( optim->trx->error_state = DB_SUCCESS; } else { - ib::error() << "(" << ut_strerr(error) + ib::error() << "(" << error << ") while reading document."; break; /* Exit the loop. */ @@ -1362,12 +1362,6 @@ fts_optimize_word( enc.src_last_doc_id = 0; enc.src_ilist_ptr = NULL; - if (fts_enable_diag_print) { - word->text.f_str[word->text.f_len] = 0; - ib::info() << "FTS_OPTIMIZE: optimize \"" << word->text.f_str - << "\""; - } - while (i < size) { ulint copied; fts_node_t* src_node; @@ -1445,11 +1439,6 @@ fts_optimize_write_word( ut_ad(fts_table->charset); - if (fts_enable_diag_print) { - ib::info() << "FTS_OPTIMIZE: processed \"" << word->f_str - << "\""; - } - pars_info_bind_varchar_literal( info, "word", word->f_str, word->f_len); @@ -1467,8 +1456,8 @@ fts_optimize_write_word( error = fts_eval_sql(trx, graph); - if (error != DB_SUCCESS) { - ib::error() << "(" << ut_strerr(error) << ") during optimize," + if (UNIV_UNLIKELY(error != DB_SUCCESS)) { + ib::error() << "(" << error << ") during optimize," " when deleting a word from the FTS index."; } @@ -1491,8 +1480,8 @@ fts_optimize_write_word( error = fts_write_node( trx, &graph, fts_table, word, node); - if (error != DB_SUCCESS) { - ib::error() << "(" << ut_strerr(error) << ")" + if (UNIV_UNLIKELY(error != DB_SUCCESS)) { + ib::error() << "(" << error << ")" " during optimize, while adding a" " word to the FTS index."; } @@ -1881,9 +1870,8 @@ fts_optimize_index_completed( error = fts_config_set_index_value( optim->trx, index, FTS_LAST_OPTIMIZED_WORD, &word); - if (error != DB_SUCCESS) { - - ib::error() << "(" << ut_strerr(error) << ") while updating" + if (UNIV_UNLIKELY(error != DB_SUCCESS)) { + ib::error() << "(" << error << ") while updating" " last optimized word!"; } @@ -2435,7 +2423,7 @@ fts_optimize_table( fts_optimize_t* optim = NULL; fts_t* fts = table->fts; - if (fts_enable_diag_print) { + if (UNIV_UNLIKELY(fts_enable_diag_print)) { ib::info() << "FTS start optimize " << table->name; } @@ -2487,7 +2475,7 @@ fts_optimize_table( if (error == DB_SUCCESS && optim->n_completed == ib_vector_size(fts->indexes)) { - if (fts_enable_diag_print) { + if (UNIV_UNLIKELY(fts_enable_diag_print)) { ib::info() << "FTS_OPTIMIZE: Completed" " Optimize, cleanup DELETED table"; } @@ -2510,7 +2498,7 @@ fts_optimize_table( fts_optimize_free(optim); - if (fts_enable_diag_print) { + if (UNIV_UNLIKELY(fts_enable_diag_print)) { ib::info() << "FTS end optimize " << table->name; } @@ -2709,7 +2697,7 @@ static bool fts_optimize_del_table(const dict_table_t* table) slot = static_cast<fts_slot_t*>(ib_vector_get(fts_slots, i)); if (slot->table == table) { - if (fts_enable_diag_print) { + if (UNIV_UNLIKELY(fts_enable_diag_print)) { ib::info() << "FTS Optimize Removing table " << table->name; } @@ -2836,8 +2824,7 @@ static void fts_optimize_callback(void *) static ulint n_tables = ib_vector_size(fts_slots); static ulint n_optimize = 0; - while (!done && srv_shutdown_state == SRV_SHUTDOWN_NONE) { - + while (!done && srv_shutdown_state <= SRV_SHUTDOWN_INITIATED) { /* If there is no message in the queue and we have tables to optimize then optimize the tables. */ diff --git a/storage/innobase/fts/fts0que.cc b/storage/innobase/fts/fts0que.cc index c789502512c..db972b5dbff 100644 --- a/storage/innobase/fts/fts0que.cc +++ b/storage/innobase/fts/fts0que.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2019, MariaDB Corporation. +Copyright (c) 2017, 2020, 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 @@ -2448,9 +2448,8 @@ fts_query_match_document( get_doc, match->doc_id, NULL, FTS_FETCH_DOC_BY_ID_EQUAL, fts_query_fetch_document, &phrase); - if (error != DB_SUCCESS) { - ib::error() << "(" << ut_strerr(error) - << ") matching document."; + if (UNIV_UNLIKELY(error != DB_SUCCESS)) { + ib::error() << "(" << error << ") matching document."; } else { *found = phrase.found; } @@ -2496,8 +2495,8 @@ fts_query_is_in_proximity_range( &get_doc, match[0]->doc_id, NULL, FTS_FETCH_DOC_BY_ID_EQUAL, fts_query_fetch_document, &phrase); - if (err != DB_SUCCESS) { - ib::error() << "(" << ut_strerr(err) << ") in verification" + if (UNIV_UNLIKELY(err != DB_SUCCESS)) { + ib::error() << "(" << err << ") in verification" " phase of proximity search"; } @@ -3503,14 +3502,6 @@ fts_query_calculate_idf( word_freq->doc_count)); } } - - if (fts_enable_diag_print) { - ib::info() << "'" << word_freq->word.f_str << "' -> " - << query->total_docs << "/" - << word_freq->doc_count << " " - << std::setw(6) << std::setprecision(5) - << word_freq->idf; - } } } @@ -3886,7 +3877,7 @@ fts_query_parse( } else { query->root = state.root; - if (fts_enable_diag_print && query->root != NULL) { + if (UNIV_UNLIKELY(fts_enable_diag_print) && query->root) { fts_ast_node_print(query->root); } } @@ -4110,7 +4101,7 @@ fts_query( ut_free(lc_query_str); - if (fts_enable_diag_print && (*result)) { + if (UNIV_UNLIKELY(fts_enable_diag_print) && (*result)) { ulint diff_time = ut_time_ms() - start_time_ms; ib::info() << "FTS Search Processing time: " @@ -4266,7 +4257,7 @@ fts_expand_query( query->total_size += SIZEOF_RBT_CREATE; - if (fts_enable_diag_print) { + if (UNIV_UNLIKELY(fts_enable_diag_print)) { fts_print_doc_id(query); } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 7e31f53ecd3..674496bd3a9 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -9513,7 +9513,7 @@ ha_innobase::ft_init_ext( const CHARSET_INFO* char_set = key->charset(); const char* query = key->ptr(); - if (fts_enable_diag_print) { + if (UNIV_UNLIKELY(fts_enable_diag_print)) { { ib::info out; out << "keynr=" << keynr << ", '"; @@ -17650,7 +17650,7 @@ innodb_adaptive_hash_index_update(THD*, st_mysql_sys_var*, void*, if (*(my_bool*) save) { btr_search_enable(); } else { - btr_search_disable(true); + btr_search_disable(); } mysql_mutex_lock(&LOCK_global_system_variables); } diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index a137eaf4406..97f56796e69 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -11250,7 +11250,7 @@ foreign_fail: trx_start_for_ddl(trx, TRX_DICT_OP_TABLE); dberr_t error = row_merge_drop_table(trx, ctx->old_table); - if (error != DB_SUCCESS) { + if (UNIV_UNLIKELY(error != DB_SUCCESS)) { ib::error() << "Inplace alter table " << ctx->old_table->name << " dropping copy of the old table failed error " << error diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index 41764afbee6..d2d9a546969 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -2965,7 +2965,7 @@ i_s_fts_index_table_fill_selected( for (;;) { error = fts_eval_sql(trx, graph); - if (error == DB_SUCCESS) { + if (UNIV_LIKELY(error == DB_SUCCESS)) { fts_sql_commit(trx); break; @@ -2979,7 +2979,7 @@ i_s_fts_index_table_fill_selected( trx->error_state = DB_SUCCESS; } else { ib::error() << "Error occurred while reading" - " FTS index: " << ut_strerr(error); + " FTS index: " << error; break; } } @@ -6571,9 +6571,7 @@ i_s_dict_fill_sys_tablespaces( break; default: - ib::error() - << "File '" << filepath << "' " - << ut_strerr(err); + ib::error() << "File '" << filepath << "' " << err; break; } diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc index c2768d2bfb9..ee5ab3eaafe 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.cc +++ b/storage/innobase/ibuf/ibuf0ibuf.cc @@ -2529,7 +2529,7 @@ static ulint ibuf_merge(ulint* n_pages) when a slow shutdown is being executed. During a slow shutdown, the insert buffer merge must be completed. */ - if (ibuf.empty && !srv_shutdown_state) { + if (ibuf.empty && srv_shutdown_state <= SRV_SHUTDOWN_INITIATED) { return(0); #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG } else if (ibuf_debug) { diff --git a/storage/innobase/include/btr0pcur.ic b/storage/innobase/include/btr0pcur.ic index 9c99da42b97..d93da475a1f 100644 --- a/storage/innobase/include/btr0pcur.ic +++ b/storage/innobase/include/btr0pcur.ic @@ -445,14 +445,14 @@ btr_pcur_open_low( #endif /* BTR_CUR_HASH_ADAPT */ file, line, mtr, autoinc); - if (err != DB_SUCCESS) { - ib::warn() << " Error code: " << err - << " btr_pcur_open_low " + if (UNIV_UNLIKELY(err != DB_SUCCESS)) { + ib::warn() << "btr_pcur_open_low" << " level: " << level << " called from file: " << file << " line: " << line << " table: " << index->table->name - << " index: " << index->name; + << " index: " << index->name + << " error: " << err; } cursor->pos_state = BTR_PCUR_IS_POSITIONED; diff --git a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0sea.h index c77faed50e1..a406676c6ed 100644 --- a/storage/innobase/include/btr0sea.h +++ b/storage/innobase/include/btr0sea.h @@ -35,18 +35,15 @@ Created 2/17/1996 Heikki Tuuri @param[in] hash_size hash table size. */ void btr_search_sys_create(ulint hash_size); -/** Resize hash index hash table. -@param[in] hash_size hash index hash table size */ -void btr_search_sys_resize(ulint hash_size); - /** Frees the adaptive search system at a database shutdown. */ void btr_search_sys_free(); -/** Disable the adaptive hash search system and empty the index. -@param need_mutex need to acquire dict_sys.mutex */ -void btr_search_disable(bool need_mutex); -/** Enable the adaptive hash search system. */ -void btr_search_enable(); +/** Disable the adaptive hash search system and empty the index. */ +void btr_search_disable(); + +/** Enable the adaptive hash search system. +@param resize whether buf_pool_t::resize() is the caller */ +void btr_search_enable(bool resize= false); /*********************************************************************//** Updates the search info. */ @@ -186,7 +183,6 @@ static inline hash_table_t* btr_get_search_table(const dict_index_t* index); # define btr_search_move_or_delete_hash_entries(new_block, block) # define btr_search_update_hash_on_insert(cursor, ahi_latch) # define btr_search_update_hash_on_delete(cursor) -# define btr_search_sys_resize(hash_size) #endif /* BTR_CUR_HASH_ADAPT */ #ifdef BTR_CUR_ADAPT diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h index c05fc1541b7..9faf12f13a3 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -541,6 +541,7 @@ lock_has_to_wait( locks are record locks */ /*********************************************************************//** Reports that a transaction id is insensible, i.e., in the future. */ +ATTRIBUTE_COLD void lock_report_trx_id_insanity( /*========================*/ diff --git a/storage/innobase/include/srv0start.h b/storage/innobase/include/srv0start.h index 34ca11a23f0..596f6d4f5ab 100644 --- a/storage/innobase/include/srv0start.h +++ b/storage/innobase/include/srv0start.h @@ -109,6 +109,8 @@ extern ibool srv_start_raw_disk_in_use; /** Shutdown state */ enum srv_shutdown_t { SRV_SHUTDOWN_NONE = 0, /*!< Database running normally */ + /** Shutdown initiated in srv_shutdown_bg_undo_sources() */ + SRV_SHUTDOWN_INITIATED, SRV_SHUTDOWN_CLEANUP, /*!< Cleaning up in logs_empty_and_mark_files_at_shutdown() */ SRV_SHUTDOWN_FLUSH_PHASE,/*!< At this phase the master and the diff --git a/storage/innobase/include/ut0ut.h b/storage/innobase/include/ut0ut.h index 0d8cfb817ea..6b79a445789 100644 --- a/storage/innobase/include/ut0ut.h +++ b/storage/innobase/include/ut0ut.h @@ -328,48 +328,41 @@ operator<<( It contains a std::ostringstream object. The main purpose of this class is to forward operator<< to the underlying std::ostringstream object. Do not use this class directly, instead use one of the derived classes. */ -class logger { -public: - template<typename T> - ATTRIBUTE_COLD - logger& operator<<(const T& rhs) - { - m_oss << rhs; - return(*this); - } - - /** Write the given buffer to the internal string stream object. - @param[in] buf the buffer whose contents will be logged. - @param[in] count the length of the buffer buf. - @return the output stream into which buffer was written. */ - ATTRIBUTE_COLD - std::ostream& - write( - const char* buf, - std::streamsize count) - { - return(m_oss.write(buf, count)); - } - - /** Write the given buffer to the internal string stream object. - @param[in] buf the buffer whose contents will be logged. - @param[in] count the length of the buffer buf. - @return the output stream into which buffer was written. */ - ATTRIBUTE_COLD - std::ostream& - write( - const byte* buf, - std::streamsize count) - { - return(m_oss.write(reinterpret_cast<const char*>(buf), count)); - } - - std::ostringstream m_oss; +class logger +{ protected: - /* This class must not be used directly, hence making the default - constructor protected. */ - ATTRIBUTE_COLD - logger() {} + /* This class must not be used directly */ + ATTRIBUTE_COLD ATTRIBUTE_NOINLINE logger() {} +public: + template<typename T> ATTRIBUTE_COLD ATTRIBUTE_NOINLINE + logger& operator<<(const T& rhs) + { + m_oss << rhs; + return *this; + } + + /** Handle a fixed character string in the same way as a pointer to + an unknown-length character string, to reduce object code bloat. */ + template<size_t N> logger& operator<<(const char (&rhs)[N]) + { return *this << static_cast<const char*>(rhs); } + + /** Output an error code name */ + ATTRIBUTE_COLD logger& operator<<(dberr_t err); + + /** Append a string. + @param buf string buffer + @param size buffer size + @return the output stream */ + ATTRIBUTE_COLD __attribute__((noinline)) + std::ostream &write(const char *buf, std::streamsize size) + { + return m_oss.write(buf, size); + } + + std::ostream &write(const byte *buf, std::streamsize size) + { return write(reinterpret_cast<const char*>(buf), size); } + + std::ostringstream m_oss; }; /** The class info is used to emit informational log messages. It is to be diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index e07efa4f094..e93348a463b 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -318,6 +318,7 @@ static FILE* lock_latest_err_file; /*********************************************************************//** Reports that a transaction id is insensible, i.e., in the future. */ +ATTRIBUTE_COLD void lock_report_trx_id_insanity( /*========================*/ @@ -331,7 +332,7 @@ lock_report_trx_id_insanity( ut_ad(!rec_is_metadata(rec, *index)); ib::error() - << "Transaction id " << trx_id + << "Transaction id " << ib::hex(trx_id) << " associated with record" << rec_offsets_print(rec, offsets) << " in index " << index->name << " of table " << index->table->name @@ -356,7 +357,7 @@ lock_check_trx_id_sanity( trx_id_t max_trx_id = trx_sys.get_max_trx_id(); ut_ad(max_trx_id || srv_force_recovery >= SRV_FORCE_NO_UNDO_LOG_SCAN); - if (max_trx_id && trx_id >= max_trx_id) { + if (UNIV_LIKELY(max_trx_id) && UNIV_UNLIKELY(trx_id >= max_trx_id)) { lock_report_trx_id_insanity( trx_id, rec, index, offsets, max_trx_id); return false; @@ -732,7 +733,7 @@ lock_rec_has_to_wait( && wsrep_thd_is_BF(lock2->trx->mysql_thd, TRUE)) { mtr_t mtr; - if (wsrep_debug) { + if (UNIV_UNLIKELY(wsrep_debug)) { ib::info() << "BF-BF lock conflict, locking: " << for_locking; lock_rec_print(stderr, lock2, mtr); @@ -744,7 +745,7 @@ lock_rec_has_to_wait( if ((type_mode & LOCK_MODE_MASK) == LOCK_X && (lock2->type_mode & LOCK_MODE_MASK) == LOCK_X) { - if (for_locking || wsrep_debug) { + if (for_locking || UNIV_UNLIKELY(wsrep_debug)) { /* exclusive lock conflicts are not accepted */ ib::info() @@ -779,7 +780,7 @@ lock_rec_has_to_wait( << ":" << lock2->type_mode << " idx: " << lock2->index->name() << " table: " - << lock2->index->table->name.m_name + << lock2->index->table->name << " n_uniq: " << lock2->index->n_uniq << " n_user: " << lock2->index->n_user_defined_cols @@ -1085,7 +1086,7 @@ wsrep_kill_victim( trx->mysql_thd, lock->trx->mysql_thd))) { if (lock->trx->lock.que_state == TRX_QUE_LOCK_WAIT) { - if (wsrep_debug) { + if (UNIV_UNLIKELY(wsrep_debug)) { ib::info() << "WSREP: BF victim waiting\n"; } /* cannot release lock, until our lock @@ -1263,13 +1264,14 @@ lock_number_of_tables_locked( /*============== RECORD LOCK CREATION AND QUEUE MANAGEMENT =============*/ #ifdef WITH_WSREP +ATTRIBUTE_COLD static void wsrep_print_wait_locks( /*===================*/ lock_t* c_lock) /* conflicting lock to print */ { - if (wsrep_debug && c_lock->trx->lock.wait_lock != c_lock) { + if (c_lock->trx->lock.wait_lock != c_lock) { mtr_t mtr; ib::info() << "WSREP: c_lock != wait lock"; ib::info() << " SQL: " @@ -1421,7 +1423,7 @@ lock_rec_create_low( c_lock->trx->lock.was_chosen_as_deadlock_victim = TRUE; - if (wsrep_debug) { + if (UNIV_UNLIKELY(wsrep_debug)) { wsrep_print_wait_locks(c_lock); } @@ -1448,7 +1450,7 @@ lock_rec_create_low( trx_mutex_exit(c_lock->trx); - if (wsrep_debug) { + if (UNIV_UNLIKELY(wsrep_debug)) { ib::info() << "WSREP: c_lock canceled " << ib::hex(c_lock->trx->id) << " SQL: " @@ -1718,7 +1720,7 @@ lock_rec_enqueue_waiting( transaction as a victim, it is possible that we already have the lock now granted! */ #ifdef WITH_WSREP - if (wsrep_debug) { + if (UNIV_UNLIKELY(wsrep_debug)) { ib::info() << "WSREP: BF thread got lock granted early, ID " << ib::hex(trx->id) << " query: " << wsrep_thd_query(trx->mysql_thd); } @@ -2039,7 +2041,7 @@ lock_rec_has_to_wait_in_queue( #ifdef WITH_WSREP if (wsrep_thd_is_BF(wait_lock->trx->mysql_thd, FALSE) && wsrep_thd_is_BF(lock->trx->mysql_thd, TRUE)) { - if (wsrep_debug) { + if (UNIV_UNLIKELY(wsrep_debug)) { mtr_t mtr; ib::info() << "WSREP: waiting BF trx: " << ib::hex(wait_lock->trx->id) << " query: " << wsrep_thd_query(wait_lock->trx->mysql_thd); @@ -3502,7 +3504,7 @@ lock_table_create( if (wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { ut_list_insert(table->locks, c_lock, lock, TableLockGetNode()); - if (wsrep_debug) { + if (UNIV_UNLIKELY(wsrep_debug)) { ib::info() << "table lock BF conflict for " << ib::hex(c_lock->trx->id) << " SQL: " @@ -3518,7 +3520,7 @@ lock_table_create( if (c_lock->trx->lock.que_state == TRX_QUE_LOCK_WAIT) { c_lock->trx->lock.was_chosen_as_deadlock_victim = TRUE; - if (wsrep_debug) { + if (UNIV_UNLIKELY(wsrep_debug)) { wsrep_print_wait_locks(c_lock); } @@ -3529,7 +3531,7 @@ lock_table_create( c_lock->trx->lock.wait_lock); trx_mutex_enter(trx); - if (wsrep_debug) { + if (UNIV_UNLIKELY(wsrep_debug)) { ib::info() << "WSREP: c_lock canceled " << ib::hex(c_lock->trx->id) << " SQL: " @@ -3802,9 +3804,9 @@ lock_table_other_has_incompatible( #ifdef WITH_WSREP if (lock->trx->is_wsrep()) { - if (wsrep_debug) { + if (UNIV_UNLIKELY(wsrep_debug)) { ib::info() << "WSREP: table lock abort for table:" - << table->name.m_name; + << table->name; ib::info() << " SQL: " << wsrep_thd_query(lock->trx->mysql_thd); } diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index 67b45ab9bac..37e6e450638 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -1041,7 +1041,7 @@ static void log_write(bool rotate_key) } } - if (UNIV_UNLIKELY(srv_shutdown_state != SRV_SHUTDOWN_NONE)) { + if (UNIV_UNLIKELY(srv_shutdown_state > SRV_SHUTDOWN_INITIATED)) { service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL, "InnoDB log write: " LSN_PF, log_sys.write_lsn); @@ -1240,7 +1240,7 @@ void log_write_checkpoint_info(lsn_t end_lsn) ut_ad(end_lsn == 0 || end_lsn >= log_sys.next_checkpoint_lsn); ut_ad(end_lsn <= log_sys.get_lsn()); ut_ad(end_lsn + SIZE_OF_FILE_CHECKPOINT <= log_sys.get_lsn() - || srv_shutdown_state != SRV_SHUTDOWN_NONE); + || srv_shutdown_state > SRV_SHUTDOWN_INITIATED); DBUG_PRINT("ib_log", ("checkpoint " UINT64PF " at " LSN_PF " written", @@ -1354,7 +1354,7 @@ bool log_checkpoint() if (oldest_lsn > log_sys.last_checkpoint_lsn + SIZE_OF_FILE_CHECKPOINT) { /* Some log has been written since the previous checkpoint. */ - } else if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { + } else if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) { /* MariaDB startup expects the redo log file to be logically empty (not even containing a MLOG_CHECKPOINT record) after a clean shutdown. Perform an extra checkpoint at @@ -1379,7 +1379,7 @@ bool log_checkpoint() lsn_t flush_lsn = oldest_lsn; const lsn_t end_lsn = log_sys.get_lsn(); const bool do_write - = srv_shutdown_state == SRV_SHUTDOWN_NONE + = srv_shutdown_state <= SRV_SHUTDOWN_INITIATED || flush_lsn != end_lsn; if (fil_names_clear(flush_lsn, do_write)) { diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index 3437f3182aa..5c6b665a604 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -1204,7 +1204,7 @@ fail: } }); - if (crc != cksum) { + if (UNIV_UNLIKELY(crc != cksum)) { ib::error() << "Invalid log block checksum." << " block: " << block_number << " checkpoint no: " @@ -1482,7 +1482,7 @@ static dberr_t recv_log_recover_10_4() ulint crc = log_block_calc_checksum_crc32(buf); ulint cksum = log_block_get_checksum(buf); - if (crc != cksum) { + if (UNIV_UNLIKELY(crc != cksum)) { ib::error() << "Invalid log block checksum." << " block: " << log_block_get_hdr_no(buf) @@ -3183,7 +3183,7 @@ func_exit: entire redo log. If rescan is needed or innodb_force_recovery is set, we can ignore missing tablespaces. */ for (const recv_spaces_t::value_type& rs : recv_spaces) { - if (rs.second.status != file_name_t::MISSING) { + if (UNIV_LIKELY(rs.second.status != file_name_t::MISSING)) { continue; } diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index cfc2e1f57a8..ae51a6d1bad 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -3614,7 +3614,7 @@ fallback: ? 0 : posix_fallocate(file, current_size, size - current_size); } while (err == EINTR - && srv_shutdown_state == SRV_SHUTDOWN_NONE); + && srv_shutdown_state <= SRV_SHUTDOWN_INITIATED); switch (err) { case 0: @@ -3648,7 +3648,7 @@ fallback: os_offset_t current_size = os_file_get_size(file); while (current_size < size - && srv_shutdown_state == SRV_SHUTDOWN_NONE) { + && srv_shutdown_state <= SRV_SHUTDOWN_INITIATED) { ulint n_bytes; if (size - current_size < (os_offset_t) buf_size) { diff --git a/storage/innobase/page/page0page.cc b/storage/innobase/page/page0page.cc index 9e084e3f2a5..f40dac2c7ab 100644 --- a/storage/innobase/page/page0page.cc +++ b/storage/innobase/page/page0page.cc @@ -1994,7 +1994,7 @@ bool page_validate(const page_t* page, const dict_index_t* index) const rec_t* rec; const rec_t* old_rec = NULL; const rec_t* first_rec = NULL; - ulint offs; + ulint offs = 0; ulint n_slots; ibool ret = TRUE; ulint i; diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc index e1b71f21dc8..42188fb98b5 100644 --- a/storage/innobase/row/row0ftsort.cc +++ b/storage/innobase/row/row0ftsort.cc @@ -849,7 +849,8 @@ loop: num_doc_processed++; - if (fts_enable_diag_print && num_doc_processed % 10000 == 1) { + if (UNIV_UNLIKELY(fts_enable_diag_print) + && num_doc_processed % 10000 == 1) { ib::info() << "Number of documents processed: " << num_doc_processed; #ifdef FTS_INTERNAL_DIAG_PRINT @@ -994,7 +995,7 @@ exit: } } - if (fts_enable_diag_print) { + if (UNIV_UNLIKELY(fts_enable_diag_print)) { DEBUG_FTS_SORT_PRINT(" InnoDB_FTS: start merge sort\n"); } @@ -1025,7 +1026,7 @@ exit: } func_exit: - if (fts_enable_diag_print) { + if (UNIV_UNLIKELY(fts_enable_diag_print)) { DEBUG_FTS_SORT_PRINT(" InnoDB_FTS: complete merge sort\n"); } @@ -1185,11 +1186,9 @@ row_merge_write_fts_word( error = row_merge_write_fts_node(ins_ctx, &word->text, fts_node); - if (error != DB_SUCCESS) { - ib::error() << "Failed to write word " - << word->text.f_str << " to FTS auxiliary" - " index table, error (" << ut_strerr(error) - << ")"; + if (UNIV_UNLIKELY(error != DB_SUCCESS)) { + ib::error() << "Failed to write word to FTS auxiliary" + " index table, error " << error; ret = error; } @@ -1603,7 +1602,7 @@ row_fts_merge_insert( count_diag += psort_info[i].merge_file[id]->n_rec; } - if (fts_enable_diag_print) { + if (UNIV_UNLIKELY(fts_enable_diag_print)) { ib::info() << "InnoDB_FTS: to insert " << count_diag << " records"; } @@ -1772,7 +1771,7 @@ exit: mem_heap_free(heap); - if (fts_enable_diag_print) { + if (UNIV_UNLIKELY(fts_enable_diag_print)) { ib::info() << "InnoDB_FTS: inserted " << count << " records"; } diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index 99eddf03919..9612d95690b 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -1899,7 +1899,7 @@ PageConverter::update_index_page( row_index_t* index = find_index(id); - if (index == 0) { + if (UNIV_UNLIKELY(!index)) { ib::error() << "Page for tablespace " << m_space << " is index page with id " << id << " but that index is not found from" @@ -2188,7 +2188,7 @@ row_import_cleanup( prebuilt->trx->error_info = NULL; ib::info() << "Discarding tablespace of table " - << table->name << ": " << ut_strerr(err); + << table->name << ": " << err; if (!trx->dict_operation_lock_mode) { row_mysql_lock_data_dictionary(trx); diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 3b898c21e12..ac17f098292 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -4718,7 +4718,8 @@ row_merge_build_indexes( goto func_exit; } - if (indexes[i]->type & DICT_FTS && fts_enable_diag_print) { + if (indexes[i]->type & DICT_FTS + && UNIV_UNLIKELY(fts_enable_diag_print)) { ib::info() << "Finished building full-text index " << indexes[i]->name; } diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 640db10907a..eacb718211a 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -97,7 +97,7 @@ static UT_LIST_BASE_NODE_T(row_mysql_drop_t) row_mysql_drop_list; static ib_mutex_t row_drop_list_mutex; /** Flag: has row_mysql_drop_list been initialized? */ -static ibool row_mysql_drop_list_inited = FALSE; +static bool row_mysql_drop_list_inited; /*******************************************************************//** Determine if the given name is a name reserved for MySQL system tables. @@ -786,8 +786,7 @@ handle_new_error: " foreign constraints and try again"; goto rollback_to_savept; default: - ib::fatal() << "Unknown error code " << err << ": " - << ut_strerr(err); + ib::fatal() << "Unknown error " << err; } if (trx->error_state != DB_SUCCESS) { @@ -2661,15 +2660,33 @@ next: ut_a(!table->can_be_evicted); + bool skip = false; + if (!table->to_be_dropped) { +skip: dict_table_close(table, FALSE, FALSE); mutex_enter(&row_drop_list_mutex); UT_LIST_REMOVE(row_mysql_drop_list, drop); - UT_LIST_ADD_LAST(row_mysql_drop_list, drop); + if (!skip) { + UT_LIST_ADD_LAST(row_mysql_drop_list, drop); + } else { + ut_free(drop); + } goto next; } + if (!srv_fast_shutdown && !trx_sys.any_active_transactions()) { + lock_mutex_enter(); + skip = UT_LIST_GET_LEN(table->locks) != 0; + lock_mutex_exit(); + if (skip) { + /* We cannot drop tables that are locked by XA + PREPARE transactions. */ + goto skip; + } + } + char* name = mem_strdup(table->name.m_name); dict_table_close(table, FALSE, FALSE); @@ -3236,10 +3253,10 @@ row_drop_ancillary_fts_tables( dberr_t err = fts_drop_tables(trx, table); - if (err != DB_SUCCESS) { + if (UNIV_UNLIKELY(err != DB_SUCCESS)) { ib::error() << " Unable to remove ancillary FTS" " tables for table " - << table->name << " : " << ut_strerr(err); + << table->name << " : " << err; return(err); } @@ -3419,15 +3436,15 @@ row_drop_table_for_mysql( btr_defragment_remove_table(table); } - /* Remove stats for this table and all of its indexes from the - persistent storage if it exists and if there are stats for this - table in there. This function creates its own trx and commits - it. */ - char errstr[1024]; - err = dict_stats_drop_table(name, errstr, sizeof(errstr)); - - if (err != DB_SUCCESS) { - ib::warn() << errstr; + if (UNIV_LIKELY(!strstr(name, "/" TEMP_FILE_PREFIX_INNODB))) { + /* Remove any persistent statistics for this table, + in a separate transaction. */ + char errstr[1024]; + err = dict_stats_drop_table(name, errstr, + sizeof errstr); + if (err != DB_SUCCESS) { + ib::warn() << errstr; + } } } @@ -4025,10 +4042,10 @@ loop: table_name, trx, SQLCOM_DROP_DB); trx_commit_for_mysql(trx); - if (err != DB_SUCCESS) { + if (UNIV_UNLIKELY(err != DB_SUCCESS)) { ib::error() << "DROP DATABASE " << ut_get_name(trx, name) << " failed" - " with error (" << ut_strerr(err) << ") for" + " with error (" << err << ") for" " table " << ut_get_name(trx, table_name); ut_free(table_name); break; @@ -4823,19 +4840,22 @@ row_mysql_init(void) row_mysql_drop_list, &row_mysql_drop_t::row_mysql_drop_list); - row_mysql_drop_list_inited = TRUE; + row_mysql_drop_list_inited = true; } -/*********************************************************************//** -Close this module */ -void -row_mysql_close(void) -/*================*/ +void row_mysql_close() { - ut_a(UT_LIST_GET_LEN(row_mysql_drop_list) == 0); - - if (row_mysql_drop_list_inited) { - mutex_free(&row_drop_list_mutex); - row_mysql_drop_list_inited = FALSE; - } + ut_ad(!UT_LIST_GET_LEN(row_mysql_drop_list) || + srv_force_recovery >= SRV_FORCE_NO_BACKGROUND); + if (row_mysql_drop_list_inited) + { + row_mysql_drop_list_inited= false; + mutex_free(&row_drop_list_mutex); + + while (row_mysql_drop_t *drop= UT_LIST_GET_FIRST(row_mysql_drop_list)) + { + UT_LIST_REMOVE(row_mysql_drop_list, drop); + ut_free(drop); + } + } } diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc index e9023473fd7..aec4fa32ad7 100644 --- a/storage/innobase/row/row0purge.cc +++ b/storage/innobase/row/row0purge.cc @@ -956,7 +956,7 @@ already_locked: if (!mysqld_server_started) { node->close_table(); - if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { + if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) { return(false); } os_thread_sleep(1000000); @@ -1110,7 +1110,7 @@ row_purge( node, undo_rec, thr, updated_extern); if (purged - || srv_shutdown_state != SRV_SHUTDOWN_NONE) { + || srv_shutdown_state > SRV_SHUTDOWN_INITIATED) { return; } diff --git a/storage/innobase/row/row0undo.cc b/storage/innobase/row/row0undo.cc index 2d56ddb21b5..398e31a5ae5 100644 --- a/storage/innobase/row/row0undo.cc +++ b/storage/innobase/row/row0undo.cc @@ -499,15 +499,8 @@ row_undo_step( trx->error_state = err; - if (err != DB_SUCCESS) { - /* SQL error detected */ - - if (err == DB_OUT_OF_FILE_SPACE) { - ib::fatal() << "Out of tablespace during rollback." - " Consider increasing your tablespace."; - } - - ib::fatal() << "Error (" << ut_strerr(err) << ") in rollback."; + if (UNIV_UNLIKELY(err != DB_SUCCESS)) { + ib::fatal() << "Error (" << err << ") in rollback."; } return(thr); diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index c52e503237a..894ee3e1e0c 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -2156,7 +2156,7 @@ row_upd_sec_index_entry( err = DB_SUCCESS; break; case DB_LOCK_WAIT: - if (wsrep_debug) { + if (UNIV_UNLIKELY(wsrep_debug)) { ib::warn() << "WSREP: sec index FK lock wait" << " index " << index->name << " table " << index->table->name @@ -2164,7 +2164,7 @@ row_upd_sec_index_entry( } break; case DB_DEADLOCK: - if (wsrep_get_debug()) { + if (UNIV_UNLIKELY(wsrep_debug)) { ib::warn() << "WSREP: sec index FK check fail for deadlock" << " index " << index->name << " table " << index->table->name @@ -2172,7 +2172,7 @@ row_upd_sec_index_entry( } break; default: - ib::error() << "WSREP: referenced FK check fail: " << ut_strerr(err) + ib::error() << "WSREP: referenced FK check fail: " << err << " index " << index->name << " table " << index->table->name << " query " << wsrep_thd_query(trx->mysql_thd); @@ -2482,14 +2482,14 @@ check_fk: err = DB_SUCCESS; break; case DB_DEADLOCK: - if (wsrep_get_debug()) { + if (UNIV_UNLIKELY(wsrep_debug)) { ib::warn() << "WSREP: sec index FK check fail for deadlock" << " index " << index->name << " table " << index->table->name; } goto err_exit; default: - ib::error() << "WSREP: referenced FK check fail: " << ut_strerr(err) + ib::error() << "WSREP: referenced FK check fail: " << err << " index " << index->name << " table " << index->table->name; goto err_exit; @@ -2707,14 +2707,14 @@ row_upd_del_mark_clust_rec( err = DB_SUCCESS; break; case DB_DEADLOCK: - if (wsrep_get_debug()) { + if (UNIV_UNLIKELY(wsrep_debug)) { ib::warn() << "WSREP: sec index FK check fail for deadlock" << " index " << index->name << " table " << index->table->name; } break; default: - ib::error() << "WSREP: referenced FK check fail: " << ut_strerr(err) + ib::error() << "WSREP: referenced FK check fail: " << err << " index " << index->name << " table " << index->table->name; diff --git a/storage/innobase/srv/srv0conc.cc b/storage/innobase/srv/srv0conc.cc index 2f358901f2e..07e0299dc98 100644 --- a/storage/innobase/srv/srv0conc.cc +++ b/storage/innobase/srv/srv0conc.cc @@ -120,7 +120,7 @@ srv_conc_enter_innodb_with_atomics( ulint sleep_in_us; #ifdef WITH_WSREP if (trx->is_wsrep() && wsrep_thd_is_aborting(trx->mysql_thd)) { - if (wsrep_get_debug()) { + if (UNIV_UNLIKELY(wsrep_debug)) { ib::info() << "srv_conc_enter due to MUST_ABORT"; } @@ -308,14 +308,14 @@ wsrep_srv_conc_cancel_wait( srv_conc_enter_innodb_with_atomics(). No need to cancel here, thr will wake up after os_sleep and let to enter innodb */ - if (wsrep_get_debug()) { + if (UNIV_UNLIKELY(wsrep_debug)) { ib::info() << "WSREP: conc slot cancel, no atomics"; } #else // JAN: TODO: MySQL 5.7 //os_fast_mutex_lock(&srv_conc_mutex); if (trx->wsrep_event) { - if (wsrep_get_debug()) { + if (UNIV_UNLIKELY(wsrep_debug)) { ib::info() << "WSREP: conc slot cancel"; } os_event_set(trx->wsrep_event); diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index 2c082a49be5..cbdfec25b42 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -968,7 +968,8 @@ srv_printf_innodb_monitor( ibuf_print(file); #ifdef BTR_CUR_HASH_ADAPT - for (ulint i = 0; i < btr_ahi_parts; ++i) { + btr_search_x_lock_all(); + for (ulint i = 0; i < btr_ahi_parts && btr_search_enabled; ++i) { const hash_table_t* table = btr_search_sys->hash_tables[i]; ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); @@ -992,6 +993,7 @@ srv_printf_innodb_monitor( ", node heap has " ULINTPF " buffer(s)\n", table->n_cells, heap->base.count - !heap->free_block); } + btr_search_x_unlock_all(); fprintf(file, "%.2f hash searches/s, %.2f non-hash searches/s\n", @@ -1129,9 +1131,14 @@ srv_export_innodb_status(void) #ifdef BTR_CUR_HASH_ADAPT ulint mem_adaptive_hash = 0; - ut_ad(btr_search_sys->hash_tables); for (ulong i = 0; i < btr_ahi_parts; i++) { rw_lock_s_lock(btr_search_latches[i]); + if (!btr_search_sys->hash_tables) { +next: + rw_lock_s_unlock(btr_search_latches[i]); + continue; + } + hash_table_t* ht = btr_search_sys->hash_tables[i]; ut_ad(ht); @@ -1143,7 +1150,7 @@ srv_export_innodb_status(void) mem_adaptive_hash += mem_heap_get_size(ht->heap) + ht->n_cells * sizeof(hash_cell_t); - rw_lock_s_unlock(btr_search_latches[i]); + goto next; } export_vars.innodb_mem_adaptive_hash = mem_adaptive_hash; #endif @@ -1816,7 +1823,7 @@ srv_master_do_active_tasks(void) ut_d(srv_master_do_disabled_loop()); - if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { + if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) { return; } @@ -1834,7 +1841,7 @@ srv_master_do_active_tasks(void) /* Now see if various tasks that are performed at defined intervals need to be performed. */ - if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { + if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) { return; } @@ -1859,7 +1866,7 @@ srv_master_do_active_tasks(void) early and often to avoid those situations. */ DBUG_EXECUTE_IF("ib_log_checkpoint_avoid", return;); - if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { + if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) { return; } @@ -1902,7 +1909,7 @@ srv_master_do_idle_tasks(void) ut_d(srv_master_do_disabled_loop()); - if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { + if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) { return; } @@ -1911,7 +1918,7 @@ srv_master_do_idle_tasks(void) srv_main_thread_op_info = "checking free log space"; log_free_check(); - if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { + if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) { return; } @@ -1939,7 +1946,7 @@ srv_master_do_idle_tasks(void) early and often to avoid those situations. */ DBUG_EXECUTE_IF("ib_log_checkpoint_avoid", return;); - if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { + if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) { return; } @@ -1992,7 +1999,7 @@ void srv_master_callback(void*) { static ulint old_activity_count; - ut_a(srv_shutdown_state == SRV_SHUTDOWN_NONE); + ut_a(srv_shutdown_state <= SRV_SHUTDOWN_INITIATED); srv_main_thread_op_info = ""; MONITOR_INC(MONITOR_MASTER_THREAD_SLEEP); @@ -2008,33 +2015,33 @@ void srv_master_callback(void*) /** @return whether purge should exit due to shutdown */ static bool srv_purge_should_exit() { - ut_ad(srv_shutdown_state == SRV_SHUTDOWN_NONE - || srv_shutdown_state == SRV_SHUTDOWN_CLEANUP); + ut_ad(srv_shutdown_state <= SRV_SHUTDOWN_CLEANUP); - if (srv_undo_sources) { - return(false); - } - if (srv_fast_shutdown) { - return(true); - } - /* Slow shutdown was requested. */ - uint32_t history_size = trx_sys.rseg_history_len; - if (history_size) { + if (srv_undo_sources) + return false; + + if (srv_fast_shutdown) + return true; + + /* Slow shutdown was requested. */ + if (const uint32_t history_size= trx_sys.rseg_history_len) + { + static time_t progress_time; + time_t now= time(NULL); + if (now - progress_time >= 15) + { + progress_time= now; #if defined HAVE_SYSTEMD && !defined EMBEDDED_LIBRARY - static time_t progress_time; - time_t now = time(NULL); - if (now - progress_time >= 15) { - progress_time = now; - service_manager_extend_timeout( - INNODB_EXTEND_TIMEOUT_INTERVAL, - "InnoDB: to purge %u transactions", - history_size); - } + service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL, + "InnoDB: to purge %u transactions", + history_size); + ib::info() << "to purge " << history_size << " transactions"; #endif - return false; - } + } + return false; + } - return !trx_sys.any_active_transactions(); + return !trx_sys.any_active_transactions(); } /*********************************************************************//** diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 88e733afff6..c83b2370ef3 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -954,7 +954,7 @@ srv_init_abort_low( #ifdef UNIV_DEBUG " at " << innobase_basename(file) << "[" << line << "]" #endif /* UNIV_DEBUG */ - " with error " << ut_strerr(err) << ". You may need" + " with error " << err << ". You may need" " to delete the ibdata1 file before trying to start" " up again."; } else { @@ -962,7 +962,7 @@ srv_init_abort_low( #ifdef UNIV_DEBUG " at " << innobase_basename(file) << "[" << line << "]" #endif /* UNIV_DEBUG */ - " with error " << ut_strerr(err); + " with error " << err; } srv_shutdown_bg_undo_sources(); @@ -2042,6 +2042,7 @@ void srv_shutdown_bg_undo_sources() { if (srv_undo_sources) { ut_ad(!srv_read_only_mode); + srv_shutdown_state = SRV_SHUTDOWN_INITIATED; fts_optimize_shutdown(); dict_stats_shutdown(); while (row_get_background_drop_list_len_low()) { @@ -2147,7 +2148,7 @@ void innodb_shutdown() #ifdef BTR_CUR_HASH_ADAPT if (dict_sys.is_initialised()) { - btr_search_disable(true); + btr_search_disable(); } #endif /* BTR_CUR_HASH_ADAPT */ ibuf_close(); diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index d77de6b03e2..9c2c9a02536 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -398,9 +398,8 @@ void trx_free(trx_t*& trx) ut_ad(!trx->internal); ut_ad(!trx->mysql_log_file_name); - if (trx->declared_to_be_inside_innodb) { - - ib::error() << "Freeing a trx (" << trx << ", " + if (UNIV_UNLIKELY(trx->declared_to_be_inside_innodb)) { + ib::error() << "Freeing a trx (" << trx_get_id_for_print(trx) << ") which is declared" " to be processing inside InnoDB"; diff --git a/storage/innobase/ut/ut0ut.cc b/storage/innobase/ut/ut0ut.cc index b3b6ad6099c..dfc1d62c60c 100644 --- a/storage/innobase/ut/ut0ut.cc +++ b/storage/innobase/ut/ut0ut.cc @@ -545,6 +545,12 @@ ut_basename_noext( namespace ib { +ATTRIBUTE_COLD logger& logger::operator<<(dberr_t err) +{ + m_oss << ut_strerr(err); + return *this; +} + info::~info() { sql_print_information("InnoDB: %s", m_oss.str().c_str()); diff --git a/win/packaging/CMakeLists.txt b/win/packaging/CMakeLists.txt index 7b26289c0e7..89c6db9ab6f 100644 --- a/win/packaging/CMakeLists.txt +++ b/win/packaging/CMakeLists.txt @@ -223,10 +223,17 @@ IF(SIGNCODE) ENDIF() ADD_CUSTOM_TARGET( - win_package + win_package_zip ${SIGN_COMMAND} COMMAND ${CMAKE_CPACK_COMMAND} ${CPACK_CONFIG_PARAM} --config ${CMAKE_CURRENT_SOURCE_DIR}/CPackZipConfig.cmake + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} +) + +ADD_CUSTOM_TARGET( + win_package_debuginfo COMMAND ${CMAKE_CPACK_COMMAND} ${CPACK_CONFIG_PARAM} --config ${CMAKE_CURRENT_SOURCE_DIR}/CPackZipDebugInfoConfig.cmake WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) +ADD_CUSTOM_TARGET(win_package DEPENDS win_package_zip win_package_debuginfo) + |