diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index 92eaaff0f..230e44804 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -94,7 +94,9 @@ char* syslog_ident_str = NULL; */ static int lmlock; static logmanager_t* lm; - +static bool flushall_flag; +static bool flushall_started_flag; +static bool flushall_done_flag; /** Writer thread structure */ struct filewriter_st { @@ -286,12 +288,14 @@ static char* add_slash(char* str); static bool check_file_and_path( char* filename, - bool* writable); + bool* writable, + bool do_log); static bool file_is_symlink(char* filename); static int skygw_log_disable_raw(logfile_id_t id, bool emergency); /*< no locking */ static int find_last_seqno(strpart_t* parts, int seqno, int seqnoidx); - +void flushall_logfiles(bool flush); +bool thr_flushall_check(); const char* get_suffix_default(void) { @@ -441,17 +445,6 @@ static bool logmanager_init_nomutex( return_succp: if (err != 0) { - if (lm != NULL) - { - if (lm->lm_clientmes != NULL) - { - skygw_message_done(lm->lm_clientmes); - } - if (lm->lm_logmes != NULL) - { - skygw_message_done(lm->lm_logmes); - } - } /** This releases memory of all created objects */ logmanager_done_nomutex(); fprintf(stderr, "*\n* Error : Initializing log manager failed.\n*\n"); @@ -2053,7 +2046,7 @@ static bool logfile_create( * If file exists but is different type, create fails and * new, increased sequence number is added to file name. */ - if (check_file_and_path(lf->lf_full_file_name, &writable)) + if (check_file_and_path(lf->lf_full_file_name, &writable, true)) { /** Found similarly named file which isn't writable */ if (!writable || file_is_symlink(lf->lf_full_file_name)) @@ -2077,13 +2070,11 @@ static bool logfile_create( if (store_shmem) { - if (check_file_and_path(lf->lf_full_file_name, &writable)) + if (check_file_and_path(lf->lf_full_link_name, &writable, true)) { - /** Found similarly named file which isn't writable */ - if (!writable || - file_is_symlink(lf->lf_full_file_name)) + /** Found similarly named link which isn't writable */ + if (!writable) { - unlink(lf->lf_full_file_name); nameconflicts = true; } } @@ -2214,7 +2205,6 @@ return_succp: * * @return Pointer to filename, of NULL if failed. * - * */ static char* form_full_file_name( strpart_t* parts, @@ -2231,9 +2221,21 @@ static char* form_full_file_name( if (lf->lf_name_seqno != -1) { - lf->lf_name_seqno = find_last_seqno(parts, - lf->lf_name_seqno, - seqnoidx); + int file_sn; + int link_sn = 0; + char* tmp = parts[0].sp_string; + + file_sn = find_last_seqno(parts, lf->lf_name_seqno, seqnoidx); + + if (lf->lf_linkpath != NULL) + { + tmp = parts[0].sp_string; + parts[0].sp_string = lf->lf_linkpath; + link_sn = find_last_seqno(parts, lf->lf_name_seqno, seqnoidx); + parts[0].sp_string = tmp; + } + lf->lf_name_seqno = MAX(file_sn, link_sn); + seqno = lf->lf_name_seqno; s = UINTLEN(seqno); seqnostr = (char *)malloc((int)s+1); @@ -2354,7 +2356,8 @@ static char* add_slash( */ static bool check_file_and_path( char* filename, - bool* writable) + bool* writable, + bool do_log) { int fd; bool exists; @@ -2382,11 +2385,23 @@ static bool check_file_and_path( if (fd == -1) { - fprintf(stderr, - "*\n* Error : Can't access %s due " - "to %s.\n", - filename, - strerror(errno)); + if (do_log && file_is_symlink(filename)) + { + fprintf(stderr, + "*\n* Error : Can't access " + "file pointed to by %s due " + "to %s.\n", + filename, + strerror(errno)); + } + else if (do_log) + { + fprintf(stderr, + "*\n* Error : Can't access %s due " + "to %s.\n", + filename, + strerror(errno)); + } if (writable) { *writable = false; @@ -2403,11 +2418,24 @@ static bool check_file_and_path( } else { - fprintf(stderr, - "*\n* Error : Can't write to " - "%s due to %s.\n", - filename, - strerror(errno)); + if (do_log && + file_is_symlink(filename)) + { + fprintf(stderr, + "*\n* Error : Can't write to " + "file pointed to by %s due to " + "%s.\n", + filename, + strerror(errno)); + } + else if (do_log) + { + fprintf(stderr, + "*\n* Error : Can't write to " + "%s due to %s.\n", + filename, + strerror(errno)); + } *writable = false; } } @@ -2417,10 +2445,21 @@ static bool check_file_and_path( } else { - fprintf(stderr, - "*\n* Error : Can't access %s due to %s.\n", - filename, - strerror(errno)); + if (do_log && file_is_symlink(filename)) + { + fprintf(stderr, + "*\n* Error : Can't access the file " + "pointed to by %s due to %s.\n", + filename, + strerror(errno)); + } + else if (do_log) + { + fprintf(stderr, + "*\n* Error : Can't access %s due to %s.\n", + filename, + strerror(errno)); + } exists = false; if (writable) @@ -2572,7 +2611,7 @@ static bool logfile_init( logfile_free_memory(logfile); goto return_with_succp; } -#if defined(SS_DEBUG) + if (store_shmem) { fprintf(stderr, "%s\t: %s->%s\n", @@ -2586,7 +2625,6 @@ static bool logfile_init( STRLOGNAME(logfile_id), logfile->lf_full_file_name); } -#endif succp = true; logfile->lf_state = RUN; CHK_LOGFILE(logfile); @@ -2802,13 +2840,15 @@ static void* thr_filewriter_fun( int i; blockbuf_state_t flush_blockbuf; /**< flush single block buffer. */ bool flush_logfile; /**< flush logfile */ - bool flushall_logfiles;/**< flush all logfiles */ + bool do_flushall = false; bool rotate_logfile; /*< close current and open new file */ size_t vn1; size_t vn2; thr = (skygw_thread_t *)data; fwr = (filewriter_t *)skygw_thread_get_data(thr); + flushall_logfiles(false); + CHK_FILEWRITER(fwr); ss_debug(skygw_thread_set_state(thr, THR_RUNNING)); @@ -2821,8 +2861,9 @@ static void* thr_filewriter_fun( * Reset message to avoid redundant calls. */ skygw_message_wait(fwr->fwr_logmes); - - flushall_logfiles = skygw_thread_must_exit(thr); + if(skygw_thread_must_exit(thr)){ + flushall_logfiles(true); + } /** Process all logfiles which have buffered writes. */ for (i=LOGFILE_FIRST; i<=LOGFILE_LAST; i <<= 1) @@ -2831,6 +2872,10 @@ static void* thr_filewriter_fun( /** * Get file pointer of current logfile. */ + + + + do_flushall = thr_flushall_check(); file = fwr->fwr_file[i]; lf = &lm->lm_logfile[(logfile_id_t)i]; @@ -2901,7 +2946,7 @@ static void* thr_filewriter_fun( if (bb->bb_buf_used != 0 && (flush_blockbuf == BB_FULL || flush_logfile || - flushall_logfiles)) + do_flushall)) { /** * buffer is at least half-full @@ -2920,7 +2965,7 @@ static void* thr_filewriter_fun( (void *)bb->bb_buf, bb->bb_buf_used, (flush_logfile || - flushall_logfiles)); + do_flushall)); if (err) { fprintf(stderr, @@ -2967,13 +3012,28 @@ static void* thr_filewriter_fun( * Loop is restarted to ensure that all logfiles are * flushed. */ - if (!flushall_logfiles && skygw_thread_must_exit(thr)) + + if(flushall_started_flag){ + flushall_started_flag = false; + flushall_done_flag = true; + i = LOGFILE_FIRST; + goto retry_flush_on_exit; + } + + if (!thr_flushall_check() && skygw_thread_must_exit(thr)) { - flushall_logfiles = true; + flushall_logfiles(true); i = LOGFILE_FIRST; goto retry_flush_on_exit; } - } /* for */ + }/* for */ + + if(flushall_done_flag){ + flushall_done_flag = false; + flushall_logfiles(false); + skygw_message_send(fwr->fwr_clientmes); + } + } /* while (!skygw_thread_must_exit) */ ss_debug(skygw_thread_set_state(thr, THR_STOPPED)); @@ -3061,7 +3121,7 @@ static int find_last_seqno( } } - if (check_file_and_path(filename, NULL)) + if (check_file_and_path(filename, NULL, false)) { seqno++; } @@ -3073,4 +3133,34 @@ static int find_last_seqno( free(snstr); return seqno; -} \ No newline at end of file +} + +bool thr_flushall_check() +{ + bool rval = false; + simple_mutex_lock(&lm->lm_mutex,true); + rval = flushall_flag; + if(rval && !flushall_started_flag && !flushall_done_flag){ + flushall_started_flag = true; + } + simple_mutex_unlock(&lm->lm_mutex); + return rval; +} + +void flushall_logfiles(bool flush) +{ + simple_mutex_lock(&lm->lm_mutex,true); + flushall_flag = flush; + simple_mutex_unlock(&lm->lm_mutex); +} + +/** + * Flush all log files synchronously + */ +void skygw_log_sync_all(void) +{ + skygw_log_write(LOGFILE_TRACE,"Starting log flushing to disk."); + flushall_logfiles(true); + skygw_message_send(lm->lm_logmes); + skygw_message_wait(lm->lm_clientmes); +} diff --git a/server/MaxScale_template.cnf b/server/MaxScale_template.cnf index cb49c3e14..0a6d22a88 100644 --- a/server/MaxScale_template.cnf +++ b/server/MaxScale_template.cnf @@ -31,7 +31,7 @@ threads=4 # backend_write_timeout= # backend_read_timeout= # -## mysql_monitor specific options: +## MySQL monitor-specific options: # # Enable detection of replication slaves lag via replication_heartbeat # table - optional. @@ -43,6 +43,13 @@ threads=4 # # detect_stale_master=[1|0] (default 0) # +## Galera monitor-specific options: +# +# If disable_master_failback is not set, recovery of previously failed master +# causes mastership to be switched back to it. Enabling the option prevents it. +# +# disable_master_failback=[0|1] (default 0) +# ## Examples: [MySQL Monitor] @@ -65,6 +72,7 @@ servers=server1,server2,server3 user=myuser passwd=mypwd monitor_interval=10000 +disable_master_failback=1 ## Filter definition # diff --git a/server/modules/protocol/maxscaled.c b/server/modules/protocol/maxscaled.c index 1c564da56..1bf009d97 100644 --- a/server/modules/protocol/maxscaled.c +++ b/server/modules/protocol/maxscaled.c @@ -374,8 +374,8 @@ int rc; rc = listen(listener->fd, SOMAXCONN); if (rc == 0) { - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, + LOGIF(LM, (skygw_log_write( + LOGFILE_MESSAGE, "Listening maxscale connections at %s\n", config))); } else { diff --git a/server/modules/protocol/mysql_common.c b/server/modules/protocol/mysql_common.c index 27159dc21..364b13595 100644 --- a/server/modules/protocol/mysql_common.c +++ b/server/modules/protocol/mysql_common.c @@ -577,8 +577,8 @@ int gw_send_authentication_to_backend( dcb = conn->owner_dcb; final_capabilities = gw_mysql_get_byte4((uint8_t *)&server_capabilities); - /** Copy client's flags to backend */ - final_capabilities |= conn->client_capabilities; + /** Copy client's flags to backend but with the known capabilities mask */ + final_capabilities |= (conn->client_capabilities & GW_MYSQL_CAPABILITIES_CLIENT); /* get charset the client sent and use it for connection auth */ charset = conn->charset; diff --git a/utils/skygw_utils.cc b/utils/skygw_utils.cc index 8e285c6a2..fd25c60cf 100644 --- a/utils/skygw_utils.cc +++ b/utils/skygw_utils.cc @@ -1680,12 +1680,12 @@ static bool file_write_header( if (wbytes1 != 1 || wbytes2 != 1 || wbytes3 != 1 || wbytes4 != 1) { fprintf(stderr, - "* Writing header %s %s %s to %s failed.\n", + "\nError : Writing header %s %s %s %s failed.\n", header_buf1, header_buf2, header_buf3, header_buf4); - perror("Logfile header write.\n"); + perror("Logfile header write"); goto return_succp; } #endif @@ -1757,11 +1757,11 @@ static bool file_write_footer( if (wbytes1 != 1 || wbytes3 != 1 || wbytes4 != 1) { fprintf(stderr, - "* Writing header %s %s to %s failed.\n", + "\nError : Writing header %s %s to %s failed.\n", header_buf1, header_buf3, header_buf4); - perror("Logfile header write.\n"); + perror("Logfile header write"); goto return_succp; } #endif @@ -1875,7 +1875,7 @@ skygw_file_t* skygw_file_init( int eno = errno; errno = 0; fprintf(stderr, - "* Writing header of log file %s failed due %d, %s.\n", + "\nError : Writing header of log file %s failed due %d, %s.\n", file->sf_fname, eno, strerror(eno));