从SQL Server 2017中AlwaysOn高可用性组中的数据库集恢复正常的SQL数据库时遇到问题。
我将生产数据库的副本还原到另一台服务器,用作QA测试数据库,并使用不同的名称 - MyDB_demo
问题是,QA应用程序副本(与具有新开发增强功能的生产相同的代码)在某些时候会出错。
即使我的conn str指向MyDB_demo,我也会收到以下错误
[SqlException(0x80131904):目标数据库(' MyDB')位于可用性组中,当应用程序意图设置为只读时,当前可以访问连接。有关应用程序意图的详细信息,请参阅SQL Server联机丛书。]
System.Data.SqlClient.SqlConnection.OnError(SqlException exception,Boolean breakConnection,Action 1 wrapCloseInAction)+2444190
System.Data.SqlClient.SqlInternalConnection.OnError(SqlException异常,Boolean breakConnection,Action 1 wrapCloseInAction)+5775712
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj,Boolean callerHasConnectionLock,Boolean asyncClose)+285
System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior,SqlCommand cmdHandler,SqlDataReader dataStream,BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateObj,Boolean& dataReady)+4169
System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()+58
System.Data.SqlClient.SqlDataReader.get_MetaData()+89
System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds,RunBehavior runBehavior,String resetOptionsString,Boolean isInternal,Boolean forDescribeParameterEncryption)+409
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior,RunBehavior runBehavior,Boolean returnStream,Boolean async,Int32 timeout,Task& task,Boolean asyncWrite,Boolean inRetry,SqlDataReader ds,Boolean describeParameterEncryptionRequest)+2127
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior runBehavior,Boolean returnStream,String method,TaskCompletionSource`1 completion,Int32 timeout,Task& task,Boolean& usedCache,Boolean asyncWrite,Boolean inRetry)+911
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior runBehavior,Boolean returnStream,String method)+64
System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior,String method)+240
System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)+41
System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior)+12
System.Data.Common.DbDataAdapter.FillInternal(DataSet数据集,DataTable [] datatables,Int32 startRecord,Int32 maxRecords,String srcTable,IDbCommand命令,CommandBehavior行为)+139
System.Data.Common.DbDataAdapter.Fill(DataSet dataSet,Int32 startRecord,Int32 maxRecords,String srcTable,IDbCommand command,CommandBehavior behavior)+136
System.Data.Common.DbDataAdapter.Fill(DataSet dataSet)+88
MyApp.SqlHelper.ExecuteDataset(SqlConnection连接,CommandType commandType,String commandText,SqlParameter [] commandParameters)+163
MyApp.PermitFunctions.GetSystemMessages(String sp,Int32 iPermitID,Int32 iAppID,SqlConnection cn)+219
MyApp.Municipality.LoadSystemMessage()+ 3869
MyApp.Municipality.Page_Load(Object sender,EventArgs e)+101
System.Web.UI.Control.OnLoad(EventArgs e)+95
System.Web.UI.Control.LoadRecursive()+59
System.Web.UI.Control.LoadRecursive()+131
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint,Boolean includeStagesAfterAsyncPoint)+678
新恢复的数据库(名为now MyDB_demo
)中是否存在存储生产数据库的原始名称以及为什么要尝试访问它的引用?
任何建议都表示赞赏。
修改
实际上,用于恢复MyDB_demo
的服务器是AlwasyOn可用性组的辅助节点之一;它还包含生产数据库的RO副本MyDB
。
所以服务器有:
MyDB
)MyDB_demo
因此,我理解错误消息 - 如果我尝试从连接字符串直接访问生产数据库的辅助RO副本,那将是有意义的。
但我没有:连接字符串(我经过双重检查)试图连接到QA db,MyDB_demo。
以下是一些其他信息:
SQLHelper
函数ExecuteDataset
类(MS中的帮助程序类与SQL Server一起使用)中引发错误
所以看起来某种方式连接字符串MIGHT被改变(!!!)是NET应用程序本身的某种方式,并且只针对这个存储过程?
有没有人遇到过这样的事情?
谢谢
答案 0 :(得分:0)
由于奇怪的(读取:愚蠢)情况,罪魁祸首SP只在从应用程序内部调用时失败,但在SSMS中尝试运行正常时,我尝试了一种“愚蠢”的方法:我检查了它的代码,注释掉了两个字段使用像select top 1 from ..... where....
这样的子选项进行设置(实际上我将这些值替换为虚拟值)并更改了最初指定为"InspectionType" Desc
的 Order By 字段,其中删除了引号。
这样做,即使从应用程序调用,SP也突然开始正常工作。 然后我将所有更改恢复为原始版本(添加后引用并放回子选项)并且SP继续正常工作。
所以......问题解决了。 愚蠢问题的愚蠢方法(!?!?!)
无论如何,如果有人对可能发生的事情有更好的想法或解释,我会很高兴听到它
修改强>
我想我理解这个问题。 通过编辑和保存存储过程,重新编译其查询计划。 因此原始错误可能是由旧的查询计划引起的。 但为什么它引用了数据库名称?查询计划中引用的实际数据库名称是?这对我来说有点奇怪。
另一个问题(开放):
SQL Server优化程序是否检测数据库是否以高可用性模式运行,并且在优化查询时,它是否确定查询是否为只读模式并自动将其重定向到只读节点?即使连接字符串中不存在ApplicationIntent readonly参数? 因为它不是在这种情况下,即使在生产中 - 我们只是实现了AlwaysOn功能,并且正在更新应用程序以利用R / O节点。
赞赏任何评论