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_IGNORE_SERVER_IDS,
OPT_DO_SERVER_IDS, OPT_DO_SERVER_IDS,
OPT_SSL_FP, OPT_SSL_FPLIST, OPT_SSL_FP, OPT_SSL_FPLIST,
OPT_UPDATE_HISTORY,
OPT_MAX_CLIENT_OPTION /* should be always the last */ 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); name, name + 9);
rc= run_query(qbuf, 1); rc= run_query(qbuf, 1);
if (verbose) if (!opt_silent)
printf("%-50s %s\n", name, rc ? "FAILED" : "OK"); printf("%-50s %s\n", name, rc ? "FAILED" : "OK");
DBUG_RETURN(rc); 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 " my_snprintf(qbuf, sizeof(qbuf), "ALTER DATABASE %`s UPGRADE DATA DIRECTORY "
"NAME", name); "NAME", name);
rc= run_query(qbuf, 1); rc= run_query(qbuf, 1);
if (verbose) if (!opt_silent)
printf("%-50s %s\n", name, rc ? "FAILED" : "OK"); printf("%-50s %s\n", name, rc ? "FAILED" : "OK");
DBUG_RETURN(rc); DBUG_RETURN(rc);
} }
@ -840,8 +840,8 @@ static int rebuild_table(char *name)
fprintf(stderr, "Error: %s\n", mysql_error(sock)); fprintf(stderr, "Error: %s\n", mysql_error(sock));
rc= 1; rc= 1;
} }
if (verbose) if (!opt_silent)
printf("%-50s %s\n", name, rc ? "FAILED" : "FIXED"); printf("%-50s %s\n", name, rc ? "FAILED" : "OK");
my_free(query); my_free(query);
DBUG_RETURN(rc); DBUG_RETURN(rc);
} }
@ -1035,7 +1035,6 @@ static void __attribute__((noinline)) print_result()
MYSQL_RES *res; MYSQL_RES *res;
MYSQL_ROW row; MYSQL_ROW row;
char prev[(NAME_LEN+9)*3+2]; char prev[(NAME_LEN+9)*3+2];
char prev_alter[MAX_ALTER_STR_SIZE];
size_t length_of_db= strlen(sock->db); size_t length_of_db= strlen(sock->db);
my_bool found_error=0, table_rebuild=0; my_bool found_error=0, table_rebuild=0;
DYNAMIC_ARRAY *array4repair= &tables4repair; DYNAMIC_ARRAY *array4repair= &tables4repair;
@ -1044,7 +1043,6 @@ static void __attribute__((noinline)) print_result()
res = mysql_use_result(sock); res = mysql_use_result(sock);
prev[0] = '\0'; prev[0] = '\0';
prev_alter[0]= 0;
while ((row = mysql_fetch_row(res))) while ((row = mysql_fetch_row(res)))
{ {
int changed = strcmp(prev, row[0]); int changed = strcmp(prev, row[0]);
@ -1061,19 +1059,13 @@ static void __attribute__((noinline)) print_result()
strcmp(row[3],"OK")) strcmp(row[3],"OK"))
{ {
if (table_rebuild) if (table_rebuild)
{ insert_table_name(&tables4rebuild, prev, length_of_db);
if (prev_alter[0])
insert_dynamic(&alter_table_cmds, (uchar*) prev_alter);
else
insert_table_name(&tables4rebuild, prev, length_of_db);
}
else else
insert_table_name(array4repair, prev, length_of_db); insert_table_name(array4repair, prev, length_of_db);
} }
array4repair= &tables4repair; array4repair= &tables4repair;
found_error=0; found_error=0;
table_rebuild=0; table_rebuild=0;
prev_alter[0]= 0;
if (opt_silent) if (opt_silent)
continue; continue;
} }
@ -1083,20 +1075,28 @@ static void __attribute__((noinline)) print_result()
{ {
/* /*
If the error message includes REPAIR TABLE, we assume it means 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""... 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 ")) 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; 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 else
printf("%s\n%-9s: %s", row[0], row[2], row[3]); 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; found_error=1;
if (opt_auto_repair && strstr(row[3], "ALTER TABLE") != NULL) if (strstr(row[3], "ALTER TABLE"))
table_rebuild=1; 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 (found_error && opt_auto_repair && what_to_do != DO_REPAIR)
{ {
if (table_rebuild) if (table_rebuild)
{ insert_table_name(&tables4rebuild, prev, length_of_db);
if (prev_alter[0])
insert_dynamic(&alter_table_cmds, prev_alter);
else
insert_table_name(&tables4rebuild, prev, length_of_db);
}
else else
insert_table_name(array4repair, prev, length_of_db); 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_include_master_host_port= 0,
opt_events= 0, opt_comments_used= 0, opt_events= 0, opt_comments_used= 0,
opt_alltspcs=0, opt_notspcs= 0, opt_logging, 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; opt_drop_trigger= 0, opt_dump_history= 0;
#define OPT_SYSTEM_ALL 1 #define OPT_SYSTEM_ALL 1
#define OPT_SYSTEM_USERS 2 #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 ulong opt_max_allowed_packet, opt_net_buffer_length;
static double opt_max_statement_time= 0.0; static double opt_max_statement_time= 0.0;
static MYSQL *mysql=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, static char *opt_password=0,*current_user=0,
*current_host=0,*path=0,*fields_terminated=0, *current_host=0,*path=0,*fields_terminated=0,
*lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=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.", {"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}, &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 " {"dump-history", 'H', "Dump system-versioned tables with history (only for "
"timestamp based versioning)", &opt_dump_history, "timestamp based versioning). Use also --update-history if "
&opt_dump_history, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, "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, {"dump-slave", OPT_MYSQLDUMP_SLAVE_DATA,
"This causes the binary log position and filename of the master to be " "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" "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); fprintf(stderr, "%s: --xml can't be used with --tab or --dir.\n", my_progname_short);
return(EX_USAGE); 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", if (opt_update_history)
my_progname_short); {
return(EX_USAGE); /* dump history requires timezone "+00:00" */
} opt_tz_utc= 1;
if (opt_replace_into && opt_dump_history) }
{ if (opt_xml)
fprintf(stderr, "%s: --dump-history can't be used with --replace.\n", {
my_progname_short); fprintf(stderr, "%s: --xml can't be used with --dump-history.\n",
return(EX_USAGE); my_progname_short);
} return(EX_USAGE);
if (opt_asof_timestamp && opt_dump_history) }
{ if (opt_replace_into)
fprintf(stderr, "%s: --dump-history can't be used with --as-of.\n", {
my_progname_short); fprintf(stderr, "%s: --dump-history can't be used with --replace.\n",
return(EX_USAGE); 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, '\'')) if (opt_asof_timestamp && strchr(opt_asof_timestamp, '\''))
{ {
@ -1997,6 +2013,7 @@ static void free_resources()
dynstr_free(&insert_pat); dynstr_free(&insert_pat);
dynstr_free(&select_field_names); dynstr_free(&select_field_names);
dynstr_free(&select_field_names_for_header); dynstr_free(&select_field_names_for_header);
dynstr_free(&insert_field_names);
if (defaults_argv) if (defaults_argv)
free_defaults(defaults_argv); free_defaults(defaults_argv);
mysql_library_end(); 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; my_ulonglong num_fields;
char *result_table, *opt_quoted_table; char *result_table, *opt_quoted_table;
const char *insert_option; 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 table_buff2[NAME_LEN*2+3], query_buff[QUERY_LENGTH];
char temp_buff[NAME_LEN*2 + 3], temp_buff2[NAME_LEN*2 + 3]; char temp_buff[NAME_LEN*2 + 3], temp_buff2[NAME_LEN*2 + 3];
char *last_name;
FILE *sql_file= md_result_file; FILE *sql_file= md_result_file;
size_t len; size_t len;
my_bool is_log_table; my_bool is_log_table, dummy_versioned;
MYSQL_RES *result; MYSQL_RES *result;
MYSQL_ROW row; MYSQL_ROW row;
const char *s3_engine_ptr; 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; select_field_names_inited= 1;
init_dynamic_string_checked(&select_field_names, "", 1024, 1024); init_dynamic_string_checked(&select_field_names, "", 1024, 1024);
init_dynamic_string_checked(&insert_field_names, "", 1024, 1024);
if (opt_header) if (opt_header)
init_dynamic_string_checked(&select_field_names_for_header, "", 1024, 1024); init_dynamic_string_checked(&select_field_names_for_header, "", 1024, 1024);
} }
else else
{ {
dynstr_set_checked(&select_field_names, ""); dynstr_set_checked(&select_field_names, "");
dynstr_set_checked(&insert_field_names, "");
if (opt_header) if (opt_header)
dynstr_set_checked(&select_field_names_for_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 (versioned)
{ {
if (!opt_asof_timestamp && !opt_dump_history) if (!opt_asof_timestamp && !opt_dump_history)
versioned= NULL; *versioned= 0;
else else
{ {
my_snprintf(query_buff, sizeof(query_buff), "select 1 from" 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; *versioned= 0;
} }
} }
else
{
versioned= &dummy_versioned;
dummy_versioned= 0;
}
len= my_snprintf(query_buff, sizeof(query_buff), len= my_snprintf(query_buff, sizeof(query_buff),
"SET SQL_QUOTE_SHOW_CREATE=%d", opt_quoted || opt_keywords); "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)) 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 */ /* using SHOW CREATE statement */
if (!opt_no_create_info) 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) if (init)
{ {
dynstr_append_checked(&select_field_names, ", "); dynstr_append_checked(&select_field_names, ", ");
dynstr_append_checked(&insert_field_names, ", ");
if (opt_header) if (opt_header)
dynstr_append_checked(&select_field_names_for_header, ", "); dynstr_append_checked(&select_field_names_for_header, ", ");
} }
init=1; 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) if (opt_header)
dynstr_append_checked(&select_field_names_for_header, dynstr_append_checked(&select_field_names_for_header,
quote_for_equal(row[0], name_buff)); 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) if (vers_hidden)
{ {
complete_insert= 1; 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) 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); num_fields= mysql_num_rows(result) + (vers_hidden ? 2 : 0);
mysql_free_result(result); mysql_free_result(result);
} }
@ -3751,6 +3799,7 @@ continue_xml:
DBUG_RETURN((uint) num_fields); DBUG_RETURN((uint) num_fields);
} /* get_table_structure */ } /* get_table_structure */
static void dump_trigger_old(FILE *sql_file, MYSQL_RES *show_triggers_rs, static void dump_trigger_old(FILE *sql_file, MYSQL_RES *show_triggers_rs,
MYSQL_ROW *show_trigger_row, MYSQL_ROW *show_trigger_row,
const char *table_name) 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 # Copying maria050313_utf8_croatian_ci.* to MYSQLD_DATADIR
CHECK TABLE maria050313_utf8_croatian_ci FOR UPGRADE; CHECK TABLE maria050313_utf8_croatian_ci FOR UPGRADE;
Table Op Msg_type Msg_text 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; 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! 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; REPAIR TABLE maria050313_utf8_croatian_ci;
@ -43,7 +43,7 @@ DROP TABLE maria050313_utf8_croatian_ci;
# Copying maria050313_ucs2_croatian_ci.* to MYSQLD_DATADIR # Copying maria050313_ucs2_croatian_ci.* to MYSQLD_DATADIR
CHECK TABLE maria050313_ucs2_croatian_ci_def FOR UPGRADE; CHECK TABLE maria050313_ucs2_croatian_ci_def FOR UPGRADE;
Table Op Msg_type Msg_text 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; 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! 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; 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 # Copying maria050313_ucs2_croatian_ci.* to MYSQLD_DATADIR
CHECK TABLE maria050313_ucs2_croatian_ci_def; CHECK TABLE maria050313_ucs2_croatian_ci_def;
Table Op Msg_type Msg_text 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; REPAIR TABLE maria050313_ucs2_croatian_ci_def;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.maria050313_ucs2_croatian_ci_def repair status OK 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 # Copying maria050533_xxx_croatian_ci.* to MYSQLD_DATADIR
CHECK TABLE maria050533_xxx_croatian_ci FOR UPGRADE; CHECK TABLE maria050533_xxx_croatian_ci FOR UPGRADE;
Table Op Msg_type Msg_text 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; REPAIR TABLE maria050533_xxx_croatian_ci;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.maria050533_xxx_croatian_ci repair status OK 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 # Copying maria100004_xxx_croatian_ci.* to MYSQLD_DATADIR
CHECK TABLE maria100004_xxx_croatian_ci FOR UPGRADE; CHECK TABLE maria100004_xxx_croatian_ci FOR UPGRADE;
Table Op Msg_type Msg_text 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; 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! 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; REPAIR TABLE maria100004_xxx_croatian_ci;
@ -374,17 +374,17 @@ performance_schema
sys sys
sys.sys_config OK sys.sys_config OK
test test
test.maria050313_ucs2_croatian_ci_def Needs upgrade test.maria050313_ucs2_croatian_ci_def Needs upgrade with ALTER TABLE FORCE
test.maria050313_utf8_croatian_ci Needs upgrade test.maria050313_utf8_croatian_ci Needs upgrade with ALTER TABLE FORCE
test.maria050533_xxx_croatian_ci Needs upgrade test.maria050533_xxx_croatian_ci Needs upgrade with ALTER TABLE FORCE
test.maria100004_xxx_croatian_ci Needs upgrade test.maria100004_xxx_croatian_ci Needs upgrade with ALTER TABLE FORCE
test.mysql050614_xxx_croatian_ci OK test.mysql050614_xxx_croatian_ci OK
Repairing tables Repairing tables
test.maria050313_ucs2_croatian_ci_def OK `test`.`maria050313_ucs2_croatian_ci_def` OK
test.maria050313_utf8_croatian_ci OK `test`.`maria050313_utf8_croatian_ci` OK
test.maria050533_xxx_croatian_ci OK `test`.`maria050533_xxx_croatian_ci` OK
test.maria100004_xxx_croatian_ci OK `test`.`maria100004_xxx_croatian_ci` OK
Phase 7/8: uninstalling plugins Phase 7/8: uninstalling plugins
Phase 8/8: Running 'FLUSH PRIVILEGES' Phase 8/8: Running 'FLUSH PRIVILEGES'
OK 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! ERROR HY000: Table rebuild required. Please do "ALTER TABLE `test.t1` FORCE" or dump/reload to fix it!
CHECK TABLE t1; CHECK TABLE t1;
Table Op Msg_type Msg_text 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; REPAIR TABLE t1;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 repair status OK test.t1 repair status OK

View File

@ -10611,7 +10611,7 @@ a 1
ä 2 ä 2
CHECK TABLE t1; CHECK TABLE t1;
Table Op Msg_type Msg_text 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'); INSERT INTO t1 VALUES ('A');
ERROR 23000: Duplicate entry 'A' for key 'a' ERROR 23000: Duplicate entry 'A' for key 'a'
INSERT INTO t1 VALUES ('Ä'); INSERT INTO t1 VALUES ('Ä');
@ -10624,7 +10624,7 @@ a 1
Ấ 3 Ấ 3
CHECK TABLE t1; CHECK TABLE t1;
Table Op Msg_type Msg_text 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; ALTER TABLE t1 FORCE;
ERROR 23000: Duplicate entry 'ä' for key 'a' ERROR 23000: Duplicate entry 'ä' for key 'a'
DELETE FROM t1 WHERE OCTET_LENGTH(a)>1; DELETE FROM t1 WHERE OCTET_LENGTH(a)>1;

View File

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

View File

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

View File

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

View File

@ -210,6 +210,7 @@ Tables_in_test
t1 t1
v1 v1
test.t1 OK test.t1 OK
#mysql50#v-1 OK
show tables; show tables;
Tables_in_test Tables_in_test
t1 t1
@ -226,6 +227,7 @@ set @@character_set_client=@save_character_set_client;
set @@character_set_results=@save_character_set_client; set @@character_set_results=@save_character_set_client;
set @@collation_connection=@save_collation_connection; set @@collation_connection=@save_collation_connection;
mysqlcheck --fix-table-names --databases test mysqlcheck --fix-table-names --databases test
#mysql50#@ OK
SET NAMES utf8; SET NAMES utf8;
SHOW TABLES; SHOW TABLES;
Tables_in_test 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 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 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 mysqlcheck --fix-db-names --fix-table-names --all-databases
#mysql50#a@b OK
#mysql50#c@d OK
USE `a@b`; USE `a@b`;
SELECT * FROM INFORMATION_SCHEMA.TRIGGERS SELECT * FROM INFORMATION_SCHEMA.TRIGGERS
WHERE TRIGGER_SCHEMA="a@b" ORDER BY trigger_name; WHERE TRIGGER_SCHEMA="a@b" ORDER BY trigger_name;
@ -281,11 +285,13 @@ USE test;
# #
drop table if exists `#mysql50#t1-1`; drop table if exists `#mysql50#t1-1`;
create table `#mysql50#t1-1` (a int) engine=myisam; create table `#mysql50#t1-1` (a int) engine=myisam;
#mysql50#t1-1 OK
show tables like 't1-1'; show tables like 't1-1';
Tables_in_test (t1-1) Tables_in_test (t1-1)
t1-1 t1-1
drop table `t1-1`; drop table `t1-1`;
create table `#mysql50#t1-1` (a int) engine=myisam; create table `#mysql50#t1-1` (a int) engine=myisam;
#mysql50#t1-1 OK
show tables like 't1-1'; show tables like 't1-1';
Tables_in_test (t1-1) Tables_in_test (t1-1)
t1-1 t1-1
@ -328,27 +334,27 @@ CHECK TABLE bug47205 FOR UPGRADE;
Table Op Msg_type Msg_text 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! 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 # Running mysqlcheck to check and upgrade
test.bug47205 test.bug47205 Needs upgrade with ALTER TABLE FORCE
error : Table rebuild required. Please do "ALTER TABLE `bug47205` FORCE" or dump/reload to fix it!
Repairing tables Repairing tables
`test`.`bug47205` OK
# Table should now be ok # Table should now be ok
CHECK TABLE bug47205 FOR UPGRADE; CHECK TABLE bug47205 FOR UPGRADE;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.bug47205 check status OK test.bug47205 check status OK
DROP TABLE bug47205; DROP TABLE bug47205;
# #
# Test 3: MyISAM - REPAIR supported # Test 3: MyISAM - ALTER TABLE supported
# Use an old FRM that will require upgrade # 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; CHECK TABLE bug47205 FOR UPGRADE;
Table Op Msg_type Msg_text 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 # Running mysqlcheck to check and upgrade
test.bug47205 Needs upgrade test.bug47205 Needs upgrade with ALTER TABLE FORCE
Repairing tables Repairing tables
test.bug47205 OK `test`.`bug47205` OK
# Table should now be ok # Table should now be ok
CHECK TABLE bug47205 FOR UPGRADE; CHECK TABLE bug47205 FOR UPGRADE;
Table Op Msg_type Msg_text 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`; flush table `t.2`;
mysqlcheck --check-upgrade --auto-repair test mysqlcheck --check-upgrade --auto-repair test
test.t.1 OK test.t.1 OK
test.t.2 test.t.2 Needs upgrade with ALTER TABLE FORCE
error : Table rebuild required. Please do "ALTER TABLE `t.2` FORCE" or dump/reload to fix it! test.t.3 Needs upgrade with ALTER TABLE FORCE
test.t.3 Needs upgrade
Repairing tables Repairing tables
test.t.3 OK `test`.`t.2` OK
`test`.`t.3` OK
check table `t.1`, `t.2`, `t.3`; check table `t.1`, `t.2`, `t.3`;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t.1 check status OK test.t.1 check status OK
@ -411,13 +417,14 @@ drop view v1;
create table t1(a int); create table t1(a int);
mysqlcheck --process-views --check-upgrade --auto-repair test mysqlcheck --process-views --check-upgrade --auto-repair test
test.t1 OK test.t1 OK
test.v1 Needs upgrade test.v1 Needs upgrade with REPAIR
Repairing views Repairing views
test.v1 OK test.v1 OK
drop view v1; drop view v1;
drop table t1; drop table t1;
create table `#mysql50#t1``1` (a int) engine=myisam; create table `#mysql50#t1``1` (a int) engine=myisam;
#mysql50#t1`1 OK
show tables; show tables;
Tables_in_test Tables_in_test
t1`1 t1`1

