~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/repl_failsafe.cc

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
#include <mysql.h>
 
36
 
 
37
#define SLAVE_LIST_CHUNK 128
 
38
#define SLAVE_ERRMSG_SIZE (FN_REFLEN+64)
 
39
 
 
40
 
 
41
RPL_STATUS rpl_status=RPL_NULL;
 
42
pthread_mutex_t LOCK_rpl_status;
 
43
pthread_cond_t COND_rpl_status;
 
44
HASH slave_list;
 
45
 
 
46
const char *rpl_role_type[] = {"MASTER","SLAVE",NullS};
 
47
TYPELIB rpl_role_typelib = {array_elements(rpl_role_type)-1,"",
 
48
                            rpl_role_type, NULL};
 
49
 
 
50
const char* rpl_status_type[]=
 
51
{
 
52
  "AUTH_MASTER","ACTIVE_SLAVE","IDLE_SLAVE", "LOST_SOLDIER","TROOP_SOLDIER",
 
53
  "RECOVERY_CAPTAIN","NULL",NullS
 
54
};
 
55
TYPELIB rpl_status_typelib= {array_elements(rpl_status_type)-1,"",
 
56
                             rpl_status_type, NULL};
 
57
 
 
58
 
 
59
void change_rpl_status(RPL_STATUS from_status, RPL_STATUS to_status)
 
60
{
 
61
  pthread_mutex_lock(&LOCK_rpl_status);
 
62
  if (rpl_status == from_status || rpl_status == RPL_ANY)
 
63
    rpl_status = to_status;
 
64
  pthread_cond_signal(&COND_rpl_status);
 
65
  pthread_mutex_unlock(&LOCK_rpl_status);
 
66
}
 
67
 
 
68
 
 
69
#define get_object(p, obj, msg) \
 
70
{\
 
71
  uint len = (uint)*p++;  \
 
72
  if (p + len > p_end || len >= sizeof(obj)) \
 
73
  {\
 
74
    errmsg= msg;\
 
75
    goto err; \
 
76
  }\
 
77
  strmake(obj,(char*) p,len); \
 
78
  p+= len; \
 
79
}\
 
80
 
 
81
 
 
82
static inline int cmp_master_pos(Slave_log_event* sev, LEX_MASTER_INFO* mi)
 
83
{
 
84
  return cmp_master_pos(sev->master_log, sev->master_pos, mi->log_file_name,
 
85
                        mi->pos);
 
86
}
 
87
 
 
88
 
 
89
void unregister_slave(THD* thd, bool only_mine, bool need_mutex)
 
90
{
 
91
  if (thd->server_id)
 
92
  {
 
93
    if (need_mutex)
 
94
      pthread_mutex_lock(&LOCK_slave_list);
 
95
 
 
96
    SLAVE_INFO* old_si;
 
97
    if ((old_si = (SLAVE_INFO*)hash_search(&slave_list,
 
98
                                           (uchar*)&thd->server_id, 4)) &&
 
99
        (!only_mine || old_si->thd == thd))
 
100
    hash_delete(&slave_list, (uchar*)old_si);
 
101
 
 
102
    if (need_mutex)
 
103
      pthread_mutex_unlock(&LOCK_slave_list);
 
104
  }
 
105
}
 
106
 
 
107
 
 
108
/**
 
109
  Register slave in 'slave_list' hash table.
 
110
 
 
111
  @return
 
112
    0   ok
 
113
  @return
 
114
    1   Error.   Error message sent to client
 
115
*/
 
116
 
 
117
int register_slave(THD* thd, uchar* packet, uint packet_length)
 
118
{
 
119
  int res;
 
120
  SLAVE_INFO *si;
 
121
  uchar *p= packet, *p_end= packet + packet_length;
 
122
  const char *errmsg= "Wrong parameters to function register_slave";
 
123
 
 
124
  if (!(si = (SLAVE_INFO*)my_malloc(sizeof(SLAVE_INFO), MYF(MY_WME))))
 
125
    goto err2;
 
126
 
 
127
  thd->server_id= si->server_id= uint4korr(p);
 
128
  p+= 4;
 
129
  get_object(p,si->host, "Failed to register slave: too long 'report-host'");
 
130
  get_object(p,si->user, "Failed to register slave: too long 'report-user'");
 
131
  get_object(p,si->password, "Failed to register slave; too long 'report-password'");
 
132
  if (p+10 > p_end)
 
133
    goto err;
 
134
  si->port= uint2korr(p);
 
135
  p += 2;
 
136
  si->rpl_recovery_rank= uint4korr(p);
 
137
  p += 4;
 
138
  if (!(si->master_id= uint4korr(p)))
 
139
    si->master_id= server_id;
 
140
  si->thd= thd;
 
141
 
 
142
  pthread_mutex_lock(&LOCK_slave_list);
 
143
  unregister_slave(thd,0,0);
 
144
  res= my_hash_insert(&slave_list, (uchar*) si);
 
145
  pthread_mutex_unlock(&LOCK_slave_list);
 
146
  return res;
 
147
 
 
148
err:
 
149
  my_free(si, MYF(MY_WME));
 
150
  my_message(ER_UNKNOWN_ERROR, errmsg, MYF(0)); /* purecov: inspected */
 
151
err2:
 
152
  return 1;
 
153
}
 
