2013-07-05 8 views
17

Alla sessione WWDC 2013 '207: Novità in Core Data', si dice che è possibile abilitare SQLite WAL passando un dizionario di opzioni quando si aggiunge un negozio persistente:iOS CoreData - ci sono degli svantaggi nell'abilitare il logging WAL/Write-Ahead di sqlite

@{ NSSQLitePragmasOption: @"journal_mode = WAL" } 

(che è disponibile su iOS4 + e sarà l'impostazione predefinita per le future versioni di iOS).

Mi chiedo se questo sarebbe in genere una buona cosa da abilitare nella mia app anche per le versioni precedenti di iOS.

Ho consultato i SQLite page about write ahead logging e gli svantaggi che menzionano, la maggior parte di loro sembrano non applicare a iOS a parte:

  • WAL potrebbe essere molto leggermente più lento (forse 1% o 2% più lento) rispetto l'approccio di tipo rollback-journal tradizionale in applicazioni che funzionano principalmente su e raramente scrivono.

praticamente tutti i vantaggi suonano come se probabilmente sarà un beneficio su iOS:

  • WAL è significativamente più veloce nella maggior parte degli scenari.
  • WAL offre maggiore concorrenza in quanto i lettori non bloccano i writer e uno scrittore non blocca i lettori. La lettura e la scrittura possono procedere contemporaneamente.
  • Le operazioni di I/O su disco tendono ad essere più sequenziali utilizzando WAL.
  • WAL utilizza molte meno operazioni fsync() ed è quindi meno vulnerabile ai problemi nei sistemi in cui la chiamata di sistema fsync() è interrotta.

Sto pungendo (forse soggetto a fare alcuni controlli sulla mia app per assicurarsi che non rallenti) che questa sarebbe una buona cosa da abilitare, ma c'è qualche aspetto negativo che dovrei guardare per o eventuali problemi noti?

risposta

17

http://pablin.org/2013/05/24/problems-with-core-data-migration-manager-and-journal-mode-wal/ suggerisce che la loro potrebbe essere problemi con le migrazioni, in particolare:

Quando si utilizza un manager di migrazione, Core Data creerà un nuovo database per voi, e iniziare a copiare i soggetti uno per uno da il vecchio DB a il nuovo.

Poiché stiamo usando journal_mode = WAL, c'è un altro file oltre a DB.sqlite chiamato DB.sqlite-wal.

Da quello che posso dire, il problema sembra essere che Core Data crea un DB temporanea , inserisce tutto quello che c'è, e quando lo rinomina il nome originale , il file -wal è conservato come un residuo del vecchia versione . Il problema è che si finisce con un DB incoerente.

(anche menzionato sul https://github.com/magicalpanda/MagicalRecord/issues/490 - che suggerisce che se si utilizza record di magico, allora è già inadempiente per WAL)

+4

Devo notare che questo si verifica solo nelle migrazioni "avanzate", quando è necessario un gestore di migrazione. Migrazioni meno radicali (come l'aggiunta o la ridenominazione di una colonna) funzioneranno correttamente, poiché vengono eseguite sullo stesso database e non in una copia. – pgb

+0

@pgb è bello sapere, grazie per il chiarimento! – JosephH

+0

Non potresti disabilitare temporaneamente WAL, cancellando il journal (-wal file), e poi fai la migrazione ...? – CommaToast

2

Per quanto riguarda il bug che si verifica con le migrazioni non-leggeri che coinvolgono sottoclassi NSMigrationManager, che ho' Ho ripubblicato ad Apple come Bug 16038419.

Ho anche fatto un diverso, method-swizzling workaround quali patch il bug nei casi in cui si sempre desidera utilizzare legacy cancellare/rollback diario. A quanto ho capito, Pablin's fix è per i casi in cui si desidera utilizzare WAL eccetto durante le migrazioni. Inoltre, puoi vedere che l'errore si verifica in this video.

+0

Fantastico, grazie. Non interessante, in quali casi vorresti evitare sempre il WAL? – JosephH

+1

Caso 1: app Mac OS X Core Data che non utilizza pacchetti di file. Il file sqlite è il file del documento. Gli utenti graffiano le teste quando vedono -shm e -wal file adiacenti ai loro documenti in Finder. Potrebbero pensare che siano spazzatura e o cestinarli o ignorarli durante lo spostamento o la copia del documento. Risultato: perdita di dati. Caso 2: "WAL journal_mode non è, tuttavia, consigliato per i file di database di sola lettura o per i file che devono interagire con iOS 4 o versioni precedenti." Cioè da: https://developer.apple.com/library/ios/releasenotes/DataManagement/WhatsNew_CoreData_iOS/ –

Problemi correlati