diff options
Diffstat (limited to 'extra/mariabackup/xtrabackup.cc')
-rw-r--r-- | extra/mariabackup/xtrabackup.cc | 201 |
1 files changed, 107 insertions, 94 deletions
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index ddaed8bd16a..869539dd96c 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -200,6 +200,7 @@ static char* log_ignored_opt; extern my_bool opt_use_ssl; +extern char *opt_tls_version; my_bool opt_ssl_verify_server_cert; my_bool opt_extended_validation; my_bool opt_encrypted_backup; @@ -470,9 +471,18 @@ DECLARE_THREAD(dbug_execute_in_new_connection)(void *arg) dbug_thread_param_t *par= (dbug_thread_param_t *)arg; int err = mysql_query(par->con, par->query); int err_no = mysql_errno(par->con); - DBUG_ASSERT(par->expect_err == err); - if (err && par->expect_errno) - DBUG_ASSERT(err_no == par->expect_errno); + if(par->expect_err != err) + { + msg("FATAL: dbug_execute_in_new_connection : mysql_query '%s' returns %d, instead of expected %d", + par->query, err, par->expect_err); + _exit(1); + } + if (err && par->expect_errno && par->expect_errno != err_no) + { + msg("FATAL: dbug_execute_in_new_connection: mysql_query '%s' returns mysql_errno %d, instead of expected %d", + par->query, err_no, par->expect_errno); + _exit(1); + } mysql_close(par->con); mysql_thread_end(); os_event_t done = par->done_event; @@ -628,7 +638,6 @@ static void backup_file_op_fail(ulint space_id, const byte* flags, const byte* name, ulint len, const byte* new_name, ulint new_len) { - ut_a(opt_no_lock); bool fail; if (flags) { msg("DDL tracking : create %zu \"%.*s\": %x", @@ -649,6 +658,7 @@ static void backup_file_op_fail(ulint space_id, const byte* flags, msg("DDL tracking : delete %zu \"%.*s\"", space_id, int(len), name); } if (fail) { + ut_a(opt_no_lock); die("DDL operation detected in the late phase of backup." "Backup is inconsistent. Remove --no-lock option to fix."); } @@ -669,9 +679,9 @@ static void backup_optimized_ddl_op(ulint space_id) run with --no-lock. Usually aborts the backup. */ static void backup_optimized_ddl_op_fail(ulint space_id) { - ut_a(opt_no_lock); msg("DDL tracking : optimized DDL on space %zu", space_id); if (ddl_tracker.tables_in_backup.find(space_id) != ddl_tracker.tables_in_backup.end()) { + ut_a(opt_no_lock); msg("ERROR : Optimized DDL operation detected in the late phase of backup." "Backup is inconsistent. Remove --no-lock option to fix."); exit(EXIT_FAILURE); @@ -679,16 +689,6 @@ static void backup_optimized_ddl_op_fail(ulint space_id) { } -/** Callback whenever MLOG_TRUNCATE happens. */ -static void backup_truncate_fail() -{ - msg("mariabackup: Incompatible TRUNCATE operation detected.%s", - opt_lock_ddl_per_table - ? "" - : " Use --lock-ddl-per-table to lock all tables before backup."); -} - - /* Retrieve default data directory, to be used with --copy-back. @@ -832,6 +832,7 @@ enum options_xtrabackup OPT_XTRA_CHECK_PRIVILEGES }; + struct my_option xb_client_options[] = { {"verbose", 'V', "display verbose output", @@ -1693,7 +1694,7 @@ xb_get_one_option(int optid, case OPT_INNODB_CHECKSUM_ALGORITHM: - ut_a(srv_checksum_algorithm <= SRV_CHECKSUM_ALGORITHM_STRICT_NONE); + ut_a(srv_checksum_algorithm <= SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32); ADD_PRINT_PARAM_OPT(innodb_checksum_algorithm_names[srv_checksum_algorithm]); break; @@ -1862,15 +1863,18 @@ static bool innodb_init_param() msg("innodb_data_file_path = %s", innobase_data_file_path); - /* This is the first time univ_page_size is used. - It was initialized to 16k pages before srv_page_size was set */ - univ_page_size.copy_from( - page_size_t(srv_page_size, srv_page_size, false)); - srv_sys_space.set_space_id(TRX_SYS_SPACE); srv_sys_space.set_name("innodb_system"); srv_sys_space.set_path(srv_data_home); - srv_sys_space.set_flags(FSP_FLAGS_PAGE_SSIZE()); + switch (srv_checksum_algorithm) { + case SRV_CHECKSUM_ALGORITHM_FULL_CRC32: + case SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32: + srv_sys_space.set_flags(FSP_FLAGS_FCRC32_MASK_MARKER + | FSP_FLAGS_FCRC32_PAGE_SSIZE()); + break; + default: + srv_sys_space.set_flags(FSP_FLAGS_PAGE_SSIZE()); + } if (!srv_sys_space.parse_params(innobase_data_file_path, true)) { goto error; @@ -2164,8 +2168,7 @@ xb_read_delta_metadata(const char *filepath, xb_delta_info_t *info) msg("page_size is required in %s", filepath); r = FALSE; } else { - info->page_size = page_size_t(zip_size ? zip_size : page_size, - page_size, zip_size != 0); + info->page_size = zip_size ? zip_size : page_size; } if (info->space_id == ULINT_UNDEFINED) { @@ -2193,9 +2196,8 @@ xb_write_delta_metadata(const char *filename, const xb_delta_info_t *info) "page_size = " ULINTPF "\n" "zip_size = " ULINTPF " \n" "space_id = " ULINTPF "\n", - info->page_size.logical(), - info->page_size.is_compressed() - ? info->page_size.physical() : 0, + info->page_size, + info->zip_size, info->space_id); len = strlen(buf); @@ -2378,6 +2380,18 @@ check_if_skip_table( const char *ptr; char *eptr; + + dbname = NULL; + tbname = name; + while ((ptr = strchr(tbname, '/')) != NULL) { + dbname = tbname; + tbname = ptr + 1; + } + + if (strncmp(tbname, tmp_file_prefix, tmp_file_prefix_length) == 0) { + return TRUE; + } + if (regex_exclude_list.empty() && regex_include_list.empty() && tables_include_hash == NULL && @@ -2387,13 +2401,6 @@ check_if_skip_table( return(FALSE); } - dbname = NULL; - tbname = name; - while ((ptr = strchr(tbname, '/')) != NULL) { - dbname = tbname; - tbname = ptr + 1; - } - if (dbname == NULL) { return(FALSE); } @@ -2665,13 +2672,12 @@ static lsn_t xtrabackup_copy_log(lsn_t start_lsn, lsn_t end_lsn, bool last) log_block, scanned_lsn + data_len); - recv_sys->scanned_lsn = scanned_lsn + data_len; + recv_sys.scanned_lsn = scanned_lsn + data_len; if (data_len == OS_FILE_LOG_BLOCK_SIZE) { /* We got a full log block. */ scanned_lsn += data_len; - } else if (data_len - >= OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE + } else if (data_len >= log_sys.trailer_offset() || data_len <= LOG_BLOCK_HDR_SIZE) { /* We got a garbage block (abrupt end of the log). */ msg(0,"garbage block: " LSN_PF ",%zu",scanned_lsn, data_len); @@ -2720,13 +2726,13 @@ static lsn_t xtrabackup_copy_log(lsn_t start_lsn, lsn_t end_lsn, bool last) static bool xtrabackup_copy_logfile(bool last = false) { ut_a(dst_log_file != NULL); - ut_ad(recv_sys != NULL); + ut_ad(recv_sys.is_initialised()); lsn_t start_lsn; lsn_t end_lsn; - recv_sys->parse_start_lsn = log_copy_scanned_lsn; - recv_sys->scanned_lsn = log_copy_scanned_lsn; + recv_sys.parse_start_lsn = log_copy_scanned_lsn; + recv_sys.scanned_lsn = log_copy_scanned_lsn; start_lsn = ut_uint64_align_down(log_copy_scanned_lsn, OS_FILE_LOG_BLOCK_SIZE); @@ -2749,15 +2755,15 @@ static bool xtrabackup_copy_logfile(bool last = false) if (lsn == start_lsn) { start_lsn = 0; } else { - mutex_enter(&recv_sys->mutex); + mutex_enter(&recv_sys.mutex); start_lsn = xtrabackup_copy_log(start_lsn, lsn, last); - mutex_exit(&recv_sys->mutex); + mutex_exit(&recv_sys.mutex); } log_mutex_exit(); if (!start_lsn) { - die(recv_sys->found_corrupt_log + die(recv_sys.found_corrupt_log ? "xtrabackup_copy_logfile() failed: corrupt log." : "xtrabackup_copy_logfile() failed."); return true; @@ -3106,7 +3112,7 @@ xb_load_single_table_tablespace( ut_a(node_size != (os_offset_t) -1); - n_pages = node_size / page_size_t(file->flags()).physical(); + n_pages = node_size / fil_space_t::physical_size(file->flags()); space = fil_space_create( name, file->space_id(), file->flags(), @@ -3284,7 +3290,8 @@ static dberr_t xb_assign_undo_space_start() bool ret; dberr_t error = DB_SUCCESS; ulint space; - int n_retries = 5; + int n_retries = 5; + ulint fsp_flags; if (srv_undo_tablespaces == 0) { return error; @@ -3301,6 +3308,15 @@ static dberr_t xb_assign_undo_space_start() buf = static_cast<byte*>(ut_malloc_nokey(2U << srv_page_size_shift)); page = static_cast<byte*>(ut_align(buf, srv_page_size)); + if (os_file_read(IORequestRead, file, page, 0, srv_page_size) + != DB_SUCCESS) { + msg("Reading first page failed.\n"); + error = DB_ERROR; + goto func_exit; + } + + fsp_flags = mach_read_from_4( + page + FSP_HEADER_OFFSET + FSP_SPACE_FLAGS); retry: if (os_file_read(IORequestRead, file, page, TRX_SYS_PAGE_NO << srv_page_size_shift, @@ -3311,7 +3327,7 @@ retry: } /* TRX_SYS page can't be compressed or encrypted. */ - if (buf_page_is_corrupted(false, page, univ_page_size)) { + if (buf_page_is_corrupted(false, page, fsp_flags)) { if (n_retries--) { os_thread_sleep(1000); goto retry; @@ -3330,9 +3346,9 @@ retry: + TRX_SYS_RSEG_PAGE_NO + page) != FIL_NULL); - space = mach_read_ulint(TRX_SYS + TRX_SYS_RSEGS - + TRX_SYS_RSEG_SLOT_SIZE - + TRX_SYS_RSEG_SPACE + page, MLOG_4BYTES); + space = mach_read_from_4(TRX_SYS + TRX_SYS_RSEGS + + TRX_SYS_RSEG_SLOT_SIZE + + TRX_SYS_RSEG_SPACE + page); srv_undo_space_id_start = space; @@ -4062,7 +4078,7 @@ fail: ut_crc32_init(); crc_init(); - recv_sys_init(); + recv_sys.create(); #ifdef WITH_INNODB_DISALLOW_WRITES srv_allow_writes_event = os_event_create(0); @@ -4222,9 +4238,8 @@ fail_before_log_copying_thread_start: /* copy log file by current position */ log_copy_scanned_lsn = checkpoint_lsn_start; - recv_sys->recovered_lsn = log_copy_scanned_lsn; + recv_sys.recovered_lsn = log_copy_scanned_lsn; log_optimized_ddl_op = backup_optimized_ddl_op; - log_truncate = backup_truncate_fail; if (xtrabackup_copy_logfile()) goto fail_before_log_copying_thread_start; @@ -4254,7 +4269,7 @@ fail_before_log_copying_thread_start: DBUG_EXECUTE_IF("check_mdl_lock_works", dbug_alter_thread_done = dbug_start_query_thread("ALTER TABLE test.t ADD COLUMN mdl_lock_column int", - "Waiting for table metadata lock", 1, ER_QUERY_INTERRUPTED);); + "Waiting for table metadata lock", 0, 0);); } datafiles_iter_t *it = datafiles_iter_new(); @@ -4472,6 +4487,7 @@ void backup_fix_ddl(void) } datafiles_iter_free(it); + DBUG_EXECUTE_IF("check_mdl_lock_works", DBUG_ASSERT(new_tables.size() == 0);); for (std::set<std::string>::iterator iter = new_tables.begin(); iter != new_tables.end(); iter++) { const char *space_name = iter->c_str(); @@ -4583,16 +4599,17 @@ xb_space_create_file( fsp_header_init_fields(page, space_id, flags); mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, space_id); - const page_size_t page_size(flags); + const ulint zip_size = fil_space_t::zip_size(flags); - if (!page_size.is_compressed()) { - buf_flush_init_for_writing(NULL, page, NULL, 0); + if (!zip_size) { + buf_flush_init_for_writing( + NULL, page, NULL, 0, + fil_space_t::full_crc32(flags)); ret = os_file_write(IORequestWrite, path, *file, page, 0, srv_page_size); } else { page_zip_des_t page_zip; - ulint zip_size = page_size.physical(); page_zip_set_size(&page_zip, zip_size); page_zip.data = page + srv_page_size; fprintf(stderr, "zip_size = " ULINTPF "\n", zip_size); @@ -4603,7 +4620,7 @@ xb_space_create_file( page_zip.m_end = page_zip.m_nonempty = page_zip.n_blobs = 0; - buf_flush_init_for_writing(NULL, page, &page_zip, 0); + buf_flush_init_for_writing(NULL, page, &page_zip, 0, false); ret = os_file_write(IORequestWrite, path, *file, page_zip.data, 0, zip_size); @@ -4769,19 +4786,20 @@ exit: } /* No matching space found. create the new one. */ - const ulint flags = info.page_size.is_compressed() - ? get_bit_shift(info.page_size.physical() + const ulint flags = info.zip_size + ? get_bit_shift(info.page_size >> (UNIV_ZIP_SIZE_SHIFT_MIN - 1)) << FSP_FLAGS_POS_ZIP_SSIZE | FSP_FLAGS_MASK_POST_ANTELOPE | FSP_FLAGS_MASK_ATOMIC_BLOBS - | (info.page_size.logical() == UNIV_PAGE_SIZE_ORIG + | (srv_page_size == UNIV_PAGE_SIZE_ORIG ? 0 - : get_bit_shift(info.page_size.logical() + : get_bit_shift(srv_page_size >> (UNIV_ZIP_SIZE_SHIFT_MIN - 1)) << FSP_FLAGS_POS_PAGE_SSIZE) : FSP_FLAGS_PAGE_SSIZE(); - ut_ad(page_size_t(flags).equals_to(info.page_size)); + ut_ad(fil_space_t::zip_size(flags) == info.zip_size); + ut_ad(fil_space_t::physical_size(flags) == info.page_size); if (fil_space_create(dest_space_name, info.space_id, flags, FIL_TYPE_TABLESPACE, 0)) { @@ -4818,7 +4836,7 @@ xtrabackup_apply_delta( ulint page_in_buffer; ulint incremental_buffers = 0; - xb_delta_info_t info(univ_page_size, SRV_TMP_SPACE_ID); + xb_delta_info_t info(srv_page_size, 0, SRV_TMP_SPACE_ID); ulint page_size; ulint page_size_shift; byte* incremental_buffer_base = NULL; @@ -4857,7 +4875,7 @@ xtrabackup_apply_delta( goto error; } - page_size = info.page_size.physical(); + page_size = info.page_size; page_size_shift = get_bit_shift(page_size); msg("page size for %s is %zu bytes", src_path, page_size); @@ -4905,9 +4923,9 @@ xtrabackup_apply_delta( /* first block of block cluster */ offset = ((incremental_buffers * (page_size / 4)) << page_size_shift); - success = os_file_read(IORequestRead, src_file, - incremental_buffer, offset, page_size); - if (success != DB_SUCCESS) { + if (os_file_read(IORequestRead, src_file, + incremental_buffer, offset, page_size) + != DB_SUCCESS) { goto error; } @@ -4937,10 +4955,10 @@ xtrabackup_apply_delta( ut_a(last_buffer || page_in_buffer == page_size / 4); /* read whole of the cluster */ - success = os_file_read(IORequestRead, src_file, - incremental_buffer, - offset, page_in_buffer * page_size); - if (success != DB_SUCCESS) { + if (os_file_read(IORequestRead, src_file, + incremental_buffer, + offset, page_in_buffer * page_size) + != DB_SUCCESS) { goto error; } @@ -4986,9 +5004,9 @@ xtrabackup_apply_delta( } } - success = os_file_write(IORequestWrite, - dst_path, dst_file, buf, off, page_size); - if (success != DB_SUCCESS) { + if (os_file_write(IORequestWrite, + dst_path, dst_file, buf, off, + page_size) != DB_SUCCESS) { goto error; } } @@ -5131,7 +5149,7 @@ xb_process_datadir( handle_datadir_entry_func_t func) /*!<in: callback */ { ulint ret; - char dbpath[OS_FILE_MAX_PATH+1]; + char dbpath[OS_FILE_MAX_PATH+2]; os_file_dir_t dir; os_file_dir_t dbdir; os_file_stat_t dbinfo; @@ -5466,7 +5484,7 @@ static bool xtrabackup_prepare_func(char** argv) sync_check_init(); ut_d(sync_check_enable()); ut_crc32_init(); - recv_sys_init(); + recv_sys.create(); log_sys.create(); recv_recovery_on = true; @@ -5703,26 +5721,24 @@ int check_privilege( } -/******************************************************************//** +/** Check DB user privileges according to the intended actions. Fetches DB user privileges, determines intended actions based on command-line arguments and prints missing privileges. -May terminate application with EXIT_FAILURE exit code.*/ -static void -check_all_privileges() +@return whether all the necessary privileges are granted */ +static bool check_all_privileges() { if (!mysql_connection) { /* Not connected, no queries is going to be executed. */ - return; + return true; } /* Fetch effective privileges. */ std::list<std::string> granted_privileges; - MYSQL_ROW row = 0; MYSQL_RES* result = xb_mysql_query(mysql_connection, "SHOW GRANTS", - true); - while ((row = mysql_fetch_row(result))) { + true); + while (MYSQL_ROW row = mysql_fetch_row(result)) { granted_privileges.push_back(*row); } mysql_free_result(result); @@ -5735,13 +5751,9 @@ check_all_privileges() check_result |= check_privilege( granted_privileges, "RELOAD", "*", "*"); - } - - if (!opt_no_lock) - { check_result |= check_privilege( granted_privileges, - "PROCESS", "*", "*"); + "PROCESS", "*", "*"); } /* KILL ... */ @@ -5765,7 +5777,6 @@ check_all_privileges() } if (check_result & PRIVILEGE_ERROR) { - mysql_close(mysql_connection); msg("Current privileges, as reported by 'SHOW GRANTS': "); int n=1; for (std::list<std::string>::const_iterator it = granted_privileges.begin(); @@ -5773,8 +5784,10 @@ check_all_privileges() it++,n++) { msg(" %d.%s", n, it->c_str()); } - die("Insufficient privileges"); + return false; } + + return true; } bool @@ -5841,8 +5854,8 @@ xb_init() if (!get_mysql_vars(mysql_connection)) { return(false); } - if (opt_check_privileges) { - check_all_privileges(); + if (opt_check_privileges && !check_all_privileges()) { + return(false); } history_start_time = time(NULL); |