Commit 2637dda6 authored by Sergei Golubchik's avatar Sergei Golubchik

merged

parents d5c0d257 9653feb1
...@@ -240,7 +240,7 @@ select hex(s1) from t1; ...@@ -240,7 +240,7 @@ select hex(s1) from t1;
hex(s1) hex(s1)
41 41
drop table t1; drop table t1;
create table t1 (a text character set utf8, primary key(a(360))); create table t1 (a text character set utf8, primary key(a(371)));
ERROR 42000: Specified key was too long; max key length is 1000 bytes ERROR 42000: Specified key was too long; max key length is 1000 bytes
CREATE TABLE t1 ( a varchar(10) ) CHARACTER SET utf8; CREATE TABLE t1 ( a varchar(10) ) CHARACTER SET utf8;
INSERT INTO t1 VALUES ( 'test' ); INSERT INTO t1 VALUES ( 'test' );
......
...@@ -164,7 +164,7 @@ drop table t1; ...@@ -164,7 +164,7 @@ drop table t1;
# UTF8 breaks primary keys for cols > 333 characters # UTF8 breaks primary keys for cols > 333 characters
# #
--error 1071 --error 1071
create table t1 (a text character set utf8, primary key(a(360))); create table t1 (a text character set utf8, primary key(a(371)));
# #
......
...@@ -2381,7 +2381,8 @@ int ha_maria::external_lock(THD *thd, int lock_type) ...@@ -2381,7 +2381,8 @@ int ha_maria::external_lock(THD *thd, int lock_type)
Note that we can come here without having an exclusive lock on the Note that we can come here without having an exclusive lock on the
table, for example in this case: table, for example in this case:
external_lock(F_(WR|RD)LCK); thr_lock() which fails due to lock external_lock(F_(WR|RD)LCK); thr_lock() which fails due to lock
abortion; external_lock(F_UNLCK). abortion; external_lock(F_UNLCK). Fortunately, the re-enabling happens
only if we were the thread which disabled logging.
*/ */
if (_ma_reenable_logging_for_table(file, TRUE)) if (_ma_reenable_logging_for_table(file, TRUE))
DBUG_RETURN(1); DBUG_RETURN(1);
......
...@@ -122,6 +122,7 @@ static inline MARIA_RECORD_POS ma_recordpos(pgcache_page_no_t page, ...@@ -122,6 +122,7 @@ static inline MARIA_RECORD_POS ma_recordpos(pgcache_page_no_t page,
uint dir_entry) uint dir_entry)
{ {
DBUG_ASSERT(dir_entry <= 255); DBUG_ASSERT(dir_entry <= 255);
DBUG_ASSERT(page > 0); /* page 0 is bitmap, not data page */
return (MARIA_RECORD_POS) (((ulonglong) page << 8) | dir_entry); return (MARIA_RECORD_POS) (((ulonglong) page << 8) | dir_entry);
} }
......
...@@ -653,6 +653,14 @@ pthread_handler_t ma_checkpoint_background(void *arg) ...@@ -653,6 +653,14 @@ pthread_handler_t ma_checkpoint_background(void *arg)
We use FLUSH_KEEP_LAZY: if a file is already in flush, it's We use FLUSH_KEEP_LAZY: if a file is already in flush, it's
smarter to move to the next file than wait for this one to be smarter to move to the next file than wait for this one to be
completely flushed, which may take long. completely flushed, which may take long.
StaleFilePointersInFlush: notice how below we use "dfile" which
is an OS file descriptor plus some function and MARIA_SHARE
pointers; this data dates from a previous checkpoint; since then,
the table may have been closed (so MARIA_SHARE* became stale), and
the file descriptor reassigned to another table which does not
have the same CRC-read-set callbacks: it is thus important that
flush_pagecache_blocks_with_filter() does not use the pointers,
only the OS file descriptor.
*/ */
int res= int res=
flush_pagecache_blocks_with_filter(maria_pagecache, flush_pagecache_blocks_with_filter(maria_pagecache,
......
...@@ -592,7 +592,11 @@ int _ma_flush_table_files(MARIA_HA *info, uint flush_data_or_index, ...@@ -592,7 +592,11 @@ int _ma_flush_table_files(MARIA_HA *info, uint flush_data_or_index,
error= 1; error= 1;
} }
else else
info->s->bitmap.changed= 0; {
pthread_mutex_lock(&share->bitmap.bitmap_lock);
share->bitmap.changed= 0;
pthread_mutex_unlock(&share->bitmap.bitmap_lock);
}
if (flush_pagecache_blocks(share->pagecache, &info->dfile, if (flush_pagecache_blocks(share->pagecache, &info->dfile,
flush_type_for_data)) flush_type_for_data))
error= 1; error= 1;
......
...@@ -391,9 +391,15 @@ int _ma_mark_file_changed(MARIA_HA *info) ...@@ -391,9 +391,15 @@ int _ma_mark_file_changed(MARIA_HA *info)
{ {
uchar buff[3]; uchar buff[3];
register MARIA_SHARE *share= info->s; register MARIA_SHARE *share= info->s;
int error= 1;
DBUG_ENTER("_ma_mark_file_changed"); DBUG_ENTER("_ma_mark_file_changed");
if (!(share->state.changed & STATE_CHANGED) || ! share->global_changed) #define _MA_ALREADY_MARKED_FILE_CHANGED \
((share->state.changed & STATE_CHANGED) && share->global_changed)
if (_MA_ALREADY_MARKED_FILE_CHANGED)
DBUG_RETURN(0);
pthread_mutex_lock(&share->intern_lock); /* recheck under mutex */
if (! _MA_ALREADY_MARKED_FILE_CHANGED)
{ {
share->state.changed|=(STATE_CHANGED | STATE_NOT_ANALYZED | share->state.changed|=(STATE_CHANGED | STATE_NOT_ANALYZED |
STATE_NOT_OPTIMIZED_KEYS); STATE_NOT_OPTIMIZED_KEYS);
...@@ -420,7 +426,7 @@ int _ma_mark_file_changed(MARIA_HA *info) ...@@ -420,7 +426,7 @@ int _ma_mark_file_changed(MARIA_HA *info)
sizeof(share->state.header) + sizeof(share->state.header) +
MARIA_FILE_OPEN_COUNT_OFFSET, MARIA_FILE_OPEN_COUNT_OFFSET,
MYF(MY_NABP))) MYF(MY_NABP)))
DBUG_RETURN(1); goto err;
} }
/* Set uuid of file if not yet set (zerofilled file) */ /* Set uuid of file if not yet set (zerofilled file) */
if (share->base.born_transactional && if (share->base.born_transactional &&
...@@ -432,11 +438,15 @@ int _ma_mark_file_changed(MARIA_HA *info) ...@@ -432,11 +438,15 @@ int _ma_mark_file_changed(MARIA_HA *info)
_ma_update_state_lsns_sub(share, LSN_IMPOSSIBLE, _ma_update_state_lsns_sub(share, LSN_IMPOSSIBLE,
trnman_get_min_trid(), trnman_get_min_trid(),
TRUE, TRUE))) TRUE, TRUE)))
DBUG_RETURN(1); goto err;
share->state.changed|= STATE_NOT_MOVABLE; share->state.changed|= STATE_NOT_MOVABLE;
} }
} }
DBUG_RETURN(0); error= 0;
err:
pthread_mutex_unlock(&share->intern_lock);
DBUG_RETURN(error);
#undef _MA_ALREADY_MARKED_FILE_CHANGED
} }
/* /*
......
...@@ -4227,11 +4227,11 @@ static int flush_cached_blocks(PAGECACHE *pagecache, ...@@ -4227,11 +4227,11 @@ static int flush_cached_blocks(PAGECACHE *pagecache,
@todo IO If page is contiguous with next page to flush, group flushes @todo IO If page is contiguous with next page to flush, group flushes
in one single my_pwrite(). in one single my_pwrite().
*/ */
/* /**
It is important to use block->hash_link->file below and not 'file', as It is important to use block->hash_link->file below and not 'file', as
the first one is right and the second may have different content (and the first one is right and the second may have different out-of-date
this matters for callbacks, bitmap pages and data pages have different content (see StaleFilePointersInFlush in ma_checkpoint.c).
ones). @todo change argument of functions to be File.
*/ */
error= pagecache_fwrite(pagecache, &block->hash_link->file, error= pagecache_fwrite(pagecache, &block->hash_link->file,
block->buffer, block->buffer,
......
...@@ -3326,7 +3326,10 @@ void _ma_tmp_disable_logging_for_table(MARIA_HA *info, ...@@ -3326,7 +3326,10 @@ void _ma_tmp_disable_logging_for_table(MARIA_HA *info,
/** /**
Re-enables logging for a table which had it temporarily disabled. Re-enables logging for a table which had it temporarily disabled.
Only the thread which disabled logging is allowed to reenable it. Only the thread which disabled logging is allowed to reenable it. Indeed,
re-enabling logging affects all open instances, one must have exclusive
access to the table to do that. In practice, the one which disables has
such access.
@param info table @param info table
@param flush_pages if function needs to flush pages first @param flush_pages if function needs to flush pages first
......
...@@ -433,7 +433,7 @@ int maria_rtree_get_first(MARIA_HA *info, uint keynr, uint key_length) ...@@ -433,7 +433,7 @@ int maria_rtree_get_first(MARIA_HA *info, uint keynr, uint key_length)
info->maria_rtree_recursion_depth= -1; info->maria_rtree_recursion_depth= -1;
info->keyread_buff_used= 1; info->keyread_buff_used= 1;
return maria_rtree_get_req(info, &keyinfo[keynr], key_length, root, 0); return maria_rtree_get_req(info, keyinfo, key_length, root, 0);
} }
......
...@@ -378,6 +378,7 @@ err1: ...@@ -378,6 +378,7 @@ err1:
int rtree_get_first(MI_INFO *info, uint keynr, uint key_length) int rtree_get_first(MI_INFO *info, uint keynr, uint key_length)
{ {
my_off_t root; my_off_t root;
MI_KEYDEF *keyinfo = info->s->keyinfo + keynr;
if ((root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR) if ((root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
{ {
...@@ -388,7 +389,7 @@ int rtree_get_first(MI_INFO *info, uint keynr, uint key_length) ...@@ -388,7 +389,7 @@ int rtree_get_first(MI_INFO *info, uint keynr, uint key_length)
info->rtree_recursion_depth = -1; info->rtree_recursion_depth = -1;
info->buff_used = 1; info->buff_used = 1;
return rtree_get_req(info, info->s->keyinfo, key_length, root, 0); return rtree_get_req(info, keyinfo, key_length, root, 0);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment