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