Commit 9ec19b9b authored by Monty's avatar Monty

Reducing memory when using information schema

The background is that one user had a lot of views and using some complex
queries on information schema temporary memory of more than 2G was used.

- Added new element 'total_alloc' to MEM_ROOT for easier debugging.
- Added MAX_MEMORY_USED to information_schema.processlist.
- Added new status variable "Memory_used_initial" that shows how much MariaDB
  uses at startup. This gives the base value for "Memory_used".
- Reuse memory continuously for information schema queries instead of
  only freeing memory at query end.

Other things
- Removed some not needed set_notnull() calls for not null columns.
parent 2ec7b870
......@@ -43,6 +43,7 @@ typedef struct st_mem_root
/* if block have less memory it will be put in 'used' list */
size_t min_malloc;
size_t block_size; /* initial block size */
size_t total_alloc;
unsigned int block_num; /* allocated blocks counter */
/*
first free block in queue test counter (if it exceed
......
......@@ -236,6 +236,7 @@ typedef struct st_mem_root
USED_MEM *pre_alloc;
size_t min_malloc;
size_t block_size;
size_t total_alloc;
unsigned int block_num;
unsigned int first_block_usage;
void (*error_handler)(void);
......
......@@ -1173,6 +1173,7 @@ t1 CREATE TABLE `t1` (
`MAX_STAGE` tinyint(2) NOT NULL DEFAULT 0,
`PROGRESS` decimal(7,3) NOT NULL DEFAULT 0.000,
`MEMORY_USED` bigint(7) NOT NULL DEFAULT 0,
`MAX_MEMORY_USED` bigint(7) NOT NULL DEFAULT 0,
`EXAMINED_ROWS` int(7) NOT NULL DEFAULT 0,
`QUERY_ID` bigint(4) NOT NULL DEFAULT 0,
`INFO_BINARY` blob DEFAULT NULL,
......@@ -1196,6 +1197,7 @@ t1 CREATE TEMPORARY TABLE `t1` (
`MAX_STAGE` tinyint(2) NOT NULL DEFAULT 0,
`PROGRESS` decimal(7,3) NOT NULL DEFAULT 0.000,
`MEMORY_USED` bigint(7) NOT NULL DEFAULT 0,
`MAX_MEMORY_USED` bigint(7) NOT NULL DEFAULT 0,
`EXAMINED_ROWS` int(7) NOT NULL DEFAULT 0,
`QUERY_ID` bigint(4) NOT NULL DEFAULT 0,
`INFO_BINARY` blob DEFAULT NULL,
......
......@@ -158,7 +158,7 @@ WHERE DB = 'information_schema' AND COMMAND = 'Sleep' AND USER = 'ddicttestuser1
eval SHOW CREATE TABLE $table;
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS
eval SHOW $table;
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 MAX_MEMORY 15 ROWS 16 QUERY_ID 18 TID
eval SELECT * FROM $table $select_where ORDER BY id;
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID
eval SELECT $columns FROM $table $select_where ORDER BY id;
......@@ -178,7 +178,7 @@ connection con100;
eval SHOW CREATE TABLE $table;
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS
eval SHOW $table;
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 MAX_MEMORY 15 ROWS 16 QUERY_ID 18 TID
eval SELECT * FROM $table $select_where ORDER BY id;
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID
eval SELECT $columns FROM $table $select_where ORDER BY id;
......@@ -204,7 +204,7 @@ connection con100;
SHOW GRANTS;
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS
SHOW processlist;
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 MAX_MEMORY 15 ROWS 16 QUERY_ID 18 TID
SELECT * FROM information_schema.processlist;
--real_sleep 0.3
......@@ -216,7 +216,7 @@ connect (con101,localhost,ddicttestuser1,ddictpass,information_schema);
SHOW GRANTS;
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS
SHOW processlist;
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 MAX_MEMORY 15 ROWS 16 QUERY_ID 18 TID
SELECT * FROM information_schema.processlist;
--real_sleep 0.3
......@@ -239,7 +239,7 @@ connect (anonymous1,localhost,"''",,information_schema);
SHOW GRANTS;
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS
SHOW processlist;
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 MAX_MEMORY 15 ROWS 16 QUERY_ID 18 TID
SELECT * FROM information_schema.processlist;
--real_sleep 0.3
......@@ -261,7 +261,7 @@ connect (con102,localhost,ddicttestuser1,ddictpass,information_schema);
SHOW GRANTS;
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS
SHOW processlist;
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 MAX_MEMORY 15 ROWS 16 QUERY_ID 18 TID
SELECT * FROM information_schema.processlist;
--real_sleep 0.3
......@@ -287,7 +287,7 @@ if ($fixed_bug_30395)
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS
SHOW processlist;
}
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 MAX_MEMORY 15 ROWS 16 QUERY_ID 18 TID
SELECT * FROM information_schema.processlist;
--real_sleep 0.3
......@@ -308,7 +308,7 @@ connect (con103,localhost,ddicttestuser1,ddictpass,information_schema);
SHOW GRANTS FOR 'ddicttestuser1'@'localhost';
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS
SHOW processlist;
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 MAX_MEMORY 15 ROWS 16 QUERY_ID 18 TID
SELECT * FROM information_schema.processlist;
--real_sleep 0.3
......@@ -330,7 +330,7 @@ connect (con104,localhost,ddicttestuser1,ddictpass,information_schema);
SHOW GRANTS FOR 'ddicttestuser1'@'localhost';
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS
SHOW processlist;
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 MAX_MEMORY 15 ROWS 16 QUERY_ID 18 TID
SELECT * FROM information_schema.processlist;
--real_sleep 0.3
......@@ -377,7 +377,7 @@ connect (con200,localhost,ddicttestuser2,ddictpass,information_schema);
SHOW GRANTS FOR 'ddicttestuser2'@'localhost';
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS
SHOW processlist;
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 MAX_MEMORY 15 ROWS 16 QUERY_ID 18 TID
SELECT * FROM information_schema.processlist;
--real_sleep 0.3
......@@ -398,7 +398,7 @@ connect (con201,localhost,ddicttestuser2,ddictpass,information_schema);
SHOW GRANTS;
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS
SHOW processlist;
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 MAX_MEMORY 15 ROWS 16 QUERY_ID 18 TID
SELECT * FROM information_schema.processlist;
--real_sleep 0.3
......@@ -421,7 +421,7 @@ SHOW GRANTS FOR 'ddicttestuser1'@'localhost';
GRANT PROCESS ON *.* TO 'ddicttestuser2'@'localhost';
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS
SHOW processlist;
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 MAX_MEMORY 15 ROWS 16 QUERY_ID 18 TID
SELECT * FROM information_schema.processlist;
--real_sleep 0.3
......@@ -445,7 +445,7 @@ connect (con108,localhost,ddicttestuser1,ddictpass,information_schema);
SHOW GRANTS FOR 'ddicttestuser1'@'localhost';
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS
SHOW processlist;
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID
--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 MAX_MEMORY 15 ROWS 16 QUERY_ID 18 TID
SELECT * FROM information_schema.processlist;
--real_sleep 0.3
......
......@@ -92,7 +92,7 @@ echo
# - INFO must contain the corresponding SHOW/SELECT PROCESSLIST
#
# 1. Just dump what we get
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> 13 <MEMORY> 14 <ROWS> 15 <QUERY_ID> 17 <TID>
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> 13 <MEMORY> 14 <MAX_MEMORY> 15 <ROWS> 16 <QUERY_ID> 18 <TID>
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> 13 <MEMORY> 14 <ROWS>
SHOW FULL PROCESSLIST;
......@@ -159,7 +159,7 @@ let $wait_condition= SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST
WHERE COMMAND = 'Sleep' AND USER = 'test_user';
--source include/wait_condition.inc
# 1. Just dump what we get
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 7 <STATE> 9 <TIME_MS> 13 <MEMORY> 14 <ROWS> 15 <QUERY_ID> 17 <TID>
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 7 <STATE> 9 <TIME_MS> 13 <MEMORY> 14 <MAX_MEMORY> 15 <ROWS> 16 <QUERY_ID> 18 <TID>
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME>
SHOW FULL PROCESSLIST;
......@@ -201,7 +201,7 @@ echo
#----------------------------------------------------------------------------
;
connection con1;
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> 13 <MEMORY> 14 <ROWS> 15 <QUERY_ID> 17 <TID>
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> 13 <MEMORY> 14 <MAX_MEMORY> 15 <ROWS> 16 <QUERY_ID> 18 <TID>
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME>
SHOW FULL PROCESSLIST;
......@@ -226,7 +226,7 @@ let $wait_condition= SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.PROCESSLIST
--source include/wait_condition.inc
connection con2;
# Just dump what we get
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> 13 <MEMORY> 14 <ROWS> 15 <QUERY_ID> 17 <TID>
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> 13 <MEMORY> 14 <MAX_MEMORY> 15 <ROWS> 16 <QUERY_ID> 18 <TID>
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME>
SHOW FULL PROCESSLIST;
......@@ -277,7 +277,7 @@ WHERE ID = @test_user_con2_id AND Command IN('Query','Execute')
AND State = 'User sleep' AND INFO IS NOT NULL ;
--source include/wait_condition.inc
# 1. Just dump what we get
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> 13 <MEMORY> 14 <ROWS> 15 <QUERY_ID> 17 <TID>
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> 13 <MEMORY> 14 <MAX_MEMORY> 15 <ROWS> 16 <QUERY_ID> 18 <TID>
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME>
SHOW FULL PROCESSLIST;
......@@ -336,7 +336,7 @@ let $wait_condition= SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST
#
# Expect to see the state 'Waiting for table metadata lock' for the third
# connection because the SELECT collides with the WRITE TABLE LOCK.
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> 13 <MEMORY> 14 <ROWS> 15 <QUERY_ID> 17 <TID>
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> 13 <MEMORY> 14 <MAX_MEMORY> 15 <ROWS> 16 <QUERY_ID> 18 <TID>
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
UNLOCK TABLES;
#
......@@ -383,7 +383,7 @@ echo
# SHOW FULL PROCESSLIST Complete statement
# SHOW PROCESSLIST statement truncated after 100 char
;
--replace_column 1 <ID> 3 <HOST_NAME> 5 <COMMAND> 6 <TIME> 7 <STATE> 9 <TIME_MS> 13 <MEMORY> 14 <ROWS> 15 <QUERY_ID> 17 <TID>
--replace_column 1 <ID> 3 <HOST_NAME> 5 <COMMAND> 6 <TIME> 7 <STATE> 9 <TIME_MS> 13 <MEMORY> 14 <MAX_MEMORY> 15 <ROWS> 16 <QUERY_ID> 18 <TID>
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
--replace_column 1 <ID> 3 <HOST_NAME> 5 <COMMAND> 6 <TIME> 7 <STATE>
SHOW FULL PROCESSLIST;
......
......@@ -256,18 +256,19 @@ def information_schema PLUGINS PLUGIN_TYPE_VERSION 5 '' NO varchar 20 60 NULL NU
def information_schema PLUGINS PLUGIN_VERSION 2 '' NO varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) select NEVER NULL
def information_schema PROCESSLIST COMMAND 5 '' NO varchar 16 48 NULL NULL NULL utf8 utf8_general_ci varchar(16) select NEVER NULL
def information_schema PROCESSLIST DB 4 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select NEVER NULL
def information_schema PROCESSLIST EXAMINED_ROWS 14 0 NO int NULL NULL 10 0 NULL NULL NULL int(7) select NEVER NULL
def information_schema PROCESSLIST EXAMINED_ROWS 15 0 NO int NULL NULL 10 0 NULL NULL NULL int(7) select NEVER NULL
def information_schema PROCESSLIST HOST 3 '' NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select NEVER NULL
def information_schema PROCESSLIST ID 1 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(4) select NEVER NULL
def information_schema PROCESSLIST INFO 8 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext select NEVER NULL
def information_schema PROCESSLIST INFO_BINARY 16 NULL YES blob 65535 65535 NULL NULL NULL NULL NULL blob select NEVER NULL
def information_schema PROCESSLIST INFO_BINARY 17 NULL YES blob 65535 65535 NULL NULL NULL NULL NULL blob select NEVER NULL
def information_schema PROCESSLIST MAX_MEMORY_USED 14 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(7) select NEVER NULL
def information_schema PROCESSLIST MAX_STAGE 11 0 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(2) select NEVER NULL
def information_schema PROCESSLIST MEMORY_USED 13 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(7) select NEVER NULL
def information_schema PROCESSLIST PROGRESS 12 0.000 NO decimal NULL NULL 7 3 NULL NULL NULL decimal(7,3) select NEVER NULL
def information_schema PROCESSLIST QUERY_ID 15 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(4) select NEVER NULL
def information_schema PROCESSLIST QUERY_ID 16 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(4) select NEVER NULL
def information_schema PROCESSLIST STAGE 10 0 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(2) select NEVER NULL
def information_schema PROCESSLIST STATE 7 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select NEVER NULL
def information_schema PROCESSLIST TID 17 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(4) select NEVER NULL
def information_schema PROCESSLIST TID 18 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(4) select NEVER NULL
def information_schema PROCESSLIST TIME 6 0 NO int NULL NULL 10 0 NULL NULL NULL int(7) select NEVER NULL
def information_schema PROCESSLIST TIME_MS 9 0.000 NO decimal NULL NULL 22 3 NULL NULL NULL decimal(22,3) select NEVER NULL
def information_schema PROCESSLIST USER 2 '' NO varchar 128 384 NULL NULL NULL utf8 utf8_general_ci varchar(128) select NEVER NULL
......@@ -797,6 +798,7 @@ NULL information_schema PROCESSLIST STAGE tinyint NULL NULL NULL NULL tinyint(2)
NULL information_schema PROCESSLIST MAX_STAGE tinyint NULL NULL NULL NULL tinyint(2)
NULL information_schema PROCESSLIST PROGRESS decimal NULL NULL NULL NULL decimal(7,3)
NULL information_schema PROCESSLIST MEMORY_USED bigint NULL NULL NULL NULL bigint(7)
NULL information_schema PROCESSLIST MAX_MEMORY_USED bigint NULL NULL NULL NULL bigint(7)
NULL information_schema PROCESSLIST EXAMINED_ROWS int NULL NULL NULL NULL int(7)
NULL information_schema PROCESSLIST QUERY_ID bigint NULL NULL NULL NULL bigint(4)
1.0000 information_schema PROCESSLIST INFO_BINARY blob 65535 65535 NULL NULL blob
......
......@@ -68,6 +68,7 @@ void init_alloc_root(MEM_ROOT *mem_root, size_t block_size,
mem_root->error_handler= 0;
mem_root->block_num= 4; /* We shift this with >>2 */
mem_root->first_block_usage= 0;
mem_root->total_alloc= 0;
#if !(defined(HAVE_valgrind) && defined(EXTRA_DEBUG))
if (pre_alloc_size)
......@@ -77,6 +78,7 @@ void init_alloc_root(MEM_ROOT *mem_root, size_t block_size,
MYF(my_flags))))
{
mem_root->free->size= pre_alloc_size+ALIGN_SIZE(sizeof(USED_MEM));
mem_root->total_alloc= pre_alloc_size+ALIGN_SIZE(sizeof(USED_MEM));
mem_root->free->left= pre_alloc_size;
mem_root->free->next= 0;
}
......@@ -134,6 +136,7 @@ void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size,
{
/* remove block from the list and free it */
*prev= mem->next;
mem_root->total_alloc-= mem->size;
my_free(mem);
}
else
......@@ -145,9 +148,10 @@ void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size,
block_size)))))
{
mem->size= size;
mem_root->total_alloc+= size;
mem->left= pre_alloc_size;
mem->next= *prev;
*prev= mem_root->pre_alloc= mem;
*prev= mem_root->pre_alloc= mem;
}
else
{
......@@ -190,8 +194,10 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length)
DBUG_RETURN((uchar*) 0); /* purecov: inspected */
}
next->next= mem_root->used;
next->left= 0;
next->size= length;
mem_root->used= next;
mem_root->total_alloc+= length;
DBUG_PRINT("exit",("ptr: %p", (((char*) next)+
ALIGN_SIZE(sizeof(USED_MEM)))));
DBUG_RETURN((uchar*) (((char*) next)+ALIGN_SIZE(sizeof(USED_MEM))));
......@@ -244,6 +250,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length)
DBUG_RETURN((void*) 0); /* purecov: inspected */
}
mem_root->block_num++;
mem_root->total_alloc+= get_size;
next->next= *prev;
next->size= get_size;
next->left= get_size-ALIGN_SIZE(sizeof(USED_MEM));
......@@ -346,6 +353,7 @@ static inline void mark_blocks_free(MEM_ROOT* root)
/* Now everything is set; Indicate that nothing is used anymore */
root->used= 0;
root->first_block_usage= 0;
root->block_num= 4;
}
......@@ -374,11 +382,17 @@ void free_root(MEM_ROOT *root, myf MyFlags)
DBUG_ENTER("free_root");
DBUG_PRINT("enter",("root: %p flags: %u", root, (uint) MyFlags));
#if !(defined(HAVE_valgrind) && defined(EXTRA_DEBUG))
/*
There is no point in using mark_blocks_free when using valgrind as
it will not reclaim any memory
*/
if (MyFlags & MY_MARK_BLOCKS_FREE)
{
mark_blocks_free(root);
DBUG_VOID_RETURN;
}
#endif
if (!(MyFlags & MY_KEEP_PREALLOC))
root->pre_alloc=0;
......@@ -386,13 +400,19 @@ void free_root(MEM_ROOT *root, myf MyFlags)
{
old=next; next= next->next ;
if (old != root->pre_alloc)
{
root->total_alloc-= old->size;
my_free(old);
}
}
for (next=root->free ; next ;)
{
old=next; next= next->next;
if (old != root->pre_alloc)
{
root->total_alloc-= old->size;
my_free(old);
}
}
root->used=root->free=0;
if (root->pre_alloc)
......
......@@ -381,6 +381,7 @@ mysql_cond_t COND_thread_cache;
static mysql_cond_t COND_flush_thread_cache;
mysql_cond_t COND_slave_background;
static DYNAMIC_ARRAY all_options;
static longlong start_memory_used;
/* Global variables */
......@@ -4040,6 +4041,8 @@ static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific)
(longlong) thd->status_var.local_memory_used,
size));
thd->status_var.local_memory_used+= size;
set_if_bigger(thd->status_var.max_local_memory_used,
thd->status_var.local_memory_used);
if (size > 0 &&
thd->status_var.local_memory_used > (int64)thd->variables.max_mem_used &&
!thd->killed && !thd->get_stmt_da()->is_set())
......@@ -6065,6 +6068,9 @@ int mysqld_main(int argc, char **argv)
MYSQL_SET_STAGE(0 ,__FILE__, __LINE__);
/* Memory used when everything is setup */
start_memory_used= global_status_var.global_memory_used;
#if defined(_WIN32) || defined(HAVE_SMEM)
handle_connections_methods();
#else
......@@ -8462,6 +8468,7 @@ SHOW_VAR status_vars[]= {
{"Master_gtid_wait_time", (char*) offsetof(STATUS_VAR, master_gtid_wait_time), SHOW_LONGLONG_STATUS},
{"Max_used_connections", (char*) &max_used_connections, SHOW_LONG},
{"Memory_used", (char*) &show_memory_used, SHOW_SIMPLE_FUNC},
{"Memory_used_initial", (char*) &start_memory_used, SHOW_LONGLONG},
{"Not_flushed_delayed_rows", (char*) &delayed_rows_in_use, SHOW_LONG_NOFLUSH},
{"Open_files", (char*) &my_file_opened, SHOW_LONG_NOFLUSH},
{"Open_streams", (char*) &my_stream_opened, SHOW_LONG_NOFLUSH},
......
......@@ -815,6 +815,7 @@ typedef struct system_status_var
double cpu_time, busy_time;
/* Don't initialize */
/* Memory used for thread local storage */
int64 max_local_memory_used;
volatile int64 local_memory_used;
/* Memory allocated for global usage */
volatile int64 global_memory_used;
......@@ -4513,7 +4514,6 @@ class THD :public Statement,
See also sp_head::merge_lex().
*/
bool restore_from_local_lex_to_old_lex(LEX *oldlex);
};
inline void add_to_active_threads(THD *thd)
......
......@@ -175,6 +175,11 @@
#define TABLE_ALLOC_BLOCK_SIZE 1024
#define WARN_ALLOC_BLOCK_SIZE 2048
#define WARN_ALLOC_PREALLOC_SIZE 1024
/*
Note that if we are using 32K or less, then TCmalloc will use a local
heap without locks!
*/
#define SHOW_ALLOC_BLOCK_SIZE (32768-MALLOC_OVERHEAD)
/*
The following parameters is to decide when to use an extra cache to
......
......@@ -93,7 +93,6 @@ enum enum_i_s_events_fields
#define USERNAME_WITH_HOST_CHAR_LENGTH (USERNAME_CHAR_LENGTH + HOSTNAME_LENGTH + 2)
static const LEX_CSTRING trg_action_time_type_names[]=
{
{ STRING_WITH_LEN("BEFORE") },
......@@ -3092,17 +3091,17 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
{
table->field[7]->store(tmp->query(),
MY_MIN(PROCESS_LIST_INFO_WIDTH,
tmp->query_length()), cs);
tmp->query_length()), cs);
table->field[7]->set_notnull();
}
/* INFO_BINARY */
if (tmp->query())
{
table->field[15]->store(tmp->query(),
table->field[16]->store(tmp->query(),
MY_MIN(PROCESS_LIST_INFO_WIDTH,
tmp->query_length()), &my_charset_bin);
table->field[15]->set_notnull();
table->field[16]->set_notnull();
}
/*
......@@ -3125,14 +3124,14 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
*/
table->field[12]->store((longlong) tmp->status_var.local_memory_used,
FALSE);
table->field[12]->set_notnull();
table->field[13]->store((longlong) tmp->get_examined_row_count(), TRUE);
table->field[13]->set_notnull();
table->field[13]->store((longlong) tmp->status_var.max_local_memory_used,
FALSE);
table->field[14]->store((longlong) tmp->get_examined_row_count(), TRUE);
/* QUERY_ID */
table->field[14]->store(tmp->query_id, TRUE);
table->field[15]->store(tmp->query_id, TRUE);
table->field[16]->store(tmp->os_thread_id);
table->field[17]->store(tmp->os_thread_id);
if (schema_table_store_record(thd, table))
{
......@@ -4293,14 +4292,15 @@ static void get_table_engine_for_i_s(THD *thd, char *buf, TABLE_LIST *tl,
@retval TRUE - Failure.
*/
static bool
fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys,
fill_schema_table_by_open(THD *thd, MEM_ROOT *mem_root,
bool is_show_fields_or_keys,
TABLE *table, ST_SCHEMA_TABLE *schema_table,
LEX_CSTRING *orig_db_name,
LEX_CSTRING *orig_table_name,
Open_tables_backup *open_tables_state_backup,
bool can_deadlock)
{
Query_arena i_s_arena(thd->mem_root,
Query_arena i_s_arena(mem_root,
Query_arena::STMT_CONVENTIONAL_EXECUTION),
backup_arena, *old_arena;
LEX *old_lex= thd->lex, temp_lex, *lex;
......@@ -4877,8 +4877,11 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
#endif
uint table_open_method= tables->table_open_method;
bool can_deadlock;
MEM_ROOT tmp_mem_root;
DBUG_ENTER("get_all_tables");
bzero(&tmp_mem_root, sizeof(tmp_mem_root));
/*
In cases when SELECT from I_S table being filled by this call is
part of statement which also uses other tables or is being executed
......@@ -4914,7 +4917,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
table_name.str= lsel->table_list.first->table_name;
table_name.length= lsel->table_list.first->table_name_length;
error= fill_schema_table_by_open(thd, TRUE,
error= fill_schema_table_by_open(thd, thd->mem_root, TRUE,
table, schema_table,
&db_name, &table_name,
&open_tables_state_backup,
......@@ -4939,6 +4942,11 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
if (make_db_list(thd, &db_names, &plan->lookup_field_vals))
goto err;
/* Use tmp_mem_root to allocate data for opened tables */
init_alloc_root(&tmp_mem_root, SHOW_ALLOC_BLOCK_SIZE, SHOW_ALLOC_BLOCK_SIZE,
MY_THREAD_SPECIFIC);
for (size_t i=0; i < db_names.elements(); i++)
{
LEX_CSTRING *db_name= db_names.at(i);
......@@ -5024,12 +5032,13 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
}
DEBUG_SYNC(thd, "before_open_in_get_all_tables");
if (fill_schema_table_by_open(thd, FALSE,
if (fill_schema_table_by_open(thd, &tmp_mem_root, FALSE,
table, schema_table,
db_name, table_name,
&open_tables_state_backup,
can_deadlock))
goto err;
free_root(&tmp_mem_root, MY_MARK_BLOCKS_FREE);
}
}
}
......@@ -5039,6 +5048,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
error= 0;
err:
thd->restore_backup_open_tables_state(&open_tables_state_backup);
free_root(&tmp_mem_root, 0);
DBUG_RETURN(error);
}
......@@ -9064,6 +9074,7 @@ ST_FIELD_INFO processlist_fields_info[]=
{"PROGRESS", 703, MYSQL_TYPE_DECIMAL, 0, 0, "Progress",
SKIP_OPEN_TABLE},
{"MEMORY_USED", 7, MYSQL_TYPE_LONGLONG, 0, 0, "Memory_used", SKIP_OPEN_TABLE},
{"MAX_MEMORY_USED", 7, MYSQL_TYPE_LONGLONG, 0, 0, "Max_memory_used", SKIP_OPEN_TABLE},
{"EXAMINED_ROWS", 7, MYSQL_TYPE_LONG, 0, 0, "Examined_rows", SKIP_OPEN_TABLE},
{"QUERY_ID", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0, SKIP_OPEN_TABLE},
{"INFO_BINARY", PROCESS_LIST_INFO_WIDTH, MYSQL_TYPE_BLOB, 0, 1,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment