diff options
author | Monty <monty@mariadb.org> | 2017-06-30 17:56:58 +0300 |
---|---|---|
committer | Monty <monty@mariadb.org> | 2017-06-30 22:31:37 +0300 |
commit | dd8474b1dc556d0ea9491d1908a2d1237818e8c1 (patch) | |
tree | 9ab8535fbac53bf3a644482a41c59eaca1371754 | |
parent | 9f484b63f1b61e6ade1481cfb8465f8fe208386d (diff) | |
download | mariadb-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.result | 14 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result | 30 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/r/tmp_disk_table_size_basic.result | 146 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/r/tmp_disk_table_size_func.result | 25 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/r/tmp_memory_table_size_basic.result | 165 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/t/tmp_disk_table_size_basic.test | 207 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/t/tmp_disk_table_size_func.test | 26 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/t/tmp_memory_table_size_basic.test | 209 | ||||
-rw-r--r-- | sql/item_sum.cc | 4 | ||||
-rw-r--r-- | sql/opt_subselect.cc | 8 | ||||
-rw-r--r-- | sql/sql_class.h | 3 | ||||
-rw-r--r-- | sql/sql_select.cc | 19 | ||||
-rw-r--r-- | sql/sys_vars.cc | 22 | ||||
-rw-r--r-- | storage/maria/ma_create.c | 10 | ||||
-rw-r--r-- | storage/maria/ma_open.c | 10 | ||||
-rw-r--r-- | storage/maria/ma_state.c | 11 | ||||
-rw-r--r-- | storage/maria/ma_write.c | 7 | ||||
-rw-r--r-- | storage/maria/maria_def.h | 1 |
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) |