Merge 10.2 into 10.3
This commit is contained in:
commit
892378fb9d
@ -338,11 +338,9 @@ static bool page_is_corrupted(const byte *page, ulint page_no,
|
|||||||
|
|
||||||
memcpy(tmp_page, page, page_size);
|
memcpy(tmp_page, page, page_size);
|
||||||
|
|
||||||
bool decrypted = false;
|
|
||||||
if (!space->crypt_data
|
if (!space->crypt_data
|
||||||
|| space->crypt_data->type == CRYPT_SCHEME_UNENCRYPTED
|
|| space->crypt_data->type == CRYPT_SCHEME_UNENCRYPTED
|
||||||
|| !fil_space_decrypt(space, tmp_frame, tmp_page,
|
|| !fil_space_decrypt(space, tmp_frame, tmp_page)) {
|
||||||
&decrypted)) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1528,7 +1528,8 @@ static int prepare_export()
|
|||||||
" --defaults-extra-file=./backup-my.cnf --defaults-group-suffix=%s --datadir=."
|
" --defaults-extra-file=./backup-my.cnf --defaults-group-suffix=%s --datadir=."
|
||||||
" --innodb --innodb-fast-shutdown=0 --loose-partition"
|
" --innodb --innodb-fast-shutdown=0 --loose-partition"
|
||||||
" --innodb_purge_rseg_truncate_frequency=1 --innodb-buffer-pool-size=%llu"
|
" --innodb_purge_rseg_truncate_frequency=1 --innodb-buffer-pool-size=%llu"
|
||||||
" --console --skip-log-error --bootstrap < " BOOTSTRAP_FILENAME IF_WIN("\"",""),
|
" --console --skip-log-error --skip-log-bin --bootstrap < "
|
||||||
|
BOOTSTRAP_FILENAME IF_WIN("\"",""),
|
||||||
mariabackup_exe,
|
mariabackup_exe,
|
||||||
orig_argv1, (my_defaults_group_suffix?my_defaults_group_suffix:""),
|
orig_argv1, (my_defaults_group_suffix?my_defaults_group_suffix:""),
|
||||||
xtrabackup_use_memory);
|
xtrabackup_use_memory);
|
||||||
@ -1540,7 +1541,8 @@ static int prepare_export()
|
|||||||
" --defaults-file=./backup-my.cnf --defaults-group-suffix=%s --datadir=."
|
" --defaults-file=./backup-my.cnf --defaults-group-suffix=%s --datadir=."
|
||||||
" --innodb --innodb-fast-shutdown=0 --loose-partition"
|
" --innodb --innodb-fast-shutdown=0 --loose-partition"
|
||||||
" --innodb_purge_rseg_truncate_frequency=1 --innodb-buffer-pool-size=%llu"
|
" --innodb_purge_rseg_truncate_frequency=1 --innodb-buffer-pool-size=%llu"
|
||||||
" --console --log-error= --bootstrap < " BOOTSTRAP_FILENAME IF_WIN("\"",""),
|
" --console --log-error= --skip-log-bin --bootstrap < "
|
||||||
|
BOOTSTRAP_FILENAME IF_WIN("\"",""),
|
||||||
mariabackup_exe,
|
mariabackup_exe,
|
||||||
(my_defaults_group_suffix?my_defaults_group_suffix:""),
|
(my_defaults_group_suffix?my_defaults_group_suffix:""),
|
||||||
xtrabackup_use_memory);
|
xtrabackup_use_memory);
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 544b6f1d12f0e5b2a141129075ff2d64feb0e4c9
|
Subproject commit c6403c4c847d94ed6b40d3fd128e729271867e75
|
BIN
mysql-test/std_data/binlog_before_20574.bin
Normal file
BIN
mysql-test/std_data/binlog_before_20574.bin
Normal file
Binary file not shown.
@ -0,0 +1,27 @@
|
|||||||
|
include/master-slave.inc
|
||||||
|
[connection master]
|
||||||
|
connection slave;
|
||||||
|
include/stop_slave.inc
|
||||||
|
connection master;
|
||||||
|
include/rpl_stop_server.inc [server_number=1]
|
||||||
|
# Data in binlog
|
||||||
|
# CREATE TABLE t1 (a INT);
|
||||||
|
# INSERT INTO t1 VALUES (1),(2),(3);
|
||||||
|
# REPLACE INTO t1 VALUES (4);
|
||||||
|
include/rpl_start_server.inc [server_number=1]
|
||||||
|
connection slave;
|
||||||
|
RESET SLAVE;
|
||||||
|
RESET MASTER;
|
||||||
|
CHANGE MASTER TO master_host='127.0.0.1', master_port=SERVER_MYPORT_1, master_user='root', master_log_file='master-bin.000001', master_log_pos=4;
|
||||||
|
include/start_slave.inc
|
||||||
|
DESC t1;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
a int(11) YES NULL
|
||||||
|
SELECT * FROM t1 ORDER BY a;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
||||||
|
DROP TABLE t1;
|
||||||
|
include/rpl_end.inc
|
@ -0,0 +1,46 @@
|
|||||||
|
# MDEV-20574 Position of events reported by mysqlbinlog is wrong with encrypted binlogs, SHOW BINLOG EVENTS reports the correct one.
|
||||||
|
# Test replicating off old master.
|
||||||
|
# Test case Desc:- When new server reads the data from old server binlog which
|
||||||
|
# does not send START_ENCRYPTION_EVENT to slave.
|
||||||
|
# We simulate old master by copying in pre-generated binlog files from earlier
|
||||||
|
# server versions with encrypted binlog.
|
||||||
|
--source include/have_binlog_format_row.inc
|
||||||
|
--source include/master-slave.inc
|
||||||
|
--source include/have_innodb.inc
|
||||||
|
|
||||||
|
--connection slave
|
||||||
|
--source include/stop_slave.inc
|
||||||
|
|
||||||
|
--connection master
|
||||||
|
--let $datadir= `SELECT @@datadir`
|
||||||
|
|
||||||
|
--let $rpl_server_number= 1
|
||||||
|
--source include/rpl_stop_server.inc
|
||||||
|
|
||||||
|
--remove_file $datadir/master-bin.000001
|
||||||
|
--remove_file $datadir/master-bin.state
|
||||||
|
--echo # Data in binlog
|
||||||
|
--echo # CREATE TABLE t1 (a INT);
|
||||||
|
--echo # INSERT INTO t1 VALUES (1),(2),(3);
|
||||||
|
--echo # REPLACE INTO t1 VALUES (4);
|
||||||
|
|
||||||
|
--copy_file $MYSQL_TEST_DIR/std_data/binlog_before_20574.bin $datadir/master-bin.000001
|
||||||
|
|
||||||
|
--let $rpl_server_number= 1
|
||||||
|
--source include/rpl_start_server.inc
|
||||||
|
|
||||||
|
--source include/wait_until_connected_again.inc
|
||||||
|
--save_master_pos
|
||||||
|
|
||||||
|
--connection slave
|
||||||
|
RESET SLAVE;
|
||||||
|
RESET MASTER;
|
||||||
|
--replace_result $SERVER_MYPORT_1 SERVER_MYPORT_1
|
||||||
|
eval CHANGE MASTER TO master_host='127.0.0.1', master_port=$SERVER_MYPORT_1, master_user='root', master_log_file='master-bin.000001', master_log_pos=4;
|
||||||
|
--source include/start_slave.inc
|
||||||
|
--sync_with_master
|
||||||
|
DESC t1;
|
||||||
|
SELECT * FROM t1 ORDER BY a;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
--source include/rpl_end.inc
|
@ -104,6 +104,9 @@ DELIMITER /*!*/;
|
|||||||
#010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup
|
#010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup
|
||||||
ROLLBACK/*!*/;
|
ROLLBACK/*!*/;
|
||||||
# at #
|
# at #
|
||||||
|
#010909 4:46:40 server id # end_log_pos # Ignorable
|
||||||
|
# Ignorable event type 164 (Start_encryption)
|
||||||
|
# at #
|
||||||
#010909 4:46:40 server id # end_log_pos # Gtid list []
|
#010909 4:46:40 server id # end_log_pos # Gtid list []
|
||||||
# at #
|
# at #
|
||||||
#010909 4:46:40 server id # end_log_pos # Binlog checkpoint master-bin.000001
|
#010909 4:46:40 server id # end_log_pos # Binlog checkpoint master-bin.000001
|
||||||
@ -342,6 +345,9 @@ DELIMITER /*!*/;
|
|||||||
#010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup
|
#010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup
|
||||||
ROLLBACK/*!*/;
|
ROLLBACK/*!*/;
|
||||||
# at #
|
# at #
|
||||||
|
#010909 4:46:40 server id # end_log_pos # Ignorable
|
||||||
|
# Ignorable event type 164 (Start_encryption)
|
||||||
|
# at #
|
||||||
#010909 4:46:40 server id # end_log_pos # Gtid list []
|
#010909 4:46:40 server id # end_log_pos # Gtid list []
|
||||||
# at #
|
# at #
|
||||||
#010909 4:46:40 server id # end_log_pos # Binlog checkpoint master-bin.000001
|
#010909 4:46:40 server id # end_log_pos # Binlog checkpoint master-bin.000001
|
||||||
@ -502,6 +508,9 @@ DELIMITER /*!*/;
|
|||||||
#010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup
|
#010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup
|
||||||
ROLLBACK/*!*/;
|
ROLLBACK/*!*/;
|
||||||
# at #
|
# at #
|
||||||
|
#010909 4:46:40 server id # end_log_pos # Ignorable
|
||||||
|
# Ignorable event type 164 (Start_encryption)
|
||||||
|
# at #
|
||||||
#010909 4:46:40 server id # end_log_pos # Gtid list []
|
#010909 4:46:40 server id # end_log_pos # Gtid list []
|
||||||
# at #
|
# at #
|
||||||
#010909 4:46:40 server id # end_log_pos # Binlog checkpoint master-bin.000001
|
#010909 4:46:40 server id # end_log_pos # Binlog checkpoint master-bin.000001
|
||||||
|
@ -4,3 +4,4 @@ INSERT INTO t1 VALUES (1),(2),(3);
|
|||||||
REPLACE INTO t1 VALUES (4);
|
REPLACE INTO t1 VALUES (4);
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
FLUSH LOGS;
|
FLUSH LOGS;
|
||||||
|
FOUND 1 /Ignorable event type 164.*/ in binlog_enc.sql
|
||||||
|
@ -17,5 +17,8 @@ let outfile=$MYSQLTEST_VARDIR/tmp/binlog_enc.sql;
|
|||||||
exec $MYSQL_BINLOG $local > $outfile;
|
exec $MYSQL_BINLOG $local > $outfile;
|
||||||
exec $MYSQL_BINLOG $local --force-read >> $outfile;
|
exec $MYSQL_BINLOG $local --force-read >> $outfile;
|
||||||
exec $MYSQL_BINLOG $remote >> $outfile;
|
exec $MYSQL_BINLOG $remote >> $outfile;
|
||||||
|
--let SEARCH_FILE= $outfile
|
||||||
|
--let SEARCH_PATTERN= Ignorable event type 164.*
|
||||||
|
--source include/search_pattern_in_file.inc
|
||||||
remove_file $outfile;
|
remove_file $outfile;
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ CREATE TABLE t2(i int) ENGINE INNODB;
|
|||||||
|
|
||||||
echo # xtrabackup backup;
|
echo # xtrabackup backup;
|
||||||
|
|
||||||
let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
|
let targetdir=$MYSQLTEST_VARDIR/tmp/backup;
|
||||||
--disable_result_log
|
--disable_result_log
|
||||||
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup "--tables=test.*1" --target-dir=$targetdir;
|
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup "--tables=test.*1" --target-dir=$targetdir;
|
||||||
--enable_result_log
|
--enable_result_log
|
||||||
@ -25,13 +25,27 @@ EOF
|
|||||||
write_file $targetdir/test/junk.frm;
|
write_file $targetdir/test/junk.frm;
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
let server_cnf=$targetdir/server.cnf;
|
||||||
|
copy_file $MYSQLTEST_VARDIR/my.cnf $server_cnf;
|
||||||
|
|
||||||
|
# Emulate server config file turnes on binary logs
|
||||||
|
perl;
|
||||||
|
my $binlog_path="$ENV{'targetdir'}/mysqld-bin";
|
||||||
|
my $config_path=$ENV{'server_cnf'};
|
||||||
|
open(my $fd, '>>', "$config_path");
|
||||||
|
print $fd "\n[mysqld]\n";
|
||||||
|
print $fd "log-bin=$binlog_path\n";
|
||||||
|
close $fd;
|
||||||
|
EOF
|
||||||
|
|
||||||
echo # xtrabackup prepare;
|
echo # xtrabackup prepare;
|
||||||
--disable_result_log
|
--disable_result_log
|
||||||
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --defaults-group-suffix=.1 --prepare --export --target-dir=$targetdir;
|
exec $XTRABACKUP --defaults-file=$server_cnf --defaults-group-suffix=.1 --prepare --export --target-dir=$targetdir;
|
||||||
--enable_result_log
|
--enable_result_log
|
||||||
|
|
||||||
list_files $targetdir/test *.cfg;
|
list_files $targetdir/test *.cfg;
|
||||||
|
# There must not be binary logs created on --prepare step
|
||||||
|
list_files $targetdir/ mysqld-bin.*;
|
||||||
|
|
||||||
let $MYSQLD_DATADIR= `select @@datadir`;
|
let $MYSQLD_DATADIR= `select @@datadir`;
|
||||||
ALTER TABLE t1 DISCARD TABLESPACE;
|
ALTER TABLE t1 DISCARD TABLESPACE;
|
||||||
|
@ -28,11 +28,6 @@
|
|||||||
There is no reference counting and no unloading either.
|
There is no reference counting and no unloading either.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
/* Silence warnings about variable 'unused' being used. */
|
|
||||||
#define FORCE_INIT_OF_VARS 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <my_global.h>
|
#include <my_global.h>
|
||||||
#include "mysql.h"
|
#include "mysql.h"
|
||||||
#include <my_sys.h>
|
#include <my_sys.h>
|
||||||
@ -243,12 +238,12 @@ int mysql_client_plugin_init()
|
|||||||
struct st_mysql_client_plugin **builtin;
|
struct st_mysql_client_plugin **builtin;
|
||||||
va_list unused;
|
va_list unused;
|
||||||
DBUG_ENTER("mysql_client_plugin_init");
|
DBUG_ENTER("mysql_client_plugin_init");
|
||||||
LINT_INIT_STRUCT(unused);
|
|
||||||
|
|
||||||
if (initialized)
|
if (initialized)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
bzero(&mysql, sizeof(mysql)); /* dummy mysql for set_mysql_extended_error */
|
bzero(&mysql, sizeof(mysql)); /* dummy mysql for set_mysql_extended_error */
|
||||||
|
bzero(&unused, sizeof unused);
|
||||||
|
|
||||||
mysql_mutex_init(0, &LOCK_load_client_plugin, MY_MUTEX_INIT_SLOW);
|
mysql_mutex_init(0, &LOCK_load_client_plugin, MY_MUTEX_INIT_SLOW);
|
||||||
init_alloc_root(&mem_root, "client_plugin", 128, 128, MYF(0));
|
init_alloc_root(&mem_root, "client_plugin", 128, 128, MYF(0));
|
||||||
@ -306,9 +301,7 @@ struct st_mysql_client_plugin *
|
|||||||
mysql_client_register_plugin(MYSQL *mysql,
|
mysql_client_register_plugin(MYSQL *mysql,
|
||||||
struct st_mysql_client_plugin *plugin)
|
struct st_mysql_client_plugin *plugin)
|
||||||
{
|
{
|
||||||
va_list unused;
|
|
||||||
DBUG_ENTER("mysql_client_register_plugin");
|
DBUG_ENTER("mysql_client_register_plugin");
|
||||||
LINT_INIT_STRUCT(unused);
|
|
||||||
|
|
||||||
if (is_not_initialized(mysql, plugin->name))
|
if (is_not_initialized(mysql, plugin->name))
|
||||||
DBUG_RETURN(NULL);
|
DBUG_RETURN(NULL);
|
||||||
@ -324,7 +317,11 @@ mysql_client_register_plugin(MYSQL *mysql,
|
|||||||
plugin= NULL;
|
plugin= NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
va_list unused;
|
||||||
|
bzero(&unused, sizeof unused);
|
||||||
plugin= add_plugin(mysql, plugin, 0, 0, unused);
|
plugin= add_plugin(mysql, plugin, 0, 0, unused);
|
||||||
|
}
|
||||||
|
|
||||||
mysql_mutex_unlock(&LOCK_load_client_plugin);
|
mysql_mutex_unlock(&LOCK_load_client_plugin);
|
||||||
DBUG_RETURN(plugin);
|
DBUG_RETURN(plugin);
|
||||||
|
@ -2096,6 +2096,19 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
|
|||||||
alg != BINLOG_CHECKSUM_ALG_OFF))
|
alg != BINLOG_CHECKSUM_ALG_OFF))
|
||||||
event_len= event_len - BINLOG_CHECKSUM_LEN;
|
event_len= event_len - BINLOG_CHECKSUM_LEN;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Create an object of Ignorable_log_event for unrecognized sub-class.
|
||||||
|
So that SLAVE SQL THREAD will only update the position and continue.
|
||||||
|
We should look for this flag first instead of judging by event_type
|
||||||
|
Any event can be Ignorable_log_event if it has this flag on.
|
||||||
|
look into @note of Ignorable_log_event
|
||||||
|
*/
|
||||||
|
if (uint2korr(buf + FLAGS_OFFSET) & LOG_EVENT_IGNORABLE_F)
|
||||||
|
{
|
||||||
|
ev= new Ignorable_log_event(buf, fdle,
|
||||||
|
get_type_str((Log_event_type) event_type));
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
switch(event_type) {
|
switch(event_type) {
|
||||||
case QUERY_EVENT:
|
case QUERY_EVENT:
|
||||||
ev = new Query_log_event(buf, event_len, fdle, QUERY_EVENT);
|
ev = new Query_log_event(buf, event_len, fdle, QUERY_EVENT);
|
||||||
@ -2222,24 +2235,13 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
|
|||||||
ev = new Start_encryption_log_event(buf, event_len, fdle);
|
ev = new Start_encryption_log_event(buf, event_len, fdle);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/*
|
DBUG_PRINT("error",("Unknown event code: %d",
|
||||||
Create an object of Ignorable_log_event for unrecognized sub-class.
|
(uchar) buf[EVENT_TYPE_OFFSET]));
|
||||||
So that SLAVE SQL THREAD will only update the position and continue.
|
ev= NULL;
|
||||||
*/
|
break;
|
||||||
if (uint2korr(buf + FLAGS_OFFSET) & LOG_EVENT_IGNORABLE_F)
|
|
||||||
{
|
|
||||||
ev= new Ignorable_log_event(buf, fdle,
|
|
||||||
get_type_str((Log_event_type) event_type));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DBUG_PRINT("error",("Unknown event code: %d",
|
|
||||||
(uchar) buf[EVENT_TYPE_OFFSET]));
|
|
||||||
ev= NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
exit:
|
||||||
|
|
||||||
if (ev)
|
if (ev)
|
||||||
{
|
{
|
||||||
|
11
sql/slave.cc
11
sql/slave.cc
@ -6741,7 +6741,18 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
|
|||||||
mi->last_queued_gtid.seq_no == 1000)
|
mi->last_queued_gtid.seq_no == 1000)
|
||||||
goto skip_relay_logging;
|
goto skip_relay_logging;
|
||||||
});
|
});
|
||||||
|
goto default_action;
|
||||||
#endif
|
#endif
|
||||||
|
case START_ENCRYPTION_EVENT:
|
||||||
|
if (uint2korr(buf + FLAGS_OFFSET) & LOG_EVENT_IGNORABLE_F)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
If the event was not requested by the slave (the slave did not ask for
|
||||||
|
it), i.e. has end_log_pos=0, we do not increment mi->master_log_pos
|
||||||
|
*/
|
||||||
|
inc_pos= uint4korr(buf+LOG_POS_OFFSET) ? event_len : 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
/* fall through */
|
/* fall through */
|
||||||
default:
|
default:
|
||||||
default_action:
|
default_action:
|
||||||
|
@ -3751,32 +3751,6 @@ open_and_process_table(THD *thd, TABLE_LIST *tables, uint *counter, uint flags,
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_use_stat_tables_mode(thd) > NEVER && tables->table)
|
|
||||||
{
|
|
||||||
TABLE_SHARE *table_share= tables->table->s;
|
|
||||||
if (table_share && table_share->table_category == TABLE_CATEGORY_USER &&
|
|
||||||
table_share->tmp_table == NO_TMP_TABLE)
|
|
||||||
{
|
|
||||||
if (table_share->stats_cb.stats_can_be_read ||
|
|
||||||
!alloc_statistics_for_table_share(thd, table_share, FALSE))
|
|
||||||
{
|
|
||||||
if (table_share->stats_cb.stats_can_be_read)
|
|
||||||
{
|
|
||||||
KEY *key_info= table_share->key_info;
|
|
||||||
KEY *key_info_end= key_info + table_share->keys;
|
|
||||||
KEY *table_key_info= tables->table->key_info;
|
|
||||||
for ( ; key_info < key_info_end; key_info++, table_key_info++)
|
|
||||||
table_key_info->read_stats= key_info->read_stats;
|
|
||||||
Field **field_ptr= table_share->field;
|
|
||||||
Field **table_field_ptr= tables->table->field;
|
|
||||||
for ( ; *field_ptr; field_ptr++, table_field_ptr++)
|
|
||||||
(*table_field_ptr)->read_stats= (*field_ptr)->read_stats;
|
|
||||||
tables->table->stats_is_read= table_share->stats_cb.stats_is_read;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
process_view_routines:
|
process_view_routines:
|
||||||
/*
|
/*
|
||||||
Again we may need cache all routines used by this view and add
|
Again we may need cache all routines used by this view and add
|
||||||
|
@ -850,7 +850,6 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
|
|||||||
invoker.init();
|
invoker.init();
|
||||||
prepare_derived_at_open= FALSE;
|
prepare_derived_at_open= FALSE;
|
||||||
create_tmp_table_for_derived= FALSE;
|
create_tmp_table_for_derived= FALSE;
|
||||||
force_read_stats= FALSE;
|
|
||||||
save_prep_leaf_list= FALSE;
|
save_prep_leaf_list= FALSE;
|
||||||
org_charset= 0;
|
org_charset= 0;
|
||||||
/* Restore THR_THD */
|
/* Restore THR_THD */
|
||||||
|
@ -2444,9 +2444,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool create_tmp_table_for_derived;
|
bool create_tmp_table_for_derived;
|
||||||
|
|
||||||
/* The flag to force reading statistics from EITS tables */
|
|
||||||
bool force_read_stats;
|
|
||||||
|
|
||||||
bool save_prep_leaf_list;
|
bool save_prep_leaf_list;
|
||||||
|
|
||||||
/* container for handler's private per-connection data */
|
/* container for handler's private per-connection data */
|
||||||
|
@ -427,16 +427,27 @@ static int send_file(THD *thd)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
Internal to mysql_binlog_send() routine that recalculates checksum for
|
Internal to mysql_binlog_send() routine that recalculates checksum for
|
||||||
a FD event (asserted) that needs additional arranment prior sending to slave.
|
1. FD event (asserted) that needs additional arranment prior sending to slave.
|
||||||
|
2. Start_encryption_log_event whose Ignored flag is set
|
||||||
|
TODO DBUG_ASSERT can be removed if this function is used for more general cases
|
||||||
*/
|
*/
|
||||||
inline void fix_checksum(String *packet, ulong ev_offset)
|
|
||||||
|
inline void fix_checksum(enum_binlog_checksum_alg checksum_alg, String *packet,
|
||||||
|
ulong ev_offset)
|
||||||
{
|
{
|
||||||
|
if (checksum_alg == BINLOG_CHECKSUM_ALG_OFF ||
|
||||||
|
checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF)
|
||||||
|
return;
|
||||||
/* recalculate the crc for this event */
|
/* recalculate the crc for this event */
|
||||||
uint data_len = uint4korr(packet->ptr() + ev_offset + EVENT_LEN_OFFSET);
|
uint data_len = uint4korr(packet->ptr() + ev_offset + EVENT_LEN_OFFSET);
|
||||||
ha_checksum crc;
|
ha_checksum crc;
|
||||||
DBUG_ASSERT(data_len ==
|
DBUG_ASSERT((data_len ==
|
||||||
LOG_EVENT_MINIMAL_HEADER_LEN + FORMAT_DESCRIPTION_HEADER_LEN +
|
LOG_EVENT_MINIMAL_HEADER_LEN + FORMAT_DESCRIPTION_HEADER_LEN +
|
||||||
BINLOG_CHECKSUM_ALG_DESC_LEN + BINLOG_CHECKSUM_LEN);
|
BINLOG_CHECKSUM_ALG_DESC_LEN + BINLOG_CHECKSUM_LEN) ||
|
||||||
|
(data_len ==
|
||||||
|
LOG_EVENT_MINIMAL_HEADER_LEN + BINLOG_CRYPTO_SCHEME_LENGTH +
|
||||||
|
BINLOG_KEY_VERSION_LENGTH + BINLOG_NONCE_LENGTH +
|
||||||
|
BINLOG_CHECKSUM_LEN));
|
||||||
crc= my_checksum(0, (uchar *)packet->ptr() + ev_offset, data_len -
|
crc= my_checksum(0, (uchar *)packet->ptr() + ev_offset, data_len -
|
||||||
BINLOG_CHECKSUM_LEN);
|
BINLOG_CHECKSUM_LEN);
|
||||||
int4store(packet->ptr() + ev_offset + data_len - BINLOG_CHECKSUM_LEN, crc);
|
int4store(packet->ptr() + ev_offset + data_len - BINLOG_CHECKSUM_LEN, crc);
|
||||||
@ -2169,6 +2180,7 @@ static int send_format_descriptor_event(binlog_send_info *info, IO_CACHE *log,
|
|||||||
THD *thd= info->thd;
|
THD *thd= info->thd;
|
||||||
String *packet= info->packet;
|
String *packet= info->packet;
|
||||||
Log_event_type event_type;
|
Log_event_type event_type;
|
||||||
|
bool initial_log_pos= info->clear_initial_log_pos;
|
||||||
DBUG_ENTER("send_format_descriptor_event");
|
DBUG_ENTER("send_format_descriptor_event");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2267,7 +2279,7 @@ static int send_format_descriptor_event(binlog_send_info *info, IO_CACHE *log,
|
|||||||
|
|
||||||
(*packet)[FLAGS_OFFSET+ev_offset] &= ~LOG_EVENT_BINLOG_IN_USE_F;
|
(*packet)[FLAGS_OFFSET+ev_offset] &= ~LOG_EVENT_BINLOG_IN_USE_F;
|
||||||
|
|
||||||
if (info->clear_initial_log_pos)
|
if (initial_log_pos)
|
||||||
{
|
{
|
||||||
info->clear_initial_log_pos= false;
|
info->clear_initial_log_pos= false;
|
||||||
/*
|
/*
|
||||||
@ -2285,9 +2297,7 @@ static int send_format_descriptor_event(binlog_send_info *info, IO_CACHE *log,
|
|||||||
ST_CREATED_OFFSET+ev_offset, (ulong) 0);
|
ST_CREATED_OFFSET+ev_offset, (ulong) 0);
|
||||||
|
|
||||||
/* fix the checksum due to latest changes in header */
|
/* fix the checksum due to latest changes in header */
|
||||||
if (info->current_checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
|
fix_checksum(info->current_checksum_alg, packet, ev_offset);
|
||||||
info->current_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
|
|
||||||
fix_checksum(packet, ev_offset);
|
|
||||||
}
|
}
|
||||||
else if (info->using_gtid_state)
|
else if (info->using_gtid_state)
|
||||||
{
|
{
|
||||||
@ -2308,9 +2318,7 @@ static int send_format_descriptor_event(binlog_send_info *info, IO_CACHE *log,
|
|||||||
{
|
{
|
||||||
int4store((char*) packet->ptr()+LOG_EVENT_MINIMAL_HEADER_LEN+
|
int4store((char*) packet->ptr()+LOG_EVENT_MINIMAL_HEADER_LEN+
|
||||||
ST_CREATED_OFFSET+ev_offset, (ulong) 0);
|
ST_CREATED_OFFSET+ev_offset, (ulong) 0);
|
||||||
if (info->current_checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
|
fix_checksum(info->current_checksum_alg, packet, ev_offset);
|
||||||
info->current_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
|
|
||||||
fix_checksum(packet, ev_offset);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2323,12 +2331,16 @@ static int send_format_descriptor_event(binlog_send_info *info, IO_CACHE *log,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Read the following Start_encryption_log_event but don't send it to slave.
|
Read the following Start_encryption_log_event and send it to slave as
|
||||||
Slave doesn't need to know whether master's binlog is encrypted,
|
Ignorable_log_event. Although Slave doesn't need to know whether master's
|
||||||
and if it'll want to encrypt its logs, it should generate its own
|
binlog is encrypted but it needs to update slave log pos (for mysqlbinlog).
|
||||||
random nonce, not use the one from the master.
|
|
||||||
|
If slave want to encrypt its logs, it should generate its own
|
||||||
|
random nonce, it should not use the one from the master.
|
||||||
*/
|
*/
|
||||||
packet->length(0);
|
/* reset transmit packet for the event read from binary log file */
|
||||||
|
if (reset_transmit_packet(info, info->flags, &ev_offset, &info->errmsg))
|
||||||
|
DBUG_RETURN(1);
|
||||||
info->last_pos= linfo->pos;
|
info->last_pos= linfo->pos;
|
||||||
error= Log_event::read_log_event(log, packet, info->fdev,
|
error= Log_event::read_log_event(log, packet, info->fdev,
|
||||||
opt_master_verify_checksum
|
opt_master_verify_checksum
|
||||||
@ -2342,12 +2354,13 @@ static int send_format_descriptor_event(binlog_send_info *info, IO_CACHE *log,
|
|||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
event_type= (Log_event_type)((uchar)(*packet)[LOG_EVENT_OFFSET]);
|
event_type= (Log_event_type)((uchar)(*packet)[LOG_EVENT_OFFSET + ev_offset]);
|
||||||
if (event_type == START_ENCRYPTION_EVENT)
|
if (event_type == START_ENCRYPTION_EVENT)
|
||||||
{
|
{
|
||||||
Start_encryption_log_event *sele= (Start_encryption_log_event *)
|
Start_encryption_log_event *sele= (Start_encryption_log_event *)
|
||||||
Log_event::read_log_event(packet->ptr(), packet->length(), &info->errmsg,
|
Log_event::read_log_event(packet->ptr() + ev_offset, packet->length()
|
||||||
info->fdev, BINLOG_CHECKSUM_ALG_OFF);
|
- ev_offset, &info->errmsg, info->fdev,
|
||||||
|
BINLOG_CHECKSUM_ALG_OFF);
|
||||||
if (!sele)
|
if (!sele)
|
||||||
{
|
{
|
||||||
info->error= ER_MASTER_FATAL_ERROR_READING_BINLOG;
|
info->error= ER_MASTER_FATAL_ERROR_READING_BINLOG;
|
||||||
@ -2361,6 +2374,18 @@ static int send_format_descriptor_event(binlog_send_info *info, IO_CACHE *log,
|
|||||||
delete sele;
|
delete sele;
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
/* Make it Ignorable_log_event and send it */
|
||||||
|
(*packet)[FLAGS_OFFSET+ev_offset] |= LOG_EVENT_IGNORABLE_F;
|
||||||
|
if (initial_log_pos)
|
||||||
|
int4store((char*) packet->ptr()+LOG_POS_OFFSET+ev_offset, (ulong) 0);
|
||||||
|
/* fix the checksum due to latest changes in header */
|
||||||
|
fix_checksum(info->current_checksum_alg, packet, ev_offset);
|
||||||
|
if (my_net_write(info->net, (uchar*) packet->ptr(), packet->length()))
|
||||||
|
{
|
||||||
|
info->errmsg= "Failed on my_net_write()";
|
||||||
|
info->error= ER_UNKNOWN_ERROR;
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
delete sele;
|
delete sele;
|
||||||
}
|
}
|
||||||
else if (start_pos == BIN_LOG_HEADER_SIZE)
|
else if (start_pos == BIN_LOG_HEADER_SIZE)
|
||||||
|
@ -4614,10 +4614,8 @@ fill_schema_table_by_open(THD *thd, MEM_ROOT *mem_root,
|
|||||||
}
|
}
|
||||||
|
|
||||||
DBUG_ASSERT(thd->lex == lex);
|
DBUG_ASSERT(thd->lex == lex);
|
||||||
thd->force_read_stats= get_schema_table_idx(schema_table) == SCH_STATISTICS;
|
|
||||||
result= open_tables_only_view_structure(thd, table_list, can_deadlock);
|
result= open_tables_only_view_structure(thd, table_list, can_deadlock);
|
||||||
(void) read_statistics_for_tables_if_needed(thd, table_list);
|
(void) read_statistics_for_tables_if_needed(thd, table_list);
|
||||||
thd->force_read_stats= false;
|
|
||||||
|
|
||||||
DEBUG_SYNC(thd, "after_open_table_ignore_flush");
|
DEBUG_SYNC(thd, "after_open_table_ignore_flush");
|
||||||
|
|
||||||
@ -6607,6 +6605,7 @@ static int get_schema_stat_record(THD *thd, TABLE_LIST *tables,
|
|||||||
KEY *key_info=show_table->s->key_info;
|
KEY *key_info=show_table->s->key_info;
|
||||||
if (show_table->file)
|
if (show_table->file)
|
||||||
{
|
{
|
||||||
|
(void) read_statistics_for_tables(thd, tables);
|
||||||
show_table->file->info(HA_STATUS_VARIABLE |
|
show_table->file->info(HA_STATUS_VARIABLE |
|
||||||
HA_STATUS_NO_LOCK |
|
HA_STATUS_NO_LOCK |
|
||||||
HA_STATUS_TIME);
|
HA_STATUS_TIME);
|
||||||
|
@ -2169,54 +2169,6 @@ int alloc_statistics_for_table(THD* thd, TABLE *table)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
@brief
|
|
||||||
Check whether any persistent statistics for the processed command is needed
|
|
||||||
|
|
||||||
@param
|
|
||||||
thd The thread handle
|
|
||||||
|
|
||||||
@details
|
|
||||||
The function checks whether any persitent statistics for the processed
|
|
||||||
command is needed to be read.
|
|
||||||
|
|
||||||
@retval
|
|
||||||
TRUE statistics is needed to be read
|
|
||||||
@retval
|
|
||||||
FALSE Otherwise
|
|
||||||
*/
|
|
||||||
|
|
||||||
static
|
|
||||||
inline bool statistics_for_command_is_needed(THD *thd)
|
|
||||||
{
|
|
||||||
if (thd->bootstrap || thd->variables.use_stat_tables == NEVER)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (thd->force_read_stats)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
switch(thd->lex->sql_command) {
|
|
||||||
case SQLCOM_SELECT:
|
|
||||||
case SQLCOM_INSERT:
|
|
||||||
case SQLCOM_INSERT_SELECT:
|
|
||||||
case SQLCOM_UPDATE:
|
|
||||||
case SQLCOM_UPDATE_MULTI:
|
|
||||||
case SQLCOM_DELETE:
|
|
||||||
case SQLCOM_DELETE_MULTI:
|
|
||||||
case SQLCOM_REPLACE:
|
|
||||||
case SQLCOM_REPLACE_SELECT:
|
|
||||||
case SQLCOM_CREATE_TABLE:
|
|
||||||
case SQLCOM_SET_OPTION:
|
|
||||||
case SQLCOM_DO:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief
|
@brief
|
||||||
Allocate memory for the statistical data used by a table share
|
Allocate memory for the statistical data used by a table share
|
||||||
@ -2225,8 +2177,6 @@ inline bool statistics_for_command_is_needed(THD *thd)
|
|||||||
thd Thread handler
|
thd Thread handler
|
||||||
@param
|
@param
|
||||||
table_share Table share for which the memory for statistical data is allocated
|
table_share Table share for which the memory for statistical data is allocated
|
||||||
@param
|
|
||||||
is_safe TRUE <-> at any time only one thread can perform the function
|
|
||||||
|
|
||||||
@note
|
@note
|
||||||
The function allocates the memory for the statistical data on a table in the
|
The function allocates the memory for the statistical data on a table in the
|
||||||
@ -2235,8 +2185,6 @@ inline bool statistics_for_command_is_needed(THD *thd)
|
|||||||
mysql.index_stats. The memory is allocated for the statistics on the table,
|
mysql.index_stats. The memory is allocated for the statistics on the table,
|
||||||
on the tables's columns, and on the table's indexes. The memory is allocated
|
on the tables's columns, and on the table's indexes. The memory is allocated
|
||||||
in the table_share's mem_root.
|
in the table_share's mem_root.
|
||||||
If the parameter is_safe is TRUE then it is guaranteed that at any given time
|
|
||||||
only one thread is executed the code of the function.
|
|
||||||
|
|
||||||
@retval
|
@retval
|
||||||
0 If the memory for all statistical data has been successfully allocated
|
0 If the memory for all statistical data has been successfully allocated
|
||||||
@ -2255,16 +2203,10 @@ inline bool statistics_for_command_is_needed(THD *thd)
|
|||||||
Here the second and the third threads try to allocate the memory for
|
Here the second and the third threads try to allocate the memory for
|
||||||
statistical data at the same time. The precautions are taken to
|
statistical data at the same time. The precautions are taken to
|
||||||
guarantee the correctness of the allocation.
|
guarantee the correctness of the allocation.
|
||||||
|
|
||||||
@note
|
|
||||||
Currently the function always is called with the parameter is_safe set
|
|
||||||
to FALSE.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int alloc_statistics_for_table_share(THD* thd, TABLE_SHARE *table_share,
|
static int alloc_statistics_for_table_share(THD* thd, TABLE_SHARE *table_share)
|
||||||
bool is_safe)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
Field **field_ptr;
|
Field **field_ptr;
|
||||||
KEY *key_info, *end;
|
KEY *key_info, *end;
|
||||||
TABLE_STATISTICS_CB *stats_cb= &table_share->stats_cb;
|
TABLE_STATISTICS_CB *stats_cb= &table_share->stats_cb;
|
||||||
@ -2274,16 +2216,11 @@ int alloc_statistics_for_table_share(THD* thd, TABLE_SHARE *table_share,
|
|||||||
DEBUG_SYNC(thd, "statistics_mem_alloc_start1");
|
DEBUG_SYNC(thd, "statistics_mem_alloc_start1");
|
||||||
DEBUG_SYNC(thd, "statistics_mem_alloc_start2");
|
DEBUG_SYNC(thd, "statistics_mem_alloc_start2");
|
||||||
|
|
||||||
if (!statistics_for_command_is_needed(thd))
|
mysql_mutex_lock(&table_share->LOCK_share);
|
||||||
DBUG_RETURN(1);
|
|
||||||
|
|
||||||
if (!is_safe)
|
|
||||||
mysql_mutex_lock(&table_share->LOCK_share);
|
|
||||||
|
|
||||||
if (stats_cb->stats_can_be_read)
|
if (stats_cb->stats_can_be_read)
|
||||||
{
|
{
|
||||||
if (!is_safe)
|
mysql_mutex_unlock(&table_share->LOCK_share);
|
||||||
mysql_mutex_unlock(&table_share->LOCK_share);
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2294,8 +2231,7 @@ int alloc_statistics_for_table_share(THD* thd, TABLE_SHARE *table_share,
|
|||||||
sizeof(Table_statistics));
|
sizeof(Table_statistics));
|
||||||
if (!table_stats)
|
if (!table_stats)
|
||||||
{
|
{
|
||||||
if (!is_safe)
|
mysql_mutex_unlock(&table_share->LOCK_share);
|
||||||
mysql_mutex_unlock(&table_share->LOCK_share);
|
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
memset(table_stats, 0, sizeof(Table_statistics));
|
memset(table_stats, 0, sizeof(Table_statistics));
|
||||||
@ -2367,8 +2303,7 @@ int alloc_statistics_for_table_share(THD* thd, TABLE_SHARE *table_share,
|
|||||||
if (column_stats && index_stats && idx_avg_frequency)
|
if (column_stats && index_stats && idx_avg_frequency)
|
||||||
stats_cb->stats_can_be_read= TRUE;
|
stats_cb->stats_can_be_read= TRUE;
|
||||||
|
|
||||||
if (!is_safe)
|
mysql_mutex_unlock(&table_share->LOCK_share);
|
||||||
mysql_mutex_unlock(&table_share->LOCK_share);
|
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
@ -3139,9 +3074,6 @@ bool statistics_for_tables_is_needed(THD *thd, TABLE_LIST *tables)
|
|||||||
if (!tables)
|
if (!tables)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!statistics_for_command_is_needed(thd))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Do not read statistics for any query that explicity involves
|
Do not read statistics for any query that explicity involves
|
||||||
statistical tables, failure to to do so we may end up
|
statistical tables, failure to to do so we may end up
|
||||||
@ -3272,11 +3204,65 @@ int read_histograms_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int read_statistics_for_tables_if_needed(THD *thd, TABLE_LIST *tables)
|
int read_statistics_for_tables_if_needed(THD *thd, TABLE_LIST *tables)
|
||||||
|
{
|
||||||
|
switch (thd->lex->sql_command) {
|
||||||
|
case SQLCOM_SELECT:
|
||||||
|
case SQLCOM_INSERT:
|
||||||
|
case SQLCOM_INSERT_SELECT:
|
||||||
|
case SQLCOM_UPDATE:
|
||||||
|
case SQLCOM_UPDATE_MULTI:
|
||||||
|
case SQLCOM_DELETE:
|
||||||
|
case SQLCOM_DELETE_MULTI:
|
||||||
|
case SQLCOM_REPLACE:
|
||||||
|
case SQLCOM_REPLACE_SELECT:
|
||||||
|
case SQLCOM_CREATE_TABLE:
|
||||||
|
case SQLCOM_SET_OPTION:
|
||||||
|
case SQLCOM_DO:
|
||||||
|
return read_statistics_for_tables(thd, tables);
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int read_statistics_for_tables(THD *thd, TABLE_LIST *tables)
|
||||||
{
|
{
|
||||||
TABLE_LIST stat_tables[STATISTICS_TABLES];
|
TABLE_LIST stat_tables[STATISTICS_TABLES];
|
||||||
Open_tables_backup open_tables_backup;
|
Open_tables_backup open_tables_backup;
|
||||||
|
|
||||||
DBUG_ENTER("read_statistics_for_tables_if_needed");
|
DBUG_ENTER("read_statistics_for_tables");
|
||||||
|
|
||||||
|
if (thd->bootstrap || thd->variables.use_stat_tables == NEVER)
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
|
for (TABLE_LIST *tl= tables; tl; tl= tl->next_global)
|
||||||
|
{
|
||||||
|
if (tl->table)
|
||||||
|
{
|
||||||
|
TABLE_SHARE *table_share= tl->table->s;
|
||||||
|
if (table_share && table_share->table_category == TABLE_CATEGORY_USER &&
|
||||||
|
table_share->tmp_table == NO_TMP_TABLE)
|
||||||
|
{
|
||||||
|
if (table_share->stats_cb.stats_can_be_read ||
|
||||||
|
!alloc_statistics_for_table_share(thd, table_share))
|
||||||
|
{
|
||||||
|
if (table_share->stats_cb.stats_can_be_read)
|
||||||
|
{
|
||||||
|
KEY *key_info= table_share->key_info;
|
||||||
|
KEY *key_info_end= key_info + table_share->keys;
|
||||||
|
KEY *table_key_info= tl->table->key_info;
|
||||||
|
for ( ; key_info < key_info_end; key_info++, table_key_info++)
|
||||||
|
table_key_info->read_stats= key_info->read_stats;
|
||||||
|
Field **field_ptr= table_share->field;
|
||||||
|
Field **table_field_ptr= tl->table->field;
|
||||||
|
for ( ; *field_ptr; field_ptr++, table_field_ptr++)
|
||||||
|
(*table_field_ptr)->read_stats= (*field_ptr)->read_stats;
|
||||||
|
tl->table->stats_is_read= table_share->stats_cb.stats_is_read;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG_SYNC(thd, "statistics_read_start");
|
DEBUG_SYNC(thd, "statistics_read_start");
|
||||||
|
|
||||||
|
@ -89,9 +89,8 @@ Use_stat_tables_mode get_use_stat_tables_mode(THD *thd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int read_statistics_for_tables_if_needed(THD *thd, TABLE_LIST *tables);
|
int read_statistics_for_tables_if_needed(THD *thd, TABLE_LIST *tables);
|
||||||
|
int read_statistics_for_tables(THD *thd, TABLE_LIST *tables);
|
||||||
int collect_statistics_for_table(THD *thd, TABLE *table);
|
int collect_statistics_for_table(THD *thd, TABLE *table);
|
||||||
int alloc_statistics_for_table_share(THD* thd, TABLE_SHARE *share,
|
|
||||||
bool is_safe);
|
|
||||||
void delete_stat_values_for_table_share(TABLE_SHARE *table_share);
|
void delete_stat_values_for_table_share(TABLE_SHARE *table_share);
|
||||||
int alloc_statistics_for_table(THD *thd, TABLE *table);
|
int alloc_statistics_for_table(THD *thd, TABLE *table);
|
||||||
int update_statistics_for_table(THD *thd, TABLE *table);
|
int update_statistics_for_table(THD *thd, TABLE *table);
|
||||||
|
@ -194,7 +194,7 @@ static void PROFILE_Save( FILE *file, PROFILESECTION *section )
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (key = section->key; key; key = key->next)
|
for (key = section->key; key; key = key->next)
|
||||||
if (key->name && key->name[0]) {
|
if (key->name[0]) {
|
||||||
fprintf(file, "%s", SVP(key->name));
|
fprintf(file, "%s", SVP(key->name));
|
||||||
|
|
||||||
if (key->value)
|
if (key->value)
|
||||||
|
@ -3314,25 +3314,22 @@ btr_parse_set_min_rec_mark(
|
|||||||
return(ptr + 2);
|
return(ptr + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************//**
|
/** Sets a record as the predefined minimum record. */
|
||||||
Sets a record as the predefined minimum record. */
|
void btr_set_min_rec_mark(rec_t* rec, mtr_t* mtr)
|
||||||
void
|
|
||||||
btr_set_min_rec_mark(
|
|
||||||
/*=================*/
|
|
||||||
rec_t* rec, /*!< in: record */
|
|
||||||
mtr_t* mtr) /*!< in: mtr */
|
|
||||||
{
|
{
|
||||||
ulint info_bits;
|
const bool comp = page_rec_is_comp(rec);
|
||||||
|
|
||||||
if (page_rec_is_comp(rec)) {
|
ut_ad(rec == page_rec_get_next_const(page_get_infimum_rec(
|
||||||
info_bits = rec_get_info_bits(rec, TRUE);
|
page_align(rec))));
|
||||||
|
ut_ad(!(rec_get_info_bits(page_rec_get_next(rec), comp)
|
||||||
|
& REC_INFO_MIN_REC_FLAG));
|
||||||
|
|
||||||
|
size_t info_bits = rec_get_info_bits(rec, comp);
|
||||||
|
if (comp) {
|
||||||
rec_set_info_bits_new(rec, info_bits | REC_INFO_MIN_REC_FLAG);
|
rec_set_info_bits_new(rec, info_bits | REC_INFO_MIN_REC_FLAG);
|
||||||
|
|
||||||
btr_set_min_rec_mark_log(rec, MLOG_COMP_REC_MIN_MARK, mtr);
|
btr_set_min_rec_mark_log(rec, MLOG_COMP_REC_MIN_MARK, mtr);
|
||||||
} else {
|
} else {
|
||||||
info_bits = rec_get_info_bits(rec, FALSE);
|
|
||||||
|
|
||||||
rec_set_info_bits_old(rec, info_bits | REC_INFO_MIN_REC_FLAG);
|
rec_set_info_bits_old(rec, info_bits | REC_INFO_MIN_REC_FLAG);
|
||||||
|
|
||||||
btr_set_min_rec_mark_log(rec, MLOG_REC_MIN_MARK, mtr);
|
btr_set_min_rec_mark_log(rec, MLOG_REC_MIN_MARK, mtr);
|
||||||
|
@ -5675,6 +5675,9 @@ btr_cur_pessimistic_delete(
|
|||||||
#endif /* UNIV_ZIP_DEBUG */
|
#endif /* UNIV_ZIP_DEBUG */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rec_t* next_rec = NULL;
|
||||||
|
bool min_mark_next_rec = false;
|
||||||
|
|
||||||
if (page_is_leaf(page)) {
|
if (page_is_leaf(page)) {
|
||||||
const bool is_metadata = rec_get_info_bits(
|
const bool is_metadata = rec_get_info_bits(
|
||||||
rec, page_rec_is_comp(rec)) & REC_INFO_MIN_REC_FLAG;
|
rec, page_rec_is_comp(rec)) & REC_INFO_MIN_REC_FLAG;
|
||||||
@ -5748,20 +5751,14 @@ discard_page:
|
|||||||
goto return_after_reservations;
|
goto return_after_reservations;
|
||||||
}
|
}
|
||||||
|
|
||||||
rec_t* next_rec = page_rec_get_next(rec);
|
next_rec = page_rec_get_next(rec);
|
||||||
|
|
||||||
if (!page_has_prev(page)) {
|
if (!page_has_prev(page)) {
|
||||||
|
|
||||||
/* If we delete the leftmost node pointer on a
|
/* If we delete the leftmost node pointer on a
|
||||||
non-leaf level, we must mark the new leftmost node
|
non-leaf level, we must mark the new leftmost node
|
||||||
pointer as the predefined minimum record */
|
pointer as the predefined minimum record */
|
||||||
|
|
||||||
/* This will make page_zip_validate() fail until
|
min_mark_next_rec = true;
|
||||||
page_cur_delete_rec() completes. This is harmless,
|
|
||||||
because everything will take place within a single
|
|
||||||
mini-transaction and because writing to the redo log
|
|
||||||
is an atomic operation (performed by mtr_commit()). */
|
|
||||||
btr_set_min_rec_mark(next_rec, mtr);
|
|
||||||
} else if (dict_index_is_spatial(index)) {
|
} else if (dict_index_is_spatial(index)) {
|
||||||
/* For rtree, if delete the leftmost node pointer,
|
/* For rtree, if delete the leftmost node pointer,
|
||||||
we need to update parent page. */
|
we need to update parent page. */
|
||||||
@ -5829,6 +5826,11 @@ discard_page:
|
|||||||
block->page.size, mtr);
|
block->page.size, mtr);
|
||||||
page_cur_delete_rec(btr_cur_get_page_cur(cursor), index,
|
page_cur_delete_rec(btr_cur_get_page_cur(cursor), index,
|
||||||
offsets, mtr);
|
offsets, mtr);
|
||||||
|
|
||||||
|
if (min_mark_next_rec) {
|
||||||
|
btr_set_min_rec_mark(next_rec, mtr);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef UNIV_ZIP_DEBUG
|
#ifdef UNIV_ZIP_DEBUG
|
||||||
ut_a(!page_zip || page_zip_validate(page_zip, page, index));
|
ut_a(!page_zip || page_zip_validate(page_zip, page, index));
|
||||||
#endif /* UNIV_ZIP_DEBUG */
|
#endif /* UNIV_ZIP_DEBUG */
|
||||||
|
@ -589,12 +589,6 @@ decrypt_failed:
|
|||||||
<< mach_read_from_4(
|
<< mach_read_from_4(
|
||||||
FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION
|
FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION
|
||||||
+ dst_frame);
|
+ dst_frame);
|
||||||
/* Mark page encrypted in case it should be. */
|
|
||||||
if (space->crypt_data->type
|
|
||||||
!= CRYPT_SCHEME_UNENCRYPTED) {
|
|
||||||
bpage->encrypted = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -605,8 +599,7 @@ decrypt_failed:
|
|||||||
ut_d(fil_page_type_validate(dst_frame));
|
ut_d(fil_page_type_validate(dst_frame));
|
||||||
|
|
||||||
/* decrypt using crypt_buf to dst_frame */
|
/* decrypt using crypt_buf to dst_frame */
|
||||||
if (!fil_space_decrypt(space, slot->crypt_buf,
|
if (!fil_space_decrypt(space, slot->crypt_buf, dst_frame)) {
|
||||||
dst_frame, &bpage->encrypted)) {
|
|
||||||
slot->release();
|
slot->release();
|
||||||
goto decrypt_failed;
|
goto decrypt_failed;
|
||||||
}
|
}
|
||||||
@ -1573,7 +1566,6 @@ buf_block_init(
|
|||||||
block->page.buf_fix_count = 0;
|
block->page.buf_fix_count = 0;
|
||||||
block->page.io_fix = BUF_IO_NONE;
|
block->page.io_fix = BUF_IO_NONE;
|
||||||
block->page.flush_observer = NULL;
|
block->page.flush_observer = NULL;
|
||||||
block->page.encrypted = false;
|
|
||||||
block->page.real_size = 0;
|
block->page.real_size = 0;
|
||||||
block->page.write_size = 0;
|
block->page.write_size = 0;
|
||||||
block->modify_clock = 0;
|
block->modify_clock = 0;
|
||||||
@ -4087,7 +4079,6 @@ err_exit:
|
|||||||
if (encrypted) {
|
if (encrypted) {
|
||||||
ib::info() << "Row compressed page could be encrypted"
|
ib::info() << "Row compressed page could be encrypted"
|
||||||
" with key_version " << key_version;
|
" with key_version " << key_version;
|
||||||
block->page.encrypted = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (space) {
|
if (space) {
|
||||||
@ -5293,7 +5284,6 @@ buf_page_init_low(
|
|||||||
bpage->newest_modification = 0;
|
bpage->newest_modification = 0;
|
||||||
bpage->oldest_modification = 0;
|
bpage->oldest_modification = 0;
|
||||||
bpage->write_size = 0;
|
bpage->write_size = 0;
|
||||||
bpage->encrypted = false;
|
|
||||||
bpage->real_size = 0;
|
bpage->real_size = 0;
|
||||||
bpage->slot = NULL;
|
bpage->slot = NULL;
|
||||||
|
|
||||||
@ -5887,17 +5877,19 @@ buf_page_monitor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Mark a table corrupted.
|
/** Mark a table corrupted.
|
||||||
Also remove the bpage from LRU list.
|
@param[in] bpage corrupted page
|
||||||
@param[in] bpage Corrupted page. */
|
@param[in] space tablespace of the corrupted page */
|
||||||
static void buf_mark_space_corrupt(buf_page_t* bpage, const fil_space_t* space)
|
ATTRIBUTE_COLD
|
||||||
|
static void buf_mark_space_corrupt(buf_page_t* bpage, const fil_space_t& space)
|
||||||
{
|
{
|
||||||
/* If block is not encrypted find the table with specified
|
/* If block is not encrypted find the table with specified
|
||||||
space id, and mark it corrupted. Encrypted tables
|
space id, and mark it corrupted. Encrypted tables
|
||||||
are marked unusable later e.g. in ::open(). */
|
are marked unusable later e.g. in ::open(). */
|
||||||
if (!bpage->encrypted) {
|
if (!space.crypt_data
|
||||||
dict_set_corrupted_by_space(space);
|
|| space.crypt_data->type == CRYPT_SCHEME_UNENCRYPTED) {
|
||||||
|
dict_set_corrupted_by_space(&space);
|
||||||
} else {
|
} else {
|
||||||
dict_set_encrypted_by_space(space);
|
dict_set_encrypted_by_space(&space);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5936,7 +5928,7 @@ buf_corrupt_page_release(buf_page_t* bpage, const fil_space_t* space)
|
|||||||
mutex_exit(buf_page_get_mutex(bpage));
|
mutex_exit(buf_page_get_mutex(bpage));
|
||||||
|
|
||||||
if (!srv_force_recovery) {
|
if (!srv_force_recovery) {
|
||||||
buf_mark_space_corrupt(bpage, space);
|
buf_mark_space_corrupt(bpage, *space);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* After this point bpage can't be referenced. */
|
/* After this point bpage can't be referenced. */
|
||||||
@ -5966,7 +5958,6 @@ static dberr_t buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space)
|
|||||||
byte* dst_frame = (bpage->zip.data) ? bpage->zip.data :
|
byte* dst_frame = (bpage->zip.data) ? bpage->zip.data :
|
||||||
((buf_block_t*) bpage)->frame;
|
((buf_block_t*) bpage)->frame;
|
||||||
dberr_t err = DB_SUCCESS;
|
dberr_t err = DB_SUCCESS;
|
||||||
bool corrupted = false;
|
|
||||||
|
|
||||||
/* In buf_decrypt_after_read we have either decrypted the page if
|
/* In buf_decrypt_after_read we have either decrypted the page if
|
||||||
page post encryption checksum matches and used key_id is found
|
page post encryption checksum matches and used key_id is found
|
||||||
@ -5974,33 +5965,20 @@ static dberr_t buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space)
|
|||||||
not decrypted and it could be either encrypted and corrupted
|
not decrypted and it could be either encrypted and corrupted
|
||||||
or corrupted or good page. If we decrypted, there page could
|
or corrupted or good page. If we decrypted, there page could
|
||||||
still be corrupted if used key does not match. */
|
still be corrupted if used key does not match. */
|
||||||
const bool still_encrypted = mach_read_from_4(
|
const bool seems_encrypted = mach_read_from_4(
|
||||||
dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION)
|
dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION)
|
||||||
&& space->crypt_data
|
&& space->crypt_data
|
||||||
&& space->crypt_data->type != CRYPT_SCHEME_UNENCRYPTED
|
&& space->crypt_data->type != CRYPT_SCHEME_UNENCRYPTED;
|
||||||
&& !bpage->encrypted
|
|
||||||
&& fil_space_verify_crypt_checksum(dst_frame, bpage->size);
|
|
||||||
|
|
||||||
if (!still_encrypted) {
|
/* If traditional checksums match, we assume that page is
|
||||||
/* If traditional checksums match, we assume that page is
|
not anymore encrypted. */
|
||||||
not anymore encrypted. */
|
if (buf_page_is_corrupted(
|
||||||
corrupted = buf_page_is_corrupted(
|
true, dst_frame, bpage->size, space)) {
|
||||||
true, dst_frame, bpage->size, space);
|
err = DB_PAGE_CORRUPTED;
|
||||||
|
|
||||||
if (!corrupted) {
|
|
||||||
bpage->encrypted = false;
|
|
||||||
} else {
|
|
||||||
err = DB_PAGE_CORRUPTED;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pages that we think are unencrypted but do not match the checksum
|
if (seems_encrypted && err == DB_PAGE_CORRUPTED
|
||||||
checks could be corrupted or encrypted or both. */
|
&& bpage->id.page_no() != 0) {
|
||||||
if (corrupted && !bpage->encrypted) {
|
|
||||||
/* An error will be reported by
|
|
||||||
buf_page_io_complete(). */
|
|
||||||
} else if (still_encrypted || (bpage->encrypted && corrupted)) {
|
|
||||||
bpage->encrypted = true;
|
|
||||||
err = DB_DECRYPTION_FAILED;
|
err = DB_DECRYPTION_FAILED;
|
||||||
|
|
||||||
ib::error()
|
ib::error()
|
||||||
@ -6062,7 +6040,6 @@ buf_page_io_complete(buf_page_t* bpage, bool dblwr, bool evict)
|
|||||||
if (io_type == BUF_IO_READ) {
|
if (io_type == BUF_IO_READ) {
|
||||||
ulint read_page_no = 0;
|
ulint read_page_no = 0;
|
||||||
ulint read_space_id = 0;
|
ulint read_space_id = 0;
|
||||||
uint key_version = 0;
|
|
||||||
byte* frame = bpage->zip.data
|
byte* frame = bpage->zip.data
|
||||||
? bpage->zip.data
|
? bpage->zip.data
|
||||||
: reinterpret_cast<buf_block_t*>(bpage)->frame;
|
: reinterpret_cast<buf_block_t*>(bpage)->frame;
|
||||||
@ -6102,8 +6079,6 @@ buf_page_io_complete(buf_page_t* bpage, bool dblwr, bool evict)
|
|||||||
read_page_no = mach_read_from_4(frame + FIL_PAGE_OFFSET);
|
read_page_no = mach_read_from_4(frame + FIL_PAGE_OFFSET);
|
||||||
read_space_id = mach_read_from_4(
|
read_space_id = mach_read_from_4(
|
||||||
frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
|
frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
|
||||||
key_version = mach_read_from_4(
|
|
||||||
frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
|
|
||||||
|
|
||||||
if (bpage->id.space() == TRX_SYS_SPACE
|
if (bpage->id.space() == TRX_SYS_SPACE
|
||||||
&& buf_dblwr_page_inside(bpage->id.page_no())) {
|
&& buf_dblwr_page_inside(bpage->id.page_no())) {
|
||||||
@ -6219,23 +6194,9 @@ database_corrupted:
|
|||||||
&& fil_page_get_type(frame) == FIL_PAGE_INDEX
|
&& fil_page_get_type(frame) == FIL_PAGE_INDEX
|
||||||
&& page_is_leaf(frame)) {
|
&& page_is_leaf(frame)) {
|
||||||
|
|
||||||
if (bpage->encrypted) {
|
ibuf_merge_or_delete_for_page(
|
||||||
ib::warn()
|
(buf_block_t*) bpage, bpage->id,
|
||||||
<< "Table in tablespace "
|
&bpage->size, TRUE);
|
||||||
<< bpage->id.space()
|
|
||||||
<< " encrypted. However key "
|
|
||||||
"management plugin or used "
|
|
||||||
<< "key_version " << key_version
|
|
||||||
<< " is not found or"
|
|
||||||
" used encryption algorithm or method does not match."
|
|
||||||
" Can't continue opening the table.";
|
|
||||||
} else {
|
|
||||||
|
|
||||||
ibuf_merge_or_delete_for_page(
|
|
||||||
(buf_block_t*) bpage, bpage->id,
|
|
||||||
&bpage->size, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
space->release_for_io();
|
space->release_for_io();
|
||||||
|
@ -792,7 +792,6 @@ Decrypt a page.
|
|||||||
@param[in] space Tablespace
|
@param[in] space Tablespace
|
||||||
@param[in] tmp_frame Temporary buffer used for decrypting
|
@param[in] tmp_frame Temporary buffer used for decrypting
|
||||||
@param[in,out] src_frame Page to decrypt
|
@param[in,out] src_frame Page to decrypt
|
||||||
@param[out] decrypted true if page was decrypted
|
|
||||||
@return decrypted page, or original not encrypted page if decryption is
|
@return decrypted page, or original not encrypted page if decryption is
|
||||||
not needed.*/
|
not needed.*/
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
@ -800,13 +799,11 @@ byte*
|
|||||||
fil_space_decrypt(
|
fil_space_decrypt(
|
||||||
const fil_space_t* space,
|
const fil_space_t* space,
|
||||||
byte* tmp_frame,
|
byte* tmp_frame,
|
||||||
byte* src_frame,
|
byte* src_frame)
|
||||||
bool* decrypted)
|
|
||||||
{
|
{
|
||||||
dberr_t err = DB_SUCCESS;
|
dberr_t err = DB_SUCCESS;
|
||||||
byte* res = NULL;
|
byte* res = NULL;
|
||||||
const page_size_t page_size(space->flags);
|
const page_size_t page_size(space->flags);
|
||||||
*decrypted = false;
|
|
||||||
|
|
||||||
ut_ad(space->crypt_data != NULL && space->crypt_data->is_encrypted());
|
ut_ad(space->crypt_data != NULL && space->crypt_data->is_encrypted());
|
||||||
ut_ad(space->pending_io());
|
ut_ad(space->pending_io());
|
||||||
@ -816,7 +813,6 @@ fil_space_decrypt(
|
|||||||
|
|
||||||
if (err == DB_SUCCESS) {
|
if (err == DB_SUCCESS) {
|
||||||
if (encrypted) {
|
if (encrypted) {
|
||||||
*decrypted = true;
|
|
||||||
/* Copy the decrypted page back to page buffer, not
|
/* Copy the decrypted page back to page buffer, not
|
||||||
really any other options. */
|
really any other options. */
|
||||||
memcpy(src_frame, tmp_frame, page_size.physical());
|
memcpy(src_frame, tmp_frame, page_size.physical());
|
||||||
|
@ -336,10 +336,8 @@ ibuf_header_page_get(
|
|||||||
page_id_t(IBUF_SPACE_ID, FSP_IBUF_HEADER_PAGE_NO),
|
page_id_t(IBUF_SPACE_ID, FSP_IBUF_HEADER_PAGE_NO),
|
||||||
univ_page_size, RW_X_LATCH, mtr);
|
univ_page_size, RW_X_LATCH, mtr);
|
||||||
|
|
||||||
|
if (block) {
|
||||||
if (!block->page.encrypted) {
|
|
||||||
buf_block_dbg_add_level(block, SYNC_IBUF_HEADER);
|
buf_block_dbg_add_level(block, SYNC_IBUF_HEADER);
|
||||||
|
|
||||||
page = buf_block_get_frame(block);
|
page = buf_block_get_frame(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,14 +520,10 @@ btr_insert_on_non_leaf_level_func(
|
|||||||
mtr_t* mtr); /*!< in: mtr */
|
mtr_t* mtr); /*!< in: mtr */
|
||||||
#define btr_insert_on_non_leaf_level(f,i,l,t,m) \
|
#define btr_insert_on_non_leaf_level(f,i,l,t,m) \
|
||||||
btr_insert_on_non_leaf_level_func(f,i,l,t,__FILE__,__LINE__,m)
|
btr_insert_on_non_leaf_level_func(f,i,l,t,__FILE__,__LINE__,m)
|
||||||
/****************************************************************//**
|
|
||||||
Sets a record as the predefined minimum record. */
|
/** Sets a record as the predefined minimum record. */
|
||||||
void
|
void btr_set_min_rec_mark(rec_t* rec, mtr_t* mtr) MY_ATTRIBUTE((nonnull));
|
||||||
btr_set_min_rec_mark(
|
|
||||||
/*=================*/
|
|
||||||
rec_t* rec, /*!< in/out: record */
|
|
||||||
mtr_t* mtr) /*!< in: mtr */
|
|
||||||
MY_ATTRIBUTE((nonnull));
|
|
||||||
/** Seek to the parent page of a B-tree page.
|
/** Seek to the parent page of a B-tree page.
|
||||||
@param[in,out] index b-tree
|
@param[in,out] index b-tree
|
||||||
@param[in] block child page
|
@param[in] block child page
|
||||||
|
@ -1468,8 +1468,6 @@ public:
|
|||||||
if written again we check is TRIM
|
if written again we check is TRIM
|
||||||
operation needed. */
|
operation needed. */
|
||||||
|
|
||||||
bool encrypted; /*!< page is still encrypted */
|
|
||||||
|
|
||||||
ulint real_size; /*!< Real size of the page
|
ulint real_size; /*!< Real size of the page
|
||||||
Normal pages == srv_page_size
|
Normal pages == srv_page_size
|
||||||
page compressed pages, payload
|
page compressed pages, payload
|
||||||
|
@ -167,16 +167,6 @@ void
|
|||||||
buf_flush_wait_flushed(
|
buf_flush_wait_flushed(
|
||||||
lsn_t new_oldest);
|
lsn_t new_oldest);
|
||||||
|
|
||||||
/******************************************************************//**
|
|
||||||
Waits until a flush batch of the given type ends. This is called by
|
|
||||||
a thread that only wants to wait for a flush to end but doesn't do
|
|
||||||
any flushing itself. */
|
|
||||||
void
|
|
||||||
buf_flush_wait_batch_end_wait_only(
|
|
||||||
/*===============================*/
|
|
||||||
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
|
|
||||||
buf_flush_t type); /*!< in: BUF_FLUSH_LRU
|
|
||||||
or BUF_FLUSH_LIST */
|
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
This function should be called at a mini-transaction commit, if a page was
|
This function should be called at a mini-transaction commit, if a page was
|
||||||
modified in it. Puts the block to the list of modified blocks, if it not
|
modified in it. Puts the block to the list of modified blocks, if it not
|
||||||
|
@ -373,7 +373,6 @@ Decrypt a page
|
|||||||
@param[in] space Tablespace
|
@param[in] space Tablespace
|
||||||
@param[in] tmp_frame Temporary buffer used for decrypting
|
@param[in] tmp_frame Temporary buffer used for decrypting
|
||||||
@param[in,out] src_frame Page to decrypt
|
@param[in,out] src_frame Page to decrypt
|
||||||
@param[out] decrypted true if page was decrypted
|
|
||||||
@return decrypted page, or original not encrypted page if decryption is
|
@return decrypted page, or original not encrypted page if decryption is
|
||||||
not needed.*/
|
not needed.*/
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
@ -381,8 +380,7 @@ byte*
|
|||||||
fil_space_decrypt(
|
fil_space_decrypt(
|
||||||
const fil_space_t* space,
|
const fil_space_t* space,
|
||||||
byte* tmp_frame,
|
byte* tmp_frame,
|
||||||
byte* src_frame,
|
byte* src_frame)
|
||||||
bool* decrypted)
|
|
||||||
MY_ATTRIBUTE((warn_unused_result));
|
MY_ATTRIBUTE((warn_unused_result));
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
|
@ -1310,15 +1310,12 @@ ibool
|
|||||||
page_simple_validate_new(
|
page_simple_validate_new(
|
||||||
/*=====================*/
|
/*=====================*/
|
||||||
const page_t* page); /*!< in: index page in ROW_FORMAT!=REDUNDANT */
|
const page_t* page); /*!< in: index page in ROW_FORMAT!=REDUNDANT */
|
||||||
/***************************************************************//**
|
/** Check the consistency of an index page.
|
||||||
This function checks the consistency of an index page.
|
@param[in] page index page
|
||||||
@return TRUE if ok */
|
@param[in] index B-tree or R-tree index
|
||||||
ibool
|
@return whether the page is valid */
|
||||||
page_validate(
|
bool page_validate(const page_t* page, const dict_index_t* index)
|
||||||
/*==========*/
|
MY_ATTRIBUTE((nonnull));
|
||||||
const page_t* page, /*!< in: index page */
|
|
||||||
dict_index_t* index); /*!< in: data dictionary index containing
|
|
||||||
the page record type definition */
|
|
||||||
/***************************************************************//**
|
/***************************************************************//**
|
||||||
Looks in the page record list for a record with the given heap number.
|
Looks in the page record list for a record with the given heap number.
|
||||||
@return record, NULL if not found */
|
@return record, NULL if not found */
|
||||||
|
@ -659,6 +659,10 @@ page_rec_get_next_low(
|
|||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ut_ad(page_rec_is_infimum(rec)
|
||||||
|
|| !(rec_get_info_bits(page + offs, comp)
|
||||||
|
& REC_INFO_MIN_REC_FLAG));
|
||||||
|
|
||||||
return(page + offs);
|
return(page + offs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2425,10 +2425,6 @@ page_cur_delete_rec(
|
|||||||
if (cur_n_owned <= PAGE_DIR_SLOT_MIN_N_OWNED) {
|
if (cur_n_owned <= PAGE_DIR_SLOT_MIN_N_OWNED) {
|
||||||
page_dir_balance_slot(page, page_zip, cur_slot_no);
|
page_dir_balance_slot(page, page_zip, cur_slot_no);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UNIV_ZIP_DEBUG
|
|
||||||
ut_a(!page_zip || page_zip_validate(page_zip, page, index));
|
|
||||||
#endif /* UNIV_ZIP_DEBUG */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UNIV_COMPILE_TEST_FUNCS
|
#ifdef UNIV_COMPILE_TEST_FUNCS
|
||||||
|
@ -2374,19 +2374,16 @@ func_exit:
|
|||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************//**
|
/** Check the consistency of an index page.
|
||||||
This function checks the consistency of an index page.
|
@param[in] page index page
|
||||||
@return TRUE if ok */
|
@param[in] index B-tree or R-tree index
|
||||||
ibool
|
@return whether the page is valid */
|
||||||
page_validate(
|
bool page_validate(const page_t* page, const dict_index_t* index)
|
||||||
/*==========*/
|
|
||||||
const page_t* page, /*!< in: index page */
|
|
||||||
dict_index_t* index) /*!< in: data dictionary index containing
|
|
||||||
the page record type definition */
|
|
||||||
{
|
{
|
||||||
const page_dir_slot_t* slot;
|
const page_dir_slot_t* slot;
|
||||||
const rec_t* rec;
|
const rec_t* rec;
|
||||||
const rec_t* old_rec = NULL;
|
const rec_t* old_rec = NULL;
|
||||||
|
const rec_t* first_rec = NULL;
|
||||||
ulint offs;
|
ulint offs;
|
||||||
ulint n_slots;
|
ulint n_slots;
|
||||||
ibool ret = TRUE;
|
ibool ret = TRUE;
|
||||||
@ -2510,6 +2507,43 @@ wrong_page_type:
|
|||||||
goto next_rec;
|
goto next_rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rec == first_rec) {
|
||||||
|
if ((rec_get_info_bits(rec, page_is_comp(page))
|
||||||
|
& REC_INFO_MIN_REC_FLAG)) {
|
||||||
|
if (page_has_prev(page)) {
|
||||||
|
ib::error() << "REC_INFO_MIN_REC_FLAG "
|
||||||
|
"is set in on non-left page";
|
||||||
|
ret = false;
|
||||||
|
} else if (!page_is_leaf(page)) {
|
||||||
|
/* leftmost node pointer page */
|
||||||
|
} else if (!index->is_instant()) {
|
||||||
|
ib::error() << "REC_INFO_MIN_REC_FLAG "
|
||||||
|
"is set in a leaf-page record";
|
||||||
|
ret = false;
|
||||||
|
} else if (rec_get_deleted_flag(
|
||||||
|
rec, page_is_comp(page))) {
|
||||||
|
/* If this were a 10.4 metadata
|
||||||
|
record for index->table->instant
|
||||||
|
we should not get here in 10.3, because
|
||||||
|
the metadata record should not have
|
||||||
|
been recognized by
|
||||||
|
btr_cur_instant_init_low(). */
|
||||||
|
ib::error() << "Metadata record "
|
||||||
|
"is delete-marked";
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
} else if (!page_has_prev(page)
|
||||||
|
&& index->is_instant()) {
|
||||||
|
ib::error() << "Metadata record is missing";
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
} else if (rec_get_info_bits(rec, page_is_comp(page))
|
||||||
|
& REC_INFO_MIN_REC_FLAG) {
|
||||||
|
ib::error() << "REC_INFO_MIN_REC_FLAG record is not "
|
||||||
|
"first in page";
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check that the records are in the ascending order */
|
/* Check that the records are in the ascending order */
|
||||||
if (count >= PAGE_HEAP_NO_USER_LOW
|
if (count >= PAGE_HEAP_NO_USER_LOW
|
||||||
&& !page_rec_is_supremum(rec)) {
|
&& !page_rec_is_supremum(rec)) {
|
||||||
@ -2616,6 +2650,11 @@ next_rec:
|
|||||||
old_rec = rec;
|
old_rec = rec;
|
||||||
rec = page_rec_get_next_const(rec);
|
rec = page_rec_get_next_const(rec);
|
||||||
|
|
||||||
|
if (page_rec_is_infimum(old_rec)
|
||||||
|
&& page_rec_is_user_rec(rec)) {
|
||||||
|
first_rec = rec;
|
||||||
|
}
|
||||||
|
|
||||||
/* set old_offsets to offsets; recycle offsets */
|
/* set old_offsets to offsets; recycle offsets */
|
||||||
{
|
{
|
||||||
ulint* offs = old_offsets;
|
ulint* offs = old_offsets;
|
||||||
|
@ -4369,10 +4369,6 @@ page_zip_clear_rec(
|
|||||||
} else {
|
} else {
|
||||||
ut_ad(!rec_offs_any_extern(offsets));
|
ut_ad(!rec_offs_any_extern(offsets));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UNIV_ZIP_DEBUG
|
|
||||||
ut_a(page_zip_validate(page_zip, page, index));
|
|
||||||
#endif /* UNIV_ZIP_DEBUG */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************//**
|
/**********************************************************************//**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user