一、故障报错:
无法为数据库 'BPMCloud_Log' 中的对象 'dbo.T_Log_Manage'.'IX_T_Log_Manage_32' 分配空间,因为 'PRIMARY' 文件组已满。请删除不需要的文件、删除文件组中的对象、将其他文件添加到文件组或为文件组中的现有文件启用自动增长,以便增加可用磁盘空间。
Could not allocate space for object 'dbo.T_Log_Manage'.'IX_T_Log_Manage_32' in database 'BPMCloud_Log' because the 'PRIMARY' filegroup is full. Create disk space by deleting unneeded files, dropping objects in the filegroup, adding additional files to the filegroup, or setting autogrowth on for existing files in the filegroup.
数据无法写入,影响业务,我们sqlserver所有的数据文件都设置成了无限制增大,也就是磁盘有多大,他就可以增长到多大;
二、排查思路:
1)检查你的磁盘剩余空间是否足够,如果没有磁盘剩余空间,则清理磁盘,腾出空间。或者从新挂在一个新的盘,然后新增加一个文件组和文件(这样以后新建表可以指定到这个新的文件组,注意不会影响存量表)。
2)检查你的磁盘分区格式:如果是FAT16,则数据文件最大只能是2G,如果是FAT32,则数据文件最大只能是4G,改为NTFS分区则没有这种限制。
3)检查一下你有没有限制数据库文件的大小:企业管理器--右键你的数据库--属性--文件增长限制--如果有限制大小,取消限制。
4)检查你的SQL版本,SQL Server Express版本通常会对数据库文件的大小设定一个上限(如10GB),而标准版和企业版则没有这样的限制;
解决方法:更换数据库为企业版即可;
5)当磁盘空间充裕、数据库文件大小没有限制、数据库版本是企业版本、磁盘分区格式为NTFS的格式的时候,那么你就去添加一个新的数据文件给报错的文件组;
6)如果数据增长很快,并且你的数据文件增量(自动扩展)比较小,那么也可以能会报错primary 文件组过大。检查数据库文件的自动增长设置。如果自动增长设置为每次增加很小的量(如几MB),那么在数据快速增长时,数据库文件可能无法快速响应并增长以满足需求。
解决方案:增加自动增长的量,比如设置为按百分比增长(如10%)或设置为一个较大的固定值(如几百MB或更多,视具体情况而定
三、问题处理:
经过排查我们:磁盘空间充裕、数据库文件大小没有限制、数据库版本是企业版本、磁盘分区格式为NTFS,于是尝试给primary数据组添加一个次要文件,
企业管理器--右击数据库---属性---文件---添加--修改下逻辑名字和具体文件名字--最后点击确认
注意次要文件名建议以.ndf结尾,如下所示我起名字不规范!
或者命令行如下所示:
如果想添加一个无限增大的文件,省略MAXSIZE即可!
ALTER DATABASE fff
ADD FILE
(
NAME = 'fff7',
FILENAME = 'D:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER63\MSSQL\DATA\fff07.ndf',
SIZE = 5MB,
FILEGROWTH = 5MB
)
TO FILEGROUP [primary];
四、理论分析:
1、sqlserver 数据库和文件组以及文件的关系?
借助如下网络上的一张图展示
一个数据库有一个或多个文件组,其中主文件组(Primary File Group)是系统自动创建的,用户可以根据需要添加文件组。每一个文件组管理一个或多个文件,其中主文件组中包含主要数据文件(*.mdf),主文件组中也可以包含次要数据文件 。(主要数据文件是系统默认生成的,并且在数据库中是唯一的;次要数据文件是用户根据需要添加的。)除了主文件组之外,其他文件组只能包含辅助文件。
1)SQL Server数据库文件:
数据文件用于存储数据,由一个主要数据文件(.mdf)和若干个次要数据文件(.ndf)构成;
日志文件用于存储事物日志,由.ldf文件构成。
不同的文件可以分布到不同的物理硬盘上,这样便于分散硬盘IO,提高数据的读取速度。
2)文件和文件组的关系:
数据文件的组合,称作文件组(File Group),数据库不能直接设置存储数据的数据文件,而是通过文件组来指定。
SQL Server 的数据存储在文件中,文件是实际存储数据的物理实体,文件组是逻辑对象,SQL Server 通过文件组来管理文件。
- 一个文件或文件组不能由多个数据库使用。一个文件只能让一个数据库使用!。
- 一个文件只能是一个文件组的成员。
- 事务日志文件不能属于任何文件组
3)SQL Server 文件具有两种文件名类型:
- logical_file_name:logical_file_name 是在所有 Transact-SQL 语句中引用物理文件时所使用的名称。 逻辑文件名必须符合 SQL Server 标识符规则, 而且在数据库中的逻辑文件名中必须唯一。
- os_file_name:os_file_name 是包括目录路径的物理文件的名称。 它必须符合操作系统文件命名规则
SQL Server 数据和日志文件可保存在 FAT 或 NTFS 文件系统中。 由于 NTFS 在安全方面具有优势,因此,Microsoft 建议在 Windows 系统上使用 NTFS 文件系统
2、sqlserver数据库如何规划文件组和数据文件?
- 大多数数据库在只有单个数据文件和单个事务日志文件的情况下性能良好。可以单独给日志文件分配一块磁盘,数据文件一个磁盘;
- 如果使用多个数据文件,请为次要文件创建第二个文件组,并将其设置为默认文件组。 这样,主文件将只包含系统表和对象。
- 若要使性能最大化,请在尽可能多的不同可用磁盘上创建文件或文件组。 将争夺空间最激烈的对象置于不同的文件组中。
- 使用文件组将对象放置在特定的物理磁盘上。
- 将在同一联接查询中使用的不同表置于不同的文件组中。 由于采用并行磁盘 I/O 对联接数据进行搜索,所以此步骤可改善性能。
- 将最常访问的表和属于这些表的非聚集索引置于不同的文件组中。 如果文件位于不同的物理磁盘上,由于采用并行 I/O,所以使用不同的文件组可改善性能。
- 在SQL Server中,当给数据库新加了一个数据组(用户定义文件组),并且将其设置为默认数据组时,这个改变并不会自动影响已经存在的表。已存在的表及其数据(包括未来新增的数据行)默认仍然存储在它们最初被创建时指定的文件组(通常是主文件组,即PRIMARY)中。
- 在创建表、索引等数据库对象时,可以指定它们存储在哪个文件组中。如果没有指定,则这些对象将存储在默认文件组(即主文件组)
3、文件和文件组填充策略
文件组对组内的所有文件都使用按比例填充策略。 当数据写入文件组时,SQL Server 数据库引擎会按文件中的可用空间比例将数据写入文件组中的每个文件,而不是将所有数据都写入第一个文件直至其变满为止。 然后再写入下一个文件。 例如,如果文件 f1 有 100 MB 可用空间,文件 f2 有 200 MB 可用空间,则从文件 f1 中提供一个盘区,从文件 f2 中提供两个盘区,依此类推。 这样,两个文件几乎同时填满,并且可获得简单的条带化。
例如,某个文件组由三个文件组成,它们都设置为自动增长。 当文件组中所有文件的空间都已用完时,只扩展第一个文件。 当第一个文件已满,无法再向文件组中写入更多数据时,将扩展第二个文件。 当第二个文件已满,无法再向文件组中写入更多数据时,将扩展第三个文件。 当第三个文件已满,无法再向文件组中写入更多数据时,将再次扩展第一个文件,依此类推。
4、Sqlserver数据库文件个数和大小限制?
- 可以为每个数据库指定最多 32,767 个文件和 32,767 个文件组;
- 每个文件还可以指定一个最大大小。 如果没有指定最大大小,文件可以一直增长到用完磁盘上的所有可用空间;
- windows操作系统中NTFS文件系统的最大单个文件大小理论上是 2^64-1字节,即约 16EB(1EB=1024PB=1048576TB)
5、数据文件自动增长导致的问题
当数据文件爆满,没有空间存储数据时,此时执行insert命令,这会导致数据文件的增长。如果filegrowth选项设置的过大,会导致SQL Server耗费较长时间来实现文件的增长,在数据文件增长时,该文件是不能访问的,因此,即使用户仅插入一条数据,也要等待很长时间才能完成查询,对用户来说,体验不友好。
数据文件增长是非常耗费系统资源和影响性能,如果设置SQL Server 自动增长,可能会导致系统性能不够稳定,所以,应该预测可能的空间使用需求,并提前做好规划。尽量避免空间用尽而使得SQL Server不得不自动增长的现象发生。同时也要确保每一次自动增长都能够在可接受的时间内完成,及时满足客户端应用的需求
总结:
1、一般我们建议给sqlsever数据库服务器规划两个物理磁盘,一个是存数据,一个存事务日志;
2、如果数据量不大,不超过1t,建议直接使用默认的主文件组和主文件存储数据即可,如果数据量大,需要使用多个数据文件的时候,请为次要文件创建第二个文件组,并将其设置为默认文件组。 这样,主文件将只包含系统表和对象;
3、尽管有些时候我们设置了某个文件为无限增大,理论上文件可以一直增长到用完磁盘上的所有可用空间为止,但是有的情况下并非如此,磁盘还有空间呢,也报错the 'PRIMARY' filegroup is full,这个时候建议直接给PRIMARY文件组添加次要文件即可!