Commit 5022e56c authored by monty@mashka.mysql.fi's avatar monty@mashka.mysql.fi

Ensure that BEGIN / COMMIT is handled properly if slave dies

Added syntax support for
CREATE TABLE foo (a char CHARACTER SET latin1) CHARSET=latin1;
parent 146814f2
......@@ -1797,7 +1797,7 @@ The package contains the following information:
@multitable @columnfractions .30 .70
@item Size @tab Comment
@item (param_count+7)/8 @tab Null bit map
@item (param_count+9)/8 @tab Null bit map (2 bits reserved for protocol)
@item 1 @tab new_parameter_bound flag. Is set to 1 for first
execute or if one has rebound the parameters.
@item 2*param_count @tab Type of parameters (only given if new_parameter_bound flag is 1)
......@@ -1813,7 +1813,7 @@ The parameters are stored the following ways:
@multitable @columnfractions .20 .10 .70
@item Type @tab Size @tab Comment
@item tynyint @tab 1 @tab One byte integer
@item tinyint @tab 1 @tab One byte integer
@item short @tab 2 @tab
@item int @tab 4 @tab
@item longlong @tab 8 @tab
......@@ -1849,6 +1849,18 @@ bound parameters to the client. The server is always sending the data
as type given for 'column type' for respective column. It's up to the
client to convert the parameter to the requested type.
DATETIME, DATE and TIME are sent to the server in a binary format as follows:
@multitable @columnfractions .20 .10 .70
@item Type @tab Size @tab Comment
@item date @tab 1 + 0-11 @tab Length + 2 byte year, 1 byte MMDDHHMMSS, 4 byte billionth of a second
@item datetime @tab 1 + 0-11 @tab Length + 2 byte year, 1 byte MMDDHHMMSS, 4 byte billionth of a second
@item time @tab 1 + 0-14 @tab Length + sign (0 = pos, 1= neg), 4 byte days, 1 byte HHMMDD, 4 byte billionth of a second
@end multitable
The first byte is a length byte and then comes all parameters that are
not 0. (Always counted from the beginning).
@node Fulltext Search, , protocol, Top
@chapter Fulltext Search in MySQL
......
......@@ -42,7 +42,8 @@ Created 5/24/1996 Heikki Tuuri
#define DB_CANNOT_ADD_CONSTRAINT 38 /* adding a foreign key constraint
to a table failed */
#define DB_CORRUPTION 39 /* data structure corruption noticed */
#define DB_COL_APPEARS_TWICE_IN_INDEX 40
/* The following are partial failure codes */
#define DB_FAIL 1000
#define DB_OVERFLOW 1001
......
......@@ -46,8 +46,17 @@ insert into t1 values ('skr',NULL),('skr',NULL),('test',NULL);
select * from t1;
sid id
skr 1
skr 2
skr 1
test 1
insert into t1 values ('rts',NULL),('rts',NULL),('test',NULL);
select * from t1;
sid id
rts 1
rts 2
skr 1
skr 1
test 1
test 2
drop table t1;
drop database if exists foo;
create database foo;
......
......@@ -654,7 +654,12 @@ int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli)
rli->linfo.log_file_name);
goto err;
}
/*
Reset position to current log. This involves setting both of the
position variables:
*/
rli->relay_log_pos = BIN_LOG_HEADER_SIZE;
rli->pending = 0;
strmake(rli->relay_log_name,rli->linfo.log_file_name,
sizeof(rli->relay_log_name)-1);
......
......@@ -208,9 +208,13 @@ int Log_event::exec_event(struct st_relay_log_info* rli)
{
if (rli) // QQ When is this not true ?
{
rli->inc_pos(get_event_len(),log_pos);
DBUG_ASSERT(rli->sql_thd != 0);
flush_relay_log_info(rli);
if (rli->inside_transaction)
rli->inc_pending(get_event_len());
else
{
rli->inc_pos(get_event_len(),log_pos);
flush_relay_log_info(rli);
}
}
return 0;
}
......@@ -1707,6 +1711,19 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli)
mysql_log.write(thd,COM_QUERY,"%s",thd->query);
DBUG_PRINT("query",("%s",thd->query));
mysql_parse(thd, thd->query, q_len);
/*
Set a flag if we are inside an transaction so that we can restart
the transaction from the start if we are killed
This will only be done if we are supporting transactional tables
in the slave.
*/
if (!strcmp(thd->query,"BEGIN"))
rli->inside_transaction= opt_using_transactions;
else if (!strcmp(thd->query,"COMMIT"))
rli->inside_transaction=0;
if ((expected_error != (actual_error = thd->net.last_errno)) &&
expected_error &&
!ignored_error_code(actual_error) &&
......
......@@ -2711,7 +2711,12 @@ static IO_CACHE *reopen_relay_log(RELAY_LOG_INFO *rli, const char **errmsg)
if ((rli->cur_log_fd=open_binlog(cur_log,rli->relay_log_name,
errmsg)) <0)
DBUG_RETURN(0);
my_b_seek(cur_log,rli->relay_log_pos);
/*
We want to start exactly where we was before:
relay_log_pos Current log pos
pending Number of bytes already processed from the event
*/
my_b_seek(cur_log,rli->relay_log_pos + rli->pending);
DBUG_RETURN(cur_log);
}
......
......@@ -169,11 +169,13 @@ typedef struct st_relay_log_info
volatile bool abort_slave, slave_running;
bool log_pos_current;
bool skip_log_purge;
bool inside_transaction;
st_relay_log_info()
:info_fd(-1),cur_log_fd(-1), cur_log_old_open_count(0), abort_pos_wait(0),
slave_run_id(0), inited(0), abort_slave(0), slave_running(0),
log_pos_current(0), skip_log_purge(0)
:info_fd(-1),cur_log_fd(-1), cur_log_old_open_count(0), abort_pos_wait(0),
slave_run_id(0), inited(0), abort_slave(0), slave_running(0),
log_pos_current(0), skip_log_purge(0),
inside_transaction(0) /* the default is autocommit=1 */
{
relay_log_name[0] = master_log_name[0] = 0;
bzero(&info_file,sizeof(info_file));
......
......@@ -310,30 +310,6 @@ void field_str::add()
was_maybe_zerofill = num_info.maybe_zerofill;
}
if (room_in_tree)
{
if (res != &s)
s.copy(*res);
if (!tree_search(&tree, (void*) &s)) // If not in tree
{
s.copy(); // slow, when SAFE_MALLOC is in use
if (!tree_insert(&tree, (void*) &s, 0))
{
room_in_tree = 0; // Remove tree, out of RAM ?
delete_tree(&tree);
}
else
{
bzero((char*) &s, sizeof(s)); // Let tree handle free of this
if ((treemem += length) > pc->max_treemem)
{
room_in_tree = 0; // Remove tree, too big tree
delete_tree(&tree);
}
}
}
}
if (!found)
{
found = 1;
......@@ -364,6 +340,31 @@ void field_str::add()
max_arg.copy(*res);
}
}
if (room_in_tree)
{
if (res != &s)
s.copy(*res);
if (!tree_search(&tree, (void*) &s)) // If not in tree
{
s.copy(); // slow, when SAFE_MALLOC is in use
if (!tree_insert(&tree, (void*) &s, 0))
{
room_in_tree = 0; // Remove tree, out of RAM ?
delete_tree(&tree);
}
else
{
bzero((char*) &s, sizeof(s)); // Let tree handle free of this
if ((treemem += length) > pc->max_treemem)
{
room_in_tree = 0; // Remove tree, too big tree
delete_tree(&tree);
}
}
}
}
if ((num_info.zerofill && (max_length != min_length)) ||
(was_zero_fill && (max_length != min_length)))
can_be_still_num = 0; // zerofilled numbers must be of same length
......
......@@ -167,6 +167,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token CACHE_SYM
%token CASCADE
%token CAST_SYM
%token CHARSET
%token CHECKSUM_SYM
%token CHECK_SYM
%token COMMITTED_SYM
......@@ -855,6 +856,8 @@ create_table_option:
table_list->next=0;
lex->create_info.used_fields|= HA_CREATE_USED_UNION;
}
| CHARSET opt_equal ident {}
| CHAR_SYM SET opt_equal ident {}
| INSERT_METHOD EQ merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;}
| DATA_SYM DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.data_file_name= $4.str; }
| INDEX DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.index_file_name= $4.str; };
......@@ -1088,6 +1091,7 @@ attribute:
opt_binary:
/* empty */ {}
| BINARY { Lex->type|=BINARY_FLAG; };
| CHAR_SYM SET opt_equal ident {}
references:
REFERENCES table_ident opt_on_delete {}
......@@ -3192,6 +3196,7 @@ keyword:
| BOOLEAN_SYM {}
| CACHE_SYM {}
| CHANGED {}
| CHARSET {}
| CHECKSUM_SYM {}
| CIPHER_SYM {}
| CLIENT_SYM {}
......
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