in gui/frontend/src/modules/db-editor/PerformanceDashboard.tsx [768:983]
private renderInnoDBStatus(gridColumn: number): ComponentChild[] {
const { graphData } = this.state;
const colors = colorSchemes.get(graphData.activeColorScheme)!;
const innoDBBufferPoolUsage = graphData.computedValues.innoDBBufferPoolUsage;
const innoDBBufferReads = graphData.computedValues.innoDBBufferReads;
const innoDBBufferWrites = graphData.computedValues.innoDBBufferWrites;
const innoDBBufferDiskReads = graphData.computedValues.innoDBBufferDiskReads;
const innoDBRedoLogDataWritten = graphData.computedValues.innoDBRedoLogDataWritten;
const innoDBRedoLogWrites = graphData.computedValues.innoDBRedoLogWrites;
const innoDBDoubleWriteBufferWrites = graphData.computedValues.innoDBDoubleWriteBufferWrites;
const innoDBDataWritten = graphData.computedValues.innoDBDataWritten;
const innoDBDataRead = graphData.computedValues.innoDBDataRead;
const checkpointAge = graphData.computedValues.checkpointAge;
const innoDBBufferReadRatio = graphData.computedValues.innoDBBufferReadRatio;
const innoDBDiskWritesData = graphData.series.get("innoDBDiskWritesData") ?? [];
const innoDBDiskReadsData = graphData.series.get("innoDBDiskReadsData") ?? [];
const bufferPoolGraphOptions: IGraphOptions = {
viewport: { left: 0, top: 0, width: 400, height: 300 },
series: [
{
id: "innoDBStatus1",
type: "pie",
radius: [60, 130],
showValues: false,
rotation: "0deg",
colors: [colors[Color.PieValue], colors[Color.PieNoValue]],
transformation: { x: "50%", y: "50%", width: 400, height: 300 },
tooltip: this.pieTooltipPercent,
data: [
{ name: "Buffer Pool Usage", value: innoDBBufferPoolUsage < 0 ? 0 : innoDBBufferPoolUsage },
{ name: "Unused", value: innoDBBufferPoolUsage < 0 ? 0 : 1 - innoDBBufferPoolUsage },
],
},
],
};
// A value < 0 indicates that no value has been read yet. Start with all 0 allow an animation when
// values arrive.
let sync = checkpointAge < 0 ? 0 : 0.125;
let async = checkpointAge < 0 ? 0 : 0.125;
let available = checkpointAge < 0 ? 0 : 1 - checkpointAge - 0.25;
if (available < 0) {
async += available;
available = 0;
}
if (async < 0) {
sync += async;
async = 0;
}
const checkpointAgeGraphOptions: IGraphOptions = {
viewport: { left: 0, top: 0, width: 400, height: 300 },
series: [
{
id: "innoDBStatus2",
type: "pie",
radius: [60, 130],
showValues: false,
colors: [colors[0], colors[1], colors[3], colors[5]],
transformation: { x: "50%", y: "50%", width: 400, height: 300 },
tooltip: this.pieTooltipPercent,
data: [
{ name: "Checkpoint Age", value: checkpointAge < 0 ? 0 : checkpointAge },
{ name: "Available Range", value: available },
{ name: "Async Flush Range", value: async },
{ name: "Sync Flush Range", value: sync },
],
},
],
};
const diskReadRatioGraphOptions: IGraphOptions = {
viewport: { left: 0, top: 0, width: 400, height: 300 },
series: [
{
id: "innoDBStatus3",
type: "pie",
borderRadius: 8,
radius: [60, 130],
showValues: false,
colors: [colors[Color.PieValue], colors[Color.PieNoValue]],
transformation: { x: "50%", y: "50%", width: 400, height: 300 },
tooltip: this.pieTooltipPercent,
data: [
{ name: "Disk Reads", value: innoDBBufferReadRatio < 0 ? 0 : innoDBBufferReadRatio },
{ name: "Memory Reads", value: innoDBBufferReadRatio < 0 ? 0 : 1 - innoDBBufferReadRatio },
],
},
],
};
const timestamp = new Date().getTime();
const xDomain: [number, number] = [
timestamp - PerformanceDashboard.sampleInterval * graphData.displayInterval,
timestamp,
];
const diskWritesGraphOptions: IGraphOptions = {
viewport: { left: 0, top: 0, width: 400, height: 300 },
series: [
{
id: "innoDBStatus4",
type: "line",
strokeWidth: 2,
colors: [colors[Color.Sending]],
marginLeft: 80,
xDomain,
yFormat: this.formatTrafficValue,
yDomain: this.findYDomainValues(innoDBDiskWritesData, 0),
curve: "Linear",
yTickCount: 6,
tooltip: this.trafficTooltip,
transformation: { x: 0, y: 0, width: 400, height: 300 },
data: innoDBDiskWritesData,
},
],
};
const diskReadsGraphOptions: IGraphOptions = {
viewport: { left: 0, top: 0, width: 400, height: 300 },
series: [
{
id: "innoDBStatus5",
type: "line",
strokeWidth: 2,
colors: [colors[Color.Receiving]],
marginLeft: 80,
xDomain,
yFormat: this.formatTrafficValue,
yDomain: this.findYDomainValues(innoDBDiskReadsData, 0),
curve: "Linear",
yTickCount: 6,
tooltip: this.trafficTooltip,
transformation: { x: 0, y: 0, width: 400, height: 300 },
data: innoDBDiskReadsData,
},
],
};
const cells: ComponentChild[] = [];
cells.push(
<GridCell
className="title"
orientation={Orientation.TopDown}
style={{ gridColumn, gridRow: 1 }}
crossAlignment={ContentAlignment.Center}
>
<Icon className="sectionIcon" src={Assets.db.databaseEngineIcon} />
<Label>InnoDB Status</Label>
<Label>
Overview of the InnoDB buffer pool and disk activity generated by the InnoDB storage engine.
</Label>
</GridCell>,
<GridCell orientation={Orientation.TopDown} style={{ gridColumn, gridRow: 2 }}>
<Grid columns={2} rowGap={12} equalHeight={true} style={{ marginBottom: "8px" }}>
<GridCell orientation={Orientation.TopDown} columnSpan={2} style={{ padding: "0 25%" }}>
<Label className="pieTitle">InnoDB Buffer Pool</Label>
<GraphHost
id="bufferPoolGraph"
options={bufferPoolGraphOptions}
/>
</GridCell>
<GridCell orientation={Orientation.TopDown}>
<Label className="pieTitle">Checkpoint Age</Label>
<GraphHost
id="threadsGraph"
options={checkpointAgeGraphOptions}
/>
</GridCell>
<GridCell orientation={Orientation.TopDown}>
<Label className="pieTitle">Disk Read Ratio</Label>
<GraphHost
id="openFilesGraph"
options={diskReadRatioGraphOptions}
/>
</GridCell>
</Grid>
{this.renderNameValuePair("Read Requests", `${innoDBBufferReads.toFixed(0)} pages/s`,
MarkerType.Incoming, "The number of logical read requests InnoDB has done to the buffer pool.")}
{this.renderNameValuePair("Write Requests", `${innoDBBufferWrites.toFixed(0)} pages/s`,
MarkerType.Outgoing, "The number of logical write requests InnoDB has done to the buffer pool.")}
{this.renderNameValuePair("Disk Reads", `${innoDBBufferDiskReads.toFixed(0)} #/s`, MarkerType.Incoming,
"The number of logical reads that InnoDB could not satisfy from the buffer " +
"pool, and had to read directly from the disk.")}
</GridCell>,
<GridCell orientation={Orientation.TopDown} style={{ gridColumn, gridRow: 3 }}>
<Label className="subTitle">InnoDB Disk Writes</Label>
<GraphHost
options={diskWritesGraphOptions}
/>
{this.renderNameValuePair("Log data written", this.formatTrafficValue(innoDBRedoLogDataWritten),
MarkerType.Outgoing, "The number of bytes written to the InnoDB redo log files.")}
{this.renderNameValuePair("Log writes", `${innoDBRedoLogWrites.toFixed(0)} #/s`, MarkerType.Outgoing,
"The number of physical writes to the InnoDB redo log file.")}
{this.renderNameValuePair("Writing", this.formatTrafficValue(innoDBDataWritten), MarkerType.Incoming,
"Total amount of data in bytes written in file operations by the InnoDB storage engine.")}
</GridCell>,
<GridCell orientation={Orientation.TopDown} style={{ gridColumn, gridRow: 4 }}>
<Label className="subTitle">InnoDB Disk Reads</Label>
<GraphHost
options={diskReadsGraphOptions}
/>
{this.renderNameValuePair("Buffer Writes", this.formatTrafficValue(innoDBDoubleWriteBufferWrites),
MarkerType.Outgoing, "The number of double-write operations that have been performed.")}
{this.renderNameValuePair("Reading", this.formatTrafficValue(innoDBDataRead), MarkerType.Incoming,
"Total amount of data in bytes read in file operations by the InnoDB storage engine.")}
</GridCell>,
);
return cells;
}