mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 20:42:30 +01:00
0db0e64f33
MAP 'REPAIR TABLE' TO RECREATE +ANALYZE FOR ENGINES NOT SUPPORTING NATIVE REPAIR Executing 'mysqlcheck --check-upgrade --auto-repair ...' will first issue 'CHECK TABLE FOR UPGRADE' for all tables in the database in order to check if the tables are compatible with the current version of MySQL. Any tables that are found incompatible are then upgraded using 'REPAIR TABLE'. The problem was that some engines (e.g. InnoDB) do not support 'REPAIR TABLE'. This caused any such tables to be left incompatible. As a result such tables were not properly fixed by the mysql_upgrade tool. This patch fixes the problem by first changing 'CHECK TABLE FOR UPGRADE' to return a different error message if the engine does not support REPAIR. Instead of "Table upgrade required. Please do "REPAIR TABLE ..." it will report "Table rebuild required. Please do "ALTER TABLE ... FORCE ..." Second, the patch changes mysqlcheck to do 'ALTER TABLE ... FORCE' instead of 'REPAIR TABLE' in these cases. This patch also fixes 'ALTER TABLE ... FORCE' to actually rebuild the table. This change should be reflected in the documentation. Before this patch, 'ALTER TABLE ... FORCE' was unused (See Bug#11746162) Test case added to mysqlcheck.test client/mysqlcheck.c: Changed mysqlcheck to do 'ALTER TABLE ... FORCE' if 'CHECK TABLE FOR UPGRADE' reports ER_TABLE_NEEDS_REBUILD and not ER_TABLE_NEEDS_UPGRADE. mysql-test/r/mysqlcheck.result: Added regression test. mysql-test/std_data/bug47205.frm: InnoDB 5.0 FRM which contains a varchar primary key using utf8_general_ci. This is an incompatible FRM for 5.5. mysql-test/t/mysqlcheck.test: Added regression test. sql/handler.h: Added new HA_CAN_REPAIR flag. sql/share/errmsg-utf8.txt: Added new error message ER_TABLE_NEEDS_REBUILD sql/sql_admin.cc: Changed 'CHECK TABLE FOR UPDATE' to give ER_TABLE_NEEDS_REBUILD instead of ER_TABLE_NEEDS_UPGRADE if the engine does not support REPAIR (as indicated by the new HA_CAN_REPAIR flag). sql/sql_lex.h: Remove unused ALTER_FORCE flag. sql/sql_yacc.yy: Make sure ALTER TABLE ... FORCE recreates the table by setting the ALTER_RECREATE flag as the ALTER_FORCE flag was unused. storage/archive/ha_archive.h: Added new HA_CAN_REPAIR flag to Archive storage/csv/ha_tina.h: Added new HA_CAN_REPAIR flag to CSV storage/federated/ha_federated.h: Added new HA_CAN_REPAIR flag to Federated storage/myisam/ha_myisam.cc: Added new HA_CAN_REPAIR flag to MyISAM
175 lines
5.7 KiB
C++
175 lines
5.7 KiB
C++
/* Copyright (C) 2003 MySQL AB, 2008-2009 Sun Microsystems, Inc
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; version 2 of the License.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <my_dir.h>
|
|
#include "transparent_file.h"
|
|
|
|
#define DEFAULT_CHAIN_LENGTH 512
|
|
/*
|
|
Version for file format.
|
|
1 - Initial Version. That is, the version when the metafile was introduced.
|
|
*/
|
|
|
|
#define TINA_VERSION 1
|
|
|
|
typedef struct st_tina_share {
|
|
char *table_name;
|
|
char data_file_name[FN_REFLEN];
|
|
uint table_name_length, use_count;
|
|
/*
|
|
Below flag is needed to make log tables work with concurrent insert.
|
|
For more details see comment to ha_tina::update_status.
|
|
*/
|
|
my_bool is_log_table;
|
|
/*
|
|
Here we save the length of the file for readers. This is updated by
|
|
inserts, updates and deletes. The var is initialized along with the
|
|
share initialization.
|
|
*/
|
|
my_off_t saved_data_file_length;
|
|
mysql_mutex_t mutex;
|
|
THR_LOCK lock;
|
|
bool update_file_opened;
|
|
bool tina_write_opened;
|
|
File meta_file; /* Meta file we use */
|
|
File tina_write_filedes; /* File handler for readers */
|
|
bool crashed; /* Meta file is crashed */
|
|
ha_rows rows_recorded; /* Number of rows in tables */
|
|
uint data_file_version; /* Version of the data file used */
|
|
} TINA_SHARE;
|
|
|
|
struct tina_set {
|
|
my_off_t begin;
|
|
my_off_t end;
|
|
};
|
|
|
|
class ha_tina: public handler
|
|
{
|
|
THR_LOCK_DATA lock; /* MySQL lock */
|
|
TINA_SHARE *share; /* Shared lock info */
|
|
my_off_t current_position; /* Current position in the file during a file scan */
|
|
my_off_t next_position; /* Next position in the file scan */
|
|
my_off_t local_saved_data_file_length; /* save position for reads */
|
|
my_off_t temp_file_length;
|
|
uchar byte_buffer[IO_SIZE];
|
|
Transparent_file *file_buff;
|
|
File data_file; /* File handler for readers */
|
|
File update_temp_file;
|
|
String buffer;
|
|
/*
|
|
The chain contains "holes" in the file, occured because of
|
|
deletes/updates. It is used in rnd_end() to get rid of them
|
|
in the end of the query.
|
|
*/
|
|
tina_set chain_buffer[DEFAULT_CHAIN_LENGTH];
|
|
tina_set *chain;
|
|
tina_set *chain_ptr;
|
|
uchar chain_alloced;
|
|
uint32 chain_size;
|
|
uint local_data_file_version; /* Saved version of the data file used */
|
|
bool records_is_known;
|
|
MEM_ROOT blobroot;
|
|
|
|
private:
|
|
bool get_write_pos(my_off_t *end_pos, tina_set *closest_hole);
|
|
int open_update_temp_file_if_needed();
|
|
int init_tina_writer();
|
|
int init_data_file();
|
|
|
|
public:
|
|
ha_tina(handlerton *hton, TABLE_SHARE *table_arg);
|
|
~ha_tina()
|
|
{
|
|
if (chain_alloced)
|
|
my_free(chain);
|
|
if (file_buff)
|
|
delete file_buff;
|
|
free_root(&blobroot, MYF(0));
|
|
}
|
|
const char *table_type() const { return "CSV"; }
|
|
const char *index_type(uint inx) { return "NONE"; }
|
|
const char **bas_ext() const;
|
|
ulonglong table_flags() const
|
|
{
|
|
return (HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ | HA_NO_AUTO_INCREMENT |
|
|
HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
|
|
HA_CAN_REPAIR);
|
|
}
|
|
ulong index_flags(uint idx, uint part, bool all_parts) const
|
|
{
|
|
/*
|
|
We will never have indexes so this will never be called(AKA we return
|
|
zero)
|
|
*/
|
|
return 0;
|
|
}
|
|
uint max_record_length() const { return HA_MAX_REC_LENGTH; }
|
|
uint max_keys() const { return 0; }
|
|
uint max_key_parts() const { return 0; }
|
|
uint max_key_length() const { return 0; }
|
|
/*
|
|
Called in test_quick_select to determine if indexes should be used.
|
|
*/
|
|
virtual double scan_time() { return (double) (stats.records+stats.deleted) / 20.0+10; }
|
|
/* The next method will never be called */
|
|
virtual bool fast_key_read() { return 1;}
|
|
/*
|
|
TODO: return actual upper bound of number of records in the table.
|
|
(e.g. save number of records seen on full table scan and/or use file size
|
|
as upper bound)
|
|
*/
|
|
ha_rows estimate_rows_upper_bound() { return HA_POS_ERROR; }
|
|
|
|
int open(const char *name, int mode, uint open_options);
|
|
int close(void);
|
|
int write_row(uchar * buf);
|
|
int update_row(const uchar * old_data, uchar * new_data);
|
|
int delete_row(const uchar * buf);
|
|
int rnd_init(bool scan=1);
|
|
int rnd_next(uchar *buf);
|
|
int rnd_pos(uchar * buf, uchar *pos);
|
|
bool check_and_repair(THD *thd);
|
|
int check(THD* thd, HA_CHECK_OPT* check_opt);
|
|
bool is_crashed() const;
|
|
int rnd_end();
|
|
int repair(THD* thd, HA_CHECK_OPT* check_opt);
|
|
/* This is required for SQL layer to know that we support autorepair */
|
|
bool auto_repair() const { return 1; }
|
|
void position(const uchar *record);
|
|
int info(uint);
|
|
int extra(enum ha_extra_function operation);
|
|
int delete_all_rows(void);
|
|
int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info);
|
|
bool check_if_incompatible_data(HA_CREATE_INFO *info,
|
|
uint table_changes);
|
|
|
|
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
|
|
enum thr_lock_type lock_type);
|
|
|
|
/*
|
|
These functions used to get/update status of the handler.
|
|
Needed to enable concurrent inserts.
|
|
*/
|
|
void get_status();
|
|
void update_status();
|
|
|
|
/* The following methods were added just for TINA */
|
|
int encode_quote(uchar *buf);
|
|
int find_current_row(uchar *buf);
|
|
int chain_append();
|
|
};
|
|
|