1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Merge remote-tracking branch 'origin/10.0' into 10.1

This commit is contained in:
Alexander Barkov
2018-06-19 14:04:53 +04:00
9 changed files with 251 additions and 35 deletions

View File

@ -713,6 +713,23 @@ a ct
set sql_mode=@save_sql_mode; set sql_mode=@save_sql_mode;
drop table t1; drop table t1;
# #
# mdev-16235: impossible HAVING in query without aggregation
#
explain extended
select * from mysql.help_topic where example = 'foo' having description is null;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible HAVING
Warnings:
Note 1003 select `mysql`.`help_topic`.`help_topic_id` AS `help_topic_id`,`mysql`.`help_topic`.`name` AS `name`,`mysql`.`help_topic`.`help_category_id` AS `help_category_id`,`mysql`.`help_topic`.`description` AS `description`,`mysql`.`help_topic`.`example` AS `example`,`mysql`.`help_topic`.`url` AS `url` from `mysql`.`help_topic` where (`mysql`.`help_topic`.`example` = 'foo') having 0
select * from mysql.help_topic where example = 'foo' having description is null;
help_topic_id name help_category_id description example url
#
# End of 5. tests
#
#
# Start of 10.0 tests
#
#
# Bug mdev-5160: two-way join with HAVING over the second table # Bug mdev-5160: two-way join with HAVING over the second table
# #
CREATE TABLE t1 (c1 varchar(6)) ENGINE=MyISAM; CREATE TABLE t1 (c1 varchar(6)) ENGINE=MyISAM;

Binary file not shown.

View File

@ -354,6 +354,16 @@ a b c
DROP TABLE t1; DROP TABLE t1;
SET sql_mode=DEFAULT; SET sql_mode=DEFAULT;
# #
# MDEV-15834 The code in TABLE_SHARE::init_from_binary_frm_image() is not safe
#
SHOW TABLES;
Tables_in_test
t1
SHOW CREATE TABLE t1;
ERROR HY000: Incorrect information in file: './test/t1.frm'
ALTER TABLE t1;
ERROR HY000: Incorrect information in file: './test/t1.frm'
#
# End of 5.5 tests # End of 5.5 tests
# #
# #

View File

@ -1,5 +1,7 @@
--source include/have_ucs2.inc --source include/have_ucs2.inc
let $MYSQLD_DATADIR= `select @@datadir`;
--disable_warnings --disable_warnings
drop table if exists t1,t2; drop table if exists t1,t2;
--enable_warnings --enable_warnings
@ -318,6 +320,20 @@ SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
SET sql_mode=DEFAULT; SET sql_mode=DEFAULT;
--echo #
--echo # MDEV-15834 The code in TABLE_SHARE::init_from_binary_frm_image() is not safe
--echo #
--copy_file std_data/frm/t1.frm $MYSQLD_DATADIR/test/t1.frm
SHOW TABLES;
--error ER_NOT_FORM_FILE
SHOW CREATE TABLE t1;
--error ER_NOT_FORM_FILE
ALTER TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.frm
--echo # --echo #
--echo # End of 5.5 tests --echo # End of 5.5 tests
--echo # --echo #

View File

@ -745,6 +745,23 @@ set sql_mode=@save_sql_mode;
drop table t1; drop table t1;
--echo #
--echo # mdev-16235: impossible HAVING in query without aggregation
--echo #
explain extended
select * from mysql.help_topic where example = 'foo' having description is null;
select * from mysql.help_topic where example = 'foo' having description is null;
--echo #
--echo # End of 5. tests
--echo #
--echo #
--echo # Start of 10.0 tests
--echo #
--echo # --echo #
--echo # Bug mdev-5160: two-way join with HAVING over the second table --echo # Bug mdev-5160: two-way join with HAVING over the second table
--echo # --echo #

View File

@ -5955,6 +5955,7 @@ bool JOIN::choose_tableless_subquery_plan()
functions produce empty subquery result. There is no need to further functions produce empty subquery result. There is no need to further
rewrite the subquery because it will not be executed at all. rewrite the subquery because it will not be executed at all.
*/ */
exec_const_cond= 0;
return FALSE; return FALSE;
} }
@ -5986,6 +5987,6 @@ bool JOIN::choose_tableless_subquery_plan()
tmp_having= having; tmp_having= having;
} }
} }
exec_const_cond= conds; exec_const_cond= zero_result_cause ? 0 : conds;
return FALSE; return FALSE;
} }

View File

@ -1261,7 +1261,6 @@ JOIN::optimize_inner()
{ {
DBUG_PRINT("info", ("Zero limit")); DBUG_PRINT("info", ("Zero limit"));
zero_result_cause= "Zero limit"; zero_result_cause= "Zero limit";
conds= 0;
} }
table_count= top_join_tab_count= 0; table_count= top_join_tab_count= 0;
error= 0; error= 0;

View File

@ -1533,7 +1533,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
if ((uchar)field_type == (uchar)MYSQL_TYPE_VIRTUAL) if ((uchar)field_type == (uchar)MYSQL_TYPE_VIRTUAL)
{ {
DBUG_ASSERT(interval_nr); // Expect non-null expression if (!interval_nr) // Expect non-null expression
goto err;
/* /*
The interval_id byte in the .frm file stores the length of the The interval_id byte in the .frm file stores the length of the
expression statement for a virtual column. expression statement for a virtual column.

View File

@ -78,6 +78,32 @@ typedef union
uchar buffer[TRANSLOG_PAGE_SIZE]; uchar buffer[TRANSLOG_PAGE_SIZE];
} TRANSLOG_PAGE_SIZE_BUFF; } TRANSLOG_PAGE_SIZE_BUFF;
#define MAX_TRUNSLOG_USED_BUFFERS 3
typedef struct
{
struct st_translog_buffer *buff[MAX_TRUNSLOG_USED_BUFFERS];
uint8 wrt_ptr;
uint8 unlck_ptr;
} TRUNSLOG_USED_BUFFERS;
static void
used_buffs_init(TRUNSLOG_USED_BUFFERS *buffs)
{
buffs->unlck_ptr= buffs->wrt_ptr= 0;
}
static void
used_buffs_add(TRUNSLOG_USED_BUFFERS *buffs,
struct st_translog_buffer *buff);
static void
used_buffs_register_unlock(TRUNSLOG_USED_BUFFERS *buffs,
struct st_translog_buffer *buff);
static void
used_buffs_urgent_unlock(TRUNSLOG_USED_BUFFERS *buffs);
/* min chunk length */ /* min chunk length */
#define TRANSLOG_MIN_CHUNK 3 #define TRANSLOG_MIN_CHUNK 3
/* /*
@ -156,7 +182,28 @@ struct st_translog_buffer
TRANSLOG_FILE *file; TRANSLOG_FILE *file;
/* Threads which are waiting for buffer filling/freeing */ /* Threads which are waiting for buffer filling/freeing */
mysql_cond_t waiting_filling_buffer; mysql_cond_t waiting_filling_buffer;
/* Number of records which are in copy progress */ /*
Number of records which are in copy progress.
Controlled via translog_buffer_increase_writers() and
translog_buffer_decrease_writers().
1 Simple case: translog_force_current_buffer_to_finish both called in
the same procedure.
2 Simple case: translog_write_variable_record_1group:
translog_advance_pointer() increase writer of the buffer and
translog_buffer_decrease_writers() decrease it.
Usual case:
1) translog_advance_pointer (i.e. reserve place for future writing)
increase writers for all buffers where place reserved.
Simpliest case: just all space reserved in one buffer
complex case: end of the first buffer, all second buffer, beginning
of the third buffer.
2) When we finish with writing translog_chaser_page_next() will be
called and unlock the buffer by decreasing number of writers.
*/
uint copy_to_buffer_in_progress; uint copy_to_buffer_in_progress;
/* list of waiting buffer ready threads */ /* list of waiting buffer ready threads */
struct st_my_thread_var *waiting_flush; struct st_my_thread_var *waiting_flush;
@ -214,6 +261,7 @@ struct st_translog_buffer
struct st_buffer_cursor struct st_buffer_cursor
{ {
TRUNSLOG_USED_BUFFERS buffs;
/* pointer into the buffer */ /* pointer into the buffer */
uchar *ptr; uchar *ptr;
/* current buffer */ /* current buffer */
@ -1648,15 +1696,12 @@ static my_bool translog_create_new_file()
DBUG_PRINT("info", ("file_no: %lu", (ulong)file_no)); DBUG_PRINT("info", ("file_no: %lu", (ulong)file_no));
if (translog_write_file_header()) if (translog_write_file_header())
DBUG_RETURN(1); goto error;
if (ma_control_file_write_and_force(last_checkpoint_lsn, file_no, if (ma_control_file_write_and_force(last_checkpoint_lsn, file_no,
max_trid_in_control_file, max_trid_in_control_file,
recovery_failures)) recovery_failures))
{ goto error;
translog_stop_writing();
DBUG_RETURN(1);
}
DBUG_RETURN(0); DBUG_RETURN(0);
@ -1697,10 +1742,6 @@ static void translog_buffer_lock(struct st_translog_buffer *buffer)
SYNOPSIS SYNOPSIS
translog_buffer_unlock() translog_buffer_unlock()
buffer This buffer which should be unlocked buffer This buffer which should be unlocked
RETURN
0 OK
1 Error
*/ */
static void translog_buffer_unlock(struct st_translog_buffer *buffer) static void translog_buffer_unlock(struct st_translog_buffer *buffer)
@ -1894,7 +1935,10 @@ static void translog_finish_page(TRANSLOG_ADDRESS *horizon,
(ulong) cursor->buffer->size, (ulong) cursor->buffer->size,
(ulong) (cursor->ptr -cursor->buffer->buffer), (ulong) (cursor->ptr -cursor->buffer->buffer),
(uint) cursor->current_page_fill, (uint) left)); (uint) cursor->current_page_fill, (uint) left));
DBUG_ASSERT(LSN_FILE_NO(*horizon) == LSN_FILE_NO(cursor->buffer->offset)); DBUG_ASSERT(LSN_FILE_NO(*horizon) == LSN_FILE_NO(cursor->buffer->offset)
|| translog_status == TRANSLOG_UNINITED);
if ((LSN_FILE_NO(*horizon) != LSN_FILE_NO(cursor->buffer->offset)))
DBUG_VOID_RETURN; // everything wrong do not write to awoid more problems
translog_check_cursor(cursor); translog_check_cursor(cursor);
if (cursor->protected) if (cursor->protected)
{ {
@ -4588,6 +4632,7 @@ static my_bool translog_chaser_page_next(TRANSLOG_ADDRESS *horizon,
{ {
translog_buffer_lock(buffer_to_flush); translog_buffer_lock(buffer_to_flush);
translog_buffer_decrease_writers(buffer_to_flush); translog_buffer_decrease_writers(buffer_to_flush);
used_buffs_register_unlock(&cursor->buffs, buffer_to_flush);
if (!rc) if (!rc)
rc= translog_buffer_flush(buffer_to_flush); rc= translog_buffer_flush(buffer_to_flush);
translog_buffer_unlock(buffer_to_flush); translog_buffer_unlock(buffer_to_flush);
@ -4692,7 +4737,8 @@ translog_write_variable_record_chunk3_page(struct st_translog_parts *parts,
1 Error 1 Error
*/ */
static my_bool translog_advance_pointer(int pages, uint16 last_page_data) static my_bool translog_advance_pointer(int pages, uint16 last_page_data,
TRUNSLOG_USED_BUFFERS *buffs)
{ {
translog_size_t last_page_offset= (log_descriptor.page_overhead + translog_size_t last_page_offset= (log_descriptor.page_overhead +
last_page_data); last_page_data);
@ -4709,6 +4755,8 @@ static my_bool translog_advance_pointer(int pages, uint16 last_page_data)
(uint) last_page_data)); (uint) last_page_data));
translog_lock_assert_owner(); translog_lock_assert_owner();
used_buffs_init(buffs);
if (pages == -1) if (pages == -1)
{ {
/* /*
@ -4786,8 +4834,10 @@ static my_bool translog_advance_pointer(int pages, uint16 last_page_data)
translog_wait_for_buffer_free(new_buffer); translog_wait_for_buffer_free(new_buffer);
#ifndef DBUG_OFF #ifndef DBUG_OFF
/* We keep the handler locked so nobody can start this new buffer */ /* We keep the handler locked so nobody can start this new buffer */
DBUG_ASSERT(offset == new_buffer->offset && new_buffer->file == NULL && DBUG_ASSERT((offset == new_buffer->offset && new_buffer->file == NULL &&
(file == NULL ? ver : (uint8)(ver + 1)) == new_buffer->ver); (file == NULL ? ver : (uint8)(ver + 1)) ==
new_buffer->ver) ||
translog_status == TRANSLOG_READONLY);
} }
#endif #endif
@ -4808,6 +4858,8 @@ static my_bool translog_advance_pointer(int pages, uint16 last_page_data)
DBUG_ASSERT(log_descriptor.bc.buffer->buffer_no == DBUG_ASSERT(log_descriptor.bc.buffer->buffer_no ==
log_descriptor.bc.buffer_no); log_descriptor.bc.buffer_no);
translog_buffer_increase_writers(log_descriptor.bc.buffer); translog_buffer_increase_writers(log_descriptor.bc.buffer);
// register for case of error
used_buffs_add(buffs, log_descriptor.bc.buffer);
if (file_end_offset <= buffer_end_offset) if (file_end_offset <= buffer_end_offset)
{ {
@ -4818,6 +4870,10 @@ static my_bool translog_advance_pointer(int pages, uint16 last_page_data)
(ulong) LSN_FILE_NO(log_descriptor.horizon))); (ulong) LSN_FILE_NO(log_descriptor.horizon)));
if (translog_create_new_file()) if (translog_create_new_file())
{ {
struct st_translog_buffer *ob= log_descriptor.bc.buffer;
translog_buffer_unlock(ob);
used_buffs_urgent_unlock(buffs);
translog_buffer_lock(ob);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
} }
@ -4839,6 +4895,7 @@ end:
log_descriptor.bc.ptr+= offset; log_descriptor.bc.ptr+= offset;
log_descriptor.bc.buffer->size+= offset; log_descriptor.bc.buffer->size+= offset;
translog_buffer_increase_writers(log_descriptor.bc.buffer); translog_buffer_increase_writers(log_descriptor.bc.buffer);
used_buffs_add(buffs, log_descriptor.bc.buffer);
log_descriptor.horizon+= offset; /* offset increasing */ log_descriptor.horizon+= offset; /* offset increasing */
log_descriptor.bc.current_page_fill= last_page_offset; log_descriptor.bc.current_page_fill= last_page_offset;
DBUG_PRINT("info", ("NewP buffer #%u: 0x%lx chaser: %d Size: %lu (%lu) " DBUG_PRINT("info", ("NewP buffer #%u: 0x%lx chaser: %d Size: %lu (%lu) "
@ -4859,6 +4916,56 @@ end:
DBUG_RETURN(0); DBUG_RETURN(0);
} }
static void
used_buffs_add(TRUNSLOG_USED_BUFFERS *buffs,
struct st_translog_buffer *buff)
{
DBUG_ENTER("used_buffs_add");
DBUG_PRINT("enter", ("ADD buffs: %p unlk %u (%p) wrt_ptr: %u (%p)"
" buff %p (%u)",
buffs,
buffs->wrt_ptr, buffs->buff[buffs->wrt_ptr],
buffs->unlck_ptr, buffs->buff[buffs->unlck_ptr],
buff, buff->buffer_no));
DBUG_ASSERT(buffs->wrt_ptr < MAX_TRUNSLOG_USED_BUFFERS);
buffs->buff[buffs->wrt_ptr++]= buff;
DBUG_VOID_RETURN;
}
static void
used_buffs_register_unlock(TRUNSLOG_USED_BUFFERS *buffs,
struct st_translog_buffer *buff
__attribute__((unused)) )
{
DBUG_ENTER("used_buffs_register_unlock");
DBUG_PRINT("enter", ("SUB buffs: %p unlk %u (%p) wrt_ptr: %u (%p)"
" buff %p (%u)",
buffs,
buffs->wrt_ptr, buffs->buff[buffs->wrt_ptr],
buffs->unlck_ptr, buffs->buff[buffs->unlck_ptr],
buff, buff->buffer_no));
DBUG_ASSERT(buffs->buff[buffs->unlck_ptr] == buff);
buffs->unlck_ptr++;
DBUG_VOID_RETURN;
}
static void used_buffs_urgent_unlock(TRUNSLOG_USED_BUFFERS *buffs)
{
uint i;
DBUG_ENTER("used_buffs_urgent_unlock");
translog_lock();
translog_stop_writing();
translog_unlock();
for (i= buffs->unlck_ptr; i < buffs->wrt_ptr; i++)
{
struct st_translog_buffer *buf= buffs->buff[i];
translog_buffer_lock(buf);
translog_buffer_decrease_writers(buf);
translog_buffer_unlock(buf);
buffs->buff[i]= NULL;
}
used_buffs_init(buffs);
DBUG_VOID_RETURN;
}
/* /*
Get page rest Get page rest
@ -4997,6 +5104,11 @@ translog_write_variable_record_1group(LSN *lsn,
lsn, hook_arg))) lsn, hook_arg)))
{ {
translog_unlock(); translog_unlock();
if (buffer_to_flush != NULL)
{
translog_buffer_flush(buffer_to_flush);
translog_buffer_unlock(buffer_to_flush);
}
DBUG_RETURN(1); DBUG_RETURN(1);
} }
cursor= log_descriptor.bc; cursor= log_descriptor.bc;
@ -5027,8 +5139,9 @@ translog_write_variable_record_1group(LSN *lsn,
(log_descriptor.page_capacity_chunk_2 - 1), (log_descriptor.page_capacity_chunk_2 - 1),
record_rest, parts->record_length)); record_rest, parts->record_length));
/* record_rest + 3 is chunk type 3 overhead + record_rest */ /* record_rest + 3 is chunk type 3 overhead + record_rest */
rc|= translog_advance_pointer((int)(full_pages + additional_chunk3_page), rc= translog_advance_pointer((int)(full_pages + additional_chunk3_page),
(record_rest ? record_rest + 3 : 0)); (record_rest ? record_rest + 3 : 0),
&cursor.buffs);
log_descriptor.bc.buffer->last_lsn= *lsn; log_descriptor.bc.buffer->last_lsn= *lsn;
DBUG_PRINT("info", ("last_lsn set to (%lu,0x%lx) buffer: 0x%lx", DBUG_PRINT("info", ("last_lsn set to (%lu,0x%lx) buffer: 0x%lx",
LSN_IN_PARTS(log_descriptor.bc.buffer->last_lsn), LSN_IN_PARTS(log_descriptor.bc.buffer->last_lsn),
@ -5047,7 +5160,11 @@ translog_write_variable_record_1group(LSN *lsn,
translog_buffer_unlock(buffer_to_flush); translog_buffer_unlock(buffer_to_flush);
} }
if (rc) if (rc)
{
//translog_advance_pointer decreased writers so it is OK
DBUG_ASSERT(cursor.buffs.unlck_ptr == cursor.buffs.wrt_ptr);
DBUG_RETURN(1); DBUG_RETURN(1);
}
translog_write_variable_record_1group_header(parts, type, short_trid, translog_write_variable_record_1group_header(parts, type, short_trid,
header_length, chunk0_header); header_length, chunk0_header);
@ -5062,7 +5179,7 @@ translog_write_variable_record_1group(LSN *lsn,
for (i= 0; i < full_pages; i++) for (i= 0; i < full_pages; i++)
{ {
if (translog_write_variable_record_chunk2_page(parts, &horizon, &cursor)) if (translog_write_variable_record_chunk2_page(parts, &horizon, &cursor))
DBUG_RETURN(1); goto error;
DBUG_PRINT("info", ("absolute horizon: (%lu,0x%lx) local: (%lu,0x%lx)", DBUG_PRINT("info", ("absolute horizon: (%lu,0x%lx) local: (%lu,0x%lx)",
LSN_IN_PARTS(log_descriptor.horizon), LSN_IN_PARTS(log_descriptor.horizon),
@ -5075,7 +5192,7 @@ translog_write_variable_record_1group(LSN *lsn,
log_descriptor. log_descriptor.
page_capacity_chunk_2 - 2, page_capacity_chunk_2 - 2,
&horizon, &cursor)) &horizon, &cursor))
DBUG_RETURN(1); goto error;
DBUG_PRINT("info", ("absolute horizon: (%lu,0x%lx) local: (%lu,0x%lx)", DBUG_PRINT("info", ("absolute horizon: (%lu,0x%lx) local: (%lu,0x%lx)",
LSN_IN_PARTS(log_descriptor.horizon), LSN_IN_PARTS(log_descriptor.horizon),
LSN_IN_PARTS(horizon))); LSN_IN_PARTS(horizon)));
@ -5085,17 +5202,22 @@ translog_write_variable_record_1group(LSN *lsn,
if (translog_write_variable_record_chunk3_page(parts, if (translog_write_variable_record_chunk3_page(parts,
record_rest, record_rest,
&horizon, &cursor)) &horizon, &cursor))
DBUG_RETURN(1); goto error;
DBUG_PRINT("info", ("absolute horizon: (%lu,0x%lx) local: (%lu,0x%lx)", DBUG_PRINT("info", ("absolute horizon: (%lu,0x%lx) local: (%lu,0x%lx)",
(ulong) LSN_FILE_NO(log_descriptor.horizon), (ulong) LSN_FILE_NO(log_descriptor.horizon),
(ulong) LSN_OFFSET(log_descriptor.horizon), (ulong) LSN_OFFSET(log_descriptor.horizon),
(ulong) LSN_FILE_NO(horizon), (ulong) LSN_FILE_NO(horizon),
(ulong) LSN_OFFSET(horizon))); (ulong) LSN_OFFSET(horizon)));
translog_buffer_lock(cursor.buffer); translog_buffer_lock(cursor.buffer);
translog_buffer_decrease_writers(cursor.buffer); translog_buffer_decrease_writers(cursor.buffer);
used_buffs_register_unlock(&cursor.buffs, cursor.buffer);
translog_buffer_unlock(cursor.buffer); translog_buffer_unlock(cursor.buffer);
DBUG_RETURN(rc); DBUG_ASSERT(cursor.buffs.unlck_ptr == cursor.buffs.wrt_ptr);
DBUG_RETURN(0);
error:
used_buffs_urgent_unlock(&cursor.buffs);
DBUG_RETURN(1);
} }
@ -5149,7 +5271,8 @@ translog_write_variable_record_1chunk(LSN *lsn,
lsn, hook_arg))) lsn, hook_arg)))
{ {
translog_unlock(); translog_unlock();
DBUG_RETURN(1); rc= 1;
goto err;
} }
rc= translog_write_parts_on_page(&log_descriptor.horizon, rc= translog_write_parts_on_page(&log_descriptor.horizon,
@ -5165,6 +5288,7 @@ translog_write_variable_record_1chunk(LSN *lsn,
check if we switched buffer and need process it (current buffer is check if we switched buffer and need process it (current buffer is
unlocked already => we will not delay other threads unlocked already => we will not delay other threads
*/ */
err:
if (buffer_to_flush != NULL) if (buffer_to_flush != NULL)
{ {
if (!rc) if (!rc)
@ -5504,9 +5628,11 @@ translog_write_variable_record_mgroup(LSN *lsn,
uint file_of_the_first_group; uint file_of_the_first_group;
int pages_to_skip; int pages_to_skip;
struct st_translog_buffer *buffer_of_last_lsn; struct st_translog_buffer *buffer_of_last_lsn;
my_bool external_buffer_to_flush= TRUE;
DBUG_ENTER("translog_write_variable_record_mgroup"); DBUG_ENTER("translog_write_variable_record_mgroup");
translog_lock_assert_owner(); translog_lock_assert_owner();
used_buffs_init(&cursor.buffs);
chunk2_header[0]= TRANSLOG_CHUNK_NOHDR; chunk2_header[0]= TRANSLOG_CHUNK_NOHDR;
if (my_init_dynamic_array(&groups, if (my_init_dynamic_array(&groups,
@ -5514,6 +5640,11 @@ translog_write_variable_record_mgroup(LSN *lsn,
10, 10, MYF(0))) 10, 10, MYF(0)))
{ {
translog_unlock(); translog_unlock();
if (buffer_to_flush != NULL)
{
translog_buffer_flush(buffer_to_flush);
translog_buffer_unlock(buffer_to_flush);
}
DBUG_PRINT("error", ("init array failed")); DBUG_PRINT("error", ("init array failed"));
DBUG_RETURN(1); DBUG_RETURN(1);
} }
@ -5540,6 +5671,7 @@ translog_write_variable_record_mgroup(LSN *lsn,
translog_mark_file_unfinished(file_of_the_first_group); translog_mark_file_unfinished(file_of_the_first_group);
do do
{ {
DBUG_ASSERT(cursor.buffs.unlck_ptr == cursor.buffs.wrt_ptr);
group.addr= horizon= log_descriptor.horizon; group.addr= horizon= log_descriptor.horizon;
cursor= log_descriptor.bc; cursor= log_descriptor.bc;
cursor.chaser= 1; cursor.chaser= 1;
@ -5572,21 +5704,26 @@ translog_write_variable_record_mgroup(LSN *lsn,
(ulong)(parts->record_length - (first_page - 1 + (ulong)(parts->record_length - (first_page - 1 +
buffer_rest) - buffer_rest) -
done))); done)));
rc|= translog_advance_pointer((int)full_pages, 0); rc= translog_advance_pointer((int)full_pages, 0, &cursor.buffs);
translog_unlock(); translog_unlock();
if (buffer_to_flush != NULL) if (buffer_to_flush != NULL)
{ {
translog_buffer_decrease_writers(buffer_to_flush); if (!external_buffer_to_flush)
translog_buffer_decrease_writers(buffer_to_flush);
if (!rc) if (!rc)
rc= translog_buffer_flush(buffer_to_flush); rc= translog_buffer_flush(buffer_to_flush);
translog_buffer_unlock(buffer_to_flush); translog_buffer_unlock(buffer_to_flush);
buffer_to_flush= NULL; buffer_to_flush= NULL;
} }
external_buffer_to_flush= FALSE;
if (rc) if (rc)
{ {
DBUG_PRINT("error", ("flush of unlock buffer failed")); DBUG_PRINT("error", ("flush of unlock buffer failed"));
//translog_advance_pointer decreased writers so it is OK
DBUG_ASSERT(cursor.buffs.unlck_ptr == cursor.buffs.wrt_ptr);
goto err; goto err;
} }
@ -5623,6 +5760,7 @@ translog_write_variable_record_mgroup(LSN *lsn,
} }
translog_buffer_lock(cursor.buffer); translog_buffer_lock(cursor.buffer);
translog_buffer_decrease_writers(cursor.buffer); translog_buffer_decrease_writers(cursor.buffer);
used_buffs_register_unlock(&cursor.buffs, cursor.buffer);
translog_buffer_unlock(cursor.buffer); translog_buffer_unlock(cursor.buffer);
translog_lock(); translog_lock();
@ -5637,6 +5775,11 @@ translog_write_variable_record_mgroup(LSN *lsn,
first_page= translog_get_current_page_rest(); first_page= translog_get_current_page_rest();
} }
buffer_rest= translog_get_current_group_size(); buffer_rest= translog_get_current_group_size();
if (buffer_to_flush)
used_buffs_register_unlock(&cursor.buffs,
buffer_to_flush); // will be unlocked
} while ((translog_size_t)(first_page + buffer_rest) < } while ((translog_size_t)(first_page + buffer_rest) <
(translog_size_t)(parts->record_length - done)); (translog_size_t)(parts->record_length - done));
@ -5732,17 +5875,21 @@ translog_write_variable_record_mgroup(LSN *lsn,
(ulong) full_pages * (ulong) full_pages *
log_descriptor.page_capacity_chunk_2, log_descriptor.page_capacity_chunk_2,
chunk3_pages, (uint) chunk3_size, (uint) record_rest)); chunk3_pages, (uint) chunk3_size, (uint) record_rest));
DBUG_ASSERT(cursor.buffs.unlck_ptr == cursor.buffs.wrt_ptr);
rc= translog_advance_pointer(pages_to_skip + (int)(chunk0_pages - 1), rc= translog_advance_pointer(pages_to_skip + (int)(chunk0_pages - 1),
record_rest + header_fixed_part + record_rest + header_fixed_part +
(groups.elements - (groups.elements -
((page_capacity - ((page_capacity -
header_fixed_part) / (7 + 1)) * header_fixed_part) / (7 + 1)) *
(chunk0_pages - 1)) * (7 + 1)); (chunk0_pages - 1)) * (7 + 1),
&cursor.buffs);
buffer_of_last_lsn= log_descriptor.bc.buffer; buffer_of_last_lsn= log_descriptor.bc.buffer;
translog_unlock(); translog_unlock();
if (buffer_to_flush != NULL) if (buffer_to_flush != NULL)
{ {
DBUG_ASSERT(!external_buffer_to_flush);
translog_buffer_decrease_writers(buffer_to_flush); translog_buffer_decrease_writers(buffer_to_flush);
if (!rc) if (!rc)
rc= translog_buffer_flush(buffer_to_flush); rc= translog_buffer_flush(buffer_to_flush);
@ -5906,8 +6053,10 @@ translog_write_variable_record_mgroup(LSN *lsn,
} while (chunk0_pages != 0); } while (chunk0_pages != 0);
translog_buffer_lock(cursor.buffer); translog_buffer_lock(cursor.buffer);
translog_buffer_decrease_writers(cursor.buffer); translog_buffer_decrease_writers(cursor.buffer);
used_buffs_register_unlock(&cursor.buffs, cursor.buffer);
translog_buffer_unlock(cursor.buffer); translog_buffer_unlock(cursor.buffer);
rc= 0; rc= 0;
DBUG_ASSERT(cursor.buffs.unlck_ptr == cursor.buffs.wrt_ptr);
if (translog_set_lsn_for_files(file_of_the_first_group, LSN_FILE_NO(*lsn), if (translog_set_lsn_for_files(file_of_the_first_group, LSN_FILE_NO(*lsn),
*lsn, FALSE)) *lsn, FALSE))
@ -5916,17 +6065,22 @@ translog_write_variable_record_mgroup(LSN *lsn,
translog_mark_file_finished(file_of_the_first_group); translog_mark_file_finished(file_of_the_first_group);
delete_dynamic(&groups); delete_dynamic(&groups);
DBUG_RETURN(rc); DBUG_RETURN(0);
err_unlock: err_unlock:
translog_unlock(); translog_unlock();
err: err:
if (cursor.buffs.unlck_ptr != cursor.buffs.wrt_ptr)
used_buffs_urgent_unlock(&cursor.buffs);
if (buffer_to_flush != NULL) if (buffer_to_flush != NULL)
{ {
/* This is to prevent locking buffer forever in case of error */ /* This is to prevent locking buffer forever in case of error */
translog_buffer_decrease_writers(buffer_to_flush); if (!external_buffer_to_flush)
translog_buffer_decrease_writers(buffer_to_flush);
if (!rc) if (!rc)
rc= translog_buffer_flush(buffer_to_flush); rc= translog_buffer_flush(buffer_to_flush);
translog_buffer_unlock(buffer_to_flush); translog_buffer_unlock(buffer_to_flush);
@ -7480,7 +7634,8 @@ static void translog_force_current_buffer_to_finish()
DBUG_ASSERT(log_descriptor.bc.ptr !=NULL); DBUG_ASSERT(log_descriptor.bc.ptr !=NULL);
DBUG_ASSERT(LSN_FILE_NO(log_descriptor.horizon) == DBUG_ASSERT(LSN_FILE_NO(log_descriptor.horizon) ==
LSN_FILE_NO(old_buffer->offset)); LSN_FILE_NO(old_buffer->offset) ||
translog_status == TRANSLOG_READONLY );
translog_check_cursor(&log_descriptor.bc); translog_check_cursor(&log_descriptor.bc);
DBUG_ASSERT(left < TRANSLOG_PAGE_SIZE); DBUG_ASSERT(left < TRANSLOG_PAGE_SIZE);
if (left) if (left)