Revision: 47923
Author:   river
Date:     2009-03-02 08:17:15 +0000 (Mon, 02 Mar 2009)

Log Message:
-----------
- remove multi-threaded writers, as it never really worked and isn't used
- add configuration options for several command-line options

Modified Paths:
--------------
    trunk/tools/trainwreck/Makefile
    trunk/tools/trainwreck/config.c
    trunk/tools/trainwreck/config.h
    trunk/tools/trainwreck/trainwreck.c
    trunk/tools/trainwreck/trainwreck.conf.sample

Removed Paths:
-------------
    trunk/tools/trainwreck/fnv.h
    trunk/tools/trainwreck/hash_32a.c

Modified: trunk/tools/trainwreck/Makefile
===================================================================
--- trunk/tools/trainwreck/Makefile     2009-03-02 07:53:27 UTC (rev 47922)
+++ trunk/tools/trainwreck/Makefile     2009-03-02 08:17:15 UTC (rev 47923)
@@ -14,7 +14,6 @@
 SRCS           =       \
        trainwreck.c    \
        config.c        \
-       hash_32a.c      \
 
 OBJS           = $(SRCS:.c=.o)
 
@@ -33,7 +32,7 @@
        lint $(INCLUDES) $(MYSQL_CFLAGS) -axsm -u -errtags=yes -s -Xc99=%none 
-Xarch=amd64 -errsecurity=core -erroff=E_INCONS_ARG_DECL2 
-erroff=E_CONSTANT_CONDITION $(SRCS)
 
 clean:
-       rm -f trainwreck $(OBJS) twctl.o
+       rm -f trainwreck twctl $(OBJS) twctl.o
 
 .PHONY: clean install lint
 .KEEP_STATE:

Modified: trunk/tools/trainwreck/config.c
===================================================================
--- trunk/tools/trainwreck/config.c     2009-03-02 07:53:27 UTC (rev 47922)
+++ trunk/tools/trainwreck/config.c     2009-03-02 08:17:15 UTC (rev 47923)
@@ -20,7 +20,6 @@
 regex_t *ignore_regex;
 
 int server_id = 4123;
-int nwriters = 1;
 int *ignorable_errno;
 int nignorable;
 
@@ -31,6 +30,9 @@
 int max_buffer = 0;
 
 char *ctldoor;
+char *statedir;
+int autostart;
+int unsynced;
 
 static void do_ignore_errno(unsigned);
 
