~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2001-2006 MySQL AB & Sasha
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
/**
17
  @file
18
19
  All of the functions defined in this file which are not used (the ones to
20
  handle failsafe) are not used; their code has not been updated for more
21
  than one year now so should be considered as BADLY BROKEN. Do not enable
22
  it. The used functions (to handle LOAD DATA FROM MASTER, plus some small
23
  functions like register_slave()) are working.
24
*/
25
26
#include "mysql_priv.h"
27
#ifdef HAVE_REPLICATION
28
29
#include "repl_failsafe.h"
30
#include "sql_repl.h"
31
#include "slave.h"
32
#include "rpl_mi.h"
33
#include "rpl_filter.h"
34
#include "log_event.h"
35
36
#define SLAVE_LIST_CHUNK 128
37
#define SLAVE_ERRMSG_SIZE (FN_REFLEN+64)
38
39
40
RPL_STATUS rpl_status=RPL_NULL;
41
pthread_mutex_t LOCK_rpl_status;
42
pthread_cond_t COND_rpl_status;
43
HASH slave_list;
44
45
const char *rpl_role_type[] = {"MASTER","SLAVE",NullS};
46
TYPELIB rpl_role_typelib = {array_elements(rpl_role_type)-1,"",
47
			    rpl_role_type, NULL};
48
49
const char* rpl_status_type[]=
50
{
51
  "AUTH_MASTER","ACTIVE_SLAVE","IDLE_SLAVE", "LOST_SOLDIER","TROOP_SOLDIER",
52
  "RECOVERY_CAPTAIN","NULL",NullS
53
};
54
TYPELIB rpl_status_typelib= {array_elements(rpl_status_type)-1,"",
55
			     rpl_status_type, NULL};
56
57
58
void change_rpl_status(RPL_STATUS from_status, RPL_STATUS to_status)
59
{
60
  pthread_mutex_lock(&LOCK_rpl_status);
61
  if (rpl_status == from_status || rpl_status == RPL_ANY)
62
    rpl_status = to_status;
63
  pthread_cond_signal(&COND_rpl_status);
64
  pthread_mutex_unlock(&LOCK_rpl_status);
65
}
66
67
68
#define get_object(p, obj, msg) \
69
{\
70
  uint len = (uint)*p++;  \
71
  if (p + len > p_end || len >= sizeof(obj)) \
72
  {\
73
    errmsg= msg;\
74
    goto err; \
75
  }\
76
  strmake(obj,(char*) p,len); \
77
  p+= len; \
78
}\
79
80
81
static inline int cmp_master_pos(Slave_log_event* sev, LEX_MASTER_INFO* mi)
82
{
83
  return cmp_master_pos(sev->master_log, sev->master_pos, mi->log_file_name,
84
			mi->pos);
85
}
86
87
88
void unregister_slave(THD* thd, bool only_mine, bool need_mutex)
89
{
90
  if (thd->server_id)
91
  {
92
    if (need_mutex)
93
      pthread_mutex_lock(&LOCK_slave_list);
94
95
    SLAVE_INFO* old_si;
96
    if ((old_si = (SLAVE_INFO*)hash_search(&slave_list,
97
					   (uchar*)&thd->server_id, 4)) &&
98
	(!only_mine || old_si->thd == thd))
99
    hash_delete(&slave_list, (uchar*)old_si);
100
101
    if (need_mutex)
102
      pthread_mutex_unlock(&LOCK_slave_list);
103
  }
104
}
105
106
107
/**
108
  Register slave in 'slave_list' hash table.
109
110
  @return
111
    0	ok
112
  @return
113
    1	Error.   Error message sent to client
114
*/
115
116
int register_slave(THD* thd, uchar* packet, uint packet_length)
117
{
118
  int res;
119
  SLAVE_INFO *si;
120
  uchar *p= packet, *p_end= packet + packet_length;
121
  const char *errmsg= "Wrong parameters to function register_slave";
122
123
  if (!(si = (SLAVE_INFO*)my_malloc(sizeof(SLAVE_INFO), MYF(MY_WME))))
124
    goto err2;
125
126
  thd->server_id= si->server_id= uint4korr(p);
127
  p+= 4;
128
  get_object(p,si->host, "Failed to register slave: too long 'report-host'");
129
  get_object(p,si->user, "Failed to register slave: too long 'report-user'");
130
  get_object(p,si->password, "Failed to register slave; too long 'report-password'");
131
  if (p+10 > p_end)
132
    goto err;
133
  si->port= uint2korr(p);
134
  p += 2;
135
  si->rpl_recovery_rank= uint4korr(p);
136
  p += 4;
137
  if (!(si->master_id= uint4korr(p)))
138
    si->master_id= server_id;
139
  si->thd= thd;
140
141
  pthread_mutex_lock(&LOCK_slave_list);
142
  unregister_slave(thd,0,0);
143
  res= my_hash_insert(&slave_list, (uchar*) si);
144
  pthread_mutex_unlock(&LOCK_slave_list);
145
  return res;
146
147
err:
148
  my_free(si, MYF(MY_WME));
149
  my_message(ER_UNKNOWN_ERROR, errmsg, MYF(0)); /* purecov: inspected */
150
err2:
151
  return 1;
152
}
153
154
extern "C" uint32
155
*slave_list_key(SLAVE_INFO* si, size_t *len,
156
		my_bool not_used __attribute__((unused)))
