此功能允许将非结构化文档添加到数据库中。您可以在 SQL Server 数据库中存储图像、PDF、视频或任何您想要的文件。它允许您拥有图像的事务一致性。
我们曾与大型 FILESTREAM SQL Server 实施合作过。我将展示此功能如何导致许多问题。以及您可以采取哪些措施来解决这些问题。
让我们从环境描述开始,这样您会了解一些背景信息:
数据大小 – 50TB+
实体业务
营业时间为周一至周六上午 8 点至下午 6 点,覆盖所有 大型数据库 美国时区。周日休息
我们在 FILESTREAM DB 中存储什么:文档(PDF,MS Word 文件),图片(jpg,jpeg,gif,bmp 等)
SQL Server 安装是什么样的?4 节点 SQL Server 故障转移地理分布式群集
另一台用于灾难恢复 (DR) 的服务器
大约 15 个用户数据库。
最大的数据库小于 2TB
所有文件流数据都驻留在用户数据库之外的单独数据库中
存储:具有三个级别磁盘速度的 SAN
快速 – SSD
中型 – 15,000 RPM 驱动器
速度慢 – 7,500 RPM 硬盘
何时 MS SQL FILESTREAM是一个好的解决方案?
如果 3-5 年内数据大小将增长到 1TB 以下 – FILESTREAM 可能可以发挥作用。
如果您需要对存储的文档或图像进行时间点恢复。
如果您存储小文件(每个文件小于 1MB)。请查看此 大型数据库 白皮书进行确认。其中提到了文件大小。
如果一切属实——那就去做吧!
您在下面读到的所有问题并非都可以归咎于 SQL Server。
有些数据库管理很糟糕。
这是一个业务问题——业务量每 9 个月翻一番,但没有人为这种类型的数据爆炸做好计划。
有些编码本来可以更好。
SAN 和一些网络使一些事情变得过于复杂。
有些人已经尽了最大努力,但结 vnpay 数据库 果却更糟。
重点是——这种解决方案的边缘很锋利,如果不小心,你会割伤自己。
SQL Server FILESTREAM 的问题和一些解决方案
备份
DB 备份持续时间。
随着 FILESTREAM 数据库的增长,我们无法再快速进行完整数据库备份。备份持续时间开始超过 24 小时,然后很快 48 小时就不够了。最后,完整备份将于周五下午 6 点开始,而周一早上,它仍在进行中。
修复。加快 SQL 备份。将备份拆分为 32 个文件很有帮助。此外,更改BUFFERCOUNT, BLOCKSIZE和– 也很有帮助。请在此处MAXTRANSFERSIZE 查看更多信息。
您如何调整备份速度,如何找到最适合您情况的备份文件数、和的数字BUFFERCOUNT?BLOCKSIZE ……MAXTRANSFERSIZE测试。我们进行了很多次。
我们测试了一个非常低的数字(BUFFERCOUNT),然后得到了很高的数字。我测量并记录了数据。找到了一个最佳参数。
然后转到下一个参数(BLOCKSIZE)。找到了最佳参数。转到下一个。您明白了。
当所有参数都有最佳值时,我们将它 大型数据库 们全部合并。我不记得确切的数字,但它大大缩短了备份时间。缩短了 30-40% 左右。
备份大小。
备份大小变得难以管理。由于设计方式的原因,我们不得不使用完整备份。
愚蠢的备份。
这是我的“技术术语”。这意味着每次完整备份都包含 10 年前的数据。继续备份不会改变的数据是愚蠢的吗?但要达到只备份最近数据的程度,需要做一些工作——稍后会详细介绍。
SAN 存储。
由于这是一个具有共享存储和有限 SAN 空间 tw 列表 的集群,我们开始遇到 SAN 容量问题。
您不仅必须存储大型数据库。然后,您至少需要 大型数据库 两个完整备份。而且数据压缩效果不佳。因为存储的数据都是 PDF/jpg 等 – 已经压缩。因此,现在我们需要数据库大小乘以三……至少。
添加差异和事务备份。您可以看到 50TB 数据库很容易需要 150-200TB 的 SAN 存储。这不是每个人都能拥有的奢侈品。
低级环境。
将 FILESTREAM 数据库还原到 DEV
QA、UAT 环境变得不可能。这不仅是因为所需的时间几乎是“永远”。而且,低级环境通常没有那么多 TB 可供您使用。
修复– 我们将部署由 T-SQL 脚本构建的数据库,而不是备份和恢复来刷新 DEV、QA 和 UAT。
然后运行另一个脚本,将文档填充到每个表中的 100,000 条记录。这样,我们只需要 1GB,而不是 50TB。
SAN 速度。
这不是 SQL Server 问题。但 SAN 配置严重错误。吞吐量数字很糟糕。在某些时候,传输速度比 USB2 速度慢(低于 45MB/s)。是的……
如果您还在这里,您可能仍在考虑将 FILESTREAM 用于您的项目。继续阅读,因为到最后您可能不太喜欢此功能。
分区
备份 10 年前的数据。
在某个时候,我们意识到唯一被修改的数据是过去 90 天内存储的文档。如果我们可以将数据划分为单独的文件组 (FG),我们可能只备份过去 90 天的数据。而不是 10 年的数据。现在我们开始讨论!
你好,SQL 分区!
我们对数据进行了分区,并将文件组 (FG) 拆分为每年。将这些文件组设置为 READ_ONLY。备份 READ_ONLY FG 一次。这包含了大部分存储空间。
留下了过去 90 天的活动分区。现在可以将此 FG 移至更快的 SAN 层,因为我们不再需要大量的空间。
一些分区的优点和缺点:
缺点:更复杂。
缺点:现在需要特别注意不要损坏 READ_ONLY 备份。因为如 将 sql server 数据从 azure 同步到本地 sql server 的不同方法 果损坏,我们可能会丢失完整备份。
缺点:必须使用 SQL Enterprise 版本。但我们已经使用了该版本。没有问题。
另外:可以使用SQL Server 数据库部分可用性(忽略该文档 是关于 SQL 2005 的 – 其中大部分内容相关并展示了当今的运作方式)。部分可用性非常棒。如果我们必须从备份中恢复 PROD,我们可以恢复 PRIMARY 文件组 (FG),加上包含过去 90 天数据的 FG,并且 DB 现在可用于进行事务。恢复旧数据可以在后台继续进入那些 READ_ONLY FG,同时 PROD 可以正常运行。
但在实现分区之前,我们必须撤消别人失败的分区尝试。
防病毒和数据库损坏
当我们开始处理这个 FILESTREAM DB 时,首先要做的事情之一就是运行DBCC CHECKDB。
发现了大约 40 个损坏错误。这些错误无法通过 SQL 命令修复。
我们最终致电微软支持,他们的建议是将所有数据导出到新数据库中。然后扔掉旧的。
– 嗯……是的……那大概需要嗯……永远……谢谢,但我们将其作为最后的选择。
我将这个损坏的数据库恢复到另一台服务器上,并测试了几项。并且能够修复损坏!!哈哈!
基本上,问题在于 FS 将图像存储在磁盘上。采用奇怪的目录结构。当 DB 中的记录被删除时,磁盘上的文件却没有被删除。这让 SQL Server 认为 – DB 已损坏。
我所要做的就是弄清楚如何将损坏的记录转换为目录路径(不,我现在不记得怎么做了),然后进入磁盘并删除该路径。重新运行DBCC CHECKDB,然后砰!我少了一个错误。