History

perf tools: Add more documentation to export-to-postgresql.py script

Add some comments to the script and some 'views' to the created database that better illustrate the database structure and how it can be used.

Adrian Hunter committed 11 years ago

Commit 35ca01c1 parent a38f48e1 file · +221 −0Browse files

Showing the changes to tools/perf/scripts/python/export-to-postgresql.py (1 of 1 file). Show all

Unified · Split

tools/perf/scripts/python/export-to-postgresql.py+221−0
@@ -61,6 +61,142 @@ import datetime · 60 unmodified lines
61#61#
62# An example of using the database is provided by the script62# An example of using the database is provided by the script
63# call-graph-from-postgresql.py. Refer to that script for details.63# call-graph-from-postgresql.py. Refer to that script for details.
64#
65# Tables:
66#
67# The tables largely correspond to perf tools' data structures. They are largely self-explanatory.
68#
69# samples
70#
71# 'samples' is the main table. It represents what instruction was executing at a point in time
72# when something (a selected event) happened. The memory address is the instruction pointer or 'ip'.
73#
74# calls
75#
76# 'calls' represents function calls and is related to 'samples' by 'call_id' and 'return_id'.
77# 'calls' is only created when the 'calls' option to this script is specified.
78#
79# call_paths
80#
81# 'call_paths' represents all the call stacks. Each 'call' has an associated record in 'call_paths'.
82# 'calls_paths' is only created when the 'calls' option to this script is specified.
83#
84# branch_types
85#
86# 'branch_types' provides descriptions for each type of branch.
87#
88# comm_threads
89#
90# 'comm_threads' shows how 'comms' relates to 'threads'.
91#
92# comms
93#
94# 'comms' contains a record for each 'comm' - the name given to the executable that is running.
95#
96# dsos
97#
98# 'dsos' contains a record for each executable file or library.
99#
100# machines
101#
102# 'machines' can be used to distinguish virtual machines if virtualization is supported.
103#
104# selected_events
105#
106# 'selected_events' contains a record for each kind of event that has been sampled.
107#
108# symbols
109#
110# 'symbols' contains a record for each symbol. Only symbols that have samples are present.
111#
112# threads
113#
114# 'threads' contains a record for each thread.
115#
116# Views:
117#
118# Most of the tables have views for more friendly display. The views are:
119#
120# calls_view
121# call_paths_view
122# comm_threads_view
123# dsos_view
124# machines_view
125# samples_view
126# symbols_view
127# threads_view
128#
129# More examples of browsing the database with psql:
130# Note that some of the examples are not the most optimal SQL query.
131# Note that call information is only available if the script's 'calls' option has been used.
132#
133# Top 10 function calls (not aggregated by symbol):
134#
135# SELECT * FROM calls_view ORDER BY elapsed_time DESC LIMIT 10;
136#
137# Top 10 function calls (aggregated by symbol):
138#
139# SELECT symbol_id,(SELECT name FROM symbols WHERE id = symbol_id) AS symbol,
140# SUM(elapsed_time) AS tot_elapsed_time,SUM(branch_count) AS tot_branch_count
141# FROM calls_view GROUP BY symbol_id ORDER BY tot_elapsed_time DESC LIMIT 10;
142#
143# Note that the branch count gives a rough estimation of cpu usage, so functions
144# that took a long time but have a relatively low branch count must have spent time
145# waiting.
146#
147# Find symbols by pattern matching on part of the name (e.g. names containing 'alloc'):
148#
149# SELECT * FROM symbols_view WHERE name LIKE '%alloc%';
150#
151# Top 10 function calls for a specific symbol (e.g. whose symbol_id is 187):
152#
153# SELECT * FROM calls_view WHERE symbol_id = 187 ORDER BY elapsed_time DESC LIMIT 10;
154#
155# Show function calls made by function in the same context (i.e. same call path) (e.g. one with call_path_id 254):
156#
157# SELECT * FROM calls_view WHERE parent_call_path_id = 254;
158#
159# Show branches made during a function call (e.g. where call_id is 29357 and return_id is 29370 and tid is 29670)
160#
161# SELECT * FROM samples_view WHERE id >= 29357 AND id <= 29370 AND tid = 29670 AND event LIKE 'branches%';
162#
163# Show transactions:
164#
165# SELECT * FROM samples_view WHERE event = 'transactions';
166#
167# Note transaction start has 'in_tx' true whereas, transaction end has 'in_tx' false.
168# Transaction aborts have branch_type_name 'transaction abort'
169#
170# Show transaction aborts:
171#
172# SELECT * FROM samples_view WHERE event = 'transactions' AND branch_type_name = 'transaction abort';
173#
174# To print a call stack requires walking the call_paths table. For example this python script:
175# #!/usr/bin/python2
176#
177# import sys
178# from PySide.QtSql import *
179#
180# if __name__ == '__main__':
181# if (len(sys.argv) < 3):
182# print >> sys.stderr, "Usage is: printcallstack.py <database name> <call_path_id>"
183# raise Exception("Too few arguments")
184# dbname = sys.argv[1]
185# call_path_id = sys.argv[2]
186# db = QSqlDatabase.addDatabase('QPSQL')
187# db.setDatabaseName(dbname)
188# if not db.open():
189# raise Exception("Failed to open database " + dbname + " error: " + db.lastError().text())
190# query = QSqlQuery(db)
191# print " id ip symbol_id symbol dso_id dso_short_name"
192# while call_path_id != 0 and call_path_id != 1:
193# ret = query.exec_('SELECT * FROM call_paths_view WHERE id = ' + str(call_path_id))
194# if not ret:
195# raise Exception("Query failed: " + query.lastError().text())
196# if not query.next():
197# raise Exception("Query failed")
198# print "{0:>6} {1:>10} {2:>9} {3:<30} {4:>6} {5:<30}".format(query.value(0), query.value(1), query.value(2), query.value(3), query.value(4), query.value(5))
199# call_path_id = query.value(6)
64 200
65from PySide.QtSql import *201from PySide.QtSql import *
66 202
@@ -244,6 +380,91 @@ if perf_db_export_calls: · 177 unmodified lines
244 'parent_call_path_id bigint,'380 'parent_call_path_id bigint,'
245 'flags integer)')381 'flags integer)')
246 382
383do_query(query, 'CREATE VIEW machines_view AS '
384 'SELECT '
385 'id,'
386 'pid,'
387 'root_dir,'
388 'CASE WHEN id=0 THEN \'unknown\' WHEN pid=-1 THEN \'host\' ELSE \'guest\' END AS host_or_guest'
389 ' FROM machines')
390
391do_query(query, 'CREATE VIEW dsos_view AS '
392 'SELECT '
393 'id,'
394 'machine_id,'
395 '(SELECT host_or_guest FROM machines_view WHERE id = machine_id) AS host_or_guest,'
396 'short_name,'
397 'long_name,'
398 'build_id'
399 ' FROM dsos')
400
401do_query(query, 'CREATE VIEW symbols_view AS '
402 'SELECT '
403 'id,'
404 'name,'
405 '(SELECT short_name FROM dsos WHERE id=dso_id) AS dso,'
406 'dso_id,'
407 'sym_start,'
408 'sym_end,'
409 'CASE WHEN binding=0 THEN \'local\' WHEN binding=1 THEN \'global\' ELSE \'weak\' END AS binding'
410 ' FROM symbols')
411
412do_query(query, 'CREATE VIEW threads_view AS '
413 'SELECT '
414 'id,'
415 'machine_id,'
416 '(SELECT host_or_guest FROM machines_view WHERE id = machine_id) AS host_or_guest,'
417 'process_id,'
418 'pid,'
419 'tid'
420 ' FROM threads')
421
422do_query(query, 'CREATE VIEW comm_threads_view AS '
423 'SELECT '
424 'comm_id,'
425 '(SELECT comm FROM comms WHERE id = comm_id) AS command,'
426 'thread_id,'
427 '(SELECT pid FROM threads WHERE id = thread_id) AS pid,'
428 '(SELECT tid FROM threads WHERE id = thread_id) AS tid'
429 ' FROM comm_threads')
430
431if perf_db_export_calls:
432 do_query(query, 'CREATE VIEW call_paths_view AS '
433 'SELECT '
434 'c.id,'
435 'to_hex(c.ip) AS ip,'
436 'c.symbol_id,'
437 '(SELECT name FROM symbols WHERE id = c.symbol_id) AS symbol,'
438 '(SELECT dso_id FROM symbols WHERE id = c.symbol_id) AS dso_id,'
439 '(SELECT dso FROM symbols_view WHERE id = c.symbol_id) AS dso_short_name,'
440 'c.parent_id,'
441 'to_hex(p.ip) AS parent_ip,'
442 'p.symbol_id AS parent_symbol_id,'
443 '(SELECT name FROM symbols WHERE id = p.symbol_id) AS parent_symbol,'
444 '(SELECT dso_id FROM symbols WHERE id = p.symbol_id) AS parent_dso_id,'
445 '(SELECT dso FROM symbols_view WHERE id = p.symbol_id) AS parent_dso_short_name'
446 ' FROM call_paths c INNER JOIN call_paths p ON p.id = c.parent_id')
447 do_query(query, 'CREATE VIEW calls_view AS '
448 'SELECT '
449 'calls.id,'
450 'thread_id,'
451 '(SELECT pid FROM threads WHERE id = thread_id) AS pid,'
452 '(SELECT tid FROM threads WHERE id = thread_id) AS tid,'
453 '(SELECT comm FROM comms WHERE id = comm_id) AS command,'
454 'call_path_id,'
455 'to_hex(ip) AS ip,'
456 'symbol_id,'
457 '(SELECT name FROM symbols WHERE id = symbol_id) AS symbol,'
458 'call_time,'
459 'return_time,'
460 'return_time - call_time AS elapsed_time,'
461 'branch_count,'
462 'call_id,'
463 'return_id,'
464 'CASE WHEN flags=1 THEN \'no call\' WHEN flags=2 THEN \'no return\' WHEN flags=3 THEN \'no call/return\' ELSE \'\' END AS flags,'
465 'parent_call_path_id'
466 ' FROM calls INNER JOIN call_paths ON call_paths.id = call_path_id')
467
247do_query(query, 'CREATE VIEW samples_view AS '468do_query(query, 'CREATE VIEW samples_view AS '
248 'SELECT '469 'SELECT '
249 'id,'470 'id,'