View File

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

View File

@ -122,7 +122,7 @@ SELECT * FROM t1;
id id
1 1
2 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; CHECK TABLE t1 FOR UPGRADE;
Table Op Msg_type Msg_text 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! 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 id
1 1
DROP TABLE t1; 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 # End of 5.0 tests
DROP TABLE IF EXISTS tt1; DROP TABLE IF EXISTS tt1;
CREATE TEMPORARY TABLE tt1 (c1 INT); CREATE TEMPORARY TABLE tt1 (c1 INT);

View File

@ -138,7 +138,7 @@ let $MYSQLD_DATADIR= `select @@datadir`;
SHOW TABLE STATUS LIKE 't1'; SHOW TABLE STATUS LIKE 't1';
SELECT * FROM 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; CHECK TABLE t1 FOR UPGRADE;
--echo # REPAIR old table USE_FRM should fail --echo # REPAIR old table USE_FRM should fail
@ -155,6 +155,13 @@ SELECT * FROM t1;
DROP TABLE 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 --echo # End of 5.0 tests
# #

View File

@ -24,6 +24,9 @@ show tables in `#mysql50#mysqltest-1`;
Tables_in_#mysql50#mysqltest-1 Tables_in_#mysql50#mysqltest-1
#mysql50#t-1 #mysql50#t-1
t1 t1
#mysql50#mysqltest-1 OK
#mysql50#t-1 OK
#mysql50#t-1 OK
show create database `mysqltest1`; show create database `mysqltest1`;
Database Create Database Database Create Database
mysqltest1 CREATE DATABASE `mysqltest1` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */ 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 255 3
CHECK TABLE t1 FOR UPGRADE; CHECK TABLE t1 FOR UPGRADE;
Table Op Msg_type Msg_text 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; REPAIR TABLE t1;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 repair status OK 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 CONV_TYPE_IMPOSSIBLE
}; };
/* Old 32 bit timestamp */
extern const uchar timestamp_old_bytes[7];
class Conv_param 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_temporal(const Copy_field *copy, date_mode_t fuzzydate);
static void do_field_datetime(const Copy_field *copy); static void do_field_datetime(const Copy_field *copy);
static void do_field_timestamp(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); static void do_field_decimal(const Copy_field *copy);
public: public:
static void *operator new(size_t size, MEM_ROOT *mem_root) throw () 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) 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); 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) 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 *Field_timestamp::get_copy_func(const Field *from) const
{ {
Field::Copy_func *copy= Field_temporal::get_copy_func(from); Field::Copy_func *copy= Field_temporal::get_copy_func(from);
if (copy == do_field_datetime && from->type() == MYSQL_TYPE_TIMESTAMP) if (from->type() == MYSQL_TYPE_TIMESTAMP)
return do_field_timestamp; {
else if (copy == do_field_datetime)
return copy; 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 handler::ha_check_for_upgrade(HA_CHECK_OPT *check_opt)
{ {
int error; int error;
@ -5025,6 +5045,9 @@ int handler::ha_check_for_upgrade(HA_CHECK_OPT *check_opt)
if (unlikely((error= check_long_hash_compatibility()))) if (unlikely((error= check_long_hash_compatibility())))
return error; return error;
if (unlikely((error= check_versioned_compatibility())))
return error;
return check_for_upgrade(check_opt); return check_for_upgrade(check_opt);
} }
@ -5083,7 +5106,6 @@ err:
} }
/** /**
@return @return
key if error because of duplicated keys key if error because of duplicated keys
@ -5225,7 +5247,7 @@ bool non_existing_table_error(int error)
@retval @retval
HA_ADMIN_OK Successful upgrade HA_ADMIN_OK Successful upgrade
@retval @retval
HA_ADMIN_NEEDS_UPGRADE Table has structures requiring upgrade HA_ADMIN_NEEDS_UPGRADE Table has structures requiring REPAIR TABLE
@retval @retval
HA_ADMIN_NEEDS_ALTER Table has structures requiring ALTER TABLE HA_ADMIN_NEEDS_ALTER Table has structures requiring ALTER TABLE
@retval @retval

View File

@ -3639,6 +3639,8 @@ protected:
public: public:
int check_collation_compatibility(); int check_collation_compatibility();
int check_long_hash_compatibility() const; 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); int ha_check_for_upgrade(HA_CHECK_OPT *check_opt);
/** to be actually called to get 'check()' functionality*/ /** to be actually called to get 'check()' functionality*/
int ha_check(THD *thd, HA_CHECK_OPT *check_opt); 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_count_rw_2pc(THD *thd, bool all);
uint ha_check_and_coalesce_trx_read_only(THD *thd, Ha_trx_info *ha_list, uint ha_check_and_coalesce_trx_read_only(THD *thd, Ha_trx_info *ha_list,
bool all); bool all);
inline void Cost_estimate::reset(handler *file) inline void Cost_estimate::reset(handler *file)
{ {
reset(); 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. // 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) if (table->vers_start_field()->get_timestamp(&sec_part) == 0 && sec_part == 0)
table->vers_update_fields(); 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(); table->vers_end_field()->set_max();
m_vers_from_plain= true; 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")); 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_table->versioned())
{ {
if (m_vers_from_plain && m_table->versioned(VERS_TIMESTAMP)) if (m_table->versioned(VERS_TIMESTAMP))
m_table->vers_update_fields(); {
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()) if (!history_change && !m_table->vers_end_field()->is_max())
{ {
tl->trg_event_map|= trg2bit(TRG_EVENT_DELETE); tl->trg_event_map|= trg2bit(TRG_EVENT_DELETE);

View File

@ -242,6 +242,7 @@ class Master_info : public Slave_reporting_capability
THD *io_thd; THD *io_thd;
MYSQL* mysql; MYSQL* mysql;
uint32 file_id; /* for 3.23 load data infile */ uint32 file_id; /* for 3.23 load data infile */
uint mysql_version;
Relay_log_info rli; Relay_log_info rli;
uint port; uint port;
Rpl_filter* rpl_filter; /* Each replication can set its filter rule*/ 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; int err_code= 0;
MYSQL_RES *master_res= 0; MYSQL_RES *master_res= 0;
MYSQL_ROW master_row; 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"); 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; delete mi->rli.relay_log.description_event_for_queue;
mi->rli.relay_log.description_event_for_queue= 0; mi->rli.relay_log.description_event_for_queue= 0;
mi->mysql_version= full_version;
if (!my_isdigit(&my_charset_bin,*mysql->server_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_db.h" // get_default_db_collation
#include "sql_update.h" // class Sql_cmd_update #include "sql_update.h" // class Sql_cmd_update
#include "sql_delete.h" // class Sql_cmd_delete #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 #ifdef WITH_WSREP
#include "wsrep_schema.h" #include "wsrep_schema.h"
@ -9555,6 +9556,34 @@ void TABLE::vers_update_end()
DBUG_ASSERT(0); 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 Reset markers that fields are being updated
*/ */

View File

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