2012-06-13 43 views
5

Trong bảng loại mysql MyISAM có một cột Image loại mediumblob và lưu trữ hình ảnh đã chụp. Tôi có một số hình ảnh thú vị và có vấn đề. Một số hình ảnh là dữ liệu gradually losing.Dữ liệu hình ảnh MySQL BLOB dần mất?

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

my.ini max allowd kích thước gói cài đặt max_allowed_packet = 8M

image1 image2 image3

đây là vấn đề

Khi C# ứng dụng lấy dữ liệu từ máy chủ mỗi khi các loại hình ảnh s mất dữ liệu dần dần và kích thước ngẫu nhiên. Tôi đã nhận được 10-12 hình ảnh xấu như thế này trong 100000+ dữ liệu hình ảnh.

Điều gì có thể là nguyên nhân của loại hành vi này? Bất cứ ai cũng có bất kỳ ý tưởng/giải pháp làm thế nào để sửa chữa/tránh vấn đề này.

Cập nhật 1:
byte Reading hình thức 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(); 
}   

Tiết kiệm mảng byte vào cơ sở dữ liệu như dữ liệu blob trung bình. Khi lấy dữ liệu từ cơ sở dữ liệu tôi đúc các dữ liệu đọc

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

Nếu bạn lưu trữ hình ảnh trong cơ sở dữ liệu, bạn đang gonna có một thời gian xấu. Tại sao không lưu trữ chúng dưới dạng tệp thông thường? – Sarke

+0

@niksonkantiPaul Tôi chỉ tò mò tại sao bạn lưu hình ảnh vào DB, và không chỉ là đường dẫn và hình ảnh vào một thư mục? – jcho360

Trả lời

4

Thủ phạm là loại lưu trữ MyISAM.

Chúng tôi đã sử dụng bộ nhớ InnoDB để lưu trữ một triệu hình ảnh và tiến hành kiểm tra căng thẳng, chúng tôi có kết quả phù hợp. Một trong hai tập tin được lấy ra một cách chính xác hoặc nó không phải là ở tất cả lấy (ít hơn 0,01%), kể từ khi InnoDB là axit tuân thủ.

Khi chúng tôi chuyển sang MyISAM, tỷ lệ lỗi tăng lên 20% với dữ liệu mất dữ liệu cũng giống như trường hợp của bạn.Và lý do là, MyISAM sử dụng khóa bảng, như vậy trong khi ghi được tiến hành toàn bộ bảng bị khóa và trong trường hợp thời gian chờ, nó ghi đè lên một cái gì đó dẫn đến mất dữ liệu.

Bây giờ chúng ta đã chuyển tất cả mọi thứ để MS SQL, vì InnoDB hoạt động tốt nhưng vẫn không bao giờ tái sử dụng không gian tập tin bị xóa, vì vậy InnoDB vô tận vẫn tiếp tục phát triển. MS SQL express có giới hạn 10gb, vì vậy chúng tôi đã tạo các trang có kích thước 4-8gb và chúng tôi lưu trữ các đốm màu ở đó. Và chúng tôi có bản sao tùy chỉnh của riêng mình để sao chép các tệp trên ba máy chủ trên mạng với cùng một cấu hình.

Lưu trữ dưới dạng tệp trên đĩa không tốt vì nhiều lý do, mọi người tiếp tục nói rằng hệ thống tệp được thiết kế cho hiệu suất cao và có thể lưu trữ hàng triệu tệp, điều này không đúng, ổ đĩa không hoạt động nhanh hơn khi bạn có hơn 100 nghìn tệp . Chúng hoạt động tốt với một tệp lớn rồi 1000 tệp nhỏ hơn. Hiện tại chúng tôi đang lưu trữ 10 triệu tệp và lưu trữ nó trong db có ý nghĩa hơn vì db tối ưu hóa truy vấn và lưu trữ bộ nhớ đệm tốt. Bạn có thể đọc thêm tại http://akashkava.com/blog/127/huge-file-storage-in-database-instead-of-file-system/

Đây là lý do chính xác tại sao MongoDb, Hadoop, Cửa hàng Azure Blob, Haystack và Amazon S3 được phát minh.

5

