Re: BUG #17731: Server doesn't start after abnormal shutdown while creating unlogged tables
От | Karina Litskevich |
---|---|
Тема | Re: BUG #17731: Server doesn't start after abnormal shutdown while creating unlogged tables |
Дата | |
Msg-id | CACiT8ibXxDpJHO0gFtCXxD5nShnByW5OS37H2hPgjsoxBKD_Xw@mail.gmail.com обсуждение исходный текст |
Ответ на | BUG #17731: Server doesn't start after abnormal shutdown while creating unlogged tables (PG Bug reporting form <noreply@postgresql.org>) |
Ответы |
Re: BUG #17731: Server doesn't start after abnormal shutdown while creating unlogged tables
Re: BUG #17731: Server doesn't start after abnormal shutdown while creating unlogged tables |
Список | pgsql-bugs |
For unlogged tables and indexes init forks are created to simulate truncate on server startup. In StartupXLOG() every main fork, for which corresponding init fork exists, is deleted before replaying WAL, and then new main fork is created by copying init fork: ResetUnloggedRelations(UNLOGGED_RELATION_CLEANUP); ... PerformWalRecovery(); ... ResetUnloggedRelations(UNLOGGED_RELATION_INIT); So in case before WAL recovery main fork exists and init fork isn't, and during recovery init fork is created, we get this problem. The second ResetUnloggedRelations() call sees just created init fork and tries to create a main fork from it expecting that the old main fork was already deleted by the first ResetUnloggedRelations() call, but it wasn't because the main fork hasn't corresponding init fork at that moment yet. If you try to start server again, it will start successfully, as this time both init and main forks will present from the beginning. The situation, when main fork of the unlogged table is present but init fork is not, can happen because main fork file isn't actually being deleted when table is dropped. It's deletion is being postponed until the next checkpoint. See comment before mdunlink(): /* ... * Leaving the empty file in place prevents that relfilenumber * from being reused. The scenario this protects us from is: * 1. We delete a relation (and commit, and actually remove its file). * 2. We create a new relation, which by chance gets the same relfilenumber as * the just-deleted one (OIDs must've wrapped around for that to happen). * 3. We crash before another checkpoint occurs. * ... */ Theoretically, this applies to all versions, but the script somehow doesn't lead to an error on REL_11_STABLE. I haven't investigated it yet. I see two solutions: 1) keep init fork files until the next checkpoint as well as main fork files, 2) ignore (rewrite if exists) presence of an empty main fork file when copying from init fork. I found the latter less elegant so I implemented the first one. The patch is attached. Best regards, Karina Litskevich Postgres Professional: http://postgrespro.com/
Вложения
В списке pgsql-bugs по дате отправления: