ALTER TABLE and replication should convert old row_end timestamps to new timestamp range

MDEV-32188 make TIMESTAMP use whole 32-bit unsigned range

- Added --update-history option to mariadb-dump to change 2038
  row_end timestamp to 2106.
- Updated ALTER TABLE ... to convert old row_end timestamps to
  2106 timestamp for tables created before MariaDB 11.4.0.
- Fixed bug in CHECK TABLE where we wrongly suggested to USE REPAIR
  TABLE when ALTER TABLE...FORCE is needed.
- mariadb-check printed table names that where used with REPAIR TABLE but
  did not print table names used with ALTER TABLE or with name repair.
  Fixed by always printing a table that is fixed if --silent is not
  used.
- Added TABLE::vers_fix_old_timestamp() that will change max-timestamp
  for versioned tables when replication from a pre-11.4.0 server.

A few test cases changed. This is caused by:
- CHECK TABLE now prints 'Please do ALTER TABLE... instead of
  'Please do REPAIR TABLE' when there is a problem with the information
  in the .frm file (for example a very old frm file).
- mariadb-check now prints repaired table names.
- mariadb-check also now prints nicer error message in case ALTER TABLE
  is needed to repair a table.
This commit is contained in:
Monty 2023-12-19 17:51:23 +02:00 committed by Sergei Golubchik
parent c4cad8d50c
commit 24c57165d5
37 changed files with 438 additions and 110 deletions

View File

@ -72,6 +72,7 @@ enum options_client
OPT_IGNORE_SERVER_IDS,
OPT_DO_SERVER_IDS,
OPT_SSL_FP, OPT_SSL_FPLIST,
OPT_UPDATE_HISTORY,
OPT_MAX_CLIENT_OPTION /* should be always the last */
};

View File

@ -801,7 +801,7 @@ static int fix_table_storage_name(const char *name)
name, name + 9);
rc= run_query(qbuf, 1);
if (verbose)
if (!opt_silent)
printf("%-50s %s\n", name, rc ? "FAILED" : "OK");
DBUG_RETURN(rc);
}
@ -817,7 +817,7 @@ static int fix_database_storage_name(const char *name)
my_snprintf(qbuf, sizeof(qbuf), "ALTER DATABASE %`s UPGRADE DATA DIRECTORY "
"NAME", name);
rc= run_query(qbuf, 1);
if (verbose)
if (!opt_silent)
printf("%-50s %s\n", name, rc ? "FAILED" : "OK");
DBUG_RETURN(rc);
}
@ -840,8 +840,8 @@ static int rebuild_table(char *name)
fprintf(stderr, "Error: %s\n", mysql_error(sock));
rc= 1;
}
if (verbose)
printf("%-50s %s\n", name, rc ? "FAILED" : "FIXED");
if (!opt_silent)
printf("%-50s %s\n", name, rc ? "FAILED" : "OK");
my_free(query);
DBUG_RETURN(rc);
}
@ -1035,7 +1035,6 @@ static void __attribute__((noinline)) print_result()
MYSQL_RES *res;
MYSQL_ROW row;
char prev[(NAME_LEN+9)*3+2];
char prev_alter[MAX_ALTER_STR_SIZE];
size_t length_of_db= strlen(sock->db);
my_bool found_error=0, table_rebuild=0;
DYNAMIC_ARRAY *array4repair= &tables4repair;
@ -1044,7 +1043,6 @@ static void __attribute__((noinline)) print_result()
res = mysql_use_result(sock);
prev[0] = '\0';
prev_alter[0]= 0;
while ((row = mysql_fetch_row(res)))
{
int changed = strcmp(prev, row[0]);
@ -1061,19 +1059,13 @@ static void __attribute__((noinline)) print_result()
strcmp(row[3],"OK"))
{
if (table_rebuild)
{
if (prev_alter[0])
insert_dynamic(&alter_table_cmds, (uchar*) prev_alter);
else
insert_table_name(&tables4rebuild, prev, length_of_db);
}
insert_table_name(&tables4rebuild, prev, length_of_db);
else
insert_table_name(array4repair, prev, length_of_db);
}
array4repair= &tables4repair;
found_error=0;
table_rebuild=0;
prev_alter[0]= 0;
if (opt_silent)
continue;
}
@ -1083,20 +1075,28 @@ static void __attribute__((noinline)) print_result()
{
/*
If the error message includes REPAIR TABLE, we assume it means
we have to run upgrade on it. In this case we write a nicer message
we have to run REPAIR on it. In this case we write a nicer message
than "Please do "REPAIR TABLE""...
If the message inclused ALTER TABLE then there is something wrong
with the table definition and we have to run ALTER TABLE to fix it.
Write also a nice error message for this csae.
*/
if (!strcmp(row[2],"error") && strstr(row[3],"REPAIR "))
{
printf("%-50s %s", row[0], "Needs upgrade");
printf("%-50s %s", row[0], "Needs upgrade with REPAIR");
array4repair= strstr(row[3], "VIEW") ? &views4repair : &tables4repair;
}
else if (!strcmp(row[2],"error") && strstr(row[3],"ALTER TABLE"))
{
printf("%-50s %s", row[0], "Needs upgrade with ALTER TABLE FORCE");
array4repair= &tables4rebuild;
}
else
printf("%s\n%-9s: %s", row[0], row[2], row[3]);
if (opt_auto_repair && strcmp(row[2],"note"))
if (strcmp(row[2],"note"))
{
found_error=1;
if (opt_auto_repair && strstr(row[3], "ALTER TABLE") != NULL)
if (strstr(row[3], "ALTER TABLE"))
table_rebuild=1;
}
}
@ -1109,12 +1109,7 @@ static void __attribute__((noinline)) print_result()
if (found_error && opt_auto_repair && what_to_do != DO_REPAIR)
{
if (table_rebuild)
{
if (prev_alter[0])
insert_dynamic(&alter_table_cmds, prev_alter);
else
insert_table_name(&tables4rebuild, prev, length_of_db);
}
insert_table_name(&tables4rebuild, prev, length_of_db);
else
insert_table_name(array4repair, prev, length_of_db);
}

View File

