2012-06-13 3 views
5

В mysql MyISAM Тип таблицы имеет столбец Image тип mediumblob и хранение захваченного изображения. У меня есть интересные и проблемные образы. Некоторые из изображений: gradually losing.Данные MySQL BLOB постепенно теряются?

Field   type 
-------------------------- 
image   mediumblob 

my.ini макс allowd размер пакета установлен max_allowed_packet = 8M

image1 image2 image3

это проблема

Когда C# приложение извлечения данных с сервера каждый раз, когда эти виды изображения Потеря данных постепенно и случайным образом. Я получил 10-12 плохие изображения, подобные этому, в 100000+ данные изображения.

Что может быть причиной такого поведения? У любого есть идея/решение, как исправить/избежать этой проблемы.

Update 1:
Чтение байтов форма PictureBox

MemoryStream ms = new MemoryStream(); 
byte[] ret = null; 

try 
{ 
    picturebox.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); 
    byte[] Data = new byte[ms.Length]; 
    ms.Read(Data, 0, (int)ms.Length); 
    ret = byteData; 
    ms.Close(); 
}   

Сохранение массива байтов в базу данных в качестве среды BLOB. При извлечении данных из базы данных Я прогоняю данные читателя

byte[] Data = (byte[])reader["Image"]; 
+0

Если вы храните изображения в базе данных, у вас будет плохое время. Почему бы не сохранить их как обычные файлы? – Sarke

+0

@niksonkantiPaul Мне просто интересно, почему вы сохраняете изображение в БД, а не только путь и изображение в папку? – jcho360

ответ

4

Culprit - это хранилище MyISAM.

Мы использовали хранилище InnoDB для хранения миллиона изображений и провели стресс-тест, у нас были правильные результаты. Либо файл был восстановлен правильно, либо он вообще не был найден (менее 0,01%), так как InnoDB соответствует кислотности.

Когда мы перешли на MyISAM, уровень сбоев увеличился до 20% с данными с потерями, а также с вашим случаем.И причина в том, что MyISAM использует блокировку таблиц, поэтому во время записи вся таблица заблокирована, а в случае таймаута она перезаписывает что-то, что приводит к потере данных.

Теперь мы переместили все на MS SQL, так как InnoDB работает хорошо, но при этом он никогда не использует удаленное файловое пространство, поэтому InnoDB бесконечно продолжает расти. MS SQL express имеет ограничение 10gb, поэтому мы создали страницы размером 4-8gb, и там мы сохраняем blob. И у нас есть собственная пользовательская репликация для репликации файлов по трем серверам по сети с одинаковой конфигурацией.

Хранение файлов на диске плохо по многим причинам, все продолжают говорить, что файловые системы предназначены для высокой производительности и могут хранить миллионы файлов, это неверно, диски не работают быстрее, когда у вас более 100 тысяч файлов , Они хорошо работают с одним большим файлом, а затем с 1000 меньшими файлами. В настоящее время мы сохраняем 10 миллионов файлов и сохраняем их в db, имеет больше смысла, потому что db делает оптимизацию по запросу и делает хорошее кэширование. Вы можете узнать больше на http://akashkava.com/blog/127/huge-file-storage-in-database-instead-of-file-system/

Именно по этой причине были изобретены MongoDb, Hadoop, Azure Blob Store, Haystack и Amazon S3.

5

Прежде всего, как уже упоминалась Сарка, хранение файлов содержимое в БД не лучшая идея (файл мета данные совсем другая история.

Почему

  1. Производительность:. в большинстве кэшем случаев файла ОС будет опережать ничего встроенного в СУБД
  2. восстановление
  3. Disaster: вероятность потери всех/большинство файлов на неудачи путь выше, чем с файловой системой и восстановления является гораздо сложнее
  4. Масштабирование: если вы увеличиваете пропускную способность одного сервера, добавляя уровень наложения уровня приложения, это тривиально и без штрафных санкций. Многосерверной DB расстановок более «болезненным»
  5. несколько решений, доступных/легкость миграции: Есть много аппаратных и программных решений для хранения большого коллекций файлов и миграции между ними гораздо более простым, чем переход между СУБД

I хранит около 2 миллионов изображений, которые хранятся в простой структуре папок: /xx/yy/filename, где filename = md5 файла (+ необязательный номер, если произойдет хеш-столкновение), xx = первые 2 символа md5, yy = 3-й и 4-й символы md5 , Он отлично работает, и я не должен замедлять замедление FS в течение длительного времени (по крайней мере, на 2 порядка).

Возвращаясь к вашему вопросу есть 3 варианта

  1. Файлы никогда не сохраняются правильно в БД. Это может быть проблема в приложении, которое загружает фотографии или изображение слишком велико.Ваш max_allowed_packet ограничивает размер изображения до ~ 8 МБ, mediub_blob может хранить максимум 16 МБ. Чтобы управлять этим, увеличьте max_allowed_packet до 32 МБ и проверьте. Вам нужно убедиться, что изображение не будет превышать этот размер в любой момент и убедитесь, что приложение работает правильно при загрузке фотографий. Если вы можете найти изображение, которое было загружено и отображено отлично (от DB!), А позже это не так, это не является причиной.
  2. Файлы повреждаются во время обновления - если что-либо обновляет фотографии в любом случае, даже если исходный файл в порядке, обновленный не может быть - он может, например, превышать пределы размера из точки 1.
  3. (наименее вероятно, один). Если файл хранится и обновляется без ущерба для него, он становится поврежденным при сохранении -> без сообщений об ошибках MySQL на этом (и это не останется незамеченным). Я бы посмотрел на аппаратное обеспечение сервера.
+0

1. без частичной записи 2. повреждение является постоянным, –

+0

Просто убедитесь, что вы подтвердили, что изображения были в порядке (вытащили их хотя бы один раз, не поврежденный из БД) и только позже обнаружили, что они теперь повреждены? – c2h5oh

+0

да, но его не так часто –

2

Я думаю, вам сначала нужно выяснить, является ли это ваше приложение или какой-то внешний процесс (резервное копирование/восстановление?), Который изменяет эти данные. На самом деле, я не вижу причин, по которым вашему приложению потребуется обновить это изображение (т. Е. Обновить поле теми же данными), если файл должен оставаться неизменным.

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

Если, как я полагаю, такое обновление не должно происходить, установка триггера BEFORE UPDATE на стол позволит вам точно знать, когда возникнет проблема, и может помочь в определении возможного шаблона. Сравните значения OLD и NEW и запишите как можно больше доступных данных в таблице журналов - будьте осторожны, сравнивая большие BLOB-файлы, вы можете быть убийцей производительности, внимательно следите за своими действиями.

0

Какой API вы используете для получения данных из базы данных? Получите код, который извлекает данные.

Обычно BLOB-коды считываются из базы данных с использованием какой-либо «потоковой передачи», поэтому, возможно, вам придется переключиться на нечто более надежное, чем ADO.NET, если вы его используете.

Эта страница может быть полезно: http://dev.mysql.com/doc/refman/5.5/en/connector-net-programming-blob.html

1

Моя компания выбирает для хранения изображений вне базы данных. Мы заметили, что Blobs, как и тот, который вы используете, подвержены проблемам коррупции и производительности. Мы видели те же проблемы в MSSQL, Sybase и Faircom.

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

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

+0

, то почему это происходит неоднократно на одном и том же изображении :(, –

+0

Ваша программа когда-либо переписывает запись (включая поле Blob)? – CEPA

Смежные вопросы