├── mysql_innodb_status.py ├── readme.md └── show-innodb-status-v2.py /mysql_innodb_status.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import re, hashlib, time, datetime 3 | import MySQLdb 4 | import sys 5 | import getopt 6 | 7 | NUM_REG='\s*\d+.?\d*\s*' 8 | """ 9 | INNODB_STATUS_DICT = { 10 | 'section':{ 11 | 'key':['prefix','suffix','unit'], 12 | 'key':['prefix','suffix','unit'] 13 | } 14 | PREFIX: 15 | ^ BEGIN 16 | SUFFIX: 17 | $ END 18 | UNIT: BYTE,NUM,PER_SECOND... 19 | OPER ... CONTROL MARK 20 | """ 21 | INNODB_STATUS_DICT = { 22 | 'bufferpool_memory':{ 23 | #Total large memory allocated 549715968 24 | #Dictionary memory allocated 470460 25 | #Buffer pool size 32768 26 | #Free buffers 23188 27 | #Database pages 9484 28 | #Old database pages 3480 29 | #Modified db pages 0 30 | #Pending reads 0 31 | #Pending writes: LRU 0, flush list 0, single page 0 32 | #Pages made young 3067, not young 48190 33 | #0.00 youngs/s, 0.00 non-youngs/s 34 | #Pages read 7721, created 1771, written 18370 35 | #Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s 36 | #LRU len: 9484, unzip_LRU len: 0 37 | 'total_large_memory_allocated':['^Total large memory allocated ','$','BYTE'], 38 | 'dictionary_memory_allocated':['^Dictionary memory allocated ','$','BYTE'], 39 | 'buffer_pool_size':['^Buffer pool size ','$','NUM'], 40 | 'free_buffers':['^Free buffers ','$','NUM'], 41 | 'database_pages':['^Database pages ','$','PAGE'], 42 | 'old_database_pages':['^Old database pages ','$','PAGE'], 43 | 'modified_db_pages':['^Modified db pages ','$','PAGE'], 44 | 'pending_writes_lru':['^Pending writes: LRU ',',','NUM'], 45 | 'pending_writes_flush_list':['^Pending writes: LRU'+NUM_REG+', flush list ',',','NUM'], 46 | 'pending_writes_single_page':['^Pending writes: LRU'+NUM_REG+', flush list'+NUM_REG+', single page ','$','NUM'], 47 | 'pages_made_young':['^Pages made young ',',','NUM'], 48 | 'pages_made_not_young':['^Pages made young'+NUM_REG+', not young','$','NUM'], 49 | 'pages_made_young_per_sec':['^','youngs/s,','PER_SECOND'], 50 | 'pages_made_non_young_per_sec':['^'+NUM_REG+'youngs/s,','non-youngs/s','PER_SECOND'], 51 | 'pages_read':['^Pages read ',',','NUM'], 52 | 'pages_created':['^Pages read'+NUM_REG+', created ',',','NUM'], 53 | 'pages_written':['^Pages read'+NUM_REG+', created'+NUM_REG+', written ','$','NUM'], 54 | 'pages_read_ahead':['^Pages read ahead ','/s,','PER_SECOND'], 55 | 'evicted_without_access':['^Pages read ahead'+NUM_REG+'/s, evicted without access ','/s','PER_SECOND'], 56 | 'random_read_ahead':['^Pages read ahead'+NUM_REG+'/s, evicted without access'+NUM_REG+'/s, Random read ahead ','/s','PER_SECOND'], 57 | 'lrn_len':['^LRU len: ',',','NUM'], 58 | 'unzip_lru_len':['^LRU len:'+NUM_REG+', unzip_LRU len: ','$','NUM'] 59 | }, 60 | 'log':{ 61 | #Log sequence number 1283658707 62 | #Log flushed up to 1283658707 63 | #Pages flushed up to 1283658707 64 | #Last checkpoint at 1283658698 65 | #0 pending log flushes, 0 pending chkp writes 66 | #14438 log i/o's done, 0.00 log i/o's/second 67 | 'log_sequence_number':['^Log sequence number ','$','NUM'], 68 | 'log_flushed_up_to':['^Log flushed up to ','$','NUM'], 69 | 'pages_flushed_up_to':['^Pages flushed up to ','$','NUM'], 70 | 'last_checkpoint_at':['^Last checkpoint at ','$','NUM'], 71 | 'pending_log_flushes':['^','pending log flushes,','NUM'], 72 | 'pending_chkp_writes':['^'+NUM_REG+'pending log flushes,','pending chkp writes$','NUM'], 73 | 'log_ios_done':['^',"log i/o's done,",'NUM'], 74 | 'log_ios_per_second':["^'+NUM_REG+' log i/o's done,","log i/o's/second$",'NUM'] 75 | }, 76 | 'row_operations':{ 77 | #0 queries inside InnoDB, 0 queries in queue 78 | #0 read views open inside InnoDB 79 | #Process ID=12436, Main thread ID=140668680787712, state: sleeping 80 | #Number of rows inserted 16618, updated 50031, deleted 16618, read 7034937 81 | #0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.00 reads/s 82 | 'queries_inside_innodb':['^','queries inside InnoDB,','NUM'], 83 | 'queries_in_queue':["^'+NUM_REG+'queries inside InnoDB,",'queries in queue$','NUM'], 84 | 'read_views_open_inside_innodb':['^','read views open inside InnoDB$','NUM'], 85 | 'number_of_rows_inserted':['^Number of rows inserted ',',','NUM'], 86 | 'number_of_rows_updated':['^Number of rows inserted'+NUM_REG+', updated ',',','NUM'], 87 | 'number_of_rows_deleted':['^Number of rows inserted'+NUM_REG+', updated'+NUM_REG+', deleted ',',','NUM'], 88 | 'number_of_rows_read':['^Number of rows inserted'+NUM_REG+', updated'+NUM_REG+', deleted'+NUM_REG+', read ','$','NUM'], 89 | 'inserts_per_second':['^','inserts/s,','NUM'], 90 | 'updates_per_second':['^'+NUM_REG+' inserts/s, ','updates/s,','NUM'], 91 | 'deletes_per_second':['^'+NUM_REG+' inserts/s, '+NUM_REG+' updates/s,','deletes/s,','NUM'], 92 | 'reads_per_second':['^'+NUM_REG+' inserts/s, '+NUM_REG+' updates/s, '+NUM_REG+' deletes/s,','reads/s$','NUM'] 93 | }, 94 | 'insert_buffer_adaptive_hash_index':{ 95 | #Ibuf: size 1, free list len 0, seg size 2, 0 merges 96 | #merged operations: 97 | # insert 0, delete mark 0, delete 0 98 | #discarded operations: 99 | # insert 0, delete mark 0, delete 0 100 | #Hash table size 138389, node heap has 0 buffer(s) 101 | #... 102 | #Hash table size 138389, node heap has 10 buffer(s) 103 | #2535.04 hash searches/s, 2076.08 non-hash searches/s 104 | 'ibuf_size':['^Ibuf: size',',','NUM'], 105 | 'ibuf_free_list_len':['^Ibuf: size '+NUM_REG+', free list len ',',','NUM'], 106 | 'ibuf_seg_size':['^Ibuf: size '+NUM_REG+', free list len '+NUM_REG+', seg size ',',','NUM'], 107 | 'ibuf_merges':['^Ibuf: size '+NUM_REG+', free list len '+NUM_REG+', seg size '+NUM_REG+', ','merges$','NUM'], 108 | 'merged_operations':['^merged operations:','$','OPER'], 109 | '_insert':['^ insert ',',','NUM'], 110 | '_delete_mark':['^ insert '+NUM_REG+', delete mark ',',','NUM'], 111 | '_delete':['^ insert '+NUM_REG+', delete mark '+NUM_REG+', delete ','$','NUM'], 112 | 'discarded_operations':['^discarded operations:','$','OPER'], 113 | '_insert':['^ insert ',',','NUM'], 114 | '_delete_mark':['^ insert '+NUM_REG+', delete mark ',',','NUM'], 115 | '_delete':['^ insert '+NUM_REG+', delete mark '+NUM_REG+', delete ','$','NUM'], 116 | 'hash_searches_per_second':['^','hash searches/s,','PER_SECOND'], 117 | 'non_hash_searches_per_second':['^'+NUM_REG+' hash searches/s, ','non-hash searches/s$','PER_SECOND'] 118 | }, 119 | 'file_io':{ 120 | #I/O thread 0 state: waiting for completed aio requests (insert buffer thread) 121 | #... 122 | #I/O thread 17 state: waiting for completed aio requests (write thread) 123 | #Pending normal aio reads: [0, 0, 0, 0, 0, 0, 0, 0] , aio writes: [0, 0, 0, 0, 0, 0, 0, 0] , 124 | #ibuf aio reads:, log i/o's:, sync i/o's: 125 | #Pending flushes (fsync) log: 0; buffer pool: 0 126 | #2593 OS file reads, 28093 OS file writes, 530 OS fsyncs 127 | #0.00 reads/s, 0 avg bytes/read, 0.00 writes/s, 0.00 fsyncs/s 128 | 'os_file_reads':['^','OS file reads,','NUM'], 129 | 'os_file_writes':['^'+NUM_REG+' OS file reads, ','OS file writes,','NUM'], 130 | 'os_fsyncs':['^'+NUM_REG+' OS file reads, '+NUM_REG+' OS file writes, ','OS fsyncs$','NUM'], 131 | 'reads_per_second':['^','reads/s,','NUM'], 132 | 'avg_bytes_per_read':['^'+NUM_REG+' reads/s, ','avg bytes/read,','BYTE'], 133 | 'writes_per_second':['^'+NUM_REG+' reads/s, '+NUM_REG+' avg bytes/read,','writes/s,','NUM'], 134 | 'fsyncs_per_second':['^'+NUM_REG+' reads/s, '+NUM_REG+' avg bytes/read,'+NUM_REG+'writes/s,','fsyncs/s$','NUM'] 135 | }, 136 | 'transactions':{ 137 | #Trx id counter 924584 138 | #Purge done for trx's n:o < 924584 undo n:o < 0 state: running but idle 139 | #History list length 610 140 | 'trx_counter':['^Trx id counter','$','NUM'], 141 | 'purge_done_for_trx':["^Purge done for trx's n:o <",'undo n:o','NUM'], 142 | 'purge_done_for_undo':["^Purge done for trx's n:o <"+NUM_REG+' undo n:o <','state:','NUM'], 143 | 'history_list_length':['^History list length','$','NUM'] 144 | }, 145 | 'semaphores':{ 146 | #OS WAIT ARRAY INFO: reservation count 26272 147 | #OS WAIT ARRAY INFO: signal count 26035 148 | #RW-shared spins 0, rounds 12106, OS waits 2966 149 | #RW-excl spins 0, rounds 35158, OS waits 2424 150 | #RW-sx spins 7, rounds 210, OS waits 7 151 | #Spin rounds per wait: 12106.00 RW-shared, 35158.00 RW-excl, 30.00 RW-sx 152 | 'reservation_count':['^OS WAIT ARRAY INFO: reservation count','$','NUM'], 153 | 'signal_count':['^OS WAIT ARRAY INFO: signal count','$','NUM'], 154 | 'rw_shared_spins':['^RW-shared spins',',','NUM'], 155 | 'rw_shared_rounds':['^RW-shared spins '+NUM_REG+', rounds',',','NUM'], 156 | 'rw_shared_os_waits':['^RW-shared spins '+NUM_REG+', rounds '+NUM_REG+' OS waits','$','NUM'], 157 | 'rw_excl_spins':['^RW-excl spins',',','NUM'], 158 | 'rw_excl_rounds':['^RW-excl spins '+NUM_REG+', rounds',',','NUM'], 159 | 'rw_excl_os_waits':['^RW-excl spins '+NUM_REG+', rounds '+NUM_REG+' OS waits','$','NUM'], 160 | 'rw_sx_spins':['^RW-sx spins',',','NUM'], 161 | 'rw_sx_rounds':['^RW-sx spins '+NUM_REG+', rounds',',','NUM'], 162 | 'rw_sx_os_waits':['^RW-sx spins '+NUM_REG+', rounds '+NUM_REG+' OS waits','$','NUM'], 163 | 'spin_rounds_per_wait_rw_shared':['^Spin rounds per wait:','RW-shared,','NUM'], 164 | 'spin_rounds_per_wait_rw_excl':['^Spin rounds per wait:'+NUM_REG+' RW-shared, ','RW-excl,','NUM'], 165 | 'spin_rounds_per_wait_rw_sx':['^Spin rounds per wait:'+NUM_REG+' RW-shared, '+NUM_REG+' RW-excl, ','RW-sx$','NUM'] 166 | }, 167 | 'background_thread':{ 168 | #srv_master_thread loops: 147 srv_active, 0 srv_shutdown, 19300 srv_idle 169 | #srv_master_thread log flush and writes: 19447 170 | 'master_thread_loops_active':['^srv_master_thread loops:','srv_active,','NUM'], 171 | 'master_thread_loops_shutdown':['^srv_master_thread loops: '+NUM_REG+' srv_active,','srv_shutdown,','NUM'], 172 | 'master_thread_loops_idle':['^srv_master_thread loops: '+NUM_REG+' srv_active, '+NUM_REG+'srv_shutdown,','srv_idle$','NUM'], 173 | 'master_thread_log_flush_and_writes':['^srv_master_thread log flush and writes:','$','NUM'] 174 | } 175 | } 176 | def query_innodb_status(p_host,p_user,p_pwd): 177 | conn = MySQLdb.connect(p_host, p_user, p_pwd, 'information_schema', charset="utf8"); 178 | query = "SHOW ENGINE INNODB STATUS;" 179 | cursor = conn.cursor() 180 | cursor.execute(query) 181 | result_list = [] 182 | temp_list = cursor.fetchall() 183 | for o in temp_list: 184 | result_list = result_list + str(o).split("\\n") 185 | conn.close() 186 | return result_list 187 | 188 | def deal_log(v_data): 189 | """ 190 | RETURN STRUCTURE 191 | { 192 | 'section': 193 | { 194 | 'key':{'val':'xxx','unit':'xxx'} 195 | } 196 | } 197 | example: 198 | { 199 | 'bufferpool_memory': 200 | { 201 | 'buffer_pool_size': {'unit': 'BYTE', 'val': '32768'}, 202 | 'database_pages': {'unit': 'PAGE', 'val': '9484'}, 203 | 'dictionary_memory_allocated': {'unit': 'BYTE'} 204 | } 205 | } 206 | """ 207 | result_dict = {} 208 | regex_background_thread = re.compile("^BACKGROUND THREAD") 209 | regex_transactions = re.compile("^TRANSACTIONS") 210 | regex_semaphores = re.compile("^SEMAPHORES") 211 | regex_file_io = re.compile("^FILE I/O") 212 | regex_ins_buf_ahi = re.compile("^INSERT BUFFER AND ADAPTIVE HASH INDEX") 213 | regex_log = re.compile("^LOG") 214 | regex_bufferpool_memory = re.compile("^BUFFER POOL AND MEMORY") 215 | regex_row_operations = re.compile("^ROW OPERATIONS") 216 | regex_end = re.compile("^END OF INNODB MONITOR OUTPUT") 217 | 218 | cur_section = 'other' 219 | key_prefix = '' 220 | for line in v_data: 221 | if regex_background_thread.match(line): 222 | cur_section='background_thread' 223 | elif regex_transactions.match(line): 224 | cur_section='transactions' 225 | elif regex_semaphores.match(line): 226 | cur_section='semaphores' 227 | elif regex_file_io.match(line): 228 | cur_section='file_io' 229 | elif regex_ins_buf_ahi.match(line): 230 | cur_section='insert_buffer_adaptive_hash_index' 231 | elif regex_log.match(line): 232 | cur_section='log' 233 | elif regex_bufferpool_memory.match(line): 234 | cur_section='bufferpool_memory' 235 | elif regex_row_operations.match(line): 236 | cur_section='row_operations' 237 | elif regex_end.match(line): 238 | cur_section='other' 239 | else: 240 | if INNODB_STATUS_DICT.has_key(cur_section): 241 | for item in INNODB_STATUS_DICT[cur_section].keys(): 242 | re_str = INNODB_STATUS_DICT[cur_section][item][0]+''+NUM_REG+''+INNODB_STATUS_DICT[cur_section][item][1] 243 | if cur_section=='insert_buffer_adaptive_hash_index' and re.findall("merged operations",line): 244 | key_prefix = 'merged_operations' 245 | break 246 | if cur_section=='insert_buffer_adaptive_hash_index' and re.findall("discarded operations",line): 247 | key_prefix = 'discarded_operations' 248 | break 249 | if cur_section=='insert_buffer_adaptive_hash_index' and re.findall("Hash table size",line): 250 | key_prefix = '' 251 | if re.findall(re_str,line): 252 | if INNODB_STATUS_DICT[cur_section][item][1]=="$": 253 | val = re.split(INNODB_STATUS_DICT[cur_section][item][0],line)[-1] 254 | else: 255 | val = re.split(INNODB_STATUS_DICT[cur_section][item][1],re.split(INNODB_STATUS_DICT[cur_section][item][0],line)[-1])[0] 256 | if result_dict.has_key(cur_section) == 0: 257 | result_dict[cur_section]={} 258 | if key_prefix == '': 259 | result_dict[cur_section][item]={'val':val.strip(),'unit':INNODB_STATUS_DICT[cur_section][item][2]} 260 | else: 261 | result_dict[cur_section][key_prefix+item]={'val':val.strip(),'unit':INNODB_STATUS_DICT[cur_section][item][2]} 262 | return result_dict 263 | 264 | def print_help(): 265 | print "Usage:" 266 | print "./mysql_innodb_status.py -h -u -p " 267 | print " -h : database ip address/domain name" 268 | print " -u : username" 269 | print " -p : password" 270 | 271 | if __name__ == "__main__": 272 | try: 273 | opts,args = getopt.getopt(sys.argv[1:],"h:u:p:") 274 | for o,v in opts: 275 | if o=="-h": 276 | db=v 277 | elif o=="-u": 278 | username=v 279 | elif o=="-p": 280 | pwd=v 281 | except getopt.GetoptError,msg: 282 | print_help() 283 | exit() 284 | 285 | v_innodb_status = [] 286 | v_innodb_status = query_innodb_status(db,username,pwd) 287 | v_dict = deal_log(v_innodb_status) 288 | for section in sorted(v_dict.keys()): 289 | print 290 | print '[',section,']' 291 | print '-'*80 292 | for key in sorted(v_dict[section]): 293 | #print key,v_dict[section][key]['val'],v_dict[section][key]['unit'] 294 | print key.ljust(40),v_dict[section][key]['val'].rjust(20),v_dict[section][key]['unit'].rjust(15) -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ## 作者 2 | hanfeng 3 | 4 | ## 使用方法 5 | ### (1).准备条件 6 | 模块 - MySQLDB 7 | Python版本 >= 2.6.x (3.x版本没测试) 8 | ### (2).调用方法 9 | Usage: 10 | ./mysql_innodb_status.py -h -u -p 11 | -h : database ip address/domain name 12 | -u : username 13 | -p : password 14 | ### (3).输出结构 15 | 程序返回为如下结构体,可在自己代码中直接调用即可。 16 | 17 | RETURN STRUCTURE 18 | { 19 | 'section': 20 | { 21 | 'key':{'val':'xxx','unit':'xxx'} 22 | } 23 | } 24 | example: 25 | { 26 | 'bufferpool_memory': 27 | { 28 | 'buffer_pool_size': {'unit': 'BYTE', 'val': '32768'}, 29 | 'database_pages': {'unit': 'PAGE', 'val': '9484'}, 30 | 'dictionary_memory_allocated': {'unit': 'BYTE'} 31 | } 32 | } 33 | ## 输出示例 34 | [ background_thread ] 35 | -------------------------------------------------------------------------------- 36 | master_thread_log_flush_and_writes 26579 NUM 37 | master_thread_loops_active 445 NUM 38 | master_thread_loops_idle 26134 NUM 39 | master_thread_loops_shutdown 0 NUM 40 | 41 | [ bufferpool_memory ] 42 | -------------------------------------------------------------------------------- 43 | buffer_pool_size 32764 NUM 44 | database_pages 2635 PAGE 45 | dictionary_memory_allocated 365465 BYTE 46 | evicted_without_access 0.00 PER_SECOND 47 | free_buffers 30117 NUM 48 | lrn_len 2635 NUM 49 | modified_db_pages 0 PAGE 50 | old_database_pages 957 PAGE 51 | pages_created 73 NUM 52 | pages_made_non_young_per_sec 0.00 PER_SECOND 53 | pages_made_not_young 0 NUM 54 | pages_made_young 21 NUM 55 | pages_made_young_per_sec 0.00 PER_SECOND 56 | pages_read 2562 NUM 57 | pages_read_ahead 0.00 PER_SECOND 58 | pages_written 5148 NUM 59 | pending_writes_flush_list 0 NUM 60 | pending_writes_lru 0 NUM 61 | pending_writes_single_page 0 NUM 62 | random_read_ahead 0.00 PER_SECOND 63 | total_large_memory_allocated 549715968 BYTE 64 | unzip_lru_len 0 NUM 65 | 66 | [ file_io ] 67 | -------------------------------------------------------------------------------- 68 | avg_bytes_per_read 0 BYTE 69 | fsyncs_per_second 0.00 NUM 70 | os_file_reads 2593 NUM 71 | os_file_writes 118211 NUM 72 | os_fsyncs 1973 NUM 73 | reads_per_second 0.00 NUM 74 | writes_per_second 0.00 NUM 75 | 76 | [ insert_buffer_adaptive_hash_index ] 77 | -------------------------------------------------------------------------------- 78 | discarded_operations_delete 0 NUM 79 | discarded_operations_delete_mark 0 NUM 80 | discarded_operations_insert 0 NUM 81 | hash_searches_per_second 0.00 PER_SECOND 82 | ibuf_free_list_len 0 NUM 83 | ibuf_merges 0 NUM 84 | ibuf_seg_size 2 NUM 85 | ibuf_size 1 NUM 86 | merged_operations_delete 0 NUM 87 | merged_operations_delete_mark 0 NUM 88 | merged_operations_insert 0 NUM 89 | non_hash_searches_per_second 0.00 PER_SECOND 90 | 91 | [ log ] 92 | -------------------------------------------------------------------------------- 93 | last_checkpoint_at 1444180670 NUM 94 | log_flushed_up_to 1444180679 NUM 95 | log_ios_done 112643 NUM 96 | log_sequence_number 1444180679 NUM 97 | pages_flushed_up_to 1444180679 NUM 98 | pending_chkp_writes 0 NUM 99 | pending_log_flushes 0 NUM 100 | 101 | [ row_operations ] 102 | -------------------------------------------------------------------------------- 103 | deletes_per_second 0.00 NUM 104 | inserts_per_second 0.00 NUM 105 | number_of_rows_deleted 129117 NUM 106 | number_of_rows_inserted 129117 NUM 107 | number_of_rows_read 54637053 NUM 108 | number_of_rows_updated 388671 NUM 109 | queries_inside_innodb 0 NUM 110 | read_views_open_inside_innodb 0 NUM 111 | reads_per_second 0.00 NUM 112 | updates_per_second 0.00 NUM 113 | 114 | [ semaphores ] 115 | -------------------------------------------------------------------------------- 116 | reservation_count 116821 NUM 117 | rw_excl_os_waits 10287 NUM 118 | rw_excl_rounds 139507 NUM 119 | rw_excl_spins 0 NUM 120 | rw_shared_os_waits 13124 NUM 121 | rw_shared_rounds 53483 NUM 122 | rw_shared_spins 0 NUM 123 | rw_sx_os_waits 25 NUM 124 | rw_sx_rounds 750 NUM 125 | rw_sx_spins 25 NUM 126 | signal_count 116126 NUM 127 | spin_rounds_per_wait_rw_excl 139507.00 NUM 128 | spin_rounds_per_wait_rw_shared 53483.00 NUM 129 | spin_rounds_per_wait_rw_sx 30.00 NUM 130 | 131 | [ transactions ] 132 | -------------------------------------------------------------------------------- 133 | history_list_length 633 NUM 134 | purge_done_for_trx 1126318 NUM 135 | purge_done_for_undo 0 NUM 136 | trx_counter 1126318 NUM 137 | -------------------------------------------------------------------------------- /show-innodb-status-v2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import re, hashlib, time, datetime 3 | import MySQLdb 4 | import sys 5 | import getopt 6 | import time 7 | import pprint 8 | 9 | NUM_REG='\s*\d+.?\d*\s*' 10 | """ 11 | INNODB_STATUS_DICT = { 12 | 'section':{ 13 | 'key':['prefix','suffix','unit'], 14 | 'key':['prefix','suffix','unit'] 15 | } 16 | PREFIX: 17 | ^ BEGIN 18 | SUFFIX: 19 | $ END 20 | UNIT: BYTE,NUM,PER_SECOND... 21 | OPER ... CONTROL MARK 22 | """ 23 | 24 | INNODB_STATUS_DICT = { 25 | 'bufferpool_memory':{ 26 | #Total large memory allocated 549715968 27 | #Dictionary memory allocated 470460 28 | #Buffer pool size 32768 29 | #Free buffers 23188 30 | #Database pages 9484 31 | #Old database pages 3480 32 | #Modified db pages 0 33 | #Pending reads 0 34 | #Pending writes: LRU 0, flush list 0, single page 0 35 | #Pages made young 3067, not young 48190 36 | #0.00 youngs/s, 0.00 non-youngs/s 37 | #Pages read 7721, created 1771, written 18370 38 | #Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s 39 | #LRU len: 9484, unzip_LRU len: 0 40 | 'total_large_memory_allocated':['^Total large memory allocated ','$','BYTE'], 41 | 'dictionary_memory_allocated':['^Dictionary memory allocated ','$','BYTE'], 42 | 'buffer_pool_size':['^Buffer pool size ','$','NUM'], 43 | 'free_buffers':['^Free buffers ','$','NUM'], 44 | 'database_pages':['^Database pages ','$','PAGE'], 45 | 'old_database_pages':['^Old database pages ','$','PAGE'], 46 | 'modified_db_pages':['^Modified db pages ','$','PAGE'], 47 | 'pending_writes_lru':['^Pending writes: LRU ',',','NUM'], 48 | 'pending_writes_flush_list':['^Pending writes: LRU'+NUM_REG+', flush list ',',','NUM'], 49 | 'pending_writes_single_page':['^Pending writes: LRU'+NUM_REG+', flush list'+NUM_REG+', single page ','$','NUM'], 50 | 'pages_made_young':['^Pages made young ',',','NUM'], 51 | 'pages_made_not_young':['^Pages made young'+NUM_REG+', not young','$','NUM'], 52 | 'pages_made_young_per_sec':['^','youngs/s,','PER_SECOND'], 53 | 'pages_made_non_young_per_sec':['^'+NUM_REG+'youngs/s,','non-youngs/s','PER_SECOND'], 54 | 'pages_read':['^Pages read ',',','NUM'], 55 | 'pages_created':['^Pages read'+NUM_REG+', created ',',','NUM'], 56 | 'pages_written':['^Pages read'+NUM_REG+', created'+NUM_REG+', written ','$','NUM'], 57 | 'pages_read_ahead':['^Pages read ahead ','/s,','PER_SECOND'], 58 | 'evicted_without_access':['^Pages read ahead'+NUM_REG+'/s, evicted without access ','/s','PER_SECOND'], 59 | 'random_read_ahead':['^Pages read ahead'+NUM_REG+'/s, evicted without access'+NUM_REG+'/s, Random read ahead ','/s','PER_SECOND'], 60 | 'lrn_len':['^LRU len: ',',','NUM'], 61 | 'unzip_lru_len':['^LRU len:'+NUM_REG+', unzip_LRU len: ','$','NUM'] 62 | }, 63 | 'log':{ 64 | #Log sequence number 1283658707 65 | #Log flushed up to 1283658707 66 | #Pages flushed up to 1283658707 67 | #Last checkpoint at 1283658698 68 | #0 pending log flushes, 0 pending chkp writes 69 | #14438 log i/o's done, 0.00 log i/o's/second 70 | 'log_sequence_number':['^Log sequence number ','$','NUM'], 71 | 'log_flushed_up_to':['^Log flushed up to ','$','NUM'], 72 | 'pages_flushed_up_to':['^Pages flushed up to ','$','NUM'], 73 | 'last_checkpoint_at':['^Last checkpoint at ','$','NUM'], 74 | 'pending_log_flushes':['^','pending log flushes,','NUM'], 75 | 'pending_chkp_writes':['^'+NUM_REG+'pending log flushes,','pending chkp writes$','NUM'], 76 | 'log_ios_done':['^',"log i/o's done,",'NUM'], 77 | 'log_ios_per_second':["^'+NUM_REG+' log i/o's done,","log i/o's/second$",'NUM'] 78 | }, 79 | 'row_operations':{ 80 | #0 queries inside InnoDB, 0 queries in queue 81 | #0 read views open inside InnoDB 82 | #Process ID=12436, Main thread ID=140668680787712, state: sleeping 83 | #Number of rows inserted 16618, updated 50031, deleted 16618, read 7034937 84 | #0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.00 reads/s 85 | 'queries_inside_innodb':['^','queries inside InnoDB,','NUM'], 86 | 'queries_in_queue':["^'+NUM_REG+'queries inside InnoDB,",'queries in queue$','NUM'], 87 | 'read_views_open_inside_innodb':['^','read views open inside InnoDB$','NUM'], 88 | 'number_of_rows_inserted':['^Number of rows inserted ',',','NUM'], 89 | 'number_of_rows_updated':['^Number of rows inserted'+NUM_REG+', updated ',',','NUM'], 90 | 'number_of_rows_deleted':['^Number of rows inserted'+NUM_REG+', updated'+NUM_REG+', deleted ',',','NUM'], 91 | 'number_of_rows_read':['^Number of rows inserted'+NUM_REG+', updated'+NUM_REG+', deleted'+NUM_REG+', read ','$','NUM'], 92 | 'inserts_per_second':['^','inserts/s,','NUM'], 93 | 'updates_per_second':['^'+NUM_REG+' inserts/s, ','updates/s,','NUM'], 94 | 'deletes_per_second':['^'+NUM_REG+' inserts/s, '+NUM_REG+' updates/s,','deletes/s,','NUM'], 95 | 'reads_per_second':['^'+NUM_REG+' inserts/s, '+NUM_REG+' updates/s, '+NUM_REG+' deletes/s,','reads/s$','NUM'] 96 | }, 97 | 'insert_buffer_adaptive_hash_index':{ 98 | #Ibuf: size 1, free list len 0, seg size 2, 0 merges 99 | #merged operations: 100 | # insert 0, delete mark 0, delete 0 101 | #discarded operations: 102 | # insert 0, delete mark 0, delete 0 103 | #Hash table size 138389, node heap has 0 buffer(s) 104 | #... 105 | #Hash table size 138389, node heap has 10 buffer(s) 106 | #2535.04 hash searches/s, 2076.08 non-hash searches/s 107 | 'ibuf_size':['^Ibuf: size',',','NUM'], 108 | 'ibuf_free_list_len':['^Ibuf: size '+NUM_REG+', free list len ',',','NUM'], 109 | 'ibuf_seg_size':['^Ibuf: size '+NUM_REG+', free list len '+NUM_REG+', seg size ',',','NUM'], 110 | 'ibuf_merges':['^Ibuf: size '+NUM_REG+', free list len '+NUM_REG+', seg size '+NUM_REG+', ','merges$','NUM'], 111 | 'merged_operations':['^merged operations:','$','OPER'], 112 | '_insert':['^ insert ',',','NUM'], 113 | '_delete_mark':['^ insert '+NUM_REG+', delete mark ',',','NUM'], 114 | '_delete':['^ insert '+NUM_REG+', delete mark '+NUM_REG+', delete ','$','NUM'], 115 | 'discarded_operations':['^discarded operations:','$','OPER'], 116 | '_insert':['^ insert ',',','NUM'], 117 | '_delete_mark':['^ insert '+NUM_REG+', delete mark ',',','NUM'], 118 | '_delete':['^ insert '+NUM_REG+', delete mark '+NUM_REG+', delete ','$','NUM'], 119 | 'hash_searches_per_second':['^','hash searches/s,','PER_SECOND'], 120 | 'non_hash_searches_per_second':['^'+NUM_REG+' hash searches/s, ','non-hash searches/s$','PER_SECOND'] 121 | }, 122 | 'file_io':{ 123 | #I/O thread 0 state: waiting for completed aio requests (insert buffer thread) 124 | #... 125 | #I/O thread 17 state: waiting for completed aio requests (write thread) 126 | #Pending normal aio reads: [0, 0, 0, 0, 0, 0, 0, 0] , aio writes: [0, 0, 0, 0, 0, 0, 0, 0] , 127 | #ibuf aio reads:, log i/o's:, sync i/o's: 128 | #Pending flushes (fsync) log: 0; buffer pool: 0 129 | #2593 OS file reads, 28093 OS file writes, 530 OS fsyncs 130 | #0.00 reads/s, 0 avg bytes/read, 0.00 writes/s, 0.00 fsyncs/s 131 | 'os_file_reads':['^','OS file reads,','NUM'], 132 | 'os_file_writes':['^'+NUM_REG+' OS file reads, ','OS file writes,','NUM'], 133 | 'os_fsyncs':['^'+NUM_REG+' OS file reads, '+NUM_REG+' OS file writes, ','OS fsyncs$','NUM'], 134 | 'reads_per_second':['^','reads/s,','NUM'], 135 | 'avg_bytes_per_read':['^'+NUM_REG+' reads/s, ','avg bytes/read,','BYTE'], 136 | 'writes_per_second':['^'+NUM_REG+' reads/s, '+NUM_REG+' avg bytes/read,','writes/s,','NUM'], 137 | 'fsyncs_per_second':['^'+NUM_REG+' reads/s, '+NUM_REG+' avg bytes/read,'+NUM_REG+'writes/s,','fsyncs/s$','NUM'] 138 | }, 139 | 'transactions':{ 140 | #Trx id counter 924584 141 | #Purge done for trx's n:o < 924584 undo n:o < 0 state: running but idle 142 | #History list length 610 143 | 'trx_counter':['^Trx id counter','$','NUM'], 144 | 'purge_done_for_trx':["^Purge done for trx's n:o <",'undo n:o','NUM'], 145 | 'purge_done_for_undo':["^Purge done for trx's n:o <"+NUM_REG+' undo n:o <','state:','NUM'], 146 | 'history_list_length':['^History list length','$','NUM'] 147 | }, 148 | 'semaphores':{ 149 | #OS WAIT ARRAY INFO: reservation count 26272 150 | #OS WAIT ARRAY INFO: signal count 26035 151 | #RW-shared spins 0, rounds 12106, OS waits 2966 152 | #RW-excl spins 0, rounds 35158, OS waits 2424 153 | #RW-sx spins 7, rounds 210, OS waits 7 154 | #Spin rounds per wait: 12106.00 RW-shared, 35158.00 RW-excl, 30.00 RW-sx 155 | 'reservation_count':['^OS WAIT ARRAY INFO: reservation count','$','NUM'], 156 | 'signal_count':['^OS WAIT ARRAY INFO: signal count','$','NUM'], 157 | 'rw_shared_spins':['^RW-shared spins',',','NUM'], 158 | 'rw_shared_rounds':['^RW-shared spins '+NUM_REG+', rounds',',','NUM'], 159 | 'rw_shared_os_waits':['^RW-shared spins '+NUM_REG+', rounds '+NUM_REG+' OS waits','$','NUM'], 160 | 'rw_excl_spins':['^RW-excl spins',',','NUM'], 161 | 'rw_excl_rounds':['^RW-excl spins '+NUM_REG+', rounds',',','NUM'], 162 | 'rw_excl_os_waits':['^RW-excl spins '+NUM_REG+', rounds '+NUM_REG+' OS waits','$','NUM'], 163 | 'rw_sx_spins':['^RW-sx spins',',','NUM'], 164 | 'rw_sx_rounds':['^RW-sx spins '+NUM_REG+', rounds',',','NUM'], 165 | 'rw_sx_os_waits':['^RW-sx spins '+NUM_REG+', rounds '+NUM_REG+' OS waits','$','NUM'], 166 | 'spin_rounds_per_wait_rw_shared':['^Spin rounds per wait:','RW-shared,','NUM'], 167 | 'spin_rounds_per_wait_rw_excl':['^Spin rounds per wait:'+NUM_REG+' RW-shared, ','RW-excl,','NUM'], 168 | 'spin_rounds_per_wait_rw_sx':['^Spin rounds per wait:'+NUM_REG+' RW-shared, '+NUM_REG+' RW-excl, ','RW-sx$','NUM'] 169 | }, 170 | 'background_thread':{ 171 | #srv_master_thread loops: 147 srv_active, 0 srv_shutdown, 19300 srv_idle 172 | #srv_master_thread log flush and writes: 19447 173 | 'master_thread_loops_active':['^srv_master_thread loops:','srv_active,','NUM'], 174 | 'master_thread_loops_shutdown':['^srv_master_thread loops: '+NUM_REG+' srv_active,','srv_shutdown,','NUM'], 175 | 'master_thread_loops_idle':['^srv_master_thread loops: '+NUM_REG+' srv_active, '+NUM_REG+'srv_shutdown,','srv_idle$','NUM'], 176 | 'master_thread_log_flush_and_writes':['^srv_master_thread log flush and writes:','$','NUM'] 177 | } 178 | } 179 | def query_innodb_status(p_host,p_user,p_pwd): 180 | conn = MySQLdb.connect(p_host, p_user, p_pwd, 'information_schema', charset="utf8"); 181 | query = "SHOW ENGINE INNODB STATUS;" 182 | cursor = conn.cursor() 183 | cursor.execute(query) 184 | result_list = [] 185 | temp_list = cursor.fetchall() 186 | for o in temp_list: 187 | result_list = result_list + str(o).split("\\n") 188 | conn.close() 189 | return result_list 190 | 191 | def deal_log(v_data): 192 | """ 193 | RETURN STRUCTURE 194 | { 195 | 'section': 196 | { 197 | 'key':{'val':'xxx','unit':'xxx'} 198 | } 199 | } 200 | example: 201 | { 202 | 'bufferpool_memory': 203 | { 204 | 'buffer_pool_size': {'unit': 'BYTE', 'val': '32768'}, 205 | 'database_pages': {'unit': 'PAGE', 'val': '9484'}, 206 | 'dictionary_memory_allocated': {'unit': 'BYTE'} 207 | } 208 | } 209 | """ 210 | result_dict = {} 211 | regex_background_thread = re.compile("^BACKGROUND THREAD") 212 | regex_transactions = re.compile("^TRANSACTIONS") 213 | regex_semaphores = re.compile("^SEMAPHORES") 214 | regex_file_io = re.compile("^FILE I/O") 215 | regex_ins_buf_ahi = re.compile("^INSERT BUFFER AND ADAPTIVE HASH INDEX") 216 | regex_log = re.compile("^LOG") 217 | regex_bufferpool_memory = re.compile("^BUFFER POOL AND MEMORY") 218 | regex_row_operations = re.compile("^ROW OPERATIONS") 219 | regex_end = re.compile("^END OF INNODB MONITOR OUTPUT") 220 | 221 | cur_section = 'other' 222 | key_prefix = '' 223 | for line in v_data: 224 | if regex_background_thread.match(line): 225 | cur_section='background_thread' 226 | elif regex_transactions.match(line): 227 | cur_section='transactions' 228 | elif regex_semaphores.match(line): 229 | cur_section='semaphores' 230 | elif regex_file_io.match(line): 231 | cur_section='file_io' 232 | elif regex_ins_buf_ahi.match(line): 233 | cur_section='insert_buffer_adaptive_hash_index' 234 | elif regex_log.match(line): 235 | cur_section='log' 236 | elif regex_bufferpool_memory.match(line): 237 | cur_section='bufferpool_memory' 238 | elif regex_row_operations.match(line): 239 | cur_section='row_operations' 240 | elif regex_end.match(line): 241 | cur_section='other' 242 | else: 243 | if INNODB_STATUS_DICT.has_key(cur_section): 244 | for item in INNODB_STATUS_DICT[cur_section].keys(): 245 | re_str = INNODB_STATUS_DICT[cur_section][item][0]+''+NUM_REG+''+INNODB_STATUS_DICT[cur_section][item][1] 246 | if cur_section=='insert_buffer_adaptive_hash_index' and re.findall("merged operations",line): 247 | key_prefix = 'merged_operations' 248 | break 249 | if cur_section=='insert_buffer_adaptive_hash_index' and re.findall("discarded operations",line): 250 | key_prefix = 'discarded_operations' 251 | break 252 | if cur_section=='insert_buffer_adaptive_hash_index' and re.findall("Hash table size",line): 253 | key_prefix = '' 254 | if re.findall(re_str,line): 255 | if INNODB_STATUS_DICT[cur_section][item][1]=="$": 256 | val = re.split(INNODB_STATUS_DICT[cur_section][item][0],line)[-1] 257 | else: 258 | val = re.split(INNODB_STATUS_DICT[cur_section][item][1],re.split(INNODB_STATUS_DICT[cur_section][item][0],line)[-1])[0] 259 | if result_dict.has_key(cur_section) == 0: 260 | result_dict[cur_section]={} 261 | if key_prefix == '': 262 | result_dict[cur_section][item]={'val':val.strip(),'unit':INNODB_STATUS_DICT[cur_section][item][2]} 263 | else: 264 | result_dict[cur_section][key_prefix+item]={'val':val.strip(),'unit':INNODB_STATUS_DICT[cur_section][item][2]} 265 | return result_dict 266 | 267 | def print_help(): 268 | print("Usage:") 269 | print "./mysql_innodb_status.py -h -u -p " 270 | print " -h : database ip address/domain name" 271 | print " -u : username" 272 | print " -p : password" 273 | print " -k : print specified items(section.key1,section.key2) or section.*" 274 | print " -n : interval time" 275 | print " -w : item width" 276 | 277 | if __name__ == "__main__": 278 | interval = 0 279 | width = 10 280 | try: 281 | opts,args = getopt.getopt(sys.argv[1:],"h:u:p:k:n:w:") 282 | for o,v in opts: 283 | if o=="-h": 284 | db=v 285 | elif o=="-u": 286 | username=v 287 | elif o=="-p": 288 | pwd=v 289 | elif o=="-k": 290 | keys=v 291 | elif o=="-n": 292 | interval=int(v) 293 | elif o=="-w": 294 | width=int(v) 295 | except getopt.GetoptError,msg: 296 | print_help() 297 | exit() 298 | 299 | v_innodb_status = [] 300 | v_innodb_status = query_innodb_status(db,username,pwd) 301 | v_dict = deal_log(v_innodb_status) 302 | if keys.upper()=="ALL": 303 | for section in sorted(v_dict.keys()): 304 | print 305 | print '[',section,']' 306 | print '-'*80 307 | for key in sorted(v_dict[section]): 308 | print key.ljust(40),v_dict[section][key]['val'].rjust(20),v_dict[section][key]['unit'].rjust(15) 309 | else: 310 | if keys.find('.*')<>-1: 311 | section = keys.replace('.*','') 312 | keys = section+'.'+(','+section+'.').join(v_dict[section].keys()) 313 | if interval==0: 314 | print time.strftime("%H:%M:%S",time.localtime(time.time())) 315 | for key in keys.split(','): 316 | print key.ljust(45),v_dict[key.split('.')[0]][key.split('.')[1]]['val'].rjust(30) 317 | else: 318 | iredraw=1 319 | while True: 320 | if iredraw==1: 321 | print "\033[1;31;40m%s\033[0m" % "Time".ljust(9), 322 | for key in keys.split(','): 323 | print "\033[1;31;40m%s\033[0m" % key.split('.')[1][:(width)].rjust(width), 324 | print 325 | print time.strftime("%H:%M:%S",time.localtime(time.time())).ljust(9), 326 | for key in keys.split(','): 327 | print v_dict[key.split('.')[0]][key.split('.')[1]]['val'][:(width)].rjust(width), 328 | print 329 | time.sleep(interval) 330 | v_innodb_status = [] 331 | v_innodb_status = query_innodb_status(db,username,pwd) 332 | v_dict = deal_log(v_innodb_status) 333 | iredraw = 1 if iredraw >5 else iredraw + 1 --------------------------------------------------------------------------------