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