summaryrefslogtreecommitdiff
path: root/storage/maria/ma_open.c
diff options
context:
space:
mode:
Diffstat (limited to 'storage/maria/ma_open.c')
-rw-r--r--storage/maria/ma_open.c257
1 files changed, 189 insertions, 68 deletions
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index 670588e4dd2..255332a926a 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -23,6 +23,7 @@
#include "ma_trnman.h"
#include <m_ctype.h>
#include "ma_crypt.h"
+#include "s3_func.h"
#if defined(MSDOS) || defined(__WIN__)
#ifdef __WIN__
@@ -91,7 +92,8 @@ MARIA_HA *_ma_test_if_reopen(const char *filename)
static MARIA_HA *maria_clone_internal(MARIA_SHARE *share,
int mode, File data_file,
- uint internal_table)
+ uint internal_table,
+ struct ms3_st *s3)
{
int save_errno;
uint errpos;
@@ -129,6 +131,7 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share,
goto err;
errpos= 6;
+ info.s3= s3;
memcpy(info.blobs,share->blobs,sizeof(MARIA_BLOB)*share->base.blobs);
info.lastkey_buff2= info.lastkey_buff + share->base.max_key_length;
info.last_key.data= info.lastkey_buff;
@@ -237,6 +240,7 @@ err:
case 6:
(*share->end)(&info);
delete_dynamic(&info.pinned_pages);
+ my_free(m_info->s3);
my_free(m_info);
/* fall through */
case 5:
@@ -258,9 +262,10 @@ err:
have an open count of 0.
******************************************************************************/
-MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
+MARIA_HA *maria_open(const char *name, int mode, uint open_flags,
+ S3_INFO *s3)
{
- int kfile,open_mode,save_errno;
+ int open_mode,save_errno;
uint i,j,len,errpos,head_length,base_pos,keys, realpath_err,
key_parts,base_key_parts,unique_key_parts,fulltext_keys,uniques;
uint internal_table= MY_TEST(open_flags & HA_OPEN_INTERNAL_TABLE);
@@ -276,28 +281,49 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
my_off_t key_root[HA_MAX_POSSIBLE_KEY];
ulonglong max_key_file_length, max_data_file_length;
my_bool versioning= 1;
- File data_file= -1;
+ File data_file= -1, kfile= -1;
+ struct ms3_st *s3_client= 0;
+ S3_INFO *share_s3= 0;
+ S3_BLOCK index_header;
DBUG_ENTER("maria_open");
- kfile= -1;
errpos= 0;
head_length=sizeof(share_buff.state.header);
bzero((uchar*) &info,sizeof(info));
+ bzero((uchar*) &index_header, sizeof(index_header));
- realpath_err= my_realpath(name_buff, fn_format(org_name, name, "",
- MARIA_NAME_IEXT,
- MY_UNPACK_FILENAME),MYF(0));
- if (realpath_err > 0) /* File not found, no point in looking further. */
+#ifndef WITH_S3_STORAGE_ENGINE
+ DBUG_ASSERT(!s3);
+#endif /* WITH_S3_STORAGE_ENGINE */
+
+ if (!s3)
{
- DBUG_RETURN(NULL);
- }
+ realpath_err= my_realpath(name_buff, fn_format(org_name, name, "",
+ MARIA_NAME_IEXT,
+ MY_UNPACK_FILENAME),MYF(0));
+ if (realpath_err > 0) /* File not found, no point in looking further. */
+ {
+ DBUG_RETURN(NULL);
+ }
- if (my_is_symlink(org_name) &&
- (realpath_err || mysys_test_invalid_symlink(name_buff)))
+ if (my_is_symlink(org_name) &&
+ (realpath_err || mysys_test_invalid_symlink(name_buff)))
+ {
+ my_errno= HA_WRONG_CREATE_OPTION;
+ DBUG_RETURN(0);
+ }
+ }
+#ifdef WITH_S3_STORAGE_ENGINE
+ else
{
- my_errno= HA_WRONG_CREATE_OPTION;
- DBUG_RETURN(0);
+ strmake(name_buff, name, sizeof(name_buff)-1); /* test_if_reopen() */
+ if (!(s3_client= s3_open_connection(s3)))
+ {
+ internal_table= 1; /* Avoid unlock on error */
+ goto err;
+ }
}
+#endif /* WITH_S3_STORAGE_ENGINE */
old_info= 0;
if (!internal_table)
@@ -312,32 +338,70 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
(uint) strlen(name_buff),
maria_pagecache);
- DBUG_EXECUTE_IF("maria_pretend_crashed_table_on_open",
- if (strstr(name, "/t1"))
- {
- my_errno= HA_ERR_CRASHED;
- goto err;
- });
- DEBUG_SYNC_C("mi_open_kfile");
- if ((kfile=mysql_file_open(key_file_kfile, name_buff,
- (open_mode=O_RDWR) | O_SHARE | O_NOFOLLOW | O_CLOEXEC,
- MYF(MY_NOSYMLINKS))) < 0)
+ if (!s3)
{
- if ((errno != EROFS && errno != EACCES) ||
- mode != O_RDONLY ||
- (kfile=mysql_file_open(key_file_kfile, name_buff,
- (open_mode=O_RDONLY) | O_SHARE | O_NOFOLLOW | O_CLOEXEC,
+ DBUG_EXECUTE_IF("maria_pretend_crashed_table_on_open",
+ if (strstr(name, "/t1"))
+ {
+ my_errno= HA_ERR_CRASHED;
+ goto err;
+ });
+ DEBUG_SYNC_C("mi_open_kfile");
+ if ((kfile=mysql_file_open(key_file_kfile, name_buff,
+ (open_mode=O_RDWR) | O_SHARE | O_NOFOLLOW | O_CLOEXEC,
MYF(MY_NOSYMLINKS))) < 0)
- goto err;
+ {
+ if ((errno != EROFS && errno != EACCES) ||
+ mode != O_RDONLY ||
+ (kfile=mysql_file_open(key_file_kfile, name_buff,
+ (open_mode=O_RDONLY) | O_SHARE | O_NOFOLLOW | O_CLOEXEC,
+ MYF(MY_NOSYMLINKS))) < 0)
+ goto err;
+ }
+ errpos= 1;
+ if (mysql_file_pread(kfile,share->state.header.file_version, head_length,
+ 0, MYF(MY_NABP)))
+ {
+ my_errno= HA_ERR_NOT_A_TABLE;
+ goto err;
+ }
}
- share->mode=open_mode;
- errpos= 1;
- if (mysql_file_pread(kfile,share->state.header.file_version, head_length,
- 0, MYF(MY_NABP)))
+#ifdef WITH_S3_STORAGE_ENGINE
+ else
{
- my_errno= HA_ERR_NOT_A_TABLE;
- goto err;
+ errpos= 1;
+ if (set_database_and_table_from_path(s3, name_buff))
+ {
+ my_printf_error(HA_ERR_NO_SUCH_TABLE,
+ "Can't find database and path from %s", MYF(0),
+ name_buff);
+ my_errno= HA_ERR_NO_SUCH_TABLE;
+ goto err;
+ }
+ if (!(share_s3= share->s3_path= s3_info_copy(s3)))
+ goto err; /* EiOM */
+
+ /* Check if table has changed in S3 */
+ if (s3_check_frm_version(s3_client, share_s3) == 1)
+ {
+ my_errno= HA_ERR_TABLE_DEF_CHANGED;
+ goto err;
+ }
+
+ if (read_index_header(s3_client, share_s3, &index_header))
+ goto err;
+ if (index_header.length < head_length)
+ {
+ my_errno=HA_ERR_NOT_A_TABLE;
+ goto err;
+ }
+ memcpy(share->state.header.file_version, index_header.str,
+ head_length);
+ kfile= s3_unique_file_number();
}
+#endif /* WITH_S3_STORAGE_ENGINE */
+
+ share->mode=open_mode;
if (memcmp(share->state.header.file_version, maria_file_magic, 4))
{
DBUG_PRINT("error",("Wrong header in %s",name_buff));
@@ -366,23 +430,31 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
my_errno= HA_ERR_UNSUPPORTED;
goto err;
}
- /* Don't call realpath() if the name can't be a link */
- if (!strcmp(name_buff, org_name) ||
- my_readlink(index_name, org_name, MYF(0)) == -1)
- (void) strmov(index_name, org_name);
- *strrchr(org_name, FN_EXTCHAR)= '\0';
- (void) fn_format(data_name,org_name,"",MARIA_NAME_DEXT,
- MY_APPEND_EXT|MY_UNPACK_FILENAME);
- if (my_is_symlink(data_name))
+ if (!s3)
{
- if (my_realpath(data_name, data_name, MYF(0)))
- goto err;
- if (mysys_test_invalid_symlink(data_name))
+ /* Don't call realpath() if the name can't be a link */
+ if (!strcmp(name_buff, org_name) ||
+ my_readlink(index_name, org_name, MYF(0)) == -1)
+ (void) strmov(index_name, org_name);
+ *strrchr(org_name, FN_EXTCHAR)= '\0';
+ (void) fn_format(data_name,org_name,"",MARIA_NAME_DEXT,
+ MY_APPEND_EXT|MY_UNPACK_FILENAME);
+ if (my_is_symlink(data_name))
{
- my_errno= HA_WRONG_CREATE_OPTION;
- goto err;
+ if (my_realpath(data_name, data_name, MYF(0)))
+ goto err;
+ if (mysys_test_invalid_symlink(data_name))
+ {
+ my_errno= HA_WRONG_CREATE_OPTION;
+ goto err;
+ }
+ share->mode|= O_NOFOLLOW; /* all symlinks are resolved by realpath() */
}
- share->mode|= O_NOFOLLOW; /* all symlinks are resolved by realpath() */
+ }
+ else
+ {
+ /* Don't show DIRECTORY in show create table */
+ index_name[0]= data_name[0]= 0;
}
info_length=mi_uint2korr(share->state.header.header_length);
@@ -400,11 +472,26 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
end_pos=disk_cache+info_length;
errpos= 3;
- if (mysql_file_pread(kfile, disk_cache, info_length, 0L, MYF(MY_NABP)))
+ if (!s3)
{
- _ma_set_fatal_error(share, HA_ERR_CRASHED);
- goto err;
+ if (mysql_file_pread(kfile, disk_cache, info_length, 0L, MYF(MY_NABP)))
+ {
+ _ma_set_fatal_error(share, HA_ERR_CRASHED);
+ goto err;
+ }
+ }
+#ifdef WITH_S3_STORAGE_ENGINE
+ else
+ {
+ if (index_header.length < info_length)
+ {
+ my_errno=HA_ERR_NOT_A_TABLE;
+ goto err;
+ }
+ memcpy(disk_cache, index_header.str, info_length);
}
+#endif /* WITH_S3_STORAGE_ENGINE */
+
len=mi_uint2korr(share->state.header.state_info_length);
keys= (uint) share->state.header.keys;
uniques= (uint) share->state.header.uniques;
@@ -435,7 +522,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
file_version= (share->state.header.not_used == 0);
if (file_version == 0)
share->base.language= share->state.header.not_used;
-
+
share->state.state_length=base_pos;
/* For newly opened tables we reset the error-has-been-printed flag */
share->state.changed&= ~STATE_CRASHED_PRINTED;
@@ -462,7 +549,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
- share->state.create_trid > trnman_get_max_trid()
- Critical as trid as stored releative to create_trid.
- uuid is different
-
+
STATE_NOT_MOVABLE is reset when a table is zerofilled
(has no LSN's and no trids)
@@ -526,7 +613,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
my_errno=HA_ERR_UNSUPPORTED;
my_printf_error(my_errno, "Wrong block size %u; Expected %u",
MYF(0),
- (uint) share->base.block_size,
+ (uint) share->base.block_size,
(uint) maria_block_size);
goto err;
}
@@ -870,9 +957,16 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
if ((share->data_file_type == BLOCK_RECORD ||
share->data_file_type == COMPRESSED_RECORD))
{
- if (_ma_open_datafile(&info, share))
- goto err;
- data_file= info.dfile.file;
+ if (!s3)
+ {
+ if (_ma_open_datafile(&info, share))
+ goto err;
+ data_file= info.dfile.file;
+ }
+#ifdef WITH_S3_STORAGE_ENGINE
+ else
+ data_file= info.dfile.file= s3_unique_file_number();
+#endif /* WITH_S3_STORAGE_ENGINE */
}
errpos= 5;
@@ -914,6 +1008,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
max_data_file_length= share->base.max_data_file_length;
if ((*share->once_init)(share, info.dfile.file))
goto err;
+ errpos= 6;
if (internal_table)
set_if_smaller(share->base.max_data_file_length,
max_data_file_length);
@@ -1042,6 +1137,13 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
info.s= share;
maria_extra(&info, HA_EXTRA_MMAP, 0);
}
+#ifdef WITH_S3_STORAGE_ENGINE
+ if (s3_client)
+ {
+ size_t block_size= share->base.s3_block_size;
+ ms3_set_option(s3_client, MS3_OPT_BUFFER_CHUNK_SIZE, &block_size);
+ }
+#endif /* WITH_S3_STORAGE_ENGINE */
}
else
{
@@ -1050,8 +1152,13 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
data_file= share->bitmap.file.file; /* Only opened once */
}
+#ifdef WITH_S3_STORAGE_ENGINE
+ if (index_header.alloc_ptr)
+ s3_free(&index_header);
+#endif /* WITH_S3_STORAGE_ENGINE */
+
if (!(m_info= maria_clone_internal(share, mode, data_file,
- internal_table)))
+ internal_table, s3_client)))
goto err;
if (maria_is_crashed(m_info))
@@ -1078,12 +1185,16 @@ err:
_ma_report_error(save_errno, &tmp_name);
}
switch (errpos) {
+ case 6:
+ /* Avoid mutex test in _ma_bitmap_end() */
+ share->internal_table= 1;
+ (*share->once_end)(share);
+ /* fall through */
case 5:
- if (data_file >= 0)
+ if (data_file >= 0 && !s3_client)
mysql_file_close(data_file, MYF(0));
if (old_info)
break; /* Don't remove open table */
- (*share->once_end)(share);
/* fall through */
case 4:
ma_crypt_free(share);
@@ -1094,12 +1205,20 @@ err:
my_free(share_buff.state.rec_per_key_part);
/* fall through */
case 1:
- mysql_file_close(kfile,MYF(0));
+ if (!s3)
+ mysql_file_close(kfile,MYF(0));
+ my_free(share_s3);
/* fall through */
case 0:
default:
break;
}
+#ifdef WITH_S3_STORAGE_ENGINE
+ if (s3_client)
+ ms3_deinit(s3_client);
+ if (index_header.alloc_ptr)
+ s3_free(&index_header);
+#endif /* WITH_S3_STORAGE_ENGINE */
if (!internal_table)
mysql_mutex_unlock(&THR_LOCK_maria);
my_errno= save_errno;
@@ -1633,14 +1752,15 @@ uint _ma_base_info_write(File file, MARIA_BASE_INFO *base)
*ptr++= base->keys;
*ptr++= base->auto_key;
*ptr++= base->born_transactional;
- *ptr++= 0; /* Reserved */
+ *ptr++= base->compression_algorithm;
mi_int2store(ptr,base->pack_bytes); ptr+= 2;
mi_int2store(ptr,base->blobs); ptr+= 2;
mi_int2store(ptr,base->max_key_block_length); ptr+= 2;
mi_int2store(ptr,base->max_key_length); ptr+= 2;
mi_int2store(ptr,base->extra_alloc_bytes); ptr+= 2;
*ptr++= base->extra_alloc_procent;
- bzero(ptr,16); ptr+= 16; /* extra */
+ mi_int3store(ptr, base->s3_block_size); ptr+= 3;
+ bzero(ptr,13); ptr+= 13; /* extra */
DBUG_ASSERT((ptr - buff) == MARIA_BASE_INFO_SIZE);
return mysql_file_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
}
@@ -1677,14 +1797,15 @@ static uchar *_ma_base_info_read(uchar *ptr, MARIA_BASE_INFO *base)
base->keys= *ptr++;
base->auto_key= *ptr++;
base->born_transactional= *ptr++;
- ptr++;
+ base->compression_algorithm= *ptr++;
base->pack_bytes= mi_uint2korr(ptr); ptr+= 2;
base->blobs= mi_uint2korr(ptr); ptr+= 2;
base->max_key_block_length= mi_uint2korr(ptr); ptr+= 2;
base->max_key_length= mi_uint2korr(ptr); ptr+= 2;
base->extra_alloc_bytes= mi_uint2korr(ptr); ptr+= 2;
base->extra_alloc_procent= *ptr++;
- ptr+= 16;
+ base->s3_block_size= mi_uint3korr(ptr); ptr+= 3;
+ ptr+= 13;
return ptr;
}
@@ -1835,7 +1956,7 @@ uchar *_ma_columndef_read(uchar *ptr, MARIA_COLUMNDEF *columndef)
columndef->empty_pos= mi_uint2korr(ptr); ptr+= 2;
columndef->null_bit= (uint8) *ptr++;
columndef->empty_bit= (uint8) *ptr++;
- high_offset= mi_uint2korr(ptr); ptr+= 2;
+ high_offset= mi_uint2korr(ptr); ptr+= 2;
columndef->offset|= ((ulong) high_offset << 16);
ptr+= 2;
return ptr;