mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-35469 Heap tables are calling mallocs to often
Heap tables are allocated blocks to store rows according to my_default_record_cache (mapped to the server global variable read_buffer_size). This causes performance issues when the record length is big (> 1000 bytes) and the my_default_record_cache is small. Changed to instead split the default heap allocation to 1/16 of the allowed space and not use my_default_record_cache anymore when creating the heap. The allocation is also aligned to be just under a power of 2. For some test that I have been running, which was using record length=633, the speed of the query doubled thanks to this change. Other things: - Fixed calculation of max_records passed to hp_create() to take into account padding between records. - Updated calculation of memory needed by heap tables. Before we did not take into account internal structures needed to access rows. - Changed block sized for memory_table from 1 to 16384 to get less fragmentation. This also avoids a problem where we need 1K to manage index and row storage which was not counted for before. - Moved heap memory usage to a separate test for 32 bit. - Allocate all data blocks in heap in powers of 2. Change reported memory usage for heap to reflect this. Reviewed-by: Sergei Golubchik <serg@mariadb.org>
This commit is contained in:
@@ -105,6 +105,7 @@ typedef struct st_heap_block
|
|||||||
uint recbuffer; /* Length of one saved record */
|
uint recbuffer; /* Length of one saved record */
|
||||||
ulong records_in_block; /* Records in one heap-block */
|
ulong records_in_block; /* Records in one heap-block */
|
||||||
ulong last_allocated; /* number of records there is allocated space for */
|
ulong last_allocated; /* number of records there is allocated space for */
|
||||||
|
size_t alloc_size; /* Allocate blocks of this size */
|
||||||
} HP_BLOCK;
|
} HP_BLOCK;
|
||||||
|
|
||||||
struct st_heap_info; /* For reference */
|
struct st_heap_info; /* For reference */
|
||||||
|
@@ -670,7 +670,7 @@ typedef SOCKET_SIZE_TYPE size_socket;
|
|||||||
How much overhead does malloc have. The code often allocates
|
How much overhead does malloc have. The code often allocates
|
||||||
something like 1024-MALLOC_OVERHEAD bytes
|
something like 1024-MALLOC_OVERHEAD bytes
|
||||||
*/
|
*/
|
||||||
#define MALLOC_OVERHEAD 8
|
#define MALLOC_OVERHEAD (8+24)
|
||||||
|
|
||||||
/* get memory in huncs */
|
/* get memory in huncs */
|
||||||
#define ONCE_ALLOC_INIT (uint) 4096
|
#define ONCE_ALLOC_INIT (uint) 4096
|
||||||
|
@@ -97,6 +97,8 @@ drop view v1;
|
|||||||
create table t1 (user_id char(64) character set utf8);
|
create table t1 (user_id char(64) character set utf8);
|
||||||
insert t1 values(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15),(16),(17);
|
insert t1 values(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15),(16),(17);
|
||||||
set @@tmp_table_size = 1024;
|
set @@tmp_table_size = 1024;
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Truncated incorrect tmp_table_size value: '1024'
|
||||||
select count(distinct user_id) from t1;
|
select count(distinct user_id) from t1;
|
||||||
count(distinct user_id)
|
count(distinct user_id)
|
||||||
17
|
17
|
||||||
@@ -126,6 +128,8 @@ insert into t1 values
|
|||||||
( 2 , 13 ),
|
( 2 , 13 ),
|
||||||
( 3 , 14 );
|
( 3 , 14 );
|
||||||
set @@tmp_table_size=1024;
|
set @@tmp_table_size=1024;
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Truncated incorrect tmp_table_size value: '1024'
|
||||||
select count(distinct a) from t1;
|
select count(distinct a) from t1;
|
||||||
count(distinct a)
|
count(distinct a)
|
||||||
10
|
10
|
||||||
|
@@ -310,7 +310,7 @@ a char(2) NOT NULL DEFAULT '',
|
|||||||
PRIMARY KEY (a)
|
PRIMARY KEY (a)
|
||||||
) ENGINE=MyISAM;
|
) ENGINE=MyISAM;
|
||||||
INSERT INTO t4 VALUES ('CD');
|
INSERT INTO t4 VALUES ('CD');
|
||||||
set @@tmp_table_size=8192;
|
set @@tmp_table_size=16384;
|
||||||
EXPLAIN
|
EXPLAIN
|
||||||
SELECT * FROM t3 AS tx JOIN t2 AS ty ON (tx.pk = ty.pk)
|
SELECT * FROM t3 AS tx JOIN t2 AS ty ON (tx.pk = ty.pk)
|
||||||
WHERE
|
WHERE
|
||||||
|
@@ -245,7 +245,7 @@ CREATE TABLE t4 (
|
|||||||
) ENGINE=MyISAM;
|
) ENGINE=MyISAM;
|
||||||
INSERT INTO t4 VALUES ('CD');
|
INSERT INTO t4 VALUES ('CD');
|
||||||
|
|
||||||
set @@tmp_table_size=8192;
|
set @@tmp_table_size=16384;
|
||||||
|
|
||||||
--replace_column 9 #
|
--replace_column 9 #
|
||||||
EXPLAIN
|
EXPLAIN
|
||||||
|
@@ -2183,6 +2183,8 @@ INSERT INTO t3 VALUES ('Miami');
|
|||||||
SET @save_optimizer_switch=@@optimizer_switch;
|
SET @save_optimizer_switch=@@optimizer_switch;
|
||||||
SET optimizer_switch = 'derived_with_keys=on';
|
SET optimizer_switch = 'derived_with_keys=on';
|
||||||
SET @@tmp_table_size=1024*4;
|
SET @@tmp_table_size=1024*4;
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Truncated incorrect tmp_table_size value: '4096'
|
||||||
explain SELECT * FROM (SELECT t1.* FROM t1, t2) AS t JOIN t3 ON t3.a = t.b;
|
explain SELECT * FROM (SELECT t1.* FROM t1, t2) AS t JOIN t3 ON t3.a = t.b;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t3 system NULL NULL NULL NULL 1
|
1 SIMPLE t3 system NULL NULL NULL NULL 1
|
||||||
|
@@ -1005,6 +1005,8 @@ DROP TABLE t1;
|
|||||||
#
|
#
|
||||||
SET @tmp_table_size_save= @@tmp_table_size;
|
SET @tmp_table_size_save= @@tmp_table_size;
|
||||||
SET @@tmp_table_size= 1024;
|
SET @@tmp_table_size= 1024;
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Truncated incorrect tmp_table_size value: '1024'
|
||||||
CREATE TABLE t1 (a INT);
|
CREATE TABLE t1 (a INT);
|
||||||
INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8);
|
INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8);
|
||||||
INSERT INTO t1 SELECT a+8 FROM t1;
|
INSERT INTO t1 SELECT a+8 FROM t1;
|
||||||
|
@@ -1,15 +1,12 @@
|
|||||||
CREATE TABLE t1 (
|
CREATE TABLE t1 (
|
||||||
a varchar(32) character set utf8 collate utf8_bin NOT NULL,
|
a varchar(128) character set utf8 collate utf8_bin NOT NULL,
|
||||||
b varchar(32) character set utf8 collate utf8_bin NOT NULL )
|
b varchar(128) character set utf8 collate utf8_bin NOT NULL )
|
||||||
ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
INSERT INTO t1 VALUES
|
INSERT INTO t1
|
||||||
('AAAAAAAAAA','AAAAAAAAAA'), ('AAAAAAAAAB','AAAAAAAAAB '),
|
select concat(repeat("A", 50),char(32+mod(seq,31)),char(32+mod(seq,29))),
|
||||||
('AAAAAAAAAB','AAAAAAAAAB'), ('AAAAAAAAAC','AAAAAAAAAC'),
|
concat(repeat("A", 50),char(32+mod(seq,31)),char(32+mod(seq,29)))
|
||||||
('AAAAAAAAAD','AAAAAAAAAD'), ('AAAAAAAAAE','AAAAAAAAAE'),
|
from seq_1_to_128;
|
||||||
('AAAAAAAAAF','AAAAAAAAAF'), ('AAAAAAAAAG','AAAAAAAAAG'),
|
set tmp_table_size=16384;
|
||||||
('AAAAAAAAAH','AAAAAAAAAH'), ('AAAAAAAAAI','AAAAAAAAAI'),
|
|
||||||
('AAAAAAAAAJ','AAAAAAAAAJ'), ('AAAAAAAAAK','AAAAAAAAAK');
|
|
||||||
set tmp_table_size=1024;
|
|
||||||
SET @saved_dbug = @@SESSION.debug_dbug;
|
SET @saved_dbug = @@SESSION.debug_dbug;
|
||||||
set session debug_dbug="+d,raise_error";
|
set session debug_dbug="+d,raise_error";
|
||||||
SELECT MAX(a) FROM t1 GROUP BY a,b;
|
SELECT MAX(a) FROM t1 GROUP BY a,b;
|
||||||
|
@@ -1,23 +1,20 @@
|
|||||||
--source include/have_debug.inc
|
--source include/have_debug.inc
|
||||||
--source include/not_embedded.inc
|
--source include/not_embedded.inc
|
||||||
|
--source include/have_sequence.inc
|
||||||
#
|
#
|
||||||
# Bug #28499: crash for grouping query when tmp_table_size is too small
|
# Bug #28499: crash for grouping query when tmp_table_size is too small
|
||||||
#
|
#
|
||||||
CREATE TABLE t1 (
|
CREATE TABLE t1 (
|
||||||
a varchar(32) character set utf8 collate utf8_bin NOT NULL,
|
a varchar(128) character set utf8 collate utf8_bin NOT NULL,
|
||||||
b varchar(32) character set utf8 collate utf8_bin NOT NULL )
|
b varchar(128) character set utf8 collate utf8_bin NOT NULL )
|
||||||
ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
INSERT INTO t1 VALUES
|
INSERT INTO t1
|
||||||
('AAAAAAAAAA','AAAAAAAAAA'), ('AAAAAAAAAB','AAAAAAAAAB '),
|
select concat(repeat("A", 50),char(32+mod(seq,31)),char(32+mod(seq,29))),
|
||||||
('AAAAAAAAAB','AAAAAAAAAB'), ('AAAAAAAAAC','AAAAAAAAAC'),
|
concat(repeat("A", 50),char(32+mod(seq,31)),char(32+mod(seq,29)))
|
||||||
('AAAAAAAAAD','AAAAAAAAAD'), ('AAAAAAAAAE','AAAAAAAAAE'),
|
from seq_1_to_128;
|
||||||
('AAAAAAAAAF','AAAAAAAAAF'), ('AAAAAAAAAG','AAAAAAAAAG'),
|
|
||||||
('AAAAAAAAAH','AAAAAAAAAH'), ('AAAAAAAAAI','AAAAAAAAAI'),
|
|
||||||
('AAAAAAAAAJ','AAAAAAAAAJ'), ('AAAAAAAAAK','AAAAAAAAAK');
|
|
||||||
|
|
||||||
set tmp_table_size=1024;
|
set tmp_table_size=16384;
|
||||||
|
|
||||||
# Set debug flag so an error is returned when
|
# Set debug flag so an error is returned when
|
||||||
# tmp table in query is converted from heap to myisam
|
# tmp table in query is converted from heap to myisam
|
||||||
|
@@ -4331,6 +4331,8 @@ CREATE TABLE t1(a VARCHAR(1027), b INT);
|
|||||||
INSERT INTO t1 SELECT seq, seq from seq_1_to_34;
|
INSERT INTO t1 SELECT seq, seq from seq_1_to_34;
|
||||||
SET @save_tmp_memory_table_size= @@tmp_memory_table_size;
|
SET @save_tmp_memory_table_size= @@tmp_memory_table_size;
|
||||||
SET tmp_memory_table_size= 1056*2;
|
SET tmp_memory_table_size= 1056*2;
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Truncated incorrect tmp_memory_table_size value: '2112'
|
||||||
SELECT COUNT(DISTINCT a) FROM t1;
|
SELECT COUNT(DISTINCT a) FROM t1;
|
||||||
COUNT(DISTINCT a)
|
COUNT(DISTINCT a)
|
||||||
34
|
34
|
||||||
|
@@ -1085,10 +1085,8 @@ select 1 union all select 2 union all select 3 union select 4;
|
|||||||
3
|
3
|
||||||
4
|
4
|
||||||
# test with limited resource
|
# test with limited resource
|
||||||
set @@max_heap_table_size= 1024;
|
set @@max_heap_table_size= 16384;
|
||||||
Warnings:
|
set @@tmp_table_size= 16384;
|
||||||
Warning 1292 Truncated incorrect max_heap_table_size value: '1024'
|
|
||||||
set @@tmp_table_size= 1024;
|
|
||||||
create table t1 (a int, b int);
|
create table t1 (a int, b int);
|
||||||
insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(0,0);
|
insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(0,0);
|
||||||
insert into t1 select * from t1;
|
insert into t1 select * from t1;
|
||||||
|
@@ -457,8 +457,8 @@ select 1 union all select 2 union all select 3 union select 4;
|
|||||||
|
|
||||||
--echo # test with limited resource
|
--echo # test with limited resource
|
||||||
|
|
||||||
set @@max_heap_table_size= 1024;
|
set @@max_heap_table_size= 16384;
|
||||||
set @@tmp_table_size= 1024;
|
set @@tmp_table_size= 16384;
|
||||||
|
|
||||||
create table t1 (a int, b int);
|
create table t1 (a int, b int);
|
||||||
insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(0,0);
|
insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(0,0);
|
||||||
|
@@ -874,7 +874,7 @@ insert into t1 select * from t2;
|
|||||||
insert into t2 select * from t1;
|
insert into t2 select * from t1;
|
||||||
insert into t1 select * from t2;
|
insert into t1 select * from t2;
|
||||||
insert into t2 select * from t1;
|
insert into t2 select * from t1;
|
||||||
set local tmp_table_size=1024;
|
set local tmp_table_size=16384;
|
||||||
select count(*) from (select * from t1 union all select * from t2 order by 1) b;
|
select count(*) from (select * from t1 union all select * from t2 order by 1) b;
|
||||||
count(*)
|
count(*)
|
||||||
21
|
21
|
||||||
|
@@ -503,7 +503,7 @@ insert into t1 select * from t2;
|
|||||||
insert into t2 select * from t1;
|
insert into t2 select * from t1;
|
||||||
insert into t1 select * from t2;
|
insert into t1 select * from t2;
|
||||||
insert into t2 select * from t1;
|
insert into t2 select * from t1;
|
||||||
set local tmp_table_size=1024;
|
set local tmp_table_size=16384;
|
||||||
select count(*) from (select * from t1 union all select * from t2 order by 1) b;
|
select count(*) from (select * from t1 union all select * from t2 order by 1) b;
|
||||||
select count(*) from t1;
|
select count(*) from t1;
|
||||||
select count(*) from t2;
|
select count(*) from t2;
|
||||||
|
@@ -491,7 +491,9 @@ a quux
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
connect con1,localhost,root,,test;
|
connect con1,localhost,root,,test;
|
||||||
connection con1;
|
connection con1;
|
||||||
set tmp_table_size=1024;
|
set tmp_table_size=2048;
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Truncated incorrect tmp_table_size value: '2048'
|
||||||
create table t1 (id int, a int, key idx(a));
|
create table t1 (id int, a int, key idx(a));
|
||||||
create table t2 (id int unsigned not null auto_increment primary key, a int);
|
create table t2 (id int unsigned not null auto_increment primary key, a int);
|
||||||
insert into t2(a) values(1),(2),(3),(4),(5),(6),(7),(8);
|
insert into t2(a) values(1),(2),(3),(4),(5),(6),(7),(8);
|
||||||
|
@@ -397,7 +397,7 @@ DROP TABLE t1;
|
|||||||
connect (con1,localhost,root,,test);
|
connect (con1,localhost,root,,test);
|
||||||
connection con1;
|
connection con1;
|
||||||
|
|
||||||
set tmp_table_size=1024;
|
set tmp_table_size=2048;
|
||||||
|
|
||||||
# Create the test tables
|
# Create the test tables
|
||||||
create table t1 (id int, a int, key idx(a));
|
create table t1 (id int, a int, key idx(a));
|
||||||
|
@@ -547,7 +547,7 @@ set global table_open_cache=100;
|
|||||||
set default_storage_engine=myisam;
|
set default_storage_engine=myisam;
|
||||||
set global thread_cache_size=100;
|
set global thread_cache_size=100;
|
||||||
set timestamp=1, timestamp=default;
|
set timestamp=1, timestamp=default;
|
||||||
set tmp_table_size=1024;
|
set tmp_table_size=16384;
|
||||||
set tx_isolation="READ-COMMITTED";
|
set tx_isolation="READ-COMMITTED";
|
||||||
set wait_timeout=100;
|
set wait_timeout=100;
|
||||||
set log_warnings=1;
|
set log_warnings=1;
|
||||||
|
@@ -340,7 +340,7 @@ set global table_open_cache=100;
|
|||||||
set default_storage_engine=myisam;
|
set default_storage_engine=myisam;
|
||||||
set global thread_cache_size=100;
|
set global thread_cache_size=100;
|
||||||
set timestamp=1, timestamp=default;
|
set timestamp=1, timestamp=default;
|
||||||
set tmp_table_size=1024;
|
set tmp_table_size=16384;
|
||||||
set tx_isolation="READ-COMMITTED";
|
set tx_isolation="READ-COMMITTED";
|
||||||
set wait_timeout=100;
|
set wait_timeout=100;
|
||||||
set log_warnings=1;
|
set log_warnings=1;
|
||||||
|
@@ -798,58 +798,6 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
3 DERIVED t1 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Using where
|
3 DERIVED t1 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Using where
|
||||||
DROP TABLE t1,t2,h1;
|
DROP TABLE t1,t2,h1;
|
||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
CREATE TABLE t1 (a int, index(a)) engine=heap min_rows=10 max_rows=100;
|
|
||||||
insert into t1 values(1);
|
|
||||||
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
|
||||||
data_length index_length
|
|
||||||
1600 2400
|
|
||||||
drop table t1;
|
|
||||||
CREATE TABLE t1 (a int, index(a)) engine=heap min_rows=10 max_rows=10000;
|
|
||||||
insert into t1 values(1);
|
|
||||||
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
|
||||||
data_length index_length
|
|
||||||
16000 24000
|
|
||||||
drop table t1;
|
|
||||||
CREATE TABLE t1 (a int, index(a)) engine=heap min_rows=3000 max_rows=3000;
|
|
||||||
insert into t1 values(1);
|
|
||||||
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
|
||||||
data_length index_length
|
|
||||||
48000 72000
|
|
||||||
drop table t1;
|
|
||||||
CREATE TABLE t1 (a int, index(a)) engine=heap max_rows=15000;
|
|
||||||
insert into t1 values(1);
|
|
||||||
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
|
||||||
data_length index_length
|
|
||||||
24000 36000
|
|
||||||
drop table t1;
|
|
||||||
create table t1 (c1 int, index(c1)) engine=heap max_rows=10000;
|
|
||||||
insert into t1 select rand(100000000);
|
|
||||||
insert into t1 select rand(100000000) from t1;
|
|
||||||
insert into t1 select rand(100000000) from t1;
|
|
||||||
insert into t1 select rand(100000000) from t1;
|
|
||||||
insert into t1 select rand(100000000) from t1;
|
|
||||||
insert into t1 select rand(100000000) from t1;
|
|
||||||
insert into t1 select rand(100000000) from t1;
|
|
||||||
insert into t1 select rand(100000000) from t1;
|
|
||||||
insert into t1 select rand(100000000) from t1;
|
|
||||||
insert into t1 select rand(100000000) from t1;
|
|
||||||
insert into t1 select rand(100000000) from t1 limit 488;
|
|
||||||
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
|
||||||
data_length index_length
|
|
||||||
16000 24000
|
|
||||||
insert into t1 select rand(100000000) from t1 limit 1;
|
|
||||||
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
|
||||||
data_length index_length
|
|
||||||
33024 49024
|
|
||||||
insert into t1 select rand(100000000) from t1 limit 1000;
|
|
||||||
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
|
||||||
data_length index_length
|
|
||||||
49024 73024
|
|
||||||
insert into t1 select rand(100000000) from t1;
|
|
||||||
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
|
||||||
data_length index_length
|
|
||||||
81024 121024
|
|
||||||
drop table t1;
|
|
||||||
CREATE TABLE t1 (id INT);
|
CREATE TABLE t1 (id INT);
|
||||||
INSERT INTO t1 VALUES (1);
|
INSERT INTO t1 VALUES (1);
|
||||||
INSERT INTO t1 VALUES (2);
|
INSERT INTO t1 VALUES (2);
|
||||||
|
@@ -546,7 +546,7 @@ CREATE TABLE t1 (
|
|||||||
);
|
);
|
||||||
|
|
||||||
INSERT INTO t1 VALUES (19,5,'h'),(20,5,'h');
|
INSERT INTO t1 VALUES (19,5,'h'),(20,5,'h');
|
||||||
|
|
||||||
CREATE TABLE t2 (col_int_nokey INT);
|
CREATE TABLE t2 (col_int_nokey INT);
|
||||||
|
|
||||||
INSERT INTO t2 VALUES (1),(2);
|
INSERT INTO t2 VALUES (1),(2);
|
||||||
@@ -567,58 +567,6 @@ DROP TABLE t1,t2,h1;
|
|||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
# End of 5.1 tests
|
# End of 5.1 tests
|
||||||
|
|
||||||
#
|
|
||||||
# Show that MIN_ROWS and MAX_ROWS have an effect on how data_length
|
|
||||||
# and index_length are allocated.
|
|
||||||
# Result is different for 32 / 64 bit machines as pointer lengths are different
|
|
||||||
#
|
|
||||||
|
|
||||||
CREATE TABLE t1 (a int, index(a)) engine=heap min_rows=10 max_rows=100;
|
|
||||||
insert into t1 values(1);
|
|
||||||
--replace_result 800 1600 1200 2400
|
|
||||||
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
|
||||||
drop table t1;
|
|
||||||
CREATE TABLE t1 (a int, index(a)) engine=heap min_rows=10 max_rows=10000;
|
|
||||||
insert into t1 values(1);
|
|
||||||
--replace_result 8000 16000 12000 24000
|
|
||||||
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
|
||||||
drop table t1;
|
|
||||||
CREATE TABLE t1 (a int, index(a)) engine=heap min_rows=3000 max_rows=3000;
|
|
||||||
insert into t1 values(1);
|
|
||||||
--replace_result 24000 48000 36000 72000
|
|
||||||
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
|
||||||
drop table t1;
|
|
||||||
CREATE TABLE t1 (a int, index(a)) engine=heap max_rows=15000;
|
|
||||||
insert into t1 values(1);
|
|
||||||
--replace_result 12000 24000 18000 36000
|
|
||||||
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
|
||||||
drop table t1;
|
|
||||||
|
|
||||||
create table t1 (c1 int, index(c1)) engine=heap max_rows=10000;
|
|
||||||
insert into t1 select rand(100000000);
|
|
||||||
insert into t1 select rand(100000000) from t1;
|
|
||||||
insert into t1 select rand(100000000) from t1;
|
|
||||||
insert into t1 select rand(100000000) from t1;
|
|
||||||
insert into t1 select rand(100000000) from t1;
|
|
||||||
insert into t1 select rand(100000000) from t1;
|
|
||||||
insert into t1 select rand(100000000) from t1;
|
|
||||||
insert into t1 select rand(100000000) from t1;
|
|
||||||
insert into t1 select rand(100000000) from t1;
|
|
||||||
insert into t1 select rand(100000000) from t1;
|
|
||||||
insert into t1 select rand(100000000) from t1 limit 488;
|
|
||||||
--replace_result 8000 16000 12000 24000
|
|
||||||
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
|
||||||
insert into t1 select rand(100000000) from t1 limit 1;
|
|
||||||
--replace_result 16512 33024 24512 49024
|
|
||||||
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
|
||||||
insert into t1 select rand(100000000) from t1 limit 1000;
|
|
||||||
--replace_result 24512 49024 36512 73024
|
|
||||||
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
|
||||||
insert into t1 select rand(100000000) from t1;
|
|
||||||
--replace_result 40512 81024 60512 121024
|
|
||||||
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
|
||||||
drop table t1;
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# MDEV-5905 Creating tmp. memory table kills the server
|
# MDEV-5905 Creating tmp. memory table kills the server
|
||||||
#
|
#
|
||||||
|
40
mysql-test/suite/heap/heap_memory_used,32bit.rdiff
Normal file
40
mysql-test/suite/heap/heap_memory_used,32bit.rdiff
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
--- suite/heap/heap_memory_used.result
|
||||||
|
+++ suite/heap/heap_memory_used.reject
|
||||||
|
@@ -17,13 +17,13 @@
|
||||||
|
insert into t1 values(1);
|
||||||
|
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
||||||
|
data_length index_length
|
||||||
|
-65504 131040
|
||||||
|
+32736 65504
|
||||||
|
drop table t1;
|
||||||
|
CREATE TABLE t1 (a int, index(a)) engine=heap max_rows=15000;
|
||||||
|
insert into t1 values(1);
|
||||||
|
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
||||||
|
data_length index_length
|
||||||
|
-16352 32736
|
||||||
|
+16352 16352
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (c1 int, index(c1)) engine=heap max_rows=10000;
|
||||||
|
insert into t1 select rand(100000000);
|
||||||
|
@@ -39,17 +39,17 @@
|
||||||
|
insert into t1 select rand(100000000) from t1 limit 488;
|
||||||
|
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
||||||
|
data_length index_length
|
||||||
|
-32704 32704
|
||||||
|
+16352 16352
|
||||||
|
insert into t1 select rand(100000000) from t1 limit 1;
|
||||||
|
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
||||||
|
data_length index_length
|
||||||
|
-32704 32704
|
||||||
|
+16352 16352
|
||||||
|
insert into t1 select rand(100000000) from t1 limit 1000;
|
||||||
|
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
||||||
|
data_length index_length
|
||||||
|
-49056 65408
|
||||||
|
+32704 32704
|
||||||
|
insert into t1 select rand(100000000) from t1;
|
||||||
|
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
||||||
|
data_length index_length
|
||||||
|
-81760 114464
|
||||||
|
+49056 65408
|
||||||
|
drop table t1;
|
55
mysql-test/suite/heap/heap_memory_used.result
Normal file
55
mysql-test/suite/heap/heap_memory_used.result
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#
|
||||||
|
# Test of heap table memory usage
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a int, index(a)) engine=heap min_rows=10 max_rows=100;
|
||||||
|
insert into t1 values(1);
|
||||||
|
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
||||||
|
data_length index_length
|
||||||
|
16352 16352
|
||||||
|
drop table t1;
|
||||||
|
CREATE TABLE t1 (a int, index(a)) engine=heap min_rows=10 max_rows=10000;
|
||||||
|
insert into t1 values(1);
|
||||||
|
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
||||||
|
data_length index_length
|
||||||
|
16352 16352
|
||||||
|
drop table t1;
|
||||||
|
CREATE TABLE t1 (a int, index(a)) engine=heap min_rows=3000 max_rows=3000;
|
||||||
|
insert into t1 values(1);
|
||||||
|
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
||||||
|
data_length index_length
|
||||||
|
65504 131040
|
||||||
|
drop table t1;
|
||||||
|
CREATE TABLE t1 (a int, index(a)) engine=heap max_rows=15000;
|
||||||
|
insert into t1 values(1);
|
||||||
|
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
||||||
|
data_length index_length
|
||||||
|
16352 32736
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (c1 int, index(c1)) engine=heap max_rows=10000;
|
||||||
|
insert into t1 select rand(100000000);
|
||||||
|
insert into t1 select rand(100000000) from t1;
|
||||||
|
insert into t1 select rand(100000000) from t1;
|
||||||
|
insert into t1 select rand(100000000) from t1;
|
||||||
|
insert into t1 select rand(100000000) from t1;
|
||||||
|
insert into t1 select rand(100000000) from t1;
|
||||||
|
insert into t1 select rand(100000000) from t1;
|
||||||
|
insert into t1 select rand(100000000) from t1;
|
||||||
|
insert into t1 select rand(100000000) from t1;
|
||||||
|
insert into t1 select rand(100000000) from t1;
|
||||||
|
insert into t1 select rand(100000000) from t1 limit 488;
|
||||||
|
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
||||||
|
data_length index_length
|
||||||
|
32704 32704
|
||||||
|
insert into t1 select rand(100000000) from t1 limit 1;
|
||||||
|
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
||||||
|
data_length index_length
|
||||||
|
32704 32704
|
||||||
|
insert into t1 select rand(100000000) from t1 limit 1000;
|
||||||
|
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
||||||
|
data_length index_length
|
||||||
|
49056 65408
|
||||||
|
insert into t1 select rand(100000000) from t1;
|
||||||
|
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
||||||
|
data_length index_length
|
||||||
|
81760 114464
|
||||||
|
drop table t1;
|
50
mysql-test/suite/heap/heap_memory_used.test
Normal file
50
mysql-test/suite/heap/heap_memory_used.test
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
--echo #
|
||||||
|
--echo # Test of heap table memory usage
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--source include/word_size.inc
|
||||||
|
|
||||||
|
#
|
||||||
|
# Show that MIN_ROWS and MAX_ROWS have an effect on how data_length
|
||||||
|
# and index_length are allocated.
|
||||||
|
# Result is different for 32 / 64 bit machines as pointer lengths are different
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a int, index(a)) engine=heap min_rows=10 max_rows=100;
|
||||||
|
insert into t1 values(1);
|
||||||
|
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a int, index(a)) engine=heap min_rows=10 max_rows=10000;
|
||||||
|
insert into t1 values(1);
|
||||||
|
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
||||||
|
drop table t1;
|
||||||
|
CREATE TABLE t1 (a int, index(a)) engine=heap min_rows=3000 max_rows=3000;
|
||||||
|
insert into t1 values(1);
|
||||||
|
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
||||||
|
drop table t1;
|
||||||
|
CREATE TABLE t1 (a int, index(a)) engine=heap max_rows=15000;
|
||||||
|
insert into t1 values(1);
|
||||||
|
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
create table t1 (c1 int, index(c1)) engine=heap max_rows=10000;
|
||||||
|
insert into t1 select rand(100000000);
|
||||||
|
insert into t1 select rand(100000000) from t1;
|
||||||
|
insert into t1 select rand(100000000) from t1;
|
||||||
|
insert into t1 select rand(100000000) from t1;
|
||||||
|
insert into t1 select rand(100000000) from t1;
|
||||||
|
insert into t1 select rand(100000000) from t1;
|
||||||
|
insert into t1 select rand(100000000) from t1;
|
||||||
|
insert into t1 select rand(100000000) from t1;
|
||||||
|
insert into t1 select rand(100000000) from t1;
|
||||||
|
insert into t1 select rand(100000000) from t1;
|
||||||
|
insert into t1 select rand(100000000) from t1 limit 488;
|
||||||
|
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
||||||
|
insert into t1 select rand(100000000) from t1 limit 1;
|
||||||
|
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
||||||
|
insert into t1 select rand(100000000) from t1 limit 1000;
|
||||||
|
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
||||||
|
insert into t1 select rand(100000000) from t1;
|
||||||
|
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
|
||||||
|
drop table t1;
|
@@ -5,6 +5,8 @@ Note 1105 Cast to unsigned converted negative integer to it's positive complemen
|
|||||||
Note 1105 Cast to unsigned converted negative integer to it's positive complement
|
Note 1105 Cast to unsigned converted negative integer to it's positive complement
|
||||||
Warning 1292 Truncated incorrect aria_sort_buffer_size value: '18446744073709551615'
|
Warning 1292 Truncated incorrect aria_sort_buffer_size value: '18446744073709551615'
|
||||||
SET SESSION tmp_table_size=65535;
|
SET SESSION tmp_table_size=65535;
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Truncated incorrect tmp_table_size value: '65535'
|
||||||
CREATE TABLE t1 (a VARCHAR(255));
|
CREATE TABLE t1 (a VARCHAR(255));
|
||||||
insert into t1 (a) select seq from seq_1_to_1000;
|
insert into t1 (a) select seq from seq_1_to_1000;
|
||||||
UPDATE t1 SET a=( (SELECT MAX(a) FROM t1));
|
UPDATE t1 SET a=( (SELECT MAX(a) FROM t1));
|
||||||
|
@@ -2,6 +2,8 @@ SET sql_mode='';
|
|||||||
CREATE TEMPORARY TABLE t1 (a tinyINT,b CHAR(1)) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
|
CREATE TEMPORARY TABLE t1 (a tinyINT,b CHAR(1)) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
|
||||||
INSERT INTO t1 VALUES (1,1),(3,3),(2,2);
|
INSERT INTO t1 VALUES (1,1),(3,3),(2,2);
|
||||||
SET SESSION tmp_table_size=True;
|
SET SESSION tmp_table_size=True;
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Truncated incorrect tmp_table_size value: '1'
|
||||||
CREATE TABLE t2 (c INT, d DATE) ENGINE=InnoDB PARTITION BY RANGE (YEAR (d)) SUBPARTITION BY HASH (TO_DAYS (d)) (PARTITION p0 VALUES LESS THAN (1990) (SUBPARTITION s0, SUBPARTITION s1), PARTITION p1 VALUES LESS THAN MAXVALUE (SUBPARTITION s4, SUBPARTITION s5));
|
CREATE TABLE t2 (c INT, d DATE) ENGINE=InnoDB PARTITION BY RANGE (YEAR (d)) SUBPARTITION BY HASH (TO_DAYS (d)) (PARTITION p0 VALUES LESS THAN (1990) (SUBPARTITION s0, SUBPARTITION s1), PARTITION p1 VALUES LESS THAN MAXVALUE (SUBPARTITION s4, SUBPARTITION s5));
|
||||||
SET SESSION aria_sort_buffer_size=CAST(-1 AS UNSIGNED INT);
|
SET SESSION aria_sort_buffer_size=CAST(-1 AS UNSIGNED INT);
|
||||||
Warnings:
|
Warnings:
|
||||||
|
@@ -9,7 +9,7 @@ Warnings:
|
|||||||
Warning 1292 Truncated incorrect tmp_table_size value: '40960'
|
Warning 1292 Truncated incorrect tmp_table_size value: '40960'
|
||||||
SELECT @@session.tmp_table_size;
|
SELECT @@session.tmp_table_size;
|
||||||
@@session.tmp_table_size
|
@@session.tmp_table_size
|
||||||
8192
|
16384
|
||||||
SET @@session.max_join_size=40960;
|
SET @@session.max_join_size=40960;
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1292 Truncated incorrect max_join_size value: '40960'
|
Warning 1292 Truncated incorrect max_join_size value: '40960'
|
||||||
|
@@ -3718,7 +3718,7 @@ VARIABLE_TYPE BIGINT UNSIGNED
|
|||||||
VARIABLE_COMMENT If an internal in-memory temporary table exceeds this size, MariaDB will automatically convert it to an on-disk MyISAM or Aria table. Same as tmp_table_size.
|
VARIABLE_COMMENT If an internal in-memory temporary table exceeds this size, MariaDB will automatically convert it to an on-disk MyISAM or Aria table. Same as tmp_table_size.
|
||||||
NUMERIC_MIN_VALUE 0
|
NUMERIC_MIN_VALUE 0
|
||||||
NUMERIC_MAX_VALUE 18446744073709551615
|
NUMERIC_MAX_VALUE 18446744073709551615
|
||||||
NUMERIC_BLOCK_SIZE 1
|
NUMERIC_BLOCK_SIZE 16384
|
||||||
ENUM_VALUE_LIST NULL
|
ENUM_VALUE_LIST NULL
|
||||||
READ_ONLY NO
|
READ_ONLY NO
|
||||||
COMMAND_LINE_ARGUMENT REQUIRED
|
COMMAND_LINE_ARGUMENT REQUIRED
|
||||||
@@ -3728,7 +3728,7 @@ VARIABLE_TYPE BIGINT UNSIGNED
|
|||||||
VARIABLE_COMMENT Alias for tmp_memory_table_size. If an internal in-memory temporary table exceeds this size, MariaDB 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, MariaDB will automatically convert it to an on-disk MyISAM or Aria table.
|
||||||
NUMERIC_MIN_VALUE 0
|
NUMERIC_MIN_VALUE 0
|
||||||
NUMERIC_MAX_VALUE 18446744073709551615
|
NUMERIC_MAX_VALUE 18446744073709551615
|
||||||
NUMERIC_BLOCK_SIZE 1
|
NUMERIC_BLOCK_SIZE 16384
|
||||||
ENUM_VALUE_LIST NULL
|
ENUM_VALUE_LIST NULL
|
||||||
READ_ONLY NO
|
READ_ONLY NO
|
||||||
COMMAND_LINE_ARGUMENT REQUIRED
|
COMMAND_LINE_ARGUMENT REQUIRED
|
||||||
|
@@ -4498,7 +4498,7 @@ VARIABLE_TYPE BIGINT UNSIGNED
|
|||||||
VARIABLE_COMMENT If an internal in-memory temporary table exceeds this size, MariaDB will automatically convert it to an on-disk MyISAM or Aria table. Same as tmp_table_size.
|
VARIABLE_COMMENT If an internal in-memory temporary table exceeds this size, MariaDB will automatically convert it to an on-disk MyISAM or Aria table. Same as tmp_table_size.
|
||||||
NUMERIC_MIN_VALUE 0
|
NUMERIC_MIN_VALUE 0
|
||||||
NUMERIC_MAX_VALUE 18446744073709551615
|
NUMERIC_MAX_VALUE 18446744073709551615
|
||||||
NUMERIC_BLOCK_SIZE 1
|
NUMERIC_BLOCK_SIZE 16384
|
||||||
ENUM_VALUE_LIST NULL
|
ENUM_VALUE_LIST NULL
|
||||||
READ_ONLY NO
|
READ_ONLY NO
|
||||||
COMMAND_LINE_ARGUMENT REQUIRED
|
COMMAND_LINE_ARGUMENT REQUIRED
|
||||||
@@ -4508,7 +4508,7 @@ VARIABLE_TYPE BIGINT UNSIGNED
|
|||||||
VARIABLE_COMMENT Alias for tmp_memory_table_size. If an internal in-memory temporary table exceeds this size, MariaDB 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, MariaDB will automatically convert it to an on-disk MyISAM or Aria table.
|
||||||
NUMERIC_MIN_VALUE 0
|
NUMERIC_MIN_VALUE 0
|
||||||
NUMERIC_MAX_VALUE 18446744073709551615
|
NUMERIC_MAX_VALUE 18446744073709551615
|
||||||
NUMERIC_BLOCK_SIZE 1
|
NUMERIC_BLOCK_SIZE 16384
|
||||||
ENUM_VALUE_LIST NULL
|
ENUM_VALUE_LIST NULL
|
||||||
READ_ONLY NO
|
READ_ONLY NO
|
||||||
COMMAND_LINE_ARGUMENT REQUIRED
|
COMMAND_LINE_ARGUMENT REQUIRED
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
SET @start_tmp_memory_table_size=@@session.tmp_memory_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 @start_tmp_disk_table_size=@@session.tmp_disk_table_size;
|
||||||
set @@session.tmp_memory_table_size=1000;
|
set @@session.tmp_memory_table_size=16384;
|
||||||
set @@session.tmp_disk_table_size=3000000;
|
set @@session.tmp_disk_table_size=3000000;
|
||||||
create table t1 (a int primary key, b varchar(2000));
|
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 select seq,repeat(char(mod(seq,62)+64),seq) from seq_1_to_2000;
|
||||||
|
@@ -168,7 +168,6 @@ SET @@global.transaction_alloc_block_size = @start_global_value;
|
|||||||
SELECT @@global.transaction_alloc_block_size;
|
SELECT @@global.transaction_alloc_block_size;
|
||||||
@@global.transaction_alloc_block_size
|
@@global.transaction_alloc_block_size
|
||||||
8192
|
8192
|
||||||
SET @@session.tmp_table_size = @start_session_value;
|
|
||||||
SELECT @@session.transaction_alloc_block_size;
|
SELECT @@session.transaction_alloc_block_size;
|
||||||
@@session.transaction_alloc_block_size
|
@@session.transaction_alloc_block_size
|
||||||
1024
|
1024
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
--maximum-auto-increment-increment=8192
|
--maximum-auto-increment-increment=8192
|
||||||
--maximum-tmp-table-size=8192
|
--maximum-tmp-table-size=16384
|
||||||
--maximum-max-join-size=8192
|
--maximum-max-join-size=8192
|
||||||
--maximum-use-stat-tables=COMPLEMENTARY
|
--maximum-use-stat-tables=COMPLEMENTARY
|
||||||
--maximum-sql-mode='REAL_AS_FLOAT,ANSI_QUOTES'
|
--maximum-sql-mode='REAL_AS_FLOAT,ANSI_QUOTES'
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
SET @start_tmp_memory_table_size=@@session.tmp_memory_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 @start_tmp_disk_table_size=@@session.tmp_disk_table_size;
|
||||||
|
|
||||||
set @@session.tmp_memory_table_size=1000;
|
set @@session.tmp_memory_table_size=16384;
|
||||||
set @@session.tmp_disk_table_size=3000000;
|
set @@session.tmp_disk_table_size=3000000;
|
||||||
|
|
||||||
--disable_ps2_protocol
|
--disable_ps2_protocol
|
||||||
|
@@ -218,11 +218,9 @@ SELECT transaction_alloc_block_size = @@session.transaction_alloc_block_size;
|
|||||||
|
|
||||||
SET @@global.transaction_alloc_block_size = @start_global_value;
|
SET @@global.transaction_alloc_block_size = @start_global_value;
|
||||||
SELECT @@global.transaction_alloc_block_size;
|
SELECT @@global.transaction_alloc_block_size;
|
||||||
SET @@session.tmp_table_size = @start_session_value;
|
|
||||||
SELECT @@session.transaction_alloc_block_size;
|
SELECT @@session.transaction_alloc_block_size;
|
||||||
|
|
||||||
|
|
||||||
#############################################################
|
#############################################################
|
||||||
# END OF transaction_alloc_block_size TESTS #
|
# END OF transaction_alloc_block_size TESTS #
|
||||||
#############################################################
|
#############################################################
|
||||||
|
|
||||||
|
@@ -1117,7 +1117,7 @@ f varchar(45000)
|
|||||||
partition by system_time interval 1 year (partition p1 history,
|
partition by system_time interval 1 year (partition p1 history,
|
||||||
partition pn current);
|
partition pn current);
|
||||||
# fill the table until full
|
# fill the table until full
|
||||||
insert into t1 () values (),(),(),(),(),(),(),(),(),(),(),(),(),(),(),();
|
insert into t1 () values (),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),();
|
||||||
insert into t1 (f) select f from t1;
|
insert into t1 (f) select f from t1;
|
||||||
ERROR HY000: The table 't1' is full
|
ERROR HY000: The table 't1' is full
|
||||||
# leave space for exactly one record in current partition
|
# leave space for exactly one record in current partition
|
||||||
@@ -1133,7 +1133,7 @@ f varchar(45000)
|
|||||||
) with system versioning engine=memory
|
) with system versioning engine=memory
|
||||||
partition by system_time interval 1 year (partition p1 history,
|
partition by system_time interval 1 year (partition p1 history,
|
||||||
partition pn current);
|
partition pn current);
|
||||||
insert into t1 () values (),(),(),(),(),(),(),(),(),(),(),(),(),(),(),();
|
insert into t1 () values (),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),();
|
||||||
select * into outfile 'load.data' from t1;
|
select * into outfile 'load.data' from t1;
|
||||||
load data infile 'load.data' replace into table t1;
|
load data infile 'load.data' replace into table t1;
|
||||||
load data infile 'load.data' replace into table t1;
|
load data infile 'load.data' replace into table t1;
|
||||||
|
@@ -977,7 +977,7 @@ create or replace table t1 (
|
|||||||
partition pn current);
|
partition pn current);
|
||||||
|
|
||||||
--echo # fill the table until full
|
--echo # fill the table until full
|
||||||
insert into t1 () values (),(),(),(),(),(),(),(),(),(),(),(),(),(),(),();
|
insert into t1 () values (),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),();
|
||||||
--error ER_RECORD_FILE_FULL
|
--error ER_RECORD_FILE_FULL
|
||||||
insert into t1 (f) select f from t1;
|
insert into t1 (f) select f from t1;
|
||||||
--echo # leave space for exactly one record in current partition
|
--echo # leave space for exactly one record in current partition
|
||||||
@@ -995,7 +995,7 @@ create or replace table t1 (
|
|||||||
partition by system_time interval 1 year (partition p1 history,
|
partition by system_time interval 1 year (partition p1 history,
|
||||||
partition pn current);
|
partition pn current);
|
||||||
|
|
||||||
insert into t1 () values (),(),(),(),(),(),(),(),(),(),(),(),(),(),(),();
|
insert into t1 () values (),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),();
|
||||||
|
|
||||||
--disable_cursor_protocol
|
--disable_cursor_protocol
|
||||||
--disable_ps2_protocol
|
--disable_ps2_protocol
|
||||||
|
@@ -20577,7 +20577,7 @@ bool Create_tmp_table::finalize(THD *thd,
|
|||||||
MY_MIN(thd->variables.tmp_memory_table_size,
|
MY_MIN(thd->variables.tmp_memory_table_size,
|
||||||
thd->variables.max_heap_table_size) :
|
thd->variables.max_heap_table_size) :
|
||||||
thd->variables.tmp_disk_table_size) /
|
thd->variables.tmp_disk_table_size) /
|
||||||
share->reclength);
|
MY_ALIGN(share->reclength, sizeof(char*)));
|
||||||
set_if_bigger(share->max_rows,1); // For dummy start options
|
set_if_bigger(share->max_rows,1); // For dummy start options
|
||||||
/*
|
/*
|
||||||
Push the LIMIT clause to the temporary table creation, so that we
|
Push the LIMIT clause to the temporary table creation, so that we
|
||||||
|
@@ -4218,7 +4218,7 @@ static Sys_var_ulonglong Sys_tmp_table_size(
|
|||||||
"will automatically convert it to an on-disk MyISAM or Aria table.",
|
"will automatically convert it to an on-disk MyISAM or Aria table.",
|
||||||
SESSION_VAR(tmp_memory_table_size), CMD_LINE(REQUIRED_ARG),
|
SESSION_VAR(tmp_memory_table_size), CMD_LINE(REQUIRED_ARG),
|
||||||
VALID_RANGE(0, (ulonglong)~(intptr)0), DEFAULT(16*1024*1024),
|
VALID_RANGE(0, (ulonglong)~(intptr)0), DEFAULT(16*1024*1024),
|
||||||
BLOCK_SIZE(1));
|
BLOCK_SIZE(16384));
|
||||||
|
|
||||||
static Sys_var_ulonglong Sys_tmp_memory_table_size(
|
static Sys_var_ulonglong Sys_tmp_memory_table_size(
|
||||||
"tmp_memory_table_size",
|
"tmp_memory_table_size",
|
||||||
@@ -4227,7 +4227,7 @@ static Sys_var_ulonglong Sys_tmp_memory_table_size(
|
|||||||
"Same as tmp_table_size.",
|
"Same as tmp_table_size.",
|
||||||
SESSION_VAR(tmp_memory_table_size), CMD_LINE(REQUIRED_ARG),
|
SESSION_VAR(tmp_memory_table_size), CMD_LINE(REQUIRED_ARG),
|
||||||
VALID_RANGE(0, (ulonglong)~(intptr)0), DEFAULT(16*1024*1024),
|
VALID_RANGE(0, (ulonglong)~(intptr)0), DEFAULT(16*1024*1024),
|
||||||
BLOCK_SIZE(1));
|
BLOCK_SIZE(16384));
|
||||||
|
|
||||||
static Sys_var_ulonglong Sys_tmp_disk_table_size(
|
static Sys_var_ulonglong Sys_tmp_disk_table_size(
|
||||||
"tmp_disk_table_size",
|
"tmp_disk_table_size",
|
||||||
|
@@ -619,7 +619,7 @@ static int heap_prepare_hp_create_info(TABLE *table_arg, bool internal_table,
|
|||||||
case HA_KEY_ALG_UNDEF:
|
case HA_KEY_ALG_UNDEF:
|
||||||
case HA_KEY_ALG_HASH:
|
case HA_KEY_ALG_HASH:
|
||||||
keydef[key].algorithm= HA_KEY_ALG_HASH;
|
keydef[key].algorithm= HA_KEY_ALG_HASH;
|
||||||
mem_per_row+= sizeof(char*) * 2; // = sizeof(HASH_INFO)
|
mem_per_row+= sizeof(HASH_INFO);
|
||||||
break;
|
break;
|
||||||
case HA_KEY_ALG_BTREE:
|
case HA_KEY_ALG_BTREE:
|
||||||
keydef[key].algorithm= HA_KEY_ALG_BTREE;
|
keydef[key].algorithm= HA_KEY_ALG_BTREE;
|
||||||
@@ -688,7 +688,6 @@ static int heap_prepare_hp_create_info(TABLE *table_arg, bool internal_table,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mem_per_row+= MY_ALIGN(MY_MAX(share->reclength, sizeof(char*)) + 1, sizeof(char*));
|
|
||||||
if (table_arg->found_next_number_field)
|
if (table_arg->found_next_number_field)
|
||||||
{
|
{
|
||||||
keydef[share->next_number_index].flag|= HA_AUTO_KEY;
|
keydef[share->next_number_index].flag|= HA_AUTO_KEY;
|
||||||
@@ -696,11 +695,18 @@ static int heap_prepare_hp_create_info(TABLE *table_arg, bool internal_table,
|
|||||||
}
|
}
|
||||||
hp_create_info->auto_key= auto_key;
|
hp_create_info->auto_key= auto_key;
|
||||||
hp_create_info->auto_key_type= auto_key_type;
|
hp_create_info->auto_key_type= auto_key_type;
|
||||||
hp_create_info->max_table_size=current_thd->variables.max_heap_table_size;
|
hp_create_info->max_table_size= MY_MAX(current_thd->variables.max_heap_table_size, sizeof(HP_PTRS));
|
||||||
hp_create_info->with_auto_increment= found_real_auto_increment;
|
hp_create_info->with_auto_increment= found_real_auto_increment;
|
||||||
hp_create_info->internal_table= internal_table;
|
hp_create_info->internal_table= internal_table;
|
||||||
|
|
||||||
max_rows= (ha_rows) (hp_create_info->max_table_size / mem_per_row);
|
max_rows= hp_rows_in_memory(share->reclength, mem_per_row,
|
||||||
|
hp_create_info->max_table_size);
|
||||||
|
#ifdef GIVE_ERROR_IF_NOT_MEMORY_TO_INSERT_ONE_ROW
|
||||||
|
/* We do not give the error now but instead give an error on first insert */
|
||||||
|
if (!max_rows)
|
||||||
|
return HA_WRONG_CREATE_OPTION;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (share->max_rows && share->max_rows < max_rows)
|
if (share->max_rows && share->max_rows < max_rows)
|
||||||
max_rows= share->max_rows;
|
max_rows= share->max_rows;
|
||||||
|
|
||||||
|
@@ -100,6 +100,9 @@ extern void hp_clear(HP_SHARE *info);
|
|||||||
extern void hp_clear_keys(HP_SHARE *info);
|
extern void hp_clear_keys(HP_SHARE *info);
|
||||||
extern uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old,
|
extern uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old,
|
||||||
key_part_map keypart_map);
|
key_part_map keypart_map);
|
||||||
|
extern ha_rows hp_rows_in_memory(size_t reclength, size_t index_size,
|
||||||
|
size_t memory_limit);
|
||||||
|
extern size_t hp_memory_needed_per_row(size_t reclength);
|
||||||
|
|
||||||
extern mysql_mutex_t THR_LOCK_heap;
|
extern mysql_mutex_t THR_LOCK_heap;
|
||||||
|
|
||||||
|
@@ -75,9 +75,11 @@ int hp_get_new_block(HP_SHARE *info, HP_BLOCK *block, size_t *alloc_length)
|
|||||||
Next time we allocate data for X rows.
|
Next time we allocate data for X rows.
|
||||||
When level 1 is full, we allocate data for HP_PTRS_IN_NOD at level 2 and 1
|
When level 1 is full, we allocate data for HP_PTRS_IN_NOD at level 2 and 1
|
||||||
+ X rows at level 0.
|
+ X rows at level 0.
|
||||||
*/
|
*/
|
||||||
*alloc_length= (sizeof(HP_PTRS) * ((i == block->levels) ? i : i - 1) +
|
*alloc_length= (sizeof(HP_PTRS) * ((i == block->levels) ? i : i - 1) +
|
||||||
(ulonglong)block->records_in_block * block->recbuffer);
|
(ulonglong)block->records_in_block * block->recbuffer);
|
||||||
|
/* Alloc in blocks of powers of 2 */
|
||||||
|
*alloc_length= MY_MAX(*alloc_length, block->alloc_size);
|
||||||
if (!(root=(HP_PTRS*) my_malloc(hp_key_memory_HP_PTRS, *alloc_length,
|
if (!(root=(HP_PTRS*) my_malloc(hp_key_memory_HP_PTRS, *alloc_length,
|
||||||
MYF(MY_WME |
|
MYF(MY_WME |
|
||||||
(info->internal ?
|
(info->internal ?
|
||||||
|
@@ -15,11 +15,23 @@
|
|||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
|
||||||
|
|
||||||
#include "heapdef.h"
|
#include "heapdef.h"
|
||||||
|
#include <my_bit.h>
|
||||||
|
|
||||||
static int keys_compare(void *heap_rb, const void *key1, const void *key2);
|
static int keys_compare(void *heap_rb, const void *key1, const void *key2);
|
||||||
static void init_block(HP_BLOCK *block,uint reclength,ulong min_records,
|
static void init_block(HP_BLOCK *block, size_t reclength, ulong min_records,
|
||||||
ulong max_records);
|
ulong max_records);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
In how many parts are we going to do allocations of memory and indexes
|
||||||
|
If we assigne 1M to the heap table memory, we will allocate roughly
|
||||||
|
(1M/16) bytes per allocaiton
|
||||||
|
*/
|
||||||
|
static const int heap_allocation_parts= 16;
|
||||||
|
|
||||||
|
/* min block allocation */
|
||||||
|
static const ulong heap_min_allocation_block= 16384;
|
||||||
|
|
||||||
/* Create a heap table */
|
/* Create a heap table */
|
||||||
|
|
||||||
int heap_create(const char *name, HP_CREATE_INFO *create_info,
|
int heap_create(const char *name, HP_CREATE_INFO *create_info,
|
||||||
@@ -170,7 +182,8 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info,
|
|||||||
share->keydef= (HP_KEYDEF*) (share + 1);
|
share->keydef= (HP_KEYDEF*) (share + 1);
|
||||||
share->key_stat_version= 1;
|
share->key_stat_version= 1;
|
||||||
keyseg= (HA_KEYSEG*) (share->keydef + keys);
|
keyseg= (HA_KEYSEG*) (share->keydef + keys);
|
||||||
init_block(&share->block, visible_offset + 1, min_records, max_records);
|
init_block(&share->block, hp_memory_needed_per_row(reclength),
|
||||||
|
min_records, max_records);
|
||||||
/* Fix keys */
|
/* Fix keys */
|
||||||
memcpy(share->keydef, keydef, (size_t) (sizeof(keydef[0]) * keys));
|
memcpy(share->keydef, keydef, (size_t) (sizeof(keydef[0]) * keys));
|
||||||
for (i= 0, keyinfo= share->keydef; i < keys; i++, keyinfo++)
|
for (i= 0, keyinfo= share->keydef; i < keys; i++, keyinfo++)
|
||||||
@@ -266,44 +279,90 @@ static int keys_compare(void *heap_rb_, const void *key1_,
|
|||||||
heap_rb->search_flag, not_used);
|
heap_rb->search_flag, not_used);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_block(HP_BLOCK *block, uint reclength, ulong min_records,
|
|
||||||
|
/*
|
||||||
|
Calculate length needed for storing one row
|
||||||
|
*/
|
||||||
|
|
||||||
|
size_t hp_memory_needed_per_row(size_t reclength)
|
||||||
|
{
|
||||||
|
/* Data needed for storing record + pointer to records */
|
||||||
|
reclength= MY_MAX(reclength, sizeof(char*));
|
||||||
|
/* The + 1 below is for the delete marker at the end of record*/
|
||||||
|
reclength= MY_ALIGN(reclength+1, sizeof(char*));
|
||||||
|
return reclength;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Calculate the number of rows that fits into a given memory size
|
||||||
|
*/
|
||||||
|
|
||||||
|
ha_rows hp_rows_in_memory(size_t reclength, size_t index_size,
|
||||||
|
size_t memory_limit)
|
||||||
|
{
|
||||||
|
reclength= hp_memory_needed_per_row(reclength);
|
||||||
|
if ((memory_limit < index_size + reclength + sizeof(HP_PTRS)))
|
||||||
|
return 0; /* Wrong arguments */
|
||||||
|
return (ha_rows) ((memory_limit - sizeof(HP_PTRS)) /
|
||||||
|
(index_size + reclength));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void init_block(HP_BLOCK *block, size_t reclength, ulong min_records,
|
||||||
ulong max_records)
|
ulong max_records)
|
||||||
{
|
{
|
||||||
ulong i,recbuffer,records_in_block;
|
ulong i,records_in_block;
|
||||||
|
ulong recbuffer= (ulong) MY_ALIGN(reclength, sizeof(uchar*));
|
||||||
|
ulong extra;
|
||||||
|
ulonglong memory_needed;
|
||||||
|
size_t alloc_size;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If not min_records and max_records are given, optimize for 1000 rows
|
If not min_records and max_records are given, optimize for 1000 rows
|
||||||
*/
|
*/
|
||||||
if (!min_records)
|
if (!min_records)
|
||||||
min_records= MY_MIN(1000, max_records);
|
min_records= MY_MIN(1000, max_records / heap_allocation_parts);
|
||||||
if (!max_records)
|
if (!max_records)
|
||||||
max_records= MY_MAX(min_records, 1000);
|
max_records= MY_MAX(min_records, 1000);
|
||||||
|
min_records= MY_MIN(min_records, max_records);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We don't want too few records_in_block as otherwise the overhead of
|
We don't want too few records_in_block as otherwise the overhead of
|
||||||
of the HP_PTRS block will be too notable
|
of the HP_PTRS block will be too notable
|
||||||
*/
|
*/
|
||||||
records_in_block= MY_MAX(1000, min_records);
|
records_in_block= MY_MAX(min_records, max_records / heap_allocation_parts);
|
||||||
records_in_block= MY_MIN(records_in_block, max_records);
|
|
||||||
/* If big max_records is given, allocate bigger blocks */
|
/*
|
||||||
records_in_block= MY_MAX(records_in_block, max_records / 10);
|
Align allocation sizes to power of 2 to get less memory fragmentation from
|
||||||
|
system alloc().
|
||||||
|
As long as we have less than 128 allocations, all but one of the
|
||||||
|
allocations will have an extra HP_PTRS size structure at the start
|
||||||
|
of the block.
|
||||||
|
|
||||||
|
We ensure that the block is not smaller than heap_min_allocation_block
|
||||||
|
as otherwise we get strange results when max_records <
|
||||||
|
heap_allocation_parts)
|
||||||
|
*/
|
||||||
|
extra= sizeof(HP_PTRS) + MALLOC_OVERHEAD;
|
||||||
|
|
||||||
/* We don't want too few blocks per row either */
|
/* We don't want too few blocks per row either */
|
||||||
if (records_in_block < 10)
|
if (records_in_block < 10)
|
||||||
records_in_block= 10;
|
records_in_block= MY_MIN(10, max_records);
|
||||||
|
memory_needed= MY_MAX(((ulonglong) records_in_block * recbuffer + extra),
|
||||||
|
(ulonglong) heap_min_allocation_block);
|
||||||
|
|
||||||
|
/* We have to limit memory to INT_MAX32 as my_round_up_to_next_power() is 32 bit */
|
||||||
|
memory_needed= MY_MIN(memory_needed, (ulonglong) INT_MAX32);
|
||||||
|
alloc_size= my_round_up_to_next_power((uint32)memory_needed);
|
||||||
|
records_in_block= (ulong) ((alloc_size - extra)/ recbuffer);
|
||||||
|
|
||||||
|
DBUG_PRINT("info", ("records_in_block: %lu" ,records_in_block));
|
||||||
|
|
||||||
recbuffer= (uint) (reclength + sizeof(uchar**) - 1) & ~(sizeof(uchar**) - 1);
|
|
||||||
/*
|
|
||||||
Don't allocate more than my_default_record_cache_size per level.
|
|
||||||
The + 1 is there to ensure that we get at least 1 row per level (for
|
|
||||||
the exceptional case of very long rows)
|
|
||||||
*/
|
|
||||||
if ((ulonglong) records_in_block*recbuffer >
|
|
||||||
(my_default_record_cache_size-sizeof(HP_PTRS)*HP_MAX_LEVELS))
|
|
||||||
records_in_block= (my_default_record_cache_size - sizeof(HP_PTRS) *
|
|
||||||
HP_MAX_LEVELS) / recbuffer + 1;
|
|
||||||
block->records_in_block= records_in_block;
|
block->records_in_block= records_in_block;
|
||||||
block->recbuffer= recbuffer;
|
block->recbuffer= recbuffer;
|
||||||
block->last_allocated= 0L;
|
block->last_allocated= 0L;
|
||||||
|
/* All alloctions are done with this size, if possible */
|
||||||
|
block->alloc_size= alloc_size - MALLOC_OVERHEAD;
|
||||||
|
|
||||||
for (i= 0; i <= HP_MAX_LEVELS; i++)
|
for (i= 0; i <= HP_MAX_LEVELS; i++)
|
||||||
block->level_info[i].records_under_level=
|
block->level_info[i].records_under_level=
|
||||||
|
@@ -145,21 +145,22 @@ static uchar *next_free_record_pos(HP_SHARE *info)
|
|||||||
DBUG_PRINT("exit",("Used old position: %p", pos));
|
DBUG_PRINT("exit",("Used old position: %p", pos));
|
||||||
DBUG_RETURN(pos);
|
DBUG_RETURN(pos);
|
||||||
}
|
}
|
||||||
if ((info->records > info->max_records && info->max_records) ||
|
|
||||||
(info->data_length + info->index_length >= info->max_table_size))
|
|
||||||
{
|
|
||||||
DBUG_PRINT("error",
|
|
||||||
("record file full. records: %lu max_records: %lu "
|
|
||||||
"data_length: %llu index_length: %llu "
|
|
||||||
"max_table_size: %llu",
|
|
||||||
info->records, info->max_records,
|
|
||||||
info->data_length, info->index_length,
|
|
||||||
info->max_table_size));
|
|
||||||
my_errno=HA_ERR_RECORD_FILE_FULL;
|
|
||||||
DBUG_RETURN(NULL);
|
|
||||||
}
|
|
||||||
if (!(block_pos=(info->records % info->block.records_in_block)))
|
if (!(block_pos=(info->records % info->block.records_in_block)))
|
||||||
{
|
{
|
||||||
|
if ((info->records > info->max_records && info->max_records) ||
|
||||||
|
(info->data_length + info->index_length >= info->max_table_size))
|
||||||
|
{
|
||||||
|
DBUG_PRINT("error",
|
||||||
|
("record file full. records: %lu max_records: %lu "
|
||||||
|
"data_length: %llu index_length: %llu "
|
||||||
|
"max_table_size: %llu",
|
||||||
|
info->records, info->max_records,
|
||||||
|
info->data_length, info->index_length,
|
||||||
|
info->max_table_size));
|
||||||
|
my_errno=HA_ERR_RECORD_FILE_FULL;
|
||||||
|
DBUG_RETURN(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (hp_get_new_block(info, &info->block,&length))
|
if (hp_get_new_block(info, &info->block,&length))
|
||||||
DBUG_RETURN(NULL);
|
DBUG_RETURN(NULL);
|
||||||
info->data_length+=length;
|
info->data_length+=length;
|
||||||
|
Reference in New Issue
Block a user