* Acquire lock on a table to be dumped by a worker process. * * The leader process is already holding an ACCESS SHARE lock. Ordinarily * it's no problem for a worker to get one too, but if anything else besides * pg_dump is running, there's a possible deadlock: * * 1) Leader dumps the schema and locks all tables in ACCESS SHARE mode. * 2) Another process requests an ACCESS EXCLUSIVE lock (
| 1303 | * so we have a deadlock. We must fail the backup in that case. |
| 1304 | */ |
| 1305 | static void |
| 1306 | lockTableForWorker(ArchiveHandle *AH, TocEntry *te) |
| 1307 | { |
| 1308 | const char *qualId; |
| 1309 | PQExpBuffer query; |
| 1310 | PGresult *res; |
| 1311 | |
| 1312 | /* Nothing to do for BLOBS */ |
| 1313 | if (strcmp(te->desc, "BLOBS") == 0) |
| 1314 | return; |
| 1315 | |
| 1316 | query = createPQExpBuffer(); |
| 1317 | |
| 1318 | qualId = fmtQualifiedId(te->namespace, te->tag); |
| 1319 | |
| 1320 | appendPQExpBuffer(query, "LOCK TABLE %s IN ACCESS SHARE MODE NOWAIT", |
| 1321 | qualId); |
| 1322 | |
| 1323 | res = PQexec(AH->connection, query->data); |
| 1324 | |
| 1325 | if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) |
| 1326 | fatal("could not obtain lock on relation \"%s\"\n" |
| 1327 | "This usually means that someone requested an ACCESS EXCLUSIVE lock " |
| 1328 | "on the table after the pg_dump parent process had gotten the " |
| 1329 | "initial ACCESS SHARE lock on the table.", qualId); |
| 1330 | |
| 1331 | PQclear(res); |
| 1332 | destroyPQExpBuffer(query); |
| 1333 | } |
| 1334 | |
| 1335 | /* |
| 1336 | * WaitForCommands: main routine for a worker process. |
no test coverage detected