mirror of
https://github.com/MariaDB/server.git
synced 2025-01-15 19:42:28 +01:00
MDEV-24564 Statistics are lost after ALTER TABLE
Ever since commit 007f68c37f
,
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.
This commit is contained in:
parent
744e9752d8
commit
6d1f1b61b5
10 changed files with 135 additions and 41 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue