innodb_ruby 0.9.12 → 0.9.13
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/innodb_space +360 -4
- data/lib/innodb/version.rb +1 -1
- metadata +2 -2
data/bin/innodb_space
CHANGED
@@ -11,6 +11,10 @@ def rgb_to_ansi(rgb)
|
|
11
11
|
16 + (rgb_n[0] * 36) + (rgb_n[1] * 6) + rgb_n[2]
|
12
12
|
end
|
13
13
|
|
14
|
+
def rgb_to_rgbhex(rgb)
|
15
|
+
rgb.map { |c| "%02x" % [(c * 255.0).round] }.join
|
16
|
+
end
|
17
|
+
|
14
18
|
# Interpolate intermediate float-arrays between two float-arrays. Do not
|
15
19
|
# include the points a and b in the result.
|
16
20
|
def interpolate(a, b, count)
|
@@ -49,6 +53,10 @@ HEATMAP_PROGRESSION = [
|
|
49
53
|
# Typical heatmap color progression.
|
50
54
|
ANSI_COLORS_HEATMAP = interpolate_sequence(HEATMAP_PROGRESSION, 6).map { |rgb| rgb_to_ansi(rgb) }
|
51
55
|
|
56
|
+
RGBHEX_COLORS_HEATMAP = interpolate_sequence(HEATMAP_PROGRESSION, 41).map { |rgb| rgb_to_rgbhex(rgb) }
|
57
|
+
|
58
|
+
RGBHEX_COLORS_RANDOM = 100.times.inject([]) { |a, x| a << rgb_to_rgbhex([rand * 0.7 + 0.25, rand * 0.7 + 0.25, rand * 0.7 + 0.25]) }
|
59
|
+
|
52
60
|
# The 24-step grayscale progression.
|
53
61
|
ANSI_COLORS_GRAYSCALE = (0xe8..0xff).to_a
|
54
62
|
|
@@ -83,6 +91,35 @@ def filled_block(fraction, identifier=nil, block_chars=BLOCK_CHARS_V)
|
|
83
91
|
end
|
84
92
|
end
|
85
93
|
|
94
|
+
def svg_join_args(args)
|
95
|
+
args.map { |arg| "%s=\"%s\"" % [ arg[0], arg[1], ] }.join(" ")
|
96
|
+
end
|
97
|
+
|
98
|
+
def svg(elem, args, content=nil)
|
99
|
+
if content
|
100
|
+
"<" + elem.to_s + " " + svg_join_args(args) + ">" +
|
101
|
+
content.to_s +
|
102
|
+
"</" + elem.to_s + ">"
|
103
|
+
else
|
104
|
+
"<" + elem.to_s + " " + svg_join_args(args) + " />"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def svg_path_rounded_rect(x, y, w, h, r)
|
109
|
+
[
|
110
|
+
"M%i,%i" % [ x + r, y - r ],
|
111
|
+
"L%i,%i" % [ x + w - r, y - r ],
|
112
|
+
"S%i,%i %i,%i" % [ x + w + r, y - r, x + w + r, y + r ],
|
113
|
+
"L%i,%i" % [ x + w + r, y + h - r ],
|
114
|
+
"S%i,%i %i,%i" % [ x + w + r, y + h + r, x + w - r, y + h + r ],
|
115
|
+
"L%i,%i" % [ x + r, y + h + r ],
|
116
|
+
"S%i,%i %i,%i" % [ x - r, y + h + r, x - r, y + h - r ],
|
117
|
+
"L%i,%i" % [ x - r, y + r ],
|
118
|
+
"S%i,%i %i,%i" % [ x - r, y - r, x + r, y - r ],
|
119
|
+
"Z",
|
120
|
+
].join(" ")
|
121
|
+
end
|
122
|
+
|
86
123
|
# Print metadata about each list in an array of InnoDB::List objects.
|
87
124
|
def print_lists(lists)
|
88
125
|
puts "%-20s%-12s%-12s%-12s%-12s%-12s" % [
|
@@ -504,6 +541,7 @@ def space_extents_illustrate(space)
|
|
504
541
|
},
|
505
542
|
]
|
506
543
|
end
|
544
|
+
total_pages = count_by_identifier.values.reduce(:+)
|
507
545
|
|
508
546
|
puts "%12s ╰%-#{width}s╯" % [ "", "─" * width ]
|
509
547
|
|
@@ -516,25 +554,210 @@ def space_extents_illustrate(space)
|
|
516
554
|
filled_block(1.0, nil),
|
517
555
|
"System",
|
518
556
|
count_by_identifier[nil],
|
519
|
-
100.0 * (count_by_identifier[nil].to_f /
|
557
|
+
100.0 * (count_by_identifier[nil].to_f / total_pages.to_f),
|
520
558
|
]
|
521
559
|
identifiers.sort.each do |identifier, description|
|
522
560
|
puts " %s %-60s %8i %7.2f%%" % [
|
523
561
|
filled_block(1.0, identifier),
|
524
562
|
description,
|
525
563
|
count_by_identifier[identifier],
|
526
|
-
100.0 * (count_by_identifier[identifier].to_f /
|
564
|
+
100.0 * (count_by_identifier[identifier].to_f / total_pages.to_f),
|
527
565
|
]
|
528
566
|
end
|
529
567
|
puts " %s %-60s %8i %7.2f%%" % [
|
530
568
|
filled_block(0.0, nil),
|
531
569
|
"Free space",
|
532
570
|
count_by_identifier[:free],
|
533
|
-
100.0 * (count_by_identifier[:free].to_f /
|
571
|
+
100.0 * (count_by_identifier[:free].to_f / total_pages.to_f),
|
534
572
|
]
|
535
573
|
puts
|
536
574
|
end
|
537
575
|
|
576
|
+
def svg_extent_legend(x, y, block_size, color=nil, description=nil, pages=nil, ratio=nil)
|
577
|
+
[
|
578
|
+
svg("rect", {
|
579
|
+
"y" => y,
|
580
|
+
"x" => x,
|
581
|
+
"width" => block_size,
|
582
|
+
"height" => block_size,
|
583
|
+
"fill" => color ? color : "white",
|
584
|
+
"stroke" => description ? "black" : "none",
|
585
|
+
}),
|
586
|
+
svg("text", {
|
587
|
+
"y" => y + block_size - 4,
|
588
|
+
"x" => x + (description ? block_size + 5 : 0),
|
589
|
+
"font-family" => "monospace",
|
590
|
+
"font-size" => block_size,
|
591
|
+
"font-weight" => description ? "normal" : "bold",
|
592
|
+
"text-anchor" => "start",
|
593
|
+
}, description ? description : "Page Type"),
|
594
|
+
svg("text", {
|
595
|
+
"y" => y + block_size - 4,
|
596
|
+
"x" => x + block_size + 5 + (40 * block_size),
|
597
|
+
"font-family" => "monospace",
|
598
|
+
"font-size" => block_size,
|
599
|
+
"font-weight" => description ? "normal" : "bold",
|
600
|
+
"text-anchor" => "end",
|
601
|
+
}, pages ? pages : "Pages"),
|
602
|
+
svg("text", {
|
603
|
+
"y" => y + block_size - 4,
|
604
|
+
"x" => x + block_size + 5 + (40 * block_size) + (10 * block_size),
|
605
|
+
"font-family" => "monospace",
|
606
|
+
"font-size" => block_size,
|
607
|
+
"font-weight" => description ? "normal" : "bold",
|
608
|
+
"text-anchor" => "end",
|
609
|
+
}, ratio ? ("%7.2f%%" % [ratio]) : "Ratio"),
|
610
|
+
].join("\n")
|
611
|
+
end
|
612
|
+
|
613
|
+
# Illustrate the space by printing each extent and for each page, printing a
|
614
|
+
# filled block colored based on the index the page is part of. Print a legend
|
615
|
+
# for the colors used afterwards.
|
616
|
+
def space_extents_illustrate_svg(space)
|
617
|
+
width = space.pages_per_extent
|
618
|
+
|
619
|
+
puts "<?xml version=\"1.0\"?>"
|
620
|
+
puts "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">"
|
621
|
+
|
622
|
+
identifiers = {}
|
623
|
+
count_by_identifier = Hash.new(0)
|
624
|
+
|
625
|
+
block_size = 16
|
626
|
+
graphic_x = 48
|
627
|
+
graphic_y = 16
|
628
|
+
|
629
|
+
puts svg("text", {
|
630
|
+
"y" => graphic_y - 3,
|
631
|
+
"x" => graphic_x - 7,
|
632
|
+
"font-family" => "monospace",
|
633
|
+
"font-size" => block_size,
|
634
|
+
"font-weight" => "bold",
|
635
|
+
"text-anchor" => "end",
|
636
|
+
}, "Page")
|
637
|
+
|
638
|
+
block_x = 0
|
639
|
+
block_y = 0
|
640
|
+
space.each_xdes do |entry|
|
641
|
+
block_x = 0
|
642
|
+
|
643
|
+
puts svg("text", {
|
644
|
+
"y" => graphic_y + block_y + block_size,
|
645
|
+
"x" => graphic_x - 7,
|
646
|
+
"font-family" => "monospace",
|
647
|
+
"font-size" => block_size,
|
648
|
+
"text-anchor" => "end",
|
649
|
+
}, entry.xdes[:start_page])
|
650
|
+
|
651
|
+
entry.each_page_status do |page_number, page_status|
|
652
|
+
if page_number < space.pages
|
653
|
+
used_fraction = 1.0
|
654
|
+
identifier = nil
|
655
|
+
if page_status[:free]
|
656
|
+
used_fraction = 0.0
|
657
|
+
else
|
658
|
+
page = space.page(page_number)
|
659
|
+
if page.respond_to?(:used_space)
|
660
|
+
used_fraction = page.used_space.to_f / page.size.to_f
|
661
|
+
end
|
662
|
+
if page.respond_to?(:index_id)
|
663
|
+
identifier = page.index_id
|
664
|
+
unless identifiers[identifier]
|
665
|
+
identifiers[identifier] = (page.index_id == Innodb::IbufIndex::INDEX_ID) ?
|
666
|
+
"Insert Buffer Index" :
|
667
|
+
"Index #{page.index_id}"
|
668
|
+
if space.innodb_system
|
669
|
+
table, index = space.innodb_system.table_and_index_name_by_id(page.index_id)
|
670
|
+
if table && index
|
671
|
+
identifiers[identifier] += " (%s.%s)" % [table, index]
|
672
|
+
end
|
673
|
+
end
|
674
|
+
end
|
675
|
+
end
|
676
|
+
end
|
677
|
+
if used_fraction != 0.0
|
678
|
+
count_by_identifier[identifier] += 1
|
679
|
+
else
|
680
|
+
count_by_identifier[:free] += 1
|
681
|
+
end
|
682
|
+
|
683
|
+
block_height = block_size * used_fraction
|
684
|
+
color = "black"
|
685
|
+
if identifier
|
686
|
+
color = "#" + RGBHEX_COLORS_RANDOM[(identifier * COLOR_SPACING_PRIME) % RGBHEX_COLORS_RANDOM.size]
|
687
|
+
end
|
688
|
+
puts svg("rect", {
|
689
|
+
"x" => graphic_x + block_x,
|
690
|
+
"y" => graphic_y + block_y + (block_size - block_height),
|
691
|
+
"width" => block_size,
|
692
|
+
"height" => block_height,
|
693
|
+
"fill" => color,
|
694
|
+
})
|
695
|
+
end
|
696
|
+
block_x += block_size
|
697
|
+
end
|
698
|
+
block_y += block_size
|
699
|
+
end
|
700
|
+
|
701
|
+
puts svg("path", {
|
702
|
+
"stroke" => "black",
|
703
|
+
"stroke-width" => 1,
|
704
|
+
"fill" => "none",
|
705
|
+
"d" => svg_path_rounded_rect(
|
706
|
+
graphic_x,
|
707
|
+
graphic_y,
|
708
|
+
block_x,
|
709
|
+
block_y,
|
710
|
+
4
|
711
|
+
),
|
712
|
+
})
|
713
|
+
|
714
|
+
block_x = 0
|
715
|
+
block_y += 10
|
716
|
+
puts svg_extent_legend(
|
717
|
+
graphic_x + block_x,
|
718
|
+
graphic_y + block_y,
|
719
|
+
block_size,
|
720
|
+
)
|
721
|
+
block_y += block_size + 2
|
722
|
+
|
723
|
+
puts svg_extent_legend(
|
724
|
+
graphic_x + block_x,
|
725
|
+
graphic_y + block_y,
|
726
|
+
block_size,
|
727
|
+
"black",
|
728
|
+
"System",
|
729
|
+
count_by_identifier[nil],
|
730
|
+
100.0 * (count_by_identifier[nil].to_f / space.pages.to_f)
|
731
|
+
)
|
732
|
+
block_y += block_size + 2
|
733
|
+
|
734
|
+
identifiers.sort.each do |identifier, description|
|
735
|
+
puts svg_extent_legend(
|
736
|
+
graphic_x + block_x,
|
737
|
+
graphic_y + block_y,
|
738
|
+
block_size,
|
739
|
+
"#" + RGBHEX_COLORS_RANDOM[(identifier * COLOR_SPACING_PRIME) % RGBHEX_COLORS_RANDOM.size],
|
740
|
+
description,
|
741
|
+
count_by_identifier[identifier],
|
742
|
+
100.0 * (count_by_identifier[identifier].to_f / space.pages.to_f)
|
743
|
+
)
|
744
|
+
block_y += block_size + 2
|
745
|
+
end
|
746
|
+
|
747
|
+
puts svg_extent_legend(
|
748
|
+
graphic_x + block_x,
|
749
|
+
graphic_y + block_y,
|
750
|
+
block_size,
|
751
|
+
"white",
|
752
|
+
"Free space",
|
753
|
+
count_by_identifier[:free],
|
754
|
+
100.0 * (count_by_identifier[:free].to_f / space.pages.to_f)
|
755
|
+
)
|
756
|
+
|
757
|
+
puts "</svg>"
|
758
|
+
end
|
759
|
+
|
760
|
+
|
538
761
|
def space_lsn_age_illustrate(space)
|
539
762
|
colors = ANSI_COLORS_HEATMAP
|
540
763
|
|
@@ -615,6 +838,125 @@ def space_lsn_age_illustrate(space)
|
|
615
838
|
]
|
616
839
|
end
|
617
840
|
|
841
|
+
def space_lsn_age_illustrate_svg(space)
|
842
|
+
colors = RGBHEX_COLORS_HEATMAP
|
843
|
+
|
844
|
+
puts "<?xml version=\"1.0\"?>"
|
845
|
+
puts "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">"
|
846
|
+
|
847
|
+
# Calculate the minimum and maximum LSN in the space. This is pretty
|
848
|
+
# inefficient as we end up scanning all pages twice.
|
849
|
+
page_lsn = Array.new(space.pages)
|
850
|
+
|
851
|
+
lsn_min = lsn_max = space.page(0).lsn
|
852
|
+
space.each_page do |page_number, page|
|
853
|
+
if page.lsn != 0
|
854
|
+
page_lsn[page_number] = page.lsn
|
855
|
+
lsn_min = page.lsn < lsn_min ? page.lsn : lsn_min
|
856
|
+
lsn_max = page.lsn > lsn_max ? page.lsn : lsn_max
|
857
|
+
end
|
858
|
+
end
|
859
|
+
lsn_delta = lsn_max - lsn_min
|
860
|
+
|
861
|
+
block_size = 16
|
862
|
+
graphic_x = 48
|
863
|
+
graphic_y = 16
|
864
|
+
|
865
|
+
block_x = 0
|
866
|
+
block_y = 0
|
867
|
+
|
868
|
+
puts svg("text", {
|
869
|
+
"y" => graphic_y - 3,
|
870
|
+
"x" => graphic_x - 7,
|
871
|
+
"font-family" => "monospace",
|
872
|
+
"font-size" => block_size,
|
873
|
+
"font-weight" => "bold",
|
874
|
+
"text-anchor" => "end",
|
875
|
+
}, "Page")
|
876
|
+
|
877
|
+
start_page = 0
|
878
|
+
page_lsn.each_slice(64) do |slice|
|
879
|
+
block_x = 0
|
880
|
+
slice.each do |lsn|
|
881
|
+
rgbhex = ""
|
882
|
+
if lsn
|
883
|
+
age_ratio = (lsn - lsn_min).to_f / lsn_delta.to_f
|
884
|
+
color = colors[(age_ratio * colors.size.to_f).floor]
|
885
|
+
end
|
886
|
+
puts svg("rect", {
|
887
|
+
"y" => graphic_y + block_y,
|
888
|
+
"x" => graphic_x + block_x,
|
889
|
+
"width" => block_size,
|
890
|
+
"height" => block_size,
|
891
|
+
"fill" => color ? "#" + color : "black",
|
892
|
+
})
|
893
|
+
block_x += block_size
|
894
|
+
end
|
895
|
+
puts svg("text", {
|
896
|
+
"y" => graphic_y + block_y + block_size,
|
897
|
+
"x" => graphic_x - 7,
|
898
|
+
"font-family" => "monospace",
|
899
|
+
"font-size" => block_size,
|
900
|
+
"text-anchor" => "end",
|
901
|
+
}, start_page)
|
902
|
+
block_y += block_size
|
903
|
+
start_page += 64
|
904
|
+
end
|
905
|
+
|
906
|
+
puts svg("path", {
|
907
|
+
"stroke" => "black",
|
908
|
+
"stroke-width" => 1,
|
909
|
+
"fill" => "none",
|
910
|
+
"d" => svg_path_rounded_rect(
|
911
|
+
graphic_x,
|
912
|
+
graphic_y,
|
913
|
+
block_x,
|
914
|
+
block_y,
|
915
|
+
4
|
916
|
+
),
|
917
|
+
})
|
918
|
+
|
919
|
+
block_x = 0
|
920
|
+
block_y += 16
|
921
|
+
puts svg("text", {
|
922
|
+
"y" => graphic_y + block_y + block_size - 4,
|
923
|
+
"x" => graphic_x + block_x,
|
924
|
+
"font-family" => "monospace",
|
925
|
+
"font-size" => block_size,
|
926
|
+
"text-anchor" => "start",
|
927
|
+
}, lsn_min)
|
928
|
+
color_width = ((64.0 * block_size.to_f) / colors.size.to_f).round
|
929
|
+
colors.each do |color|
|
930
|
+
puts svg("rect", {
|
931
|
+
"y" => graphic_y + block_y + block_size,
|
932
|
+
"x" => graphic_x + block_x,
|
933
|
+
"width" => color_width,
|
934
|
+
"height" => block_size,
|
935
|
+
"fill" => "#" + color,
|
936
|
+
})
|
937
|
+
block_x += color_width
|
938
|
+
end
|
939
|
+
puts svg("text", {
|
940
|
+
"y" => graphic_y + block_y + block_size - 4,
|
941
|
+
"x" => graphic_x + block_x,
|
942
|
+
"font-family" => "monospace",
|
943
|
+
"font-size" => block_size,
|
944
|
+
"text-anchor" => "end",
|
945
|
+
}, lsn_max)
|
946
|
+
|
947
|
+
puts svg("text", {
|
948
|
+
"y" => graphic_y + block_y + block_size - 4,
|
949
|
+
"x" => graphic_x + (block_x / 2),
|
950
|
+
"font-family" => "monospace",
|
951
|
+
"font-weight" => "bold",
|
952
|
+
"font-size" => block_size,
|
953
|
+
"text-anchor" => "middle",
|
954
|
+
}, "LSN Age")
|
955
|
+
|
956
|
+
|
957
|
+
puts "</svg>\n"
|
958
|
+
end
|
959
|
+
|
618
960
|
def print_inode_summary(inode)
|
619
961
|
puts "INODE fseg_id=%d, pages=%d, frag=%d, full=%d, not_full=%d, free=%d" % [
|
620
962
|
inode.fseg_id,
|
@@ -1193,9 +1535,19 @@ The following modes are supported:
|
|
1193
1535
|
color and Unicode box drawing characters to show page usage throughout
|
1194
1536
|
the space.
|
1195
1537
|
|
1538
|
+
space-extents-illustrate-svg
|
1539
|
+
Iterate through all extents, illustrating the extent usage in SVG format
|
1540
|
+
printed to stdout to show page usage throughout the space.
|
1541
|
+
|
1196
1542
|
space-lsn-age-illustrate
|
1197
1543
|
Iterate through all pages, producing a heat map colored by the page LSN
|
1198
|
-
|
1544
|
+
using ANSI color and Unicode box drawing characters, allowing the user to
|
1545
|
+
get an overview of page modification recency.
|
1546
|
+
|
1547
|
+
space-lsn-age-illustrate-svg
|
1548
|
+
Iterate through all pages, producing a heat map colored by the page LSN
|
1549
|
+
producing SVG format output, allowing the user to get an overview of page
|
1550
|
+
modification recency.
|
1199
1551
|
|
1200
1552
|
space-inodes-summary
|
1201
1553
|
Iterate through all inodes, printing a short summary of each FSEG.
|
@@ -1468,8 +1820,12 @@ when "space-extents"
|
|
1468
1820
|
space_extents(space)
|
1469
1821
|
when "space-extents-illustrate"
|
1470
1822
|
space_extents_illustrate(space)
|
1823
|
+
when "space-extents-illustrate-svg"
|
1824
|
+
space_extents_illustrate_svg(space)
|
1471
1825
|
when "space-lsn-age-illustrate"
|
1472
1826
|
space_lsn_age_illustrate(space)
|
1827
|
+
when "space-lsn-age-illustrate-svg"
|
1828
|
+
space_lsn_age_illustrate_svg(space)
|
1473
1829
|
when "space-inodes-summary"
|
1474
1830
|
space_inodes_summary(space)
|
1475
1831
|
when "space-inodes-detail"
|
data/lib/innodb/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: innodb_ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.13
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2015-06-06 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bindata
|