1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +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:
Sergei Golubchik
2019-05-02 13:09:27 +02:00
parent 651a43e0a0
commit ffb83ba650
10 changed files with 121 additions and 143 deletions

View File

@ -4876,10 +4876,7 @@ void handler::get_dynamic_partition_info(PARTITION_STATS *stat_info,
stat_info->create_time= stats.create_time;
stat_info->update_time= stats.update_time;
stat_info->check_time= stats.check_time;
stat_info->check_sum= 0;
if (table_flags() & (HA_HAS_OLD_CHECKSUM | HA_HAS_NEW_CHECKSUM))
stat_info->check_sum= checksum();
return;
stat_info->check_sum= stats.checksum;
}
@ -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
****************************************************************************/