mirror of
https://github.com/MariaDB/server.git
synced 2025-07-20 10:24:14 +03:00
cleanup: move checksum code to handler class
make live checksum to be returned in handler::info(), and slow table-scan checksum to be calculated in handler::checksum(). part of MDEV-16249 CHECKSUM TABLE for a spider table is not parallel and saves all data in memory in the spider head by default
This commit is contained in:
@ -8202,8 +8202,9 @@ int ha_partition::info(uint flag)
|
|||||||
stats.deleted= 0;
|
stats.deleted= 0;
|
||||||
stats.data_file_length= 0;
|
stats.data_file_length= 0;
|
||||||
stats.index_file_length= 0;
|
stats.index_file_length= 0;
|
||||||
stats.check_time= 0;
|
|
||||||
stats.delete_length= 0;
|
stats.delete_length= 0;
|
||||||
|
stats.check_time= 0;
|
||||||
|
stats.checksum= 0;
|
||||||
for (i= bitmap_get_first_set(&m_part_info->read_partitions);
|
for (i= bitmap_get_first_set(&m_part_info->read_partitions);
|
||||||
i < m_tot_parts;
|
i < m_tot_parts;
|
||||||
i= bitmap_get_next_set(&m_part_info->read_partitions, i))
|
i= bitmap_get_next_set(&m_part_info->read_partitions, i))
|
||||||
@ -8217,6 +8218,7 @@ int ha_partition::info(uint flag)
|
|||||||
stats.delete_length+= file->stats.delete_length;
|
stats.delete_length+= file->stats.delete_length;
|
||||||
if (file->stats.check_time > stats.check_time)
|
if (file->stats.check_time > stats.check_time)
|
||||||
stats.check_time= file->stats.check_time;
|
stats.check_time= file->stats.check_time;
|
||||||
|
stats.checksum+= file->stats.checksum;
|
||||||
}
|
}
|
||||||
if (stats.records && stats.records < 2 &&
|
if (stats.records && stats.records < 2 &&
|
||||||
!(m_file[0]->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT))
|
!(m_file[0]->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT))
|
||||||
@ -8372,10 +8374,7 @@ void ha_partition::get_dynamic_partition_info(PARTITION_STATS *stat_info,
|
|||||||
stat_info->create_time= file->stats.create_time;
|
stat_info->create_time= file->stats.create_time;
|
||||||
stat_info->update_time= file->stats.update_time;
|
stat_info->update_time= file->stats.update_time;
|
||||||
stat_info->check_time= file->stats.check_time;
|
stat_info->check_time= file->stats.check_time;
|
||||||
stat_info->check_sum= 0;
|
stat_info->check_sum= file->stats.checksum;
|
||||||
if (file->ha_table_flags() & (HA_HAS_OLD_CHECKSUM | HA_HAS_NEW_CHECKSUM))
|
|
||||||
stat_info->check_sum= file->checksum();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -10563,27 +10562,6 @@ void ha_partition::init_table_handle_for_HANDLER()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Return the checksum of the table (all partitions)
|
|
||||||
*/
|
|
||||||
|
|
||||||
uint ha_partition::checksum() const
|
|
||||||
{
|
|
||||||
ha_checksum sum= 0;
|
|
||||||
|
|
||||||
DBUG_ENTER("ha_partition::checksum");
|
|
||||||
if ((table_flags() & (HA_HAS_OLD_CHECKSUM | HA_HAS_NEW_CHECKSUM)))
|
|
||||||
{
|
|
||||||
handler **file= m_file;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
sum+= (*file)->checksum();
|
|
||||||
} while (*(++file));
|
|
||||||
}
|
|
||||||
DBUG_RETURN(sum);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
MODULE enable/disable indexes
|
MODULE enable/disable indexes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -1454,7 +1454,6 @@ public:
|
|||||||
virtual int dump(THD* thd, int fd = -1);
|
virtual int dump(THD* thd, int fd = -1);
|
||||||
virtual int net_read_dump(NET* net);
|
virtual int net_read_dump(NET* net);
|
||||||
*/
|
*/
|
||||||
virtual uint checksum() const;
|
|
||||||
/* Enabled keycache for performance reasons, WL#4571 */
|
/* Enabled keycache for performance reasons, WL#4571 */
|
||||||
virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt);
|
virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt);
|
||||||
virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt);
|
virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt);
|
||||||
|
@ -4876,10 +4876,7 @@ void handler::get_dynamic_partition_info(PARTITION_STATS *stat_info,
|
|||||||
stat_info->create_time= stats.create_time;
|
stat_info->create_time= stats.create_time;
|
||||||
stat_info->update_time= stats.update_time;
|
stat_info->update_time= stats.update_time;
|
||||||
stat_info->check_time= stats.check_time;
|
stat_info->check_time= stats.check_time;
|
||||||
stat_info->check_sum= 0;
|
stat_info->check_sum= stats.checksum;
|
||||||
if (table_flags() & (HA_HAS_OLD_CHECKSUM | HA_HAS_NEW_CHECKSUM))
|
|
||||||
stat_info->check_sum= checksum();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -5001,6 +4998,98 @@ end:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void flush_checksum(ha_checksum *row_crc, uchar **checksum_start,
|
||||||
|
size_t *checksum_length)
|
||||||
|
{
|
||||||
|
if (*checksum_start)
|
||||||
|
{
|
||||||
|
*row_crc= my_checksum(*row_crc, *checksum_start, *checksum_length);
|
||||||
|
*checksum_start= NULL;
|
||||||
|
*checksum_length= 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* calculating table's checksum */
|
||||||
|
int handler::calculate_checksum()
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
THD *thd=ha_thd();
|
||||||
|
DBUG_ASSERT(table->s->last_null_bit_pos < 8);
|
||||||
|
uchar null_mask= table->s->last_null_bit_pos
|
||||||
|
? 256 - (1 << table->s->last_null_bit_pos) : 0;
|
||||||
|
|
||||||
|
table->use_all_columns();
|
||||||
|
stats.checksum= 0;
|
||||||
|
|
||||||
|
if ((error= ha_rnd_init(1)))
|
||||||
|
return error;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (thd->killed)
|
||||||
|
return HA_ERR_ABORTED_BY_USER;
|
||||||
|
|
||||||
|
ha_checksum row_crc= 0;
|
||||||
|
error= table->file->ha_rnd_next(table->record[0]);
|
||||||
|
if (error)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (table->s->null_bytes)
|
||||||
|
{
|
||||||
|
/* fix undefined null bits */
|
||||||
|
table->record[0][table->s->null_bytes-1] |= null_mask;
|
||||||
|
if (!(table->s->db_create_options & HA_OPTION_PACK_RECORD))
|
||||||
|
table->record[0][0] |= 1;
|
||||||
|
|
||||||
|
row_crc= my_checksum(row_crc, table->record[0], table->s->null_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
uchar *checksum_start= NULL;
|
||||||
|
size_t checksum_length= 0;
|
||||||
|
for (uint i= 0; i < table->s->fields; i++ )
|
||||||
|
{
|
||||||
|
Field *f= table->field[i];
|
||||||
|
|
||||||
|
if (! thd->variables.old_mode && f->is_real_null(0))
|
||||||
|
{
|
||||||
|
flush_checksum(&row_crc, &checksum_start, &checksum_length);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
BLOB and VARCHAR have pointers in their field, we must convert
|
||||||
|
to string; GEOMETRY is implemented on top of BLOB.
|
||||||
|
BIT may store its data among NULL bits, convert as well.
|
||||||
|
*/
|
||||||
|
switch (f->type()) {
|
||||||
|
case MYSQL_TYPE_BLOB:
|
||||||
|
case MYSQL_TYPE_VARCHAR:
|
||||||
|
case MYSQL_TYPE_GEOMETRY:
|
||||||
|
case MYSQL_TYPE_BIT:
|
||||||
|
{
|
||||||
|
flush_checksum(&row_crc, &checksum_start, &checksum_length);
|
||||||
|
String tmp;
|
||||||
|
f->val_str(&tmp);
|
||||||
|
row_crc= my_checksum(row_crc, (uchar*) tmp.ptr(), tmp.length());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if (!checksum_start)
|
||||||
|
checksum_start= f->ptr;
|
||||||
|
DBUG_ASSERT(checksum_start + checksum_length == f->ptr);
|
||||||
|
checksum_length+= f->pack_length();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
flush_checksum(&row_crc, &checksum_start, &checksum_length);
|
||||||
|
|
||||||
|
stats.checksum+= row_crc;
|
||||||
|
}
|
||||||
|
table->file->ha_rnd_end();
|
||||||
|
return error == HA_ERR_END_OF_FILE ? 0 : error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
** Some general functions that isn't in the handler class
|
** Some general functions that isn't in the handler class
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -2780,6 +2780,7 @@ public:
|
|||||||
time_t check_time;
|
time_t check_time;
|
||||||
time_t update_time;
|
time_t update_time;
|
||||||
uint block_size; /* index block size */
|
uint block_size; /* index block size */
|
||||||
|
ha_checksum checksum;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
number of buffer bytes that native mrr implementation needs,
|
number of buffer bytes that native mrr implementation needs,
|
||||||
@ -3804,7 +3805,7 @@ public:
|
|||||||
virtual uint max_supported_key_part_length() const { return 255; }
|
virtual uint max_supported_key_part_length() const { return 255; }
|
||||||
virtual uint min_record_length(uint options) const { return 1; }
|
virtual uint min_record_length(uint options) const { return 1; }
|
||||||
|
|
||||||
virtual uint checksum() const { return 0; }
|
virtual int calculate_checksum();
|
||||||
virtual bool is_crashed() const { return 0; }
|
virtual bool is_crashed() const { return 0; }
|
||||||
virtual bool auto_repair(int error) const { return 0; }
|
virtual bool auto_repair(int error) const { return 0; }
|
||||||
|
|
||||||
|
@ -5636,7 +5636,7 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
|
|||||||
}
|
}
|
||||||
if (file->ha_table_flags() & (HA_HAS_OLD_CHECKSUM | HA_HAS_NEW_CHECKSUM))
|
if (file->ha_table_flags() & (HA_HAS_OLD_CHECKSUM | HA_HAS_NEW_CHECKSUM))
|
||||||
{
|
{
|
||||||
table->field[18]->store((longlong) file->checksum(), TRUE);
|
table->field[18]->store((longlong) file->stats.checksum, TRUE);
|
||||||
table->field[18]->set_notnull();
|
table->field[18]->set_notnull();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10630,18 +10630,6 @@ bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool table_copy)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void flush_checksum(ha_checksum *row_crc, uchar **checksum_start,
|
|
||||||
size_t *checksum_length)
|
|
||||||
{
|
|
||||||
if (*checksum_start)
|
|
||||||
{
|
|
||||||
*row_crc= my_checksum(*row_crc, *checksum_start, *checksum_length);
|
|
||||||
*checksum_start= NULL;
|
|
||||||
*checksum_length= 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
|
bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
|
||||||
HA_CHECK_OPT *check_opt)
|
HA_CHECK_OPT *check_opt)
|
||||||
{
|
{
|
||||||
@ -10718,26 +10706,17 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
|
|||||||
if (!(check_opt->flags & T_EXTEND) &&
|
if (!(check_opt->flags & T_EXTEND) &&
|
||||||
(((t->file->ha_table_flags() & HA_HAS_OLD_CHECKSUM) && thd->variables.old_mode) ||
|
(((t->file->ha_table_flags() & HA_HAS_OLD_CHECKSUM) && thd->variables.old_mode) ||
|
||||||
((t->file->ha_table_flags() & HA_HAS_NEW_CHECKSUM) && !thd->variables.old_mode)))
|
((t->file->ha_table_flags() & HA_HAS_NEW_CHECKSUM) && !thd->variables.old_mode)))
|
||||||
protocol->store((ulonglong)t->file->checksum());
|
{
|
||||||
|
if (t->file->info(HA_STATUS_VARIABLE))
|
||||||
|
protocol->store_null();
|
||||||
|
else
|
||||||
|
protocol->store((longlong)t->file->stats.checksum);
|
||||||
|
}
|
||||||
else if (check_opt->flags & T_QUICK)
|
else if (check_opt->flags & T_QUICK)
|
||||||
protocol->store_null();
|
protocol->store_null();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* calculating table's checksum */
|
int error= t->file->calculate_checksum();
|
||||||
ha_checksum crc= 0;
|
|
||||||
DBUG_ASSERT(t->s->last_null_bit_pos < 8);
|
|
||||||
uchar null_mask= (t->s->last_null_bit_pos ?
|
|
||||||
(256 - (1 << t->s->last_null_bit_pos)):
|
|
||||||
0);
|
|
||||||
|
|
||||||
t->use_all_columns();
|
|
||||||
|
|
||||||
if (t->file->ha_rnd_init(1))
|
|
||||||
protocol->store_null();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
if (thd->killed)
|
if (thd->killed)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -10748,66 +10727,10 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
|
|||||||
thd->protocol->remove_last_row();
|
thd->protocol->remove_last_row();
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
ha_checksum row_crc= 0;
|
if (error)
|
||||||
int error= t->file->ha_rnd_next(t->record[0]);
|
protocol->store_null();
|
||||||
if (unlikely(error))
|
else
|
||||||
{
|
protocol->store((longlong)t->file->stats.checksum);
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (t->s->null_bytes)
|
|
||||||
{
|
|
||||||
/* fix undefined null bits */
|
|
||||||
t->record[0][t->s->null_bytes-1] |= null_mask;
|
|
||||||
if (!(t->s->db_create_options & HA_OPTION_PACK_RECORD))
|
|
||||||
t->record[0][0] |= 1;
|
|
||||||
|
|
||||||
row_crc= my_checksum(row_crc, t->record[0], t->s->null_bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
uchar *checksum_start= NULL;
|
|
||||||
size_t checksum_length= 0;
|
|
||||||
for (uint i= 0; i < t->s->fields; i++ )
|
|
||||||
{
|
|
||||||
Field *f= t->field[i];
|
|
||||||
|
|
||||||
if (! thd->variables.old_mode && f->is_real_null(0))
|
|
||||||
{
|
|
||||||
flush_checksum(&row_crc, &checksum_start, &checksum_length);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
BLOB and VARCHAR have pointers in their field, we must convert
|
|
||||||
to string; GEOMETRY is implemented on top of BLOB.
|
|
||||||
BIT may store its data among NULL bits, convert as well.
|
|
||||||
*/
|
|
||||||
switch (f->type()) {
|
|
||||||
case MYSQL_TYPE_BLOB:
|
|
||||||
case MYSQL_TYPE_VARCHAR:
|
|
||||||
case MYSQL_TYPE_GEOMETRY:
|
|
||||||
case MYSQL_TYPE_BIT:
|
|
||||||
{
|
|
||||||
flush_checksum(&row_crc, &checksum_start, &checksum_length);
|
|
||||||
String tmp;
|
|
||||||
f->val_str(&tmp);
|
|
||||||
row_crc= my_checksum(row_crc, (uchar*) tmp.ptr(),
|
|
||||||
tmp.length());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
if (!checksum_start)
|
|
||||||
checksum_start= f->ptr;
|
|
||||||
DBUG_ASSERT(checksum_start + checksum_length == f->ptr);
|
|
||||||
checksum_length+= f->pack_length();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
flush_checksum(&row_crc, &checksum_start, &checksum_length);
|
|
||||||
|
|
||||||
crc+= row_crc;
|
|
||||||
}
|
|
||||||
protocol->store((ulonglong)crc);
|
|
||||||
t->file->ha_rnd_end();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
trans_rollback_stmt(thd);
|
trans_rollback_stmt(thd);
|
||||||
close_thread_tables(thd);
|
close_thread_tables(thd);
|
||||||
|
@ -2528,6 +2528,7 @@ int ha_maria::info(uint flag)
|
|||||||
stats.delete_length= maria_info.delete_length;
|
stats.delete_length= maria_info.delete_length;
|
||||||
stats.check_time= maria_info.check_time;
|
stats.check_time= maria_info.check_time;
|
||||||
stats.mean_rec_length= maria_info.mean_reclength;
|
stats.mean_rec_length= maria_info.mean_reclength;
|
||||||
|
stats.checksum= file->state->checksum;
|
||||||
}
|
}
|
||||||
if (flag & HA_STATUS_CONST)
|
if (flag & HA_STATUS_CONST)
|
||||||
{
|
{
|
||||||
@ -3277,12 +3278,6 @@ int ha_maria::ft_read(uchar * buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint ha_maria::checksum() const
|
|
||||||
{
|
|
||||||
return (uint) file->state->checksum;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool ha_maria::check_if_incompatible_data(HA_CREATE_INFO *create_info,
|
bool ha_maria::check_if_incompatible_data(HA_CREATE_INFO *create_info,
|
||||||
uint table_changes)
|
uint table_changes)
|
||||||
{
|
{
|
||||||
|
@ -68,7 +68,6 @@ public:
|
|||||||
uint max_supported_key_part_length() const
|
uint max_supported_key_part_length() const
|
||||||
{ return max_supported_key_length(); }
|
{ return max_supported_key_length(); }
|
||||||
enum row_type get_row_type() const;
|
enum row_type get_row_type() const;
|
||||||
uint checksum() const;
|
|
||||||
void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share);
|
void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share);
|
||||||
virtual double scan_time();
|
virtual double scan_time();
|
||||||
|
|
||||||
|
@ -2000,6 +2000,7 @@ int ha_myisam::info(uint flag)
|
|||||||
stats.delete_length= misam_info.delete_length;
|
stats.delete_length= misam_info.delete_length;
|
||||||
stats.check_time= (ulong) misam_info.check_time;
|
stats.check_time= (ulong) misam_info.check_time;
|
||||||
stats.mean_rec_length= misam_info.mean_reclength;
|
stats.mean_rec_length= misam_info.mean_reclength;
|
||||||
|
stats.checksum= file->state->checksum;
|
||||||
}
|
}
|
||||||
if (flag & HA_STATUS_CONST)
|
if (flag & HA_STATUS_CONST)
|
||||||
{
|
{
|
||||||
@ -2304,12 +2305,6 @@ int ha_myisam::ft_read(uchar *buf)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint ha_myisam::checksum() const
|
|
||||||
{
|
|
||||||
return (uint)file->state->checksum;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
enum_alter_inplace_result
|
enum_alter_inplace_result
|
||||||
ha_myisam::check_if_supported_inplace_alter(TABLE *new_table,
|
ha_myisam::check_if_supported_inplace_alter(TABLE *new_table,
|
||||||
Alter_inplace_info *alter_info)
|
Alter_inplace_info *alter_info)
|
||||||
|
@ -66,7 +66,6 @@ class ha_myisam: public handler
|
|||||||
uint max_supported_key_parts() const { return HA_MAX_KEY_SEG; }
|
uint max_supported_key_parts() const { return HA_MAX_KEY_SEG; }
|
||||||
uint max_supported_key_length() const { return HA_MAX_KEY_LENGTH; }
|
uint max_supported_key_length() const { return HA_MAX_KEY_LENGTH; }
|
||||||
uint max_supported_key_part_length() const { return HA_MAX_KEY_LENGTH; }
|
uint max_supported_key_part_length() const { return HA_MAX_KEY_LENGTH; }
|
||||||
uint checksum() const;
|
|
||||||
void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share);
|
void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share);
|
||||||
int open(const char *name, int mode, uint test_if_locked);
|
int open(const char *name, int mode, uint test_if_locked);
|
||||||
int close(void);
|
int close(void);
|
||||||
|
Reference in New Issue
Block a user