MDEV-381: fdatasync() does not correctly flush growing binlog file

Revert the old work-around for buggy fdatasync() on Linux ext3. This bug was
fixed in Linux > 10 years ago back to kernel version at least 3.0.

Reviewed-by: Marko Mäkelä <marko.makela@mariadb.com>
Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
This commit is contained in:
Kristian Nielsen 2023-08-03 14:20:47 +02:00
parent e9333ff03c
commit 5055490c17
4 changed files with 9 additions and 25 deletions

View file

@ -92,7 +92,6 @@ typedef struct my_aio_result {
#define MY_THREADSAFE 2048U /* my_seek(): lock fd mutex */ #define MY_THREADSAFE 2048U /* my_seek(): lock fd mutex */
#define MY_SYNC 4096U /* my_copy(): sync dst file */ #define MY_SYNC 4096U /* my_copy(): sync dst file */
#define MY_SYNC_DIR 32768U /* my_create/delete/rename: sync directory */ #define MY_SYNC_DIR 32768U /* my_create/delete/rename: sync directory */
#define MY_SYNC_FILESIZE 65536U /* my_sync(): safe sync when file is extended */
#define MY_THREAD_SPECIFIC 0x10000U /* my_malloc(): thread specific */ #define MY_THREAD_SPECIFIC 0x10000U /* my_malloc(): thread specific */
#define MY_THREAD_MOVE 0x20000U /* realloc(); Memory can move */ #define MY_THREAD_MOVE 0x20000U /* realloc(); Memory can move */
/* Tree that should delete things automatically */ /* Tree that should delete things automatically */

View file

@ -49,13 +49,6 @@ void thr_set_sync_wait_callback(void (*before_wait)(void),
(which is correct behaviour, if we know that the other thread synced the (which is correct behaviour, if we know that the other thread synced the
file before closing) file before closing)
MY_SYNC_FILESIZE is useful when syncing a file after it has been extended.
On Linux, fdatasync() on ext3/ext4 file systems does not properly flush
to disk the inode data required to preserve the added data across a crash
(this looks to be a bug). But when a file is extended, inode data will most
likely need flushing in any case, so passing MY_SYNC_FILESIZE as flags
is not likely to be any slower, and will be crash safe on Linux ext3/ext4.
RETURN RETURN
0 ok 0 ok
-1 error -1 error
@ -88,12 +81,8 @@ int my_sync(File fd, myf my_flags)
DBUG_PRINT("info",("fcntl(F_FULLFSYNC) failed, falling back")); DBUG_PRINT("info",("fcntl(F_FULLFSYNC) failed, falling back"));
#endif #endif
#if defined(HAVE_FDATASYNC) && HAVE_DECL_FDATASYNC #if defined(HAVE_FDATASYNC) && HAVE_DECL_FDATASYNC
if (!(my_flags & MY_SYNC_FILESIZE)) res= fdatasync(fd);
res= fdatasync(fd); #elif defined(HAVE_FSYNC)
else
{
#endif
#if defined(HAVE_FSYNC)
res= fsync(fd); res= fsync(fd);
if (res == -1 && errno == ENOLCK) if (res == -1 && errno == ENOLCK)
res= 0; /* Result Bug in Old FreeBSD */ res= 0; /* Result Bug in Old FreeBSD */
@ -102,9 +91,6 @@ int my_sync(File fd, myf my_flags)
#else #else
#error Cannot find a way to sync a file, durability in danger #error Cannot find a way to sync a file, durability in danger
res= 0; /* No sync (strange OS) */ res= 0; /* No sync (strange OS) */
#endif
#if defined(HAVE_FDATASYNC) && HAVE_DECL_FDATASYNC
}
#endif #endif
} while (res == -1 && errno == EINTR); } while (res == -1 && errno == EINTR);

View file

@ -311,8 +311,7 @@ static bool backup_block_commit(THD *thd)
if (mysql_bin_log.is_open()) if (mysql_bin_log.is_open())
{ {
mysql_mutex_lock(mysql_bin_log.get_log_lock()); mysql_mutex_lock(mysql_bin_log.get_log_lock());
mysql_file_sync(mysql_bin_log.get_log_file()->file, mysql_file_sync(mysql_bin_log.get_log_file()->file, MYF(MY_WME));
MYF(MY_WME|MY_SYNC_FILESIZE));
mysql_mutex_unlock(mysql_bin_log.get_log_lock()); mysql_mutex_unlock(mysql_bin_log.get_log_lock());
} }
thd->clear_error(); thd->clear_error();

View file

@ -3730,7 +3730,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
bytes_written+= description_event_for_queue->data_written; bytes_written+= description_event_for_queue->data_written;
} }
if (flush_io_cache(&log_file) || if (flush_io_cache(&log_file) ||
mysql_file_sync(log_file.file, MYF(MY_WME|MY_SYNC_FILESIZE))) mysql_file_sync(log_file.file, MYF(MY_WME)))
goto err; goto err;
my_off_t offset= my_b_tell(&log_file); my_off_t offset= my_b_tell(&log_file);
@ -3768,7 +3768,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
strlen(log_file_name)) || strlen(log_file_name)) ||
my_b_write(&index_file, (uchar*) "\n", 1) || my_b_write(&index_file, (uchar*) "\n", 1) ||
flush_io_cache(&index_file) || flush_io_cache(&index_file) ||
mysql_file_sync(index_file.file, MYF(MY_WME|MY_SYNC_FILESIZE))) mysql_file_sync(index_file.file, MYF(MY_WME)))
goto err; goto err;
#ifdef HAVE_REPLICATION #ifdef HAVE_REPLICATION
@ -3908,7 +3908,7 @@ static bool copy_up_file_and_fill(IO_CACHE *index_file, my_off_t offset)
} }
/* The following will either truncate the file or fill the end with \n' */ /* The following will either truncate the file or fill the end with \n' */
if (mysql_file_chsize(file, offset - init_offset, '\n', MYF(MY_WME)) || if (mysql_file_chsize(file, offset - init_offset, '\n', MYF(MY_WME)) ||
mysql_file_sync(file, MYF(MY_WME|MY_SYNC_FILESIZE))) mysql_file_sync(file, MYF(MY_WME)))
goto err; goto err;
/* Reset data in old index cache */ /* Reset data in old index cache */
@ -4702,7 +4702,7 @@ int MYSQL_BIN_LOG::sync_purge_index_file()
if (unlikely((error= flush_io_cache(&purge_index_file))) || if (unlikely((error= flush_io_cache(&purge_index_file))) ||
unlikely((error= my_sync(purge_index_file.file, unlikely((error= my_sync(purge_index_file.file,
MYF(MY_WME | MY_SYNC_FILESIZE))))) MYF(MY_WME)))))
DBUG_RETURN(error); DBUG_RETURN(error);
DBUG_RETURN(error); DBUG_RETURN(error);
@ -5462,7 +5462,7 @@ bool MYSQL_BIN_LOG::flush_and_sync(bool *synced)
if (sync_period && ++sync_counter >= sync_period) if (sync_period && ++sync_counter >= sync_period)
{ {
sync_counter= 0; sync_counter= 0;
err= mysql_file_sync(fd, MYF(MY_WME|MY_SYNC_FILESIZE)); err= mysql_file_sync(fd, MYF(MY_WME));
if (synced) if (synced)
*synced= 1; *synced= 1;
#ifndef DBUG_OFF #ifndef DBUG_OFF
@ -6142,7 +6142,7 @@ MYSQL_BIN_LOG::write_state_to_file()
log_inited= false; log_inited= false;
if ((err= end_io_cache(&cache))) if ((err= end_io_cache(&cache)))
goto err; goto err;
if ((err= mysql_file_sync(file_no, MYF(MY_WME|MY_SYNC_FILESIZE)))) if ((err= mysql_file_sync(file_no, MYF(MY_WME))))
goto err; goto err;
goto end; goto end;