summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <monty@mariadb.org>2017-06-30 17:56:58 +0300
committerMonty <monty@mariadb.org>2017-06-30 22:31:37 +0300
commitdd8474b1dc556d0ea9491d1908a2d1237818e8c1 (patch)
tree9ab8535fbac53bf3a644482a41c59eaca1371754
parent9f484b63f1b61e6ade1481cfb8465f8fe208386d (diff)
downloadmariadb-git-dd8474b1dc556d0ea9491d1908a2d1237818e8c1.tar.gz
Added tmp_disk_table_size to limit size of Aria temp tables in tmpdir
- Added variable tmp_disk_table_size - Added variable tmp_memory_table_size as an alias for tmp_table_size - Changed internal variable tmp_table_size to tmp_memory_table_size - create_info.data_file_length is now set with tmp_disk_table_size - Fixed that Aria doesn't reset max_data_file_length for internal tables - Added status flag if table is full so that we can detect this on next insert. This ensures that the table is always 'correct', but we get the error one row after the row that grow the table too big. - Removed some mutex lock for internal temporary tables
-rw-r--r--mysql-test/r/mysqld--help.result14
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result30
-rw-r--r--mysql-test/suite/sys_vars/r/tmp_disk_table_size_basic.result146
-rw-r--r--mysql-test/suite/sys_vars/r/tmp_disk_table_size_func.result25
-rw-r--r--mysql-test/suite/sys_vars/r/tmp_memory_table_size_basic.result165
-rw-r--r--mysql-test/suite/sys_vars/t/tmp_disk_table_size_basic.test207
-rw-r--r--mysql-test/suite/sys_vars/t/tmp_disk_table_size_func.test26
-rw-r--r--mysql-test/suite/sys_vars/t/tmp_memory_table_size_basic.test209
-rw-r--r--sql/item_sum.cc4
-rw-r--r--sql/opt_subselect.cc8
-rw-r--r--sql/sql_class.h3
-rw-r--r--sql/sql_select.cc19
-rw-r--r--sql/sys_vars.cc22
-rw-r--r--storage/maria/ma_create.c10
-rw-r--r--storage/maria/ma_open.c10
-rw-r--r--storage/maria/ma_state.c11
-rw-r--r--storage/maria/ma_write.c7
-rw-r--r--storage/maria/maria_def.h1
18 files changed, 882 insertions, 35 deletions
diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result
index 24827da53be..bc4c96ed26f 100644
--- a/mysql-test/r/mysqld--help.result
+++ b/mysql-test/r/mysqld--help.result
@@ -1146,9 +1146,17 @@ The following options may be given as the first argument:
--time-format=name The TIME format (ignored)
--timed-mutexes Specify whether to time mutexes. Deprecated, has no
effect.
- --tmp-table-size=# If an internal in-memory temporary table exceeds this
+ --tmp-disk-table-size=#
+ Max size for data for an internal temporary on-disk
+ MyISAM or Aria table.
+ --tmp-memory-table-size=#
+ If an internal in-memory temporary table exceeds this
size, MySQL will automatically convert it to an on-disk
- MyISAM or Aria table
+ MyISAM or Aria table. Same as tmp_table_size.
+ --tmp-table-size=# Alias for tmp_memory_table_size. If an internal in-memory
+ temporary table exceeds this size, MySQL will
+ automatically convert it to an on-disk MyISAM or Aria
+ table.
-t, --tmpdir=name Path for temporary files. Several paths may be specified,
separated by a colon (:), in this case they are used in a
round-robin fashion
@@ -1499,6 +1507,8 @@ thread-pool-stall-limit 500
thread-stack 299008
time-format %H:%i:%s
timed-mutexes FALSE
+tmp-disk-table-size 18446744073709551615
+tmp-memory-table-size 16777216
tmp-table-size 16777216
transaction-alloc-block-size 8192
transaction-isolation REPEATABLE-READ
diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
index 8b062075db8..6e36a67b96a 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
@@ -4951,6 +4951,34 @@ NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST NULL
READ_ONLY YES
COMMAND_LINE_ARGUMENT REQUIRED
+VARIABLE_NAME TMP_DISK_TABLE_SIZE
+SESSION_VALUE 18446744073709551615
+GLOBAL_VALUE 18446744073709551615
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE 18446744073709551615
+VARIABLE_SCOPE SESSION
+VARIABLE_TYPE BIGINT UNSIGNED
+VARIABLE_COMMENT Max size for data for an internal temporary on-disk MyISAM or Aria table.
+NUMERIC_MIN_VALUE 1024
+NUMERIC_MAX_VALUE 18446744073709551615
+NUMERIC_BLOCK_SIZE 1
+ENUM_VALUE_LIST NULL
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT REQUIRED
+VARIABLE_NAME TMP_MEMORY_TABLE_SIZE
+SESSION_VALUE 16777216
+GLOBAL_VALUE 16777216
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE 16777216
+VARIABLE_SCOPE SESSION
+VARIABLE_TYPE BIGINT UNSIGNED
+VARIABLE_COMMENT If an internal in-memory temporary table exceeds this size, MySQL will automatically convert it to an on-disk MyISAM or Aria table. Same as tmp_table_size.
+NUMERIC_MIN_VALUE 1024
+NUMERIC_MAX_VALUE 18446744073709551615
+NUMERIC_BLOCK_SIZE 1
+ENUM_VALUE_LIST NULL
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME TMP_TABLE_SIZE
SESSION_VALUE 16777216
GLOBAL_VALUE 16777216
@@ -4958,7 +4986,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 16777216
VARIABLE_SCOPE SESSION
VARIABLE_TYPE BIGINT UNSIGNED
-VARIABLE_COMMENT If an internal in-memory temporary table exceeds this size, MySQL will automatically convert it to an on-disk MyISAM or Aria table
+VARIABLE_COMMENT Alias for tmp_memory_table_size. If an internal in-memory temporary table exceeds this size, MySQL will automatically convert it to an on-disk MyISAM or Aria table.
NUMERIC_MIN_VALUE 1024
NUMERIC_MAX_VALUE 18446744073709551615
NUMERIC_BLOCK_SIZE 1
diff --git a/mysql-test/suite/sys_vars/r/tmp_disk_table_size_basic.result b/mysql-test/suite/sys_vars/r/tmp_disk_table_size_basic.result
new file mode 100644
index 00000000000..0acf8428100
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/tmp_disk_table_size_basic.result
@@ -0,0 +1,146 @@
+SET @start_global_value = @@global.tmp_disk_table_size;
+SET @start_session_value = @@session.tmp_disk_table_size;
+'#--------------------FN_DYNVARS_005_01-------------------------#'
+SET @@global.tmp_disk_table_size = 100;
+Warnings:
+Warning 1292 Truncated incorrect tmp_disk_table_size value: '100'
+SET @@global.tmp_disk_table_size = DEFAULT;
+SET @@session.tmp_disk_table_size = 200;
+Warnings:
+Warning 1292 Truncated incorrect tmp_disk_table_size value: '200'
+SET @@session.tmp_disk_table_size = DEFAULT;
+'#--------------------FN_DYNVARS_005_02-------------------------#'
+SELECT @@global.tmp_disk_table_size >= 16777216;
+@@global.tmp_disk_table_size >= 16777216
+1
+SELECT @@session.tmp_disk_table_size >= 16777216;
+@@session.tmp_disk_table_size >= 16777216
+1
+'#--------------------FN_DYNVARS_005_03-------------------------#'
+SET @@global.tmp_disk_table_size = 1024;
+SELECT @@global.tmp_disk_table_size;
+@@global.tmp_disk_table_size
+1024
+SET @@global.tmp_disk_table_size = 60020;
+SELECT @@global.tmp_disk_table_size;
+@@global.tmp_disk_table_size
+60020
+SET @@global.tmp_disk_table_size = 4294967295;
+SELECT @@global.tmp_disk_table_size;
+@@global.tmp_disk_table_size
+4294967295
+'#--------------------FN_DYNVARS_005_04-------------------------#'
+SET @@session.tmp_disk_table_size = 1024;
+SELECT @@session.tmp_disk_table_size;
+@@session.tmp_disk_table_size
+1024
+SET @@session.tmp_disk_table_size = 4294967295;
+SELECT @@session.tmp_disk_table_size;
+@@session.tmp_disk_table_size
+4294967295
+SET @@session.tmp_disk_table_size = 65535;
+SELECT @@session.tmp_disk_table_size;
+@@session.tmp_disk_table_size
+65535
+'#------------------FN_DYNVARS_005_05-----------------------#'
+SET @@global.tmp_disk_table_size = 0;
+Warnings:
+Warning 1292 Truncated incorrect tmp_disk_table_size value: '0'
+SELECT @@global.tmp_disk_table_size;
+@@global.tmp_disk_table_size
+1024
+SET @@global.tmp_disk_table_size = -1024;
+Warnings:
+Warning 1292 Truncated incorrect tmp_disk_table_size value: '-1024'
+SELECT @@global.tmp_disk_table_size;
+@@global.tmp_disk_table_size
+1024
+SET @@global.tmp_disk_table_size = 1000;
+Warnings:
+Warning 1292 Truncated incorrect tmp_disk_table_size value: '1000'
+SELECT @@global.tmp_disk_table_size;
+@@global.tmp_disk_table_size
+1024
+SET @@global.tmp_disk_table_size = ON;
+ERROR 42000: Incorrect argument type to variable 'tmp_disk_table_size'
+SET @@global.tmp_disk_table_size = OFF;
+ERROR 42000: Incorrect argument type to variable 'tmp_disk_table_size'
+SET @@global.tmp_disk_table_size = True;
+Warnings:
+Warning 1292 Truncated incorrect tmp_disk_table_size value: '1'
+SELECT @@global.tmp_disk_table_size;
+@@global.tmp_disk_table_size
+1024
+SET @@global.tmp_disk_table_size = False;
+Warnings:
+Warning 1292 Truncated incorrect tmp_disk_table_size value: '0'
+SELECT @@global.tmp_disk_table_size;
+@@global.tmp_disk_table_size
+1024
+SET @@global.tmp_disk_table_size = 65530.34;
+ERROR 42000: Incorrect argument type to variable 'tmp_disk_table_size'
+SET @@global.tmp_disk_table_size ="Test";
+ERROR 42000: Incorrect argument type to variable 'tmp_disk_table_size'
+SET @@session.tmp_disk_table_size = ON;
+ERROR 42000: Incorrect argument type to variable 'tmp_disk_table_size'
+SET @@session.tmp_disk_table_size = OFF;
+ERROR 42000: Incorrect argument type to variable 'tmp_disk_table_size'
+SET @@session.tmp_disk_table_size = True;
+Warnings:
+Warning 1292 Truncated incorrect tmp_disk_table_size value: '1'
+SELECT @@session.tmp_disk_table_size;
+@@session.tmp_disk_table_size
+1024
+SET @@session.tmp_disk_table_size = False;
+Warnings:
+Warning 1292 Truncated incorrect tmp_disk_table_size value: '0'
+SELECT @@session.tmp_disk_table_size;
+@@session.tmp_disk_table_size
+1024
+SET @@session.tmp_disk_table_size = "Test";
+ERROR 42000: Incorrect argument type to variable 'tmp_disk_table_size'
+SET @@session.tmp_disk_table_size = 12345678901;
+SELECT @@session.tmp_disk_table_size IN (12345678901,4294967295);
+@@session.tmp_disk_table_size IN (12345678901,4294967295)
+1
+'#------------------FN_DYNVARS_005_06-----------------------#'
+SELECT @@global.tmp_disk_table_size = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='tmp_disk_table_size';
+@@global.tmp_disk_table_size = VARIABLE_VALUE
+1
+'#------------------FN_DYNVARS_005_07-----------------------#'
+SELECT @@session.tmp_disk_table_size = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.SESSION_VARIABLES
+WHERE VARIABLE_NAME='tmp_disk_table_size';
+@@session.tmp_disk_table_size = VARIABLE_VALUE
+1
+'#---------------------FN_DYNVARS_001_09----------------------#'
+SET @@global.tmp_disk_table_size = 1024;
+SET @@tmp_disk_table_size = 4294967295;
+SELECT @@tmp_disk_table_size = @@global.tmp_disk_table_size;
+@@tmp_disk_table_size = @@global.tmp_disk_table_size
+0
+'#---------------------FN_DYNVARS_001_10----------------------#'
+SET @@tmp_disk_table_size = 100;
+Warnings:
+Warning 1292 Truncated incorrect tmp_disk_table_size value: '100'
+SELECT @@tmp_disk_table_size = @@local.tmp_disk_table_size;
+@@tmp_disk_table_size = @@local.tmp_disk_table_size
+1
+SELECT @@local.tmp_disk_table_size = @@session.tmp_disk_table_size;
+@@local.tmp_disk_table_size = @@session.tmp_disk_table_size
+1
+'#---------------------FN_DYNVARS_001_11----------------------#'
+SET tmp_disk_table_size = 1027;
+SELECT @@tmp_disk_table_size;
+@@tmp_disk_table_size
+1027
+SELECT local.tmp_disk_table_size;
+ERROR 42S02: Unknown table 'local' in field list
+SELECT global.tmp_disk_table_size;
+ERROR 42S02: Unknown table 'global' in field list
+SELECT tmp_disk_table_size = @@session.tmp_disk_table_size;
+ERROR 42S22: Unknown column 'tmp_disk_table_size' in 'field list'
+SET @@global.tmp_disk_table_size = @start_global_value;
+SET @@session.tmp_disk_table_size = @start_session_value;
diff --git a/mysql-test/suite/sys_vars/r/tmp_disk_table_size_func.result b/mysql-test/suite/sys_vars/r/tmp_disk_table_size_func.result
new file mode 100644
index 00000000000..d2a5ad46129
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/tmp_disk_table_size_func.result
@@ -0,0 +1,25 @@
+
+"Ensure that we get an error if we exceed tmp_disk_table_size"
+
+SET @start_tmp_memory_table_size=@@session.tmp_memory_table_size;
+SET @start_tmp_disk_table_size=@@session.tmp_disk_table_size;
+set @@session.tmp_memory_table_size=1000;
+Warnings:
+Warning 1292 Truncated incorrect tmp_memory_table_size value: '1000'
+set @@session.tmp_disk_table_size=3000000;
+create table t1 (a int primary key, b varchar(2000));
+insert into t1 select seq,repeat(char(mod(seq,62)+64),seq) from seq_1_to_2000;
+insert into t1 values (20000,"A");
+select count(*) as c from t1 group by b having c>1;
+c
+2
+show status like "created_tmp_disk%";
+Variable_name Value
+Created_tmp_disk_tables 1
+set @@session.tmp_disk_table_size=1000000;
+select count(*) as c from t1 group by b having c>1;
+ERROR HY000: The table '#sql_xxx' is full
+show status like "created_tmp_disk%";
+Variable_name Value
+Created_tmp_disk_tables 2
+drop table t1;
diff --git a/mysql-test/suite/sys_vars/r/tmp_memory_table_size_basic.result b/mysql-test/suite/sys_vars/r/tmp_memory_table_size_basic.result
new file mode 100644
index 00000000000..dddba1a6dfe
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/tmp_memory_table_size_basic.result
@@ -0,0 +1,165 @@
+SET @start_global_value = @@global.tmp_memory_table_size;
+SET @start_session_value = @@session.tmp_memory_table_size;
+'#--------------------FN_DYNVARS_005_01-------------------------#'
+SET @@global.tmp_memory_table_size = 10000;
+SELECT @@global.tmp_memory_table_size;
+@@global.tmp_memory_table_size
+10000
+SET @@global.tmp_memory_table_size = DEFAULT;
+SELECT @@global.tmp_memory_table_size;
+@@global.tmp_memory_table_size
+16777216
+SET @@session.tmp_memory_table_size = 20000;
+SELECT @@session.tmp_memory_table_size;
+@@session.tmp_memory_table_size
+20000
+SET @@session.tmp_memory_table_size = DEFAULT;
+SELECT @@session.tmp_memory_table_size;
+@@session.tmp_memory_table_size
+16777216
+'#--------------------FN_DYNVARS_005_02-------------------------#'
+SELECT @@global.tmp_memory_table_size >= 16777216;
+@@global.tmp_memory_table_size >= 16777216
+1
+SELECT @@session.tmp_memory_table_size >= 16777216;
+@@session.tmp_memory_table_size >= 16777216
+1
+'#--------------------FN_DYNVARS_005_03-------------------------#'
+SET @@global.tmp_memory_table_size = 1024;
+SELECT @@global.tmp_memory_table_size;
+@@global.tmp_memory_table_size
+1024
+SET @@global.tmp_memory_table_size = 60020;
+SELECT @@global.tmp_memory_table_size;
+@@global.tmp_memory_table_size
+60020
+SET @@global.tmp_memory_table_size = 4294967295;
+SELECT @@global.tmp_memory_table_size;
+@@global.tmp_memory_table_size
+4294967295
+'#--------------------FN_DYNVARS_005_04-------------------------#'
+SET @@session.tmp_memory_table_size = 1024;
+SELECT @@session.tmp_memory_table_size;
+@@session.tmp_memory_table_size
+1024
+SET @@session.tmp_memory_table_size = 4294967295;
+SELECT @@session.tmp_memory_table_size;
+@@session.tmp_memory_table_size
+4294967295
+SET @@session.tmp_memory_table_size = 65535;
+SELECT @@session.tmp_memory_table_size;
+@@session.tmp_memory_table_size
+65535
+'#------------------FN_DYNVARS_005_05-----------------------#'
+SET @@global.tmp_memory_table_size = 0;
+Warnings:
+Warning 1292 Truncated incorrect tmp_memory_table_size value: '0'
+SELECT @@global.tmp_memory_table_size;
+@@global.tmp_memory_table_size
+1024
+SET @@global.tmp_memory_table_size = -1024;
+Warnings:
+Warning 1292 Truncated incorrect tmp_memory_table_size value: '-1024'
+SELECT @@global.tmp_memory_table_size;
+@@global.tmp_memory_table_size
+1024
+SET @@global.tmp_memory_table_size = 1000;
+Warnings:
+Warning 1292 Truncated incorrect tmp_memory_table_size value: '1000'
+SELECT @@global.tmp_memory_table_size;
+@@global.tmp_memory_table_size
+1024
+SET @@global.tmp_memory_table_size = ON;
+ERROR 42000: Incorrect argument type to variable 'tmp_memory_table_size'
+SET @@global.tmp_memory_table_size = OFF;
+ERROR 42000: Incorrect argument type to variable 'tmp_memory_table_size'
+SET @@global.tmp_memory_table_size = True;
+Warnings:
+Warning 1292 Truncated incorrect tmp_memory_table_size value: '1'
+SELECT @@global.tmp_memory_table_size;
+@@global.tmp_memory_table_size
+1024
+SET @@global.tmp_memory_table_size = False;
+Warnings:
+Warning 1292 Truncated incorrect tmp_memory_table_size value: '0'
+SELECT @@global.tmp_memory_table_size;
+@@global.tmp_memory_table_size
+1024
+SET @@global.tmp_memory_table_size = 65530.34;
+ERROR 42000: Incorrect argument type to variable 'tmp_memory_table_size'
+SET @@global.tmp_memory_table_size ="Test";
+ERROR 42000: Incorrect argument type to variable 'tmp_memory_table_size'
+SET @@session.tmp_memory_table_size = ON;
+ERROR 42000: Incorrect argument type to variable 'tmp_memory_table_size'
+SET @@session.tmp_memory_table_size = OFF;
+ERROR 42000: Incorrect argument type to variable 'tmp_memory_table_size'
+SET @@session.tmp_memory_table_size = True;
+Warnings:
+Warning 1292 Truncated incorrect tmp_memory_table_size value: '1'
+SELECT @@session.tmp_memory_table_size;
+@@session.tmp_memory_table_size
+1024
+SET @@session.tmp_memory_table_size = False;
+Warnings:
+Warning 1292 Truncated incorrect tmp_memory_table_size value: '0'
+SELECT @@session.tmp_memory_table_size;
+@@session.tmp_memory_table_size
+1024
+SET @@session.tmp_memory_table_size = "Test";
+ERROR 42000: Incorrect argument type to variable 'tmp_memory_table_size'
+SET @@session.tmp_memory_table_size = 12345678901;
+SELECT @@session.tmp_memory_table_size IN (12345678901,4294967295);
+@@session.tmp_memory_table_size IN (12345678901,4294967295)
+1
+'#------------------FN_DYNVARS_005_06-----------------------#'
+SELECT @@global.tmp_memory_table_size = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='tmp_memory_table_size';
+@@global.tmp_memory_table_size = VARIABLE_VALUE
+1
+'#------------------FN_DYNVARS_005_07-----------------------#'
+SELECT @@session.tmp_memory_table_size = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.SESSION_VARIABLES
+WHERE VARIABLE_NAME='tmp_memory_table_size';
+@@session.tmp_memory_table_size = VARIABLE_VALUE
+1
+'#---------------------FN_DYNVARS_001_09----------------------#'
+SET @@global.tmp_memory_table_size = 1024;
+SET @@tmp_memory_table_size = 4294967295;
+SELECT @@tmp_memory_table_size = @@global.tmp_memory_table_size;
+@@tmp_memory_table_size = @@global.tmp_memory_table_size
+0
+'#---------------------FN_DYNVARS_001_10----------------------#'
+SET @@tmp_memory_table_size = 100;
+Warnings:
+Warning 1292 Truncated incorrect tmp_memory_table_size value: '100'
+SELECT @@tmp_memory_table_size = @@local.tmp_memory_table_size;
+@@tmp_memory_table_size = @@local.tmp_memory_table_size
+1
+SELECT @@local.tmp_memory_table_size = @@session.tmp_memory_table_size;
+@@local.tmp_memory_table_size = @@session.tmp_memory_table_size
+1
+'#---------------------FN_DYNVARS_001_11----------------------#'
+SET tmp_memory_table_size = 1027;
+SELECT @@tmp_memory_table_size;
+@@tmp_memory_table_size
+1027
+SELECT local.tmp_memory_table_size;
+ERROR 42S02: Unknown table 'local' in field list
+SELECT global.tmp_memory_table_size;
+ERROR 42S02: Unknown table 'global' in field list
+SELECT tmp_memory_table_size = @@session.tmp_memory_table_size;
+ERROR 42S22: Unknown column 'tmp_memory_table_size' in 'field list'
+
+"Check that tmp_memory_table_size and tmp_table_size are the same"
+
+set @@session.tmp_memory_table_size=100000;
+select @@session.tmp_memory_table_size,@@session.tmp_table_size;
+@@session.tmp_memory_table_size @@session.tmp_table_size
+100000 100000
+set @@session.tmp_memory_table_size=200000;
+select @@session.tmp_memory_table_size,@@session.tmp_table_size;
+@@session.tmp_memory_table_size @@session.tmp_table_size
+200000 200000
+SET @@global.tmp_memory_table_size = @start_global_value;
+SET @@session.tmp_memory_table_size = @start_session_value;
diff --git a/mysql-test/suite/sys_vars/t/tmp_disk_table_size_basic.test b/mysql-test/suite/sys_vars/t/tmp_disk_table_size_basic.test
new file mode 100644
index 00000000000..123f522a3a4
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/tmp_disk_table_size_basic.test
@@ -0,0 +1,207 @@
+###################### tmp_disk_table_size_basic.test ######################
+# #
+# Variable Name: tmp_disk_table_size #
+# Scope: GLOBAL | SESSION #
+# Access Type: Dynamic #
+# Data Type: numeric #
+# Default Value: system dependend #
+# Range: 1024-system dependend #
+# #
+# #
+# Creation Date: 2008-02-13 #
+# Author: Salman #
+# #
+# Description: Test Cases of Dynamic System Variable tmp_table_size #
+# that checks the behavior of this variable in the following ways#
+# * Default Value #
+# * Valid & Invalid values #
+# * Scope & Access method #
+# * Data Integrity #
+# Modified: 2008-12-04 HHunger #
+# removed the differences between 64 and 32 bit platforms #
+# #
+# Reference: #
+# http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html #
+# #
+###############################################################################
+
+--source include/load_sysvars.inc
+
+##############################################################
+# START OF tmp_disk_table_size TESTS #
+##############################################################
+
+#############################################################
+# Save initial value #
+#############################################################
+
+SET @start_global_value = @@global.tmp_disk_table_size;
+SET @start_session_value = @@session.tmp_disk_table_size;
+
+--echo '#--------------------FN_DYNVARS_005_01-------------------------#'
+##############################################################
+# Display the DEFAULT value of tmp_disk_table_size #
+##############################################################
+
+SET @@global.tmp_disk_table_size = 100;
+SET @@global.tmp_disk_table_size = DEFAULT;
+
+SET @@session.tmp_disk_table_size = 200;
+SET @@session.tmp_disk_table_size = DEFAULT;
+
+--echo '#--------------------FN_DYNVARS_005_02-------------------------#'
+########################################################################
+# Check the DEFAULT value of tmp_disk_table_size #
+########################################################################
+# The DEFAULT value is system dependend.
+# Therefore we have only a plausibility check here
+SELECT @@global.tmp_disk_table_size >= 16777216;
+SELECT @@session.tmp_disk_table_size >= 16777216;
+
+--echo '#--------------------FN_DYNVARS_005_03-------------------------#'
+########################################################################
+# Change the value of tmp_disk_table_size to a valid value for GLOBAL Scope #
+########################################################################
+
+SET @@global.tmp_disk_table_size = 1024;
+SELECT @@global.tmp_disk_table_size;
+SET @@global.tmp_disk_table_size = 60020;
+SELECT @@global.tmp_disk_table_size;
+SET @@global.tmp_disk_table_size = 4294967295;
+SELECT @@global.tmp_disk_table_size;
+
+
+--echo '#--------------------FN_DYNVARS_005_04-------------------------#'
+#########################################################################
+# Change the value of tmp_disk_table_size to a valid value for SESSION Scope #
+#########################################################################
+
+SET @@session.tmp_disk_table_size = 1024;
+SELECT @@session.tmp_disk_table_size;
+
+SET @@session.tmp_disk_table_size = 4294967295;
+SELECT @@session.tmp_disk_table_size;
+SET @@session.tmp_disk_table_size = 65535;
+SELECT @@session.tmp_disk_table_size;
+
+
+--echo '#------------------FN_DYNVARS_005_05-----------------------#'
+##########################################################
+# Change the value of tmp_disk_table_size to an invalid value #
+##########################################################
+
+SET @@global.tmp_disk_table_size = 0;
+SELECT @@global.tmp_disk_table_size;
+
+SET @@global.tmp_disk_table_size = -1024;
+SELECT @@global.tmp_disk_table_size;
+
+SET @@global.tmp_disk_table_size = 1000;
+SELECT @@global.tmp_disk_table_size;
+
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@global.tmp_disk_table_size = ON;
+
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@global.tmp_disk_table_size = OFF;
+
+SET @@global.tmp_disk_table_size = True;
+SELECT @@global.tmp_disk_table_size;
+
+SET @@global.tmp_disk_table_size = False;
+SELECT @@global.tmp_disk_table_size;
+
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@global.tmp_disk_table_size = 65530.34;
+
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@global.tmp_disk_table_size ="Test";
+
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@session.tmp_disk_table_size = ON;
+
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@session.tmp_disk_table_size = OFF;
+
+SET @@session.tmp_disk_table_size = True;
+SELECT @@session.tmp_disk_table_size;
+
+SET @@session.tmp_disk_table_size = False;
+SELECT @@session.tmp_disk_table_size;
+
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@session.tmp_disk_table_size = "Test";
+
+--disable_warnings
+SET @@session.tmp_disk_table_size = 12345678901;
+--enable_warnings
+# With a 64 bit mysqld:12345678901,with a 32 bit mysqld: 4294967295
+SELECT @@session.tmp_disk_table_size IN (12345678901,4294967295);
+
+--echo '#------------------FN_DYNVARS_005_06-----------------------#'
+####################################################################
+# Check if the value in GLOBAL Table matches value in variable #
+####################################################################
+
+SELECT @@global.tmp_disk_table_size = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='tmp_disk_table_size';
+
+--echo '#------------------FN_DYNVARS_005_07-----------------------#'
+####################################################################
+# Check if the value in SESSION Table matches value in variable #
+####################################################################
+
+SELECT @@session.tmp_disk_table_size = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.SESSION_VARIABLES
+WHERE VARIABLE_NAME='tmp_disk_table_size';
+
+--echo '#---------------------FN_DYNVARS_001_09----------------------#'
+########################################################################
+# Check if global and session variables are independent of each other #
+########################################################################
+
+SET @@global.tmp_disk_table_size = 1024;
+SET @@tmp_disk_table_size = 4294967295;
+SELECT @@tmp_disk_table_size = @@global.tmp_disk_table_size;
+
+--echo '#---------------------FN_DYNVARS_001_10----------------------#'
+##################################################################
+# Check if accessing variable with SESSION,LOCAL and without #
+# SCOPE points to same session variable #
+##################################################################
+
+SET @@tmp_disk_table_size = 100;
+SELECT @@tmp_disk_table_size = @@local.tmp_disk_table_size;
+SELECT @@local.tmp_disk_table_size = @@session.tmp_disk_table_size;
+
+
+--echo '#---------------------FN_DYNVARS_001_11----------------------#'
+#########################################################################
+# Check if tmp_disk_table_size can be accessed with and without @@ sign #
+#########################################################################
+
+SET tmp_disk_table_size = 1027;
+SELECT @@tmp_disk_table_size;
+
+--Error ER_UNKNOWN_TABLE
+SELECT local.tmp_disk_table_size;
+
+--Error ER_UNKNOWN_TABLE
+SELECT global.tmp_disk_table_size;
+
+--Error ER_BAD_FIELD_ERROR
+SELECT tmp_disk_table_size = @@session.tmp_disk_table_size;
+
+
+####################################
+# Restore initial value #
+####################################
+
+SET @@global.tmp_disk_table_size = @start_global_value;
+SET @@session.tmp_disk_table_size = @start_session_value;
+
+###################################################
+# END OF tmp_disk_table_size TESTS #
+###################################################
+
diff --git a/mysql-test/suite/sys_vars/t/tmp_disk_table_size_func.test b/mysql-test/suite/sys_vars/t/tmp_disk_table_size_func.test
new file mode 100644
index 00000000000..bf93b4646d9
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/tmp_disk_table_size_func.test
@@ -0,0 +1,26 @@
+###################### tmp_memory_table_size_func.test ########################
+
+--source include/load_sysvars.inc
+--source include/have_sequence.inc
+
+--echo
+--echo "Ensure that we get an error if we exceed tmp_disk_table_size"
+--echo
+
+SET @start_tmp_memory_table_size=@@session.tmp_memory_table_size;
+SET @start_tmp_disk_table_size=@@session.tmp_disk_table_size;
+
+set @@session.tmp_memory_table_size=1000;
+set @@session.tmp_disk_table_size=3000000;
+
+create table t1 (a int primary key, b varchar(2000));
+insert into t1 select seq,repeat(char(mod(seq,62)+64),seq) from seq_1_to_2000;
+insert into t1 values (20000,"A");
+select count(*) as c from t1 group by b having c>1;
+show status like "created_tmp_disk%";
+set @@session.tmp_disk_table_size=1000000;
+--replace_regex /The table '.*' is full/The table '#sql_xxx' is full/
+--error ER_RECORD_FILE_FULL
+select count(*) as c from t1 group by b having c>1;
+show status like "created_tmp_disk%";
+drop table t1;
diff --git a/mysql-test/suite/sys_vars/t/tmp_memory_table_size_basic.test b/mysql-test/suite/sys_vars/t/tmp_memory_table_size_basic.test
new file mode 100644
index 00000000000..f5fcb17c8a5
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/tmp_memory_table_size_basic.test
@@ -0,0 +1,209 @@
+###################### tmp_memory_table_size_basic.test ######################
+# #
+# Variable Name: tmp_memory_table_size #
+# Scope: GLOBAL | SESSION #
+# Access Type: Dynamic #
+# Data Type: numeric #
+# #
+# Description: Test Cases of Dynamic System Variable tmp_table_size #
+# that checks the behavior of this variable in the following ways#
+# * Default Value #
+# * Valid & Invalid values #
+# * Scope & Access method #
+# * Data Integrity #
+# #
+###############################################################################
+
+--source include/load_sysvars.inc
+
+##############################################################
+# START OF tmp_memory_table_size TESTS #
+##############################################################
+
+#############################################################
+# Save initial value #
+#############################################################
+
+SET @start_global_value = @@global.tmp_memory_table_size;
+SET @start_session_value = @@session.tmp_memory_table_size;
+
+--echo '#--------------------FN_DYNVARS_005_01-------------------------#'
+##############################################################
+# Display the DEFAULT value of tmp_memory_table_size #
+##############################################################
+
+SET @@global.tmp_memory_table_size = 10000;
+SELECT @@global.tmp_memory_table_size;
+SET @@global.tmp_memory_table_size = DEFAULT;
+SELECT @@global.tmp_memory_table_size;
+
+SET @@session.tmp_memory_table_size = 20000;
+SELECT @@session.tmp_memory_table_size;
+SET @@session.tmp_memory_table_size = DEFAULT;
+SELECT @@session.tmp_memory_table_size;
+
+--echo '#--------------------FN_DYNVARS_005_02-------------------------#'
+########################################################################
+# Check the DEFAULT value of tmp_memory_table_size #
+########################################################################
+# The DEFAULT value is system dependend.
+# Therefore we have only a plausibility check here
+SELECT @@global.tmp_memory_table_size >= 16777216;
+SELECT @@session.tmp_memory_table_size >= 16777216;
+
+--echo '#--------------------FN_DYNVARS_005_03-------------------------#'
+########################################################################
+# Change the value of tmp_memory_table_size to a valid value for GLOBAL Scope #
+########################################################################
+
+SET @@global.tmp_memory_table_size = 1024;
+SELECT @@global.tmp_memory_table_size;
+SET @@global.tmp_memory_table_size = 60020;
+SELECT @@global.tmp_memory_table_size;
+SET @@global.tmp_memory_table_size = 4294967295;
+SELECT @@global.tmp_memory_table_size;
+
+
+--echo '#--------------------FN_DYNVARS_005_04-------------------------#'
+#########################################################################
+# Change the value of tmp_memory_table_size to a valid value for SESSION Scope #
+#########################################################################
+
+SET @@session.tmp_memory_table_size = 1024;
+SELECT @@session.tmp_memory_table_size;
+
+SET @@session.tmp_memory_table_size = 4294967295;
+SELECT @@session.tmp_memory_table_size;
+SET @@session.tmp_memory_table_size = 65535;
+SELECT @@session.tmp_memory_table_size;
+
+
+--echo '#------------------FN_DYNVARS_005_05-----------------------#'
+##########################################################
+# Change the value of tmp_memory_table_size to an invalid value #
+##########################################################
+
+SET @@global.tmp_memory_table_size = 0;
+SELECT @@global.tmp_memory_table_size;
+
+SET @@global.tmp_memory_table_size = -1024;
+SELECT @@global.tmp_memory_table_size;
+
+SET @@global.tmp_memory_table_size = 1000;
+SELECT @@global.tmp_memory_table_size;
+
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@global.tmp_memory_table_size = ON;
+
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@global.tmp_memory_table_size = OFF;
+
+SET @@global.tmp_memory_table_size = True;
+SELECT @@global.tmp_memory_table_size;
+
+SET @@global.tmp_memory_table_size = False;
+SELECT @@global.tmp_memory_table_size;
+
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@global.tmp_memory_table_size = 65530.34;
+
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@global.tmp_memory_table_size ="Test";
+
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@session.tmp_memory_table_size = ON;
+
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@session.tmp_memory_table_size = OFF;
+
+SET @@session.tmp_memory_table_size = True;
+SELECT @@session.tmp_memory_table_size;
+
+SET @@session.tmp_memory_table_size = False;
+SELECT @@session.tmp_memory_table_size;
+
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@session.tmp_memory_table_size = "Test";
+
+--disable_warnings
+SET @@session.tmp_memory_table_size = 12345678901;
+--enable_warnings
+# With a 64 bit mysqld:12345678901,with a 32 bit mysqld: 4294967295
+SELECT @@session.tmp_memory_table_size IN (12345678901,4294967295);
+
+--echo '#------------------FN_DYNVARS_005_06-----------------------#'
+####################################################################
+# Check if the value in GLOBAL Table matches value in variable #
+####################################################################
+
+SELECT @@global.tmp_memory_table_size = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='tmp_memory_table_size';
+
+--echo '#------------------FN_DYNVARS_005_07-----------------------#'
+####################################################################
+# Check if the value in SESSION Table matches value in variable #
+####################################################################
+
+SELECT @@session.tmp_memory_table_size = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.SESSION_VARIABLES
+WHERE VARIABLE_NAME='tmp_memory_table_size';
+
+--echo '#---------------------FN_DYNVARS_001_09----------------------#'
+########################################################################
+# Check if global and session variables are independent of each other #
+########################################################################
+
+SET @@global.tmp_memory_table_size = 1024;
+SET @@tmp_memory_table_size = 4294967295;
+SELECT @@tmp_memory_table_size = @@global.tmp_memory_table_size;
+
+--echo '#---------------------FN_DYNVARS_001_10----------------------#'
+##################################################################
+# Check if accessing variable with SESSION,LOCAL and without #
+# SCOPE points to same session variable #
+##################################################################
+
+SET @@tmp_memory_table_size = 100;
+SELECT @@tmp_memory_table_size = @@local.tmp_memory_table_size;
+SELECT @@local.tmp_memory_table_size = @@session.tmp_memory_table_size;
+
+
+--echo '#---------------------FN_DYNVARS_001_11----------------------#'
+#########################################################################
+# Check if tmp_memory_table_size can be accessed with and without @@ sign #
+#########################################################################
+
+SET tmp_memory_table_size = 1027;
+SELECT @@tmp_memory_table_size;
+
+--Error ER_UNKNOWN_TABLE
+SELECT local.tmp_memory_table_size;
+
+--Error ER_UNKNOWN_TABLE
+SELECT global.tmp_memory_table_size;
+
+--Error ER_BAD_FIELD_ERROR
+SELECT tmp_memory_table_size = @@session.tmp_memory_table_size;
+
+--echo
+--echo "Check that tmp_memory_table_size and tmp_table_size are the same"
+--echo
+
+set @@session.tmp_memory_table_size=100000;
+select @@session.tmp_memory_table_size,@@session.tmp_table_size;
+set @@session.tmp_memory_table_size=200000;
+select @@session.tmp_memory_table_size,@@session.tmp_table_size;
+
+
+####################################
+# Restore initial value #
+####################################
+
+SET @@global.tmp_memory_table_size = @start_global_value;
+SET @@session.tmp_memory_table_size = @start_session_value;
+
+###################################################
+# END OF tmp_memory_table_size TESTS #
+###################################################
+
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index cb2d3e839b8..35e8dea46a7 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -38,8 +38,8 @@
ulonglong Item_sum::ram_limitation(THD *thd)
{
- return MY_MIN(thd->variables.tmp_table_size,
- thd->variables.max_heap_table_size);
+ return MY_MIN(thd->variables.tmp_memory_table_size,
+ thd->variables.max_heap_table_size);
}
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index 027d696a14f..0b01925ba93 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -4238,13 +4238,13 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd)
field->set_table_name(&table->alias);
}
- if (thd->variables.tmp_table_size == ~ (ulonglong) 0) // No limit
+ if (thd->variables.tmp_memory_table_size == ~ (ulonglong) 0) // No limit
share->max_rows= ~(ha_rows) 0;
else
share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
- MY_MIN(thd->variables.tmp_table_size,
- thd->variables.max_heap_table_size) :
- thd->variables.tmp_table_size) /
+ MY_MIN(thd->variables.tmp_memory_table_size,
+ thd->variables.max_heap_table_size) :
+ thd->variables.tmp_memory_table_size) /
share->reclength);
set_if_bigger(share->max_rows,1); // For dummy start options
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 0a1be8c13c8..8052e28fbb4 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -536,7 +536,8 @@ typedef struct system_variables
uint dynamic_variables_size; /* how many bytes are in use */
ulonglong max_heap_table_size;
- ulonglong tmp_table_size;
+ ulonglong tmp_memory_table_size;
+ ulonglong tmp_disk_table_size;
ulonglong long_query_time;
ulonglong max_statement_time;
ulonglong optimizer_switch;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 6c56f0115ca..540271bc961 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -16703,7 +16703,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
if (blob_count || using_unique_constraint
|| (thd->variables.big_tables && !(select_options & SELECT_SMALL_RESULT))
|| (select_options & TMP_TABLE_FORCE_MYISAM)
- || thd->variables.tmp_table_size == 0)
+ || thd->variables.tmp_memory_table_size == 0)
{
share->db_plugin= ha_lock_engine(0, TMP_ENGINE_HTON);
table->file= get_new_handler(share, &table->mem_root,
@@ -16867,14 +16867,14 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
param->recinfo= recinfo; // Pointer to after last field
store_record(table,s->default_values); // Make empty default record
- if (thd->variables.tmp_table_size == ~ (ulonglong) 0) // No limit
+ if (thd->variables.tmp_memory_table_size == ~ (ulonglong) 0) // No limit
share->max_rows= ~(ha_rows) 0;
else
share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
- MY_MIN(thd->variables.tmp_table_size,
+ MY_MIN(thd->variables.tmp_memory_table_size,
thd->variables.max_heap_table_size) :
- thd->variables.tmp_table_size) /
- share->reclength);
+ thd->variables.tmp_memory_table_size) /
+ share->reclength);
set_if_bigger(share->max_rows,1); // For dummy start options
/*
Push the LIMIT clause to the temporary table creation, so that we
@@ -17412,10 +17412,7 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
}
}
bzero((char*) &create_info,sizeof(create_info));
-
- /* Use long data format, to ensure we never get a 'table is full' error */
- if (!(options & SELECT_SMALL_RESULT))
- create_info.data_file_length= ~(ulonglong) 0;
+ create_info.data_file_length= table->in_use->variables.tmp_disk_table_size;
/*
The logic for choosing the record format:
@@ -17611,9 +17608,7 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
}
MI_CREATE_INFO create_info;
bzero((char*) &create_info,sizeof(create_info));
-
- if (!(options & SELECT_SMALL_RESULT))
- create_info.data_file_length= ~(ulonglong) 0;
+ create_info.data_file_length= table->in_use->variables.tmp_disk_table_size;
if ((error=mi_create(share->table_name.str, share->keys, &keydef,
(uint) (*recinfo-start_recinfo),
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 9ab5e42755e..2c74ad5cb29 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -3421,12 +3421,30 @@ static Sys_var_tx_read_only Sys_tx_read_only(
static Sys_var_ulonglong Sys_tmp_table_size(
"tmp_table_size",
+ "Alias for tmp_memory_table_size. "
"If an internal in-memory temporary table exceeds this size, MySQL "
- "will automatically convert it to an on-disk MyISAM or Aria table",
- SESSION_VAR(tmp_table_size), CMD_LINE(REQUIRED_ARG),
+ "will automatically convert it to an on-disk MyISAM or Aria table.",
+ SESSION_VAR(tmp_memory_table_size), CMD_LINE(REQUIRED_ARG),
VALID_RANGE(1024, (ulonglong)~(intptr)0), DEFAULT(16*1024*1024),
BLOCK_SIZE(1));
+static Sys_var_ulonglong Sys_tmp_memory_table_size(
+ "tmp_memory_table_size",
+ "If an internal in-memory temporary table exceeds this size, MySQL "
+ "will automatically convert it to an on-disk MyISAM or Aria table. "
+ "Same as tmp_table_size.",
+ SESSION_VAR(tmp_memory_table_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1024, (ulonglong)~(intptr)0), DEFAULT(16*1024*1024),
+ BLOCK_SIZE(1));
+
+static Sys_var_ulonglong Sys_tmp_disk_table_size(
+ "tmp_disk_table_size",
+ "Max size for data for an internal temporary on-disk MyISAM or Aria table.",
+ SESSION_VAR(tmp_disk_table_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1024, (ulonglong)~(intptr)0),
+ DEFAULT((ulonglong)~(intptr)0),
+ BLOCK_SIZE(1));
+
static Sys_var_mybool Sys_timed_mutexes(
"timed_mutexes",
"Specify whether to time mutexes. Deprecated, has no effect.",
diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c
index 0ddd8b226e2..80e38fc2b00 100644
--- a/storage/maria/ma_create.c
+++ b/storage/maria/ma_create.c
@@ -375,18 +375,18 @@ int maria_create(const char *name, enum data_file_type datafile_type,
if (rows_per_page > 0)
{
set_if_smaller(rows_per_page, MAX_ROWS_PER_PAGE);
- ci->max_rows= data_file_length / maria_block_size * rows_per_page;
+ ci->max_rows= (data_file_length / maria_block_size+1) * rows_per_page;
}
else
ci->max_rows= data_file_length / (min_pack_length +
extra_header_size +
- DIR_ENTRY_SIZE);
+ DIR_ENTRY_SIZE)+1;
}
else
ci->max_rows=(ha_rows) (ci->data_file_length/(min_pack_length +
((options &
HA_OPTION_PACK_RECORD) ?
- 3 : 0)));
+ 3 : 0)))+1;
}
max_rows= (ulonglong) ci->max_rows;
if (datafile_type == BLOCK_RECORD)
@@ -1204,7 +1204,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
if (mysql_file_chsize(file,(ulong) share.base.keystart,0,MYF(0)))
goto err;
- if (sync_dir && mysql_file_sync(file, MYF(0)))
+ if (!internal_table && sync_dir && mysql_file_sync(file, MYF(0)))
goto err;
if (! (flags & HA_DONT_TOUCH_DATA))
@@ -1214,7 +1214,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
share.base.min_pack_length*ci->reloc_rows,0,MYF(0)))
goto err;
#endif
- if (sync_dir && mysql_file_sync(dfile, MYF(0)))
+ if (!internal_table && sync_dir && mysql_file_sync(dfile, MYF(0)))
goto err;
if (mysql_file_close(dfile,MYF(0)))
goto err;
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index c4a7df4443c..5c5e41be1f8 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -565,7 +565,10 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
set_if_smaller(max_data_file_length, INT_MAX32);
set_if_smaller(max_key_file_length, INT_MAX32);
#endif
- share->base.max_data_file_length=(my_off_t) max_data_file_length;
+ /* For internal temporary tables, max_data_file_length is already set */
+ if (!internal_table || !share->base.max_data_file_length)
+ share->base.max_data_file_length=(my_off_t) max_data_file_length;
+ DBUG_ASSERT(share->base.max_data_file_length);
share->base.max_key_file_length=(my_off_t) max_key_file_length;
if (share->options & HA_OPTION_COMPRESS_RECORD)
@@ -909,9 +912,12 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
share->block_size * keys : 0));
my_free(disk_cache);
_ma_setup_functions(share);
+ max_data_file_length= share->base.max_data_file_length;
if ((*share->once_init)(share, info.dfile.file))
goto err;
- if (share->now_transactional)
+ if (internal_table)
+ set_if_smaller(share->base.max_data_file_length,
+ max_data_file_length);
{
/* Setup initial state that is visible for all */
MARIA_STATE_HISTORY_CLOSED *history;
diff --git a/storage/maria/ma_state.c b/storage/maria/ma_state.c
index 88ce88b8f98..15cc48ad468 100644
--- a/storage/maria/ma_state.c
+++ b/storage/maria/ma_state.c
@@ -750,9 +750,18 @@ void maria_versioning(MARIA_HA *info, my_bool versioning)
void _ma_set_share_data_file_length(MARIA_SHARE *share, ulonglong new_length)
{
- mysql_mutex_lock(&share->intern_lock);
+ if (!share->internal_table)
+ mysql_mutex_lock(&share->intern_lock);
if (share->state.state.data_file_length < new_length)
+ {
share->state.state.data_file_length= new_length;
+ if (new_length >= share->base.max_data_file_length)
+ {
+ /* Give an error on next insert */
+ share->state.changed|= STATE_DATA_FILE_FULL;
+ }
+ }
+ if (!share->internal_table)
mysql_mutex_unlock(&share->intern_lock);
}
diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c
index fdcb5abd090..06aa2da7ae2 100644
--- a/storage/maria/ma_write.c
+++ b/storage/maria/ma_write.c
@@ -107,9 +107,10 @@ int maria_write(MARIA_HA *info, uchar *record)
if (_ma_readinfo(info,F_WRLCK,1))
DBUG_RETURN(my_errno);
- if (share->base.reloc == (ha_rows) 1 &&
- share->base.records == (ha_rows) 1 &&
- share->state.state.records == (ha_rows) 1)
+ if ((share->state.changed & STATE_DATA_FILE_FULL) ||
+ (share->base.reloc == (ha_rows) 1 &&
+ share->base.records == (ha_rows) 1 &&
+ share->state.state.records == (ha_rows) 1))
{ /* System file */
my_errno=HA_ERR_RECORD_FILE_FULL;
goto err2;
diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h
index 8664157a65a..cc100b3706c 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -734,6 +734,7 @@ struct st_maria_handler
#define STATE_MOVED 512U /* set if base->uuid != maria_uuid */
#define STATE_IN_REPAIR 1024U /* We are running repair on table */
#define STATE_CRASHED_PRINTED 2048U
+#define STATE_DATA_FILE_FULL 4096U
#define STATE_CRASHED_FLAGS (STATE_CRASHED | STATE_CRASHED_ON_REPAIR | STATE_CRASHED_PRINTED)