@@ -95,14 +97,18 @@
                        slave_port = atoi(value);
                } else if (!strcmp(opt, "ignore-errno")) {
                        do_ignore_errno(atoi(value));
-               } else if (!strcmp(opt, "nwriters")) {
-                       nwriters = atoi(value);
                } else if (!strcmp(opt, "max-buffer")) {
                        max_buffer = atoi(value);
                } else if (!strcmp(opt, "server-id")) {
                        server_id = atoi(value);
                } else if (!strcmp(opt, "control-door")) {
                        strdup_free(&ctldoor, value);
+               } else if (!strcmp(opt, "statedir")) {
+                       strdup_free(&statedir, value);
+               } else if (!strcmp(opt, "autostart")) {
+                       autostart = atoi(value);
+               } else if (!strcmp(opt, "unsynced")) {
+                       unsynced = atoi(value);
                } else if (!strcmp(opt, "only-replicate")) {
                int     err;
                        db_regex = calloc(1, sizeof(*db_regex));

Modified: trunk/tools/trainwreck/config.h
===================================================================
--- trunk/tools/trainwreck/config.h     2009-03-02 07:53:27 UTC (rev 47922)
+++ trunk/tools/trainwreck/config.h     2009-03-02 08:17:15 UTC (rev 47923)
@@ -17,7 +17,6 @@
 
 int can_ignore_errno(unsigned);
 
-extern int nwriters;
 extern int *ignorable_errno;
 extern int nignorable;
 
@@ -29,6 +28,9 @@
 extern int max_buffer;
 
 extern char *ctldoor;
+extern char *statedir;
+extern int autostart;
+extern int unsynced;
 
 extern regex_t *db_regex;
 extern regex_t *ignore_regex;

Deleted: trunk/tools/trainwreck/fnv.h
===================================================================
--- trunk/tools/trainwreck/fnv.h        2009-03-02 07:53:27 UTC (rev 47922)
+++ trunk/tools/trainwreck/fnv.h        2009-03-02 08:17:15 UTC (rev 47923)
@@ -1,114 +0,0 @@
-/* $Id$ */
-/*
- * fnv - Fowler/Noll/Vo- hash code
- *
- * @(#) Revision: 1.5
- * @(#) Id: fnv.h,v 1.5 2003/10/03 20:35:52 chongo Exp
- * @(#) Source: /usr/local/src/cmd/fnv/RCS/fnv.h,v
- *
- ***
- *
- * Fowler/Noll/Vo- hash
- *
- * The basis of this hash algorithm was taken from an idea sent
- * as reviewer comments to the IEEE POSIX P1003.2 committee by:
- *
- *      Phong Vo (http://www.research.att.com/info/kpv/)
- *      Glenn Fowler (http://www.research.att.com/~gsf/)
- *
- * In a subsequent ballot round:
- *
- *      Landon Curt Noll (http://www.isthe.com/chongo/)
- *
- * improved on their algorithm.  Some people tried this hash
- * and found that it worked rather well.  In an EMail message
- * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash.
- *
- * FNV hashes are designed to be fast while maintaining a low
- * collision rate. The FNV speed allows one to quickly hash lots
- * of data while maintaining a reasonable collision rate.  See:
- *
- *      http://www.isthe.com/chongo/tech/comp/fnv/index.html
- *
- * for more details as well as other forms of the FNV hash.
- *
- ***
- *
- * NOTE: The FNV-0 historic hash is not recommended.  One should use
- *      the FNV-1 hash instead.
- *
- * To use the 32 bit FNV-0 historic hash, pass FNV0_32_INIT as the
- * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str().
- *
- * To use the 64 bit FNV-0 historic hash, pass FNV0_64_INIT as the
- * Fnv64_t hashval argument to fnv_64_buf() or fnv_64_str().
- *
- * To use the recommended 32 bit FNV-1 hash, pass FNV1_32_INIT as the
- * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str().
- *
- * To use the recommended 64 bit FNV-1 hash, pass FNV1_64_INIT as the
- * Fnv64_t hashval argument to fnv_64_buf() or fnv_64_str().
- *
- * To use the recommended 32 bit FNV-1a hash, pass FNV1_32A_INIT as the
- * Fnv32_t hashval argument to fnv_32a_buf() or fnv_32a_str().
- *
- * To use the recommended 64 bit FNV-1a hash, pass FNV1_64A_INIT as the
- * Fnv64_t hashval argument to fnv_64a_buf() or fnv_64a_str().
- *
- ***
- *
- * Please do not copyright this code.  This code is in the public domain.
- *
- * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
- * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
- * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
- * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * By:
- *     chongo <Landon Curt Noll> /\oo/\
- *      http://www.isthe.com/chongo/
- *
- * Share and Enjoy!    :-)
- */
-
-#if !defined(__FNV_H__)
-#define __FNV_H__
-
-
-/*
- * 32 bit FNV-0 hash type
- */
-typedef unsigned long Fnv32_t;
-
-
-/*
- * 32 bit FNV-0 zero initial basis
- *
- * This historic hash is not recommended.  One should use
- * the FNV-1 hash and initial basis instead.
- */
-#define FNV0_32_INIT ((Fnv32_t)0)
-
-
-/*
- * 32 bit FNV-1 and FNV-1a non-zero initial basis
- *
- * The FNV-1 initial basis is the FNV-0 hash of the following 32 octets:
- *
- *              chongo <Landon Curt Noll> /\../\
- *
- * NOTE: The \'s above are not back-slashing escape characters.
- * They are literal ASCII  backslash 0x5c characters.
- *
- * NOTE: The FNV-1a initial basis is the same value as FNV-1 by definition.
- */
-#define FNV1_32_INIT ((Fnv32_t)0x811c9dc5)
-#define FNV1_32A_INIT FNV1_32_INIT
-
-
-extern Fnv32_t fnv_32a_str(char const *buf, Fnv32_t hashval);
-
-#endif /* __FNV_H__ */

Deleted: trunk/tools/trainwreck/hash_32a.c
===================================================================
--- trunk/tools/trainwreck/hash_32a.c   2009-03-02 07:53:27 UTC (rev 47922)
+++ trunk/tools/trainwreck/hash_32a.c   2009-03-02 08:17:15 UTC (rev 47923)
@@ -1,102 +0,0 @@
-/* $Id$ */
-/*
- * hash_32 - 32 bit Fowler/Noll/Vo FNV-1a hash code
- *
- * @(#) Revision: 1.1
- * @(#) Id: hash_32a.c,v 1.1 2003/10/03 20:38:53 chongo Exp
- * @(#) Source: /usr/local/src/cmd/fnv/RCS/hash_32a.c,v
- *
- ***
- *
- * Fowler/Noll/Vo hash
- *
- * The basis of this hash algorithm was taken from an idea sent
- * as reviewer comments to the IEEE POSIX P1003.2 committee by:
- *
- *      Phong Vo (http://www.research.att.com/info/kpv/)
- *      Glenn Fowler (http://www.research.att.com/~gsf/)
- *
- * In a subsequent ballot round:
- *
- *      Landon Curt Noll (http://www.isthe.com/chongo/)
- *
- * improved on their algorithm.  Some people tried this hash
- * and found that it worked rather well.  In an EMail message
- * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash.
- *
- * FNV hashes are designed to be fast while maintaining a low
- * collision rate. The FNV speed allows one to quickly hash lots
- * of data while maintaining a reasonable collision rate.  See:
- *
- *      http://www.isthe.com/chongo/tech/comp/fnv/index.html
- *
- * for more details as well as other forms of the FNV hash.
- ***
- *
- * To use the recommended 32 bit FNV-1a hash, pass FNV1_32A_INIT as the
- * Fnv32_t hashval argument to fnv_32a_buf() or fnv_32a_str().
- *
- ***
- *
- * Please do not copyright this code.  This code is in the public domain.
- *
- * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
- * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
- * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
- * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * By:
- *     chongo <Landon Curt Noll> /\oo/\
- *      http://www.isthe.com/chongo/
- *
- * Share and Enjoy!    :-)
- */
-
-#include <stdlib.h>
-#include "fnv.h"
-
-/*
- * 32 bit magic FNV-1a prime
- */
-#define FNV_32_PRIME ((Fnv32_t)0x01000193)
-
-/*
- * fnv_32a_str - perform a 32 bit Fowler/Noll/Vo FNV-1a hash on a string
- *
- * input:
- *     str     - string to hash
- *     hval    - previous hash value or 0 if first call
- *
- * returns:
- *     32 bit hash as a static hash type
- *
- * NOTE: To use the recommended 32 bit FNV-1a hash, use FNV1_32A_INIT as the
- *      hval arg on the first call to either fnv_32a_buf() or fnv_32a_str().
- */
-Fnv32_t
-fnv_32a_str(char const *str, Fnv32_t hval)
-{
-    unsigned char *s = (unsigned char *)str;   /* unsigned string */
-
-    /*
-     * FNV-1a hash each octet in the buffer
-     */
-    while (*s) {
-
-       /* xor the bottom with the current octet */
-       hval ^= (Fnv32_t)*s++;
-
-       /* multiply by the 32 bit FNV magic prime mod 2^32 */
-#if defined(NO_FNV_GCC_OPTIMIZATION)
-       hval *= FNV_32_PRIME;
-#else
-       hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24);
-#endif
-    }
-
-    /* return our new hash value */
-    return hval;
-}

Modified: trunk/tools/trainwreck/trainwreck.c
===================================================================
--- trunk/tools/trainwreck/trainwreck.c 2009-03-02 07:53:27 UTC (rev 47922)
+++ trunk/tools/trainwreck/trainwreck.c 2009-03-02 08:17:15 UTC (rev 47923)
@@ -9,35 +9,9 @@
 /* $Id$ */
 
 /*
- * trainwreck: multi-threaded MySQL replication tool.
+ * trainwreck: MySQL replication tool.
  */
 
-/*
- * About multi-writer replication status:
- *
- * At startup, we create 1 reader thread to collect the binlogs from the 
- * master, and N writers to send queries to the slaves.  The reader 
distributes 
- * write queries between writers based on a hash of the database name, so 
- * updates for the same database always go to the same writer.  This ensures 
- * that replication within a database is always linear.  We don't make any 
- * attempt to handle cross-database updates, and they probably won't work 
- * properly.
- *
- * Each writer maintains its own on-disk state, holding the binlog it is 
- * replicating, and the position it's replicated up to.  When the reader 
- * detects a binlog rotation, it causes a synchronisation event to ensure that 
- * all writers have caught up to the end of the current binlog before 
changing.  
- * This ensures that all writers are executing the same binlog, which makes 
- * recovery from saved state after startup much easier.
- * 
- * At startup, each writer reads its saved state.  A note is kept of the 
oldest 
- * log position any writer has seen, and each writer also stores its own 
- * current position.  Then the reader thread starts, and requests binlogs from 
- * the master starting from the oldest state and sends them to the writers.  
- * Each writer then discards logs it's already seen.  Once we pass the last 
- * seen logs, it starts executing queries again.
- */
-
 #include       <stdio.h>
 #include       <string.h>
 #include       <errno.h>
@@ -54,7 +28,6 @@
 
 #include       "queue.h"
 #include       "status.h"
-#include       "fnv.h"
 #include       "config.h"
 
 typedef uint32_t logpos_t;
@@ -87,7 +60,6 @@
 
 static int execute_query(MYSQL *, char const *);
 
-#define ET_SYNC -2
 #define ET_QUERY 2
 #define ET_INTVAR 5
 #define ET_ROTATE 4
@@ -126,7 +98,6 @@
 static logentry_t *lq_get(le_queue_t *);
 
 typedef struct writer {
-       int              wr_num;
        pthread_t        wr_thread;
        logpos_t         wr_last_executed_pos;
        char            *wr_last_executed_file;
@@ -137,16 +108,14 @@
        int              wr_status;
 } writer_t;
 
-writer_t *writers;
+writer_t writer;
 
 static void writer_init(writer_t *);
 static int retrieve_binlog_position(writer_t *);
-static writer_t *get_writer_for_dbname(char const *);
 
 static pthread_mutex_t rst_mtx = PTHREAD_MUTEX_INITIALIZER,
                       wst_mtx = PTHREAD_MUTEX_INITIALIZER;
 static status_t reader_st = ST_STOPPED;
-static int autostart;
 static int master_thread_stop;
 
 static void executed_up_to(writer_t *, char const *, logpos_t);
@@ -162,8 +131,6 @@
 static pthread_cond_t wi_cond = PTHREAD_COND_INITIALIZER;
 static logpos_t lowest_log_pos;
 
-static int unsynced;
-
 #define CTL_STOP       1
 #define CTL_START      2
 #define CTL_SHUTDOWN   3
@@ -206,10 +173,6 @@
                        unsynced = 1;
                        break;
 
-               case 'c':
-                       cfgfile = optarg;
-                       break;
-
                default:
                        usage();
                        exit(1);
@@ -232,15 +195,15 @@
                return 1;
        }
 
+       if (!statedir) {
+               (void) fprintf(stderr, "error: statedir not specified in 
configuration file\n");
+               return 1;
+       }
+
        setup_status_door();
 
-       writers = calloc(1, sizeof(writer_t) * nwriters);
+       writer_init(&writer);
 
-       for (i = 0; i < nwriters; ++i) {
-               writer_init(&writers[i]);
-               writers[i].wr_num = i;
-       }
-
        if (autostart) {
                (void) start_slave_write_thread();
                (void) start_master_read_thread();
@@ -314,15 +277,12 @@
 stop_slave_write_thread()
 {
 int    i;
-       for (i = 0; i < nwriters; ++i) {
-               (void) pthread_cancel(writers[i].wr_thread);
-               if (pthread_join(writers[i].wr_thread, NULL) == -1) {
-                       logmsg("cannot join slave thread: %s",
-                                       strerror(errno));
-               }
-               mysql_close(writers[i].wr_conn);
-               writers[i].wr_status = ST_STOPPED;
+       (void) pthread_cancel(writer.wr_thread);
+       if (pthread_join(writer.wr_thread, NULL) == -1) {
+               logmsg("cannot join slave thread: %s", strerror(errno));
        }
+       mysql_close(writer.wr_conn);
+       writer.wr_status = ST_STOPPED;
        logmsg("slave threads stopped");
 }
 
@@ -505,35 +465,8 @@
 
                if (ent->le_type == ET_ROTATE && ent->le_time != 0) {
                int     i;
-                       /*
-                        * Insert an ET_SYNC event into every writer, and wait 
-                        * for all writers to sync.  This is needed to simplify 
-                        * binlog management.
-                        */
-                       nsyncs = nwriters;
-                       for (i = 0; i < nwriters; ++i) {
-                       logentry_t      *ent;
-                               ent = calloc(1, sizeof(*ent));
-                               ent->le_type = ET_SYNC;
-                               lq_put(&writers[i].wr_log_queue, ent);
-                       }
+                       executed_up_to(&writer, ent->le_info, 4);
 
-                       (void) pthread_mutex_lock(&sync_mtx);
-                       while (nsyncs)
-                               (void) pthread_cond_wait(&sync_cond, &sync_mtx);
-                       (void) pthread_mutex_unlock(&sync_mtx);
-
-                       /*
-                        * Set the saved position for all writers to the new 
-                        * log position.
-                        */
-                       for (i = 0; i < nwriters; ++i)
-                               executed_up_to(&writers[i], ent->le_info, 4);
-
-                       /*
-                        * Now do the actual rotation.
-                        */
-
                        strdup_free(&curfile, ent->le_info);
                        curpos = 4;
                        logmsg("rotating to %s,4", curfile);
@@ -552,7 +485,6 @@
                            (ignore_regex == NULL || regexec(ignore_regex, 
ent->le_database, 0, NULL, 0) != 0) &&
                            (ent->le_type == ET_INTVAR || ent->le_type == 
ET_QUERY)) {
                        writer_t        *writer;
-                               writer = 
get_writer_for_dbname(ent->le_database);
                                lq_put(&writer->wr_log_queue, ent);
                        } else {
                                free_log_entry(ent);
@@ -790,16 +722,12 @@
 {
 int    i;
        (void) pthread_mutex_lock(&wst_mtx);
-       for (i = 0; i < nwriters; i++)
-               if (writers[i].wr_status != ST_STOPPED)
-                       return -1;
+       if (writer.wr_status != ST_STOPPED)
+               return -1;
 
-       writers_initialising = nwriters;
        (void) pthread_mutex_unlock(&wst_mtx);
 
-       for (i = 0; i < nwriters; ++i) {
-               (void) pthread_create(&writers[i].wr_thread, NULL, 
slave_write_thread, &writers[i]);
-       }
+       (void) pthread_create(&writer.wr_thread, NULL, slave_write_thread, 
&writer);
        return 0;
 }
 
@@ -820,7 +748,7 @@
         */
        (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
 
-       (void) snprintf(namebuf, sizeof(namebuf), "writer-%d", self->wr_num);
+       (void) snprintf(namebuf, sizeof(namebuf), "writer");
        set_thread_name(namebuf);
 
        self->wr_status = ST_INITIALISING;
@@ -852,8 +780,8 @@
        self->wr_status = ST_WAIT_FOR_ENTRY;
        while ((e = lq_get(&self->wr_log_queue)) != NULL) {
                if (debug)
-                       logmsg("%s,%lu [%d: %s]", e->le_file, (unsigned long) 
e->le_pos,
-                               self->wr_num, e->le_database);
+                       logmsg("%s,%lu [%s]", e->le_file, (unsigned long) 
e->le_pos,
+                               e->le_database);
 
                self->wr_status = ST_EXECUTING;
                self->wr_last_executed_time = e->le_time;
@@ -867,11 +795,6 @@
                        }
 
                switch (e->le_type) {
-               case ET_SYNC:
-                       logmsg("syncing for binlog rotation...");
-                       sync_ack(self);
-                       break;
-
                case ET_INTVAR: {
                char    query[128];
                        (void) snprintf(query, sizeof(query), "SET 
INSERT_ID=%llu",
@@ -967,7 +890,8 @@
        char const *log;
        logpos_t pos;
 {
-char   buf[BINLOG_NAMELEN + 4];
+char   buf[2048];
+int    fd;
 
        (void) pthread_mutex_lock(&wst_mtx);
        if (writer->wr_last_executed_file && !strcmp(log, 
writer->wr_last_executed_file)) {
@@ -980,28 +904,31 @@
        writer->wr_last_executed_pos = pos;
        (void) pthread_mutex_unlock(&wst_mtx);
 
-       if (writer->wr_rstat == 0) {
-               (void) snprintf(buf, sizeof(buf), "%d.logpos", writer->wr_num);
+       if (!writer || writer->wr_rstat == 0) {
+               (void) snprintf(buf, sizeof(buf), "%s/logpos", statedir);
                if (unlink(buf) == -1 && errno != ENOENT) {
                        logmsg("cannot remove old state file \"%s\": %s",
                                        buf, strerror(errno));
                        exit(1);
                }
 
-               if ((writer->wr_rstat = open(buf, O_WRONLY | O_CREAT | O_EXCL, 
0600)) == -1) {
+               if ((fd = open(buf, O_WRONLY | O_CREAT | O_EXCL, 0600)) == -1) {
                        logmsg("cannot open state file \"%s\": %s",
                                        buf, strerror(errno));
                        exit(1);
                }
+
+               if (writer)
+                       writer->wr_rstat = fd;
        } else
                (void) lseek(writer->wr_rstat, 0, SEEK_SET);
 
-       (void) ftruncate(writer->wr_rstat, 0);
+       (void) ftruncate(fd, 0);
        int4store(buf, pos);
        (void) strlcpy(buf + 4, log, sizeof(buf) - 4);
-       (void) write(writer->wr_rstat, buf, 4 + strlen(log));
+       (void) write(fd, buf, 4 + strlen(log));
        if (!unsynced)
-               (void) fdatasync(writer->wr_rstat);
+               (void) fdatasync(fd);
 }
 
 static int
@@ -1012,8 +939,8 @@
 ssize_t                 n;
 struct stat     st;
 char           *buf;
-char            sname[128];
-       (void) snprintf(sname, sizeof(sname), "%d.logpos", writer->wr_num);
+char            sname[2048];
+       (void) snprintf(sname, sizeof(sname), "%s/logpos", statedir);
        if ((rstat = open(sname, O_RDONLY)) == -1) {
                logmsg("cannot open state file \"%s\": %s",
                                sname, strerror(errno));
@@ -1118,18 +1045,17 @@
                return;
 
        case RQ_STATUS:
-               st = malloc(2 + nwriters);
+               st = malloc(2 + 1);
                st[0] = RR_OK;
                (void) pthread_mutex_lock(&rst_mtx);
                st[1] = reader_st;
                (void) pthread_mutex_unlock(&rst_mtx);
 
                (void) pthread_mutex_lock(&wst_mtx);
-               for (i = 0; i < nwriters; i++)
-                       st[2 + i] = writers[i].wr_status;
+               st[2] = writer.wr_status;
                (void) pthread_mutex_unlock(&wst_mtx);
 
-               door_return((char *) st, 2 + nwriters, NULL, 0);
+               door_return((char *) st, 2 + 1, NULL, 0);
                return;
 
        case RQ_READER_POSITION:
@@ -1153,22 +1079,19 @@
        case RQ_WRITER_POSITION:
                (void) pthread_mutex_lock(&wst_mtx);
                offs = 2;
-               st = alloca(1 + (10 + BINLOG_NAMELEN) * nwriters);
+               st = alloca(1 + (10 + BINLOG_NAMELEN));
                st[0] = RR_OK;
-               st[1] = nwriters;
+               st[1] = 1;
 
-               for (i = 0; i < nwriters; ++i) {
-                       if (!writers[i].wr_last_executed_file) {
-                               int4store(st + offs, (uint32_t) 0);
-                               offs += 4;
-                               continue;
-                       }
-
-                       blen = strlen(writers[i].wr_last_executed_file);
-                       int4store(st + offs, writers[i].wr_last_executed_pos);
-                       int4store(st + offs + 4, (uint32_t) 
writers[i].wr_last_executed_time);
+               if (!writer.wr_last_executed_file) {
+                       int4store(st + offs, (uint32_t) 0);
+                       offs += 4;
+               } else {
+                       blen = strlen(writer.wr_last_executed_file);
+                       int4store(st + offs, writer.wr_last_executed_pos);
+                       int4store(st + offs + 4, (uint32_t) 
writer.wr_last_executed_time);
                        int2store(st + offs + 8, (uint16_t) blen);
-                       (void) memcpy(st + offs + 10, 
writers[i].wr_last_executed_file, blen);
+                       (void) memcpy(st + offs + 10, 
writer.wr_last_executed_file, blen);
                        offs += 10 + blen;
                }
 
@@ -1201,14 +1124,6 @@
        }
 }
 
-static writer_t *
-get_writer_for_dbname(name)
-       char const *name;
-{
-int    n = fnv_32a_str(name, FNV1_32A_INIT) % nwriters;
-       return &writers[n];
-}
-
 static void
 writer_init(wr)
        writer_t *wr;

Modified: trunk/tools/trainwreck/trainwreck.conf.sample
===================================================================
--- trunk/tools/trainwreck/trainwreck.conf.sample       2009-03-02 07:53:27 UTC 
(rev 47922)
+++ trunk/tools/trainwreck/trainwreck.conf.sample       2009-03-02 08:17:15 UTC 
(rev 47923)
@@ -47,3 +47,15 @@
 # times.  Note: if you need this, it might indicate out-of-sync replication.  
 # DO NOT set this for transient error likes 'Lock wait timeout exceeded'.
 ignore-errno 1061
+
+# Where the log position state is called.  Needs to be writable by trainwreck.
+statedir /var/trainwreck
+
+# Set this to 1 if you want trainwreck to start replicating when it's started,
+# or 0 if you want to start replication manually.
+autostart 1
+
+# Whether to fsync() every time we write to the binlog state file.  Turning
+# this off can improve performance, but if the system crashes, we might restart
+# replication from the wrong position.
+fsync 1



_______________________________________________
MediaWiki-CVS mailing list
MediaWiki-CVS@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to