@ -129,7 +129,7 @@ static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0, opt_no_data_m
opt_include_master_host_port= 0,
opt_events= 0, opt_comments_used= 0,
opt_alltspcs=0, opt_notspcs= 0, opt_logging,
opt_header=0,
opt_header=0, opt_update_history= 0,
opt_drop_trigger= 0, opt_dump_history= 0;
#define OPT_SYSTEM_ALL 1
#define OPT_SYSTEM_USERS 2
@ -151,7 +151,8 @@ static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0,
static ulong opt_max_allowed_packet, opt_net_buffer_length;
static double opt_max_statement_time= 0.0;
static MYSQL *mysql=0;
static DYNAMIC_STRING insert_pat, select_field_names, select_field_names_for_header;
static DYNAMIC_STRING insert_pat, select_field_names,
select_field_names_for_header, insert_field_names;
static char *opt_password=0,*current_user=0,
*current_host=0,*path=0,*fields_terminated=0,
*lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=0,
@ -364,8 +365,15 @@ static struct my_option my_long_options[] =
{"dump-date", 0, "Put a dump date to the end of the output.",
&opt_dump_date, &opt_dump_date, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
{"dump-history", 'H', "Dump system-versioned tables with history (only for "
"timestamp based versioning)", &opt_dump_history,
&opt_dump_history, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
"timestamp based versioning). Use also --update-history if "
"upgrading to MariaDB 11.5 or newer from a version before 11.5",
&opt_dump_history, &opt_dump_history, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"update-history", OPT_UPDATE_HISTORY,
"Update row_end history timestamp to support dates up to year 2106. "
"This option will also enable tz-utc. "
"Should be used when upgrading to MariaDB 11.5 or above.",
&opt_update_history, &opt_update_history,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"dump-slave", OPT_MYSQLDUMP_SLAVE_DATA,
"This causes the binary log position and filename of the master to be "
"appended to the dumped data output. Setting the value to 1, will print"
@ -1345,23 +1353,31 @@ static int get_options(int *argc, char ***argv)
fprintf(stderr, "%s: --xml can't be used with --tab or --dir.\n", my_progname_short);
return(EX_USAGE);
}
if (opt_xml && opt_dump_history)
if (opt_dump_history)
{
fprintf(stderr, "%s: --xml can't be used with --dump-history.\n",
my_progname_short);
return(EX_USAGE);
}
if (opt_replace_into && opt_dump_history)
{
fprintf(stderr, "%s: --dump-history can't be used with --replace.\n",
my_progname_short);
return(EX_USAGE);
}
if (opt_asof_timestamp && opt_dump_history)
{
fprintf(stderr, "%s: --dump-history can't be used with --as-of.\n",
my_progname_short);
return(EX_USAGE);
if (opt_update_history)
{
/* dump history requires timezone "+00:00" */
opt_tz_utc= 1;
}
if (opt_xml)
{
fprintf(stderr, "%s: --xml can't be used with --dump-history.\n",
my_progname_short);
return(EX_USAGE);
}
if (opt_replace_into)
{
fprintf(stderr, "%s: --dump-history can't be used with --replace.\n",
my_progname_short);
return(EX_USAGE);
}
if (opt_asof_timestamp)
{
fprintf(stderr, "%s: --dump-history can't be used with --as-of.\n",
my_progname_short);
return(EX_USAGE);
}
}
if (opt_asof_timestamp && strchr(opt_asof_timestamp, '\''))
{
@ -1997,6 +2013,7 @@ static void free_resources()
dynstr_free(&insert_pat);
dynstr_free(&select_field_names);
dynstr_free(&select_field_names_for_header);
dynstr_free(&insert_field_names);
if (defaults_argv)
free_defaults(defaults_argv);
mysql_library_end();
@ -3122,12 +3139,13 @@ static uint get_table_structure(const char *table, const char *db, char *table_t
my_ulonglong num_fields;
char *result_table, *opt_quoted_table;
const char *insert_option;
char name_buff[NAME_LEN+3],table_buff[NAME_LEN*2+3];
char name_buff[NAME_LEN*2+3],table_buff[NAME_LEN*2+3];
char table_buff2[NAME_LEN*2+3], query_buff[QUERY_LENGTH];
char temp_buff[NAME_LEN*2 + 3], temp_buff2[NAME_LEN*2 + 3];
char *last_name;
FILE *sql_file= md_result_file;
size_t len;
my_bool is_log_table;
my_bool is_log_table, dummy_versioned;
MYSQL_RES *result;
MYSQL_ROW row;
const char *s3_engine_ptr;
@ -3166,12 +3184,14 @@ static uint get_table_structure(const char *table, const char *db, char *table_t
{
select_field_names_inited= 1;
init_dynamic_string_checked(&select_field_names, "", 1024, 1024);
init_dynamic_string_checked(&insert_field_names, "", 1024, 1024);
if (opt_header)
init_dynamic_string_checked(&select_field_names_for_header, "", 1024, 1024);
}
else
{
dynstr_set_checked(&select_field_names, "");
dynstr_set_checked(&insert_field_names, "");
if (opt_header)
dynstr_set_checked(&select_field_names_for_header, "");
}
@ -3184,7 +3204,7 @@ static uint get_table_structure(const char *table, const char *db, char *table_t
if (versioned)
{
if (!opt_asof_timestamp && !opt_dump_history)
versioned= NULL;
*versioned= 0;
else
{
my_snprintf(query_buff, sizeof(query_buff), "select 1 from"
@ -3200,6 +3220,11 @@ static uint get_table_structure(const char *table, const char *db, char *table_t
*versioned= 0;
}
}
else
{
versioned= &dummy_versioned;
dummy_versioned= 0;
}
len= my_snprintf(query_buff, sizeof(query_buff),
"SET SQL_QUOTE_SHOW_CREATE=%d", opt_quoted || opt_keywords);
@ -3215,7 +3240,7 @@ static uint get_table_structure(const char *table, const char *db, char *table_t
if (!opt_xml && !mysql_query_with_error_report(mysql, 0, query_buff))
{
int vers_hidden= opt_dump_history && versioned && *versioned;
int vers_hidden= opt_dump_history && *versioned;
/* using SHOW CREATE statement */
if (!opt_no_create_info)
{
@ -3442,12 +3467,28 @@ static uint get_table_structure(const char *table, const char *db, char *table_t
if (init)
{
dynstr_append_checked(&select_field_names, ", ");
dynstr_append_checked(&insert_field_names, ", ");
if (opt_header)
dynstr_append_checked(&select_field_names_for_header, ", ");
}
init=1;
dynstr_append_checked(&select_field_names,
quote_name(row[0], name_buff, 0));
last_name= quote_name(row[0], name_buff, 0);
if (opt_dump_history && *versioned && opt_update_history &&
row[2] && strcmp(row[2], "ROW END") == 0)
{
dynstr_append_checked(&select_field_names, "if(");
dynstr_append_checked(&select_field_names, last_name);
dynstr_append_checked(&select_field_names,
"= \"2038-01-19 03:14:07.999999\","
"\"2106-02-07 06:28:15.999999\", ");
dynstr_append_checked(&select_field_names, last_name);
dynstr_append_checked(&select_field_names, ") as ");
dynstr_append_checked(&select_field_names, last_name);
}
else
dynstr_append_checked(&select_field_names, last_name);
dynstr_append_checked(&insert_field_names, last_name);
if (opt_header)
dynstr_append_checked(&select_field_names_for_header,
quote_for_equal(row[0], name_buff));
@ -3456,7 +3497,14 @@ static uint get_table_structure(const char *table, const char *db, char *table_t
if (vers_hidden)
{
complete_insert= 1;
dynstr_append_checked(&select_field_names, ", row_start, row_end");
dynstr_append_checked(&select_field_names, ", row_start,");
dynstr_append_checked(&select_field_names,
opt_update_history ?
"if(row_end = \"2038-01-19 03:14:07.999999\","
"\"2106-02-07 06:28:15.999999\", row_end) as "
"row_end" :
"row_end");
dynstr_append_checked(&insert_field_names, ", row_start, row_end");
}
/*
@ -3488,7 +3536,7 @@ static uint get_table_structure(const char *table, const char *db, char *table_t
}
if (complete_insert)
dynstr_append_checked(&insert_pat, select_field_names.str);
dynstr_append_checked(&insert_pat, insert_field_names.str);
num_fields= mysql_num_rows(result) + (vers_hidden ? 2 : 0);
mysql_free_result(result);
}
@ -3751,6 +3799,7 @@ continue_xml:
DBUG_RETURN((uint) num_fields);
} /* get_table_structure */
static void dump_trigger_old(FILE *sql_file, MYSQL_RES *show_triggers_rs,
MYSQL_ROW *show_trigger_row,
const char *table_name)

View File

@ -6,7 +6,7 @@ call mtr.add_suppression("Table rebuild required");
# Copying maria050313_utf8_croatian_ci.* to MYSQLD_DATADIR
CHECK TABLE maria050313_utf8_croatian_ci FOR UPGRADE;
Table Op Msg_type Msg_text
test.maria050313_utf8_croatian_ci check error Upgrade required. Please do "REPAIR TABLE `maria050313_utf8_croatian_ci`" or dump/reload to fix it!
test.maria050313_utf8_croatian_ci check error Table rebuild required. Please do "ALTER TABLE `maria050313_utf8_croatian_ci` FORCE" or dump/reload to fix it!
SHOW CREATE TABLE maria050313_utf8_croatian_ci;
ERROR HY000: Table rebuild required. Please do "ALTER TABLE `test.maria050313_utf8_croatian_ci` FORCE" or dump/reload to fix it!
REPAIR TABLE maria050313_utf8_croatian_ci;
@ -43,7 +43,7 @@ DROP TABLE maria050313_utf8_croatian_ci;
# Copying maria050313_ucs2_croatian_ci.* to MYSQLD_DATADIR
CHECK TABLE maria050313_ucs2_croatian_ci_def FOR UPGRADE;
Table Op Msg_type Msg_text
test.maria050313_ucs2_croatian_ci_def check error Upgrade required. Please do "REPAIR TABLE `maria050313_ucs2_croatian_ci_def`" or dump/reload to fix it!
test.maria050313_ucs2_croatian_ci_def check error Table rebuild required. Please do "ALTER TABLE `maria050313_ucs2_croatian_ci_def` FORCE" or dump/reload to fix it!
SELECT count(*) FROM maria050313_ucs2_croatian_ci_def;
ERROR HY000: Table rebuild required. Please do "ALTER TABLE `test.maria050313_ucs2_croatian_ci_def` FORCE" or dump/reload to fix it!
REPAIR TABLE maria050313_ucs2_croatian_ci_def;
@ -58,7 +58,7 @@ DROP TABLE maria050313_ucs2_croatian_ci_def;
# Copying maria050313_ucs2_croatian_ci.* to MYSQLD_DATADIR
CHECK TABLE maria050313_ucs2_croatian_ci_def;
Table Op Msg_type Msg_text
test.maria050313_ucs2_croatian_ci_def check error Upgrade required. Please do "REPAIR TABLE `maria050313_ucs2_croatian_ci_def`" or dump/reload to fix it!
test.maria050313_ucs2_croatian_ci_def check error Table rebuild required. Please do "ALTER TABLE `maria050313_ucs2_croatian_ci_def` FORCE" or dump/reload to fix it!
REPAIR TABLE maria050313_ucs2_croatian_ci_def;
Table Op Msg_type Msg_text
test.maria050313_ucs2_croatian_ci_def repair status OK
@ -84,7 +84,7 @@ DROP TABLE maria050313_ucs2_croatian_ci_def;
# Copying maria050533_xxx_croatian_ci.* to MYSQLD_DATADIR
CHECK TABLE maria050533_xxx_croatian_ci FOR UPGRADE;
Table Op Msg_type Msg_text
test.maria050533_xxx_croatian_ci check error Upgrade required. Please do "REPAIR TABLE `maria050533_xxx_croatian_ci`" or dump/reload to fix it!
test.maria050533_xxx_croatian_ci check error Table rebuild required. Please do "ALTER TABLE `maria050533_xxx_croatian_ci` FORCE" or dump/reload to fix it!
REPAIR TABLE maria050533_xxx_croatian_ci;
Table Op Msg_type Msg_text
test.maria050533_xxx_croatian_ci repair status OK
@ -141,7 +141,7 @@ DROP TABLE maria050533_xxx_croatian_ci;
# Copying maria100004_xxx_croatian_ci.* to MYSQLD_DATADIR
CHECK TABLE maria100004_xxx_croatian_ci FOR UPGRADE;
Table Op Msg_type Msg_text
test.maria100004_xxx_croatian_ci check error Upgrade required. Please do "REPAIR TABLE `maria100004_xxx_croatian_ci`" or dump/reload to fix it!
test.maria100004_xxx_croatian_ci check error Table rebuild required. Please do "ALTER TABLE `maria100004_xxx_croatian_ci` FORCE" or dump/reload to fix it!
SELECT count(*) FROM maria100004_xxx_croatian_ci;
ERROR HY000: Table rebuild required. Please do "ALTER TABLE `test.maria100004_xxx_croatian_ci` FORCE" or dump/reload to fix it!
REPAIR TABLE maria100004_xxx_croatian_ci;
@ -374,17 +374,17 @@ performance_schema
sys
sys.sys_config OK
test
test.maria050313_ucs2_croatian_ci_def Needs upgrade
test.maria050313_utf8_croatian_ci Needs upgrade
test.maria050533_xxx_croatian_ci Needs upgrade
test.maria100004_xxx_croatian_ci Needs upgrade
test.maria050313_ucs2_croatian_ci_def Needs upgrade with ALTER TABLE FORCE
test.maria050313_utf8_croatian_ci Needs upgrade with ALTER TABLE FORCE
test.maria050533_xxx_croatian_ci Needs upgrade with ALTER TABLE FORCE
test.maria100004_xxx_croatian_ci Needs upgrade with ALTER TABLE FORCE
test.mysql050614_xxx_croatian_ci OK
Repairing tables
test.maria050313_ucs2_croatian_ci_def OK
test.maria050313_utf8_croatian_ci OK
test.maria050533_xxx_croatian_ci OK
test.maria100004_xxx_croatian_ci OK
`test`.`maria050313_ucs2_croatian_ci_def` OK
`test`.`maria050313_utf8_croatian_ci` OK
`test`.`maria050533_xxx_croatian_ci` OK
`test`.`maria100004_xxx_croatian_ci` OK
Phase 7/8: uninstalling plugins
Phase 8/8: Running 'FLUSH PRIVILEGES'
OK
@ -622,7 +622,7 @@ SELECT * FROM t1 IGNORE KEY(a);
ERROR HY000: Table rebuild required. Please do "ALTER TABLE `test.t1` FORCE" or dump/reload to fix it!
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check error Upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it!
test.t1 check error Table rebuild required. Please do "ALTER TABLE `t1` FORCE" or dump/reload to fix it!
REPAIR TABLE t1;
Table Op Msg_type Msg_text
test.t1 repair status OK

View File

@ -10611,7 +10611,7 @@ a 1
ä 2
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check error Upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it!
test.t1 check error Table rebuild required. Please do "ALTER TABLE `t1` FORCE" or dump/reload to fix it!
INSERT INTO t1 VALUES ('A');
ERROR 23000: Duplicate entry 'A' for key 'a'
INSERT INTO t1 VALUES ('Ä');
@ -10624,7 +10624,7 @@ a 1
Ấ 3
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check error Upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it!
test.t1 check error Table rebuild required. Please do "ALTER TABLE `t1` FORCE" or dump/reload to fix it!
ALTER TABLE t1 FORCE;
ERROR 23000: Duplicate entry 'ä' for key 'a'
DELETE FROM t1 WHERE OCTET_LENGTH(a)>1;

View File

@ -170,12 +170,12 @@ performance_schema
sys
sys.sys_config OK
test
test.mysql_json_test Needs upgrade
test.mysql_json_test_big Needs upgrade
test.mysql_json_test Needs upgrade with ALTER TABLE FORCE
test.mysql_json_test_big Needs upgrade with ALTER TABLE FORCE
Repairing tables
test.mysql_json_test OK
test.mysql_json_test_big OK
`test`.`mysql_json_test` OK
`test`.`mysql_json_test_big` OK
Phase 7/8: uninstalling plugins
uninstalling plugin for 'type_mysql_json' data type
Phase 8/8: Running 'FLUSH PRIVILEGES'

View File

@ -157,14 +157,14 @@ performance_schema
sys
sys.sys_config OK
test
test.mysql_json_test Needs upgrade
test.mysql_json_test_big Needs upgrade
test.tempty Needs upgrade
test.mysql_json_test Needs upgrade with ALTER TABLE FORCE
test.mysql_json_test_big Needs upgrade with ALTER TABLE FORCE
test.tempty Needs upgrade with ALTER TABLE FORCE
Repairing tables
test.mysql_json_test OK
test.mysql_json_test_big OK
test.tempty OK
`test`.`mysql_json_test` OK
`test`.`mysql_json_test_big` OK
`test`.`tempty` OK
Phase 7/8: uninstalling plugins
Phase 8/8: Running 'FLUSH PRIVILEGES'
OK

View File

@ -170,12 +170,12 @@ performance_schema
sys
sys.sys_config OK
test
test.mysql_json_test Needs upgrade
test.mysql_json_test_big Needs upgrade
test.mysql_json_test Needs upgrade with ALTER TABLE FORCE
test.mysql_json_test_big Needs upgrade with ALTER TABLE FORCE
Repairing tables
test.mysql_json_test OK
test.mysql_json_test_big OK
`test`.`mysql_json_test` OK
`test`.`mysql_json_test_big` OK
Phase 7/8: uninstalling plugins
Phase 8/8: Running 'FLUSH PRIVILEGES'
OK

View File

@ -210,6 +210,7 @@ Tables_in_test
t1
v1
test.t1 OK
#mysql50#v-1 OK
show tables;
Tables_in_test
t1
@ -226,6 +227,7 @@ set @@character_set_client=@save_character_set_client;
set @@character_set_results=@save_character_set_client;
set @@collation_connection=@save_collation_connection;
mysqlcheck --fix-table-names --databases test
#mysql50#@ OK
SET NAMES utf8;
SHOW TABLES;
Tables_in_test
@ -258,6 +260,8 @@ TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATA
def #mysql50#a@b tr1 INSERT def #mysql50#a@b #mysql50#c@d 1 NULL SET NEW.a = 10 * NEW.a ROW BEFORE NULL NULL OLD NEW NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci
def #mysql50#a@b tr2 INSERT def #mysql50#a@b t1 1 NULL SET NEW.a = 100 * NEW.a ROW BEFORE NULL NULL OLD NEW NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci
mysqlcheck --fix-db-names --fix-table-names --all-databases
#mysql50#a@b OK
#mysql50#c@d OK
USE `a@b`;
SELECT * FROM INFORMATION_SCHEMA.TRIGGERS
WHERE TRIGGER_SCHEMA="a@b" ORDER BY trigger_name;
@ -281,11 +285,13 @@ USE test;
#
drop table if exists `#mysql50#t1-1`;
create table `#mysql50#t1-1` (a int) engine=myisam;
#mysql50#t1-1 OK
show tables like 't1-1';
Tables_in_test (t1-1)
t1-1
drop table `t1-1`;
create table `#mysql50#t1-1` (a int) engine=myisam;
#mysql50#t1-1 OK
show tables like 't1-1';
Tables_in_test (t1-1)
t1-1
@ -328,27 +334,27 @@ CHECK TABLE bug47205 FOR UPGRADE;
Table Op Msg_type Msg_text
test.bug47205 check error Table rebuild required. Please do "ALTER TABLE `bug47205` FORCE" or dump/reload to fix it!
# Running mysqlcheck to check and upgrade
test.bug47205
error : Table rebuild required. Please do "ALTER TABLE `bug47205` FORCE" or dump/reload to fix it!
test.bug47205 Needs upgrade with ALTER TABLE FORCE
Repairing tables
`test`.`bug47205` OK
# Table should now be ok
CHECK TABLE bug47205 FOR UPGRADE;
Table Op Msg_type Msg_text
test.bug47205 check status OK
DROP TABLE bug47205;
#
# Test 3: MyISAM - REPAIR supported
# Test 3: MyISAM - ALTER TABLE supported
# Use an old FRM that will require upgrade
# Should indicate that REPAIR TABLE is needed
# Should indicate that ALTER TABLE is needed
CHECK TABLE bug47205 FOR UPGRADE;
Table Op Msg_type Msg_text
test.bug47205 check error Upgrade required. Please do "REPAIR TABLE `bug47205`" or dump/reload to fix it!
test.bug47205 check error Table rebuild required. Please do "ALTER TABLE `bug47205` FORCE" or dump/reload to fix it!
# Running mysqlcheck to check and upgrade
test.bug47205 Needs upgrade
test.bug47205 Needs upgrade with ALTER TABLE FORCE
Repairing tables
test.bug47205 OK
`test`.`bug47205` OK
# Table should now be ok
CHECK TABLE bug47205 FOR UPGRADE;
Table Op Msg_type Msg_text
@ -370,12 +376,12 @@ create table `t.2`(a varchar(20) primary key) default character set utf8 collate
flush table `t.2`;
mysqlcheck --check-upgrade --auto-repair test
test.t.1 OK
test.t.2
error : Table rebuild required. Please do "ALTER TABLE `t.2` FORCE" or dump/reload to fix it!
test.t.3 Needs upgrade
test.t.2 Needs upgrade with ALTER TABLE FORCE
test.t.3 Needs upgrade with ALTER TABLE FORCE
Repairing tables
test.t.3 OK
`test`.`t.2` OK
`test`.`t.3` OK
check table `t.1`, `t.2`, `t.3`;
Table Op Msg_type Msg_text
test.t.1 check status OK
@ -411,13 +417,14 @@ drop view v1;
create table t1(a int);
mysqlcheck --process-views --check-upgrade --auto-repair test
test.t1 OK
test.v1 Needs upgrade
test.v1 Needs upgrade with REPAIR
Repairing views
test.v1 OK
drop view v1;
drop table t1;
create table `#mysql50#t1``1` (a int) engine=myisam;
#mysql50#t1`1 OK
show tables;
Tables_in_test
t1`1

View File

@ -305,17 +305,18 @@ CHECK TABLE bug47205 FOR UPGRADE;
DROP TABLE bug47205;
--echo #
--echo # Test 3: MyISAM - REPAIR supported
--echo # Test 3: MyISAM - ALTER TABLE supported
--echo # Use an old FRM that will require upgrade
--copy_file std_data/bug36055.frm $MYSQLD_DATADIR/test/bug47205.frm
--copy_file std_data/bug36055.MYD $MYSQLD_DATADIR/test/bug47205.MYD
--copy_file std_data/bug36055.MYI $MYSQLD_DATADIR/test/bug47205.MYI
--echo # Should indicate that REPAIR TABLE is needed
--echo # Should indicate that ALTER TABLE is needed
CHECK TABLE bug47205 FOR UPGRADE;
--echo # Running mysqlcheck to check and upgrade
--exec $MYSQL_CHECK --check-upgrade --auto-repair test
--echo # Table should now be ok

View File

@ -122,7 +122,7 @@ SELECT * FROM t1;
id
1
2
# Run CHECK TABLE, it should indicate table need a REPAIR TABLE
# Run CHECK TABLE, it should indicate table need a ALTER TABLE
CHECK TABLE t1 FOR UPGRADE;
Table Op Msg_type Msg_text
test.t1 check error Table rebuild required. Please do "ALTER TABLE `t1` FORCE" or dump/reload to fix it!
@ -151,6 +151,11 @@ SELECT * FROM t1;
id
1
DROP TABLE t1;
ALTER TABLE t1 FORCE;
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
# End of 5.0 tests
DROP TABLE IF EXISTS tt1;
CREATE TEMPORARY TABLE tt1 (c1 INT);

View File

@ -138,7 +138,7 @@ let $MYSQLD_DATADIR= `select @@datadir`;
SHOW TABLE STATUS LIKE 't1';
SELECT * FROM t1;
--echo # Run CHECK TABLE, it should indicate table need a REPAIR TABLE
--echo # Run CHECK TABLE, it should indicate table need a ALTER TABLE
CHECK TABLE t1 FOR UPGRADE;
--echo # REPAIR old table USE_FRM should fail
@ -155,6 +155,13 @@ SELECT * FROM t1;
DROP TABLE t1;
--copy_file std_data/bug36055.frm $MYSQLD_DATADIR/test/t1.frm
--copy_file std_data/bug36055.MYD $MYSQLD_DATADIR/test/t1.MYD
--copy_file std_data/bug36055.MYI $MYSQLD_DATADIR/test/t1.MYI
ALTER TABLE t1 FORCE;
CHECK TABLE t1;
DROP TABLE t1;
--echo # End of 5.0 tests
#

View File

@ -24,6 +24,9 @@ show tables in `#mysql50#mysqltest-1`;
Tables_in_#mysql50#mysqltest-1
#mysql50#t-1
t1
#mysql50#mysqltest-1 OK
#mysql50#t-1 OK
#mysql50#t-1 OK
show create database `mysqltest1`;
Database Create Database
mysqltest1 CREATE DATABASE `mysqltest1` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */

View File

@ -91,7 +91,7 @@ length(a) length(b)
255 3
CHECK TABLE t1 FOR UPGRADE;
Table Op Msg_type Msg_text
test.t1 check error Upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it!
test.t1 check error Table rebuild required. Please do "ALTER TABLE `t1` FORCE" or dump/reload to fix it!
REPAIR TABLE t1;
Table Op Msg_type Msg_text
test.t1 repair status OK

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,106 @@
/*!999999\- enable the sandbox mode */
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `sv_basic` (
`a` int(11) NOT NULL,
PRIMARY KEY (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!101100 SET @old_system_versioning_insert_history=@@session.system_versioning_insert_history, @@session.system_versioning_insert_history=1 */;
INSERT INTO `sv_basic` (`a`, row_start, row_end) VALUES (1,'2023-12-19 14:23:22.304434','2038-01-19 03:14:07.999999'),
(2,'2023-12-19 14:23:22.304434','2023-12-19 14:23:22.305292'),
(3,'2023-12-19 14:23:22.304434','2038-01-19 03:14:07.999999');
/*!101100 SET system_versioning_insert_history=@old_system_versioning_insert_history */;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `sv_explicit` (
`a` int(11) DEFAULT NULL,
`row_foo_start` timestamp(6) GENERATED ALWAYS AS ROW START,
`row_foo_end` timestamp(6) GENERATED ALWAYS AS ROW END,
PERIOD FOR SYSTEM_TIME (`row_foo_start`, `row_foo_end`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!101100 SET @old_system_versioning_insert_history=@@session.system_versioning_insert_history, @@session.system_versioning_insert_history=1 */;
INSERT INTO `sv_explicit` VALUES
(1,'2023-12-19 14:23:22.358302','2038-01-19 03:14:07.999999'),
(2,'2023-12-19 14:23:22.358302','2023-12-19 14:23:22.359113'),
(3,'2023-12-19 14:23:22.358302','2038-01-19 03:14:07.999999');
/*!101100 SET system_versioning_insert_history=@old_system_versioning_insert_history */;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `sv_partition` (
`a` int(11) NOT NULL,
PRIMARY KEY (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
PARTITION BY SYSTEM_TIME
(PARTITION `p_hist` HISTORY ENGINE = MyISAM,
PARTITION `p_cur` CURRENT ENGINE = MyISAM);
/*!40101 SET character_set_client = @saved_cs_client */;
/*!101100 SET @old_system_versioning_insert_history=@@session.system_versioning_insert_history, @@session.system_versioning_insert_history=1 */;
INSERT INTO `sv_partition` (`a`, row_start, row_end) VALUES (2,'2023-12-19 14:23:22.331143','2023-12-19 14:23:22.332359'),
(1,'2023-12-19 14:23:22.331143','2038-01-19 03:14:07.999999'),
(3,'2023-12-19 14:23:22.331143','2038-01-19 03:14:07.999999');
/*!101100 SET system_versioning_insert_history=@old_system_versioning_insert_history */;
/*!999999\- enable the sandbox mode */
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `sv_basic` (
`a` int(11) NOT NULL,
PRIMARY KEY (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!101100 SET @old_system_versioning_insert_history=@@session.system_versioning_insert_history, @@session.system_versioning_insert_history=1 */;
INSERT INTO `sv_basic` (`a`, row_start, row_end) VALUES (1,'2023-12-19 14:23:22.304434','2106-02-07 06:28:15.999999'),
(2,'2023-12-19 14:23:22.304434','2023-12-19 14:23:22.305292'),
(3,'2023-12-19 14:23:22.304434','2106-02-07 06:28:15.999999');
/*!101100 SET system_versioning_insert_history=@old_system_versioning_insert_history */;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `sv_explicit` (
`a` int(11) DEFAULT NULL,
`row_foo_start` timestamp(6) GENERATED ALWAYS AS ROW START,
`row_foo_end` timestamp(6) GENERATED ALWAYS AS ROW END,
PERIOD FOR SYSTEM_TIME (`row_foo_start`, `row_foo_end`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!101100 SET @old_system_versioning_insert_history=@@session.system_versioning_insert_history, @@session.system_versioning_insert_history=1 */;
INSERT INTO `sv_explicit` VALUES
(1,'2023-12-19 14:23:22.358302','2106-02-07 06:28:15.999999'),
(2,'2023-12-19 14:23:22.358302','2023-12-19 14:23:22.359113'),
(3,'2023-12-19 14:23:22.358302','2106-02-07 06:28:15.999999');
/*!101100 SET system_versioning_insert_history=@old_system_versioning_insert_history */;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `sv_partition` (
`a` int(11) NOT NULL,
PRIMARY KEY (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING
PARTITION BY SYSTEM_TIME
(PARTITION `p_hist` HISTORY ENGINE = MyISAM,
PARTITION `p_cur` CURRENT ENGINE = MyISAM);
/*!40101 SET character_set_client = @saved_cs_client */;
/*!101100 SET @old_system_versioning_insert_history=@@session.system_versioning_insert_history, @@session.system_versioning_insert_history=1 */;
INSERT INTO `sv_partition` (`a`, row_start, row_end) VALUES (2,'2023-12-19 14:23:22.331143','2023-12-19 14:23:22.332359'),
(1,'2023-12-19 14:23:22.331143','2106-02-07 06:28:15.999999'),
(3,'2023-12-19 14:23:22.331143','2106-02-07 06:28:15.999999');
/*!101100 SET system_versioning_insert_history=@old_system_versioning_insert_history */;
test.sv_basic Needs upgrade with ALTER TABLE FORCE
test.sv_explicit Needs upgrade with ALTER TABLE FORCE
test.sv_partition Needs upgrade with ALTER TABLE FORCE
set @@time_zone="+00:00";
select a,row_end from sv_basic for system_time all;
a row_end
1 2106-02-07 06:28:15.999999
2 2023-12-19 14:23:22.305292
3 2106-02-07 06:28:15.999999
select a,row_end from sv_partition for system_time all;
a row_end
1 2106-02-07 06:28:15.999999
2 2023-12-19 14:23:22.332359
3 2106-02-07 06:28:15.999999
select a,row_foo_end from sv_explicit for system_time all;
a row_foo_end
1 2106-02-07 06:28:15.999999
2 2023-12-19 14:23:22.359113
3 2106-02-07 06:28:15.999999
drop table sv_basic,sv_partition,sv_explicit;

View File

@ -0,0 +1,59 @@
--source include/not_embedded.inc
--source include/have_partition.inc
--source include/have_innodb.inc
--source include/have_64bit_timestamp.inc
# Test old row_end timestamps from MariaDB 11.3
# The original tables where created as follows in 11.3
# CREATE TABLE sv_basic (a int NOT NULL PRIMARY KEY) ENGINE=MyISAM
# WITH SYSTEM VERSIONING;
# INSERT INTO sv_basic values (1),(2),(3);
# delete from sv_basic where a=2;
# select a,row_start,row_end from sv_basic for system_time all;
#
# CREATE TABLE sv_partition (a int NOT NULL PRIMARY KEY) engine=MyISAM
# WITH SYSTEM VERSIONING
# PARTITION BY SYSTEM_TIME
# (PARTITION p_hist HISTORY, PARTITION p_cur CURRENT);
# INSERT INTO sv_partition values (1),(2),(3);
# delete from sv_partition where a=2;
# select a,row_start,row_end from sv_partition for system_time all;
#
# CREATE TABLE sv_explicit (a int,
# row_foo_start timestamp(6) as row start,
# row_foo_end timestamp(6) as row end,
# period for system_time(row_foo_start,row_foo_end))
# engine=myisam with system versioning;
# INSERT INTO sv_explicit (a) values (1),(2),(3);
# delete from sv_explicit where a=2;
# select * from sv_explicit for system_time all;
let $MARIADB_DATADIR= `select @@datadir`;
--copy_file std_data/sv_basic.MYD $MARIADB_DATADIR/test/sv_basic.MYD
--copy_file std_data/sv_basic.MYI $MARIADB_DATADIR/test/sv_basic.MYI
--copy_file std_data/sv_basic.frm $MARIADB_DATADIR/test/sv_basic.frm
--copy_file std_data/sv_explicit.MYD $MARIADB_DATADIR/test/sv_explicit.MYD
--copy_file std_data/sv_explicit.MYI $MARIADB_DATADIR/test/sv_explicit.MYI
--copy_file std_data/sv_explicit.frm $MARIADB_DATADIR/test/sv_explicit.frm
--copy_file std_data/sv_partition#P#p_cur.MYD $MARIADB_DATADIR/test/sv_partition#P#p_cur.MYD
--copy_file std_data/sv_partition#P#p_cur.MYI $MARIADB_DATADIR/test/sv_partition#P#p_cur.MYI
--copy_file std_data/sv_partition#P#p_hist.MYD $MARIADB_DATADIR/test/sv_partition#P#p_hist.MYD
--copy_file std_data/sv_partition#P#p_hist.MYI $MARIADB_DATADIR/test/sv_partition#P#p_hist.MYI
--copy_file std_data/sv_partition.frm $MARIADB_DATADIR/test/sv_partition.frm
--copy_file std_data/sv_partition.par $MARIADB_DATADIR/test/sv_partition.par
--exec $MYSQL_DUMP --compact --dump-history test
--exec $MYSQL_DUMP --compact --dump-history --update-history test
--exec $MYSQL_UPGRADE --force --silent 2>&1
--remove_file $MARIADB_DATADIR/mariadb_upgrade_info
set @@time_zone="+00:00";
select a,row_end from sv_basic for system_time all;
select a,row_end from sv_partition for system_time all;
select a,row_foo_end from sv_explicit for system_time all;
drop table sv_basic,sv_partition,sv_explicit;

View File

@ -82,6 +82,8 @@ enum enum_conv_type
CONV_TYPE_IMPOSSIBLE
};
/* Old 32 bit timestamp */
extern const uchar timestamp_old_bytes[7];
class Conv_param
{
@ -774,6 +776,7 @@ protected:
static void do_field_temporal(const Copy_field *copy, date_mode_t fuzzydate);
static void do_field_datetime(const Copy_field *copy);
static void do_field_timestamp(const Copy_field *copy);
static void do_field_versioned_timestamp(const Copy_field *copy);
static void do_field_decimal(const Copy_field *copy);
public:
static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()

View File

@ -420,10 +420,27 @@ void Field::do_field_decimal(const Copy_field *copy)
void Field::do_field_timestamp(const Copy_field *copy)
{
// XXX why couldn't we do it everywhere?
/* Use general but slow copy function */
copy->from_field->save_in_field(copy->to_field);
}
/* Binary representation of the maximum possible pre-11.5 TIMESTAMP(6) */
const uchar timestamp_old_bytes[7]=
{
0x7f, 0xff, 0xff, 0xff, 0x0f, 0x42, 0x3f
};
void Field::do_field_versioned_timestamp(const Copy_field *copy)
{
memcpy(copy->to_ptr, copy->from_ptr, copy->to_length);
if (!memcmp(copy->to_ptr, timestamp_old_bytes, sizeof(timestamp_old_bytes)))
{
/* Convert row_end to max possible timestamp (2106) */
copy->to_ptr[0]= 0xff;
}
}
void Field::do_field_temporal(const Copy_field *copy, date_mode_t fuzzydate)
{
@ -761,10 +778,16 @@ void Copy_field::set(Field *to,Field *from,bool save)
Field::Copy_func *Field_timestamp::get_copy_func(const Field *from) const
{
Field::Copy_func *copy= Field_temporal::get_copy_func(from);
if (copy == do_field_datetime && from->type() == MYSQL_TYPE_TIMESTAMP)
return do_field_timestamp;
else
return copy;
if (from->type() == MYSQL_TYPE_TIMESTAMP)
{
if (copy == do_field_datetime)
return do_field_timestamp;
if (copy == do_field_eq &&
from->table->file->check_versioned_compatibility() &&
(flags & VERS_ROW_END) && (from->flags & VERS_ROW_END))
return do_field_versioned_timestamp;
}
return copy;
}

View File

@ -4977,6 +4977,26 @@ int handler::check_long_hash_compatibility() const
}
int handler::check_versioned_compatibility() const
{
/* Versioned timestamp extended in 11.5.0 for 64 bit systems */
if (table->s->mysql_version < 110500 && table->versioned() &&
TIMESTAMP_MAX_YEAR == 2106)
return HA_ADMIN_NEEDS_DATA_CONVERSION;
return 0;
}
int handler::check_versioned_compatibility(uint mysql_version) const
{
/* Versioned timestamp extended in 11.4.0 for 64 bit systems */
if (mysql_version < 110500 && table->versioned() &&
TIMESTAMP_MAX_YEAR == 2106)
return HA_ADMIN_NEEDS_DATA_CONVERSION;
return 0;
}
int handler::ha_check_for_upgrade(HA_CHECK_OPT *check_opt)
{
int error;
@ -5025,6 +5045,9 @@ int handler::ha_check_for_upgrade(HA_CHECK_OPT *check_opt)
if (unlikely((error= check_long_hash_compatibility())))
return error;
if (unlikely((error= check_versioned_compatibility())))
return error;
return check_for_upgrade(check_opt);
}
@ -5083,7 +5106,6 @@ err:
}
/**
@return
key if error because of duplicated keys
@ -5225,7 +5247,7 @@ bool non_existing_table_error(int error)
@retval
HA_ADMIN_OK Successful upgrade
@retval
HA_ADMIN_NEEDS_UPGRADE Table has structures requiring upgrade
HA_ADMIN_NEEDS_UPGRADE Table has structures requiring REPAIR TABLE
@retval
HA_ADMIN_NEEDS_ALTER Table has structures requiring ALTER TABLE
@retval

View File

@ -3639,6 +3639,8 @@ protected:
public:
int check_collation_compatibility();
int check_long_hash_compatibility() const;
int check_versioned_compatibility() const;
int check_versioned_compatibility(uint version) const;
int ha_check_for_upgrade(HA_CHECK_OPT *check_opt);
/** to be actually called to get 'check()' functionality*/
int ha_check(THD *thd, HA_CHECK_OPT *check_opt);
@ -5822,7 +5824,6 @@ bool non_existing_table_error(int error);
uint ha_count_rw_2pc(THD *thd, bool all);
uint ha_check_and_coalesce_trx_read_only(THD *thd, Ha_trx_info *ha_list,
bool all);
inline void Cost_estimate::reset(handler *file)
{
reset();

View File

@ -6779,6 +6779,7 @@ int Rows_log_event::write_row(rpl_group_info *rgi, const bool overwrite)
// Check whether a row came from unversioned table and fix vers fields.
if (table->vers_start_field()->get_timestamp(&sec_part) == 0 && sec_part == 0)
table->vers_update_fields();
table->vers_fix_old_timestamp(rgi);
}
/*
@ -7514,6 +7515,11 @@ int Rows_log_event::find_row(rpl_group_info *rgi)
table->vers_end_field()->set_max();
m_vers_from_plain= true;
}
else if (m_table->versioned(VERS_TIMESTAMP))
{
/* Change row_end in record[0] to new end date if old server */
m_table->vers_fix_old_timestamp(rgi);
}
}
DBUG_PRINT("info",("looking for the following record"));
@ -8080,8 +8086,12 @@ Update_rows_log_event::do_exec_row(rpl_group_info *rgi)
if (m_table->versioned())
{
if (m_vers_from_plain && m_table->versioned(VERS_TIMESTAMP))
m_table->vers_update_fields();
if (m_table->versioned(VERS_TIMESTAMP))
{
if (m_vers_from_plain)
m_table->vers_update_fields();
m_table->vers_fix_old_timestamp(rgi);
}
if (!history_change && !m_table->vers_end_field()->is_max())
{
tl->trg_event_map|= trg2bit(TRG_EVENT_DELETE);

View File

@ -242,6 +242,7 @@ class Master_info : public Slave_reporting_capability
THD *io_thd;
MYSQL* mysql;
uint32 file_id; /* for 3.23 load data infile */
uint mysql_version;
Relay_log_info rli;
uint port;
Rpl_filter* rpl_filter; /* Each replication can set its filter rule*/

View File

@ -1728,7 +1728,8 @@ static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi)
int err_code= 0;
MYSQL_RES *master_res= 0;
MYSQL_ROW master_row;
uint version= mysql_get_server_version(mysql) / 10000;
uint full_version= mysql_get_server_version(mysql);
uint version= full_version/ 10000;
DBUG_ENTER("get_master_version_and_clock");
/*
@ -1737,6 +1738,7 @@ static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi)
*/
delete mi->rli.relay_log.description_event_for_queue;
mi->rli.relay_log.description_event_for_queue= 0;
mi->mysql_version= full_version;
if (!my_isdigit(&my_charset_bin,*mysql->server_version))
{

View File

@ -48,7 +48,8 @@
#include "sql_db.h" // get_default_db_collation
#include "sql_update.h" // class Sql_cmd_update
#include "sql_delete.h" // class Sql_cmd_delete
#include "rpl_rli.h" // class rpl_group_info
#include "rpl_mi.h" // class Master_info
#ifdef WITH_WSREP
#include "wsrep_schema.h"
@ -9555,6 +9556,34 @@ void TABLE::vers_update_end()
DBUG_ASSERT(0);
}
#ifdef HAVE_REPLICATION
void TABLE::vers_fix_old_timestamp(rpl_group_info *rgi)
{
/*
rgi->rli->mi is not set if we are not connected to a slave.
This can happen in case of
- Data sent from mariadb-binlog
- online_alter_read_from_binlog (in this case no transformation is needed)
*/
if (rgi->rli->mi &&
file->check_versioned_compatibility(rgi->rli->mi->mysql_version))
{
Field *end_field= vers_end_field();
if (!memcmp(end_field->ptr, timestamp_old_bytes,
sizeof(timestamp_old_bytes)))
{
/*
Upgrade timestamp.
Check Field::do_field_versioned_timestamp() for details
*/
end_field->ptr[0]= 0xff;
}
}
}
#endif /* HAVE_REPLICATION */
/**
Reset markers that fields are being updated
*/

View File

@ -81,6 +81,7 @@ struct Name_resolution_context;
class Table_function_json_table;
class Open_table_context;
class MYSQL_LOG;
struct rpl_group_info;
/*
Used to identify NESTED_JOIN structures within a join (applicable only to
@ -1937,6 +1938,9 @@ public:
bool vers_update_fields();
/* Used in DELETE, DUP REPLACE and insert history row */
void vers_update_end();
#ifdef HAVE_REPLICATION
void vers_fix_old_timestamp(rpl_group_info *rgi);
#endif
void find_constraint_correlated_indexes();
/** Number of additional fields used in versioned tables */