symfonic.memory.backends.postgres_erase_chunks¶
postgres_erase_chunks ¶
One keyset chunk of a durable native erase job (CORE-199 S3).
A claims-phase job's graph content is already gone: either it left with the
job's first transaction, or content chunks (postgres_erase_content) erased
it before the job reached this phase. A permanent job with the opt-in vector
phase continues to vector chunks after claims. Each chunk is its own transaction
on the eraser's connection and erases at most CHUNK_BUDGET claims:
SELECT ... FOR UPDATEon the job row serializes resumers. A second resumer waits, then re-reads the row as the first left it: the advanced cursor, or no row once the first completed the job. No chunk is erased twice and none is skipped.- The read seeks
(scope_path, token)after the persisted cursor through the keyset index, so dead entries earlier chunks left behind are never revisited, however old a snapshot keeps them from being pruned. - The delete names tokens only and re-checks the range on what it erased; any claim that moved or vanished in between refuses and rolls the chunk back, cursor included.
- The cursor advances in the same commit. A crash after commit resumes from it; a crash before commit leaves cursor and claims as they were.
A chunk that reads fewer than the budget has reached the end of the range. Ordinary jobs delete the job and write a digest-only receipt in that commit. An opted-in permanent job moves to vector chunks and stays fenced permanently. Completion independently proves physical absence before certifying its receipt. No new claim can enter the range behind the cursor: every native writer and claim reader refuses under an erasing job (S1), checked after its memory_nodes lock, and the job committed under EXCLUSIVE, before or together with the content erase. A writer still running pre-S1 code is the exception, and only the operator's fleet barrier excludes it.
Chunk transactions take no table lock beyond ROW EXCLUSIVE on the claims, so another tenant's writes never wait on them.
advance
async
¶
Erase one chunk; True once complete, False while more remain, None if unknown.
Source code in src/symfonic/memory/backends/postgres_erase_chunks.py
keyset_sql ¶
The chunk read; tests EXPLAIN this exact text.
Source code in src/symfonic/memory/backends/postgres_erase_chunks.py
step
async
¶
step(conn: Any, jobs: str, receipts: str, claims: str, job_id: str, key: bytes, receipt_authority: Any = None) -> tuple[bool | None, str | None]
advance, plus the phase the chunk ran in (None for an unknown job).
Source code in src/symfonic/memory/backends/postgres_erase_chunks.py
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | |