1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

manual merge: mysql-5.1-rep+2 (bug tree) --> mysql-5.1-rep+2 (latest)

CONFLICTS
=========

Text conflict in sql/sql_yacc.yy
1 conflicts encountered.
This commit is contained in:
Luis Soares
2009-11-13 10:17:53 +00:00
81 changed files with 267 additions and 2351 deletions

View File

@ -703,329 +703,5 @@ bool show_slave_hosts(THD* thd)
DBUG_RETURN(FALSE);
}
int connect_to_master(THD *thd, MYSQL* mysql, Master_info* mi)
{
DBUG_ENTER("connect_to_master");
if (!mi->host || !*mi->host) /* empty host */
{
strmov(mysql->net.last_error, "Master is not configured");
DBUG_RETURN(1);
}
mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (char *) &slave_net_timeout);
mysql_options(mysql, MYSQL_OPT_READ_TIMEOUT, (char *) &slave_net_timeout);
#ifdef HAVE_OPENSSL
if (mi->ssl)
{
mysql_ssl_set(mysql,
mi->ssl_key[0]?mi->ssl_key:0,
mi->ssl_cert[0]?mi->ssl_cert:0,
mi->ssl_ca[0]?mi->ssl_ca:0,
mi->ssl_capath[0]?mi->ssl_capath:0,
mi->ssl_cipher[0]?mi->ssl_cipher:0);
mysql_options(mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
&mi->ssl_verify_server_cert);
}
#endif
mysql_options(mysql, MYSQL_SET_CHARSET_NAME, default_charset_info->csname);
mysql_options(mysql, MYSQL_SET_CHARSET_DIR, (char *) charsets_dir);
if (!mysql_real_connect(mysql, mi->host, mi->user, mi->password, 0,
mi->port, 0, 0))
DBUG_RETURN(1);
mysql->reconnect= 1;
DBUG_RETURN(0);
}
static inline void cleanup_mysql_results(MYSQL_RES* db_res,
MYSQL_RES** cur, MYSQL_RES** start)
{
for (; cur >= start; --cur)
{
if (*cur)
mysql_free_result(*cur);
}
mysql_free_result(db_res);
}
static int fetch_db_tables(THD *thd, MYSQL *mysql, const char *db,
MYSQL_RES *table_res, Master_info *mi)
{
MYSQL_ROW row;
for (row = mysql_fetch_row(table_res); row;
row = mysql_fetch_row(table_res))
{
TABLE_LIST table;
const char* table_name= row[0];
int error;
if (rpl_filter->is_on())
{
bzero((char*) &table, sizeof(table)); //just for safe
table.db= (char*) db;
table.table_name= (char*) table_name;
table.updating= 1;
if (!rpl_filter->tables_ok(thd->db, &table))
continue;
}
/* download master's table and overwrite slave's table */
if ((error= fetch_master_table(thd, db, table_name, mi, mysql, 1)))
return error;
}
return 0;
}
/**
Load all MyISAM tables from master to this slave.
REQUIREMENTS
- No active transaction (flush_relay_log_info would not work in this case).
@todo
- add special option, not enabled
by default, to allow inclusion of mysql database into load
data from master
*/
bool load_master_data(THD* thd)
{
MYSQL mysql;
MYSQL_RES* master_status_res = 0;
int error = 0;
const char* errmsg=0;
int restart_thread_mask;
HA_CREATE_INFO create_info;
mysql_init(&mysql);
/*
We do not want anyone messing with the slave at all for the entire
duration of the data load.
*/
pthread_mutex_lock(&LOCK_active_mi);
lock_slave_threads(active_mi);
init_thread_mask(&restart_thread_mask,active_mi,0 /*not inverse*/);
if (restart_thread_mask &&
(error=terminate_slave_threads(active_mi,restart_thread_mask,
1 /*skip lock*/)))
{
my_message(error, ER(error), MYF(0));
unlock_slave_threads(active_mi);
pthread_mutex_unlock(&LOCK_active_mi);
return TRUE;
}
if (connect_to_master(thd, &mysql, active_mi))
{
my_error(error= ER_CONNECT_TO_MASTER, MYF(0), mysql_error(&mysql));
goto err;
}
// now that we are connected, get all database and tables in each
{
MYSQL_RES *db_res, **table_res, **table_res_end, **cur_table_res;
uint num_dbs;
if (mysql_real_query(&mysql, STRING_WITH_LEN("SHOW DATABASES")) ||
!(db_res = mysql_store_result(&mysql)))
{
my_error(error= ER_QUERY_ON_MASTER, MYF(0), mysql_error(&mysql));
goto err;
}
if (!(num_dbs = (uint) mysql_num_rows(db_res)))
goto err;
/*
In theory, the master could have no databases at all
and run with skip-grant
*/
if (!(table_res = (MYSQL_RES**)thd->alloc(num_dbs * sizeof(MYSQL_RES*))))
{
my_message(error = ER_OUTOFMEMORY, ER(ER_OUTOFMEMORY), MYF(0));
goto err;
}
/*
This is a temporary solution until we have online backup
capabilities - to be replaced once online backup is working
we wait to issue FLUSH TABLES WITH READ LOCK for as long as we
can to minimize the lock time.
*/
if (mysql_real_query(&mysql,
STRING_WITH_LEN("FLUSH TABLES WITH READ LOCK")) ||
mysql_real_query(&mysql, STRING_WITH_LEN("SHOW MASTER STATUS")) ||
!(master_status_res = mysql_store_result(&mysql)))
{
my_error(error= ER_QUERY_ON_MASTER, MYF(0), mysql_error(&mysql));
goto err;
}
/*
Go through every table in every database, and if the replication
rules allow replicating it, get it
*/
table_res_end = table_res + num_dbs;
for (cur_table_res = table_res; cur_table_res < table_res_end;
cur_table_res++)
{
// since we know how many rows we have, this can never be NULL
MYSQL_ROW row = mysql_fetch_row(db_res);
char* db = row[0];
/*
Do not replicate databases excluded by rules. We also test
replicate_wild_*_table rules (replicate_wild_ignore_table='db1.%' will
be considered as "ignore the 'db1' database as a whole, as it already
works for CREATE DATABASE and DROP DATABASE).
Also skip 'mysql' database - in most cases the user will
mess up and not exclude mysql database with the rules when
he actually means to - in this case, he is up for a surprise if
his priv tables get dropped and downloaded from master
TODO - add special option, not enabled
by default, to allow inclusion of mysql database into load
data from master
*/
if (!rpl_filter->db_ok(db) ||
!rpl_filter->db_ok_with_wild_table(db) ||
!strcmp(db,"mysql") ||
is_schema_db(db))
{
*cur_table_res = 0;
continue;
}
bzero((char*) &create_info, sizeof(create_info));
create_info.options= HA_LEX_CREATE_IF_NOT_EXISTS;
if (mysql_create_db(thd, db, &create_info, 1))
{
cleanup_mysql_results(db_res, cur_table_res - 1, table_res);
goto err;
}
/* Clear the result of mysql_create_db(). */
thd->main_da.reset_diagnostics_area();
if (mysql_select_db(&mysql, db) ||
mysql_real_query(&mysql, STRING_WITH_LEN("SHOW TABLES")) ||
!(*cur_table_res = mysql_store_result(&mysql)))
{
my_error(error= ER_QUERY_ON_MASTER, MYF(0), mysql_error(&mysql));
cleanup_mysql_results(db_res, cur_table_res - 1, table_res);
goto err;
}
if ((error = fetch_db_tables(thd,&mysql,db,*cur_table_res,active_mi)))
{
// we do not report the error - fetch_db_tables handles it
cleanup_mysql_results(db_res, cur_table_res, table_res);
goto err;
}
}
cleanup_mysql_results(db_res, cur_table_res - 1, table_res);
// adjust replication coordinates from the master
if (master_status_res)
{
MYSQL_ROW row = mysql_fetch_row(master_status_res);
/*
We need this check because the master may not be running with
log-bin, but it will still allow us to do all the steps
of LOAD DATA FROM MASTER - no reason to forbid it, really,
although it does not make much sense for the user to do it
*/
if (row && row[0] && row[1])
{
/*
If the slave's master info is not inited, we init it, then we write
the new coordinates to it. Must call init_master_info() *before*
setting active_mi, because init_master_info() sets active_mi with
defaults.
*/
int error_2;
if (init_master_info(active_mi, master_info_file, relay_log_info_file,
0, (SLAVE_IO | SLAVE_SQL)))
my_message(ER_MASTER_INFO, ER(ER_MASTER_INFO), MYF(0));
strmake(active_mi->master_log_name, row[0],
sizeof(active_mi->master_log_name) -1);
active_mi->master_log_pos= my_strtoll10(row[1], (char**) 0, &error_2);
/* at least in recent versions, the condition below should be false */
if (active_mi->master_log_pos < BIN_LOG_HEADER_SIZE)
active_mi->master_log_pos = BIN_LOG_HEADER_SIZE;
/*
Relay log's IO_CACHE may not be inited (even if we are sure that some
host was specified; there could have been a problem when replication
started, which led to relay log's IO_CACHE to not be inited.
*/
if (flush_master_info(active_mi, 0))
sql_print_error("Failed to flush master info file");
}
mysql_free_result(master_status_res);
}
if (mysql_real_query(&mysql, STRING_WITH_LEN("UNLOCK TABLES")))
{
my_error(error= ER_QUERY_ON_MASTER, MYF(0), mysql_error(&mysql));
goto err;
}
}
thd_proc_info(thd, "purging old relay logs");
if (purge_relay_logs(&active_mi->rli,thd,
0 /* not only reset, but also reinit */,
&errmsg))
{
my_error(ER_RELAY_LOG_FAIL, MYF(0), errmsg);
unlock_slave_threads(active_mi);
pthread_mutex_unlock(&LOCK_active_mi);
return TRUE;
}
pthread_mutex_lock(&active_mi->rli.data_lock);
active_mi->rli.group_master_log_pos = active_mi->master_log_pos;
strmake(active_mi->rli.group_master_log_name,active_mi->master_log_name,
sizeof(active_mi->rli.group_master_log_name)-1);
/*
Cancel the previous START SLAVE UNTIL, as the fact to download
a new copy logically makes UNTIL irrelevant.
*/
active_mi->rli.clear_until_condition();
/*
No need to update rli.event* coordinates, they will be when the slave
threads start ; only rli.group* coordinates are necessary here.
*/
flush_relay_log_info(&active_mi->rli);
pthread_cond_broadcast(&active_mi->rli.data_cond);
pthread_mutex_unlock(&active_mi->rli.data_lock);
thd_proc_info(thd, "starting slave");
if (restart_thread_mask)
{
error=start_slave_threads(0 /* mutex not needed */,
1 /* wait for start */,
active_mi,master_info_file,relay_log_info_file,
restart_thread_mask);
}
err:
unlock_slave_threads(active_mi);
pthread_mutex_unlock(&LOCK_active_mi);
thd_proc_info(thd, 0);
mysql_close(&mysql); // safe to call since we always do mysql_init()
if (!error)
my_ok(thd);
return error;
}
#endif /* HAVE_REPLICATION */