innodb_ruby 0.9.12 → 0.9.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|