diff --git a/mysql-test/r/rpl_temporary.result b/mysql-test/r/rpl_temporary.result index e7b64066c37..97561aa1218 100644 --- a/mysql-test/r/rpl_temporary.result +++ b/mysql-test/r/rpl_temporary.result @@ -7,6 +7,12 @@ start slave; reset master; SET @@session.pseudo_thread_id=100; ERROR HY000: Access denied. You need the SUPER privilege for this operation +SET @@session.sql_log_bin=0; +ERROR HY000: Access denied. You need the SUPER privilege for this operation +SET @@session.pseudo_thread_id=100; +SET @@session.pseudo_thread_id=connection_id(); +SET @@session.sql_log_bin=0; +SET @@session.sql_log_bin=1; drop table if exists t1,t2; create table t1(f int); create table t2(f int); diff --git a/mysql-test/t/rpl_temporary.test b/mysql-test/t/rpl_temporary.test index 0df8ceb6377..c456562f0e5 100644 --- a/mysql-test/t/rpl_temporary.test +++ b/mysql-test/t/rpl_temporary.test @@ -30,7 +30,17 @@ connect (con3,localhost,zedjzlcsjhd,,); connection con3; --error 1227 SET @@session.pseudo_thread_id=100; +# While we are here we also test that SQL_LOG_BIN can't be set +--error 1227 +SET @@session.sql_log_bin=0; +# Now as root, to be sure it works +connection con2; +SET @@session.pseudo_thread_id=100; +SET @@session.pseudo_thread_id=connection_id(); +SET @@session.sql_log_bin=0; +SET @@session.sql_log_bin=1; +connection con3; let $VERSION=`select version()`; --disable_warnings diff --git a/sql/handler.cc b/sql/handler.cc index 8a4a6005d85..d69836dadfa 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -486,7 +486,7 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans) operation_done=1; } #endif - if (trans == &thd->transaction.all) + if ((trans == &thd->transaction.all) && mysql_bin_log.is_open()) { /* Update the binary log with a BEGIN/ROLLBACK block if we have cached some @@ -494,7 +494,6 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans) be rare (updating a non-transactional table inside a transaction...). */ if (unlikely((thd->options & OPTION_STATUS_NO_TRANS_UPDATE) && - mysql_bin_log.is_open() && my_b_tell(&thd->transaction.trans_log))) mysql_bin_log.write(thd, &thd->transaction.trans_log, 0); /* Flushed or not, empty the binlog cache */ @@ -559,7 +558,7 @@ int ha_rollback_to_savepoint(THD *thd, char *savepoint_name) my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), error); error=1; } - else + else if (mysql_bin_log.is_open()) { /* Write ROLLBACK TO SAVEPOINT to the binlog cache if we have updated some @@ -567,7 +566,6 @@ int ha_rollback_to_savepoint(THD *thd, char *savepoint_name) from the SAVEPOINT command. */ if (unlikely((thd->options & OPTION_STATUS_NO_TRANS_UPDATE) && - mysql_bin_log.is_open() && my_b_tell(&thd->transaction.trans_log))) { Query_log_event qinfo(thd, thd->query, thd->query_length, TRUE); @@ -596,23 +594,26 @@ Return value: always 0, that is, succeeds always int ha_savepoint(THD *thd, char *savepoint_name) { - my_off_t binlog_cache_pos=0; int error=0; DBUG_ENTER("ha_savepoint"); #ifdef USING_TRANSACTIONS if (opt_using_transactions) { - binlog_cache_pos=my_b_tell(&thd->transaction.trans_log); -#ifdef HAVE_INNOBASE_DB - innobase_savepoint(thd,savepoint_name, binlog_cache_pos); -#endif - /* Write it to the binary log (see comments of ha_rollback_to_savepoint). */ + /* Write it to the binary log (see comments of ha_rollback_to_savepoint) */ if (mysql_bin_log.is_open()) { +#ifdef HAVE_INNOBASE_DB + innobase_savepoint(thd,savepoint_name, + my_b_tell(&thd->transaction.trans_log)); +#endif Query_log_event qinfo(thd, thd->query, thd->query_length, TRUE); if (mysql_bin_log.write(&qinfo)) error= 1; } +#ifdef HAVE_INNOBASE_DB + else + innobase_savepoint(thd,savepoint_name,0); +#endif } #endif /* USING_TRANSACTIONS */ DBUG_RETURN(error); diff --git a/sql/log.cc b/sql/log.cc index e25d853e2b6..6b091484a82 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1208,8 +1208,7 @@ bool MYSQL_LOG::write(Log_event* event_info) "do the involved tables match (to be implemented) binlog_[wild_]{do|ignore}_table?" (WL#1049)" */ - if ((thd && !(thd->options & OPTION_BIN_LOG) && - (thd->master_access & SUPER_ACL)) || + if ((thd && !(thd->options & OPTION_BIN_LOG)) || (local_db && !db_ok(local_db, binlog_do_db, binlog_ignore_db))) { VOID(pthread_mutex_unlock(&LOCK_log)); @@ -1556,11 +1555,7 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length, int tmp_errno=0; char buff[80],*end; end=buff; - if (!(thd->options & OPTION_UPDATE_LOG) -#ifndef NO_EMBEDDED_ACCESS_CHECKS - && (thd->master_access & SUPER_ACL) -#endif - ) + if (!(thd->options & OPTION_UPDATE_LOG)) { VOID(pthread_mutex_unlock(&LOCK_log)); return 0; diff --git a/sql/set_var.cc b/sql/set_var.cc index 8e39e1c275d..74c4fc74d8a 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -2284,6 +2284,13 @@ static bool set_option_autocommit(THD *thd, set_var *var) static bool set_log_update(THD *thd, set_var *var) { +#ifndef NO_EMBEDDED_ACCESS_CHECKS + if (!(thd->master_access & SUPER_ACL)) + { + my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER"); + return 1; + } +#endif if (opt_sql_bin_update) ((sys_var_thd_bit*) var->var)->bit_flag|= (OPTION_BIN_LOG | OPTION_UPDATE_LOG); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 945414f532b..1b4c8bec416 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -169,7 +169,11 @@ THD::THD():user_time(0), current_statement(0), is_fatal_error(0), tablespace_op=FALSE; #ifdef USING_TRANSACTIONS bzero((char*) &transaction,sizeof(transaction)); - if (opt_using_transactions) + /* + 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, diff --git a/sql/sql_class.h b/sql/sql_class.h index 51039999345..6815d0ae43c 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -684,7 +684,7 @@ public: delayed_insert *di; my_bool tablespace_op; /* This is TRUE in DISCARD/IMPORT TABLESPACE */ struct st_transactions { - IO_CACHE trans_log; + IO_CACHE trans_log; // Inited ONLY if binlog is open ! THD_TRANS all; // Trans since BEGIN WORK THD_TRANS stmt; // Trans for current statement uint bdb_lock_count; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index a9b947505f0..f463c6a27ff 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -134,15 +134,10 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, thd->lex->select_lex.table_list.first; DBUG_ENTER("mysql_insert"); -#ifndef NO_EMBEDDED_ACCESS_CHECKS - if (thd->master_access & SUPER_ACL) -#endif - { - if (!(thd->options & OPTION_UPDATE_LOG)) - log_on&= ~(int) DELAYED_LOG_UPDATE; - if (!(thd->options & OPTION_BIN_LOG)) - log_on&= ~(int) DELAYED_LOG_BIN; - } + if (!(thd->options & OPTION_UPDATE_LOG)) + log_on&= ~(int) DELAYED_LOG_UPDATE; + if (!(thd->options & OPTION_BIN_LOG)) + log_on&= ~(int) DELAYED_LOG_BIN; /* in safe mode or with skip-new change delayed insert to be regular if we are told to replace duplicates, the insert cannot be concurrent