2013-07-05 30 views
17

Tại phiên WWDC 2013 '207: Có gì mới trong dữ liệu cốt lõi', họ đề cập rằng bạn có thể bật SQLite WAL bằng cách chuyển từ điển tùy chọn khi thêm lưu trữ liên tục:iOS CoreData - có bất kỳ nhược điểm nào khi kích hoạt tính năng sqlite WAL/Write-Ahead Logging

@{ NSSQLitePragmasOption: @"journal_mode = WAL" } 

(có sẵn trên iOS4 + và sẽ là mặc định cho các phiên bản iOS trong tương lai).

Tôi tự hỏi liệu điều này nói chung sẽ là một điều tốt để bật trong ứng dụng của tôi cho các phiên bản iOS cũ hơn.

Tôi đã tham khảo ý kiến ​​SQLite page about write ahead logging và những nhược điểm họ đề cập, hầu hết trong số họ dường như không áp dụng cho iOS ngoài:

  • WAL có thể rất hơi chậm (có lẽ 1% hoặc 2% chậm hơn) hơn phương pháp tiếp cận rollback-journal truyền thống trong các ứng dụng chủ yếu là đọc và ít khi viết.

khá nhiều tất cả những ưu điểm làm âm thanh như họ có thể sẽ là một lợi ích trên iOS:

  • WAL là đáng kể nhanh hơn trong hầu hết các tình huống.
  • WAL cung cấp đồng thời hơn vì người đọc không chặn nhà văn và người viết không chặn người đọc. Đọc và viết có thể tiến hành đồng thời.
  • Hoạt động I/O đĩa thường có xu hướng tuần tự hơn bằng cách sử dụng WAL.
  • WAL sử dụng nhiều thao tác fsync() ít hơn và do đó ít dễ bị tổn thương hơn đối với các sự cố trên hệ thống mà cuộc gọi hệ thống fsync() bị hỏng.

Tôi đang chuẩn bị (có thể phải thực hiện một số kiểm tra trên ứng dụng của mình để đảm bảo rằng nó không làm chậm công việc), đây là một điều tốt để kích hoạt, nhưng có bất kỳ nhược điểm nào tôi nên xem hoặc bất kỳ vấn đề đã biết nào?

Trả lời

17

http://pablin.org/2013/05/24/problems-with-core-data-migration-manager-and-journal-mode-wal/ gợi ý rằng họ có thể là vấn đề với di cư, đặc biệt là:

Khi bạn sử dụng một Giám đốc Migration, Core Dữ liệu sẽ tạo ra một cơ sở dữ liệu mới cho bạn, và bắt đầu sao chép các đối tượng từng người một từ DB cũ thành hình mới.

Vì chúng tôi đang sử dụng journal_mode = WAL, có một tệp bổ sung bên cạnh DB.sqlite được gọi là DB.sqlite-wal. Từ những gì tôi có thể nói, vấn đề dường như là dữ liệu cốt lõi tạo ra một mã số tạm thời DB, chèn tất cả mọi thứ ở đó, và khi nó đổi tên thành tên gốc, tập tin -wal được giữ như một phần còn lại từ cũ phiên bản. Vấn đề là bạn kết thúc với một DB không nhất quán.

(cũng được đề cập trên https://github.com/magicalpanda/MagicalRecord/issues/490 - điều này gợi ý rằng nếu bạn sử dụng kỷ lục kỳ diệu sau đó nó đã được mặc định cho WAL)

+4

Tôi nên lưu ý rằng điều này chỉ xảy ra trong quá trình di chuyển "nâng cao" khi bạn cần Trình quản lý di chuyển. Di chuyển ít triệt để hơn (như thêm hoặc đổi tên một cột) sẽ hoạt động tốt, vì chúng được thực hiện trên cùng một cơ sở dữ liệu chứ không phải trong một bản sao. – pgb

+0

@pgb đó là điều tốt để biết, cảm ơn bạn đã làm rõ! – JosephH

+0

Bạn không thể tạm thời vô hiệu hóa WAL, xóa tạp chí (tập tin -wal), và sau đó thực hiện di chuyển ...? – CommaToast

2

Về lỗi xảy ra với di cư phi nhẹ liên quan đến subclassing NSMigrationManager, mà tôi đã báo cáo lại cho Apple là Bug 16038419.

Tôi cũng đã thực hiện một khác nhau, method-swizzling workaround vá lỗi trong trường hợp bạn luôn luôn muốn sử dụng nhật ký xóa/khôi phục cũ. Theo tôi hiểu, Pablin's fix dành cho các trường hợp bạn muốn sử dụng WAL ngoại trừ trong khi di chuyển. Ngoài ra, bạn có thể thấy lỗi đó xảy ra trong this video.

+0

Tuyệt vời, cảm ơn. Không quan tâm, trong trường hợp nào bạn muốn luôn tránh WAL? – JosephH

+1

Trường hợp 1: Ứng dụng Mac OS X Core Data không sử dụng gói tệp. Tệp sqlite là tệp tài liệu. Người dùng làm xước đầu khi họ nhìn thấy các tệp -shm và -wal bên cạnh tài liệu của họ trong Trình tìm kiếm. Họ có thể nghĩ rằng đây là rác và thùng rác, hoặc bỏ qua chúng khi di chuyển hoặc sao chép các tập tin tài liệu. Kết quả: mất dữ liệu. Trường hợp 2: "WAL journal_mode không được khuyến nghị cho các tệp cơ sở dữ liệu chỉ đọc hoặc cho các tệp cần tương thích với iOS 4 trở về trước". Đó là từ: https://developer.apple.com/library/ios/releasenotes/DataManagement/WhatsNew_CoreData_iOS/ –

Các vấn đề liên quan