昨天在检查YourSQLDba备份时,发现有台数据库做备份时出现了下面错误信息,如下所示:

<Exec>

  <ctx>yMaint.ShrinkLog</ctx>

  <inf>Log Shrink</inf>

  <Sql>

--  ========================================================================

-- Shrink of log file E:\SQL_LOG\xxxx_log.ldf

USE [xxxx]

DBCC SHRINKFILE (N'xxx_Log',      19043) with no_infomsgs           

--  ========================================================================

   </Sql>

  <err>Error 3023, Severity 16, level 2 : Backup, file manipulation operations (such as ALTER DATABASE ADD FILE) and encryption changes on a database must be serialized. Reissue the statement after the current backup or file manipulation operation is completed.

</err>

</Exec>

关于这个错误,是因为调整了作业的YourSQLDba_LogBackups的Schedule,导致YourSQLDba_FullBackups_And_Maintenance在运行时,事务日志备份已经开始了(这个数据库的事务日志由于索引重建、重组,会变得比较巨大),此时YourSQLDba_FullBackups_And_Maintenance作业执行收缩事务日志,就出现了这个错误。下面我们根据官方文档SQL Server generates a 3023 message when backup and file operations are tried at the same time来验证,测试一下这个错误出现的各类场景:

1: 当数据库正在做备份时,不允许修改恢复模式(Recovery Model)。

  •   There are limited recovery model changes allowed while backups are occurring.

 

会话1:执行备份数据库TEST

BACKUP DATABASE [TEST] TO  DISK = N'D:\DB_BACKUP\TEST_20160705.bak' WITH NOFORMAT, NOINIT,  

       NAME = N'TEST-Full Database Backup', SKIP, NOREWIND, NOUNLOAD,  STATS = 10;

GO

 

会话2:修改数据库的恢复模式。

USE [master]

GO

ALTER DATABASE [TEST] SET RECOVERY SIMPLE WITH NO_WAIT

GO

如上所示,在备份数据库TEST时,如果我们去修改数据库TEST的恢复模式,就会报这个错误,这是不允许的。

 

 

2:当数据库正在备份时,添加或删除文件是不允许的

  • You cannot add or drop files to a database while a backup is occurring.

测试验证如下

1:会话窗口1执行备份数据库TEST

BACKUP DATABASE [TEST] TO  DISK = N'D:\DB_BACKUP\TEST_20160705.bak' WITH NOFORMAT, NOINIT,  

       NAME = N'TEST-Full Database Backup', SKIP, NOREWIND, NOUNLOAD,  STATS = 10;

GO

 

2:会话窗口2执行增加日志文件时就会报错

USE [master]

GO

ALTER DATABASE [TEST] ADD FILE ( NAME = N'QCMDB_Data1', 

        FILENAME = N'D:\tmp\QCMDB_Data1.ndf' , SIZE = 5120KB , 

        MAXSIZE = 10485760KB , FILEGROWTH = 20480KB ) TO FILEGROUP [PRIMARY]

GO

-----------------------------------------------------------------------

Msg 3023, Level 16, State 2, Line 3

Backup, file manipulation operations (such as ALTER DATABASE ADD FILE) and encryption changes on a database must be serialized. Reissue the statement after the current backup or file manipulation operation is completed.

 

3:同一时刻只能允许一个事务日志备份(log backup),(当数据库正在做全备时,事务日志备份是允许的)

  • Only one log backup can happen at a time (a log backup is allowed when a full database backup is occurring).

