Merge serg.mylan:/usr/home/serg/Abk/mysql-5.0

into serg.mylan:/usr/home/serg/Abk/mysql-5.0-xa


configure.in:
  Auto merged
mysql-test/r/drop_temp_table.result:
  Auto merged
mysql-test/r/innodb.result:
  Auto merged
mysql-test/t/innodb.test:
  Auto merged
sql/ha_innodb.cc:
  Auto merged
sql/item_func.h:
  Auto merged
sql/log.cc:
  Auto merged
sql/mysql_priv.h:
  Auto merged
sql/mysqld.cc:
  Auto merged
sql/set_var.h:
  Auto merged
sql/sql_base.cc:
  Auto merged
sql/sql_delete.cc:
  Auto merged
sql/sql_insert.cc:
  Auto merged
sql/sql_lex.cc:
  Auto merged
sql/sql_parse.cc:
  Auto merged
This commit is contained in:
unknown 2005-02-18 12:02:46 +01:00
commit 61a88ff0a1
90 changed files with 4486 additions and 3147 deletions

View file

@ -1100,7 +1100,7 @@ at offset %lu ; this could be a log format error or read error",
/* EOF can't be hit here normally, so it's a real error */ /* EOF can't be hit here normally, so it's a real error */
die("Could not read a Rotate_log_event event \ die("Could not read a Rotate_log_event event \
at offset %lu ; this could be a log format error or read error", at offset %lu ; this could be a log format error or read error",
tmp_pos); tmp_pos);
} }
else else
break; break;
@ -1169,9 +1169,15 @@ static int dump_local_log_entries(const char* logname)
Log_event* ev = Log_event::read_log_event(file, description_event); Log_event* ev = Log_event::read_log_event(file, description_event);
if (!ev) if (!ev)
{ {
if (file->error) /*
if binlog wasn't closed properly ("in use" flag is set) don't complain
about a corruption, but treat it as EOF and move to the next binlog.
*/
if (description_event->flags & LOG_EVENT_BINLOG_IN_USE_F)
file->error= 0;
else if (file->error)
{ {
fprintf(stderr, fprintf(stderr,
"Could not read entry at offset %s:" "Could not read entry at offset %s:"
"Error in log format or read error\n", "Error in log format or read error\n",
llstr(old_off,llbuff)); llstr(old_off,llbuff));

View file

@ -1887,7 +1887,7 @@ AC_CHECK_FUNCS(alarm bcmp bfill bmove bzero chsize cuserid fchmod fcntl \
getcwd gethostbyaddr_r gethostbyname_r getpass getpassphrase getpwnam \ getcwd gethostbyaddr_r gethostbyname_r getpass getpassphrase getpwnam \
getpwuid getrlimit getrusage getwd gmtime_r index initgroups isnan \ getpwuid getrlimit getrusage getwd gmtime_r index initgroups isnan \
localtime_r locking longjmp lrand48 madvise mallinfo memcpy memmove \ localtime_r locking longjmp lrand48 madvise mallinfo memcpy memmove \
mkstemp mlockall perror poll pread pthread_attr_create mmap \ mkstemp mlockall perror poll pread pthread_attr_create mmap getpagesize \
pthread_attr_getstacksize pthread_attr_setprio pthread_attr_setschedparam \ pthread_attr_getstacksize pthread_attr_setprio pthread_attr_setschedparam \
pthread_attr_setstacksize pthread_condattr_create pthread_getsequence_np \ pthread_attr_setstacksize pthread_condattr_create pthread_getsequence_np \
pthread_key_delete pthread_rwlock_rdlock pthread_setprio \ pthread_key_delete pthread_rwlock_rdlock pthread_setprio \

View file

@ -761,7 +761,7 @@ typedef long int32;
#endif #endif
typedef unsigned long uint32; /* Short for unsigned integer >= 32 bits */ typedef unsigned long uint32; /* Short for unsigned integer >= 32 bits */
#else #else
error "Neither int or long is of 4 bytes width" #error "Neither int or long is of 4 bytes width"
#endif #endif
#if !defined(HAVE_ULONG) && !defined(HAVE_LINUXTHREADS) && !defined(__USE_MISC) #if !defined(HAVE_ULONG) && !defined(HAVE_LINUXTHREADS) && !defined(__USE_MISC)

View file

@ -689,12 +689,12 @@ extern pthread_t shutdown_th, main_th, signal_th;
#define thread_safe_add(V,C,L) (pthread_mutex_lock((L)), (V)+=(C), pthread_mutex_unlock((L))) #define thread_safe_add(V,C,L) (pthread_mutex_lock((L)), (V)+=(C), pthread_mutex_unlock((L)))
#define thread_safe_sub(V,C,L) \ #define thread_safe_sub(V,C,L) \
(pthread_mutex_lock((L)), (V)-=(C), pthread_mutex_unlock((L))) (pthread_mutex_lock((L)), (V)-=(C), pthread_mutex_unlock((L)))
#if defined (__GNUC__) || defined (__cplusplus) #ifdef __cplusplus
static inline bool thread_safe_dec_and_test(ulong V, pthread_mutex_t *L) static inline bool thread_safe_dec_and_test(ulong &V, pthread_mutex_t *L)
{ {
ulong res; ulong res;
pthread_mutex_lock(L); pthread_mutex_lock(L);
res=V--; res=--V;
pthread_mutex_unlock(L); pthread_mutex_unlock(L);
return res==0; return res==0;
} }

View file

@ -315,7 +315,7 @@ trx_is_active(
} }
if (ut_dulint_cmp(trx_id, trx_sys->max_trx_id) >= 0) { if (ut_dulint_cmp(trx_id, trx_sys->max_trx_id) >= 0) {
/* There must be corruption: we return TRUE because this /* There must be corruption: we return TRUE because this
function is only called by lock_clust_rec_some_has_impl() function is only called by lock_clust_rec_some_has_impl()
and row_vers_impl_x_locked_off_kernel() and they have and row_vers_impl_x_locked_off_kernel() and they have
@ -325,8 +325,9 @@ trx_is_active(
} }
trx = trx_get_on_id(trx_id); trx = trx_get_on_id(trx_id);
if (trx && (trx->conc_state == TRX_ACTIVE)) { if (trx && (trx->conc_state == TRX_ACTIVE ||
trx->conc_state == TRX_PREPARED)) {
return(TRUE); return(TRUE);
} }

View file

@ -153,10 +153,11 @@ read_view_open_now(
/* No active transaction should be visible, except cr_trx */ /* No active transaction should be visible, except cr_trx */
while (trx) { while (trx) {
if (trx != cr_trx && trx->conc_state == TRX_ACTIVE) { if (trx != cr_trx && (trx->conc_state == TRX_ACTIVE ||
trx->conc_state == TRX_PREPARED)) {
read_view_set_nth_trx_id(view, n, trx->id); read_view_set_nth_trx_id(view, n, trx->id);
n++; n++;
/* NOTE that a transaction whose trx number is < /* NOTE that a transaction whose trx number is <
@ -164,7 +165,7 @@ read_view_open_now(
in the middle of its commit! Note that when a in the middle of its commit! Note that when a
transaction starts, we initialize trx->no to transaction starts, we initialize trx->no to
ut_dulint_max. */ ut_dulint_max. */
if (ut_dulint_cmp(view->low_limit_no, trx->no) > 0) { if (ut_dulint_cmp(view->low_limit_no, trx->no) > 0) {
view->low_limit_no = trx->no; view->low_limit_no = trx->no;

View file

@ -1617,20 +1617,21 @@ trx_print(
(ulong) ut_dulint_get_high(trx->id), (ulong) ut_dulint_get_high(trx->id),
(ulong) ut_dulint_get_low(trx->id)); (ulong) ut_dulint_get_low(trx->id));
switch (trx->conc_state) { switch (trx->conc_state) {
case TRX_NOT_STARTED: case TRX_NOT_STARTED:
fputs(", not started", f); fputs(", not started", f);
break; break;
case TRX_ACTIVE: case TRX_ACTIVE:
case TRX_PREPARED:
fprintf(f, ", ACTIVE %lu sec", fprintf(f, ", ACTIVE %lu sec",
(ulong)difftime(time(NULL), trx->start_time)); (ulong)difftime(time(NULL), trx->start_time));
break; break;
case TRX_COMMITTED_IN_MEMORY: case TRX_COMMITTED_IN_MEMORY:
fputs(", COMMITTED IN MEMORY", f); fputs(", COMMITTED IN MEMORY", f);
break; break;
default: default:
fprintf(f, " state %lu", (ulong) trx->conc_state); fprintf(f, " state %lu", (ulong) trx->conc_state);
} }
#ifdef UNIV_LINUX #ifdef UNIV_LINUX
fprintf(f, ", process no %lu", trx->mysql_process_no); fprintf(f, ", process no %lu", trx->mysql_process_no);

0
libmysqld/libmysqld.rc Executable file → Normal file
View file

0
libmysqld/resource.h Executable file → Normal file
View file

View file

@ -523,11 +523,12 @@ create table t2 (c char(30)) charset=ucs2;
set @v=convert('abc' using ucs2); set @v=convert('abc' using ucs2);
reset master; reset master;
insert into t2 values (@v); insert into t2 values (@v);
show binlog events from 95; show binlog events from 96;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 95 User var 1 135 @`v`=_ucs2 0x006100620063 COLLATE ucs2_general_ci master-bin.000001 96 User var 1 136 @`v`=_ucs2 0x006100620063 COLLATE ucs2_general_ci
master-bin.000001 135 Query 1 225 use `test`; insert into t2 values (@v) master-bin.000001 136 Query 1 226 use `test`; insert into t2 values (@v)
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
SET @`v`:=_ucs2 0x006100620063 COLLATE `ucs2_general_ci`; SET @`v`:=_ucs2 0x006100620063 COLLATE `ucs2_general_ci`;
use test; use test;
SET TIMESTAMP=10000; SET TIMESTAMP=10000;

View file

@ -271,7 +271,7 @@ n
6 6
7 7
rollback to savepoint `my_savepoint`; rollback to savepoint `my_savepoint`;
ERROR HY000: Got error 153 during ROLLBACK ERROR 42000: SAVEPOINT my_savepoint does not exist
set autocommit=1; set autocommit=1;
rollback; rollback;
drop table t1; drop table t1;
@ -1633,14 +1633,14 @@ t2 CREATE TABLE `t2` (
drop table t2, t1; drop table t2, t1;
show status like "binlog_cache_use"; show status like "binlog_cache_use";
Variable_name Value Variable_name Value
Binlog_cache_use 25 Binlog_cache_use 152
show status like "binlog_cache_disk_use"; show status like "binlog_cache_disk_use";
Variable_name Value Variable_name Value
Binlog_cache_disk_use 0 Binlog_cache_disk_use 0
create table t1 (a int) engine=innodb; create table t1 (a int) engine=innodb;
show status like "binlog_cache_use"; show status like "binlog_cache_use";
Variable_name Value Variable_name Value
Binlog_cache_use 26 Binlog_cache_use 153
show status like "binlog_cache_disk_use"; show status like "binlog_cache_disk_use";
Variable_name Value Variable_name Value
Binlog_cache_disk_use 1 Binlog_cache_disk_use 1
@ -1649,7 +1649,7 @@ delete from t1;
commit; commit;
show status like "binlog_cache_use"; show status like "binlog_cache_use";
Variable_name Value Variable_name Value
Binlog_cache_use 27 Binlog_cache_use 154
show status like "binlog_cache_disk_use"; show status like "binlog_cache_disk_use";
Variable_name Value Variable_name Value
Binlog_cache_disk_use 1 Binlog_cache_disk_use 1

View file

@ -74,8 +74,8 @@ insert into t1 select * from t2;
ERROR 23000: Duplicate entry '2' for key 1 ERROR 23000: Duplicate entry '2' for key 1
show binlog events; show binlog events;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 4 Format_desc 1 95 Server ver: VERSION, Binlog ver: 4 master-bin.000001 4 Format_desc 1 96 Server ver: VERSION, Binlog ver: 4
master-bin.000001 95 Query 1 190 use `test`; insert into t1 select * from t2 master-bin.000001 96 Query 1 191 use `test`; insert into t1 select * from t2
select * from t1; select * from t1;
a a
1 1
@ -88,7 +88,7 @@ create table t2(unique(a)) select a from t1;
ERROR 23000: Duplicate entry '1' for key 1 ERROR 23000: Duplicate entry '1' for key 1
show binlog events; show binlog events;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 4 Format_desc 1 95 Server ver: VERSION, Binlog ver: 4 master-bin.000001 4 Format_desc 1 96 Server ver: VERSION, Binlog ver: 4
drop table t1; drop table t1;
create table t1 (a int not null); create table t1 (a int not null);
create table t2 (a int not null); create table t2 (a int not null);

View file

@ -6,12 +6,12 @@ begin;
insert into t1 values(1); insert into t1 values(1);
insert into t2 select * from t1; insert into t2 select * from t1;
commit; commit;
show binlog events from 95; show binlog events from 96;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 95 Query 1 # use `test`; BEGIN master-bin.000001 96 Query 1 # use `test`; BEGIN
master-bin.000001 164 Query 1 # use `test`; insert into t1 values(1) master-bin.000001 165 Query 1 # use `test`; insert into t1 values(1)
master-bin.000001 252 Query 1 # use `test`; insert into t2 select * from t1 master-bin.000001 253 Query 1 # use `test`; insert into t2 select * from t1
master-bin.000001 347 Query 1 # use `test`; COMMIT master-bin.000001 348 Xid 1 # COMMIT /* xid=7 */
delete from t1; delete from t1;
delete from t2; delete from t2;
reset master; reset master;
@ -21,12 +21,12 @@ insert into t2 select * from t1;
rollback; rollback;
Warnings: Warnings:
Warning 1196 Some non-transactional changed tables couldn't be rolled back Warning 1196 Some non-transactional changed tables couldn't be rolled back
show binlog events from 95; show binlog events from 96;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 95 Query 1 # use `test`; BEGIN master-bin.000001 96 Query 1 # use `test`; BEGIN
master-bin.000001 164 Query 1 # use `test`; insert into t1 values(2) master-bin.000001 165 Query 1 # use `test`; insert into t1 values(2)
master-bin.000001 252 Query 1 # use `test`; insert into t2 select * from t1 master-bin.000001 253 Query 1 # use `test`; insert into t2 select * from t1
master-bin.000001 347 Query 1 # use `test`; ROLLBACK master-bin.000001 348 Query 1 # use `test`; ROLLBACK
delete from t1; delete from t1;
delete from t2; delete from t2;
reset master; reset master;
@ -39,15 +39,15 @@ rollback to savepoint my_savepoint;
Warnings: Warnings:
Warning 1196 Some non-transactional changed tables couldn't be rolled back Warning 1196 Some non-transactional changed tables couldn't be rolled back
commit; commit;
show binlog events from 95; show binlog events from 96;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 95 Query 1 # use `test`; BEGIN master-bin.000001 96 Query 1 # use `test`; BEGIN
master-bin.000001 164 Query 1 # use `test`; insert into t1 values(3) master-bin.000001 165 Query 1 # use `test`; insert into t1 values(3)
master-bin.000001 252 Query 1 # use `test`; savepoint my_savepoint master-bin.000001 253 Query 1 # use `test`; savepoint my_savepoint
master-bin.000001 338 Query 1 # use `test`; insert into t1 values(4) master-bin.000001 339 Query 1 # use `test`; insert into t1 values(4)
master-bin.000001 426 Query 1 # use `test`; insert into t2 select * from t1 master-bin.000001 427 Query 1 # use `test`; insert into t2 select * from t1
master-bin.000001 521 Query 1 # use `test`; rollback to savepoint my_savepoint master-bin.000001 522 Query 1 # use `test`; rollback to savepoint my_savepoint
master-bin.000001 619 Query 1 # use `test`; COMMIT master-bin.000001 620 Xid 1 # COMMIT /* xid=24 */
delete from t1; delete from t1;
delete from t2; delete from t2;
reset master; reset master;
@ -65,16 +65,16 @@ select a from t1 order by a;
a a
5 5
7 7
show binlog events from 95; show binlog events from 96;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 95 Query 1 # use `test`; BEGIN master-bin.000001 96 Query 1 # use `test`; BEGIN
master-bin.000001 164 Query 1 # use `test`; insert into t1 values(5) master-bin.000001 165 Query 1 # use `test`; insert into t1 values(5)
master-bin.000001 252 Query 1 # use `test`; savepoint my_savepoint master-bin.000001 253 Query 1 # use `test`; savepoint my_savepoint
master-bin.000001 338 Query 1 # use `test`; insert into t1 values(6) master-bin.000001 339 Query 1 # use `test`; insert into t1 values(6)
master-bin.000001 426 Query 1 # use `test`; insert into t2 select * from t1 master-bin.000001 427 Query 1 # use `test`; insert into t2 select * from t1
master-bin.000001 521 Query 1 # use `test`; rollback to savepoint my_savepoint master-bin.000001 522 Query 1 # use `test`; rollback to savepoint my_savepoint
master-bin.000001 619 Query 1 # use `test`; insert into t1 values(7) master-bin.000001 620 Query 1 # use `test`; insert into t1 values(7)
master-bin.000001 707 Query 1 # use `test`; COMMIT master-bin.000001 708 Xid 1 # COMMIT /* xid=36 */
delete from t1; delete from t1;
delete from t2; delete from t2;
reset master; reset master;
@ -87,40 +87,47 @@ insert into t2 select * from t1;
select get_lock("a",10); select get_lock("a",10);
get_lock("a",10) get_lock("a",10)
1 1
show binlog events from 95; show binlog events from 96;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 95 Query 1 # use `test`; BEGIN master-bin.000001 96 Query 1 # use `test`; BEGIN
master-bin.000001 164 Query 1 # use `test`; insert into t1 values(8) master-bin.000001 165 Query 1 # use `test`; insert into t1 values(8)
master-bin.000001 252 Query 1 # use `test`; insert into t2 select * from t1 master-bin.000001 253 Query 1 # use `test`; insert into t2 select * from t1
master-bin.000001 347 Query 1 # use `test`; ROLLBACK master-bin.000001 348 Query 1 # use `test`; ROLLBACK
master-bin.000001 420 Query 1 # use `test`; DO RELEASE_LOCK("a")
delete from t1; delete from t1;
delete from t2; delete from t2;
reset master; reset master;
insert into t1 values(9); insert into t1 values(9);
insert into t2 select * from t1; insert into t2 select * from t1;
show binlog events from 95; show binlog events from 96;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 95 Query 1 # use `test`; insert into t1 values(9) master-bin.000001 96 Query 1 # use `test`; BEGIN
master-bin.000001 183 Query 1 # use `test`; insert into t2 select * from t1 master-bin.000001 165 Query 1 # use `test`; insert into t1 values(9)
master-bin.000001 253 Xid 1 # COMMIT /* xid=59 */
master-bin.000001 280 Query 1 # use `test`; insert into t2 select * from t1
delete from t1; delete from t1;
delete from t2; delete from t2;
reset master; reset master;
insert into t1 values(10); insert into t1 values(10);
begin; begin;
insert into t2 select * from t1; insert into t2 select * from t1;
show binlog events from 95; show binlog events from 96;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 95 Query 1 # use `test`; insert into t1 values(10) master-bin.000001 96 Query 1 # use `test`; BEGIN
master-bin.000001 184 Query 1 # use `test`; insert into t2 select * from t1 master-bin.000001 165 Query 1 # use `test`; insert into t1 values(10)
master-bin.000001 254 Xid 1 # COMMIT /* xid=65 */
master-bin.000001 281 Query 1 # use `test`; insert into t2 select * from t1
insert into t1 values(11); insert into t1 values(11);
commit; commit;
show binlog events from 95; show binlog events from 96;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 95 Query 1 # use `test`; insert into t1 values(10) master-bin.000001 96 Query 1 # use `test`; BEGIN
master-bin.000001 184 Query 1 # use `test`; insert into t2 select * from t1 master-bin.000001 165 Query 1 # use `test`; insert into t1 values(10)
master-bin.000001 279 Query 1 # use `test`; BEGIN master-bin.000001 254 Xid 1 # COMMIT /* xid=65 */
master-bin.000001 348 Query 1 # use `test`; insert into t1 values(11) master-bin.000001 281 Query 1 # use `test`; insert into t2 select * from t1
master-bin.000001 437 Query 1 # use `test`; COMMIT master-bin.000001 376 Query 1 # use `test`; BEGIN
master-bin.000001 445 Query 1 # use `test`; insert into t1 values(11)
master-bin.000001 534 Xid 1 # COMMIT /* xid=67 */
alter table t2 engine=INNODB; alter table t2 engine=INNODB;
delete from t1; delete from t1;
delete from t2; delete from t2;
@ -129,12 +136,12 @@ begin;
insert into t1 values(12); insert into t1 values(12);
insert into t2 select * from t1; insert into t2 select * from t1;
commit; commit;
show binlog events from 95; show binlog events from 96;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 95 Query 1 # use `test`; BEGIN master-bin.000001 96 Query 1 # use `test`; BEGIN
master-bin.000001 164 Query 1 # use `test`; insert into t1 values(12) master-bin.000001 165 Query 1 # use `test`; insert into t1 values(12)
master-bin.000001 253 Query 1 # use `test`; insert into t2 select * from t1 master-bin.000001 254 Query 1 # use `test`; insert into t2 select * from t1
master-bin.000001 348 Query 1 # use `test`; COMMIT master-bin.000001 349 Xid 1 # COMMIT /* xid=77 */
delete from t1; delete from t1;
delete from t2; delete from t2;
reset master; reset master;
@ -142,7 +149,7 @@ begin;
insert into t1 values(13); insert into t1 values(13);
insert into t2 select * from t1; insert into t2 select * from t1;
rollback; rollback;
show binlog events from 95; show binlog events from 96;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
delete from t1; delete from t1;
delete from t2; delete from t2;
@ -154,11 +161,11 @@ insert into t1 values(15);
insert into t2 select * from t1; insert into t2 select * from t1;
rollback to savepoint my_savepoint; rollback to savepoint my_savepoint;
commit; commit;
show binlog events from 95; show binlog events from 96;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 95 Query 1 # use `test`; BEGIN master-bin.000001 96 Query 1 # use `test`; BEGIN
master-bin.000001 164 Query 1 # use `test`; insert into t1 values(14) master-bin.000001 165 Query 1 # use `test`; insert into t1 values(14)
master-bin.000001 253 Query 1 # use `test`; COMMIT master-bin.000001 254 Xid 1 # COMMIT /* xid=93 */
delete from t1; delete from t1;
delete from t2; delete from t2;
reset master; reset master;
@ -174,12 +181,12 @@ select a from t1 order by a;
a a
16 16
18 18
show binlog events from 95; show binlog events from 96;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 95 Query 1 # use `test`; BEGIN master-bin.000001 96 Query 1 # use `test`; BEGIN
master-bin.000001 164 Query 1 # use `test`; insert into t1 values(16) master-bin.000001 165 Query 1 # use `test`; insert into t1 values(16)
master-bin.000001 253 Query 1 # use `test`; insert into t1 values(18) master-bin.000001 254 Query 1 # use `test`; insert into t1 values(18)
master-bin.000001 342 Query 1 # use `test`; COMMIT master-bin.000001 343 Xid 1 # COMMIT /* xid=104 */
delete from t1; delete from t1;
delete from t2; delete from t2;
alter table t2 type=MyISAM; alter table t2 type=MyISAM;

View file

@ -15,6 +15,7 @@ flush logs;
--- Local -- --- Local --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
use test; use test;
SET TIMESTAMP=1000000000; SET TIMESTAMP=1000000000;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
@ -47,6 +48,7 @@ insert into t1 values ("Alas");
--- --database -- --- --database --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
SET INSERT_ID=1; SET INSERT_ID=1;
--- --position -- --- --position --
@ -60,6 +62,7 @@ insert into t1 values ("Alas");
--- Remote -- --- Remote --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
use test; use test;
SET TIMESTAMP=1000000000; SET TIMESTAMP=1000000000;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
@ -92,6 +95,7 @@ insert into t1 values ("Alas");
--- --database -- --- --database --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
SET INSERT_ID=1; SET INSERT_ID=1;
--- --position -- --- --position --
@ -105,6 +109,7 @@ insert into t1 values ("Alas");
--- reading stdin -- --- reading stdin --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
use test; use test;
SET TIMESTAMP=1065204671; SET TIMESTAMP=1065204671;
BEGIN; BEGIN;

View file

@ -16,6 +16,7 @@ insert into t1 values(null, "f");
--- Local -- --- Local --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
use test; use test;
SET TIMESTAMP=1579609942; SET TIMESTAMP=1579609942;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
@ -40,6 +41,7 @@ insert into t1 values(null, "e");
--- offset -- --- offset --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
SET INSERT_ID=1; SET INSERT_ID=1;
use test; use test;
SET TIMESTAMP=1579609942; SET TIMESTAMP=1579609942;
@ -75,6 +77,7 @@ insert into t1 values(null, "e");
--- stop-position -- --- stop-position --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
use test; use test;
SET TIMESTAMP=1579609942; SET TIMESTAMP=1579609942;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
@ -93,6 +96,7 @@ insert into t1 values(null, "c");
--- start-datetime -- --- start-datetime --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
SET INSERT_ID=3; SET INSERT_ID=3;
use test; use test;
SET TIMESTAMP=1579609944; SET TIMESTAMP=1579609944;
@ -109,6 +113,7 @@ insert into t1 values(null, "e");
--- stop-datetime -- --- stop-datetime --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
use test; use test;
SET TIMESTAMP=1579609942; SET TIMESTAMP=1579609942;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
@ -124,6 +129,7 @@ insert into t1 values(null, "b");
--- Local with 2 binlogs on command line -- --- Local with 2 binlogs on command line --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
use test; use test;
SET TIMESTAMP=1579609942; SET TIMESTAMP=1579609942;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
@ -155,6 +161,7 @@ insert into t1 values(null, "f");
--- offset -- --- offset --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
SET INSERT_ID=1; SET INSERT_ID=1;
use test; use test;
SET TIMESTAMP=1579609942; SET TIMESTAMP=1579609942;
@ -204,6 +211,7 @@ insert into t1 values(null, "f");
--- stop-position -- --- stop-position --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
use test; use test;
SET TIMESTAMP=1579609942; SET TIMESTAMP=1579609942;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
@ -229,6 +237,7 @@ SET INSERT_ID=6;
--- start-datetime -- --- start-datetime --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
SET INSERT_ID=3; SET INSERT_ID=3;
use test; use test;
SET TIMESTAMP=1579609944; SET TIMESTAMP=1579609944;
@ -252,6 +261,7 @@ insert into t1 values(null, "f");
--- stop-datetime -- --- stop-datetime --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
use test; use test;
SET TIMESTAMP=1579609942; SET TIMESTAMP=1579609942;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
@ -267,6 +277,7 @@ insert into t1 values(null, "b");
--- Remote -- --- Remote --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
use test; use test;
SET TIMESTAMP=1579609942; SET TIMESTAMP=1579609942;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
@ -291,6 +302,7 @@ insert into t1 values(null, "e");
--- offset -- --- offset --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
SET INSERT_ID=1; SET INSERT_ID=1;
use test; use test;
SET TIMESTAMP=1579609942; SET TIMESTAMP=1579609942;
@ -326,6 +338,7 @@ insert into t1 values(null, "e");
--- stop-position -- --- stop-position --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
use test; use test;
SET TIMESTAMP=1579609942; SET TIMESTAMP=1579609942;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
@ -344,6 +357,7 @@ insert into t1 values(null, "c");
--- start-datetime -- --- start-datetime --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
SET INSERT_ID=3; SET INSERT_ID=3;
use test; use test;
SET TIMESTAMP=1579609944; SET TIMESTAMP=1579609944;
@ -360,6 +374,7 @@ insert into t1 values(null, "e");
--- stop-datetime -- --- stop-datetime --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
use test; use test;
SET TIMESTAMP=1579609942; SET TIMESTAMP=1579609942;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
@ -375,6 +390,7 @@ insert into t1 values(null, "b");
--- Remote with 2 binlogs on command line -- --- Remote with 2 binlogs on command line --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
use test; use test;
SET TIMESTAMP=1579609942; SET TIMESTAMP=1579609942;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
@ -406,6 +422,7 @@ insert into t1 values(null, "f");
--- offset -- --- offset --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
SET INSERT_ID=1; SET INSERT_ID=1;
use test; use test;
SET TIMESTAMP=1579609942; SET TIMESTAMP=1579609942;
@ -455,6 +472,7 @@ insert into t1 values(null, "f");
--- stop-position -- --- stop-position --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
use test; use test;
SET TIMESTAMP=1579609942; SET TIMESTAMP=1579609942;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
@ -480,6 +498,7 @@ SET INSERT_ID=6;
--- start-datetime -- --- start-datetime --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
SET INSERT_ID=3; SET INSERT_ID=3;
use test; use test;
SET TIMESTAMP=1579609944; SET TIMESTAMP=1579609944;
@ -503,6 +522,7 @@ insert into t1 values(null, "f");
--- stop-datetime -- --- stop-datetime --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
use test; use test;
SET TIMESTAMP=1579609942; SET TIMESTAMP=1579609942;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
@ -518,6 +538,7 @@ insert into t1 values(null, "b");
--- to-last-log -- --- to-last-log --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
use test; use test;
SET TIMESTAMP=1579609942; SET TIMESTAMP=1579609942;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;

View file

@ -1,7 +1,7 @@
reset master; reset master;
show master status; show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000001 95 master-bin.000001 96
reset slave; reset slave;
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
@ -17,7 +17,7 @@ Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File
start slave; start slave;
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root MASTER_PORT 7 master-bin.000001 95 # # master-bin.000001 Yes Yes 0 0 95 # None 0 No # # 127.0.0.1 root MASTER_PORT 7 master-bin.000001 96 # # master-bin.000001 Yes Yes 0 0 96 # None 0 No #
drop table if exists t1; drop table if exists t1;
create table t1 (n int); create table t1 (n int);
insert into t1 values (10),(45),(90); insert into t1 values (10),(45),(90);

View file

@ -16,11 +16,11 @@ n
1 1
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 376 # # master-bin.000001 No No 0 0 288 # None 0 No # # 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 377 # # master-bin.000001 No No 0 0 289 # None 0 No #
change master to master_user='root'; change master to master_user='root';
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 288 # # master-bin.000001 No No 0 0 288 # None 0 No # # 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 289 # # master-bin.000001 No No 0 0 289 # None 0 No #
select release_lock("a"); select release_lock("a");
release_lock("a") release_lock("a")
1 1

View file

@ -103,7 +103,7 @@ a b
1 cp850_general_ci 1 cp850_general_ci
drop database mysqltest2; drop database mysqltest2;
drop database mysqltest3; drop database mysqltest3;
show binlog events from 95; show binlog events from 96;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # drop database if exists mysqltest2 master-bin.000001 # Query 1 # drop database if exists mysqltest2
master-bin.000001 # Query 1 # drop database if exists mysqltest3 master-bin.000001 # Query 1 # drop database if exists mysqltest3
@ -175,6 +175,7 @@ select hex(c1), hex(c2) from t1;
hex(c1) hex(c2) hex(c1) hex(c2)
CDF32C20E7E020F0FBE1E0EBEAF3 CDF32C20E7E020F0FBE1E0EBEAF3 CDF32C20E7E020F0FBE1E0EBEAF3 CDF32C20E7E020F0FBE1E0EBEAF3
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
SET TIMESTAMP=1000000000; SET TIMESTAMP=1000000000;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
SET @@session.sql_mode=0; SET @@session.sql_mode=0;

View file

@ -9,7 +9,7 @@ insert into t1 values (1),(1);
ERROR 23000: Duplicate entry '1' for key 1 ERROR 23000: Duplicate entry '1' for key 1
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 287 # # master-bin.000001 Yes Yes test.t3,test.t1,test.t2 0 0 287 # None 0 No # # 127.0.0.1 root MASTER_PORT 1 master-bin.000001 288 # # master-bin.000001 Yes Yes test.t3,test.t1,test.t2 0 0 288 # None 0 No #
show tables like 't1'; show tables like 't1';
Tables_in_test (t1) Tables_in_test (t1)
drop table t1; drop table t1;
@ -26,14 +26,14 @@ select (@id := id) - id from t3;
0 0
kill @id; kill @id;
drop table t2,t3; drop table t2,t3;
show binlog events from 95; show binlog events from 96;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 95 Query 1 194 use `test`; create table t1 (a int primary key) master-bin.000001 96 Query 1 195 use `test`; create table t1 (a int primary key)
master-bin.000001 194 Query 1 287 use `test`; insert into t1 values (1),(1) master-bin.000001 195 Query 1 288 use `test`; insert into t1 values (1),(1)
master-bin.000001 287 Query 1 364 use `test`; drop table t1 master-bin.000001 288 Query 1 365 use `test`; drop table t1
master-bin.000001 364 Query 1 463 use `test`; create table t2 (a int primary key) master-bin.000001 365 Query 1 464 use `test`; create table t2 (a int primary key)
master-bin.000001 463 Query 1 551 use `test`; insert into t2 values(1) master-bin.000001 464 Query 1 552 use `test`; insert into t2 values(1)
master-bin.000001 551 Query 1 639 use `test`; create table t3 (id int) master-bin.000001 552 Query 1 640 use `test`; create table t3 (id int)
master-bin.000001 639 Query 1 741 use `test`; insert into t3 values(connection_id()) master-bin.000001 640 Query 1 742 use `test`; insert into t3 values(connection_id())
master-bin.000001 741 Query 1 861 use `test`; update t2 set a = a + 1 + get_lock('crash_lock%20C', 10) master-bin.000001 742 Query 1 862 use `test`; update t2 set a = a + 1 + get_lock('crash_lock%20C', 10)
master-bin.000001 861 Query 1 941 use `test`; drop table t2,t3 master-bin.000001 862 Query 1 942 use `test`; drop table t2,t3

View file

@ -14,4 +14,4 @@ start slave;
flush logs; flush logs;
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root SLAVE_PORT 60 slave-bin.000001 206 # # slave-bin.000001 Yes Yes 0 0 206 # None 0 No # # 127.0.0.1 root SLAVE_PORT 60 slave-bin.000001 207 # # slave-bin.000001 Yes Yes 0 0 207 # None 0 No #

View file

@ -14,27 +14,27 @@ rename table t1 to t5, t2 to t1;
flush no_write_to_binlog tables; flush no_write_to_binlog tables;
show binlog events; show binlog events;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 4 Format_desc 1 95 Server ver: SERVER_VERSION, Binlog ver: 4 master-bin.000001 4 Format_desc 1 96 Server ver: SERVER_VERSION, Binlog ver: 4
master-bin.000001 95 Query 1 182 use `test`; create table t1 (a int) master-bin.000001 96 Query 1 183 use `test`; create table t1 (a int)
master-bin.000001 182 Query 1 272 use `test`; insert into t1 values (10) master-bin.000001 183 Query 1 273 use `test`; insert into t1 values (10)
master-bin.000001 272 Query 1 359 use `test`; create table t2 (a int) master-bin.000001 273 Query 1 360 use `test`; create table t2 (a int)
master-bin.000001 359 Query 1 469 use `test`; create table t3 (a int) engine=merge union(t1) master-bin.000001 360 Query 1 470 use `test`; create table t3 (a int) engine=merge union(t1)
master-bin.000001 469 Query 1 556 use `test`; create table t4 (a int) master-bin.000001 470 Query 1 557 use `test`; create table t4 (a int)
master-bin.000001 556 Query 1 651 use `test`; insert into t4 select * from t3 master-bin.000001 557 Query 1 652 use `test`; insert into t4 select * from t3
master-bin.000001 651 Query 1 746 use `test`; rename table t1 to t5, t2 to t1 master-bin.000001 652 Query 1 747 use `test`; rename table t1 to t5, t2 to t1
select * from t3; select * from t3;
a a
flush tables; flush tables;
show binlog events; show binlog events;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 4 Format_desc 1 95 Server ver: SERVER_VERSION, Binlog ver: 4 master-bin.000001 4 Format_desc 1 96 Server ver: SERVER_VERSION, Binlog ver: 4
master-bin.000001 95 Query 1 182 use `test`; create table t1 (a int) master-bin.000001 96 Query 1 183 use `test`; create table t1 (a int)
master-bin.000001 182 Query 1 272 use `test`; insert into t1 values (10) master-bin.000001 183 Query 1 273 use `test`; insert into t1 values (10)
master-bin.000001 272 Query 1 359 use `test`; create table t2 (a int) master-bin.000001 273 Query 1 360 use `test`; create table t2 (a int)
master-bin.000001 359 Query 1 469 use `test`; create table t3 (a int) engine=merge union(t1) master-bin.000001 360 Query 1 470 use `test`; create table t3 (a int) engine=merge union(t1)
master-bin.000001 469 Query 1 556 use `test`; create table t4 (a int) master-bin.000001 470 Query 1 557 use `test`; create table t4 (a int)
master-bin.000001 556 Query 1 651 use `test`; insert into t4 select * from t3 master-bin.000001 557 Query 1 652 use `test`; insert into t4 select * from t3
master-bin.000001 651 Query 1 746 use `test`; rename table t1 to t5, t2 to t1 master-bin.000001 652 Query 1 747 use `test`; rename table t1 to t5, t2 to t1
master-bin.000001 746 Query 1 822 use `test`; flush tables master-bin.000001 747 Query 1 823 use `test`; flush tables
select * from t3; select * from t3;
a a

View file

@ -22,7 +22,7 @@ day id category name
2003-03-22 2416 a bbbbb 2003-03-22 2416 a bbbbb
show master status; show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB File Position Binlog_Do_DB Binlog_Ignore_DB
slave-bin.000001 1096 slave-bin.000001 1097
drop table t1; drop table t1;
drop table t2; drop table t2;
drop table t3; drop table t3;
@ -33,7 +33,7 @@ set global sql_slave_skip_counter=1;
start slave; start slave;
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1559 # # master-bin.000001 Yes Yes 0 0 1559 # None 0 No # # 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1560 # # master-bin.000001 Yes Yes 0 0 1560 # None 0 No #
set sql_log_bin=0; set sql_log_bin=0;
delete from t1; delete from t1;
set sql_log_bin=1; set sql_log_bin=1;
@ -43,7 +43,7 @@ change master to master_user='test';
change master to master_user='root'; change master to master_user='root';
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1667 # # master-bin.000001 No No 0 0 1667 # None 0 No # # 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1668 # # master-bin.000001 No No 0 0 1668 # None 0 No #
set global sql_slave_skip_counter=1; set global sql_slave_skip_counter=1;
start slave; start slave;
set sql_log_bin=0; set sql_log_bin=0;
@ -64,5 +64,5 @@ terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by
ERROR 23000: Duplicate entry '2003-03-22' for key 1 ERROR 23000: Duplicate entry '2003-03-22' for key 1
show master status; show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000001 536 master-bin.000001 537
drop table t2; drop table t2;

View file

@ -10,8 +10,8 @@ create database mysqltest;
create table t1(a int, b int, unique(b)); create table t1(a int, b int, unique(b));
use mysqltest; use mysqltest;
load data infile '../../std_data/rpl_loaddata.dat' into table test.t1; load data infile '../../std_data/rpl_loaddata.dat' into table test.t1;
show binlog events from 95; show binlog events from 96;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 95 Query 1 197 drop database if exists mysqltest master-bin.000001 96 Query 1 198 drop database if exists mysqltest
master-bin.000001 197 Query 1 291 create database mysqltest master-bin.000001 198 Query 1 292 create database mysqltest
drop database mysqltest; drop database mysqltest;

View file

@ -10,5 +10,5 @@ load data infile '../../std_data/rpl_loaddata.dat' into table test.t1;
select count(*) from t1; select count(*) from t1;
count(*) count(*)
2 2
show binlog events from 95; show binlog events from 96;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info

View file

@ -19,25 +19,25 @@ count(*)
drop table t1; drop table t1;
show binlog events; show binlog events;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 4 Format_desc 1 95 Server ver: VERSION, Binlog ver: 4 master-bin.000001 4 Format_desc 1 96 Server ver: VERSION, Binlog ver: 4
master-bin.000001 95 Query 1 217 use `test`; create table t1(n int not null auto_increment primary key) master-bin.000001 96 Query 1 218 use `test`; create table t1(n int not null auto_increment primary key)
master-bin.000001 217 Intvar 1 245 INSERT_ID=1 master-bin.000001 218 Intvar 1 246 INSERT_ID=1
master-bin.000001 245 Query 1 337 use `test`; insert into t1 values (NULL) master-bin.000001 246 Query 1 338 use `test`; insert into t1 values (NULL)
master-bin.000001 337 Query 1 414 use `test`; drop table t1 master-bin.000001 338 Query 1 415 use `test`; drop table t1
master-bin.000001 414 Query 1 518 use `test`; create table t1 (word char(20) not null) master-bin.000001 415 Query 1 519 use `test`; create table t1 (word char(20) not null)
master-bin.000001 518 Create_file 1 1188 db=test;table=t1;file_id=1;block_len=581 master-bin.000001 519 Create_file 1 1189 db=test;table=t1;file_id=1;block_len=581
master-bin.000001 1188 Exec_load 1 1211 ;file_id=1 master-bin.000001 1189 Exec_load 1 1212 ;file_id=1
master-bin.000001 1211 Query 1 1288 use `test`; drop table t1 master-bin.000001 1212 Query 1 1289 use `test`; drop table t1
show binlog events from 95 limit 1; show binlog events from 96 limit 1;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 95 Query 1 217 use `test`; create table t1(n int not null auto_increment primary key) master-bin.000001 96 Query 1 218 use `test`; create table t1(n int not null auto_increment primary key)
show binlog events from 95 limit 2; show binlog events from 96 limit 2;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 95 Query 1 217 use `test`; create table t1(n int not null auto_increment primary key) master-bin.000001 96 Query 1 218 use `test`; create table t1(n int not null auto_increment primary key)
master-bin.000001 217 Intvar 1 245 INSERT_ID=1 master-bin.000001 218 Intvar 1 246 INSERT_ID=1
show binlog events from 95 limit 2,1; show binlog events from 96 limit 2,1;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 245 Query 1 337 use `test`; insert into t1 values (NULL) master-bin.000001 246 Query 1 338 use `test`; insert into t1 values (NULL)
flush logs; flush logs;
create table t5 (a int); create table t5 (a int);
drop table t5; drop table t5;
@ -49,24 +49,24 @@ insert into t1 values (1);
drop table t1; drop table t1;
show binlog events; show binlog events;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 4 Format_desc 1 95 Server ver: VERSION, Binlog ver: 4 master-bin.000001 4 Format_desc 1 96 Server ver: VERSION, Binlog ver: 4
master-bin.000001 95 Query 1 217 use `test`; create table t1(n int not null auto_increment primary key) master-bin.000001 96 Query 1 218 use `test`; create table t1(n int not null auto_increment primary key)
master-bin.000001 217 Intvar 1 245 INSERT_ID=1 master-bin.000001 218 Intvar 1 246 INSERT_ID=1
master-bin.000001 245 Query 1 337 use `test`; insert into t1 values (NULL) master-bin.000001 246 Query 1 338 use `test`; insert into t1 values (NULL)
master-bin.000001 337 Query 1 414 use `test`; drop table t1 master-bin.000001 338 Query 1 415 use `test`; drop table t1
master-bin.000001 414 Query 1 518 use `test`; create table t1 (word char(20) not null) master-bin.000001 415 Query 1 519 use `test`; create table t1 (word char(20) not null)
master-bin.000001 518 Create_file 1 1188 db=test;table=t1;file_id=1;block_len=581 master-bin.000001 519 Create_file 1 1189 db=test;table=t1;file_id=1;block_len=581
master-bin.000001 1188 Exec_load 1 1211 ;file_id=1 master-bin.000001 1189 Exec_load 1 1212 ;file_id=1
master-bin.000001 1211 Query 1 1288 use `test`; drop table t1 master-bin.000001 1212 Query 1 1289 use `test`; drop table t1
master-bin.000001 1288 Rotate 1 1332 master-bin.000002;pos=4 master-bin.000001 1289 Rotate 1 1333 master-bin.000002;pos=4
show binlog events in 'master-bin.000002'; show binlog events in 'master-bin.000002';
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000002 4 Format_desc 1 95 Server ver: VERSION, Binlog ver: 4 master-bin.000002 4 Format_desc 1 96 Server ver: VERSION, Binlog ver: 4
master-bin.000002 95 Query 1 182 use `test`; create table t5 (a int) master-bin.000002 96 Query 1 183 use `test`; create table t5 (a int)
master-bin.000002 182 Query 1 259 use `test`; drop table t5 master-bin.000002 183 Query 1 260 use `test`; drop table t5
master-bin.000002 259 Query 1 346 use `test`; create table t1 (n int) master-bin.000002 260 Query 1 347 use `test`; create table t1 (n int)
master-bin.000002 346 Query 1 435 use `test`; insert into t1 values (1) master-bin.000002 347 Query 1 436 use `test`; insert into t1 values (1)
master-bin.000002 435 Query 1 512 use `test`; drop table t1 master-bin.000002 436 Query 1 513 use `test`; drop table t1
show binary logs; show binary logs;
Log_name Log_name
master-bin.000001 master-bin.000001
@ -78,26 +78,26 @@ slave-bin.000001
slave-bin.000002 slave-bin.000002
show binlog events in 'slave-bin.000001' from 4; show binlog events in 'slave-bin.000001' from 4;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
slave-bin.000001 4 Format_desc 2 95 Server ver: VERSION, Binlog ver: 4 slave-bin.000001 4 Format_desc 2 96 Server ver: VERSION, Binlog ver: 4
slave-bin.000001 95 Query 1 217 use `test`; create table t1(n int not null auto_increment primary key) slave-bin.000001 96 Query 1 218 use `test`; create table t1(n int not null auto_increment primary key)
slave-bin.000001 217 Intvar 1 245 INSERT_ID=1 slave-bin.000001 218 Intvar 1 246 INSERT_ID=1
slave-bin.000001 245 Query 1 337 use `test`; insert into t1 values (NULL) slave-bin.000001 246 Query 1 338 use `test`; insert into t1 values (NULL)
slave-bin.000001 337 Query 1 414 use `test`; drop table t1 slave-bin.000001 338 Query 1 415 use `test`; drop table t1
slave-bin.000001 414 Query 1 518 use `test`; create table t1 (word char(20) not null) slave-bin.000001 415 Query 1 519 use `test`; create table t1 (word char(20) not null)
slave-bin.000001 518 Create_file 1 1197 db=test;table=t1;file_id=1;block_len=581 slave-bin.000001 519 Create_file 1 1198 db=test;table=t1;file_id=1;block_len=581
slave-bin.000001 1197 Exec_load 1 1220 ;file_id=1 slave-bin.000001 1198 Exec_load 1 1221 ;file_id=1
slave-bin.000001 1220 Query 1 1297 use `test`; drop table t1 slave-bin.000001 1221 Query 1 1298 use `test`; drop table t1
slave-bin.000001 1297 Query 1 1384 use `test`; create table t5 (a int) slave-bin.000001 1298 Query 1 1385 use `test`; create table t5 (a int)
slave-bin.000001 1384 Query 1 1461 use `test`; drop table t5 slave-bin.000001 1385 Query 1 1462 use `test`; drop table t5
slave-bin.000001 1461 Rotate 2 1504 slave-bin.000002;pos=4 slave-bin.000001 1462 Rotate 2 1505 slave-bin.000002;pos=4
show binlog events in 'slave-bin.000002' from 4; show binlog events in 'slave-bin.000002' from 4;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
slave-bin.000002 4 Format_desc 2 95 Server ver: VERSION, Binlog ver: 4 slave-bin.000002 4 Format_desc 2 96 Server ver: VERSION, Binlog ver: 4
slave-bin.000002 95 Query 1 182 use `test`; create table t1 (n int) slave-bin.000002 96 Query 1 183 use `test`; create table t1 (n int)
slave-bin.000002 182 Query 1 271 use `test`; insert into t1 values (1) slave-bin.000002 183 Query 1 272 use `test`; insert into t1 values (1)
slave-bin.000002 271 Query 1 348 use `test`; drop table t1 slave-bin.000002 272 Query 1 349 use `test`; drop table t1
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root MASTER_PORT 1 master-bin.000002 512 # # master-bin.000002 Yes Yes 0 0 512 # None 0 No # # 127.0.0.1 root MASTER_PORT 1 master-bin.000002 513 # # master-bin.000002 Yes Yes 0 0 513 # None 0 No #
show binlog events in 'slave-bin.000005' from 4; show binlog events in 'slave-bin.000005' from 4;
ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Could not find target log ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Could not find target log

View file

@ -6,10 +6,10 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave; start slave;
show master status; show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000001 95 master-bin.000001 96
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 95 # # master-bin.000001 Yes Yes 0 0 95 # None 0 No # # 127.0.0.1 root MASTER_PORT 1 master-bin.000001 96 # # master-bin.000001 Yes Yes 0 0 96 # None 0 No #
stop slave; stop slave;
change master to master_log_pos=73; change master to master_log_pos=73;
start slave; start slave;
@ -30,13 +30,13 @@ Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File
# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 173 # # master-bin.000001 No Yes 0 0 173 # None 0 No # # 127.0.0.1 root MASTER_PORT 1 master-bin.000001 173 # # master-bin.000001 No Yes 0 0 173 # None 0 No #
show master status; show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000001 95 master-bin.000001 96
create table if not exists t1 (n int); create table if not exists t1 (n int);
drop table if exists t1; drop table if exists t1;
create table t1 (n int); create table t1 (n int);
insert into t1 values (1),(2),(3); insert into t1 values (1),(2),(3);
stop slave; stop slave;
change master to master_log_pos=95; change master to master_log_pos=96;
start slave; start slave;
select * from t1; select * from t1;
n n

View file

@ -16,7 +16,7 @@ select @@global.max_relay_log_size;
start slave; start slave;
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 73751 # # master-bin.000001 Yes Yes 0 0 73751 # None 0 No # # 127.0.0.1 root MASTER_PORT 1 master-bin.000001 73752 # # master-bin.000001 Yes Yes 0 0 73752 # None 0 No #
stop slave; stop slave;
reset slave; reset slave;
set global max_relay_log_size=(5*4096); set global max_relay_log_size=(5*4096);
@ -26,7 +26,7 @@ select @@global.max_relay_log_size;
start slave; start slave;
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 73751 # # master-bin.000001 Yes Yes 0 0 73751 # None 0 No # # 127.0.0.1 root MASTER_PORT 1 master-bin.000001 73752 # # master-bin.000001 Yes Yes 0 0 73752 # None 0 No #
stop slave; stop slave;
reset slave; reset slave;
set global max_relay_log_size=0; set global max_relay_log_size=0;
@ -36,7 +36,7 @@ select @@global.max_relay_log_size;
start slave; start slave;
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 73751 # # master-bin.000001 Yes Yes 0 0 73751 # None 0 No # # 127.0.0.1 root MASTER_PORT 1 master-bin.000001 73752 # # master-bin.000001 Yes Yes 0 0 73752 # None 0 No #
stop slave; stop slave;
reset slave; reset slave;
flush logs; flush logs;
@ -49,13 +49,13 @@ flush logs;
create table t1 (a int); create table t1 (a int);
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 73838 # # master-bin.000001 Yes Yes 0 0 73838 # None 0 No # # 127.0.0.1 root MASTER_PORT 1 master-bin.000001 73839 # # master-bin.000001 Yes Yes 0 0 73839 # None 0 No #
flush logs; flush logs;
drop table t1; drop table t1;
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 73915 # # master-bin.000001 Yes Yes 0 0 73915 # None 0 No # # 127.0.0.1 root MASTER_PORT 1 master-bin.000001 73916 # # master-bin.000001 Yes Yes 0 0 73916 # None 0 No #
flush logs; flush logs;
show master status; show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000002 95 master-bin.000002 96

View file

@ -18,5 +18,5 @@ max(a)
8000 8000
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 743228 # # master-bin.000001 Yes Yes 0 0 743228 # None 0 No # # 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 743186 # # master-bin.000001 Yes Yes 0 0 743186 # None 0 No #
drop table t1; drop table t1;

View file

@ -28,4 +28,4 @@ ERROR 42S02: Table 'test.t11' doesn't exist
drop table if exists t1,t2,t11; drop table if exists t1,t2,t11;
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1617 # # master-bin.000001 Yes Yes test.t1 0 0 1617 # None 0 No # # 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1618 # # master-bin.000001 Yes Yes test.t1 0 0 1618 # None 0 No #

View file

@ -6,12 +6,12 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave; start slave;
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 95 # # master-bin.000001 Yes Yes 0 0 95 # None 0 No # # 127.0.0.1 root MASTER_PORT 1 master-bin.000001 96 # # master-bin.000001 Yes Yes 0 0 96 # None 0 No #
stop slave; stop slave;
change master to master_user='test'; change master to master_user='test';
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 test MASTER_PORT 1 master-bin.000001 95 # # master-bin.000001 No No 0 0 95 # None 0 No # # 127.0.0.1 test MASTER_PORT 1 master-bin.000001 96 # # master-bin.000001 No No 0 0 96 # None 0 No #
reset slave; reset slave;
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
@ -19,7 +19,7 @@ Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File
start slave; start slave;
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 95 # # master-bin.000001 Yes Yes 0 0 95 # None 0 No # # 127.0.0.1 root MASTER_PORT 1 master-bin.000001 96 # # master-bin.000001 Yes Yes 0 0 96 # None 0 No #
stop slave; stop slave;
reset slave; reset slave;
start slave; start slave;

View file

@ -16,7 +16,7 @@ create table t1 (s text);
insert into t1 values('Could not break slave'),('Tried hard'); insert into t1 values('Could not break slave'),('Tried hard');
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root MASTER_PORT 60 master-bin.000001 549 # # master-bin.000001 Yes Yes 0 0 549 # None 0 No # # 127.0.0.1 root MASTER_PORT 60 master-bin.000001 550 # # master-bin.000001 Yes Yes 0 0 550 # None 0 No #
select * from t1; select * from t1;
s s
Could not break slave Could not break slave
@ -57,7 +57,7 @@ master-bin.000003
insert into t2 values (65); insert into t2 values (65);
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root MASTER_PORT 60 master-bin.000003 497 # # master-bin.000003 Yes Yes 0 0 497 # None 0 No # # 127.0.0.1 root MASTER_PORT 60 master-bin.000003 498 # # master-bin.000003 Yes Yes 0 0 498 # None 0 No #
select * from t2; select * from t2;
m m
34 34
@ -79,13 +79,13 @@ master-bin.000004
master-bin.000005 master-bin.000005
show master status; show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000005 2050 master-bin.000005 2051
select * from t4; select * from t4;
a a
testing temporary tables part 2 testing temporary tables part 2
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root MASTER_PORT 60 master-bin.000005 2050 # # master-bin.000005 Yes Yes 0 0 2050 # None 0 No # # 127.0.0.1 root MASTER_PORT 60 master-bin.000005 2051 # # master-bin.000005 Yes Yes 0 0 2051 # None 0 No #
lock tables t3 read; lock tables t3 read;
select count(*) from t3 where n >= 4; select count(*) from t3 where n >= 4;
count(*) count(*)

View file

@ -10,7 +10,7 @@ stop slave;
change master to master_port=SLAVE_PORT; change master to master_port=SLAVE_PORT;
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
127.0.0.1 root SLAVE_PORT 1 4 slave-relay-bin.000001 4 No No # 0 0 0 95 None 0 No NULL 127.0.0.1 root SLAVE_PORT 1 4 slave-relay-bin.000001 4 No No # 0 0 0 96 None 0 No NULL
start slave; start slave;
insert into t1 values (1); insert into t1 values (1);
show status like "slave_running"; show status like "slave_running";

View file

@ -10,7 +10,7 @@ stop slave;
change master to master_port=SLAVE_PORT; change master to master_port=SLAVE_PORT;
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
127.0.0.1 root SLAVE_PORT 1 4 slave-relay-bin.000001 4 No No # 0 0 0 95 None 0 No NULL 127.0.0.1 root SLAVE_PORT 1 4 slave-relay-bin.000001 4 No No # 0 0 0 96 None 0 No NULL
start slave; start slave;
insert into t1 values (1); insert into t1 values (1);
select * from t1; select * from t1;

View file

@ -38,19 +38,19 @@ f
7 7
show binlog events; show binlog events;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 4 Format_desc 1 95 Server ver: VERSION, Binlog ver: 4 master-bin.000001 4 Format_desc 1 96 Server ver: VERSION, Binlog ver: 4
master-bin.000001 95 Query 1 185 use `test`; drop table if exists t1,t2 master-bin.000001 96 Query 1 186 use `test`; drop table if exists t1,t2
master-bin.000001 185 Query 1 271 use `test`; create table t1(f int) master-bin.000001 186 Query 1 272 use `test`; create table t1(f int)
master-bin.000001 271 Query 1 357 use `test`; create table t2(f int) master-bin.000001 272 Query 1 358 use `test`; create table t2(f int)
master-bin.000001 357 Query 1 483 use `test`; insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10) master-bin.000001 358 Query 1 484 use `test`; insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10)
master-bin.000001 483 Query 1 579 use `test`; create temporary table t3(f int) master-bin.000001 484 Query 1 580 use `test`; create temporary table t3(f int)
master-bin.000001 579 Query 1 684 use `test`; insert into t3 select * from t1 where f<6 master-bin.000001 580 Query 1 685 use `test`; insert into t3 select * from t1 where f<6
master-bin.000001 684 Query 1 780 use `test`; create temporary table t3(f int) master-bin.000001 685 Query 1 781 use `test`; create temporary table t3(f int)
master-bin.000001 780 Query 1 882 use `test`; insert into t2 select count(*) from t3 master-bin.000001 781 Query 1 883 use `test`; insert into t2 select count(*) from t3
master-bin.000001 882 Query 1 988 use `test`; insert into t3 select * from t1 where f>=4 master-bin.000001 883 Query 1 989 use `test`; insert into t3 select * from t1 where f>=4
master-bin.000001 988 Query 1 1075 use `test`; drop temporary table t3 master-bin.000001 989 Query 1 1076 use `test`; drop temporary table t3
master-bin.000001 1075 Query 1 1177 use `test`; insert into t2 select count(*) from t3 master-bin.000001 1076 Query 1 1178 use `test`; insert into t2 select count(*) from t3
master-bin.000001 1177 Query 1 1264 use `test`; drop temporary table t3 master-bin.000001 1178 Query 1 1265 use `test`; drop temporary table t3
drop table t1, t2; drop table t1, t2;
use test; use test;
SET TIMESTAMP=1040323920; SET TIMESTAMP=1040323920;

View file

@ -32,13 +32,13 @@ t
2004-06-11 09:39:02 2004-06-11 09:39:02
show binlog events; show binlog events;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 4 Format_desc 1 95 Server ver: VERSION, Binlog ver: 4 master-bin.000001 4 Format_desc 1 96 Server ver: VERSION, Binlog ver: 4
master-bin.000001 95 Query 1 188 use `test`; create table t1 (t timestamp) master-bin.000001 96 Query 1 189 use `test`; create table t1 (t timestamp)
master-bin.000001 188 Query 1 280 use `test`; create table t2 (t char(32)) master-bin.000001 189 Query 1 281 use `test`; create table t2 (t char(32))
master-bin.000001 280 Query 1 372 use `test`; SET ONE_SHOT TIME_ZONE='UTC' master-bin.000001 281 Query 1 373 use `test`; SET ONE_SHOT TIME_ZONE='UTC'
master-bin.000001 372 Query 1 496 use `test`; insert into t1 values ('20040101000000'), ('20040611093902') master-bin.000001 373 Query 1 497 use `test`; insert into t1 values ('20040101000000'), ('20040611093902')
master-bin.000001 496 Query 1 574 use `test`; delete from t1 master-bin.000001 497 Query 1 575 use `test`; delete from t1
master-bin.000001 574 Query 1 698 use `test`; insert into t1 values ('20040101000000'), ('20040611093902') master-bin.000001 575 Query 1 699 use `test`; insert into t1 values ('20040101000000'), ('20040611093902')
set time_zone='MET'; set time_zone='MET';
insert into t2 (select t from t1); insert into t2 (select t from t1);
select * from t1; select * from t1;

View file

@ -14,14 +14,14 @@ insert into t2 values (3),(4);
drop table t2; drop table t2;
show binlog events; show binlog events;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 4 Format_desc 1 95 Server ver: VERSION, Binlog ver: 4 master-bin.000001 4 Format_desc 1 96 Server ver: VERSION, Binlog ver: 4
master-bin.000001 95 Query 1 217 use `test`; create table t1(n int not null auto_increment primary key) master-bin.000001 96 Query 1 218 use `test`; create table t1(n int not null auto_increment primary key)
master-bin.000001 217 Query 1 318 use `test`; insert into t1 values (1),(2),(3),(4) master-bin.000001 218 Query 1 319 use `test`; insert into t1 values (1),(2),(3),(4)
master-bin.000001 318 Query 1 395 use `test`; drop table t1 master-bin.000001 319 Query 1 396 use `test`; drop table t1
master-bin.000001 395 Query 1 517 use `test`; create table t2(n int not null auto_increment primary key) master-bin.000001 396 Query 1 518 use `test`; create table t2(n int not null auto_increment primary key)
master-bin.000001 517 Query 1 610 use `test`; insert into t2 values (1),(2) master-bin.000001 518 Query 1 611 use `test`; insert into t2 values (1),(2)
master-bin.000001 610 Query 1 703 use `test`; insert into t2 values (3),(4) master-bin.000001 611 Query 1 704 use `test`; insert into t2 values (3),(4)
master-bin.000001 703 Query 1 780 use `test`; drop table t2 master-bin.000001 704 Query 1 781 use `test`; drop table t2
start slave until master_log_file='master-bin.000001', master_log_pos=304; start slave until master_log_file='master-bin.000001', master_log_pos=304;
select * from t1; select * from t1;
n n
@ -31,7 +31,7 @@ n
4 4
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 780 slave-relay-bin.000004 # master-bin.000001 Yes No 0 0 318 # Master master-bin.000001 304 No # # 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 781 slave-relay-bin.000004 # master-bin.000001 Yes No 0 0 319 # Master master-bin.000001 304 No #
start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291; start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291;
select * from t1; select * from t1;
n n
@ -41,7 +41,7 @@ n
4 4
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 780 slave-relay-bin.000004 # master-bin.000001 Yes No 0 0 318 # Master master-no-such-bin.000001 291 No # # 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 781 slave-relay-bin.000004 # master-bin.000001 Yes No 0 0 319 # Master master-no-such-bin.000001 291 No #
start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=710; start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=710;
select * from t2; select * from t2;
n n
@ -49,13 +49,13 @@ n
2 2
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 780 slave-relay-bin.000004 # master-bin.000001 Yes No 0 0 610 # Relay slave-relay-bin.000004 710 No # # 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 781 slave-relay-bin.000004 # master-bin.000001 Yes No 0 0 611 # Relay slave-relay-bin.000004 710 No #
start slave; start slave;
stop slave; stop slave;
start slave until master_log_file='master-bin.000001', master_log_pos=710; start slave until master_log_file='master-bin.000001', master_log_pos=710;
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 780 slave-relay-bin.000004 # master-bin.000001 Yes No 0 0 780 # Master master-bin.000001 710 No # # 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 781 slave-relay-bin.000004 # master-bin.000001 Yes No 0 0 781 # Master master-bin.000001 710 No #
start slave until master_log_file='master-bin', master_log_pos=561; start slave until master_log_file='master-bin', master_log_pos=561;
ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL
start slave until master_log_file='master-bin.000001', master_log_pos=561, relay_log_pos=12; start slave until master_log_file='master-bin.000001', master_log_pos=561, relay_log_pos=12;

View file

@ -76,35 +76,35 @@ abcn1n2
NULL NULL
NULL NULL
NULL NULL
show binlog events from 95; show binlog events from 96;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
slave-bin.000001 95 Query 1 186 use `test`; create table t1(n char(30)) slave-bin.000001 96 Query 1 187 use `test`; create table t1(n char(30))
slave-bin.000001 186 User var 2 229 @`i1`=12345678901234 slave-bin.000001 187 User var 2 230 @`i1`=12345678901234
slave-bin.000001 229 User var 2 272 @`i2`=-12345678901234 slave-bin.000001 230 User var 2 273 @`i2`=-12345678901234
slave-bin.000001 272 User var 2 315 @`i3`=0 slave-bin.000001 273 User var 2 316 @`i3`=0
slave-bin.000001 315 User var 2 358 @`i4`=-1 slave-bin.000001 316 User var 2 359 @`i4`=-1
slave-bin.000001 358 Query 1 470 use `test`; insert into t1 values (@i1), (@i2), (@i3), (@i4) slave-bin.000001 359 Query 1 471 use `test`; insert into t1 values (@i1), (@i2), (@i3), (@i4)
slave-bin.000001 470 User var 2 509 @`r1`=12.5 slave-bin.000001 471 User var 2 510 @`r1`=12.5
slave-bin.000001 509 User var 2 548 @`r2`=-12.5 slave-bin.000001 510 User var 2 549 @`r2`=-12.5
slave-bin.000001 548 Query 1 646 use `test`; insert into t1 values (@r1), (@r2) slave-bin.000001 549 Query 1 647 use `test`; insert into t1 values (@r1), (@r2)
slave-bin.000001 646 User var 2 695 @`s1`=_latin1 0x5468697320697320612074657374 COLLATE latin1_swedish_ci slave-bin.000001 647 User var 2 696 @`s1`=_latin1 0x5468697320697320612074657374 COLLATE latin1_swedish_ci
slave-bin.000001 695 User var 2 730 @`s2`=_latin1 "" COLLATE latin1_swedish_ci slave-bin.000001 696 User var 2 731 @`s2`=_latin1 "" COLLATE latin1_swedish_ci
slave-bin.000001 730 User var 2 772 @`s3`=_latin1 0x61626327646566 COLLATE latin1_swedish_ci slave-bin.000001 731 User var 2 773 @`s3`=_latin1 0x61626327646566 COLLATE latin1_swedish_ci
slave-bin.000001 772 User var 2 814 @`s4`=_latin1 0x6162635C646566 COLLATE latin1_swedish_ci slave-bin.000001 773 User var 2 815 @`s4`=_latin1 0x6162635C646566 COLLATE latin1_swedish_ci
slave-bin.000001 814 User var 2 856 @`s5`=_latin1 0x61626327646566 COLLATE latin1_swedish_ci slave-bin.000001 815 User var 2 857 @`s5`=_latin1 0x61626327646566 COLLATE latin1_swedish_ci
slave-bin.000001 856 Query 1 975 use `test`; insert into t1 values (@s1), (@s2), (@s3), (@s4), (@s5) slave-bin.000001 857 Query 1 976 use `test`; insert into t1 values (@s1), (@s2), (@s3), (@s4), (@s5)
slave-bin.000001 975 User var 2 1001 @`n1`=NULL slave-bin.000001 976 User var 2 1002 @`n1`=NULL
slave-bin.000001 1001 Query 1 1092 use `test`; insert into t1 values (@n1) slave-bin.000001 1002 Query 1 1093 use `test`; insert into t1 values (@n1)
slave-bin.000001 1092 User var 2 1118 @`n2`=NULL slave-bin.000001 1093 User var 2 1119 @`n2`=NULL
slave-bin.000001 1118 Query 1 1209 use `test`; insert into t1 values (@n2) slave-bin.000001 1119 Query 1 1210 use `test`; insert into t1 values (@n2)
slave-bin.000001 1209 Query 1 1326 use `test`; insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1) slave-bin.000001 1210 Query 1 1327 use `test`; insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1)
slave-bin.000001 1326 User var 2 1368 @`a`=2 slave-bin.000001 1327 User var 2 1369 @`a`=2
slave-bin.000001 1368 Query 1 1469 use `test`; insert into t1 values (@a+(@b:=@a+1)) slave-bin.000001 1369 Query 1 1470 use `test`; insert into t1 values (@a+(@b:=@a+1))
slave-bin.000001 1469 User var 2 1506 @`q`=_latin1 0x616263 COLLATE latin1_swedish_ci slave-bin.000001 1470 User var 2 1507 @`q`=_latin1 0x616263 COLLATE latin1_swedish_ci
slave-bin.000001 1506 Query 1 1639 use `test`; insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2')) slave-bin.000001 1507 Query 1 1640 use `test`; insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2'))
slave-bin.000001 1639 User var 2 1681 @`a`=5 slave-bin.000001 1640 User var 2 1682 @`a`=5
slave-bin.000001 1681 Query 1 1776 use `test`; insert into t1 values (@a),(@a) slave-bin.000001 1682 Query 1 1777 use `test`; insert into t1 values (@a),(@a)
slave-bin.000001 1776 User var 2 1801 @`a`=NULL slave-bin.000001 1777 User var 2 1802 @`a`=NULL
slave-bin.000001 1801 Query 1 1903 use `test`; insert into t1 values (@a),(@a),(@a*5) slave-bin.000001 1802 Query 1 1904 use `test`; insert into t1 values (@a),(@a),(@a*5)
drop table t1; drop table t1;
stop slave; stop slave;

View file

@ -174,14 +174,15 @@ INSERT INTO t1 VALUES(@`a b`);
set @var1= "';aaa"; set @var1= "';aaa";
SET @var2=char(ascii('a')); SET @var2=char(ascii('a'));
insert into t1 values (@var1),(@var2); insert into t1 values (@var1),(@var2);
show binlog events from 95; show binlog events from 96;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 95 User var 1 136 @`a b`=_latin1 0x68656C6C6F COLLATE latin1_swedish_ci master-bin.000001 96 User var 1 137 @`a b`=_latin1 0x68656C6C6F COLLATE latin1_swedish_ci
master-bin.000001 136 Query 1 229 use `test`; INSERT INTO t1 VALUES(@`a b`) master-bin.000001 137 Query 1 230 use `test`; INSERT INTO t1 VALUES(@`a b`)
master-bin.000001 229 User var 1 271 @`var1`=_latin1 0x273B616161 COLLATE latin1_swedish_ci master-bin.000001 230 User var 1 272 @`var1`=_latin1 0x273B616161 COLLATE latin1_swedish_ci
master-bin.000001 271 User var 1 309 @`var2`=_latin1 0x61 COLLATE latin1_swedish_ci master-bin.000001 272 User var 1 310 @`var2`=_latin1 0x61 COLLATE latin1_swedish_ci
master-bin.000001 309 Query 1 410 use `test`; insert into t1 values (@var1),(@var2) master-bin.000001 310 Query 1 411 use `test`; insert into t1 values (@var1),(@var2)
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
ROLLBACK;
SET @`a b`:=_latin1 0x68656C6C6F COLLATE `latin1_swedish_ci`; SET @`a b`:=_latin1 0x68656C6C6F COLLATE `latin1_swedish_ci`;
use test; use test;
SET TIMESTAMP=10000; SET TIMESTAMP=10000;

View file

@ -338,7 +338,7 @@ create table t2 (c char(30)) charset=ucs2;
set @v=convert('abc' using ucs2); set @v=convert('abc' using ucs2);
reset master; reset master;
insert into t2 values (@v); insert into t2 values (@v);
show binlog events from 95; show binlog events from 96;
# more important than SHOW BINLOG EVENTS, mysqlbinlog (where we # more important than SHOW BINLOG EVENTS, mysqlbinlog (where we
# absolutely need variables names to be quoted and strings to be # absolutely need variables names to be quoted and strings to be
# escaped). # escaped).

View file

@ -139,7 +139,7 @@ select n from t1;
rollback to savepoint `savept2`; rollback to savepoint `savept2`;
release savepoint `my_savepoint`; release savepoint `my_savepoint`;
select n from t1; select n from t1;
-- error 1181 -- error 1305
rollback to savepoint `my_savepoint`; rollback to savepoint `my_savepoint`;
set autocommit=1; set autocommit=1;
# nop # nop

View file

@ -26,7 +26,8 @@ insert into t2 select * from t1;
commit; commit;
--replace_column 5 # --replace_column 5 #
show binlog events from 95; --replace_result "xid=12" "xid=7"
show binlog events from 96;
delete from t1; delete from t1;
delete from t2; delete from t2;
@ -39,7 +40,7 @@ insert into t2 select * from t1;
rollback; rollback;
--replace_column 5 # --replace_column 5 #
show binlog events from 95; show binlog events from 96;
delete from t1; delete from t1;
delete from t2; delete from t2;
@ -54,7 +55,8 @@ rollback to savepoint my_savepoint;
commit; commit;
--replace_column 5 # --replace_column 5 #
show binlog events from 95; --replace_result "xid=45" "xid=24"
show binlog events from 96;
delete from t1; delete from t1;
delete from t2; delete from t2;
@ -71,7 +73,8 @@ commit;
select a from t1 order by a; # check that savepoints work :) select a from t1 order by a; # check that savepoints work :)
--replace_column 5 # --replace_column 5 #
show binlog events from 95; --replace_result "xid=67" "xid=36"
show binlog events from 96;
# and when ROLLBACK is not explicit? # and when ROLLBACK is not explicit?
delete from t1; delete from t1;
@ -92,7 +95,7 @@ connection con2;
# logging has been done, we use a user lock. # logging has been done, we use a user lock.
select get_lock("a",10); select get_lock("a",10);
--replace_column 5 # --replace_column 5 #
show binlog events from 95; show binlog events from 96;
# and when not in a transact1on? # and when not in a transact1on?
delete from t1; delete from t1;
@ -103,7 +106,8 @@ insert into t1 values(9);
insert into t2 select * from t1; insert into t2 select * from t1;
--replace_column 5 # --replace_column 5 #
show binlog events from 95; --replace_result "xid=116" "xid=59"
show binlog events from 96;
# Check that when the query updat1ng the MyISAM table is the first in the # Check that when the query updat1ng the MyISAM table is the first in the
# transaction, we log it immediately. # transaction, we log it immediately.
@ -115,12 +119,14 @@ insert into t1 values(10); # first make t1 non-empty
begin; begin;
insert into t2 select * from t1; insert into t2 select * from t1;
--replace_column 5 # --replace_column 5 #
show binlog events from 95; --replace_result "xid=130" "xid=65"
show binlog events from 96;
insert into t1 values(11); insert into t1 values(11);
commit; commit;
--replace_column 5 # --replace_column 5 #
show binlog events from 95; --replace_result "xid=130" "xid=65" "xid=133" "xid=67"
show binlog events from 96;
# Check that things work like before this BEGIN/ROLLBACK code was added, # Check that things work like before this BEGIN/ROLLBACK code was added,
@ -138,7 +144,8 @@ insert into t2 select * from t1;
commit; commit;
--replace_column 5 # --replace_column 5 #
show binlog events from 95; --replace_result "xid=152" "xid=77"
show binlog events from 96;
delete from t1; delete from t1;
delete from t2; delete from t2;
@ -150,7 +157,7 @@ insert into t2 select * from t1;
rollback; rollback;
--replace_column 5 # --replace_column 5 #
show binlog events from 95; show binlog events from 96;
delete from t1; delete from t1;
delete from t2; delete from t2;
@ -165,7 +172,8 @@ rollback to savepoint my_savepoint;
commit; commit;
--replace_column 5 # --replace_column 5 #
show binlog events from 95; --replace_result "xid=184" "xid=93"
show binlog events from 96;
delete from t1; delete from t1;
delete from t2; delete from t2;
@ -182,7 +190,8 @@ commit;
select a from t1 order by a; # check that savepoints work :) select a from t1 order by a; # check that savepoints work :)
--replace_column 5 # --replace_column 5 #
show binlog events from 95; --replace_result "xid=205" "xid=104"
show binlog events from 96;
# Test for BUG#5714, where a MyISAM update in the transaction used to # Test for BUG#5714, where a MyISAM update in the transaction used to
# release row-level locks in InnoDB # release row-level locks in InnoDB

View file

@ -61,7 +61,7 @@ select "--- --database --" as "";
select "--- --position --" as ""; select "--- --position --" as "";
--enable_query_log --enable_query_log
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
--exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --position=118 $MYSQL_TEST_DIR/var/log/master-bin.000002 --exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --position=119 $MYSQL_TEST_DIR/var/log/master-bin.000002
# These are tests for remote binlog. # These are tests for remote binlog.
# They should return the same as previous test. # They should return the same as previous test.
@ -93,7 +93,7 @@ select "--- --database --" as "";
select "--- --position --" as ""; select "--- --position --" as "";
--enable_query_log --enable_query_log
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
--exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --read-from-remote-server --position=118 --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002 --exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --read-from-remote-server --position=119 --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002
# Bug#7853 (mysqlbinlog does not accept input from stdin) # Bug#7853 (mysqlbinlog does not accept input from stdin)
--disable_query_log --disable_query_log
@ -107,3 +107,4 @@ select "--- reading stdin --" as "";
# clean up # clean up
drop table t1, t2; drop table t1, t2;

View file

@ -46,11 +46,11 @@ select "--- offset --" as "";
--disable_query_log --disable_query_log
select "--- start-position --" as ""; select "--- start-position --" as "";
--enable_query_log --enable_query_log
--exec $MYSQL_BINLOG --short-form --start-position=601 $MYSQL_TEST_DIR/var/log/master-bin.000001 --exec $MYSQL_BINLOG --short-form --start-position=602 $MYSQL_TEST_DIR/var/log/master-bin.000001
--disable_query_log --disable_query_log
select "--- stop-position --" as ""; select "--- stop-position --" as "";
--enable_query_log --enable_query_log
--exec $MYSQL_BINLOG --short-form --stop-position=601 $MYSQL_TEST_DIR/var/log/master-bin.000001 --exec $MYSQL_BINLOG --short-form --stop-position=602 $MYSQL_TEST_DIR/var/log/master-bin.000001
--disable_query_log --disable_query_log
select "--- start-datetime --" as ""; select "--- start-datetime --" as "";
--enable_query_log --enable_query_log
@ -75,11 +75,11 @@ select "--- offset --" as "";
--disable_query_log --disable_query_log
select "--- start-position --" as ""; select "--- start-position --" as "";
--enable_query_log --enable_query_log
--exec $MYSQL_BINLOG --short-form --start-position=601 $MYSQL_TEST_DIR/var/log/master-bin.000001 $MYSQL_TEST_DIR/var/log/master-bin.000002 --exec $MYSQL_BINLOG --short-form --start-position=602 $MYSQL_TEST_DIR/var/log/master-bin.000001 $MYSQL_TEST_DIR/var/log/master-bin.000002
--disable_query_log --disable_query_log
select "--- stop-position --" as ""; select "--- stop-position --" as "";
--enable_query_log --enable_query_log
--exec $MYSQL_BINLOG --short-form --stop-position=123 $MYSQL_TEST_DIR/var/log/master-bin.000001 $MYSQL_TEST_DIR/var/log/master-bin.000002 --exec $MYSQL_BINLOG --short-form --stop-position=124 $MYSQL_TEST_DIR/var/log/master-bin.000001 $MYSQL_TEST_DIR/var/log/master-bin.000002
--disable_query_log --disable_query_log
select "--- start-datetime --" as ""; select "--- start-datetime --" as "";
--enable_query_log --enable_query_log
@ -102,11 +102,11 @@ select "--- offset --" as "";
--disable_query_log --disable_query_log
select "--- start-position --" as ""; select "--- start-position --" as "";
--enable_query_log --enable_query_log
--exec $MYSQL_BINLOG --short-form --start-position=601 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 --exec $MYSQL_BINLOG --short-form --start-position=602 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
--disable_query_log --disable_query_log
select "--- stop-position --" as ""; select "--- stop-position --" as "";
--enable_query_log --enable_query_log
--exec $MYSQL_BINLOG --short-form --stop-position=601 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 --exec $MYSQL_BINLOG --short-form --stop-position=602 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
--disable_query_log --disable_query_log
select "--- start-datetime --" as ""; select "--- start-datetime --" as "";
--enable_query_log --enable_query_log
@ -129,11 +129,11 @@ select "--- offset --" as "";
--disable_query_log --disable_query_log
select "--- start-position --" as ""; select "--- start-position --" as "";
--enable_query_log --enable_query_log
--exec $MYSQL_BINLOG --short-form --start-position=601 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 master-bin.000002 --exec $MYSQL_BINLOG --short-form --start-position=602 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 master-bin.000002
--disable_query_log --disable_query_log
select "--- stop-position --" as ""; select "--- stop-position --" as "";
--enable_query_log --enable_query_log
--exec $MYSQL_BINLOG --short-form --stop-position=123 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 master-bin.000002 --exec $MYSQL_BINLOG --short-form --stop-position=124 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 master-bin.000002
--disable_query_log --disable_query_log
select "--- start-datetime --" as ""; select "--- start-datetime --" as "";
--enable_query_log --enable_query_log

View file

@ -107,7 +107,7 @@ connection master;
drop database mysqltest2; drop database mysqltest2;
drop database mysqltest3; drop database mysqltest3;
--replace_column 2 # 5 # --replace_column 2 # 5 #
show binlog events from 95; show binlog events from 96;
sync_slave_with_master; sync_slave_with_master;
# Check that we can change global.collation_server (since 5.0.3) # Check that we can change global.collation_server (since 5.0.3)
@ -156,3 +156,4 @@ connection master;
--exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.000001 --exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.000001
drop table t1; drop table t1;
sync_slave_with_master; sync_slave_with_master;

View file

@ -48,7 +48,7 @@ connection master;
--error 0,1053; --error 0,1053;
reap; reap;
connection master1; connection master1;
show binlog events from 95; show binlog events from 96;
save_master_pos; save_master_pos;
connection slave; connection slave;
# SQL slave thread should not have stopped (because table of the killed # SQL slave thread should not have stopped (because table of the killed

View file

@ -19,5 +19,5 @@ create database mysqltest;
create table t1(a int, b int, unique(b)); create table t1(a int, b int, unique(b));
use mysqltest; use mysqltest;
load data infile '../../std_data/rpl_loaddata.dat' into table test.t1; load data infile '../../std_data/rpl_loaddata.dat' into table test.t1;
show binlog events from 95; # should be nothing show binlog events from 96; # should be nothing
drop database mysqltest; drop database mysqltest;

View file

@ -17,4 +17,4 @@ save_master_pos;
connection slave; connection slave;
sync_with_master; sync_with_master;
select count(*) from t1; # check that LOAD was replicated select count(*) from t1; # check that LOAD was replicated
show binlog events from 95; # should be nothing show binlog events from 96; # should be nothing

View file

@ -38,9 +38,9 @@ select count(*) from t1;
drop table t1; drop table t1;
--replace_result $VERSION VERSION --replace_result $VERSION VERSION
show binlog events; show binlog events;
show binlog events from 95 limit 1; show binlog events from 96 limit 1;
show binlog events from 95 limit 2; show binlog events from 96 limit 2;
show binlog events from 95 limit 2,1; show binlog events from 96 limit 2,1;
flush logs; flush logs;
# We need an extra update before doing save_master_pos. # We need an extra update before doing save_master_pos.

View file

@ -38,7 +38,7 @@ insert into t1 values (1),(2),(3);
save_master_pos; save_master_pos;
connection slave; connection slave;
stop slave; stop slave;
change master to master_log_pos=95; change master to master_log_pos=96;
start slave; start slave;
sync_with_master; sync_with_master;
select * from t1; select * from t1;

View file

@ -46,7 +46,7 @@ save_master_pos;
connection slave; connection slave;
sync_with_master; sync_with_master;
select * from t1; select * from t1;
show binlog events from 95; show binlog events from 96;
connection master; connection master;
drop table t1; drop table t1;
save_master_pos; save_master_pos;

View file

@ -866,12 +866,12 @@ DROP TABLE t1;
CREATE TABLE t1 (col1 CHAR(5), col2 VARCHAR(6)); CREATE TABLE t1 (col1 CHAR(5), col2 VARCHAR(6));
INSERT INTO t1 VALUES ('hello', 'hello'),('he', 'he'),('hello ', 'hello '); INSERT INTO t1 VALUES ('hello', 'hello'),('he', 'he'),('hello ', 'hello ');
--error 1400 --error 1406
INSERT INTO t1 (col1) VALUES ('hellobob'); INSERT INTO t1 (col1) VALUES ('hellobob');
--error 1265 --error 1265
INSERT INTO t1 (col2) VALUES ('hellobob'); INSERT INTO t1 (col2) VALUES ('hellobob');
INSERT INTO t1 (col2) VALUES ('hello '); INSERT INTO t1 (col2) VALUES ('hello ');
--error 1400 --error 1406
UPDATE t1 SET col1 ='hellobob' WHERE col1 ='he'; UPDATE t1 SET col1 ='hellobob' WHERE col1 ='he';
--error 1265 --error 1265
UPDATE t1 SET col2 ='hellobob' WHERE col2 ='he'; UPDATE t1 SET col2 ='hellobob' WHERE col2 ='he';

View file

@ -110,7 +110,7 @@ INSERT INTO t1 VALUES(@`a b`);
set @var1= "';aaa"; set @var1= "';aaa";
SET @var2=char(ascii('a')); SET @var2=char(ascii('a'));
insert into t1 values (@var1),(@var2); insert into t1 values (@var1),(@var2);
show binlog events from 95; show binlog events from 96;
# more important than SHOW BINLOG EVENTS, mysqlbinlog (where we # more important than SHOW BINLOG EVENTS, mysqlbinlog (where we
# absolutely need variables names to be quoted and strings to be # absolutely need variables names to be quoted and strings to be
# escaped). # escaped).

View file

@ -103,7 +103,7 @@ static inline void hash_free_elements(HASH *hash)
hash_free() hash_free()
hash the hash to delete elements of hash the hash to delete elements of
NOTES: Hash can't be reused wuthing calling hash_init again. NOTES: Hash can't be reused without calling hash_init again.
*/ */
void hash_free(HASH *hash) void hash_free(HASH *hash)

View file

@ -135,6 +135,23 @@ static HASH archive_open_tables;
#define DATA_BUFFER_SIZE 2 // Size of the data used in the data file #define DATA_BUFFER_SIZE 2 // Size of the data used in the data file
#define ARCHIVE_CHECK_HEADER 254 // The number we use to determine corruption #define ARCHIVE_CHECK_HEADER 254 // The number we use to determine corruption
/* dummy handlerton - only to have something to return from archive_db_init */
static handlerton archive_hton = {
0, /* slot */
0, /* savepoint size. */
0, /* close_connection */
0, /* savepoint */
0, /* rollback to savepoint */
0, /* releas savepoint */
0, /* commit */
0, /* rollback */
0, /* prepare */
0, /* recover */
0, /* commit_by_xid */
0 /* rollback_by_xid */
};
/* /*
Used for hash table that tracks open tables. Used for hash table that tracks open tables.
*/ */
@ -154,19 +171,20 @@ static byte* archive_get_key(ARCHIVE_SHARE *share,uint *length,
void void
RETURN RETURN
FALSE OK &archive_hton OK
TRUE Error 0 Error
*/ */
bool archive_db_init() handlerton *archive_db_init()
{ {
archive_inited= 1; archive_inited= 1;
VOID(pthread_mutex_init(&archive_mutex, MY_MUTEX_INIT_FAST)); VOID(pthread_mutex_init(&archive_mutex, MY_MUTEX_INIT_FAST));
return (hash_init(&archive_open_tables, system_charset_info, 32, 0, 0, if (hash_init(&archive_open_tables, system_charset_info, 32, 0, 0,
(hash_get_key) archive_get_key, 0, 0)); (hash_get_key) archive_get_key, 0, 0))
return 0;
return &archive_hton;
} }
/* /*
Release the archive handler. Release the archive handler.
@ -734,7 +752,7 @@ int ha_archive::rnd_next(byte *buf)
} }
/* /*
Thanks to the table flag HA_REC_NOT_IN_SEQ this will be called after Thanks to the table flag HA_REC_NOT_IN_SEQ this will be called after
each call to ha_archive::rnd_next() if an ordering of the rows is each call to ha_archive::rnd_next() if an ordering of the rows is
needed. needed.
@ -743,7 +761,7 @@ int ha_archive::rnd_next(byte *buf)
void ha_archive::position(const byte *record) void ha_archive::position(const byte *record)
{ {
DBUG_ENTER("ha_archive::position"); DBUG_ENTER("ha_archive::position");
ha_store_ptr(ref, ref_length, current_position); my_store_ptr(ref, ref_length, current_position);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -760,7 +778,7 @@ int ha_archive::rnd_pos(byte * buf, byte *pos)
DBUG_ENTER("ha_archive::rnd_pos"); DBUG_ENTER("ha_archive::rnd_pos");
statistic_increment(table->in_use->status_var.ha_read_rnd_next_count, statistic_increment(table->in_use->status_var.ha_read_rnd_next_count,
&LOCK_status); &LOCK_status);
current_position= ha_get_ptr(pos, ref_length); current_position= my_get_ptr(pos, ref_length);
z_off_t seek= gzseek(archive, current_position, SEEK_SET); z_off_t seek= gzseek(archive, current_position, SEEK_SET);
DBUG_RETURN(get_row(archive, buf)); DBUG_RETURN(get_row(archive, buf));

View file

@ -106,6 +106,6 @@ public:
enum thr_lock_type lock_type); enum thr_lock_type lock_type);
}; };
bool archive_db_init(void); handlerton *archive_db_init(void);
bool archive_db_end(void); bool archive_db_end(void);

View file

@ -102,11 +102,34 @@ static int write_status(DB *status_block, char *buff, uint length);
static void update_status(BDB_SHARE *share, TABLE *table); static void update_status(BDB_SHARE *share, TABLE *table);
static void berkeley_noticecall(DB_ENV *db_env, db_notices notice); static void berkeley_noticecall(DB_ENV *db_env, db_notices notice);
static int berkeley_close_connection(THD *thd);
static int berkeley_commit(THD *thd, bool all);
static int berkeley_rollback(THD *thd, bool all);
static handlerton berkeley_hton = {
0, /* slot */
0, /* savepoint size */
berkeley_close_connection,
NULL, /* savepoint_set */
NULL, /* savepoint_rollback */
NULL, /* savepoint_release */
berkeley_commit,
berkeley_rollback,
NULL, /* prepare */
NULL, /* recover */
NULL, /* commit_by_xid */
NULL /* rollback_by_xid */
};
typedef struct st_berkeley_trx_data {
DB_TXN *all;
DB_TXN *stmt;
uint bdb_lock_count;
} berkeley_trx_data;
/* General functions */ /* General functions */
bool berkeley_init(void) handlerton *berkeley_init(void)
{ {
DBUG_ENTER("berkeley_init"); DBUG_ENTER("berkeley_init");
@ -135,7 +158,7 @@ bool berkeley_init(void)
berkeley_log_file_size= max(berkeley_log_file_size, 10*1024*1024L); berkeley_log_file_size= max(berkeley_log_file_size, 10*1024*1024L);
if (db_env_create(&db_env,0)) if (db_env_create(&db_env,0))
DBUG_RETURN(1); /* purecov: inspected */ DBUG_RETURN(0);
db_env->set_errcall(db_env,berkeley_print_error); db_env->set_errcall(db_env,berkeley_print_error);
db_env->set_errpfx(db_env,"bdb"); db_env->set_errpfx(db_env,"bdb");
db_env->set_noticecall(db_env, berkeley_noticecall); db_env->set_noticecall(db_env, berkeley_noticecall);
@ -163,16 +186,15 @@ bool berkeley_init(void)
DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN |
DB_CREATE | DB_THREAD, 0666)) DB_CREATE | DB_THREAD, 0666))
{ {
db_env->close(db_env,0); /* purecov: inspected */ db_env->close(db_env,0);
db_env=0; /* purecov: inspected */ db_env=0;
goto err; DBUG_RETURN(0);
} }
(void) hash_init(&bdb_open_tables,system_charset_info,32,0,0, (void) hash_init(&bdb_open_tables,system_charset_info,32,0,0,
(hash_get_key) bdb_get_key,0,0); (hash_get_key) bdb_get_key,0,0);
pthread_mutex_init(&bdb_mutex,MY_MUTEX_INIT_FAST); pthread_mutex_init(&bdb_mutex,MY_MUTEX_INIT_FAST);
err: DBUG_RETURN(&berkeley_hton);
DBUG_RETURN(db_env == 0);
} }
@ -190,6 +212,11 @@ bool berkeley_end(void)
DBUG_RETURN(error != 0); DBUG_RETURN(error != 0);
} }
static int berkeley_close_connection(THD *thd)
{
my_free((gptr)thd->ha_data[berkeley_hton.slot], MYF(0));
}
bool berkeley_flush_logs() bool berkeley_flush_logs()
{ {
int error; int error;
@ -208,26 +235,29 @@ bool berkeley_flush_logs()
DBUG_RETURN(result); DBUG_RETURN(result);
} }
static int berkeley_commit(THD *thd, bool all)
int berkeley_commit(THD *thd, void *trans)
{ {
DBUG_ENTER("berkeley_commit"); DBUG_ENTER("berkeley_commit");
DBUG_PRINT("trans",("ending transaction %s", DBUG_PRINT("trans",("ending transaction %s", all ? "all" : "stmt"));
trans == thd->transaction.stmt.bdb_tid ? "stmt" : "all")); berkeley_trx_data *trx=(berkeley_trx_data *)thd->ha_data[berkeley_hton.slot];
int error=txn_commit((DB_TXN*) trans,0); DB_TXN **txn= all ? &trx->all : &trx->stmt;
int error=txn_commit(*txn,0);
*txn=0;
#ifndef DBUG_OFF #ifndef DBUG_OFF
if (error) if (error)
DBUG_PRINT("error",("error: %d",error)); /* purecov: inspected */ DBUG_PRINT("error",("error: %d",error));
#endif #endif
DBUG_RETURN(error); DBUG_RETURN(error);
} }
int berkeley_rollback(THD *thd, void *trans) static int berkeley_rollback(THD *thd, bool all)
{ {
DBUG_ENTER("berkeley_rollback"); DBUG_ENTER("berkeley_rollback");
DBUG_PRINT("trans",("aborting transaction %s", DBUG_PRINT("trans",("aborting transaction %s", all ? "all" : "stmt"));
trans == thd->transaction.stmt.bdb_tid ? "stmt" : "all")); berkeley_trx_data *trx=(berkeley_trx_data *)thd->ha_data[berkeley_hton.slot];
int error=txn_abort((DB_TXN*) trans); DB_TXN **txn= all ? &trx->all : &trx->stmt;
int error=txn_abort(*txn);
*txn=0;
DBUG_RETURN(error); DBUG_RETURN(error);
} }
@ -1842,62 +1872,65 @@ int ha_berkeley::reset(void)
int ha_berkeley::external_lock(THD *thd, int lock_type) int ha_berkeley::external_lock(THD *thd, int lock_type)
{ {
int error=0; int error=0;
berkeley_trx_data *trx=(berkeley_trx_data *)thd->ha_data[berkeley_hton.slot];
DBUG_ENTER("ha_berkeley::external_lock"); DBUG_ENTER("ha_berkeley::external_lock");
if (!trx)
{
thd->ha_data[berkeley_hton.slot]= trx= (berkeley_trx_data *)
my_malloc(sizeof(*trx), MYF(MY_ZEROFILL));
if (!trx)
DBUG_RETURN(1);
}
if (lock_type != F_UNLCK) if (lock_type != F_UNLCK)
{ {
if (!thd->transaction.bdb_lock_count++) if (!trx->bdb_lock_count++)
{ {
DBUG_ASSERT(thd->transaction.stmt.bdb_tid == 0); DBUG_ASSERT(trx->stmt == 0);
transaction=0; // Safety transaction=0; // Safety
/* First table lock, start transaction */ /* First table lock, start transaction */
if ((thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN | if ((thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN |
OPTION_TABLE_LOCK)) && OPTION_TABLE_LOCK)) && !trx->all)
!thd->transaction.all.bdb_tid)
{ {
/* We have to start a master transaction */ /* We have to start a master transaction */
DBUG_PRINT("trans",("starting transaction all: options: 0x%lx", DBUG_PRINT("trans",("starting transaction all: options: 0x%lx",
(ulong) thd->options)); (ulong) thd->options));
if ((error=txn_begin(db_env, 0, if ((error=txn_begin(db_env, 0, &trx->all, 0)))
(DB_TXN**) &thd->transaction.all.bdb_tid,
0)))
{ {
thd->transaction.bdb_lock_count--; // We didn't get the lock /* purecov: inspected */ trx->bdb_lock_count--; // We didn't get the lock
DBUG_RETURN(error); /* purecov: inspected */ DBUG_RETURN(error);
} }
trans_register_ha(thd, TRUE, &berkeley_hton);
if (thd->in_lock_tables) if (thd->in_lock_tables)
DBUG_RETURN(0); // Don't create stmt trans DBUG_RETURN(0); // Don't create stmt trans
} }
DBUG_PRINT("trans",("starting transaction stmt")); DBUG_PRINT("trans",("starting transaction stmt"));
if ((error=txn_begin(db_env, if ((error=txn_begin(db_env, trx->all, &trx->stmt, 0)))
(DB_TXN*) thd->transaction.all.bdb_tid,
(DB_TXN**) &thd->transaction.stmt.bdb_tid,
0)))
{ {
/* We leave the possible master transaction open */ /* We leave the possible master transaction open */
thd->transaction.bdb_lock_count--; // We didn't get the lock /* purecov: inspected */ trx->bdb_lock_count--; // We didn't get the lock
DBUG_RETURN(error); /* purecov: inspected */ DBUG_RETURN(error);
} }
trans_register_ha(thd, FALSE, &berkeley_hton);
} }
transaction= (DB_TXN*) thd->transaction.stmt.bdb_tid; transaction= trx->stmt;
} }
else else
{ {
lock.type=TL_UNLOCK; // Unlocked lock.type=TL_UNLOCK; // Unlocked
thread_safe_add(share->rows, changed_rows, &share->mutex); thread_safe_add(share->rows, changed_rows, &share->mutex);
changed_rows=0; changed_rows=0;
if (!--thd->transaction.bdb_lock_count) if (!--trx->bdb_lock_count)
{ {
if (thd->transaction.stmt.bdb_tid) if (trx->stmt)
{ {
/* /*
F_UNLOCK is done without a transaction commit / rollback. F_UNLCK is done without a transaction commit / rollback.
This happens if the thread didn't update any rows This happens if the thread didn't update any rows
We must in this case commit the work to keep the row locks We must in this case commit the work to keep the row locks
*/ */
DBUG_PRINT("trans",("commiting non-updating transaction")); DBUG_PRINT("trans",("commiting non-updating transaction"));
error=txn_commit((DB_TXN*) thd->transaction.stmt.bdb_tid,0); error= txn_commit(trx->stmt,0);
thd->transaction.stmt.bdb_tid=0; trx->stmt= transaction= 0;
transaction=0;
} }
} }
} }
@ -1915,14 +1948,20 @@ int ha_berkeley::start_stmt(THD *thd)
{ {
int error=0; int error=0;
DBUG_ENTER("ha_berkeley::start_stmt"); DBUG_ENTER("ha_berkeley::start_stmt");
if (!thd->transaction.stmt.bdb_tid) berkeley_trx_data *trx=(berkeley_trx_data *)thd->ha_data[berkeley_hton.slot];
DBUG_ASSERT(trx);
/*
note that trx->stmt may have been already initialized as start_stmt()
is called for *each table* not for each storage engine,
and there could be many bdb tables referenced in the query
*/
if (!trx->stmt)
{ {
DBUG_PRINT("trans",("starting transaction stmt")); DBUG_PRINT("trans",("starting transaction stmt"));
error=txn_begin(db_env, (DB_TXN*) thd->transaction.all.bdb_tid, error=txn_begin(db_env, trx->all, &trx->stmt, 0);
(DB_TXN**) &thd->transaction.stmt.bdb_tid, trans_register_ha(thd, FALSE, &berkeley_hton);
0);
} }
transaction= (DB_TXN*) thd->transaction.stmt.bdb_tid; transaction= trx->stmt;
DBUG_RETURN(error); DBUG_RETURN(error);
} }
@ -2258,6 +2297,8 @@ int ha_berkeley::analyze(THD* thd, HA_CHECK_OPT* check_opt)
uint i; uint i;
DB_BTREE_STAT *stat=0; DB_BTREE_STAT *stat=0;
DB_TXN_STAT *txn_stat_ptr= 0; DB_TXN_STAT *txn_stat_ptr= 0;
berkeley_trx_data *trx=(berkeley_trx_data *)thd->ha_data[berkeley_hton.slot];
DBUG_ASSERT(trx);
/* /*
Original bdb documentation says: Original bdb documentation says:
@ -2272,13 +2313,10 @@ int ha_berkeley::analyze(THD* thd, HA_CHECK_OPT* check_opt)
txn_stat_ptr && txn_stat_ptr->st_nactive>=2) txn_stat_ptr && txn_stat_ptr->st_nactive>=2)
{ {
DB_TXN_ACTIVE *atxn_stmt= 0, *atxn_all= 0; DB_TXN_ACTIVE *atxn_stmt= 0, *atxn_all= 0;
DB_TXN *txn_all= (DB_TXN*) thd->transaction.all.bdb_tid; u_int32_t all_id= trx->all->id(trx->all);
u_int32_t all_id= txn_all->id(txn_all); u_int32_t stmt_id= trx->stmt->id(trx->stmt);
DB_TXN *txn_stmt= (DB_TXN*) thd->transaction.stmt.bdb_tid;
u_int32_t stmt_id= txn_stmt->id(txn_stmt);
DB_TXN_ACTIVE *cur= txn_stat_ptr->st_txnarray; DB_TXN_ACTIVE *cur= txn_stat_ptr->st_txnarray;
DB_TXN_ACTIVE *end= cur + txn_stat_ptr->st_nactive; DB_TXN_ACTIVE *end= cur + txn_stat_ptr->st_nactive;
for (; cur!=end && (!atxn_stmt || !atxn_all); cur++) for (; cur!=end && (!atxn_stmt || !atxn_all); cur++)
@ -2286,7 +2324,7 @@ int ha_berkeley::analyze(THD* thd, HA_CHECK_OPT* check_opt)
if (cur->txnid==all_id) atxn_all= cur; if (cur->txnid==all_id) atxn_all= cur;
if (cur->txnid==stmt_id) atxn_stmt= cur; if (cur->txnid==stmt_id) atxn_stmt= cur;
} }
if (atxn_stmt && atxn_all && if (atxn_stmt && atxn_all &&
log_compare(&atxn_stmt->lsn,&atxn_all->lsn)) log_compare(&atxn_stmt->lsn,&atxn_all->lsn))
{ {

View file

@ -168,9 +168,7 @@ extern char *berkeley_home, *berkeley_tmpdir, *berkeley_logdir;
extern long berkeley_lock_scan_time; extern long berkeley_lock_scan_time;
extern TYPELIB berkeley_lock_typelib; extern TYPELIB berkeley_lock_typelib;
bool berkeley_init(void); handlerton *berkeley_init(void);
bool berkeley_end(void); bool berkeley_end(void);
bool berkeley_flush_logs(void); bool berkeley_flush_logs(void);
int berkeley_commit(THD *thd, void *trans);
int berkeley_rollback(THD *thd, void *trans);
int berkeley_show_logs(Protocol *protocol); int berkeley_show_logs(Protocol *protocol);

View file

@ -14,14 +14,12 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file defines the InnoDB handler: the interface between MySQL and /* This file defines the InnoDB handler: the interface between MySQL and InnoDB
InnoDB
NOTE: You can only use noninlined InnoDB functions in this file, because we NOTE: You can only use noninlined InnoDB functions in this file, because we
have disables the InnoDB inlining in this file. */ have disables the InnoDB inlining in this file. */
/* TODO list for the InnoDB handler in 4.1: /* TODO list for the InnoDB handler in 5.0:
- Remove the flag innodb_active_trans from thd and replace it with a - Remove the flag trx->active_trans and look at the InnoDB
function call innodb_active_trans(thd), which looks at the InnoDB
trx struct state field trx struct state field
- Find out what kind of problems the OS X case-insensitivity causes to - Find out what kind of problems the OS X case-insensitivity causes to
table and database names; should we 'normalize' the names like we do table and database names; should we 'normalize' the names like we do
@ -141,8 +139,6 @@ ulong innobase_active_counter = 0;
char* innobase_home = NULL; char* innobase_home = NULL;
char innodb_dummy_stmt_trx_handle = 'D';
static HASH innobase_open_tables; static HASH innobase_open_tables;
#ifdef __NETWARE__ /* some special cleanup for NetWare */ #ifdef __NETWARE__ /* some special cleanup for NetWare */
@ -153,6 +149,27 @@ static mysql_byte* innobase_get_key(INNOBASE_SHARE *share,uint *length,
my_bool not_used __attribute__((unused))); my_bool not_used __attribute__((unused)));
static INNOBASE_SHARE *get_share(const char *table_name); static INNOBASE_SHARE *get_share(const char *table_name);
static void free_share(INNOBASE_SHARE *share); static void free_share(INNOBASE_SHARE *share);
static int innobase_close_connection(THD* thd);
static int innobase_commit(THD* thd, bool all);
static int innobase_rollback(THD* thd, bool all);
static int innobase_rollback_to_savepoint(THD* thd, void *savepoint);
static int innobase_savepoint(THD* thd, void *savepoint);
static int innobase_release_savepoint(THD* thd, void *savepoint);
static handlerton innobase_hton = {
0, /* slot */
sizeof(trx_named_savept_t), /* savepoint size. TODO: use it */
innobase_close_connection,
innobase_savepoint,
innobase_rollback_to_savepoint,
innobase_release_savepoint,
innobase_commit, /* commit */
innobase_rollback, /* rollback */
innobase_xa_prepare, /* prepare */
innobase_xa_recover, /* recover */
innobase_commit_by_xid, /* commit_by_xid */
innobase_rollback_by_xid /* rollback_by_xid */
};
/********************************************************************* /*********************************************************************
Commits a transaction in an InnoDB database. */ Commits a transaction in an InnoDB database. */
@ -250,7 +267,7 @@ struct show_var_st innodb_status_variables[]= {
{"rows_updated", {"rows_updated",
(char*) &export_vars.innodb_rows_updated, SHOW_LONG}, (char*) &export_vars.innodb_rows_updated, SHOW_LONG},
{NullS, NullS, SHOW_LONG}}; {NullS, NullS, SHOW_LONG}};
/* General functions */ /* General functions */
/********************************************************************** /**********************************************************************
@ -317,9 +334,11 @@ documentation, see handler.cc. */
void void
innobase_release_temporary_latches( innobase_release_temporary_latches(
/*===============================*/ /*===============================*/
void* innobase_tid) THD *thd)
{ {
innobase_release_stat_resources((trx_t*)innobase_tid); trx_t *trx= (trx_t*) thd->ha_data[innobase_hton.slot];
if (trx)
innobase_release_stat_resources(trx);
} }
/************************************************************************ /************************************************************************
@ -652,25 +671,17 @@ check_trx_exists(
ut_ad(thd == current_thd); ut_ad(thd == current_thd);
trx = (trx_t*) thd->transaction.all.innobase_tid; trx = (trx_t*) thd->ha_data[innobase_hton.slot];
if (trx == NULL) { if (trx == NULL) {
DBUG_ASSERT(thd != NULL); DBUG_ASSERT(thd != NULL);
trx = trx_allocate_for_mysql(); trx = trx_allocate_for_mysql();
trx->mysql_thd = thd; trx->mysql_thd = thd;
trx->mysql_query_str = &((*thd).query); trx->mysql_query_str = &(thd->query);
trx->active_trans = 0;
thd->transaction.all.innobase_tid = trx;
/* The execution of a single SQL statement is denoted by thd->ha_data[innobase_hton.slot] = trx;
a 'transaction' handle which is a dummy pointer: InnoDB
remembers internally where the latest SQL statement
started, and if error handling requires rolling back the
latest statement, InnoDB does a rollback to a savepoint. */
thd->transaction.stmt.innobase_tid =
(void*)&innodb_dummy_stmt_trx_handle;
} else { } else {
if (trx->magic_n != TRX_MAGIC_N) { if (trx->magic_n != TRX_MAGIC_N) {
mem_analyze_corruption((byte*)trx); mem_analyze_corruption((byte*)trx);
@ -707,7 +718,7 @@ ha_innobase::update_thd(
{ {
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
trx_t* trx; trx_t* trx;
trx = check_trx_exists(thd); trx = check_trx_exists(thd);
if (prebuilt->trx != trx) { if (prebuilt->trx != trx) {
@ -720,6 +731,24 @@ ha_innobase::update_thd(
return(0); return(0);
} }
/*************************************************************************
Registers the InnoDB transaction in MySQL, to receive commit/rollback
events. This function must be called every time InnoDB starts a
transaction internally. */
static
void
register_trans(
/*============*/
THD* thd) /* in: thd to use the handle */
{
/* register the start of the statement */
trans_register_ha(thd, FALSE, &innobase_hton);
if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
/* no autocommit mode, register for a transaction */
trans_register_ha(thd, TRUE, &innobase_hton);
}
}
/* BACKGROUND INFO: HOW THE MYSQL QUERY CACHE WORKS WITH INNODB /* BACKGROUND INFO: HOW THE MYSQL QUERY CACHE WORKS WITH INNODB
------------------------------------------------------------ ------------------------------------------------------------
@ -813,12 +842,7 @@ innobase_query_caching_of_table_permitted(
return((my_bool)FALSE); return((my_bool)FALSE);
} }
trx = (trx_t*) thd->transaction.all.innobase_tid; trx = check_trx_exists(thd);
if (trx == NULL) {
trx = check_trx_exists(thd);
}
if (trx->has_search_latch) { if (trx->has_search_latch) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, fprintf(stderr,
@ -871,7 +895,11 @@ innobase_query_caching_of_table_permitted(
/* The call of row_search_.. will start a new transaction if it is /* The call of row_search_.. will start a new transaction if it is
not yet started */ not yet started */
thd->transaction.all.innodb_active_trans = 1; if (trx->active_trans == 0) {
register_trans(thd);
trx->active_trans = 1;
}
if (row_search_check_if_query_cache_permitted(trx, norm_name)) { if (row_search_check_if_query_cache_permitted(trx, norm_name)) {
@ -983,7 +1011,12 @@ ha_innobase::init_table_handle_for_HANDLER(void)
/* Set the MySQL flag to mark that there is an active transaction */ /* Set the MySQL flag to mark that there is an active transaction */
current_thd->transaction.all.innodb_active_trans = 1; if (prebuilt->trx->active_trans == 0) {
register_trans(current_thd);
prebuilt->trx->active_trans = 1;
}
/* We did the necessary inits in this function, no need to repeat them /* We did the necessary inits in this function, no need to repeat them
in row_search_for_mysql */ in row_search_for_mysql */
@ -1013,7 +1046,7 @@ ha_innobase::init_table_handle_for_HANDLER(void)
/************************************************************************* /*************************************************************************
Opens an InnoDB database. */ Opens an InnoDB database. */
bool handlerton *
innobase_init(void) innobase_init(void)
/*===============*/ /*===============*/
/* out: TRUE if error */ /* out: TRUE if error */
@ -1090,7 +1123,7 @@ innobase_init(void)
"InnoDB: syntax error in innodb_data_file_path"); "InnoDB: syntax error in innodb_data_file_path");
my_free(internal_innobase_data_file_path, my_free(internal_innobase_data_file_path,
MYF(MY_ALLOW_ZERO_PTR)); MYF(MY_ALLOW_ZERO_PTR));
DBUG_RETURN(TRUE); DBUG_RETURN(0);
} }
/* -------------- Log files ---------------------------*/ /* -------------- Log files ---------------------------*/
@ -1122,7 +1155,7 @@ innobase_init(void)
my_free(internal_innobase_data_file_path, my_free(internal_innobase_data_file_path,
MYF(MY_ALLOW_ZERO_PTR)); MYF(MY_ALLOW_ZERO_PTR));
DBUG_RETURN(TRUE); DBUG_RETURN(0);
} }
/* --------------------------------------------------*/ /* --------------------------------------------------*/
@ -1212,7 +1245,7 @@ innobase_init(void)
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
my_free(internal_innobase_data_file_path, my_free(internal_innobase_data_file_path,
MYF(MY_ALLOW_ZERO_PTR)); MYF(MY_ALLOW_ZERO_PTR));
DBUG_RETURN(1); DBUG_RETURN(0);
} }
(void) hash_init(&innobase_open_tables,system_charset_info, 32, 0, 0, (void) hash_init(&innobase_open_tables,system_charset_info, 32, 0, 0,
@ -1235,7 +1268,7 @@ innobase_init(void)
glob_mi.pos = trx_sys_mysql_master_log_pos; glob_mi.pos = trx_sys_mysql_master_log_pos;
} }
*/ */
DBUG_RETURN(0); DBUG_RETURN(&innobase_hton);
} }
/*********************************************************************** /***********************************************************************
@ -1359,7 +1392,12 @@ innobase_start_trx_and_assign_read_view(
/* Set the MySQL flag to mark that there is an active transaction */ /* Set the MySQL flag to mark that there is an active transaction */
current_thd->transaction.all.innodb_active_trans = 1; if (trx->active_trans == 0) {
register_trans(current_thd);
trx->active_trans = 1;
}
DBUG_RETURN(0); DBUG_RETURN(0);
} }
@ -1368,15 +1406,14 @@ innobase_start_trx_and_assign_read_view(
Commits a transaction in an InnoDB database or marks an SQL statement Commits a transaction in an InnoDB database or marks an SQL statement
ended. */ ended. */
int static int
innobase_commit( innobase_commit(
/*============*/ /*============*/
/* out: 0 */ /* out: 0 */
THD* thd, /* in: MySQL thread handle of the user for whom THD* thd, /* in: MySQL thread handle of the user for whom
the transaction should be committed */ the transaction should be committed */
void* trx_handle)/* in: InnoDB trx handle or bool all) /* in: TRUE - commit transaction
&innodb_dummy_stmt_trx_handle: the latter means FALSE - the current SQL statement ended */
that the current SQL statement ended */
{ {
trx_t* trx; trx_t* trx;
@ -1391,7 +1428,7 @@ innobase_commit(
innobase_release_stat_resources(trx); innobase_release_stat_resources(trx);
/* The flag thd->transaction.all.innodb_active_trans is set to 1 in /* The flag trx->active_trans is set to 1 in
1. ::external_lock(), 1. ::external_lock(),
2. ::start_stmt(), 2. ::start_stmt(),
@ -1406,23 +1443,22 @@ innobase_commit(
For the time being, we play safe and do the cleanup though there should For the time being, we play safe and do the cleanup though there should
be nothing to clean up. */ be nothing to clean up. */
if (thd->transaction.all.innodb_active_trans == 0 if (trx->active_trans == 0
&& trx->conc_state != TRX_NOT_STARTED) { && trx->conc_state != TRX_NOT_STARTED) {
fprintf(stderr, fprintf(stderr,
"InnoDB: Error: thd->transaction.all.innodb_active_trans == 0\n" "InnoDB: Error: trx->active_trans == 0\n"
"InnoDB: but trx->conc_state != TRX_NOT_STARTED\n"); "InnoDB: but trx->conc_state != TRX_NOT_STARTED\n");
} }
if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle if (all || (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) {
|| (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) {
/* We were instructed to commit the whole transaction, or /* We were instructed to commit the whole transaction, or
this is an SQL statement end and autocommit is on */ this is an SQL statement end and autocommit is on */
innobase_commit_low(trx); innobase_commit_low(trx);
thd->transaction.all.innodb_active_trans = 0; trx->active_trans = 0;
} else { } else {
/* We just mark the SQL statement ended and do not do a /* We just mark the SQL statement ended and do not do a
transaction commit */ transaction commit */
@ -1448,6 +1484,11 @@ innobase_commit(
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/*
don't delete it - it may be re-enabled later
as an optimization for the most common case InnoDB+binlog
*/
#if 0
/********************************************************************* /*********************************************************************
This is called when MySQL writes the binlog entry for the current This is called when MySQL writes the binlog entry for the current
transaction. Writes to the InnoDB tablespace info which tells where the transaction. Writes to the InnoDB tablespace info which tells where the
@ -1473,18 +1514,51 @@ innobase_report_binlog_offset_and_commit(
ut_a(trx != NULL); ut_a(trx != NULL);
trx->mysql_log_file_name = log_file_name; trx->mysql_log_file_name = log_file_name;
trx->mysql_log_offset = (ib_longlong)end_offset; trx->mysql_log_offset = (ib_longlong)end_offset;
trx->flush_log_later = TRUE; trx->flush_log_later = TRUE;
innobase_commit(thd, trx_handle); innobase_commit(thd, trx_handle);
trx->flush_log_later = FALSE; trx->flush_log_later = FALSE;
return(0); return(0);
} }
/***********************************************************************
This function stores the binlog offset and flushes logs. */
void
innobase_store_binlog_offset_and_flush_log(
/*=======================================*/
char *binlog_name, /* in: binlog name */
longlong offset) /* in: binlog offset */
{
mtr_t mtr;
assert(binlog_name != NULL);
/* Start a mini-transaction */
mtr_start_noninline(&mtr);
/* Update the latest MySQL binlog name and offset info
in trx sys header */
trx_sys_update_mysql_binlog_offset(
binlog_name,
offset,
TRX_SYS_MYSQL_LOG_INFO, &mtr);
/* Commits the mini-transaction */
mtr_commit(&mtr);
/* Syncronous flush of the log buffer to disk */
log_buffer_flush_to_disk();
}
#endif
/********************************************************************* /*********************************************************************
This is called after MySQL has written the binlog entry for the current This is called after MySQL has written the binlog entry for the current
transaction. Flushes the InnoDB log files to disk if required. */ transaction. Flushes the InnoDB log files to disk if required. */
@ -1493,20 +1567,23 @@ int
innobase_commit_complete( innobase_commit_complete(
/*=====================*/ /*=====================*/
/* out: 0 */ /* out: 0 */
void* trx_handle) /* in: InnoDB trx handle */ THD* thd) /* in: user thread */
{ {
trx_t* trx; trx_t* trx;
if (srv_flush_log_at_trx_commit == 0) { trx = (trx_t*) thd->ha_data[innobase_hton.slot];
return(0); if (trx && trx->active_trans) {
}
trx = (trx_t*)trx_handle; trx->active_trans = 0;
ut_a(trx != NULL); if (srv_flush_log_at_trx_commit == 0) {
trx_commit_complete_for_mysql(trx); return(0);
}
trx_commit_complete_for_mysql(trx);
}
return(0); return(0);
} }
@ -1514,15 +1591,14 @@ innobase_commit_complete(
/********************************************************************* /*********************************************************************
Rolls back a transaction or the latest SQL statement. */ Rolls back a transaction or the latest SQL statement. */
int static int
innobase_rollback( innobase_rollback(
/*==============*/ /*==============*/
/* out: 0 or error number */ /* out: 0 or error number */
THD* thd, /* in: handle to the MySQL thread of the user THD* thd, /* in: handle to the MySQL thread of the user
whose transaction should be rolled back */ whose transaction should be rolled back */
void* trx_handle)/* in: InnoDB trx handle or a dummy stmt handle; bool all) /* in: TRUE - commit transaction
the latter means we roll back the latest SQL FALSE - the current SQL statement ended */
statement */
{ {
int error = 0; int error = 0;
trx_t* trx; trx_t* trx;
@ -1546,11 +1622,10 @@ innobase_rollback(
row_unlock_table_autoinc_for_mysql(trx); row_unlock_table_autoinc_for_mysql(trx);
} }
if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle if (all || (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) {
|| (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) {
error = trx_rollback_for_mysql(trx); error = trx_rollback_for_mysql(trx);
thd->transaction.all.innodb_active_trans = 0; trx->active_trans = 0;
} else { } else {
error = trx_rollback_last_sql_stat_for_mysql(trx); error = trx_rollback_last_sql_stat_for_mysql(trx);
} }
@ -1594,17 +1669,14 @@ innobase_rollback_trx(
/********************************************************************* /*********************************************************************
Rolls back a transaction to a savepoint. */ Rolls back a transaction to a savepoint. */
int static int
innobase_rollback_to_savepoint( innobase_rollback_to_savepoint(
/*===========================*/ /*===========================*/
/* out: 0 if success, HA_ERR_NO_SAVEPOINT if /* out: 0 if success, HA_ERR_NO_SAVEPOINT if
no savepoint with the given name */ no savepoint with the given name */
THD* thd, /* in: handle to the MySQL thread of the user THD* thd, /* in: handle to the MySQL thread of the user
whose transaction should be rolled back */ whose transaction should be rolled back */
char* savepoint_name, /* in: savepoint name */ void *savepoint) /* in: savepoint data */
my_off_t* binlog_cache_pos)/* out: position which corresponds to the
savepoint in the binlog cache of this
transaction, not defined if error */
{ {
ib_longlong mysql_binlog_cache_pos; ib_longlong mysql_binlog_cache_pos;
int error = 0; int error = 0;
@ -1620,34 +1692,35 @@ innobase_rollback_to_savepoint(
innobase_release_stat_resources(trx); innobase_release_stat_resources(trx);
error = trx_rollback_to_savepoint_for_mysql(trx, savepoint_name, /* TODO: use provided savepoint data area to store savepoint data */
char name[16]; sprintf(name, "s_%08lx", savepoint);
error = trx_rollback_to_savepoint_for_mysql(trx, name,
&mysql_binlog_cache_pos); &mysql_binlog_cache_pos);
*binlog_cache_pos = (my_off_t)mysql_binlog_cache_pos;
DBUG_RETURN(convert_error_code_to_mysql(error, NULL)); DBUG_RETURN(convert_error_code_to_mysql(error, NULL));
} }
/********************************************************************* /*********************************************************************
Release transaction savepoint name. */ Release transaction savepoint name. */
int static int
innobase_release_savepoint_name( innobase_release_savepoint(
/*===========================*/ /*===========================*/
/* out: 0 if success, HA_ERR_NO_SAVEPOINT if /* out: 0 if success, HA_ERR_NO_SAVEPOINT if
no savepoint with the given name */ no savepoint with the given name */
THD* thd, /* in: handle to the MySQL thread of the user THD* thd, /* in: handle to the MySQL thread of the user
whose transaction should be rolled back */ whose transaction should be rolled back */
char* savepoint_name) /* in: savepoint name */ void *savepoint) /* in: savepoint data */
{ {
ib_longlong mysql_binlog_cache_pos;
int error = 0; int error = 0;
trx_t* trx; trx_t* trx;
DBUG_ENTER("innobase_release_savepoint_name"); DBUG_ENTER("innobase_release_savepoint");
trx = check_trx_exists(thd); trx = check_trx_exists(thd);
error = trx_release_savepoint_for_mysql(trx, savepoint_name); /* TODO: use provided savepoint data area to store savepoint data */
char name[16]; sprintf(name, "s_%08lx", savepoint);
error = trx_release_savepoint_for_mysql(trx, name);
DBUG_RETURN(convert_error_code_to_mysql(error, NULL)); DBUG_RETURN(convert_error_code_to_mysql(error, NULL));
} }
@ -1655,17 +1728,12 @@ innobase_release_savepoint_name(
/********************************************************************* /*********************************************************************
Sets a transaction savepoint. */ Sets a transaction savepoint. */
int static int
innobase_savepoint( innobase_savepoint(
/*===============*/ /*===============*/
/* out: always 0, that is, always succeeds */ /* out: always 0, that is, always succeeds */
THD* thd, /* in: handle to the MySQL thread */ THD* thd, /* in: handle to the MySQL thread */
char* savepoint_name, /* in: savepoint name */ void *savepoint) /* in: savepoint data */
my_off_t binlog_cache_pos)/* in: offset up to which the current
transaction has cached log entries to its
binlog cache, not defined if no transaction
active, or we are in the autocommit state, or
binlogging is not switched on */
{ {
int error = 0; int error = 0;
trx_t* trx; trx_t* trx;
@ -1686,14 +1754,12 @@ innobase_savepoint(
innobase_release_stat_resources(trx); innobase_release_stat_resources(trx);
/* Setting a savepoint starts a transaction inside InnoDB since /* cannot happen outside of transaction */
it allocates resources for it (memory to store the savepoint name, DBUG_ASSERT(trx->active_trans);
for example) */
thd->transaction.all.innodb_active_trans = 1; /* TODO: use provided savepoint data area to store savepoint data */
char name[16]; sprintf(name, "s_%08lx", savepoint);
error = trx_savepoint_for_mysql(trx, savepoint_name, error = trx_savepoint_for_mysql(trx, name, (ib_longlong)0);
(ib_longlong)binlog_cache_pos);
DBUG_RETURN(convert_error_code_to_mysql(error, NULL)); DBUG_RETURN(convert_error_code_to_mysql(error, NULL));
} }
@ -1701,25 +1767,14 @@ innobase_savepoint(
/********************************************************************* /*********************************************************************
Frees a possible InnoDB trx object associated with the current THD. */ Frees a possible InnoDB trx object associated with the current THD. */
int static int
innobase_close_connection( innobase_close_connection(
/*======================*/ /*======================*/
/* out: 0 or error number */ /* out: 0 or error number */
THD* thd) /* in: handle to the MySQL thread of the user THD* thd) /* in: handle to the MySQL thread of the user
whose transaction should be rolled back */ whose resources should be free'd */
{ {
trx_t* trx; trx_free_for_mysql((trx_t*)thd->ha_data[innobase_hton.slot]);
trx = (trx_t*)thd->transaction.all.innobase_tid;
if (NULL != trx) {
innobase_rollback(thd, (void*)trx);
trx_free_for_mysql(trx);
thd->transaction.all.innobase_tid = NULL;
}
return(0); return(0);
} }
@ -2535,19 +2590,19 @@ ha_innobase::write_row(
DBUG_ENTER("ha_innobase::write_row"); DBUG_ENTER("ha_innobase::write_row");
if (prebuilt->trx != if (prebuilt->trx !=
(trx_t*) current_thd->transaction.all.innobase_tid) { (trx_t*) current_thd->ha_data[innobase_hton.slot]) {
fprintf(stderr, fprintf(stderr,
"InnoDB: Error: the transaction object for the table handle is at\n" "InnoDB: Error: the transaction object for the table handle is at\n"
"InnoDB: %p, but for the current thread it is at %p\n", "InnoDB: %p, but for the current thread it is at %p\n",
prebuilt->trx, prebuilt->trx,
current_thd->transaction.all.innobase_tid); (trx_t*) current_thd->ha_data[innobase_hton.slot]);
fputs("InnoDB: Dump of 200 bytes around prebuilt: ", stderr); fputs("InnoDB: Dump of 200 bytes around prebuilt: ", stderr);
ut_print_buf(stderr, ((const byte*)prebuilt) - 100, 200); ut_print_buf(stderr, ((const byte*)prebuilt) - 100, 200);
fputs("\n" fputs("\n"
"InnoDB: Dump of 200 bytes around transaction.all: ", "InnoDB: Dump of 200 bytes around transaction.all: ",
stderr); stderr);
ut_print_buf(stderr, ut_print_buf(stderr,
((byte*)(&(current_thd->transaction.all))) - 100, 200); ((byte*)(&(current_thd->ha_data[innobase_hton.slot]))) - 100, 200);
putc('\n', stderr); putc('\n', stderr);
ut_error; ut_error;
} }
@ -2599,7 +2654,7 @@ ha_innobase::write_row(
/* Altering to InnoDB format */ /* Altering to InnoDB format */
innobase_commit(user_thd, prebuilt->trx); innobase_commit(user_thd, prebuilt->trx);
/* Note that this transaction is still active. */ /* Note that this transaction is still active. */
user_thd->transaction.all.innodb_active_trans = 1; prebuilt->trx->active_trans = 1;
/* We will need an IX lock on the destination table. */ /* We will need an IX lock on the destination table. */
prebuilt->sql_stat_start = TRUE; prebuilt->sql_stat_start = TRUE;
} else { } else {
@ -2614,7 +2669,7 @@ ha_innobase::write_row(
locks, so they have to be acquired again. */ locks, so they have to be acquired again. */
innobase_commit(user_thd, prebuilt->trx); innobase_commit(user_thd, prebuilt->trx);
/* Note that this transaction is still active. */ /* Note that this transaction is still active. */
user_thd->transaction.all.innodb_active_trans = 1; prebuilt->trx->active_trans = 1;
/* Re-acquire the table lock on the source table. */ /* Re-acquire the table lock on the source table. */
row_lock_table_for_mysql(prebuilt, src_table, mode); row_lock_table_for_mysql(prebuilt, src_table, mode);
/* We will need an IX lock on the destination table. */ /* We will need an IX lock on the destination table. */
@ -2902,7 +2957,7 @@ ha_innobase::update_row(
DBUG_ENTER("ha_innobase::update_row"); DBUG_ENTER("ha_innobase::update_row");
ut_ad(prebuilt->trx == ut_ad(prebuilt->trx ==
(trx_t*) current_thd->transaction.all.innobase_tid); (trx_t*) current_thd->ha_data[innobase_hton.slot]);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
table->timestamp_field->set_time(); table->timestamp_field->set_time();
@ -2963,7 +3018,7 @@ ha_innobase::delete_row(
DBUG_ENTER("ha_innobase::delete_row"); DBUG_ENTER("ha_innobase::delete_row");
ut_ad(prebuilt->trx == ut_ad(prebuilt->trx ==
(trx_t*) current_thd->transaction.all.innobase_tid); (trx_t*) current_thd->ha_data[innobase_hton.slot]);
if (last_query_id != user_thd->query_id) { if (last_query_id != user_thd->query_id) {
prebuilt->sql_stat_start = TRUE; prebuilt->sql_stat_start = TRUE;
@ -3173,7 +3228,7 @@ ha_innobase::index_read(
DBUG_ENTER("index_read"); DBUG_ENTER("index_read");
ut_ad(prebuilt->trx == ut_ad(prebuilt->trx ==
(trx_t*) current_thd->transaction.all.innobase_tid); (trx_t*) current_thd->ha_data[innobase_hton.slot]);
statistic_increment(current_thd->status_var.ha_read_key_count, statistic_increment(current_thd->status_var.ha_read_key_count,
&LOCK_status); &LOCK_status);
@ -3288,7 +3343,7 @@ ha_innobase::change_active_index(
ut_ad(user_thd == current_thd); ut_ad(user_thd == current_thd);
ut_ad(prebuilt->trx == ut_ad(prebuilt->trx ==
(trx_t*) current_thd->transaction.all.innobase_tid); (trx_t*) current_thd->ha_data[innobase_hton.slot]);
active_index = keynr; active_index = keynr;
@ -3376,7 +3431,7 @@ ha_innobase::general_fetch(
DBUG_ENTER("general_fetch"); DBUG_ENTER("general_fetch");
ut_ad(prebuilt->trx == ut_ad(prebuilt->trx ==
(trx_t*) current_thd->transaction.all.innobase_tid); (trx_t*) current_thd->ha_data[innobase_hton.slot]);
innodb_srv_conc_enter_innodb(prebuilt->trx); innodb_srv_conc_enter_innodb(prebuilt->trx);
@ -3602,7 +3657,7 @@ ha_innobase::rnd_pos(
&LOCK_status); &LOCK_status);
ut_ad(prebuilt->trx == ut_ad(prebuilt->trx ==
(trx_t*) current_thd->transaction.all.innobase_tid); (trx_t*) current_thd->ha_data[innobase_hton.slot]);
if (prebuilt->clust_index_was_generated) { if (prebuilt->clust_index_was_generated) {
/* No primary key was defined for the table and we /* No primary key was defined for the table and we
@ -3651,7 +3706,7 @@ ha_innobase::position(
uint len; uint len;
ut_ad(prebuilt->trx == ut_ad(prebuilt->trx ==
(trx_t*) current_thd->transaction.all.innobase_tid); (trx_t*) current_thd->ha_data[innobase_hton.slot]);
if (prebuilt->clust_index_was_generated) { if (prebuilt->clust_index_was_generated) {
/* No primary key was defined for the table and we /* No primary key was defined for the table and we
@ -4141,7 +4196,7 @@ ha_innobase::discard_or_import_tablespace(
ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N); ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N);
ut_a(prebuilt->trx == ut_a(prebuilt->trx ==
(trx_t*) current_thd->transaction.all.innobase_tid); (trx_t*) current_thd->ha_data[innobase_hton.slot]);
dict_table = prebuilt->table; dict_table = prebuilt->table;
trx = prebuilt->trx; trx = prebuilt->trx;
@ -4847,7 +4902,7 @@ ha_innobase::check(
ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N); ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N);
ut_a(prebuilt->trx == ut_a(prebuilt->trx ==
(trx_t*) current_thd->transaction.all.innobase_tid); (trx_t*) current_thd->ha_data[innobase_hton.slot]);
if (prebuilt->mysql_template == NULL) { if (prebuilt->mysql_template == NULL) {
/* Build the template; we will use a dummy template /* Build the template; we will use a dummy template
@ -5285,7 +5340,11 @@ ha_innobase::start_stmt(
} }
/* Set the MySQL flag to mark that there is an active transaction */ /* Set the MySQL flag to mark that there is an active transaction */
thd->transaction.all.innodb_active_trans = 1; if (trx->active_trans == 0) {
register_trans(thd);
trx->active_trans = 1;
}
return(0); return(0);
} }
@ -5353,7 +5412,11 @@ ha_innobase::external_lock(
/* Set the MySQL flag to mark that there is an active /* Set the MySQL flag to mark that there is an active
transaction */ transaction */
thd->transaction.all.innodb_active_trans = 1; if (trx->active_trans == 0) {
register_trans(thd);
trx->active_trans = 1;
}
trx->n_mysql_tables_in_use++; trx->n_mysql_tables_in_use++;
prebuilt->mysql_has_locked = TRUE; prebuilt->mysql_has_locked = TRUE;
@ -5433,8 +5496,8 @@ ha_innobase::external_lock(
innobase_release_stat_resources(trx); innobase_release_stat_resources(trx);
if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
if (thd->transaction.all.innodb_active_trans != 0) { if (trx->active_trans != 0) {
innobase_commit(thd, trx); innobase_commit(thd, TRUE);
} }
} else { } else {
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
@ -5513,12 +5576,16 @@ ha_innobase::transactional_table_lock(
/* MySQL is setting a new transactional table lock */ /* MySQL is setting a new transactional table lock */
/* Set the MySQL flag to mark that there is an active transaction */ /* Set the MySQL flag to mark that there is an active transaction */
thd->transaction.all.innodb_active_trans = 1; if (trx->active_trans == 0) {
register_trans(thd);
trx->active_trans = 1;
}
if (thd->in_lock_tables && thd->variables.innodb_table_locks) { if (thd->in_lock_tables && thd->variables.innodb_table_locks) {
ulint error = DB_SUCCESS; ulint error = DB_SUCCESS;
error = row_lock_table_for_mysql(prebuilt,NULL, error = row_lock_table_for_mysql(prebuilt,NULL,
LOCK_TABLE_TRANSACTIONAL); LOCK_TABLE_TRANSACTIONAL);
if (error != DB_SUCCESS) { if (error != DB_SUCCESS) {
@ -5917,7 +5984,7 @@ ha_innobase::innobase_read_and_init_auto_inc(
ut_a(prebuilt); ut_a(prebuilt);
ut_a(prebuilt->trx == ut_a(prebuilt->trx ==
(trx_t*) current_thd->transaction.all.innobase_tid); (trx_t*) current_thd->ha_data[innobase_hton.slot]);
ut_a(prebuilt->table); ut_a(prebuilt->table);
/* In case MySQL calls this in the middle of a SELECT query, release /* In case MySQL calls this in the middle of a SELECT query, release
@ -6027,37 +6094,6 @@ ha_innobase::get_auto_increment()
return((ulonglong) nr); return((ulonglong) nr);
} }
/***********************************************************************
This function stores the binlog offset and flushes logs. */
void
innobase_store_binlog_offset_and_flush_log(
/*=======================================*/
char *binlog_name, /* in: binlog name */
longlong offset) /* in: binlog offset */
{
mtr_t mtr;
assert(binlog_name != NULL);
/* Start a mini-transaction */
mtr_start_noninline(&mtr);
/* Update the latest MySQL binlog name and offset info
in trx sys header */
trx_sys_update_mysql_binlog_offset(
binlog_name,
offset,
TRX_SYS_MYSQL_LOG_INFO, &mtr);
/* Commits the mini-transaction */
mtr_commit(&mtr);
/* Syncronous flush of the log buffer to disk */
log_buffer_flush_to_disk();
}
int int
ha_innobase::cmp_ref( ha_innobase::cmp_ref(
@ -6252,9 +6288,7 @@ innobase_xa_prepare(
trx = check_trx_exists(thd); trx = check_trx_exists(thd);
/* TODO: Get X/Open XA Transaction Identification from MySQL*/ trx->xid=thd->transaction.xid;
memset(&trx->xid, 0, sizeof(trx->xid));
trx->xid.formatID = -1;
/* Release a possible FIFO ticket and search latch. Since we will /* Release a possible FIFO ticket and search latch. Since we will
reserve the kernel mutex, we have to release the search system latch reserve the kernel mutex, we have to release the search system latch
@ -6265,14 +6299,14 @@ innobase_xa_prepare(
if (trx->active_trans == 0 && trx->conc_state != TRX_NOT_STARTED) { if (trx->active_trans == 0 && trx->conc_state != TRX_NOT_STARTED) {
fprintf(stderr, fprintf(stderr,
"InnoDB: Error: thd->transaction.all.innodb_active_trans == 0\n" "InnoDB: Error: trx->active_trans == 0\n"
"InnoDB: but trx->conc_state != TRX_NOT_STARTED\n"); "InnoDB: but trx->conc_state != TRX_NOT_STARTED\n");
} }
if (all || (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) { if (all || (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) {
/* We were instructed to prepare the whole transaction, or /* We were instructed to prepare the whole transaction, or
this is an SQL statement end and autocommit is on */ this is an SQL statement end and autocommit is on */
error = trx_prepare_for_mysql(trx); error = trx_prepare_for_mysql(trx);
} else { } else {

View file

@ -245,38 +245,31 @@ extern ulong srv_thread_concurrency;
extern TYPELIB innobase_lock_typelib; extern TYPELIB innobase_lock_typelib;
bool innobase_init(void); handlerton *innobase_init(void);
bool innobase_end(void); bool innobase_end(void);
bool innobase_flush_logs(void); bool innobase_flush_logs(void);
uint innobase_get_free_space(void); uint innobase_get_free_space(void);
int innobase_commit(THD *thd, void* trx_handle); /*
don't delete it - it may be re-enabled later
as an optimization for the most common case InnoDB+binlog
*/
#if 0
int innobase_report_binlog_offset_and_commit( int innobase_report_binlog_offset_and_commit(
THD* thd, THD* thd,
void* trx_handle, void* trx_handle,
char* log_file_name, char* log_file_name,
my_off_t end_offset); my_off_t end_offset);
int innobase_commit_complete( int innobase_commit_complete(void* trx_handle);
void* trx_handle); void innobase_store_binlog_offset_and_flush_log(char *binlog_name,longlong offset);
int innobase_rollback(THD *thd, void* trx_handle); #endif
int innobase_rollback_to_savepoint(
THD* thd,
char* savepoint_name,
my_off_t* binlog_cache_pos);
int innobase_savepoint(
THD* thd,
char* savepoint_name,
my_off_t binlog_cache_pos);
int innobase_release_savepoint_name(
THD* thd,
char* savepoint_name);
int innobase_close_connection(THD *thd);
int innobase_drop_database(char *path); int innobase_drop_database(char *path);
bool innodb_show_status(THD* thd); bool innodb_show_status(THD* thd);
bool innodb_mutex_show_status(THD* thd); bool innodb_mutex_show_status(THD* thd);
void innodb_export_status(void); void innodb_export_status(void);
void innobase_release_temporary_latches(void* innobase_tid); void innobase_release_temporary_latches(THD *thd);
void innobase_store_binlog_offset_and_flush_log(char *binlog_name,longlong offset); void innobase_store_binlog_offset_and_flush_log(char *binlog_name,longlong offset);

View file

@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
/* /*
@ -45,6 +45,23 @@ static const int max_transactions= 256;
static const char *ha_ndb_ext=".ndb"; static const char *ha_ndb_ext=".ndb";
static int ndbcluster_close_connection(THD *thd);
static int ndbcluster_commit(THD *thd, bool all);
static int ndbcluster_rollback(THD *thd, bool all);
static handlerton ndbcluster_hton = {
0, /* slot */
0, /* savepoint size */
ndbcluster_close_connection,
NULL, /* savepoint_set */
NULL, /* savepoint_rollback */
NULL, /* savepoint_release */
ndbcluster_commit,
ndbcluster_rollback,
NULL, /* prepare */
NULL /* recover */
};
#define NDB_HIDDEN_PRIMARY_KEY_LENGTH 8 #define NDB_HIDDEN_PRIMARY_KEY_LENGTH 8
@ -258,6 +275,8 @@ Thd_ndb::Thd_ndb()
ndb= new Ndb(g_ndb_cluster_connection, ""); ndb= new Ndb(g_ndb_cluster_connection, "");
lock_count= 0; lock_count= 0;
count= 0; count= 0;
all= NULL;
stmt= NULL;
error= 0; error= 0;
} }
@ -268,10 +287,18 @@ Thd_ndb::~Thd_ndb()
ndb= 0; ndb= 0;
} }
inline
Thd_ndb *
get_thd_ndb(THD *thd) { return (Thd_ndb *) thd->ha_data[ndbcluster_hton.slot]; }
inline
void
set_thd_ndb(THD *thd, Thd_ndb *thd_ndb) { thd->ha_data[ndbcluster_hton.slot]= thd_ndb; }
inline inline
Ndb *ha_ndbcluster::get_ndb() Ndb *ha_ndbcluster::get_ndb()
{ {
return ((Thd_ndb*)current_thd->transaction.thd_ndb)->ndb; return get_thd_ndb(table->in_use)->ndb;
} }
/* /*
@ -315,7 +342,7 @@ void ha_ndbcluster::records_update()
} }
{ {
THD *thd= current_thd; THD *thd= current_thd;
if (((Thd_ndb*)(thd->transaction.thd_ndb))->error) if (get_thd_ndb(thd)->error)
info->no_uncommitted_rows_count= 0; info->no_uncommitted_rows_count= 0;
} }
records= info->records+ info->no_uncommitted_rows_count; records= info->records+ info->no_uncommitted_rows_count;
@ -327,8 +354,7 @@ void ha_ndbcluster::no_uncommitted_rows_execute_failure()
if (m_ha_not_exact_count) if (m_ha_not_exact_count)
return; return;
DBUG_ENTER("ha_ndbcluster::no_uncommitted_rows_execute_failure"); DBUG_ENTER("ha_ndbcluster::no_uncommitted_rows_execute_failure");
THD *thd= current_thd; get_thd_ndb(table->in_use)->error= 1;
((Thd_ndb*)(thd->transaction.thd_ndb))->error= 1;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -338,7 +364,7 @@ void ha_ndbcluster::no_uncommitted_rows_init(THD *thd)
return; return;
DBUG_ENTER("ha_ndbcluster::no_uncommitted_rows_init"); DBUG_ENTER("ha_ndbcluster::no_uncommitted_rows_init");
struct Ndb_table_local_info *info= (struct Ndb_table_local_info *)m_table_info; struct Ndb_table_local_info *info= (struct Ndb_table_local_info *)m_table_info;
Thd_ndb *thd_ndb= (Thd_ndb *)thd->transaction.thd_ndb; Thd_ndb *thd_ndb= get_thd_ndb(thd);
if (info->last_count != thd_ndb->count) if (info->last_count != thd_ndb->count)
{ {
info->last_count= thd_ndb->count; info->last_count= thd_ndb->count;
@ -370,14 +396,15 @@ void ha_ndbcluster::no_uncommitted_rows_reset(THD *thd)
if (m_ha_not_exact_count) if (m_ha_not_exact_count)
return; return;
DBUG_ENTER("ha_ndbcluster::no_uncommitted_rows_reset"); DBUG_ENTER("ha_ndbcluster::no_uncommitted_rows_reset");
((Thd_ndb*)(thd->transaction.thd_ndb))->count++; Thd_ndb *thd_ndb= get_thd_ndb(thd);
((Thd_ndb*)(thd->transaction.thd_ndb))->error= 0; thd_ndb->count++;
thd_ndb->error= 0;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/* /*
Take care of the error that occured in NDB Take care of the error that occured in NDB
RETURN RETURN
0 No error 0 No error
# The mapped error code # The mapped error code
@ -3136,9 +3163,9 @@ THR_LOCK_DATA **ha_ndbcluster::store_lock(THD *thd,
As MySQL will execute an external lock for every new table it uses As MySQL will execute an external lock for every new table it uses
we can use this to start the transactions. we can use this to start the transactions.
If we are in auto_commit mode we just need to start a transaction If we are in auto_commit mode we just need to start a transaction
for the statement, this will be stored in transaction.stmt. for the statement, this will be stored in thd_ndb.stmt.
If not, we have to start a master transaction if there doesn't exist If not, we have to start a master transaction if there doesn't exist
one from before, this will be stored in transaction.all one from before, this will be stored in thd_ndb.all
When a table lock is held one transaction will be started which holds When a table lock is held one transaction will be started which holds
the table lock and for each statement a hupp transaction will be started the table lock and for each statement a hupp transaction will be started
@ -3157,7 +3184,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
if (check_ndb_connection()) if (check_ndb_connection())
DBUG_RETURN(1); DBUG_RETURN(1);
Thd_ndb *thd_ndb= (Thd_ndb*)thd->transaction.thd_ndb; Thd_ndb *thd_ndb= get_thd_ndb(thd);
Ndb *ndb= thd_ndb->ndb; Ndb *ndb= thd_ndb->ndb;
DBUG_PRINT("enter", ("transaction.thd_ndb->lock_count: %d", DBUG_PRINT("enter", ("transaction.thd_ndb->lock_count: %d",
@ -3173,18 +3200,19 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN | OPTION_TABLE_LOCK))) if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN | OPTION_TABLE_LOCK)))
{ {
// Autocommit transaction // Autocommit transaction
DBUG_ASSERT(!thd->transaction.stmt.ndb_tid); DBUG_ASSERT(!thd_ndb->stmt);
DBUG_PRINT("trans",("Starting transaction stmt")); DBUG_PRINT("trans",("Starting transaction stmt"));
trans= ndb->startTransaction(); trans= ndb->startTransaction();
if (trans == NULL) if (trans == NULL)
ERR_RETURN(ndb->getNdbError()); ERR_RETURN(ndb->getNdbError());
no_uncommitted_rows_reset(thd); no_uncommitted_rows_reset(thd);
thd->transaction.stmt.ndb_tid= trans; thd_ndb->stmt= trans;
trans_register_ha(thd, FALSE, &ndbcluster_hton);
} }
else else
{ {
if (!thd->transaction.all.ndb_tid) if (!thd_ndb->all)
{ {
// Not autocommit transaction // Not autocommit transaction
// A "master" transaction ha not been started yet // A "master" transaction ha not been started yet
@ -3194,6 +3222,8 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
if (trans == NULL) if (trans == NULL)
ERR_RETURN(ndb->getNdbError()); ERR_RETURN(ndb->getNdbError());
no_uncommitted_rows_reset(thd); no_uncommitted_rows_reset(thd);
thd_ndb->all= trans;
trans_register_ha(thd, TRUE, &ndbcluster_hton);
/* /*
If this is the start of a LOCK TABLE, a table look If this is the start of a LOCK TABLE, a table look
@ -3207,7 +3237,6 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
DBUG_PRINT("info", ("Locking the table..." )); DBUG_PRINT("info", ("Locking the table..." ));
} }
thd->transaction.all.ndb_tid= trans;
} }
} }
} }
@ -3232,9 +3261,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
else else
m_transaction_on= thd->variables.ndb_use_transactions; m_transaction_on= thd->variables.ndb_use_transactions;
m_active_trans= thd->transaction.all.ndb_tid ? m_active_trans= thd_ndb->all ? thd_ndb->all : thd_ndb->stmt;
(NdbTransaction*)thd->transaction.all.ndb_tid:
(NdbTransaction*)thd->transaction.stmt.ndb_tid;
DBUG_ASSERT(m_active_trans); DBUG_ASSERT(m_active_trans);
// Start of transaction // Start of transaction
m_retrieve_all_fields= FALSE; m_retrieve_all_fields= FALSE;
@ -3260,7 +3287,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
DBUG_PRINT("trans", ("Last external_lock")); DBUG_PRINT("trans", ("Last external_lock"));
PRINT_OPTION_FLAGS(thd); PRINT_OPTION_FLAGS(thd);
if (thd->transaction.stmt.ndb_tid) if (thd_ndb->stmt)
{ {
/* /*
Unlock is done without a transaction commit / rollback. Unlock is done without a transaction commit / rollback.
@ -3269,7 +3296,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
*/ */
DBUG_PRINT("trans",("ending non-updating transaction")); DBUG_PRINT("trans",("ending non-updating transaction"));
ndb->closeTransaction(m_active_trans); ndb->closeTransaction(m_active_trans);
thd->transaction.stmt.ndb_tid= 0; thd_ndb->stmt= NULL;
} }
} }
m_table= NULL; m_table= NULL;
@ -3316,14 +3343,14 @@ int ha_ndbcluster::start_stmt(THD *thd)
DBUG_ENTER("start_stmt"); DBUG_ENTER("start_stmt");
PRINT_OPTION_FLAGS(thd); PRINT_OPTION_FLAGS(thd);
NdbTransaction *trans= (NdbTransaction*)thd->transaction.stmt.ndb_tid; Thd_ndb *thd_ndb= get_thd_ndb(thd);
NdbTransaction *trans= thd_ndb->stmt;
if (!trans){ if (!trans){
Ndb *ndb= ((Thd_ndb*)thd->transaction.thd_ndb)->ndb; Ndb *ndb= thd_ndb->ndb;
DBUG_PRINT("trans",("Starting transaction stmt")); DBUG_PRINT("trans",("Starting transaction stmt"));
#if 0 #if 0
NdbTransaction *tablock_trans= NdbTransaction *tablock_trans= thd_ndb->all;
(NdbTransaction*)thd->transaction.all.ndb_tid;
DBUG_PRINT("info", ("tablock_trans: %x", (UintPtr)tablock_trans)); DBUG_PRINT("info", ("tablock_trans: %x", (UintPtr)tablock_trans));
DBUG_ASSERT(tablock_trans); DBUG_ASSERT(tablock_trans);
// trans= ndb->hupp(tablock_trans); // trans= ndb->hupp(tablock_trans);
@ -3332,7 +3359,8 @@ int ha_ndbcluster::start_stmt(THD *thd)
if (trans == NULL) if (trans == NULL)
ERR_RETURN(ndb->getNdbError()); ERR_RETURN(ndb->getNdbError());
no_uncommitted_rows_reset(thd); no_uncommitted_rows_reset(thd);
thd->transaction.stmt.ndb_tid= trans; thd_ndb->stmt= trans;
trans_register_ha(thd, FALSE, &ndbcluster_hton);
} }
m_active_trans= trans; m_active_trans= trans;
@ -3349,15 +3377,16 @@ int ha_ndbcluster::start_stmt(THD *thd)
Commit a transaction started in NDB Commit a transaction started in NDB
*/ */
int ndbcluster_commit(THD *thd, void *ndb_transaction) int ndbcluster_commit(THD *thd, bool all)
{ {
int res= 0; int res= 0;
Ndb *ndb= ((Thd_ndb*)thd->transaction.thd_ndb)->ndb; Thd_ndb *thd_ndb= get_thd_ndb(thd);
NdbTransaction *trans= (NdbTransaction*)ndb_transaction; Ndb *ndb= thd_ndb->ndb;
NdbTransaction *trans= all ? thd_ndb->all : thd_ndb->stmt;
DBUG_ENTER("ndbcluster_commit"); DBUG_ENTER("ndbcluster_commit");
DBUG_PRINT("transaction",("%s", DBUG_PRINT("transaction",("%s",
trans == thd->transaction.stmt.ndb_tid ? trans == thd_ndb->stmt ?
"stmt" : "all")); "stmt" : "all"));
DBUG_ASSERT(ndb && trans); DBUG_ASSERT(ndb && trans);
@ -3371,6 +3400,7 @@ int ndbcluster_commit(THD *thd, void *ndb_transaction)
ndbcluster_print_error(res, error_op); ndbcluster_print_error(res, error_op);
} }
ndb->closeTransaction(trans); ndb->closeTransaction(trans);
thd_ndb->all= thd_ndb->stmt= NULL;
DBUG_RETURN(res); DBUG_RETURN(res);
} }
@ -3379,15 +3409,16 @@ int ndbcluster_commit(THD *thd, void *ndb_transaction)
Rollback a transaction started in NDB Rollback a transaction started in NDB
*/ */
int ndbcluster_rollback(THD *thd, void *ndb_transaction) int ndbcluster_rollback(THD *thd, bool all)
{ {
int res= 0; int res= 0;
Ndb *ndb= ((Thd_ndb*)thd->transaction.thd_ndb)->ndb; Thd_ndb *thd_ndb= get_thd_ndb(thd);
NdbTransaction *trans= (NdbTransaction*)ndb_transaction; Ndb *ndb= thd_ndb->ndb;
NdbTransaction *trans= all ? thd_ndb->all : thd_ndb->stmt;
DBUG_ENTER("ndbcluster_rollback"); DBUG_ENTER("ndbcluster_rollback");
DBUG_PRINT("transaction",("%s", DBUG_PRINT("transaction",("%s",
trans == thd->transaction.stmt.ndb_tid ? trans == thd_ndb->stmt ?
"stmt" : "all")); "stmt" : "all"));
DBUG_ASSERT(ndb && trans); DBUG_ASSERT(ndb && trans);
@ -3401,7 +3432,8 @@ int ndbcluster_rollback(THD *thd, void *ndb_transaction)
ndbcluster_print_error(res, error_op); ndbcluster_print_error(res, error_op);
} }
ndb->closeTransaction(trans); ndb->closeTransaction(trans);
DBUG_RETURN(0); thd_ndb->all= thd_ndb->stmt= NULL;
DBUG_RETURN(res);
} }
@ -4257,12 +4289,12 @@ void ha_ndbcluster::release_thd_ndb(Thd_ndb* thd_ndb)
Ndb* check_ndb_in_thd(THD* thd) Ndb* check_ndb_in_thd(THD* thd)
{ {
Thd_ndb *thd_ndb= (Thd_ndb*)thd->transaction.thd_ndb; Thd_ndb *thd_ndb= get_thd_ndb(thd);
if (!thd_ndb) if (!thd_ndb)
{ {
if (!(thd_ndb= ha_ndbcluster::seize_thd_ndb())) if (!(thd_ndb= ha_ndbcluster::seize_thd_ndb()))
return NULL; return NULL;
thd->transaction.thd_ndb= thd_ndb; set_thd_ndb(thd, thd_ndb);
} }
return thd_ndb->ndb; return thd_ndb->ndb;
} }
@ -4282,16 +4314,16 @@ int ha_ndbcluster::check_ndb_connection()
} }
void ndbcluster_close_connection(THD *thd) int ndbcluster_close_connection(THD *thd)
{ {
Thd_ndb *thd_ndb= (Thd_ndb*)thd->transaction.thd_ndb; Thd_ndb *thd_ndb= get_thd_ndb(thd);
DBUG_ENTER("ndbcluster_close_connection"); DBUG_ENTER("ndbcluster_close_connection");
if (thd_ndb) if (thd_ndb)
{ {
ha_ndbcluster::release_thd_ndb(thd_ndb); ha_ndbcluster::release_thd_ndb(thd_ndb);
thd->transaction.thd_ndb= NULL; set_thd_ndb(thd, NULL); // not strictly required but does not hurt either
} }
DBUG_VOID_RETURN; DBUG_RETURN(0);
} }
@ -4554,7 +4586,8 @@ static int connect_callback()
return 0; return 0;
} }
bool ndbcluster_init() handlerton *
ndbcluster_init()
{ {
int res; int res;
DBUG_ENTER("ndbcluster_init"); DBUG_ENTER("ndbcluster_init");
@ -4630,11 +4663,11 @@ bool ndbcluster_init()
} }
ndbcluster_inited= 1; ndbcluster_inited= 1;
DBUG_RETURN(FALSE); DBUG_RETURN(&ndbcluster_hton);
ndbcluster_init_error: ndbcluster_init_error:
ndbcluster_end(); ndbcluster_end();
DBUG_RETURN(TRUE); DBUG_RETURN(NULL);
} }

View file

@ -74,6 +74,8 @@ class Thd_ndb {
Ndb *ndb; Ndb *ndb;
ulong count; ulong count;
uint lock_count; uint lock_count;
NdbTransaction *all;
NdbTransaction *stmt;
int error; int error;
}; };
@ -286,14 +288,9 @@ private:
extern struct show_var_st ndb_status_variables[]; extern struct show_var_st ndb_status_variables[];
bool ndbcluster_init(void); handlerton *ndbcluster_init(void);
bool ndbcluster_end(void); bool ndbcluster_end(void);
int ndbcluster_commit(THD *thd, void* ndb_transaction);
int ndbcluster_rollback(THD *thd, void* ndb_transaction);
void ndbcluster_close_connection(THD *thd);
int ndbcluster_discover(THD* thd, const char* dbname, const char* name, int ndbcluster_discover(THD* thd, const char* dbname, const char* name,
const void** frmblob, uint* frmlen); const void** frmblob, uint* frmlen);
int ndbcluster_find_files(THD *thd,const char *db,const char *path, int ndbcluster_find_files(THD *thd,const char *db,const char *path,

File diff suppressed because it is too large Load diff

View file

@ -93,6 +93,11 @@
#define HA_KEY_SWITCH_NONUNIQ_SAVE 2 #define HA_KEY_SWITCH_NONUNIQ_SAVE 2
#define HA_KEY_SWITCH_ALL_SAVE 3 #define HA_KEY_SWITCH_ALL_SAVE 3
/*
Note: the following includes binlog and closing 0.
so: innodb+bdb+ndb+binlog+0
*/
#define MAX_HA 5
/* /*
Bits in index_ddl_flags(KEY *wanted_index) Bits in index_ddl_flags(KEY *wanted_index)
@ -192,16 +197,12 @@ enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED,
#define HA_CREATE_USED_COMMENT (1L << 16) #define HA_CREATE_USED_COMMENT (1L << 16)
#define HA_CREATE_USED_PASSWORD (1L << 17) #define HA_CREATE_USED_PASSWORD (1L << 17)
typedef struct st_thd_trans { typedef ulonglong my_xid;
void *bdb_tid; #define MYSQL_XID_PREFIX "MySQLXid"
void *innobase_tid; #define MYSQL_XID_PREFIX_LEN 8 // must be a multiple of 8
bool innodb_active_trans; #define MYSQL_XID_OFFSET (MYSQL_XID_PREFIX_LEN+sizeof(server_id))
void *ndb_tid; #define MYSQL_XID_GTRID_LEN (MYSQL_XID_OFFSET+sizeof(my_xid))
} THD_TRANS;
#ifndef XIDDATASIZE /* no xa.h included */
/* XXX - may be we should disable xa completely in this case ? */
#define XIDDATASIZE 128 #define XIDDATASIZE 128
#define MAXGTRIDSIZE 64 #define MAXGTRIDSIZE 64
#define MAXBQUALSIZE 64 #define MAXBQUALSIZE 64
@ -210,22 +211,106 @@ struct xid_t {
long formatID; long formatID;
long gtrid_length; long gtrid_length;
long bqual_length; long bqual_length;
char data[XIDDATASIZE]; char data[XIDDATASIZE]; // not \0-terminated !
};
bool eq(LEX_STRING *l) { return eq(l->length, 0, l->str); }
bool eq(long g, long b, const char *d)
{ return g == gtrid_length && b == bqual_length && !memcmp(d, data, g+b); }
void set(LEX_STRING *l) { set(l->length, 0, l->str); }
void set(ulonglong l)
{
set(MYSQL_XID_PREFIX_LEN, 0, MYSQL_XID_PREFIX);
*(ulong*)(data+MYSQL_XID_PREFIX_LEN)=server_id;
*(my_xid*)(data+MYSQL_XID_OFFSET)=l;
gtrid_length=MYSQL_XID_GTRID_LEN;
}
void set(long g, long b, const char *d)
{
formatID=1;
gtrid_length= g;
bqual_length= b;
memcpy(data, d, g+b);
}
bool is_null() { return formatID == -1; }
void null() { formatID= -1; }
my_xid quick_get_my_xid()
{
return *(my_xid*)(data+MYSQL_XID_OFFSET);
}
my_xid get_my_xid()
{
return gtrid_length == MYSQL_XID_GTRID_LEN && bqual_length == 0 &&
*(ulong*)(data+MYSQL_XID_PREFIX_LEN) == server_id &&
!memcmp(data, MYSQL_XID_PREFIX, MYSQL_XID_PREFIX_LEN) ?
quick_get_my_xid() : 0;
}
};
typedef struct xid_t XID; typedef struct xid_t XID;
/* for recover() handlerton call */
#define MIN_XID_LIST_SIZE 128
#define MAX_XID_LIST_SIZE (1024*128)
#endif /*
handlerton is a singleton structure - one instance per storage engine -
to provide access to storage engine functionality that works on
"global" level (unlike handler class that works on per-table basis)
usually handlerton instance is defined statically in ha_xxx.cc as
static handlerton { ... } xxx_hton;
savepoint_*, prepare, recover, and *_by_xid pointers can be 0.
*/
typedef struct typedef struct
{ {
byte slot; /*
each storage engine has it's own memory area (actually a pointer)
in the thd, for storing per-connection information.
It is accessed as
thd->ha_data[xxx_hton.slot]
slot number is initialized by MySQL after xxx_init() is called.
*/
uint slot;
/*
to store per-savepoint data storage engine is provided with an area
of a requested size (0 is ok here).
savepoint_offset must be initialized statically to the size of
the needed memory to store per-savepoint information.
After xxx_init it is changed to be an offset to savepoint storage
area and need not be used by storage engine.
see binlog_hton and binlog_savepoint_set/rollback for an example.
*/
uint savepoint_offset; uint savepoint_offset;
/*
handlerton methods:
close_connection is only called if
thd->ha_data[xxx_hton.slot] is non-zero, so even if you don't need
this storage area - set it to something, so that MySQL would know
this storage engine was accessed in this connection
*/
int (*close_connection)(THD *thd); int (*close_connection)(THD *thd);
/*
sv points to an uninitialized storage area of requested size
(see savepoint_offset description)
*/
int (*savepoint_set)(THD *thd, void *sv); int (*savepoint_set)(THD *thd, void *sv);
/*
sv points to a storage area, that was earlier passed
to the savepoint_set call
*/
int (*savepoint_rollback)(THD *thd, void *sv); int (*savepoint_rollback)(THD *thd, void *sv);
int (*savepoint_release)(THD *thd, void *sv); int (*savepoint_release)(THD *thd, void *sv);
/*
'all' is true if it's a real commit, that makes persistent changes
'all' is false if it's not in fact a commit but an end of the
statement that is part of the transaction.
NOTE 'all' is also false in auto-commit mode where 'end of statement'
and 'real commit' mean the same event.
*/
int (*commit)(THD *thd, bool all); int (*commit)(THD *thd, bool all);
int (*rollback)(THD *thd, bool all); int (*rollback)(THD *thd, bool all);
int (*prepare)(THD *thd, bool all); int (*prepare)(THD *thd, bool all);
@ -234,6 +319,16 @@ typedef struct
int (*rollback_by_xid)(XID *xid); int (*rollback_by_xid)(XID *xid);
} handlerton; } handlerton;
typedef struct st_thd_trans
{
/* number of entries in the ht[] */
uint nht;
/* true is not all entries in the ht[] support 2pc */
bool no_2pc;
/* storage engines that registered themselves for this transaction */
handlerton *ht[MAX_HA];
} THD_TRANS;
enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED, enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED,
ISO_REPEATABLE_READ, ISO_SERIALIZABLE}; ISO_REPEATABLE_READ, ISO_SERIALIZABLE};
@ -268,6 +363,9 @@ typedef struct st_table TABLE;
struct st_foreign_key_info; struct st_foreign_key_info;
typedef struct st_foreign_key_info FOREIGN_KEY_INFO; typedef struct st_foreign_key_info FOREIGN_KEY_INFO;
typedef struct st_savepoint SAVEPOINT;
extern ulong savepoint_alloc_size;
typedef struct st_ha_check_opt typedef struct st_ha_check_opt
{ {
ulong sort_buffer_size; ulong sort_buffer_size;
@ -626,57 +724,72 @@ public:
extern struct show_table_type_st sys_table_types[]; extern struct show_table_type_st sys_table_types[];
extern const char *ha_row_type[]; extern const char *ha_row_type[];
extern TYPELIB tx_isolation_typelib; extern TYPELIB tx_isolation_typelib;
extern handlerton *handlertons[MAX_HA];
extern ulong total_ha, total_ha_2pc;
/* Wrapper functions */ /* Wrapper functions */
#define ha_commit_stmt(thd) (ha_commit_trans((thd), &((thd)->transaction.stmt))) #define ha_commit_stmt(thd) (ha_commit_trans((thd), FALSE))
#define ha_rollback_stmt(thd) (ha_rollback_trans((thd), &((thd)->transaction.stmt))) #define ha_rollback_stmt(thd) (ha_rollback_trans((thd), FALSE))
#define ha_commit(thd) (ha_commit_trans((thd), &((thd)->transaction.all))) #define ha_commit(thd) (ha_commit_trans((thd), TRUE))
#define ha_rollback(thd) (ha_rollback_trans((thd), &((thd)->transaction.all))) #define ha_rollback(thd) (ha_rollback_trans((thd), TRUE))
#define ha_supports_generate(T) (T != DB_TYPE_INNODB && \ #define ha_supports_generate(T) (T != DB_TYPE_INNODB && \
T != DB_TYPE_BERKELEY_DB && \ T != DB_TYPE_BERKELEY_DB && \
T != DB_TYPE_NDBCLUSTER) T != DB_TYPE_NDBCLUSTER)
/* lookups */
enum db_type ha_resolve_by_name(const char *name, uint namelen); enum db_type ha_resolve_by_name(const char *name, uint namelen);
const char *ha_get_storage_engine(enum db_type db_type); const char *ha_get_storage_engine(enum db_type db_type);
handler *get_new_handler(TABLE *table, enum db_type db_type); handler *get_new_handler(TABLE *table, enum db_type db_type);
my_off_t ha_get_ptr(byte *ptr, uint pack_length);
void ha_store_ptr(byte *buff, uint pack_length, my_off_t pos);
int ha_init(void);
int ha_panic(enum ha_panic_function flag);
void ha_close_connection(THD* thd);
enum db_type ha_checktype(enum db_type database_type); enum db_type ha_checktype(enum db_type database_type);
/* basic stuff */
int ha_init(void);
TYPELIB *ha_known_exts(void);
int ha_panic(enum ha_panic_function flag);
int ha_update_statistics();
void ha_close_connection(THD* thd);
bool ha_flush_logs(void);
void ha_drop_database(char* path);
int ha_create_table(const char *name, HA_CREATE_INFO *create_info, int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
bool update_create_info); bool update_create_info);
int ha_delete_table(enum db_type db_type, const char *path);
/* discovery */
int ha_create_table_from_engine(THD* thd, const char *db, const char *name, int ha_create_table_from_engine(THD* thd, const char *db, const char *name,
bool create_if_found); bool create_if_found);
int ha_delete_table(enum db_type db_type, const char *path); int ha_discover(THD* thd, const char* dbname, const char* name,
void ha_drop_database(char* path); const void** frmblob, uint* frmlen);
int ha_find_files(THD *thd,const char *db,const char *path,
const char *wild, bool dir,List<char>* files);
int ha_table_exists(THD* thd, const char* db, const char* name);
/* key cache */
int ha_init_key_cache(const char *name, KEY_CACHE *key_cache); int ha_init_key_cache(const char *name, KEY_CACHE *key_cache);
int ha_resize_key_cache(KEY_CACHE *key_cache); int ha_resize_key_cache(KEY_CACHE *key_cache);
int ha_change_key_cache_param(KEY_CACHE *key_cache); int ha_change_key_cache_param(KEY_CACHE *key_cache);
int ha_change_key_cache(KEY_CACHE *old_key_cache, KEY_CACHE *new_key_cache);
int ha_end_key_cache(KEY_CACHE *key_cache); int ha_end_key_cache(KEY_CACHE *key_cache);
int ha_start_stmt(THD *thd);
int ha_report_binlog_offset_and_commit(THD *thd, char *log_file_name, /* weird stuff */
my_off_t end_offset);
int ha_commit_complete(THD *thd);
int ha_release_temporary_latches(THD *thd); int ha_release_temporary_latches(THD *thd);
int ha_update_statistics();
int ha_commit_trans(THD *thd, THD_TRANS *trans); /* transactions: interface to handlerton functions */
int ha_rollback_trans(THD *thd, THD_TRANS *trans);
int ha_rollback_to_savepoint(THD *thd, char *savepoint_name);
int ha_savepoint(THD *thd, char *savepoint_name);
int ha_release_savepoint_name(THD *thd, char *savepoint_name);
int ha_autocommit_or_rollback(THD *thd, int error);
void ha_set_spin_retries(uint retries);
bool ha_flush_logs(void);
int ha_enable_transaction(THD *thd, bool on);
int ha_change_key_cache(KEY_CACHE *old_key_cache,
KEY_CACHE *new_key_cache);
int ha_discover(THD* thd, const char* dbname, const char* name,
const void** frmblob, uint* frmlen);
int ha_find_files(THD *thd,const char *db,const char *path,
const char *wild, bool dir,List<char>* files);
int ha_table_exists(THD* thd, const char* db, const char* name);
TYPELIB *ha_known_exts(void);
int ha_start_consistent_snapshot(THD *thd); int ha_start_consistent_snapshot(THD *thd);
int ha_commit_or_rollback_by_xid(LEX_STRING *ident, bool commit);
int ha_commit_one_phase(THD *thd, bool all);
int ha_rollback_trans(THD *thd, bool all);
int ha_prepare(THD *thd);
int ha_recover(HASH *commit_list);
/* transactions: these functions never call handlerton functions directly */
int ha_commit_trans(THD *thd, bool all);
int ha_autocommit_or_rollback(THD *thd, int error);
int ha_enable_transaction(THD *thd, bool on);
void trans_register_ha(THD *thd, bool all, handlerton *ht);
/* savepoints */
int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv);
int ha_savepoint(THD *thd, SAVEPOINT *sv);
int ha_release_savepoint(THD *thd, SAVEPOINT *sv);

View file

@ -2823,7 +2823,7 @@ void item_user_lock_release(User_level_lock *ull)
tmp.copy(command, strlen(command), tmp.charset()); tmp.copy(command, strlen(command), tmp.charset());
tmp.append(ull->key,ull->key_length); tmp.append(ull->key,ull->key_length);
tmp.append("\")", 2); tmp.append("\")", 2);
Query_log_event qev(current_thd, tmp.ptr(), tmp.length(),1, FALSE); Query_log_event qev(current_thd, tmp.ptr(), tmp.length(), 0, FALSE);
qev.error_code=0; // this query is always safe to run on slave qev.error_code=0; // this query is always safe to run on slave
mysql_bin_log.write(&qev); mysql_bin_log.write(&qev);
} }

View file

@ -19,11 +19,11 @@
#include "lex_symbol.h" #include "lex_symbol.h"
/* We don't want to include sql_yacc.h into gen_lex_hash */
SYM_GROUP sym_group_common= {"", ""}; SYM_GROUP sym_group_common= {"", ""};
SYM_GROUP sym_group_geom= {"Spatial extentions", "HAVE_SPATIAL"}; SYM_GROUP sym_group_geom= {"Spatial extentions", "HAVE_SPATIAL"};
SYM_GROUP sym_group_rtree= {"RTree keys", "HAVE_RTREE_KEYS"}; SYM_GROUP sym_group_rtree= {"RTree keys", "HAVE_RTREE_KEYS"};
/* We don't want to include sql_yacc.h into gen_lex_hash */
#ifdef NO_YACC_SYMBOLS #ifdef NO_YACC_SYMBOLS
#define SYM_OR_NULL(A) 0 #define SYM_OR_NULL(A) 0
#else #else
@ -314,6 +314,7 @@ static SYMBOL symbols[] = {
{ "MERGE", SYM(MERGE_SYM)}, { "MERGE", SYM(MERGE_SYM)},
{ "MICROSECOND", SYM(MICROSECOND_SYM)}, { "MICROSECOND", SYM(MICROSECOND_SYM)},
{ "MIDDLEINT", SYM(MEDIUMINT)}, /* For powerbuilder */ { "MIDDLEINT", SYM(MEDIUMINT)}, /* For powerbuilder */
{ "MIGRATE", SYM(MIGRATE_SYM)},
{ "MINUTE", SYM(MINUTE_SYM)}, { "MINUTE", SYM(MINUTE_SYM)},
{ "MINUTE_MICROSECOND", SYM(MINUTE_MICROSECOND_SYM)}, { "MINUTE_MICROSECOND", SYM(MINUTE_MICROSECOND_SYM)},
{ "MINUTE_SECOND", SYM(MINUTE_SECOND_SYM)}, { "MINUTE_SECOND", SYM(MINUTE_SECOND_SYM)},
@ -346,6 +347,7 @@ static SYMBOL symbols[] = {
{ "OFFSET", SYM(OFFSET_SYM)}, { "OFFSET", SYM(OFFSET_SYM)},
{ "OLD_PASSWORD", SYM(OLD_PASSWORD)}, { "OLD_PASSWORD", SYM(OLD_PASSWORD)},
{ "ON", SYM(ON)}, { "ON", SYM(ON)},
{ "ONE", SYM(ONE_SYM)},
{ "ONE_SHOT", SYM(ONE_SHOT_SYM)}, { "ONE_SHOT", SYM(ONE_SHOT_SYM)},
{ "OPEN", SYM(OPEN_SYM)}, { "OPEN", SYM(OPEN_SYM)},
{ "OPTIMIZE", SYM(OPTIMIZE)}, { "OPTIMIZE", SYM(OPTIMIZE)},
@ -359,6 +361,7 @@ static SYMBOL symbols[] = {
{ "PACK_KEYS", SYM(PACK_KEYS_SYM)}, { "PACK_KEYS", SYM(PACK_KEYS_SYM)},
{ "PARTIAL", SYM(PARTIAL)}, { "PARTIAL", SYM(PARTIAL)},
{ "PASSWORD", SYM(PASSWORD)}, { "PASSWORD", SYM(PASSWORD)},
{ "PHASE", SYM(PHASE_SYM)},
{ "POINT", SYM(POINT_SYM)}, { "POINT", SYM(POINT_SYM)},
{ "POLYGON", SYM(POLYGON)}, { "POLYGON", SYM(POLYGON)},
{ "PRECISION", SYM(PRECISION)}, { "PRECISION", SYM(PRECISION)},
@ -380,6 +383,7 @@ static SYMBOL symbols[] = {
{ "READ", SYM(READ_SYM)}, { "READ", SYM(READ_SYM)},
{ "READS", SYM(READS_SYM)}, { "READS", SYM(READS_SYM)},
{ "REAL", SYM(REAL)}, { "REAL", SYM(REAL)},
{ "RECOVER", SYM(RECOVER_SYM)},
{ "REDUNDANT", SYM(REDUNDANT_SYM)}, { "REDUNDANT", SYM(REDUNDANT_SYM)},
{ "REFERENCES", SYM(REFERENCES)}, { "REFERENCES", SYM(REFERENCES)},
{ "REGEXP", SYM(REGEXP)}, { "REGEXP", SYM(REGEXP)},
@ -398,6 +402,7 @@ static SYMBOL symbols[] = {
{ "RESET", SYM(RESET_SYM)}, { "RESET", SYM(RESET_SYM)},
{ "RESTORE", SYM(RESTORE_SYM)}, { "RESTORE", SYM(RESTORE_SYM)},
{ "RESTRICT", SYM(RESTRICT)}, { "RESTRICT", SYM(RESTRICT)},
{ "RESUME", SYM(RESUME_SYM)},
{ "RETURN", SYM(RETURN_SYM)}, { "RETURN", SYM(RETURN_SYM)},
{ "RETURNS", SYM(RETURNS_SYM)}, { "RETURNS", SYM(RETURNS_SYM)},
{ "REVOKE", SYM(REVOKE)}, { "REVOKE", SYM(REVOKE)},
@ -467,6 +472,7 @@ static SYMBOL symbols[] = {
{ "STRIPED", SYM(RAID_STRIPED_SYM)}, { "STRIPED", SYM(RAID_STRIPED_SYM)},
{ "SUBJECT", SYM(SUBJECT_SYM)}, { "SUBJECT", SYM(SUBJECT_SYM)},
{ "SUPER", SYM(SUPER_SYM)}, { "SUPER", SYM(SUPER_SYM)},
{ "SUSPEND", SYM(SUSPEND_SYM)},
{ "TABLE", SYM(TABLE_SYM)}, { "TABLE", SYM(TABLE_SYM)},
{ "TABLES", SYM(TABLES)}, { "TABLES", SYM(TABLES)},
{ "TABLESPACE", SYM(TABLESPACE)}, { "TABLESPACE", SYM(TABLESPACE)},
@ -528,6 +534,7 @@ static SYMBOL symbols[] = {
{ "WRITE", SYM(WRITE_SYM)}, { "WRITE", SYM(WRITE_SYM)},
{ "X509", SYM(X509_SYM)}, { "X509", SYM(X509_SYM)},
{ "XOR", SYM(XOR)}, { "XOR", SYM(XOR)},
{ "XA", SYM(XA_SYM)},
{ "YEAR", SYM(YEAR_SYM)}, { "YEAR", SYM(YEAR_SYM)},
{ "YEAR_MONTH", SYM(YEAR_MONTH_SYM)}, { "YEAR_MONTH", SYM(YEAR_MONTH_SYM)},
{ "ZEROFILL", SYM(ZEROFILL)}, { "ZEROFILL", SYM(ZEROFILL)},

1428
sql/log.cc

File diff suppressed because it is too large Load diff

View file

@ -269,9 +269,10 @@ const char* Log_event::get_type_str()
case DELETE_FILE_EVENT: return "Delete_file"; case DELETE_FILE_EVENT: return "Delete_file";
case EXEC_LOAD_EVENT: return "Exec_load"; case EXEC_LOAD_EVENT: return "Exec_load";
case RAND_EVENT: return "RAND"; case RAND_EVENT: return "RAND";
case XID_EVENT: return "Xid";
case USER_VAR_EVENT: return "User var"; case USER_VAR_EVENT: return "User var";
case FORMAT_DESCRIPTION_EVENT: return "Format_desc"; case FORMAT_DESCRIPTION_EVENT: return "Format_desc";
default: return "Unknown"; /* impossible */ default: return "Unknown"; /* impossible */
} }
} }
@ -286,16 +287,15 @@ Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans)
{ {
server_id= thd->server_id; server_id= thd->server_id;
when= thd->start_time; when= thd->start_time;
cache_stmt= (using_trans && cache_stmt= using_trans;
(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)));
} }
/* /*
This minimal constructor is for when you are not even sure that there is a This minimal constructor is for when you are not even sure that there
valid THD. For example in the server when we are shutting down or flushing is a valid THD. For example in the server when we are shutting down or
logs after receiving a SIGHUP (then we must write a Rotate to the binlog but flushing logs after receiving a SIGHUP (then we must write a Rotate to
we have no THD, so we need this minimal constructor). the binlog but we have no THD, so we need this minimal constructor).
*/ */
Log_event::Log_event() Log_event::Log_event()
@ -314,12 +314,12 @@ Log_event::Log_event()
*/ */
Log_event::Log_event(const char* buf, Log_event::Log_event(const char* buf,
const Format_description_log_event* description_event) const Format_description_log_event* description_event)
:temp_buf(0), cache_stmt(0) :temp_buf(0), cache_stmt(0)
{ {
#ifndef MYSQL_CLIENT #ifndef MYSQL_CLIENT
thd = 0; thd = 0;
#endif #endif
when = uint4korr(buf); when = uint4korr(buf);
server_id = uint4korr(buf + SERVER_ID_OFFSET); server_id = uint4korr(buf + SERVER_ID_OFFSET);
if (description_event->binlog_version==1) if (description_event->binlog_version==1)
@ -331,14 +331,14 @@ Log_event::Log_event(const char* buf,
/* 4.0 or newer */ /* 4.0 or newer */
log_pos= uint4korr(buf + LOG_POS_OFFSET); log_pos= uint4korr(buf + LOG_POS_OFFSET);
/* /*
If the log is 4.0 (so here it can only be a 4.0 relay log read by the SQL If the log is 4.0 (so here it can only be a 4.0 relay log read by
thread or a 4.0 master binlog read by the I/O thread), log_pos is the the SQL thread or a 4.0 master binlog read by the I/O thread),
beginning of the event: we transform it into the end of the event, which is log_pos is the beginning of the event: we transform it into the end
more useful. of the event, which is more useful.
But how do you know that the log is 4.0: you know it if description_event But how do you know that the log is 4.0: you know it if
is version 3 *and* you are not reading a Format_desc (remember that description_event is version 3 *and* you are not reading a
mysqlbinlog starts by assuming that 5.0 logs are in 4.0 format, until it Format_desc (remember that mysqlbinlog starts by assuming that 5.0
finds a Format_desc). logs are in 4.0 format, until it finds a Format_desc).
*/ */
if (description_event->binlog_version==3 && if (description_event->binlog_version==3 &&
buf[EVENT_TYPE_OFFSET]<FORMAT_DESCRIPTION_EVENT && log_pos) buf[EVENT_TYPE_OFFSET]<FORMAT_DESCRIPTION_EVENT && log_pos)
@ -346,13 +346,13 @@ Log_event::Log_event(const char* buf,
/* /*
If log_pos=0, don't change it. log_pos==0 is a marker to mean If log_pos=0, don't change it. log_pos==0 is a marker to mean
"don't change rli->group_master_log_pos" (see "don't change rli->group_master_log_pos" (see
inc_group_relay_log_pos()). As it is unreal log_pos, adding the event inc_group_relay_log_pos()). As it is unreal log_pos, adding the
len's is nonsense. For example, a fake Rotate event should event len's is nonsense. For example, a fake Rotate event should
not have its log_pos (which is 0) changed or it will modify not have its log_pos (which is 0) changed or it will modify
Exec_master_log_pos in SHOW SLAVE STATUS, displaying a nonsense value Exec_master_log_pos in SHOW SLAVE STATUS, displaying a nonsense
of (a non-zero offset which does not exist in the master's binlog, so value of (a non-zero offset which does not exist in the master's
which will cause problems if the user uses this value in binlog, so which will cause problems if the user uses this value
CHANGE MASTER). in CHANGE MASTER).
*/ */
log_pos+= uint4korr(buf + EVENT_LEN_OFFSET); log_pos+= uint4korr(buf + EVENT_LEN_OFFSET);
} }
@ -363,16 +363,17 @@ Log_event::Log_event(const char* buf,
(buf[EVENT_TYPE_OFFSET] == ROTATE_EVENT)) (buf[EVENT_TYPE_OFFSET] == ROTATE_EVENT))
{ {
/* /*
These events always have a header which stops here (i.e. their header is These events always have a header which stops here (i.e. their
FROZEN). header is FROZEN).
*/ */
/* /*
Initialization to zero of all other Log_event members as they're not Initialization to zero of all other Log_event members as they're
specified. Currently there are no such members; in the future there will not specified. Currently there are no such members; in the future
be an event UID (but Format_description and Rotate don't need this UID, there will be an event UID (but Format_description and Rotate
as they are not propagated through --log-slave-updates (remember the UID don't need this UID, as they are not propagated through
is used to not play a query twice when you have two masters which are --log-slave-updates (remember the UID is used to not play a query
slaves of a 3rd master). Then we are done. twice when you have two masters which are slaves of a 3rd master).
Then we are done.
*/ */
return; return;
} }
@ -402,31 +403,32 @@ int Log_event::exec_event(struct st_relay_log_info* rli)
only in the case discussed above, 'if (rli)' is useless here. only in the case discussed above, 'if (rli)' is useless here.
But as we are not 100% sure, keep it for now. But as we are not 100% sure, keep it for now.
*/ */
if (rli) if (rli)
{ {
/* /*
If in a transaction, and if the slave supports transactions, If in a transaction, and if the slave supports transactions, just
just inc_event_relay_log_pos(). We only have to check for OPTION_BEGIN inc_event_relay_log_pos(). We only have to check for OPTION_BEGIN
(not OPTION_NOT_AUTOCOMMIT) as transactions are logged (not OPTION_NOT_AUTOCOMMIT) as transactions are logged with
with BEGIN/COMMIT, not with SET AUTOCOMMIT= . BEGIN/COMMIT, not with SET AUTOCOMMIT= .
CAUTION: opt_using_transactions means CAUTION: opt_using_transactions means
innodb || bdb ; suppose the master supports InnoDB and BDB, innodb || bdb ; suppose the master supports InnoDB and BDB,
but the slave supports only BDB, problems but the slave supports only BDB, problems
will arise: will arise:
- suppose an InnoDB table is created on the master, - suppose an InnoDB table is created on the master,
- then it will be MyISAM on the slave - then it will be MyISAM on the slave
- but as opt_using_transactions is true, the slave will believe he is - but as opt_using_transactions is true, the slave will believe he
transactional with the MyISAM table. And problems will come when one is transactional with the MyISAM table. And problems will come
does START SLAVE; STOP SLAVE; START SLAVE; (the slave will resume at when one does START SLAVE; STOP SLAVE; START SLAVE; (the slave
BEGIN whereas there has not been any rollback). This is the problem of will resume at BEGIN whereas there has not been any rollback).
using opt_using_transactions instead of a finer This is the problem of using opt_using_transactions instead of a
"does the slave support _the_transactional_handler_used_on_the_master_". finer "does the slave support
_the_transactional_handler_used_on_the_master_".
More generally, we'll have problems when a query mixes a transactional
handler and MyISAM and STOP SLAVE is issued in the middle of the More generally, we'll have problems when a query mixes a
"transaction". START SLAVE will resume at BEGIN while the MyISAM table transactional handler and MyISAM and STOP SLAVE is issued in the
has already been updated. middle of the "transaction". START SLAVE will resume at BEGIN
while the MyISAM table has already been updated.
*/ */
if ((thd->options & OPTION_BEGIN) && opt_using_transactions) if ((thd->options & OPTION_BEGIN) && opt_using_transactions)
rli->inc_event_relay_log_pos(); rli->inc_event_relay_log_pos();
@ -435,8 +437,8 @@ int Log_event::exec_event(struct st_relay_log_info* rli)
rli->inc_group_relay_log_pos(log_pos); rli->inc_group_relay_log_pos(log_pos);
flush_relay_log_info(rli); flush_relay_log_info(rli);
/* /*
Note that Rotate_log_event::exec_event() does not call this function, Note that Rotate_log_event::exec_event() does not call this
so there is no chance that a fake rotate event resets function, so there is no chance that a fake rotate event resets
last_master_timestamp. last_master_timestamp.
Note that we update without mutex (probably ok - except in some very Note that we update without mutex (probably ok - except in some very
rare cases, only consequence is that value may take some time to rare cases, only consequence is that value may take some time to
@ -649,11 +651,9 @@ end:
#ifndef MYSQL_CLIENT #ifndef MYSQL_CLIENT
#define UNLOCK_MUTEX if (log_lock) pthread_mutex_unlock(log_lock); #define UNLOCK_MUTEX if (log_lock) pthread_mutex_unlock(log_lock);
#define LOCK_MUTEX if (log_lock) pthread_mutex_lock(log_lock); #define LOCK_MUTEX if (log_lock) pthread_mutex_lock(log_lock);
#define max_allowed_packet current_thd->variables.max_allowed_packet
#else #else
#define UNLOCK_MUTEX #define UNLOCK_MUTEX
#define LOCK_MUTEX #define LOCK_MUTEX
#define max_allowed_packet (*mysql_get_parameters()->p_max_allowed_packet)
#endif #endif
/* /*
@ -670,16 +670,17 @@ Log_event* Log_event::read_log_event(IO_CACHE* file,
#else #else
Log_event* Log_event::read_log_event(IO_CACHE* file, Log_event* Log_event::read_log_event(IO_CACHE* file,
const Format_description_log_event *description_event) const Format_description_log_event *description_event)
#endif #endif
{ {
DBUG_ENTER("Log_event::read_log_event(IO_CACHE *, Format_description_log_event *");
DBUG_ASSERT(description_event); DBUG_ASSERT(description_event);
char head[LOG_EVENT_MINIMAL_HEADER_LEN]; char head[LOG_EVENT_MINIMAL_HEADER_LEN];
/* /*
First we only want to read at most LOG_EVENT_MINIMAL_HEADER_LEN, just to First we only want to read at most LOG_EVENT_MINIMAL_HEADER_LEN, just to
check the event for sanity and to know its length; no need to really parse check the event for sanity and to know its length; no need to really parse
it. We say "at most" because this could be a 3.23 master, which has header it. We say "at most" because this could be a 3.23 master, which has header
of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's "minimal" of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's
over the set {MySQL >=4.0}). "minimal" over the set {MySQL >=4.0}).
*/ */
uint header_size= min(description_event->common_header_len, uint header_size= min(description_event->common_header_len,
LOG_EVENT_MINIMAL_HEADER_LEN); LOG_EVENT_MINIMAL_HEADER_LEN);
@ -692,17 +693,21 @@ Log_event* Log_event::read_log_event(IO_CACHE* file,
failed my_b_read")); failed my_b_read"));
UNLOCK_MUTEX; UNLOCK_MUTEX;
/* /*
No error here; it could be that we are at the file's end. However if the No error here; it could be that we are at the file's end. However
next my_b_read() fails (below), it will be an error as we were able to if the next my_b_read() fails (below), it will be an error as we
read the first bytes. were able to read the first bytes.
*/ */
return 0; DBUG_RETURN(0);
} }
uint data_len = uint4korr(head + EVENT_LEN_OFFSET); uint data_len = uint4korr(head + EVENT_LEN_OFFSET);
char *buf= 0; char *buf= 0;
const char *error= 0; const char *error= 0;
Log_event *res= 0; Log_event *res= 0;
#ifndef max_allowed_packet
THD *thd=current_thd;
uint max_allowed_packet= thd ? thd->variables.max_allowed_packet : ~0;
#endif
if (data_len > max_allowed_packet) if (data_len > max_allowed_packet)
{ {
@ -729,16 +734,16 @@ failed my_b_read"));
error = "read error"; error = "read error";
goto err; goto err;
} }
if ((res= read_log_event(buf, data_len, &error, if ((res= read_log_event(buf, data_len, &error, description_event)))
description_event)))
res->register_temp_buf(buf); res->register_temp_buf(buf);
err: err:
UNLOCK_MUTEX; UNLOCK_MUTEX;
if (error) if (!res)
{ {
sql_print_error("\ DBUG_ASSERT(error);
Error in Log_event::read_log_event(): '%s', data_len: %d, event_type: %d", sql_print_error("Error in Log_event::read_log_event(): "
"'%s', data_len: %d, event_type: %d",
error,data_len,head[EVENT_TYPE_OFFSET]); error,data_len,head[EVENT_TYPE_OFFSET]);
my_free(buf, MYF(MY_ALLOW_ZERO_PTR)); my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
/* /*
@ -751,7 +756,7 @@ Error in Log_event::read_log_event(): '%s', data_len: %d, event_type: %d",
*/ */
file->error= -1; file->error= -1;
} }
return res; DBUG_RETURN(res);
} }
@ -775,7 +780,7 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
*error="Sanity check failed"; // Needed to free buffer *error="Sanity check failed"; // Needed to free buffer
DBUG_RETURN(NULL); // general sanity check - will fail on a partial read DBUG_RETURN(NULL); // general sanity check - will fail on a partial read
} }
switch(buf[EVENT_TYPE_OFFSET]) { switch(buf[EVENT_TYPE_OFFSET]) {
case QUERY_EVENT: case QUERY_EVENT:
ev = new Query_log_event(buf, event_len, description_event); ev = new Query_log_event(buf, event_len, description_event);
@ -809,14 +814,15 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
case START_EVENT_V3: /* this is sent only by MySQL <=4.x */ case START_EVENT_V3: /* this is sent only by MySQL <=4.x */
ev = new Start_log_event_v3(buf, description_event); ev = new Start_log_event_v3(buf, description_event);
break; break;
#ifdef HAVE_REPLICATION
case STOP_EVENT: case STOP_EVENT:
ev = new Stop_log_event(buf, description_event); ev = new Stop_log_event(buf, description_event);
break; break;
#endif /* HAVE_REPLICATION */
case INTVAR_EVENT: case INTVAR_EVENT:
ev = new Intvar_log_event(buf, description_event); ev = new Intvar_log_event(buf, description_event);
break; break;
case XID_EVENT:
ev = new Xid_log_event(buf, description_event);
break;
case RAND_EVENT: case RAND_EVENT:
ev = new Rand_log_event(buf, description_event); ev = new Rand_log_event(buf, description_event);
break; break;
@ -831,14 +837,15 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
ev= NULL; ev= NULL;
break; break;
} }
/* /*
is_valid() are small event-specific sanity tests which are important; for is_valid() are small event-specific sanity tests which are
example there are some my_malloc() in constructors important; for example there are some my_malloc() in constructors
(e.g. Query_log_event::Query_log_event(char*...)); when these my_malloc() (e.g. Query_log_event::Query_log_event(char*...)); when these
fail we can't return an error out of the constructor (because constructor my_malloc() fail we can't return an error out of the constructor
is "void") ; so instead we leave the pointer we wanted to allocate (because constructor is "void") ; so instead we leave the pointer we
(e.g. 'query') to 0 and we test it in is_valid(). Same for wanted to allocate (e.g. 'query') to 0 and we test it in is_valid().
Format_description_log_event, member 'post_header_len'. Same for Format_description_log_event, member 'post_header_len'.
*/ */
if (!ev || !ev->is_valid()) if (!ev || !ev->is_valid())
{ {
@ -923,8 +930,8 @@ void Query_log_event::pack_info(Protocol *protocol)
char *buf, *pos; char *buf, *pos;
if (!(buf= my_malloc(9 + db_len + q_len, MYF(MY_WME)))) if (!(buf= my_malloc(9 + db_len + q_len, MYF(MY_WME))))
return; return;
pos= buf; pos= buf;
if (!(flags & LOG_EVENT_SUPPRESS_USE_F) if (!(flags & LOG_EVENT_SUPPRESS_USE_F)
&& db && db_len) && db && db_len)
{ {
pos= strmov(buf, "use `"); pos= strmov(buf, "use `");
@ -1082,8 +1089,8 @@ bool Query_log_event::write(IO_CACHE* file)
return (write_header(file, event_length) || return (write_header(file, event_length) ||
my_b_safe_write(file, (byte*) buf, (uint) (start-buf)) || my_b_safe_write(file, (byte*) buf, (uint) (start-buf)) ||
my_b_safe_write(file, (db) ? (byte*) db : (byte*)"", db_len + 1) || my_b_safe_write(file, (db) ? (byte*) db : (byte*)"", db_len + 1) ||
my_b_safe_write(file, (byte*) query, q_len)) ? 1 : 0; my_b_safe_write(file, (byte*) query, q_len)) ? 1 : 0;
} }
@ -1095,7 +1102,7 @@ bool Query_log_event::write(IO_CACHE* file)
Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
ulong query_length, bool using_trans, ulong query_length, bool using_trans,
bool suppress_use) bool suppress_use)
:Log_event(thd_arg, :Log_event(thd_arg,
((thd_arg->tmp_table_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0) ((thd_arg->tmp_table_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0)
| (suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0)), | (suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0)),
using_trans), using_trans),
@ -1303,18 +1310,12 @@ void Query_log_event::print(FILE* file, bool short_form,
my_fwrite(file, (byte*) buff, (uint) (end-buff),MYF(MY_NABP | MY_WME)); my_fwrite(file, (byte*) buff, (uint) (end-buff),MYF(MY_NABP | MY_WME));
if (flags & LOG_EVENT_THREAD_SPECIFIC_F) if (flags & LOG_EVENT_THREAD_SPECIFIC_F)
fprintf(file,"SET @@session.pseudo_thread_id=%lu;\n",(ulong)thread_id); fprintf(file,"SET @@session.pseudo_thread_id=%lu;\n",(ulong)thread_id);
/*
Now the session variables;
it's more efficient to pass SQL_MODE as a number instead of a
comma-separated list.
FOREIGN_KEY_CHECKS, SQL_AUTO_IS_NULL, UNIQUE_CHECKS are session-only
variables (they have no global version; they're not listed in sql_class.h),
The tests below work for pure binlogs or pure relay logs. Won't work for
mixed relay logs but we don't create mixed relay logs (that is, there is no
relay log with a format change except within the 3 first events, which
mysqlbinlog handles gracefully). So this code should always be good.
*/
/*
If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to
print (remember we don't produce mixed relay logs so there cannot be
5.0 events before that one so there is nothing to reset).
*/
if (likely(flags2_inited)) /* likely as this will mainly read 5.0 logs */ if (likely(flags2_inited)) /* likely as this will mainly read 5.0 logs */
{ {
/* tmp is a bitmask of bits which have changed. */ /* tmp is a bitmask of bits which have changed. */
@ -1343,9 +1344,16 @@ void Query_log_event::print(FILE* file, bool short_form,
} }
/* /*
If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to print Now the session variables;
(remember we don't produce mixed relay logs so there cannot be 5.0 events it's more efficient to pass SQL_MODE as a number instead of a
before that one so there is nothing to reset). comma-separated list.
FOREIGN_KEY_CHECKS, SQL_AUTO_IS_NULL, UNIQUE_CHECKS are session-only
variables (they have no global version; they're not listed in
sql_class.h), The tests below work for pure binlogs or pure relay
logs. Won't work for mixed relay logs but we don't create mixed
relay logs (that is, there is no relay log with a format change
except within the 3 first events, which mysqlbinlog handles
gracefully). So this code should always be good.
*/ */
if (likely(sql_mode_inited)) if (likely(sql_mode_inited))
@ -1439,7 +1447,7 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli)
thd->query_length= q_len; thd->query_length= q_len;
thd->query = (char*)query; thd->query = (char*)query;
VOID(pthread_mutex_lock(&LOCK_thread_count)); VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_id = query_id++; thd->query_id = next_query_id();
VOID(pthread_mutex_unlock(&LOCK_thread_count)); VOID(pthread_mutex_unlock(&LOCK_thread_count));
thd->variables.pseudo_thread_id= thread_id; // for temp tables thd->variables.pseudo_thread_id= thread_id; // for temp tables
mysql_log.write(thd,COM_QUERY,"%s",thd->query); mysql_log.write(thd,COM_QUERY,"%s",thd->query);
@ -1587,7 +1595,7 @@ Default database: '%s'. Query: '%s'",
We may also want an option to tell the slave to ignore "affected" We may also want an option to tell the slave to ignore "affected"
mismatch. This mismatch could be implemented with a new ER_ code, and mismatch. This mismatch could be implemented with a new ER_ code, and
to ignore it you would use --slave-skip-errors... to ignore it you would use --slave-skip-errors...
To do the comparison we need to know the value of "affected" which the To do the comparison we need to know the value of "affected" which the
above mysql_parse() computed. And we need to know the value of above mysql_parse() computed. And we need to know the value of
"affected" in the master's binlog. Both will be implemented later. The "affected" in the master's binlog. Both will be implemented later. The
@ -1674,14 +1682,20 @@ void Start_log_event_v3::print(FILE* file, bool short_form, LAST_EVENT_INFO* las
fprintf(file," at startup"); fprintf(file," at startup");
fputc('\n', file); fputc('\n', file);
} }
if (!artificial_event && created)
{
#ifdef WHEN_WE_HAVE_THE_RESET_CONNECTION_SQL_COMMAND #ifdef WHEN_WE_HAVE_THE_RESET_CONNECTION_SQL_COMMAND
/* /*
This is for mysqlbinlog: like in replication, we want to delete the stale This is for mysqlbinlog: like in replication, we want to delete the stale
tmp files left by an unclean shutdown of mysqld (temporary tables). Probably tmp files left by an unclean shutdown of mysqld (temporary tables)
this can be done with RESET CONNECTION (syntax to be defined). and rollback unfinished transaction.
*/ Probably this can be done with RESET CONNECTION (syntax to be defined).
fprintf(file,"RESET CONNECTION;\n"); */
fprintf(file,"RESET CONNECTION;\n");
#else
fprintf(file,"ROLLBACK;\n");
#endif #endif
}
fflush(file); fflush(file);
} }
#endif /* MYSQL_CLIENT */ #endif /* MYSQL_CLIENT */
@ -1757,34 +1771,14 @@ int Start_log_event_v3::exec_event(struct st_relay_log_info* rli)
close_temporary_tables(thd); close_temporary_tables(thd);
cleanup_load_tmpdir(); cleanup_load_tmpdir();
} }
/*
As a transaction NEVER spans on 2 or more binlogs:
if we have an active transaction at this point, the master died while
writing the transaction to the binary log, i.e. while flushing the binlog
cache to the binlog. As the write was started, the transaction had been
committed on the master, so we lack of information to replay this
transaction on the slave; all we can do is stop with error.
Note: this event could be sent by the master to inform us of the format
of its binlog; in other words maybe it is not at its original place when
it comes to us; we'll know this by checking log_pos ("artificial" events
have log_pos == 0).
*/
if (!artificial_event && (thd->options & OPTION_BEGIN))
{
slave_print_error(rli, 0, "\
Rolling back unfinished transaction (no COMMIT or ROLLBACK) from relay log. \
A probable cause is that the master died while writing the transaction to its \
binary log.");
return(1);
}
break; break;
/* /*
Now the older formats; in that case load_tmpdir is cleaned up by the I/O Now the older formats; in that case load_tmpdir is cleaned up by the I/O
thread. thread.
*/ */
case 1: case 1:
if (strncmp(rli->relay_log.description_event_for_exec->server_version, if (strncmp(rli->relay_log.description_event_for_exec->server_version,
"3.23.57",7) >= 0 && created) "3.23.57",7) >= 0 && created)
{ {
/* /*
@ -1816,7 +1810,7 @@ binary log.");
SYNOPSIS SYNOPSIS
Format_description_log_event::Format_description_log_event Format_description_log_event::Format_description_log_event
binlog_version the binlog version for which we want to build binlog_version the binlog version for which we want to build
an event. Can be 1 (=MySQL 3.23), 3 (=4.0.x an event. Can be 1 (=MySQL 3.23), 3 (=4.0.x
x>=2 and 4.1) or 4 (MySQL 5.0). Note that the x>=2 and 4.1) or 4 (MySQL 5.0). Note that the
old 4.0 (binlog version 2) is not supported; old 4.0 (binlog version 2) is not supported;
@ -1836,8 +1830,7 @@ binary log.");
*/ */
Format_description_log_event:: Format_description_log_event::
Format_description_log_event(uint8 binlog_ver, Format_description_log_event(uint8 binlog_ver, const char* server_ver)
const char* server_ver)
:Start_log_event_v3() :Start_log_event_v3()
{ {
created= when; created= when;
@ -1849,7 +1842,7 @@ Format_description_log_event(uint8 binlog_ver,
number_of_event_types= LOG_EVENT_TYPES; number_of_event_types= LOG_EVENT_TYPES;
/* we'll catch my_malloc() error in is_valid() */ /* we'll catch my_malloc() error in is_valid() */
post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8), post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8),
MYF(0)); MYF(MY_ZEROFILL));
/* /*
This long list of assignments is not beautiful, but I see no way to This long list of assignments is not beautiful, but I see no way to
make it nicer, as the right members are #defines, not array members, so make it nicer, as the right members are #defines, not array members, so
@ -1859,18 +1852,13 @@ Format_description_log_event(uint8 binlog_ver,
{ {
post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN; post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN;
post_header_len[QUERY_EVENT-1]= QUERY_HEADER_LEN; post_header_len[QUERY_EVENT-1]= QUERY_HEADER_LEN;
post_header_len[STOP_EVENT-1]= 0;
post_header_len[ROTATE_EVENT-1]= ROTATE_HEADER_LEN; post_header_len[ROTATE_EVENT-1]= ROTATE_HEADER_LEN;
post_header_len[INTVAR_EVENT-1]= 0;
post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN; post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN;
post_header_len[SLAVE_EVENT-1]= 0;
post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN; post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN;
post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN; post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN;
post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN; post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN;
post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN; post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN;
post_header_len[NEW_LOAD_EVENT-1]= post_header_len[LOAD_EVENT-1]; post_header_len[NEW_LOAD_EVENT-1]= post_header_len[LOAD_EVENT-1];
post_header_len[RAND_EVENT-1]= 0;
post_header_len[USER_VAR_EVENT-1]= 0;
post_header_len[FORMAT_DESCRIPTION_EVENT-1]= FORMAT_DESCRIPTION_HEADER_LEN; post_header_len[FORMAT_DESCRIPTION_EVENT-1]= FORMAT_DESCRIPTION_HEADER_LEN;
} }
break; break;
@ -1886,7 +1874,7 @@ Format_description_log_event(uint8 binlog_ver,
else else
strmov(server_version, server_ver ? server_ver : "4.0"); strmov(server_version, server_ver ? server_ver : "4.0");
common_header_len= binlog_ver==1 ? OLD_HEADER_LEN : common_header_len= binlog_ver==1 ? OLD_HEADER_LEN :
LOG_EVENT_MINIMAL_HEADER_LEN; LOG_EVENT_MINIMAL_HEADER_LEN;
/* /*
The first new event in binlog version 4 is Format_desc. So any event type The first new event in binlog version 4 is Format_desc. So any event type
after that does not exist in older versions. We use the events known by after that does not exist in older versions. We use the events known by
@ -1896,7 +1884,7 @@ Format_description_log_event(uint8 binlog_ver,
*/ */
number_of_event_types= FORMAT_DESCRIPTION_EVENT - 1; number_of_event_types= FORMAT_DESCRIPTION_EVENT - 1;
post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8), post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8),
MYF(0)); MYF(0));
if (post_header_len) if (post_header_len)
{ {
post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN; post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN;
@ -1927,7 +1915,7 @@ Format_description_log_event(uint8 binlog_ver,
length different from this version, but we don't know this length as we length different from this version, but we don't know this length as we
have not read the Format_description_log_event which says it, yet. This have not read the Format_description_log_event which says it, yet. This
length is in the post-header of the event, but we don't know where the length is in the post-header of the event, but we don't know where the
post-header starts. post-header starts.
So this type of event HAS to: So this type of event HAS to:
- either have the header's length at the beginning (in the header, at a - either have the header's length at the beginning (in the header, at a
fixed position which will never be changed), not in the post-header. That fixed position which will never be changed), not in the post-header. That
@ -1943,7 +1931,7 @@ Format_description_log_event(const char* buf,
uint event_len, uint event_len,
const const
Format_description_log_event* Format_description_log_event*
description_event) description_event)
:Start_log_event_v3(buf, description_event) :Start_log_event_v3(buf, description_event)
{ {
DBUG_ENTER("Format_description_log_event::Format_description_log_event(char*,...)"); DBUG_ENTER("Format_description_log_event::Format_description_log_event(char*,...)");
@ -1953,12 +1941,11 @@ Format_description_log_event(const char* buf,
number_of_event_types= number_of_event_types=
event_len-(LOG_EVENT_MINIMAL_HEADER_LEN+ST_COMMON_HEADER_LEN_OFFSET+1); event_len-(LOG_EVENT_MINIMAL_HEADER_LEN+ST_COMMON_HEADER_LEN_OFFSET+1);
DBUG_PRINT("info", ("common_header_len=%d number_of_event_types=%d", DBUG_PRINT("info", ("common_header_len=%d number_of_event_types=%d",
common_header_len, number_of_event_types)); common_header_len, number_of_event_types));
/* If alloc fails, we'll detect it in is_valid() */ /* If alloc fails, we'll detect it in is_valid() */
post_header_len= (uint8*) my_memdup((byte*)buf+ST_COMMON_HEADER_LEN_OFFSET+1, post_header_len= (uint8*) my_memdup((byte*)buf+ST_COMMON_HEADER_LEN_OFFSET+1,
number_of_event_types* number_of_event_types*
sizeof(*post_header_len), sizeof(*post_header_len), MYF(0));
MYF(0));
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -1973,17 +1960,17 @@ bool Format_description_log_event::write(IO_CACHE* file)
int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version); int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
memcpy((char*) buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN); memcpy((char*) buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
int4store(buff + ST_CREATED_OFFSET,created); int4store(buff + ST_CREATED_OFFSET,created);
buff[ST_COMMON_HEADER_LEN_OFFSET]= LOG_EVENT_HEADER_LEN; buff[ST_COMMON_HEADER_LEN_OFFSET]= LOG_EVENT_HEADER_LEN;
memcpy((char*) buff+ST_COMMON_HEADER_LEN_OFFSET+1, (byte*) post_header_len, memcpy((char*) buff+ST_COMMON_HEADER_LEN_OFFSET+1, (byte*) post_header_len,
LOG_EVENT_TYPES); LOG_EVENT_TYPES);
return (write_header(file, sizeof(buff)) || return (write_header(file, sizeof(buff)) ||
my_b_safe_write(file, buff, sizeof(buff))); my_b_safe_write(file, buff, sizeof(buff)));
} }
/* /*
SYNOPSIS SYNOPSIS
Format_description_log_event::exec_event() Format_description_log_event::exec_event()
IMPLEMENTATION IMPLEMENTATION
Save the information which describes the binlog's format, to be able to Save the information which describes the binlog's format, to be able to
read all coming events. read all coming events.
@ -1994,11 +1981,32 @@ bool Format_description_log_event::write(IO_CACHE* file)
int Format_description_log_event::exec_event(struct st_relay_log_info* rli) int Format_description_log_event::exec_event(struct st_relay_log_info* rli)
{ {
DBUG_ENTER("Format_description_log_event::exec_event"); DBUG_ENTER("Format_description_log_event::exec_event");
/* save the information describing this binlog */ /* save the information describing this binlog */
delete rli->relay_log.description_event_for_exec; delete rli->relay_log.description_event_for_exec;
rli->relay_log.description_event_for_exec= this; rli->relay_log.description_event_for_exec= this;
/*
As a transaction NEVER spans on 2 or more binlogs:
if we have an active transaction at this point, the master died
while writing the transaction to the binary log, i.e. while
flushing the binlog cache to the binlog. As the write was started,
the transaction had been committed on the master, so we lack of
information to replay this transaction on the slave; all we can do
is stop with error.
Note: this event could be sent by the master to inform us of the
format of its binlog; in other words maybe it is not at its
original place when it comes to us; we'll know this by checking
log_pos ("artificial" events have log_pos == 0).
*/
if (!artificial_event && created && thd->transaction.all.nht)
{
slave_print_error(rli, 0, "Rolling back unfinished transaction (no "
"COMMIT or ROLLBACK) from relay log. A probable cause "
"is that the master died while writing the transaction "
"to its binary log.");
end_trans(thd, ROLLBACK);
}
/* /*
If this event comes from ourselves, there is no cleaning task to perform, If this event comes from ourselves, there is no cleaning task to perform,
we don't call Start_log_event_v3::exec_event() (this was just to update the we don't call Start_log_event_v3::exec_event() (this was just to update the
@ -2027,18 +2035,18 @@ int Format_description_log_event::exec_event(struct st_relay_log_info* rli)
If the event was not requested by the slave i.e. the master sent it while If the event was not requested by the slave i.e. the master sent it while
the slave asked for a position >4, the event will make the slave asked for a position >4, the event will make
rli->group_master_log_pos advance. Say that the slave asked for position rli->group_master_log_pos advance. Say that the slave asked for position
1000, and the Format_desc event's end is 95. Then in the beginning of 1000, and the Format_desc event's end is 96. Then in the beginning of
replication rli->group_master_log_pos will be 0, then 95, then jump to first replication rli->group_master_log_pos will be 0, then 96, then jump to
really asked event (which is >95). So this is ok. first really asked event (which is >96). So this is ok.
*/ */
DBUG_RETURN(Start_log_event_v3::exec_event(rli)); DBUG_RETURN(Start_log_event_v3::exec_event(rli));
} }
#endif #endif
/************************************************************************** /**************************************************************************
Load_log_event methods Load_log_event methods
General note about Load_log_event: the binlogging of LOAD DATA INFILE is General note about Load_log_event: the binlogging of LOAD DATA INFILE is
going to be changed in 5.0 (or maybe in 4.1; not decided yet). going to be changed in 5.0 (or maybe in 5.1; not decided yet).
However, the 5.0 slave could still have to read such events (from a 4.x However, the 5.0 slave could still have to read such events (from a 4.x
master), convert them (which just means maybe expand the header, when 5.0 master), convert them (which just means maybe expand the header, when 5.0
servers have a UID in events) (remember that whatever is after the header servers have a UID in events) (remember that whatever is after the header
@ -2062,7 +2070,7 @@ void Load_log_event::pack_info(Protocol *protocol)
char *buf, *pos; char *buf, *pos;
uint buf_len; uint buf_len;
buf_len= buf_len=
5 + db_len + 3 + // "use DB; " 5 + db_len + 3 + // "use DB; "
18 + fname_len + 2 + // "LOAD DATA INFILE 'file''" 18 + fname_len + 2 + // "LOAD DATA INFILE 'file''"
7 + // LOCAL 7 + // LOCAL
@ -2072,8 +2080,8 @@ void Load_log_event::pack_info(Protocol *protocol)
23 + sql_ex.enclosed_len*4 + 2 + // " OPTIONALLY ENCLOSED BY 'str'" 23 + sql_ex.enclosed_len*4 + 2 + // " OPTIONALLY ENCLOSED BY 'str'"
12 + sql_ex.escaped_len*4 + 2 + // " ESCAPED BY 'str'" 12 + sql_ex.escaped_len*4 + 2 + // " ESCAPED BY 'str'"
21 + sql_ex.line_term_len*4 + 2 + // " FIELDS TERMINATED BY 'str'" 21 + sql_ex.line_term_len*4 + 2 + // " FIELDS TERMINATED BY 'str'"
19 + sql_ex.line_start_len*4 + 2 + // " LINES STARTING BY 'str'" 19 + sql_ex.line_start_len*4 + 2 + // " LINES STARTING BY 'str'"
15 + 22 + // " IGNORE xxx LINES" 15 + 22 + // " IGNORE xxx LINES"
3 + (num_fields-1)*2 + field_block_len; // " (field1, field2, ...)" 3 + (num_fields-1)*2 + field_block_len; // " (field1, field2, ...)"
if (!(buf= my_malloc(buf_len, MYF(MY_WME)))) if (!(buf= my_malloc(buf_len, MYF(MY_WME))))
@ -2553,7 +2561,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
{ {
thd->set_time((time_t)when); thd->set_time((time_t)when);
VOID(pthread_mutex_lock(&LOCK_thread_count)); VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_id = query_id++; thd->query_id = next_query_id();
VOID(pthread_mutex_unlock(&LOCK_thread_count)); VOID(pthread_mutex_unlock(&LOCK_thread_count));
/* /*
Initing thd->row_count is not necessary in theory as this variable has no Initing thd->row_count is not necessary in theory as this variable has no
@ -3068,6 +3076,72 @@ int Rand_log_event::exec_event(struct st_relay_log_info* rli)
#endif /* !MYSQL_CLIENT */ #endif /* !MYSQL_CLIENT */
/**************************************************************************
Xid_log_event methods
**************************************************************************/
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
void Xid_log_event::pack_info(Protocol *protocol)
{
char buf[128], *pos;
pos= strmov(buf, "COMMIT /* xid=");
pos= longlong10_to_str(xid, pos, 10);
pos= strmov(pos, " */");
protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
}
#endif
/*
NOTE it's ok not to use int8store here,
as long as xid_t::set(ulonglong) and
xid_t::get_my_xid doesn't do it either
we don't care about actual values of xids as long as
identical numbers compare identically
*/
Xid_log_event::Xid_log_event(const char* buf,
const Format_description_log_event* description_event)
:Log_event(buf, description_event)
{
buf+= description_event->common_header_len;
xid=*((my_xid *)buf);
}
bool Xid_log_event::write(IO_CACHE* file)
{
return write_header(file, sizeof(xid)) ||
my_b_safe_write(file, (byte*) &xid, sizeof(xid));
}
#ifdef MYSQL_CLIENT
void Xid_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info)
{
if (!short_form)
{
char buf[64];
longlong10_to_str(xid, buf, 10);
print_header(file);
fprintf(file, "\tXid = %s\n", buf);
fflush(file);
}
fprintf(file, "COMMIT;\n");
}
#endif /* MYSQL_CLIENT */
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
int Xid_log_event::exec_event(struct st_relay_log_info* rli)
{
rli->inc_event_relay_log_pos();
/* For a slave Xid_log_event is COMMIT */
return end_trans(thd, COMMIT);
}
#endif /* !MYSQL_CLIENT */
/************************************************************************** /**************************************************************************
User_var_log_event methods User_var_log_event methods
**************************************************************************/ **************************************************************************/
@ -3443,7 +3517,7 @@ Slave_log_event::Slave_log_event(THD* thd_arg,
DBUG_ENTER("Slave_log_event"); DBUG_ENTER("Slave_log_event");
if (!rli->inited) // QQ When can this happen ? if (!rli->inited) // QQ When can this happen ?
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
MASTER_INFO* mi = rli->mi; MASTER_INFO* mi = rli->mi;
// TODO: re-write this better without holding both locks at the same time // TODO: re-write this better without holding both locks at the same time
pthread_mutex_lock(&mi->data_lock); pthread_mutex_lock(&mi->data_lock);
@ -3577,7 +3651,7 @@ void Stop_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_ev
/* /*
Stop_log_event::exec_event() Stop_log_event::exec_event()
The master stopped. The master stopped.
We used to clean up all temporary tables but this is useless as, as the We used to clean up all temporary tables but this is useless as, as the
master has shut down properly, it has written all DROP TEMPORARY TABLE and DO master has shut down properly, it has written all DROP TEMPORARY TABLE and DO
RELEASE_LOCK (prepared statements' deletion is TODO). RELEASE_LOCK (prepared statements' deletion is TODO).

View file

@ -302,6 +302,31 @@ struct sql_ex_info
#define LOG_EVENT_TIME_F 0x1 #define LOG_EVENT_TIME_F 0x1
#define LOG_EVENT_FORCED_ROTATE_F 0x2 #define LOG_EVENT_FORCED_ROTATE_F 0x2
#endif #endif
/*
This flag only makes sense for Format_description_log_event. It is set
when the event is written, and *reset* when a binlog file is
closed (yes, it's the only case when MySQL modifies already written
part of binlog). Thus it is a reliable indicator that binlog was
closed correctly. (Stop_log_event is not enough, there's always a
small chance that mysqld crashes in the middle of insert and end of
the binlog would look like a Stop_log_event).
This flag is used to detect a restart after a crash, and to provide
"unbreakable" binlog. The problem is that on a crash storage engines
rollback automatically, while binlog does not. To solve this we use this
flag and automatically append ROLLBACK to every non-closed binlog (append
virtually, on reading, file itself is not changed). If this flag is found,
mysqlbinlog simply prints "ROLLBACK" Replication master does not abort on
binlog corruption, but takes it as EOF, and replication slave forces a
rollback in this case.
Note, that old binlogs does not have this flag set, so we get a
a backward-compatible behaviour.
*/
#define LOG_EVENT_BINLOG_IN_USE_F 0x1
/* /*
If the query depends on the thread (for example: TEMPORARY TABLE). If the query depends on the thread (for example: TEMPORARY TABLE).
Currently this is used by mysqlbinlog to know it must print Currently this is used by mysqlbinlog to know it must print
@ -310,26 +335,6 @@ struct sql_ex_info
*/ */
#define LOG_EVENT_THREAD_SPECIFIC_F 0x4 #define LOG_EVENT_THREAD_SPECIFIC_F 0x4
/*
OPTIONS_WRITTEN_TO_BIN_LOG are the bits of thd->options which must be written
to the binlog. OPTIONS_WRITTEN_TO_BINLOG could be written into the
Format_description_log_event, so that if later we don't want to replicate a
variable we did replicate, or the contrary, it's doable. But it should not be
too hard to decide once for all of what we replicate and what we don't, among
the fixed 32 bits of thd->options.
I (Guilhem) have read through every option's usage, and it looks like
OPTION_AUTO_IS_NULL and OPTION_NO_FOREIGN_KEYS are the only ones which alter
how the query modifies the table. It's good to replicate
OPTION_RELAXED_UNIQUE_CHECKS too because otherwise, the slave may insert data
slower than the master, in InnoDB.
OPTION_BIG_SELECTS is not needed (the slave thread runs with
max_join_size=HA_POS_ERROR) and OPTION_BIG_TABLES is not needed either, as
the manual says (because a too big in-memory temp table is automatically
written to disk).
*/
#define OPTIONS_WRITTEN_TO_BIN_LOG (OPTION_AUTO_IS_NULL | \
OPTION_NO_FOREIGN_KEY_CHECKS | OPTION_RELAXED_UNIQUE_CHECKS)
/* /*
Suppress the generation of 'USE' statements before the actual Suppress the generation of 'USE' statements before the actual
statement. This flag should be set for any events that does not need statement. This flag should be set for any events that does not need
@ -343,24 +348,51 @@ OPTION_NO_FOREIGN_KEY_CHECKS | OPTION_RELAXED_UNIQUE_CHECKS)
*/ */
#define LOG_EVENT_SUPPRESS_USE_F 0x8 #define LOG_EVENT_SUPPRESS_USE_F 0x8
/*
OPTIONS_WRITTEN_TO_BIN_LOG are the bits of thd->options which must be
written to the binlog. OPTIONS_WRITTEN_TO_BINLOG could be written
into the Format_description_log_event, so that if later we don't want
to replicate a variable we did replicate, or the contrary, it's
doable. But it should not be too hard to decide once for all of what
we replicate and what we don't, among the fixed 32 bits of
thd->options.
I (Guilhem) have read through every option's usage, and it looks like
OPTION_AUTO_IS_NULL and OPTION_NO_FOREIGN_KEYS are the only ones
which alter how the query modifies the table. It's good to replicate
OPTION_RELAXED_UNIQUE_CHECKS too because otherwise, the slave may
insert data slower than the master, in InnoDB.
OPTION_BIG_SELECTS is not needed (the slave thread runs with
max_join_size=HA_POS_ERROR) and OPTION_BIG_TABLES is not needed
either, as the manual says (because a too big in-memory temp table is
automatically written to disk).
*/
#define OPTIONS_WRITTEN_TO_BIN_LOG (OPTION_AUTO_IS_NULL | \
OPTION_NO_FOREIGN_KEY_CHECKS | OPTION_RELAXED_UNIQUE_CHECKS)
enum Log_event_type enum Log_event_type
{ {
/* /*
Every time you update this enum (when you add a type), you have to Every time you update this enum (when you add a type), you have to
update the code of Format_description_log_event::Format_description_log_event(). fix Format_description_log_event::Format_description_log_event().
Make sure you always insert new types ***BEFORE*** ENUM_END_EVENT.
*/ */
UNKNOWN_EVENT= 0, START_EVENT_V3, QUERY_EVENT, STOP_EVENT, ROTATE_EVENT, UNKNOWN_EVENT= 0, START_EVENT_V3, QUERY_EVENT, STOP_EVENT, ROTATE_EVENT,
INTVAR_EVENT, LOAD_EVENT, SLAVE_EVENT, CREATE_FILE_EVENT, INTVAR_EVENT, LOAD_EVENT, SLAVE_EVENT, CREATE_FILE_EVENT,
APPEND_BLOCK_EVENT, EXEC_LOAD_EVENT, DELETE_FILE_EVENT, APPEND_BLOCK_EVENT, EXEC_LOAD_EVENT, DELETE_FILE_EVENT,
/* /*
NEW_LOAD_EVENT is like LOAD_EVENT except that it has a longer sql_ex, NEW_LOAD_EVENT is like LOAD_EVENT except that it has a longer
allowing multibyte TERMINATED BY etc; both types share the same class sql_ex, allowing multibyte TERMINATED BY etc; both types share the
(Load_log_event) same class (Load_log_event)
*/ */
NEW_LOAD_EVENT, NEW_LOAD_EVENT,
RAND_EVENT, USER_VAR_EVENT, RAND_EVENT, USER_VAR_EVENT,
FORMAT_DESCRIPTION_EVENT, FORMAT_DESCRIPTION_EVENT,
XID_EVENT,
/*
add new events here - right above this comment!
existing events should never change their numbers
*/
ENUM_END_EVENT /* end marker */ ENUM_END_EVENT /* end marker */
}; };
@ -461,16 +493,15 @@ public:
ulong data_written; ulong data_written;
/* /*
The master's server id (is preserved in the relay log; used to prevent from The master's server id (is preserved in the relay log; used to
infinite loops in circular replication). prevent from infinite loops in circular replication).
*/ */
uint32 server_id; uint32 server_id;
/* /*
Some 16 flags. Only one is really used now; look above for Some 16 flags. Look above for LOG_EVENT_TIME_F,
LOG_EVENT_TIME_F, LOG_EVENT_FORCED_ROTATE_F, LOG_EVENT_FORCED_ROTATE_F, LOG_EVENT_THREAD_SPECIFIC_F, and
LOG_EVENT_THREAD_SPECIFIC_F, and LOG_EVENT_SUPPRESS_USE_F for LOG_EVENT_SUPPRESS_USE_F for notes.
notes.
*/ */
uint16 flags; uint16 flags;
@ -566,11 +597,11 @@ public:
temp_buf = 0; temp_buf = 0;
} }
} }
virtual int get_data_size() { return 0;}
/* /*
Get event length for simple events. For complicated events the length Get event length for simple events. For complicated events the length
is calculated during write() is calculated during write()
*/ */
virtual int get_data_size() { return 0;}
static Log_event* read_log_event(const char* buf, uint event_len, static Log_event* read_log_event(const char* buf, uint event_len,
const char **error, const char **error,
const Format_description_log_event const Format_description_log_event
@ -862,8 +893,8 @@ public:
binary log) was created. In the other case (i.e. this event is at binary log) was created. In the other case (i.e. this event is at
the start of a binary log created by FLUSH LOGS or automatic the start of a binary log created by FLUSH LOGS or automatic
rotation), 'created' should be 0. This "trick" is used by MySQL rotation), 'created' should be 0. This "trick" is used by MySQL
>=4.0.14 slaves to know if they must drop the stale temporary >=4.0.14 slaves to know whether they must drop stale temporary
tables or not. tables and whether they should abort unfinished transaction.
Note that when 'created'!=0, it is always equal to the event's Note that when 'created'!=0, it is always equal to the event's
timestamp; indeed Start_log_event is written only in log.cc where timestamp; indeed Start_log_event is written only in log.cc where
@ -1037,6 +1068,40 @@ class Rand_log_event: public Log_event
bool is_valid() const { return 1; } bool is_valid() const { return 1; }
}; };
/*****************************************************************************
Xid Log Event class
Logs xid of the transaction-to-be-committed in the 2pc protocol.
Has no meaning in replication, slaves ignore it.
****************************************************************************/
#ifdef MYSQL_CLIENT
typedef ulong my_xid;
#endif
class Xid_log_event: public Log_event
{
public:
my_xid xid;
#ifndef MYSQL_CLIENT
Xid_log_event(THD* thd_arg, my_xid x): Log_event(thd_arg,0,0), xid(x) {}
#ifdef HAVE_REPLICATION
void pack_info(Protocol* protocol);
int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */
#else
void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
#endif
Xid_log_event(const char* buf, const Format_description_log_event* description_event);
~Xid_log_event() {}
Log_event_type get_type_code() { return XID_EVENT;}
int get_data_size() { return sizeof(xid); }
bool write(IO_CACHE* file);
bool is_valid() const { return 1; }
};
/***************************************************************************** /*****************************************************************************
@ -1086,8 +1151,6 @@ public:
Stop Log Event class Stop Log Event class
****************************************************************************/ ****************************************************************************/
#ifdef HAVE_REPLICATION
class Stop_log_event: public Log_event class Stop_log_event: public Log_event
{ {
public: public:
@ -1107,14 +1170,11 @@ public:
bool is_valid() const { return 1; } bool is_valid() const { return 1; }
}; };
#endif /* HAVE_REPLICATION */
/***************************************************************************** /*****************************************************************************
Rotate Log Event class Rotate Log Event class
This will be depricated when we move to using sequence ids. This will be deprecated when we move to using sequence ids.
****************************************************************************/ ****************************************************************************/

View file

@ -409,9 +409,16 @@ inline THD *_current_thd(void)
} }
#define current_thd _current_thd() #define current_thd _current_thd()
/*
External variables
*/
extern ulong server_id, concurrency;
typedef my_bool (*qc_engine_callback)(THD *thd, char *table_key, typedef my_bool (*qc_engine_callback)(THD *thd, char *table_key,
uint key_length, uint key_length,
ulonglong *engine_data); ulonglong *engine_data);
#include "sql_string.h" #include "sql_string.h"
#include "sql_list.h" #include "sql_list.h"
#include "sql_map.h" #include "sql_map.h"
@ -449,6 +456,14 @@ bool delete_precheck(THD *thd, TABLE_LIST *tables);
bool insert_precheck(THD *thd, TABLE_LIST *tables); bool insert_precheck(THD *thd, TABLE_LIST *tables);
bool create_table_precheck(THD *thd, TABLE_LIST *tables, bool create_table_precheck(THD *thd, TABLE_LIST *tables,
TABLE_LIST *create_table); TABLE_LIST *create_table);
enum enum_mysql_completiontype {
ROLLBACK_RELEASE=-2, ROLLBACK=1, ROLLBACK_AND_CHAIN=7,
COMMIT_RELEASE=-1, COMMIT=0, COMMIT_AND_CHAIN=6
};
int end_trans(THD *thd, enum enum_mysql_completiontype completion);
Item *negate_expression(THD *thd, Item *expr); Item *negate_expression(THD *thd, Item *expr);
#include "sql_class.h" #include "sql_class.h"
#include "sql_acl.h" #include "sql_acl.h"
@ -572,6 +587,8 @@ bool mysql_preload_keys(THD* thd, TABLE_LIST* table_list);
int reassign_keycache_tables(THD* thd, KEY_CACHE *src_cache, int reassign_keycache_tables(THD* thd, KEY_CACHE *src_cache,
KEY_CACHE *dst_cache); KEY_CACHE *dst_cache);
bool mysql_xa_recover(THD *thd);
bool check_simple_select(); bool check_simple_select();
SORT_FIELD * make_unireg_sortorder(ORDER *order, uint *length); SORT_FIELD * make_unireg_sortorder(ORDER *order, uint *length);
@ -944,11 +961,9 @@ void sql_print_information(const char *format, ...);
bool fn_format_relative_to_data_home(my_string to, const char *name, bool fn_format_relative_to_data_home(my_string to, const char *name,
const char *dir, const char *extension); const char *dir, const char *extension);
bool open_log(MYSQL_LOG *log, const char *hostname, File open_binlog(IO_CACHE *log, const char *log_file_name,
const char *opt_name, const char *extension, const char **errmsg);
const char *index_file_name, handlerton *binlog_init();
enum_log_type type, bool read_append,
bool no_auto_events, ulong max_size);
/* mysqld.cc */ /* mysqld.cc */
extern void yyerror(const char*); extern void yyerror(const char*);
@ -1003,7 +1018,7 @@ extern double last_query_cost;
extern double log_10[32]; extern double log_10[32];
extern ulonglong log_10_int[20]; extern ulonglong log_10_int[20];
extern ulonglong keybuff_size; extern ulonglong keybuff_size;
extern ulong refresh_version,flush_version, thread_id,query_id; extern ulong refresh_version,flush_version, thread_id;
extern ulong binlog_cache_use, binlog_cache_disk_use; extern ulong binlog_cache_use, binlog_cache_disk_use;
extern ulong aborted_threads,aborted_connects; extern ulong aborted_threads,aborted_connects;
extern ulong delayed_insert_timeout; extern ulong delayed_insert_timeout;
@ -1013,8 +1028,6 @@ extern ulong delayed_rows_in_use,delayed_insert_errors;
extern ulong slave_open_temp_tables; extern ulong slave_open_temp_tables;
extern ulong query_cache_size, query_cache_min_res_unit; extern ulong query_cache_size, query_cache_min_res_unit;
extern ulong thd_startup_options, slow_launch_threads, slow_launch_time; extern ulong thd_startup_options, slow_launch_threads, slow_launch_time;
extern ulong server_id, concurrency;
extern ulong ha_read_count, ha_discover_count;
extern ulong table_cache_size; extern ulong table_cache_size;
extern ulong max_connections,max_connect_errors, connect_timeout; extern ulong max_connections,max_connect_errors, connect_timeout;
extern ulong slave_net_timeout; extern ulong slave_net_timeout;
@ -1056,6 +1069,7 @@ extern uint opt_large_page_size;
extern MYSQL_LOG mysql_log,mysql_slow_log,mysql_bin_log; extern MYSQL_LOG mysql_log,mysql_slow_log,mysql_bin_log;
extern FILE *bootstrap_file; extern FILE *bootstrap_file;
extern int bootstrap_error;
extern pthread_key(MEM_ROOT**,THR_MALLOC); extern pthread_key(MEM_ROOT**,THR_MALLOC);
extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open, extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open,
LOCK_thread_count,LOCK_mapped_file,LOCK_user_locks, LOCK_status, LOCK_thread_count,LOCK_mapped_file,LOCK_user_locks, LOCK_status,
@ -1259,6 +1273,14 @@ SQL_CRYPT *get_crypt_for_frm(void);
#include "sql_view.h" #include "sql_view.h"
/* query_id */
typedef ulonglong query_id_t;
extern query_id_t query_id;
/* increment query_id and return it. */
inline query_id_t next_query_id() { return query_id++; }
/* Some inline functions for more speed */ /* Some inline functions for more speed */
inline bool add_item_to_list(THD *thd, Item *item) inline bool add_item_to_list(THD *thd, Item *item)

View file

@ -54,7 +54,8 @@
#endif #endif
#ifdef HAVE_NDBCLUSTER_DB #ifdef HAVE_NDBCLUSTER_DB
#define OPT_NDBCLUSTER_DEFAULT 0 #define OPT_NDBCLUSTER_DEFAULT 0
#if defined(NOT_ENOUGH_TESTED) && defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000 #if defined(NOT_ENOUGH_TESTED) \
&& defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000
#define OPT_NDB_SHM_DEFAULT 1 #define OPT_NDB_SHM_DEFAULT 1
#else #else
#define OPT_NDB_SHM_DEFAULT 0 #define OPT_NDB_SHM_DEFAULT 0
@ -147,11 +148,11 @@ int deny_severity = LOG_WARNING;
#include <sys/mman.h> #include <sys/mman.h>
#endif #endif
#ifdef __NETWARE__
#define zVOLSTATE_ACTIVE 6 #define zVOLSTATE_ACTIVE 6
#define zVOLSTATE_DEACTIVE 2 #define zVOLSTATE_DEACTIVE 2
#define zVOLSTATE_MAINTENANCE 3 #define zVOLSTATE_MAINTENANCE 3
#ifdef __NETWARE__
#include <nks/vm.h> #include <nks/vm.h>
#include <library.h> #include <library.h>
#include <monitor.h> #include <monitor.h>
@ -245,6 +246,10 @@ const char *sql_mode_names[] =
}; };
TYPELIB sql_mode_typelib= { array_elements(sql_mode_names)-1,"", TYPELIB sql_mode_typelib= { array_elements(sql_mode_names)-1,"",
sql_mode_names, NULL }; sql_mode_names, NULL };
const char *tc_heuristic_recover_names[]= { "COMMIT", "ROLLBACK", NullS };
TYPELIB tc_heuristic_recover_typelib=
{ array_elements(tc_heuristic_recover_names)-1,"",
tc_heuristic_recover_names, NULL };
const char *first_keyword= "first", *binary_keyword= "BINARY"; const char *first_keyword= "first", *binary_keyword= "BINARY";
const char *my_localhost= "localhost", *delayed_user= "DELAYED"; const char *my_localhost= "localhost", *delayed_user= "DELAYED";
#if SIZEOF_OFF_T > 4 && defined(BIG_TABLES) #if SIZEOF_OFF_T > 4 && defined(BIG_TABLES)
@ -300,14 +305,13 @@ my_bool opt_secure_auth= 0;
my_bool opt_short_log_format= 0; my_bool opt_short_log_format= 0;
my_bool opt_log_queries_not_using_indexes= 0; my_bool opt_log_queries_not_using_indexes= 0;
my_bool lower_case_file_system= 0; my_bool lower_case_file_system= 0;
my_bool opt_innodb_safe_binlog= 0;
my_bool opt_large_pages= 0; my_bool opt_large_pages= 0;
uint opt_large_page_size= 0; uint opt_large_page_size= 0;
my_bool opt_old_style_user_limits= 0; my_bool opt_old_style_user_limits= 0;
/* /*
True if there is at least one per-hour limit for some user, so we should check True if there is at least one per-hour limit for some user, so we should
them before each query (and possibly reset counters when hour is changed). check them before each query (and possibly reset counters when hour is
False otherwise. changed). False otherwise.
*/ */
volatile bool mqh_used = 0; volatile bool mqh_used = 0;
my_bool sp_automatic_privileges= 1; my_bool sp_automatic_privileges= 1;
@ -315,7 +319,7 @@ my_bool sp_automatic_privileges= 1;
uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options; uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options;
uint delay_key_write_options, protocol_version; uint delay_key_write_options, protocol_version;
uint lower_case_table_names; uint lower_case_table_names;
uint opt_crash_binlog_innodb; uint tc_heuristic_recover= 0;
uint volatile thread_count, thread_running, kill_cached_threads, wake_thread; uint volatile thread_count, thread_running, kill_cached_threads, wake_thread;
ulong back_log, connect_timeout, concurrency; ulong back_log, connect_timeout, concurrency;
@ -327,7 +331,7 @@ ulong slave_net_timeout;
ulong thread_cache_size=0, binlog_cache_size=0, max_binlog_cache_size=0; ulong thread_cache_size=0, binlog_cache_size=0, max_binlog_cache_size=0;
ulong query_cache_size=0; ulong query_cache_size=0;
ulong refresh_version, flush_version; /* Increments on each reload */ ulong refresh_version, flush_version; /* Increments on each reload */
ulong query_id; query_id_t query_id;
ulong aborted_threads, killed_threads, aborted_connects; ulong aborted_threads, killed_threads, aborted_connects;
ulong delayed_insert_timeout, delayed_insert_limit, delayed_queue_size; ulong delayed_insert_timeout, delayed_insert_limit, delayed_queue_size;
ulong delayed_insert_threads, delayed_insert_writes, delayed_rows_in_use; ulong delayed_insert_threads, delayed_insert_writes, delayed_rows_in_use;
@ -384,6 +388,7 @@ Le_creator le_creator;
FILE *bootstrap_file; FILE *bootstrap_file;
int bootstrap_error;
I_List<i_string_pair> replicate_rewrite_db; I_List<i_string_pair> replicate_rewrite_db;
I_List<i_string> replicate_do_db, replicate_ignore_db; I_List<i_string> replicate_do_db, replicate_ignore_db;
@ -445,7 +450,7 @@ static my_bool opt_do_pstack, opt_noacl, opt_bootstrap, opt_myisam_log;
static int cleanup_done; static int cleanup_done;
static ulong opt_specialflag, opt_myisam_block_size; static ulong opt_specialflag, opt_myisam_block_size;
static char *opt_logname, *opt_update_logname, *opt_binlog_index_name; static char *opt_logname, *opt_update_logname, *opt_binlog_index_name;
static char *opt_slow_logname; static char *opt_slow_logname, *opt_tc_log_file, *opt_tc_heuristic_recover;
static char *mysql_home_ptr, *pidfile_name_ptr; static char *mysql_home_ptr, *pidfile_name_ptr;
static char **defaults_argv; static char **defaults_argv;
static char *opt_bin_logname; static char *opt_bin_logname;
@ -527,7 +532,7 @@ static char *get_relative_path(const char *path);
static void fix_paths(void); static void fix_paths(void);
extern "C" pthread_handler_decl(handle_connections_sockets,arg); extern "C" pthread_handler_decl(handle_connections_sockets,arg);
extern "C" pthread_handler_decl(kill_server_thread,arg); extern "C" pthread_handler_decl(kill_server_thread,arg);
static int bootstrap(FILE *file); static void bootstrap(FILE *file);
static void close_server_sock(); static void close_server_sock();
static bool read_init_file(char *file_name); static bool read_init_file(char *file_name);
#ifdef __NT__ #ifdef __NT__
@ -969,6 +974,8 @@ void clean_up(bool print_message)
udf_free(); udf_free();
#endif #endif
(void) ha_panic(HA_PANIC_CLOSE); /* close all tables and logs */ (void) ha_panic(HA_PANIC_CLOSE); /* close all tables and logs */
if (tc_log)
tc_log->close();
delete_elements(&key_caches, (void (*)(const char*, gptr)) free_key_cache); delete_elements(&key_caches, (void (*)(const char*, gptr)) free_key_cache);
multi_keycache_free(); multi_keycache_free();
end_thr_alarm(1); /* Free allocated memory */ end_thr_alarm(1); /* Free allocated memory */
@ -1576,11 +1583,11 @@ void mysql_down_server_cb(void *, void *)
// destroy callback resources // destroy callback resources
void mysql_cb_destroy(void *) void mysql_cb_destroy(void *)
{ {
UnRegisterEventNotification(eh); // cleanup down event notification UnRegisterEventNotification(eh); // cleanup down event notification
NX_UNWRAP_INTERFACE(ref); NX_UNWRAP_INTERFACE(ref);
/* Deregister NSS volume deactivation event */ /* Deregister NSS volume deactivation event */
NX_UNWRAP_INTERFACE(refneb); NX_UNWRAP_INTERFACE(refneb);
if (neb_consumer_id) if (neb_consumer_id)
UnRegisterConsumer(neb_consumer_id, NULL); UnRegisterConsumer(neb_consumer_id, NULL);
} }
@ -1703,7 +1710,6 @@ ulong neb_event_callback(struct EventBlock *eblock)
nw_panic = TRUE; nw_panic = TRUE;
event_flag= TRUE; event_flag= TRUE;
kill_server(0); kill_server(0);
} }
} }
return 0; return 0;
@ -1761,7 +1767,7 @@ static void getvolumeID(BYTE *volumeName)
datavolid.clockSeqLow= info.vol.volumeID.clockSeqLow; datavolid.clockSeqLow= info.vol.volumeID.clockSeqLow;
/* This is guranteed to be 6-byte length (but sizeof() would be better) */ /* This is guranteed to be 6-byte length (but sizeof() would be better) */
memcpy(datavolid.node, info.vol.volumeID.node, (unsigned int) 6); memcpy(datavolid.node, info.vol.volumeID.node, (unsigned int) 6);
exit: exit:
if (rootKey) if (rootKey)
zClose(rootKey); zClose(rootKey);
@ -2174,8 +2180,8 @@ static void check_data_home(const char *path)
/* /*
All global error messages are sent here where the first one is stored for All global error messages are sent here where the first one is stored
the client for the client
*/ */
@ -2211,7 +2217,7 @@ extern "C" int my_message_sql(uint error, const char *str, myf MyFlags)
(thd->lex->current_select ? (thd->lex->current_select ?
thd->lex->current_select->no_error : 0), thd->lex->current_select->no_error : 0),
(int) thd->is_fatal_error)); (int) thd->is_fatal_error));
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, str); push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, str);
} }
else else
@ -2301,45 +2307,14 @@ extern "C" pthread_handler_decl(handle_shutdown,arg)
#endif #endif
const char *load_default_groups[]= { const char *load_default_groups[]= {
#ifdef HAVE_NDBCLUSTER_DB #ifdef HAVE_NDBCLUSTER_DB
"mysql_cluster", "mysql_cluster",
#endif #endif
"mysqld","server",MYSQL_BASE_VERSION,0,0}; "mysqld","server", MYSQL_BASE_VERSION, 0, 0};
static const int load_default_groups_sz= static const int load_default_groups_sz=
sizeof(load_default_groups)/sizeof(load_default_groups[0]); sizeof(load_default_groups)/sizeof(load_default_groups[0]);
bool open_log(MYSQL_LOG *log, const char *hostname,
const char *opt_name, const char *extension,
const char *index_file_name,
enum_log_type type, bool read_append,
bool no_auto_events, ulong max_size)
{
char tmp[FN_REFLEN];
if (!opt_name || !opt_name[0])
{
/*
TODO: The following should be using fn_format(); We just need to
first change fn_format() to cut the file name if it's too long.
*/
strmake(tmp,hostname,FN_REFLEN-5);
strmov(fn_ext(tmp),extension);
opt_name=tmp;
}
// get rid of extension if the log is binary to avoid problems
if (type == LOG_BIN)
{
char *p = fn_ext(opt_name);
uint length=(uint) (p-opt_name);
strmake(tmp,opt_name,min(length,FN_REFLEN));
opt_name=tmp;
}
return log->open(opt_name, type, 0, index_file_name,
(read_append) ? SEQ_READ_APPEND : WRITE_CACHE,
no_auto_events, max_size, 0);
}
/* /*
Initialize one of the global date/time format variables Initialize one of the global date/time format variables
@ -2347,7 +2322,7 @@ bool open_log(MYSQL_LOG *log, const char *hostname,
init_global_datetime_format() init_global_datetime_format()
format_type What kind of format should be supported format_type What kind of format should be supported
var_ptr Pointer to variable that should be updated var_ptr Pointer to variable that should be updated
NOTES NOTES
The default value is taken from either opt_date_time_formats[] or The default value is taken from either opt_date_time_formats[] or
the ISO format (ANSI SQL) the ISO format (ANSI SQL)
@ -2630,8 +2605,7 @@ static int init_server_components()
#endif #endif
/* Setup log files */ /* Setup log files */
if (opt_log) if (opt_log)
open_log(&mysql_log, glob_hostname, opt_logname, ".log", NullS, mysql_log.open_query_log(opt_logname);
LOG_NORMAL, 0, 0, 0);
if (opt_update_log) if (opt_update_log)
{ {
/* /*
@ -2684,57 +2658,15 @@ version 5.0 and above. It is replaced by the binary log. Now starting MySQL \
with --log-bin instead."); with --log-bin instead.");
} }
} }
if (opt_slow_log) if (opt_log_slave_updates && !opt_bin_log)
open_log(&mysql_slow_log, glob_hostname, opt_slow_logname, "-slow.log", {
NullS, LOG_NORMAL, 0, 0, 0); sql_print_warning("You need to use --log-bin to make "
"--log-slave-updates work.");
unireg_abort(1);
}
if (opt_bin_log) if (opt_slow_log)
{ mysql_slow_log.open_slow_log(opt_slow_logname);
/* If we fail to open binlog, it's going to hinder our recovery, so die */
if (open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin",
opt_binlog_index_name, LOG_BIN, 0, 0, max_binlog_size))
unireg_abort(1);
using_update_log=1;
#ifdef HAVE_REPLICATION
if (expire_logs_days)
{
long purge_time= time(0) - expire_logs_days*24*60*60;
if (purge_time >= 0)
mysql_bin_log.purge_logs_before_date(purge_time);
}
#endif
if (!opt_bin_logname && !opt_binlog_index_name)
{
/*
User didn't give us info to name the binlog index file.
Picking `hostname`-bin.index like did in 4.x, causes replication to
fail if the hostname is changed later. So, we would like to instead
require a name. But as we don't want to break many existing setups, we
only give warning, not error.
*/
sql_print_warning("\
No argument was provided to --log-bin, and --log-bin-index was not used; \
so replication may break when this MySQL server acts as a master and \
has his hostname changed!! Please use '--log-bin=%s' to avoid \
this problem.",
mysql_bin_log.get_name());
}
}
else
{
if (opt_log_slave_updates)
{
sql_print_error("\
You need to use --log-bin=# to make --log-slave-updates work.");
unireg_abort(1);
}
if (opt_binlog_index_name)
{
sql_print_error("\
You need to use --log-bin=# to make --log-bin-index work.");
unireg_abort(1);
}
}
#ifdef HAVE_REPLICATION #ifdef HAVE_REPLICATION
if (opt_log_slave_updates && replicate_same_server_id) if (opt_log_slave_updates && replicate_same_server_id)
@ -2766,39 +2698,33 @@ server.");
} }
} }
if (opt_innodb_safe_binlog) if (opt_bin_log)
{ {
if (have_innodb != SHOW_OPTION_YES) char buf[FN_REFLEN];
sql_print_warning("--innodb-safe-binlog is meaningful only if " const char *ln;
"the InnoDB storage engine is enabled in the server."); ln= mysql_bin_log.generate_name(opt_bin_logname, "-bin", 1, buf);
#ifdef HAVE_INNOBASE_DB if (!opt_bin_logname && !opt_binlog_index_name)
if (innobase_flush_log_at_trx_commit != 1)
{
sql_print_warning("--innodb-safe-binlog is meaningful only if "
"innodb_flush_log_at_trx_commit is 1; now setting it "
"to 1.");
innobase_flush_log_at_trx_commit= 1;
}
if (innobase_unix_file_flush_method)
{ {
/* /*
This option has so many values that it's hard to know which value is User didn't give us info to name the binlog index file.
good (especially "littlesync", and on Windows... see Picking `hostname`-bin.index like did in 4.x, causes replication to
srv/srv0start.c). fail if the hostname is changed later. So, we would like to instead
require a name. But as we don't want to break many existing setups, we
only give warning, not error.
*/ */
sql_print_warning("--innodb-safe-binlog requires that " sql_print_warning("No argument was provided to --log-bin, and "
"the innodb_flush_method actually synchronizes the " "--log-bin-index was not used; so replication "
"InnoDB log to disk; it is your responsibility " "may break when this MySQL server acts as a "
"to verify that the method you chose does it."); "master and has his hostname changed!! Please "
"use '--log-bin=%s' to avoid this problem.", ln);
} }
if (sync_binlog_period != 1) if (ln == buf)
{ {
sql_print_warning("--innodb-safe-binlog is meaningful only if " my_free(opt_bin_logname, MYF(MY_ALLOW_ZERO_PTR));
"the global sync_binlog variable is 1; now setting it " opt_bin_logname=my_strdup(buf, MYF(0));
"to 1.");
sync_binlog_period= 1;
} }
#endif mysql_bin_log.open_index_file(opt_binlog_index_name, ln);
using_update_log=1;
} }
if (ha_init()) if (ha_init())
@ -2806,21 +2732,33 @@ server.");
sql_print_error("Can't init databases"); sql_print_error("Can't init databases");
unireg_abort(1); unireg_abort(1);
} }
tc_log= total_ha_2pc > 1 ? opt_bin_log ?
(TC_LOG *)&mysql_bin_log :
(TC_LOG *)&tc_log_mmap :
(TC_LOG *)&tc_log_dummy;
if (tc_log->open(opt_tc_log_file))
{
sql_print_error("Can't init tc log");
unireg_abort(1);
}
if (opt_bin_log && mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0,
WRITE_CACHE, 0, max_binlog_size, 0))
unireg_abort(1);
#ifdef HAVE_REPLICATION
if (opt_bin_log && expire_logs_days)
{
long purge_time= time(0) - expire_logs_days*24*60*60;
if (purge_time >= 0)
mysql_bin_log.purge_logs_before_date(purge_time);
}
#endif
if (opt_myisam_log) if (opt_myisam_log)
(void) mi_log(1); (void) mi_log(1);
/*
Now that InnoDB is initialized, we can know the last good binlog position
and cut the binlog if needed. This function does nothing if there was no
crash recovery by InnoDB.
*/
if (opt_innodb_safe_binlog)
{
/* not fatal if fails (but print errors) */
mysql_bin_log.cut_spurious_tail();
}
mysql_bin_log.report_pos_in_innodb();
/* call ha_init_key_cache() on all key caches to init them */ /* call ha_init_key_cache() on all key caches to init them */
process_key_caches(&ha_init_key_cache); process_key_caches(&ha_init_key_cache);
@ -3137,9 +3075,9 @@ we force server id to 2, but this MySQL server will not act as a slave.");
if (opt_bootstrap) if (opt_bootstrap)
{ {
int error=bootstrap(stdin); bootstrap(stdin);
end_thr_alarm(1); // Don't allow alarms end_thr_alarm(1); // Don't allow alarms
unireg_abort(error ? 1 : 0); unireg_abort(bootstrap_error ? 1 : 0);
} }
if (opt_init_file) if (opt_init_file)
{ {
@ -3327,10 +3265,10 @@ int main(int argc, char **argv)
/* When several instances are running on the same machine, we /* When several instances are running on the same machine, we
need to have an unique named hEventShudown through the need to have an unique named hEventShudown through the
application PID e.g.: MySQLShutdown1890; MySQLShutdown2342 application PID e.g.: MySQLShutdown1890; MySQLShutdown2342
*/ */
int10_to_str((int) GetCurrentProcessId(),strmov(shutdown_event_name, int10_to_str((int) GetCurrentProcessId(),strmov(shutdown_event_name,
"MySQLShutdown"), 10); "MySQLShutdown"), 10);
/* Must be initialized early for comparison of service name */ /* Must be initialized early for comparison of service name */
system_charset_info= &my_charset_utf8_general_ci; system_charset_info= &my_charset_utf8_general_ci;
@ -3429,7 +3367,7 @@ int main(int argc, char **argv)
create MySQL privilege tables without having to start a full MySQL server. create MySQL privilege tables without having to start a full MySQL server.
*/ */
static int bootstrap(FILE *file) static void bootstrap(FILE *file)
{ {
int error= 0; int error= 0;
DBUG_ENTER("bootstrap"); DBUG_ENTER("bootstrap");
@ -3449,7 +3387,8 @@ static int bootstrap(FILE *file)
(void*) thd)) (void*) thd))
{ {
sql_print_warning("Can't create thread to handle bootstrap"); sql_print_warning("Can't create thread to handle bootstrap");
DBUG_RETURN(-1); bootstrap_error=-1;
DBUG_VOID_RETURN;
} }
/* Wait for thread to die */ /* Wait for thread to die */
(void) pthread_mutex_lock(&LOCK_thread_count); (void) pthread_mutex_lock(&LOCK_thread_count);
@ -3464,13 +3403,7 @@ static int bootstrap(FILE *file)
handle_bootstrap((void *)thd); handle_bootstrap((void *)thd);
#endif #endif
error= thd->is_fatal_error; DBUG_VOID_RETURN;
#ifndef EMBEDDED_LIBRARY
net_end(&thd->net);
#endif
thd->cleanup();
delete thd;
DBUG_RETURN(error);
} }
@ -3481,7 +3414,7 @@ static bool read_init_file(char *file_name)
DBUG_PRINT("enter",("name: %s",file_name)); DBUG_PRINT("enter",("name: %s",file_name));
if (!(file=my_fopen(file_name,O_RDONLY,MYF(MY_WME)))) if (!(file=my_fopen(file_name,O_RDONLY,MYF(MY_WME))))
return(1); return(1);
bootstrap(file); /* Ignore errors from this */ bootstrap(file);
(void) my_fclose(file,MYF(MY_WME)); (void) my_fclose(file,MYF(MY_WME));
return 0; return 0;
} }
@ -3960,7 +3893,7 @@ pthread_handler_decl(handle_connections_shared_memory,arg)
/* /*
it can be after shutdown command it can be after shutdown command
*/ */
if (abort_loop) if (abort_loop)
goto error; goto error;
HANDLE handle_client_file_map= 0; HANDLE handle_client_file_map= 0;
@ -4140,7 +4073,7 @@ enum options_mysqld
OPT_MASTER_HOST, OPT_MASTER_USER, OPT_MASTER_HOST, OPT_MASTER_USER,
OPT_MASTER_PASSWORD, OPT_MASTER_PORT, OPT_MASTER_PASSWORD, OPT_MASTER_PORT,
OPT_MASTER_INFO_FILE, OPT_MASTER_CONNECT_RETRY, OPT_MASTER_INFO_FILE, OPT_MASTER_CONNECT_RETRY,
OPT_MASTER_RETRY_COUNT, OPT_MASTER_RETRY_COUNT, OPT_LOG_TC, OPT_LOG_TC_SIZE,
OPT_MASTER_SSL, OPT_MASTER_SSL_KEY, OPT_MASTER_SSL, OPT_MASTER_SSL_KEY,
OPT_MASTER_SSL_CERT, OPT_MASTER_SSL_CAPATH, OPT_MASTER_SSL_CERT, OPT_MASTER_SSL_CAPATH,
OPT_MASTER_SSL_CIPHER, OPT_MASTER_SSL_CA, OPT_MASTER_SSL_CIPHER, OPT_MASTER_SSL_CA,
@ -4154,7 +4087,7 @@ enum options_mysqld
OPT_SAFEMALLOC_MEM_LIMIT, OPT_REPLICATE_DO_TABLE, OPT_SAFEMALLOC_MEM_LIMIT, OPT_REPLICATE_DO_TABLE,
OPT_REPLICATE_IGNORE_TABLE, OPT_REPLICATE_WILD_DO_TABLE, OPT_REPLICATE_IGNORE_TABLE, OPT_REPLICATE_WILD_DO_TABLE,
OPT_REPLICATE_WILD_IGNORE_TABLE, OPT_REPLICATE_SAME_SERVER_ID, OPT_REPLICATE_WILD_IGNORE_TABLE, OPT_REPLICATE_SAME_SERVER_ID,
OPT_DISCONNECT_SLAVE_EVENT_COUNT, OPT_DISCONNECT_SLAVE_EVENT_COUNT, OPT_TC_HEURISTIC_RECOVER,
OPT_ABORT_SLAVE_EVENT_COUNT, OPT_ABORT_SLAVE_EVENT_COUNT,
OPT_INNODB_DATA_HOME_DIR, OPT_INNODB_DATA_HOME_DIR,
OPT_INNODB_DATA_FILE_PATH, OPT_INNODB_DATA_FILE_PATH,
@ -4577,6 +4510,14 @@ Disable with --skip-isam.",
"Log slow queries to this log file. Defaults logging to hostname-slow.log file.", "Log slow queries to this log file. Defaults logging to hostname-slow.log file.",
(gptr*) &opt_slow_logname, (gptr*) &opt_slow_logname, 0, GET_STR, OPT_ARG, (gptr*) &opt_slow_logname, (gptr*) &opt_slow_logname, 0, GET_STR, OPT_ARG,
0, 0, 0, 0, 0, 0}, 0, 0, 0, 0, 0, 0},
{"log-tc", OPT_LOG_TC,
"Path to transaction coordinator log (used for transactions that affect "
"more than one storage engine, when binary log is disabled)",
(gptr*) &opt_tc_log_file, (gptr*) &opt_tc_log_file, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"log-tc-size", OPT_LOG_TC_SIZE, "Size of transaction coordinator log.",
(gptr*) &opt_tc_log_size, (gptr*) &opt_tc_log_size, 0, GET_ULONG,
REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, ~0, 0, TC_LOG_PAGE_SIZE, 0},
{"log-update", OPT_UPDATE_LOG, {"log-update", OPT_UPDATE_LOG,
"The update log is deprecated since version 5.0, is replaced by the binary \ "The update log is deprecated since version 5.0, is replaced by the binary \
log and this option justs turns on --log-bin instead.", log and this option justs turns on --log-bin instead.",
@ -4912,6 +4853,10 @@ log and this option does nothing anymore.",
{"symbolic-links", 's', "Enable symbolic link support.", {"symbolic-links", 's', "Enable symbolic link support.",
(gptr*) &my_use_symdir, (gptr*) &my_use_symdir, 0, GET_BOOL, NO_ARG, (gptr*) &my_use_symdir, (gptr*) &my_use_symdir, 0, GET_BOOL, NO_ARG,
IF_PURIFY(0,1), 0, 0, 0, 0, 0}, IF_PURIFY(0,1), 0, 0, 0, 0, 0},
{"tc-heuristic-recover", OPT_TC_HEURISTIC_RECOVER,
"Decision to use in heuristic recover process. Possible values are COMMIT or ROLLBACK",
(gptr*) &opt_tc_heuristic_recover, (gptr*) &opt_tc_heuristic_recover,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"temp-pool", OPT_TEMP_POOL, {"temp-pool", OPT_TEMP_POOL,
"Using this option will cause most temporary files created to use a small set of names, rather than a unique name for each new file.", "Using this option will cause most temporary files created to use a small set of names, rather than a unique name for each new file.",
(gptr*) &use_temp_pool, (gptr*) &use_temp_pool, 0, GET_BOOL, NO_ARG, 1, (gptr*) &use_temp_pool, (gptr*) &use_temp_pool, 0, GET_BOOL, NO_ARG, 1,
@ -4982,12 +4927,6 @@ log and this option does nothing anymore.",
"The number of seconds the mysqld server is waiting for a connect packet before responding with 'Bad handshake'.", "The number of seconds the mysqld server is waiting for a connect packet before responding with 'Bad handshake'.",
(gptr*) &connect_timeout, (gptr*) &connect_timeout, (gptr*) &connect_timeout, (gptr*) &connect_timeout,
0, GET_ULONG, REQUIRED_ARG, CONNECT_TIMEOUT, 2, LONG_TIMEOUT, 0, 1, 0 }, 0, GET_ULONG, REQUIRED_ARG, CONNECT_TIMEOUT, 2, LONG_TIMEOUT, 0, 1, 0 },
#ifdef HAVE_REPLICATION
{"crash_binlog_innodb", OPT_CRASH_BINLOG_INNODB,
"Used only for testing, to crash when writing Nth event to binlog.",
(gptr*) &opt_crash_binlog_innodb, (gptr*) &opt_crash_binlog_innodb,
0, GET_UINT, REQUIRED_ARG, 0, 0, ~(uint)0, 0, 1, 0},
#endif
{ "date_format", OPT_DATE_FORMAT, { "date_format", OPT_DATE_FORMAT,
"The DATE format (For future).", "The DATE format (For future).",
(gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_DATE], (gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_DATE],
@ -5108,26 +5047,6 @@ log and this option does nothing anymore.",
"How many files at the maximum InnoDB keeps open at the same time.", "How many files at the maximum InnoDB keeps open at the same time.",
(gptr*) &innobase_open_files, (gptr*) &innobase_open_files, 0, (gptr*) &innobase_open_files, (gptr*) &innobase_open_files, 0,
GET_LONG, REQUIRED_ARG, 300L, 10L, ~0L, 0, 1L, 0}, GET_LONG, REQUIRED_ARG, 300L, 10L, ~0L, 0, 1L, 0},
#ifdef HAVE_REPLICATION
/*
Disabled for the 4.1.3 release. Disabling just this paragraph of code is
enough, as then user can't set it to 1 so it will always be ignored in the
rest of code.
*/
#if MYSQL_VERSION_ID >= 40103
/*
innodb_safe_binlog is not a variable, just an option. Does not make
sense to make it a variable, as it is only used at startup (and so the
value would be lost at next startup, so setting it on the fly would have no
effect).
*/
{"innodb_safe_binlog", OPT_INNODB_SAFE_BINLOG,
"After a crash recovery by InnoDB, truncate the binary log after the last "
"not-rolled-back statement/transaction.",
(gptr*) &opt_innodb_safe_binlog, (gptr*) &opt_innodb_safe_binlog,
0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
#endif
#endif
{"innodb_sync_spin_loops", OPT_INNODB_SYNC_SPIN_LOOPS, {"innodb_sync_spin_loops", OPT_INNODB_SYNC_SPIN_LOOPS,
"Count of spin-loop rounds in InnoDB mutexes", "Count of spin-loop rounds in InnoDB mutexes",
(gptr*) &srv_n_spin_wait_rounds, (gptr*) &srv_n_spin_wait_rounds,
@ -5529,12 +5448,9 @@ struct show_var_st status_vars[]= {
{"Aborted_connects", (char*) &aborted_connects, SHOW_LONG}, {"Aborted_connects", (char*) &aborted_connects, SHOW_LONG},
{"Binlog_cache_disk_use", (char*) &binlog_cache_disk_use, SHOW_LONG}, {"Binlog_cache_disk_use", (char*) &binlog_cache_disk_use, SHOW_LONG},
{"Binlog_cache_use", (char*) &binlog_cache_use, SHOW_LONG}, {"Binlog_cache_use", (char*) &binlog_cache_use, SHOW_LONG},
{"Bytes_received", (char*) offsetof(STATUS_VAR, bytes_received), {"Bytes_received", (char*) offsetof(STATUS_VAR, bytes_received), SHOW_LONG_STATUS},
SHOW_LONG_STATUS}, {"Bytes_sent", (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONG_STATUS},
{"Bytes_sent", (char*) offsetof(STATUS_VAR, bytes_sent), {"Com_admin_commands", (char*) offsetof(STATUS_VAR, com_other), SHOW_LONG_STATUS},
SHOW_LONG_STATUS},
{"Com_admin_commands", (char*) offsetof(STATUS_VAR, com_other),
SHOW_LONG_STATUS},
{"Com_alter_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_DB]), SHOW_LONG_STATUS}, {"Com_alter_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_DB]), SHOW_LONG_STATUS},
{"Com_alter_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_TABLE]), SHOW_LONG_STATUS}, {"Com_alter_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_TABLE]), SHOW_LONG_STATUS},
{"Com_analyze", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ANALYZE]), SHOW_LONG_STATUS}, {"Com_analyze", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ANALYZE]), SHOW_LONG_STATUS},
@ -5621,62 +5537,45 @@ struct show_var_st status_vars[]= {
{"Com_unlock_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UNLOCK_TABLES]), SHOW_LONG_STATUS}, {"Com_unlock_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UNLOCK_TABLES]), SHOW_LONG_STATUS},
{"Com_update", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UPDATE]), SHOW_LONG_STATUS}, {"Com_update", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UPDATE]), SHOW_LONG_STATUS},
{"Com_update_multi", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UPDATE_MULTI]), SHOW_LONG_STATUS}, {"Com_update_multi", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UPDATE_MULTI]), SHOW_LONG_STATUS},
{"Com_xa_commit", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_COMMIT]),SHOW_LONG_STATUS},
{"Com_xa_end", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_END]),SHOW_LONG_STATUS},
{"Com_xa_prepare", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_PREPARE]),SHOW_LONG_STATUS},
{"Com_xa_recover", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_RECOVER]),SHOW_LONG_STATUS},
{"Com_xa_rollback", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_ROLLBACK]),SHOW_LONG_STATUS},
{"Com_xa_start", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_START]),SHOW_LONG_STATUS},
{"Connections", (char*) &thread_id, SHOW_LONG_CONST}, {"Connections", (char*) &thread_id, SHOW_LONG_CONST},
{"Created_tmp_disk_tables", (char*) offsetof(STATUS_VAR, {"Created_tmp_disk_tables", (char*) offsetof(STATUS_VAR, created_tmp_disk_tables), SHOW_LONG_STATUS},
created_tmp_disk_tables),
SHOW_LONG_STATUS},
{"Created_tmp_files", (char*) &my_tmp_file_created, SHOW_LONG}, {"Created_tmp_files", (char*) &my_tmp_file_created, SHOW_LONG},
{"Created_tmp_tables", (char*) offsetof(STATUS_VAR, {"Created_tmp_tables", (char*) offsetof(STATUS_VAR, created_tmp_tables), SHOW_LONG_STATUS},
created_tmp_tables),
SHOW_LONG_STATUS},
{"Delayed_errors", (char*) &delayed_insert_errors, SHOW_LONG}, {"Delayed_errors", (char*) &delayed_insert_errors, SHOW_LONG},
{"Delayed_insert_threads", (char*) &delayed_insert_threads, SHOW_LONG_CONST}, {"Delayed_insert_threads", (char*) &delayed_insert_threads, SHOW_LONG_CONST},
{"Delayed_writes", (char*) &delayed_insert_writes, SHOW_LONG}, {"Delayed_writes", (char*) &delayed_insert_writes, SHOW_LONG},
{"Flush_commands", (char*) &refresh_version, SHOW_LONG_CONST}, {"Flush_commands", (char*) &refresh_version, SHOW_LONG_CONST},
{"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), {"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS},
SHOW_LONG_STATUS}, {"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS},
{"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), {"Handler_discover", (char*) offsetof(STATUS_VAR, ha_discover_count), SHOW_LONG_STATUS},
SHOW_LONG_STATUS}, {"Handler_prepare", (char*) offsetof(STATUS_VAR, ha_prepare_count), SHOW_LONG_STATUS},
{"Handler_discover", (char*) &ha_discover_count, SHOW_LONG}, {"Handler_read_first", (char*) offsetof(STATUS_VAR, ha_read_first_count), SHOW_LONG_STATUS},
{"Handler_read_first", (char*) offsetof(STATUS_VAR, {"Handler_read_key", (char*) offsetof(STATUS_VAR, ha_read_key_count), SHOW_LONG_STATUS},
ha_read_first_count), {"Handler_read_next", (char*) offsetof(STATUS_VAR, ha_read_next_count), SHOW_LONG_STATUS},
SHOW_LONG_STATUS}, {"Handler_read_prev", (char*) offsetof(STATUS_VAR, ha_read_prev_count), SHOW_LONG_STATUS},
{"Handler_read_key", (char*) offsetof(STATUS_VAR, ha_read_key_count), {"Handler_read_rnd", (char*) offsetof(STATUS_VAR, ha_read_rnd_count), SHOW_LONG_STATUS},
SHOW_LONG_STATUS}, {"Handler_read_rnd_next", (char*) offsetof(STATUS_VAR, ha_read_rnd_next_count), SHOW_LONG_STATUS},
{"Handler_read_next", (char*) offsetof(STATUS_VAR, {"Handler_rollback", (char*) offsetof(STATUS_VAR, ha_rollback_count), SHOW_LONG_STATUS},
ha_read_next_count), {"Handler_savepoint", (char*) offsetof(STATUS_VAR, ha_savepoint_count), SHOW_LONG_STATUS},
SHOW_LONG_STATUS}, {"Handler_savepoint_rollback",(char*) offsetof(STATUS_VAR, ha_savepoint_rollback_count), SHOW_LONG_STATUS},
{"Handler_read_prev", (char*) offsetof(STATUS_VAR, {"Handler_update", (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS},
ha_read_prev_count), {"Handler_write", (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS},
SHOW_LONG_STATUS},
{"Handler_read_rnd", (char*) offsetof(STATUS_VAR, ha_read_rnd_count),
SHOW_LONG_STATUS},
{"Handler_read_rnd_next", (char*) offsetof(STATUS_VAR,
ha_read_rnd_next_count),
SHOW_LONG_STATUS},
{"Handler_rollback", (char*) offsetof(STATUS_VAR, ha_rollback_count),
SHOW_LONG_STATUS},
{"Handler_update", (char*) offsetof(STATUS_VAR, ha_update_count),
SHOW_LONG_STATUS},
{"Handler_write", (char*) offsetof(STATUS_VAR, ha_write_count),
SHOW_LONG_STATUS},
#ifdef HAVE_INNOBASE_DB #ifdef HAVE_INNOBASE_DB
{"Innodb_", (char*) &innodb_status_variables, SHOW_VARS}, {"Innodb_", (char*) &innodb_status_variables, SHOW_VARS},
#endif /*HAVE_INNOBASE_DB*/ #endif /*HAVE_INNOBASE_DB*/
{"Key_blocks_not_flushed", (char*) &dflt_key_cache_var.global_blocks_changed, {"Key_blocks_not_flushed", (char*) &dflt_key_cache_var.global_blocks_changed, SHOW_KEY_CACHE_LONG},
SHOW_KEY_CACHE_LONG}, {"Key_blocks_unused", (char*) &dflt_key_cache_var.blocks_unused, SHOW_KEY_CACHE_CONST_LONG},
{"Key_blocks_unused", (char*) &dflt_key_cache_var.blocks_unused, {"Key_blocks_used", (char*) &dflt_key_cache_var.blocks_used, SHOW_KEY_CACHE_CONST_LONG},
SHOW_KEY_CACHE_CONST_LONG}, {"Key_read_requests", (char*) &dflt_key_cache_var.global_cache_r_requests, SHOW_KEY_CACHE_LONG},
{"Key_blocks_used", (char*) &dflt_key_cache_var.blocks_used, {"Key_reads", (char*) &dflt_key_cache_var.global_cache_read, SHOW_KEY_CACHE_LONG},
SHOW_KEY_CACHE_CONST_LONG}, {"Key_write_requests", (char*) &dflt_key_cache_var.global_cache_w_requests, SHOW_KEY_CACHE_LONG},
{"Key_read_requests", (char*) &dflt_key_cache_var.global_cache_r_requests, {"Key_writes", (char*) &dflt_key_cache_var.global_cache_write, SHOW_KEY_CACHE_LONG},
SHOW_KEY_CACHE_LONG},
{"Key_reads", (char*) &dflt_key_cache_var.global_cache_read,
SHOW_KEY_CACHE_LONG},
{"Key_write_requests", (char*) &dflt_key_cache_var.global_cache_w_requests,
SHOW_KEY_CACHE_LONG},
{"Key_writes", (char*) &dflt_key_cache_var.global_cache_write,
SHOW_KEY_CACHE_LONG},
{"Last_query_cost", (char*) &last_query_cost, SHOW_DOUBLE}, {"Last_query_cost", (char*) &last_query_cost, SHOW_DOUBLE},
{"Max_used_connections", (char*) &max_used_connections, SHOW_LONG}, {"Max_used_connections", (char*) &max_used_connections, SHOW_LONG},
#ifdef HAVE_NDBCLUSTER_DB #ifdef HAVE_NDBCLUSTER_DB
@ -5686,53 +5585,32 @@ struct show_var_st status_vars[]= {
{"Open_files", (char*) &my_file_opened, SHOW_LONG_CONST}, {"Open_files", (char*) &my_file_opened, SHOW_LONG_CONST},
{"Open_streams", (char*) &my_stream_opened, SHOW_LONG_CONST}, {"Open_streams", (char*) &my_stream_opened, SHOW_LONG_CONST},
{"Open_tables", (char*) 0, SHOW_OPENTABLES}, {"Open_tables", (char*) 0, SHOW_OPENTABLES},
{"Opened_tables", (char*) offsetof(STATUS_VAR, opened_tables), {"Opened_tables", (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS},
SHOW_LONG_STATUS},
#ifdef HAVE_QUERY_CACHE #ifdef HAVE_QUERY_CACHE
{"Qcache_free_blocks", (char*) &query_cache.free_memory_blocks, {"Qcache_free_blocks", (char*) &query_cache.free_memory_blocks, SHOW_LONG_CONST},
SHOW_LONG_CONST}, {"Qcache_free_memory", (char*) &query_cache.free_memory, SHOW_LONG_CONST},
{"Qcache_free_memory", (char*) &query_cache.free_memory,
SHOW_LONG_CONST},
{"Qcache_hits", (char*) &query_cache.hits, SHOW_LONG}, {"Qcache_hits", (char*) &query_cache.hits, SHOW_LONG},
{"Qcache_inserts", (char*) &query_cache.inserts, SHOW_LONG}, {"Qcache_inserts", (char*) &query_cache.inserts, SHOW_LONG},
{"Qcache_lowmem_prunes", (char*) &query_cache.lowmem_prunes, SHOW_LONG}, {"Qcache_lowmem_prunes", (char*) &query_cache.lowmem_prunes, SHOW_LONG},
{"Qcache_not_cached", (char*) &query_cache.refused, SHOW_LONG}, {"Qcache_not_cached", (char*) &query_cache.refused, SHOW_LONG},
{"Qcache_queries_in_cache", (char*) &query_cache.queries_in_cache, SHOW_LONG_CONST}, {"Qcache_queries_in_cache", (char*) &query_cache.queries_in_cache, SHOW_LONG_CONST},
{"Qcache_total_blocks", (char*) &query_cache.total_blocks, {"Qcache_total_blocks", (char*) &query_cache.total_blocks, SHOW_LONG_CONST},
SHOW_LONG_CONST},
#endif /*HAVE_QUERY_CACHE*/ #endif /*HAVE_QUERY_CACHE*/
{"Questions", (char*) 0, SHOW_QUESTION}, {"Questions", (char*) 0, SHOW_QUESTION},
{"Rpl_status", (char*) 0, SHOW_RPL_STATUS}, {"Rpl_status", (char*) 0, SHOW_RPL_STATUS},
{"Select_full_join", (char*) offsetof(STATUS_VAR, {"Select_full_join", (char*) offsetof(STATUS_VAR, select_full_join_count), SHOW_LONG_STATUS},
select_full_join_count), {"Select_full_range_join", (char*) offsetof(STATUS_VAR, select_full_range_join_count), SHOW_LONG_STATUS},
SHOW_LONG_STATUS}, {"Select_range", (char*) offsetof(STATUS_VAR, select_range_count), SHOW_LONG_STATUS},
{"Select_full_range_join", (char*) offsetof(STATUS_VAR, {"Select_range_check", (char*) offsetof(STATUS_VAR, select_range_check_count), SHOW_LONG_STATUS},
select_full_range_join_count), {"Select_scan", (char*) offsetof(STATUS_VAR, select_scan_count), SHOW_LONG_STATUS},
SHOW_LONG_STATUS},
{"Select_range", (char*) offsetof(STATUS_VAR,
select_range_count),
SHOW_LONG_STATUS},
{"Select_range_check", (char*) offsetof(STATUS_VAR,
select_range_check_count),
SHOW_LONG_STATUS},
{"Select_scan", (char*) offsetof(STATUS_VAR, select_scan_count),
SHOW_LONG_STATUS},
{"Slave_open_temp_tables", (char*) &slave_open_temp_tables, SHOW_LONG}, {"Slave_open_temp_tables", (char*) &slave_open_temp_tables, SHOW_LONG},
{"Slave_running", (char*) 0, SHOW_SLAVE_RUNNING}, {"Slave_running", (char*) 0, SHOW_SLAVE_RUNNING},
{"Slow_launch_threads", (char*) &slow_launch_threads, SHOW_LONG}, {"Slow_launch_threads", (char*) &slow_launch_threads, SHOW_LONG},
{"Slow_queries", (char*) offsetof(STATUS_VAR, long_query_count), {"Slow_queries", (char*) offsetof(STATUS_VAR, long_query_count), SHOW_LONG_STATUS},
SHOW_LONG_STATUS}, {"Sort_merge_passes", (char*) offsetof(STATUS_VAR, filesort_merge_passes), SHOW_LONG_STATUS},
{"Sort_merge_passes", (char*) offsetof(STATUS_VAR, {"Sort_range", (char*) offsetof(STATUS_VAR, filesort_range_count), SHOW_LONG_STATUS},
filesort_merge_passes), {"Sort_rows", (char*) offsetof(STATUS_VAR, filesort_rows), SHOW_LONG_STATUS},
SHOW_LONG_STATUS}, {"Sort_scan", (char*) offsetof(STATUS_VAR, filesort_scan_count), SHOW_LONG_STATUS},
{"Sort_range", (char*) offsetof(STATUS_VAR,
filesort_range_count),
SHOW_LONG_STATUS},
{"Sort_rows", (char*) offsetof(STATUS_VAR, filesort_rows),
SHOW_LONG_STATUS},
{"Sort_scan", (char*) offsetof(STATUS_VAR,
filesort_scan_count),
SHOW_LONG_STATUS},
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
{"Ssl_accept_renegotiates", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE}, {"Ssl_accept_renegotiates", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE},
{"Ssl_accepts", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT}, {"Ssl_accepts", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT},
@ -5760,6 +5638,9 @@ struct show_var_st status_vars[]= {
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
{"Table_locks_immediate", (char*) &locks_immediate, SHOW_LONG}, {"Table_locks_immediate", (char*) &locks_immediate, SHOW_LONG},
{"Table_locks_waited", (char*) &locks_waited, SHOW_LONG}, {"Table_locks_waited", (char*) &locks_waited, SHOW_LONG},
{"Tc_log_max_pages_used", (char*) &tc_log_max_pages_used, SHOW_LONG},
{"Tc_log_page_size", (char*) &tc_log_page_size, SHOW_LONG},
{"Tc_log_page_waits", (char*) &tc_log_page_waits, SHOW_LONG},
{"Threads_cached", (char*) &cached_thread_count, SHOW_LONG_CONST}, {"Threads_cached", (char*) &cached_thread_count, SHOW_LONG_CONST},
{"Threads_connected", (char*) &thread_count, SHOW_INT_CONST}, {"Threads_connected", (char*) &thread_count, SHOW_INT_CONST},
{"Threads_created", (char*) &thread_created, SHOW_LONG_CONST}, {"Threads_created", (char*) &thread_created, SHOW_LONG_CONST},
@ -5852,7 +5733,8 @@ static void mysql_init_variables(void)
mysql_home[0]= pidfile_name[0]= log_error_file[0]= 0; mysql_home[0]= pidfile_name[0]= log_error_file[0]= 0;
opt_log= opt_update_log= opt_bin_log= opt_slow_log= 0; opt_log= opt_update_log= opt_bin_log= opt_slow_log= 0;
opt_disable_networking= opt_skip_show_db=0; opt_disable_networking= opt_skip_show_db=0;
opt_logname= opt_update_logname= opt_binlog_index_name= opt_slow_logname=0; opt_logname= opt_update_logname= opt_binlog_index_name= opt_slow_logname= 0;
opt_tc_log_file= "tc.log"; // no hostname in tc_log file name !
opt_secure_auth= 0; opt_secure_auth= 0;
opt_bootstrap= opt_myisam_log= 0; opt_bootstrap= opt_myisam_log= 0;
mqh_used= 0; mqh_used= 0;
@ -6545,6 +6427,16 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
ha_open_options|=HA_OPEN_ABORT_IF_CRASHED; ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
break; break;
} }
case OPT_TC_HEURISTIC_RECOVER:
{
if ((tc_heuristic_recover=find_type(argument,
&tc_heuristic_recover_typelib, 2)) <=0)
{
fprintf(stderr, "Unknown option to tc-heuristic-recover: %s\n",argument);
exit(1);
}
break;
}
case OPT_SQL_MODE: case OPT_SQL_MODE:
{ {
sql_mode_str= argument; sql_mode_str= argument;

View file

@ -779,7 +779,7 @@ public:
} save_result; } save_result;
LEX_STRING base; /* for structs */ LEX_STRING base; /* for structs */
set_var(enum_var_type type_arg, sys_var *var_arg, LEX_STRING *base_name_arg, set_var(enum_var_type type_arg, sys_var *var_arg, const LEX_STRING *base_name_arg,
Item *value_arg) Item *value_arg)
:var(var_arg), type(type_arg), base(*base_name_arg) :var(var_arg), type(type_arg), base(*base_name_arg)
{ {

View file

@ -5306,6 +5306,18 @@ ER_CANNOT_USER
eng "Operation %s failed for %.256s" eng "Operation %s failed for %.256s"
ger "Das Kommando %s scheiterte für %.256s" ger "Das Kommando %s scheiterte für %.256s"
norwegian-ny "Operation %s failed for '%.256s'" norwegian-ny "Operation %s failed for '%.256s'"
ER_XAER_NOTA XAE04
eng "XAER_NOTA: Unknown XID"
ER_XAER_INVAL XAE05
eng "XAER_INVAL: Invalid arguments (or unsupported command)"
ER_XAER_RMFAIL XAE07
eng "XAER_RMFAIL: The command cannot be executed in the %.64s state"
ER_XAER_OUTSIDE XAE09
eng "XAER_OUTSIDE: Some work is done outside global transaction"
ER_XAER_RMERR XAE03
eng "XAER_RMERR: Fatal error occurred in the transaction branch - check your data for consistency"
ER_XA_RBROLLBACK XA100
eng "XA_RBROLLBACK: Transaction branch was rolled back"
ER_NONEXISTING_PROC_GRANT 42000 ER_NONEXISTING_PROC_GRANT 42000
eng "There is no such grant defined for user '%-.32s' on host '%-.64s' on routine '%-.64s'" eng "There is no such grant defined for user '%-.32s' on host '%-.64s' on routine '%-.64s'"
ER_PROC_AUTO_GRANT_FAIL ER_PROC_AUTO_GRANT_FAIL

View file

@ -1,15 +1,15 @@
/* Copyright (C) 2000-2003 MySQL AB /* Copyright (C) 2000-2003 MySQL AB
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@ -158,7 +158,7 @@ int init_slave()
sql_print_error("Failed to allocate memory for the master info structure"); sql_print_error("Failed to allocate memory for the master info structure");
goto err; goto err;
} }
if (init_master_info(active_mi,master_info_file,relay_log_info_file, if (init_master_info(active_mi,master_info_file,relay_log_info_file,
!master_host, (SLAVE_IO | SLAVE_SQL))) !master_host, (SLAVE_IO | SLAVE_SQL)))
{ {
@ -551,9 +551,9 @@ int purge_relay_logs(RELAY_LOG_INFO* rli, THD *thd, bool just_reset,
/* /*
Even if rli->inited==0, we still try to empty rli->master_log_* variables. Even if rli->inited==0, we still try to empty rli->master_log_* variables.
Indeed, rli->inited==0 does not imply that they already are empty. Indeed, rli->inited==0 does not imply that they already are empty.
It could be that slave's info initialization partly succeeded : It could be that slave's info initialization partly succeeded :
for example if relay-log.info existed but *relay-bin*.* for example if relay-log.info existed but *relay-bin*.*
have been manually removed, init_relay_log_info reads the old have been manually removed, init_relay_log_info reads the old
relay-log.info and fills rli->master_log_*, then init_relay_log_info relay-log.info and fills rli->master_log_*, then init_relay_log_info
checks for the existence of the relay log, this fails and checks for the existence of the relay log, this fails and
init_relay_log_info leaves rli->inited to 0. init_relay_log_info leaves rli->inited to 0.
@ -562,7 +562,7 @@ int purge_relay_logs(RELAY_LOG_INFO* rli, THD *thd, bool just_reset,
MASTER, the callers of purge_relay_logs, will delete bogus *.info files MASTER, the callers of purge_relay_logs, will delete bogus *.info files
or replace them with correct files), however if the user does SHOW SLAVE or replace them with correct files), however if the user does SHOW SLAVE
STATUS before START SLAVE, he will see old, confusing rli->master_log_*. STATUS before START SLAVE, he will see old, confusing rli->master_log_*.
In other words, we reinit rli->master_log_* for SHOW SLAVE STATUS In other words, we reinit rli->master_log_* for SHOW SLAVE STATUS
to display fine in any case. to display fine in any case.
*/ */
@ -671,11 +671,11 @@ int terminate_slave_thread(THD* thd, pthread_mutex_t* term_lock,
} }
} }
DBUG_ASSERT(thd != 0); DBUG_ASSERT(thd != 0);
THD_CHECK_SENTRY(thd);
/* /*
Is is criticate to test if the slave is running. Otherwise, we might Is is critical to test if the slave is running. Otherwise, we might
be referening freed memory trying to kick it be referening freed memory trying to kick it
*/ */
THD_CHECK_SENTRY(thd);
while (*slave_running) // Should always be true while (*slave_running) // Should always be true
{ {
@ -1674,7 +1674,8 @@ void end_master_info(MASTER_INFO* mi)
} }
int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname) static int init_relay_log_info(RELAY_LOG_INFO* rli,
const char* info_fname)
{ {
char fname[FN_REFLEN+128]; char fname[FN_REFLEN+128];
int info_fd; int info_fd;
@ -1682,7 +1683,7 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname)
int error = 0; int error = 0;
DBUG_ENTER("init_relay_log_info"); DBUG_ENTER("init_relay_log_info");
if (rli->inited) // Set if this function called if (rli->inited) // Set if this function called
DBUG_RETURN(0); DBUG_RETURN(0);
fn_format(fname, info_fname, mysql_data_home, "", 4+32); fn_format(fname, info_fname, mysql_data_home, "", 4+32);
pthread_mutex_lock(&rli->data_lock); pthread_mutex_lock(&rli->data_lock);
@ -1693,23 +1694,10 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname)
rli->log_space_limit= relay_log_space_limit; rli->log_space_limit= relay_log_space_limit;
rli->log_space_total= 0; rli->log_space_total= 0;
// TODO: make this work with multi-master
if (!opt_relay_logname)
{
char tmp[FN_REFLEN];
/*
TODO: The following should be using fn_format(); We just need to
first change fn_format() to cut the file name if it's too long.
*/
strmake(tmp,glob_hostname,FN_REFLEN-5);
strmov(strcend(tmp,'.'),"-relay-bin");
opt_relay_logname=my_strdup(tmp,MYF(MY_WME));
}
/* /*
The relay log will now be opened, as a SEQ_READ_APPEND IO_CACHE. The relay log will now be opened, as a SEQ_READ_APPEND IO_CACHE.
Note that the I/O thread flushes it to disk after writing every event, in Note that the I/O thread flushes it to disk after writing every
flush_master_info(mi, 1). event, in flush_master_info(mi, 1).
*/ */
/* /*
@ -1721,16 +1709,25 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname)
switch to using max_binlog_size for the relay log) and update switch to using max_binlog_size for the relay log) and update
rli->relay_log.max_size (and mysql_bin_log.max_size). rli->relay_log.max_size (and mysql_bin_log.max_size).
*/ */
if (open_log(&rli->relay_log, glob_hostname, opt_relay_logname,
"-relay-bin", opt_relaylog_index_name,
LOG_BIN, 1 /* read_append cache */,
0 /* starting from 5.0 we want relay logs to have auto events */,
max_relay_log_size ? max_relay_log_size : max_binlog_size))
{ {
pthread_mutex_unlock(&rli->data_lock); char buf[FN_REFLEN];
sql_print_error("Failed in open_log() called from init_relay_log_info()"); const char *ln;
DBUG_RETURN(1); ln= rli->relay_log.generate_name(opt_relay_logname, "-relay-bin",
1, buf);
/*
note, that if open() fails, we'll still have index file open
but a destructor will take care of that
*/
if (rli->relay_log.open_index_file(opt_relaylog_index_name, ln) ||
rli->relay_log.open(ln, LOG_BIN, 0, SEQ_READ_APPEND, 0,
(max_relay_log_size ? max_relay_log_size :
max_binlog_size), 1))
{
pthread_mutex_unlock(&rli->data_lock);
sql_print_error("Failed in open_log() called from init_relay_log_info()");
DBUG_RETURN(1);
}
} }
/* if file does not exist */ /* if file does not exist */
@ -1993,9 +1990,9 @@ void clear_until_condition(RELAY_LOG_INFO* rli)
int init_master_info(MASTER_INFO* mi, const char* master_info_fname, int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
const char* slave_info_fname, const char* slave_info_fname,
bool abort_if_no_master_info_file, bool abort_if_no_master_info_file,
int thread_mask) int thread_mask)
{ {
int fd,error; int fd,error;
char fname[FN_REFLEN+128]; char fname[FN_REFLEN+128];
@ -2009,7 +2006,7 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
last time. If this case pos_in_file would be set and we would last time. If this case pos_in_file would be set and we would
get a crash when trying to read the signature for the binary get a crash when trying to read the signature for the binary
relay log. relay log.
We only rewind the read position if we are starting the SQL We only rewind the read position if we are starting the SQL
thread. The handle_slave_sql thread assumes that the read thread. The handle_slave_sql thread assumes that the read
position is at the beginning of the file, and will read the position is at the beginning of the file, and will read the
@ -2035,7 +2032,7 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
fd = mi->fd; fd = mi->fd;
/* does master.info exist ? */ /* does master.info exist ? */
if (access(fname,F_OK)) if (access(fname,F_OK))
{ {
if (abort_if_no_master_info_file) if (abort_if_no_master_info_file)
@ -2071,7 +2068,7 @@ file '%s')", fname);
{ {
if (fd >= 0) if (fd >= 0)
reinit_io_cache(&mi->file, READ_CACHE, 0L,0,0); reinit_io_cache(&mi->file, READ_CACHE, 0L,0,0);
else else
{ {
if ((fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0 ) if ((fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0 )
{ {
@ -2091,52 +2088,52 @@ file '%s')", fname);
mi->fd = fd; mi->fd = fd;
int port, connect_retry, master_log_pos, ssl= 0, lines; int port, connect_retry, master_log_pos, ssl= 0, lines;
char *first_non_digit; char *first_non_digit;
/* /*
Starting from 4.1.x master.info has new format. Now its Starting from 4.1.x master.info has new format. Now its
first line contains number of lines in file. By reading this first line contains number of lines in file. By reading this
number we will be always distinguish to which version our number we will be always distinguish to which version our
master.info corresponds to. We can't simply count lines in master.info corresponds to. We can't simply count lines in
file since versions before 4.1.x could generate files with more file since versions before 4.1.x could generate files with more
lines than needed. lines than needed.
If first line doesn't contain a number or contain number less than If first line doesn't contain a number or contain number less than
14 then such file is treated like file from pre 4.1.1 version. 14 then such file is treated like file from pre 4.1.1 version.
There is no ambiguity when reading an old master.info, as before There is no ambiguity when reading an old master.info, as before
4.1.1, the first line contained the binlog's name, which is either 4.1.1, the first line contained the binlog's name, which is either
empty or has an extension (contains a '.'), so can't be confused empty or has an extension (contains a '.'), so can't be confused
with an integer. with an integer.
So we're just reading first line and trying to figure which version So we're just reading first line and trying to figure which version
is this. is this.
*/ */
/* /*
The first row is temporarily stored in mi->master_log_name, The first row is temporarily stored in mi->master_log_name,
if it is line count and not binlog name (new format) it will be if it is line count and not binlog name (new format) it will be
overwritten by the second row later. overwritten by the second row later.
*/ */
if (init_strvar_from_file(mi->master_log_name, if (init_strvar_from_file(mi->master_log_name,
sizeof(mi->master_log_name), &mi->file, sizeof(mi->master_log_name), &mi->file,
"")) ""))
goto errwithmsg; goto errwithmsg;
lines= strtoul(mi->master_log_name, &first_non_digit, 10); lines= strtoul(mi->master_log_name, &first_non_digit, 10);
if (mi->master_log_name[0]!='\0' && if (mi->master_log_name[0]!='\0' &&
*first_non_digit=='\0' && lines >= LINES_IN_MASTER_INFO_WITH_SSL) *first_non_digit=='\0' && lines >= LINES_IN_MASTER_INFO_WITH_SSL)
{ // Seems to be new format { // Seems to be new format
if (init_strvar_from_file(mi->master_log_name, if (init_strvar_from_file(mi->master_log_name,
sizeof(mi->master_log_name), &mi->file, "")) sizeof(mi->master_log_name), &mi->file, ""))
goto errwithmsg; goto errwithmsg;
} }
else else
lines= 7; lines= 7;
if (init_intvar_from_file(&master_log_pos, &mi->file, 4) || if (init_intvar_from_file(&master_log_pos, &mi->file, 4) ||
init_strvar_from_file(mi->host, sizeof(mi->host), &mi->file, init_strvar_from_file(mi->host, sizeof(mi->host), &mi->file,
master_host) || master_host) ||
init_strvar_from_file(mi->user, sizeof(mi->user), &mi->file, init_strvar_from_file(mi->user, sizeof(mi->user), &mi->file,
master_user) || master_user) ||
init_strvar_from_file(mi->password, SCRAMBLED_PASSWORD_CHAR_LENGTH+1, init_strvar_from_file(mi->password, SCRAMBLED_PASSWORD_CHAR_LENGTH+1,
&mi->file, master_password) || &mi->file, master_password) ||
init_intvar_from_file(&port, &mi->file, master_port) || init_intvar_from_file(&port, &mi->file, master_port) ||
@ -2144,17 +2141,17 @@ file '%s')", fname);
master_connect_retry)) master_connect_retry))
goto errwithmsg; goto errwithmsg;
/* /*
If file has ssl part use it even if we have server without If file has ssl part use it even if we have server without
SSL support. But these option will be ignored later when SSL support. But these option will be ignored later when
slave will try connect to master, so in this case warning slave will try connect to master, so in this case warning
is printed. is printed.
*/ */
if (lines >= LINES_IN_MASTER_INFO_WITH_SSL && if (lines >= LINES_IN_MASTER_INFO_WITH_SSL &&
(init_intvar_from_file(&ssl, &mi->file, master_ssl) || (init_intvar_from_file(&ssl, &mi->file, master_ssl) ||
init_strvar_from_file(mi->ssl_ca, sizeof(mi->ssl_ca), init_strvar_from_file(mi->ssl_ca, sizeof(mi->ssl_ca),
&mi->file, master_ssl_ca) || &mi->file, master_ssl_ca) ||
init_strvar_from_file(mi->ssl_capath, sizeof(mi->ssl_capath), init_strvar_from_file(mi->ssl_capath, sizeof(mi->ssl_capath),
&mi->file, master_ssl_capath) || &mi->file, master_ssl_capath) ||
init_strvar_from_file(mi->ssl_cert, sizeof(mi->ssl_cert), init_strvar_from_file(mi->ssl_cert, sizeof(mi->ssl_cert),
&mi->file, master_ssl_cert) || &mi->file, master_ssl_cert) ||
@ -2169,7 +2166,7 @@ file '%s')", fname);
"('%s') are ignored because this MySQL slave was compiled " "('%s') are ignored because this MySQL slave was compiled "
"without SSL support.", fname); "without SSL support.", fname);
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
/* /*
This has to be handled here as init_intvar_from_file can't handle This has to be handled here as init_intvar_from_file can't handle
my_off_t types my_off_t types
@ -2189,15 +2186,15 @@ file '%s')", fname);
mi->inited = 1; mi->inited = 1;
// now change cache READ -> WRITE - must do this before flush_master_info // now change cache READ -> WRITE - must do this before flush_master_info
reinit_io_cache(&mi->file, WRITE_CACHE,0L,0,1); reinit_io_cache(&mi->file, WRITE_CACHE, 0L, 0, 1);
if ((error=test(flush_master_info(mi, 1)))) if ((error=test(flush_master_info(mi, 1))))
sql_print_error("Failed to flush master info file"); sql_print_error("Failed to flush master info file");
pthread_mutex_unlock(&mi->data_lock); pthread_mutex_unlock(&mi->data_lock);
DBUG_RETURN(error); DBUG_RETURN(error);
errwithmsg: errwithmsg:
sql_print_error("Error reading master configuration"); sql_print_error("Error reading master configuration");
err: err:
if (fd >= 0) if (fd >= 0)
{ {
@ -2968,8 +2965,7 @@ static ulong read_event(MYSQL* mysql, MASTER_INFO *mi, bool* suppress_warnings)
*suppress_warnings= TRUE; *suppress_warnings= TRUE;
} }
else else
sql_print_error("Error reading packet from server: %s (\ sql_print_error("Error reading packet from server: %s ( server_errno=%d)",
server_errno=%d)",
mysql_error(mysql), mysql_errno(mysql)); mysql_error(mysql), mysql_errno(mysql));
return packet_error; return packet_error;
} }
@ -3115,17 +3111,17 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
{ {
/* /*
We acquire this mutex since we need it for all operations except We acquire this mutex since we need it for all operations except
event execution. But we will release it in places where we will event execution. But we will release it in places where we will
wait for something for example inside of next_event(). wait for something for example inside of next_event().
*/ */
pthread_mutex_lock(&rli->data_lock); pthread_mutex_lock(&rli->data_lock);
if (rli->until_condition!=RELAY_LOG_INFO::UNTIL_NONE && if (rli->until_condition!=RELAY_LOG_INFO::UNTIL_NONE &&
rli->is_until_satisfied()) rli->is_until_satisfied())
{ {
sql_print_error("Slave SQL thread stopped because it reached its" sql_print_error("Slave SQL thread stopped because it reached its"
" UNTIL position %ld", (long) rli->until_pos()); " UNTIL position %ld", (long) rli->until_pos());
/* /*
Setting abort_slave flag because we do not want additional message about Setting abort_slave flag because we do not want additional message about
error in query execution to be printed. error in query execution to be printed.
*/ */
@ -3133,11 +3129,11 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
pthread_mutex_unlock(&rli->data_lock); pthread_mutex_unlock(&rli->data_lock);
return 1; return 1;
} }
Log_event * ev = next_event(rli); Log_event * ev = next_event(rli);
DBUG_ASSERT(rli->sql_thd==thd); DBUG_ASSERT(rli->sql_thd==thd);
if (sql_slave_killed(thd,rli)) if (sql_slave_killed(thd,rli))
{ {
pthread_mutex_unlock(&rli->data_lock); pthread_mutex_unlock(&rli->data_lock);
@ -3162,13 +3158,13 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
events created by the creation/rotation of the relay log (remember that events created by the creation/rotation of the relay log (remember that
now the relay log starts with its Format_desc, has a Rotate etc). now the relay log starts with its Format_desc, has a Rotate etc).
*/ */
DBUG_PRINT("info",("type_code=%d, server_id=%d",type_code,ev->server_id)); DBUG_PRINT("info",("type_code=%d, server_id=%d",type_code,ev->server_id));
if ((ev->server_id == (uint32) ::server_id && if ((ev->server_id == (uint32) ::server_id &&
!replicate_same_server_id && !replicate_same_server_id &&
type_code != FORMAT_DESCRIPTION_EVENT) || type_code != FORMAT_DESCRIPTION_EVENT) ||
(rli->slave_skip_counter && (rli->slave_skip_counter &&
type_code != ROTATE_EVENT && type_code != STOP_EVENT && type_code != ROTATE_EVENT && type_code != STOP_EVENT &&
type_code != START_EVENT_V3 && type_code!= FORMAT_DESCRIPTION_EVENT)) type_code != START_EVENT_V3 && type_code!= FORMAT_DESCRIPTION_EVENT))
{ {
@ -3177,24 +3173,24 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
rli->inc_event_relay_log_pos(); rli->inc_event_relay_log_pos();
else else
{ {
rli->inc_group_relay_log_pos((type_code == ROTATE_EVENT || rli->inc_group_relay_log_pos((type_code == ROTATE_EVENT ||
type_code == STOP_EVENT || type_code == STOP_EVENT ||
type_code == FORMAT_DESCRIPTION_EVENT) ? type_code == FORMAT_DESCRIPTION_EVENT) ?
LL(0) : ev->log_pos, LL(0) : ev->log_pos,
1/* skip lock*/); 1/* skip lock*/);
flush_relay_log_info(rli); flush_relay_log_info(rli);
} }
/* /*
Protect against common user error of setting the counter to 1 Protect against common user error of setting the counter to 1
instead of 2 while recovering from an insert which used auto_increment, instead of 2 while recovering from an insert which used auto_increment,
rand or user var. rand or user var.
*/ */
if (rli->slave_skip_counter && if (rli->slave_skip_counter &&
!((type_code == INTVAR_EVENT || !((type_code == INTVAR_EVENT ||
type_code == RAND_EVENT || type_code == RAND_EVENT ||
type_code == USER_VAR_EVENT) && type_code == USER_VAR_EVENT) &&
rli->slave_skip_counter == 1) && rli->slave_skip_counter == 1) &&
/* /*
The events from ourselves which have something to do with the relay The events from ourselves which have something to do with the relay
log itself must be skipped, true, but they mustn't decrement log itself must be skipped, true, but they mustn't decrement
@ -3209,11 +3205,11 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
type_code == START_EVENT_V3 || type_code == FORMAT_DESCRIPTION_EVENT))) type_code == START_EVENT_V3 || type_code == FORMAT_DESCRIPTION_EVENT)))
--rli->slave_skip_counter; --rli->slave_skip_counter;
pthread_mutex_unlock(&rli->data_lock); pthread_mutex_unlock(&rli->data_lock);
delete ev; delete ev;
return 0; // avoid infinite update loops return 0; // avoid infinite update loops
} }
pthread_mutex_unlock(&rli->data_lock); pthread_mutex_unlock(&rli->data_lock);
thd->server_id = ev->server_id; // use the original server id for logging thd->server_id = ev->server_id; // use the original server id for logging
thd->set_time(); // time the query thd->set_time(); // time the query
thd->lex->current_select= 0; thd->lex->current_select= 0;
@ -3222,7 +3218,7 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
ev->thd = thd; ev->thd = thd;
exec_res = ev->exec_event(rli); exec_res = ev->exec_event(rli);
DBUG_ASSERT(rli->sql_thd==thd); DBUG_ASSERT(rli->sql_thd==thd);
/* /*
Format_description_log_event should not be deleted because it will be Format_description_log_event should not be deleted because it will be
used to read info about the relay log's format; it will be deleted when used to read info about the relay log's format; it will be deleted when
the SQL thread does not need it, i.e. when this thread terminates. the SQL thread does not need it, i.e. when this thread terminates.
@ -3257,17 +3253,17 @@ extern "C" pthread_handler_decl(handle_slave_io,arg)
{ {
THD *thd; // needs to be first for thread_stack THD *thd; // needs to be first for thread_stack
MYSQL *mysql; MYSQL *mysql;
MASTER_INFO *mi = (MASTER_INFO*)arg; MASTER_INFO *mi = (MASTER_INFO*)arg;
char llbuff[22]; char llbuff[22];
uint retry_count; uint retry_count;
// needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff // needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
my_thread_init(); my_thread_init();
DBUG_ENTER("handle_slave_io"); DBUG_ENTER("handle_slave_io");
#ifndef DBUG_OFF #ifndef DBUG_OFF
slave_begin: slave_begin:
#endif #endif
DBUG_ASSERT(mi->inited); DBUG_ASSERT(mi->inited);
mysql= NULL ; mysql= NULL ;
retry_count= 0; retry_count= 0;
@ -3276,10 +3272,10 @@ slave_begin:
/* Inform waiting threads that slave has started */ /* Inform waiting threads that slave has started */
mi->slave_run_id++; mi->slave_run_id++;
#ifndef DBUG_OFF #ifndef DBUG_OFF
mi->events_till_abort = abort_slave_event_count; mi->events_till_abort = abort_slave_event_count;
#endif #endif
thd= new THD; // note that contructor of THD uses DBUG_ ! thd= new THD; // note that contructor of THD uses DBUG_ !
THD_CHECK_SENTRY(thd); THD_CHECK_SENTRY(thd);
@ -3300,17 +3296,16 @@ slave_begin:
mi->abort_slave = 0; mi->abort_slave = 0;
pthread_mutex_unlock(&mi->run_lock); pthread_mutex_unlock(&mi->run_lock);
pthread_cond_broadcast(&mi->start_cond); pthread_cond_broadcast(&mi->start_cond);
DBUG_PRINT("master_info",("log_file_name: '%s' position: %s", DBUG_PRINT("master_info",("log_file_name: '%s' position: %s",
mi->master_log_name, mi->master_log_name,
llstr(mi->master_log_pos,llbuff))); llstr(mi->master_log_pos,llbuff)));
if (!(mi->mysql = mysql = mysql_init(NULL))) if (!(mi->mysql = mysql = mysql_init(NULL)))
{ {
sql_print_error("Slave I/O thread: error in mysql_init()"); sql_print_error("Slave I/O thread: error in mysql_init()");
goto err; goto err;
} }
thd->proc_info = "Connecting to master"; thd->proc_info = "Connecting to master";
// we can get killed during safe_connect // we can get killed during safe_connect
@ -3346,11 +3341,11 @@ connected:
if (register_slave_on_master(mysql) || update_slave_list(mysql, mi)) if (register_slave_on_master(mysql) || update_slave_list(mysql, mi))
goto err; goto err;
} }
DBUG_PRINT("info",("Starting reading binary log from master")); DBUG_PRINT("info",("Starting reading binary log from master"));
while (!io_slave_killed(thd,mi)) while (!io_slave_killed(thd,mi))
{ {
bool suppress_warnings= 0; bool suppress_warnings= 0;
thd->proc_info = "Requesting binlog dump"; thd->proc_info = "Requesting binlog dump";
if (request_dump(mysql, mi, &suppress_warnings)) if (request_dump(mysql, mi, &suppress_warnings))
{ {
@ -3361,7 +3356,7 @@ connected:
dump"); dump");
goto err; goto err;
} }
mi->slave_running= MYSQL_SLAVE_RUN_NOT_CONNECT; mi->slave_running= MYSQL_SLAVE_RUN_NOT_CONNECT;
thd->proc_info= "Waiting to reconnect after a failed binlog dump request"; thd->proc_info= "Waiting to reconnect after a failed binlog dump request";
#ifdef SIGNAL_WITH_VIO_CLOSE #ifdef SIGNAL_WITH_VIO_CLOSE
@ -3405,12 +3400,12 @@ after reconnect");
while (!io_slave_killed(thd,mi)) while (!io_slave_killed(thd,mi))
{ {
bool suppress_warnings= 0; bool suppress_warnings= 0;
/* /*
We say "waiting" because read_event() will wait if there's nothing to We say "waiting" because read_event() will wait if there's nothing to
read. But if there's something to read, it will not wait. The important read. But if there's something to read, it will not wait. The
thing is to not confuse users by saying "reading" whereas we're in fact important thing is to not confuse users by saying "reading" whereas
receiving nothing. we're in fact receiving nothing.
*/ */
thd->proc_info = "Waiting for master to send event"; thd->proc_info = "Waiting for master to send event";
ulong event_len = read_event(mysql, mi, &suppress_warnings); ulong event_len = read_event(mysql, mi, &suppress_warnings);
@ -3420,7 +3415,7 @@ after reconnect");
sql_print_information("Slave I/O thread killed while reading event"); sql_print_information("Slave I/O thread killed while reading event");
goto err; goto err;
} }
if (event_len == packet_error) if (event_len == packet_error)
{ {
uint mysql_error_number= mysql_errno(mysql); uint mysql_error_number= mysql_errno(mysql);
@ -3451,7 +3446,7 @@ max_allowed_packet",
goto err; // Don't retry forever goto err; // Don't retry forever
safe_sleep(thd,mi->connect_retry,(CHECK_KILLED_FUNC)io_slave_killed, safe_sleep(thd,mi->connect_retry,(CHECK_KILLED_FUNC)io_slave_killed,
(void*) mi); (void*) mi);
} }
if (io_slave_killed(thd,mi)) if (io_slave_killed(thd,mi))
{ {
if (global_system_variables.log_warnings) if (global_system_variables.log_warnings)
@ -3474,7 +3469,7 @@ reconnect done to recover from failed read");
} }
goto connected; goto connected;
} // if (event_len == packet_error) } // if (event_len == packet_error)
retry_count=0; // ok event, reset retry counter retry_count=0; // ok event, reset retry counter
thd->proc_info = "Queueing master event to the relay log"; thd->proc_info = "Queueing master event to the relay log";
if (queue_event(mi,(const char*)mysql->net.read_pos + 1, if (queue_event(mi,(const char*)mysql->net.read_pos + 1,
@ -3935,6 +3930,7 @@ static int process_io_rotate(MASTER_INFO *mi, Rotate_log_event *rev)
if (disconnect_slave_event_count) if (disconnect_slave_event_count)
events_till_disconnect++; events_till_disconnect++;
#endif #endif
/* /*
If description_event_for_queue is format <4, there is conversion in the If description_event_for_queue is format <4, there is conversion in the
relay log to the slave's format (4). And Rotate can mean upgrade or relay log to the slave's format (4). And Rotate can mean upgrade or
@ -3958,8 +3954,8 @@ static int process_io_rotate(MASTER_INFO *mi, Rotate_log_event *rev)
} }
/* /*
Reads a 3.23 event and converts it to the slave's format. This code was copied Reads a 3.23 event and converts it to the slave's format. This code was
from MySQL 4.0. copied from MySQL 4.0.
*/ */
static int queue_binlog_ver_1_event(MASTER_INFO *mi, const char *buf, static int queue_binlog_ver_1_event(MASTER_INFO *mi, const char *buf,
ulong event_len) ulong event_len)
@ -4222,9 +4218,9 @@ int queue_event(MASTER_INFO* mi,const char* buf, ulong event_len)
to write this event again). to write this event again).
*/ */
/* /*
We are the only thread which reads/writes description_event_for_queue. The We are the only thread which reads/writes description_event_for_queue.
relay_log struct does not move (though some members of it can change), so The relay_log struct does not move (though some members of it can
we needn't any lock (no rli->data_lock, no log lock). change), so we needn't any lock (no rli->data_lock, no log lock).
*/ */
Format_description_log_event* tmp; Format_description_log_event* tmp;
const char* errmsg; const char* errmsg;
@ -4615,7 +4611,7 @@ Log_event* next_event(RELAY_LOG_INFO* rli)
/* This is an assertion which sometimes fails, let's try to track it */ /* This is an assertion which sometimes fails, let's try to track it */
char llbuf1[22], llbuf2[22]; char llbuf1[22], llbuf2[22];
DBUG_PRINT("info", ("my_b_tell(cur_log)=%s rli->event_relay_log_pos=%s", DBUG_PRINT("info", ("my_b_tell(cur_log)=%s rli->event_relay_log_pos=%s",
llstr(my_b_tell(cur_log),llbuf1), llstr(my_b_tell(cur_log),llbuf1),
llstr(rli->event_relay_log_pos,llbuf2))); llstr(rli->event_relay_log_pos,llbuf2)));
DBUG_ASSERT(my_b_tell(cur_log) >= BIN_LOG_HEADER_SIZE); DBUG_ASSERT(my_b_tell(cur_log) >= BIN_LOG_HEADER_SIZE);
DBUG_ASSERT(my_b_tell(cur_log) == rli->event_relay_log_pos); DBUG_ASSERT(my_b_tell(cur_log) == rli->event_relay_log_pos);
@ -4635,7 +4631,7 @@ Log_event* next_event(RELAY_LOG_INFO* rli)
*/ */
if ((ev=Log_event::read_log_event(cur_log,0, if ((ev=Log_event::read_log_event(cur_log,0,
rli->relay_log.description_event_for_exec))) rli->relay_log.description_event_for_exec)))
{ {
DBUG_ASSERT(thd==rli->sql_thd); DBUG_ASSERT(thd==rli->sql_thd);
/* /*

View file

@ -1,15 +1,15 @@
/* Copyright (C) 2000-2003 MySQL AB /* Copyright (C) 2000-2003 MySQL AB
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@ -392,11 +392,11 @@ typedef struct st_master_info
my_bool ssl; // enables use of SSL connection if true my_bool ssl; // enables use of SSL connection if true
char ssl_ca[FN_REFLEN], ssl_capath[FN_REFLEN], ssl_cert[FN_REFLEN]; char ssl_ca[FN_REFLEN], ssl_capath[FN_REFLEN], ssl_cert[FN_REFLEN];
char ssl_cipher[FN_REFLEN], ssl_key[FN_REFLEN]; char ssl_cipher[FN_REFLEN], ssl_key[FN_REFLEN];
my_off_t master_log_pos; my_off_t master_log_pos;
File fd; // we keep the file open, so we need to remember the file pointer File fd; // we keep the file open, so we need to remember the file pointer
IO_CACHE file; IO_CACHE file;
pthread_mutex_t data_lock,run_lock; pthread_mutex_t data_lock,run_lock;
pthread_cond_t data_cond,start_cond,stop_cond; pthread_cond_t data_cond,start_cond,stop_cond;
THD *io_thd; THD *io_thd;
@ -412,7 +412,7 @@ typedef struct st_master_info
volatile bool abort_slave; volatile bool abort_slave;
volatile uint slave_running; volatile uint slave_running;
volatile ulong slave_run_id; volatile ulong slave_run_id;
/* /*
The difference in seconds between the clock of the master and the clock of The difference in seconds between the clock of the master and the clock of
the slave (second - first). It must be signed as it may be <0 or >0. the slave (second - first). It must be signed as it may be <0 or >0.
clock_diff_with_master is computed when the I/O thread starts; for this the clock_diff_with_master is computed when the I/O thread starts; for this the
@ -421,8 +421,8 @@ typedef struct st_master_info
clock_of_slave - last_timestamp_executed_by_SQL_thread - clock_diff_with_master clock_of_slave - last_timestamp_executed_by_SQL_thread - clock_diff_with_master
*/ */
long clock_diff_with_master; long clock_diff_with_master;
st_master_info() st_master_info()
:ssl(0), fd(-1), io_thd(0), inited(0), :ssl(0), fd(-1), io_thd(0), inited(0),
abort_slave(0),slave_running(0), slave_run_id(0) abort_slave(0),slave_running(0), slave_run_id(0)
@ -430,7 +430,7 @@ typedef struct st_master_info
host[0] = 0; user[0] = 0; password[0] = 0; host[0] = 0; user[0] = 0; password[0] = 0;
ssl_ca[0]= 0; ssl_capath[0]= 0; ssl_cert[0]= 0; ssl_ca[0]= 0; ssl_capath[0]= 0; ssl_cert[0]= 0;
ssl_cipher[0]= 0; ssl_key[0]= 0; ssl_cipher[0]= 0; ssl_key[0]= 0;
bzero((char*) &file, sizeof(file)); bzero((char*) &file, sizeof(file));
pthread_mutex_init(&run_lock, MY_MUTEX_INIT_FAST); pthread_mutex_init(&run_lock, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&data_lock, MY_MUTEX_INIT_FAST); pthread_mutex_init(&data_lock, MY_MUTEX_INIT_FAST);
@ -550,7 +550,6 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
bool abort_if_no_master_info_file, bool abort_if_no_master_info_file,
int thread_mask); int thread_mask);
void end_master_info(MASTER_INFO* mi); void end_master_info(MASTER_INFO* mi);
int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname);
void end_relay_log_info(RELAY_LOG_INFO* rli); void end_relay_log_info(RELAY_LOG_INFO* rli);
void lock_slave_threads(MASTER_INFO* mi); void lock_slave_threads(MASTER_INFO* mi);
void unlock_slave_threads(MASTER_INFO* mi); void unlock_slave_threads(MASTER_INFO* mi);

View file

@ -1243,7 +1243,7 @@ sp_instr_stmt::exec_stmt(THD *thd, LEX *lex)
thd->free_list= NULL; thd->free_list= NULL;
VOID(pthread_mutex_lock(&LOCK_thread_count)); VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_id= query_id++; thd->query_id= next_query_id();
VOID(pthread_mutex_unlock(&LOCK_thread_count)); VOID(pthread_mutex_unlock(&LOCK_thread_count));
reset_stmt_for_execute(thd, lex); reset_stmt_for_execute(thd, lex);

View file

@ -384,8 +384,8 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived,
{ {
TABLE *table, *next; TABLE *table, *next;
/* /*
Close all derived tables generated from questions like Close all derived tables generated in queries like
SELECT * from (select * from t1)) SELECT * FROM (SELECT * FROM t1)
*/ */
for (table= thd->derived_tables ; table ; table= next) for (table= thd->derived_tables ; table ; table= next)
{ {
@ -405,6 +405,18 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived,
mysql_unlock_tables(thd, thd->lock); mysql_unlock_tables(thd, thd->lock);
thd->lock=0; thd->lock=0;
} }
/*
assume handlers auto-commit (if some doesn't - transaction handling
in MySQL should be redesigned to support it; it's a big change,
and it's not worth it - better to commit explicitly only writing
transactions, read-only ones should better take care of themselves.
saves some work in 2pc too)
see also sql_parse.cc - dispatch_command()
*/
bzero(&thd->transaction.stmt, sizeof(thd->transaction.stmt));
if (!thd->active_transaction())
thd->transaction.xid.null();
/* VOID(pthread_sigmask(SIG_SETMASK,&thd->block_signals,NULL)); */ /* VOID(pthread_sigmask(SIG_SETMASK,&thd->block_signals,NULL)); */
if (!lock_in_use) if (!lock_in_use)
VOID(pthread_mutex_lock(&LOCK_open)); VOID(pthread_mutex_lock(&LOCK_open));
@ -1824,7 +1836,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type)
-1 - error -1 - error
NOTE NOTE
The lock will automaticly be freed by close_thread_tables() The lock will automaticaly be freed by close_thread_tables()
*/ */
int simple_open_n_lock_tables(THD *thd, TABLE_LIST *tables) int simple_open_n_lock_tables(THD *thd, TABLE_LIST *tables)
@ -1851,7 +1863,7 @@ int simple_open_n_lock_tables(THD *thd, TABLE_LIST *tables)
TRUE - error TRUE - error
NOTE NOTE
The lock will automaticly be freed by close_thread_tables() The lock will automaticaly be freed by close_thread_tables()
*/ */
bool open_and_lock_tables(THD *thd, TABLE_LIST *tables) bool open_and_lock_tables(THD *thd, TABLE_LIST *tables)

View file

@ -194,6 +194,7 @@ THD::THD()
file_id = 0; file_id = 0;
warn_id= 0; warn_id= 0;
db_charset= global_system_variables.collation_database; db_charset= global_system_variables.collation_database;
bzero(ha_data, sizeof(ha_data));
mysys_var=0; mysys_var=0;
#ifndef DBUG_OFF #ifndef DBUG_OFF
dbug_sentry=THD_SENTRY_MAGIC; dbug_sentry=THD_SENTRY_MAGIC;
@ -205,7 +206,6 @@ THD::THD()
ull=0; ull=0;
system_thread= cleanup_done= abort_on_warning= 0; system_thread= cleanup_done= abort_on_warning= 0;
peer_port= 0; // For SHOW PROCESSLIST peer_port= 0; // For SHOW PROCESSLIST
transaction.changed_tables = 0;
#ifdef __WIN__ #ifdef __WIN__
real_id = 0; real_id = 0;
#endif #endif
@ -240,9 +240,7 @@ THD::THD()
/* For user vars replication*/ /* For user vars replication*/
if (opt_bin_log) if (opt_bin_log)
my_init_dynamic_array(&user_var_events, my_init_dynamic_array(&user_var_events,
sizeof(BINLOG_USER_VAR_EVENT *), sizeof(BINLOG_USER_VAR_EVENT *), 16, 16);
16,
16);
else else
bzero((char*) &user_var_events, sizeof(user_var_events)); bzero((char*) &user_var_events, sizeof(user_var_events));
@ -252,26 +250,8 @@ THD::THD()
protocol_prep.init(this); protocol_prep.init(this);
tablespace_op=FALSE; tablespace_op=FALSE;
#ifdef USING_TRANSACTIONS
bzero((char*) &transaction,sizeof(transaction));
/*
Binlog is always open (if needed) before a THD is created (including
bootstrap).
*/
if (opt_using_transactions && mysql_bin_log.is_open())
{
if (open_cached_file(&transaction.trans_log,
mysql_tmpdir, LOG_PREFIX, binlog_cache_size,
MYF(MY_WME)))
killed= KILL_CONNECTION;
transaction.trans_log.end_of_file= max_binlog_cache_size;
}
#endif
init_sql_alloc(&transaction.mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
{
ulong tmp=sql_rnd_with_mutex(); ulong tmp=sql_rnd_with_mutex();
randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::query_id); randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::query_id);
}
} }
@ -320,9 +300,12 @@ void THD::init_for_queries()
reset_root_defaults(mem_root, variables.query_alloc_block_size, reset_root_defaults(mem_root, variables.query_alloc_block_size,
variables.query_prealloc_size); variables.query_prealloc_size);
#ifdef USING_TRANSACTIONS
reset_root_defaults(&transaction.mem_root, reset_root_defaults(&transaction.mem_root,
variables.trans_alloc_block_size, variables.trans_alloc_block_size,
variables.trans_prealloc_size); variables.trans_prealloc_size);
#endif
transaction.xid.null();
} }
@ -407,13 +390,8 @@ THD::~THD()
#endif #endif
if (!cleanup_done) if (!cleanup_done)
cleanup(); cleanup();
#ifdef USING_TRANSACTIONS
if (opt_using_transactions)
{
close_cached_file(&transaction.trans_log);
ha_close_connection(this); ha_close_connection(this);
}
#endif
sp_cache_clear(&sp_proc_cache); sp_cache_clear(&sp_proc_cache);
sp_cache_clear(&sp_func_cache); sp_cache_clear(&sp_func_cache);
@ -426,7 +404,9 @@ THD::~THD()
safeFree(ip); safeFree(ip);
safeFree(db); safeFree(db);
free_root(&warn_root,MYF(0)); free_root(&warn_root,MYF(0));
#ifdef USING_TRANSACTIONS
free_root(&transaction.mem_root,MYF(0)); free_root(&transaction.mem_root,MYF(0));
#endif
mysys_var=0; // Safety (shouldn't be needed) mysys_var=0; // Safety (shouldn't be needed)
pthread_mutex_destroy(&LOCK_delete); pthread_mutex_destroy(&LOCK_delete);
#ifndef DBUG_OFF #ifndef DBUG_OFF
@ -868,7 +848,6 @@ bool select_send::send_data(List<Item> &items)
InnoDB adaptive hash S-latch to avoid thread deadlocks if it was reserved InnoDB adaptive hash S-latch to avoid thread deadlocks if it was reserved
by thd by thd
*/ */
if (thd->transaction.all.innobase_tid)
ha_release_temporary_latches(thd); ha_release_temporary_latches(thd);
#endif #endif
@ -903,7 +882,6 @@ bool select_send::send_eof()
/* We may be passing the control from mysqld to the client: release the /* We may be passing the control from mysqld to the client: release the
InnoDB adaptive hash S-latch to avoid thread deadlocks if it was reserved InnoDB adaptive hash S-latch to avoid thread deadlocks if it was reserved
by thd */ by thd */
if (thd->transaction.all.innobase_tid)
ha_release_temporary_latches(thd); ha_release_temporary_latches(thd);
#endif #endif

View file

@ -43,6 +43,96 @@ enum enum_check_fields { CHECK_FIELD_IGNORE, CHECK_FIELD_WARN,
extern char internal_table_name[2]; extern char internal_table_name[2];
extern const char **errmesg; extern const char **errmesg;
#define TC_LOG_PAGE_SIZE 8192
#define TC_LOG_MIN_SIZE (3*TC_LOG_PAGE_SIZE)
extern uint opt_tc_log_size;
extern uint tc_log_max_pages_used;
extern uint tc_log_page_size;
extern uint tc_log_page_waits;
#define TC_HEURISTIC_RECOVER_COMMIT 1
#define TC_HEURISTIC_RECOVER_ROLLBACK 2
extern uint tc_heuristic_recover;
/*
Transaction Coordinator log - a base abstract class
for two different implementations
*/
class TC_LOG
{
public:
int using_heuristic_recover();
TC_LOG() {}
virtual ~TC_LOG() {}
virtual int open(const char *opt_name)=0;
virtual void close()=0;
virtual int log(THD *thd, my_xid xid)=0;
virtual void unlog(ulong cookie, my_xid xid)=0;
};
class TC_LOG_DUMMY: public TC_LOG // use it to disable the logging
{
public:
int open(const char *opt_name) { return 0; }
void close() { }
int log(THD *thd, my_xid xid) { return 1; }
void unlog(ulong cookie, my_xid xid) { }
};
class TC_LOG_MMAP: public TC_LOG
{
private:
typedef enum {
POOL, // page is in pool
ERROR, // last sync failed
DIRTY // new xids added since last sync
} PAGE_STATE;
typedef struct st_page {
struct st_page *next; // page a linked in a fifo queue
my_xid *start, *end; // usable area of a page
my_xid *ptr; // next xid will be written here
int size, free; // max and current number of free xid slots on the page
int waiters; // number of waiters on condition
PAGE_STATE state; // see above
pthread_mutex_t lock; // to access page data or control structure
pthread_cond_t cond; // to wait for a sync
} PAGE;
char logname[FN_REFLEN];
File fd;
uint file_length, npages, inited;
uchar *data;
struct st_page *pages, *syncing, *active, *pool, *pool_last;
/*
note that, e.g. LOCK_active is only used to protect
'active' pointer, to protect the content of the active page
one has to use active->lock.
Same for LOCK_pool and LOCK_sync
*/
pthread_mutex_t LOCK_active, LOCK_pool, LOCK_sync;
pthread_cond_t COND_pool, COND_active;
public:
TC_LOG_MMAP(): inited(0) {}
int open(const char *opt_name);
void close();
int log(THD *thd, my_xid xid);
void unlog(ulong cookie, my_xid xid);
int recover();
private:
void get_active_from_pool();
int sync();
int overflow();
};
extern TC_LOG *tc_log;
extern TC_LOG_MMAP tc_log_mmap;
extern TC_LOG_DUMMY tc_log_dummy;
/* log info errors */ /* log info errors */
#define LOG_INFO_EOF -1 #define LOG_INFO_EOF -1
#define LOG_INFO_IO -2 #define LOG_INFO_IO -2
@ -81,8 +171,18 @@ typedef struct st_user_var_events
class Log_event; class Log_event;
class MYSQL_LOG /*
{ TODO split MYSQL_LOG into base MYSQL_LOG and
MYSQL_QUERY_LOG, MYSQL_SLOW_LOG, MYSQL_BIN_LOG
most of the code from MYSQL_LOG should be in the MYSQL_BIN_LOG
only (TC_LOG included)
TODO use mmap instead of IO_CACHE for binlog
(mmap+fsync is two times faster than write+fsync)
*/
class MYSQL_LOG: public TC_LOG
{
private: private:
/* LOCK_log and LOCK_index are inited by init_pthread_objects() */ /* LOCK_log and LOCK_index are inited by init_pthread_objects() */
pthread_mutex_t LOCK_log, LOCK_index; pthread_mutex_t LOCK_log, LOCK_index;
@ -108,8 +208,8 @@ class MYSQL_LOG
etc. So in 4.x this is 1 for relay logs, 0 for binlogs. etc. So in 4.x this is 1 for relay logs, 0 for binlogs.
In 5.0 it's 0 for relay logs too! In 5.0 it's 0 for relay logs too!
*/ */
bool no_auto_events; bool no_auto_events;
/* /*
The max size before rotation (usable only if log_type == LOG_BIN: binary The max size before rotation (usable only if log_type == LOG_BIN: binary
logs and relay logs). logs and relay logs).
For a binlog, max_size should be max_binlog_size. For a binlog, max_size should be max_binlog_size.
@ -117,16 +217,26 @@ class MYSQL_LOG
max_binlog_size otherwise. max_binlog_size otherwise.
max_size is set in init(), and dynamically changed (when one does SET max_size is set in init(), and dynamically changed (when one does SET
GLOBAL MAX_BINLOG_SIZE|MAX_RELAY_LOG_SIZE) by fix_max_binlog_size and GLOBAL MAX_BINLOG_SIZE|MAX_RELAY_LOG_SIZE) by fix_max_binlog_size and
fix_max_relay_log_size). fix_max_relay_log_size).
*/ */
ulong max_size; ulong max_size;
ulong prepared_xids; /* for tc log - number of xids to remember */
pthread_mutex_t LOCK_prep_xids;
pthread_cond_t COND_prep_xids;
friend class Log_event; friend class Log_event;
public: public:
MYSQL_LOG(); MYSQL_LOG();
~MYSQL_LOG(); ~MYSQL_LOG();
/* int open(const char *opt_name);
void close();
int log(THD *thd, my_xid xid);
void unlog(ulong cookie, my_xid xid);
int recover(IO_CACHE *log, Format_description_log_event *fdle);
/*
These describe the log's format. This is used only for relay logs. These describe the log's format. This is used only for relay logs.
_for_exec is used by the SQL thread, _for_queue by the I/O thread. It's _for_exec is used by the SQL thread, _for_queue by the I/O thread. It's
necessary to have 2 distinct objects, because the I/O thread may be reading necessary to have 2 distinct objects, because the I/O thread may be reading
@ -145,7 +255,7 @@ public:
{ {
#ifndef DBUG_OFF #ifndef DBUG_OFF
char buf1[22],buf2[22]; char buf1[22],buf2[22];
#endif #endif
DBUG_ENTER("harvest_bytes_written"); DBUG_ENTER("harvest_bytes_written");
(*counter)+=bytes_written; (*counter)+=bytes_written;
DBUG_PRINT("info",("counter: %s bytes_written: %s", llstr(*counter,buf1), DBUG_PRINT("info",("counter: %s bytes_written: %s", llstr(*counter,buf1),
@ -162,18 +272,36 @@ public:
bool no_auto_events_arg, ulong max_size); bool no_auto_events_arg, ulong max_size);
void init_pthread_objects(); void init_pthread_objects();
void cleanup(); void cleanup();
bool open(const char *log_name,enum_log_type log_type, bool open(const char *log_name,
const char *new_name, const char *index_file_name_arg, enum_log_type log_type,
const char *new_name,
enum cache_type io_cache_type_arg, enum cache_type io_cache_type_arg,
bool no_auto_events_arg, ulong max_size, bool no_auto_events_arg, ulong max_size,
bool null_created); bool null_created);
const char *generate_name(const char *log_name, const char *suffix,
bool strip_ext, char *buff);
/* simplified open_xxx wrappers for the gigantic open above */
bool open_query_log(const char *log_name)
{
char buf[FN_REFLEN];
return open(generate_name(log_name, ".log", 0, buf),
LOG_NORMAL, 0, WRITE_CACHE, 0, 0, 0);
}
bool open_slow_log(const char *log_name)
{
char buf[FN_REFLEN];
return open(generate_name(log_name, "-slow.log", 0, buf),
LOG_NORMAL, 0, WRITE_CACHE, 0, 0, 0);
}
bool open_index_file(const char *index_file_name_arg,
const char *log_name);
void new_file(bool need_lock= 1); void new_file(bool need_lock= 1);
bool write(THD *thd, enum enum_server_command command, bool write(THD *thd, enum enum_server_command command,
const char *format,...); const char *format,...);
bool write(THD *thd, const char *query, uint query_length, bool write(THD *thd, const char *query, uint query_length,
time_t query_start=0); time_t query_start=0);
bool write(Log_event* event_info); // binary log write bool write(Log_event* event_info); // binary log write
bool write(THD *thd, IO_CACHE *cache, bool commit_or_rollback); bool write(THD *thd, IO_CACHE *cache);
/* /*
v stands for vector v stands for vector
@ -181,20 +309,18 @@ public:
*/ */
bool appendv(const char* buf,uint len,...); bool appendv(const char* buf,uint len,...);
bool append(Log_event* ev); bool append(Log_event* ev);
int generate_new_name(char *new_name,const char *old_name); int generate_new_name(char *new_name,const char *old_name);
void make_log_name(char* buf, const char* log_ident); void make_log_name(char* buf, const char* log_ident);
bool is_active(const char* log_file_name); bool is_active(const char* log_file_name);
int update_log_index(LOG_INFO* linfo, bool need_update_threads); int update_log_index(LOG_INFO* linfo, bool need_update_threads);
int purge_logs(const char *to_log, bool included, int purge_logs(const char *to_log, bool included,
bool need_mutex, bool need_update_threads, bool need_mutex, bool need_update_threads,
ulonglong *decrease_log_space); ulonglong *decrease_log_space);
int purge_logs_before_date(time_t purge_time); int purge_logs_before_date(time_t purge_time);
int purge_first_log(struct st_relay_log_info* rli, bool included); int purge_first_log(struct st_relay_log_info* rli, bool included);
bool reset_logs(THD* thd); bool reset_logs(THD* thd);
void close(uint exiting); void close(uint exiting);
bool cut_spurious_tail();
void report_pos_in_innodb();
// iterating through the log index file // iterating through the log index file
int find_log_pos(LOG_INFO* linfo, const char* log_name, int find_log_pos(LOG_INFO* linfo, const char* log_name,
@ -487,6 +613,10 @@ typedef struct system_status_var
ulong ha_rollback_count; ulong ha_rollback_count;
ulong ha_update_count; ulong ha_update_count;
ulong ha_write_count; ulong ha_write_count;
ulong ha_prepare_count;
ulong ha_discover_count;
ulong ha_savepoint_count;
ulong ha_savepoint_rollback_count;
/* KEY_CACHE parts. These are copies of the original */ /* KEY_CACHE parts. These are copies of the original */
ulong key_blocks_changed; ulong key_blocks_changed;
@ -765,6 +895,14 @@ private:
Statement *last_found_statement; Statement *last_found_statement;
}; };
struct st_savepoint {
struct st_savepoint *prev;
char *name;
uint length, nht;
};
enum xa_states {XA_NOTR=0, XA_ACTIVE, XA_IDLE, XA_PREPARED};
extern const char *xa_state_names[];
/* /*
A registry for item tree transformations performed during A registry for item tree transformations performed during
@ -907,15 +1045,15 @@ public:
thr_lock_type update_lock_default; thr_lock_type update_lock_default;
delayed_insert *di; delayed_insert *di;
my_bool tablespace_op; /* This is TRUE in DISCARD/IMPORT TABLESPACE */ my_bool tablespace_op; /* This is TRUE in DISCARD/IMPORT TABLESPACE */
/* container for handler's private per-connection data */
void *ha_data[MAX_HA];
struct st_transactions { struct st_transactions {
IO_CACHE trans_log; // Inited ONLY if binlog is open ! SAVEPOINT *savepoints;
THD_TRANS all; // Trans since BEGIN WORK THD_TRANS all; // Trans since BEGIN WORK
THD_TRANS stmt; // Trans for current statement THD_TRANS stmt; // Trans for current statement
uint bdb_lock_count;
#ifdef HAVE_NDBCLUSTER_DB
void* thd_ndb;
#endif
bool on; bool on;
XID xid;
enum xa_states xa_state;
/* /*
Tables changed in transaction (that must be invalidated in query cache). Tables changed in transaction (that must be invalidated in query cache).
List contain only transactional tables, that not invalidated in query List contain only transactional tables, that not invalidated in query
@ -926,8 +1064,18 @@ public:
void cleanup() void cleanup()
{ {
changed_tables = 0; changed_tables = 0;
#ifdef USING_TRANSACTIONS
free_root(&mem_root,MYF(MY_KEEP_PREALLOC)); free_root(&mem_root,MYF(MY_KEEP_PREALLOC));
#endif
} }
#ifdef USING_TRANSACTIONS
st_transactions()
{
bzero((char*)this, sizeof(*this));
xid.null();
init_sql_alloc(&mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
}
#endif
} transaction; } transaction;
Field *dupp_field; Field *dupp_field;
#ifndef __WIN__ #ifndef __WIN__
@ -1126,7 +1274,7 @@ public:
inline ulonglong insert_id(void) inline ulonglong insert_id(void)
{ {
if (!last_insert_id_used) if (!last_insert_id_used)
{ {
last_insert_id_used=1; last_insert_id_used=1;
current_insert_id=last_insert_id; current_insert_id=last_insert_id;
} }
@ -1135,13 +1283,11 @@ public:
inline ulonglong found_rows(void) inline ulonglong found_rows(void)
{ {
return limit_found_rows; return limit_found_rows;
} }
inline bool active_transaction() inline bool active_transaction()
{ {
#ifdef USING_TRANSACTIONS #ifdef USING_TRANSACTIONS
return (transaction.all.bdb_tid != 0 || return server_status & SERVER_STATUS_IN_TRANS;
transaction.all.innodb_active_trans != 0 ||
transaction.all.ndb_tid != 0);
#else #else
return 0; return 0;
#endif #endif
@ -1665,7 +1811,7 @@ class multi_delete :public select_result_interceptor
ha_rows deleted, found; ha_rows deleted, found;
uint num_of_tables; uint num_of_tables;
int error; int error;
bool do_delete, transactional_tables, log_delayed, normal_tables; bool do_delete, transactional_tables, normal_tables;
public: public:
multi_delete(THD *thd, TABLE_LIST *dt, uint num_of_tables); multi_delete(THD *thd, TABLE_LIST *dt, uint num_of_tables);
~multi_delete(); ~multi_delete();
@ -1692,7 +1838,7 @@ class multi_update :public select_result_interceptor
uint table_count; uint table_count;
Copy_field *copy_field; Copy_field *copy_field;
enum enum_duplicates handle_duplicates; enum enum_duplicates handle_duplicates;
bool do_update, trans_safe, transactional_tables, log_delayed, ignore; bool do_update, trans_safe, transactional_tables, ignore;
public: public:
multi_update(THD *thd_arg, TABLE_LIST *ut, TABLE_LIST *leaves_list, multi_update(THD *thd_arg, TABLE_LIST *ut, TABLE_LIST *leaves_list,

View file

@ -36,8 +36,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
TABLE *table; TABLE *table;
SQL_SELECT *select=0; SQL_SELECT *select=0;
READ_RECORD info; READ_RECORD info;
bool using_limit=limit != HA_POS_ERROR; bool using_limit=limit != HA_POS_ERROR;
bool transactional_table, log_delayed, safe_update, const_cond; bool transactional_table, safe_update, const_cond;
ha_rows deleted; ha_rows deleted;
SELECT_LEX *select_lex= &thd->lex->select_lex; SELECT_LEX *select_lex= &thd->lex->select_lex;
DBUG_ENTER("mysql_delete"); DBUG_ENTER("mysql_delete");
@ -233,7 +233,6 @@ cleanup:
delete select; delete select;
transactional_table= table->file->has_transactions(); transactional_table= table->file->has_transactions();
log_delayed= (transactional_table || table->s->tmp_table);
/* /*
We write to the binary log even if we deleted no row, because maybe the We write to the binary log even if we deleted no row, because maybe the
user is using this command to ensure that a table is clean on master *and user is using this command to ensure that a table is clean on master *and
@ -249,11 +248,11 @@ cleanup:
if (error <= 0) if (error <= 0)
thd->clear_error(); thd->clear_error();
Query_log_event qinfo(thd, thd->query, thd->query_length, Query_log_event qinfo(thd, thd->query, thd->query_length,
log_delayed, FALSE); transactional_table, FALSE);
if (mysql_bin_log.write(&qinfo) && transactional_table) if (mysql_bin_log.write(&qinfo) && transactional_table)
error=1; error=1;
} }
if (!log_delayed) if (!transactional_table)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE; thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
} }
if (transactional_table) if (transactional_table)
@ -398,7 +397,7 @@ multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt,
uint num_of_tables_arg) uint num_of_tables_arg)
: delete_tables(dt), thd(thd_arg), deleted(0), found(0), : delete_tables(dt), thd(thd_arg), deleted(0), found(0),
num_of_tables(num_of_tables_arg), error(0), num_of_tables(num_of_tables_arg), error(0),
do_delete(0), transactional_tables(0), log_delayed(0), normal_tables(0) do_delete(0), transactional_tables(0), normal_tables(0)
{ {
tempfiles = (Unique **) sql_calloc(sizeof(Unique *) * (num_of_tables-1)); tempfiles = (Unique **) sql_calloc(sizeof(Unique *) * (num_of_tables-1));
} }
@ -445,9 +444,7 @@ multi_delete::initialize_tables(JOIN *join)
tbl->no_cache= 1; tbl->no_cache= 1;
tbl->used_keys.clear_all(); tbl->used_keys.clear_all();
if (tbl->file->has_transactions()) if (tbl->file->has_transactions())
log_delayed= transactional_tables= 1; transactional_tables= 1;
else if (tbl->s->tmp_table != NO_TMP_TABLE)
log_delayed= 1;
else else
normal_tables= 1; normal_tables= 1;
} }
@ -670,14 +667,14 @@ bool multi_delete::send_eof()
if (error <= 0) if (error <= 0)
thd->clear_error(); thd->clear_error();
Query_log_event qinfo(thd, thd->query, thd->query_length, Query_log_event qinfo(thd, thd->query, thd->query_length,
log_delayed, FALSE); transactional_tables, FALSE);
if (mysql_bin_log.write(&qinfo) && !normal_tables) if (mysql_bin_log.write(&qinfo) && !normal_tables)
local_error=1; // Log write failed: roll back the SQL statement local_error=1; // Log write failed: roll back the SQL statement
} }
if (!log_delayed) if (!transactional_tables)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE; thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
} }
/* Commit or rollback the current SQL statement */ /* Commit or rollback the current SQL statement */
if (transactional_tables) if (transactional_tables)
if (ha_autocommit_or_rollback(thd,local_error > 0)) if (ha_autocommit_or_rollback(thd,local_error > 0))
local_error=1; local_error=1;
@ -736,7 +733,7 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
If we return here we will not have logged the truncation to the bin log If we return here we will not have logged the truncation to the bin log
and we will not send_ok() to the client. and we will not send_ok() to the client.
*/ */
goto end; goto end;
} }
(void) sprintf(path,"%s/%s/%s%s",mysql_data_home,table_list->db, (void) sprintf(path,"%s/%s/%s%s",mysql_data_home,table_list->db,
@ -768,7 +765,7 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
*fn_ext(path)=0; // Remove the .frm extension *fn_ext(path)=0; // Remove the .frm extension
error= ha_create_table(path,&create_info,1); error= ha_create_table(path,&create_info,1);
query_cache_invalidate3(thd, table_list, 0); query_cache_invalidate3(thd, table_list, 0);
end: end:
if (!dont_send_ok) if (!dont_send_ok)
@ -779,7 +776,7 @@ end:
{ {
thd->clear_error(); thd->clear_error();
Query_log_event qinfo(thd, thd->query, thd->query_length, Query_log_event qinfo(thd, thd->query, thd->query_length,
thd->tmp_table, FALSE); 0, FALSE);
mysql_bin_log.write(&qinfo); mysql_bin_log.write(&qinfo);
} }
send_ok(thd); // This should return record count send_ok(thd); // This should return record count

View file

@ -168,7 +168,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
runs without --log-update or --log-bin). runs without --log-update or --log-bin).
*/ */
bool log_on= (thd->options & OPTION_BIN_LOG) || (!(thd->master_access & SUPER_ACL)); bool log_on= (thd->options & OPTION_BIN_LOG) || (!(thd->master_access & SUPER_ACL));
bool transactional_table, log_delayed; bool transactional_table;
uint value_count; uint value_count;
ulong counter = 1; ulong counter = 1;
ulonglong id; ulonglong id;
@ -433,7 +433,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
/* /*
Invalidate the table in the query cache if something changed. Invalidate the table in the query cache if something changed.
For the transactional algorithm to work the invalidation must be For the transactional algorithm to work the invalidation must be
before binlog writing and ha_autocommit_... before binlog writing and ha_autocommit_or_rollback
*/ */
if (info.copied || info.deleted || info.updated) if (info.copied || info.deleted || info.updated)
{ {
@ -442,7 +442,6 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
transactional_table= table->file->has_transactions(); transactional_table= table->file->has_transactions();
log_delayed= (transactional_table || table->s->tmp_table);
if ((info.copied || info.deleted || info.updated) && if ((info.copied || info.deleted || info.updated) &&
(error <= 0 || !transactional_table)) (error <= 0 || !transactional_table))
{ {
@ -451,11 +450,11 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
if (error <= 0) if (error <= 0)
thd->clear_error(); thd->clear_error();
Query_log_event qinfo(thd, thd->query, thd->query_length, Query_log_event qinfo(thd, thd->query, thd->query_length,
log_delayed, FALSE); transactional_table, FALSE);
if (mysql_bin_log.write(&qinfo) && transactional_table) if (mysql_bin_log.write(&qinfo) && transactional_table)
error=1; error=1;
} }
if (!log_delayed) if (!transactional_table)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE; thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
} }
if (transactional_table) if (transactional_table)
@ -1974,7 +1973,7 @@ bool select_insert::send_eof()
/* /*
We must invalidate the table in the query cache before binlog writing We must invalidate the table in the query cache before binlog writing
and ha_autocommit_... and ha_autocommit_or_rollback
*/ */
if (info.copied || info.deleted || info.updated) if (info.copied || info.deleted || info.updated)

View file

@ -141,7 +141,7 @@ void lex_start(THD *thd, uchar *buf,uint length)
lex->view_prepare_mode= FALSE; lex->view_prepare_mode= FALSE;
lex->derived_tables= 0; lex->derived_tables= 0;
lex->lock_option= TL_READ; lex->lock_option= TL_READ;
lex->found_colon= 0; lex->found_semicolon= 0;
lex->safe_to_cache_query= 1; lex->safe_to_cache_query= 1;
lex->time_zone_tables_used= 0; lex->time_zone_tables_used= 0;
lex->leaf_tables_insert= lex->proc_table= lex->query_tables= 0; lex->leaf_tables_insert= lex->proc_table= lex->query_tables= 0;
@ -970,7 +970,7 @@ int yylex(void *arg, void *yythd)
(thd->command != COM_PREPARE)) (thd->command != COM_PREPARE))
{ {
lex->safe_to_cache_query= 0; lex->safe_to_cache_query= 0;
lex->found_colon= (char*) lex->ptr; lex->found_semicolon=(char*) lex->ptr;
thd->server_status|= SERVER_MORE_RESULTS_EXISTS; thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
lex->next_state= MY_LEX_END; lex->next_state= MY_LEX_END;
return (END_OF_INPUT); return (END_OF_INPUT);

View file

@ -87,6 +87,8 @@ enum enum_sql_command {
SQLCOM_PREPARE, SQLCOM_EXECUTE, SQLCOM_DEALLOCATE_PREPARE, SQLCOM_PREPARE, SQLCOM_EXECUTE, SQLCOM_DEALLOCATE_PREPARE,
SQLCOM_CREATE_VIEW, SQLCOM_DROP_VIEW, SQLCOM_CREATE_VIEW, SQLCOM_DROP_VIEW,
SQLCOM_CREATE_TRIGGER, SQLCOM_DROP_TRIGGER, SQLCOM_CREATE_TRIGGER, SQLCOM_DROP_TRIGGER,
SQLCOM_XA_START, SQLCOM_XA_END, SQLCOM_XA_PREPARE,
SQLCOM_XA_COMMIT, SQLCOM_XA_ROLLBACK, SQLCOM_XA_RECOVER,
/* This should be the last !!! */ /* This should be the last !!! */
SQLCOM_END SQLCOM_END
@ -635,6 +637,9 @@ struct st_trg_chistics
extern sys_var_long_ptr trg_new_row_fake_var; extern sys_var_long_ptr trg_new_row_fake_var;
enum xa_option_words {XA_NONE, XA_JOIN, XA_RESUME, XA_ONE_PHASE,
XA_SUSPEND, XA_FOR_MIGRATE};
/* The state of the lex parsing. This is saved in the THD struct */ /* The state of the lex parsing. This is saved in the THD struct */
typedef struct st_lex typedef struct st_lex
@ -654,12 +659,12 @@ typedef struct st_lex
char *backup_dir; /* For RESTORE/BACKUP */ char *backup_dir; /* For RESTORE/BACKUP */
char* to_log; /* For PURGE MASTER LOGS TO */ char* to_log; /* For PURGE MASTER LOGS TO */
char* x509_subject,*x509_issuer,*ssl_cipher; char* x509_subject,*x509_issuer,*ssl_cipher;
char* found_colon; /* For multi queries - next query */ char* found_semicolon; /* For multi queries - next query */
String *wild; String *wild;
sql_exchange *exchange; sql_exchange *exchange;
select_result *result; select_result *result;
Item *default_value, *on_update_value; Item *default_value, *on_update_value;
LEX_STRING *comment, name_and_length; LEX_STRING comment, ident;
LEX_USER *grant_user; LEX_USER *grant_user;
gptr yacc_yyss,yacc_yyvs; gptr yacc_yyss,yacc_yyvs;
THD *thd; THD *thd;
@ -689,7 +694,6 @@ typedef struct st_lex
List<LEX_STRING> view_list; // view list (list of field names in view) List<LEX_STRING> view_list; // view list (list of field names in view)
SQL_LIST proc_list, auxilliary_table_list, save_list; SQL_LIST proc_list, auxilliary_table_list, save_list;
create_field *last_field; create_field *last_field;
char *savepoint_name; // Transaction savepoint id
udf_func udf; udf_func udf;
HA_CHECK_OPT check_opt; // check/repair options HA_CHECK_OPT check_opt; // check/repair options
HA_CREATE_INFO create_info; HA_CREATE_INFO create_info;
@ -703,7 +707,10 @@ typedef struct st_lex
enum enum_duplicates duplicates; enum enum_duplicates duplicates;
enum enum_tx_isolation tx_isolation; enum enum_tx_isolation tx_isolation;
enum enum_ha_read_modes ha_read_mode; enum enum_ha_read_modes ha_read_mode;
union {
enum ha_rkey_function ha_rkey_mode; enum ha_rkey_function ha_rkey_mode;
enum xa_option_words xa_opt;
};
enum enum_var_type option_type; enum enum_var_type option_type;
enum enum_view_create_mode create_view_mode; enum enum_view_create_mode create_view_mode;
enum enum_drop_mode drop_mode; enum enum_drop_mode drop_mode;

View file

@ -105,7 +105,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
char *tdb= thd->db ? thd->db : db; // Result is never null char *tdb= thd->db ? thd->db : db; // Result is never null
ulong skip_lines= ex->skip_lines; ulong skip_lines= ex->skip_lines;
int res; int res;
bool transactional_table, log_delayed; bool transactional_table;
DBUG_ENTER("mysql_load"); DBUG_ENTER("mysql_load");
#ifdef EMBEDDED_LIBRARY #ifdef EMBEDDED_LIBRARY
@ -133,7 +133,6 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
} }
table= table_list->table; table= table_list->table;
transactional_table= table->file->has_transactions(); transactional_table= table->file->has_transactions();
log_delayed= (transactional_table || table->s->tmp_table);
if (!fields.elements) if (!fields.elements)
{ {
@ -263,7 +262,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
lf_info.handle_dup = handle_duplicates; lf_info.handle_dup = handle_duplicates;
lf_info.wrote_create_file = 0; lf_info.wrote_create_file = 0;
lf_info.last_pos_in_file = HA_POS_ERROR; lf_info.last_pos_in_file = HA_POS_ERROR;
lf_info.log_delayed= log_delayed; lf_info.log_delayed= transactional_table;
read_info.set_io_cache_arg((void*) &lf_info); read_info.set_io_cache_arg((void*) &lf_info);
} }
#endif /*!EMBEDDED_LIBRARY*/ #endif /*!EMBEDDED_LIBRARY*/
@ -365,7 +364,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
/* If the file was not empty, wrote_create_file is true */ /* If the file was not empty, wrote_create_file is true */
if (lf_info.wrote_create_file) if (lf_info.wrote_create_file)
{ {
Delete_file_log_event d(thd, db, log_delayed); Delete_file_log_event d(thd, db, transactional_table);
mysql_bin_log.write(&d); mysql_bin_log.write(&d);
} }
} }
@ -377,7 +376,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
(ulong) (info.records - info.copied), (ulong) thd->cuted_fields); (ulong) (info.records - info.copied), (ulong) thd->cuted_fields);
send_ok(thd,info.copied+info.deleted,0L,name); send_ok(thd,info.copied+info.deleted,0L,name);
if (!log_delayed) if (!transactional_table)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE; thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
if (mysql_bin_log.is_open()) if (mysql_bin_log.is_open())
@ -387,16 +386,16 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
block will be logged only after Execute_load_log_event (which is wrong), block will be logged only after Execute_load_log_event (which is wrong),
when read_info is destroyed. when read_info is destroyed.
*/ */
read_info.end_io_cache(); read_info.end_io_cache();
if (lf_info.wrote_create_file) if (lf_info.wrote_create_file)
{ {
Execute_load_log_event e(thd, db, log_delayed); Execute_load_log_event e(thd, db, transactional_table);
mysql_bin_log.write(&e); mysql_bin_log.write(&e);
} }
} }
#endif /*!EMBEDDED_LIBRARY*/ #endif /*!EMBEDDED_LIBRARY*/
if (transactional_table) if (transactional_table)
error=ha_autocommit_or_rollback(thd,error); error=ha_autocommit_or_rollback(thd,error);
err: err:
if (thd->lock) if (thd->lock)
@ -404,7 +403,7 @@ err:
mysql_unlock_tables(thd, thd->lock); mysql_unlock_tables(thd, thd->lock);
thd->lock=0; thd->lock=0;
} }
thd->abort_on_warning= 0; thd->abort_on_warning= 0;
DBUG_RETURN(error); DBUG_RETURN(error);
} }
@ -732,12 +731,11 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs,
my_free((gptr) buffer,MYF(0)); /* purecov: inspected */ my_free((gptr) buffer,MYF(0)); /* purecov: inspected */
error=1; error=1;
} }
else else
{ {
/* /*
init_io_cache() will not initialize read_function member init_io_cache() will not initialize read_function member
if the cache is READ_NET. The reason is explained in if the cache is READ_NET. So we work around the problem with a
mysys/mf_iocache.c. So we work around the problem with a
manual assignment manual assignment
*/ */
need_end_io_cache = 1; need_end_io_cache = 1;

View file

@ -83,6 +83,10 @@ const char *command_name[]={
"Error" // Last command number "Error" // Last command number
}; };
const char *xa_state_names[]={
"NON-EXISTING", "ACTIVE", "IDLE", "PREPARED"
};
static char empty_c_string[1]= {0}; // Used for not defined 'db' static char empty_c_string[1]= {0}; // Used for not defined 'db'
#ifdef __WIN__ #ifdef __WIN__
@ -152,7 +156,7 @@ static bool begin_trans(THD *thd)
OPTION_BEGIN); OPTION_BEGIN);
thd->server_status|= SERVER_STATUS_IN_TRANS; thd->server_status|= SERVER_STATUS_IN_TRANS;
if (lex->start_transaction_opt & MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT) if (lex->start_transaction_opt & MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT)
error= ha_start_consistent_snapshot(thd); error= ha_start_consistent_snapshot(thd);
} }
return error; return error;
} }
@ -555,6 +559,12 @@ void free_max_user_conn(void)
sql_command is actually set to SQLCOM_END sometimes sql_command is actually set to SQLCOM_END sometimes
so we need the +1 to include it in the array. so we need the +1 to include it in the array.
numbers are:
0 - read-only query
!= 0 - query that may change a table
2 - query that returns meaningful ROW_COUNT() -
a number of modified rows
*/ */
char uc_update_queries[SQLCOM_END+1]; char uc_update_queries[SQLCOM_END+1];
@ -566,23 +576,23 @@ void init_update_queries(void)
uc_update_queries[SQLCOM_CREATE_TABLE]=1; uc_update_queries[SQLCOM_CREATE_TABLE]=1;
uc_update_queries[SQLCOM_CREATE_INDEX]=1; uc_update_queries[SQLCOM_CREATE_INDEX]=1;
uc_update_queries[SQLCOM_ALTER_TABLE]=1; uc_update_queries[SQLCOM_ALTER_TABLE]=1;
uc_update_queries[SQLCOM_UPDATE]=1; uc_update_queries[SQLCOM_UPDATE]=2;
uc_update_queries[SQLCOM_INSERT]=1; uc_update_queries[SQLCOM_UPDATE_MULTI]=2;
uc_update_queries[SQLCOM_INSERT_SELECT]=1; uc_update_queries[SQLCOM_INSERT]=2;
uc_update_queries[SQLCOM_DELETE]=1; uc_update_queries[SQLCOM_INSERT_SELECT]=2;
uc_update_queries[SQLCOM_DELETE]=2;
uc_update_queries[SQLCOM_DELETE_MULTI]=2;
uc_update_queries[SQLCOM_TRUNCATE]=1; uc_update_queries[SQLCOM_TRUNCATE]=1;
uc_update_queries[SQLCOM_DROP_TABLE]=1; uc_update_queries[SQLCOM_DROP_TABLE]=1;
uc_update_queries[SQLCOM_LOAD]=1; uc_update_queries[SQLCOM_LOAD]=1;
uc_update_queries[SQLCOM_CREATE_DB]=1; uc_update_queries[SQLCOM_CREATE_DB]=1;
uc_update_queries[SQLCOM_DROP_DB]=1; uc_update_queries[SQLCOM_DROP_DB]=1;
uc_update_queries[SQLCOM_REPLACE]=1; uc_update_queries[SQLCOM_REPLACE]=2;
uc_update_queries[SQLCOM_REPLACE_SELECT]=1; uc_update_queries[SQLCOM_REPLACE_SELECT]=2;
uc_update_queries[SQLCOM_RENAME_TABLE]=1; uc_update_queries[SQLCOM_RENAME_TABLE]=1;
uc_update_queries[SQLCOM_BACKUP_TABLE]=1; uc_update_queries[SQLCOM_BACKUP_TABLE]=1;
uc_update_queries[SQLCOM_RESTORE_TABLE]=1; uc_update_queries[SQLCOM_RESTORE_TABLE]=1;
uc_update_queries[SQLCOM_DELETE_MULTI]=1;
uc_update_queries[SQLCOM_DROP_INDEX]=1; uc_update_queries[SQLCOM_DROP_INDEX]=1;
uc_update_queries[SQLCOM_UPDATE_MULTI]=1;
uc_update_queries[SQLCOM_CREATE_VIEW]=1; uc_update_queries[SQLCOM_CREATE_VIEW]=1;
uc_update_queries[SQLCOM_DROP_VIEW]=1; uc_update_queries[SQLCOM_DROP_VIEW]=1;
} }
@ -824,17 +834,6 @@ static int check_connection(THD *thd)
return(ER_OUT_OF_RESOURCES); return(ER_OUT_OF_RESOURCES);
thd->client_capabilities=uint2korr(net->read_pos); thd->client_capabilities=uint2korr(net->read_pos);
#ifdef TO_BE_REMOVED_IN_4_1_RELEASE
/*
This is just a safety check against any client that would use the old
CLIENT_CHANGE_USER flag
*/
if ((thd->client_capabilities & CLIENT_PROTOCOL_41) &&
!(thd->client_capabilities & (CLIENT_RESERVED |
CLIENT_SECURE_CONNECTION |
CLIENT_MULTI_RESULTS)))
thd->client_capabilities&= ~CLIENT_PROTOCOL_41;
#endif
if (thd->client_capabilities & CLIENT_PROTOCOL_41) if (thd->client_capabilities & CLIENT_PROTOCOL_41)
{ {
thd->client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16; thd->client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16;
@ -1190,24 +1189,25 @@ extern "C" pthread_handler_decl(handle_bootstrap,arg)
We don't need to obtain LOCK_thread_count here because in bootstrap We don't need to obtain LOCK_thread_count here because in bootstrap
mode we have only one thread. mode we have only one thread.
*/ */
thd->query_id=query_id++; thd->query_id=next_query_id();
if (mqh_used && thd->user_connect && check_mqh(thd, SQLCOM_END))
{
thd->net.error = 0;
close_thread_tables(thd); // Free tables
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
break;
}
mysql_parse(thd,thd->query,length); mysql_parse(thd,thd->query,length);
close_thread_tables(thd); // Free tables close_thread_tables(thd); // Free tables
if (thd->is_fatal_error) if (thd->is_fatal_error)
break; break;
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC)); free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
#ifdef USING_TRANSACTIONS
free_root(&thd->transaction.mem_root,MYF(MY_KEEP_PREALLOC)); free_root(&thd->transaction.mem_root,MYF(MY_KEEP_PREALLOC));
#endif
} }
/* thd->fatal_error should be set in case something went wrong */ /* thd->fatal_error should be set in case something went wrong */
end: end:
bootstrap_error= thd->is_fatal_error;
net_end(&thd->net);
thd->cleanup();
delete thd;
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
(void) pthread_mutex_lock(&LOCK_thread_count); (void) pthread_mutex_lock(&LOCK_thread_count);
thread_count--; thread_count--;
@ -1216,7 +1216,7 @@ end:
my_thread_end(); my_thread_end();
pthread_exit(0); pthread_exit(0);
#endif #endif
DBUG_RETURN(0); // Never reached DBUG_RETURN(0);
} }
/* This works because items are allocated with sql_alloc() */ /* This works because items are allocated with sql_alloc() */
@ -1282,45 +1282,27 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd)
my_error(ER_GET_ERRNO, MYF(0), error); my_error(ER_GET_ERRNO, MYF(0), error);
err: err:
close_thread_tables(thd);
DBUG_RETURN(error); DBUG_RETURN(error);
} }
/* /*
Ends the current transaction and (maybe) begin the next Ends the current transaction and (maybe) begin the next
First uint4 in packet is completion type
Remainder is savepoint name (if required)
SYNOPSIS SYNOPSIS
mysql_endtrans() end_trans()
thd Current thread thd Current thread
completion Completion type completion Completion type
savepoint_name Savepoint when doing ROLLBACK_SAVEPOINT_NAME
or RELEASE_SAVEPOINT_NAME
release (OUT) indicator for release operation
RETURN RETURN
0 - OK 0 - OK
*/ */
enum enum_mysql_completiontype { int end_trans(THD *thd, enum enum_mysql_completiontype completion)
ROLLBACK_RELEASE=-2,
COMMIT_RELEASE=-1,
COMMIT=0,
ROLLBACK=1,
SAVEPOINT_NAME_ROLLBACK=2,
SAVEPOINT_NAME_RELEASE=4,
COMMIT_AND_CHAIN=6,
ROLLBACK_AND_CHAIN=7
};
int mysql_endtrans(THD *thd, enum enum_mysql_completiontype completion,
char *savepoint_name)
{ {
bool do_release= 0; bool do_release= 0;
int res= 0; int res= 0;
LEX *lex= thd->lex; LEX *lex= thd->lex;
DBUG_ENTER("mysql_endtrans"); DBUG_ENTER("end_trans");
switch (completion) { switch (completion) {
case COMMIT: case COMMIT:
@ -1331,80 +1313,39 @@ int mysql_endtrans(THD *thd, enum enum_mysql_completiontype completion,
*/ */
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE); thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
thd->server_status&= ~SERVER_STATUS_IN_TRANS; thd->server_status&= ~SERVER_STATUS_IN_TRANS;
if (!(res= ha_commit(thd))) res= ha_commit(thd);
send_ok(thd);
break; break;
case COMMIT_RELEASE: case COMMIT_RELEASE:
do_release= 1; do_release= 1; /* fall through */
case COMMIT_AND_CHAIN: case COMMIT_AND_CHAIN:
res= end_active_trans(thd); res= end_active_trans(thd);
if (!res && completion == COMMIT_AND_CHAIN) if (!res && completion == COMMIT_AND_CHAIN)
res= begin_trans(thd); res= begin_trans(thd);
if (!res)
send_ok(thd);
break; break;
case ROLLBACK_RELEASE: case ROLLBACK_RELEASE:
do_release= 1; do_release= 1; /* fall through */
case ROLLBACK: case ROLLBACK:
case ROLLBACK_AND_CHAIN: case ROLLBACK_AND_CHAIN:
{ {
bool warn= 0;
thd->server_status&= ~SERVER_STATUS_IN_TRANS; thd->server_status&= ~SERVER_STATUS_IN_TRANS;
if (!ha_rollback(thd)) if (ha_rollback(thd))
{
/*
If a non-transactional table was updated, warn; don't warn if this is a
slave thread (because when a slave thread executes a ROLLBACK, it has
been read from the binary log, so it's 100% sure and normal to produce
error ER_WARNING_NOT_COMPLETE_ROLLBACK. If we sent the warning to the
slave SQL thread, it would not stop the thread but just be printed in
the error log; but we don't want users to wonder why they have this
message in the error log, so we don't send it.
*/
warn= (thd->options & OPTION_STATUS_NO_TRANS_UPDATE) &&
!thd->slave_thread;
}
else
res= -1; res= -1;
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE); thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
if (!res && (completion == ROLLBACK_AND_CHAIN)) if (!res && (completion == ROLLBACK_AND_CHAIN))
res= begin_trans(thd); res= begin_trans(thd);
if (!res)
{
if (warn)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARNING_NOT_COMPLETE_ROLLBACK,
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
send_ok(thd);
}
break; break;
} }
case SAVEPOINT_NAME_ROLLBACK:
if (!(res=ha_rollback_to_savepoint(thd, savepoint_name)))
{
if ((thd->options & OPTION_STATUS_NO_TRANS_UPDATE) && !thd->slave_thread)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARNING_NOT_COMPLETE_ROLLBACK,
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
send_ok(thd);
}
break;
case SAVEPOINT_NAME_RELEASE:
if (!(res=ha_release_savepoint_name(thd, savepoint_name)))
send_ok(thd);
break;
default: default:
res= -1; res= -1;
my_error(ER_UNKNOWN_COM_ERROR, MYF(0)); my_error(ER_UNKNOWN_COM_ERROR, MYF(0));
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
if (res < 0) if (res < 0)
my_error(thd->killed_errno(), MYF(0)); my_error(thd->killed_errno(), MYF(0));
else if ((res == 0) && do_release) else if ((res == 0) && do_release)
thd->killed= THD::KILL_CONNECTION; thd->killed= THD::KILL_CONNECTION;
DBUG_RETURN(res); DBUG_RETURN(res);
} }
@ -1519,7 +1460,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
VOID(pthread_mutex_lock(&LOCK_thread_count)); VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_id=query_id; thd->query_id=query_id;
if (command != COM_STATISTICS && command != COM_PING) if (command != COM_STATISTICS && command != COM_PING)
query_id++; next_query_id();
thread_running++; thread_running++;
/* TODO: set thd->lex->sql_command to SQLCOM_END here */ /* TODO: set thd->lex->sql_command to SQLCOM_END here */
VOID(pthread_mutex_unlock(&LOCK_thread_count)); VOID(pthread_mutex_unlock(&LOCK_thread_count));
@ -1676,9 +1617,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
DBUG_PRINT("query",("%-.4096s",thd->query)); DBUG_PRINT("query",("%-.4096s",thd->query));
mysql_parse(thd,thd->query, thd->query_length); mysql_parse(thd,thd->query, thd->query_length);
while (!thd->killed && thd->lex->found_colon && !thd->net.report_error) while (!thd->killed && thd->lex->found_semicolon && !thd->net.report_error)
{ {
char *packet= thd->lex->found_colon; char *packet= thd->lex->found_semicolon;
/* /*
Multiple queries exits, execute them individually Multiple queries exits, execute them individually
in embedded server - just store them to be executed later in embedded server - just store them to be executed later
@ -1698,7 +1639,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
VOID(pthread_mutex_lock(&LOCK_thread_count)); VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_length= length; thd->query_length= length;
thd->query= packet; thd->query= packet;
thd->query_id= query_id++; thd->query_id= next_query_id();
/* TODO: set thd->lex->sql_command to SQLCOM_END here */ /* TODO: set thd->lex->sql_command to SQLCOM_END here */
VOID(pthread_mutex_unlock(&LOCK_thread_count)); VOID(pthread_mutex_unlock(&LOCK_thread_count));
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
@ -2010,6 +1951,17 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->proc_info="closing tables"; thd->proc_info="closing tables";
close_thread_tables(thd); /* Free tables */ close_thread_tables(thd); /* Free tables */
} }
/*
assume handlers auto-commit (if some doesn't - transaction handling
in MySQL should be redesigned to support it; it's a big change,
and it's not worth it - better to commit explicitly only writing
transactions, read-only ones should better take care of themselves.
saves some work in 2pc too)
see also sql_base.cc - close_thread_tables()
*/
bzero(&thd->transaction.stmt, sizeof(thd->transaction.stmt));
if (!thd->active_transaction())
thd->transaction.xid.null();
/* report error issued during command execution */ /* report error issued during command execution */
if (thd->killed_errno() && !thd->net.report_error) if (thd->killed_errno() && !thd->net.report_error)
@ -2411,7 +2363,7 @@ mysql_execute_command(THD *thd)
*/ */
if (opt_readonly && if (opt_readonly &&
!(thd->slave_thread || (thd->master_access & SUPER_ACL)) && !(thd->slave_thread || (thd->master_access & SUPER_ACL)) &&
(uc_update_queries[lex->sql_command] > 0)) uc_update_queries[lex->sql_command])
{ {
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only"); my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
DBUG_RETURN(-1); DBUG_RETURN(-1);
@ -2677,7 +2629,7 @@ mysql_execute_command(THD *thd)
{ {
if (check_global_access(thd, REPL_SLAVE_ACL)) if (check_global_access(thd, REPL_SLAVE_ACL))
goto error; goto error;
res = show_binlog_events(thd); res = mysql_show_binlog_events(thd);
break; break;
} }
#endif #endif
@ -2712,7 +2664,7 @@ mysql_execute_command(THD *thd)
check_access(thd, INDEX_ACL, first_table->db, check_access(thd, INDEX_ACL, first_table->db,
&first_table->grant.privilege, 0, 0)) &first_table->grant.privilege, 0, 0))
goto error; goto error;
res= mysql_assign_to_keycache(thd, first_table, &lex->name_and_length); res= mysql_assign_to_keycache(thd, first_table, &lex->ident);
break; break;
} }
case SQLCOM_PRELOAD_KEYS: case SQLCOM_PRELOAD_KEYS:
@ -3333,7 +3285,7 @@ unsent_create_error:
first_table->ancestor && first_table->ancestor->next_local); first_table->ancestor && first_table->ancestor->next_local);
my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0), my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
first_table->view_db.str, first_table->view_name.str); first_table->view_db.str, first_table->view_name.str);
res= -1; res= FALSE;
break; break;
} }
@ -3358,7 +3310,6 @@ unsent_create_error:
} }
else else
res= TRUE; res= TRUE;
close_thread_tables(thd);
break; break;
} }
case SQLCOM_DROP_TABLE: case SQLCOM_DROP_TABLE:
@ -3881,7 +3832,7 @@ unsent_create_error:
*/ */
if (check_db_used(thd, all_tables)) if (check_db_used(thd, all_tables))
goto error; goto error;
res= mysql_ha_read(thd, first_table, lex->ha_read_mode, lex->backup_dir, res= mysql_ha_read(thd, first_table, lex->ha_read_mode, lex->ident.str,
lex->insert_list, lex->ha_rkey_mode, select_lex->where, lex->insert_list, lex->ha_rkey_mode, select_lex->where,
select_lex->select_limit, select_lex->offset_limit); select_lex->select_limit, select_lex->offset_limit);
break; break;
@ -3889,32 +3840,121 @@ unsent_create_error:
case SQLCOM_BEGIN: case SQLCOM_BEGIN:
if (begin_trans(thd)) if (begin_trans(thd))
goto error; goto error;
else send_ok(thd);
send_ok(thd);
break; break;
case SQLCOM_COMMIT: case SQLCOM_COMMIT:
if (mysql_endtrans(thd, lex->tx_release ? COMMIT_RELEASE : if (end_trans(thd, lex->tx_release ? COMMIT_RELEASE :
lex->tx_chain ? COMMIT_AND_CHAIN : COMMIT, 0)) lex->tx_chain ? COMMIT_AND_CHAIN : COMMIT))
goto error; goto error;
send_ok(thd);
break; break;
case SQLCOM_ROLLBACK: case SQLCOM_ROLLBACK:
if (mysql_endtrans(thd, lex->tx_release ? ROLLBACK_RELEASE : if (end_trans(thd, lex->tx_release ? ROLLBACK_RELEASE :
lex->tx_chain ? ROLLBACK_AND_CHAIN : ROLLBACK, 0)) lex->tx_chain ? ROLLBACK_AND_CHAIN : ROLLBACK))
goto error;
break;
case SQLCOM_ROLLBACK_TO_SAVEPOINT:
if (mysql_endtrans(thd, SAVEPOINT_NAME_ROLLBACK, lex->savepoint_name))
goto error;
break;
case SQLCOM_SAVEPOINT:
if (!ha_savepoint(thd, lex->savepoint_name))
send_ok(thd);
else
goto error; goto error;
send_ok(thd);
break; break;
case SQLCOM_RELEASE_SAVEPOINT: case SQLCOM_RELEASE_SAVEPOINT:
if (mysql_endtrans(thd, SAVEPOINT_NAME_RELEASE, lex->savepoint_name)) {
goto error; SAVEPOINT **sv;
for (sv=&thd->transaction.savepoints; *sv; sv=&(*sv)->prev)
{
if (my_strnncoll(system_charset_info,
(uchar *)lex->ident.str, lex->ident.length,
(uchar *)(*sv)->name, (*sv)->length) == 0)
break;
}
if (*sv)
{
if (ha_release_savepoint(thd, *sv))
res= TRUE; // cannot happen
else
send_ok(thd);
*sv=(*sv)->prev;
}
else
{
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
res= TRUE;
}
break;
}
case SQLCOM_ROLLBACK_TO_SAVEPOINT:
{
SAVEPOINT **sv;
for (sv=&thd->transaction.savepoints; *sv; sv=&(*sv)->prev)
{
if (my_strnncoll(system_charset_info,
(uchar *)lex->ident.str, lex->ident.length,
(uchar *)(*sv)->name, (*sv)->length) == 0)
break;
}
if (*sv)
{
if (ha_rollback_to_savepoint(thd, *sv))
res= TRUE; // cannot happen
else
{
if ((thd->options & OPTION_STATUS_NO_TRANS_UPDATE) &&
!thd->slave_thread)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARNING_NOT_COMPLETE_ROLLBACK,
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
send_ok(thd);
}
*sv=(*sv)->prev;
}
else
{
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
res= TRUE;
}
break;
}
case SQLCOM_SAVEPOINT:
if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) ||
!opt_using_transactions)
send_ok(thd);
else
{
SAVEPOINT **sv, *newsv;
for (sv=&thd->transaction.savepoints; *sv; sv=&(*sv)->prev)
{
if (my_strnncoll(system_charset_info,
(uchar *)lex->ident.str, lex->ident.length,
(uchar *)(*sv)->name, (*sv)->length) == 0)
break;
}
if (*sv) /* old savepoint of the same name exists */
{
newsv=*sv;
ha_release_savepoint(thd, *sv); // it cannot fail
*sv=(*sv)->prev;
}
else if ((newsv=(SAVEPOINT *) alloc_root(&thd->transaction.mem_root,
savepoint_alloc_size)) == 0)
{
my_error(ER_OUT_OF_RESOURCES, MYF(0));
res= TRUE;
break;
}
newsv->name=strmake_root(&thd->transaction.mem_root,
lex->ident.str, lex->ident.length);
newsv->length=lex->ident.length;
/*
if we'll get an error here, don't add new savepoint to the list.
we'll lose a little bit of memory in transaction mem_root, but it'll
be free'd when transaction ends anyway
*/
if (ha_savepoint(thd, newsv))
res= TRUE;
else
{
newsv->prev=thd->transaction.savepoints;
thd->transaction.savepoints=newsv;
send_ok(thd);
}
}
break; break;
case SQLCOM_CREATE_PROCEDURE: case SQLCOM_CREATE_PROCEDURE:
case SQLCOM_CREATE_SPFUNCTION: case SQLCOM_CREATE_SPFUNCTION:
@ -3931,12 +3971,12 @@ unsent_create_error:
lex->sphead= 0; lex->sphead= 0;
goto error; goto error;
} }
if (!lex->sphead->m_db.str || !lex->sphead->m_db.str[0]) if (!lex->sphead->m_db.str || !lex->sphead->m_db.str[0])
{ {
lex->sphead->m_db.length= strlen(thd->db); lex->sphead->m_db.length= strlen(thd->db);
lex->sphead->m_db.str= strmake_root(thd->mem_root, thd->db, lex->sphead->m_db.str= strmake_root(thd->mem_root, thd->db,
lex->sphead->m_db.length); lex->sphead->m_db.length);
} }
name= lex->sphead->name(&namelen); name= lex->sphead->name(&namelen);
@ -4291,7 +4331,157 @@ unsent_create_error:
res= mysql_create_or_drop_trigger(thd, all_tables, 0); res= mysql_create_or_drop_trigger(thd, all_tables, 0);
break; break;
} }
default: /* Impossible */ case SQLCOM_XA_START:
if (thd->transaction.xa_state == XA_IDLE && thd->lex->xa_opt == XA_RESUME)
{
if (! thd->transaction.xid.eq(&thd->lex->ident))
{
my_error(ER_XAER_NOTA, MYF(0));
break;
}
thd->transaction.xa_state=XA_ACTIVE;
send_ok(thd);
res=TRUE;
break;
}
if (thd->lex->ident.length > MAXGTRIDSIZE || thd->lex->xa_opt != XA_NONE)
{ // JOIN is not supported yet. TODO
my_error(ER_XAER_INVAL, MYF(0));
break;
}
if (thd->transaction.xa_state != XA_NOTR)
{
my_error(ER_XAER_RMFAIL, MYF(0),
xa_state_names[thd->transaction.xa_state]);
break;
}
if (thd->active_transaction() || thd->locked_tables)
{
my_error(ER_XAER_OUTSIDE, MYF(0));
break;
}
DBUG_ASSERT(thd->transaction.xid.is_null());
thd->transaction.xa_state=XA_ACTIVE;
thd->transaction.xid.set(&thd->lex->ident);
thd->options= ((thd->options & (ulong) ~(OPTION_STATUS_NO_TRANS_UPDATE)) |
OPTION_BEGIN);
thd->server_status|= SERVER_STATUS_IN_TRANS;
send_ok(thd);
res=TRUE;
break;
case SQLCOM_XA_END:
/* fake it */
if (thd->lex->xa_opt != XA_NONE)
{ // SUSPEND and FOR MIGRATE are not supported yet. TODO
my_error(ER_XAER_INVAL, MYF(0));
break;
}
if (thd->transaction.xa_state != XA_ACTIVE)
{
my_error(ER_XAER_RMFAIL, MYF(0),
xa_state_names[thd->transaction.xa_state]);
break;
}
if (!thd->transaction.xid.eq(&thd->lex->ident))
{
my_error(ER_XAER_NOTA, MYF(0));
break;
}
thd->transaction.xa_state=XA_IDLE;
send_ok(thd);
res=TRUE;
break;
case SQLCOM_XA_PREPARE:
if (thd->transaction.xa_state != XA_IDLE)
{
my_error(ER_XAER_RMFAIL, MYF(0),
xa_state_names[thd->transaction.xa_state]);
break;
}
if (!thd->transaction.xid.eq(&thd->lex->ident))
{
my_error(ER_XAER_NOTA, MYF(0));
break;
}
if (ha_prepare(thd))
{
my_error(ER_XA_RBROLLBACK, MYF(0));
thd->transaction.xa_state=XA_NOTR;
break;
}
res=TRUE;
thd->transaction.xa_state=XA_PREPARED;
send_ok(thd);
break;
case SQLCOM_XA_COMMIT:
if (!thd->transaction.xid.eq(&thd->lex->ident))
{
if (!(res= !ha_commit_or_rollback_by_xid(&thd->lex->ident, 1)))
my_error(ER_XAER_NOTA, MYF(0));
break;
}
if (thd->transaction.xa_state == XA_IDLE && thd->lex->xa_opt == XA_ONE_PHASE)
{
int r;
if ((r= ha_commit(thd)))
my_error(r == 1 ? ER_XA_RBROLLBACK : ER_XAER_RMERR, MYF(0));
else
{
send_ok(thd);
res= TRUE;
}
}
else
if (thd->transaction.xa_state == XA_PREPARED && thd->lex->xa_opt == XA_NONE)
{
if (ha_commit_one_phase(thd, 1))
my_error(ER_XAER_RMERR, MYF(0));
else
{
send_ok(thd);
res= TRUE;
}
}
else
{
my_error(ER_XAER_RMFAIL, MYF(0),
xa_state_names[thd->transaction.xa_state]);
break;
}
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
thd->transaction.xa_state=XA_NOTR;
break;
case SQLCOM_XA_ROLLBACK:
if (!thd->transaction.xid.eq(&thd->lex->ident))
{
if (!(res= !ha_commit_or_rollback_by_xid(&thd->lex->ident, 0)))
my_error(ER_XAER_NOTA, MYF(0));
break;
}
if (thd->transaction.xa_state != XA_IDLE &&
thd->transaction.xa_state != XA_PREPARED)
{
my_error(ER_XAER_RMFAIL, MYF(0),
xa_state_names[thd->transaction.xa_state]);
break;
}
if (ha_rollback(thd))
my_error(ER_XAER_RMERR, MYF(0));
else
{
send_ok(thd);
res= TRUE;
}
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
thd->transaction.xa_state=XA_NOTR;
break;
case SQLCOM_XA_RECOVER:
res= !mysql_xa_recover(thd);
break;
default:
DBUG_ASSERT(0); /* Impossible */
send_ok(thd); send_ok(thd);
break; break;
} }
@ -4326,22 +4516,10 @@ unsent_create_error:
the statement is not DELETE, INSERT or UPDATE (or a CALL executing the statement is not DELETE, INSERT or UPDATE (or a CALL executing
such a statement), but -1 is what JDBC and ODBC wants. such a statement), but -1 is what JDBC and ODBC wants.
*/ */
switch (lex->sql_command) { if (lex->sql_command != SQLCOM_CALL && uc_update_queries[lex->sql_command]<2)
case SQLCOM_UPDATE:
case SQLCOM_UPDATE_MULTI:
case SQLCOM_REPLACE:
case SQLCOM_INSERT:
case SQLCOM_REPLACE_SELECT:
case SQLCOM_INSERT_SELECT:
case SQLCOM_DELETE:
case SQLCOM_DELETE_MULTI:
case SQLCOM_CALL:
break;
default:
thd->row_count_func= -1; thd->row_count_func= -1;
}
goto cleanup; goto cleanup;
error: error:
res= 1; res= 1;
@ -5133,17 +5311,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
new_field->charset=cs; new_field->charset=cs;
new_field->geom_type= (Field::geometry_type) uint_geom_type; new_field->geom_type= (Field::geometry_type) uint_geom_type;
if (!comment) new_field->comment=*comment;
{
new_field->comment.str=0;
new_field->comment.length=0;
}
else
{
/* In this case comment is always of type Item_string */
new_field->comment.str= (char*) comment->str;
new_field->comment.length=comment->length;
}
/* /*
Set flag if this field doesn't have a default value Set flag if this field doesn't have a default value
Enum values has always the first value as a default (set in Enum values has always the first value as a default (set in

View file

@ -25,49 +25,34 @@ int max_binlog_dump_events = 0; // unlimited
my_bool opt_sporadic_binlog_dump_fail = 0; my_bool opt_sporadic_binlog_dump_fail = 0;
static int binlog_dump_count = 0; static int binlog_dump_count = 0;
int check_binlog_magic(IO_CACHE* log, const char** errmsg) /*
{
char magic[4];
DBUG_ASSERT(my_b_tell(log) == 0);
if (my_b_read(log, (byte*) magic, sizeof(magic)))
{
*errmsg = "I/O error reading the header from the binary log";
sql_print_error("%s, errno=%d, io cache code=%d", *errmsg, my_errno,
log->error);
return 1;
}
if (memcmp(magic, BINLOG_MAGIC, sizeof(magic)))
{
*errmsg = "Binlog has bad magic number; It's not a binary log file that can be used by this version of MySQL";
return 1;
}
return 0;
}
/*
fake_rotate_event() builds a fake (=which does not exist physically in any fake_rotate_event() builds a fake (=which does not exist physically in any
binlog) Rotate event, which contains the name of the binlog we are going to binlog) Rotate event, which contains the name of the binlog we are going to
send to the slave (because the slave may not know it if it just asked for send to the slave (because the slave may not know it if it just asked for
MASTER_LOG_FILE='', MASTER_LOG_POS=4). MASTER_LOG_FILE='', MASTER_LOG_POS=4).
< 4.0.14, fake_rotate_event() was called only if the requested pos was < 4.0.14, fake_rotate_event() was called only if the requested pos was 4.
4. After this version we always call it, so that a 3.23.58 slave can rely on After this version we always call it, so that a 3.23.58 slave can rely on
it to detect if the master is 4.0 (and stop) (the _fake_ Rotate event has it to detect if the master is 4.0 (and stop) (the _fake_ Rotate event has
zeros in the good positions which, by chance, make it possible for the 3.23 zeros in the good positions which, by chance, make it possible for the 3.23
slave to detect that this event is unexpected) (this is luck which happens slave to detect that this event is unexpected) (this is luck which happens
because the master and slave disagree on the size of the header of because the master and slave disagree on the size of the header of
Log_event). Log_event).
Relying on the event length of the Rotate event instead of these well-placed Relying on the event length of the Rotate event instead of these
zeros was not possible as Rotate events have a variable-length part. well-placed zeros was not possible as Rotate events have a variable-length
part.
*/ */
static int fake_rotate_event(NET* net, String* packet, char* log_file_name, static int fake_rotate_event(NET* net, String* packet, char* log_file_name,
ulonglong position, const char** errmsg) ulonglong position, const char** errmsg)
{ {
DBUG_ENTER("fake_rotate_event"); DBUG_ENTER("fake_rotate_event");
char header[LOG_EVENT_HEADER_LEN], buf[ROTATE_HEADER_LEN]; char header[LOG_EVENT_HEADER_LEN], buf[ROTATE_HEADER_LEN+100];
memset(header, 0, 4); // 'when' (the timestamp) does not matter, is set to 0 /*
'when' (the timestamp) is set to 0 so that slave could distinguish between
real and fake Rotate events (if necessary)
*/
memset(header, 0, 4);
header[EVENT_TYPE_OFFSET] = ROTATE_EVENT; header[EVENT_TYPE_OFFSET] = ROTATE_EVENT;
char* p = log_file_name+dirname_length(log_file_name); char* p = log_file_name+dirname_length(log_file_name);
@ -76,10 +61,10 @@ static int fake_rotate_event(NET* net, String* packet, char* log_file_name,
int4store(header + SERVER_ID_OFFSET, server_id); int4store(header + SERVER_ID_OFFSET, server_id);
int4store(header + EVENT_LEN_OFFSET, event_len); int4store(header + EVENT_LEN_OFFSET, event_len);
int2store(header + FLAGS_OFFSET, 0); int2store(header + FLAGS_OFFSET, 0);
// TODO: check what problems this may cause and fix them // TODO: check what problems this may cause and fix them
int4store(header + LOG_POS_OFFSET, 0); int4store(header + LOG_POS_OFFSET, 0);
packet->append(header, sizeof(header)); packet->append(header, sizeof(header));
int8store(buf+R_POS_OFFSET,position); int8store(buf+R_POS_OFFSET,position);
packet->append(buf, ROTATE_HEADER_LEN); packet->append(buf, ROTATE_HEADER_LEN);
@ -164,41 +149,6 @@ static int send_file(THD *thd)
} }
File open_binlog(IO_CACHE *log, const char *log_file_name,
const char **errmsg)
{
File file;
DBUG_ENTER("open_binlog");
if ((file = my_open(log_file_name, O_RDONLY | O_BINARY, MYF(MY_WME))) < 0)
{
sql_print_error("Failed to open log (\
file '%s', errno %d)", log_file_name, my_errno);
*errmsg = "Could not open log file"; // This will not be sent
goto err;
}
if (init_io_cache(log, file, IO_SIZE*2, READ_CACHE, 0, 0,
MYF(MY_WME | MY_DONT_CHECK_FILESIZE)))
{
sql_print_error("Failed to create a cache on log (\
file '%s')", log_file_name);
*errmsg = "Could not open log file"; // This will not be sent
goto err;
}
if (check_binlog_magic(log,errmsg))
goto err;
DBUG_RETURN(file);
err:
if (file >= 0)
{
my_close(file,MYF(0));
end_io_cache(log);
}
DBUG_RETURN(-1);
}
/* /*
Adjust the position pointer in the binary log file for all running slaves Adjust the position pointer in the binary log file for all running slaves
@ -330,7 +280,7 @@ bool purge_master_logs_before_date(THD* thd, time_t purge_time)
int test_for_non_eof_log_read_errors(int error, const char **errmsg) int test_for_non_eof_log_read_errors(int error, const char **errmsg)
{ {
if (error == LOG_READ_EOF) if (error == LOG_READ_EOF)
return 0; return 0;
my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG; my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
switch (error) { switch (error) {
@ -375,6 +325,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos,
const char *errmsg = "Unknown error"; const char *errmsg = "Unknown error";
NET* net = &thd->net; NET* net = &thd->net;
pthread_mutex_t *log_lock; pthread_mutex_t *log_lock;
bool binlog_can_be_corrupted= FALSE;
#ifndef DBUG_OFF #ifndef DBUG_OFF
int left_events = max_binlog_dump_events; int left_events = max_binlog_dump_events;
#endif #endif
@ -442,37 +393,38 @@ impossible position";
/* /*
Tell the client about the log name with a fake Rotate event; Tell the client about the log name with a fake Rotate event;
this is needed even if we also send a Format_description_log_event just this is needed even if we also send a Format_description_log_event
after, because that event does not contain the binlog's name. just after, because that event does not contain the binlog's name.
Note that as this Rotate event is sent before Format_description_log_event, Note that as this Rotate event is sent before
the slave cannot have any info to understand this event's format, so the Format_description_log_event, the slave cannot have any info to
header len of Rotate_log_event is FROZEN understand this event's format, so the header len of
(so in 5.0 it will have a header shorter than other events except Rotate_log_event is FROZEN (so in 5.0 it will have a header shorter
FORMAT_DESCRIPTION_EVENT). than other events except FORMAT_DESCRIPTION_EVENT).
Before 4.0.14 we called fake_rotate_event below only if Before 4.0.14 we called fake_rotate_event below only if (pos ==
(pos == BIN_LOG_HEADER_SIZE), because if this is false then the slave BIN_LOG_HEADER_SIZE), because if this is false then the slave
already knows the binlog's name. already knows the binlog's name.
Since, we always call fake_rotate_event; if the slave already knew the log's Since, we always call fake_rotate_event; if the slave already knew
name (ex: CHANGE MASTER TO MASTER_LOG_FILE=...) this is useless but does the log's name (ex: CHANGE MASTER TO MASTER_LOG_FILE=...) this is
not harm much. It is nice for 3.23 (>=.58) slaves which test Rotate events useless but does not harm much. It is nice for 3.23 (>=.58) slaves
to see if the master is 4.0 (then they choose to stop because they can't which test Rotate events to see if the master is 4.0 (then they
replicate 4.0); by always calling fake_rotate_event we are sure that choose to stop because they can't replicate 4.0); by always calling
3.23.58 and newer will detect the problem as soon as replication starts fake_rotate_event we are sure that 3.23.58 and newer will detect the
(BUG#198). problem as soon as replication starts (BUG#198).
Always calling fake_rotate_event makes sending of normal Always calling fake_rotate_event makes sending of normal
(=from-binlog) Rotate events a priori unneeded, but it is not so simple: (=from-binlog) Rotate events a priori unneeded, but it is not so
the 2 Rotate events are not equivalent, the normal one is before the Stop simple: the 2 Rotate events are not equivalent, the normal one is
event, the fake one is after. If we don't send the normal one, then the before the Stop event, the fake one is after. If we don't send the
Stop event will be interpreted (by existing 4.0 slaves) as "the master normal one, then the Stop event will be interpreted (by existing 4.0
stopped", which is wrong. So for safety, given that we want minimum slaves) as "the master stopped", which is wrong. So for safety,
modification of 4.0, we send the normal and fake Rotates. given that we want minimum modification of 4.0, we send the normal
and fake Rotates.
*/ */
if (fake_rotate_event(net, packet, log_file_name, pos, &errmsg)) if (fake_rotate_event(net, packet, log_file_name, pos, &errmsg))
{ {
/* /*
This error code is not perfect, as fake_rotate_event() does not read This error code is not perfect, as fake_rotate_event() does not
anything from the binlog; if it fails it's because of an error in read anything from the binlog; if it fails it's because of an
my_net_write(), fortunately it will say it in errmsg. error in my_net_write(), fortunately it will say so in errmsg.
*/ */
my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG; my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
goto err; goto err;
@ -480,30 +432,35 @@ impossible position";
packet->set("\0", 1, &my_charset_bin); packet->set("\0", 1, &my_charset_bin);
/* /*
We can set log_lock now, it does not move (it's a member of mysql_bin_log, We can set log_lock now, it does not move (it's a member of
and it's already inited, and it will be destroyed only at shutdown). mysql_bin_log, and it's already inited, and it will be destroyed
only at shutdown).
*/ */
log_lock = mysql_bin_log.get_log_lock(); log_lock = mysql_bin_log.get_log_lock();
if (pos > BIN_LOG_HEADER_SIZE) if (pos > BIN_LOG_HEADER_SIZE)
{ {
/* Try to find a Format_description_log_event at the beginning of the binlog */ /*
Try to find a Format_description_log_event at the beginning of
the binlog
*/
if (!(error = Log_event::read_log_event(&log, packet, log_lock))) if (!(error = Log_event::read_log_event(&log, packet, log_lock)))
{ {
/* /*
The packet has offsets equal to the normal offsets in a binlog event The packet has offsets equal to the normal offsets in a binlog
+1 (the first character is \0). event +1 (the first character is \0).
*/ */
DBUG_PRINT("info", DBUG_PRINT("info",
("Looked for a Format_description_log_event, found event type %d", ("Looked for a Format_description_log_event, found event type %d",
(*packet)[EVENT_TYPE_OFFSET+1])); (*packet)[EVENT_TYPE_OFFSET+1]));
if ((*packet)[EVENT_TYPE_OFFSET+1] == FORMAT_DESCRIPTION_EVENT) if ((*packet)[EVENT_TYPE_OFFSET+1] == FORMAT_DESCRIPTION_EVENT)
{ {
binlog_can_be_corrupted= (*packet)[FLAGS_OFFSET+1] & LOG_EVENT_BINLOG_IN_USE_F;
/* /*
mark that this event with "log_pos=0", so the slave mark that this event with "log_pos=0", so the slave
should not increment master's binlog position should not increment master's binlog position
(rli->group_master_log_pos) (rli->group_master_log_pos)
*/ */
int4store(packet->c_ptr() +LOG_POS_OFFSET+1,0); int4store(packet->c_ptr()+LOG_POS_OFFSET+1, 0);
/* send it */ /* send it */
if (my_net_write(net, (char*)packet->ptr(), packet->length())) if (my_net_write(net, (char*)packet->ptr(), packet->length()))
{ {
@ -512,24 +469,25 @@ impossible position";
goto err; goto err;
} }
/* /*
No need to save this event. We are only doing simple reads (no real No need to save this event. We are only doing simple reads
parsing of the events) so we don't need it. And so we don't need the (no real parsing of the events) so we don't need it. And so
artificial Format_description_log_event of 3.23&4.x. we don't need the artificial Format_description_log_event of
3.23&4.x.
*/ */
} }
} }
else else
if (test_for_non_eof_log_read_errors(error, &errmsg)) if (test_for_non_eof_log_read_errors(error, &errmsg))
goto err; goto err;
/* /*
else: it's EOF, nothing to do, go on reading next events, the else: it's EOF, nothing to do, go on reading next events, the
Format_description_log_event will be found naturally if it is written. Format_description_log_event will be found naturally if it is written.
*/ */
/* reset the packet as we wrote to it in any case */ /* reset the packet as we wrote to it in any case */
packet->set("\0", 1, &my_charset_bin); packet->set("\0", 1, &my_charset_bin);
} /* end of if (pos > BIN_LOG_HEADER_SIZE); if false, the Format_description_log_event } /* end of if (pos > BIN_LOG_HEADER_SIZE); if false, the
event will be found naturally. */ Format_description_log_event event will be found naturally. */
/* seek to the requested position, to start the requested dump */ /* seek to the requested position, to start the requested dump */
my_b_seek(&log, pos); // Seek will done on next read my_b_seek(&log, pos); // Seek will done on next read
@ -546,6 +504,12 @@ impossible position";
goto err; goto err;
} }
#endif #endif
if ((*packet)[EVENT_TYPE_OFFSET+1] == FORMAT_DESCRIPTION_EVENT)
binlog_can_be_corrupted= (*packet)[FLAGS_OFFSET+1] & LOG_EVENT_BINLOG_IN_USE_F;
else if ((*packet)[EVENT_TYPE_OFFSET+1] == STOP_EVENT)
binlog_can_be_corrupted= FALSE;
if (my_net_write(net, (char*)packet->ptr(), packet->length())) if (my_net_write(net, (char*)packet->ptr(), packet->length()))
{ {
errmsg = "Failed on my_net_write()"; errmsg = "Failed on my_net_write()";
@ -565,19 +529,25 @@ impossible position";
} }
packet->set("\0", 1, &my_charset_bin); packet->set("\0", 1, &my_charset_bin);
} }
/*
here we were reading binlog that was not closed properly (as a result
of a crash ?). treat any corruption as EOF
*/
if (binlog_can_be_corrupted && error != LOG_READ_MEM)
error=LOG_READ_EOF;
/* /*
TODO: now that we are logging the offset, check to make sure TODO: now that we are logging the offset, check to make sure
the recorded offset and the actual match. the recorded offset and the actual match.
Guilhem 2003-06: this is not true if this master is a slave <4.0.15 Guilhem 2003-06: this is not true if this master is a slave
running with --log-slave-updates, because then log_pos may be the offset <4.0.15 running with --log-slave-updates, because then log_pos may
in the-master-of-this-master's binlog. be the offset in the-master-of-this-master's binlog.
*/ */
if (test_for_non_eof_log_read_errors(error, &errmsg)) if (test_for_non_eof_log_read_errors(error, &errmsg))
goto err; goto err;
if (!(flags & BINLOG_DUMP_NON_BLOCK) && if (!(flags & BINLOG_DUMP_NON_BLOCK) &&
mysql_bin_log.is_active(log_file_name)) mysql_bin_log.is_active(log_file_name))
{ {
/* /*
Block until there is more data in the log Block until there is more data in the log
@ -613,9 +583,9 @@ impossible position";
now, but we'll be quick and just read one record now, but we'll be quick and just read one record
TODO: TODO:
Add an counter that is incremented for each time we update Add an counter that is incremented for each time we update the
the binary log. We can avoid the following read if the counter binary log. We can avoid the following read if the counter
has not been updated since last read. has not been updated since last read.
*/ */
pthread_mutex_lock(log_lock); pthread_mutex_lock(log_lock);
@ -708,16 +678,17 @@ impossible position";
(void) my_close(file, MYF(MY_WME)); (void) my_close(file, MYF(MY_WME));
/* /*
Call fake_rotate_event() in case the previous log (the one which we have Call fake_rotate_event() in case the previous log (the one which
just finished reading) did not contain a Rotate event (for example (I we have just finished reading) did not contain a Rotate event
don't know any other example) the previous log was the last one before (for example (I don't know any other example) the previous log
the master was shutdown & restarted). was the last one before the master was shutdown & restarted).
This way we tell the slave about the new log's name and position. This way we tell the slave about the new log's name and
If the binlog is 5.0, the next event we are going to read and send is position. If the binlog is 5.0, the next event we are going to
Format_description_log_event. read and send is Format_description_log_event.
*/ */
if ((file=open_binlog(&log, log_file_name, &errmsg)) < 0 || if ((file=open_binlog(&log, log_file_name, &errmsg)) < 0 ||
fake_rotate_event(net, packet, log_file_name, BIN_LOG_HEADER_SIZE, &errmsg)) fake_rotate_event(net, packet, log_file_name, BIN_LOG_HEADER_SIZE,
&errmsg))
{ {
my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG; my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
goto err; goto err;
@ -762,17 +733,17 @@ int start_slave(THD* thd , MASTER_INFO* mi, bool net_report)
int slave_errno= 0; int slave_errno= 0;
int thread_mask; int thread_mask;
DBUG_ENTER("start_slave"); DBUG_ENTER("start_slave");
if (check_access(thd, SUPER_ACL, any_db,0,0,0)) if (check_access(thd, SUPER_ACL, any_db,0,0,0))
DBUG_RETURN(1); DBUG_RETURN(1);
lock_slave_threads(mi); // this allows us to cleanly read slave_running lock_slave_threads(mi); // this allows us to cleanly read slave_running
// Get a mask of _stopped_ threads // Get a mask of _stopped_ threads
init_thread_mask(&thread_mask,mi,1 /* inverse */); init_thread_mask(&thread_mask,mi,1 /* inverse */);
/* /*
Below we will start all stopped threads. Below we will start all stopped threads. But if the user wants to
But if the user wants to start only one thread, do as if the other thread start only one thread, do as if the other thread was running (as we
was running (as we don't wan't to touch the other thread), so set the don't wan't to touch the other thread), so set the bit to 0 for the
bit to 0 for the other thread other thread
*/ */
if (thd->lex->slave_thd_opt) if (thd->lex->slave_thd_opt)
thread_mask&= thd->lex->slave_thd_opt; thread_mask&= thd->lex->slave_thd_opt;
@ -783,9 +754,9 @@ int start_slave(THD* thd , MASTER_INFO* mi, bool net_report)
slave_errno=ER_MASTER_INFO; slave_errno=ER_MASTER_INFO;
else if (server_id_supplied && *mi->host) else if (server_id_supplied && *mi->host)
{ {
/* /*
If we will start SQL thread we will care about UNTIL options If we will start SQL thread we will care about UNTIL options If
If not and they are specified we will ignore them and warn user not and they are specified we will ignore them and warn user
about this fact. about this fact.
*/ */
if (thread_mask & SLAVE_SQL) if (thread_mask & SLAVE_SQL)
@ -796,13 +767,13 @@ int start_slave(THD* thd , MASTER_INFO* mi, bool net_report)
{ {
mi->rli.until_condition= RELAY_LOG_INFO::UNTIL_MASTER_POS; mi->rli.until_condition= RELAY_LOG_INFO::UNTIL_MASTER_POS;
mi->rli.until_log_pos= thd->lex->mi.pos; mi->rli.until_log_pos= thd->lex->mi.pos;
/* /*
We don't check thd->lex->mi.log_file_name for NULL here We don't check thd->lex->mi.log_file_name for NULL here
since it is checked in sql_yacc.yy since it is checked in sql_yacc.yy
*/ */
strmake(mi->rli.until_log_name, thd->lex->mi.log_file_name, strmake(mi->rli.until_log_name, thd->lex->mi.log_file_name,
sizeof(mi->rli.until_log_name)-1); sizeof(mi->rli.until_log_name)-1);
} }
else if (thd->lex->mi.relay_log_pos) else if (thd->lex->mi.relay_log_pos)
{ {
mi->rli.until_condition= RELAY_LOG_INFO::UNTIL_RELAY_POS; mi->rli.until_condition= RELAY_LOG_INFO::UNTIL_RELAY_POS;
@ -826,15 +797,15 @@ int start_slave(THD* thd , MASTER_INFO* mi, bool net_report)
p_end points to the first invalid character. If it equals p_end points to the first invalid character. If it equals
to p, no digits were found, error. If it contains '\0' it to p, no digits were found, error. If it contains '\0' it
means conversion went ok. means conversion went ok.
*/ */
if (p_end==p || *p_end) if (p_end==p || *p_end)
slave_errno=ER_BAD_SLAVE_UNTIL_COND; slave_errno=ER_BAD_SLAVE_UNTIL_COND;
} }
else else
slave_errno=ER_BAD_SLAVE_UNTIL_COND; slave_errno=ER_BAD_SLAVE_UNTIL_COND;
/* mark the cached result of the UNTIL comparison as "undefined" */ /* mark the cached result of the UNTIL comparison as "undefined" */
mi->rli.until_log_names_cmp_result= mi->rli.until_log_names_cmp_result=
RELAY_LOG_INFO::UNTIL_LOG_NAMES_CMP_UNKNOWN; RELAY_LOG_INFO::UNTIL_LOG_NAMES_CMP_UNKNOWN;
/* Issuing warning then started without --skip-slave-start */ /* Issuing warning then started without --skip-slave-start */
@ -842,14 +813,13 @@ int start_slave(THD* thd , MASTER_INFO* mi, bool net_report)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_MISSING_SKIP_SLAVE, push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_MISSING_SKIP_SLAVE,
ER(ER_MISSING_SKIP_SLAVE)); ER(ER_MISSING_SKIP_SLAVE));
} }
pthread_mutex_unlock(&mi->rli.data_lock); pthread_mutex_unlock(&mi->rli.data_lock);
} }
else if (thd->lex->mi.pos || thd->lex->mi.relay_log_pos) else if (thd->lex->mi.pos || thd->lex->mi.relay_log_pos)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_UNTIL_COND_IGNORED, push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_UNTIL_COND_IGNORED,
ER(ER_UNTIL_COND_IGNORED)); ER(ER_UNTIL_COND_IGNORED));
if (!slave_errno) if (!slave_errno)
slave_errno = start_slave_threads(0 /*no mutex */, slave_errno = start_slave_threads(0 /*no mutex */,
1 /* wait for start */, 1 /* wait for start */,
@ -864,9 +834,9 @@ int start_slave(THD* thd , MASTER_INFO* mi, bool net_report)
//no error if all threads are already started, only a warning //no error if all threads are already started, only a warning
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_SLAVE_WAS_RUNNING, push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_SLAVE_WAS_RUNNING,
ER(ER_SLAVE_WAS_RUNNING)); ER(ER_SLAVE_WAS_RUNNING));
unlock_slave_threads(mi); unlock_slave_threads(mi);
if (slave_errno) if (slave_errno)
{ {
if (net_report) if (net_report)
@ -966,7 +936,7 @@ int reset_slave(THD *thd, MASTER_INFO* mi)
1 /* just reset */, 1 /* just reset */,
&errmsg))) &errmsg)))
goto err; goto err;
/* /*
Clear master's log coordinates and reset host/user/etc to the values Clear master's log coordinates and reset host/user/etc to the values
specified in mysqld's options (only for good display of SHOW SLAVE STATUS; specified in mysqld's options (only for good display of SHOW SLAVE STATUS;
@ -975,13 +945,13 @@ int reset_slave(THD *thd, MASTER_INFO* mi)
STATUS; before doing START SLAVE; STATUS; before doing START SLAVE;
*/ */
init_master_info_with_options(mi); init_master_info_with_options(mi);
/* /*
Reset errors (the idea is that we forget about the Reset errors (the idea is that we forget about the
old master). old master).
*/ */
clear_slave_error(&mi->rli); clear_slave_error(&mi->rli);
clear_until_condition(&mi->rli); clear_until_condition(&mi->rli);
// close master_info_file, relay_log_info_file, set mi->inited=rli->inited=0 // close master_info_file, relay_log_info_file, set mi->inited=rli->inited=0
end_master_info(mi); end_master_info(mi);
// and delete these two files // and delete these two files
@ -1288,7 +1258,7 @@ int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1,
} }
bool show_binlog_events(THD* thd) bool mysql_show_binlog_events(THD* thd)
{ {
Protocol *protocol= thd->protocol; Protocol *protocol= thd->protocol;
DBUG_ENTER("show_binlog_events"); DBUG_ENTER("show_binlog_events");
@ -1297,7 +1267,7 @@ bool show_binlog_events(THD* thd)
IO_CACHE log; IO_CACHE log;
File file = -1; File file = -1;
Format_description_log_event *description_event= new Format_description_log_event *description_event= new
Format_description_log_event(3); /* MySQL 4.0 by default */ Format_description_log_event(3); /* MySQL 4.0 by default */
Log_event::init_show_field_list(&field_list); Log_event::init_show_field_list(&field_list);
if (protocol->send_fields(&field_list, if (protocol->send_fields(&field_list,
@ -1314,7 +1284,7 @@ bool show_binlog_events(THD* thd)
pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock(); pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock();
LOG_INFO linfo; LOG_INFO linfo;
Log_event* ev; Log_event* ev;
limit_start= thd->lex->current_select->offset_limit; limit_start= thd->lex->current_select->offset_limit;
limit_end= thd->lex->current_select->select_limit + limit_start; limit_end= thd->lex->current_select->select_limit + limit_start;
@ -1338,15 +1308,15 @@ bool show_binlog_events(THD* thd)
pthread_mutex_lock(log_lock); pthread_mutex_lock(log_lock);
/* /*
open_binlog() sought to position 4. open_binlog() sought to position 4.
Read the first event in case it's a Format_description_log_event, to know the Read the first event in case it's a Format_description_log_event, to
format. If there's no such event, we are 3.23 or 4.x. This code, like know the format. If there's no such event, we are 3.23 or 4.x. This
before, can't read 3.23 binlogs. code, like before, can't read 3.23 binlogs.
This code will fail on a mixed relay log (one which has Format_desc then This code will fail on a mixed relay log (one which has Format_desc then
Rotate then Format_desc). Rotate then Format_desc).
*/ */
ev = Log_event::read_log_event(&log,(pthread_mutex_t*)0,description_event); ev = Log_event::read_log_event(&log,(pthread_mutex_t*)0,description_event);
if (ev) if (ev)
{ {
@ -1366,7 +1336,7 @@ bool show_binlog_events(THD* thd)
errmsg="Invalid Format_description event; could be out of memory"; errmsg="Invalid Format_description event; could be out of memory";
goto err; goto err;
} }
for (event_count = 0; for (event_count = 0;
(ev = Log_event::read_log_event(&log,(pthread_mutex_t*)0,description_event)); ) (ev = Log_event::read_log_event(&log,(pthread_mutex_t*)0,description_event)); )
{ {

View file

@ -36,15 +36,16 @@ extern I_List<i_string> binlog_do_db, binlog_ignore_db;
extern int max_binlog_dump_events; extern int max_binlog_dump_events;
extern my_bool opt_sporadic_binlog_dump_fail; extern my_bool opt_sporadic_binlog_dump_fail;
#define KICK_SLAVE(thd) { pthread_mutex_lock(&(thd)->LOCK_delete); (thd)->awake(THD::NOT_KILLED); pthread_mutex_unlock(&(thd)->LOCK_delete); } #define KICK_SLAVE(thd) do { \
pthread_mutex_lock(&(thd)->LOCK_delete); \
File open_binlog(IO_CACHE *log, const char *log_file_name, (thd)->awake(THD::NOT_KILLED); \
const char **errmsg); pthread_mutex_unlock(&(thd)->LOCK_delete); \
} while(0)
int start_slave(THD* thd, MASTER_INFO* mi, bool net_report); int start_slave(THD* thd, MASTER_INFO* mi, bool net_report);
int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report); int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report);
bool change_master(THD* thd, MASTER_INFO* mi); bool change_master(THD* thd, MASTER_INFO* mi);
bool show_binlog_events(THD* thd); bool mysql_show_binlog_events(THD* thd);
int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1, int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1,
const char* log_file_name2, ulonglong log_pos2); const char* log_file_name2, ulonglong log_pos2);
int reset_slave(THD *thd, MASTER_INFO* mi); int reset_slave(THD *thd, MASTER_INFO* mi);

View file

@ -14,7 +14,6 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* drop and alter of tables */ /* drop and alter of tables */
#include "mysql_priv.h" #include "mysql_priv.h"
@ -275,9 +274,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
{ {
if (!error) if (!error)
thd->clear_error(); thd->clear_error();
Query_log_event qinfo(thd, thd->query, thd->query_length, Query_log_event qinfo(thd, thd->query, thd->query_length, FALSE, FALSE);
tmp_table_deleted && !some_tables_deleted,
FALSE);
mysql_bin_log.write(&qinfo); mysql_bin_log.write(&qinfo);
} }
} }
@ -1297,7 +1294,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
create_info Create information (like MAX_ROWS) create_info Create information (like MAX_ROWS)
fields List of fields to create fields List of fields to create
keys List of keys to create keys List of keys to create
tmp_table Set to 1 if this is an internal temporary table internal_tmp_table Set to 1 if this is an internal temporary table
(From ALTER TABLE) (From ALTER TABLE)
DESCRIPTION DESCRIPTION
@ -1316,7 +1313,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
bool mysql_create_table(THD *thd,const char *db, const char *table_name, bool mysql_create_table(THD *thd,const char *db, const char *table_name,
HA_CREATE_INFO *create_info, HA_CREATE_INFO *create_info,
List<create_field> &fields, List<create_field> &fields,
List<Key> &keys,bool tmp_table, List<Key> &keys,bool internal_tmp_table,
uint select_field_count) uint select_field_count)
{ {
char path[FN_REFLEN]; char path[FN_REFLEN];
@ -1385,7 +1382,7 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name,
} }
if (mysql_prepare_table(thd, create_info, fields, if (mysql_prepare_table(thd, create_info, fields,
keys, tmp_table, db_options, file, keys, internal_tmp_table, db_options, file,
key_info_buffer, &key_count, key_info_buffer, &key_count,
select_field_count)) select_field_count))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
@ -1419,7 +1416,7 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name,
if (wait_if_global_read_lock(thd, 0, 1)) if (wait_if_global_read_lock(thd, 0, 1))
DBUG_RETURN(error); DBUG_RETURN(error);
VOID(pthread_mutex_lock(&LOCK_open)); VOID(pthread_mutex_lock(&LOCK_open));
if (!tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE)) if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
{ {
if (!access(path,F_OK)) if (!access(path,F_OK))
{ {
@ -1486,13 +1483,10 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name,
} }
thd->tmp_table_used= 1; thd->tmp_table_used= 1;
} }
if (!tmp_table && mysql_bin_log.is_open()) if (!internal_tmp_table && mysql_bin_log.is_open())
{ {
thd->clear_error(); thd->clear_error();
Query_log_event qinfo(thd, thd->query, thd->query_length, Query_log_event qinfo(thd, thd->query, thd->query_length, FALSE, FALSE);
test(create_info->options &
HA_LEX_CREATE_TMP_TABLE),
FALSE);
mysql_bin_log.write(&qinfo); mysql_bin_log.write(&qinfo);
} }
error= FALSE; error= FALSE;
@ -2473,10 +2467,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
if (mysql_bin_log.is_open()) if (mysql_bin_log.is_open())
{ {
thd->clear_error(); thd->clear_error();
Query_log_event qinfo(thd, thd->query, thd->query_length, Query_log_event qinfo(thd, thd->query, thd->query_length, FALSE, FALSE);
test(create_info->options &
HA_LEX_CREATE_TMP_TABLE),
FALSE);
mysql_bin_log.write(&qinfo); mysql_bin_log.write(&qinfo);
} }
res= FALSE; res= FALSE;
@ -2586,7 +2577,7 @@ mysql_discard_or_import_tablespace(THD *thd,
goto err; goto err;
if (mysql_bin_log.is_open()) if (mysql_bin_log.is_open())
{ {
Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); Query_log_event qinfo(thd, thd->query, thd->query_length, FALSE, FALSE);
mysql_bin_log.write(&qinfo); mysql_bin_log.write(&qinfo);
} }
err: err:
@ -2979,7 +2970,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (mysql_bin_log.is_open()) if (mysql_bin_log.is_open())
{ {
thd->clear_error(); thd->clear_error();
Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); Query_log_event qinfo(thd, thd->query, thd->query_length, FALSE, FALSE);
mysql_bin_log.write(&qinfo); mysql_bin_log.write(&qinfo);
} }
if (do_send_ok) if (do_send_ok)
@ -3396,7 +3387,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (mysql_bin_log.is_open()) if (mysql_bin_log.is_open())
{ {
thd->clear_error(); thd->clear_error();
Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); Query_log_event qinfo(thd, thd->query, thd->query_length, FALSE, FALSE);
mysql_bin_log.write(&qinfo); mysql_bin_log.write(&qinfo);
} }
goto end_temporary; goto end_temporary;
@ -3530,7 +3521,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (mysql_bin_log.is_open()) if (mysql_bin_log.is_open())
{ {
thd->clear_error(); thd->clear_error();
Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); Query_log_event qinfo(thd, thd->query, thd->query_length, FALSE, FALSE);
mysql_bin_log.write(&qinfo); mysql_bin_log.write(&qinfo);
} }
VOID(pthread_cond_broadcast(&COND_refresh)); VOID(pthread_cond_broadcast(&COND_refresh));

View file

@ -147,7 +147,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables)
/* Let us check if trigger with the same name exists */ /* Let us check if trigger with the same name exists */
while ((name= it++)) while ((name= it++))
{ {
if (my_strcasecmp(system_charset_info, lex->name_and_length.str, if (my_strcasecmp(system_charset_info, lex->ident.str,
name->str) == 0) name->str) == 0)
{ {
my_message(ER_TRG_ALREADY_EXISTS, ER(ER_TRG_ALREADY_EXISTS), MYF(0)); my_message(ER_TRG_ALREADY_EXISTS, ER(ER_TRG_ALREADY_EXISTS), MYF(0));
@ -238,7 +238,7 @@ bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables)
{ {
it_def++; it_def++;
if (my_strcasecmp(system_charset_info, lex->name_and_length.str, if (my_strcasecmp(system_charset_info, lex->ident.str,
name->str) == 0) name->str) == 0)
{ {
/* /*
@ -428,15 +428,15 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
if (!(trg_name_buff= alloc_root(&table->mem_root, if (!(trg_name_buff= alloc_root(&table->mem_root,
sizeof(LEX_STRING) + sizeof(LEX_STRING) +
lex.name_and_length.length + 1))) lex.ident.length + 1)))
goto err_with_lex_cleanup; goto err_with_lex_cleanup;
trg_name_str= (LEX_STRING *)trg_name_buff; trg_name_str= (LEX_STRING *)trg_name_buff;
trg_name_buff+= sizeof(LEX_STRING); trg_name_buff+= sizeof(LEX_STRING);
memcpy(trg_name_buff, lex.name_and_length.str, memcpy(trg_name_buff, lex.ident.str,
lex.name_and_length.length + 1); lex.ident.length + 1);
trg_name_str->str= trg_name_buff; trg_name_str->str= trg_name_buff;
trg_name_str->length= lex.name_and_length.length; trg_name_str->length= lex.ident.length;
if (triggers->names_list.push_back(trg_name_str, &table->mem_root)) if (triggers->names_list.push_back(trg_name_str, &table->mem_root))
goto err_with_lex_cleanup; goto err_with_lex_cleanup;

View file

@ -117,7 +117,7 @@ int mysql_update(THD *thd,
{ {
bool using_limit= limit != HA_POS_ERROR; bool using_limit= limit != HA_POS_ERROR;
bool safe_update= thd->options & OPTION_SAFE_UPDATES; bool safe_update= thd->options & OPTION_SAFE_UPDATES;
bool used_key_is_modified, transactional_table, log_delayed; bool used_key_is_modified, transactional_table;
int res; int res;
int error=0; int error=0;
uint used_index; uint used_index;
@ -469,7 +469,6 @@ int mysql_update(THD *thd,
query_cache_invalidate3(thd, table_list, 1); query_cache_invalidate3(thd, table_list, 1);
} }
log_delayed= (transactional_table || table->s->tmp_table);
if ((updated || (error < 0)) && (error <= 0 || !transactional_table)) if ((updated || (error < 0)) && (error <= 0 || !transactional_table))
{ {
if (mysql_bin_log.is_open()) if (mysql_bin_log.is_open())
@ -477,11 +476,11 @@ int mysql_update(THD *thd,
if (error <= 0) if (error <= 0)
thd->clear_error(); thd->clear_error();
Query_log_event qinfo(thd, thd->query, thd->query_length, Query_log_event qinfo(thd, thd->query, thd->query_length,
log_delayed, FALSE); transactional_table, FALSE);
if (mysql_bin_log.write(&qinfo) && transactional_table) if (mysql_bin_log.write(&qinfo) && transactional_table)
error=1; // Rollback update error=1; // Rollback update
} }
if (!log_delayed) if (!transactional_table)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE; thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
} }
if (transactional_table) if (transactional_table)
@ -1000,7 +999,6 @@ multi_update::initialize_tables(JOIN *join)
DBUG_RETURN(1); DBUG_RETURN(1);
main_table=join->join_tab->table; main_table=join->join_tab->table;
trans_safe= transactional_tables= main_table->file->has_transactions(); trans_safe= transactional_tables= main_table->file->has_transactions();
log_delayed= trans_safe || main_table->s->tmp_table != NO_TMP_TABLE;
table_to_update= 0; table_to_update= 0;
/* Create a temporary table for keys to all tables, except main table */ /* Create a temporary table for keys to all tables, except main table */
@ -1335,17 +1333,13 @@ int multi_update::do_updates(bool from_send_error)
goto err; goto err;
} }
updated++; updated++;
if (table->s->tmp_table != NO_TMP_TABLE)
log_delayed= 1;
} }
} }
if (updated != org_updated) if (updated != org_updated)
{ {
if (table->s->tmp_table != NO_TMP_TABLE)
log_delayed= 1; // Tmp tables forces delay log
if (table->file->has_transactions()) if (table->file->has_transactions())
log_delayed= transactional_tables= 1; transactional_tables= 1;
else else
trans_safe= 0; // Can't do safe rollback trans_safe= 0; // Can't do safe rollback
} }
@ -1366,10 +1360,8 @@ err:
if (updated != org_updated) if (updated != org_updated)
{ {
if (table->s->tmp_table != NO_TMP_TABLE)
log_delayed= 1;
if (table->file->has_transactions()) if (table->file->has_transactions())
log_delayed= transactional_tables= 1; transactional_tables= 1;
else else
trans_safe= 0; trans_safe= 0;
} }
@ -1411,11 +1403,11 @@ bool multi_update::send_eof()
if (local_error <= 0) if (local_error <= 0)
thd->clear_error(); thd->clear_error();
Query_log_event qinfo(thd, thd->query, thd->query_length, Query_log_event qinfo(thd, thd->query, thd->query_length,
log_delayed, FALSE); transactional_tables, FALSE);
if (mysql_bin_log.write(&qinfo) && trans_safe) if (mysql_bin_log.write(&qinfo) && trans_safe)
local_error= 1; // Rollback update local_error= 1; // Rollback update
} }
if (!log_delayed) if (!transactional_tables)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE; thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
} }

File diff suppressed because it is too large Load diff