• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/db-4.8.30/docs/gsg_db_rep/C/
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3<html xmlns="http://www.w3.org/1999/xhtml">
4  <head>
5    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6    <title>Chapter��4.��Replica versus Master Processes</title>
7    <link rel="stylesheet" href="gettingStarted.css" type="text/css" />
8    <meta name="generator" content="DocBook XSL Stylesheets V1.73.2" />
9    <link rel="start" href="index.html" title="Getting Started with Replicated Berkeley DB Applications" />
10    <link rel="up" href="index.html" title="Getting Started with Replicated Berkeley DB Applications" />
11    <link rel="prev" href="heartbeats.html" title="Managing Heartbeats" />
12    <link rel="next" href="processingloop.html" title="Processing Loop" />
13  </head>
14  <body>
15    <div class="navheader">
16      <table width="100%" summary="Navigation header">
17        <tr>
18          <th colspan="3" align="center">Chapter��4.��Replica versus Master Processes</th>
19        </tr>
20        <tr>
21          <td width="20%" align="left"><a accesskey="p" href="heartbeats.html">Prev</a>��</td>
22          <th width="60%" align="center">��</th>
23          <td width="20%" align="right">��<a accesskey="n" href="processingloop.html">Next</a></td>
24        </tr>
25      </table>
26      <hr />
27    </div>
28    <div class="chapter" lang="en" xml:lang="en">
29      <div class="titlepage">
30        <div>
31          <div>
32            <h2 class="title"><a id="fwrkmasterreplica"></a>Chapter��4.��Replica versus Master Processes</h2>
33          </div>
34        </div>
35      </div>
36      <div class="toc">
37        <p>
38          <b>Table of Contents</b>
39        </p>
40        <dl>
41          <dt>
42            <span class="sect1">
43              <a href="fwrkmasterreplica.html#determinestate">Determining State</a>
44            </span>
45          </dt>
46          <dt>
47            <span class="sect1">
48              <a href="processingloop.html">Processing Loop</a>
49            </span>
50          </dt>
51          <dt>
52            <span class="sect1">
53              <a href="exampledoloop.html">Example Processing Loop</a>
54            </span>
55          </dt>
56          <dd>
57            <dl>
58              <dt>
59                <span class="sect2">
60                  <a href="exampledoloop.html#runningit">Running It</a>
61                </span>
62              </dt>
63            </dl>
64          </dd>
65        </dl>
66      </div>
67      <p>
68                  Every environment participating in a replicated application
69                  must know whether it is a <span class="emphasis"><em>master</em></span> or
70                  <span class="emphasis"><em>replica</em></span>. The reason for this is
71                  because, simply, the master can modify the database while
72                  replicas cannot. As a result, not only will you open
73                  databases differently depended on whether the environment is
74                  running as a master, but the environment will frequently
75                  behave quite a bit differently depending on whether it
76                  thinks it is operating as the read/write interface for
77                  your database.
78          </p>
79      <p>
80                  Moreover, an environment must also be capable of
81                  gracefully switching between master and replica states.
82                  This means that the environment must be able to detect when
83                  it has switched states.
84          </p>
85      <p>
86                  Not surprisingly, a large part of your application's code
87                  will be tied up in knowing which state a given
88                  environment is in and then in the logic of how to behave depending on
89                  its state.
90          </p>
91      <p>
92                  This chapter shows you how to determine your environment's
93                  state, and it then shows you some sample code on how
94                  an application might behave depending on whether it is a
95                  master or a replica in a replicated application.
96          </p>
97      <div class="sect1" lang="en" xml:lang="en">
98        <div class="titlepage">
99          <div>
100            <div>
101              <h2 class="title" style="clear: both"><a id="determinestate"></a>Determining State</h2>
102            </div>
103          </div>
104        </div>
105        <p>
106                          In order to determine whether your code is
107                          running as a master or a replica, you implement a
108                          callback whose function it is to respond to
109                          events that happen within the DB library. 
110                          Note that these events are raised whenever the state is established. 
111                          For example, when the current environment becomes a client ���
112                          including at application startup ��� the
113                          <code class="literal">DB_EVENT_REP_CLIENT</code> event is raised. Also, when an
114                          election is held and a replica is elected to be a master, the
115                          <code class="literal">DB_EVENT_REP_MASTER</code> event is raised on the newly elected master and the
116                          <code class="literal">DB_EVENT_REP_NEWMASTER</code> is raised on the other replicas.
117                  </p>
118        <p>
119                          Note that this callback is usable for events beyond
120                          those required for replication purposes. In this
121                          section, however, we only discuss the
122                          replication-specific events.
123                  </p>
124        <p>
125                          The callback is required to determine
126                          which event has been passed to it, and then take
127                          action depending on the event. For replication,
128                          the events that we care about are:
129                  </p>
130        <div class="itemizedlist">
131          <ul type="disc">
132            <li>
133              <p>
134                                          <code class="literal">DB_EVENT_REP_MASTER</code>
135                                          
136                                  </p>
137              <p>
138                                          The local environment is now a master.
139                                  </p>
140            </li>
141            <li>
142              <p>
143                                          <code class="literal">DB_EVENT_REP_CLIENT</code>
144                                          
145                                  </p>
146              <p>
147                                          The local environment is now a replica.
148                                  </p>
149            </li>
150            <li>
151              <p>
152                                          <code class="literal">DB_EVENT_REP_STARTUPDONE</code>
153                                          
154                                  </p>
155              <p>
156                                          The replica has completed startup
157                                          synchronization and is now
158                                          processing log records received
159                                          from the master.
160                                  </p>
161            </li>
162            <li>
163              <p>
164                                          <code class="literal">DB_EVENT_REP_NEWMASTER</code>
165                                          
166                                  </p>
167              <p>
168                                          An election was held and a new environment was made a
169                                          master.  However, the current environment <span class="emphasis"><em>is
170                                              not</em></span> the master. This event exists so that
171                                          you can cause your code to take some unique action in the
172                                          event that the replication groups switches masters.
173                                  </p>
174            </li>
175          </ul>
176        </div>
177        <p>
178                          Note that these events are raised whenever the
179                          state is established. That is, when the current
180                          environment becomes a replica, and that includes
181                          at application startup, the event is raised.
182                          Also, when an election is held and a replica is elected to be a
183                          master, then the event occurs.
184                  </p>
185        <p>
186                          The implementation of this callback is fairly
187                          simple. First you pass a structure to the
188                          environment handle that you can use to record the
189                          environment's state, and then you implement a switch
190                          statement within the callback that you use to
191                          record the current state, depending on the
192                          arriving event.
193                  </p>
194        <p>
195                          For example:
196                  </p>
197        <pre class="programlisting">#include &lt;db.h&gt;
198/* Forward declaration */
199void *event_callback(DB_ENV *, u_int32_t, void *);
200
201...
202
203/* The structure we use to track our environment's state */
204typedef struct {
205    int is_master;
206} APP_DATA;
207
208...
209
210/*
211 * Inside our main() function, we declare an APP_DATA variable.
212 */
213APP_DATA my_app_data;
214my_app_data.is_master = 0; /* Assume we start as a replica */
215
216...
217
218/*
219 * Now we create our environment handle and set the APP_DATA structure
220 * to it's app_private member.
221 */
222if ((ret = db_env_create(&amp;dbenv, 0)) != 0 ) {
223    fprintf(stderr, "Error creating handles: %s\n",
224        db_strerror(ret));
225    goto err;
226}
227dbenv-&gt;app_private = &amp;my_app_data;
228
229/* Having done that, register the callback with the
230 * Berkeley DB library
231 */
232dbenv-&gt;set_event_notify(dbenv, event_callback); </pre>
233        <p>
234        That done, we still need to implement the callback itself. This
235        implementation can be fairly trivial. 
236</p>
237        <pre class="programlisting">/*
238 * A callback used to determine whether the local environment is a 
239 * replica or a master. This is called by the Replication Manager
240 * when the local environment changes state.
241 */
242void *
243event_callback(DB_ENV *dbenv, u_int32_t which, void *info)
244{
245    APP_DATA *app = dbenv-&gt;app_private;
246
247    info = NULL;                /* Currently unused. */
248
249    switch (which) {
250    case DB_EVENT_REP_MASTER:
251        app-&gt;is_master = 1;
252        break;
253
254    case DB_EVENT_REP_CLIENT:
255        app-&gt;is_master = 0;
256        break;
257
258    case DB_EVENT_REP_STARTUPDONE: /* fallthrough */
259    case DB_EVENT_REP_NEWMASTER:
260        /* Ignore. */
261        break;
262
263    default:
264        dbenv-&gt;errx(dbenv, "ignoring event %d", which);
265    }
266} </pre>
267        <p>
268        Notice how we access the
269        <code class="literal">APP_DATA</code> information using the environment
270        handle's <code class="literal">app_private</code> data member. We also ignore
271        the <code class="literal">DB_EVENT_REP_NEWMASTER</code> and
272        <code class="literal">DB_EVENT_REP_STARTUPDONE</code> cases since these are not
273        relevant for simple replicated applications.
274</p>
275        <p>
276        Of course, this only gives us the current state of the environment. We
277        still need the code that determines what to do when the environment 
278        changes state and how to behave depending on the state (described
279        in the next section).
280</p>
281      </div>
282    </div>
283    <div class="navfooter">
284      <hr />
285      <table width="100%" summary="Navigation footer">
286        <tr>
287          <td width="40%" align="left"><a accesskey="p" href="heartbeats.html">Prev</a>��</td>
288          <td width="20%" align="center">��</td>
289          <td width="40%" align="right">��<a accesskey="n" href="processingloop.html">Next</a></td>
290        </tr>
291        <tr>
292          <td width="40%" align="left" valign="top">Managing Heartbeats��</td>
293          <td width="20%" align="center">
294            <a accesskey="h" href="index.html">Home</a>
295          </td>
296          <td width="40%" align="right" valign="top">��Processing Loop</td>
297        </tr>
298      </table>
299    </div>
300  </body>
301</html>
302