• 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>Adding the Replication Manager to ex_rep_gsg_simple</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="repapp.html" title="Chapter��3.��The DB Replication Manager" />
11    <link rel="prev" href="repapp.html" title="Chapter��3.��The DB Replication Manager" />
12    <link rel="next" href="fwrkpermmessage.html" title="Permanent Message Handling" />
13  </head>
14  <body>
15    <div class="navheader">
16      <table width="100%" summary="Navigation header">
17        <tr>
18          <th colspan="3" align="center">Adding the Replication Manager to
19                    <span>ex_rep_gsg_simple</span>
20                    
21                    
22            </th>
23        </tr>
24        <tr>
25          <td width="20%" align="left"><a accesskey="p" href="repapp.html">Prev</a>��</td>
26          <th width="60%" align="center">Chapter��3.��The DB Replication Manager</th>
27          <td width="20%" align="right">��<a accesskey="n" href="fwrkpermmessage.html">Next</a></td>
28        </tr>
29      </table>
30      <hr />
31    </div>
32    <div class="sect1" lang="en" xml:lang="en">
33      <div class="titlepage">
34        <div>
35          <div>
36            <h2 class="title" style="clear: both"><a id="repmgr_init_example_c"></a>Adding the Replication Manager to
37                    <span>ex_rep_gsg_simple</span>
38                    
39                    
40            </h2>
41          </div>
42        </div>
43      </div>
44      <p>
45                    We now use the methods described above to add partial
46                    support to the 
47                    <span>ex_rep_gsg_simple</span>
48                    
49                    
50                    example that we presented in 
51                    <a class="xref" href="txnapp.html" title="Chapter��2.��Transactional Application">Transactional Application</a>.
52                    That is, in this section we will:
53            </p>
54      <div class="itemizedlist">
55        <ul type="disc">
56          <li>
57            <p>
58                                    Enhance our command line options to
59                                    accept information of interest to a
60                                    replicated application.
61                            </p>
62          </li>
63          <li>
64            <p>
65                                    Configure our environment handle to use
66                                    replication and the Replication Manager.
67                            </p>
68          </li>
69          <li>
70            <p>
71                                    Minimally configure the Replication Manager.
72                            </p>
73          </li>
74          <li>
75            <p>
76                                    Start replication.
77                            </p>
78          </li>
79        </ul>
80      </div>
81      <p>
82                Note that when we are done with this section, we will be
83                only partially ready to run the application. Some critical
84                pieces will be missing; specifically, we will not yet be
85                handling the differences between a master and a
86                replica. (We do that in the next chapter).
87            </p>
88      <p>
89                Also, note that in the following code fragments, additions
90                and changes to the code are marked in <strong class="userinput"><code>bold</code></strong>.
91            </p>
92      <p>
93                    To begin, we copy the 
94                    <span>ex_rep_gsg_simple</span>
95                    
96                    code to a new file called
97                    <code class="literal">ex_rep_gsg_repmgr.c</code>.
98
99                    <span>
100                    We then make the corresponding change to the program name.
101                    </span>
102
103                    
104            </p>
105      <pre class="programlisting">/*
106 <strong class="userinput"><code>* File: ex_rep_gsg_repmgr.c</code></strong>
107 */
108
109#include &lt;stdlib.h&gt;
110#include &lt;string.h&gt;
111#ifndef _WIN32
112#include &lt;unistd.h&gt;
113#endif
114
115#include &lt;db.h&gt;
116
117#ifdef _WIN32
118extern int getopt(int, char * const *, const char *);
119#endif
120
121#define CACHESIZE   (10 * 1024 * 1024)
122#define DATABASE    "quote.db"
123
124const char *progname = <strong class="userinput"><code>"ex_rep_gsg_repmgr";</code></strong>
125
126int create_env(const char *, DB_ENV **);
127int env_init(DB_ENV *, const char *);
128int doloop (DB_ENV *);
129int print_stocks(DBC *); </pre>
130      <p>
131        Next we update our usage function. The application will continue to
132        accept the <code class="literal">-h</code> parameter so that we can identify
133        the environment home directory used by this application. However,
134        we also add the 
135</p>
136      <div class="itemizedlist">
137        <ul type="disc">
138          <li>
139            <p>
140                    <code class="literal">-l</code> parameter which allows us to
141                    identify the host and port used by this application to
142                    listen for replication messages.
143                </p>
144          </li>
145          <li>
146            <p>
147                        <code class="literal">-r</code> parameter which allows us to
148                        specify other replicas.
149                </p>
150          </li>
151          <li>
152            <p>
153                        <code class="literal">-n</code> parameter which allows us to
154                        identify the number of sites in this replication
155                        group.
156                </p>
157          </li>
158          <li>
159            <p>
160                    <code class="literal">-p</code> option, which is used to identify
161                    this replica's priority (recall that the priority is
162                    used as a tie breaker for elections)
163                </p>
164          </li>
165        </ul>
166      </div>
167      <pre class="programlisting">/* Usage function */
168static void
169usage()
170{
171  fprintf(stderr, "usage: %s ", progname);
172  fprintf(stderr, "-h home <strong class="userinput"><code>-l host:port -n nsites</code></strong>\n");
173  <strong class="userinput"><code>fprintf(stderr, "\t\t[-r host:port][-p priority]\n");
174  fprintf(stderr, "where:\n");
175  fprintf(stderr, "\t-h identifies the environment home directory ");
176  fprintf(stderr, "(required).\n");
177  fprintf(stderr, "\t-l identifies the host and port used by this ");
178  fprintf(stderr, "site (required).\n");
179  fprintf(stderr, "\t-n identifies the number of sites in this ");
180  fprintf(stderr, "replication group (required).\n");
181  fprintf(stderr, "\t-r identifies another site participating in ");
182  fprintf(stderr, "this replication group\n");
183  fprintf(stderr, "\t-p identifies the election priority used by ");
184  fprintf(stderr, "this replica.\n");</code></strong>
185  exit(EXIT_FAILURE);
186} </pre>
187      <p>
188        Now we can begin working on our <code class="literal">main()</code> function.
189        We begin by adding a couple of variables that we will use to
190        collect TCP/IP host and port information. 
191
192
193        <span>
194        We also declare a couple
195        of flags that we use to make sure some required information is
196        provided to this application. 
197        </span>
198</p>
199      <pre class="programlisting">int
200main(int argc, char *argv[])
201{
202    extern char *optarg;
203    DB_ENV *dbenv;
204    const char *home;
205    char ch, <strong class="userinput"><code>*host, *portstr</code></strong>;
206    int ret, <strong class="userinput"><code>local_is_set, totalsites</code></strong>;
207    <strong class="userinput"><code>u_int32_t port</code></strong>;
208
209    dbenv = NULL;
210
211    ret = <strong class="userinput"><code>local_is_set = totalsites = </code></strong>0;
212    home = NULL; </pre>
213      <p>
214        At this time we can create our environment handle and configure it
215        exactly as we did for <code class="literal">simple_txn</code>.  
216        The only thing that we will do differently here is that we will set a priority,
217        arbitrarily picked to be 100, so that we can be sure the environment has
218        a priority other than 0 (the default value). This ensures that the
219        environment can become a master via an election.
220</p>
221      <pre class="programlisting">    if ((ret = create_env(progname, &amp;dbenv)) != 0)
222            goto err;
223
224    /* Default priority is 100 */
225    <strong class="userinput"><code>dbenv-&gt;rep_set_priority(dbenv, 100);</code></strong>   </pre>
226      <p>
227        Now we collect our command line arguments. As we do so, we will
228        configure host and port information as required, and we will
229        configure the application's election priority if necessary.
230</p>
231      <pre class="programlisting">    /* Collect the command line options */
232    while ((ch = getopt(argc, argv, "h:<strong class="userinput"><code>l:n:p:r:</code></strong>")) != EOF)
233        switch (ch) {
234        case 'h':
235            home = optarg;
236            break;
237        <strong class="userinput"><code>/* Set the host and port used by this environment */
238        case 'l':
239            host = strtok(optarg, ":");
240            if ((portstr = strtok(NULL, ":")) == NULL) {
241                fprintf(stderr, "Bad host specification.\n");
242                goto err;
243            }
244            port = (unsigned short)atoi(portstr);
245            if (dbenv-&gt;repmgr_set_local_site(dbenv, host, port, 0) 
246                                                              != 0) {
247                fprintf(stderr,
248                    "Could not set local address %s.\n", host);
249                goto err;
250            }
251            local_is_set = 1;
252            break;
253        /* Set the number of sites in this replication group */
254        case 'n':
255            totalsites = atoi(optarg);
256            if ((ret = dbenv-&gt;rep_set_nsites(dbenv, totalsites)) 
257              != 0)
258                dbenv-&gt;err(dbenv, ret, "set_nsites");
259            break;
260        /* Set this replica's election priority */
261        case 'p':
262            dbenv-&gt;rep_set_priority(dbenv, atoi(optarg));
263            break;
264        /* Identify another site in the replication group */
265        case 'r':
266            host = strtok(optarg, ":");
267            if ((portstr = strtok(NULL, ":")) == NULL) {
268                fprintf(stderr, "Bad host specification.\n");
269                goto err;
270            }
271            port = (unsigned short)atoi(portstr);
272            if (dbenv-&gt;repmgr_add_remote_site(dbenv, host, port, 
273                                                 NULL, 0) != 0) {
274                fprintf(stderr,
275                    "Could not add site %s.\n", host);
276                goto err;
277            }
278            break;</code></strong>
279        case '?':
280        default:
281            usage();
282        }
283
284    /* Error check command line. */
285    if (home == NULL <strong class="userinput"><code>|| !local_is_set || !totalsites</code></strong>)
286        usage(); </pre>
287      <p>
288            Having done that, we can call <code class="function">env_init()</code>, which we use to 
289        open our environment handle. Note that this function changes
290        slightly for this update (see below).
291    </p>
292      <pre class="programlisting">    if ((ret = env_init(dbenv, home)) != 0)
293        goto err; </pre>
294      <p>
295        Finally, we start replication before we go into the 
296        <code class="function">doloop()</code> function (where we perform all our
297        database access). 
298</p>
299      <pre class="programlisting">
300    <strong class="userinput"><code>if ((ret = dbenv-&gt;repmgr_start(dbenv, 3, DB_REP_ELECTION)) != 0)
301        goto err; </code></strong>
302
303    if ((ret = doloop(dbenv)) != 0) {
304        dbenv-&gt;err(dbenv, ret, "Application failed");
305        goto err;
306    }
307
308err: if (dbenv != NULL)
309        (void)dbenv-&gt;close(dbenv, 0);
310
311    return (ret);
312} </pre>
313      <p>
314            <span>Beyond that, the rest of our application remains the same for
315            now, with the exception of the <code class="function">env_init()</code>
316            function, which we use to actually open our environment handle.
317            The flags </span>
318
319            
320
321            
322
323            we use to open the environment are slightly different for a
324            replicated application than they are for a non-replicated
325            application. Namely, replication requires the
326            <span>
327            <code class="literal">DB_INIT_REP</code> flag. 
328            </span>
329
330            
331    </p>
332      <p>
333            Also, because we are using the Replication Manager, we must prepare
334            our environment for threaded usage. For this reason, we also
335            need the <code class="literal">DB_THREAD</code> flag.
336    </p>
337      <pre class="programlisting">int
338env_init(DB_ENV *dbenv, const char *home)
339{
340    u_int32_t flags;
341    int ret;
342
343    (void)dbenv-&gt;set_cachesize(dbenv, 0, CACHESIZE, 0);
344    (void)dbenv-&gt;set_flags(dbenv, DB_TXN_NOSYNC, 1);
345
346    flags = DB_CREATE | 
347            DB_INIT_LOCK | 
348            DB_INIT_LOG | 
349            DB_INIT_MPOOL |
350            <strong class="userinput"><code>DB_INIT_REP |</code></strong>
351            DB_INIT_TXN | 
352            DB_RECOVER <strong class="userinput"><code>|
353            DB_THREAD;</code></strong>
354    if ((ret = dbenv-&gt;open(dbenv, home, flags, 0)) != 0)
355        dbenv-&gt;err(dbenv, ret, "can't open environment");
356    return (ret);
357}</pre>
358      <p>
359        This completes our replication updates for the moment. We are not as
360        yet ready to actually run this program; there remains a few
361        critical pieces left to add to it. However, the work that we
362        performed in this section represents a solid foundation for the
363        remainder of our replication work.
364    </p>
365    </div>
366    <div class="navfooter">
367      <hr />
368      <table width="100%" summary="Navigation footer">
369        <tr>
370          <td width="40%" align="left"><a accesskey="p" href="repapp.html">Prev</a>��</td>
371          <td width="20%" align="center">
372            <a accesskey="u" href="repapp.html">Up</a>
373          </td>
374          <td width="40%" align="right">��<a accesskey="n" href="fwrkpermmessage.html">Next</a></td>
375        </tr>
376        <tr>
377          <td width="40%" align="left" valign="top">Chapter��3.��The DB Replication Manager��</td>
378          <td width="20%" align="center">
379            <a accesskey="h" href="index.html">Home</a>
380          </td>
381          <td width="40%" align="right" valign="top">��Permanent Message Handling</td>
382        </tr>
383      </table>
384    </div>
385  </body>
386</html>
387