关于这一点,同一时刻肯定只能允许一个事务日志备份,理论上不能出现两个并行的事务日志备份,这也是我纠结的地方,关于这段英文“Only one log backup can happen at a time (a log backup is allowed when a full database backup is occurring”, 是否两个事务日志备份是就会出现上述错误呢?

1:会话ID为64的窗口执行下面事务日志备份脚本

SELECT @@SPID;

BACKUP LOG [TEST] TO  DISK = N'D:\DB_BACKUP\TEST_20160705_1430_1.trn' 

    WITH NOFORMAT, NOINIT, 

NAME = N'TEST-Full Database Backup', SKIP, NOREWIND, NOUNLOAD,  STATS = 10

GO

 

2:会话ID为66的窗口执行下面事务日志备份脚本

SELECT @@SPID;

BACKUP LOG [TEST] TO  DISK = N'D:\DB_BACKUP\TEST_20160705_1430_2.trn' 

    WITH NOFORMAT, NOINIT, 

NAME = N'TEST-Full Database Backup', SKIP, NOREWIND, NOUNLOAD,  STATS = 10

GO

3:  在同时执行上面两个脚本前,最好先生成大量事务日志(我用重建TEST库里面几个大表的索引,生成了大量事务日志),然后同时执行上面两个窗口脚本(注意,由于需要人手工点击执行脚本,所以还是有点时间差),在第三个窗口查看会话信息

SELECT   [Spid] = er.session_id 

        ,[ecid] 

        ,[Database] = DB_NAME(sp.dbid) 

        ,[Start_Time]

        ,[SessionRunTime]    = datediff(SECOND, start_time,getdate())    

        ,[SqlRunTime]=     RIGHT(convert(varchar, 

                                 dateadd(ms, datediff(ms, sp.last_batch, getdate()), '1900-01-01'), 

                            121), 12)  

        ,[HostName]  

        ,[Users]=COALESCE(sp.LOGINAME, sp.nt_username)

        ,[Status] = er.status 

        ,[WaitType] = er.wait_type 

        ,[Waitime] = er.wait_time/1000   

        ,[Individual Query] = SUBSTRING(qt.text, er.statement_start_offset / 2,

                                       ( CASE WHEN er.statement_end_offset = -1

                                              THEN LEN(CONVERT(NVARCHAR(MAX), qt.text))

                                                   * 2

                                              ELSE er.statement_end_offset

                                         END - er.statement_start_offset ) / 2) 

        ,[Parent Query] = qt.text 

        ,[PROGRAM_NAME] = program_name 

FROM    sys.dm_exec_requests er

        INNER JOIN sys.sysprocesses sp ON er.session_id = sp.spid

        CROSS APPLY sys.dm_exec_sql_text(er.sql_handle) AS qt

WHERE   session_Id >= 51;

如上所示,会话64在执行事务日志备份备份时,会话66被阻塞,他在等待更新锁(LCK_M_U),至于为什么有更新更新锁,使用SQL Profile跟踪看到下面信息,你也许就明白了。

所以我基本上很难构造两个并发的事务日志备份,我尝试使用两个作业在同一时刻运行事务日志备份,也无法实现并发的事务日志备份,真怀疑能否实现这样的场景,所以在这种场景下,我并不能重现这个错误信息。当然如果你取消第二个事务日志备份也会出现这个错误信息(此处实验没有截图,请见第五种情形),所以,个人理解应该是对英文文档理解的一些偏差。

4:当数据库正在备份时,不能收缩数据库文件。当然这里的备份包括完整备份和事务日志备份。

  • You cannot shrink files while database backups are happening.

会话1: 在数据库TEST上执行事务日志备份(备份前,为了实验效果,最好生成大量事务日志)

BACKUP LOG [TEST] TO  DISK = N'D:\DB_BACKUP\TEST_20160705_1430_1.trn' 

    WITH NOFORMAT, NOINIT, 

NAME = N'TEST-Full Database Backup', SKIP, NOREWIND, NOUNLOAD,  STATS = 10

GO

 

会话2:执行下面收缩TEST事务日志的SQL

USE TEST;

GO

DBCC SHRINKFILE(2,10);

备份数据库的时候,收缩数据库文件倒是能测试通过,不知道是否与我的测试案例有关系,也没有太多精力去研究、改造测试案例。有兴趣的可以研究一下。

5:同一时刻,只能做一个数据库备份操作(当数据库完整备份时,差异、增量备份不能同时出现)

  • Only one data backup can occur at a time (when a full database backup occurs, differential or incremental backups cannot occur at the same time).

1:会话66执行下面完整备份脚本

BACKUP DATABASE [TEST] TO  DISK = N'D:\DB_BACKUP\TEST_20160705.bak' WITH NOFORMAT, NOINIT,  

 

       NAME = N'TEST-Full Database Backup', SKIP, NOREWIND, NOUNLOAD,  STATS = 10;

 

GO

 

2:会话65执行下面差异备份脚本

BACKUP DATABASE [TEST] TO  DISK = N'D:\DB_BACKUP\TEST_DIFF_20160705_01.bak' 

    WITH  DIFFERENTIAL , NOFORMAT, NOINIT,  NAME = N'TEST-Full Database Backup',

     SKIP, NOREWIND, NOUNLOAD,  STATS = 10

GO

3:会话窗口3执行下面脚本,检查SQL之间的阻塞

 

 

  SELECT wt.blocking_session_id                    AS BlockingSessesionId

        ,sp.program_name                           AS Blocking_ProgramName

        ,COALESCE(sp.LOGINAME, sp.nt_username)     AS Blocking_HostName    

        ,ec1.client_net_address                    AS ClientIpAddress

        ,db.name                                   AS DatabaseName        

        ,wt.wait_type                              AS WaitType                    

        ,ec1.connect_time                          AS BlockingStartTime

        ,wt.WAIT_DURATION_MS/1000                  AS WaitDuration

        ,ec1.session_id                            AS BlockedSessionId

        ,h1.TEXT                                   AS BlockedSQLText

        ,h2.TEXT                                   AS BlockingSQLText

  FROM sys.dm_tran_locks  AS tl WITH(NOLOCK)

  INNER JOIN sys.databases AS db  WITH(NOLOCK)

    ON db.database_id = tl.resource_database_id

  INNER JOIN sys.dm_os_waiting_tasks AS wt  WITH(NOLOCK)

    ON tl.lock_owner_address = wt.resource_address

  INNER JOIN sys.dm_exec_connections  ec1 WITH(NOLOCK)

    ON ec1.session_id = tl.request_session_id

  INNER JOIN sys.dm_exec_connections  ec2 WITH(NOLOCK)

    ON ec2.session_id = wt.blocking_session_id

  LEFT OUTER JOIN master.dbo.sysprocesses AS sp WITH(NOLOCK)

    ON SP.spid = wt.blocking_session_id

  CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1 

  CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2 

检查发现会话66(执行完整备份的会话)阻塞了会话65(差异备份的会话),但是如果我取消会话65,如下所示,就会发现出“backup, file manipulation operations (such as ALTER DATABASE ADD FILE) and encryption changes on a database must be serialized. Reissue the statement after the current backup or file manipulation operation is completed.”错误,当然,如果你不取消,不会出现这个错误,会话会一直阻塞,直到完整备份完成,然后继续执行差异备份。这个跟场景3基本上是一样的。

 

参考资料:

https://support.microsoft.com/en-us/kb/2979636

backup, file manipulation operations (such as ALTER DATABASE ADD FILE) and encryption changes on a database must be serialized.的更多相关文章

  1. 解决 Github:failed to add file / to index 问题

    参考: Github:failed to add file / to index 解决 Github:failed to add file / to index 问题 在通过Github for Ma ...

  2. 什么时候会刷新备库控制文件refresh the standby database control file?

    通过合理的设置,对于Primary的绝大数操作,都是可以传递到Physical Standby,datafile的操作是通过STANDBY_FILE_MANAGEMENT参数来控制的,但是即使STAN ...

  3. An attempt to attach an auto-named database for file

    在用VS自带的 .mdf读取(joint)时,报错: Server Error in '/' Application. An attempt to attach an auto-named datab ...

  4. ArcCatalog连接ArcSDE连接报:unable to create new database connection file,permission is denied

    参考博文:链接 ArcCatalog连接ArcSDE连接报:unable to create new database connection file,permission is denied 最近经 ...

  5. Azure SQL Database (22) 迁移部分数据到Azure Stretch Database

    <Windows Azure Platform 系列文章目录>  Azure SQL Database (19) Stretch Database 概览      Azure SQL Da ...

  6. 【待整理】MySQL alter table modify vs alter table add产生state不一样

    MySQL:5.6.35 OS:redhat5.8 今天更新数据库某些表字段,有如下两SQL: ①alter table xx modify xxxx;(表大概是77w) ②alter table s ...

  7. ASM ClassReader failed to parse class file - probably due to a new Java class file version that isn't supported yet

    严重: Context initialization failedorg.springframework.beans.factory.BeanDefinitionStoreException: Fai ...

  8. The URL "filename" is invalid. It may refer to a nonexistent file or folder, or refer to a valid file or folder that is not in the current Web

    Sharepoint Error : The URL "filename" is invalid. It may refer to a nonexistent file or fo ...

  9. Visual Studio发布Web项目报错:Unable to add 'xxx' to the Web site. Unable to add file 'xxx'. The specified file could not be encrypted.

    背景 Visual Studio下的Web项目 现象 发布时遇到Unable to add 'xxx' to the Web site.  Unable to add file 'xxx'. The ...

随机推荐

  1. iOS编译FFmpeg、kxmovie实现视频播放 (转载)

    由于FFmpeg开源框架的功能非常强大,可以播放的视频种类很多,同时添加第三方库kxmovie,实现视频播放,真的是爽爆了,因此今天来说一下关于FFmpeg在iOS手机上的一些配置过程,配置工具,还有 ...

  2. Myeclipse中导入项目后java类中汉字注释出现乱码问题(已解决)

    今天重装系统,安装了新的Myeclipse后,导入之前的项目后,,出现了乱码问题.乱码问题主要是java类中的注释,而jsp页面中汉字却完好如初: 右键项目,查看项目的编码格式,UTF-8,把java ...

  3. 原创:微信小程序源码解说:石头剪刀布(附源码下载)

    我的博客:来源链接 昨天看有个石头剪刀布的练习,就拿出来做了一下,布局的代码浪费了很多时间,果然CSS这块的还不是很熟练,下面直接上图上代码了. JS: var numAi = 0 var timer ...

  4. 关于引用PagerSlidingTabStrip无法引用的问题

    本人仅仅是在安卓学习阶段,在做左右滑动时,用ViewPager总是有各种各样的问题. 如今在github上已经有了这个开源项目PagerSlidingTabStrip,和ViewPager结合在一起会 ...

  5. 【JUC】JDK1.8源码分析之CopyOnWriteArraySet(七)

    一.前言 分析完了CopyOnWriteArrayList后,下面接着分析CopyOnWriteArraySet,CopyOnWriteArraySet与CopyOnWriteArrayList有莫大 ...

  6. OpenCV2:图像的几何变换,平移、镜像、缩放、旋转(2)

    在OpenCV2:图像的几何变换,平移.镜像.缩放.旋转(1)主要介绍了图像变换中的向前映射.向后映射.处理变换过程中浮点坐标像素值的插值算法,并且基于OpenCV2实现了两个简单的几何变换:平移和镜 ...

  7. Extjs4.0以上版本智能提示的方法

    最近,公司的BS项目要用Extjs,本屌学过JavaScript..和Jquery Easy UI  ,Jquery..可这个Extjs完全没接触过..可公司项目进度不能掉..只有苦心学习,终于写了点 ...

  8. openfire 初始密码

    openfire 初始密码 mssql2014 进入数据库,找到 ofUser 表 ,将密码字段对应的密文替换为下面的内容,则密码就是 admin ecbd03623cd819c48718db1b27 ...

  9. 【C#公共帮助类】JsonHelper 操作帮助类, 以后再也不用满地找Json了,拿来直接用

     四个主要操作类:JsonConverter .JsonHelper .JsonSplit .AjaxResult 一.JsonConverter: 自定义查询对象转换动态类.object动态类转换j ...

  10. javascript严格模式

    设立"严格模式"的目的,主要有以下几个: 1. 消除Javascript语法的一些不合理.不严谨之处,减少一些怪异行为; 2. 消除代码运行的一些不安全之处,保证代码运行的安全: ...