Commit cf1cf3a0 authored by tsmith@siva.hindu.god's avatar tsmith@siva.hindu.god

Applied innodb-5.1-ss1404 snapshot

Fixes:

- Bug #26662: mysqld assertion when creating temporary (InnoDB) table on a tmpfs filesystem
  Fix by not open(2)ing with O_DIRECT but rather calling fcntl(2) to set
  this flag immediately after open(2)ing. This way an error caused by
  O_DIRECT not being supported can easily be ignored.
- Bug #23313: AUTO_INCREMENT=# not reported back for InnoDB tables
- Bug #21404: AUTO_INCREMENT value reset when Adding FKEY (or ALTER?)
  Report the current value of the AUTO_INCREMENT counter to MySQL.
parent 9232def9
...@@ -3159,6 +3159,31 @@ t2 CREATE TABLE `t2` ( ...@@ -3159,6 +3159,31 @@ t2 CREATE TABLE `t2` (
CONSTRAINT `t2_t1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`) ON DELETE CASCADE ON UPDATE CASCADE CONSTRAINT `t2_t1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ) ENGINE=InnoDB DEFAULT CHARSET=latin1
DROP TABLE t2, t1; DROP TABLE t2, t1;
CREATE TABLE t1 (id int PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB
AUTO_INCREMENT=42;
INSERT INTO t1 VALUES (0),(347),(0);
SELECT * FROM t1;
id
42
347
348
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=349 DEFAULT CHARSET=latin1
CREATE TABLE t2 (id int PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t2 VALUES(42),(347),(348);
ALTER TABLE t1 ADD CONSTRAINT t1_t2 FOREIGN KEY (id) REFERENCES t2(id);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`),
CONSTRAINT `t1_t2` FOREIGN KEY (`id`) REFERENCES `t2` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=349 DEFAULT CHARSET=latin1
DROP TABLE t1,t2;
CREATE TABLE t1 (a INT, INDEX(a)) ENGINE=InnoDB; CREATE TABLE t1 (a INT, INDEX(a)) ENGINE=InnoDB;
CREATE TABLE t2 (a INT, INDEX(a)) ENGINE=InnoDB; CREATE TABLE t2 (a INT, INDEX(a)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (1);
......
...@@ -2320,6 +2320,26 @@ INSERT INTO t1 VALUES ('DDD'); ...@@ -2320,6 +2320,26 @@ INSERT INTO t1 VALUES ('DDD');
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
#
# Bug #23313 (AUTO_INCREMENT=# not reported back for InnoDB tables)
# Bug #21404 (AUTO_INCREMENT value reset when Adding FKEY (or ALTER?))
#
CREATE TABLE t1 (id int PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB
AUTO_INCREMENT=42;
INSERT INTO t1 VALUES (0),(347),(0);
SELECT * FROM t1;
SHOW CREATE TABLE t1;
CREATE TABLE t2 (id int PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t2 VALUES(42),(347),(348);
ALTER TABLE t1 ADD CONSTRAINT t1_t2 FOREIGN KEY (id) REFERENCES t2(id);
SHOW CREATE TABLE t1;
DROP TABLE t1,t2;
####################################################################### #######################################################################
# # # #
# Please, DO NOT TOUCH this file as well as the innodb.result file. # # Please, DO NOT TOUCH this file as well as the innodb.result file. #
......
...@@ -4769,6 +4769,20 @@ create_clustered_index_when_no_primary( ...@@ -4769,6 +4769,20 @@ create_clustered_index_when_no_primary(
return(error); return(error);
} }
/*********************************************************************
Update create_info. Used in SHOW CREATE TABLE et al. */
void
ha_innobase::update_create_info(
/*============================*/
HA_CREATE_INFO* create_info) /* in/out: create info */
{
if (!(create_info->used_fields & HA_CREATE_USED_AUTO)) {
ha_innobase::info(HA_STATUS_AUTO);
create_info->auto_increment_value = stats.auto_increment_value;
}
}
/********************************************************************* /*********************************************************************
Creates a new table to an InnoDB database. */ Creates a new table to an InnoDB database. */
......
...@@ -150,6 +150,7 @@ class ha_innobase: public handler ...@@ -150,6 +150,7 @@ class ha_innobase: public handler
*max_key); *max_key);
ha_rows estimate_rows_upper_bound(); ha_rows estimate_rows_upper_bound();
void update_create_info(HA_CREATE_INFO* create_info);
int create(const char *name, register TABLE *form, int create(const char *name, register TABLE *form,
HA_CREATE_INFO *create_info); HA_CREATE_INFO *create_info);
int delete_all_rows(); int delete_all_rows();
......
...@@ -318,7 +318,7 @@ os_file_get_last_error( ...@@ -318,7 +318,7 @@ os_file_get_last_error(
fflush(stderr); fflush(stderr);
if (err == ENOSPC ) { if (err == ENOSPC) {
return(OS_FILE_DISK_FULL); return(OS_FILE_DISK_FULL);
#ifdef POSIX_ASYNC_IO #ifdef POSIX_ASYNC_IO
} else if (err == EAGAIN) { } else if (err == EAGAIN) {
...@@ -337,15 +337,20 @@ os_file_get_last_error( ...@@ -337,15 +337,20 @@ os_file_get_last_error(
} }
/******************************************************************** /********************************************************************
Does error handling when a file operation fails. */ Does error handling when a file operation fails.
Conditionally exits (calling exit(3)) based on should_exit value and the
error type */
static static
ibool ibool
os_file_handle_error( os_file_handle_error_cond_exit(
/*=================*/ /*===========================*/
/* out: TRUE if we should retry the /* out: TRUE if we should retry the
operation */ operation */
const char* name, /* in: name of a file or NULL */ const char* name, /* in: name of a file or NULL */
const char* operation)/* in: operation */ const char* operation, /* in: operation */
ibool should_exit) /* in: call exit(3) if unknown error
and this parameter is TRUE */
{ {
ulint err; ulint err;
...@@ -376,11 +381,9 @@ os_file_handle_error( ...@@ -376,11 +381,9 @@ os_file_handle_error(
fflush(stderr); fflush(stderr);
return(FALSE); return(FALSE);
} else if (err == OS_FILE_AIO_RESOURCES_RESERVED) { } else if (err == OS_FILE_AIO_RESOURCES_RESERVED) {
return(TRUE); return(TRUE);
} else if (err == OS_FILE_ALREADY_EXISTS } else if (err == OS_FILE_ALREADY_EXISTS
|| err == OS_FILE_PATH_ERROR) { || err == OS_FILE_PATH_ERROR) {
...@@ -392,16 +395,49 @@ os_file_handle_error( ...@@ -392,16 +395,49 @@ os_file_handle_error(
fprintf(stderr, "InnoDB: File operation call: '%s'.\n", fprintf(stderr, "InnoDB: File operation call: '%s'.\n",
operation); operation);
if (should_exit) {
fprintf(stderr, "InnoDB: Cannot continue operation.\n"); fprintf(stderr, "InnoDB: Cannot continue operation.\n");
fflush(stderr); fflush(stderr);
exit(1); exit(1);
} }
}
return(FALSE); return(FALSE);
} }
/********************************************************************
Does error handling when a file operation fails. */
static
ibool
os_file_handle_error(
/*=================*/
/* out: TRUE if we should retry the
operation */
const char* name, /* in: name of a file or NULL */
const char* operation)/* in: operation */
{
/* exit in case of unknown error */
return(os_file_handle_error_cond_exit(name, operation, TRUE));
}
/********************************************************************
Does error handling when a file operation fails. */
static
ibool
os_file_handle_error_no_exit(
/*=========================*/
/* out: TRUE if we should retry the
operation */
const char* name, /* in: name of a file or NULL */
const char* operation)/* in: operation */
{
/* don't exit in case of unknown error */
return(os_file_handle_error_cond_exit(name, operation, FALSE));
}
#undef USE_FILE_LOCK #undef USE_FILE_LOCK
#define USE_FILE_LOCK #define USE_FILE_LOCK
#if defined(UNIV_HOTBACKUP) || defined(__WIN__) || defined(__FreeBSD__) || defined(__NETWARE__) #if defined(UNIV_HOTBACKUP) || defined(__WIN__) || defined(__FreeBSD__) || defined(__NETWARE__)
...@@ -445,68 +481,6 @@ os_file_lock( ...@@ -445,68 +481,6 @@ os_file_lock(
} }
#endif /* USE_FILE_LOCK */ #endif /* USE_FILE_LOCK */
/********************************************************************
Does error handling when a file operation fails. */
static
ibool
os_file_handle_error_no_exit(
/*=========================*/
/* out: TRUE if we should retry the
operation */
const char* name, /* in: name of a file or NULL */
const char* operation)/* in: operation */
{
ulint err;
err = os_file_get_last_error(FALSE);
if (err == OS_FILE_DISK_FULL) {
/* We only print a warning about disk full once */
if (os_has_said_disk_full) {
return(FALSE);
}
if (name) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Encountered a problem with"
" file %s\n", name);
}
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Disk is full. Try to clean the disk"
" to free space.\n");
os_has_said_disk_full = TRUE;
fflush(stderr);
return(FALSE);
} else if (err == OS_FILE_AIO_RESOURCES_RESERVED) {
return(TRUE);
} else if (err == OS_FILE_ALREADY_EXISTS
|| err == OS_FILE_PATH_ERROR) {
return(FALSE);
} else {
if (name) {
fprintf(stderr, "InnoDB: File name %s\n", name);
}
fprintf(stderr, "InnoDB: File operation call: '%s'.\n",
operation);
return (FALSE);
}
return(FALSE); /* not reached */
}
/******************************************************************** /********************************************************************
Creates the seek mutexes used in positioned reads and writes. */ Creates the seek mutexes used in positioned reads and writes. */
...@@ -1124,6 +1098,51 @@ os_file_create_simple_no_error_handling( ...@@ -1124,6 +1098,51 @@ os_file_create_simple_no_error_handling(
#endif /* __WIN__ */ #endif /* __WIN__ */
} }
/********************************************************************
Tries to disable OS caching on an opened file descriptor. */
void
os_file_set_nocache(
/*================*/
int fd, /* in: file descriptor to alter */
const char* file_name, /* in: used in the diagnostic message */
const char* operation_name) /* in: used in the diagnostic message,
we call os_file_set_nocache()
immediately after opening or creating
a file, so this is either "open" or
"create" */
{
/* some versions of Solaris may not have DIRECTIO_ON */
#if defined(UNIV_SOLARIS) && defined(DIRECTIO_ON)
if (directio(fd, DIRECTIO_ON) == -1) {
int errno_save;
errno_save = (int)errno;
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Failed to set DIRECTIO_ON "
"on file %s: %s: %s, continuing anyway\n",
file_name, operation_name, strerror(errno_save));
}
#elif defined(O_DIRECT)
if (fcntl(fd, F_SETFL, O_DIRECT) == -1) {
int errno_save;
errno_save = (int)errno;
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Failed to set O_DIRECT "
"on file %s: %s: %s, continuing anyway\n",
file_name, operation_name, strerror(errno_save));
if (errno_save == EINVAL) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: O_DIRECT is known to result in "
"'Invalid argument' on Linux on tmpfs, "
"see MySQL Bug#26662\n");
}
}
#endif
}
/******************************************************************** /********************************************************************
Opens an existing file or creates a new. */ Opens an existing file or creates a new. */
...@@ -1306,21 +1325,8 @@ try_again: ...@@ -1306,21 +1325,8 @@ try_again:
create_flag = create_flag | O_SYNC; create_flag = create_flag | O_SYNC;
} }
#endif /* O_SYNC */ #endif /* O_SYNC */
#ifdef O_DIRECT
/* We let O_DIRECT only affect data files */
if (type != OS_LOG_FILE
&& srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) {
# if 0
fprintf(stderr, "Using O_DIRECT for file %s\n", name);
# endif
create_flag = create_flag | O_DIRECT;
}
#endif /* O_DIRECT */
if (create_mode == OS_FILE_CREATE) {
file = open(name, create_flag, os_innodb_umask); file = open(name, create_flag, os_innodb_umask);
} else {
file = open(name, create_flag);
}
if (file == -1) { if (file == -1) {
*success = FALSE; *success = FALSE;
...@@ -1330,11 +1336,24 @@ try_again: ...@@ -1330,11 +1336,24 @@ try_again:
"create" : "open"); "create" : "open");
if (retry) { if (retry) {
goto try_again; goto try_again;
} else {
return(file /* -1 */);
}
} }
/* else */
*success = TRUE;
/* We disable OS caching (O_DIRECT) only on data files */
if (type != OS_LOG_FILE
&& srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) {
os_file_set_nocache(file, name, mode_str);
}
#ifdef USE_FILE_LOCK #ifdef USE_FILE_LOCK
} else if (create_mode != OS_FILE_OPEN_RAW if (create_mode != OS_FILE_OPEN_RAW && os_file_lock(file, name)) {
&& os_file_lock(file, name)) {
*success = FALSE;
if (create_mode == OS_FILE_OPEN_RETRY) { if (create_mode == OS_FILE_OPEN_RETRY) {
int i; int i;
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
...@@ -1352,12 +1371,12 @@ try_again: ...@@ -1352,12 +1371,12 @@ try_again:
fputs(" InnoDB: Unable to open the first data file\n", fputs(" InnoDB: Unable to open the first data file\n",
stderr); stderr);
} }
*success = FALSE;
close(file); close(file);
file = -1; file = -1;
#endif
} else {
*success = TRUE;
} }
#endif /* USE_FILE_LOCK */
return(file); return(file);
#endif /* __WIN__ */ #endif /* __WIN__ */
......
...@@ -30,6 +30,8 @@ MYSQL_PLUGIN_ACTIONS(innobase, [ ...@@ -30,6 +30,8 @@ MYSQL_PLUGIN_ACTIONS(innobase, [
CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";; CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";;
osf*) osf*)
CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";; CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";;
*solaris*|*SunOS*)
CFLAGS="$CFLAGS -DUNIV_SOLARIS";;
sysv5uw7*) sysv5uw7*)
# Problem when linking on SCO # Problem when linking on SCO
CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";; CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment