mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
MDEV-7109: Add support for INFORMATION_SCHEMA.INNODB_SEMAPHORE_WAITS
MDEV-7399: Add support for INFORMATION_SCHEMA.INNODB_MUTEXES MDEV-7618: Improve semaphore instrumentation Introduced two new information schema tables to monitor mutex waits and semaphore waits. Added a new configuration variable innodb_intrument_semaphores to add thread_id, file name and line of current holder of mutex/rw_lock.
This commit is contained in:
parent
9152b83973
commit
1cc7befc14
39 changed files with 2173 additions and 293 deletions
|
@ -24,6 +24,7 @@ INNODB_CMPMEM_RESET
|
|||
INNODB_CMP_PER_INDEX
|
||||
INNODB_CMP_RESET
|
||||
INNODB_LOCK_WAITS
|
||||
INNODB_MUTEXES
|
||||
INNODB_SYS_COLUMNS
|
||||
INNODB_SYS_FIELDS
|
||||
INNODB_SYS_FOREIGN
|
||||
|
@ -97,6 +98,7 @@ INNODB_CMPMEM_RESET page_size
|
|||
INNODB_CMP_PER_INDEX database_name
|
||||
INNODB_CMP_RESET page_size
|
||||
INNODB_LOCK_WAITS requesting_trx_id
|
||||
INNODB_MUTEXES NAME
|
||||
INNODB_SYS_COLUMNS TABLE_ID
|
||||
INNODB_SYS_FIELDS INDEX_ID
|
||||
INNODB_SYS_FOREIGN ID
|
||||
|
@ -170,6 +172,7 @@ INNODB_CMPMEM_RESET page_size
|
|||
INNODB_CMP_PER_INDEX database_name
|
||||
INNODB_CMP_RESET page_size
|
||||
INNODB_LOCK_WAITS requesting_trx_id
|
||||
INNODB_MUTEXES NAME
|
||||
INNODB_SYS_COLUMNS TABLE_ID
|
||||
INNODB_SYS_FIELDS INDEX_ID
|
||||
INNODB_SYS_FOREIGN ID
|
||||
|
@ -248,6 +251,7 @@ INNODB_CMPMEM_RESET information_schema.INNODB_CMPMEM_RESET 1
|
|||
INNODB_CMP_PER_INDEX information_schema.INNODB_CMP_PER_INDEX 1
|
||||
INNODB_CMP_RESET information_schema.INNODB_CMP_RESET 1
|
||||
INNODB_LOCK_WAITS information_schema.INNODB_LOCK_WAITS 1
|
||||
INNODB_MUTEXES information_schema.INNODB_MUTEXES 1
|
||||
INNODB_SYS_COLUMNS information_schema.INNODB_SYS_COLUMNS 1
|
||||
INNODB_SYS_FIELDS information_schema.INNODB_SYS_FIELDS 1
|
||||
INNODB_SYS_FOREIGN information_schema.INNODB_SYS_FOREIGN 1
|
||||
|
@ -311,6 +315,7 @@ Database: information_schema
|
|||
| INNODB_CMP_PER_INDEX |
|
||||
| INNODB_CMP_RESET |
|
||||
| INNODB_LOCK_WAITS |
|
||||
| INNODB_MUTEXES |
|
||||
| INNODB_SYS_COLUMNS |
|
||||
| INNODB_SYS_FIELDS |
|
||||
| INNODB_SYS_FOREIGN |
|
||||
|
@ -374,6 +379,7 @@ Database: INFORMATION_SCHEMA
|
|||
| INNODB_CMP_PER_INDEX |
|
||||
| INNODB_CMP_RESET |
|
||||
| INNODB_LOCK_WAITS |
|
||||
| INNODB_MUTEXES |
|
||||
| INNODB_SYS_COLUMNS |
|
||||
| INNODB_SYS_FIELDS |
|
||||
| INNODB_SYS_FOREIGN |
|
||||
|
@ -417,5 +423,5 @@ Wildcard: inf_rmation_schema
|
|||
| information_schema |
|
||||
SELECT table_schema, count(*) FROM information_schema.TABLES WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest') GROUP BY TABLE_SCHEMA;
|
||||
table_schema count(*)
|
||||
information_schema 58
|
||||
information_schema 59
|
||||
mysql 30
|
||||
|
|
21
mysql-test/suite/innodb/r/innodb_mutexes.result
Normal file
21
mysql-test/suite/innodb/r/innodb_mutexes.result
Normal file
|
@ -0,0 +1,21 @@
|
|||
create table t1(a int not null primary key, b int, c int,d CHAR(100)) engine=innodb;
|
||||
create procedure innodb_insert_proc (repeat_count int)
|
||||
begin
|
||||
declare current_num int;
|
||||
set current_num = 0;
|
||||
while current_num < repeat_count do
|
||||
insert into t1 values(current_num, RAND(), RAND(), substring(MD5(RAND()), -64));
|
||||
set current_num = current_num + 1;
|
||||
end while;
|
||||
end//
|
||||
commit;
|
||||
set autocommit=0;
|
||||
call innodb_insert_proc(20000);
|
||||
commit;
|
||||
set autocommit=1;
|
||||
delete from t1 where a between 1000 and 1300;
|
||||
update t1 set b=b+1 where a between 2000 and 2600;
|
||||
insert into t1 select a+30000,b,c,d from t1 where a between 3000 and 4000;
|
||||
delete from t1 where a between 6000 and 7000;
|
||||
drop procedure innodb_insert_proc;
|
||||
drop table t1;
|
26
mysql-test/suite/innodb/r/innodb_sys_semaphore_waits.result
Normal file
26
mysql-test/suite/innodb/r/innodb_sys_semaphore_waits.result
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Establish connection con1 (user=root)
|
||||
# Establish connection con2 (user=root)
|
||||
drop table if exists t1;
|
||||
# Switch to connection con1
|
||||
create table t1 (id integer, x integer) engine = InnoDB;
|
||||
insert into t1 values(0, 0);
|
||||
set DEBUG_DBUG='+d,fatal-semaphore-timeout';
|
||||
set autocommit=0;
|
||||
# Sending query on con1,
|
||||
# the session will hold lock table mutex and sleep
|
||||
SELECT * from t1 where id = 0 FOR UPDATE;
|
||||
# Switch to connection con2
|
||||
set autocommit=0;
|
||||
# Sending query on con2,
|
||||
# the session will be blocked on the lock table mutex and
|
||||
# thus be put into sync arry
|
||||
SELECT * from t1 where id = 0 FOR UPDATE;
|
||||
# Switched to the default connection
|
||||
# Waitting for mysqld to crash
|
||||
# Mysqld crash was detected
|
||||
# Waitting for reconnect after mysqld restarts
|
||||
# Reconnected after mysqld was successfully restarted
|
||||
# Cleaning up before exit
|
||||
set DEBUG_DBUG=NULL;
|
||||
drop table if exists t1;
|
||||
# Clean exit
|
1
mysql-test/suite/innodb/t/innodb_mutexes-master.opt
Normal file
1
mysql-test/suite/innodb/t/innodb_mutexes-master.opt
Normal file
|
@ -0,0 +1 @@
|
|||
--innodb-mutexes
|
66
mysql-test/suite/innodb/t/innodb_mutexes.test
Normal file
66
mysql-test/suite/innodb/t/innodb_mutexes.test
Normal file
|
@ -0,0 +1,66 @@
|
|||
--source include/have_innodb.inc
|
||||
|
||||
connect(con1,localhost,root,,);
|
||||
connect(con2,localhost,root,,);
|
||||
connect(con3,localhost,root,,);
|
||||
|
||||
create table t1(a int not null primary key, b int, c int,d CHAR(100)) engine=innodb;
|
||||
|
||||
delimiter //;
|
||||
create procedure innodb_insert_proc (repeat_count int)
|
||||
begin
|
||||
declare current_num int;
|
||||
set current_num = 0;
|
||||
while current_num < repeat_count do
|
||||
insert into t1 values(current_num, RAND(), RAND(), substring(MD5(RAND()), -64));
|
||||
set current_num = current_num + 1;
|
||||
end while;
|
||||
end//
|
||||
delimiter ;//
|
||||
commit;
|
||||
|
||||
set autocommit=0;
|
||||
call innodb_insert_proc(20000);
|
||||
commit;
|
||||
set autocommit=1;
|
||||
|
||||
connection con1;
|
||||
send delete from t1 where a between 1000 and 1300;
|
||||
|
||||
connection con2;
|
||||
send update t1 set b=b+1 where a between 2000 and 2600;
|
||||
|
||||
connection con3;
|
||||
send insert into t1 select a+30000,b,c,d from t1 where a between 3000 and 4000;
|
||||
|
||||
connection default;
|
||||
send delete from t1 where a between 6000 and 7000;
|
||||
|
||||
connection con1;
|
||||
reap;
|
||||
|
||||
connection con2;
|
||||
reap;
|
||||
|
||||
connection con3;
|
||||
reap;
|
||||
|
||||
connection default;
|
||||
reap;
|
||||
|
||||
disconnect con1;
|
||||
disconnect con2;
|
||||
disconnect con3;
|
||||
|
||||
# test that below does not crash, actual result is not
|
||||
# repeatable
|
||||
--disable_query_log
|
||||
--disable_result_log
|
||||
--disable_warnings
|
||||
select * from information_schema.innodb_mutexes;
|
||||
--enable_query_log
|
||||
--enable_result_log
|
||||
--enable_warnings
|
||||
|
||||
drop procedure innodb_insert_proc;
|
||||
drop table t1;
|
|
@ -0,0 +1,3 @@
|
|||
--innodb-fatal-semaphore-wait-threshold=1
|
||||
--innodb-sys-semaphore-waits=1
|
||||
--innodb-instrument-semaphores=1
|
119
mysql-test/suite/innodb/t/innodb_sys_semaphore_waits.test
Normal file
119
mysql-test/suite/innodb/t/innodb_sys_semaphore_waits.test
Normal file
|
@ -0,0 +1,119 @@
|
|||
--source include/have_innodb.inc
|
||||
--source include/not_windows.inc
|
||||
--source include/not_valgrind.inc
|
||||
--source include/not_embedded.inc
|
||||
# DEBUG_SYNC must be compiled in.
|
||||
--source include/have_debug_sync.inc
|
||||
|
||||
--echo # Establish connection con1 (user=root)
|
||||
connect (con1,localhost,root,,);
|
||||
--echo # Establish connection con2 (user=root)
|
||||
connect (con2,localhost,root,,);
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
--enable_warnings
|
||||
|
||||
--echo # Switch to connection con1
|
||||
connection con1;
|
||||
eval create table t1 (id integer, x integer) engine = InnoDB;
|
||||
insert into t1 values(0, 0);
|
||||
|
||||
# Enable the debug injection.
|
||||
set DEBUG_DBUG='+d,fatal-semaphore-timeout';
|
||||
set autocommit=0;
|
||||
|
||||
# The following query will hang for an hour since the debug injection
|
||||
# code will sleep an hour after holding the lock table mutex
|
||||
--echo # Sending query on con1,
|
||||
--echo # the session will hold lock table mutex and sleep
|
||||
--send
|
||||
SELECT * from t1 where id = 0 FOR UPDATE;
|
||||
|
||||
# To make sure con1 holding the lock table mutex and sleeping
|
||||
--sleep 2
|
||||
|
||||
--echo # Switch to connection con2
|
||||
connection con2;
|
||||
set autocommit=0;
|
||||
|
||||
# The following query will be blocked on the lock table mutex held by
|
||||
# con1 so it will be put into sync array.
|
||||
--echo # Sending query on con2,
|
||||
--echo # the session will be blocked on the lock table mutex and
|
||||
--echo # thus be put into sync arry
|
||||
--send
|
||||
SELECT * from t1 where id = 0 FOR UPDATE;
|
||||
|
||||
# Waitting for mysqld to abort due to fatal semaphore timeout.
|
||||
# Please note that, in the master.opt file, the fatal timeout
|
||||
# was set to 1 second, but in mysqld debug mode, this timeout
|
||||
# value will be timed 10 because UNIV_DEBUG_VALGRIND is set
|
||||
# (see sync_array_print_long_waits_low() in storage/innobase/sync/sync0arr.cc)
|
||||
# so the actual timeout will be 1 * 10 = 10 seconds. Besides,
|
||||
# mysqld will abort after detecting this fatal timeout 10 times in
|
||||
# a loop with interval of 1 second (see srv_error_monitor_thread
|
||||
# thread in torage/innobase/srv/srv0srv.cc), so mysqld will abort
|
||||
# in 1 * 10 + 1 * 10 = 20 seconds after con2 being blocked on
|
||||
# the lock table mutex.
|
||||
#
|
||||
# P.S. the default fatal sempahore timeout is 600 seconds,
|
||||
# so mysqld will abort after 600 * 10 + 1 * 10 = 6010 seconds
|
||||
# in debug mode and 600 + 1 * 10 = 610 seconds in release mode.
|
||||
|
||||
--echo # Switched to the default connection
|
||||
connection default;
|
||||
|
||||
--disable_result_log
|
||||
--disable_query_log
|
||||
|
||||
# Since this test generates lot of errors in log, suppress checking errors
|
||||
call mtr.add_suppression(".*");
|
||||
|
||||
# The crash is expected
|
||||
exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
|
||||
|
||||
--echo # Waitting for mysqld to crash
|
||||
|
||||
# It will take 20 seconds to detect the long semaphore and mysqld to abort.
|
||||
# This test will be treated as pass as long as mysqld crash/restart is dectected
|
||||
# in 60 seconds.
|
||||
let $counter= 60;
|
||||
let $mysql_errno= 0;
|
||||
while (!$mysql_errno)
|
||||
{
|
||||
--error 0,1040,1053,2002,2003,2006,2013
|
||||
show status;
|
||||
|
||||
--error 0,1040,1053,2002,2003,2006,2013
|
||||
select * from information_schema.innodb_sys_semaphore_waits;
|
||||
|
||||
dec $counter;
|
||||
if (!$counter)
|
||||
{
|
||||
# This will fail this test.
|
||||
--die Server failed to dissapear
|
||||
}
|
||||
--sleep 1
|
||||
}
|
||||
|
||||
--echo # Mysqld crash was detected
|
||||
--echo # Waitting for reconnect after mysqld restarts
|
||||
|
||||
enable_reconnect;
|
||||
connection default;
|
||||
|
||||
--exec echo "restart:--log-error=$error_log" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
|
||||
|
||||
# Call script that will poll the server waiting for it to be back online again
|
||||
source include/wait_until_connected_again.inc;
|
||||
|
||||
--echo # Reconnected after mysqld was successfully restarted
|
||||
|
||||
--echo # Cleaning up before exit
|
||||
--disable_warnings
|
||||
set DEBUG_DBUG=NULL;
|
||||
drop table if exists t1;
|
||||
--enable_warnings
|
||||
|
||||
--echo # Clean exit
|
|
@ -10,6 +10,7 @@ there should be *no* long test name listed below:
|
|||
select distinct variable_name as `there should be *no* variables listed below:` from t2
|
||||
left join t1 on variable_name=test_name where test_name is null;
|
||||
there should be *no* variables listed below:
|
||||
innodb_instrument_semaphores
|
||||
strict_password_validation
|
||||
drop table t1;
|
||||
drop table t2;
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
#
|
||||
# innodb_instrument_semaphores
|
||||
#
|
||||
# save the initial value
|
||||
SET @innodb_instrument_semaphores_global_saved = @@global.innodb_instrument_semaphores;
|
||||
# default
|
||||
SELECT @@global.innodb_instrument_semaphores;
|
||||
@@global.innodb_instrument_semaphores
|
||||
0
|
||||
|
||||
# scope
|
||||
SELECT @@session.innodb_instrument_semaphores;
|
||||
ERROR HY000: Variable 'innodb_instrument_semaphores' is a GLOBAL variable
|
||||
SET @@global.innodb_instrument_semaphores=OFF;
|
||||
SELECT @@global.innodb_instrument_semaphores;
|
||||
@@global.innodb_instrument_semaphores
|
||||
0
|
||||
SET @@global.innodb_instrument_semaphores=ON;
|
||||
SELECT @@global.innodb_instrument_semaphores;
|
||||
@@global.innodb_instrument_semaphores
|
||||
1
|
||||
|
||||
# valid values
|
||||
SET @@global.innodb_instrument_semaphores='OFF';
|
||||
SELECT @@global.innodb_instrument_semaphores;
|
||||
@@global.innodb_instrument_semaphores
|
||||
0
|
||||
SET @@global.innodb_instrument_semaphores=ON;
|
||||
SELECT @@global.innodb_instrument_semaphores;
|
||||
@@global.innodb_instrument_semaphores
|
||||
1
|
||||
SET @@global.innodb_instrument_semaphores=default;
|
||||
SELECT @@global.innodb_instrument_semaphores;
|
||||
@@global.innodb_instrument_semaphores
|
||||
0
|
||||
|
||||
# invalid values
|
||||
SET @@global.innodb_instrument_semaphores=NULL;
|
||||
ERROR 42000: Variable 'innodb_instrument_semaphores' can't be set to the value of 'NULL'
|
||||
SET @@global.innodb_instrument_semaphores='junk';
|
||||
ERROR 42000: Variable 'innodb_instrument_semaphores' can't be set to the value of 'junk'
|
||||
|
||||
# restore the initial value
|
||||
SET @@global.innodb_instrument_semaphores = @innodb_instrument_semaphores_global_saved;
|
||||
# End of test
|
|
@ -1209,6 +1209,20 @@ NUMERIC_BLOCK_SIZE NULL
|
|||
ENUM_VALUE_LIST NULL
|
||||
READ_ONLY NO
|
||||
COMMAND_LINE_ARGUMENT REQUIRED
|
||||
VARIABLE_NAME INNODB_INSTRUMENT_SEMAPHORES
|
||||
SESSION_VALUE NULL
|
||||
GLOBAL_VALUE OFF
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE OFF
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
VARIABLE_TYPE BOOLEAN
|
||||
VARIABLE_COMMENT Enable semaphore request instrumentation. This could have some effect on performance but allows better information on long semaphore wait problems. (Default: not enabled)
|
||||
NUMERIC_MIN_VALUE NULL
|
||||
NUMERIC_MAX_VALUE NULL
|
||||
NUMERIC_BLOCK_SIZE NULL
|
||||
ENUM_VALUE_LIST NULL
|
||||
READ_ONLY NO
|
||||
COMMAND_LINE_ARGUMENT OPTIONAL
|
||||
VARIABLE_NAME INNODB_IO_CAPACITY
|
||||
SESSION_VALUE NULL
|
||||
GLOBAL_VALUE 200
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
--source include/have_innodb.inc
|
||||
|
||||
--echo #
|
||||
--echo # innodb_instrument_semaphores
|
||||
--echo #
|
||||
|
||||
--echo # save the initial value
|
||||
SET @innodb_instrument_semaphores_global_saved = @@global.innodb_instrument_semaphores;
|
||||
|
||||
--echo # default
|
||||
SELECT @@global.innodb_instrument_semaphores;
|
||||
|
||||
--echo
|
||||
--echo # scope
|
||||
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
|
||||
SELECT @@session.innodb_instrument_semaphores;
|
||||
SET @@global.innodb_instrument_semaphores=OFF;
|
||||
SELECT @@global.innodb_instrument_semaphores;
|
||||
SET @@global.innodb_instrument_semaphores=ON;
|
||||
SELECT @@global.innodb_instrument_semaphores;
|
||||
|
||||
--echo
|
||||
--echo # valid values
|
||||
SET @@global.innodb_instrument_semaphores='OFF';
|
||||
SELECT @@global.innodb_instrument_semaphores;
|
||||
SET @@global.innodb_instrument_semaphores=ON;
|
||||
SELECT @@global.innodb_instrument_semaphores;
|
||||
SET @@global.innodb_instrument_semaphores=default;
|
||||
SELECT @@global.innodb_instrument_semaphores;
|
||||
|
||||
--echo
|
||||
--echo # invalid values
|
||||
--error ER_WRONG_VALUE_FOR_VAR
|
||||
SET @@global.innodb_instrument_semaphores=NULL;
|
||||
--error ER_WRONG_VALUE_FOR_VAR
|
||||
SET @@global.innodb_instrument_semaphores='junk';
|
||||
|
||||
--echo
|
||||
--echo # restore the initial value
|
||||
SET @@global.innodb_instrument_semaphores = @innodb_instrument_semaphores_global_saved;
|
||||
|
||||
--echo # End of test
|
|
@ -13,5 +13,6 @@
|
|||
--loose-innodb-sys-foreign-cols
|
||||
--loose-innodb-sys-tables
|
||||
--loose-innodb-sys-tablestats
|
||||
--loose-innodb-mutexes
|
||||
--loose-innodb-tablespaces-encryption
|
||||
--loose-innodb-tablespaces-scrubbing
|
||||
|
|
|
@ -19221,6 +19221,12 @@ static MYSQL_SYSVAR_BOOL(scrub_force_testing,
|
|||
NULL, NULL, FALSE);
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
static MYSQL_SYSVAR_BOOL(instrument_semaphores, srv_instrument_semaphores,
|
||||
PLUGIN_VAR_OPCMDARG,
|
||||
"Enable semaphore request instrumentation. This could have some effect on performance but allows better"
|
||||
" information on long semaphore wait problems. (Default: not enabled)",
|
||||
0, 0, FALSE);
|
||||
|
||||
static struct st_mysql_sys_var* innobase_system_variables[]= {
|
||||
MYSQL_SYSVAR(additional_mem_pool_size),
|
||||
MYSQL_SYSVAR(api_trx_level),
|
||||
|
@ -19418,6 +19424,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
|
|||
#ifdef UNIV_DEBUG
|
||||
MYSQL_SYSVAR(scrub_force_testing),
|
||||
#endif
|
||||
MYSQL_SYSVAR(instrument_semaphores),
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -19465,6 +19472,8 @@ i_s_innodb_sys_foreign,
|
|||
i_s_innodb_sys_foreign_cols,
|
||||
i_s_innodb_sys_tablespaces,
|
||||
i_s_innodb_sys_datafiles,
|
||||
i_s_innodb_mutexes,
|
||||
i_s_innodb_sys_semaphore_waits,
|
||||
i_s_innodb_tablespaces_encryption,
|
||||
i_s_innodb_tablespaces_scrubbing
|
||||
maria_declare_plugin_end;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2007, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyrigth (c) 2014, 2015, MariaDB Corporation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -21,8 +22,11 @@ this program; if not, write to the Free Software Foundation, Inc.,
|
|||
InnoDB INFORMATION SCHEMA tables interface to MySQL.
|
||||
|
||||
Created July 18, 2007 Vasil Dimov
|
||||
Modified Dec 29, 2014 Jan Lindström (Added sys_semaphore_waits)
|
||||
*******************************************************/
|
||||
|
||||
#include "univ.i"
|
||||
|
||||
#include <mysqld_error.h>
|
||||
#include <sql_acl.h>
|
||||
|
||||
|
@ -56,6 +60,7 @@ Created July 18, 2007 Vasil Dimov
|
|||
#include "fts0priv.h"
|
||||
#include "btr0btr.h"
|
||||
#include "page0zip.h"
|
||||
#include "sync0arr.h"
|
||||
|
||||
/** structure associates a name string with a file page type and/or buffer
|
||||
page state. */
|
||||
|
@ -137,45 +142,6 @@ struct buf_page_info_t{
|
|||
index_id_t index_id; /*!< Index ID if a index page */
|
||||
};
|
||||
|
||||
/** maximum number of buffer page info we would cache. */
|
||||
#define MAX_BUF_INFO_CACHED 10000
|
||||
|
||||
#define OK(expr) \
|
||||
if ((expr) != 0) { \
|
||||
DBUG_RETURN(1); \
|
||||
}
|
||||
|
||||
#define RETURN_IF_INNODB_NOT_STARTED(plugin_name) \
|
||||
do { \
|
||||
if (!srv_was_started) { \
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, \
|
||||
ER_CANT_FIND_SYSTEM_REC, \
|
||||
"InnoDB: SELECTing from " \
|
||||
"INFORMATION_SCHEMA.%s but " \
|
||||
"the InnoDB storage engine " \
|
||||
"is not installed", plugin_name); \
|
||||
DBUG_RETURN(0); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#if !defined __STRICT_ANSI__ && defined __GNUC__ && (__GNUC__) > 2 && \
|
||||
!defined __INTEL_COMPILER && !defined __clang__
|
||||
#define STRUCT_FLD(name, value) name: value
|
||||
#else
|
||||
#define STRUCT_FLD(name, value) value
|
||||
#endif
|
||||
|
||||
/* Don't use a static const variable here, as some C++ compilers (notably
|
||||
HPUX aCC: HP ANSI C++ B3910B A.03.65) can't handle it. */
|
||||
#define END_OF_ST_FIELD_INFO \
|
||||
{STRUCT_FLD(field_name, NULL), \
|
||||
STRUCT_FLD(field_length, 0), \
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_NULL), \
|
||||
STRUCT_FLD(value, 0), \
|
||||
STRUCT_FLD(field_flags, 0), \
|
||||
STRUCT_FLD(old_name, ""), \
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}
|
||||
|
||||
/*
|
||||
Use the following types mapping:
|
||||
|
||||
|
@ -204,6 +170,20 @@ time_t MYSQL_TYPE_DATETIME
|
|||
---------------------------------
|
||||
*/
|
||||
|
||||
/** Implemented on sync0arr.cc */
|
||||
/*******************************************************************//**
|
||||
Function to populate INFORMATION_SCHEMA.INNODB_SYS_SEMAPHORE_WAITS table.
|
||||
Loop through each item on sync array, and extract the column
|
||||
information and fill the INFORMATION_SCHEMA.INNODB_SYS_SEMAPHORE_WAITS table.
|
||||
@return 0 on success */
|
||||
UNIV_INTERN
|
||||
int
|
||||
sync_arr_fill_sys_semphore_waits_table(
|
||||
/*===================================*/
|
||||
THD* thd, /*!< in: thread */
|
||||
TABLE_LIST* tables, /*!< in/out: tables to fill */
|
||||
Item* ); /*!< in: condition (not used) */
|
||||
|
||||
/*******************************************************************//**
|
||||
Common function to fill any of the dynamic tables:
|
||||
INFORMATION_SCHEMA.innodb_trx
|
||||
|
@ -261,7 +241,6 @@ field_store_time_t(
|
|||
/*******************************************************************//**
|
||||
Auxiliary function to store char* value in MYSQL_TYPE_STRING field.
|
||||
@return 0 on success */
|
||||
static
|
||||
int
|
||||
field_store_string(
|
||||
/*===============*/
|
||||
|
@ -328,7 +307,6 @@ field_store_index_name(
|
|||
Auxiliary function to store ulint value in MYSQL_TYPE_LONGLONG field.
|
||||
If the value is ULINT_UNDEFINED then the field it set to NULL.
|
||||
@return 0 on success */
|
||||
static
|
||||
int
|
||||
field_store_ulint(
|
||||
/*==============*/
|
||||
|
@ -8654,3 +8632,494 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_tablespaces_scrubbing =
|
|||
STRUCT_FLD(version_info, INNODB_VERSION_STR),
|
||||
STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
|
||||
};
|
||||
|
||||
/** INNODB_MUTEXES *********************************************/
|
||||
/* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_MUTEXES */
|
||||
static ST_FIELD_INFO innodb_mutexes_fields_info[] =
|
||||
{
|
||||
#define MUTEXES_NAME 0
|
||||
{STRUCT_FLD(field_name, "NAME"),
|
||||
STRUCT_FLD(field_length, OS_FILE_MAX_PATH),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, 0),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
#define MUTEXES_CREATE_FILE 1
|
||||
{STRUCT_FLD(field_name, "CREATE_FILE"),
|
||||
STRUCT_FLD(field_length, OS_FILE_MAX_PATH),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, 0),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
#define MUTEXES_CREATE_LINE 2
|
||||
{STRUCT_FLD(field_name, "CREATE_LINE"),
|
||||
STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
#define MUTEXES_OS_WAITS 3
|
||||
{STRUCT_FLD(field_name, "OS_WAITS"),
|
||||
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
END_OF_ST_FIELD_INFO
|
||||
};
|
||||
|
||||
/*******************************************************************//**
|
||||
Function to populate INFORMATION_SCHEMA.INNODB_MUTEXES table.
|
||||
Loop through each record in mutex and rw_lock lists, and extract the column
|
||||
information and fill the INFORMATION_SCHEMA.INNODB_MUTEXES table.
|
||||
@return 0 on success */
|
||||
static
|
||||
int
|
||||
i_s_innodb_mutexes_fill_table(
|
||||
/*==========================*/
|
||||
THD* thd, /*!< in: thread */
|
||||
TABLE_LIST* tables, /*!< in/out: tables to fill */
|
||||
Item* ) /*!< in: condition (not used) */
|
||||
{
|
||||
ib_mutex_t* mutex;
|
||||
rw_lock_t* lock;
|
||||
ulint block_mutex_oswait_count = 0;
|
||||
ulint block_lock_oswait_count = 0;
|
||||
ib_mutex_t* block_mutex = NULL;
|
||||
rw_lock_t* block_lock = NULL;
|
||||
Field** fields = tables->table->field;
|
||||
|
||||
DBUG_ENTER("i_s_innodb_mutexes_fill_table");
|
||||
RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
|
||||
|
||||
/* deny access to user without PROCESS_ACL privilege */
|
||||
if (check_global_access(thd, PROCESS_ACL)) {
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
mutex_enter(&mutex_list_mutex);
|
||||
|
||||
for (mutex = UT_LIST_GET_FIRST(mutex_list); mutex != NULL;
|
||||
mutex = UT_LIST_GET_NEXT(list, mutex)) {
|
||||
if (mutex->count_os_wait == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (buf_pool_is_block_mutex(mutex)) {
|
||||
block_mutex = mutex;
|
||||
block_mutex_oswait_count += mutex->count_os_wait;
|
||||
continue;
|
||||
}
|
||||
|
||||
OK(field_store_string(fields[MUTEXES_NAME], mutex->cmutex_name));
|
||||
OK(field_store_string(fields[MUTEXES_CREATE_FILE], innobase_basename(mutex->cfile_name)));
|
||||
OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], mutex->cline));
|
||||
OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)mutex->count_os_wait));
|
||||
OK(schema_table_store_record(thd, tables->table));
|
||||
}
|
||||
|
||||
if (block_mutex) {
|
||||
char buf1[IO_SIZE];
|
||||
|
||||
my_snprintf(buf1, sizeof buf1, "combined %s",
|
||||
innobase_basename(block_mutex->cfile_name));
|
||||
|
||||
OK(field_store_string(fields[MUTEXES_NAME], block_mutex->cmutex_name));
|
||||
OK(field_store_string(fields[MUTEXES_CREATE_FILE], buf1));
|
||||
OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], block_mutex->cline));
|
||||
OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)block_mutex_oswait_count));
|
||||
OK(schema_table_store_record(thd, tables->table));
|
||||
}
|
||||
|
||||
mutex_exit(&mutex_list_mutex);
|
||||
|
||||
mutex_enter(&rw_lock_list_mutex);
|
||||
|
||||
for (lock = UT_LIST_GET_FIRST(rw_lock_list); lock != NULL;
|
||||
lock = UT_LIST_GET_NEXT(list, lock)) {
|
||||
if (lock->count_os_wait == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (buf_pool_is_block_lock(lock)) {
|
||||
block_lock = lock;
|
||||
block_lock_oswait_count += lock->count_os_wait;
|
||||
continue;
|
||||
}
|
||||
|
||||
OK(field_store_string(fields[MUTEXES_NAME], lock->lock_name));
|
||||
OK(field_store_string(fields[MUTEXES_CREATE_FILE], innobase_basename(lock->cfile_name)));
|
||||
OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], lock->cline));
|
||||
OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)lock->count_os_wait));
|
||||
OK(schema_table_store_record(thd, tables->table));
|
||||
}
|
||||
|
||||
if (block_lock) {
|
||||
char buf1[IO_SIZE];
|
||||
|
||||
my_snprintf(buf1, sizeof buf1, "combined %s",
|
||||
innobase_basename(block_lock->cfile_name));
|
||||
|
||||
OK(field_store_string(fields[MUTEXES_NAME], block_lock->lock_name));
|
||||
OK(field_store_string(fields[MUTEXES_CREATE_FILE], buf1));
|
||||
OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], block_lock->cline));
|
||||
OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)block_lock_oswait_count));
|
||||
OK(schema_table_store_record(thd, tables->table));
|
||||
}
|
||||
|
||||
mutex_exit(&rw_lock_list_mutex);
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/*******************************************************************//**
|
||||
Bind the dynamic table INFORMATION_SCHEMA.INNODB_MUTEXES
|
||||
@return 0 on success */
|
||||
static
|
||||
int
|
||||
innodb_mutexes_init(
|
||||
/*================*/
|
||||
void* p) /*!< in/out: table schema object */
|
||||
{
|
||||
ST_SCHEMA_TABLE* schema;
|
||||
|
||||
DBUG_ENTER("innodb_mutexes_init");
|
||||
|
||||
schema = (ST_SCHEMA_TABLE*) p;
|
||||
|
||||
schema->fields_info = innodb_mutexes_fields_info;
|
||||
schema->fill_table = i_s_innodb_mutexes_fill_table;
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
UNIV_INTERN struct st_maria_plugin i_s_innodb_mutexes =
|
||||
{
|
||||
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
|
||||
/* int */
|
||||
STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
|
||||
|
||||
/* pointer to type-specific plugin descriptor */
|
||||
/* void* */
|
||||
STRUCT_FLD(info, &i_s_info),
|
||||
|
||||
/* plugin name */
|
||||
/* const char* */
|
||||
STRUCT_FLD(name, "INNODB_MUTEXES"),
|
||||
|
||||
/* plugin author (for SHOW PLUGINS) */
|
||||
/* const char* */
|
||||
STRUCT_FLD(author, plugin_author),
|
||||
|
||||
/* general descriptive text (for SHOW PLUGINS) */
|
||||
/* const char* */
|
||||
STRUCT_FLD(descr, "InnoDB SYS_DATAFILES"),
|
||||
|
||||
/* the plugin license (PLUGIN_LICENSE_XXX) */
|
||||
/* int */
|
||||
STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
|
||||
|
||||
/* the function to invoke when plugin is loaded */
|
||||
/* int (*)(void*); */
|
||||
STRUCT_FLD(init, innodb_mutexes_init),
|
||||
|
||||
/* the function to invoke when plugin is unloaded */
|
||||
/* int (*)(void*); */
|
||||
STRUCT_FLD(deinit, i_s_common_deinit),
|
||||
|
||||
/* plugin version (for SHOW PLUGINS) */
|
||||
/* unsigned int */
|
||||
STRUCT_FLD(version, INNODB_VERSION_SHORT),
|
||||
|
||||
/* struct st_mysql_show_var* */
|
||||
STRUCT_FLD(status_vars, NULL),
|
||||
|
||||
/* struct st_mysql_sys_var** */
|
||||
STRUCT_FLD(system_vars, NULL),
|
||||
|
||||
/* Maria extension */
|
||||
STRUCT_FLD(version_info, INNODB_VERSION_STR),
|
||||
STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE),
|
||||
};
|
||||
|
||||
/** SYS_SEMAPHORE_WAITS ************************************************/
|
||||
/* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_SYS_SEMAPHORE_WAITS */
|
||||
static ST_FIELD_INFO innodb_sys_semaphore_waits_fields_info[] =
|
||||
{
|
||||
// SYS_SEMAPHORE_WAITS_THREAD_ID 0
|
||||
{STRUCT_FLD(field_name, "THREAD_ID"),
|
||||
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_OBJECT_NAME 1
|
||||
{STRUCT_FLD(field_name, "OBJECT_NAME"),
|
||||
STRUCT_FLD(field_length, OS_FILE_MAX_PATH),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_FILE 2
|
||||
{STRUCT_FLD(field_name, "FILE"),
|
||||
STRUCT_FLD(field_length, OS_FILE_MAX_PATH),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_LINE 3
|
||||
{STRUCT_FLD(field_name, "LINE"),
|
||||
STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_WAIT_TIME 4
|
||||
{STRUCT_FLD(field_name, "WAIT_TIME"),
|
||||
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_WAIT_OBJECT 5
|
||||
{STRUCT_FLD(field_name, "WAIT_OBJECT"),
|
||||
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_WAIT_TYPE 6
|
||||
{STRUCT_FLD(field_name, "WAIT_TYPE"),
|
||||
STRUCT_FLD(field_length, 16),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_HOLDER_THREAD_ID 7
|
||||
{STRUCT_FLD(field_name, "HOLDER_THREAD_ID"),
|
||||
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_HOLDER_FILE 8
|
||||
{STRUCT_FLD(field_name, "HOLDER_FILE"),
|
||||
STRUCT_FLD(field_length, OS_FILE_MAX_PATH),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_HOLDER_LINE 9
|
||||
{STRUCT_FLD(field_name, "HOLDER_LINE"),
|
||||
STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_CREATED_FILE 10
|
||||
{STRUCT_FLD(field_name, "CREATED_FILE"),
|
||||
STRUCT_FLD(field_length, OS_FILE_MAX_PATH),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_CREATED_LINE 11
|
||||
{STRUCT_FLD(field_name, "CREATED_LINE"),
|
||||
STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_WRITER_THREAD 12
|
||||
{STRUCT_FLD(field_name, "WRITER_THREAD"),
|
||||
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_RESERVATION_MODE 13
|
||||
{STRUCT_FLD(field_name, "RESERVATION_MODE"),
|
||||
STRUCT_FLD(field_length, 16),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_READERS 14
|
||||
{STRUCT_FLD(field_name, "READERS"),
|
||||
STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_WAITERS_FLAG 15
|
||||
{STRUCT_FLD(field_name, "WAITERS_FLAG"),
|
||||
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_LOCK_WORD 16
|
||||
{STRUCT_FLD(field_name, "LOCK_WORD"),
|
||||
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_LAST_READER_FILE 17
|
||||
{STRUCT_FLD(field_name, "LAST_READER_FILE"),
|
||||
STRUCT_FLD(field_length, OS_FILE_MAX_PATH),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_LAST_READER_LINE 18
|
||||
{STRUCT_FLD(field_name, "LAST_READER_LINE"),
|
||||
STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_LAST_WRITER_FILE 19
|
||||
{STRUCT_FLD(field_name, "LAST_WRITER_FILE"),
|
||||
STRUCT_FLD(field_length, OS_FILE_MAX_PATH),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_LAST_WRITER_LINE 20
|
||||
{STRUCT_FLD(field_name, "LAST_WRITER_LINE"),
|
||||
STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_OS_WAIT_COUNT 21
|
||||
{STRUCT_FLD(field_name, "OS_WAIT_COUNT"),
|
||||
STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
END_OF_ST_FIELD_INFO
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*******************************************************************//**
|
||||
Bind the dynamic table INFORMATION_SCHEMA.INNODB_SYS_SEMAPHORE_WAITS
|
||||
@return 0 on success */
|
||||
static
|
||||
int
|
||||
innodb_sys_semaphore_waits_init(
|
||||
/*============================*/
|
||||
void* p) /*!< in/out: table schema object */
|
||||
{
|
||||
ST_SCHEMA_TABLE* schema;
|
||||
|
||||
DBUG_ENTER("innodb_sys_semaphore_waits_init");
|
||||
|
||||
schema = (ST_SCHEMA_TABLE*) p;
|
||||
|
||||
schema->fields_info = innodb_sys_semaphore_waits_fields_info;
|
||||
schema->fill_table = sync_arr_fill_sys_semphore_waits_table;
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_semaphore_waits =
|
||||
{
|
||||
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
|
||||
/* int */
|
||||
STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
|
||||
|
||||
/* pointer to type-specific plugin descriptor */
|
||||
/* void* */
|
||||
STRUCT_FLD(info, &i_s_info),
|
||||
|
||||
/* plugin name */
|
||||
/* const char* */
|
||||
STRUCT_FLD(name, "INNODB_SYS_SEMAPHORE_WAITS"),
|
||||
|
||||
/* plugin author (for SHOW PLUGINS) */
|
||||
/* const char* */
|
||||
STRUCT_FLD(author, maria_plugin_author),
|
||||
|
||||
/* general descriptive text (for SHOW PLUGINS) */
|
||||
/* const char* */
|
||||
STRUCT_FLD(descr, "InnoDB SYS_SEMAPHORE_WAITS"),
|
||||
|
||||
/* the plugin license (PLUGIN_LICENSE_XXX) */
|
||||
/* int */
|
||||
STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
|
||||
|
||||
/* the function to invoke when plugin is loaded */
|
||||
/* int (*)(void*); */
|
||||
STRUCT_FLD(init, innodb_sys_semaphore_waits_init),
|
||||
|
||||
/* the function to invoke when plugin is unloaded */
|
||||
/* int (*)(void*); */
|
||||
STRUCT_FLD(deinit, i_s_common_deinit),
|
||||
|
||||
/* plugin version (for SHOW PLUGINS) */
|
||||
/* unsigned int */
|
||||
STRUCT_FLD(version, INNODB_VERSION_SHORT),
|
||||
|
||||
/* struct st_mysql_show_var* */
|
||||
STRUCT_FLD(status_vars, NULL),
|
||||
|
||||
/* struct st_mysql_sys_var** */
|
||||
STRUCT_FLD(system_vars, NULL),
|
||||
|
||||
/* Maria extension */
|
||||
STRUCT_FLD(version_info, INNODB_VERSION_STR),
|
||||
STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE),
|
||||
};
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2007, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyrigth (c) 2014, 2015, MariaDB Corporation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -21,12 +22,14 @@ this program; if not, write to the Free Software Foundation, Inc.,
|
|||
InnoDB INFORMATION SCHEMA tables interface to MySQL.
|
||||
|
||||
Created July 18, 2007 Vasil Dimov
|
||||
Modified Dec 29, 2014 Jan Lindström
|
||||
*******************************************************/
|
||||
|
||||
#ifndef i_s_h
|
||||
#define i_s_h
|
||||
|
||||
const char plugin_author[] = "Oracle Corporation";
|
||||
const char maria_plugin_author[] = "MariaDB Corporation";
|
||||
|
||||
extern struct st_maria_plugin i_s_innodb_trx;
|
||||
extern struct st_maria_plugin i_s_innodb_locks;
|
||||
|
@ -56,7 +59,92 @@ extern struct st_maria_plugin i_s_innodb_sys_foreign;
|
|||
extern struct st_maria_plugin i_s_innodb_sys_foreign_cols;
|
||||
extern struct st_maria_plugin i_s_innodb_sys_tablespaces;
|
||||
extern struct st_maria_plugin i_s_innodb_sys_datafiles;
|
||||
extern struct st_maria_plugin i_s_innodb_mutexes;
|
||||
extern struct st_maria_plugin i_s_innodb_tablespaces_encryption;
|
||||
extern struct st_maria_plugin i_s_innodb_tablespaces_scrubbing;
|
||||
extern struct st_maria_plugin i_s_innodb_sys_semaphore_waits;
|
||||
|
||||
/** maximum number of buffer page info we would cache. */
|
||||
#define MAX_BUF_INFO_CACHED 10000
|
||||
|
||||
#define OK(expr) \
|
||||
if ((expr) != 0) { \
|
||||
DBUG_RETURN(1); \
|
||||
}
|
||||
|
||||
#define RETURN_IF_INNODB_NOT_STARTED(plugin_name) \
|
||||
do { \
|
||||
if (!srv_was_started) { \
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, \
|
||||
ER_CANT_FIND_SYSTEM_REC, \
|
||||
"InnoDB: SELECTing from " \
|
||||
"INFORMATION_SCHEMA.%s but " \
|
||||
"the InnoDB storage engine " \
|
||||
"is not installed", plugin_name); \
|
||||
DBUG_RETURN(0); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#if !defined __STRICT_ANSI__ && defined __GNUC__ && (__GNUC__) > 2 && \
|
||||
!defined __INTEL_COMPILER && !defined __clang__
|
||||
#define STRUCT_FLD(name, value) name: value
|
||||
#else
|
||||
#define STRUCT_FLD(name, value) value
|
||||
#endif
|
||||
|
||||
/* Don't use a static const variable here, as some C++ compilers (notably
|
||||
HPUX aCC: HP ANSI C++ B3910B A.03.65) can't handle it. */
|
||||
#define END_OF_ST_FIELD_INFO \
|
||||
{STRUCT_FLD(field_name, NULL), \
|
||||
STRUCT_FLD(field_length, 0), \
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_NULL), \
|
||||
STRUCT_FLD(value, 0), \
|
||||
STRUCT_FLD(field_flags, 0), \
|
||||
STRUCT_FLD(old_name, ""), \
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}
|
||||
|
||||
/** Fields on INFORMATION_SCHEMA.SYS_SEMAMPHORE_WAITS table */
|
||||
#define SYS_SEMAPHORE_WAITS_THREAD_ID 0
|
||||
#define SYS_SEMAPHORE_WAITS_OBJECT_NAME 1
|
||||
#define SYS_SEMAPHORE_WAITS_FILE 2
|
||||
#define SYS_SEMAPHORE_WAITS_LINE 3
|
||||
#define SYS_SEMAPHORE_WAITS_WAIT_TIME 4
|
||||
#define SYS_SEMAPHORE_WAITS_WAIT_OBJECT 5
|
||||
#define SYS_SEMAPHORE_WAITS_WAIT_TYPE 6
|
||||
#define SYS_SEMAPHORE_WAITS_HOLDER_THREAD_ID 7
|
||||
#define SYS_SEMAPHORE_WAITS_HOLDER_FILE 8
|
||||
#define SYS_SEMAPHORE_WAITS_HOLDER_LINE 9
|
||||
#define SYS_SEMAPHORE_WAITS_CREATED_FILE 10
|
||||
#define SYS_SEMAPHORE_WAITS_CREATED_LINE 11
|
||||
#define SYS_SEMAPHORE_WAITS_WRITER_THREAD 12
|
||||
#define SYS_SEMAPHORE_WAITS_RESERVATION_MODE 13
|
||||
#define SYS_SEMAPHORE_WAITS_READERS 14
|
||||
#define SYS_SEMAPHORE_WAITS_WAITERS_FLAG 15
|
||||
#define SYS_SEMAPHORE_WAITS_LOCK_WORD 16
|
||||
#define SYS_SEMAPHORE_WAITS_LAST_READER_FILE 17
|
||||
#define SYS_SEMAPHORE_WAITS_LAST_READER_LINE 18
|
||||
#define SYS_SEMAPHORE_WAITS_LAST_WRITER_FILE 19
|
||||
#define SYS_SEMAPHORE_WAITS_LAST_WRITER_LINE 20
|
||||
#define SYS_SEMAPHORE_WAITS_OS_WAIT_COUNT 21
|
||||
|
||||
/*******************************************************************//**
|
||||
Auxiliary function to store ulint value in MYSQL_TYPE_LONGLONG field.
|
||||
If the value is ULINT_UNDEFINED then the field it set to NULL.
|
||||
@return 0 on success */
|
||||
int
|
||||
field_store_ulint(
|
||||
/*==============*/
|
||||
Field* field, /*!< in/out: target field for storage */
|
||||
ulint n); /*!< in: value to store */
|
||||
|
||||
/*******************************************************************//**
|
||||
Auxiliary function to store char* value in MYSQL_TYPE_STRING field.
|
||||
@return 0 on success */
|
||||
int
|
||||
field_store_string(
|
||||
/*===============*/
|
||||
Field* field, /*!< in/out: target field for storage */
|
||||
const char* str); /*!< in: NUL-terminated utf-8 string,
|
||||
or NULL */
|
||||
|
||||
#endif /* i_s_h */
|
||||
|
|
|
@ -565,6 +565,9 @@ extern ulong srv_fatal_semaphore_wait_threshold;
|
|||
/** Default encryption key used for page encryption */
|
||||
extern uint srv_default_page_encryption_key;
|
||||
|
||||
/** Enable semaphore request instrumentation */
|
||||
extern my_bool srv_instrument_semaphores;
|
||||
|
||||
# ifdef UNIV_PFS_THREAD
|
||||
/* Keys to register InnoDB threads with performance schema */
|
||||
extern mysql_pfs_key_t buf_page_cleaner_thread_key;
|
||||
|
|
|
@ -31,7 +31,7 @@ Created 9/5/1995 Heikki Tuuri
|
|||
#include "ut0mem.h"
|
||||
#include "os0thread.h"
|
||||
|
||||
/** Synchronization wait array cell */
|
||||
/** Synchonization cell */
|
||||
struct sync_cell_t;
|
||||
/** Synchronization wait array */
|
||||
struct sync_array_t;
|
||||
|
@ -154,6 +154,16 @@ UNIV_INTERN
|
|||
void
|
||||
sync_array_print_innodb(void);
|
||||
|
||||
/*****************************************************************//**
|
||||
Gets the nth cell in array.
|
||||
@return cell */
|
||||
UNIV_INTERN
|
||||
sync_cell_t*
|
||||
sync_array_get_nth_cell(
|
||||
/*====================*/
|
||||
sync_array_t* arr, /*!< in: sync array */
|
||||
ulint n); /*!< in: index */
|
||||
|
||||
#ifndef UNIV_NONINL
|
||||
#include "sync0arr.ic"
|
||||
#endif
|
||||
|
|
|
@ -40,6 +40,9 @@ Created 9/11/1995 Heikki Tuuri
|
|||
#include "sync0sync.h"
|
||||
#include "os0sync.h"
|
||||
|
||||
/** Enable semaphore request instrumentation */
|
||||
extern my_bool srv_instrument_semaphores;
|
||||
|
||||
/* The following undef is to prevent a name conflict with a macro
|
||||
in MySQL: */
|
||||
#undef rw_lock_t
|
||||
|
@ -224,7 +227,7 @@ unlocking, not the corresponding function. */
|
|||
# endif/* UNIV_SYNC_DEBUG */
|
||||
# else /* UNIV_DEBUG */
|
||||
# define rw_lock_create(K, L, level) \
|
||||
pfs_rw_lock_create_func((K), (L), __FILE__, __LINE__)
|
||||
pfs_rw_lock_create_func((K), (L), #L, __FILE__, __LINE__)
|
||||
# endif /* UNIV_DEBUG */
|
||||
|
||||
/******************************************************************
|
||||
|
@ -294,8 +297,8 @@ rw_lock_create_func(
|
|||
# ifdef UNIV_SYNC_DEBUG
|
||||
ulint level, /*!< in: level */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
const char* cmutex_name, /*!< in: mutex name */
|
||||
#endif /* UNIV_DEBUG */
|
||||
const char* cmutex_name, /*!< in: mutex name */
|
||||
const char* cfile_name, /*!< in: file name where created */
|
||||
ulint cline); /*!< in: file line where created */
|
||||
/******************************************************************//**
|
||||
|
@ -610,6 +613,10 @@ struct rw_lock_t {
|
|||
#endif
|
||||
ulint count_os_wait; /*!< Count of os_waits. May not be accurate */
|
||||
const char* cfile_name;/*!< File name where lock created */
|
||||
const char* lock_name; /*!< lock name */
|
||||
os_thread_id_t thread_id;/*!< thread id */
|
||||
const char* file_name;/*!< File name where the lock was obtained */
|
||||
ulint line; /*!< Line where the rw-lock was locked */
|
||||
/* last s-lock file/line is not guaranteed to be correct */
|
||||
const char* last_s_file_name;/*!< File name where last s-locked */
|
||||
const char* last_x_file_name;/*!< File name where last x-locked */
|
||||
|
@ -688,8 +695,8 @@ pfs_rw_lock_create_func(
|
|||
# ifdef UNIV_SYNC_DEBUG
|
||||
ulint level, /*!< in: level */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
const char* cmutex_name, /*!< in: mutex name */
|
||||
#endif /* UNIV_DEBUG */
|
||||
const char* cmutex_name, /*!< in: mutex name */
|
||||
const char* cfile_name, /*!< in: file name where created */
|
||||
ulint cline); /*!< in: file line where created */
|
||||
|
||||
|
|
|
@ -325,6 +325,12 @@ rw_lock_s_lock_low(
|
|||
lock->last_s_file_name = file_name;
|
||||
lock->last_s_line = line;
|
||||
|
||||
if (srv_instrument_semaphores) {
|
||||
lock->thread_id = os_thread_get_curr_id();
|
||||
lock->file_name = file_name;
|
||||
lock->line = line;
|
||||
}
|
||||
|
||||
return(TRUE); /* locking succeeded */
|
||||
}
|
||||
|
||||
|
@ -426,6 +432,12 @@ rw_lock_x_lock_func_nowait(
|
|||
rw_lock_add_debug_info(lock, 0, RW_LOCK_EX, file_name, line);
|
||||
#endif
|
||||
|
||||
if (srv_instrument_semaphores) {
|
||||
lock->thread_id = os_thread_get_curr_id();
|
||||
lock->file_name = file_name;
|
||||
lock->line = line;
|
||||
}
|
||||
|
||||
lock->last_x_file_name = file_name;
|
||||
lock->last_x_line = line;
|
||||
|
||||
|
@ -546,8 +558,8 @@ pfs_rw_lock_create_func(
|
|||
# ifdef UNIV_SYNC_DEBUG
|
||||
ulint level, /*!< in: level */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
const char* cmutex_name, /*!< in: mutex name */
|
||||
# endif /* UNIV_DEBUG */
|
||||
const char* cmutex_name, /*!< in: mutex name */
|
||||
const char* cfile_name, /*!< in: file name where created */
|
||||
ulint cline) /*!< in: file line where created */
|
||||
{
|
||||
|
@ -560,8 +572,8 @@ pfs_rw_lock_create_func(
|
|||
# ifdef UNIV_SYNC_DEBUG
|
||||
level,
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
cmutex_name,
|
||||
# endif /* UNIV_DEBUG */
|
||||
cmutex_name,
|
||||
cfile_name,
|
||||
cline);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,9 @@ Created 9/5/1995 Heikki Tuuri
|
|||
#include "os0sync.h"
|
||||
#include "sync0arr.h"
|
||||
|
||||
/** Enable semaphore request instrumentation */
|
||||
extern my_bool srv_instrument_semaphores;
|
||||
|
||||
#if defined(UNIV_DEBUG) && !defined(UNIV_HOTBACKUP)
|
||||
extern "C" my_bool timed_mutexes;
|
||||
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
|
||||
|
@ -180,7 +183,7 @@ necessary only if the memory block containing it is freed. */
|
|||
# endif/* UNIV_SYNC_DEBUG */
|
||||
# else
|
||||
# define mutex_create(K, M, level) \
|
||||
pfs_mutex_create_func((K), (M), __FILE__, __LINE__)
|
||||
pfs_mutex_create_func((K), (M), #M, __FILE__, __LINE__)
|
||||
# endif /* UNIV_DEBUG */
|
||||
|
||||
# define mutex_enter(M) \
|
||||
|
@ -231,8 +234,8 @@ void
|
|||
mutex_create_func(
|
||||
/*==============*/
|
||||
ib_mutex_t* mutex, /*!< in: pointer to memory */
|
||||
#ifdef UNIV_DEBUG
|
||||
const char* cmutex_name, /*!< in: mutex name */
|
||||
#ifdef UNIV_DEBUG
|
||||
# ifdef UNIV_SYNC_DEBUG
|
||||
ulint level, /*!< in: level */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
|
@ -305,8 +308,8 @@ pfs_mutex_create_func(
|
|||
/*==================*/
|
||||
PSI_mutex_key key, /*!< in: Performance Schema key */
|
||||
ib_mutex_t* mutex, /*!< in: pointer to memory */
|
||||
# ifdef UNIV_DEBUG
|
||||
const char* cmutex_name, /*!< in: mutex name */
|
||||
# ifdef UNIV_DEBUG
|
||||
# ifdef UNIV_SYNC_DEBUG
|
||||
ulint level, /*!< in: level */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
|
@ -763,22 +766,22 @@ struct ib_mutex_t {
|
|||
UT_LIST_NODE_T(ib_mutex_t) list; /*!< All allocated mutexes are put into
|
||||
a list. Pointers to the next and prev. */
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
const char* file_name; /*!< File where the mutex was locked */
|
||||
ulint line; /*!< Line where the mutex was locked */
|
||||
ulint level; /*!< Level in the global latching order */
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
const char* file_name; /*!< File where the mutex was locked */
|
||||
ulint line; /*!< Line where the mutex was locked */
|
||||
const char* cfile_name;/*!< File name where mutex created */
|
||||
ulint cline; /*!< Line where created */
|
||||
ulong count_os_wait; /*!< count of os_wait */
|
||||
const char* cmutex_name; /*!< mutex name */
|
||||
os_thread_id_t thread_id; /*!< The thread id of the thread
|
||||
which locked the mutex. */
|
||||
#ifdef UNIV_DEBUG
|
||||
|
||||
/** Value of mutex_t::magic_n */
|
||||
# define MUTEX_MAGIC_N 979585UL
|
||||
|
||||
os_thread_id_t thread_id; /*!< The thread id of the thread
|
||||
which locked the mutex. */
|
||||
ulint magic_n; /*!< MUTEX_MAGIC_N */
|
||||
const char* cmutex_name; /*!< mutex name */
|
||||
ulint ib_mutex_type; /*!< 0=usual mutex, 1=rw_lock mutex */
|
||||
#endif /* UNIV_DEBUG */
|
||||
#ifdef UNIV_PFS_MUTEX
|
||||
|
|
|
@ -162,7 +162,7 @@ mutex_exit_func(
|
|||
{
|
||||
ut_ad(mutex_own(mutex));
|
||||
|
||||
ut_d(mutex->thread_id = (os_thread_id_t) ULINT_UNDEFINED);
|
||||
mutex->thread_id = (os_thread_id_t) ULINT_UNDEFINED;
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
sync_thread_reset_level(mutex);
|
||||
|
@ -213,10 +213,15 @@ mutex_enter_func(
|
|||
the atomic test_and_set; we could peek, and possibly save time. */
|
||||
|
||||
if (!ib_mutex_test_and_set(mutex)) {
|
||||
ut_d(mutex->thread_id = os_thread_get_curr_id());
|
||||
mutex->thread_id = os_thread_get_curr_id();
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
mutex_set_debug_info(mutex, file_name, line);
|
||||
#endif
|
||||
if (srv_instrument_semaphores) {
|
||||
mutex->file_name = file_name;
|
||||
mutex->line = line;
|
||||
}
|
||||
|
||||
return; /* Succeeded! */
|
||||
}
|
||||
|
||||
|
@ -324,8 +329,8 @@ pfs_mutex_create_func(
|
|||
/*==================*/
|
||||
mysql_pfs_key_t key, /*!< in: Performance Schema key */
|
||||
ib_mutex_t* mutex, /*!< in: pointer to memory */
|
||||
# ifdef UNIV_DEBUG
|
||||
const char* cmutex_name, /*!< in: mutex name */
|
||||
# ifdef UNIV_DEBUG
|
||||
# ifdef UNIV_SYNC_DEBUG
|
||||
ulint level, /*!< in: level */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
|
@ -336,8 +341,8 @@ pfs_mutex_create_func(
|
|||
mutex->pfs_psi = PSI_MUTEX_CALL(init_mutex)(key, mutex);
|
||||
|
||||
mutex_create_func(mutex,
|
||||
# ifdef UNIV_DEBUG
|
||||
cmutex_name,
|
||||
# ifdef UNIV_DEBUG
|
||||
# ifdef UNIV_SYNC_DEBUG
|
||||
level,
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
|
|
|
@ -76,6 +76,7 @@ Created 10/8/1995 Heikki Tuuri
|
|||
#include "fil0fil.h"
|
||||
#include "fil0pagecompress.h"
|
||||
#include "btr0scrub.h"
|
||||
#include "fil0pageencryption.h"
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
extern int wsrep_debug;
|
||||
|
@ -523,7 +524,10 @@ second. */
|
|||
static time_t srv_last_log_flush_time;
|
||||
|
||||
/** Default encryption key used for page encryption */
|
||||
UNIV_INTERN uint srv_default_page_encryption_key;
|
||||
UNIV_INTERN uint srv_default_page_encryption_key = DEFAULT_ENCRYPTION_KEY;
|
||||
|
||||
/** Enable semaphore request instrumentation */
|
||||
UNIV_INTERN my_bool srv_instrument_semaphores = FALSE;
|
||||
|
||||
/* Interval in seconds at which various tasks are performed by the
|
||||
master thread when server is active. In order to balance the workload,
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2008, Google Inc.
|
||||
Copyright (c) 2013, 2015, MariaDB Corporation. All Rights Reserved.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted by
|
||||
Google, Inc. Those modifications are gratefully acknowledged and are described
|
||||
|
@ -30,11 +31,26 @@ The wait array used in synchronization primitives
|
|||
Created 9/5/1995 Heikki Tuuri
|
||||
*******************************************************/
|
||||
|
||||
#include "univ.i"
|
||||
|
||||
#include "sync0arr.h"
|
||||
#ifdef UNIV_NONINL
|
||||
#include "sync0arr.ic"
|
||||
#endif
|
||||
|
||||
#include <mysqld_error.h>
|
||||
#include <mysql/plugin.h>
|
||||
#include <hash.h>
|
||||
#include <myisampack.h>
|
||||
#include <sql_acl.h>
|
||||
#include <mysys_err.h>
|
||||
#include <my_sys.h>
|
||||
#include "srv0srv.h"
|
||||
#include "srv0start.h"
|
||||
#include "i_s.h"
|
||||
#include <sql_plugin.h>
|
||||
#include <innodb_priv.h>
|
||||
|
||||
#include "sync0sync.h"
|
||||
#include "sync0rw.h"
|
||||
#include "os0sync.h"
|
||||
|
@ -115,7 +131,6 @@ for an event allocated for the array without owning the
|
|||
protecting mutex (depending on the case: OS or database mutex), but
|
||||
all changes (set or reset) to the state of the event must be made
|
||||
while owning the mutex. */
|
||||
|
||||
/** Synchronization array */
|
||||
struct sync_array_t {
|
||||
ulint n_reserved; /*!< number of currently reserved
|
||||
|
@ -168,7 +183,6 @@ sync_array_detect_deadlock(
|
|||
/*****************************************************************//**
|
||||
Gets the nth cell in array.
|
||||
@return cell */
|
||||
static
|
||||
sync_cell_t*
|
||||
sync_array_get_nth_cell(
|
||||
/*====================*/
|
||||
|
@ -507,7 +521,7 @@ sync_array_cell_print(
|
|||
: type == RW_LOCK_WAIT_EX ? "X-lock (wait_ex) on"
|
||||
: "S-lock on", file);
|
||||
|
||||
rwlock = cell->old_wait_rw_lock;
|
||||
rwlock = (rw_lock_t*)cell->old_wait_rw_lock;
|
||||
|
||||
if (rwlock) {
|
||||
fprintf(file,
|
||||
|
@ -1282,3 +1296,153 @@ sync_array_print_innodb(void)
|
|||
fputs("InnoDB: Semaphore wait debug output ended:\n", stderr);
|
||||
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Get number of items on sync array. */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
sync_arr_get_n_items(void)
|
||||
/*======================*/
|
||||
{
|
||||
sync_array_t* sync_arr = sync_array_get();
|
||||
return (ulint) sync_arr->n_cells;
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
Get specified item from sync array if it is reserved. Set given
|
||||
pointer to array item if it is reserved.
|
||||
@return true if item is reserved, false othervise */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
sync_arr_get_item(
|
||||
/*==============*/
|
||||
ulint i, /*!< in: requested item */
|
||||
sync_cell_t **cell) /*!< out: cell contents if item
|
||||
reserved */
|
||||
{
|
||||
sync_array_t* sync_arr;
|
||||
sync_cell_t* wait_cell;
|
||||
void* wait_object;
|
||||
ibool found = FALSE;
|
||||
|
||||
sync_arr = sync_array_get();
|
||||
wait_cell = sync_array_get_nth_cell(sync_arr, i);
|
||||
|
||||
if (wait_cell) {
|
||||
wait_object = wait_cell->wait_object;
|
||||
|
||||
if(wait_object != NULL && wait_cell->waiting) {
|
||||
found = TRUE;
|
||||
*cell = wait_cell;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/*******************************************************************//**
|
||||
Function to populate INFORMATION_SCHEMA.INNODB_SYS_SEMAPHORE_WAITS table.
|
||||
Loop through each item on sync array, and extract the column
|
||||
information and fill the INFORMATION_SCHEMA.INNODB_SYS_SEMAPHORE_WAITS table.
|
||||
@return 0 on success */
|
||||
UNIV_INTERN
|
||||
int
|
||||
sync_arr_fill_sys_semphore_waits_table(
|
||||
/*===================================*/
|
||||
THD* thd, /*!< in: thread */
|
||||
TABLE_LIST* tables, /*!< in/out: tables to fill */
|
||||
Item* ) /*!< in: condition (not used) */
|
||||
{
|
||||
Field** fields;
|
||||
ulint n_items;
|
||||
|
||||
DBUG_ENTER("i_s_sys_semaphore_waits_fill_table");
|
||||
RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
|
||||
|
||||
/* deny access to user without PROCESS_ACL privilege */
|
||||
if (check_global_access(thd, PROCESS_ACL)) {
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
fields = tables->table->field;
|
||||
n_items = sync_arr_get_n_items();
|
||||
ulint type;
|
||||
|
||||
for(ulint i=0; i < n_items;i++) {
|
||||
sync_cell_t *cell=NULL;
|
||||
if (sync_arr_get_item(i, &cell)) {
|
||||
ib_mutex_t* mutex;
|
||||
type = cell->request_type;
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_THREAD_ID], (longlong)os_thread_pf(cell->thread)));
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_FILE], innobase_basename(cell->file)));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_LINE], cell->line));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_WAIT_TIME], (longlong)difftime(time(NULL), cell->reservation_time)));
|
||||
|
||||
if (type == SYNC_MUTEX) {
|
||||
mutex = static_cast<ib_mutex_t*>(cell->old_wait_mutex);
|
||||
|
||||
if (mutex) {
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_OBJECT_NAME], mutex->cmutex_name));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_WAIT_OBJECT], (longlong)mutex));
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_WAIT_TYPE], "MUTEX"));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_HOLDER_THREAD_ID], (longlong)mutex->thread_id));
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_HOLDER_FILE], innobase_basename(mutex->file_name)));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_HOLDER_LINE], mutex->line));
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_CREATED_FILE], innobase_basename(mutex->cfile_name)));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_CREATED_LINE], mutex->cline));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_WAITERS_FLAG], (longlong)mutex->waiters));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_LOCK_WORD], (longlong)mutex->lock_word));
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_LAST_WRITER_FILE], innobase_basename(mutex->file_name)));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_LAST_WRITER_LINE], mutex->line));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_OS_WAIT_COUNT], mutex->count_os_wait));
|
||||
}
|
||||
} else if (type == RW_LOCK_EX
|
||||
|| type == RW_LOCK_WAIT_EX
|
||||
|| type == RW_LOCK_SHARED) {
|
||||
rw_lock_t* rwlock=NULL;
|
||||
|
||||
rwlock = static_cast<rw_lock_t *> (cell->old_wait_rw_lock);
|
||||
|
||||
if (rwlock) {
|
||||
ulint writer = rw_lock_get_writer(rwlock);
|
||||
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_WAIT_OBJECT], (longlong)rwlock));
|
||||
if (type == RW_LOCK_EX) {
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_WAIT_TYPE], "RW_LOCK_EX"));
|
||||
} else if (type == RW_LOCK_WAIT_EX) {
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_WAIT_TYPE], "RW_LOCK_WAIT_EX"));
|
||||
} else if (type == RW_LOCK_SHARED) {
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_WAIT_TYPE], "RW_LOCK_SHARED"));
|
||||
}
|
||||
|
||||
if (writer != RW_LOCK_NOT_LOCKED) {
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_OBJECT_NAME], rwlock->lock_name));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_WRITER_THREAD], (longlong)os_thread_pf(rwlock->writer_thread)));
|
||||
|
||||
if (writer == RW_LOCK_EX) {
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_RESERVATION_MODE], "RW_LOCK_EX"));
|
||||
} else if (writer == RW_LOCK_WAIT_EX) {
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_RESERVATION_MODE], "RW_LOCK_WAIT_EX"));
|
||||
}
|
||||
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_HOLDER_THREAD_ID], (longlong)rwlock->thread_id));
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_HOLDER_FILE], innobase_basename(rwlock->file_name)));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_HOLDER_LINE], rwlock->line));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_READERS], rw_lock_get_reader_count(rwlock)));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_WAITERS_FLAG], (longlong)rwlock->waiters));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_LOCK_WORD], (longlong)rwlock->lock_word));
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_LAST_READER_FILE], innobase_basename(rwlock->last_s_file_name)));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_LAST_READER_LINE], rwlock->last_s_line));
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_LAST_WRITER_FILE], innobase_basename(rwlock->last_x_file_name)));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_LAST_WRITER_LINE], rwlock->last_x_line));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_OS_WAIT_COUNT], rwlock->count_os_wait));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OK(schema_table_store_record(thd, tables->table));
|
||||
}
|
||||
}
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
|
|
@ -209,8 +209,8 @@ rw_lock_create_func(
|
|||
# ifdef UNIV_SYNC_DEBUG
|
||||
ulint level, /*!< in: level */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
const char* cmutex_name, /*!< in: mutex name */
|
||||
#endif /* UNIV_DEBUG */
|
||||
const char* cmutex_name, /*!< in: mutex name */
|
||||
const char* cfile_name, /*!< in: file name where created */
|
||||
ulint cline) /*!< in: file line where created */
|
||||
{
|
||||
|
@ -223,8 +223,7 @@ rw_lock_create_func(
|
|||
|
||||
lock->mutex.cfile_name = cfile_name;
|
||||
lock->mutex.cline = cline;
|
||||
|
||||
ut_d(lock->mutex.cmutex_name = cmutex_name);
|
||||
lock->mutex.lock_name = cmutex_name;
|
||||
ut_d(lock->mutex.ib_mutex_type = 1);
|
||||
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
|
||||
# ifdef UNIV_DEBUG
|
||||
|
@ -253,8 +252,10 @@ rw_lock_create_func(
|
|||
|
||||
lock->cfile_name = cfile_name;
|
||||
lock->cline = (unsigned int) cline;
|
||||
|
||||
lock->lock_name = cmutex_name;
|
||||
lock->count_os_wait = 0;
|
||||
lock->file_name = "not yet reserved";
|
||||
lock->line = 0;
|
||||
lock->last_s_file_name = "not yet reserved";
|
||||
lock->last_x_file_name = "not yet reserved";
|
||||
lock->last_s_line = 0;
|
||||
|
@ -516,6 +517,12 @@ rw_lock_x_lock_wait(
|
|||
file_name, line);
|
||||
#endif
|
||||
|
||||
if (srv_instrument_semaphores) {
|
||||
lock->thread_id = os_thread_get_curr_id();
|
||||
lock->file_name = file_name;
|
||||
lock->line = line;
|
||||
}
|
||||
|
||||
sync_array_wait_event(sync_arr, index);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
rw_lock_remove_debug_info(
|
||||
|
@ -588,6 +595,13 @@ rw_lock_x_lock_low(
|
|||
#ifdef UNIV_SYNC_DEBUG
|
||||
rw_lock_add_debug_info(lock, pass, RW_LOCK_EX, file_name, line);
|
||||
#endif
|
||||
|
||||
if (srv_instrument_semaphores) {
|
||||
lock->thread_id = os_thread_get_curr_id();
|
||||
lock->file_name = file_name;
|
||||
lock->line = line;
|
||||
}
|
||||
|
||||
lock->last_x_file_name = file_name;
|
||||
lock->last_x_line = (unsigned int) line;
|
||||
|
||||
|
|
|
@ -265,8 +265,8 @@ void
|
|||
mutex_create_func(
|
||||
/*==============*/
|
||||
ib_mutex_t* mutex, /*!< in: pointer to memory */
|
||||
#ifdef UNIV_DEBUG
|
||||
const char* cmutex_name, /*!< in: mutex name */
|
||||
#ifdef UNIV_DEBUG
|
||||
# ifdef UNIV_SYNC_DEBUG
|
||||
ulint level, /*!< in: level */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
|
@ -285,9 +285,10 @@ mutex_create_func(
|
|||
#ifdef UNIV_DEBUG
|
||||
mutex->magic_n = MUTEX_MAGIC_N;
|
||||
#endif /* UNIV_DEBUG */
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
|
||||
mutex->line = 0;
|
||||
mutex->file_name = "not yet reserved";
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
mutex->level = level;
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
mutex->cfile_name = cfile_name;
|
||||
|
@ -398,11 +399,15 @@ mutex_enter_nowait_func(
|
|||
|
||||
if (!ib_mutex_test_and_set(mutex)) {
|
||||
|
||||
ut_d(mutex->thread_id = os_thread_get_curr_id());
|
||||
mutex->thread_id = os_thread_get_curr_id();
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
mutex_set_debug_info(mutex, file_name, line);
|
||||
#else
|
||||
if (srv_instrument_semaphores) {
|
||||
mutex->file_name = file_name;
|
||||
mutex->line = line;
|
||||
}
|
||||
#endif
|
||||
|
||||
return(0); /* Succeeded! */
|
||||
}
|
||||
|
||||
|
@ -520,10 +525,15 @@ spin_loop:
|
|||
if (ib_mutex_test_and_set(mutex) == 0) {
|
||||
/* Succeeded! */
|
||||
|
||||
ut_d(mutex->thread_id = os_thread_get_curr_id());
|
||||
mutex->thread_id = os_thread_get_curr_id();
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
mutex_set_debug_info(mutex, file_name, line);
|
||||
#endif
|
||||
if (srv_instrument_semaphores) {
|
||||
mutex->file_name = file_name;
|
||||
mutex->line = line;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -563,10 +573,14 @@ spin_loop:
|
|||
|
||||
sync_array_free_cell(sync_arr, index);
|
||||
|
||||
ut_d(mutex->thread_id = os_thread_get_curr_id());
|
||||
mutex->thread_id = os_thread_get_curr_id();
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
mutex_set_debug_info(mutex, file_name, line);
|
||||
#endif
|
||||
if (srv_instrument_semaphores) {
|
||||
mutex->file_name = file_name;
|
||||
mutex->line = line;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
|
|
|
@ -20412,6 +20412,12 @@ static MYSQL_SYSVAR_BOOL(scrub_force_testing,
|
|||
NULL, NULL, FALSE);
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
static MYSQL_SYSVAR_BOOL(instrument_semaphores, srv_instrument_semaphores,
|
||||
PLUGIN_VAR_OPCMDARG,
|
||||
"Enable semaphore request instrumentation. This could have some effect on performance but allows better"
|
||||
" information on long semaphore wait problems. (Default: not enabled)",
|
||||
0, 0, FALSE);
|
||||
|
||||
static struct st_mysql_sys_var* innobase_system_variables[]= {
|
||||
MYSQL_SYSVAR(log_block_size),
|
||||
MYSQL_SYSVAR(additional_mem_pool_size),
|
||||
|
@ -20646,7 +20652,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
|
|||
#ifdef UNIV_DEBUG
|
||||
MYSQL_SYSVAR(scrub_force_testing),
|
||||
#endif
|
||||
|
||||
MYSQL_SYSVAR(instrument_semaphores),
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -20698,6 +20704,8 @@ i_s_innodb_sys_foreign_cols,
|
|||
i_s_innodb_sys_tablespaces,
|
||||
i_s_innodb_sys_datafiles,
|
||||
i_s_innodb_changed_pages,
|
||||
i_s_innodb_mutexes,
|
||||
i_s_innodb_sys_semaphore_waits,
|
||||
i_s_innodb_tablespaces_encryption,
|
||||
i_s_innodb_tablespaces_scrubbing
|
||||
maria_declare_plugin_end;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2007, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyrigth (c) 2014, 2015, MariaDB Corporation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -21,7 +22,9 @@ this program; if not, write to the Free Software Foundation, Inc.,
|
|||
InnoDB INFORMATION SCHEMA tables interface to MySQL.
|
||||
|
||||
Created July 18, 2007 Vasil Dimov
|
||||
Modified Dec 29, 2014 Jan Lindström (Added sys_semaphore_waits)
|
||||
*******************************************************/
|
||||
#include "univ.i"
|
||||
#include <my_global.h>
|
||||
#ifndef MYSQL_SERVER
|
||||
#define MYSQL_SERVER /* For Item_* classes */
|
||||
|
@ -68,6 +71,7 @@ Created July 18, 2007 Vasil Dimov
|
|||
#include "log0online.h"
|
||||
#include "btr0btr.h"
|
||||
#include "page0zip.h"
|
||||
#include "sync0arr.h"
|
||||
|
||||
/** structure associates a name string with a file page type and/or buffer
|
||||
page state. */
|
||||
|
@ -149,45 +153,6 @@ struct buf_page_info_t{
|
|||
index_id_t index_id; /*!< Index ID if a index page */
|
||||
};
|
||||
|
||||
/** maximum number of buffer page info we would cache. */
|
||||
#define MAX_BUF_INFO_CACHED 10000
|
||||
|
||||
#define OK(expr) \
|
||||
if ((expr) != 0) { \
|
||||
DBUG_RETURN(1); \
|
||||
}
|
||||
|
||||
#define RETURN_IF_INNODB_NOT_STARTED(plugin_name) \
|
||||
do { \
|
||||
if (!srv_was_started) { \
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, \
|
||||
ER_CANT_FIND_SYSTEM_REC, \
|
||||
"InnoDB: SELECTing from " \
|
||||
"INFORMATION_SCHEMA.%s but " \
|
||||
"the InnoDB storage engine " \
|
||||
"is not installed", plugin_name); \
|
||||
DBUG_RETURN(0); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#if !defined __STRICT_ANSI__ && defined __GNUC__ && (__GNUC__) > 2 && \
|
||||
!defined __INTEL_COMPILER && !defined __clang__
|
||||
#define STRUCT_FLD(name, value) name: value
|
||||
#else
|
||||
#define STRUCT_FLD(name, value) value
|
||||
#endif
|
||||
|
||||
/* Don't use a static const variable here, as some C++ compilers (notably
|
||||
HPUX aCC: HP ANSI C++ B3910B A.03.65) can't handle it. */
|
||||
#define END_OF_ST_FIELD_INFO \
|
||||
{STRUCT_FLD(field_name, NULL), \
|
||||
STRUCT_FLD(field_length, 0), \
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_NULL), \
|
||||
STRUCT_FLD(value, 0), \
|
||||
STRUCT_FLD(field_flags, 0), \
|
||||
STRUCT_FLD(old_name, ""), \
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}
|
||||
|
||||
/*
|
||||
Use the following types mapping:
|
||||
|
||||
|
@ -216,6 +181,20 @@ time_t MYSQL_TYPE_DATETIME
|
|||
---------------------------------
|
||||
*/
|
||||
|
||||
/** Implemented on sync0arr.cc */
|
||||
/*******************************************************************//**
|
||||
Function to populate INFORMATION_SCHEMA.INNODB_SYS_SEMAPHORE_WAITS table.
|
||||
Loop through each item on sync array, and extract the column
|
||||
information and fill the INFORMATION_SCHEMA.INNODB_SYS_SEMAPHORE_WAITS table.
|
||||
@return 0 on success */
|
||||
UNIV_INTERN
|
||||
int
|
||||
sync_arr_fill_sys_semphore_waits_table(
|
||||
/*===================================*/
|
||||
THD* thd, /*!< in: thread */
|
||||
TABLE_LIST* tables, /*!< in/out: tables to fill */
|
||||
Item* ); /*!< in: condition (not used) */
|
||||
|
||||
/*******************************************************************//**
|
||||
Common function to fill any of the dynamic tables:
|
||||
INFORMATION_SCHEMA.innodb_trx
|
||||
|
@ -273,7 +252,6 @@ field_store_time_t(
|
|||
/*******************************************************************//**
|
||||
Auxiliary function to store char* value in MYSQL_TYPE_STRING field.
|
||||
@return 0 on success */
|
||||
static
|
||||
int
|
||||
field_store_string(
|
||||
/*===============*/
|
||||
|
@ -340,7 +318,6 @@ field_store_index_name(
|
|||
Auxiliary function to store ulint value in MYSQL_TYPE_LONGLONG field.
|
||||
If the value is ULINT_UNDEFINED then the field it set to NULL.
|
||||
@return 0 on success */
|
||||
static
|
||||
int
|
||||
field_store_ulint(
|
||||
/*==============*/
|
||||
|
@ -8992,3 +8969,494 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_tablespaces_scrubbing =
|
|||
STRUCT_FLD(version_info, INNODB_VERSION_STR),
|
||||
STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
|
||||
};
|
||||
|
||||
/** INNODB_MUTEXES *********************************************/
|
||||
/* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_MUTEXES */
|
||||
static ST_FIELD_INFO innodb_mutexes_fields_info[] =
|
||||
{
|
||||
#define MUTEXES_NAME 0
|
||||
{STRUCT_FLD(field_name, "NAME"),
|
||||
STRUCT_FLD(field_length, OS_FILE_MAX_PATH),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, 0),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
#define MUTEXES_CREATE_FILE 1
|
||||
{STRUCT_FLD(field_name, "CREATE_FILE"),
|
||||
STRUCT_FLD(field_length, OS_FILE_MAX_PATH),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, 0),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
#define MUTEXES_CREATE_LINE 2
|
||||
{STRUCT_FLD(field_name, "CREATE_LINE"),
|
||||
STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
#define MUTEXES_OS_WAITS 3
|
||||
{STRUCT_FLD(field_name, "OS_WAITS"),
|
||||
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
END_OF_ST_FIELD_INFO
|
||||
};
|
||||
|
||||
/*******************************************************************//**
|
||||
Function to populate INFORMATION_SCHEMA.INNODB_MUTEXES table.
|
||||
Loop through each record in mutex and rw_lock lists, and extract the column
|
||||
information and fill the INFORMATION_SCHEMA.INNODB_MUTEXES table.
|
||||
@return 0 on success */
|
||||
static
|
||||
int
|
||||
i_s_innodb_mutexes_fill_table(
|
||||
/*==========================*/
|
||||
THD* thd, /*!< in: thread */
|
||||
TABLE_LIST* tables, /*!< in/out: tables to fill */
|
||||
Item* ) /*!< in: condition (not used) */
|
||||
{
|
||||
ib_mutex_t* mutex;
|
||||
rw_lock_t* lock;
|
||||
ulint block_mutex_oswait_count = 0;
|
||||
ulint block_lock_oswait_count = 0;
|
||||
ib_mutex_t* block_mutex = NULL;
|
||||
rw_lock_t* block_lock = NULL;
|
||||
Field** fields = tables->table->field;
|
||||
|
||||
DBUG_ENTER("i_s_innodb_mutexes_fill_table");
|
||||
RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
|
||||
|
||||
/* deny access to user without PROCESS_ACL privilege */
|
||||
if (check_global_access(thd, PROCESS_ACL)) {
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
mutex_enter(&mutex_list_mutex);
|
||||
|
||||
for (mutex = UT_LIST_GET_FIRST(mutex_list); mutex != NULL;
|
||||
mutex = UT_LIST_GET_NEXT(list, mutex)) {
|
||||
if (mutex->count_os_wait == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (buf_pool_is_block_mutex(mutex)) {
|
||||
block_mutex = mutex;
|
||||
block_mutex_oswait_count += mutex->count_os_wait;
|
||||
continue;
|
||||
}
|
||||
|
||||
OK(field_store_string(fields[MUTEXES_NAME], mutex->cmutex_name));
|
||||
OK(field_store_string(fields[MUTEXES_CREATE_FILE], innobase_basename(mutex->cfile_name)));
|
||||
OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], mutex->cline));
|
||||
OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)mutex->count_os_wait));
|
||||
OK(schema_table_store_record(thd, tables->table));
|
||||
}
|
||||
|
||||
if (block_mutex) {
|
||||
char buf1[IO_SIZE];
|
||||
|
||||
my_snprintf(buf1, sizeof buf1, "combined %s",
|
||||
innobase_basename(block_mutex->cfile_name));
|
||||
|
||||
OK(field_store_string(fields[MUTEXES_NAME], block_mutex->cmutex_name));
|
||||
OK(field_store_string(fields[MUTEXES_CREATE_FILE], buf1));
|
||||
OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], block_mutex->cline));
|
||||
OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)block_mutex_oswait_count));
|
||||
OK(schema_table_store_record(thd, tables->table));
|
||||
}
|
||||
|
||||
mutex_exit(&mutex_list_mutex);
|
||||
|
||||
mutex_enter(&rw_lock_list_mutex);
|
||||
|
||||
for (lock = UT_LIST_GET_FIRST(rw_lock_list); lock != NULL;
|
||||
lock = UT_LIST_GET_NEXT(list, lock)) {
|
||||
if (lock->count_os_wait == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (buf_pool_is_block_lock(lock)) {
|
||||
block_lock = lock;
|
||||
block_lock_oswait_count += lock->count_os_wait;
|
||||
continue;
|
||||
}
|
||||
|
||||
OK(field_store_string(fields[MUTEXES_NAME], lock->lock_name));
|
||||
OK(field_store_string(fields[MUTEXES_CREATE_FILE], innobase_basename(lock->cfile_name)));
|
||||
OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], lock->cline));
|
||||
OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)lock->count_os_wait));
|
||||
OK(schema_table_store_record(thd, tables->table));
|
||||
}
|
||||
|
||||
if (block_lock) {
|
||||
char buf1[IO_SIZE];
|
||||
|
||||
my_snprintf(buf1, sizeof buf1, "combined %s",
|
||||
innobase_basename(block_lock->cfile_name));
|
||||
|
||||
OK(field_store_string(fields[MUTEXES_NAME], block_lock->lock_name));
|
||||
OK(field_store_string(fields[MUTEXES_CREATE_FILE], buf1));
|
||||
OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], block_lock->cline));
|
||||
OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)block_lock_oswait_count));
|
||||
OK(schema_table_store_record(thd, tables->table));
|
||||
}
|
||||
|
||||
mutex_exit(&rw_lock_list_mutex);
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/*******************************************************************//**
|
||||
Bind the dynamic table INFORMATION_SCHEMA.INNODB_MUTEXES
|
||||
@return 0 on success */
|
||||
static
|
||||
int
|
||||
innodb_mutexes_init(
|
||||
/*================*/
|
||||
void* p) /*!< in/out: table schema object */
|
||||
{
|
||||
ST_SCHEMA_TABLE* schema;
|
||||
|
||||
DBUG_ENTER("innodb_mutexes_init");
|
||||
|
||||
schema = (ST_SCHEMA_TABLE*) p;
|
||||
|
||||
schema->fields_info = innodb_mutexes_fields_info;
|
||||
schema->fill_table = i_s_innodb_mutexes_fill_table;
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
UNIV_INTERN struct st_mysql_plugin i_s_innodb_mutexes =
|
||||
{
|
||||
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
|
||||
/* int */
|
||||
STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
|
||||
|
||||
/* pointer to type-specific plugin descriptor */
|
||||
/* void* */
|
||||
STRUCT_FLD(info, &i_s_info),
|
||||
|
||||
/* plugin name */
|
||||
/* const char* */
|
||||
STRUCT_FLD(name, "INNODB_MUTEXES"),
|
||||
|
||||
/* plugin author (for SHOW PLUGINS) */
|
||||
/* const char* */
|
||||
STRUCT_FLD(author, plugin_author),
|
||||
|
||||
/* general descriptive text (for SHOW PLUGINS) */
|
||||
/* const char* */
|
||||
STRUCT_FLD(descr, "InnoDB SYS_DATAFILES"),
|
||||
|
||||
/* the plugin license (PLUGIN_LICENSE_XXX) */
|
||||
/* int */
|
||||
STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
|
||||
|
||||
/* the function to invoke when plugin is loaded */
|
||||
/* int (*)(void*); */
|
||||
STRUCT_FLD(init, innodb_mutexes_init),
|
||||
|
||||
/* the function to invoke when plugin is unloaded */
|
||||
/* int (*)(void*); */
|
||||
STRUCT_FLD(deinit, i_s_common_deinit),
|
||||
|
||||
/* plugin version (for SHOW PLUGINS) */
|
||||
/* unsigned int */
|
||||
STRUCT_FLD(version, INNODB_VERSION_SHORT),
|
||||
|
||||
/* struct st_mysql_show_var* */
|
||||
STRUCT_FLD(status_vars, NULL),
|
||||
|
||||
/* struct st_mysql_sys_var** */
|
||||
STRUCT_FLD(system_vars, NULL),
|
||||
|
||||
/* Maria extension */
|
||||
STRUCT_FLD(version_info, INNODB_VERSION_STR),
|
||||
STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE),
|
||||
};
|
||||
|
||||
/** SYS_SEMAPHORE_WAITS ************************************************/
|
||||
/* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_SYS_SEMAPHORE_WAITS */
|
||||
static ST_FIELD_INFO innodb_sys_semaphore_waits_fields_info[] =
|
||||
{
|
||||
// SYS_SEMAPHORE_WAITS_THREAD_ID 0
|
||||
{STRUCT_FLD(field_name, "THREAD_ID"),
|
||||
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_OBJECT_NAME 1
|
||||
{STRUCT_FLD(field_name, "OBJECT_NAME"),
|
||||
STRUCT_FLD(field_length, OS_FILE_MAX_PATH),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_FILE 2
|
||||
{STRUCT_FLD(field_name, "FILE"),
|
||||
STRUCT_FLD(field_length, OS_FILE_MAX_PATH),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_LINE 3
|
||||
{STRUCT_FLD(field_name, "LINE"),
|
||||
STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_WAIT_TIME 4
|
||||
{STRUCT_FLD(field_name, "WAIT_TIME"),
|
||||
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_WAIT_OBJECT 5
|
||||
{STRUCT_FLD(field_name, "WAIT_OBJECT"),
|
||||
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_WAIT_TYPE 6
|
||||
{STRUCT_FLD(field_name, "WAIT_TYPE"),
|
||||
STRUCT_FLD(field_length, 16),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_HOLDER_THREAD_ID 7
|
||||
{STRUCT_FLD(field_name, "HOLDER_THREAD_ID"),
|
||||
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_HOLDER_FILE 8
|
||||
{STRUCT_FLD(field_name, "HOLDER_FILE"),
|
||||
STRUCT_FLD(field_length, OS_FILE_MAX_PATH),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_HOLDER_LINE 9
|
||||
{STRUCT_FLD(field_name, "HOLDER_LINE"),
|
||||
STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_CREATED_FILE 10
|
||||
{STRUCT_FLD(field_name, "CREATED_FILE"),
|
||||
STRUCT_FLD(field_length, OS_FILE_MAX_PATH),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_CREATED_LINE 11
|
||||
{STRUCT_FLD(field_name, "CREATED_LINE"),
|
||||
STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_WRITER_THREAD 12
|
||||
{STRUCT_FLD(field_name, "WRITER_THREAD"),
|
||||
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_RESERVATION_MODE 13
|
||||
{STRUCT_FLD(field_name, "RESERVATION_MODE"),
|
||||
STRUCT_FLD(field_length, 16),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_READERS 14
|
||||
{STRUCT_FLD(field_name, "READERS"),
|
||||
STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_WAITERS_FLAG 15
|
||||
{STRUCT_FLD(field_name, "WAITERS_FLAG"),
|
||||
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_LOCK_WORD 16
|
||||
{STRUCT_FLD(field_name, "LOCK_WORD"),
|
||||
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_LAST_READER_FILE 17
|
||||
{STRUCT_FLD(field_name, "LAST_READER_FILE"),
|
||||
STRUCT_FLD(field_length, OS_FILE_MAX_PATH),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_LAST_READER_LINE 18
|
||||
{STRUCT_FLD(field_name, "LAST_READER_LINE"),
|
||||
STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_LAST_WRITER_FILE 19
|
||||
{STRUCT_FLD(field_name, "LAST_WRITER_FILE"),
|
||||
STRUCT_FLD(field_length, OS_FILE_MAX_PATH),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_LAST_WRITER_LINE 20
|
||||
{STRUCT_FLD(field_name, "LAST_WRITER_LINE"),
|
||||
STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
// SYS_SEMAPHORE_WAITS_OS_WAIT_COUNT 21
|
||||
{STRUCT_FLD(field_name, "OS_WAIT_COUNT"),
|
||||
STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
END_OF_ST_FIELD_INFO
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*******************************************************************//**
|
||||
Bind the dynamic table INFORMATION_SCHEMA.INNODB_SYS_SEMAPHORE_WAITS
|
||||
@return 0 on success */
|
||||
static
|
||||
int
|
||||
innodb_sys_semaphore_waits_init(
|
||||
/*============================*/
|
||||
void* p) /*!< in/out: table schema object */
|
||||
{
|
||||
ST_SCHEMA_TABLE* schema;
|
||||
|
||||
DBUG_ENTER("innodb_sys_semaphore_waits_init");
|
||||
|
||||
schema = (ST_SCHEMA_TABLE*) p;
|
||||
|
||||
schema->fields_info = innodb_sys_semaphore_waits_fields_info;
|
||||
schema->fill_table = sync_arr_fill_sys_semphore_waits_table;
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_semaphore_waits =
|
||||
{
|
||||
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
|
||||
/* int */
|
||||
STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
|
||||
|
||||
/* pointer to type-specific plugin descriptor */
|
||||
/* void* */
|
||||
STRUCT_FLD(info, &i_s_info),
|
||||
|
||||
/* plugin name */
|
||||
/* const char* */
|
||||
STRUCT_FLD(name, "INNODB_SYS_SEMAPHORE_WAITS"),
|
||||
|
||||
/* plugin author (for SHOW PLUGINS) */
|
||||
/* const char* */
|
||||
STRUCT_FLD(author, maria_plugin_author),
|
||||
|
||||
/* general descriptive text (for SHOW PLUGINS) */
|
||||
/* const char* */
|
||||
STRUCT_FLD(descr, "InnoDB SYS_SEMAPHORE_WAITS"),
|
||||
|
||||
/* the plugin license (PLUGIN_LICENSE_XXX) */
|
||||
/* int */
|
||||
STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
|
||||
|
||||
/* the function to invoke when plugin is loaded */
|
||||
/* int (*)(void*); */
|
||||
STRUCT_FLD(init, innodb_sys_semaphore_waits_init),
|
||||
|
||||
/* the function to invoke when plugin is unloaded */
|
||||
/* int (*)(void*); */
|
||||
STRUCT_FLD(deinit, i_s_common_deinit),
|
||||
|
||||
/* plugin version (for SHOW PLUGINS) */
|
||||
/* unsigned int */
|
||||
STRUCT_FLD(version, INNODB_VERSION_SHORT),
|
||||
|
||||
/* struct st_mysql_show_var* */
|
||||
STRUCT_FLD(status_vars, NULL),
|
||||
|
||||
/* struct st_mysql_sys_var** */
|
||||
STRUCT_FLD(system_vars, NULL),
|
||||
|
||||
/* Maria extension */
|
||||
STRUCT_FLD(version_info, INNODB_VERSION_STR),
|
||||
STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE),
|
||||
};
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2007, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyrigth (c) 2014, 2015, MariaDB Corporation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -21,12 +22,14 @@ this program; if not, write to the Free Software Foundation, Inc.,
|
|||
InnoDB INFORMATION SCHEMA tables interface to MySQL.
|
||||
|
||||
Created July 18, 2007 Vasil Dimov
|
||||
Modified Dec 29, 2014 Jan Lindström
|
||||
*******************************************************/
|
||||
|
||||
#ifndef i_s_h
|
||||
#define i_s_h
|
||||
|
||||
const char plugin_author[] = "Oracle Corporation";
|
||||
const char maria_plugin_author[] = "MariaDB Corporation";
|
||||
|
||||
#define st_mysql_plugin st_maria_plugin
|
||||
|
||||
|
@ -60,7 +63,91 @@ extern struct st_mysql_plugin i_s_innodb_sys_foreign_cols;
|
|||
extern struct st_mysql_plugin i_s_innodb_sys_tablespaces;
|
||||
extern struct st_mysql_plugin i_s_innodb_sys_datafiles;
|
||||
extern struct st_mysql_plugin i_s_innodb_changed_pages;
|
||||
extern struct st_mysql_plugin i_s_innodb_mutexes;
|
||||
extern struct st_maria_plugin i_s_innodb_tablespaces_encryption;
|
||||
extern struct st_maria_plugin i_s_innodb_tablespaces_scrubbing;
|
||||
extern struct st_mysql_plugin i_s_innodb_sys_semaphore_waits;
|
||||
|
||||
/** maximum number of buffer page info we would cache. */
|
||||
#define MAX_BUF_INFO_CACHED 10000
|
||||
|
||||
#define OK(expr) \
|
||||
if ((expr) != 0) { \
|
||||
DBUG_RETURN(1); \
|
||||
}
|
||||
|
||||
#define RETURN_IF_INNODB_NOT_STARTED(plugin_name) \
|
||||
do { \
|
||||
if (!srv_was_started) { \
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, \
|
||||
ER_CANT_FIND_SYSTEM_REC, \
|
||||
"InnoDB: SELECTing from " \
|
||||
"INFORMATION_SCHEMA.%s but " \
|
||||
"the InnoDB storage engine " \
|
||||
"is not installed", plugin_name); \
|
||||
DBUG_RETURN(0); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#if !defined __STRICT_ANSI__ && defined __GNUC__ && (__GNUC__) > 2 && \
|
||||
!defined __INTEL_COMPILER && !defined __clang__
|
||||
#define STRUCT_FLD(name, value) name: value
|
||||
#else
|
||||
#define STRUCT_FLD(name, value) value
|
||||
#endif
|
||||
|
||||
/* Don't use a static const variable here, as some C++ compilers (notably
|
||||
HPUX aCC: HP ANSI C++ B3910B A.03.65) can't handle it. */
|
||||
#define END_OF_ST_FIELD_INFO \
|
||||
{STRUCT_FLD(field_name, NULL), \
|
||||
STRUCT_FLD(field_length, 0), \
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_NULL), \
|
||||
STRUCT_FLD(value, 0), \
|
||||
STRUCT_FLD(field_flags, 0), \
|
||||
STRUCT_FLD(old_name, ""), \
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}
|
||||
|
||||
/** Fields on INFORMATION_SCHEMA.SYS_SEMAMPHORE_WAITS table */
|
||||
#define SYS_SEMAPHORE_WAITS_THREAD_ID 0
|
||||
#define SYS_SEMAPHORE_WAITS_OBJECT_NAME 1
|
||||
#define SYS_SEMAPHORE_WAITS_FILE 2
|
||||
#define SYS_SEMAPHORE_WAITS_LINE 3
|
||||
#define SYS_SEMAPHORE_WAITS_WAIT_TIME 4
|
||||
#define SYS_SEMAPHORE_WAITS_WAIT_OBJECT 5
|
||||
#define SYS_SEMAPHORE_WAITS_WAIT_TYPE 6
|
||||
#define SYS_SEMAPHORE_WAITS_HOLDER_THREAD_ID 7
|
||||
#define SYS_SEMAPHORE_WAITS_HOLDER_FILE 8
|
||||
#define SYS_SEMAPHORE_WAITS_HOLDER_LINE 9
|
||||
#define SYS_SEMAPHORE_WAITS_CREATED_FILE 10
|
||||
#define SYS_SEMAPHORE_WAITS_CREATED_LINE 11
|
||||
#define SYS_SEMAPHORE_WAITS_WRITER_THREAD 12
|
||||
#define SYS_SEMAPHORE_WAITS_RESERVATION_MODE 13
|
||||
#define SYS_SEMAPHORE_WAITS_READERS 14
|
||||
#define SYS_SEMAPHORE_WAITS_WAITERS_FLAG 15
|
||||
#define SYS_SEMAPHORE_WAITS_LOCK_WORD 16
|
||||
#define SYS_SEMAPHORE_WAITS_LAST_READER_FILE 17
|
||||
#define SYS_SEMAPHORE_WAITS_LAST_READER_LINE 18
|
||||
#define SYS_SEMAPHORE_WAITS_LAST_WRITER_FILE 19
|
||||
#define SYS_SEMAPHORE_WAITS_LAST_WRITER_LINE 20
|
||||
#define SYS_SEMAPHORE_WAITS_OS_WAIT_COUNT 21
|
||||
|
||||
/*******************************************************************//**
|
||||
Auxiliary function to store ulint value in MYSQL_TYPE_LONGLONG field.
|
||||
If the value is ULINT_UNDEFINED then the field it set to NULL.
|
||||
@return 0 on success */
|
||||
int
|
||||
field_store_ulint(
|
||||
/*==============*/
|
||||
Field* field, /*!< in/out: target field for storage */
|
||||
ulint n); /*!< in: value to store */
|
||||
|
||||
/*******************************************************************//**
|
||||
Auxiliary function to store char* value in MYSQL_TYPE_STRING field.
|
||||
@return 0 on success */
|
||||
int
|
||||
field_store_string(
|
||||
/*===============*/
|
||||
Field* field, /*!< in/out: target field for storage */
|
||||
const char* str); /*!< in: NUL-terminated utf-8 string,
|
||||
or NULL */
|
||||
#endif /* i_s_h */
|
||||
|
|
|
@ -17,6 +17,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
|
|||
|
||||
*****************************************************************************/
|
||||
|
||||
#include "univ.i"
|
||||
#include <mysqld_error.h>
|
||||
#include <sql_acl.h> // PROCESS_ACL
|
||||
|
||||
|
@ -43,94 +44,6 @@ this program; if not, write to the Free Software Foundation, Inc.,
|
|||
|
||||
#define PLUGIN_AUTHOR "Percona Inc."
|
||||
|
||||
#define OK(expr) \
|
||||
if ((expr) != 0) { \
|
||||
DBUG_RETURN(1); \
|
||||
}
|
||||
|
||||
#define RETURN_IF_INNODB_NOT_STARTED(plugin_name) \
|
||||
do { \
|
||||
if (!srv_was_started) { \
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, \
|
||||
ER_CANT_FIND_SYSTEM_REC, \
|
||||
"InnoDB: SELECTing from " \
|
||||
"INFORMATION_SCHEMA.%s but " \
|
||||
"the InnoDB storage engine " \
|
||||
"is not installed", plugin_name); \
|
||||
DBUG_RETURN(0); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#if !defined __STRICT_ANSI__ && defined __GNUC__ && (__GNUC__) > 2 && \
|
||||
!defined __INTEL_COMPILER && !defined __clang__
|
||||
#define STRUCT_FLD(name, value) name: value
|
||||
#else
|
||||
#define STRUCT_FLD(name, value) value
|
||||
#endif
|
||||
|
||||
#define END_OF_ST_FIELD_INFO \
|
||||
{STRUCT_FLD(field_name, NULL), \
|
||||
STRUCT_FLD(field_length, 0), \
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_NULL), \
|
||||
STRUCT_FLD(value, 0), \
|
||||
STRUCT_FLD(field_flags, 0), \
|
||||
STRUCT_FLD(old_name, ""), \
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}
|
||||
|
||||
|
||||
/*******************************************************************//**
|
||||
Auxiliary function to store ulint value in MYSQL_TYPE_LONGLONG field.
|
||||
If the value is ULINT_UNDEFINED then the field it set to NULL.
|
||||
@return 0 on success */
|
||||
static
|
||||
int
|
||||
field_store_ulint(
|
||||
/*==============*/
|
||||
Field* field, /*!< in/out: target field for storage */
|
||||
ulint n) /*!< in: value to store */
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (n != ULINT_UNDEFINED) {
|
||||
|
||||
ret = field->store(n);
|
||||
field->set_notnull();
|
||||
} else {
|
||||
|
||||
ret = 0; /* success */
|
||||
field->set_null();
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/*******************************************************************//**
|
||||
Auxiliary function to store char* value in MYSQL_TYPE_STRING field.
|
||||
@return 0 on success */
|
||||
static
|
||||
int
|
||||
field_store_string(
|
||||
/*===============*/
|
||||
Field* field, /*!< in/out: target field for storage */
|
||||
const char* str) /*!< in: NUL-terminated utf-8 string,
|
||||
or NULL */
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (str != NULL) {
|
||||
|
||||
ret = field->store(str, strlen(str),
|
||||
system_charset_info);
|
||||
field->set_notnull();
|
||||
} else {
|
||||
|
||||
ret = 0; /* success */
|
||||
field->set_null();
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
i_s_common_deinit(
|
||||
|
|
|
@ -708,6 +708,9 @@ extern ulong srv_fatal_semaphore_wait_threshold;
|
|||
/** Default encryption key used for page encryption */
|
||||
extern uint srv_default_page_encryption_key;
|
||||
|
||||
/** Enable semaphore request instrumentation */
|
||||
extern my_bool srv_instrument_semaphores;
|
||||
|
||||
# ifdef UNIV_PFS_THREAD
|
||||
/* Keys to register InnoDB threads with performance schema */
|
||||
extern mysql_pfs_key_t buf_page_cleaner_thread_key;
|
||||
|
|
|
@ -31,7 +31,7 @@ Created 9/5/1995 Heikki Tuuri
|
|||
#include "ut0mem.h"
|
||||
#include "os0thread.h"
|
||||
|
||||
/** Synchronization wait array cell */
|
||||
/** Synchonization cell */
|
||||
struct sync_cell_t;
|
||||
/** Synchronization wait array */
|
||||
struct sync_array_t;
|
||||
|
@ -154,6 +154,16 @@ UNIV_INTERN
|
|||
void
|
||||
sync_array_print_xtradb(void);
|
||||
|
||||
/*****************************************************************//**
|
||||
Gets the nth cell in array.
|
||||
@return cell */
|
||||
UNIV_INTERN
|
||||
sync_cell_t*
|
||||
sync_array_get_nth_cell(
|
||||
/*====================*/
|
||||
sync_array_t* arr, /*!< in: sync array */
|
||||
ulint n); /*!< in: index */
|
||||
|
||||
#ifndef UNIV_NONINL
|
||||
#include "sync0arr.ic"
|
||||
#endif
|
||||
|
|
|
@ -40,6 +40,9 @@ Created 9/11/1995 Heikki Tuuri
|
|||
#include "sync0sync.h"
|
||||
#include "os0sync.h"
|
||||
|
||||
/** Enable semaphore request instrumentation */
|
||||
extern my_bool srv_instrument_semaphores;
|
||||
|
||||
/* The following undef is to prevent a name conflict with a macro
|
||||
in MySQL: */
|
||||
#undef rw_lock_t
|
||||
|
@ -153,14 +156,14 @@ defined, the rwlock are instrumented with performance schema probes. */
|
|||
# ifdef UNIV_DEBUG
|
||||
# ifdef UNIV_SYNC_DEBUG
|
||||
# define rw_lock_create(K, L, level) \
|
||||
rw_lock_create_func((L), (level), __FILE__, __LINE__, #L)
|
||||
rw_lock_create_func((L), (level), #L, __FILE__, __LINE__)
|
||||
# else /* UNIV_SYNC_DEBUG */
|
||||
# define rw_lock_create(K, L, level) \
|
||||
rw_lock_create_func((L), __FILE__, __LINE__, #L)
|
||||
rw_lock_create_func((L), #L, __FILE__, __LINE__)
|
||||
# endif/* UNIV_SYNC_DEBUG */
|
||||
# else /* UNIV_DEBUG */
|
||||
# define rw_lock_create(K, L, level) \
|
||||
rw_lock_create_func((L), #L)
|
||||
rw_lock_create_func((L), __FILE__, __LINE__)
|
||||
# endif /* UNIV_DEBUG */
|
||||
|
||||
/**************************************************************//**
|
||||
|
@ -218,14 +221,14 @@ unlocking, not the corresponding function. */
|
|||
# ifdef UNIV_DEBUG
|
||||
# ifdef UNIV_SYNC_DEBUG
|
||||
# define rw_lock_create(K, L, level) \
|
||||
pfs_rw_lock_create_func((K), (L), (level), __FILE__, __LINE__, #L)
|
||||
pfs_rw_lock_create_func((K), (L), (level), #L, __FILE__, __LINE__)
|
||||
# else /* UNIV_SYNC_DEBUG */
|
||||
# define rw_lock_create(K, L, level) \
|
||||
pfs_rw_lock_create_func((K), (L), __FILE__, __LINE__, #L)
|
||||
pfs_rw_lock_create_func((K), (L), #L, __FILE__, __LINE__)
|
||||
# endif/* UNIV_SYNC_DEBUG */
|
||||
# else /* UNIV_DEBUG */
|
||||
# define rw_lock_create(K, L, level) \
|
||||
pfs_rw_lock_create_func((K), (L), #L)
|
||||
pfs_rw_lock_create_func((K), (L), #L, __FILE__, __LINE__)
|
||||
# endif /* UNIV_DEBUG */
|
||||
|
||||
/******************************************************************
|
||||
|
@ -295,10 +298,10 @@ rw_lock_create_func(
|
|||
# ifdef UNIV_SYNC_DEBUG
|
||||
ulint level, /*!< in: level */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
const char* cfile_name, /*!< in: file name where created */
|
||||
ulint cline, /*!< in: file line where created */
|
||||
#endif /* UNIV_DEBUG */
|
||||
const char* cmutex_name); /*!< in: mutex name */
|
||||
const char* cmutex_name, /*!< in: mutex name */
|
||||
const char* cfile_name, /*!< in: file name where created */
|
||||
ulint cline); /*!< in: file line where created */
|
||||
/******************************************************************//**
|
||||
Creates, or rather, initializes a priority rw-lock object in a specified memory
|
||||
location (which must be appropriately aligned). The rw-lock is initialized
|
||||
|
@ -313,10 +316,10 @@ rw_lock_create_func(
|
|||
# ifdef UNIV_SYNC_DEBUG
|
||||
ulint level, /*!< in: level */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
const char* cfile_name, /*!< in: file name where created */
|
||||
ulint cline, /*!< in: file line where created */
|
||||
#endif /* UNIV_DEBUG */
|
||||
const char* cmutex_name); /*!< in: mutex name */
|
||||
const char* cmutex_name, /*!< in: mutex name */
|
||||
const char* cfile_name, /*!< in: file name where created */
|
||||
ulint cline); /*!< in: file line where created */
|
||||
/******************************************************************//**
|
||||
Calling this function is obligatory only if the memory buffer containing
|
||||
the rw-lock is freed. Removes an rw-lock object from the global list. The
|
||||
|
@ -752,8 +755,11 @@ struct rw_lock_t {
|
|||
struct PSI_rwlock *pfs_psi;/*!< The instrumentation hook */
|
||||
#endif
|
||||
ulint count_os_wait; /*!< Count of os_waits. May not be accurate */
|
||||
//const char* cfile_name;/*!< File name where lock created */
|
||||
const char* cfile_name;/*!< File name where lock created */
|
||||
const char* lock_name;/*!< lock name */
|
||||
os_thread_id_t thread_id;/*!< thread id */
|
||||
const char* file_name;/*!< File name where the lock was obtained */
|
||||
ulint line; /*!< Line where the rw-lock was locked */
|
||||
/* last s-lock file/line is not guaranteed to be correct */
|
||||
const char* last_s_file_name;/*!< File name where last s-locked */
|
||||
const char* last_x_file_name;/*!< File name where last x-locked */
|
||||
|
@ -764,7 +770,7 @@ struct rw_lock_t {
|
|||
are at the start of this struct, thus we can
|
||||
peek this field without causing much memory
|
||||
bus traffic */
|
||||
//unsigned cline:14; /*!< Line where created */
|
||||
unsigned cline:14; /*!< Line where created */
|
||||
unsigned last_s_line:14; /*!< Line number where last time s-locked */
|
||||
unsigned last_x_line:14; /*!< Line number where last time x-locked */
|
||||
#ifdef UNIV_DEBUG
|
||||
|
@ -853,10 +859,10 @@ pfs_rw_lock_create_func(
|
|||
# ifdef UNIV_SYNC_DEBUG
|
||||
ulint level, /*!< in: level */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
const char* cfile_name, /*!< in: file name where created */
|
||||
ulint cline, /*!< in: file line where created */
|
||||
#endif /* UNIV_DEBUG */
|
||||
const char* cmutex_name); /*!< in: mutex name */
|
||||
const char* cmutex_name, /*!< in: mutex name */
|
||||
const char* cfile_name, /*!< in: file name where created */
|
||||
ulint cline); /*!< in: file line where created */
|
||||
|
||||
/******************************************************************//**
|
||||
Performance schema instrumented wrap function for rw_lock_create_func()
|
||||
|
@ -873,10 +879,10 @@ pfs_rw_lock_create_func(
|
|||
# ifdef UNIV_SYNC_DEBUG
|
||||
ulint level, /*!< in: level */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
const char* cfile_name, /*!< in: file name where created */
|
||||
ulint cline, /*!< in: file line where created */
|
||||
#endif /* UNIV_DEBUG */
|
||||
const char* cmutex_name); /*!< in: mutex name */
|
||||
const char* cmutex_name, /*!< in: mutex name */
|
||||
const char* cfile_name, /*!< in: file name where created */
|
||||
ulint cline); /*!< in: file line where created */
|
||||
|
||||
/******************************************************************//**
|
||||
Performance schema instrumented wrap function for rw_lock_x_lock_func()
|
||||
|
|
|
@ -382,6 +382,12 @@ rw_lock_s_lock_low(
|
|||
lock->last_s_file_name = file_name;
|
||||
lock->last_s_line = line;
|
||||
|
||||
if (srv_instrument_semaphores) {
|
||||
lock->thread_id = os_thread_get_curr_id();
|
||||
lock->file_name = file_name;
|
||||
lock->line = line;
|
||||
}
|
||||
|
||||
return(TRUE); /* locking succeeded */
|
||||
}
|
||||
|
||||
|
@ -551,6 +557,12 @@ rw_lock_x_lock_func_nowait(
|
|||
rw_lock_add_debug_info(lock, 0, RW_LOCK_EX, file_name, line);
|
||||
#endif
|
||||
|
||||
if (srv_instrument_semaphores) {
|
||||
lock->thread_id = os_thread_get_curr_id();
|
||||
lock->file_name = file_name;
|
||||
lock->line = line;
|
||||
}
|
||||
|
||||
lock->last_x_file_name = file_name;
|
||||
lock->last_x_line = line;
|
||||
|
||||
|
@ -799,10 +811,10 @@ pfs_rw_lock_create_func(
|
|||
# ifdef UNIV_SYNC_DEBUG
|
||||
ulint level, /*!< in: level */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
const char* cfile_name, /*!< in: file name where created */
|
||||
ulint cline, /*!< in: file line where created */
|
||||
# endif /* UNIV_DEBUG */
|
||||
const char* cmutex_name) /*!< in: mutex name */
|
||||
const char* cmutex_name, /*!< in: mutex name */
|
||||
const char* cfile_name, /*!< in: file name where created */
|
||||
ulint cline) /*!< in: file line where created */
|
||||
{
|
||||
/* Initialize the rwlock for performance schema */
|
||||
lock->pfs_psi = PSI_RWLOCK_CALL(init_rwlock)(key, lock);
|
||||
|
@ -813,10 +825,10 @@ pfs_rw_lock_create_func(
|
|||
# ifdef UNIV_SYNC_DEBUG
|
||||
level,
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
cfile_name,
|
||||
cline,
|
||||
# endif /* UNIV_DEBUG */
|
||||
cmutex_name);
|
||||
cmutex_name,
|
||||
cfile_name,
|
||||
cline);
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
|
@ -834,10 +846,10 @@ pfs_rw_lock_create_func(
|
|||
# ifdef UNIV_SYNC_DEBUG
|
||||
ulint level, /*!< in: level */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
const char* cfile_name, /*!< in: file name where created */
|
||||
ulint cline, /*!< in: file line where created */
|
||||
# endif /* UNIV_DEBUG */
|
||||
const char* cmutex_name) /*!< in: mutex name */
|
||||
const char* cmutex_name, /*!< in: mutex name */
|
||||
const char* cfile_name, /*!< in: file name where created */
|
||||
ulint cline) /*!< in: file line where created */
|
||||
{
|
||||
/* Initialize the rwlock for performance schema */
|
||||
lock->base_lock.pfs_psi = PSI_RWLOCK_CALL(init_rwlock)(key, lock);
|
||||
|
@ -848,10 +860,10 @@ pfs_rw_lock_create_func(
|
|||
# ifdef UNIV_SYNC_DEBUG
|
||||
level,
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
cfile_name,
|
||||
cline,
|
||||
# endif /* UNIV_DEBUG */
|
||||
cmutex_name);
|
||||
cmutex_name,
|
||||
cfile_name,
|
||||
cline);
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
|
|
|
@ -43,6 +43,9 @@ Created 9/5/1995 Heikki Tuuri
|
|||
#include "sync0arr.h"
|
||||
#include "ut0counter.h"
|
||||
|
||||
/** Enable semaphore request instrumentation */
|
||||
extern my_bool srv_instrument_semaphores;
|
||||
|
||||
#if defined(UNIV_DEBUG) && !defined(UNIV_HOTBACKUP)
|
||||
extern "C" my_bool timed_mutexes;
|
||||
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
|
||||
|
@ -189,7 +192,7 @@ necessary only if the memory block containing it is freed. */
|
|||
# endif/* UNIV_SYNC_DEBUG */
|
||||
# else
|
||||
# define mutex_create(K, M, level) \
|
||||
pfs_mutex_create_func((K), (M), #M)
|
||||
pfs_mutex_create_func((K), (M), __FILE__, __LINE__, #M)
|
||||
# endif /* UNIV_DEBUG */
|
||||
|
||||
# define mutex_enter(M) \
|
||||
|
@ -256,9 +259,9 @@ mutex_create_func(
|
|||
# ifdef UNIV_SYNC_DEBUG
|
||||
ulint level, /*!< in: level */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
#endif /* UNIV_DEBUG */
|
||||
const char* cfile_name, /*!< in: file name where created */
|
||||
ulint cline, /*!< in: file line where created */
|
||||
#endif /* UNIV_DEBUG */
|
||||
const char* cmutex_name); /*!< in: mutex name */
|
||||
|
||||
/******************************************************************//**
|
||||
|
@ -275,11 +278,11 @@ mutex_create_func(
|
|||
# ifdef UNIV_SYNC_DEBUG
|
||||
ulint level, /*!< in: level */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
#endif /* UNIV_DEBUG */
|
||||
const char* cfile_name, /*!< in: file name where
|
||||
created */
|
||||
ulint cline, /*!< in: file line where
|
||||
created */
|
||||
#endif /* UNIV_DEBUG */
|
||||
const char* cmutex_name); /*!< in: mutex name */
|
||||
/******************************************************************//**
|
||||
NOTE! Use the corresponding macro mutex_free(), not directly this function!
|
||||
|
@ -402,9 +405,9 @@ pfs_mutex_create_func(
|
|||
# ifdef UNIV_SYNC_DEBUG
|
||||
ulint level, /*!< in: level */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
# endif /* UNIV_DEBUG */
|
||||
const char* cfile_name, /*!< in: file name where created */
|
||||
ulint cline, /*!< in: file line where created */
|
||||
# endif /* UNIV_DEBUG */
|
||||
const char* cmutex_name);
|
||||
/******************************************************************//**
|
||||
NOTE! Please use the corresponding macro mutex_create(), not directly
|
||||
|
@ -423,11 +426,11 @@ pfs_mutex_create_func(
|
|||
# ifdef UNIV_SYNC_DEBUG
|
||||
ulint level, /*!< in: level */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
# endif /* UNIV_DEBUG */
|
||||
const char* cfile_name, /*!< in: file name where
|
||||
created */
|
||||
ulint cline, /*!< in: file line where
|
||||
created */
|
||||
# endif /* UNIV_DEBUG */
|
||||
const char* cmutex_name);
|
||||
/******************************************************************//**
|
||||
NOTE! Please use the corresponding macro mutex_enter(), not directly
|
||||
|
@ -947,27 +950,28 @@ struct ib_mutex_t {
|
|||
Otherwise, this is 0. */
|
||||
UT_LIST_NODE_T(ib_mutex_t) list; /*!< All allocated mutexes are put into
|
||||
a list. Pointers to the next and prev. */
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
const char* file_name; /*!< File where the mutex was locked */
|
||||
ulint line; /*!< Line where the mutex was locked */
|
||||
ulint level; /*!< Level in the global latching order */
|
||||
ulint level; /*!< Level in the global latching order */
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
#ifdef UNIV_DEBUG
|
||||
const char* cfile_name;/*!< File name where mutex created */
|
||||
ulint cline; /*!< Line where created */
|
||||
#endif
|
||||
|
||||
const char* file_name; /*!< File where the mutex was locked */
|
||||
ulint line; /*!< Line where the mutex was locked */
|
||||
const char* cfile_name; /*!< File name where mutex created */
|
||||
ulint cline; /*!< Line where created */
|
||||
ulong count_os_wait; /*!< count of os_wait */
|
||||
const char* cmutex_name; /*!< mutex name */
|
||||
os_thread_id_t thread_id; /*!< The thread id of the thread
|
||||
which locked the mutex. */
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
|
||||
/** Value of mutex_t::magic_n */
|
||||
# define MUTEX_MAGIC_N 979585UL
|
||||
|
||||
os_thread_id_t thread_id; /*!< The thread id of the thread
|
||||
which locked the mutex. */
|
||||
ulint magic_n; /*!< MUTEX_MAGIC_N */
|
||||
ulint ib_mutex_type; /*!< 0=usual mutex, 1=rw_lock mutex */
|
||||
#endif /* UNIV_DEBUG */
|
||||
const char* cmutex_name; /*!< mutex name */
|
||||
|
||||
#ifdef UNIV_PFS_MUTEX
|
||||
struct PSI_mutex* pfs_psi; /*!< The performance schema
|
||||
instrumentation hook */
|
||||
|
|
|
@ -165,7 +165,7 @@ mutex_exit_func(
|
|||
{
|
||||
ut_ad(mutex_own(mutex));
|
||||
|
||||
ut_d(mutex->thread_id = (os_thread_id_t) ULINT_UNDEFINED);
|
||||
mutex->thread_id = (os_thread_id_t) ULINT_UNDEFINED;
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
sync_thread_reset_level(mutex);
|
||||
|
@ -205,7 +205,7 @@ mutex_exit_func(
|
|||
{
|
||||
ut_ad(mutex_own(mutex));
|
||||
|
||||
ut_d(mutex->base_mutex.thread_id = (os_thread_id_t) ULINT_UNDEFINED);
|
||||
mutex->base_mutex.thread_id = (os_thread_id_t) ULINT_UNDEFINED;
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
sync_thread_reset_level(&mutex->base_mutex);
|
||||
|
@ -264,10 +264,15 @@ mutex_enter_func(
|
|||
the atomic test_and_set; we could peek, and possibly save time. */
|
||||
|
||||
if (!ib_mutex_test_and_set(mutex)) {
|
||||
ut_d(mutex->thread_id = os_thread_get_curr_id());
|
||||
mutex->thread_id = os_thread_get_curr_id();
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
mutex_set_debug_info(mutex, file_name, line);
|
||||
#endif
|
||||
if (srv_instrument_semaphores) {
|
||||
mutex->file_name = file_name;
|
||||
mutex->line = line;
|
||||
}
|
||||
|
||||
return; /* Succeeded! */
|
||||
}
|
||||
|
||||
|
@ -304,10 +309,15 @@ mutex_enter_func(
|
|||
the atomic test_and_set; we could peek, and possibly save time. */
|
||||
|
||||
if (!ib_mutex_test_and_set(&mutex->base_mutex)) {
|
||||
ut_d(mutex->base_mutex.thread_id = os_thread_get_curr_id());
|
||||
mutex->base_mutex.thread_id = os_thread_get_curr_id();
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
mutex_set_debug_info(&mutex->base_mutex, file_name, line);
|
||||
#endif
|
||||
if(srv_instrument_semaphores) {
|
||||
mutex->base_mutex.file_name = file_name;
|
||||
mutex->base_mutex.line = line;
|
||||
}
|
||||
|
||||
return; /* Succeeded! */
|
||||
}
|
||||
|
||||
|
@ -515,9 +525,9 @@ pfs_mutex_create_func(
|
|||
# ifdef UNIV_SYNC_DEBUG
|
||||
ulint level, /*!< in: level */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
# endif /* UNIV_DEBUG */
|
||||
const char* cfile_name, /*!< in: file name where created */
|
||||
ulint cline, /*!< in: file line where created */
|
||||
# endif /* UNIV_DEBUG */
|
||||
const char* cmutex_name) /*!< in: mutex name */
|
||||
{
|
||||
mutex->pfs_psi = PSI_MUTEX_CALL(init_mutex)(key, mutex);
|
||||
|
@ -527,9 +537,9 @@ pfs_mutex_create_func(
|
|||
# ifdef UNIV_SYNC_DEBUG
|
||||
level,
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
# endif /* UNIV_DEBUG */
|
||||
cfile_name,
|
||||
cline,
|
||||
# endif /* UNIV_DEBUG */
|
||||
cmutex_name);
|
||||
}
|
||||
|
||||
|
@ -550,11 +560,11 @@ pfs_mutex_create_func(
|
|||
# ifdef UNIV_SYNC_DEBUG
|
||||
ulint level, /*!< in: level */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
# endif /* UNIV_DEBUG */
|
||||
const char* cfile_name, /*!< in: file name where
|
||||
created */
|
||||
ulint cline, /*!< in: file line where
|
||||
created */
|
||||
# endif /* UNIV_DEBUG */
|
||||
const char* cmutex_name)
|
||||
{
|
||||
mutex->base_mutex.pfs_psi = PSI_MUTEX_CALL(init_mutex)(key, mutex);
|
||||
|
@ -564,9 +574,9 @@ pfs_mutex_create_func(
|
|||
# ifdef UNIV_SYNC_DEBUG
|
||||
level,
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
# endif /* UNIV_DEBUG */
|
||||
cfile_name,
|
||||
cline,
|
||||
# endif /* UNIV_DEBUG */
|
||||
cmutex_name);
|
||||
}
|
||||
|
||||
|
|
|
@ -78,6 +78,7 @@ Created 10/8/1995 Heikki Tuuri
|
|||
#include "fil0pagecompress.h"
|
||||
#include <my_rdtsc.h>
|
||||
#include "btr0scrub.h"
|
||||
#include "fil0pageencryption.h"
|
||||
|
||||
/* prototypes of new functions added to ha_innodb.cc for kill_idle_transaction */
|
||||
ibool innobase_thd_is_idle(const void* thd);
|
||||
|
@ -670,7 +671,10 @@ second. */
|
|||
static time_t srv_last_log_flush_time;
|
||||
|
||||
/** Default encryption key used for page encryption */
|
||||
UNIV_INTERN uint srv_default_page_encryption_key;
|
||||
UNIV_INTERN uint srv_default_page_encryption_key = DEFAULT_ENCRYPTION_KEY;
|
||||
|
||||
/** Enable semaphore request instrumentation */
|
||||
UNIV_INTERN my_bool srv_instrument_semaphores = FALSE;
|
||||
|
||||
/* Interval in seconds at which various tasks are performed by the
|
||||
master thread when server is active. In order to balance the workload,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2008, Google Inc.
|
||||
Copyright (c) 2013, 2014, MariaDB Corporation. All Rights Reserved.
|
||||
Copyright (c) 2013, 2015, MariaDB Corporation. All Rights Reserved.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted by
|
||||
Google, Inc. Those modifications are gratefully acknowledged and are described
|
||||
|
@ -31,11 +31,26 @@ The wait array used in synchronization primitives
|
|||
Created 9/5/1995 Heikki Tuuri
|
||||
*******************************************************/
|
||||
|
||||
#include "univ.i"
|
||||
|
||||
#include "sync0arr.h"
|
||||
#ifdef UNIV_NONINL
|
||||
#include "sync0arr.ic"
|
||||
#endif
|
||||
|
||||
#include <mysqld_error.h>
|
||||
#include <mysql/plugin.h>
|
||||
#include <hash.h>
|
||||
#include <myisampack.h>
|
||||
#include <sql_acl.h>
|
||||
#include <mysys_err.h>
|
||||
#include <my_sys.h>
|
||||
#include "srv0srv.h"
|
||||
#include "srv0start.h"
|
||||
#include "i_s.h"
|
||||
#include <sql_plugin.h>
|
||||
#include <innodb_priv.h>
|
||||
|
||||
#include "sync0sync.h"
|
||||
#include "sync0rw.h"
|
||||
#include "os0sync.h"
|
||||
|
@ -117,7 +132,6 @@ for an event allocated for the array without owning the
|
|||
protecting mutex (depending on the case: OS or database mutex), but
|
||||
all changes (set or reset) to the state of the event must be made
|
||||
while owning the mutex. */
|
||||
|
||||
/** Synchronization array */
|
||||
struct sync_array_t {
|
||||
ulint n_reserved; /*!< number of currently reserved
|
||||
|
@ -170,7 +184,6 @@ sync_array_detect_deadlock(
|
|||
/*****************************************************************//**
|
||||
Gets the nth cell in array.
|
||||
@return cell */
|
||||
static
|
||||
sync_cell_t*
|
||||
sync_array_get_nth_cell(
|
||||
/*====================*/
|
||||
|
@ -1374,3 +1387,173 @@ sync_array_print_xtradb(void)
|
|||
fputs("InnoDB: Semaphore wait debug output ended:\n", stderr);
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Get number of items on sync array. */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
sync_arr_get_n_items(void)
|
||||
/*======================*/
|
||||
{
|
||||
sync_array_t* sync_arr = sync_array_get();
|
||||
return (ulint) sync_arr->n_cells;
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
Get specified item from sync array if it is reserved. Set given
|
||||
pointer to array item if it is reserved.
|
||||
@return true if item is reserved, false othervise */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
sync_arr_get_item(
|
||||
/*==============*/
|
||||
ulint i, /*!< in: requested item */
|
||||
sync_cell_t **cell) /*!< out: cell contents if item
|
||||
reserved */
|
||||
{
|
||||
sync_array_t* sync_arr;
|
||||
sync_cell_t* wait_cell;
|
||||
void* wait_object;
|
||||
ibool found = FALSE;
|
||||
|
||||
sync_arr = sync_array_get();
|
||||
wait_cell = sync_array_get_nth_cell(sync_arr, i);
|
||||
|
||||
if (wait_cell) {
|
||||
wait_object = wait_cell->wait_object;
|
||||
|
||||
if(wait_object != NULL && wait_cell->waiting) {
|
||||
found = TRUE;
|
||||
*cell = wait_cell;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/*******************************************************************//**
|
||||
Function to populate INFORMATION_SCHEMA.INNODB_SYS_SEMAPHORE_WAITS table.
|
||||
Loop through each item on sync array, and extract the column
|
||||
information and fill the INFORMATION_SCHEMA.INNODB_SYS_SEMAPHORE_WAITS table.
|
||||
@return 0 on success */
|
||||
UNIV_INTERN
|
||||
int
|
||||
sync_arr_fill_sys_semphore_waits_table(
|
||||
/*===================================*/
|
||||
THD* thd, /*!< in: thread */
|
||||
TABLE_LIST* tables, /*!< in/out: tables to fill */
|
||||
Item* ) /*!< in: condition (not used) */
|
||||
{
|
||||
Field** fields;
|
||||
ulint n_items;
|
||||
|
||||
DBUG_ENTER("i_s_sys_semaphore_waits_fill_table");
|
||||
RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
|
||||
|
||||
/* deny access to user without PROCESS_ACL privilege */
|
||||
if (check_global_access(thd, PROCESS_ACL)) {
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
fields = tables->table->field;
|
||||
n_items = sync_arr_get_n_items();
|
||||
ulint type;
|
||||
|
||||
for(ulint i=0; i < n_items;i++) {
|
||||
sync_cell_t *cell=NULL;
|
||||
if (sync_arr_get_item(i, &cell)) {
|
||||
ib_prio_mutex_t* prio_mutex;
|
||||
ib_mutex_t* mutex;
|
||||
type = cell->request_type;
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_THREAD_ID], (longlong)os_thread_pf(cell->thread)));
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_FILE], innobase_basename(cell->file)));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_LINE], cell->line));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_WAIT_TIME], (longlong)difftime(time(NULL), cell->reservation_time)));
|
||||
|
||||
if (type == SYNC_MUTEX || type == SYNC_PRIO_MUTEX) {
|
||||
if (type == SYNC_MUTEX) {
|
||||
mutex = static_cast<ib_mutex_t*>(cell->old_wait_mutex);
|
||||
} else {
|
||||
|
||||
prio_mutex = static_cast<ib_prio_mutex_t*>
|
||||
(cell->old_wait_mutex);
|
||||
mutex = &prio_mutex->base_mutex;
|
||||
}
|
||||
|
||||
if (mutex) {
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_OBJECT_NAME], mutex->cmutex_name));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_WAIT_OBJECT], (longlong)mutex));
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_WAIT_TYPE], "MUTEX"));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_HOLDER_THREAD_ID], (longlong)mutex->thread_id));
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_HOLDER_FILE], innobase_basename(mutex->file_name)));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_HOLDER_LINE], mutex->line));
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_CREATED_FILE], innobase_basename(mutex->cfile_name)));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_CREATED_LINE], mutex->cline));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_WAITERS_FLAG], (longlong)mutex->waiters));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_LOCK_WORD], (longlong)mutex->lock_word));
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_LAST_WRITER_FILE], innobase_basename(mutex->file_name)));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_LAST_WRITER_LINE], mutex->line));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_OS_WAIT_COUNT], mutex->count_os_wait));
|
||||
}
|
||||
} else if (type == RW_LOCK_EX
|
||||
|| type == RW_LOCK_WAIT_EX
|
||||
|| type == RW_LOCK_SHARED
|
||||
|| type == PRIO_RW_LOCK_SHARED
|
||||
|| type == PRIO_RW_LOCK_EX) {
|
||||
rw_lock_t* rwlock=NULL;
|
||||
prio_rw_lock_t* prio_rwlock=NULL;
|
||||
|
||||
if (type == RW_LOCK_EX || type == RW_LOCK_WAIT_EX
|
||||
|| type == RW_LOCK_SHARED) {
|
||||
|
||||
rwlock = static_cast<rw_lock_t *>
|
||||
(cell->old_wait_rw_lock);
|
||||
} else {
|
||||
|
||||
prio_rwlock = static_cast<prio_rw_lock_t *>
|
||||
(cell->old_wait_rw_lock);
|
||||
rwlock = &prio_rwlock->base_lock;
|
||||
}
|
||||
|
||||
if (rwlock) {
|
||||
ulint writer = rw_lock_get_writer(rwlock);
|
||||
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_WAIT_OBJECT], (longlong)rwlock));
|
||||
if (type == RW_LOCK_EX) {
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_WAIT_TYPE], "RW_LOCK_EX"));
|
||||
} else if (type == RW_LOCK_WAIT_EX) {
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_WAIT_TYPE], "RW_LOCK_WAIT_EX"));
|
||||
} else if (type == RW_LOCK_SHARED) {
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_WAIT_TYPE], "RW_LOCK_SHARED"));
|
||||
}
|
||||
|
||||
if (writer != RW_LOCK_NOT_LOCKED) {
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_OBJECT_NAME], rwlock->lock_name));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_WRITER_THREAD], (longlong)os_thread_pf(rwlock->writer_thread)));
|
||||
|
||||
if (writer == RW_LOCK_EX) {
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_RESERVATION_MODE], "RW_LOCK_EX"));
|
||||
} else if (writer == RW_LOCK_WAIT_EX) {
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_RESERVATION_MODE], "RW_LOCK_WAIT_EX"));
|
||||
}
|
||||
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_HOLDER_THREAD_ID], (longlong)rwlock->thread_id));
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_HOLDER_FILE], innobase_basename(rwlock->file_name)));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_HOLDER_LINE], rwlock->line));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_READERS], rw_lock_get_reader_count(rwlock)));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_WAITERS_FLAG], (longlong)rwlock->waiters));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_LOCK_WORD], (longlong)rwlock->lock_word));
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_LAST_READER_FILE], innobase_basename(rwlock->last_s_file_name)));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_LAST_READER_LINE], rwlock->last_s_line));
|
||||
OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_LAST_WRITER_FILE], innobase_basename(rwlock->last_x_file_name)));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_LAST_WRITER_LINE], rwlock->last_x_line));
|
||||
OK(field_store_ulint(fields[SYS_SEMAPHORE_WAITS_OS_WAIT_COUNT], rwlock->count_os_wait));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OK(schema_table_store_record(thd, tables->table));
|
||||
}
|
||||
}
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
|
|
@ -209,10 +209,10 @@ rw_lock_create_func(
|
|||
# ifdef UNIV_SYNC_DEBUG
|
||||
ulint level, /*!< in: level */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
const char* cfile_name, /*!< in: file name where created */
|
||||
ulint cline, /*!< in: file line where created */
|
||||
#endif /* UNIV_DEBUG */
|
||||
const char* cmutex_name) /*!< in: mutex name */
|
||||
const char* cmutex_name, /*!< in: mutex name */
|
||||
const char* cfile_name, /*!< in: file name where created */
|
||||
ulint cline) /*!< in: file line where created */
|
||||
{
|
||||
/* If this is the very first time a synchronization object is
|
||||
created, then the following call initializes the sync system. */
|
||||
|
@ -221,15 +221,14 @@ rw_lock_create_func(
|
|||
mutex_create(rw_lock_mutex_key, rw_lock_get_mutex(lock),
|
||||
SYNC_NO_ORDER_CHECK);
|
||||
|
||||
ut_d(lock->mutex.cfile_name = cfile_name);
|
||||
ut_d(lock->mutex.cline = cline);
|
||||
|
||||
lock->mutex.cmutex_name = cmutex_name;
|
||||
lock->mutex.cfile_name = cfile_name;
|
||||
lock->mutex.cline = cline;
|
||||
lock->mutex.lock_name = cmutex_name;
|
||||
ut_d(lock->mutex.ib_mutex_type = 1);
|
||||
|
||||
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
|
||||
# ifdef UNIV_DEBUG
|
||||
UT_NOT_USED(cfile_name);
|
||||
UT_NOT_USED(cline);
|
||||
UT_NOT_USED(cmutex_name);
|
||||
# endif
|
||||
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
|
||||
|
||||
|
@ -252,9 +251,12 @@ rw_lock_create_func(
|
|||
|
||||
ut_d(lock->magic_n = RW_LOCK_MAGIC_N);
|
||||
|
||||
lock->cfile_name = cfile_name;
|
||||
lock->cline = (unsigned int) cline;
|
||||
lock->lock_name = cmutex_name;
|
||||
|
||||
lock->count_os_wait = 0;
|
||||
lock->file_name = "not yet reserved";
|
||||
lock->line = 0;
|
||||
lock->last_s_file_name = "not yet reserved";
|
||||
lock->last_x_file_name = "not yet reserved";
|
||||
lock->last_s_line = 0;
|
||||
|
@ -286,20 +288,21 @@ rw_lock_create_func(
|
|||
# ifdef UNIV_SYNC_DEBUG
|
||||
ulint level, /*!< in: level */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
const char* cfile_name, /*!< in: file name where created */
|
||||
ulint cline, /*!< in: file line where created */
|
||||
#endif /* UNIV_DEBUG */
|
||||
const char* cmutex_name) /*!< in: mutex name */
|
||||
const char* cmutex_name, /*!< in: mutex name */
|
||||
const char* cfile_name, /*!< in: file name where created */
|
||||
ulint cline) /*!< in: file line where created */
|
||||
{
|
||||
rw_lock_create_func(&lock->base_lock,
|
||||
#ifdef UNIV_DEBUG
|
||||
# ifdef UNIV_SYNC_DEBUG
|
||||
level,
|
||||
# endif
|
||||
cfile_name,
|
||||
cline,
|
||||
#endif
|
||||
cmutex_name);
|
||||
cmutex_name,
|
||||
cfile_name,
|
||||
cline);
|
||||
|
||||
lock->high_priority_s_waiters = 0;
|
||||
lock->high_priority_s_event = os_event_create();
|
||||
lock->high_priority_x_waiters = 0;
|
||||
|
@ -655,6 +658,12 @@ rw_lock_x_lock_wait(
|
|||
file_name, line);
|
||||
#endif
|
||||
|
||||
if (srv_instrument_semaphores) {
|
||||
lock->thread_id = os_thread_get_curr_id();
|
||||
lock->file_name = file_name;
|
||||
lock->line = line;
|
||||
}
|
||||
|
||||
sync_array_wait_event(sync_arr, index);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
rw_lock_remove_debug_info(
|
||||
|
@ -740,6 +749,12 @@ rw_lock_x_lock_low(
|
|||
lock->last_x_file_name = file_name;
|
||||
lock->last_x_line = (unsigned int) line;
|
||||
|
||||
if (srv_instrument_semaphores) {
|
||||
lock->thread_id = os_thread_get_curr_id();
|
||||
lock->file_name = file_name;
|
||||
lock->line = line;
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
|
|
@ -273,9 +273,9 @@ mutex_create_func(
|
|||
# ifdef UNIV_SYNC_DEBUG
|
||||
ulint level, /*!< in: level */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
#endif /* UNIV_DEBUG */
|
||||
const char* cfile_name, /*!< in: file name where created */
|
||||
ulint cline, /*!< in: file line where created */
|
||||
#endif /* UNIV_DEBUG */
|
||||
const char* cmutex_name) /*!< in: mutex name */
|
||||
{
|
||||
#if defined(HAVE_ATOMIC_BUILTINS)
|
||||
|
@ -288,16 +288,13 @@ mutex_create_func(
|
|||
mutex_set_waiters(mutex, 0);
|
||||
#ifdef UNIV_DEBUG
|
||||
mutex->magic_n = MUTEX_MAGIC_N;
|
||||
mutex->level = level;
|
||||
#endif /* UNIV_DEBUG */
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
|
||||
mutex->line = 0;
|
||||
mutex->file_name = "not yet reserved";
|
||||
mutex->level = level;
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
#ifdef UNIV_DEBUG
|
||||
mutex->cfile_name = cfile_name;
|
||||
mutex->cline = cline;
|
||||
#endif /* UNIV_DEBUG */
|
||||
mutex->count_os_wait = 0;
|
||||
mutex->cmutex_name= cmutex_name;
|
||||
|
||||
|
@ -339,11 +336,11 @@ mutex_create_func(
|
|||
# ifdef UNIV_SYNC_DEBUG
|
||||
ulint level, /*!< in: level */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
#endif /* UNIV_DEBUG */
|
||||
const char* cfile_name, /*!< in: file name where
|
||||
created */
|
||||
ulint cline, /*!< in: file line where
|
||||
created */
|
||||
#endif /* UNIV_DEBUG */
|
||||
const char* cmutex_name) /*!< in: mutex name */
|
||||
{
|
||||
mutex_create_func(&mutex->base_mutex,
|
||||
|
@ -351,9 +348,9 @@ mutex_create_func(
|
|||
# ifdef UNIV_SYNC_DEBUG
|
||||
level,
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
#endif /* UNIV_DEBUG */
|
||||
cfile_name,
|
||||
cline,
|
||||
#endif /* UNIV_DEBUG */
|
||||
cmutex_name);
|
||||
mutex->high_priority_waiters = 0;
|
||||
mutex->high_priority_event = os_event_create();
|
||||
|
@ -463,10 +460,14 @@ mutex_enter_nowait_func(
|
|||
|
||||
if (!ib_mutex_test_and_set(mutex)) {
|
||||
|
||||
ut_d(mutex->thread_id = os_thread_get_curr_id());
|
||||
mutex->thread_id = os_thread_get_curr_id();
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
mutex_set_debug_info(mutex, file_name, line);
|
||||
#endif
|
||||
if (srv_instrument_semaphores) {
|
||||
mutex->file_name = file_name;
|
||||
mutex->line = line;
|
||||
}
|
||||
|
||||
return(0); /* Succeeded! */
|
||||
}
|
||||
|
@ -607,10 +608,15 @@ spin_loop:
|
|||
if (ib_mutex_test_and_set(mutex) == 0) {
|
||||
/* Succeeded! */
|
||||
|
||||
ut_d(mutex->thread_id = os_thread_get_curr_id());
|
||||
mutex->thread_id = os_thread_get_curr_id();
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
mutex_set_debug_info(mutex, file_name, line);
|
||||
#endif
|
||||
if (srv_instrument_semaphores) {
|
||||
mutex->file_name = file_name;
|
||||
mutex->line = line;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -661,10 +667,14 @@ spin_loop:
|
|||
|
||||
sync_array_free_cell(sync_arr, index);
|
||||
|
||||
ut_d(mutex->thread_id = os_thread_get_curr_id());
|
||||
mutex->thread_id = os_thread_get_curr_id();
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
mutex_set_debug_info(mutex, file_name, line);
|
||||
#endif
|
||||
if (srv_instrument_semaphores) {
|
||||
mutex->file_name = file_name;
|
||||
mutex->line = line;
|
||||
}
|
||||
|
||||
if (prio_mutex) {
|
||||
os_atomic_decrement_ulint(
|
||||
|
|
Loading…
Reference in a new issue