Index: trunk/tools/trainwreck/trainwreck.c |
— | — | @@ -141,6 +141,7 @@ |
142 | 142 | pthread_t wr_thread; |
143 | 143 | logpos_t wr_last_executed_pos; |
144 | 144 | char *wr_last_executed_file; |
| 145 | + uint32_t wr_last_executed_time; |
145 | 146 | le_queue_t wr_log_queue; |
146 | 147 | MYSQL *wr_conn; |
147 | 148 | int wr_rstat; |
— | — | @@ -875,6 +876,7 @@ |
876 | 877 | self->wr_num, e->le_database); |
877 | 878 | |
878 | 879 | self->wr_status = ST_EXECUTING; |
| 880 | + self->wr_last_executed_time = e->le_time; |
879 | 881 | if (mysql_select_db(self->wr_conn, e->le_database) != 0) { |
880 | 882 | logmsg("%s,%lu: cannot select \"%s\": %s", |
881 | 883 | e->le_file, (unsigned long) e->le_pos, |
— | — | @@ -1148,7 +1150,7 @@ |
1149 | 1151 | case RQ_WRITER_POSITION: |
1150 | 1152 | pthread_mutex_lock(&wst_mtx); |
1151 | 1153 | offs = 2; |
1152 | | - st = alloca(1 + (6 + BINLOG_NAMELEN) * nwriters); |
| 1154 | + st = alloca(1 + (10 + BINLOG_NAMELEN) * nwriters); |
1153 | 1155 | st[0] = RR_OK; |
1154 | 1156 | st[1] = nwriters; |
1155 | 1157 | |
— | — | @@ -1161,9 +1163,10 @@ |
1162 | 1164 | |
1163 | 1165 | blen = strlen(writers[i].wr_last_executed_file); |
1164 | 1166 | int4store(st + offs, writers[i].wr_last_executed_pos); |
1165 | | - int2store(st + offs + 4, (uint16_t) blen); |
1166 | | - memcpy(st + offs + 6, writers[i].wr_last_executed_file, blen); |
1167 | | - offs += 6 + blen; |
| 1167 | + int4store(st + offs + 4, (uint32_t) writers[i].wr_last_executed_time); |
| 1168 | + int2store(st + offs + 8, (uint16_t) blen); |
| 1169 | + memcpy(st + offs + 10, writers[i].wr_last_executed_file, blen); |
| 1170 | + offs += 10 + blen; |
1168 | 1171 | } |
1169 | 1172 | |
1170 | 1173 | pthread_mutex_unlock(&wst_mtx); |
Index: trunk/tools/trainwreck/twctl.c |
— | — | @@ -25,6 +25,7 @@ |
26 | 26 | static int rq_shutdown(void); |
27 | 27 | |
28 | 28 | static char const *status_to_name(int); |
| 29 | +static char const *format_seconds(uint32_t nsecs); |
29 | 30 | |
30 | 31 | static int door; |
31 | 32 | static door_arg_t args; |
— | — | @@ -135,7 +136,7 @@ |
136 | 137 | rq_status() |
137 | 138 | { |
138 | 139 | char rq = RQ_STATUS; |
139 | | -uint32_t logpos; |
| 140 | +uint32_t logpos, logtime; |
140 | 141 | char *logname; |
141 | 142 | int rstat; |
142 | 143 | char *wstats; |
— | — | @@ -243,10 +244,16 @@ |
244 | 245 | continue; |
245 | 246 | } |
246 | 247 | |
247 | | - loglen = uint2korr(args.rbuf + 4); |
| 248 | + logtime = uint4korr(args.rbuf + 4); |
| 249 | + loglen = uint2korr(args.rbuf + 8); |
248 | 250 | (void) printf(" log position: %.*s,%lu\n", |
249 | | - loglen, args.rbuf + 6, |
| 251 | + loglen, args.rbuf + 10, |
250 | 252 | (unsigned long) logpos); |
| 253 | + if (logtime != 0) { |
| 254 | + time_t now = time(NULL); |
| 255 | + (void) printf(" seconds behind master: %s\n", |
| 256 | + format_seconds(now - logtime)); |
| 257 | + } |
251 | 258 | args.rbuf += 6 + loglen; |
252 | 259 | i++; |
253 | 260 | } |
— | — | @@ -346,3 +353,31 @@ |
347 | 354 | return "unknown"; |
348 | 355 | } |
349 | 356 | } |
| 357 | + |
| 358 | +static char const * |
| 359 | +format_seconds(t) |
| 360 | + uint32_t t; |
| 361 | +{ |
| 362 | +static char buf[512], *p = buf; |
| 363 | +int weeks, days, hours, minutes, seconds; |
| 364 | + weeks = t / (60 * 60 * 24 * 7); |
| 365 | + t %= (60 * 60 * 24 * 7); |
| 366 | + days = t / (60 * 60 * 24); |
| 367 | + t %= (60 * 60 * 24); |
| 368 | + hours = t / (60 * 60); |
| 369 | + t %= (60 * 60); |
| 370 | + minutes = t / 60; |
| 371 | + t %= 60; |
| 372 | + seconds = t; |
| 373 | + |
| 374 | + if (weeks) |
| 375 | + p += sprintf(p, " %dw", weeks); |
| 376 | + if (days) |
| 377 | + p += sprintf(p, " %dd", days); |
| 378 | + if (hours) |
| 379 | + p += sprintf(p, " %dh", hours); |
| 380 | + if (minutes) |
| 381 | + p += sprintf(p, " %dm", minutes); |
| 382 | + sprintf(p, " %ds", seconds); |
| 383 | + return buf + 1; |
| 384 | +} |