Trước hết, như Sarke đề cập, lưu trữ các file nội dung trong DB không phải là ý tưởng tốt nhất (file meta dữ liệu là một câu chuyện hoàn toàn khác nhau.

tại sao

  1. hiệu suất:. trong đa số trường hợp hệ điều hành tập tin bộ nhớ cache sẽ làm tốt hơn bất cứ điều gì được xây dựng vào DBMS
  2. phục hồi
  3. thiên tai: tỷ lệ cược của mất tất cả/nhất các tập tin trên thất bại là cách cao hơn với hệ thống tập tin và phục hồi Là khó khăn hơn nhiều:
  4. Mở rộng quy mô: nếu bạn vượt quá dung lượng của một máy chủ đơn, việc thêm sharding cấp ứng dụng là tầm thường và không bị phạt hiệu suất. Multiserver DB thiết lập nhiều "đau đớn"
  5. Nhiều giải pháp có sẵn/dễ di cư: Có rất nhiều phần cứng và phần mềm giải pháp cho lớn lưu trữ bộ sưu tập tập tin và di chuyển giữa chúng là xa đơn giản hơn di cư giữa các DBMS

tôi lưu trữ gần 2 triệu hình ảnh được lưu trữ trong cấu trúc thư mục đơn giản: /xx/yy/filename, trong đó tên tệp = md5 của tệp (+ số tùy chọn nếu xảy ra xung đột băm), xx = 2 ký tự đầu tiên của md5, yy = 3rd và 4th character of md5 . Nó hoạt động tốt và tôi không nên nhận được bất kỳ sự chậm trễ liên quan đến FS trong một thời gian dài (ít nhất là 2 đơn đặt hàng).

Bắt trở lại câu hỏi của bạn có 3 lựa chọn

  1. Các tập tin không bao giờ được lưu một cách chính xác để DB. Có thể sự cố trong ứng dụng đang tải lên ảnh hoặc hình ảnh quá lớn.max_allowed_packet giới hạn kích thước hình ảnh của bạn ~ 8 MB, mediub_blob có thể lưu trữ tối đa 16 MB. Để loại trừ số này, hãy tăng max_allowed_packet lên 32 MB và kiểm tra. Bạn sẽ cần đảm bảo không có hình ảnh nào vượt quá kích thước này tại bất kỳ thời điểm nào và đảm bảo ứng dụng thực hiện công việc ngay khi tải ảnh lên. Nếu bạn có thể tìm thấy một hình ảnh đã được tải lên và hiển thị tốt (từ DB!) Và sau đó nó không thì đây không phải là nguyên nhân.
  2. Các tệp bị hỏng trong quá trình cập nhật - nếu có bất kỳ nội dung nào cập nhật ảnh theo bất kỳ cách nào thì ngay cả khi tệp gốc có thể không được cập nhật - ví dụ: có thể vượt quá giới hạn kích thước từ điểm 1.
  3. có thể một) Nếu tệp được lưu trữ và cập nhật mà không làm hỏng nó thì nó sẽ bị hỏng khi đang được lưu trữ -> không có lỗi MySQL nào được báo cáo (và điều này sẽ không được chú ý).
+0

1. không viết một phần 2. thiệt hại là vĩnh viễn, –

+0

Chỉ cần chắc chắn: bạn đã xác nhận hình ảnh là ok (lấy chúng ít nhất một lần không bị hư hại từ DB) và chỉ sau này phát hiện ra chúng đã bị hỏng? – c2h5oh

+0

có, nhưng không quá thường xuyên –

2

Tôi nghĩ trước tiên bạn cần phải tìm hiểu xem ứng dụng của bạn hoặc một số quy trình bên ngoài (sao lưu/khôi phục?) Có thay đổi dữ liệu này hay không. Thực ra, tôi thấy ít lý do khiến ứng dụng của bạn cần phải cập nhật ảnh này (tức là cập nhật trường có cùng dữ liệu), nếu tệp được cho là không thay đổi.

Khi bạn tìm thấy phần nào của ứng dụng của bạn cập nhật trường này, bạn có thể muốn đăng một số mã để xem không có chuyển đổi, thoát hay bất kỳ điều gì khác đang diễn ra. Nếu, như tôi cho rằng, cập nhật như vậy sẽ không bao giờ xảy ra, hãy đặt kích hoạt BEFORE UPDATE trên bàn sẽ cho phép bạn biết chính xác thời điểm sự cố xảy ra và có thể giúp xác định mẫu có thể. So sánh các giá trị OLDNEW và ghi lại nhiều dữ liệu có sẵn có liên quan như bạn có thể trong bảng nhật ký - hãy cẩn thận, so sánh các BLOB lớn có thể là sát thủ hiệu suất, xem hiệu suất của bạn chặt chẽ.

0

API nào bạn sử dụng để lấy dữ liệu từ cơ sở dữ liệu? Cho chúng tôi một số mã tìm nạp dữ liệu.

Thông thường BLOB được đọc từ cơ sở dữ liệu bằng cách sử dụng một số loại 'streaming', vì vậy có thể bạn sẽ cần phải chuyển sang một cái gì đó mạnh mẽ hơn ADO.NET nếu bạn đang sử dụng nó.

Trang này có thể có ích: http://dev.mysql.com/doc/refman/5.5/en/connector-net-programming-blob.html

1

Công ty của tôi bầu để lưu trữ hình ảnh bên ngoài của cơ sở dữ liệu. Chúng tôi nhận thấy rằng Blobs, giống như một trong những bạn đang sử dụng, dễ bị tham nhũng và các vấn đề hiệu suất. Chúng tôi đã thấy các vấn đề tương tự trong MSSQL, Sybase và Faircom.

Bất cứ khi nào ứng dụng cần quyền truy cập vào hình ảnh, ứng dụng cần quyền truy cập vào bộ nhớ mạng (hoặc dựa trên web) nơi có thể tìm thấy hình ảnh đó. Sau đó, dữ liệu chỉ lưu trữ đường dẫn đến hình ảnh.

Vì hình ảnh là tệp phẳng ở đâu đó trong hệ thống tệp, nếu bản ghi cần được cập nhật (tức là ghi chú được thêm vào để mô tả hình ảnh), hình ảnh đó không tự biên dịch lại thành đốm màu không có cơ hội bị hỏng.

+0

thì tại sao lại xảy ra nhiều lần trong cùng một hình ảnh :(, –

+0

Chương trình của bạn có bao giờ viết lại bản ghi (bao gồm cả trường Blob) không? – CEPA

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