Повреждение основного хранилища данных

14

Несколько клиентов для моего iPhone-приложения испытывают повреждение хранилища Core Data (предположим, так как ошибка "Не удалось сохранить в хранилище данных: операция не может быть завершена" (Cocoa ошибка 259.) ")

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

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

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

Изменить:

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

  • 2
    Также получаю эту ошибку: «База данных в /var/mobile/Applications/<UUID>/Documents/foo.sqlite повреждена. Код ошибки SQLite 11, образ диска базы данных искажен».
  • 0
    Похоже, это может быть связано с изменением библиотеки SQLite, включенной в 4.2 против 4.3: devforums.apple.com/message/409734
Показать ещё 4 комментария
Теги:
core-data
iphone

8 ответов

18

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

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

  • 4
    Это помогло мне решить проблему во время переноса основных данных, когда после миграции были файлы -wal и -shm. Когда это произошло, я получил сообщение о поврежденной базе данных. Так как режим журнала базы данных был установлен на УДАЛИТЬ, эти файлы действительно никогда не должны быть там. Вздох. В любом случае, убедитесь, что они удалены, прежде чем настраивать постоянное хранилище. Спасибо Мартин.
2

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

Моя проблема была подробно описана терминалом Xcode следующим образом:

CoreData: error: (11) Неустранимая ошибка. База данных по /Пользователи/etc/Library/Developer/CoreSimulator/Devices/etc/data/Контейнеры/Данные/Приложение/etc/Library/Поддержка приложений /com.etc.etc/etc.sqlite повреждена. Код ошибки SQLite: 11, "образ диска базы данных искажен".

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

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

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

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

Примечания по этому опыту:

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

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

  • Открыть терминал [команды терминала /sqlite ];
  • Перейдите к соответствующему местоположению файла [ cd];
  • В целях резервного копирования сделайте копию файла базы данных "malformed" (например, dbMalFormedBU.sqlite) (который может быть удален позже, если восстановление выполнено успешно) [cp];
  • Чтобы быть уверенным, удалите файлы dbMalFormed.sqlite-shm и dbMalFormed.sqlite-wal [rm];
  • Откройте свой файл базы данных "неправильный" [sqlite3 dbMalFormed.sqlite];
  • Клонирование файла базы данных [ .clone dbMalFormedNew.sqlite];
  • Выход из SQLite3 [ .exit];
  • Удалить старый файл с ошибкой [ rm dbMalFormed.sqlite);
  • Переименуйте новый файл базы данных в ранее используемое имя [ mv dbMalFormedNew.sqlite dbMalFormed.sqlite].
2

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

  • 0
    +1 еще одна хорошая идея. Полный диск может иногда вызывать странные, казалось бы, не связанные ошибки.
  • 3
    Как правило, из-за нехватки места выдается ошибка «диск заполнен». У меня был один пользователь, который сообщал, что «образ диска базы данных - это неправильно сформированная ошибка». Телефон сообщил о доступной памяти выше 1,5 ГБ. При переустановке (которая начинается заново с новой SQlite DB) все еще сообщается об ошибке повреждения. Затем он очистил дополнительное место для хранения, переустановил и заявил, что он работает. Не знаю, был ли причиной переполнения диска, или было ли неисправно оборудование для хранения в некоторых областях, и очистка пространства вынудила приложение переустановиться в другое место и начать работать. Независимо от того, есть ли у пользователя свободное пространство, стоит попробовать
2

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

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

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

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

Изменить

Это трудно будет отследить, потому что такие ошибки настолько редко встречаются в Core Data, что нет никаких инструментов для поиска проблемы.

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

  • Проверка выше, где ошибка исходит из кода. Возможно, что-то бросает магазин или заставляет его смотреть в другом месте.
  • Проверьте, где бы вы ни занимались, что-то нестандартное. Например, если вы создаете собственную карту сущности в коде, ее легко отбросить, если вы не будете осторожны.
  • 0
    Это может привести к коду ошибки, но мне нужно выяснить причину этого повреждения - и это сложно, потому что это затрагивает лишь небольшую часть пользователей.
1

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

Многопоточность была проблемой в моем случае. Исправлено его обертывание всего метода блоком @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

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

1

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

  • 0
    +1 Это очень хорошая идея. Я никогда не делал этого, поэтому я не думал об этом. Тем не менее, Core Data очень и очень суетливо относится к своему магазину. Наименьшая ошибка приведет к тому, что он будет ошибаться.
  • 0
    Нет, просто стандартные вещи Core Data, NSPersistentStoreCoordinator , NSManagedObjectModel и друзья.
0

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

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

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

 File at path does not appear to be a SQLite database

Ещё вопросы

Сообщество Overcoder
Наверх
Меню