存档

2010年8月 的存档,文章数:22

oracle的版本为:10gr2,10.2.0.1.0。

利用oracle中的hsodbc连接sqlserver2005数据库。已成功连接。db link的名字为: sql2005fororacle。

执行:select count(*) from sysdatabases@sql2005fororacle; 能够成功执行。

但是,在执行: select count(*) from sysobjects@sql2005fororacle;却导致系统出现了死机症状,无法响应任务的操作,任务管理器看到cpu利用率不高。无奈,只能强制关机。

在alert_<SID>.log文件中发现有这么几句:

Memory Notification: Library Cache Object loaded into SGA
Heap size 2225K exceeds notification threshold (2048K)
KGL object name :XDB.XDbD/PLZ01TcHgNAgAIIegtw==

原来遇到oracle的bug了。上网检索,说 是oracle的一个bug在10g10.2.0.1的各个平台上都出现过。 Oracle10g中,在load较大的对象进library cache中时,会记录以上警告。在版本10.2.0.1中,这个定义大对象的阈值是2M,这是有隐含参数 _kgl_large_heap_warning_threshold 指定的从10.2.0.2起,这个参数的默认值被修改为50M。

解决方法1 :升级到10.2.0.2或者以上。

解决方法2

SQL> alter system set "_kgl_large_heap_warning_threshold"=20388608 scope=spfile ;
SQL> shutdown immediate

SQL> startup

或者将 2038860调成更大的值。

我是通过调整隐式参数的方式解决的,重启后。

下面就是在oracle中访问sqlserver2005数据库的数据的效果:

SQL> select "name" from sysobjects@sql2005fororacle where "type"='U';
name
--------------------------------------------------------------------------------
spt_fallback_db
spt_fallback_dev
spt_fallback_usg
QuestSoftwareProc
pbcattbl
pbcatcol
pbcatfmt
pbcatvld
pbcatedt
spt_monitor
spt_values
name
--------------------------------------------------------------------------------
MSreplication_options
已选择12行。
SQL> desc sysusers@sql2005fororacle
 名称                                      是否为空? 类型
 ----------------------------------------- -------- ----------------------------
 uid                                                NUMBER(5)
 status                                             NUMBER(5)
 name                                      NOT NULL VARCHAR2(128 CHAR)
 sid                                                RAW(85)
 roles                                              RAW(2000)
 createdate                                NOT NULL DATE
 updatedate                                NOT NULL DATE
 altuid                                             NUMBER(5)
 password                                           RAW(256)
 gid                                                NUMBER(5)
 environ                                            VARCHAR2(32512 CHAR)
 hasdbaccess                                        NUMBER(10)
 islogin                                            NUMBER(10)
 isntname                                           NUMBER(10)
 isntgroup                                          NUMBER(10)
 isntuser                                           NUMBER(10)
 issqluser                                          NUMBER(10)
 isaliased                                          NUMBER(10)
 issqlrole                                          NUMBER(10)
 isapprole                                          NUMBER(10)
SQL>

在Sybase中,表内新添加的列都位于表的最后。其它数据库也基本相同,这和数据库的内部物理存储是有必然关系的。我研究过sybase 中数据的物理存储结构,理解在sybase以及其它数据库中新增加的列必须放置在最后的原因。 在项目实践中,可能有这样的需求:需要将最后添加的一列放置到前面的位置。比如:表test中原来的列为:a,b,c,不想让最后添加的列d放在第四个位置,而让列d放在第2个位置,形成:a,d,b,c这样的顺序。如何实现呢? 一般的办法是: 1.新建一个临时表:test_bak,

create table test_bak ( a 列属性,

d 列属性,

b 列属性,

c 列属性

)
 

2.将原表test的数据拷贝到临时表test_bak中

insert into test_bak(a,d,b,c)

select a,d,b,c from test
 

3.将原表删除,临时表改名为原表的名字

drop table test

sp_rename test_bak,test
 

以上是常规的办法。如果表内的数据量很大的时候,则会比较耗费时间。 下面我介绍另外一个比较简便的方法。

主要思路是调整表在syscolumns中对应的colid的值。

先建立一个新的测试表test

1> drop table test

2> go

1> create table test(id int not null,name varchar(30) null,age tinyint not null, se_x char(1) not null,birthday datetime null)

2> go

1> select *  from test
2> go
id          name                           age se_x birthday
----------- ------------------------------ --- --- --------------------------

(0 rows affected)

插入一条测试数据

1> insert into test
2> values(1,'andkylee',28,'F','1982-03-20 12:00:00')
3> go
(1 row affected)
1> select *  from test
2> go
id          name                           age se_x birthday
----------- ------------------------------ --- --- --------------------------
           1 andkylee                        28 F          Mar 20 1982 12:00PM
(1 row affected)

调整各个的顺序,使之倒序。将原来的id,name,age,se_x,birthday改成:birthday,se_x,age,name,id
调整方法:修改syscolumns表中测试表test的各个列的colid的顺序。

1> select *  from test
2> go
birthday                   se_x age name                           id
-------------------------- --- --- ------------------------------ -----------
        Mar 20 1982 12:00PM F    28 andkylee                                 1

(1 row affected)

列的顺序逆序后,显示插入数据。
 

1> insert into test(id,name,age,se_x,birthday)
2> values(2,'liu',30,'M','2000-01-01 11:59:59')
3> go
(1 row affected)
1> select * from test
2> go
birthday                   se_x age name                           id
-------------------------- --- --- ------------------------------ -----------
        Mar 20 1982 12:00PM F    28 andkylee                                 1
        Jan  1 2000 11:59AM M    30 liu                                      2

(2 rows affected)

如果按照调整数据之前的列的顺序插入数据,则会报错。

1> insert into test
2> values(3,'zhang',29,'F','1980-01-01 11:59:59')
3> go

Msg 206, Level 16, State 2:
Server 'SYB_NFJD_TEST', Line 1:
Operand type clash: INT is incompatible with DATETIME
Msg 257, Level 16, State 1:
Server 'SYB_NFJD_TEST', Line 1:
Implicit conversion from datatype 'VARCHAR' to 'INT' is not allowed.  Use the
CONVERT function to run this query.

新的数据要按照修改后的列的顺序插入。

1> insert into test
2> values('1980-01-01 11:59:59','F',29,'zhang',3)
3> go
(1 row affected)

最后,查看测试表的数据。

1> select * from test
2> go
birthday                   se_x age name                           id
-------------------------- --- --- ------------------------------ -----------
        Mar 20 1982 12:00PM F    28 andkylee                                 1
        Jan  1 2000 11:59AM M    30 liu                                      2
        Jan  1 1980 11:59AM F    29 zhang                                    3

(3 rows affected)

备注:绝大多数sybase客户端工具显示表的列时都是按照colid的顺序显示的。所以,此种方法能够实现调整数据库表中列的位置的功能。

————————————————————————————————————
——— 本文为andkylee个人原创,请在尊重作者劳动成果的前提下进行转载;
——— 转载务必注明原始出处 : http://www.dbainfo.net
——— 关键字: 列显示顺序 syscolumns colid
————————————————————————————————————

dbcc writepage是sqlserver 2000 和 2005中未公开的命令,也就是说使用这些未官方支持的命令出现的任何后果与MS无关。

同样,本文仅仅演示dbcc writepage的使用,您在操作时出现的任何后果与本人无关。

dbcc writepage的语法为:

   dbcc writepage ({ dbid, ‘dbname’ }, fileid, pageid, offset, length, data)

下面演示dbcc writepage的使用方法:

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

第一步:创建一个测试表

1> create table test (id int not null,name varchar(30) null)
2> go
1> insert into test
2> select 1,'china'
3> go

(1 行受影响)
1> insert into test
2> select 2,'beijing'
3> go

(1 行受影响)

 

1> select object_id('test')
2> go

-----------
 1877581727

(1 行受影响)

表的ID为: 1877581727。


第二步:查看表内数据所在的页面号

1> select * from sysindexes
2> where id = 1877581727
3> go
id          status      first    indid  root     minlen keycnt groupid dpages
   reserved    used        rowcnt               rowmodctr   reserved3 reserved4
xmaxlen maxirow OrigFillFactor StatVersion reserved2   FirstIAM impid  lockflags
 pgmodctr    keys
                                                                name

                                 statblob

                                                    maxlen      rows
----------- ----------- -------- ------ -------- ------ ------ ------- ---------
-- ----------- ----------- -------------------- ----------- --------- ---------
------- ------- -------------- ----------- ----------- -------- ------ ---------
 ----------- -------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------- ----------------
--------------------------------------------------------------------------------
-------------------------------- -----------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------- ----------- -----------
 1877581727           0 0x3B4F00       0 0x000000      8      0       1
 1           2           2                    2           2         0         0
     57       0              0           0           0 0x3C4F00      0         0
           0 NULL
                                                               NULL

                                 NULL

                                                           8000           2

(1 行受影响)


查询属于test表的第一个数据页的页号,在sysindexes表中first列表示对象的第一个物理存储页的页号:0x384F00,也就是页号(1:20283)。

 

第三步:查询修改前的数据内容

下面查询修改前页面(1,20283)上的数据内容。可以看出(1,20283)页上有2行记录,这和插入的2行记录数保持一致。然后,观察到页面的头部有china和beijing的字样,

这和插入的2行记录内容“似乎”一致。


下面我用红色标记了test表中两行测试数据的内容。1,'china'    2,'beijing'

1> dbcc page(9,1,20283,2)
2> go

DATA:
Memory Dump @0x518FC000

518FC000:   01010400 00800001 00000000 00000800 ?................

518FC010:   00000000 00000200 aa000000 721f8a00 ?............r...

518FC020:   3b4f0000 01000000 92010000 75000000 ?;O..........u...

518FC030:   02000000 00000000 00000000 00000000 ?................

518FC040:   01000000 00000000 00000000 00000000 ?................

518FC050:   00000000 00000000 00000000 00000000 ?................

518FC060:   30000800 01000000 0200fc01 00140063 ?0..............c

518FC070:   68696e61 30000800 02000000 0200fc01 ?hina 0...........

518FC080:   00160062 65696a69 6e670000 21212121 ?...beijing ..!!!!

518FC090:   21212121 21212121 21212121 21212121 ?!!!!!!!!!!!!!!!!

518FC0A0:   21212121 21212121 21212121 21212121 ?!!!!!!!!!!!!!!!!

........... 这些是未分配使用的空间

518FDFC0:   21212121 21212121 21212121 21212121 ?!!!!!!!!!!!!!!!!

518FDFD0:   21212121 21212121 21212121 21212121 ?!!!!!!!!!!!!!!!!

518FDFE0:   21212121 21212121 21212121 21212121 ?!!!!!!!!!!!!!!!!

518FDFF0:   21212121 21212121 21212121 74006000 ?!!!!!!!!!!!!t.`.

OFFSET TABLE:

Row - Offset

1 (0x1) - 116 (0x74)

0 (0x0) - 96 (0x60)

DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。

 

第四步:修改物理数据页面的内容

通过上面的dbcc page输出结果,仔细数了一下,china这列内容的偏移为111,将china这五个字符改成aaaa。这是最简单的。a的asicc为:97(0x61)。

1> db cc writepage(9,1,20283,111,5,0x6161616161)
2> go
DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。

 

第五步:查看修改后的物理页面的内容

1> dbcc page(9,1,20283,2)
2> go

DATA:
Memory Dump @0x5002C000

5002C000:   01010400 00820001 00000000 00000800 ?................

5002C010:   00000000 00000200 aa000000 721f8a00 ?............r...

5002C020:   3b4f0000 01000000 92010000 75000000 ?;O..........u...

5002C030:   02000000 00000000 00000000 8234666e ?.............4fn

5002C040:   00000000 00000000 00000000 00000000 ?................

5002C050:   00000000 00000000 00000000 00000000 ?................

5002C060:   30000800 01000000 0200fc01 00140061 ?0..............a

5002C070:   61616161 30000800 02000000 0200fc01 ?aaaa 0...........

5002C080:   00160062 65696a69 6e670000 21212121 ?...beijing ..!!!!

5002C090:   21212121 21212121 21212121 21212121 ?!!!!!!!!!!!!!!!!

5002C0A0:   21212121 21212121 21212121 21212121 ?!!!!!!!!!!!!!!!!

5002C140:   21212121 21212121 21212121 21212121 ?!!!!!!!!!!!!!!!!

5002C150:   21212121 21212121 21212121 21212121 ?!!!!!!!!!!!!!!!!

..................省略未占用空间

5002DFE0:   21212121 21212121 21212121 21212121 ?!!!!!!!!!!!!!!!!

5002DFF0:   21212121 21212121 21212121 74006000 ?!!!!!!!!!!!!t.`.

OFFSET TABLE:

Row - Offset

1 (0x1) - 116 (0x74)

0 (0x0) - 96 (0x60)

DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。

 

第六步:通过客户端工具验证修改后的数据内容

1> select * from test
2> go
id          name
----------- ------------------------------
          1 aaaaa
          2 beijing

(2 行受影响)
可以看到第一行记录的name列由china改为了aaaaa

备注: 以上演示的是仅仅修改某一行某一列的数据,并且修改后的内容和修改前的内容保持长度一致。

如果修改多列或者修改前后的字段长度不一致;进一步修改整行数据,或者修改整页的数据的话,可能会复杂许多。

————————————————————————————————-
—- 本文为andkylee个人原创,请在尊重作者劳动成果的前提下进行转载;
—- 转载务必注明原始出处 : http://www.dbainfo.net
—- 关键字:dbcc writepage undocumented command 修改 物理页面 page
————————————————————————————————-

在ASE中统计某个用户表的信息,比如:表中的行数、分配的空间、数据所占空间、索引所占空间以及剩余空间等,我们可以使用系统存储过程sp_spaceused来实现。

系统存储过程sp_spaceused有两个参数:@objname和@list_indices,第一个@objname是待统计的对象名,一般 是表名;第二个@list_indices标志是否单独统计索引信息,@list_indices=1表示单独统计索引信 息,@list_indices=0则不单独统计。

示例:

1> sp_spaceused sysobjects,0
2> go
 name       rowtotal reserved data   index_size unused
 ---------- -------- -------- ------ ---------- ------
 sysobjects 1014     252 KB   132 KB 68 KB      52 KB
(1 row affected)
(return status = 0)
1> sp_spaceused sysobjects,1
2> go
 index_name   size  reserved unused
 ------------ ----- -------- ------
 ncsysobjects 48 KB 64 KB    16 KB
 csysobjects  20 KB 32 KB    12 KB
(1 row affected)
 name       rowtotal reserved data   index_size unused
 ---------- -------- -------- ------ ---------- ------
 sysobjects 1014     252 KB   132 KB 68 KB      52 KB
(return status = 0)
1>

但是利用sp_spaceused还不能实现统计某个库里面哪张表的数据记录数最多,哪张表占用的空间最大,哪些表的行数为0,以及哪些表的索引所占空间大于100M等等的问题。

如何实现呢?

方法一:改造sp_spaceused过程语法中的SQL语句。但是,sp_spaceused过程的源代码有560多行,看起来比较累,至少需要一个临时表存储中间临时数据。


方法二:是本博客专门推荐使用的,利用ASE中的代理表来实现。下面是操作步骤:

假设用户数据库名字为:andkylee

先执行:use andkylee

            go

 

步骤一:建立代理表tablespace2

create  existing table tablespace2(name varchar(128) null,rowtotal char(15) ,reserved char(15),[data] char(15),index_size char(15),unused char(15),_objname varchar(128) null,_list_indices int null) external procedure at "loopback.andkylee.dbo.sp_spaceused"

代理表的列 有:name,rowtotal,reserved,data,index_size,unused,_objname,_list_indices,其 中name,rowtotal,reserved,data,index_size,unused这几列接收存储过程sp_spaceused返回的结果 数据。

注意name,rowtotal,reserved,data,index_size,unused的各列的数据类型要和sp_spaceused返回的列的类型一致。

_objname,_list_indices 是过程sp_spaceused的参数列。

需要再sysservers中加入一个指向自己的远程服务器loopback。

sp_addserver loopback,null,@@servername
go

如果@@servername为空,则写dsedit中显示服务器名。

 

步骤二:在代理表tablespace2上建立视图,统计库内所有用户表的存储空间

create view TableSize(name,rowtotal,reserved,data_KBytes,index_size,unused)
as
select name,cast(str_replace(rowtotal,' KB','') as int),cast(str_replace(reserved,' KB','') as int),cast(str_replace(data,' KB','') as int),cast(str_replace(index_size,' KB','') as int),cast(str_replace(unused,' KB','') as int) from tablespace2 where _list_indices  = 0
and _objname in
     (
        select user_name(uid)+"."+name from andkylee.dbo.sysobjects where type='U'
     )
go

说明:可以使用其它的条件来仅仅统计某些表,比如:只统计用户test所拥有的表的空间信息,那么改为: where type='U' and uid=user_id("test")


步骤三: 针对视图TableSize,根据要求写SQL语句

比如:统计记录数最多的10个表的表名、行数、分配空间,用如下的SQL:

select top 10 name,rowtotal,reserved  from TableSize order by rowtotal desc

go

1> select top 10 name,rowtotal,reserved  from TableSize order by rowtotal desc
2> go
 name
         rowtotal    reserved
 -------------------------------------------------------------------------------
-------------------------------------------------
         ----------- -----------
 SOS_Y_Hs_Xell
             1044911      178308
 test3
             1008576       21940
 test2
             1008576       21992
 SOS_Y_Wharehouse
              380000       31488
 SOS_Y_Hs_Xell_copy_1
              288097       49596
 FLOWREC1
              285139       40580
 PartitionTestTable
              262144       11368
 lzftest
              262144        7496
 SOS_Y_Hs_Xell_Back
              236000       40512
 SOS_R_Wharehouse
              192000       38408
(10 rows affected)

 

根据自己的要求写针对TableSize的相应的SQL语句,上面的sql在此抛砖引玉。

备注:

1、由于每次统计过程中都要涉及到待统计表的存储空间大小的计算,所以,上面介绍的方法对系统性能会有一点小的影响。只要不是频繁的执行,个人感觉影响可以忽略。

2、另外针对数据库日志也就是系统表syslogs的统计结果和其它表的不一样。

1> sp_spaceused syslogs
2> go
 name            total_pages     free_pages      used_pages
         reserved_pages
 --------------- --------------- --------------- ---------------
         ---------------
 syslogs         102400          101945          455
         0
(1 row affected)
(return status = 0)
1>

所以,不要在上面的被统计表中包含syslogs表。

————————————————————————————————-
—- 本文为andkylee个人原创,请在尊重作者劳动成果的前提下进行转载;
—- 转载务必注明原始出处 : http://www.dbainfo.net
—- 关键字:ASE sp_spaceused 代理表 存储过程 统计表的空间大小 行数最多的表的记录数

                 所占空间最大的表
————————————————————————————————-

What does the “I/O request” error below represent?

 

2008-04-21 13:26:42.480 spid364      Microsoft SQL Server 2005 - 9.00.3177.00 (Intel X86)

2008-04-22 16:30:02.140 spid6s       SQL Server has encountered 2 occurrence(s) of I/O requests taking longer than 15 seconds to complete on file [F:\sql data files\xxx.MDF] in database [xxx] (5). 

2008-04-22 16:32:08.780 spid6s       SQL Server has encountered 2 occurrence(s) of I/O requests taking longer than 15 seconds to complete on file [H:\sql data files\xxx_data_4.NDF] in database [xxx] (5). 

 

Research and Findings

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

These errors may occur as result of “CPU Drift” and can be ignored and disabled, howerver, first verify both SQL DMV sys.dm_io_pending_io_requests and Windows Performance counters don’t indicate any IO delays.

 

On computers with multiple CPUs, the CPUs are designed to “sleep” during periods of low workload.  When CPUs sleep, SQL may not accurately determine CPUs overall workload and incorrectly report this as IO WARNING shown above, however, this does not represent an actual CPU performance problem.

 

To confirm if the CPUs entered low-power state, SQL Server Escalation Services created RDTSC (Read Time Stamp Counter) utility to report total CPU sleep time.  The report confirmed the CPUs were sleeping up to 24 seconds.  This would be enough for SQL Server to incorrectly report this a slow IO.  Both AMD’s and INTEL’s web sites describe the ability for CPUs to sleep.

 

RDTSCTest.exe [-md|-mt]

      -md   Detailed output (default)

      -mt   CPU speeds in table format

 

-- Current CPU Speeds --

Runtime              CPU  ExpectedMHz ActualMHz RDTSCTicks           DriftMS         

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

2008-04-22 17:53:36     0        3502      3503 0x0001564772F87FA72    16123.4

2008-04-22 17:53:36     8        3502      3506 0x00015647D8B7AE21D    23922.5

2008-04-22 17:53:36    16        3502      3507 0x00015647B5FEB4A39    21260.9

 

For more information on  RDTSC can be found at

http://blogs.msdn.com/psssql/archive/2007/08/19/sql-server-2005-rdtsc-truths-and-myths-discussed.aspx

 

Starting with SQL 2005 SP2 we’ve included two trace flags to disable the reporting of CPU Drift errors in the SQL Server errorlog. 

 

Disable this error using Trace Flag 8033

The time stamp counter of CPU on scheduler id 1 is not synchronized with other CPUs.

 

Disable this error using Trace Flag 830

SQL Server has encountered 2 occurrence(s) of I/O requests taking longer than 15 seconds to complete

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

In the majority of cases this warning indicates that an I/O operation has taken too long. This article looks at the possible reasons for this and describes what can be done to reduce the likelihood of it recurring.

There is another possible reason that is not I/O related and this is briefly referred to at the end of the article.

Let's start by examining the reason behind it. I/O requests from SQL Server are handled asynchronously by the operating system. This means that when a read or write request is made, the thread making it waits for the I/O to complete.
This frees CPU for use by another thread. Optimally an I/O should take a few ms, but can take considerably more than this. This warning is reported when the time between requesting an I/O and its completion is greater than 15 seconds.

The possible reasons for this are: I/O subsystem problems or misconfiguration, excessive I/O being requested by SQL Server, data files not optimally placed on the disk, and fragmentation.

I/O Subsystem

The first thing to do is to examine the I/O subsystem. Hardware errors are a common cause and you should run diagnostics if you are at all suspicious that this might be the case.

Two common reasons for poor I/O throughput on a SAN are out of date firmware, and insufficient queue length on the HBA. Be aware that if you upgrade SAN firmware you often need to upgrade the HBA drivers at the same time, or the server may fail to access the SAN altogether. Contact the SAN vendor for confirmation and details.

Another common cause of poor I/O performance is if a file system filter driver has been installed. A filter driver intercepts requests before they reach the file system, and performs additional processing such as anti-virus checking and encryption. It goes without saying that this can only have a negative impact on I/O performance.

If you have to have anti-virus software installed on your SQL Server, ensure that mdf, ndf and ldf files are added to the exclusion list. Even better is for realtime virus checking to be disabled completely; schedule a regular scan during quiet times instead.

I/O Load

It is often the case that there are I/O issues at night, when batch jobs are running, but it performs well during the day with no warnings in the logs.

You may find that there are several jobs running at the same time, either through poor scheduling or because one or more jobs have overrun. Provided there is sufficient free time you could reschedule one or more jobs and monitor for a couple of days to see if it has made a difference.

This is more complicated in environments where a SAN is used by several servers, as it may be jobs running on non-SQL servers overloading the SAN and causing your problems. In this case you need to discuss the problem with the system administrators responsible for these servers and agree a schedule that is mutually acceptable.

Fragmentation

Fragmentation may be internal (within tables/indexes) or external (file fragmentation on the disk).

Internal fragmentation is only a problem where in-order scans are being performed, and only on large tables. The warning message that is the subject of this article is unlikely to occur in this situation. Best practise is to monitor logical fragmentation and regularly rebuild or reorganize affected indexes.

Disk fragmentation can also be reduced through best practise, such as presizing data files (capacity planning), and not using autoshrink , or manually shrinking database files.

If you suspect disk fragmentation may be causing performance problems, I can recommend Diskeeper . This runs continuously in the background using idle CPU time only, and is able to defragment SQL Server files while they are in use. Your mileage may vary, but I have seen staggering improvements from running this tool.

I/O Configuration

Other best practise includes splitting tempdb into several files, putting data and log files on separate disks, placing clustered and non-clustered indexes in separate filegroups (on different disks), keeping statistics up-to-date, etc. All these will improve performance and some are described in SQL Server Configuration

.

One Last Possibility

In a minority of cases there may be not be an issue with I/O at all, but a problem caused by CPU drift. This is described in this article .

I stress that this is rare, and you should always examine the possible causes of slow I/O described above.

Summary

This article has described some of the most common reasons for "SQL Server has encountered n occurrence(s) of I/O requests taking longer than 15 seconds to complete on file <filename> in database <dbname>" .

In most cases this message is an accurate description of the problem, and reasons for slow I/O should be investigated.

请参考:

             aix与solaris中mount一个iso文件的方法

 

