summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-01-28 14:15:01 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2021-01-28 14:15:01 +0200
commit6d1f1b61b59310027698a92ccf533a3093f1ce04 (patch)
treed2fbe999dc4df7ebbf2e4c6b20e3f902a0ddffb4
parent744e9752d887c3be20c655d882f6ec1b7e0fd727 (diff)
downloadmariadb-git-6d1f1b61b59310027698a92ccf533a3093f1ce04.tar.gz
MDEV-24564 Statistics are lost after ALTER TABLEbb-10.5-MDEV-24564
Ever since commit 007f68c37f6b77588866a04d7515aca084ab950d, ALTER TABLE no longer invokes handler::open() after handler::commit_inplace_alter_table(). ha_innobase::reload_statistics(): Reload or recompute statistics after ALTER TABLE. innodb_notify_tabledef_changed(): A new function to invoke ha_innobase::reload_statistics(). handlerton::notify_tabledef_changed(): Add the parameter handler* so that ha_innobase::reload_statistics() can be invoked. ha_partition::notify_tabledef_changed(), partition_notify_tabledef_changed(): Pass through the call to any partitions or subpartitions. This is based on code that was supplied by Monty.
-rw-r--r--mysql-test/suite/gcol/r/innodb_virtual_stats.result16
-rw-r--r--mysql-test/suite/gcol/t/innodb_virtual_stats.test1
-rw-r--r--sql/ha_partition.cc78
-rw-r--r--sql/ha_partition.h5
-rw-r--r--sql/handler.h5
-rw-r--r--sql/sql_table.cc15
-rw-r--r--storage/innobase/handler/ha_innodb.cc26
-rw-r--r--storage/innobase/handler/ha_innodb.h4
-rw-r--r--storage/innobase/handler/handler0alter.cc14
-rw-r--r--storage/maria/ha_s3.cc12
10 files changed, 135 insertions, 41 deletions
diff --git a/mysql-test/suite/gcol/r/innodb_virtual_stats.result b/mysql-test/suite/gcol/r/innodb_virtual_stats.result
index c11b02ff8cb..c0f595263df 100644
--- a/mysql-test/suite/gcol/r/innodb_virtual_stats.result
+++ b/mysql-test/suite/gcol/r/innodb_virtual_stats.result
@@ -121,5 +121,19 @@ SELECT index_name, stat_name, stat_description
FROM mysql.innodb_index_stats
WHERE database_name = 'test' AND table_name = 't';
index_name stat_name stat_description
-# MDEV-24564 FIXME: Do reload statistics after the above ALTER TABLE!
+GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID
+GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index
+GEN_CLUST_INDEX size Number of pages in the index
+idxb n_diff_pfx01 b
+idxb n_diff_pfx02 b,DB_ROW_ID
+idxb n_leaf_pages Number of leaf pages in the index
+idxb size Number of pages in the index
+vidxe n_diff_pfx01 e
+vidxe n_diff_pfx02 e,DB_ROW_ID
+vidxe n_leaf_pages Number of leaf pages in the index
+vidxe size Number of pages in the index
+vidxf n_diff_pfx01 f
+vidxf n_diff_pfx02 f,DB_ROW_ID
+vidxf n_leaf_pages Number of leaf pages in the index
+vidxf size Number of pages in the index
DROP TABLE t;
diff --git a/mysql-test/suite/gcol/t/innodb_virtual_stats.test b/mysql-test/suite/gcol/t/innodb_virtual_stats.test
index 728f84de72c..69c67af8ed1 100644
--- a/mysql-test/suite/gcol/t/innodb_virtual_stats.test
+++ b/mysql-test/suite/gcol/t/innodb_virtual_stats.test
@@ -52,6 +52,5 @@ ALTER TABLE t DROP INDEX vidxcd;
SELECT index_name, stat_name, stat_description
FROM mysql.innodb_index_stats
WHERE database_name = 'test' AND table_name = 't';
--- echo # MDEV-24564 FIXME: Do reload statistics after the above ALTER TABLE!
DROP TABLE t;
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 470f59fe15f..0140a825ef5 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2005, 2019, Oracle and/or its affiliates.
- Copyright (c) 2009, 2020, MariaDB
+ Copyright (c) 2009, 2021, MariaDB
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
@@ -92,6 +92,61 @@ static handler *partition_create_handler(handlerton *hton,
static uint partition_flags();
static alter_table_operations alter_table_flags(alter_table_operations flags);
+
+int ha_partition::notify_tabledef_changed(LEX_CSTRING *db,
+ LEX_CSTRING *org_table_name,
+ LEX_CUSTRING *frm,
+ LEX_CUSTRING *version)
+{
+ char from_buff[FN_REFLEN + 1], from_lc_buff[FN_REFLEN + 1];
+ const char *from_path, *name_buffer_ptr, *from;
+ int res= 0;
+ handler **file= m_file;
+ DBUG_ENTER("ha_partition::notify_tabledef_changed");
+
+ from= table->s->normalized_path.str;
+
+ /* setup m_name_buffer_ptr */
+ if (read_par_file(table->s->normalized_path.str))
+ DBUG_RETURN(1);
+
+ from_path= get_canonical_filename(*file, from, from_lc_buff);
+ name_buffer_ptr= m_name_buffer_ptr;
+ do
+ {
+ LEX_CSTRING table_name;
+ const char *table_name_ptr;
+ if (create_partition_name(from_buff, sizeof(from_buff),
+ from_path, name_buffer_ptr,
+ NORMAL_PART_NAME, FALSE))
+ res=1;
+ table_name_ptr= from_buff + dirname_length(from_buff);
+
+ lex_string_set3(&table_name, table_name_ptr, strlen(table_name_ptr));
+
+ if (((*file)->ht)->notify_tabledef_changed((*file)->ht, db, &table_name,
+ frm, version, *file))
+ res=1;
+ name_buffer_ptr= strend(name_buffer_ptr) + 1;
+ } while (*(++file));
+ DBUG_RETURN(res);
+}
+
+
+static int
+partition_notify_tabledef_changed(handlerton *,
+ LEX_CSTRING *db,
+ LEX_CSTRING *table,
+ LEX_CUSTRING *frm,
+ LEX_CUSTRING *version,
+ handler *file)
+{
+ DBUG_ENTER("partition_notify_tabledef_changed");
+ DBUG_RETURN(static_cast<ha_partition*>
+ (file)->notify_tabledef_changed(db, table, frm, version));
+}
+
+
/*
If frm_error() is called then we will use this to to find out what file
extensions exist for the storage engine. This is also used by the default
@@ -149,7 +204,9 @@ static int partition_initialize(void *p)
partition_hton->db_type= DB_TYPE_PARTITION_DB;
partition_hton->create= partition_create_handler;
+
partition_hton->partition_flags= partition_flags;
+ partition_hton->notify_tabledef_changed= partition_notify_tabledef_changed;
partition_hton->alter_table_flags= alter_table_flags;
partition_hton->flags= HTON_NOT_USER_SELECTABLE |
HTON_HIDDEN |
@@ -211,25 +268,6 @@ static handler *partition_create_handler(handlerton *hton,
return file;
}
-/*
- HA_CAN_PARTITION:
- Used by storage engines that can handle partitioning without this
- partition handler
- (Partition, NDB)
-
- HA_CAN_UPDATE_PARTITION_KEY:
- Set if the handler can update fields that are part of the partition
- function.
-
- HA_CAN_PARTITION_UNIQUE:
- Set if the handler can handle unique indexes where the fields of the
- unique key are not part of the fields of the partition function. Thus
- a unique key can be set on all fields.
-
- HA_USE_AUTO_PARTITION
- Set if the handler sets all tables to be partitioned by default.
-*/
-
static uint partition_flags()
{
return HA_CAN_PARTITION;
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index 3c3e394d59f..60a2d7f6762 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -3,7 +3,7 @@
/*
Copyright (c) 2005, 2012, Oracle and/or its affiliates.
- Copyright (c) 2009, 2020, MariaDB Corporation.
+ Copyright (c) 2009, 2021, 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
@@ -1617,6 +1617,9 @@ public:
return part_recs;
}
+ int notify_tabledef_changed(LEX_CSTRING *db, LEX_CSTRING *table,
+ LEX_CUSTRING *frm, LEX_CUSTRING *version);
+
friend int cmp_key_rowid_part_id(void *ptr, uchar *ref1, uchar *ref2);
friend int cmp_key_part_id(void *key_p, uchar *ref1, uchar *ref2);
bool can_convert_string(
diff --git a/sql/handler.h b/sql/handler.h
index 4e1e3f0413f..d115fdddddc 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -2,7 +2,7 @@
#define HANDLER_INCLUDED
/*
Copyright (c) 2000, 2019, Oracle and/or its affiliates.
- Copyright (c) 2009, 2020, MariaDB
+ Copyright (c) 2009, 2021, MariaDB
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -1681,7 +1681,8 @@ struct handlerton
*/
int (*notify_tabledef_changed)(handlerton *hton, LEX_CSTRING *db,
LEX_CSTRING *table_name, LEX_CUSTRING *frm,
- LEX_CUSTRING *org_tabledef_version);
+ LEX_CUSTRING *org_tabledef_version,
+ handler *file);
/*
System Versioning
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 6825fbc8e24..116bfa7fd1c 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2019, Oracle and/or its affiliates.
- Copyright (c) 2010, 2020, MariaDB
+ Copyright (c) 2010, 2021, MariaDB
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
@@ -7934,7 +7934,6 @@ static bool mysql_inplace_alter_table(THD *thd,
Alter_info *alter_info= ha_alter_info->alter_info;
bool reopen_tables= false;
bool res;
- handlerton *hton;
const enum_alter_inplace_result inplace_supported=
ha_alter_info->inplace_supported;
@@ -8145,20 +8144,22 @@ static bool mysql_inplace_alter_table(THD *thd,
/* Notify the engine that the table definition has changed */
- hton= table->file->partition_ht();
- if (hton->notify_tabledef_changed)
+ if (table->file->partition_ht()->notify_tabledef_changed)
{
char db_buff[FN_REFLEN], table_buff[FN_REFLEN];
+ handlerton *hton= table->file->ht;
LEX_CSTRING tmp_db, tmp_table;
- tmp_db.str= db_buff;
- tmp_table.str= table_buff;
+
+ tmp_db.str= db_buff;
+ tmp_table.str= table_buff;
tmp_db.length= tablename_to_filename(table_list->db.str,
db_buff, sizeof(db_buff));
tmp_table.length= tablename_to_filename(table_list->table_name.str,
table_buff, sizeof(table_buff));
if ((hton->notify_tabledef_changed)(hton, &tmp_db, &tmp_table,
table->s->frm_image,
- &table->s->tabledef_version))
+ &table->s->tabledef_version,
+ table->file))
{
my_error(HA_ERR_INCOMPATIBLE_DEFINITION, MYF(0));
DBUG_RETURN(true);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index dd52fee3f9b..5e9a7d951e3 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -1330,6 +1330,30 @@ innobase_show_status(
stat_print_fn* stat_print,
enum ha_stat_type stat_type);
+/** After ALTER TABLE, recompute statistics. */
+inline void ha_innobase::reload_statistics()
+{
+ if (dict_table_t *table= m_prebuilt ? m_prebuilt->table : nullptr)
+ {
+ if (table->is_readable())
+ dict_stats_init(table);
+ else
+ table->stat_initialized= 1;
+ }
+}
+
+/** After ALTER TABLE, recompute statistics. */
+static int innodb_notify_tabledef_changed(handlerton *,
+ LEX_CSTRING *, LEX_CSTRING *,
+ LEX_CUSTRING *, LEX_CUSTRING *,
+ handler *handler)
+{
+ DBUG_ENTER("innodb_notify_tabledef_changed");
+ if (handler)
+ static_cast<ha_innobase*>(handler)->reload_statistics();
+ DBUG_RETURN(0);
+}
+
/****************************************************************//**
Parse and enable InnoDB monitor counters during server startup.
User can enable monitor counters/groups by specifying
@@ -3816,6 +3840,7 @@ static int innodb_init(void* p)
innobase_hton->flush_logs = innobase_flush_logs;
innobase_hton->show_status = innobase_show_status;
+ innobase_hton->notify_tabledef_changed= innodb_notify_tabledef_changed;
innobase_hton->flags =
HTON_SUPPORTS_EXTENDED_KEYS | HTON_SUPPORTS_FOREIGN_KEYS
| HTON_NATIVE_SYS_VERSIONING | HTON_WSREP_REPLICATION;
@@ -16233,6 +16258,7 @@ innobase_show_status(
/* Success */
return(false);
}
+
/*********************************************************************//**
Returns number of THR_LOCK locks used for one instance of InnoDB table.
InnoDB no longer relies on THR_LOCK locks so 0 value is returned.
diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
index b47acae01f2..d8277a7a5a8 100644
--- a/storage/innobase/handler/ha_innodb.h
+++ b/storage/innobase/handler/ha_innodb.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2020, MariaDB Corporation.
+Copyright (c) 2013, 2021, 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
@@ -211,6 +211,8 @@ public:
int check(THD* thd, HA_CHECK_OPT* check_opt) override;
char* update_table_comment(const char* comment) override;
+ inline void reload_statistics();
+
char* get_foreign_key_create_info() override;
int get_foreign_key_list(THD *thd,
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 06fa442ed0e..4248442f3da 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -11263,12 +11263,18 @@ foreign_fail:
&& m_prebuilt->table->n_v_cols
&& ha_alter_info->handler_flags & ALTER_STORED_COLUMN_ORDER)) {
DBUG_ASSERT(ctx0->old_table->get_ref_count() == 1);
+ ut_ad(ctx0->prebuilt == m_prebuilt);
trx_commit_for_mysql(m_prebuilt->trx);
- m_prebuilt->table = innobase_reload_table(m_user_thd,
- m_prebuilt->table,
- table->s->table_name,
- *ctx0);
+ for (inplace_alter_handler_ctx** pctx = ctx_array; *pctx;
+ pctx++) {
+ auto ctx= static_cast<ha_innobase_inplace_ctx*>(*pctx);
+ ctx->prebuilt->table = innobase_reload_table(
+ m_user_thd, ctx->prebuilt->table,
+ table->s->table_name, *ctx0);
+ innobase_copy_frm_flags_from_table_share(
+ ctx->prebuilt->table, altered_table->s);
+ }
row_mysql_unlock_data_dictionary(trx);
trx->free();
diff --git a/storage/maria/ha_s3.cc b/storage/maria/ha_s3.cc
index cf2b9098142..b27afc2fcf7 100644
--- a/storage/maria/ha_s3.cc
+++ b/storage/maria/ha_s3.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2019, 2020 MariaDB Corporation Ab
+/* Copyright (C) 2019, 2021 MariaDB Corporation Ab
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
@@ -887,10 +887,11 @@ int ha_s3::discover_check_version()
Update the .frm file in S3
*/
-static int s3_notify_tabledef_changed(handlerton *hton __attribute__((unused)),
+static int s3_notify_tabledef_changed(handlerton *,
LEX_CSTRING *db, LEX_CSTRING *table,
LEX_CUSTRING *frm,
- LEX_CUSTRING *org_tabledef_version)
+ LEX_CUSTRING *org_tabledef_version,
+ handler *)
{
char aws_path[AWS_PATH_LENGTH];
S3_INFO s3_info;
@@ -898,6 +899,9 @@ static int s3_notify_tabledef_changed(handlerton *hton __attribute__((unused)),
int error= 0;
DBUG_ENTER("s3_notify_tabledef_changed");
+ if (strstr(table->str, "#P#"))
+ DBUG_RETURN(0); // Ignore partitions
+
if (s3_info_init(&s3_info))
DBUG_RETURN(0);
if (!(s3_client= s3_open_connection(&s3_info)))
@@ -916,7 +920,7 @@ static int s3_notify_tabledef_changed(handlerton *hton __attribute__((unused)),
NullS);
if (s3_put_object(s3_client, s3_info.bucket.str, aws_path, (uchar*) frm->str,
- frm->length, 0))
+ frm->length, 0))
error= 2;
err: