感谢您的阅读,此博客的文章都是原著,转载请您保留相关链接,谢谢!

目标:

      主机做了MirrorReplication,当主机出现问题时,ReplicationMirror实现自动的故障转移(Mirror Replication都切换到备机,而当主机

       重新启动后,自动充当备机的角色)。

 

环境:

          五台虚拟机,配置均为Windows2008 Enterprise + SQLServer2008R2 Enterprise

          08R201Mirror 见证机(WITNESS)           IP:192.168.56.101

          08R202:主机(Rep+Mirror                  IP:192.168.56.102

          08R203Rep分发机                               IP:192.168.56.103

          08R204Rep订阅机                               IP:192.168.56.104

          08R205:镜像机(Mirror                       IP:192.168.56.105

 

步骤:

配置有见证服务器的镜像

  1. 创建证书和Endpoint

     08R202(Master) 上运行下面的脚本:

 --主机执行:
    USE master;
    CREATE MASTER KEY ENCRYPTION BY PASSWORD = '123456abc';
    CREATE CERTIFICATE HOST_A_cert WITH SUBJECT = 'HOST_A certificate' , 
    START_DATE = '11/08/2010',EXPIRY_DATE = '10/31/2099';

--主机执行:
    CREATE ENDPOINT Endpoint_Mirroring 
    STATE = STARTED 
    AS 
    TCP ( LISTENER_PORT=5022 , LISTENER_IP = ALL ) 
    FOR 
    DATABASE_MIRRORING 
    ( AUTHENTICATION = CERTIFICATE HOST_A_cert , ENCRYPTION = REQUIRED ALGORITHM AES , ROLE = ALL );

--主机执行:

    BACKUP CERTIFICATE HOST_A_cert TO FILE = 'D:\HOST_A_cert.cer';    

      08R205(Mirror) 上运行下面的脚本:

--备机执行:
    USE master;
    CREATE MASTER KEY ENCRYPTION BY PASSWORD = '123456abc';
    CREATE CERTIFICATE HOST_B_cert WITH SUBJECT = 'HOST_B certificate', 
    START_DATE = '11/08/2010',EXPIRY_DATE = '10/31/2099';

--备机执行:
    CREATE ENDPOINT Endpoint_Mirroring 
    STATE = STARTED 
    AS 
    TCP ( LISTENER_PORT=5022 , LISTENER_IP = ALL ) 
    FOR 
    DATABASE_MIRRORING 
    ( AUTHENTICATION = CERTIFICATE HOST_B_cert , ENCRYPTION = REQUIRED ALGORITHM AES , ROLE = ALL );

--备机执行:
    BACKUP CERTIFICATE HOST_B_cert TO FILE = 'D:\HOST_B_cert.cer';

      08R201(WITNESS) 上运行下面的脚本:

--见证机执行
USE master;
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '123456abc';
CREATE CERTIFICATE HOST_W_cert WITH SUBJECT = 'HOST_W certificate', 
START_DATE = '11/08/2010',EXPIRY_DATE = '10/31/2099';

--见证机执行
CREATE ENDPOINT Endpoint_Mirroring 
STATE = STARTED 
AS 
TCP ( LISTENER_PORT=5022 , LISTENER_IP = ALL ) 
FOR 
DATABASE_MIRRORING 
( AUTHENTICATION = CERTIFICATE HOST_W_cert , ENCRYPTION = REQUIRED ALGORITHM AES , ROLE = ALL );

--见证机执行
BACKUP CERTIFICATE HOST_W_cert TO FILE = 'D:\HOST_W_cert.cer';
  1. 交换证书

     将HOST_B_cert.cerHOST_W_cert.cer拷贝到 08R202 机器的”D:\Cert目录;

     将HOST_A_cert.cerHOST_W_cert.cer拷贝到 08R205 机器的”D:\Cert目录;

     将HOST_A_cert.cerHOST_B_cert.cer拷贝到 08R201 机器的”D:\Cert目录;

 

     08R202(Master) 上运行下面的脚本:

--Master
CREATE LOGIN HOST_B_login WITH PASSWORD = '123abc!@#';
CREATE USER HOST_B_user FOR LOGIN HOST_B_login;
CREATE CERTIFICATE HOST_B_cert AUTHORIZATION HOST_B_user FROM FILE = 'D:\Cert\HOST_B_cert.cer';
GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO [HOST_B_login];
    
CREATE LOGIN HOST_W_login WITH PASSWORD = '123abc!@#';
CREATE USER HOST_W_user FOR LOGIN HOST_W_login;
CREATE CERTIFICATE HOST_W_cert AUTHORIZATION HOST_W_user FROM FILE = 'D:\Cert\HOST_W_cert.cer';
GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO [HOST_W_login];

     08R205(Mirror) 上运行下面的脚本:

--Mirror
CREATE LOGIN HOST_A_login WITH PASSWORD = '123abc!@#';
CREATE USER HOST_A_user FOR LOGIN HOST_A_login;
CREATE CERTIFICATE HOST_A_cert AUTHORIZATION HOST_A_user FROM FILE = 'D:\Cert\HOST_A_cert.cer';
GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO [HOST_A_login];
    
CREATE LOGIN HOST_W_login WITH PASSWORD = '123abc!@#';
CREATE USER HOST_W_user FOR LOGIN HOST_W_login;
CREATE CERTIFICATE HOST_W_cert AUTHORIZATION HOST_W_user FROM FILE = 'D:\Cert\HOST_W_cert.cer';
GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO [HOST_W_login];

     08R201(WITNESS) 上运行下面的脚本:

--WITNESS
CREATE LOGIN HOST_A_login WITH PASSWORD = '123abc!@#';
CREATE USER HOST_A_user FOR LOGIN HOST_A_login;
CREATE CERTIFICATE HOST_A_cert AUTHORIZATION HOST_A_user FROM FILE = 'D:\Cert\HOST_A_cert.cer';
GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO [HOST_A_login];
    
CREATE LOGIN HOST_B_login WITH PASSWORD = '123abc!@#';
CREATE USER HOST_B_user FOR LOGIN HOST_B_login;
CREATE CERTIFICATE HOST_B_cert AUTHORIZATION HOST_B_user FROM FILE = 'D:\Cert\HOST_B_cert.cer';
GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO [HOST_B_login];
  1. 备份还原数据库

     08R202(Master) 上备份数据库:

  BACKUP DATABASE RepTest TO DISK='D:\temp\RepTest.bak'
  BACKUP LOG RepTest TO DISK='D:\temp\RepTest.trn'

     将备份文件拷贝到 08R205(Mirror) 上做还原(最好以SA帐号登录,使得数据库所有者为”SA“):

  --RESTORE 
RESTORE DATABASE RepTest FROM  DISK = N'D:\RepTest.bak' 
WITH  FILE = 1,  
MOVE N'RepTest' TO N'D:\Data\RepTest.mdf',  
MOVE N'RepTest_log' TO N'D:\Data\RepTest_log.ldf',   
NORECOVERY,  NOUNLOAD,  STATS = 10
GO

RESTORE LOG RepTest FROM DISK ='D:\RepTest.trn' WITH NORECOVERY
  1. 建立镜像

      在08R205(Mirror) 上执行:

--Mirror
ALTER DATABASE RepTest SET PARTNER = 'TCP://192.168.56.102:5022';

     在 08R202(Master)上执行:

ALTER DATABASE RepTest SET PARTNER = 'TCP://192.168.56.105:5022';

ALTER DATABASE RepTest SET WITNESS = 'TCP://192.168.56.101:5022';

ALTER DATABASE RepTest SET SAFETY FULL 

     到此,镜像已经建立完成。

 

配置Replication(事务型复制)

     Replicaiton不做具体的搭建过程,只做几点说明:

     1.  08R20208R205都需要搭建到08R203Distribution

      

     2.  08R20208R205上的发布库的所有者必须为“SA,否则切换会出现如下错误:The process could not execute 'sp_replcmds' on 'WIN-08R205'.

     3.  08R203分发机上配置文件需要做如下修改(配置故障转移Partner):

    --配置复制故障转移参数
    --查看代理配置,在分发服务器运行
    exec sp_help_agent_profile
    --Agent_Type含义
    --1 = Snapshot Agent; 2 = Log Reader Agent; 3 = Distribution Agent; 
    --4 = Merge Agent; 9 = Queue Reader Agent.
    --对于事务复制,需查看Agent_Type=1,2的Profile_id
    
    --对于事务复制,需要配置快照代理(Snapshot Agent)和日志读取代理(Log Reader Agent)
    exec sp_add_agent_parameter @profile_id = 1, 
    @parameter_name = N'-PublisherFailoverPartner', 
    @parameter_value = N'WIN-08R205'--镜像服务器名称
    
    exec sp_add_agent_parameter @profile_id = 2, 
    @parameter_name = N'-PublisherFailoverPartner', 
    @parameter_value = N'WIN-08R205'--镜像服务器名称

       修改完成后,记得重启Agent服务,使之生效。

      4.  08R202创建到08R204的同步链。

 

模拟故障转移并观察结果

     1.  暂停08R202SQLServer服务;

     2.  到08R205上观察镜像和同步链是否转移过去了;

      

      3.  如果同步链正常,修改某个表中的数据,看是否能同步到08R204上;

      4.  重新启动08R202SQLServer服务,看其是否成为了镜像机;

      

       5.  如果一起都正常,那恭喜啦,我们的测试成功。

 

 

 

posted @ 2012-05-25 17:40 飞洋过海 阅读(843) 评论(4) 编辑

需求

      安装数据库时,将字符集安装成了“SQL_Latin1_General_CP1_CI_AS”,现在需要将其更改为“Chinese_PRC_CI_AS”。

 

 

 

方法

           重新生成系统数据库 ,然后还原配置信息。

 

局限

重新生成 master、model、msdb 和 tempdb 系统数据库时,将删除这些数据库,然后在其原位置重新创建。 如果在重新生成语句中指定了新排序规则,则将使用该排序规则设置创建系统数据库。 用户对这些数据库所做的所有修改都会丢失。 例如,您在 master 数据库中的用户定义对象、在 msdb 中的预定作业或在 model 数据库中对默认数据库设置的更改都会丢失。

 

前期准备

在重新生成系统数据库之前执行下列任务,以确保可以将系统数据库还原至它们的当前设置。

  1. 记录所有服务器范围的配置值。
    SELECT * FROM sys.configurations;
  2. 记录所有应用到 SQL Server 实例和当前排序规则的 Service Pack 和修补程序。 重新生成系统数据库后必须重新应用这些更新。
    SELECT
    SERVERPROPERTY('ProductVersion ') AS ProductVersion,
    SERVERPROPERTY('ProductLevel') AS ProductLevel,
    SERVERPROPERTY('ResourceVersion') AS ResourceVersion,
    SERVERPROPERTY('ResourceLastUpdateDateTime') AS ResourceLastUpdateDateTime,
    SERVERPROPERTY('Collation') AS Collation;
  1. 记录系统数据库的所有数据文件和日志文件的当前位置。 重新生成系统数据库会将所有系统数据库安装到其原位置。 如果已将系统数据库数据文件或日志文件移动到其他位置,则必须再次移动这些文件。
    SELECT name, physical_name AS current_file_location
    FROM sys.master_files
    WHERE database_id IN (DB_ID('master'), DB_ID('model'), DB_ID('msdb'), DB_ID('tempdb'));
  1. 如果将 SQL Server 的实例配置为复制分发服务器,请找到该分发数据库的当前备份。
  2. 确保您有重新生成系统数据库的相应权限。 必须是 sysadmin 固定服务器角色的成员才能执行此操作。 有关详细信息,请参阅服务器级别角色
  1. 将原数据库的帐号、JOB等与系统数据库相关的信息全部备份起来(可以先生成相应的脚本),分离掉所有用户库。

 

重新生成系统数据库

运行下面的命令就可重建数据库(根据您的系统,需要做相应的修改 ;D:/Setup 是数据库安装文件所在的路径)

D:/Setup /QUIET /ACTION=REBUILDDATABASE /INSTANCENAME=MSSQLSERVER /SQLSYSADMINACCOUNTS=Administrators /SAPWD=XXXX /SQLCOLLATION=Chinese_PRC_CI_AS

参数说明:

参数名称

说明

/QUIET 或 /Q

指定在没有任何用户界面的情况下运行安装程序。

/ACTION=REBUILDDATABASE

指定安装程序将重新创建系统数据库。

/INSTANCENAME=InstanceName

SQL Server 实例的名称。 对于默认实例,请输入 MSSQLSERVER

/SQLSYSADMINACCOUNTS=accounts

指定要添加到 sysadmin 固定服务器角色中的 Windows 组或单个帐户。 指定多个帐户时,请用空格将帐户隔开。 例如,请输入 BUILTIN\Administrators MyDomain\MyUser 当您在帐户名称内指定包含空格的帐户时,用双引号将该帐户引起来。 例如,输入 NT AUTHORITY\SYSTEM

[ /SAPWD=StrongPassword ]

指定 SQL Server sa 帐户的密码。 如果实例使用混合身份验证(SQL Server Windows 身份验证)模式,则此参数是必需的。

安全说明

安全说明

sa 帐户是一个广为人知的 SQL Server 帐户,并且经常成为恶意用户的攻击目标。 因此,为 sa 登录名使用强密码非常重要。

不要为 Windows 身份验证模式指定此参数。

[ /SQLCOLLATION=CollationName ]

指定新服务器级排序规则。 此参数可选。 如果没有指定,则使用服务器的当前排序规则。

重要说明

重要提示

更改服务器级排序规则不会更改现有用户数据库的排序规则。 默认情况下,所有新创建的用户数据库都将使用新排序规则。

有关详细信息,请参阅设置或更改服务器排序规则

 

安装程序完成后,将显示如下信息,(你也可以检查 Summary.txt 日志文件以验证重新生成过程是否成功完成。 此文件位于 C:\Program Files\Microsoft SQL Server\100\Setup Bootstrap\Logs)。

 

检查和修复

系统数据库恢复完成后,先检查一下字符集是否按要求恢复了:

字符集更改完成后,我们还需要附加上用户数据库,将原来的帐号和JOB等信息以及配置信息做修复,还需要修复孤立帐号等。

 

附加说明

  如果您只需要更改某个用户数据库的字符集,非常简单:

  --修改数据库字符集

  alter database DBName collate Chinese_PRC_CI_AS

 

注意

    以上恢复是在SQLServer2008R2版本上面完成的,不同的版本您可能需要做一些修改,另外此方法存在一定的风险(主要是在重建数据库阶段),产品环境

最好还是重新安装数据库。

posted @ 2012-05-15 14:56 飞洋过海 阅读(789) 评论(0) 编辑

     很早之前就有朋友问过我,能否按业务的优先等级分配SQLServer的资源,使得不同的应用能得到不同的响应,SQLServer2008之前对这个需求貌似没有什么

解决方法,不过从SQLServer2008开始,这个需求就变得很简单了,SQLServer直接就为我们提供了按用户的要求分配资源的能力,下面我们就来介绍这个功能。

 

    SQLServer资源调控器分成三个部分:资源池、负载组和分类器函数;资源池为我们提供了将资源(CPU、Memory等)划分到不同的载体中,负载组承载负载并

将这些负载映射到资源池,分类器函数将不同的会话映射到不同的负载组中。

 

资源池:

 08提供了两种预先定义好的资源池

 内部池:内部池只用于SQLServer数据库引擎,系统管理员不能改变和设置;

 默认池:默认池用于没有分配资源池的各种负载,因此,如果你不指定资源调控器,全部负载将使用默认池。默认池也不能改变或删除,但是可以修改它的资源上

            下限。

 资源池上下限要求:

    各个资源池的下限之和不能超过100%,因为SQLServer会尽力满足每个下限;

    上限可以设置为下限和100%之间的任意值。


以下是关于资源池的基本操作:

--创建资源池
Create Resource Pool UserQueries with(max_cpu_percent=100) --删除资源池
drop Resource Pool UserQueries

 

负载组:

     负载组可以让管理员轻松地监控资源使用情况,在不同的资源池之间移动某类负载。

     负载组被映射到资源池上,一个资源池可以有零个或更多负载组,一个负载组为一组用户会话提供一个桶。

--创建负载组
Create WorkLoad Group DailyExecReports USING UserQueries;

--删除负载组
drop WorkLoad Group DailyExecReports

 

分类器函数:

     分类器函数将接入的会话分类,并为会话的请求和查询分配一个负载组。你可以根据连接串中的任意属性(IP地址/应用程序名、用户名等)分别分配组。

按以下条件分配组:

  •   一个用户接入并使用SAP_Login登录名,则为他分配SAPUsers负载组;
  •   一个用户接入程序名是SSMS,则让它成为AdhocAdmin负载组的一员;
  •   一个用户是ReportUsers组一员,则让它成为DaliyExecReports负载组一员;
  •   一个用户以共享内存连接,并在NightlyAdmin用户组中,则分配NightlyMaintanceTask组。
--创建资源池
Create Resource Pool AdminQueries with(max_cpu_percent=100)
Create Resource Pool UserQueries with(max_cpu_percent=100)

--创建负载组
Create WorkLoad Group NightlyMaintenanceTasks USING AdminQueries;
Create WorkLoad Group AdhocAdmin USING AdminQueries;
Create WorkLoad Group SAPUsers USING UserQueries;
Create WorkLoad Group DailyExecReports USING UserQueries;

--创建分类器函数
    USE master
    GO
    create FUNCTION class_func_1()
    Returns sysname with schemabinding
    begin
      Declare @val sysname
      --Handle workload groups defined by login names
      IF SUSER_SNAME()='SAP_Login'
        begin
          SET @val='SAPUsers';
          Return @val;
        end
        
      IF APP_NAME() like 'Microsoft SQL Server Management Studio%'
        begin
          Set @val='AdhocAdmin';
          Return @val;
        end
      
      IF IS_MEMBER('ReportUsers')=1
        begin
          Set @val='DailyExecReports';
          Return @val;
        end
        
      IF CONNECTIONPROPERTY('net_transport')='Shared memory' and IS_MEMBER('NightlyAdmin')=1
        begin
          Set @val='NightlyMaintenanceTasks';
          Return @val;
        end
        
      Return @val;
    end

绑定分类器函数:

--将分类器函数绑定到资源调控器上
  Alter Resource Governor With(Classifier_Function=dbo.class_func_1);

启用和禁用分类器函数:

--启用
 ALter Resource Governor Reconfigure;
--禁用
 ALTER RESOURCE GOVERNOR DISABLE;

 

测试:

现在我们分别使用SAP_Login和sysadmin用户调用此脚本

--测试脚本(分别使用SAP_Login和sysadmin用户调用此脚本)
  set nocount on 
  Declare @i int=100000000;
  Declare @s varchar(100),@count int;
   While @i>0
   begin
    Select @s=@@VERSION;
    select @count=COUNT(0) from sys.sysobjects 
    set @i=@i-1;
   end

 

通过性能计数器查看资源分配:

 我们可以选择性能计数器的资源统计:SQL Server:Resource Pools Stats;

 我们先将资源池按一比一的比例分配:

Create Resource Pool AdminQueries with(max_cpu_percent=100)
Create Resource Pool UserQueries with(max_cpu_percent=100)

 运行测试脚本,显示的CPU利用率图如下

 现在将资源分配做如下调整:

Create Resource Pool AdminQueries with(max_cpu_percent=10)
Create Resource Pool UserQueries with(max_cpu_percent=90)

 再次运行测试脚本,显示的CPU利用率图如下

可以看到,当我们调整资源后,两个Session中运行同样的脚本,它们所使用的资源差别很大,这样就达到了根据不同的应用分配不同的资源的目的。

 

DMV查看资源池:

--查看Session所在的资源池
    select s.session_id,s.login_name ,s.program_name,s.group_id,g.name 
    from 
    sys.dm_exec_sessions s join sys.dm_resource_governor_workload_groups g
    on s.group_id=g.group_id
    where session_id>50
--查看资源池情况
    select * from sys.dm_resource_governor_resource_pools

可以看到,我们创建的两个资源池(还有两个是系统资源池和默认资源池),而且不同的Session对应到了不同的资源池中。

 

 

posted @ 2012-05-07 21:51 飞洋过海 阅读(903) 评论(1) 编辑

 

   转储的英文单词是dump,但这边我们说的dump不是SQL Server本身的DUMP备份命令,而是指通过sqldumper.exe中的dump。那什么是dump呢,dump指的是将某种

内容转换为另外一种更具可读性的方式。在ORACLE中,有专门的dump命令可以dump出数据文件等的内容,其trace也相当于另外一种dump。通过dump,我们便可以了解

整个系统的运行原理。

 

SQL Server这方面的资料很少,当然,这也符合了微软不开源的策略。不过这几年来,关于这方面的资料比较多了,通过google可以获得相关的内容。

最早对此感兴趣的是碰到了很多人经常问的.mdmp文件,mdmp的叫mini dmp,也可以叫memory dmp,这是由于SQL Server 在运行过程中,遇到了一些bug或者错误而进行

转储以便记录出错信息的文件。一般对这类文件的处理,都是建议打包后提交给微软分析的。在无法获得微软帮助的情况,就需要自己对此类文件进行分析了,然后找出问题原因,

从而进行解决。

一、SQLDumper.exe介绍

前面介绍了SQL Server 会在运行时自动产生一些dump文件,我们也可以手工产生dump文件,产生dump文件的方式,就是通过Sqldumper来进行的。

自 SQL Server 2000 Service Pack 3 (SP3) 起,Microsoft SQL Server 2000 中开始附带 Sqldumper.exe。Sqldumper.exe 可根据任一 Microsoft Windows 应用程序的

需要生成转储文件。Sqldumper.exe不仅可以转储SQL Server,还可以转储其他的windows application。

我使用的环境是SQL Server 2008,因此SQLDumper位于C:\Program Files\Microsoft SQL Server\100\Shared下,我们可以运行SQLDumper /? 查看其使用方法

C:\Program Files\Microsoft SQL Server\100\Shared>SqlDumper.exe /?
Usage: SqlDumper.exe [ProcessID [ThreadId [Flags[:MiniDumpFlags] [SqlInfoPtr [DumpDir [ExceptionRecordPtr [ContextPtr [E
xtraFile]]]]]]]] [-I<InstanceName>] [-S<ServiceName>][-remoteservers:[print|dump|freeze|resume|remote:guid\dumporigin\si
gnature\localId\port\operationType]]
  Flags:
  dbgbreak = 0x0001
  nominidump = 0x0002
  validate_image = 0x0004
  referenced_memory = 0x0008
  all_memory = 0x0010
  dump_all_threads = 0x0020
  match_file_name = 0x0040
  no_longer_used_flag = 0x0080
  verbose = 0x0100
  wait_at_exit = 0x0200
  send_to_watson = 0x0400
  defaultflags = 0x0800
  maximumdump = 0x1000
  mini_and_maxdump = 0x2000
  force_send_to_watson= 0x4000
  full_filtered_dump = 0x8000

  MiniDumpFlags:
  Normal = 0x0000
  WithDataSegs = 0x0001
  WithFullMemory = 0x0002
  WithHandleData = 0x0004
  FilterMemory = 0x0008
  ScanMemory = 0x0010
  WithUnloadedModules = 0x0020
  WithIndirectlyReferencedMemory = 0x0040
  FilterModulePaths = 0x0080
  WithProcessThreadData = 0x0100
  WithPrivateReadWriteMemory = 0x0200
  WithoutOptionalData = 0x0400
  WithFullMemoryInfo = 0x0800
  WithThreadInfo = 0x1000

从上面的命令可以看出,要想对某一application进行dump,需要先找出其pid(processes id),然后加上一些Flags的控制标识来控制dump内容。

比如,我现在想对我的SQL Server 进行dump,先找到SQL Server 的pid 为900,想dump所有的内存信息,那就可以用下面的命令来进行:
C:\Program Files\Microsoft SQL Server\100\Shared>SqlDumper.exe 900 0x0010
其中,0x0010 表示all_memory,这样,在C:\Program Files\Microsoft SQL Server\100\Shared目录下会产生SQLDmprnnn.mdmp的文件,这就是转储文件(.mdmp)。

以下是几个比较常见的dump 标识:

0x0120 - Minidump,这个flag只dump 一个Process的堆栈和载入模块的信息,这是最小的转储方式,也是SQL Server自动产生dump文件的方式。

0x01100 – Full Dump,这个flag会转储Process的整块信息,如果在64位的系统上,其文件大小还是很大的。

0x8100 – Filtered Dump,这个flag用来转储用于于其他服务器用途(包括过程缓存)的内存信息

二、SQL Server方式的DUMP

使用Sqldumper只是手工产生dump文件的一种方式,当然,产生dmp文件的方式还是很多的,SQL Server内部也提供了这样的工具。主要是DBCC STACKDUMP 和dbcc dumptrigger 这

两个命令。当然还可以通过TraceFlag来控制是否产生dmp文件或者遇到什么错误时才产生文件。比如,我们想产生一个Full Dump,必须打开Trace Flag 2544 和 2546

dbcc traceon(2544, -1) 

go

dbcc traceon(2546, -1) 

go

dbcc stackdump



如果想让SQL Server 只针对 某个错误而产生转储文件,可以使用dbcc dumptrigger,下面是一个例子

dbcc traceon(2544, -1) 
go
dbcc traceon(2546, -1) 
go
--设置dump的触发器为错误802
dbcc dumptrigger('set', 802) 
go
-- 查看当期的dump触发器内容
dbcc traceon(3604, -1) 
go
dbcc dumptrigger('display') 
go
dbcc traceoff(3604, -1) 
go
-- 关闭当期的dump触发器。
dbcc dumptrigger('clear', 802) 
go


网上有听说可以使用2542 Trace Flag 来控制mdmp文件的产生,至今仍没有去试,有试过的朋友可以分享下。启用2542 TF,在启动参数后面添加 -T2542就是了。

三、分析mdmp文件的一些知识说明

以上只是介绍了mdmp的产生,以及如何自己手工产生mdmp文件,但如何对mdmp文件进行分析才是重点。曾经对其进行了一些分析,但道行有限,能获得的信息不多。把如何分析

mdmp文件的过程分享出来,希望更厉害的人能从中找到一些SQL Server的运行原理。

说到分析mdmp文件,也顺便提一个人,就是The guru guide系列的作者Ken Henderson(http://www.amazon.com/Ken-Henderson/e/B001IOFJL2/ref=ntt_athr_dp_pel_pop_1),他的

《The Guru's Guide to Transact-SQL》 就是中文版的《T-SQL权威指南》,其他的两本貌似没有找到中文版。他在Guru Guide 里面常常会介绍一些微软未公开的内容

(undocument commands),而《The Guru's Guide to SQL Server Architecture and Internals》
就是介绍了SQL Server 2000的体系结构很是深入的一本书。可惜其在2008年已经英年早逝了(http://sqlblog.com/blogs/kalen_delaney/archive/2008/01/29/ken-henderson.aspx),不然肯定能够提供更多关于SQL Server Interal的内容了。

1,调试

由于SQL Server 也是在windows平台是运行的一款程序,有问题时,把它当成一款普通的windows程序来进行调试就行了。在windows上,有两方面的调试,一个是内核模式调试,

一个是用户模式调试。内核调试是针对Windows操作系统进行调试的,反应windows OS内部和硬件设备的运行。用户模式的调试就是对应用程序进行调试,因为应用程序就是运行在

用户模式上的。二者的调试是不同的,这边就不做过多的介绍,有疑问,就google吧。

调试还有另外一个区别:是在程序运行时对其调试(live-debugging),还是读取mdmp分析调试(post-mortem debugging)。这二者也是不一样的。在live-debugging时会使程序挂起

,然后设置bp(break point),观察程序的运行行为。这边主要介绍post-mortem debugging.

2,windbg

要调试,当然得有工具,这个工具就是windbg,其主页为:

http://www.microsoft.com/whdc/devtools/debugging/default.mspx

安装完成后,除了有图形界面的调试工具(windbg),还会有命令行的调试工具(kd,cdb,ntsd)。

在调试过程中,我们最常见的是分析线程(thread)的堆栈(stack)的跟踪信息。因为在windows平台上,application是以process来运行的,而一个process又包含了thread,thread

才是真正在运行一些函数功能。我们可以通过select spid,kpid from sysprocesses 来看运行SQL Server的线程信息,也可以通ProcessExplorer
spidd kpid
------ ------
51 0
52 644

在ProcessExplorer里的查看如下,可以看到ProcessExplorer就提供了查看堆栈的功能,但仍有一些像 10 sqlservr.exe+0x58d36b的内容无法查看。



从上图可以看到,stack的内容格式一般如下:

MyModule!Func03  
MyModule!Func01

从底往上看,Func03是在Func01之后执行的。通过windbg,还会看到一些指针信息(Child-sp:Stack Pointer)和地址信息(RetAddr:Return Address)

Child-SP RetAddr Call Site  
00000000`09cbe9e8 00000000`777b2f60 ntdll!NtSignalAndWaitForSingleObject+0xa  
00000000`09cbe9f0 00000000`00bdc99e kernel32!SignalObjectAndWait+0x110  
00000000`09cbeaa0 00000000`00bc4575 sqlservr+0x1c99e  
00000000`09cbed40 00000000`00bc3ea8 sqlservr+0x4575  
00000000`09cbed80 00000000`00bdcfad sqlservr+0x3ea8  
00000000`09cbf370 00000000`01139d9c sqlservr+0x1cfad  
00000000`09cbf430 00000000`032b34c7 sqlservr+0x579d9c  
00000000`09cbf650 00000000`00bd2abb sqlservr!TlsGetValueForMsxmlSQL+0x4706d7  
00000000`09cbf6c0 00000000`00bd0fda sqlservr+0x12abb  
00000000`09cbf7e0 00000000`00bd2665 sqlservr+0x10fda  
00000000`09cbf870 00000000`0117abb0 sqlservr+0x12665  
00000000`09cbf8e0 00000000`0117c4b0 sqlservr+0x5babb0  
00000000`09cbf9a0 00000000`0117a060 sqlservr+0x5bc4b0  
00000000`09cbf9d0 00000000`0117a9ef sqlservr+0x5ba060  
00000000`09cbfa60 00000000`734937d7 sqlservr+0x5ba9ef  
00000000`09cbfaf0 00000000`73493894 MSVCR80!endthreadex+0x47  
00000000`09cbfb20 00000000`7775f56d MSVCR80!endthreadex+0x104  
00000000`09cbfb50 00000000`77893281 kernel32!BaseThreadInitThunk+0xd  
00000000`09cbfb80 00000000`00000000 ntdll!RtlUserThreadStart+0x21

要看sqlservr+0x579d9c 这样的内容,需要使用symbol来map这些16进制的值所表示的函数。使用symbol后,会得到下面的形式的内容。

Child-SP RetAddr Call Site  
00000000`09cbe9e8 00000000`777b2f60 ntdll!NtSignalAndWaitForSingleObject+0xa  
00000000`09cbe9f0 00000000`00bdc99e kernel32!SignalObjectAndWait+0x110  
00000000`09cbeaa0 00000000`00bc4575 sqlservr!SOS_Scheduler::SwitchContext+0x84e  
00000000`09cbed40 00000000`00bc3ea8 sqlservr!SOS_Scheduler::SuspendNonPreemptive+0xc5  
00000000`09cbed80 00000000`00bdcfad sqlservr!EventInternal<Spinlock<149,1,0> >::Wait+0x428  
00000000`09cbf370 00000000`01139d9c sqlservr!ResQueueBase::Dequeue+0x19d  
00000000`09cbf430 00000000`032b34c7 sqlservr!CheckpointLoop+0x1aa 
00000000`09cbf650 00000000`00bd2abb sqlservr!ckptproc+0x47  
00000000`09cbf6c0 00000000`00bd0fda sqlservr!SOS_Task::Param::Execute+0x11b  
00000000`09cbf7e0 00000000`00bd2665 sqlservr!SOS_Scheduler::RunTask+0xca  
00000000`09cbf870 00000000`0117abb0 sqlservr!SOS_Scheduler::ProcessTasks+0x95
00000000`09cbf8e0 00000000`0117c4b0 sqlservr!SchedulerManager::WorkerEntryPoint+0x110  
00000000`09cbf9a0 00000000`0117a060 sqlservr!SystemThread::RunWorker+0x60  
00000000`09cbf9d0 00000000`0117a9ef sqlservr!SystemThreadDispatcher::ProcessWorker+0x12c  
00000000`09cbfa60 00000000`734937d7 sqlservr!SchedulerManager::ThreadEntryPoint+0x12f  
00000000`09cbfaf0 00000000`73493894 MSVCR80!endthreadex+0x47  
00000000`09cbfb20 00000000`7775f56d MSVCR80!endthreadex+0x104  
00000000`09cbfb50 00000000`77893281 kernel32!BaseThreadInitThunk+0xd  
00000000`09cbfb80 00000000`00000000 ntdll!RtlUserThreadStart+0x21


在这个例子中,我们发现有sqlservr!CheckpointLoop+0x1aa 这个函数调用的信息,这就是我们说的checkpoint的实际运行信息了。通过select * from sys.dm_exec_requests
可以看出是哪个spid在运行checkpoint。

从上面也可以看出Call Site的格式一般如下:
<module_name>!<function call>
<module_name>!<class_name>::<method/function call>

四、使用windbg

在了解上述知识后,就可以使用windbg来进行分析了。

1,windbg环境的配置

到微软的网站下载windbg后直接安装,安装完成后,需要配置symbols的path,打开windbg,File --> Symbols File Path 在弹出的对话框输入

srv*c:\symbols*http://msdl.microsoft.com/download/symbols

其中c:\symbols是本地硬盘的文件夹,在使用时,windbg会到http://msdl.microsoft.com/download/symbols下载相关的symbols,也可以自己手工下载相关操作系统的symbols。

配置好,可以使用.reload命令来强制下载某个symbols,如:

.reload /f sqlservr.exe

具体的命令可以参考windbg的帮助文档。

2,打开mdmp文件

打开windbg,File --> Open Crash Dump,选择mdump文件,在弹出的对话框里点击yes

3,分析mdmp

在下面的对话框输入 ~ 会出现线程的信息

0:000> ~
. 0 Id: 384.608 Suspend: 1 Teb: 7ffdd000 Unfrozen
  1 Id: 384.698 Suspend: 1 Teb: 7ffda000 Unfrozen
  2 Id: 384.6a8 Suspend: 1 Teb: 7ffd9000 Unfrozen
  3 Id: 384.6a4 Suspend: 1 Teb: 7ffd8000 Unfrozen
  4 Id: 384.6b0 Suspend: 1 Teb: 7ffd7000 Unfrozen
  5 Id: 384.6ac Suspend: 1 Teb: 7ffd6000 Unfrozen
  6 Id: 384.6c8 Suspend: 1 Teb: 7ffd5000 Unfrozen
  7 Id: 384.6dc Suspend: 1 Teb: 7ffd4000 Unfrozen
  8 Id: 384.6e0 Suspend: 1 Teb: 7ffd3000 Unfrozen
  9 Id: 384.108 Suspend: 1 Teb: 7ff9f000 Unfrozen
  10 Id: 384.6e8 Suspend: 1 Teb: 7ff9e000 Unfrozen
  11 Id: 384.6e4 Suspend: 1 Teb: 7ff9d000 Unfrozen
  12 Id: 384.604 Suspend: 1 Teb: 7ff9c000 Unfrozen
  13 Id: 384.714 Suspend: 1 Teb: 7ff9b000 Unfrozen
  14 Id: 384.718 Suspend: 1 Teb: 7ff9a000 Unfrozen
  15 Id: 384.71c Suspend: 1 Teb: 7ff99000 Unfrozen
  16 Id: 384.720 Suspend: 1 Teb: 7ff98000 Unfrozen
  17 Id: 384.728 Suspend: 1 Teb: 7ffdc000 Unfrozen
  18 Id: 384.730 Suspend: 1 Teb: 7ff97000 Unfrozen
  19 Id: 384.74c Suspend: 1 Teb: 7ff96000 Unfrozen
  20 Id: 384.784 Suspend: 1 Teb: 7ff95000 Unfrozen
  21 Id: 384.788 Suspend: 1 Teb: 7ff94000 Unfrozen
  22 Id: 384.1e0 Suspend: 1 Teb: 7ff93000 Unfrozen
  23 Id: 384.284 Suspend: 1 Teb: 7ff92000 Unfrozen
  24 Id: 384.280 Suspend: 1 Teb: 7ff91000 Unfrozen
  25 Id: 384.23c Suspend: 1 Teb: 7ff8f000 Unfrozen
  26 Id: 384.3d0 Suspend: 1 Teb: 7ff8e000 Unfrozen
  27 Id: 384.3d4 Suspend: 1 Teb: 7ff8d000 Unfrozen
  28 Id: 384.3d8 Suspend: 1 Teb: 7ff8c000 Unfrozen
  29 Id: 384.204 Suspend: 1 Teb: 7ff8b000 Unfrozen
  30 Id: 384.43c Suspend: 1 Teb: 7ff8a000 Unfrozen
  31 Id: 384.450 Suspend: 1 Teb: 7ff89000 Unfrozen
  32 Id: 384.454 Suspend: 1 Teb: 7ff88000 Unfrozen
  33 Id: 384.458 Suspend: 1 Teb: 7ff87000 Unfrozen
  34 Id: 384.45c Suspend: 1 Teb: 7ff86000 Unfrozen
  35 Id: 384.464 Suspend: 1 Teb: 7ff84000 Unfrozen
  36 Id: 384.44c Suspend: 1 Teb: 7ff83000 Unfrozen
  37 Id: 384.1e8 Suspend: 1 Teb: 7ffdb000 Unfrozen
  38 Id: 384.1cc Suspend: 1 Teb: 7ff82000 Unfrozen
  39 Id: 384.1684 Suspend: 1 Teb: 7ff80000 Unfrozen
  40 Id: 384.c38 Suspend: 1 Teb: 7ff90000 Unfrozen
  41 Id: 384.1048 Suspend: 1 Teb: 7ff85000 Unfrozen
  42 Id: 384.140c Suspend: 1 Teb: 7ff7f000 Unfrozen
  43 Id: 384.a18 Suspend: 1 Teb: 7ff81000 Unfrozen

在我的这个例子中,我的spid在循环运行一个select命令,从sysprocesses中,可以看到spid对应的kpid是488

spid kpid
51 0
52 488

488转化为16进制刚好为1e8 ,对应的序号是37。

那我们如果想看线程37的内容,可以先使用 ~37s命令切换到线程37的上下文中

0:000> ~37s
eax=00000000 ebx=3f20f344 ecx=1f8dcf08 edx=00000001 esi=000009b5 edi=00000000
eip=7c92e514 esp=3f20f238 ebp=3f20f29c iopl=0 nv up ei ng nz ac pe cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000297
ntdll!KiFastSystemCallRet:
7c92e514 c3 ret

看起来是CPU的寄存器信息,可惜这些还看不太懂,不然可以更深入了。

接着用k命令,查看具体的函数调用信息

0:037> k
ChildEBP RetAddr   
3f20f234 7c92df5a ntdll!KiFastSystemCallRet
3f20f238 7c8025db ntdll!ZwWaitForSingleObject+0xc
3f20f29c 7c802542 kernel32!WaitForSingleObjectEx+0xa8
3f20f2b0 011e7ced kernel32!WaitForSingleObject+0x12
3f20f324 011e7ddb sqlservr!Np::StatusWriteNoComplPort+0x9f
3f20f354 011e7ea2 sqlservr!SNIStatusWriteNoComplPort+0x82
3f20f374 012a8ae0 sqlservr!TDSSNIClient::WriteStatus+0x6a
3f20f4a0 0153d30c sqlservr!write_data+0x1a6
3f20f4d0 0117492e sqlservr!flush_buffer+0xdf

3f20f6a0 015490b6 sqlservr!CKatmaiTds::SendRowImpl+0x2faf
3f20f6ac 01532f0d sqlservr!CValOdsRow::SetDataX+0x29
3f20f6bc 01532d8b sqlservr!SetMultData+0x1e
3f20f734 0154962f sqlservr!CEs::GeneralEval4+0xd0
3f20f740 01547825 sqlservr!CEs::Eval+0x13
3f20f7f8 015499af sqlservr!CXStmtQuery::ErsqExecuteQuery+0x409
3f20f85c 015401c3 sqlservr!CXStmtSelect::XretExecute+0x268
3f20f8f8 01540cc0 sqlservr!CMsqlExecContext::ExecuteStmts<1,1>+0x28d
3f20f9e0 01540686 sqlservr!CMsqlExecContext::FExecute+0x70e

3f20fa84 0153cf8c sqlservr!CSQLSource::Execute+0x598
3f20fc08 01539f79 sqlservr!process_request+0x2f0

从下面的内容,可以看出几点(个人观点:) )

3f20f354 011e7ea2 sqlservr!SNIStatusWriteNoComplPort+0x82
3f20f374 012a8ae0 sqlservr!TDSSNIClient::WriteStatus+0x6a
3f20f4a0 0153d30c sqlservr!write_data+0x1a6
3f20f4d0 0117492e sqlservr!flush_buffer+0xdf

3f20f7f8 015499af sqlservr!CXStmtQuery::ErsqExecuteQuery+0x409
3f20f85c 015401c3 sqlservr!CXStmtSelect::XretExecute+0x268
3f20f8f8 01540cc0 sqlservr!CMsqlExecContext::ExecuteStmts<1,1>+0x28d
3f20f9e0 01540686 sqlservr!CMsqlExecContext::FExecute+0x70e

从底往上看,可以看到这是一个select动作,进行select时,先对内存的一些缓存进行清除(flush_buffer),接着便是写入数据(write_data),然后再发送写状态(TDSSNIClient::WriteStatus),由于一直循环所以会有写未完成的提示(SNIStatusWriteNoComplPort)。这也基本符合一个select的动作。

如果遇到错误时,在函数调用中一般会抛出raiseerror等内容,类似如下:

00000000`220ce2d0 00000000`013a3d41 sqlservr!ex_raise2+0xcdd8bf

00000000`220ce630 00000000`02deb8ce sqlservr!ex_raise+0x51  

这时,基本可以判断出现问题的原因了。

3,其他

windbg的功能是很强大的,是通往sql server内部一个强大工具。要想了解的话,估计得好好研究下<windows internal>,有兴趣的可以自行深入。

http://topic.csdn.net/u/20101024/16/48C19360-5E68-4A59-BD39-0FFEE8157E45.html

posted @ 2012-04-28 16:17 飞洋过海 阅读(86) 评论(0) 编辑

     曾经和一些DBA和数据库开发人员交流时,问他们都用过一些什么样的DB方面的工具,大部分人除了SSMS和Profile之外,基本就没有使用过其他工具了;

诚然,SSMS和Profile足够强大,工作的大部分内容都能通过它们搞定,但是MS、第三方公司甚至是个人开发者为SQLServer提供了很多其他的工具,如果你

能充分的掌握这些工具,无疑会给我们数据库的管理、优化、测试和排错节省大量的时间和精力,下面就来介绍除SSMS和Profile之外的其他有用的工具。

 

NO1: PD(PowerDesigner)

功能:SysBase公司提供的数据库设计工具,功能很强大,是做数据库设计时必备的工具;

下载:http://www.3ddown.com/soft/14524.htm

 

NO2: Log Explorer

功能:数据库日志读取工具,主要用来恢复误操作的数据(目前只支持到2005版本),详见:

http://blog.csdn.net/jinjazz/archive/2008/05/19/2459692.aspx ;

下载地址:http://www.pc6.com/softview/SoftView_57657.html

 

NO3Tuning Advisor

功能:优化顾问,会根据数据库的运行情况,提示您做相关的优化(可靠性不是太高,需要自行判断);

下载:SQLServer自带

 

NO4:SSMSTools

功能:SSMS工具的一个插件,能提供格式化代码、追溯历史等功能(通过它,也许你可以开发自己的插件);

下载: http://www.ssmstoolspack.com/

 

NO5: DBDiff & TableDiff

功能:第一个是比较两个数据库结构的差异,第二个可用来比较表中数据的差异(而且能生成相关的脚本);

下载:http://opendbiff.codeplex.com/

 

NO6PAL Tool

功能:Performance Analysis of Logs,Perfmon日志分析工具;

下载:http://pal.codeplex.com/

 

NO7RML

功能:这个工具非常强大,下图展示了完成安装后它的四个主要功能组件;ReadTrace工具能读取数据库的Profile跟踪文件,并生成报告;Ostress能将ReadTrace

生成的文件重播,而且还可以对数据库做压力测试;ORCA能保证重报时,按照事件发生的顺序播放;Reporter能将ReadTrace后的内容通过报表的形式展现,相当

的有用。

下载:http://support.microsoft.com/kb/944837

 

NO8:SqlNexus

功能:先通过SQLServer自带的SQLdiag.exe工具收集信息,然后再用SqlNexus分析这些信息,它是前面一些工具的整合,为数据库管理人员寻找SQLServer服务器

的性能瓶颈和排查故障提供了相当强大的支持(MS工程师很多都用这个哦,买技术支持的朋友们有木有经历过MS要求你开启SQLDiag,然后将收集的数据回传给他们

的;现场支持时,是不是也开启SQLDiag收集数据,然后就出来了服务器性能报告,有木有;所以掌握它,1k/时的定期服务器检查技术支持费用可以省了);

下载:http://sqlnexus.codeplex.com/

 

NO9:SQLIO & SQLIOSim

功能:磁盘IO压力测试工具,SQLIO主要是模拟随机或者顺序的方式来测试磁盘IO的性能;SQLIOSim是模拟SQLServer的行为来测试IO性能;

下载:http://support.microsoft.com/kb/231619

 

NO10:SqlMonitor & SSBDiagnose

功能:SqlMonitor是监控Replication和Mirror的必会工具,SSBDiagnose是测试SSB配置的工具;

下载:SQLServer自带

 

posted @ 2012-04-25 12:14 飞洋过海 阅读(3133) 评论(16) 编辑
摘要: SQLServer2008在数据的高安全、高性能、高可用方面的技术已经比较成熟,这些技术和方案都是随着很多公司的业务和数据访问压力的增加而不断的升级和变迁的,同时经历了方方面面的考验,证明了它们都是成熟可靠的,下面就这方面的技术方案和变迁过程来做一些分析。阶段一:裸奔时代:优点:裸奔最大的好处就是简单,成本低。缺点:一旦服务器出现问题,恢复起来比较麻烦;如果访问压力变大,服务器可能不堪重负。阶段二:单库+Mirror+BackUp方案:说明:Mirror有两种方式,同步和异步;同步方式能保证主库和Mirror端数据的一致性,而且不需要使用企业版,但是对主库的性能影响也比较大;异步方式需要企业.阅读全文
posted @ 2012-03-23 09:54 飞洋过海 阅读(2785) 评论(17) 编辑
摘要: 数据库系统异常是DBA经常要面临的情景,一名有一定从业经验的DBA,都会有自己一套故障排查的方法和步骤,此文为为大家介绍一下通过系统性能视图(SQLServer05以上版本)来排查系统异常的基本方法,希望能对大家有所帮助。这里分两部分来介绍:一. 从数据库连接情况来判断异常:1. 首先我们来看一下目前数据库系统所有请求情况:--request infoselect s.session_id, s.status,db_name(r.database_id) as database_name,s.login_name,s.login_time, s.host_name,c.client_net_.阅读全文
posted @ 2012-03-12 14:36 飞洋过海 阅读(969) 评论(5) 编辑
摘要: NoSQL显然不是什么新鲜事物了,自其最早出现的1998年,已经过去十几个年头。2009年开始,NoSQL逐渐成为数据库领域的焦点。尤其是近期掀起的大数据热潮,引爆了NoSQL新一轮的竞争。数据库既是DBA的工具,也是DBA的舞台,NoSQL在引领新技术的同时,还引发了DBA之间更加激烈的竞争。最近的一项有关数据库的调查显示,目前有10%左右的企业正在使用NoSQL,有74.3%的DBA表示已经在接触NoSQL数据库。从这些数字中不难看出,NoSQL正在从DBA层面向传统数据库发起进攻,而非NoSQL运动初期的几家互联网公司。 那么2012年NoSQL就业趋势如何呢?本文将对Cassan...阅读全文
posted @ 2012-03-06 14:46 飞洋过海 阅读(48) 评论(0)  编辑
摘要: 故事 和尚挑水 有两个和尚住在隔壁,所谓隔壁就是隔壁那座山,他们分别住在相邻的两座山上的庙里。这两座山之间有一条溪,于是这两个和尚每天都会在同一时间下山去溪边挑水,久而久之他么变成为了好朋友。 就这样时间在每天挑水中不知不觉已经过了五年。突然有一天左边这座山的和尚没有下山挑水,右边那座山的和尚心想:“他大概睡过头了。”便不以为意。哪知道第二天左边这座山的和尚还是没有下山挑水,第三天也一样。过了一个星期还是一样,直到过了一个月右边那座山的和尚终于受不了,他心想:“我的朋友可能生病了,我要过去拜访他,看看能帮上什么忙。” 于是他便爬上了左边这座山,去探望他的老朋友。 等他到了左边这座山的庙,看到他阅读全文
posted @ 2012-03-05 14:16 飞洋过海 阅读(22) 评论(0)  编辑
摘要: 在去年的一次谈话中,basho公司的CTO Justin Sheehy认为,NoSQL是一场运动,而非技术。我立刻深表赞同,因为以往关于NoSQL的探讨并不舒心。那么,为什么说NoSQL是一场运动,而非技术呢?Justin的说法直截了当:之所以说NoSQL是一场运动,是因为这是对数据库架构的选择。任何一种单一的技术主题,反而会掩盖NoSQL运动的实质。自八十年代以来,关系型数据库(如SQL Server、Oracle和DB2)一直都是后端业务系统的主导。这些关系型数据库产品都非常优秀,它们之间有许多共通之处。回顾一下以往15年的软件开发历程,我们已经构建了许多优秀的大型数据库应用,其中不乏We阅读全文
posted @ 2012-03-01 17:02 飞洋过海 阅读(26) 评论(0)  编辑