SQL Server中避免触发镜像SUSPEND的N种方法

背景:
我们在使用数据库的过程中,很多时候要追求性能,特别在处理大批量数据的时候更希望快速处理。那么对SQL SERVER而言,数据库实现大批量插入的优化方案,这里特别介绍通过大容量插入的一种方式。
基本原理:
简单恢复模式按最小方式记录大多数大容量操作,对于完整恢复模式下的数据库,大容量导入期间执行的所有行插入操作被完整地记录到事务日志中。如果数据导入量较大,会导致迅速填满事务日志。对于大容量导入操作,按最小方式记录比完整记录更有效,并减少了大容量导入操作填满日志空间的可能性,所以性能会得到极大的提升。
       但是,大容量导入中按最小方式记录日志的前提条件需要满足:
1. 当前没有复制表
2. 指定了表锁定:

注意:锁定是 SQL Server 数据库引擎用来对多个用户同时访问同一数据块的操作进行同步。当事务修改某个数据块时,它将持有保护所做修改的锁,直到事务结束。指定大容量导入操作的表锁定后,该表将在大容量导入操作期间采取大容量更新 (BU) 锁定。大容量更新 (BU) 锁允许多个线程将数据并发地大容量导入到同一表中,同时阻止其他不进行大容量导入数据的进程访问该表。表锁定可以通过减少表的锁争用来提高大容量导入操作的性能。
基本的理论信息还很多,这里不再累述。

在阿里云SQL SERVER的主备架构中,使用大容量插入时,使用时需要特别留意一个特性需要明确指定,如果不指定,会触发微软尚未在SQL Server 2008 R2中未修复的BUG,会导致镜像SUSPEND,那么如何来避免各种情况呢? 下面列举了一些常见的场景:
 1、通过ado.net sqlbulkcopy 方式:
只需要将SqlBulkCopy 指定SqlBulkCopyOptions.CheckConstraints就好,数据库指定AdventureWorks2008R2的Person表。举个例子:

static void Main()
{
  string srcConnString = "Data Source=(local);Integrated Security=true;Initial Catalog=testdb";
  string desConnString = "Data Source=****.sqlserver.rds.aliyuncs.com,3433;User ID=**;Password=**;Initial Catalog=testdb";

  SqlConnection srcConnection = new SqlConnection();
  SqlConnection desConnection = new SqlConnection();

  SqlCommand sqlcmd = new SqlCommand();
  SqlDataAdapter da = new SqlDataAdapter();
  DataTable dt = new DataTable();

  srcConnection.ConnectionString = srcConnString;
  desConnection.ConnectionString = desConnString;
  sqlcmd.Connection = srcConnection;

  sqlcmd.CommandText = @"SELECT top 1000000 [PersonType],[NameStyle],[Title],[FirstName],[MiddleName],[LastName],[Suffix],[EmailPromotion]
           ,[AdditionalContactInfo],[Demographics],NULL as rowguid,[ModifiedDate] FROM [testdb].[dbo].[Person]";
  sqlcmd.CommandType = CommandType.Text;
  sqlcmd.Connection.Open();
  da.SelectCommand = sqlcmd;
  da.Fill(dt);

  using (SqlBulkCopy blkcpy = new SqlBulkCopy(desConnString, SqlBulkCopyOptions.CheckConstraints))
  //using (SqlBulkCopy blkcpy = new SqlBulkCopy(desConnString, SqlBulkCopyOptions.Default))
  {
    blkcpy.BatchSize = 2000;
    blkcpy.BulkCopyTimeout = 5000;
    blkcpy.SqlRowsCopied += new SqlRowsCopiedEventHandler(OnSqlRowsCopied);
    blkcpy.NotifyAfter = 2000;

    foreach (DataColumn dc in dt.Columns)
    {
      blkcpy.ColumnMappings.Add(dc.ColumnName, dc.ColumnName);
    }

    try
    {
      blkcpy.DestinationTableName = "Person";
      blkcpy.WriteToServer(dt);
    }
    catch (Exception ex)
    {
      Console.WriteLine(ex.Message);
    }
    finally
    {
      sqlcmd.Clone();
      srcConnection.Close();
      desConnection.Close();

    }
  }

}

private static void OnSqlRowsCopied(
  object sender, SqlRowsCopiedEventArgs e)
{
  Console.WriteLine("Copied {0} so far...", e.RowsCopied);
}

2、通过jdbc  sqlbulkcopy 方式:
只需要在初始化对象时指定setCheckConstraints属性为TRUE,例如:
QLServerBulkCopyOptions copyOptions = new SQLServerBulkCopyOptions();
copyOptions.setCheckConstraints(true);
3、通过DTS/SSIS方式:
1.    import/export data方式需要先保存SSIS包,然后修改Connection Manager的属性

2.    直接使用SQL Server Business Intelligence Development Stuidio新建 SSIS包

