1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

Make atomic writes general

- Atomic writes are enabled by default
- Automatically detect if device supports atomic write and use it if
  atomic writes are enabled
- Remove ATOMIC WRITE options from CREATE TABLE
  - Atomic write is a device option, not a table options as the table may
    crash if the media changes
- Add support for SHANNON SSD cards
This commit is contained in:
Sergei Golubchik
2016-12-31 15:11:52 +01:00
committed by Monty
parent ed0bc17bee
commit ed008a74cf
29 changed files with 473 additions and 377 deletions

View File

@@ -192,6 +192,14 @@ extern void my_large_free(uchar *ptr);
#define my_large_free(A) my_free_lock((A)) #define my_large_free(A) my_free_lock((A))
#endif /* HAVE_LARGE_PAGES */ #endif /* HAVE_LARGE_PAGES */
void my_init_atomic_write(void);
#ifdef __linux__
my_bool my_test_if_atomic_write(File handle, int pagesize);
#else
#define my_test_if_atomic_write(A, B) 0
#endif /* __linux__ */
extern my_bool my_may_have_atomic_write;
#if defined(HAVE_ALLOCA) && !defined(HAVE_valgrind) #if defined(HAVE_ALLOCA) && !defined(HAVE_valgrind)
#if defined(_AIX) && !defined(__GNUC__) && !defined(_AIX43) #if defined(_AIX) && !defined(__GNUC__) && !defined(_AIX43)
#pragma alloca #pragma alloca

View File

@@ -1,20 +1,20 @@
select @@global.innodb_use_atomic_writes; select @@global.innodb_use_atomic_writes;
@@global.innodb_use_atomic_writes @@global.innodb_use_atomic_writes
0 1
select @@session.innodb_use_atomic_writes; select @@session.innodb_use_atomic_writes;
ERROR HY000: Variable 'innodb_use_atomic_writes' is a GLOBAL variable ERROR HY000: Variable 'innodb_use_atomic_writes' is a GLOBAL variable
show global variables like 'innodb_use_atomic_writes'; show global variables like 'innodb_use_atomic_writes';
Variable_name Value Variable_name Value
innodb_use_atomic_writes OFF innodb_use_atomic_writes ON
show session variables like 'innodb_use_atomic_writes'; show session variables like 'innodb_use_atomic_writes';
Variable_name Value Variable_name Value
innodb_use_atomic_writes OFF innodb_use_atomic_writes ON
select * from information_schema.global_variables where variable_name='innodb_use_atomic_writes'; select * from information_schema.global_variables where variable_name='innodb_use_atomic_writes';
VARIABLE_NAME VARIABLE_VALUE VARIABLE_NAME VARIABLE_VALUE
INNODB_USE_ATOMIC_WRITES OFF INNODB_USE_ATOMIC_WRITES ON
select * from information_schema.session_variables where variable_name='innodb_use_atomic_writes'; select * from information_schema.session_variables where variable_name='innodb_use_atomic_writes';
VARIABLE_NAME VARIABLE_VALUE VARIABLE_NAME VARIABLE_VALUE
INNODB_USE_ATOMIC_WRITES OFF INNODB_USE_ATOMIC_WRITES ON
set global innodb_use_atomic_writes=1; set global innodb_use_atomic_writes=1;
ERROR HY000: Variable 'innodb_use_atomic_writes' is a read only variable ERROR HY000: Variable 'innodb_use_atomic_writes' is a read only variable
set session innodb_use_atomic_writes=1; set session innodb_use_atomic_writes=1;

View File

@@ -2584,12 +2584,12 @@ READ_ONLY YES
COMMAND_LINE_ARGUMENT REQUIRED COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME INNODB_USE_ATOMIC_WRITES VARIABLE_NAME INNODB_USE_ATOMIC_WRITES
SESSION_VALUE NULL SESSION_VALUE NULL
GLOBAL_VALUE OFF GLOBAL_VALUE ON
GLOBAL_VALUE_ORIGIN COMPILE-TIME GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE OFF DEFAULT_VALUE ON
VARIABLE_SCOPE GLOBAL VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE BOOLEAN VARIABLE_TYPE BOOLEAN
VARIABLE_COMMENT Prevent partial page writes, via atomic writes.The option is used to prevent partial writes in case of a crash/poweroff, as faster alternative to doublewrite buffer.Currently this option works only on Linux only with FusionIO device, and directFS filesystem. VARIABLE_COMMENT Enable atomic writes, instead of using the doublewrite buffer, for files on devices that supports atomic writes. To use this option one must use file_per_table=1, flush_method=O_DIRECT and use_fallocate=1. This option only works on Linux with either FusionIO cards using the directFS filesystem or with Shannon cards using any file system.
NUMERIC_MIN_VALUE NULL NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL NUMERIC_BLOCK_SIZE NULL

View File

@@ -42,6 +42,7 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c my_default.c
my_atomic.c my_getncpus.c my_safehash.c my_chmod.c my_rnd.c my_atomic.c my_getncpus.c my_safehash.c my_chmod.c my_rnd.c
my_uuid.c wqueue.c waiting_threads.c ma_dyncol.c ../sql-common/my_time.c my_uuid.c wqueue.c waiting_threads.c ma_dyncol.c ../sql-common/my_time.c
my_rdtsc.c my_context.c psi_noop.c my_rdtsc.c my_context.c psi_noop.c
my_atomic_writes.c
file_logger.c) file_logger.c)
IF (WIN32) IF (WIN32)

333
mysys/my_atomic_writes.c Normal file
View File

@@ -0,0 +1,333 @@
/* Copyright (c) 2016, MariaDB Corporation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
my_bool my_may_have_atomic_write= 0;
#ifdef __linux__
my_bool has_shannon_atomic_write= 0, has_fusion_io_atomic_write= 0;
#include <sys/ioctl.h>
/***********************************************************************
FUSION_IO
************************************************************************/
/** FusionIO atomic write control info */
#define DFS_IOCTL_ATOMIC_WRITE_SET _IOW(0x95, 2, uint)
/**
Check if the system has a funsion_io card
@return TRUE Card exists
*/
static my_bool test_if_fusion_io_card_exists()
{
/* Fusion card requires fallocate to exists */
#ifndef HAVE_POSIX_FALLOCATE
return 0;
#else
return (access("/dev/fcta", F_OK)) == 0;
#endif
}
/**
Check if a file is on a Fusion_IO device and that it supports atomic_write
@param[in] file OS file handle
@param[in] page_size page size
@return TRUE Atomic write supported
*/
static my_bool fusion_io_has_atomic_write(File file, int page_size)
{
int atomic= 1;
if (page_size <= 32768 &&
ioctl(file, DFS_IOCTL_ATOMIC_WRITE_SET, &atomic) != -1)
return(TRUE);
return(FALSE);
}
/***********************************************************************
SHANNON
************************************************************************/
#define SHANNON_IOMAGIC 'x'
#define SHANNON_IOCQATOMIC_SIZE _IO(SHANNON_IOMAGIC, 22)
#define SHANNON_MAX_DEVICES 32
#define SHANNON_NO_ATOMIC_SIZE_YET -2
struct shannon_dev
{
char dev_name[32];
dev_t st_dev;
int atomic_size;
};
static struct shannon_dev shannon_devices[SHANNON_MAX_DEVICES+1];
/**
Check if the system has a Shannon card
If card exists, record device numbers to allow us to later check if
a given file is on this device.
@return TRUE Card exists
*/
static my_bool test_if_shannon_card_exists()
{
uint shannon_found_devices= 0;
char dev_part;
uint dev_no;
if (access("/dev/scta", F_OK) < 0)
return 0;
/*
The Shannon devices are /dev/dfX, where X can be from a-z.
We have to check all of them as some may be missing if the user
removed one with the U.2 interface.
*/
for (dev_part= 'a' ; dev_part < 'z' ; dev_part++)
{
char path[32];
struct stat stat_buff;
sprintf(path, "/dev/df%c", dev_part);
#ifdef TEST_SHANNON
if (lstat(path, &stat_buff) < 0)
{
printf("%s(): lstat failed.\n", __func__);
break;
}
#endif
shannon_devices[shannon_found_devices].st_dev= stat_buff.st_rdev;
sprintf(shannon_devices[shannon_found_devices].dev_name, "/dev/sct%c",
dev_part);
#ifdef TEST_SHANNON
printf("%s(): i=%d, stat_buff.st_dev=0x%lx, stat_buff.st_rdev=0x%lx, st_rdev=0x%lx, dev_name=%s\n",
__func__,
shannon_found_devices,
(ulong) stat_buff.st_dev,
(ulong) stat_buff.st_rdev,
(ulong) shannon_devices[shannon_found_devices].st_dev,
shannon_devices[shannon_found_devices].dev_name);
#endif
/*
The atomic size will be checked on first access. This is needed
as a normal user can't open the /dev/scta file
*/
shannon_devices[shannon_found_devices].atomic_size=
SHANNON_NO_ATOMIC_SIZE_YET;
if (++shannon_found_devices== SHANNON_MAX_DEVICES)
goto end;
for (dev_no= 1 ; dev_no < 9 ; dev_no++)
{
sprintf(path, "/dev/df%c%d", dev_part, dev_no);
if (lstat(path, &stat_buff) < 0)
break;
shannon_devices[shannon_found_devices].st_dev= stat_buff.st_rdev;
sprintf(shannon_devices[shannon_found_devices].dev_name, "/dev/sct%c%d",
dev_part, dev_no);
#ifdef TEST_SHANNON
printf("%s(): i=%d, st_dev=0x%lx, st_rdev=0x%lx, dev_name=%s\n",
__func__,
shannon_found_devices,
(ulong) stat_buff.st_dev,
(ulong) shannon_devices[shannon_found_devices].st_dev,
shannon_devices[shannon_found_devices].dev_name);
#endif
/*
The atomic size will be checked on first access. This is needed
as a normal user can't open the /dev/scta file
*/
shannon_devices[shannon_found_devices].atomic_size=
SHANNON_NO_ATOMIC_SIZE_YET;
if (++shannon_found_devices == SHANNON_MAX_DEVICES)
goto end;
}
}
end:
shannon_devices[shannon_found_devices].st_dev= 0;
return shannon_found_devices > 0;
}
static my_bool shannon_dev_has_atomic_write(struct shannon_dev *dev,
int page_size)
{
#ifdef TEST_SHANNON
printf("%s: enter: page_size=%d, atomic_size=%d, dev_name=%s\n",
__func__,
page_size,
dev->atomic_size,
dev->dev_name);
#endif
if (dev->atomic_size == SHANNON_NO_ATOMIC_SIZE_YET)
{
int fd= open(dev->dev_name, 0);
if (fd < 0)
{
perror("open() failed!");
dev->atomic_size= 0; /* Don't try again */
return FALSE;
}
dev->atomic_size= ioctl(fd, SHANNON_IOCQATOMIC_SIZE);
close(fd);
}
#ifdef TEST_SHANNON
printf("%s: exit: page_size=%d, atomic_size=%d, dev_name=%s\n",
__func__,
page_size,
dev->atomic_size,
dev->dev_name);
#endif
return (page_size <= dev->atomic_size);
}
/**
Check if a file is on a Shannon device and that it supports atomic_write
@param[in] file OS file handle
@param[in] page_size page size
@return TRUE Atomic write supported
@notes
This is called only at first open of a file. In this case it's doesn't
matter so much that we loop over all cards.
We update the atomic size on first access.
*/
static my_bool shannon_has_atomic_write(File file, int page_size)
{
struct shannon_dev *dev;
struct stat stat_buff;
if (fstat(file, &stat_buff) < 0)
{
#ifdef TEST_SHANNON
printf("%s(): fstat failed\n", __func__);
#endif
return 0;
}
#ifdef TEST_SHANNON
printf("%s(): st_dev=0x%lx, st_rdev=0x%lx\n", __func__,
(ulong) stat_buff.st_dev, (ulong) stat_buff.st_rdev);
#endif
for (dev= shannon_devices ; dev->st_dev; dev++)
{
#ifdef TEST_SHANNON
printf("%s(): st_rdev=0x%lx\n", __func__, (ulong) dev->st_dev);
#endif
if (stat_buff.st_dev == dev->st_dev)
return shannon_dev_has_atomic_write(dev, page_size);
}
return 0;
}
/***********************************************************************
Generic atomic write code
************************************************************************/
/*
Initalize automic write sub systems.
Checks if we have any devices that supports atomic write
*/
void my_init_atomic_write(void)
{
if ((has_shannon_atomic_write= test_if_shannon_card_exists()) ||
(has_fusion_io_atomic_write= test_if_fusion_io_card_exists()))
my_may_have_atomic_write= 1;
#ifdef TEST_SHANNON
printf("%s(): has_shannon_atomic_write=%d, my_may_have_atomic_write=%d\n",
__func__,
has_shannon_atomic_write,
my_may_have_atomic_write);
#endif
}
/**
Check if a file supports atomic write
@return FALSE No atomic write support
TRUE File supports atomic write
*/
my_bool my_test_if_atomic_write(File handle, int page_size)
{
#ifdef TEST_SHANNON
printf("%s(): has_shannon_atomic_write=%d, my_may_have_atomic_write=%d\n",
__func__,
has_shannon_atomic_write,
my_may_have_atomic_write);
#endif
if (!my_may_have_atomic_write)
return 0;
if (has_shannon_atomic_write &&
shannon_has_atomic_write(handle, page_size))
return 1;
if (has_fusion_io_atomic_write &&
fusion_io_has_atomic_write(handle, page_size))
return 1;
return 0;
}
#ifdef TEST_SHANNON
int main()
{
int fd, ret;
my_init_atomic_write();
fd= open("/u01/1.file", O_RDWR);
ret= my_test_if_atomic_write(fd, 4096);
if (ret)
printf("support atomic_write\n");
else
printf("do not support atomic_write\n");
close(fd);
return 0;
}
#endif
#else /* __linux__ */
/* Dummy functions to provide the interfaces for other systems */
void my_init_atomic_write(void)
{
}
#endif /* __linux__ */

View File

@@ -5862,6 +5862,9 @@ int mysqld_main(int argc, char **argv)
if (my_setwd(mysql_real_data_home, opt_abort ? 0 : MYF(MY_WME)) && !opt_abort) if (my_setwd(mysql_real_data_home, opt_abort ? 0 : MYF(MY_WME)) && !opt_abort)
unireg_abort(1); /* purecov: inspected */ unireg_abort(1); /* purecov: inspected */
/* Atomic write initialization must be done as root */
my_init_atomic_write();
if ((user_info= check_user(mysqld_user))) if ((user_info= check_user(mysqld_user)))
{ {
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) #if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)

View File

@@ -1008,7 +1008,7 @@ buf_flush_write_block_low(
{ {
page_t* frame = NULL; page_t* frame = NULL;
ulint space_id = bpage->id.space(); ulint space_id = bpage->id.space();
atomic_writes_t awrites = fil_space_get_atomic_writes(space_id); bool atomic_writes = fil_space_get_atomic_writes(space_id);
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
@@ -1086,7 +1086,7 @@ buf_flush_write_block_low(
|| buf_dblwr == NULL || buf_dblwr == NULL
|| srv_read_only_mode || srv_read_only_mode
|| fsp_is_system_temporary(bpage->id.space()) || fsp_is_system_temporary(bpage->id.space())
|| awrites == ATOMIC_WRITES_ON) { || atomic_writes) {
ut_ad(!srv_read_only_mode ut_ad(!srv_read_only_mode
|| fsp_is_system_temporary(bpage->id.space())); || fsp_is_system_temporary(bpage->id.space()));

View File

@@ -7273,7 +7273,6 @@ dict_tf_to_fsp_flags(
bool is_shared = DICT_TF_HAS_SHARED_SPACE(table_flags); bool is_shared = DICT_TF_HAS_SHARED_SPACE(table_flags);
bool page_compression = DICT_TF_GET_PAGE_COMPRESSION(table_flags); bool page_compression = DICT_TF_GET_PAGE_COMPRESSION(table_flags);
ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(table_flags); ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(table_flags);
ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(table_flags);
ut_ad(!page_size.is_compressed() || has_atomic_blobs); ut_ad(!page_size.is_compressed() || has_atomic_blobs);
@@ -7305,12 +7304,6 @@ dict_tf_to_fsp_flags(
fsp_flags |= FSP_FLAGS_SET_PAGE_COMPRESSION_LEVEL(fsp_flags, page_compression_level); fsp_flags |= FSP_FLAGS_SET_PAGE_COMPRESSION_LEVEL(fsp_flags, page_compression_level);
} }
/* In addition, tablespace flags also contain flag if atomic writes
is used for this table */
if (atomic_writes) {
fsp_flags |= FSP_FLAGS_SET_ATOMIC_WRITES(fsp_flags, atomic_writes);
}
ut_ad(fsp_flags_is_valid(fsp_flags)); ut_ad(fsp_flags_is_valid(fsp_flags));
return(fsp_flags); return(fsp_flags);

View File

@@ -475,34 +475,6 @@ fil_space_is_flushed(
return(true); return(true);
} }
#ifdef UNIV_LINUX
#include <sys/ioctl.h>
/** FusionIO atomic write control info */
#define DFS_IOCTL_ATOMIC_WRITE_SET _IOW(0x95, 2, uint)
/**
Try and enable FusionIO atomic writes.
@param[in] file OS file handle
@return true if successful */
bool
fil_fusionio_enable_atomic_write(os_file_t file)
{
if (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) {
uint atomic = 1;
ut_a(file != -1);
if (ioctl(file, DFS_IOCTL_ATOMIC_WRITE_SET, &atomic) != -1) {
return(true);
}
}
return(false);
}
#endif /* UNIV_LINUX */
/** Append a file to the chain of files of a space. /** Append a file to the chain of files of a space.
@param[in] name file name of a file that is not open @param[in] name file name of a file that is not open
@@ -510,7 +482,7 @@ fil_fusionio_enable_atomic_write(os_file_t file)
@param[in,out] space tablespace from fil_space_create() @param[in,out] space tablespace from fil_space_create()
@param[in] is_raw whether this is a raw device or partition @param[in] is_raw whether this is a raw device or partition
@param[in] punch_hole true if supported for this node @param[in] punch_hole true if supported for this node
@param[in] atomic_write true if the file has atomic write enabled @param[in] atomic_write true if the file could use atomic write
@param[in] max_pages maximum number of pages in file, @param[in] max_pages maximum number of pages in file,
ULINT_MAX means the file size is unlimited. ULINT_MAX means the file size is unlimited.
@return pointer to the file name @return pointer to the file name
@@ -606,7 +578,7 @@ fil_node_create_low(
an integer an integer
@param[in,out] space space where to append @param[in,out] space space where to append
@param[in] is_raw true if a raw device or a raw disk partition @param[in] is_raw true if a raw device or a raw disk partition
@param[in] atomic_write true if the file has atomic write enabled @param[in] atomic_write true if the file could use atomic write
@param[in] max_pages maximum number of pages in file, @param[in] max_pages maximum number of pages in file,
ULINT_MAX means the file size is unlimited. ULINT_MAX means the file size is unlimited.
@return pointer to the file name @return pointer to the file name
@@ -829,7 +801,27 @@ retry:
node->handle = os_file_create( node->handle = os_file_create(
innodb_data_file_key, node->name, OS_FILE_OPEN, innodb_data_file_key, node->name, OS_FILE_OPEN,
OS_FILE_AIO, OS_DATA_FILE, read_only_mode, &success); OS_FILE_AIO, OS_DATA_FILE, read_only_mode, &success);
}
if (!space->atomic_write_tested)
{
const page_size_t page_size(space->flags);
space->atomic_write_tested= 1;
/*
Atomic writes is supported if the file can be used
with atomic_writes (not log file), O_DIRECT is
used (tested in ha_innodbc.cc) and the file is
device and file system that supports atomic writes
for the given block size
*/
space->atomic_write_supported=
srv_use_atomic_writes &&
node->atomic_write &&
my_test_if_atomic_write(node->handle,
page_size.physical()) ?
true : false;
}
}
ut_a(success); ut_a(success);
@@ -3855,37 +3847,34 @@ fil_ibd_create(
return(DB_ERROR); return(DB_ERROR);
} }
#ifdef UNIV_LINUX success= false;
const bool atomic_write = fil_fusionio_enable_atomic_write(file); #ifdef HAVE_POSIX_FALLOCATE
/*
Extend the file using posix_fallocate(). This is required by
FusionIO HW/Firmware but should also be the prefered way to extend
a file.
*/
int ret = posix_fallocate(file, 0, size * UNIV_PAGE_SIZE);
if (atomic_write) { if (ret != 0) {
/* This is required by FusionIO HW/Firmware */ ib::error() <<
int ret = posix_fallocate(file, 0, size * UNIV_PAGE_SIZE); "posix_fallocate(): Failed to preallocate"
" data for file " << path
if (ret != 0) { << ", desired size "
<< size * UNIV_PAGE_SIZE
ib::error() << << " Operating system error number " << ret
"posix_fallocate(): Failed to preallocate" << ". Check"
" data for file " << path " that the disk is not full or a disk quota"
<< ", desired size " " exceeded. Make sure the file system supports"
<< size * UNIV_PAGE_SIZE " this function. Some operating system error"
<< " Operating system error number " << ret " numbers are described at " REFMAN
<< ". Check" " operating-system-error-codes.html";
" that the disk is not full or a disk quota"
" exceeded. Make sure the file system supports"
" this function. Some operating system error"
" numbers are described at " REFMAN
" operating-system-error-codes.html";
success = false;
} else { } else {
success = true; success = true;
} }
} else #endif /* HAVE_POSIX_FALLOCATE */
#else if (!success)
const bool atomic_write = false; {
#endif /* UNIV_LINUX */
{
success = os_file_set_size( success = os_file_set_size(
path, file, size * UNIV_PAGE_SIZE, srv_read_only_mode); path, file, size * UNIV_PAGE_SIZE, srv_read_only_mode);
} }
@@ -4022,7 +4011,7 @@ fil_ibd_create(
crypt_data, true); crypt_data, true);
if (!fil_node_create_low( if (!fil_node_create_low(
path, size, space, false, punch_hole, atomic_write)) { path, size, space, false, punch_hole, TRUE)) {
if (crypt_data) { if (crypt_data) {
free(crypt_data); free(crypt_data);
@@ -4234,13 +4223,6 @@ fil_ibd_open(
df_dict.close(); df_dict.close();
} }
#ifdef UNIV_LINUX
const bool atomic_write = !srv_use_doublewrite_buf && df_default.is_open()
&& fil_fusionio_enable_atomic_write(df_default.handle());
#else
const bool atomic_write = false;
#endif /* UNIV_LINUX */
/* We have now checked all possible tablespace locations and /* We have now checked all possible tablespace locations and
have a count of how many unique files we found. If things are have a count of how many unique files we found. If things are
normal, we only found 1. */ normal, we only found 1. */
@@ -4443,7 +4425,7 @@ skip_validate:
df_remote.is_open() ? df_remote.filepath() : df_remote.is_open() ? df_remote.filepath() :
df_dict.is_open() ? df_dict.filepath() : df_dict.is_open() ? df_dict.filepath() :
df_default.filepath(), 0, space, false, df_default.filepath(), 0, space, false,
true, atomic_write) == NULL) { true, TRUE) == NULL) {
err = DB_ERROR; err = DB_ERROR;
} }

View File

@@ -200,7 +200,6 @@ fsp_flags_to_dict_tf(
bool shared_space = FSP_FLAGS_GET_SHARED(fsp_flags); bool shared_space = FSP_FLAGS_GET_SHARED(fsp_flags);
bool page_compressed = FSP_FLAGS_GET_PAGE_COMPRESSION(fsp_flags); bool page_compressed = FSP_FLAGS_GET_PAGE_COMPRESSION(fsp_flags);
ulint comp_level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(fsp_flags); ulint comp_level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(fsp_flags);
bool atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(fsp_flags);
/* FSP_FLAGS_GET_TEMPORARY(fsp_flags) does not have an equivalent /* FSP_FLAGS_GET_TEMPORARY(fsp_flags) does not have an equivalent
flag position in the table flags. But it would go into flags2 if flag position in the table flags. But it would go into flags2 if
@@ -208,7 +207,7 @@ fsp_flags_to_dict_tf(
ulint flags = dict_tf_init(post_antelope | compact, zip_ssize, ulint flags = dict_tf_init(post_antelope | compact, zip_ssize,
atomic_blobs, data_dir, shared_space, atomic_blobs, data_dir, shared_space,
page_compressed, comp_level, atomic_writes); page_compressed, comp_level, 0);
return(flags); return(flags);
} }
@@ -235,7 +234,6 @@ fsp_flags_is_valid(
ulint unused = FSP_FLAGS_GET_UNUSED(flags); ulint unused = FSP_FLAGS_GET_UNUSED(flags);
bool page_compression = FSP_FLAGS_GET_PAGE_COMPRESSION(flags); bool page_compression = FSP_FLAGS_GET_PAGE_COMPRESSION(flags);
ulint page_compression_level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(flags); ulint page_compression_level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(flags);
ulint atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(flags);
const char *file; const char *file;
ulint line; ulint line;
@@ -301,11 +299,6 @@ fsp_flags_is_valid(
} }
} }
if (atomic_writes > ATOMIC_WRITES_OFF) {
GOTO_ERROR;
return (false);
}
#if UNIV_FORMAT_MAX != UNIV_FORMAT_B #if UNIV_FORMAT_MAX != UNIV_FORMAT_B
# error UNIV_FORMAT_MAX != UNIV_FORMAT_B, Add more validations. # error UNIV_FORMAT_MAX != UNIV_FORMAT_B, Add more validations.
#endif #endif
@@ -329,8 +322,7 @@ err_exit:
<< " is_temp: " << is_temp << " is_temp: " << is_temp
<< " is_encryption: " << is_encryption << " is_encryption: " << is_encryption
<< " page_compressed: " << page_compression << " page_compressed: " << page_compression
<< " page_compression_level: " << page_compression_level << " page_compression_level: " << page_compression_level;
<< " atomic_writes: " << atomic_writes;
return (false); return (false);
} }

View File

@@ -118,13 +118,6 @@ Tablespace::open_or_create(bool is_temp)
break; break;
} }
#ifdef UNIV_LINUX
const bool atomic_write = fil_fusionio_enable_atomic_write(
it->m_handle);
#else
const bool atomic_write = false;
#endif
/* We can close the handle now and open the tablespace /* We can close the handle now and open the tablespace
the proper way. */ the proper way. */
it->close(); it->close();
@@ -149,7 +142,7 @@ Tablespace::open_or_create(bool is_temp)
/* Create the tablespace node entry for this data file. */ /* Create the tablespace node entry for this data file. */
if (!fil_node_create( if (!fil_node_create(
it->m_filepath, it->m_size, space, false, it->m_filepath, it->m_size, space, false,
atomic_write)) { TRUE)) {
err = DB_ERROR; err = DB_ERROR;
break; break;

View File

@@ -906,24 +906,6 @@ SysTablespace::open_or_create(
return(err); return(err);
} }
#ifdef UNIV_LINUX
/* Note: This should really be per node and not per
tablespace because a tablespace can contain multiple
files (nodes). The implication is that all files of
the tablespace should be on the same medium. */
it->m_atomic_write
= fil_fusionio_enable_atomic_write(it->m_handle);
if (it->m_atomic_write && srv_use_doublewrite_buf) {
ib::info() << "FusionIO atomic IO enabled,"
" disabling the double write buffer";
srv_use_doublewrite_buf = false;
}
#else
it->m_atomic_write = false;
#endif
} }
if (!create_new_db && flush_lsn) { if (!create_new_db && flush_lsn) {
@@ -975,7 +957,7 @@ SysTablespace::open_or_create(
if (!fil_node_create( if (!fil_node_create(
it->m_filepath, it->m_size, it->m_filepath, it->m_size,
space, it->m_type != SRV_NOT_RAW, space, it->m_type != SRV_NOT_RAW,
it->m_atomic_write, max_size)) { TRUE, max_size)) {
err = DB_ERROR; err = DB_ERROR;
break; break;

View File

@@ -249,7 +249,7 @@ values */
static ulong innobase_fast_shutdown = 1; static ulong innobase_fast_shutdown = 1;
static my_bool innobase_file_format_check = TRUE; static my_bool innobase_file_format_check = TRUE;
static my_bool innobase_use_atomic_writes = FALSE; static my_bool innobase_use_atomic_writes = TRUE;
static my_bool innobase_use_fallocate; static my_bool innobase_use_fallocate;
static my_bool innobase_use_doublewrite = TRUE; static my_bool innobase_use_doublewrite = TRUE;
static my_bool innobase_use_checksums = TRUE; static my_bool innobase_use_checksums = TRUE;
@@ -791,8 +791,6 @@ ha_create_table_option innodb_table_option_list[]=
/* With this option user can set zip compression level for page /* With this option user can set zip compression level for page
compression for this table*/ compression for this table*/
HA_TOPTION_NUMBER("PAGE_COMPRESSION_LEVEL", page_compression_level, 0, 1, 9, 1), HA_TOPTION_NUMBER("PAGE_COMPRESSION_LEVEL", page_compression_level, 0, 1, 9, 1),
/* With this option user can enable atomic writes feature for this table */
HA_TOPTION_ENUM("ATOMIC_WRITES", atomic_writes, "DEFAULT,ON,OFF", 0),
/* With this option the user can enable encryption for the table */ /* With this option the user can enable encryption for the table */
HA_TOPTION_ENUM("ENCRYPTED", encryption, "DEFAULT,YES,NO", 0), HA_TOPTION_ENUM("ENCRYPTED", encryption, "DEFAULT,YES,NO", 0),
/* With this option the user defines the key identifier using for the encryption */ /* With this option the user defines the key identifier using for the encryption */
@@ -4332,7 +4330,7 @@ innobase_init(
/* Create the filespace flags. */ /* Create the filespace flags. */
fsp_flags = fsp_flags_init( fsp_flags = fsp_flags_init(
univ_page_size, false, false, false, false, false, 0, ATOMIC_WRITES_DEFAULT); univ_page_size, false, false, false, false, false, 0, 0);
srv_sys_space.set_flags(fsp_flags); srv_sys_space.set_flags(fsp_flags);
srv_sys_space.set_name(reserved_system_space_name); srv_sys_space.set_name(reserved_system_space_name);
@@ -4358,7 +4356,7 @@ innobase_init(
/* Create the filespace flags with the temp flag set. */ /* Create the filespace flags with the temp flag set. */
fsp_flags = fsp_flags_init( fsp_flags = fsp_flags_init(
univ_page_size, false, false, false, true, false, 0, ATOMIC_WRITES_DEFAULT); univ_page_size, false, false, false, true, false, 0, 0);
srv_tmp_space.set_flags(fsp_flags); srv_tmp_space.set_flags(fsp_flags);
if (!srv_tmp_space.parse_params(innobase_temp_data_file_path, false)) { if (!srv_tmp_space.parse_params(innobase_temp_data_file_path, false)) {
@@ -4647,17 +4645,20 @@ innobase_change_buffering_inited_ok:
" It will be removed in MariaDB 10.3."; " It will be removed in MariaDB 10.3.";
} }
srv_use_atomic_writes = (ibool) innobase_use_atomic_writes; srv_use_atomic_writes = (ibool) (innobase_use_atomic_writes &&
if (innobase_use_atomic_writes) { my_may_have_atomic_write);
fprintf(stderr, "InnoDB: using atomic writes.\n"); if (srv_use_atomic_writes && !srv_file_per_table)
/* Force doublewrite buffer off, atomic writes replace it. */ {
if (srv_use_doublewrite_buf) { fprintf(stderr, "InnoDB: Disabling atomic_writes as file_per_table is not used.\n");
fprintf(stderr, "InnoDB: Switching off doublewrite buffer " srv_use_atomic_writes= 0;
"because of atomic writes.\n"); }
innobase_use_doublewrite = srv_use_doublewrite_buf = FALSE;
}
/* Force O_DIRECT on Unixes (on Windows writes are always unbuffered)*/ if (srv_use_atomic_writes) {
fprintf(stderr, "InnoDB: using atomic writes.\n");
/*
Force O_DIRECT on Unixes (on Windows writes are always
unbuffered)
*/
#ifndef _WIN32 #ifndef _WIN32
if (!innobase_file_flush_method || if (!innobase_file_flush_method ||
!strstr(innobase_file_flush_method, "O_DIRECT")) { !strstr(innobase_file_flush_method, "O_DIRECT")) {
@@ -13153,7 +13154,6 @@ create_table_info_t::check_table_options()
{ {
enum row_type row_format = m_form->s->row_type; enum row_type row_format = m_form->s->row_type;
ha_table_option_struct *options= m_form->s->option_struct; ha_table_option_struct *options= m_form->s->option_struct;
atomic_writes_t awrites = (atomic_writes_t)options->atomic_writes;
fil_encryption_t encrypt = (fil_encryption_t)options->encryption; fil_encryption_t encrypt = (fil_encryption_t)options->encryption;
if (encrypt != FIL_SPACE_ENCRYPTION_DEFAULT && !m_allow_file_per_table) { if (encrypt != FIL_SPACE_ENCRYPTION_DEFAULT && !m_allow_file_per_table) {
@@ -13287,19 +13287,6 @@ create_table_info_t::check_table_options()
} }
} }
/* Check atomic writes requirements */
if (awrites == ATOMIC_WRITES_ON ||
(awrites == ATOMIC_WRITES_DEFAULT && srv_use_atomic_writes)) {
if (!m_allow_file_per_table) {
push_warning(
m_thd, Sql_condition::WARN_LEVEL_WARN,
HA_WRONG_CREATE_OPTION,
"InnoDB: ATOMIC_WRITES requires"
" innodb_file_per_table.");
return "ATOMIC_WRITES";
}
}
return NULL; return NULL;
} }
@@ -13712,7 +13699,7 @@ index_bad:
options->page_compressed, options->page_compressed,
options->page_compression_level == 0 ? options->page_compression_level == 0 ?
default_compression_level : options->page_compression_level, default_compression_level : options->page_compression_level,
options->atomic_writes); 0);
if (m_use_file_per_table) { if (m_use_file_per_table) {
ut_ad(!m_use_shared_space); ut_ad(!m_use_shared_space);
@@ -15032,7 +15019,7 @@ innobase_create_tablespace(
false, /* Temporary General Tablespaces not allowed */ false, /* Temporary General Tablespaces not allowed */
false, /* Page compression is not used. */ false, /* Page compression is not used. */
0, /* Page compression level 0 */ 0, /* Page compression level 0 */
ATOMIC_WRITES_DEFAULT); /* No atomic writes yet */ 0);
tablespace.set_flags(fsp_flags); tablespace.set_flags(fsp_flags);
@@ -19482,8 +19469,8 @@ ha_innobase::check_if_incompatible_data(
/* Changes on engine specific table options requests a rebuild of the table. */ /* Changes on engine specific table options requests a rebuild of the table. */
if (param_new->page_compressed != param_old->page_compressed || if (param_new->page_compressed != param_old->page_compressed ||
param_new->page_compression_level != param_old->page_compression_level || param_new->page_compression_level != param_old->page_compression_level)
param_new->atomic_writes != param_old->atomic_writes) { {
return(COMPATIBLE_DATA_NO); return(COMPATIBLE_DATA_NO);
} }
@@ -21950,12 +21937,13 @@ static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
static MYSQL_SYSVAR_BOOL(use_atomic_writes, innobase_use_atomic_writes, static MYSQL_SYSVAR_BOOL(use_atomic_writes, innobase_use_atomic_writes,
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY, PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
"Prevent partial page writes, via atomic writes." "Enable atomic writes, instead of using the doublewrite buffer, for files "
"The option is used to prevent partial writes in case of a crash/poweroff, " "on devices that supports atomic writes. "
"as faster alternative to doublewrite buffer." "To use this option one must use "
"Currently this option works only " "file_per_table=1, flush_method=O_DIRECT and use_fallocate=1. "
"on Linux only with FusionIO device, and directFS filesystem.", "This option only works on Linux with either FusionIO cards using "
NULL, NULL, FALSE); "the directFS filesystem or with Shannon cards using any file system.",
NULL, NULL, TRUE);
static MYSQL_SYSVAR_BOOL(use_fallocate, innobase_use_fallocate, static MYSQL_SYSVAR_BOOL(use_fallocate, innobase_use_fallocate,
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY, PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,

View File

@@ -614,8 +614,7 @@ ha_innobase::check_if_supported_inplace_alter(
ha_table_option_struct *old_options= table->s->option_struct; ha_table_option_struct *old_options= table->s->option_struct;
if (new_options->page_compressed != old_options->page_compressed || if (new_options->page_compressed != old_options->page_compressed ||
new_options->page_compression_level != old_options->page_compression_level || new_options->page_compression_level != old_options->page_compression_level) {
new_options->atomic_writes != old_options->atomic_writes) {
ha_alter_info->unsupported_reason = innobase_get_err_msg( ha_alter_info->unsupported_reason = innobase_get_err_msg(
ER_ALTER_OPERATION_NOT_SUPPORTED_REASON); ER_ALTER_OPERATION_NOT_SUPPORTED_REASON);
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);

View File

@@ -1003,7 +1003,7 @@ dict_tf_set(
bool shared_space, bool shared_space,
bool page_compressed, bool page_compressed,
ulint page_compression_level, ulint page_compression_level,
ulint atomic_writes); ulint not_used);
/** Initialize a dict_table_t::flags pointer. /** Initialize a dict_table_t::flags pointer.
@param[in] compact, Table uses Compact or greater @param[in] compact, Table uses Compact or greater
@@ -1021,7 +1021,7 @@ dict_tf_init(
bool shared_space, bool shared_space,
bool page_compressed, bool page_compressed,
ulint page_compression_level, ulint page_compression_level,
ulint atomic_writes); ulint not_used);
/** Convert a 32 bit integer table flags to the 32 bit FSP Flags. /** Convert a 32 bit integer table flags to the 32 bit FSP Flags.
Fsp Flags are written into the tablespace header at the offset Fsp Flags are written into the tablespace header at the offset

View File

@@ -664,7 +664,6 @@ dict_tf_is_valid(
ulint unused = DICT_TF_GET_UNUSED(flags); ulint unused = DICT_TF_GET_UNUSED(flags);
bool page_compression = DICT_TF_GET_PAGE_COMPRESSION(flags); bool page_compression = DICT_TF_GET_PAGE_COMPRESSION(flags);
ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(flags); ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(flags);
ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(flags);
bool flags_corrupt = false; bool flags_corrupt = false;
/* Make sure there are no bits that we do not know about. */ /* Make sure there are no bits that we do not know about. */
@@ -711,12 +710,6 @@ dict_tf_is_valid(
} }
} }
if (atomic_writes) {
if(atomic_writes > ATOMIC_WRITES_OFF) {
flags_corrupt = true;
}
}
/* HAS_DATA_DIR and SHARED_SPACE are mutually exclusive. */ /* HAS_DATA_DIR and SHARED_SPACE are mutually exclusive. */
if (data_dir && shared_space) { if (data_dir && shared_space) {
@@ -734,7 +727,6 @@ dict_tf_is_valid(
<< " zip_ssize:" << zip_ssize << " zip_ssize:" << zip_ssize
<< " page_compression:" << page_compression << " page_compression:" << page_compression
<< " page_compression_level:" << page_compression_level << " page_compression_level:" << page_compression_level
<< " atomic_writes:" << atomic_writes
<< " shared_space:" << shared_space; << " shared_space:" << shared_space;
return (false); return (false);
} else { } else {
@@ -789,9 +781,6 @@ dict_sys_tables_type_validate(
ulint unused = DICT_TF_GET_UNUSED(type); ulint unused = DICT_TF_GET_UNUSED(type);
bool page_compression = DICT_TF_GET_PAGE_COMPRESSION(type); bool page_compression = DICT_TF_GET_PAGE_COMPRESSION(type);
ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(type); ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(type);
ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(type);
ut_a(atomic_writes <= ATOMIC_WRITES_OFF);
/* The low order bit of SYS_TABLES.TYPE is always set to 1. /* The low order bit of SYS_TABLES.TYPE is always set to 1.
If the format is UNIV_FORMAT_B or higher, this field is the same If the format is UNIV_FORMAT_B or higher, this field is the same
@@ -875,13 +864,6 @@ dict_sys_tables_type_validate(
} }
} }
/* Validate that the atomic writes number is within allowed range. */
if (atomic_writes > ATOMIC_WRITES_OFF) {
ib::error() << "SYS_TABLES::TYPE=" << type
<< " atomic_writes:" << atomic_writes;
return(ULINT_UNDEFINED);
}
/* Return the validated SYS_TABLES.TYPE. */ /* Return the validated SYS_TABLES.TYPE. */
return(type); return(type);
} }
@@ -949,11 +931,10 @@ dict_table_get_format(
@param[in] format File Format @param[in] format File Format
@param[in] zip_ssize Zip Shift Size @param[in] zip_ssize Zip Shift Size
@param[in] use_data_dir Table uses DATA DIRECTORY @param[in] use_data_dir Table uses DATA DIRECTORY
@param[in] atomic_writes Does table use atomic writes
@param[in] shared_space Table uses a General Shared Tablespace @param[in] shared_space Table uses a General Shared Tablespace
@param[in] page_compressed Table uses page compression @param[in] page_compressed Table uses page compression
@param[in] page_compression_level Page compression level @param[in] page_compression_level Page compression level
@param[in] atomic_writes Table uses atomic writes */ @param[in] not_used For future */
UNIV_INLINE UNIV_INLINE
void void
dict_tf_set( dict_tf_set(
@@ -965,7 +946,7 @@ dict_tf_set(
bool shared_space, bool shared_space,
bool page_compressed, bool page_compressed,
ulint page_compression_level, ulint page_compression_level,
ulint atomic_writes) ulint not_used)
{ {
switch (format) { switch (format) {
case REC_FORMAT_REDUNDANT: case REC_FORMAT_REDUNDANT:
@@ -1005,11 +986,6 @@ dict_tf_set(
ut_ad(dict_tf_get_page_compression(*flags) == TRUE); ut_ad(dict_tf_get_page_compression(*flags) == TRUE);
ut_ad(dict_tf_get_page_compression_level(*flags) == page_compression_level); ut_ad(dict_tf_get_page_compression_level(*flags) == page_compression_level);
} }
if (atomic_writes) {
*flags |= (atomic_writes << DICT_TF_POS_ATOMIC_WRITES);
ut_a(dict_tf_get_atomic_writes(*flags) == atomic_writes);
}
} }
/** Initialize a dict_table_t::flags pointer. /** Initialize a dict_table_t::flags pointer.
@@ -1020,7 +996,7 @@ dict_tf_set(
@param[in] shared_space Table uses a General Shared Tablespace @param[in] shared_space Table uses a General Shared Tablespace
@param[in] page_compression Table uses page compression @param[in] page_compression Table uses page compression
@param[in] page_compression_level used compression level @param[in] page_compression_level used compression level
@param[in] atomic_writes Table atomic writes option */ @param[in] not_used For future */
UNIV_INLINE UNIV_INLINE
ulint ulint
dict_tf_init( dict_tf_init(
@@ -1031,7 +1007,7 @@ dict_tf_init(
bool shared_space, bool shared_space,
bool page_compressed, bool page_compressed,
ulint page_compression_level, ulint page_compression_level,
ulint atomic_writes) ulint not_used)
{ {
ulint flags = 0; ulint flags = 0;
@@ -1065,11 +1041,6 @@ dict_tf_init(
ut_ad(dict_tf_get_page_compression_level(flags) == page_compression_level); ut_ad(dict_tf_get_page_compression_level(flags) == page_compression_level);
} }
if (atomic_writes) {
flags |= (atomic_writes << DICT_TF_POS_ATOMIC_WRITES);
ut_a(dict_tf_get_atomic_writes(flags) == atomic_writes);
}
return(flags); return(flags);
} }
@@ -1097,13 +1068,12 @@ dict_sys_tables_type_to_tf(
flags = redundant ? 0 : 1; flags = redundant ? 0 : 1;
/* ZIP_SSIZE, ATOMIC_BLOBS, DATA_DIR, PAGE_COMPRESSION, /* ZIP_SSIZE, ATOMIC_BLOBS, DATA_DIR, PAGE_COMPRESSION,
PAGE_COMPRESSION_LEVEL, ATOMIC_WRITES are the same. */ PAGE_COMPRESSION_LEVEL are the same. */
flags |= type & (DICT_TF_MASK_ZIP_SSIZE flags |= type & (DICT_TF_MASK_ZIP_SSIZE
| DICT_TF_MASK_ATOMIC_BLOBS | DICT_TF_MASK_ATOMIC_BLOBS
| DICT_TF_MASK_DATA_DIR | DICT_TF_MASK_DATA_DIR
| DICT_TF_MASK_PAGE_COMPRESSION | DICT_TF_MASK_PAGE_COMPRESSION
| DICT_TF_MASK_PAGE_COMPRESSION_LEVEL | DICT_TF_MASK_PAGE_COMPRESSION_LEVEL
| DICT_TF_MASK_ATOMIC_WRITES
| DICT_TF_MASK_SHARED_SPACE); | DICT_TF_MASK_SHARED_SPACE);
ut_ad(!DICT_TF_GET_ZIP_SSIZE(flags) || DICT_TF_HAS_ATOMIC_BLOBS(flags)); ut_ad(!DICT_TF_GET_ZIP_SSIZE(flags) || DICT_TF_HAS_ATOMIC_BLOBS(flags));
@@ -1134,13 +1104,12 @@ dict_tf_to_sys_tables_type(
type = 1; type = 1;
/* ZIP_SSIZE, ATOMIC_BLOBS, DATA_DIR, PAGE_COMPRESSION, /* ZIP_SSIZE, ATOMIC_BLOBS, DATA_DIR, PAGE_COMPRESSION,
PAGE_COMPRESSION_LEVEL, ATOMIC_WRITES are the same. */ PAGE_COMPRESSION_LEVEL are the same. */
type |= flags & (DICT_TF_MASK_ZIP_SSIZE type |= flags & (DICT_TF_MASK_ZIP_SSIZE
| DICT_TF_MASK_ATOMIC_BLOBS | DICT_TF_MASK_ATOMIC_BLOBS
| DICT_TF_MASK_DATA_DIR | DICT_TF_MASK_DATA_DIR
| DICT_TF_MASK_PAGE_COMPRESSION | DICT_TF_MASK_PAGE_COMPRESSION
| DICT_TF_MASK_PAGE_COMPRESSION_LEVEL | DICT_TF_MASK_PAGE_COMPRESSION_LEVEL
| DICT_TF_MASK_ATOMIC_WRITES
| DICT_TF_MASK_SHARED_SPACE); | DICT_TF_MASK_SHARED_SPACE);
return(type); return(type);

View File

@@ -67,26 +67,6 @@ dict_tf_verify_flags(
ulint fsp_flags) /*!< in: fil_space_t::flags */ ulint fsp_flags) /*!< in: fil_space_t::flags */
__attribute__((const)); __attribute__((const));
/********************************************************************//**
Extract the atomic writes flag from table flags.
@return true if atomic writes are used, false if not used */
UNIV_INLINE
atomic_writes_t
dict_tf_get_atomic_writes(
/*======================*/
ulint flags) /*!< in: flags */
__attribute__((const));
/********************************************************************//**
Check whether the table uses the atomic writes.
@return true if atomic writes is used, false if not */
UNIV_INLINE
atomic_writes_t
dict_table_get_atomic_writes(
/*=========================*/
const dict_table_t* table); /*!< in: table */
#ifndef UNIV_NONINL #ifndef UNIV_NONINL
#include "dict0pagecompress.ic" #include "dict0pagecompress.ic"
#endif #endif

View File

@@ -41,7 +41,6 @@ dict_tf_verify_flags(
ulint data_dir = DICT_TF_HAS_DATA_DIR(table_flags); ulint data_dir = DICT_TF_HAS_DATA_DIR(table_flags);
ulint page_compression = DICT_TF_GET_PAGE_COMPRESSION(table_flags); ulint page_compression = DICT_TF_GET_PAGE_COMPRESSION(table_flags);
ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(table_flags); ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(table_flags);
ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(table_flags);
ulint post_antelope = FSP_FLAGS_GET_POST_ANTELOPE(fsp_flags); ulint post_antelope = FSP_FLAGS_GET_POST_ANTELOPE(fsp_flags);
ulint zip_ssize = FSP_FLAGS_GET_ZIP_SSIZE(fsp_flags); ulint zip_ssize = FSP_FLAGS_GET_ZIP_SSIZE(fsp_flags);
ulint fsp_atomic_blobs = FSP_FLAGS_HAS_ATOMIC_BLOBS(fsp_flags); ulint fsp_atomic_blobs = FSP_FLAGS_HAS_ATOMIC_BLOBS(fsp_flags);
@@ -49,7 +48,6 @@ dict_tf_verify_flags(
ulint fsp_unused = FSP_FLAGS_GET_UNUSED(fsp_flags); ulint fsp_unused = FSP_FLAGS_GET_UNUSED(fsp_flags);
ulint fsp_page_compression = FSP_FLAGS_GET_PAGE_COMPRESSION(fsp_flags); ulint fsp_page_compression = FSP_FLAGS_GET_PAGE_COMPRESSION(fsp_flags);
ulint fsp_page_compression_level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(fsp_flags); ulint fsp_page_compression_level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(fsp_flags);
ulint fsp_atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(fsp_flags);
DBUG_EXECUTE_IF("dict_tf_verify_flags_failure", DBUG_EXECUTE_IF("dict_tf_verify_flags_failure",
return(ULINT_UNDEFINED);); return(ULINT_UNDEFINED););
@@ -97,16 +95,6 @@ dict_tf_verify_flags(
return (FALSE); return (FALSE);
} }
if (atomic_writes != fsp_atomic_writes) {
fprintf(stderr,
"InnoDB: Error: table flags has atomic writes %ld"
" in the data dictionary\n"
"InnoDB: but the flags in file has atomic_writes %ld\n",
atomic_writes, fsp_atomic_writes);
return (FALSE);
}
return(TRUE); return(TRUE);
} }
@@ -165,27 +153,3 @@ dict_table_is_page_compressed(
{ {
return (dict_tf_get_page_compression(table->flags)); return (dict_tf_get_page_compression(table->flags));
} }
/********************************************************************//**
Extract the atomic writes flag from table flags.
@return enumerated value of atomic writes */
UNIV_INLINE
atomic_writes_t
dict_tf_get_atomic_writes(
/*======================*/
ulint flags) /*!< in: flags */
{
return((atomic_writes_t)DICT_TF_GET_ATOMIC_WRITES(flags));
}
/********************************************************************//**
Check whether the table uses the atomic writes.
@return enumerated value of atomic writes */
UNIV_INLINE
atomic_writes_t
dict_table_get_atomic_writes(
/*=========================*/
const dict_table_t* table) /*!< in: table */
{
return ((atomic_writes_t)dict_tf_get_atomic_writes(table->flags));
}

View File

@@ -80,13 +80,6 @@ enum ib_quiesce_t {
QUIESCE_COMPLETE /*!< All done */ QUIESCE_COMPLETE /*!< All done */
}; };
/** Enum values for atomic_writes table option */
typedef enum {
ATOMIC_WRITES_DEFAULT = 0,
ATOMIC_WRITES_ON = 1,
ATOMIC_WRITES_OFF = 2
} atomic_writes_t;
#ifndef UNIV_INNOCHECKSUM #ifndef UNIV_INNOCHECKSUM
typedef ib_mutex_t DictSysMutex; typedef ib_mutex_t DictSysMutex;
#endif /* !UNIV_INNOCHECKSUM */ #endif /* !UNIV_INNOCHECKSUM */

View File

@@ -190,6 +190,14 @@ struct fil_space_t {
/** True if we have already printed compression failure */ /** True if we have already printed compression failure */
bool printed_compression_failure; bool printed_compression_failure;
/** True if page 0 of tablespace is read */
bool read_page0;
/** True if we have tested if this filespace supports atomic writes */
bool atomic_write_tested;
/** True if the device this filespace is on supports atomic writes */
bool atomic_write_supported;
/** Release the reserved free extents. /** Release the reserved free extents.
@param[in] n_reserved number of reserved extents */ @param[in] n_reserved number of reserved extents */
void release_free_extents(ulint n_reserved); void release_free_extents(ulint n_reserved);
@@ -244,7 +252,7 @@ struct fil_node_t {
/** block size to use for punching holes */ /** block size to use for punching holes */
ulint block_size; ulint block_size;
/** whether atomic write is enabled for this file */ /** whether this file could use atomic write (data file) */
bool atomic_write; bool atomic_write;
/** FIL_NODE_MAGIC_N */ /** FIL_NODE_MAGIC_N */
@@ -663,7 +671,7 @@ MY_ATTRIBUTE((warn_unused_result, pure));
@param[in] size file size in entire database blocks @param[in] size file size in entire database blocks
@param[in,out] space tablespace from fil_space_create() @param[in,out] space tablespace from fil_space_create()
@param[in] is_raw whether this is a raw device or partition @param[in] is_raw whether this is a raw device or partition
@param[in] atomic_write true if atomic write enabled @param[in] atomic_write true if atomic write could be enabled
@param[in] max_pages maximum number of pages in file, @param[in] max_pages maximum number of pages in file,
ULINT_MAX means the file size is unlimited. ULINT_MAX means the file size is unlimited.
@return pointer to the file name @return pointer to the file name
@@ -1730,15 +1738,6 @@ fil_names_clear(
lsn_t lsn, lsn_t lsn,
bool do_write); bool do_write);
#ifdef UNIV_LINUX
/**
Try and enable FusionIO atomic writes.
@param[in] file OS file handle
@return true if successful */
bool
fil_fusionio_enable_atomic_write(os_file_t file);
#endif /* UNIV_LINUX */
/** Note that the file system where the file resides doesn't support PUNCH HOLE /** Note that the file system where the file resides doesn't support PUNCH HOLE
@param[in,out] node Node to set */ @param[in,out] node Node to set */
void fil_no_punch_hole(fil_node_t* node); void fil_no_punch_hole(fil_node_t* node);

View File

@@ -62,7 +62,7 @@ Returns the atomic writes flag of the space, or false if the space
is not using atomic writes. The tablespace must be cached in the memory cache. is not using atomic writes. The tablespace must be cached in the memory cache.
@return atomic write table option value */ @return atomic write table option value */
UNIV_INLINE UNIV_INLINE
atomic_writes_t bool
fil_space_get_atomic_writes( fil_space_get_atomic_writes(
/*=========================*/ /*=========================*/
ulint id); /*!< in: space id */ ulint id); /*!< in: space id */

View File

@@ -65,7 +65,6 @@ public:
m_is_valid(), m_is_valid(),
m_first_page_buf(), m_first_page_buf(),
m_first_page(), m_first_page(),
m_atomic_write(),
m_last_os_error(), m_last_os_error(),
m_file_info(), m_file_info(),
m_encryption_key(NULL), m_encryption_key(NULL),
@@ -91,7 +90,6 @@ public:
m_is_valid(), m_is_valid(),
m_first_page_buf(), m_first_page_buf(),
m_first_page(), m_first_page(),
m_atomic_write(),
m_last_os_error(), m_last_os_error(),
m_file_info(), m_file_info(),
m_encryption_key(NULL), m_encryption_key(NULL),
@@ -115,7 +113,6 @@ public:
m_is_valid(file.m_is_valid), m_is_valid(file.m_is_valid),
m_first_page_buf(), m_first_page_buf(),
m_first_page(), m_first_page(),
m_atomic_write(file.m_atomic_write),
m_last_os_error(), m_last_os_error(),
m_file_info(), m_file_info(),
m_encryption_key(NULL), m_encryption_key(NULL),
@@ -183,8 +180,6 @@ public:
/* Do not copy crypt info it is read from first page */ /* Do not copy crypt info it is read from first page */
m_crypt_info = NULL; m_crypt_info = NULL;
m_atomic_write = file.m_atomic_write;
return(*this); return(*this);
} }
@@ -475,9 +470,6 @@ private:
/** Pointer to the first page held in the buffer above */ /** Pointer to the first page held in the buffer above */
byte* m_first_page; byte* m_first_page;
/** true if atomic writes enabled for this file */
bool m_atomic_write;
protected: protected:
/** Last OS error received so it can be reported if needed. */ /** Last OS error received so it can be reported if needed. */
ulint m_last_os_error; ulint m_last_os_error;

View File

@@ -708,7 +708,7 @@ fsp_flags_init(
bool is_temporary, bool is_temporary,
bool page_compression, bool page_compression,
ulint page_compression_level, ulint page_compression_level,
ulint atomic_writes, ulint not_used,
bool is_encrypted = false); bool is_encrypted = false);
/** Convert a 32 bit integer tablespace flags to the 32 bit table flags. /** Convert a 32 bit integer tablespace flags to the 32 bit table flags.

View File

@@ -184,7 +184,7 @@ fsp_flags_set_page_size(
@param[in] is_encrypted This tablespace is encrypted. @param[in] is_encrypted This tablespace is encrypted.
@param[in] page_compressed Table uses page compression @param[in] page_compressed Table uses page compression
@param[in] page_compression_level Page compression level @param[in] page_compression_level Page compression level
@param[in] atomic_writes Table uses atomic writes @param[in] not_used For future
@@return tablespace flags after initialization */ @@return tablespace flags after initialization */
UNIV_INLINE UNIV_INLINE
ulint ulint
@@ -196,7 +196,7 @@ fsp_flags_init(
bool is_temporary, bool is_temporary,
bool page_compression, bool page_compression,
ulint page_compression_level, ulint page_compression_level,
ulint atomic_writes, ulint not_used,
bool is_encrypted) bool is_encrypted)
{ {
ut_ad(page_size.physical() <= page_size.logical()); ut_ad(page_size.physical() <= page_size.logical());
@@ -247,12 +247,6 @@ fsp_flags_init(
flags |= FSP_FLAGS_SET_PAGE_COMPRESSION_LEVEL(flags, page_compression_level); flags |= FSP_FLAGS_SET_PAGE_COMPRESSION_LEVEL(flags, page_compression_level);
} }
/* In addition, tablespace flags also contain flag if atomic writes
is used for this table */
if (atomic_writes) {
flags |= FSP_FLAGS_SET_ATOMIC_WRITES(flags, atomic_writes);
}
ut_ad(fsp_flags_is_valid(flags)); ut_ad(fsp_flags_is_valid(flags));
return(flags); return(flags);

View File

@@ -68,15 +68,6 @@ fsp_flags_get_page_compression_level(
/*=================================*/ /*=================================*/
ulint flags); /*!< in: tablespace flags */ ulint flags); /*!< in: tablespace flags */
/********************************************************************//**
Determine the tablespace is using atomic writes from dict_table_t::flags.
@return true if atomic writes is used, false if not */
UNIV_INLINE
atomic_writes_t
fsp_flags_get_atomic_writes(
/*========================*/
ulint flags); /*!< in: tablespace flags */
#ifndef UNIV_NONINL #ifndef UNIV_NONINL
#include "fsp0pagecompress.ic" #include "fsp0pagecompress.ic"
#endif #endif

View File

@@ -49,17 +49,6 @@ fsp_flags_get_page_compression_level(
return(FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(flags)); return(FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(flags));
} }
/********************************************************************//**
Determine the tablespace is using atomic writes from dict_table_t::flags.
@return true if atomic writes is used, false if not */
UNIV_INLINE
atomic_writes_t
fsp_flags_get_atomic_writes(
/*========================*/
ulint flags) /*!< in: tablespace flags */
{
return((atomic_writes_t)FSP_FLAGS_GET_ATOMIC_WRITES(flags));
}
/*******************************************************************//** /*******************************************************************//**
Find out wheather the page is index page or not Find out wheather the page is index page or not
@@ -186,25 +175,28 @@ fil_get_compression_alg_name(
/*******************************************************************//** /*******************************************************************//**
Returns the atomic writes flag of the space, or false if the space Returns the atomic writes flag of the space, or false if the space
is not using atomic writes. The tablespace must be cached in the memory cache. is not using atomic writes. The tablespace must be cached in the memory cache.
@return atomic writes table option value */ @return 1 if atomic writes can be used for the file */
UNIV_INLINE UNIV_INLINE
atomic_writes_t bool
fil_space_get_atomic_writes( fil_space_get_atomic_writes(
/*========================*/ /*========================*/
ulint id) /*!< in: space id */ ulint id) /*!< in: space id */
{ {
ulint flags; struct fil_space_t* space;
bool ret= 0;
flags = fil_space_get_flags(id); ut_ad(fil_system);
if (flags && flags != ULINT_UNDEFINED) { mutex_enter(&fil_system->mutex);
return((atomic_writes_t)fsp_flags_get_atomic_writes(flags)); if ((space = fil_space_get_by_id(id)))
} ret= space->atomic_write_supported;
return((atomic_writes_t)0); mutex_exit(&fil_system->mutex);
return(ret);
} }
/*******************************************************************//** /*******************************************************************//**
Find out wheather the page is page compressed with lzo method Find out wheather the page is page compressed with lzo method
@return true if page is page compressed with lzo method, false if not */ @return true if page is page compressed with lzo method, false if not */

View File

@@ -79,13 +79,6 @@ Created 10/21/1995 Heikki Tuuri
bool innodb_calling_exit; bool innodb_calling_exit;
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
#if defined(UNIV_LINUX) && defined(HAVE_SYS_IOCTL_H)
# include <sys/ioctl.h>
# ifndef DFS_IOCTL_ATOMIC_WRITE_SET
# define DFS_IOCTL_ATOMIC_WRITE_SET _IOW(0x95, 2, uint)
# endif
#endif
#if defined(UNIV_LINUX) && defined(HAVE_SYS_STATVFS_H) #if defined(UNIV_LINUX) && defined(HAVE_SYS_STATVFS_H)
#include <sys/statvfs.h> #include <sys/statvfs.h>
#endif #endif
@@ -3310,26 +3303,6 @@ os_file_create_simple_func(
} }
#endif /* USE_FILE_LOCK */ #endif /* USE_FILE_LOCK */
/* If we have proper file handle and atomic writes should be used,
try to set atomic writes and if that fails when creating a new
table, produce a error. If atomic writes are used on existing
file, ignore error and use traditional writes for that file */
/* JAN: TODO: ATOMIC WRITES
if (file != -1
&& (awrites == ATOMIC_WRITES_ON ||
(srv_use_atomic_writes && awrites == ATOMIC_WRITES_DEFAULT))
&& !os_file_set_atomic_writes(name, file)) {
if (create_mode == OS_FILE_CREATE) {
fprintf(stderr, "InnoDB: Error: Can't create file using atomic writes\n");
close(file);
os_file_delete_if_exists_func(name);
*success = FALSE;
file = -1;
}
}
*/
return(file); return(file);
} }
@@ -3682,24 +3655,6 @@ os_file_create_func(
} }
#endif /* USE_FILE_LOCK */ #endif /* USE_FILE_LOCK */
/* If we have proper file handle and atomic writes should be used,
try to set atomic writes and if that fails when creating a new
table, produce a error. If atomic writes are used on existing
file, ignore error and use traditional writes for that file */
/* JAN: TODO: ATOMIC WRITES
if (file != -1 && type == OS_DATA_FILE
&& (awrites == ATOMIC_WRITES_ON ||
(srv_use_atomic_writes && awrites == ATOMIC_WRITES_DEFAULT))
&& !os_file_set_atomic_writes(name, file)) {
if (create_mode == OS_FILE_CREATE) {
fprintf(stderr, "InnoDB: Error: Can't create file using atomic writes\n");
close(file);
os_file_delete_if_exists_func(name);
*success = FALSE;
file = -1;
}
}
*/
return(file); return(file);
} }

View File

@@ -675,13 +675,6 @@ srv_undo_tablespace_open(
os_offset_t size; os_offset_t size;
fil_space_t* space; fil_space_t* space;
#ifdef UNIV_LINUX
const bool atomic_write = !srv_use_doublewrite_buf
&& fil_fusionio_enable_atomic_write(fh);
#else
const bool atomic_write = false;
#endif
size = os_file_get_size(fh); size = os_file_get_size(fh);
ut_a(size != (os_offset_t) -1); ut_a(size != (os_offset_t) -1);
@@ -699,7 +692,7 @@ srv_undo_tablespace_open(
/* Set the compressed page size to 0 (non-compressed) */ /* Set the compressed page size to 0 (non-compressed) */
flags = fsp_flags_init( flags = fsp_flags_init(
univ_page_size, false, false, false, false, false, 0, ATOMIC_WRITES_DEFAULT); univ_page_size, false, false, false, false, false, 0, 0);
space = fil_space_create( space = fil_space_create(
undo_name, space_id, flags, FIL_TYPE_TABLESPACE, NULL, true); undo_name, space_id, flags, FIL_TYPE_TABLESPACE, NULL, true);
@@ -713,7 +706,7 @@ srv_undo_tablespace_open(
the unit has been scaled to pages and page number is always the unit has been scaled to pages and page number is always
32 bits. */ 32 bits. */
if (fil_node_create( if (fil_node_create(
name, (ulint) n_pages, space, false, atomic_write)) { name, (ulint) n_pages, space, false, TRUE)) {
err = DB_SUCCESS; err = DB_SUCCESS;
} }

View File

@@ -8,9 +8,9 @@ then
echo client storage dbug libmysql sql-common \ echo client storage dbug libmysql sql-common \
sql extra mysys mysys_ssl strings regex pcre vio include \ sql extra mysys mysys_ssl strings regex pcre vio include \
tools unittest plugin libmysqld | \ tools unittest plugin libmysqld | \
xargs -n1 git ls-files | \ xargs -n1 git ls-files | grep -v '\.jar$' | \
xargs etags -o TAGS --append xargs etags -o TAGS --append
else else
find . -type f | find . -type f ! -name "*.jar" |
xargs etags -o TAGS --append xargs etags -o TAGS --append
fi fi