refactor: 문서 개선 중

This commit is contained in:
donghyeon-ka
2026-09-21 14:30:55 +09:00
parent c93cdea150
commit 805a18f486
1497 changed files with 525837 additions and 59152 deletions
@@ -10,19 +10,19 @@ PostgreSQL 의 fsync() 가 Guest Filesystem, Guest Block Layer, virtio-blk, QEMU
## Elements and evidence
- **PostgreSQL** (service): 필요한 시점에 fsync() 를 불러 영속성 경계까지 반영을 요청하는 게스트 프로세스. Evidence: L6742L6742, L6726L6734.
- **Guest Filesystem** (service): fsync() 요구를 처음 받는 게스트 파일시스템. Evidence: L6746L6746.
- **Guest Block Layer** (service): 요구를 FLUSH 등의 block 요청으로 바꾸는 계층. Evidence: L6749L6751.
- **virtio-blk** (service): 그 요청을 VM 경계 너머로 옮기는 게스트 driver. Evidence: L6753L6753.
- **QEMU / Backend** (service): 요청을 받아 호스트 쪽 파일 I/O 나 block I/O 로 잇는 자리. Evidence: L6756L6756, L6686L6686.
- **Host Storage Stack** (service): 호스트 Page Cache 와 파일시스템, Block Layer 가 놓인 구간. Evidence: L6759L6759, L6688L6692.
- **Physical Storage** (store): 요구가 여기까지 전달되어야 정전 이후 생존을 말할 수 있다. Evidence: L6762L6765, L6729L6729.
- **PostgreSQL** (service): 필요한 시점에 fsync() 를 불러 영속성 경계까지 반영을 요청하는 게스트 프로세스. Evidence: L6755L6755, L6739L6747.
- **Guest Filesystem** (service): fsync() 요구를 처음 받는 게스트 파일시스템. Evidence: L6759L6759.
- **Guest Block Layer** (service): 요구를 FLUSH 등의 block 요청으로 바꾸는 계층. Evidence: L6762L6764.
- **virtio-blk** (service): 그 요청을 VM 경계 너머로 옮기는 게스트 driver. Evidence: L6766L6766.
- **QEMU / Backend** (service): 요청을 받아 호스트 쪽 파일 I/O 나 block I/O 로 잇는 자리. Evidence: L6769L6769, L6699L6699.
- **Host Storage Stack** (service): 호스트 Page Cache 와 파일시스템, Block Layer 가 놓인 구간. Evidence: L6772L6772, L6701L6705.
- **Physical Storage** (store): 요구가 여기까지 전달되어야 정전 이후 생존을 말할 수 있다. Evidence: L6775L6778, L6742L6742.
## Relationships
- **PostgreSQL → Guest Filesystem:** fsync(). Evidence: L6744L6746.
- **Guest Filesystem → Guest Block Layer:** control. Evidence: L6746L6749.
- **Guest Block Layer → virtio-blk:** FLUSH 등. Evidence: L6751L6753.
- **virtio-blk → QEMU / Backend:** control. Evidence: L6753L6756.
- **QEMU / Backend → Host Storage Stack:** control. Evidence: L6756L6759.
- **Host Storage Stack → Physical Storage:** control. Evidence: L6759L6765.
- **PostgreSQL → Guest Filesystem:** fsync(). Evidence: L6757L6759.
- **Guest Filesystem → Guest Block Layer:** control. Evidence: L6759L6762.
- **Guest Block Layer → virtio-blk:** FLUSH 등. Evidence: L6764L6766.
- **virtio-blk → QEMU / Backend:** control. Evidence: L6766L6769.
- **QEMU / Backend → Host Storage Stack:** control. Evidence: L6769L6772.
- **Host Storage Stack → Physical Storage:** control. Evidence: L6772L6778.
@@ -0,0 +1,18 @@
digraph techviz {
graph [rankdir=TB, splines=ortho, nodesep=0.55, ranksep=0.85];
node [fontname=Helvetica, fontsize=11, margin="0.18,0.12", style="rounded,filled", fillcolor=white, color="#2d4357", penwidth=1.5];
edge [fontname=Helvetica, fontsize=10, color="#364b5f", penwidth=1.4, arrowsize=0.75];
n0 [label="PostgreSQL", shape=box, style="rounded,filled"];
n1 [label="Guest Filesystem", shape=box, style="rounded,filled"];
n2 [label="Guest Block Layer", shape=box, style="rounded,filled"];
n3 [label="virtio-blk", shape=box, style="rounded,filled"];
n4 [label="QEMU / Backend", shape=box, style="rounded,filled"];
n5 [label="Host Storage Stack", shape=box, style="rounded,filled"];
n6 [label="Physical Storage", shape=box, style="rounded,filled"];
n0 -> n1 [label="fsync()", style=solid];
n1 -> n2 [label="", style=solid];
n2 -> n3 [label="FLUSH 등", style=solid];
n3 -> n4 [label="", style=solid];
n4 -> n5 [label="", style=solid];
n5 -> n6 [label="", style=solid];
}
@@ -1,59 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<mxfile host="app.diagrams.net" modified="2026-07-23T00:00:00.000Z" agent="techviz-harness" version="24.7.17" type="device">
<diagram id="write-completion-boundaries" name="fsync() 의 요구가 물리 storage 까지 내려가는 사슬">
<mxGraphModel dx="680" dy="1153" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<mxGraphModel dx="680" dy="2127" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="2127" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="n_postgresql" value="PostgreSQL&lt;br/&gt;write()&lt;br/&gt;fsync()" tooltip="필요한 시점에 fsync() 를 불러 영속성 경계까지 반영을 요청하는 게스트 프로세스. | Evidence: L6742-L6742, L6726-L6734" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="75.0" y="60.0" width="150.0" height="88.0" as="geometry"/>
<mxCell id="n_postgresql" value="PostgreSQL&lt;br/&gt;write()&lt;br/&gt;fsync()" tooltip="필요한 시점에 fsync() 를 불러 영속성 경계까지 반영을 요청하는 게스트 프로세스. | Evidence: L6755-L6755, L6739-L6747" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="35.0" y="145.0" width="150.0" height="88.0" as="geometry"/>
</mxCell>
<mxCell id="n_guest-filesystem" value="Guest Filesystem" tooltip="fsync() 요구를 처음 받는 게스트 파일시스템. | Evidence: L6746-L6746" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="75.0" y="244.0" width="150.0" height="64.0" as="geometry"/>
<mxCell id="n_guest-filesystem" value="Guest Filesystem" tooltip="fsync() 요구를 처음 받는 게스트 파일시스템. | Evidence: L6759-L6759" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="47.0" y="455.0" width="150.0" height="64.0" as="geometry"/>
</mxCell>
<mxCell id="n_guest-block-layer" value="Guest Block Layer" tooltip="요구를 FLUSH 등의 block 요청으로 바꾸는 계층. | Evidence: L6749-L6751" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="73.5" y="404.0" width="153.0" height="64.0" as="geometry"/>
<mxCell id="n_guest-block-layer" value="Guest Block Layer" tooltip="요구를 FLUSH 등의 block 요청으로 바꾸는 계층. | Evidence: L6762-L6764" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="47.0" y="765.0" width="153.0" height="64.0" as="geometry"/>
</mxCell>
<mxCell id="n_virtio-blk" value="virtio-blk" tooltip="그 요청을 VM 경계 너머로 옮기는 게스트 driver. | Evidence: L6753-L6753" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="75.0" y="564.0" width="150.0" height="64.0" as="geometry"/>
<mxCell id="n_virtio-blk" value="virtio-blk" tooltip="그 요청을 VM 경계 너머로 옮기는 게스트 driver. | Evidence: L6766-L6766" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="47.0" y="1078.0" width="150.0" height="64.0" as="geometry"/>
</mxCell>
<mxCell id="n_qemu-backend" value="QEMU / Backend" tooltip="요청을 받아 호스트 쪽 파일 I/O 나 block I/O 로 잇는 자리. | Evidence: L6756-L6756, L6686-L6686" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="75.0" y="724.0" width="150.0" height="64.0" as="geometry"/>
<mxCell id="n_qemu-backend" value="QEMU / Backend" tooltip="요청을 받아 호스트 쪽 파일 I/O 나 block I/O 로 잇는 자리. | Evidence: L6769-L6769, L6699-L6699" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="47.0" y="1388.0" width="150.0" height="64.0" as="geometry"/>
</mxCell>
<mxCell id="n_host-storage-stack" value="Host Storage Stack" tooltip="호스트 Page Cache 와 파일시스템, Block Layer 가 놓인 구간. | Evidence: L6759-L6759, L6688-L6692" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="70.0" y="884.0" width="160.0" height="64.0" as="geometry"/>
<mxCell id="n_host-storage-stack" value="Host Storage Stack" tooltip="호스트 Page Cache 와 파일시스템, Block Layer 가 놓인 구간. | Evidence: L6772-L6772, L6701-L6705" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="47.0" y="1698.0" width="160.0" height="64.0" as="geometry"/>
</mxCell>
<mxCell id="n_physical-storage" value="Physical Storage" tooltip="요구가 여기까지 전달되어야 정전 이후 생존을 말할 수 있다. | Evidence: L6762-L6765, L6729-L6729" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
<mxGeometry x="75.0" y="1044.0" width="150.0" height="64.0" as="geometry"/>
<mxCell id="n_physical-storage" value="Physical Storage" tooltip="요구가 여기까지 전달되어야 정전 이후 생존을 말할 수 있다. | Evidence: L6775-L6778, L6742-L6742" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
<mxGeometry x="47.0" y="2018.0" width="150.0" height="64.0" as="geometry"/>
</mxCell>
<mxCell id="e_app-to-guest-fs" value="fsync()" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_postgresql" target="n_guest-filesystem">
<mxGeometry relative="1" as="geometry">
<mxPoint x="174.0" y="196.0" as="offset"/>
<mxPoint x="116.0" y="316.0" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_guest-fs-to-block-layer" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_guest-filesystem" target="n_guest-block-layer">
<mxGeometry relative="1" as="geometry">
<mxPoint x="174.0" y="356.0" as="offset"/>
<mxPoint x="122.8" y="614.0" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_block-layer-to-virtio" value="FLUSH 등" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_guest-block-layer" target="n_virtio-blk">
<mxGeometry relative="1" as="geometry">
<mxPoint x="174.0" y="516.0" as="offset"/>
<mxPoint x="122.8" y="925.5" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_virtio-to-qemu" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_virtio-blk" target="n_qemu-backend">
<mxGeometry relative="1" as="geometry">
<mxPoint x="174.0" y="676.0" as="offset"/>
<mxPoint x="146.0" y="1265.0" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_qemu-to-host-stack" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_qemu-backend" target="n_host-storage-stack">
<mxGeometry relative="1" as="geometry">
<mxPoint x="174.0" y="836.0" as="offset"/>
<mxPoint x="124.5" y="1547.0" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_host-stack-to-physical" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_host-storage-stack" target="n_physical-storage">
<mxGeometry relative="1" as="geometry">
<mxPoint x="174.0" y="996.0" as="offset"/>
<mxPoint x="124.5" y="1862.0" as="offset"/>
</mxGeometry>
</mxCell>
</root>
@@ -6,10 +6,10 @@
{
"id": "edge-app-to-guest-fs",
"type": "arrow",
"x": 150.0,
"y": 148.0,
"width": 0.0,
"height": 96.0,
"x": 110.0,
"y": 233.0,
"width": 12.0,
"height": 222.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
@@ -37,15 +37,15 @@
],
[
0.0,
48.0
111.0
],
[
0.0,
48.0
12.0,
111.0
],
[
0.0,
96.0
12.0,
222.0
]
],
"lastCommittedPoint": null,
@@ -66,8 +66,8 @@
{
"id": "edge-label-app-to-guest-fs",
"type": "text",
"x": 129.0,
"y": 184.0,
"x": 71.0,
"y": 304.0,
"width": 90,
"height": 24,
"angle": 0,
@@ -105,10 +105,10 @@
{
"id": "edge-guest-fs-to-block-layer",
"type": "arrow",
"x": 150.0,
"y": 308.0,
"width": 0.0,
"height": 96.0,
"x": 122.0,
"y": 519.0,
"width": 1.5,
"height": 246.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
@@ -136,15 +136,15 @@
],
[
0.0,
48.0
123.0
],
[
0.0,
48.0
1.5,
123.0
],
[
0.0,
96.0
1.5,
246.0
]
],
"lastCommittedPoint": null,
@@ -165,10 +165,10 @@
{
"id": "edge-block-layer-to-virtio",
"type": "arrow",
"x": 150.0,
"y": 468.0,
"width": 0.0,
"height": 96.0,
"x": 122.0,
"y": 829.0,
"width": 1.5,
"height": 249.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
@@ -191,20 +191,20 @@
"locked": false,
"points": [
[
0.0,
1.5,
0.0
],
[
0.0,
48.0
1.5,
124.5
],
[
0.0,
48.0
124.5
],
[
0.0,
96.0
249.0
]
],
"lastCommittedPoint": null,
@@ -225,8 +225,8 @@
{
"id": "edge-label-block-layer-to-virtio",
"type": "text",
"x": 129.0,
"y": 504.0,
"x": 77.75,
"y": 913.5,
"width": 90,
"height": 24,
"angle": 0,
@@ -264,10 +264,10 @@
{
"id": "edge-virtio-to-qemu",
"type": "arrow",
"x": 150.0,
"y": 628.0,
"x": 122.0,
"y": 1142.0,
"width": 0.0,
"height": 96.0,
"height": 246.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
@@ -295,15 +295,15 @@
],
[
0.0,
48.0
123.0
],
[
0.0,
48.0
123.0
],
[
0.0,
96.0
246.0
]
],
"lastCommittedPoint": null,
@@ -324,10 +324,10 @@
{
"id": "edge-qemu-to-host-stack",
"type": "arrow",
"x": 150.0,
"y": 788.0,
"width": 0.0,
"height": 96.0,
"x": 122.0,
"y": 1452.0,
"width": 5.0,
"height": 246.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
@@ -355,15 +355,15 @@
],
[
0.0,
48.0
123.0
],
[
0.0,
48.0
5.0,
123.0
],
[
0.0,
96.0
5.0,
246.0
]
],
"lastCommittedPoint": null,
@@ -384,10 +384,10 @@
{
"id": "edge-host-stack-to-physical",
"type": "arrow",
"x": 150.0,
"y": 948.0,
"width": 0.0,
"height": 96.0,
"x": 122.0,
"y": 1762.0,
"width": 5.0,
"height": 256.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
@@ -410,20 +410,20 @@
"locked": false,
"points": [
[
0.0,
5.0,
0.0
],
[
0.0,
48.0
5.0,
128.0
],
[
0.0,
48.0
128.0
],
[
0.0,
96.0
256.0
]
],
"lastCommittedPoint": null,
@@ -444,8 +444,8 @@
{
"id": "node-postgresql",
"type": "rectangle",
"x": 75.0,
"y": 60.0,
"x": 35.0,
"y": 145.0,
"width": 150.0,
"height": 88.0,
"angle": 0,
@@ -474,8 +474,8 @@
{
"id": "node-label-postgresql",
"type": "text",
"x": 85.0,
"y": 70.0,
"x": 45.0,
"y": 155.0,
"width": 130.0,
"height": 68.0,
"angle": 0,
@@ -513,8 +513,8 @@
{
"id": "node-guest-filesystem",
"type": "rectangle",
"x": 75.0,
"y": 244.0,
"x": 47.0,
"y": 455.0,
"width": 150.0,
"height": 64.0,
"angle": 0,
@@ -543,8 +543,8 @@
{
"id": "node-label-guest-filesystem",
"type": "text",
"x": 85.0,
"y": 254.0,
"x": 57.0,
"y": 465.0,
"width": 130.0,
"height": 44.0,
"angle": 0,
@@ -582,8 +582,8 @@
{
"id": "node-guest-block-layer",
"type": "rectangle",
"x": 73.5,
"y": 404.0,
"x": 47.0,
"y": 765.0,
"width": 153.0,
"height": 64.0,
"angle": 0,
@@ -612,8 +612,8 @@
{
"id": "node-label-guest-block-layer",
"type": "text",
"x": 83.5,
"y": 414.0,
"x": 57.0,
"y": 775.0,
"width": 133.0,
"height": 44.0,
"angle": 0,
@@ -651,8 +651,8 @@
{
"id": "node-virtio-blk",
"type": "rectangle",
"x": 75.0,
"y": 564.0,
"x": 47.0,
"y": 1078.0,
"width": 150.0,
"height": 64.0,
"angle": 0,
@@ -681,8 +681,8 @@
{
"id": "node-label-virtio-blk",
"type": "text",
"x": 85.0,
"y": 574.0,
"x": 57.0,
"y": 1088.0,
"width": 130.0,
"height": 44.0,
"angle": 0,
@@ -720,8 +720,8 @@
{
"id": "node-qemu-backend",
"type": "rectangle",
"x": 75.0,
"y": 724.0,
"x": 47.0,
"y": 1388.0,
"width": 150.0,
"height": 64.0,
"angle": 0,
@@ -750,8 +750,8 @@
{
"id": "node-label-qemu-backend",
"type": "text",
"x": 85.0,
"y": 734.0,
"x": 57.0,
"y": 1398.0,
"width": 130.0,
"height": 44.0,
"angle": 0,
@@ -789,8 +789,8 @@
{
"id": "node-host-storage-stack",
"type": "rectangle",
"x": 70.0,
"y": 884.0,
"x": 47.0,
"y": 1698.0,
"width": 160.0,
"height": 64.0,
"angle": 0,
@@ -819,8 +819,8 @@
{
"id": "node-label-host-storage-stack",
"type": "text",
"x": 80.0,
"y": 894.0,
"x": 57.0,
"y": 1708.0,
"width": 140.0,
"height": 44.0,
"angle": 0,
@@ -858,8 +858,8 @@
{
"id": "node-physical-storage",
"type": "rectangle",
"x": 75.0,
"y": 1044.0,
"x": 47.0,
"y": 2018.0,
"width": 150.0,
"height": 64.0,
"angle": 0,
@@ -888,8 +888,8 @@
{
"id": "node-label-physical-storage",
"type": "text",
"x": 85.0,
"y": 1054.0,
"x": 57.0,
"y": 2028.0,
"width": 130.0,
"height": 44.0,
"angle": 0,
@@ -2,30 +2,41 @@
"harness_version": "0.2.0",
"spec_id": "write-completion-boundaries",
"spec_version": "1.1",
"spec_sha256": "c7838bc8393b43c94ed4628db350f0fb26e90fc0d566201e471d49d533963699",
"spec_sha256": "8d44da349d9a7266196589b928fc15554c3e3b25fcf10e94f6f5f71a8cd8a39b",
"source_context": {
"document": "docs/virtualization/final/document.md",
"document_sha256": "181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd",
"document_sha256": "8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210",
"anchor": {
"kind": "heading",
"value": "150. `fsync()`가 필요한 이유",
"line": 6723
"line": 6736
}
},
"outputs": [
"write-completion-boundaries.svg",
"write-completion-boundaries.drawio",
"write-completion-boundaries.mmd",
"write-completion-boundaries.d2",
"write-completion-boundaries.dot",
"write-completion-boundaries.drawio",
"write-completion-boundaries.excalidraw",
"write-completion-boundaries.alt.md"
],
"lint_issue_count": 4,
"lint_issue_count": 5,
"assumption_count": 0,
"assumptions_allowed": false,
"composition_profile": "component-flow",
"reference_ids": [
"payment-event-flow"
],
"diagram_only": true
"diagram_only": true,
"source_spec_file_sha256": "bb567101fd18f99abd2bcd62de04ee8b9d6ab54c20ffbf1ee681daab73219a72",
"output_sha256": {
"write-completion-boundaries.svg": "c78624a9b2ee8116f73a412d52ee4fe0dda725c90e7df83d726be3a5a36be3fd",
"write-completion-boundaries.mmd": "e7642e0fc2a3b9946e471c5993218257b4aca33749521ede6ac80012c8f3981c",
"write-completion-boundaries.d2": "ad2f18856ec2c98b1c9a72fa5e7a7db65c1732e480687b15b8ed0a54416b2d9c",
"write-completion-boundaries.dot": "72373f45393d43098daec116f4373d8fe2e5473ae5bc5775c159447877c14075",
"write-completion-boundaries.drawio": "cc592ec929c1e2883309acccafac5d8c9cf566cf78fb4ff86b4542feee810a74",
"write-completion-boundaries.excalidraw": "c75a2368d625125477666b85b8305e348a06541ffe5aaf6653fddd8e217b8358",
"write-completion-boundaries.alt.md": "c14e7bb4da2acaa2e39a584d363750cdf2f4ed79ed8d55bb0c4efe6c77aa230c"
}
}
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="680" height="1153" viewBox="0 0 680 1153" role="img" aria-labelledby="diagram-title diagram-description">
<svg xmlns="http://www.w3.org/2000/svg" width="680" height="2127" viewBox="0 0 680 2127" role="img" aria-labelledby="diagram-title diagram-description">
<title id="diagram-title">fsync() 의 요구가 물리 storage 까지 내려가는 사슬</title>
<desc id="diagram-description">위에서 아래로 읽는다. 맨 위 PostgreSQL 이 fsync() 를 부르고 그 요구가 Guest Filesystem 으로 내려간다. Guest Block Layer 에서 FLUSH 등의 요청으로 바뀌고, virtio-blk 를 지나 VM 경계를 넘어 QEMU / Backend 로 간다. 거기서 Host Storage Stack 을 지나 맨 아래 Physical Storage 까지 그 의미가 전달되어야 완료가 성립한다. 여섯 번 손이 바뀌는 동안 한 곳이라도 그 의미를 지키지 않으면 게스트가 받은 완료 응답이 거짓이 된다. write() 완료와 writeback 완료, fsync/flush 완료, 전원 장애에도 안전한 durability 가 서로 다르다는 구분은 본문의 코드블록이 맡는다.</desc>
<metadata>{&quot;techviz&quot;:{&quot;spec_version&quot;:&quot;1.1&quot;,&quot;id&quot;:&quot;write-completion-boundaries&quot;,&quot;profile&quot;:&quot;component-flow&quot;},&quot;source_context&quot;:{&quot;document&quot;:&quot;docs/virtualization/final/document.md&quot;,&quot;document_sha256&quot;:&quot;181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd&quot;,&quot;anchor&quot;:{&quot;kind&quot;:&quot;heading&quot;,&quot;value&quot;:&quot;150. `fsync()`가 필요한 이유&quot;,&quot;line&quot;:6723}},&quot;evidence_policy&quot;:&quot;Each factual element cites source lines or is marked assumption.&quot;,&quot;diagram_only&quot;:true}</metadata>
<metadata>{&quot;techviz&quot;:{&quot;spec_version&quot;:&quot;1.1&quot;,&quot;id&quot;:&quot;write-completion-boundaries&quot;,&quot;profile&quot;:&quot;component-flow&quot;},&quot;source_context&quot;:{&quot;document&quot;:&quot;docs/virtualization/final/document.md&quot;,&quot;document_sha256&quot;:&quot;8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210&quot;,&quot;anchor&quot;:{&quot;kind&quot;:&quot;heading&quot;,&quot;value&quot;:&quot;150. `fsync()`가 필요한 이유&quot;,&quot;line&quot;:6736}},&quot;evidence_policy&quot;:&quot;Each factual element cites source lines or is marked assumption.&quot;,&quot;diagram_only&quot;:true}</metadata>
<defs>
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" />
@@ -49,46 +49,46 @@
.timeline-detail { font-size: 11px; fill: #4b5563; text-anchor: middle; }
</style>
</defs>
<rect class="canvas" width="680" height="1153" />
<polyline class="edge kind-control style-solid emphasis-normal" points="150.0,148.0 150.0,196.0 150.0,196.0 150.0,244.0" data-evidence="6744-6746" />
<rect class="edge-label-bg" x="141.6" y="182.0" width="64.9" height="22" rx="3" />
<text class="edge-label" x="174.0" y="197.0">fsync()</text>
<polyline class="edge kind-control style-solid emphasis-normal" points="150.0,308.0 150.0,356.0 150.0,356.0 150.0,404.0" data-evidence="6746-6749" />
<polyline class="edge kind-control style-solid emphasis-normal" points="150.0,468.0 150.0,516.0 150.0,516.0 150.0,564.0" data-evidence="6751-6753" />
<rect class="edge-label-bg" x="141.6" y="502.0" width="64.9" height="22" rx="3" />
<text class="edge-label" x="174.0" y="517.0">FLUSH 등</text>
<polyline class="edge kind-control style-solid emphasis-normal" points="150.0,628.0 150.0,676.0 150.0,676.0 150.0,724.0" data-evidence="6753-6756" />
<polyline class="edge kind-control style-solid emphasis-normal" points="150.0,788.0 150.0,836.0 150.0,836.0 150.0,884.0" data-evidence="6756-6759" />
<polyline class="edge kind-control style-solid emphasis-normal" points="150.0,948.0 150.0,996.0 150.0,996.0 150.0,1044.0" data-evidence="6759-6765" />
<rect class="canvas" width="680" height="2127" />
<polyline class="edge kind-control style-solid emphasis-normal" points="110.0,233.0 110.0,344.0 122.0,344.0 122.0,455.0" data-evidence="6757-6759" />
<rect class="edge-label-bg" x="83.5" y="302.0" width="64.9" height="22" rx="3" />
<text class="edge-label" x="116.0" y="317.0">fsync()</text>
<polyline class="edge kind-control style-solid emphasis-normal" points="122.0,519.0 122.0,642.0 123.5,642.0 123.5,765.0" data-evidence="6759-6762" />
<polyline class="edge kind-control style-solid emphasis-normal" points="123.5,829.0 123.5,953.5 122.0,953.5 122.0,1078.0" data-evidence="6764-6766" />
<rect class="edge-label-bg" x="90.3" y="911.5" width="64.9" height="22" rx="3" />
<text class="edge-label" x="122.8" y="926.5">FLUSH 등</text>
<polyline class="edge kind-control style-solid emphasis-normal" points="122.0,1142.0 122.0,1265.0 122.0,1265.0 122.0,1388.0" data-evidence="6766-6769" />
<polyline class="edge kind-control style-solid emphasis-normal" points="122.0,1452.0 122.0,1575.0 127.0,1575.0 127.0,1698.0" data-evidence="6769-6772" />
<polyline class="edge kind-control style-solid emphasis-normal" points="127.0,1762.0 127.0,1890.0 122.0,1890.0 122.0,2018.0" data-evidence="6772-6778" />
<g id="node-postgresql">
<rect class="node-shape kind-service emphasis-normal role-source" data-evidence="6742-6742,6726-6734" x="75.0" y="60.0" width="150.0" height="88.0" rx="7" />
<text class="node-label" x="150.0" y="87.0">PostgreSQL</text>
<line class="node-detail-divider" x1="89.0" y1="108.0" x2="211.0" y2="108.0" />
<text class="node-detail" x="91.0" y="125.0">write()</text>
<text class="node-detail" x="91.0" y="141.0">fsync()</text>
<rect class="node-shape kind-service emphasis-normal role-source" data-evidence="6755-6755,6739-6747" x="35.0" y="145.0" width="150.0" height="88.0" rx="7" />
<text class="node-label" x="110.0" y="172.0">PostgreSQL</text>
<line class="node-detail-divider" x1="49.0" y1="193.0" x2="171.0" y2="193.0" />
<text class="node-detail" x="51.0" y="210.0">write()</text>
<text class="node-detail" x="51.0" y="226.0">fsync()</text>
</g>
<g id="node-guest-filesystem">
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="6746-6746" x="75.0" y="244.0" width="150.0" height="64.0" rx="7" />
<text class="node-label" x="150.0" y="274.0">Guest Filesystem</text>
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="6759-6759" x="47.0" y="455.0" width="150.0" height="64.0" rx="7" />
<text class="node-label" x="122.0" y="485.0">Guest Filesystem</text>
</g>
<g id="node-guest-block-layer">
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="6749-6751" x="73.5" y="404.0" width="153.0" height="64.0" rx="7" />
<text class="node-label" x="150.0" y="434.0">Guest Block Layer</text>
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="6762-6764" x="47.0" y="765.0" width="153.0" height="64.0" rx="7" />
<text class="node-label" x="123.5" y="795.0">Guest Block Layer</text>
</g>
<g id="node-virtio-blk">
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="6753-6753" x="75.0" y="564.0" width="150.0" height="64.0" rx="7" />
<text class="node-label" x="150.0" y="594.0">virtio-blk</text>
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="6766-6766" x="47.0" y="1078.0" width="150.0" height="64.0" rx="7" />
<text class="node-label" x="122.0" y="1108.0">virtio-blk</text>
</g>
<g id="node-qemu-backend">
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="6756-6756,6686-6686" x="75.0" y="724.0" width="150.0" height="64.0" rx="7" />
<text class="node-label" x="150.0" y="754.0">QEMU / Backend</text>
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="6769-6769,6699-6699" x="47.0" y="1388.0" width="150.0" height="64.0" rx="7" />
<text class="node-label" x="122.0" y="1418.0">QEMU / Backend</text>
</g>
<g id="node-host-storage-stack">
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="6759-6759,6688-6692" x="70.0" y="884.0" width="160.0" height="64.0" rx="7" />
<text class="node-label" x="150.0" y="914.0">Host Storage Stack</text>
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="6772-6772,6701-6705" x="47.0" y="1698.0" width="160.0" height="64.0" rx="7" />
<text class="node-label" x="127.0" y="1728.0">Host Storage Stack</text>
</g>
<g id="node-physical-storage">
<rect class="node-shape kind-store emphasis-primary role-sink" data-evidence="6762-6765,6729-6729" x="75.0" y="1044.0" width="150.0" height="64.0" rx="7" />
<text class="node-label" x="150.0" y="1074.0">Physical Storage</text>
<rect class="node-shape kind-store emphasis-primary role-sink" data-evidence="6775-6778,6742-6742" x="47.0" y="2018.0" width="150.0" height="64.0" rx="7" />
<text class="node-label" x="122.0" y="2048.0">Physical Storage</text>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB