summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2014-06-19 22:07:15 +0200
committerSergei Golubchik <serg@mariadb.org>2014-06-21 08:58:08 +0200
commit5f2e893161811b86de0062d66e04b426ed5b70c8 (patch)
tree4ae9c1a7de13f97079d72dadcb761b82bf9a2ae7
parent5f21e890b710470b3021c6290899266d38d7102d (diff)
downloadmariadb-git-5f2e893161811b86de0062d66e04b426ed5b70c8.tar.gz
archive: open ARZ files in external_lock, not in rnd_init/index_initbb-10.1-rediscover
-rw-r--r--mysql-test/suite/archive/archive_debug.result1
-rw-r--r--mysql-test/suite/archive/discover.test2
-rw-r--r--mysql-test/suite/archive/repair.result3
-rw-r--r--mysql-test/suite/archive/repair.test2
-rw-r--r--storage/archive/ha_archive.cc57
-rw-r--r--storage/archive/ha_archive.h20
6 files changed, 60 insertions, 25 deletions
diff --git a/mysql-test/suite/archive/archive_debug.result b/mysql-test/suite/archive/archive_debug.result
index 7bc6a113217..164b6f5197c 100644
--- a/mysql-test/suite/archive/archive_debug.result
+++ b/mysql-test/suite/archive/archive_debug.result
@@ -7,6 +7,7 @@ INSERT INTO t1 VALUES(1);
SET SESSION debug_dbug='d,simulate_archive_open_failure';
CHECK TABLE t1;
Table Op Msg_type Msg_text
+test.t1 check Error Table 't1' is marked as crashed and should be repaired
test.t1 check error Corrupt
SET SESSION debug_dbug=DEFAULT;
DROP TABLE t1;
diff --git a/mysql-test/suite/archive/discover.test b/mysql-test/suite/archive/discover.test
index 567a57c4978..5ea02f47119 100644
--- a/mysql-test/suite/archive/discover.test
+++ b/mysql-test/suite/archive/discover.test
@@ -146,7 +146,7 @@ remove_file $mysqld_datadir/test/t1.ARZ;
copy_file $MYSQL_TMP_DIR/t1.ARZ $mysqld_datadir/test/t1.ARZ;
remove_file $MYSQL_TMP_DIR/t1.ARZ;
show create table t1;
---error 1412
+--error ER_TABLE_DEF_CHANGED
select * from t1, t1 as t2;
flush tables;
select * from t1, t1 as t2;
diff --git a/mysql-test/suite/archive/repair.result b/mysql-test/suite/archive/repair.result
index 16f0f2c1608..6a738e20628 100644
--- a/mysql-test/suite/archive/repair.result
+++ b/mysql-test/suite/archive/repair.result
@@ -1,10 +1,11 @@
create table t1 (a int) engine=archive;
insert into t1 values (1);
select * from t1;
-Got one of the listed errors
+ERROR HY000: Can't lock file (errno: 2 "No such file or directory")
insert into t1 values (2);
ERROR HY000: Table 't1' is marked as crashed and should be repaired
repair table t1;
Table Op Msg_type Msg_text
+test.t1 repair Error Table 't1' is marked as crashed and should be repaired
test.t1 repair error Corrupt
drop table t1;
diff --git a/mysql-test/suite/archive/repair.test b/mysql-test/suite/archive/repair.test
index 03946d31ead..8eeb7912956 100644
--- a/mysql-test/suite/archive/repair.test
+++ b/mysql-test/suite/archive/repair.test
@@ -9,7 +9,7 @@
create table t1 (a int) engine=archive;
insert into t1 values (1);
--remove_file $datadir/test/t1.ARZ
---error 13,1017
+--error ER_CANT_LOCK
select * from t1;
--error ER_CRASHED_ON_USAGE
insert into t1 values (2);
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
index a0a3914232f..08e02130dc7 100644
--- a/storage/archive/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -133,6 +133,8 @@ static handler *archive_create_handler(handlerton *hton,
MEM_ROOT *mem_root);
int archive_discover(handlerton *hton, THD* thd, TABLE_SHARE *share);
+static int frm_compare(azio_stream *s, TABLE *table);
+
/*
Number of rows that will force a bulk insert.
*/
@@ -490,7 +492,7 @@ Archive_share *ha_archive::get_share(const char *table_name, int *rc)
share= tmp_share;
if (archive_tmp.version == 1)
share->read_v1_metafile();
- else if (frm_compare(&archive_tmp))
+ else if (frm_compare(&archive_tmp, table))
*rc= HA_ERR_TABLE_DEF_CHANGED;
azclose(&archive_tmp);
@@ -508,7 +510,7 @@ err:
}
-int Archive_share::init_archive_writer()
+int Archive_share::init_archive_writer(TABLE *table)
{
DBUG_ENTER("Archive_share::init_archive_writer");
/*
@@ -516,13 +518,18 @@ int Archive_share::init_archive_writer()
a gzip file that can be both read and written we keep a writer open
that is shared amoung all open tables.
*/
- if (!(azopen(&archive_write, data_file_name,
- O_RDWR|O_BINARY)))
+ if (!(azopen(&archive_write, data_file_name, O_RDWR|O_BINARY)))
{
DBUG_PRINT("ha_archive", ("Could not open archive write file"));
crashed= true;
DBUG_RETURN(1);
}
+ if (frm_compare(&archive_write, table))
+ {
+ azclose(&archive_write);
+ errno= HA_ERR_TABLE_DEF_CHANGED;
+ DBUG_RETURN(1);
+ }
archive_write_open= true;
DBUG_RETURN(0);
@@ -563,7 +570,7 @@ int ha_archive::init_archive_reader()
share->crashed= TRUE;
DBUG_RETURN(1);
}
- if (frm_compare(&archive))
+ if (frm_compare(&archive, table))
{
azclose(&archive);
errno= HA_ERR_TABLE_DEF_CHANGED;
@@ -666,6 +673,37 @@ int ha_archive::close(void)
}
+int ha_archive::external_lock(THD* thd, int lock_type)
+{
+ int rc= 0;
+ DBUG_ENTER("ha_archive::external_lock");
+
+ if (share->crashed)
+ DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
+
+ switch (lock_type)
+ {
+ case F_RDLCK:
+ if (!archive_reader_open && init_archive_reader())
+ rc= errno ? errno : HA_ERR_CRASHED_ON_USAGE;
+ break;
+ case F_WRLCK:
+ mysql_mutex_lock(&share->mutex);
+ if (!share->archive_write_open && share->init_archive_writer(table))
+ rc= errno ? errno : HA_ERR_CRASHED_ON_USAGE;
+ mysql_mutex_unlock(&share->mutex);
+ break;
+ case F_UNLCK:
+ break;
+ default:
+ DBUG_ASSERT(0);
+ rc= HA_ERR_WRONG_COMMAND;
+ }
+
+ DBUG_RETURN(rc);
+}
+
+
/**
Copy a frm blob between streams.
@@ -714,7 +752,7 @@ int ha_archive::frm_copy(azio_stream *src, azio_stream *dst)
@return Zero if equal, non-zero otherwise.
*/
-int ha_archive::frm_compare(azio_stream *s)
+static int frm_compare(azio_stream *s, TABLE *table)
{
if (!s->frmver_length)
return 0; // Old pre-10.0 archive table. Never rediscover.
@@ -959,16 +997,11 @@ int ha_archive::write_row(uchar *buf)
if (!share->archive_write_open)
{
- if (share->init_archive_writer())
+ if (share->init_archive_writer(table))
{
rc= errno;
goto error;
}
- else if (frm_compare(&share->archive_write))
- {
- rc= HA_ERR_TABLE_DEF_CHANGED;
- goto error;
- }
}
if (table->next_number_field && record == table->record[0])
diff --git a/storage/archive/ha_archive.h b/storage/archive/ha_archive.h
index 56ff566db8c..2c67e13616e 100644
--- a/storage/archive/ha_archive.h
+++ b/storage/archive/ha_archive.h
@@ -59,7 +59,7 @@ public:
thr_lock_delete(&lock);
mysql_mutex_destroy(&mutex);
}
- int init_archive_writer();
+ int init_archive_writer(TABLE *table);
void close_archive_writer();
int write_v1_metafile();
int read_v1_metafile();
@@ -94,7 +94,6 @@ class ha_archive: public handler
archive_record_buffer *create_record_buffer(unsigned int length);
void destroy_record_buffer(archive_record_buffer *r);
int frm_copy(azio_stream *src, azio_stream *dst);
- int frm_compare(azio_stream *src);
unsigned int pack_row_v1(uchar *record);
public:
@@ -115,19 +114,20 @@ public:
{
return HA_ONLY_WHOLE_INDEX;
}
- virtual void get_auto_increment(ulonglong offset, ulonglong increment,
- ulonglong nb_desired_values,
- ulonglong *first_value,
- ulonglong *nb_reserved_values);
+ void get_auto_increment(ulonglong offset, ulonglong increment,
+ ulonglong nb_desired_values,
+ ulonglong *first_value,
+ ulonglong *nb_reserved_values);
uint max_supported_keys() const { return 1; }
uint max_supported_key_length() const { return sizeof(ulonglong); }
uint max_supported_key_part_length() const { return sizeof(ulonglong); }
ha_rows records() { return share->rows_recorded; }
+ int external_lock(THD* thd, int lock_type);
int index_init(uint keynr, bool sorted);
- virtual int index_read(uchar * buf, const uchar * key,
- uint key_len, enum ha_rkey_function find_flag);
- virtual int index_read_idx(uchar * buf, uint index, const uchar * key,
- uint key_len, enum ha_rkey_function find_flag);
+ int index_read(uchar * buf, const uchar * key, uint key_len,
+ enum ha_rkey_function find_flag);
+ int index_read_idx(uchar * buf, uint index, const uchar * key,
+ uint key_len, enum ha_rkey_function find_flag);
int index_next(uchar * buf);
int open(const char *name, int mode, uint test_if_locked);
int close(void);