Mysql元數據分析


Mysql元數據分析

一、information_schema庫

information_schema庫中的表,保存的是Mysql的元數據。
官網元數據表介紹
InnoDB相關的表介紹
庫中有表:

+---------------------------------------+
| Tables_in_information_schema          |
+---------------------------------------+
| CHARACTER_SETS                        |
| COLLATIONS                            |
| COLLATION_CHARACTER_SET_APPLICABILITY |
| COLUMNS                               |
| COLUMN_PRIVILEGES                     |
| ENGINES                               |
| EVENTS                                |
| FILES                                 |
| GLOBAL_STATUS                         |
| GLOBAL_VARIABLES                      |
| KEY_COLUMN_USAGE                      |
| PARAMETERS                            |
| PARTITIONS                            |
| PLUGINS                               |
| PROCESSLIST                           |
| PROFILING                             |
| REFERENTIAL_CONSTRAINTS               |
| ROUTINES                              |
| SCHEMATA                              |
| SCHEMA_PRIVILEGES                     |
| SESSION_STATUS                        |
| SESSION_VARIABLES                     |
| STATISTICS                            |
| TABLES                                |
| TABLESPACES                           |
| TABLE_CONSTRAINTS                     |
| TABLE_PRIVILEGES                      |
| TRIGGERS                              |
| USER_PRIVILEGES                       |
| VIEWS                                 |
| INNODB_CMP_RESET                      |
| INNODB_TRX                            |
| INNODB_CMPMEM_RESET                   |
| INNODB_LOCK_WAITS                     |
| INNODB_CMPMEM                         |
| INNODB_CMP                            |
| INNODB_LOCKS                          |
+---------------------------------------+

1. CHARACTER_SETS

保存所有Mysql可用的字符集。相當於命令:SHOW CHARACTER SET

2. COLLATIONS

提供了關於各字符集的對照信息

3. COLLATION_CHARACTER_SET_APPLICABILITY

4. COLUMNS

這個表保存的是所有數據庫的列信息

TABLE_CATALOG
TABLE_SCHEMA 庫名
TABLE_NAME 表名
COLUMN_NAME 列名
ORDINAL_POSITION 應該是該列在該表中的順序
COLUMN_DEFAULT 列的默認值
IS_NULLABLE 是否可以為NULL
DATA_TYPE 數據類型
CHARACTER_MAXIMUM_LENGTH 數據的長度
CHARACTER_OCTET_LENGTH 數據的存儲長度
NUMERIC_PRECISION
NUMERIC_SCALE
CHARACTER_SET_NAME 列的字符編碼
COLLATION_NAME
COLUMN_TYPE 列的類型,例如varchar(20)
COLUMN_KEY 如果等於PRI,表示是主鍵
EXTRA 定義列的時候的其他信息,例如自增,主鍵
PRIVILEGES 操作權限有:select,insert,update,references ( 官方說明
COLUMN_COMMENT 列的備注

例子:

***************************[ 1. row ]***************************
TABLE_CATALOG            | def
TABLE_SCHEMA             | test
TABLE_NAME               | sleep_account
COLUMN_NAME              | key
ORDINAL_POSITION         | 1
COLUMN_DEFAULT           | None
IS_NULLABLE              | NO
DATA_TYPE                | int
CHARACTER_MAXIMUM_LENGTH | None
CHARACTER_OCTET_LENGTH   | None
NUMERIC_PRECISION        | 10
NUMERIC_SCALE            | 0
CHARACTER_SET_NAME       | None
COLLATION_NAME           | None
COLUMN_TYPE              | int(11)
COLUMN_KEY               | PRI
EXTRA                    | auto_increment
PRIVILEGES               | select,insert,update,references
COLUMN_COMMENT           | 

5. COLUMN_PRIVILEGES

列的特權信息,應該和COLUMN表的PRIVILEGES的功能差不多的。

6. ENGINES

存儲Mysql支持的數據庫引擎類型,相當於命令SHOW ENGINES
ENGINE 引擎名
SUPPORT 是否支持,Yes,No,Default(默認)
COMMENT 引擎的說明
TRANSACTIONS 是否支持事務
XA
SAVEPOINTS

***************************[ 1. row ]***************************
ENGINE       | InnoDB
SUPPORT      | DEFAULT
COMMENT      | Supports transactions, row-level locking, and foreign keys
TRANSACTIONS | YES
XA           | YES
SAVEPOINTS   | YES

7. EVENTS

保存計划事件(scheduled events)的信息,相當於命令 show events

8. FILES

保存數據庫文件的存儲信息,當使用Mysql集群的時候有用,也就是NDB。

9.GLOBAL_STATUS

保存Mysql 的全局狀態。全局是相對於Session而言的,Session是指單個Mysql連接,全局可以理解為自從Mysql啟動以來,所有的連接,產生的狀態。

10.GLOBAL_VARIABLES

保存Mysql的全局參數。
狀態(status)是隨着Mysql的運行,會變化的,
參數(variable)只有主動修改,才會變化的。
可以使用show status 語法查看

11.KEY_COLUMN_USAGE

保存所有約束(CONSTRAINT)
CONSTRAINT_CATALOG
CONSTRAINT_SCHEMA 約束的數據庫
CONSTRAINT_NAME 約束名
TABLE_CATALOG
TABLE_SCHEMA 約束屬於哪個數據庫
TABLE_NAME 約束屬於哪個數據表
COLUMN_NAME 約束的列名
ORDINAL_POSITION 排序權重
POSITION_IN_UNIQUE_CONSTRAINT
REFERENCED_TABLE_SCHEMA
REFERENCED_TABLE_NAME
REFERENCED_COLUMN_NAME

例如:
test庫的account表中,主鍵是key,就會有下面一行記錄

CONSTRAINT_CATALOG            | def
CONSTRAINT_SCHEMA             | test
CONSTRAINT_NAME               | PRIMARY
TABLE_CATALOG                 | def
TABLE_SCHEMA                  | test
TABLE_NAME                    | account
COLUMN_NAME                   | key
ORDINAL_POSITION              | 1
POSITION_IN_UNIQUE_CONSTRAINT | None
REFERENCED_TABLE_SCHEMA       | None
REFERENCED_TABLE_NAME         | None
REFERENCED_COLUMN_NAME        | None

12.PARAMETERS

保存了所有已定義的PARAMETERS 信息

13.PARTITIONS

保存所有分區表信息

14.PLUGINS

保存所有Mysql已裝載的插件信息

15. PROCESSLIST

保存Mysql的連接信息,一行記錄代表一個數據庫連接,代表一個Mysql服務線程。相當於SHOW PROCESSLIST
查看該表會帶來一定的性能影響,因為需要一個鎖,查看Threads表卻不會。
而且查看Threads表會顯示后台線程,PROCESSLIST缺不會顯示。
這里的線程可以使用KILL語法來殺掉

ID 連接ID,根據這個ID來執行KILL命令
USER 連接的用戶名
HOST 連接的客戶端的IP,格式是IP:PORT。如果想查看一個連接對應的是哪個客戶端進程,就可以這樣:假如HOST='192.168.1.1:23501',去到192.168.1.1這台機,通過命令netstat -apn|grep 23501,看到這樣的結果:

192.168.1.1:23501           192.168.1.10:3306            ESTABLISHED 14599/python2.7

就可以知道這個Mysql的連接的客戶端是14599/python2.7這個進程

DB 連接的數據庫
COMMAND 線程在執行的命令,所有命令。常用的命令有:SLeep(等待客戶端發送SQL),Query(正在執行一個SQL)
TIME 單位是秒,表示這個連接處於現在這個命令多久了
STATE 線程執行的命令的細節描述,常見的描述。一般這個狀態持續的時間是很短的,如果持續了很久,就表明有問題了。常見的描述:Updating(正在更新數據),executing(正在執行),Sending data(發送數據給客戶端)。這里的描述和show profile for query 1;里的執行步驟是對應的
INFO 正在執行的SQL語句,如果沒有執行SQL,為空。

例子:

ID      | 51
USER    | root
HOST    | localhost:59487
DB      | information_schema
COMMAND | Query
TIME    | 0
STATE   | executing
INFO    | select * from PROCESSLIST limit 1

16. PROFILING

保存性能分析的數據,相當於 SHOW PROFILES。只有當session的profiling 參數設置為1,這個表才有數據。

17.REFERENTIAL_CONSTRAINTS

保存外鍵的數據。

18.ROUTINES

保存routines 信息,包括procedures 和 functions,但是不包含用戶定於的functions。

19.SCHEMATA

保存數據庫的信息,一行記錄是一個數據庫(database),類似命令show databases;

20.SCHEMA_PRIVILEGES

保存數據庫的權限信息。
GRANTEE 權限擁有者,格式是'user_name'@'host_name',例如root'@'192.168.137.1
TABLE_CATALOG
TABLE_SCHEMA 權限對應的數據庫
PRIVILEGE_TYPE 權限類型
IS_GRANTABLE 是否可以分配權限給其他擁有者,一般為NO

       GRANTEE: 'root'@'192.168.137.1'
 TABLE_CATALOG: def
  TABLE_SCHEMA: ggy_wrd
PRIVILEGE_TYPE: SELECT
  IS_GRANTABLE: NO

這個表示擁有者'root'@'192.168.137.1'有權限對數據庫ggy_wrd執行SELECT的操作

21.SESSION_STATUS

保存SESSION的狀態,類似於GLOBAL_STATUS

22.SESSION_VARIABLES

保存SESSION的變量,類似於GLOBAL_BARIABLES

23.STATISTICS

保存索引信息。相當於show index from tbl_name

TABLE_CATALOG
TABLE_SCHEMA 數據庫名
TABLE_NAME 表名
NON_UNIQUE 是否唯一
INDEX_SCHEMA
INDEX_NAME
SEQ_IN_INDEX
COLUMN_NAME 列名
COLLATION
CARDINALITY
SUB_PART
PACKED
NULLABLE
INDEX_TYPE 索引類型,一般是BTREE
COMMENT
INDEX_COMMENT

例子:

TABLE_CATALOG: def
 TABLE_SCHEMA: db_kklauncher
   TABLE_NAME: sleep_local_account
   NON_UNIQUE: 0
 INDEX_SCHEMA: db_kklauncher
   INDEX_NAME: PRIMARY
 SEQ_IN_INDEX: 1
  COLUMN_NAME: key
    COLLATION: A
  CARDINALITY: 10673
     SUB_PART: NULL
       PACKED: NULL
     NULLABLE: 
   INDEX_TYPE: BTREE
      COMMENT: 
INDEX_COMMENT: 

24.TABLES

保存數據表信息。類似show tables。
TABLE_CATALOG
TABLE_SCHEMA
TABLE_NAME 表名
TABLE_TYPE 表的類型
ENGINE 表的存儲引擎
VERSION 表的版本
ROW_FORMAT
TABLE_ROWS 表的行數
AVG_ROW_LENGTH 平均一行的長度
DATA_LENGTH 數據長度
MAX_DATA_LENGTH 最大一行的數據長度
INDEX_LENGTH 索引的長度
DATA_FREE
AUTO_INCREMENT 自增到哪個數
CREATE_TIME 創建時間
UPDATE_TIME 最后修改表結構的時間
CHECK_TIME
TABLE_COLLATION 表的編碼
CHECKSUM
CREATE_OPTIONS
TABLE_COMMENT

TABLE_CATALOG   | def
TABLE_SCHEMA    | db_kklauncher
TABLE_NAME      | sleep_local_account
TABLE_TYPE      | BASE TABLE
ENGINE          | InnoDB
VERSION         | 10
ROW_FORMAT      | Compact
TABLE_ROWS      | 10095
AVG_ROW_LENGTH  | 365
DATA_LENGTH     | 3686400
MAX_DATA_LENGTH | 0
INDEX_LENGTH    | 327680
DATA_FREE       | 415236096
AUTO_INCREMENT  | 24342
CREATE_TIME     | 2016-12-27 16:31:56
UPDATE_TIME     | None
CHECK_TIME      | None
TABLE_COLLATION | utf8_general_ci
CHECKSUM        | None
CREATE_OPTIONS  | 
TABLE_COMMENT   |

25.TABLESPACES

保存數據表占用的空間,如果表引擎是InnoDB,需要去查 INNODB_SYS_TABLESPACES 和INNODB_SYS_DATAFILES

26. TABLE_CONSTRAINTS

保存表的約束信息。

27.TABLE_PRIVILEGES

保存表的權限信息。如果賦予擁有者一個表的權限,TABLE_PRIVILEGES表就會有數據。如果是賦予擁有者一個庫的權限,這里就不會有數據,只會在SCHEMA_PRIVILEGES表里面有數據。
這里的數據和SCHEMA_PRIVILEGES的數據意義是一樣的,只不過多了TABLE_SCHEMA這列。

28.TRIGGERS

保存觸發器的信息

29.USER_PRIVILEGES

這里會存儲用戶的權限。

30.VIEWS

保存視圖信息

31.INNODB_CMP_RESET和INNODB_CMP

保存被壓縮的InnoDB表的信息

32.INNODB_TRX

保存InnoDB的事務信息(不會包含只讀的事務)。
官方介紹

trx_id 事務ID,唯一的,只讀事務沒有生成ID
trx_state 當前的狀態,取值:RUNNING(正在執行), LOCK WAIT(等待鎖), ROLLING BACK(回滾), and COMMITTING(提交中)
trx_started 事務啟動的時間
trx_requested_lock_id 如果狀態是LOCK WAIT,這里顯示的是正在等待的鎖的ID,對應INNODB_LOCKS表的LOCK_ID列
trx_wait_started 如果狀態是LOCK WAIT,這里顯示的是該事務等待鎖等待了多久
trx_weight 事務的權重,權重越低,Mysql越先執行一個事務,這個主要用於解決死鎖
trx_mysql_thread_id 事務對應的線程ID,和PROCESSLIST表的ID列對應
trx_query 事務正在執行的SQL
trx_operation_state 事務當前的操作狀態,如果沒有,顯示NULL
trx_tables_in_use 事務處理當前的SQL,也就是trx_query里的SQL,需要打開多少個表
trx_tables_locked 事務處理當前的SQL需要上鎖多少個表的行鎖
trx_lock_structs 有多少個鎖會被該事務保留,也就是執行該事務需要鎖住多少條行記錄
trx_lock_memory_bytes 鎖需要耗用的內存
trx_rows_locked 事務處理當前的SQL需要上鎖多少個行鎖,這只是個近似值
trx_rows_modified 事務需要修改或新增多少行內容
trx_concurrency_tickets 該線程被調度前,需要執行多少工作
trx_isolation_level 事務的隔離級別
trx_unique_checks 是否打開唯一檢查(unique_checks)
trx_foreign_key_checks 是否打開外鍵唯一檢查( foreign key checks)
trx_last_foreign_key_error 上一次外鍵錯誤信息
trx_adaptive_hash_latched
trx_adaptive_hash_timeout

例子:

trx_id                     | 7B441
trx_state                  | LOCK WAIT
trx_started                | 2017-02-06 18:16:26
trx_requested_lock_id      | 7B441:0:5172:49
trx_wait_started           | 2017-02-06 18:16:26
trx_weight                 | 2
trx_mysql_thread_id        | 60
trx_query                  | update account set nickname='aaabbb4' where `key`=11165
trx_operation_state        | starting index read
trx_tables_in_use          | 1
trx_tables_locked          | 1
trx_lock_structs           | 2
trx_lock_memory_bytes      | 376
trx_rows_locked            | 1
trx_rows_modified          | 0
trx_concurrency_tickets    | 0
trx_isolation_level        | REPEATABLE READ
trx_unique_checks          | 1
trx_foreign_key_checks     | 1
trx_last_foreign_key_error | None
trx_adaptive_hash_latched  | 0
trx_adaptive_hash_timeout  | 10000

33.NODB_LOCK_WAITS

保存等待鎖的連接的信息
requesting_trx_id 正在請求的事務ID,也就是等待鎖的事務ID
requested_lock_id 請求事務的ID獲得鎖成功后,會創建的鎖ID
blocking_trx_id 已經獲取鎖的事務ID
blocking_lock_id 已經獲取的鎖ID

requesting_trx_id | 7B444
requested_lock_id | 7B444:0:5172:49
blocking_trx_id   | 7B43F
blocking_lock_id  | 7B43F:0:5172:49

表示事務7B43F獲得了鎖7B43F:0:5172:49,事務7B444在等待鎖,獲取鎖后,會創建鎖7B444:0:5172:49

34.INNODB_LOCKS

保存InnoDB的鎖信息。只有當存在等待鎖的時候,這個表才會有數據。例如一個線程獲得了鎖,但是沒有commit,這個表是沒有數據的,當另一個線程等待鎖,這個表會有兩條數據,一個是已獲得的鎖,一個是等待的鎖。
lock_id 鎖的ID,不要嘗試解析ID的意義
lock_trx_id 已經獲取該鎖的事務ID,和INNODB_TRX 表的trx_id對應
lock_mode 鎖的模式,官方介紹
lock_type 鎖的類型,RECORD (行鎖),TABLE(表鎖)
lock_table 被鎖的表名
lock_index 如果是行鎖,顯示索引名
lock_space 如果是行鎖,顯示表空間(Tablespace )的ID
lock_page 如果是行鎖,顯示被鎖的行的頁碼
lock_rec 如果是行鎖,顯示被鎖的行的頁碼里面的堆棧號
lock_data 被鎖的行的主鍵的值,如果沒有主鍵,顯示InnoDB內部的行ID

例子:

lock_id     | 7B449:0:5172:49
lock_trx_id | 7B449
lock_mode   | X
lock_type   | RECORD
lock_table  | `test`.`account`
lock_index  | `PRIMARY`
lock_space  | 0
lock_page   | 5172
lock_rec    | 49
lock_data   | 10001

二、常用的語法

所有SHOW語法

1.SHOW STATUS 語法

SHOW [GLOBAL | SESSION] STATUS    [LIKE 'pattern' | WHERE expr]

表中有Variable_name 和Value兩個列。不區分大小寫
LIKE是WHERE的快捷方式
例如這兩個是等價的

show global status like '%thread%' 
show global status where Variable_name like '%thread%' 

WHERE的功能更強大,例如:

show global status where Value  =0 

2.status說明

所有狀態的說明

常用的:

  • Queries 執行的查詢總數
  • Threads_connected 服務器連接數,如果使用線程池,這個指標變化不大
  • Threads_running 執行查詢的線程數

行鎖相關:

  • Innodb_row_lock_current_waits 當前正在等待行鎖的連接數
  • Innodb_row_lock_time 等待行鎖耗費的時間,單位MS
  • Innodb_row_lock_time_avg 等待行鎖耗費的平均時間
  • Innodb_row_lock_time_max 等待行鎖耗費的最大時間
  • Innodb_row_lock_waits 一直以來等待行鎖的連接數

Com開頭的:
表示每個操作執行的次數,例如Com_select表示執行select操作的次數。

3. SHOW VARIABLES 語法

SHOW [GLOBAL | SESSION] VARIABLES  [LIKE 'pattern' | WHERE expr]

跟show status類似

4. variables說明

所有變量的說明

  • innodb_lock_wait_timeout 等待行鎖的超時時間

5. SHOW PROCESSLIST語法

SHOW [FULL] PROCESSLIST

如果沒有FULL,只會顯示SQL語句的前100個字符
SHOW PROCESSLIST 教程
內容同PROCESSLIST表是一樣的

6. KILL語法

官方說明

7.SHOW PROFILE語法

官方說明

8. SHOW OPEN TABLES語法

官方說明
這個語法顯示正在緩存中被打開的表。
例子:

Database    | db_kklauncher
Table       | sleep_local_account
In_use      | 1
Name_locked | 0

Database 數據庫名
Table 數據表名
In_use 使用該表的客戶端數量。一般是表示有多少個客戶端在等待這個表的鎖。
Name_locked 表名是否被鎖,一般只有刪除表或還原表的時候,這個會等於1

三、常用命令

  1. 查看哪個事務獲得了鎖(只顯示有連接在等待的鎖)

     select * from INNODB_LOCKS,`INNODB_TRX` where INNODB_TRX.trx_id=INNODB_LOCKS.lock_trx_id and INNODB_TRX.trx_state ='RUNNING'\G;
    
  2. 查看獲得鎖的連接情況

     select l.lock_id ,l.lock_index,l.lock_data,p.id,p.command,p.time,p.host from information_schema.innodb_trx as t,information_schema.innodb_locks as l ,information_schema.processlist as p where t.trx_id=l.lock_trx_id and p.id=t.trx_mysql_thread_id and l.lock_id in (select distinct blocking_lock_id from information_schema.INNODB_LOCK_WAITS)
    

四、Innodb的鎖

鎖相關說明
假如有student表:

+----+------+------+-------+
| id | name | age  | class |
+----+------+------+-------+
|  1 | 2    |   20 | A     |
|  2 | 1    |   22 | A     |
|  3 | 1    |   23 | A     |
|  4 | NULL |   24 | B     |
|  5 | NULL |   24 | B     |
+----+------+------+-------+
  1. 連接A執行SQLupdate student set name='1' where class='A' ;,但是沒有commit
    這時如果連接B執行SQLupdate student set name='2' where id=1;,然后執行查看鎖命令,結果是:

                       lock_id: 7B600:0:40373:7
                   lock_trx_id: 7B600
                     lock_type: RECORD
                    lock_table: `test`.`student`
                    lock_index: `PRIMARY`
                     lock_data: 0
                   trx_started: 2017-02-07 17:19:33
           trx_mysql_thread_id: 2
              trx_lock_structs: 2
               trx_rows_locked: 3
             trx_rows_modified: 4
    
  • 因為連接B等待id=0的行鎖,所以這里只會顯示lock_data=1,但是實際連接A是鎖住了3條記錄的(id 1-3),
  • 事務ID7B600是連接A的事務ID
  • lock_index和lock_data是關聯的,如果lock_index是PRIMARY,lock_data就是行記錄的主鍵。如果lock_index是其他索引例如是索引my_index,而my_index索引的列是class,lock_data就會是A,3,也就是前面是索引列的值,后面是主鍵。
  • 現在還不知道lock_index的索引是連接A還是連接B定位數據時使用的索引
  1. 連接A執行SQLupdate student set name='1' where class='B' ;,也就是更新id=4,5兩條記錄,但是沒有commit
    這時如果連接B執行SQLupdate student set name='2' where age<24;,也就是更新全部記錄,接着連接C執行SQLupdate student set name='1' where id=1;,更新id=1這條記錄。這樣的結果是:連接A獲取了id=4,5的鎖,連接B獲取了id=1,2,3的鎖,正在等待id=4的鎖,事務狀態是LOCK_WAIT,連接C等待id=1的鎖,事務狀態也是LOCK_WAIT。

未經許可,請不要轉載。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM