Make MaxScale handle zero-length files to aid bootstrapping.
When bootstrapping a binlog router to start it needs to know the first file to use. You can provide this information in the config file but that will never be up to date, or you can copy a file to the binlog server and start maxscale. It will then carry on from the last file’s current position. The binlog files have a 4-byte magic prefix so to start from the beginning (position 4) you need to add these to an empty file if you do this by hand. If you don’t then maxscale will attempt to download from the master at position 0 and the master will not accept this value. (This is not apparent with a mysql client as change master to … master_log_pos = 0 triggers a write of the 4 magic bytes and then asks the master for information from position 4 [not 0]). This patch makes MaxScale behave similarly and allows you to only need to touch the first binlog file to be downloaded for it to do the right thing.
This commit is contained in:
@ -164,6 +164,24 @@ blr_file_rotate(ROUTER_INSTANCE *router, char *file, uint64_t pos)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* binlog files need an initial 4 magic bytes at the start. blr_file_add_magic()
|
||||
* adds them.
|
||||
*
|
||||
* @param router The router instance
|
||||
* @param fd file descriptor to the open binlog file
|
||||
* @return Nothing
|
||||
*/
|
||||
static void
|
||||
blr_file_add_magic(ROUTER_INSTANCE *router, int fd)
|
||||
{
|
||||
unsigned char magic[] = BINLOG_MAGIC;
|
||||
|
||||
write(fd, magic, 4);
|
||||
router->binlog_position = 4; /* Initial position after the magic number */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new binlog file for the router to use.
|
||||
*
|
||||
@ -176,7 +194,6 @@ blr_file_create(ROUTER_INSTANCE *router, char *file)
|
||||
{
|
||||
char path[1024];
|
||||
int fd;
|
||||
unsigned char magic[] = BINLOG_MAGIC;
|
||||
|
||||
strcpy(path, router->binlogdir);
|
||||
strcat(path, "/");
|
||||
@ -184,7 +201,7 @@ unsigned char magic[] = BINLOG_MAGIC;
|
||||
|
||||
if ((fd = open(path, O_RDWR|O_CREAT, 0666)) != -1)
|
||||
{
|
||||
write(fd, magic, 4);
|
||||
blr_file_add_magic(router,fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -197,7 +214,7 @@ unsigned char magic[] = BINLOG_MAGIC;
|
||||
close(router->binlog_fd);
|
||||
spinlock_acquire(&router->binlog_lock);
|
||||
strncpy(router->binlog_name, file,BINLOG_FNAMELEN);
|
||||
router->binlog_position = 4; /* Initial position after the magic number */
|
||||
blr_file_add_magic(router, fd);
|
||||
spinlock_release(&router->binlog_lock);
|
||||
router->binlog_fd = fd;
|
||||
return 1;
|
||||
@ -232,6 +249,18 @@ int fd;
|
||||
spinlock_acquire(&router->binlog_lock);
|
||||
strncpy(router->binlog_name, file,BINLOG_FNAMELEN);
|
||||
router->binlog_position = lseek(fd, 0L, SEEK_END);
|
||||
if (router->binlog_position < 4) {
|
||||
if (router->binlog_position == 0) {
|
||||
blr_file_add_magic(router, fd);
|
||||
} else {
|
||||
/* If for any reason the file's length is between 1 and 3 bytes
|
||||
* then report an error. */
|
||||
LOGIF(LE, (skygw_log_write(LOGFILE_ERROR,
|
||||
"%s: binlog file %s has an invalid length %d.",
|
||||
router->service->name, path, router->binlog_position)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
spinlock_release(&router->binlog_lock);
|
||||
router->binlog_fd = fd;
|
||||
}
|
||||
|
Reference in New Issue
Block a user