diff --git a/client/client_priv.h b/client/client_priv.h index 46c0a897dcf..f559b204b12 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -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 */ }; diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 63b0a5b0979..b28bcd407d6 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -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); } diff --git a/client/mysqldump.cc b/client/mysqldump.cc index eddde3f3aad..435abb3e35a 100644 --- a/client/mysqldump.cc +++ b/client/mysqldump.cc @@ -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) diff --git a/mysql-test/main/ctype_upgrade.result b/mysql-test/main/ctype_upgrade.result index 819ff32da3e..a2dc4579866 100644 --- a/mysql-test/main/ctype_upgrade.result +++ b/mysql-test/main/ctype_upgrade.result @@ -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 diff --git a/mysql-test/main/ctype_utf8.result b/mysql-test/main/ctype_utf8.result index 7d6ecce639b..c76c33f39d0 100644 --- a/mysql-test/main/ctype_utf8.result +++ b/mysql-test/main/ctype_utf8.result @@ -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; diff --git a/mysql-test/main/mysql_upgrade_mysql_json.result b/mysql-test/main/mysql_upgrade_mysql_json.result index 05d280d9994..e55f24efb6d 100644 --- a/mysql-test/main/mysql_upgrade_mysql_json.result +++ b/mysql-test/main/mysql_upgrade_mysql_json.result @@ -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' diff --git a/mysql-test/main/mysql_upgrade_mysql_json_datatype.result b/mysql-test/main/mysql_upgrade_mysql_json_datatype.result index 2ef120222c4..5388151a1f5 100644 --- a/mysql-test/main/mysql_upgrade_mysql_json_datatype.result +++ b/mysql-test/main/mysql_upgrade_mysql_json_datatype.result @@ -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 diff --git a/mysql-test/main/mysql_upgrade_mysql_json_with_plugin_loaded.result b/mysql-test/main/mysql_upgrade_mysql_json_with_plugin_loaded.result index 373844db12c..670c1a66aeb 100644 --- a/mysql-test/main/mysql_upgrade_mysql_json_with_plugin_loaded.result +++ b/mysql-test/main/mysql_upgrade_mysql_json_with_plugin_loaded.result @@ -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 diff --git a/mysql-test/main/mysqlcheck.result b/mysql-test/main/mysqlcheck.result index 540d50ddec6..5f5a5ed0ecd 100644 --- a/mysql-test/main/mysqlcheck.result +++ b/mysql-test/main/mysqlcheck.result @@ -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 diff --git a/mysql-test/main/mysqlcheck.test b/mysql-test/main/mysqlcheck.test index ce4ac7d3be2..a9d263456fb 100644 --- a/mysql-test/main/mysqlcheck.test +++ b/mysql-test/main/mysqlcheck.test @@ -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 diff --git a/mysql-test/main/repair.result b/mysql-test/main/repair.result index da43a196898..35dd6df1805 100644 --- a/mysql-test/main/repair.result +++ b/mysql-test/main/repair.result @@ -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); diff --git a/mysql-test/main/repair.test b/mysql-test/main/repair.test index ab30067e476..cb03124e641 100644 --- a/mysql-test/main/repair.test +++ b/mysql-test/main/repair.test @@ -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 # diff --git a/mysql-test/main/upgrade.result b/mysql-test/main/upgrade.result index 61ba5e095c1..abfc24a0f69 100644 --- a/mysql-test/main/upgrade.result +++ b/mysql-test/main/upgrade.result @@ -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 */ diff --git a/mysql-test/main/varbinary.result b/mysql-test/main/varbinary.result index ad8172bcfcd..4bcb6599eb0 100644 --- a/mysql-test/main/varbinary.result +++ b/mysql-test/main/varbinary.result @@ -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 diff --git a/mysql-test/std_data/sv_basic.MYD b/mysql-test/std_data/sv_basic.MYD new file mode 100644 index 00000000000..99664f79deb Binary files /dev/null and b/mysql-test/std_data/sv_basic.MYD differ diff --git a/mysql-test/std_data/sv_basic.MYI b/mysql-test/std_data/sv_basic.MYI new file mode 100644 index 00000000000..755213913e6 Binary files /dev/null and b/mysql-test/std_data/sv_basic.MYI differ diff --git a/mysql-test/std_data/sv_basic.frm b/mysql-test/std_data/sv_basic.frm new file mode 100644 index 00000000000..4b1b177114e Binary files /dev/null and b/mysql-test/std_data/sv_basic.frm differ diff --git a/mysql-test/std_data/sv_explicit.MYD b/mysql-test/std_data/sv_explicit.MYD new file mode 100644 index 00000000000..afe3a6d0518 Binary files /dev/null and b/mysql-test/std_data/sv_explicit.MYD differ diff --git a/mysql-test/std_data/sv_explicit.MYI b/mysql-test/std_data/sv_explicit.MYI new file mode 100644 index 00000000000..8cf9ea76cf9 Binary files /dev/null and b/mysql-test/std_data/sv_explicit.MYI differ diff --git a/mysql-test/std_data/sv_explicit.frm b/mysql-test/std_data/sv_explicit.frm new file mode 100644 index 00000000000..085115f083e Binary files /dev/null and b/mysql-test/std_data/sv_explicit.frm differ diff --git a/mysql-test/std_data/sv_partition#P#p_cur.MYD b/mysql-test/std_data/sv_partition#P#p_cur.MYD new file mode 100644 index 00000000000..01b39665e09 Binary files /dev/null and b/mysql-test/std_data/sv_partition#P#p_cur.MYD differ diff --git a/mysql-test/std_data/sv_partition#P#p_cur.MYI b/mysql-test/std_data/sv_partition#P#p_cur.MYI new file mode 100644 index 00000000000..2327c5eed2a Binary files /dev/null and b/mysql-test/std_data/sv_partition#P#p_cur.MYI differ diff --git a/mysql-test/std_data/sv_partition#P#p_hist.MYD b/mysql-test/std_data/sv_partition#P#p_hist.MYD new file mode 100644 index 00000000000..f724a867812 Binary files /dev/null and b/mysql-test/std_data/sv_partition#P#p_hist.MYD differ diff --git a/mysql-test/std_data/sv_partition#P#p_hist.MYI b/mysql-test/std_data/sv_partition#P#p_hist.MYI new file mode 100644 index 00000000000..8cef681136b Binary files /dev/null and b/mysql-test/std_data/sv_partition#P#p_hist.MYI differ diff --git a/mysql-test/std_data/sv_partition.frm b/mysql-test/std_data/sv_partition.frm new file mode 100644 index 00000000000..2b64c44174c Binary files /dev/null and b/mysql-test/std_data/sv_partition.frm differ diff --git a/mysql-test/std_data/sv_partition.par b/mysql-test/std_data/sv_partition.par new file mode 100644 index 00000000000..9ba0fe29b32 Binary files /dev/null and b/mysql-test/std_data/sv_partition.par differ diff --git a/mysql-test/suite/versioning/r/old_timestamp.result b/mysql-test/suite/versioning/r/old_timestamp.result new file mode 100644 index 00000000000..80d269603d3 --- /dev/null +++ b/mysql-test/suite/versioning/r/old_timestamp.result @@ -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; diff --git a/mysql-test/suite/versioning/t/old_timestamp.test b/mysql-test/suite/versioning/t/old_timestamp.test new file mode 100644 index 00000000000..1d19ea5afab --- /dev/null +++ b/mysql-test/suite/versioning/t/old_timestamp.test @@ -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; + diff --git a/sql/field.h b/sql/field.h index 544ebca29e3..64d1013b0ad 100644 --- a/sql/field.h +++ b/sql/field.h @@ -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 () diff --git a/sql/field_conv.cc b/sql/field_conv.cc index c0d632cca66..2a9e0b37884 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -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; } diff --git a/sql/handler.cc b/sql/handler.cc index 4362af897b2..185df14596b 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -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 diff --git a/sql/handler.h b/sql/handler.h index a80ac853694..99641c838a6 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -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(); diff --git a/sql/log_event_server.cc b/sql/log_event_server.cc index a16603aa7f7..e2ab6a659cd 100644 --- a/sql/log_event_server.cc +++ b/sql/log_event_server.cc @@ -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); diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h index 7f2e4c50a1b..a0f17a7dd01 100644 --- a/sql/rpl_mi.h +++ b/sql/rpl_mi.h @@ -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*/ diff --git a/sql/slave.cc b/sql/slave.cc index 2bec9d56c8d..8f688378479 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -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)) { diff --git a/sql/table.cc b/sql/table.cc index 0909a20624d..913efd898b0 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -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 */ diff --git a/sql/table.h b/sql/table.h index acb3eb1b0c4..05995b493da 100644 --- a/sql/table.h +++ b/sql/table.h @@ -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 */