154
 
 
155
extern "C" uint32
 
156
*slave_list_key(SLAVE_INFO* si, size_t *len,
 
157
                my_bool not_used __attribute__((unused)))
 
158
{
 
159
  *len = 4;
 
160
  return &si->server_id;
 
161
}
 
162
 
 
163
extern "C" void slave_info_free(void *s)
 
164
{
 
165
  my_free(s, MYF(MY_WME));
 
166
}
 
167
 
 
168
void init_slave_list()
 
169
{
 
170
  hash_init(&slave_list, system_charset_info, SLAVE_LIST_CHUNK, 0, 0,
 
171
            (hash_get_key) slave_list_key, (hash_free_key) slave_info_free, 0);
 
172
  pthread_mutex_init(&LOCK_slave_list, MY_MUTEX_INIT_FAST);
 
173
}
 
174
 
 
175
void end_slave_list()
 
176
{
 
177
  /* No protection by a mutex needed as we are only called at shutdown */
 
178
  if (hash_inited(&slave_list))
 
179
  {
 
180
    hash_free(&slave_list);
 
181
    pthread_mutex_destroy(&LOCK_slave_list);
 
182
  }
 
183
}
 
184
 
 
185
 
 
186
bool show_slave_hosts(THD* thd)
 
187
{
 
188
  List<Item> field_list;
 
189
  Protocol *protocol= thd->protocol;
 
190
  DBUG_ENTER("show_slave_hosts");
 
191
 
 
192
  field_list.push_back(new Item_return_int("Server_id", 10,
 
193
                                           MYSQL_TYPE_LONG));
 
194
  field_list.push_back(new Item_empty_string("Host", 20));
 
195
  if (opt_show_slave_auth_info)
 
196
  {
 
197
    field_list.push_back(new Item_empty_string("User",20));
 
198
    field_list.push_back(new Item_empty_string("Password",20));
 
199
  }
 
200
  field_list.push_back(new Item_return_int("Port", 7, MYSQL_TYPE_LONG));
 
201
  field_list.push_back(new Item_return_int("Rpl_recovery_rank", 7,
 
202
                                           MYSQL_TYPE_LONG));
 
203
  field_list.push_back(new Item_return_int("Master_id", 10,
 
204
                                           MYSQL_TYPE_LONG));
 
205
 
 
206
  if (protocol->send_fields(&field_list,
 
207
                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
 
208
    DBUG_RETURN(TRUE);
 
209
 
 
210
  pthread_mutex_lock(&LOCK_slave_list);
 
211
 
 
212
  for (uint i = 0; i < slave_list.records; ++i)
 
213
  {
 
214
    SLAVE_INFO* si = (SLAVE_INFO*) hash_element(&slave_list, i);
 
215
    protocol->prepare_for_resend();
 
216
    protocol->store((uint32) si->server_id);
 
217
    protocol->store(si->host, &my_charset_bin);
 
218
    if (opt_show_slave_auth_info)
 
219
    {
 
220
      protocol->store(si->user, &my_charset_bin);
 
221
      protocol->store(si->password, &my_charset_bin);
 
222
    }
 
223
    protocol->store((uint32) si->port);
 
224
    protocol->store((uint32) si->rpl_recovery_rank);
 
225
    protocol->store((uint32) si->master_id);
 
226
    if (protocol->write())
 
227
    {
 
228
      pthread_mutex_unlock(&LOCK_slave_list);
 
229
      DBUG_RETURN(TRUE);
 
230
    }
 
231
  }
 
232
  pthread_mutex_unlock(&LOCK_slave_list);
 
233
  my_eof(thd);
 
234
  DBUG_RETURN(FALSE);
 
235
}
 
236
 
 
237
#endif /* HAVE_REPLICATION */
 
238