Linux系统在使用光盘、软盘或U盘时,必须先执行挂载(mount)命令。挂载命令会将这些存储介质指定成系统中的某个目录,以后直接访问相应目录即可读写存储介质上的数据。
  
  1.挂载光盘
  
  挂载光盘的命令如下:
  
  # mount -t is09660 /dev/cdrom /mnt/cdrom
  
  该命令将光盘挂载到/mnt/cdrom目录,使用“ls /mnt/cdrom”命令即可显示光盘中数据和文件。
  
  卸载光盘的命令如下:
  
  # umount /mnt/cdrom
  
  2.挂载软盘
  
  将软盘挂载到/mnt/floppy目录的命令如下:
  
  # mount /dev/fd0 /mnt/floppy
  
  卸载软盘的命令如下:
  
  #umount /mnt/floppy
  
  3.挂载U盘挂载U盘相对复杂一些。
  
  首先使用“fdisk -l”命令查看外挂闪存的设备号,一般为/dev/sda1。然后用“mkdir /mnt/usb”命令建立一个挂载U盘用的目录。之后使用如下命令挂载FAT格式的U盘:
  
  # mount -t msdos /dev/sda1 /mnt/usb
  
  使用如下命令挂载FAT32格式的U盘:
  
  # mount -t vfat /dev/sda1 /mnt/usb
  
  4.挂载外挂硬盘分区
  
  挂载外挂硬盘分区(FAT32格式)同样需要先用“fdisk -1”查看外挂的硬盘分区设备号,假设为/dev/hda1。建立/mnt/vfat挂载目录后,使用如下命令进行挂载:
  
  # mount -t vfat /dev/hda1 /mnt/vfat
  
  注意,默认情况下Linux只允许root用户执行mount命令。如果想让一般用户也能挂载,并且希望在系统启动时自动挂载光盘或软盘,需要修改/etc/fstab配置文件,加入以下内容:
  
  LABEL=/ / ext3   defaults  11
  /dev/cdrom/mnt/cdrom iSo9660 auto,owner,kudzu,ro,user 00
  /dev/fdo /mnt/floppy auto auto,owner,kudzu,ro,user 00
  
  其中,“user”表示将mount命令赋予一般用户使用。
  
  /etc/fstab文件在Linux的帮助手册中讲得很详细,读者不妨看一看。

光盘的使用方法

  mount命令用于物理设备中的文件系统挂在到linux文件系统的某个目录中,mount命令不使用任何选项和参数时将显示当前linux系统中已经挂载的文件系统信息。

  #ls -l /media/cdrom/(/media/cdrom/是linux系统默认的挂载点,只有当默认挂载点为total 0,时才能进行挂载。)

  #mount -t iso9660 /dev/cdrom /media/cdrom/(光盘挂载)

  #ls /media/cdrom/(读取光盘内容)

  #cp /dev/cdrom backup.iso(制作光盘镜像)

  #umount /media/cdrom/(卸载光盘)

  #eject(光盘驱动托盘弹出)

  #eject -t(收回)

  #mount -o loop -t iso9660 backup.iso /media/cdrom/(光盘镜像的挂载;backup.iso为光盘的镜像文件。)

  #umount /media/cdrom/(镜像的卸载)

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

在虚拟机上redhat 5.4 64bit上面,光驱的设备名为:./dev/hdc

挂载用:

            mkdir -p /mnt/cdrom

            mount /dev/hdc /mnt/cdrom 或者: mount -t iso9660 /dev/hdc /mnt/cdrom

卸载用:

            unmount /mnt/cdrom

前日误删除了C:\Documents and Settings\Administrator\.virtualbox目录,导致virtualbox上配置的redhat64bit虚拟机不能启动了。

试图拷贝一个其它虚拟机的xml文件修改一下,但是不可以。提示物理盘的uuid不匹配。那个虚拟机的xml文件丢失了,那么此虚拟机vdi文件上记录的uuid就无从得知了。

难道此redhat64bit虚拟机就不能用了?文件好几个G呢,删除了又太可惜,重装一遍很麻烦。

最后,在网上找到一个解决的办法:

利用virtualbox自带的命令行工具VBoxManage.exe 对残留的vdi虚拟机文件进行克隆,最后会重新生成一个uuid。