3、通过BCP方式
1.      先将数据BCP出来 BCP ...OUT
BCP testdb.dbo.person Out "bcp_data" /t  /N /U **** /P *** /S "****.sqlserver.rds.aliyuncs.com,3433"
2.      然后将数据BCP进去 BCP...IN ,但需要指定提示:/h "CHECK_CONSTRAINTS"
BCP testdb.dbo.person In "bcp_data" /C /N /q /k /h "CHECK_CONSTRAINTS" /U *** /P *** /b 500 /S  "***.sqlserver.rds.aliyuncs.com,3433"
 4、通过bulk insert方式(在RDS不可是实现,因为不允许上传文件)

BULK INSERT testdb.dbo.person_in
FROM N'D:\trace\bcp.txt'
WITH
(
 CHECK_CONSTRAINTS
);

四种方式教你在SQL Server中避免触发镜像SUSPEND,希望对大家的学习有所帮助。

(0)

相关推荐

  • SQL Server 2008 数据库镜像部署实例之一 数据库准备

    一.目标 利用Sql Server 2008 enterprise X64,建立异步(高性能)镜像数据库,同时建立见证服务器实现自动故障转移. 二.前提条件.限制和建议 2.1.伙伴双方(主体服务器和镜像服务器)及见证服务器必须使用相同版本的Sql Server 2.2.如使用见证服务器,择须确保其系统上安装 Sql Server 2005或更高版本 2.3.在镜像服务器上创建镜像数据库时,确保制定相同的数据库名称WITH NOREBOVORY来还原主题数据库备份.另外,还必须通过 WITH N

  • SQL Server 2008 数据库镜像部署实例之二 配置镜像,实施手动故障转移

    上一篇文章已经为配置镜像数据库做好了准备,接下来就要进入真正的配置阶段 一.在镜像数据库服务器上设置安全性并启动数据库镜像会话 1.展开数据库,选择VirtualManagerDB,点击右键选择任务--镜像 2.点击配置安全性,点选是,包括见证服务器 3.去掉见证服务器,以后进行配置 4.设置主体服务器,填入端点名称为site1 5.添加镜像服务器,取端点名为site2 6.指定服务账户为域管理员账户(可以在域内事先配置) 7.创建成功,点击关闭 8.弹出对话框,选择不开始开始镜像 9.点选高性

  • SQL Server 2008 数据库镜像部署实例之三 配置见证服务器

    前面已经完成了镜像数据库的配置,并进行那个了故障转移测试.接下来将部署见证服务器,实现自动故障转移. 一.关于见证服务器 1.若要支持自动故障转移,必须在高安全性模式下配置数据库镜像会话,并且还要具有第三个服务器实例(也称为"见证服务器").见证服务器是 SQL Server 的可选实例,它能使高安全性模式会话中的镜像服务器识别出是否要启动自动故障转移.与这两个伙伴不同的是,见证服务器并不能用于数据库.见证服务器的唯一角色是支持自动故障转移. 2.为了给数据库设置见证服务器,数据库所有

  • SQL Server 2005 镜像构建手册(sql2005数据库同步镜像方案)

    一. 镜像简介 1. 简介 数据库镜像是将数据库事务处理从一个SQL Server数据库移动到不同SQL Server环境中的另一个SQL Server数据库中.镜像不能直接访问;它只用在错误恢复的情况下才可以被访问. 要进行数据库镜像所需的最小需求包括了两个不同的SQL Server运行环境.主服务器被称为"主机",第二个服务器被称作"备机".主机数据库就是你实际用着的数据库,镜像数据库就是你的数据库的备用拷贝.当事务写入你的基本服务器的时候,他们也同样被传送到并

  • SQL Server 2008 R2数据库镜像部署图文教程

    概述 "数据库镜像"是一种针对数据库高可用性的基于软件的解决方案.其维护着一个数据库的两个相同的副本,这两个副本分别放置在不同的SQL Server数据库实例中.建议使用不同位置的两台服务器来承载.在同一时刻,其中一台上的数据库用于客户端访问,充当"主体服务器"角色:而另一台则根据镜像会话的配置和状态,充当热备份服务器,即"镜像服务器角色",这两种角色不是绝对的. 优点 l 增强了数据保护功能 l 提高了数据库的可用性 l 提高了生产数据库在升级

  • SQLServer 镜像功能完全实现

    在域环境下我没配置成果,也许是域用户的原因,因为我在生产环境下搞的,更改域用户需要重启SQLServer ,所以这个方法放弃了,只能用证书形式. 环境: 主机:192.168.10.2 (代号A) 镜像:192.168.10.1 (代号B,为了一会说明方便) (条件有限我没有搞见证服务器.)两台服务器上的都是SQLServer2005 首先配置主机 主机上执行以下SQL 复制代码 代码如下: --创建主机数据库主密钥 USE master; CREATE MASTER KEY ENCRYPTIO

  • SQL Server中避免触发镜像SUSPEND的N种方法

    背景: 我们在使用数据库的过程中,很多时候要追求性能,特别在处理大批量数据的时候更希望快速处理.那么对SQL SERVER而言,数据库实现大批量插入的优化方案,这里特别介绍通过大容量插入的一种方式. 基本原理: 简单恢复模式按最小方式记录大多数大容量操作,对于完整恢复模式下的数据库,大容量导入期间执行的所有行插入操作被完整地记录到事务日志中.如果数据导入量较大,会导致迅速填满事务日志.对于大容量导入操作,按最小方式记录比完整记录更有效,并减少了大容量导入操作填满日志空间的可能性,所以性能会得到极

  • 在SQL Server中使用命令调用SSIS包的具体方法

    具体操作步骤如下: 1.首先,当然是要在Business Intelligence中设计好包,并调试通过. 2.然后,有两种方式可以在SQL Server中使用命令运行SSIS包 第一种是直接执行ssis包文件,命令如: exec xp_cmdshell 'dtexec /f "c:\test.dtsx"' 第二种是将包文件发布或者导入到Integration Services服务中,然后再执行. 发布包是在Business Intelligence中生成发布文件,并发布到Integr

  • SQL Server中查询结果超出了查询时间范围解决方法

    废话少说,直接上SQL代码(有兴趣的测试验证一下),下面这个查询语句为什么将2008-11-27的记录查询出来了呢?这个是同事遇到的一个问题,个人设计了一个例子. USE AdventureWorks2014; GO SELECT * FROM [Person].[Person] WHERE ModifiedDate >= '2008-11-26 00:00:00:000' AND ModifiedDate <= '2008-11-26 23:59:59.999' 其实如果细看过文档的话,应该

  • sql server中通过查询分析器实现数据库的备份与恢复方法分享

    sql server的备份与恢复(查询分析器) 查询分析器: 命令: 1:备份数据库命令: backup database whdb1(要备份的数据库名) to disk='d:/zwh.bak'; 2:恢复数据库命令: restore database whdb1(要恢复的数据库名) from disk='d:/zwh.bak'; 3: 备份表的命令: select * into share_20090605(备份的数据) from share(表名); 作者 庄伟鸿

  • sql server中判断表或临时表是否存在的方法

    1.判断数据表是否存在 方法一: use yourdb; go if object_id(N'tablename',N'U') is not null print '存在' else print '不存在' 例如: use fireweb; go if object_id(N'TEMP_TBL',N'U') is not null print '存在' else print '不存在' 方法二: USE [实例名] GO IF EXISTS (SELECT * FROM dbo.SysObjec

  • SQL Server中统计每个表行数的快速方法

    我们都知道用聚合函数count()可以统计表的行数.如果需要统计数据库每个表各自的行数(DBA可能有这种需求),用count()函数就必须为每个表生成一个动态SQL语句并执行,才能得到结果.以前在互联网上看到有一种很好的解决方法,忘记出处了,写下来分享一下. 该方法利用了sysindexes 系统表提供的rows字段.rows字段记录了索引的数据级的行数.解决方法的代码如下: 复制代码 代码如下: select schema_name(t.schema_id) as [Schema], t.na

  • SQL Server中关于基数估计计算预估行数的一些方法探讨

    关于SQL Server 2014中的基数估计,官方文档Optimizing Your Query Plans with the SQL Server 2014 Cardinality Estimator里有大量细节介绍,但是全部是英文,估计也没有几个人仔细阅读.那么SQL Server 2014中基数估计的预估行数到底是怎么计算的呢? 有哪一些规律呢?我们下面通过一些例子来初略了解一下,下面测试案例仅供参考,如有不足或肤浅的地方,敬请指教! 下面实验测试的环境主要为SQL Server 201

  • SQL Server中Check约束的学习教程

    0.什么是Check约束? CHECK约束指在表的列中增加额外的限制条件. 注: CHECK约束不能在VIEW中定义.CHECK约束只能定义的列必须包含在所指定的表中.CHECK约束不能包含子查询. 创建表时定义CHECK约束 1.1 语法: CREATE TABLE table_name ( column1 datatype null/not null, column2 datatype null/not null, ... CONSTRAINT constraint_name CHECK (

  • 如何捕获和记录SQL Server中发生的死锁

    方法一:利用SQL Server代理(Alert+Job)具体步骤如下:1.首先使用下面的命令,将有关的跟踪标志启用.SQL code DBCC TRACEON (3605,1204,1222,-1)  说明:3605 将DBCC的结果输出到错误日志.1204 返回参与死锁的锁的资源和类型,以及受影响的当前命令.1222 返回参与死锁的锁的资源和类型,以及使用了不符合任何 XSD 架构的 XML 格式的受影响的当前命令(比1204更进一步,SQL 2005及以上可用).-1 以全局方式打开指定的

随机推荐