157
{
158
  *len = 4;
159
  return &si->server_id;
160
}
161
162
extern "C" void slave_info_free(void *s)
163
{
164
  my_free(s, MYF(MY_WME));
165
}
166
167
void init_slave_list()
168
{
169
  hash_init(&slave_list, system_charset_info, SLAVE_LIST_CHUNK, 0, 0,
170
	    (hash_get_key) slave_list_key, (hash_free_key) slave_info_free, 0);
171
  pthread_mutex_init(&LOCK_slave_list, MY_MUTEX_INIT_FAST);
172
}
173
174
void end_slave_list()
175
{
176
  /* No protection by a mutex needed as we are only called at shutdown */
177
  if (hash_inited(&slave_list))
178
  {
179
    hash_free(&slave_list);
180
    pthread_mutex_destroy(&LOCK_slave_list);
181
  }
182
}
183
184
185
bool show_slave_hosts(THD* thd)
186
{
187
  List<Item> field_list;
188
  Protocol *protocol= thd->protocol;
189
  DBUG_ENTER("show_slave_hosts");
190
191
  field_list.push_back(new Item_return_int("Server_id", 10,
192
					   MYSQL_TYPE_LONG));
193
  field_list.push_back(new Item_empty_string("Host", 20));
194
  if (opt_show_slave_auth_info)
195
  {
196
    field_list.push_back(new Item_empty_string("User",20));
197
    field_list.push_back(new Item_empty_string("Password",20));
198
  }
199
  field_list.push_back(new Item_return_int("Port", 7, MYSQL_TYPE_LONG));
200
  field_list.push_back(new Item_return_int("Rpl_recovery_rank", 7,
201
					   MYSQL_TYPE_LONG));
202
  field_list.push_back(new Item_return_int("Master_id", 10,
203
					   MYSQL_TYPE_LONG));
204
205
  if (protocol->send_fields(&field_list,
206
                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
207
    DBUG_RETURN(TRUE);
208
209
  pthread_mutex_lock(&LOCK_slave_list);
210
211
  for (uint i = 0; i < slave_list.records; ++i)
212
  {
213
    SLAVE_INFO* si = (SLAVE_INFO*) hash_element(&slave_list, i);
214
    protocol->prepare_for_resend();
215
    protocol->store((uint32) si->server_id);
216
    protocol->store(si->host, &my_charset_bin);
217
    if (opt_show_slave_auth_info)
218
    {
219
      protocol->store(si->user, &my_charset_bin);
220
      protocol->store(si->password, &my_charset_bin);
221
    }
222
    protocol->store((uint32) si->port);
223
    protocol->store((uint32) si->rpl_recovery_rank);
224
    protocol->store((uint32) si->master_id);
225
    if (protocol->write())
226
    {
227
      pthread_mutex_unlock(&LOCK_slave_list);
228
      DBUG_RETURN(TRUE);
229
    }
230
  }
231
  pthread_mutex_unlock(&LOCK_slave_list);
232
  my_eof(thd);
233
  DBUG_RETURN(FALSE);
234
}
235
236
#endif /* HAVE_REPLICATION */
237