D:\Program Files\Oracle\VirtualBox>VBoxManage.exe clonehd /?
Oracle VM VirtualBox Command Line Management Interface Version 3.2.6
(C) 2005-2010 Oracle Corporation
All rights reserved.
Usage:
VBoxManage clonehd          <uuid>|<filename> <outputfile>
                            [--format VDI|VMDK|VHD|RAW|<other>]
                            [--variant Standard,Fixed,Split2G,Stream,ESX]
                            [--type normal|writethrough|immutable]
                            [--remember] [--existing]
Syntax error: Mandatory output file parameter missing

 

步骤一:

VBoxManage.exe clonehd D:\virtual-machine\linux5_64bit\linux5_64bit.vdi  D:\virtual-machine\linux5_64bit\linux5.vdi

耐心等待一会之后,会在命令行的下面显示一个重新生成的uuid,此uuid和D:\virtual-machine\linux5_64bit\linux5.vdi中的磁盘物理uuid是一致的。

步骤二:

在VirtualBox.xml文件中有:

<MachineRegistry>
      <MachineEntry uuid="{014d4435-25a9-4ce3-9aa6-ea18cc407698 }" src="Machines\linux5_64bit\linux5.xml "/>
      <MachineEntry uuid="{4d307441-f7a7-4196-8dee-d4d6910b0bae}" src="Machines\VMWIN7\VMWIN7.xml"/>
      <MachineEntry uuid="{8046d767-abf4-4eb5-bb73-451b54fbba38}" src="D:\virtual-machine\redhat64\redhat64.xml"/>
    </MachineRegistry>
对应本机安装的所有的虚拟机,记录各个虚拟机的配置xml文件的位置,以及每个虚拟机对应的机器id(machine uuid)。

步骤三:

找到redhat64bit虚拟机的配置文件Machines\linux5_64bit\linux5.xml,其中

<StorageController name="SATA &#x63A7;&#x5236;&#x5668;" type="AHCI" PortCount="1" useHostIOCache="false" IDE0MasterEmulationPort="0" IDE0SlaveEmulationPort="1" IDE1MasterEmulationPort="2" IDE1SlaveEmulationPort="3">
        <AttachedDevice type="HardDisk" port="0" device="0">
          <Image uuid="{4a0544d6-e496-4b21-af8c-e432410ea0a7 }"/>
        </AttachedDevice>
      </StorageController>
上面的image uuid就是通过VBoxManage.exe clonehd重新生成的硬盘id。

步骤四:

linux5.xml中

<Machine uuid="{014d4435-25a9-4ce3-9aa6-ea18cc407698 }" name="linux5" OSType="RedHat_64" lastStateChange="2010-08-16T10:41:07Z">

014d4435-25a9-4ce3-9aa6-ea18cc407698 要和VirtualBox.xml中的MachineEntry uuid 保持一致。

这样基本上重新打开以下virtualbox虚拟机,就能使用redhat64bit虚拟机了。呵呵。

参考:http://www.modhul.com/2009/06/17/how-to-clone-or-copy-a-virtualbox-virtual-disk/

————————————————————————————————-
—- 本文为andkylee个人原创,请在尊重作者劳动成果的前提下进行转载;
—- 转载务必注明原始出处 : http://www.dbainfo.net
—- 关键字:virtualbox xml hard disk uuid  VBoxManage.exe clonehd
————————————————————————————————-

sql server 2005中增加了动态性能视图,可以查看sys.dm_exec_query_stats获得正在执行的SQL的一些信息。

下面的SQL语句查询当前运行时间最长的10个事务的信息:

SELECT DISTINCT TOP 10
           t.TEXT QueryName,
           s.execution_count AS ExecutionCount,
           s.max_elapsed_time AS MaxElapsedTime,
           ISNULL(s.total_elapsed_time / 1000 / NULLIF(s.execution_count, 0), 0) AS AvgElapsedTime,
           s.creation_time AS LogCreatedOn,
           ISNULL(s.execution_count / 1000 / NULLIF(DATEDIFF(s, s.creation_time, GETDATE()), 0), 0) AS FrequencyPerSec
FROM sys.dm_exec_query_stats s
      CROSS APPLY sys.dm_exec_sql_text( s.sql_handle ) t
ORDER BY s.max_elapsed_time DESC, ExecutionCount DESC
go