C# MySQL BLOB图像数据逐渐丢失?

C# MySQL BLOB图像数据逐渐丢失?,c#,mysql,image,image-processing,blob,C#,Mysql,Image,Image Processing,Blob,在mysqlMyISAMtype表中有一列Imagetypemediumblob并存储捕获的图像。我得到了一些有趣且有问题的图片。一些图像正在逐渐丢失数据 Field type -------------------------- image mediumblob my.inimax allowd数据包大小集max\u allowed\u数据包=8M 这就是问题所在 当C#应用程序每次从服务器获取数据时,这些类型的图像逐渐丢失数据,大小随机。我在100

在mysql
MyISAM
type表中有一列
Image
type
mediumblob
并存储捕获的图像。我得到了一些有趣且有问题的图片。一些图像正在逐渐丢失数据

Field          type  
--------------------------
image         mediumblob
my.ini
max allowd数据包大小集
max\u allowed\u数据包=8M

这就是问题所在

C#
应用程序每次从服务器获取数据时,这些类型的图像逐渐丢失数据,大小随机。我在
100000+
图像数据中得到了
10-12
这样的坏图像

这种行为的原因可能是什么?任何人都知道如何解决这个问题

更新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"];

首先,正如Sarke提到的,在DB中存储文件内容并不是最好的主意(文件元数据是一个完全不同的故事)

为什么?

  • 性能:在大多数情况下,操作系统文件缓存的性能优于DBMS中内置的任何东西
  • 灾难恢复:发生故障时丢失所有/大多数文件的几率远高于使用文件系统时,而且恢复要困难得多
  • 扩展:如果您的容量超过了一台服务器的容量,那么添加应用程序级分片是微不足道的,并且没有性能损失。多服务器数据库设置更“痛苦”
  • 多种解决方案可用/易于迁移:有大量用于大型文件集合存储的硬件和软件解决方案,在它们之间迁移要比在DBMS之间迁移简单得多
  • 我存储了近200万张图像,它们存储在一个简单的文件夹结构中:
    /xx/yy/filename
    ,其中filename=file的md5(+如果发生哈希冲突,可选数字),xx=md5的前2个字符,yy=md5的第3和第4个字符。它工作得很好,我应该不会在很长一段时间内出现任何与FS相关的减速(至少2个数量级)

    回到你的问题,有三种选择

  • 文件从未正确保存到DB。可能是上载照片的应用程序出现问题,或者图像太大。您的
    max_allowed_packet
    将图像大小限制为~8 MB,
    mediub_blob
    最多可存储16 MB。若要排除此问题,请将
    max_allowed_packet
    增加到32 MB并进行测试。您需要以确保在任何时候都没有图像超过此大小,并确保应用程序在上载照片时正确执行其任务。如果您可以找到上载并显示良好(从DB!)的图像,但后来没有,则这不是原因
  • 文件在更新过程中被损坏-如果有任何东西以任何方式更新了照片,那么即使原始文件很好,更新的文件也可能不好-例如,它可能会超过第1点的大小限制
  • (最不可能的一个)如果文件在存储和更新时没有损坏,那么它在存储时会被损坏->没有报告MySQL错误(这不会被忽略),我会在服务器硬件上查看

  • 我认为您首先需要确定是您的应用程序还是某个外部进程(备份/恢复?)更改了此数据。 实际上,如果文件保持不变,我看不出应用程序需要更新此图片(即使用相同的数据更新字段)的原因

    一旦发现应用程序的哪些部分更新了此字段,您可能需要发布一些代码,以查看是否没有转换、转义或其他任何情况发生


    如果,正如我所假设的,这样的更新永远不会发生,在表上设置更新前的
    触发器将允许您准确地知道问题发生的时间,并可能有助于确定可能的模式。比较
    旧的
    新的
    值,并在日志表中记录尽可能多的相关可用数据-小心,比较大的blob可能是性能杀手,请密切关注您的性能。

    您使用什么API从数据库中获取数据? 给我们一些获取数据的代码

    通常BLOB是使用某种“流”从数据库中读取的,因此如果使用ADO.NET,可能需要切换到比ADO.NET更健壮的程序


    此页面可能有用:

    我的公司选择在数据库之外存储图像。我们注意到,Blob与您正在使用的Blob一样,容易出现损坏和性能问题。我们在MSSQL、Sybase和Faircom中看到了相同的问题

    每当应用程序需要访问映像时,它都需要访问网络(或基于web的)存储,在该存储中它可以找到该映像。然后,数据只存储到映像的路径


    由于映像是文件系统中某个位置的平面文件,因此如果需要更新记录(即添加注释来描述映像),则映像本身不会重新编译到blob中,也不会损坏它。

    罪魁祸首是MyISAM存储类型

    我们使用InnoDB存储存储了一百万张图像,并进行了压力测试,我们得到了正确的结果。由于InnoDB是acid兼容的,所以要么正确检索了文件,要么根本没有检索到文件(小于0.01%)

    当我们转向MyISAM时,故障率增加到20%,有损数据和您的情况一样。原因是,MyISAM使用表锁,所以在写入过程中,整个表都被锁定,如果超时,它确实会覆盖导致数据丢失的内容

    现在,我们已经将所有内容都转移到了MS SQL,因为InnoDB性能良好,但它始终不会重用已删除的文件空间,因此InnoDB将不断增长。MS SQL express的容量限制为10gb,因此我们创建了4-8gb的页面,并在其中存储blob。我们有自己的自定义复制功能,可以使用s通过网络在三台服务器上复制文件