Повреждение основного хранилища данных - PullRequest
18 голосов
/ 30 апреля 2010

Несколько пользователей моего приложения для iPhone испытывают повреждение основного хранилища данных (я так полагаю, поскольку ошибка «Не удалось сохранить в хранилище данных: операция не может быть завершена. (Ошибка Какао 259.)»)

Кто-нибудь еще сталкивался с такой коррупцией в магазине? Я волнуюсь, так как хочу скоро загрузить обновление, которое выполняет миграцию схемы, и я боюсь, что это вызовет еще больше проблем.

Я предполагал, что API-интерфейсы Core Data / SQLlite используют атомарные операции и защищены от повреждения, за исключением случаев, когда основная файловая система испытывает повреждение.

Есть ли способ уменьшить / предотвратить коррупцию и способ воспроизвести коррупцию, чтобы я мог проверить это (я пока не добился успеха).

Edit:

Также появляется эта ошибка: «База данных в /var/mobile/Applications//Documents/foo.sqlite повреждена. Код ошибки SQLite 11, образ диска базы данных искажен».

Ответы [ 8 ]

20 голосов
/ 13 января 2014

Это случается со мной, когда я вручную перезаписываю свои Base.sqlite, не удаляя Base.sqlite-wal и Base.sqlite-shm. Действительно, эти файлы - новые функции SQLite 3.7 , возможно, добавленные в iOS 7.

Чтобы решить эту проблему, я удалил Base.sqlite-* и sqlite восстановил их из моей новой базовой версии.

2 голосов
/ 11 марта 2016

Для ясности, используя Xcode 7.2.1, хранилище данных SQLite, граф объектов Core Data, для приложения-прототипа.

Моя проблема была детализирована терминалом Xcode как:

CoreData: ошибка: (11) фатальная ошибка. База данных на / Пользователи / etc / Библиотека / Разработчик / CoreSimulator / Устройства / etc / data / Контейнеры / Данные / Приложение / etc / Библиотека / Поддержка приложений / com.etc.etc / etc.sqlite повреждена. Код ошибки SQLite: 11, «образ диска базы данных искажен».

По сути, мое приложение смогло загрузить и прочитать данные SQLite, но не смогло сохранить.

Этот ответ пользователем SO программное обеспечение эволюционировало имело смысл для меня. Во время использования Simulator я был почти уверен, что прервал операцию сохранения в контексте управляемого объекта с типом параллельного доступа к частной очереди NSPrivateQueueConcurrencyType.

Дальнейшее исследование (с использованием SQLiteManager) показало, что причиной этой проблемы была таблица SQLite, в которую я сохранял время.

Я мог бы легко удалить приложение (публичного выпуска пока нет), но я хотел хотя бы понять, как исправить эту проблему.

Заметки из этого опыта:

  • В делегате приложения по протоколу UIApplicationDelegate - (void)applicationWillResignActive:(UIApplication *)application, если контекст управляемого объекта hasChanges обязательно включает метод сохранения базы данных;
  • Если используется более одной очереди, используйте кнопку «Домой» для запуска метода делегата в пункте 1, прежде чем нажимать кнопку «Стоп» в XCode;
  • Исправить поврежденный файл базы данных - я разработал решение, подробно описанное ниже, из ответа, приведенного на этой веб-странице Исправление ошибки SQLite «Образ диска базы данных искажен» .

Метод восстановления файла базы данных SQLite:

  1. Открыть терминал [команды терминала / sqlite];
  2. Перейдите в соответствующее местоположение файла [cd];
  3. В целях резервного копирования создайте копию файла базы данных «неправильно сформированный» (например, dbMalFormedBU.sqlite) (который можно удалить позже, если восстановление выполнено успешно) [cp];
  4. Для уверенности удалите файлы dbMalFormed.sqlite-shm и dbMalFormed.sqlite-wal [rm];
  5. Откройте файл вашей базы данных с ошибками [sqlite3 dbMalFormed.sqlite];
  6. Клонировать файл базы данных [.clone dbMalFormedNew.sqlite];
  7. Выход из SQLite3 [.exit];
  8. Удалить старый «искаженный» файл базы данных [rm dbMalFormed.sqlite);
  9. Переименуйте новый файл базы данных в ранее использованное имя [mv dbMalFormedNew.sqlite dbMalFormed.sqlite].
2 голосов
/ 11 июня 2010

Также попытайтесь повторить ошибку, заполнив диск на устройстве - вы должны получить сообщение об ошибке переполнения диска вместо повреждения базы данных, но может оказаться возможным получить поврежденную базу данных таким способом.

2 голосов
/ 30 апреля 2010

Ошибка, которую вы получаете, определена в Foundation.h

NSFileReadCorruptFileError = 259, // Ошибка чтения (поврежден файл, неверный формат и т. Д.)

Я никогда не сталкивался с этим в реальном магазине, но столкнулся с чем-то похожим с плохими разрешениями (на Mac). Я также не видел, чтобы кто-нибудь упоминал подобную ошибку в Интернете. Системы предотвращения ошибок в Core Data достаточно надежны.

Я бы предположил, что самый простой способ создать это - отправить постоянное хранилище для просмотра неправильного файла, например, случайно нацелив его на текстовый файл. Если он ожидает хранилище SQL, но находит что-то еще, он пожалуется, что файл поврежден. Это просто выстрел в темноте.

Редактировать

Это будет трудно отследить, потому что подобные ошибки в Базовых данных настолько редки, что нет никаких инструментов, помогающих найти проблему.

Я бы порекомендовал:

  1. Проверка вверх по течению того, откуда исходит ошибка из кода. Возможно, что-то сбрасывает магазин или заставляет его искать в другом месте.
  2. Отметьте, где вы можете сделать что-то нестандартное. Например, если вы генерируете свою собственную карту сущностей в коде, ее легко скинуть, если вы не будете осторожны.
1 голос
/ 29 апреля 2016

Я столкнулся с этой ошибкой при попытке получить координатор постоянного хранилища.

Многопоточность была проблемой в моем случае. Исправлена ​​ошибка с обертыванием всего метода блоком @synchronized(self) {}

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    @synchronized(self) {

    // Quickly return persistent store coordinator if available
    if (__persistentStoreCoordinator != nil) {
        return __persistentStoreCoordinator;
    }

    // Persistent store coordination initialization, to be performed once
    // ...

    }
    return _persistentStoreCoordinator;
}
1 голос
/ 13 июля 2014

Я испытал «повреждение основного хранилища данных», когда я предварительно загружал базу данных отдельным потоком (не основным потоком), и было действительно трудно найти эту ошибку, так как только несколько моих клиентов вызвали сбой их приложения из-за этого .

1 голос
/ 12 июня 2010

Вы когда-нибудь взаимодействовали с базой данных, используя API sqlite? Или вы использовали какие-либо инструменты, не принадлежащие Apple, для создания исходной базы данных?

0 голосов
/ 17 августа 2010

Я недавно столкнулся с этой проблемой.В моем случае я выполнял поиск и перебирал объекты, чтобы преобразовать данные в XML и KML.Затем я бы создал обработчик электронной почты и прикрепил файлы.Затем я обновил бы поле в объектах и, наконец, сохранил в хранилище (SQL Lite).Хорошо работал в 3.x.В 4.х это сломалось.

С моей стороны было глупо выполнять всю обработку электронной почты перед изменением и сохранением БД.Перемещение всего несущественного кода в точку после сохранения устраняет эту проблему.

Эта проблема полностью повредит базу данных SQL.В моем случае ошибка:

 File at path does not appear to be a SQLite database
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...