SQL Server For The Oracle DBA
SQL Server For The Oracle DBA
Edition
SQLServer 2000
fortheOracle DBA
SQL Server for the Oracle DBA
Copying, selling, duplication or reproduction of this work is expressly forbidden without the copyright holder’s written consent.
All scripts and examples are used at your own risk.
DATABASE CHECKING ROUTINES .............. 226 SQL & T-SQL ................................... 268
LOG FILES (UDUMP, BDUMP) ............... 227
PL/SQL (T-SQL) ............................... 268
LINKED SERVERS (DATABASE LINKS) ........ 229
Comments and Statement End ....... 268
Example - Databases in the same
Understanding GO......................... 269
Instance ...................................... 231
Block Structure ............................. 270
Example - Connecting to an SQL Server
Declarations / Local Variables /
Instance ...................................... 231
Constants .................................... 270
Example - Connecting to an Oracle
Assigning values to variables & Create
Instance ...................................... 232
Table as....................................... 271
OPENQUERY, OPENROWSET,
Exception Handling (error handling) 272
OPENDATASOURCE ....................... 235
RAISEERROR and Error Messages ... 273
Remote Servers ............................ 236
Non-SQL Output ........................... 274
DTS PACKAGES .................................. 237
Cursors........................................ 275
DIAGRAMS (DATA MODEL DIAGRAMS) ....... 243
STATIC Cursors.......................... 277
Transferring Diagrams ................... 244
UTL_FILE (File IO)......................... 277
ROW CHAINING & MIGRATION ................. 245
Procedures/Functions/Packages ...... 278
TABLESPACE (FILE-GROUP) MANAGEMENT ... 245
User Defined Functions (UDF) ...... 278
PINNING TABLES ................................. 247
User defined Stored Procedures ... 279
TRIGGERS ......................................... 247
Versioning Stored Procedures ...... 280
CONSTRAINTS .................................... 248
Security & Ownership Issues........ 280
LONG RUNNING TRANSACTIONS ............... 248
Calling External Applications (command
SQL TIMEOUTS .................................. 249
shell)........................................... 281
RENAME DATABASE .............................. 249
DBMS_SQL................................... 282
USER MANAGEMENT ............................. 250
DBMS_RANDOM............................ 282
Login vs User................................ 250
DBMS_OUTPUT ............................. 283
Orphaned Logins ........................... 251
DBMS_MAIL, UTL_SMTP................. 283
Change DB Owner ......................... 252
DBMS_AQ .................................... 283
User Quotas & Account Expiry ........ 252
PSP, PL/SQL Web Toolkit................ 283
OPS$ Logins (OS Authentication) .... 252
DBMS_METADATA ......................... 283
Change Object Owner .................... 253
DBMS_JOB ................................... 284 OLE Automation ......................... 336
DBMS_LOB................................... 287 Registry Access .......................... 336
BFILE .......................................... 287 Other routines ........................... 336
Tables ......................................... 287 DATA TRANSFORMATION SERVICES ........... 337
User Defined (Inline) Functions....... 288 SYSTEM, OBJECT PRIVILEGES AND ROLES ... 337
Indexes ....................................... 289 Fixed Server Roles (Instance) ...... 339
SEQUENCES ....................................... 289 Fixed Server Roles (Database) ..... 339
What about UNIQUE IDENTIFIER? ... 292 User Defined Roles ..................... 340
BUILT IN FUNCTIONS ............................ 293 Object Privileges ........................ 340
Numeric Functions ........................ 293 AUDITING ......................................... 341
String Functions............................ 294 Application Auditing....................... 341
Date Functions.............................. 295 Profiler (trace) .............................. 344
SQL EXAMPLES WITH ORACLE COMPARISONS Instance level auditing................... 344
..................................................... 297 C2 Level Auditing .......................... 345
PARTITIONED TABLES ........................... 301 ENCRYPTION / OBFUSCATION OPTIONS ...... 345
PARALLEL QUERY ................................. 301 Networking Options ....................... 345
PARALLEL IO ..................................... 302 Encrypted File System ................... 345
SQL HINTS ....................................... 302 WITH ENCRYPTION option.............. 346
Example Hint ............................. 305 T-SQL .......................................... 347
DATA TYPES COMPARED ........................ 306
DYNAMIC SQL.................................... 309 INDEX............................................. 348
T-SQL (PL/SQL) OVERVIEW ................... 311
REFERENCES ................................... 352
NETWORKING SQL SERVER............. 313
LISTENER AND ODS ............................. 313
Multi-Protocol ............................... 315
Registry Entries ............................ 315
Client Network Utility..................... 316
ODS ............................................ 317
Tracing TCP/IP port issues.............. 317
List of Running Instances ............... 317
SSL OF SQL SERVER CONNECTIONS ......... 317
SQLOLEDB ...................................... 319
NETWORK MONITORING ........................ 320
SQLDiag ...................................... 322
MTS / ORACLE SHARED SERVER .............. 322
SECURITY ....................................... 323
SECURED INSTALLATION ........................ 323
LOGINS AND USERS ............................. 325
Authentication Modes .................... 325
BUILTIN/Administrator Login .......... 326
Using the SA login......................... 327
Duplexing a Login to Multiple Users . 327
Finding NULL Passwords................. 328
DBO Access .................................. 328
User Quota and Resource Restrictions
.................................................. 328
Password File................................ 328
Development Server Privileges ....... 328
Application Security – Connection
Strings & Authentication ................ 329
Authentication Example............... 330
Obtaining the DB Connection string
and Connecting to the Database... 331
Views and Stored Procedures.......... 333
Virtual Private Databases ............... 335
Label Security............................... 335
LOCKING DOWN EXTENDED AND SYSTEM
PROCEDURES ..................................... 335
Securing xp_cmdshell (OS Shell) .... 335
Securing xp_cmdshell (OS Shell) .... 336
1
Chapter
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
T
hroughout this chapter we will introduce you to the SQL Server Instance, the database and
core memory structures. The overview is reasonably thorough and where possible we will
drill through to the DBMS architecture, with some early examples of SQL and database
checking and consistency commands (DBCC).
In this and subsequent chapters, we will explore SQL Server 2000 and revisit some of the core
Oracle concepts to re-enforce the SQL Server equivalent technology (or lack of in some cases).
Please remember that we assume good working knowledge of the Oracle DBMS and the daily tasks
and challenges of the DBA; therefore, I don’t “beat around the bush” when explaining core
concepts or discuss at length syntax and semantics.
Please note that this ebook is not designed to be read from front to back but rather as a reference
guide to getting quick answers and where to look next.
When describing Oracle, database is used to describe the physical files and instance as the memory
structures and processes to interact with the database (3). In SQL Server 2k an instance describes
a complete, near independent installation of SQL Server that includes:
exit.
3. System databases, their physical database files, log files and other example databases
associated with the instance.
In general, think of a SQL Server instance as a new installation of SQL Server. To support multiple
installations of SQL Server on the same server SQL Server 2k introduced named instances. This is
a great feature that effectively allows you to have, say, a SQL Server 2k instance running Service
1
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Pack 2 installed and other running Service Pack 1 on the same server. In context to Oracle, its like
having v8.1.5 and v8.1.6 running on the same server.
When we run multiple named instances, we call them “near” independent installations because
there are common files used by all. Some of which (at a high level) include:
COM (DLL’s)
Replication
Tools
Enterprise Manager
Wizards
SQL Templates
Each instance maintains what is left over, namely their data files and complete set of executable
files. Installation of named instances is covered in more depth later in the book.
It is important to remember that the MDAC (Microsoft Data Access Components, see
http://www.microsoft.com/data/whatcom.htm) version is not instance dependent, it is a server
wide API for all data access (ADO, OLE-DB, ODBC). Therefore, care must be taken between service
packs and even other SQL Server installations as they may inadvertently “break” existing products.
2
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Instance Binaries
Instance Service
Instance & Address Space (oracle.exe) Instance & Address Space (sqlservr.exe)
SYSTEM MASTER
Tablespace Database
Undo MSDB
Tablespace Database
3
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
NOTE – When a new user database is created within an instance, its structure is modelled
from the MODEL system database. The DBA may customise selected properties of MODEL to
reflect these within any new database created.
1. 16 per server
3. Don’t necessarily need to install the default (non-named) instance, can start with a named
instance right from the start.
4. Instance can have different service pack levels and languages and sort orders
5. One Enterprise Manager (EM) manages all SS2k instances, with also includes the server,
client network utilities and network data providers.
6. Each instance has its own sqlserver NT service and associated binaries and registry entries
If you were wondering, I use the product Process Explorer available at sysinternals.com to drill
down into NT processes running on the server and associated file IO activity. This and other
internals tools are excellent when exploring the inner workings of the NT/Windows operating
system and associated application processes.
NOTE – When a SQL Server DBA talks about “SQL”, some are actually referring to the
product “SQL Server” rather than the SQL language.
The control file is critical to an Oracle instance, it stores a variety of information such as:
Database name
Timestamp of DB creation
Tablespace information
Checkpoint information
and more..
4
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Within a SQL Server instance this information is a divided over a range of databases. The control
file is basically the master database. Without it the instance will not be able to start as it consists of
all the information about other system and user databases. The master database can also be
viewed the system tablespace to some degree, but it distributes its data dictionary objects with
other system and user databases (such as MSDB).
The data dictionary within SQL Server is a series of system tables with the sys prefix owned by the
internal user dbo (which, like the sys account, can never be removed). These reside in all user and
system databases within the primary file-group of the database. Because the dictionary is divided
over the databases, it is important that backups include all system databases (master, model,
msdb) at a minimum, just as you would backup the system tablespace, control files, rollback
segments within an Oracle instance.
In terms of users databases and dictionary objects, each user database includes a standard set of
sys tables using to track space allocation, objects created (views, tables, constraints etc) and basic
SCN (called LSN) and database file properties.
To work with the data dictionary, SQL Server provides the DBA with:
stored procedure calls (prefixed with sp_ in the master and msdb databases)
information schema views, special pre-summarised views to simplify direct querying of the
data dictionary sys tables.
DBCC routines (database consistency checking), special database checking, validation repair
routines called from query analyser or other command line utility
Extended stored procedure calls for externally developed routines for DB management
Search for “master database, information stored in system tables”, for an excellent overview of all
sys dictionary tables within the system and user databases within the BOL (SQL Server help books
online).
As there is only one master database, there is no concept of multiplexed control files.
Datafiles
An Oracle tablespace can have one of more data files. Within SQL Server, a file-group can have
one or more datafiles. Objects can span multiple data files in its file-group as they can do within
Oracle tablespace data files. If there is more than one data file per file-group, then SQL Server will
stripe (store) data evenly across each of the datafiles (based on the % free space within each data
file).
A database file (data file) also consists of a logical-filename, this includes all database files (data
and log files). The logical filename is referred to during alter database commands and recover to
make life easier when referring to database files rather than their physical name or when referring
5
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
to the files file-group is not appropriate. The logical name of a database file must be unique for the
database but other databases can use the same name if need be.
As with Oracle tablespace datafiles, SQL Server supports dynamic datafile growth by percentage or
by megabytes to a maximum or unlimited size.
Tablespaces
Are known in SQL Server as File-Groups, these are logically named structures that hold zero or
more physical database files (zero because you can actually create a group then add files later). All
databases have a default PRIMARY group that cannot be removed or renamed although the files
within it can be manipulated. The primary group will consist of one data file containing the
databases data dictionary objects (sys tables). Adding more file-groups is synonymous to adding
more tablespaces to an existing database in which tables and indexes can be stored within. At the
database level you can specify the default file group that will be used when a users object is created
without specifying the destination group. A database user cannot have a default file-group as a
property of being a database user.
It is important to remember that a databases transaction log data file for a database cannot be
allocated to file-group, only non-log files can.
The SYSTEM tablespace is the same as the MASTER database with a SQL Server instance. As with
Oracle, it must be online for the instance (and other user and system databases within the
instance) to successfully start. This database contains a variety of critical information about other
databases, logins, extended stored procedures etc.
An UNDO tablespace in 9i has replaced rollback segments in previous versions of Oracle. The
content or meaning of has not changed within Oracle, but architecturally the undo tablespace is
very different to “rollback segment” management when using automatic undo management.
Rollback and Redo is discussed in detail in the Transactions and Locking Chapter. The equivalent
SQL Server structure closest to the undo tablespace is the databases transaction log; one
transaction log database file exists at a minimum for all system and user databases.
6
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The TEMPORARY tablespace is equivalent to the tempdb system database that is automatically
recreated on instance start-up. The DBA cannot alter the user/login properties to specify the
temporary tablespace as with Oracle, it is automatically the tempdb and cannot be removed or
altered.
The read-only tablespaces are supported in SQL Server as read only file-groups. All user-defined
file-groups can be made read-only; the primary file group cannot be made read only. To make the
primary file-group read-only you, must make the entire database read only.
The DBA cannot Offline/Online a file-group like you can an Oracle tablespace.
There is no concept similar to dictionary or locally managed tablespaces within SQL Server. Each
database maintains its own storage properties via the sys tables in the primary filegroup of the
database, apart from that, all extent and block (pages) are uniform in size and can not be altered.
The transaction log file, depending on the databases recovery model, will continue to grow in size
until the database issues a backup transaction log statement for the database, or truncates the log
(point in time recovery will not be possible though).
The backing up of the log is the same as an archived redo log file. When we backup the log we can
send it direct to tape, a file share on another server (UNC path), to disk or via a named pipe; even
so, SQL Server does not provide any magic duplexing commands with the backup statement, so
the DBA needs to copy the backed up file to cover all bases.
A transaction log exists for each database within the instance and will hold:
modifications not yet flushed to disk (to be rolled forward on database recovery)
NOTE – Where possible, do NOT create more than one transaction log data file per database.
The log is sequential and there is little benefit from duplexing files over multiple spindles.
Multiple files can be a pain to administer and deal with in terms of re-attaching databases (see
Backup and Recovery) and managing log files sizes/shrinking.
Rollback Segments
There are no rollback segments in a SQL Server database. This concept is described in detail later
in this book. Because of this, writers can block readers and SQL Server’s locking mechanism is
much more complex that Oracle’s with a higher probability of locking problems with long running,
7
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
non-committed transactions. These issues can be resolved to some degree with using different
isolation levels on connection to the instance or per transactions, or using locking hints to enhance
database concurrency.
The transaction log acts as a data store for incomplete database transactions pending a commit or
rollback. Because of this it can be a type of rollback segment but from an Oracle definition, it is
very much limited in function.
Init.ora
There is no equivalent file in SQL Server, the closest we have is the internal settings within the
master system database via the sp_configure stored procedure command or set via Enterprise
Manager, the registry settings or the service startup parameters (sqlservr.exe).
Environment Variables
There is none, the registry controls all aspects of the SQL Server instance at this level.
8
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
MEMORY STRUCTURES
It is difficult to compare the two databases at a memory level. In some respects, both use the
same, proven, fundamental data structures and techniques for managing their memory structures.
The key difference here is that Oracle provides fine grain control over virtually all aspects of the
memory (and storage) engine, whereas SQL Server provides very little control. This is not
necessarily a bad thing in a majority of cases.
NOTE – Oracle has many complex memory structures that are configurable by the DBA, some
of which are not shown in this diagram on purpose. Read the summaries later for each
memory area for more information in context to Oracle.
Shared Pool
Library Cache
Procedure Cache
Dictionary Cache
Log Caches
9
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The following provides a further drill down into the SQL Server architecture in terms of its threads
of execution and associated subsidiary engines. The key point here is that SQL Server runs with a
similar architecture to that of its underlying operating system, via a pool of threads that
asynchronously perform a variety of tasks on behalf of the DBMS and its related engine
components (storage, relational etc). Remembering this, we can see where DBWR, LGWR and
other Oracle processes are represented in the SQL Server framework. Each arrow/line typically
represents one or more of these worker threads (or fibres when DBA selects the option).
NOTE – The thread architecture for Win95 and 98 clients is not represented below.
Procedure Cache
Plan caching and reuse
Buffer Cache
Log Cache’s
Divided amongst Parse SQL
the worker Relational Optimise Plans
threads to async. Engine Exec Logical ops
scan, read and asynchronous Process DDL / other
write, a reading asynchronous logwriter Result formatting
thread wont affect worker threads threads
a subsequent
Manage files
scheduled write
Storage Build and read physical
Engine pages
checkpoint process Data buffer and IO
(buffers not added to Logging and recovery
free list) Utility functions
Free buffer list
Net-Lib
Data Files T.Log Files
Providers
10
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
There is one UMS (user mode schedular) for each CPU. On a user connecting, a worker thread and
UMS schedular is allocated for the lifetime of the connection. Idle threads are allocated from the
pool of waiting threads, if all are busy the work requests are queued and allocated in a round-robin
scheme to threads. Use the command DBCC PSS to get UMS and thread details for a SPID:
DBCC PSS (0, 1) -- Where 1 is the spid
DBCC SQLPERF(UMSSTATS)
DBCC SQLPERF(THREADS)
The virtual address space that is made up of a global memory pool and a reserved working space
for the loading of extended stored procedures (in master database and start with xp_, they are
external DLL’s), OLE-DB data providers and automation objects instantiated via sp_OACreate. This
memory allocation is controlled via the –g parameter on instance startup and defaults to 128Mb.
The only real control the DBA has over memory is the –g parameter on instance start-up, the min
and max server memory option and the set working size option (both set via sp_configure when
the instance has started). These options are best managed via EM as shown in the dialog box
below:
11
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Consider setting the maximum RAM by 10 to 20% less that the total server memory for dedicated
database servers.
NOTE – It is best practice to always control memory, setting a maximum that is appropriate
to the server configuration and the software running against it. See system table
master..syscurconfigs for current configuration options set.
Buffer Cache
SUMMARY
The buffer cache is a dynamic pool of buffers (8k pages) read from the physical data files and is
equivalent to the Oracle buffer cache. All subsequent reads/writes to physical data files occur via
the buffer cache. The cache itself consists of:
Each buffer page has a header that, among other things, contains a reference pointer that is
incremented when SQL statements reference the page. The increment may differ internally.
A value of zero on the reference counter marks the page as dirty. A write is then scheduled.
A global pool of worker threads via the user connection will manage writes and reads from
the cache.
The buffer will include data and index pages to complete all SQL from all databases hosted by the
instance.
The Oracle buffer cache goes many steps further than SQL Server in terms of configureability and
control, for example:
12
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The SQL Server DBA has no control over the sizing or the reservation or division of the cache.
To locate pages not in the buffer cache hash bucket data structures are used. To view them, run
the following:
DBCC TRACEON(3604)
GO
DBCC BUFCOUNT
GO
SQL Server can also employ a read-ahead (RA, or parallel data scan) operation concurrently via
multiple threads for a single request. The optimiser will determine the requirement for the RA
operation and schedule the RA. This may be based on a count of pages missing in the database
buffer cache at the time and the sorted nature of the data itself in terms on proximity (especially
clustered indexes). The types of operations include table scans, index leaf-level scans, DBCC
statements and the updating of statistics.
The RA options have been removed in SQL Server 2k and the DBA can no longer control the RA
operation.
To drop all clean buffers from the pool, run the following database consistency checking command
via query analyser:
DBCC DROPCLEANBUFFERS
The DBA can PIN objects into the cache as in Oracle via the DBCC PINTABLE command.
MONITORING PERFORMANCE
To monitor the hit ratio of the buffer cache, the best tool is Performance Monitor (perfmon.exe).
The counter is SQL Server : Buffer Manager, when there are multiple named instances the counter
will be something like MSSQL$<instance-name>: Buffer Manager. Other counters related to the
buffer manager include Free pages, Free List requests / sec and Free list empty/sec.
13
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The redo log buffer in Oracle is a circular buffer of redo entries (which are any changes made
by any insert, delete, update, create, alter, drop statement) stored sequentially in the SGA
and controlled via the log buffer parameter. The background process lgwr writes the redo log
buffer entries to the current active online redo log file. It is important to understand that any
block change requires the creation of a redo log buffer record, lgwr will free space as need be
in the cache. A series of latches are used to manage this process:
a) redo copy
b) redo allocation
c) redo writing
The Oracle DBA subsequently needs to monitor the log buffer size and associated space
contention; then to a lesser degree latch contention.
In a SQL Server instance we have a single log cache memory structure for all databases within
the instance; there is a series of cache buffers for each database within the instance. For
every change made to a buffer cache page a log cache entry is made recording the change,
this must be written to the databases transaction log before the dirty buffer cache record is
written (flushed) to disk. This process is essential to ensure effective rollback during database
or user transaction recovery. Due to this write-ahead strategy of log-cache Æ transaction log
Æ buffer cache flush the transaction log is at times called the write-ahead log.
The SQL Server managed log-writer threads manage the flushing of data from the cache to disk.
NOTE - Non-logged operations are primarily controlled via the recovery model used for each
database within the instance.
MANAGEMENT OF
To view the contents of the transaction log (similar to that of log miner tools), drill into the
command:
LOP_MODIFY_ROWS
LOP_INSERT_ROWS
LOP_DELETE_ROWS
14
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The procedure cache has many similar elements to that of the library and dictionary cache
combined within Oracle. The query processor (part of the relational engine that parses, compiles,
optimises and manages the submitted statement) will develop the necessary plan and return it for
execution; the plan and associated data structures are submitted to the procedure cache to
complete the call.
Compiled plan
Executable plan
Parse Tree
Stored procedure
Trigger
Views
Default
User table
System table
Check constraint
Rules
15
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
A worker thread is allocated to manage concurrent procedure cache operations. Where possible,
only one copy of a plan is stored at any one time. This enforces serialisation (not at all times) of
the compilation process and is managed via compilation locks. The Microsoft support document ID
Q263889 provides a good explanation of such locks and compile blocking, primarily dealing with
stored procedures.
NOTE – See the section on “Dynamic SQL” for more information about caching plans.
MONITORING
To get some general buffer cache statistics, use the following command.
DBCC PROCCACHE
DBCC MEMORYSTATUS
and DBCC MEMUSAGE
MANAGEMENT OF
To flush the procedure cache globally for all databases in the instance, run the DBCC command:
DBCC FREEPROCCACHE
To flush the procedure cache for a specific database in the instance (where 3 is the database ID
from sysdatabases in the master database):
DBCC FLUSHPROCINDB(3)
Do a before and after check in the master database dictionary table – syscacheobjects, to verify the
affect of the routine. Be careful with these commands especially on your long running production
server. You will effectively force the once “warm” SQL Server procedure cache to be cleared and all
this will undoubtedly result in a degradation of performance for some time whilst plans are re-
cached.
You can force the recompilation of stored procedures the next time its run via the sp_recompile
system stored procedure. The create procedure command also includes the option RECOMPILE to
prevent the caching of the execution plan.
MONITORING PERFORMANCE
Utilise the NT performance monitor and the counter “SQL Server : Cache Manager Object” and the
items “Procedure Cache [Hit Ratio (cache hits vs. lookups), Pages (#8k pages in use), Object
Counts (#cache objects)” . The counter data is also available in master..sysperfinfo.
16
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The 20 largest procedures in the cache can be monitored via the command below and can be used
to predict future space requirements:
DBCC MEMUSAGE
To view the contents of the procedure cache, query the table master..syscacheobjects table in the
master database. Here we find a breakdown of cache objects by type (eg. Executable Plan,
Extended Proc, Parse Tree, Compiled Plan for example). Some of the core columns are:
pagesused, usecounts, refcounts and of course sql (being cached).
Third party tools, like Diagnostic Manager from NetIQ, provide cache hit statistics with a hit ratio
breakdown per cache object type over time.
The properties of each SPID can be monitored via the sp_who and sp_who2 stored procedures or
by querying the master..sysprocesses table.
The DBA determines which of the databases within the instance the login can access, these are
called database users; as the login to user mapping exists separately for each instance database
with their own database level privileges (i.e. 1 login to many database users within the instance).
The sysprocesses table has a variety of information that the DBA may be interested in, namely the
ECID (execution context ID in which threads are running under for the SPID, KPID (current NT
thread managing the SPID), CMD (command being executed) and much more. Such information
may be present in the server error logs on occasions.
In terms of memory usage, SQL Server documentation is reasonable scarce in detailing the
sequence of events (although you could probably guesstimate it) and associated memory
structures. Generally, each connection will take a minimum of 12Kb + (3 x TDS Network Packet
Size), the TDS packet being 4Kb by default (see master..sysconfigures where config = 505 for
runtime value). The packet size can be set via the network packet size database option or via EM
via Tools Æ Options Æ Advanced.
The number simultaneous connections accepted can be controlled via the maximum concurrent
user connections property. Select properties for the instance and select the connections tab. The
DBA can check the value via select @@MAX_CONNECTIONS.
With SQL Server 2k, we can programmatically add up to 128 bytes of binary data to the current
session (connection). The context data remains accessible to all SQL for the session/connection.
The context_info column can be queried in the master..sysprocesses table to retrieve the data for
the SPID. To set the binary data in T-SQL code, here is an example:
17
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
select context_info
from master..sysprocesses
where spid = @@SPID
The wrapper T-SQL stored procedure is like any other stored procedure in terms of calling it. The
object is referred to in the master..sysobjects table and they can be managed via:
sp_helpextendedproc
sp_dropextendedproc
sp_addextendedproc
sp_addextendedproperty
See Microsoft Support Doc# Q190987 for a great summary of extended procedures albeit with a
lack of example code.
Checkpoint
Within the Oracle DBMS, a checkpoint is a database event that synchronises altered data blocks in
the buffer cache with the physical data files. The DBWR process on certain conditions, such as
every 3 seconds, on a redo log switch or how full the buffer cache is with committed dirty buffers,
manages the write event. The CKPT process will update the control file and data files to indicate
the last completed checkpoint with the SCN (system change number). In older versions of Oracle
the LWGR would perform job of the CKPT process unless the DBA overrides the option with the
checkpoint_process start-up parameter.
The Oracle DBA has a lot of control of the checkpoint process; it’s timing and monitoring
performance. Even so, many of these parameters are rarely understood and at times can severely
impact performance.
18
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
It is not too surprising that fundamentally, a SQL Server checkpoint (in theory) is the same as
Oracle in that both are events that synchronise altered database blocks and log files in the buffer
and log caches with the physical data files. In saying that, remember the key differences in redo
logs and server processes between the architectures.
The checkpoint operation itself results in a flush of dirty data and log pages, the databases within
each instance checkpoint separately, maintaining their own last SCN (LSN in SQL Server) for
recovery. The checkpoint will:
write to the transaction log file (redo and rollback segment in Oracle) marking the start of
the checkpoint
Write LSN to the database boot page, begin recording information about the checkpoint in a
chain of log entries.
Records the minimum LSN (MinLSN), being the LSN of the first log record to complete a
database recovery
Remove all virtual log records in the transaction log before the MinLSN (simply recovery
model, backup log command will have the same affect, also called archived redo logs)
based on the recovery interval parameter and the number of associated log entries to fulfil
the parameters setting.
NT service stopped
The DBA can control the recovery interval (in seconds) parameter for each database within the
instance. The DBA can also force a checkpoint for a specific database via:
use mydb
CHECKPOINT
19
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
This command is available to the syadmin, db_owner and db_backupoperator privileged server and
database roles.
Background Processes
An Oracle instance is implemented as a single process, namely oracle.exe, under which the
background processes, namely pmon, dbwN, lgwr, ckpt, smon, reco run as threads. The oracle.exe
process corresponds to an NT service that is typically named OracleServiceSID.
NOTE – Get the Oracle thread details by querying v$process, v$session, v$bgprocess over
the addr and paddr columns.
The threads themselves can vary depending on the installation, i.e. if clustering or replication
services are used. Some of the common ones include:
In the SQL Server world, a SQL Server instance also runs under a single process sqlservr.exe with a
number of worker threads. These threads manage (not a definitive list):
scanning the buffer cache, reading pages into cache, writing dirty buffers, populating free
buffer list
scheduled asynchronously
Selecting rows from master..sysprocesses, you will see a variety of system processes running
against the instance, some of which are managers of the individual worker threads. Some
examples are:
20
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
LAZY WRITER
LOG WRITER1
SIGNAL HANDLER
TASK MANAGER
CHECKPOINT SLEEP
These threads utilise a common memory area (stack) within the SQL Server instance address
space.
The worker thread is controlled by the configuration parameter max worker threads. The default
is 255.
Each thread is assigned a schedular (see DBCC SQLPERF (UMSSTATS) ). The wait state of worker
threads assigned to a UMS schedular is logged in the SQL Server error log and you get a thread
starvation error message if all UMS threads are in a wait state. Remember that there is one UMS
schedular for each CPU, the value of max worker threads parameter is evenly divided among the
UMS schedular(s). Each connection (SPID) is allocated to a thread linked to a UMS that never
changes throughout the life of the connection. The idle worker threads are allocated to incoming
tasks as need be, queuing requests appropriately whilst worker threads are made available. See
Q262973 for a good overview.
REMEMBER – Each individual database within the instance does not have a separate global
pool of worker threads.
21
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Storage Engine
This section covers a variety of areas related to the Storage Engine, namely:
tablespaces (file-groups)
Segments
Space management
Tablespaces
Each database within SQL Server has a minimum requirement of:
one transaction log file (logs are not associated with file groups)
A filegroup is the logical name for a tablespace. One file-group can consist of zero or more physical
database files. The transaction log file (redo log) is dedicated to the database and does not have
the concept of filegroups and therefore logical names, it is simply a redo/rollback log with a logical
and physical file name that is used for transaction management. The general extension naming
conventions for database files are:
.ndf next data file (for any other files created for the database)
The logical name is a unique name that will identify the file within the file-group. I like to use it to
identify the general contents of the file within the file-group to simplify recovery, for example
MYDB_DATA or MYDB_AUDIT.
It is important to remember that a file-group (tablespace) with two or more database files causes
SQL Server to stripe writes over the files based on the percentage of free space available within
each. Depending on your application this may provide a performance enhancement as SQL Server
creates a new IO thread for each file. This is not the case though with transaction log files which
are sequential. Best practice states that where possible have one and only one database file per
file-group.
22
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
NOTE – our temporary tablespace is the tempdb database and is shared by all databases.
Database creation is discussed in detail later in this book. Take careful note of the syntax, if you
use Enterprise Manager it will use the alter database statement to add any files other than the
primary file-group and the transaction log, rather than doing it all in one statement.
The DBA can specify the file-group in which database objects are created. By default they will be
created in the primary filegroup. Only tables, materialised views (indexed views) and indexes can
be stored to a specific file-group via the ON clause, eg:
It is important to understand that file groups are logical structures, they can be created
independently with no datafiles in them (see alter database command) and physical files can be
added or removed later. A file-group cannot be removed until all of its data files are removed.
Also, removing a single file, even if it’s the only file in the filegroup, does not mean the file-group is
dropped (this is not the case via EM). Use the alter database <mydb> remove filegroup
<logicalname> command. The primary file-group (default) cannot be removed.
SQL Server will automatically remove the physical data files when a database file is dropped. So
long as there is no user objects in the data file or in the case where the file is a transaction log file,
there are no transactions, the DBA can remove the file. See the stored procedure commands
sp_dbremove (deletes a database), sp_detach_db (removes database from instance but retains
files, preferred method), alter database <mydb> remove file <logical-name>.
23
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
A file-group can be made the default group for user objects. Best practice typically states that the
DBA creates additional file-groups (data, index) and does not use the default PRIMARY filegroup
that holds all the sys tables (mini data dictionary) for the database. Use the command alter
database <mydb> modify filegroup <logicalname> default.
We can specify the default operating system location of filegroup files as we can do with Oracle and
the db_create_file_dest parameter in 9i. The parameters in SQL Server are very basic and covers
data and log files for new user databases at an instance level. These entries are actually stored in
the registry for the instance and can be altered via Enterprise Manager (right click properties for the
instance and choose the Database Settings tab) or via the extended stored procedure (xp_routine
reside in the master database only) command:
exec xp_instance_regwrite
'HKEY_LOCAL_MACHINE',N'Software\Microsoft\MSSQLServer\MSSQLServer',N'DefaultData',REG_SZ,N'
E:\SQLServerData\'
SQL Server will not name the files for you or let you overwrite existing data files on a create
database statement. When restoring though, you can force an overwrite of existing files if need be.
For a new database (includes 1 data file for the primary file group and 1 transaction log), SQL
Server will call them:
<instance-name>_<db-name>_SYSTEM
<instance-name>_<db-name>_LOG01
If it’s the default instance then leave <instance-name> blank. I use 01 to 99 to ID the file-number
in the group. Good naming standards can assist the DBA in emergency recovery scenarios.
There is no reason why you cannot use the OFM (Oracle File Management) and associated OFA
(Oracle Flexible Architecture) naming conventions for files with SQL Server (it wont pre-empt you
anyhow so its good to stick with the conventions).
24
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
block sizes for each tablespace (up to 5 standard sizes in 9i) to cater for different storage
characteristics of objects. Earlier versions of Oracle allow the block size to be set once on the
databases creation, even so, it is completely user defined. The set block (page) size for SQL
Server is 8k, you cannot alter this, so we have no DB_BLOCK_SIZE parameters of at the database
or file-group level.
FACT – SQL Server does not support multiple block sizes or variable extents.
Header
Header (96k)
84 to
107k Table Directory
Pointer to
Row Directory text data
Row data
where
appropriate
Row data
fillfactor
(pctused)
Row offset
pointers to
There are eight different page types in SQL Server : physical data
rows
data
index
text/image
global and secondary allocation map – what extents (64k contiguous) are allocation
bulk change map – lists extents modified from bulk operations since last log backup
differential change map - extents modified since last backup database command
NOTE - Row offset table entries start at end of page, 1 entry per row, in table entries are in
reverse sequence of rows in the page.
25
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The fillfactor option is used in place of pctused in Oracle. You cannot use this option in create table
command though, it is only used when indexes (clustered or non-clustered) are created. When
DBA’s of SQLServer talk about defragmentation, it is usually in context with indexes and rebuilding
them to resolve storage issue and page splitting. The default fill factor is zero, this is similar to
100% but with space for one record left at the higher level of the index nodes.
As a clustered index defines the storage of the table, the option fillfactor has a key influence over
the leaf (actual data) pages and the most affect with subsequent inserts or updates against the
segment.
On top of fillfactor, the DBA can also specify pad_index. This option can only be used in
conjunction with fillfactor and specifies the space to leave available at all non-leaf nodes (called
intermediate pages) of the index. The pad_index value is internally set by SQL Server and is based
on the value specified by fillfactor.
Since SQL Server has fixed page sizes the extent size is also fixed at 64k (8x8k pages) as is
contiguous in its storage. This is the smallest IO call SQL Server will make. The idea of the DBA
pre-allocating extents to objects or change extent size is non-existent in SQL Server.
The DBMS has the concept of uniform and mixed extents, this affects the allocation of space to
segments. A uniform extent is one whose pages are allocated to a single segment. A mixed
extent means its 8 pages may be shared by a variety of segment pages. SQL Server will allocate
space to segments (tables/index etc) at a page level, if, during space allocation, the DBMS
determines that an entire segments mixed page allocation can fill an extent, then SQL Server will
allocate (reserve) uniform extents for the object rather than individual pages. See free space
management next for more information.
It is worth mentioning that in Oracles’ locally managed tablespace, the tablespace manages its own
extents via a bitmap structure for each datafile to track free or used blocks. As the uniform extents
26
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
are allocated and deallocated the bitmap entries for the associated blocks are also altered. On top
of this, there is no requirement for coalescing free extents to consolidate fragmented free space as
all extents are uniform in size (unlike dictionary managed tablespaces).In SQL Server, “free space
management” in terms of a ‘free-list’ entries consists of two page types:
1 = free, 0 = allocated
Tracks those extents that have mixed pages and have at least one unused page
0 = not used as mixed, or, is a mixed extent whose pages are all in use.
These pages, typically found after the file-header pages are used by SQL Server for extent
management for each data file (not including transaction log files). To complete free space
management we also have PFS pages.
A PFS (page free space) page records individual page allocations within the data file. The page
itself is a bitmap structure similar to the GAM and SGAM but only covers 8000 pages at a time. The
value of the bit denotes the percentage full within the pages for an extent, for example:
Empty
1 - 50%
51 - 80%
81 - 95%
96 - 100%
Finally, we need to discuss IAM’s (Index Allocation Maps). These are critical as they map the
extents in a database file used by the heaps (non-indexes tables), indexes (including clustered
indexed tables) and blob objects (ntext, image, text pages). Each object has at least one IAM so
long as:
27
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
the object did have data, but it was “deleted” rather than truncated.
The IAM’s are linear linked lists and are scattered throughout the data file as the objects within it
acquire space. If the file-group has more than one data file then remember that storage will be
allocated evenly over the data files based on the total % free space in the data files, therefore IAM
linked lists will span the physical data files within the logical file-group.
NOTE – IAM, PFS and other pages will be bought into the buffer cache along with other
standard page types holding row and index data.
The IAM and PFS pages are used to locate pages with enough free space to hold incoming rows.
The IAM’s are used to locate the extents for the object, whilst the PFS is used to locate page free
space. Necessary reallocation of extents (mixed to uniform) and subsequent acquisition of new
extents is via the GAM and SGAM pages.
All 8k pages,
64k extents (not sysindexes entry for all
shown in diagram) objects to first IAM
We can view the allocation of space via sp_spaceused or dbcc showcontig. With this the DBA
can see how a tables space allocation moves from mixed extents to the reservation of uniform
extents to the object. The following example was adapted from the work of Kalen Delaney
and her classic articles from SQLMag.com:
As we insert rows (row#), and execute the sp_spaceused procedure we get the following results:
28
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
NOTE – when you create a table with no indexes, an entry is placed in sysobjects and then
sysindexes for the table, the sysindexes entry record consists of an IAM binary entry pointing
to the first IAM for the object. With no data the entry is 0x000000000, as data is entered the
first IAM is allocated. If you “delete from” the table, the IAM entry remains and sp_spaceused
reports the same space utilisation!, but a truncate will clear the IAM entry altogether and
associated other GSAM, GAM pages therefore returning those pages/extents quickly back to
the storage engine.
29
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Fragmentation
Fragmentation occurs at a variety of levels with DBMS’s and seems to be one of those ongoing
struggles for the DBA to resolve. In Oracle, fragmentation of segments is a classic problem,
occurring primarily where many segments with different growth characteristics share a tablespace.
This as been addressed with locally managed tablespaces and fixed extent sizes for segments. In
SQL Server as we have seen in previous examples, the allocation of space occurs in the form of a
mixed extent then reserving uniform extents (64k - 8 contiguous pages). All this said, we still
have the following issues in both databases:
In SQL Server, the only way to resolve honeycombing object extents is via:
BCP out data (or copy to another database), script foreign keys, drop foreign keys, truncate
tables, reimport data, enable keys
For clustered indexed tables only – DBCC REINDEX or DBCC INDEXDEFRAG or drop and re-
create the clustered index (can be problematic if a primary key constraint).
The DBA can view the fragmentation of its indexes via DBCC SHOWCONTIG, which divides the
fragmentation into:
Be warned that for SHOWCONTIG to display accurate figures you may need to re-run DBCC
UPDATEUSAGE and then possibly try shrinking the database. For some strange reason statistics
used by SHOWCONTIG can become “out of date”, causing no end of confusion for the DBA.
For heaps (non-clustered indexes), space is not automatically added at the end of the structure, the
PFS will be searched for free space for the record and inserted appropriately. Therefore, a table
with a sequenced primary key that is also experiencing heavy deletions can have is rows dispersed
throughout its pre-allocated extents.
Reporting on Fragmentation
Use the command DBCC SHOWCONTIG to report on a table or indexes fragmentation. When
writing scripts to track fragmentation over time, consider this command:
30
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Loop for all user objects (sysobjects) in the current database and run the above into our
custom created fragmentation history table msdb..dba_fraghistory. An example of an indexes
fragmentation summary is shown below:
Pages scanned = total pages used (in clustered index, this of course represents the actual data pages as well
as the index intermediary nodes)
Extent switches = movements between 1 extent to another over its extent chain.
(pages scanned / 8 should-be less than extent-switches).
Avg pages / extent = technically, represents unused pages per extent, 8 is the optimal value (no unused)
Scan density = fragmentation % (best count is the ideal value vs the actual extent switch count)
avg page density = how full the average page is, again, is dependent on row size, fill-factor, and
inserts/deletes/updates.
Be warned with the values presented above. A small table, for example products in the Northwind
database, reported 77 rows, two extents (1 switch), and a scan density (fragmentation) of 50%,
with a terrible avg pages / extent of 1. The mixed extent issue is the reason and should not overly
worry you.
Resolving Fragmentation
Clustered index tables will benefit the most from SQL Server’s defragmentation routines as they are
all based around indexes (a defrag on a clustered index will of course compact data and index
pages), unlike heaps (tables without clustered indexes, compacts indexes only). The following is
recommended and can be further explored in the books online.
DBCC DBREINDEX
31
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
DBCC INDEXDEFRAG
DBCC SHRINKDATABASE
Consider dropping and re-creating your clustered indexes if the above seems to be skewed
(after re-checking the fragmentation report). Always concentrate on the largest and busiest
tables first.
32
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The actual amount should be re-confirmed with your particular SQL Server installation in case there
is variance with DBMS versions, OS and/or IO sub-system configuration. The example below
shows the reservation of space.
IMPORTANT – This example was with a heap (non-clustered index) table. See the
examples below for space utilisation after a delete with a clustered indexed table.
In terms of a HWM and the optimiser full-table scanning to the end of the tables memory allocation,
we see the following occur for empty tables:
33
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
34
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
-- truncate
Table 'largerow3'. Scan count 1, logical reads 0, physical reads 0, read-ahead reads 0.
Segments
In early versions of SQL Server (namely 6.x), we had the concept of segments and their pre-
allocation to house set objects (index, tables) typically to separate disks to increase IO speed. This
concept is no longer valid in SQL Server 7 and 2000.
data – all data type entries, text/image/ntext data can be stored inline with the data row via
the text in row option is used on table creation.
text/image – storage of data type text, image, other blob data out of line with the rest of
the data row. The data row page has a 16-byte text pointer to this entry.
GAM / SGAM
Free space
BCM
DCM
Most of these segments have already been discussed. The key fact to remember here is that
segment space is not pre-allocated by the DBA, SQL Server manages the space allocation in all
cases. The DBA can only control fillfactor (default zero or 100%) and padindex (default 1 space for
a single row) options for indexes.
Relational Engine
The relational and storage engines are completely separate within SQL Server and communicate via
the OLE-DB API. Its not too difficult to work out what the relational engine does, but I must say
that compared to Oracle, the documentation is very scarce and overly broad:
parse
35
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
execute
The SQL (T-SQL is also regarded as SQL) statements cover all forms and instantiations submitted
to the engine, namely:
batch statements
The optimiser relies on histograms (statistics) collected by the instance automatically (auto create
statistics setting for each database in the instance), indexes and manually created statistic
collections. These are used to establish a variety of figures related to the cost of the plan and
choosing the one with the lowest estimated cost. To speed plan estimation a variety of complex
algorithms are used, which, in some cases will result in only partial optimisation. The source data
structure for the optimiser is the successfully parsed sequence (query) tree.
On execution of the optimised query plan, a series of requests are sent to the storage engine in
which rowsets are returned. The data is processed by the relational engine that formats and
returns the results to the client via a UMS managed worker thread.
The relational engine may build temporary data structures (work-tables) in the tempdb system
database to complete the SQL statement.
All execution plans are stored in the procedure cache. Each plan has two parts:
query plan, read-only cached plan, up to two can exist for a batch, one for serial and one for
parallel operations
execution context, bind variables and other parameter values for the SQL
Like Oracle, the use of parameters (bind variables) increases the possibility of plan reuse.
Unless altered by the DBA, the parallelisation of the statement will be determined during the
optimisation phase.
36
2
Chapter
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Installation
T
hroughout this chapter will we discuss the installation of a SQL Server instance. Like most
DBMS’s, the DBA can do a quick and dirty install, or be thorough in terms of security and
really lock down the instance and access to it. We will discuss some of the issues to
consider in both methods and where appropriate, drill into the finer points of the installation
process.
Standard Edition
Enterprise Edition
Personal Edition
SQL Server MSDE (Microsoft Data Engine, no EM GUI with max 5 concurrent users)
Some of the key items Standard Ed does not include over Enterprise Ed:
37
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Indexed views
Multi-language capabilities
Licensing Schemes
When installing Standard or Enterprise Editions, the DBA is prompted for the SQL Server licensing
scheme to be used for the instance. The schemes are:
Per Processor (typically for web-based applications) – for each CPU, unlimited users.
Per Seat (known as a CAL or Client Access Licence) – this is a per “device connection”
licence, and not per user, if I as a user connect 10 times with mobiles/PDA/laptop etc all
simultaneously then all require a CAL.
NOTE - SQL Server does not use the pricing model of per power-unit as Oracle does (or used
did, this seems to change on a regular basis as RDBMS competition heats up).
IMPORTANT – No licence for your operating system? then all SQL Server licences are
automatically treated as “invalid” for the server.
IMPORTANT - Connection pooling is not an excuse for buying less CAL’s if using this
licensing scheme. If 20 user connections are pooled to 5 SQL Server sessions, you still need
20 CAL’s.
There are many important issues to be considered when dealing with licensing, some of these are:
Standard Edition
Enterprise Edition
Can create as many instances of the same server as you like under a single license.
38
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
A single licence scheme can be used for both servers. Attempts to use the passive
SQL Server for connections will result in further licensing issues.
Log Shipping
Developer Edition
Personal Edition
If the CE SQL Server connects to another SQL Server (i.e. replication, linked server
etc), then that “remote” SQL Server requires a per-processor licence.
http://www.microsoft.com/sql/howtobuy/sqlserverlicensing.asp
http://www.microsoft.com/sql/howtobuy/sqlserverce.asp
http://www.microsoft.com/sql/howtobuy/msde.asp
http://www.microsoft.com/sql/howtobuy/personal.asp
Some approximated pricing is shown below (believe me, with the market as it is, don’t trust me on
this one):
39
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
To locate information in regards to the existing licensing scheme, run the following within Query
Analyser:
select SERVERPROPERTY('LicenseType')
select SERVERPROPERTY('NumLicenses')
where 'NumLicenses' is not applicable for the per CPU scheme. If you are running the Developer
Edition, 'LicenseType' returns “disabled” and 'NumLicenses' is NULL.
The License Manager program (control-panel -> administrative tools) cannot display information
related to per-processor licensing for SQL Server (Q306247). To get around this issue the
installation will create a new administrative tool program to track such information as shown in the
screen shots below.
The Settings Æ Control panel Æ Licensing Æ shows only server licensing for SL Server 2000
installations (unlike v7), the applet above is used instead. Notice that you cannot switch to a per-
processor licence; you must re-install the instance to do this.
NOTE – Unless specified in your licence contract or SQL Server version on installation, the
installed instance will not automatically expire or end.
40
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
This will allow you administer your licences, but you will see one of the options is greyed out, such
as:
Change the mode to 1 (default is zero) and you get both options:
41
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Throughout the different versions of Oracle we have seen a shift to more GUI tools (driven by
Java) that cover most basics and allow the DBA to quickly get databases up and running and
add to the database any other tablespaces as need be. In SQL Server, the setup disk not only
covers the binary installation, but instance creation, maintenance tasks (registry rebuild,
system database fix etc) as well.
a) Run through installation options for default or named instance and install the instance
with instance and non-instance dependent binaries
a. Named Instance?
b. Location of binaries and the instance’s system database files
c. Setup the account in which the services will run
i. Use the same account to run the instance service and the instances SQL
Agent account?
ii. Run under the Local system account?
iii. Run under another domain user account?
iv. Auto-start service?
d. Instance Collation (language) and sort order
e. Install binaries based on selected options
f. Authentication mode for the instance
i. Mixed mode (windows and SQL Server authentication)
ii. Windows authentication
g. Setup NT services
h. Setup default networking properties
You may need to install the prerequisite options first, SQL Server setup will soon tell you about
this and also notify you when trying to install over an OS that doesn’t support the edition. You
have the flexibility to install options only (like, only the books online which is a very good idea)
and not to install or create a new SQL Server instance. These are all self explanatory with the
set-up.
a) rebuilding the registry entries (will also reinstall MDAC from the CD)
42
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Service Account
As with Oracle installation under NT, the NT account you are using on installation is called the
service account in which associated DBMS services and further installation and administrative tasks
will occur under. In many cases (the quick and dirty method), the DBA will use the administrator
account as it provides complete access to the server and its resources, reducing the possibility of
any flow on issues related to the system privileges.
If you need to install using a separate NT account that will not be a member of the administrators
group, the consider the following:
Create DB data and log file directories for database files to be created in
Login as Administrator of the server and alter the users rights as follows
43
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Login as the SQL Server user and attempt to re-start the database, debug as
required.
Access to xp_cmdshell for non-sysadmin users must be via a proxy account (select
properties of SQL Agent).
NOTE – When using replication, create a DOMAIN user account and not a local server
account.
This may not be definitive and will require some testing and checking of the SQL Server error logs
and the NT event logs to locate the reasons why specific operations are not happening with the
account being used. A classic problem is the SQL Agent service account, which does require
administrative privilege to run successfully.
verify successful start-up of instance and databases affected via the encryption.
Attempting to start the service as any user other than the user that encrypted the database data
files, results in the instance not starting, or a suspect database. Example error log entries:
udopen: Operating system error 5(error not found) during the creation/opening of physical device
E:\cktemp\efs\efs_Data.MDF.
FCB::Open failed: Could not open device E:\cktemp\efs\efs_Data.MDF for virtual device number (VDN) 1.
udopen: Operating system error 5(error not found) during the creation/opening of physical device
E:\cktemp\efs\efs_Log.LDF.
FCB::Open failed: Could not open device E:\cktemp\efs\efs_Log.LDF for virtual device number (VDN) 2.
In terms of speed, this is a tough one to measure, there are so many factors to consider it’s not
funny, for example:
hardware vendor
44
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
After some testing of the same 5000 row table on an EFS database verses a non-EFS database, we
find some interesting results. The following table was created and queried:
set @aa = 1
while @aa <= 5000 begin
insert into efs (col1, col2) values (@aa, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
set @aa = @aa + 1
end
NOTE - the following statistics are averaged figures of five different attempts at the same
SQL. Personally, I do not like to write up such figures, and I pre-warn that careful testing
must be done at your specific site with more complex scenarios.
-- Averaged 6% slower
update efs
set col2 = 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'
Table 'efs'. Scan count 1, logical reads 5875, physical reads 0, read-ahead reads 0.
Table 'efs'. Scan count 1, logical reads 1720, physical reads 1, read-ahead reads 48.
45
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Table 'efs'. Scan count 1, logical reads 1721, physical reads 0, read-ahead reads 0.
update efs
set col2 = 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'
Table 'efs'. Scan count 1, logical reads 5875, physical reads 0, read-ahead reads 0.
dbcc dropcleanbuffers
select count(*) from efs
Table 'efs'. Scan count 1, logical reads 1720, physical reads 1, read-ahead reads 48.
Be very careful, the EFS is an advanced option and I having read a variety of news-group posts
regarding recovery of servers and associated tape backups from EFS files, the process is far from
simple. Be aware of the dependency on the OS installation, server and user that will all influence
the encryption.
Some of the issues include OS versions and service packs, service accounts to be
used, placement of files, disk sub-system configuration, how many databases will be
hosted and how will their file place affect other databases?, number of users and
connectivity properties, instance names, requirement to install previous SQL Server
versions, backup locations, default passwords, who will access to the DBMS, remote
administration issues, file shares and their security, virus checking software (and is it
auto-updating).
46
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
OLTP or DSS nature of the system, affect on network bandwidth, buffer cache and
procedure cache hit ratios
Will other file-system like activity through the application such as batch document creation,
auditing log files, bulk extracts for reporting, OLAP cube builds, affect performance
significantly or pose issues with the disk subsystem?
Backup sub-system and associated disk space (will disk backups share the drive with other
database files?)
Do we really understand the expected database growth patterns? and how do you plan to
track it?
Positioning of file-groups and have we thought of using multiple file-groups over disk RAID
arrays to increase IO performance and ease administration?
These issues are particularly important in large OLTP or DSS based applications sharing the same
disk sub-system with other applications or user databases.
The question of the RAID level is a tricky one as RAID-1, RAID-5 and RAID-10 arrays are typically
determined by the money available and the total databases to be supported. I have yet to come
across any mid-sized organisation where money wasn’t as issue and don’t be fooled, high-end
server hardware is expensive (we are not talking desktop PC’s here).
In terms of performance, RAID-5 should not be overlooked. Be aware that each write results in
two IO’s plus a single read IO. Even so, I have successfully run a variety of applications over such
an array (with hardware caching enabled though at a small risk of database corruption) with very
low read/write queue lengths. Like all things, the DBA should be aware of the issue and pre-test
where possible.
As a guide, we tend to see very little IO activity around the master, msdb and model system
databases. As such they and the binaries tend to be placed in the same location, typically a RAID-1
or RAID-10 array. The tempdb database, used for temporary sort, group-by and other operations
like the temp tablespace in Oracle, may need to be placed on its own array.
The issue with the tempdb is its size and trying to justify its own disks (the minimum is typically
18Gb or 36Gb). A server with large amounts of RAM and very short transactions manipulating
small amounts of data will rarely use the tempdb. As an example, my 2Gb production database
with over 900 online users, 4Gb of RAM, sees the maximum tempdb of 800Mb.
47
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The DBA needs to consider the total server RAM, index rebuilds, DBCC executions and their
timings, the need to large data set processing, and simply monitor tempdb usage, weighing up IO
performance via performance monitor.
User database files are broken down (at their basic configuration) into two data files:
Ideally, the log files should be own their own array due to their serial writes.
In summary, as an instance includes numerous databases all with a minimum of two data files, a so
called perfect disk placement for all files is a dream for 99% of companies. From the points
discussed, I would recommend something like:
As an example, my 800 user database server with heavy OLTP activity has the following drive
configuration with close to zero problems in terms of IO contention. The disks are SCSI160 15k
18Gb disks hooked to a HP 4M raid controller with 40Mb cache, read/write ahead caching is on for
the RAID-5 array.
In Oracle, many DBA’s prescribe to some form of the OFA (Optimal Flexible Architecture) for file
placement over the array. This basically describes:
Establish a documented and orderly directory structure for installation binaries and database
files that is compatible with any disk resource
i.e. c:\SQLServer2kBin\<instance-name>\{binaries}
c:\SQLServer2kData\<instance-name>\<db-name>\{data files}
c:\SQLServer2kLog\<instance-name>\<db-name>\{log files}
c:\SQLServer2kErr\<instance-name>\{error log files}
48
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Separate database components across different disk resources for reliability and
performance
NOTE – Be aware of SQL Server data striping. If you have two or more database files for a
single file-group, SQL Server will automatically stipe data across these based on the
percentage of free space with each data file. Be aware of this is you are also planning disk
striping “by hand” during installation/restore.
The following is a summary the DBA should be considering carefully before installation, some of
which were covered in previously on RAID arrays:
a) Clustered installation?
b) Disk sub-system set-up and ready for the installation?
c) Upgrading and existing version?
a. v7 to 2000
b. v6.5 to 2000
c. mixed environment? (v7 and 2k or other combination)
d) Check OS requirements and RAID issues
e) Location of binaries and default location for installed system databases (OFA)
f) Editions and Versions
g) MDAC version support for other applications (will installing SQL Server be an issue, as a
general rule it will not).
h) Will you need to run SQL Server v7
a. Install named instances of SQL Server 2k
b. v7 cannot support multiple instances, therefore will be used as the default
instance.
i) File and instance naming standards defined?
j) Collation and Sort Order determined for instance?
k) Security – Installing under System User or another domain user account?
l) Security – Integrated or Mixed Mode?
m) Do you want to move the tempdb system database?
n) Log shipping support required? Does your edition support it? The SQL Agent service
must run under a domain user account with rights to other domain servers.
o) Full Text Search and English Query required?
p) SA Password Management and the sysadmin privilege user
q) Instance memory configuration (how much will be allocated?)
49
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
NOTE – In general, the setup is self-explanatory and we will only cover some of the wizard
dialogs presented to you.
The setup process as described, is multi-functional, to install a new database instance, we select
the Server and Client Tools option. The client tools are generic for all instances, therefore, once
installed we need to filter out these additional options. This is discussed later.
The next question presented to the DBA is the instance name, the default option will create the
default unnamed instance (if one doesn’t already exist). Based on this early decision the following
will eventually be created:
Default Instance
and the following example services, the first being the instance and the active directory helper
service for all instances, and the second set being SQL Agent (batch job processing service) for
each instance.
50
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
When prompted, always select the custom option. It is good practice to select advanced options.
You cannot specify the ORACLE_HOME and there is no environment variable; the DBA can specify
the installation directory for the binaries for an instance the default being c:\Program
Files\Microsoft SQL Server\.
51
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The options for Management Tool (Enterprise Manager and other command line and GUI tools),
Client Connectivity, BOL (Books online), Development tools and Samples are shared components
for all instances; when installed for one instance, don’t re-select them for subsequent instances.
This is especially the case when patching a system with service packs or upgrading BOL, as you
don’t want to revert back to the default installation settings accidentally. Full-text query allows the
DBMS to utilise the Microsoft Search Engine to build catalogs on table columns that allows English
like queries to be performance at high speed.
The next step is selecting the NT account in which the instance services will run. It is important
that you read the Security Chapter on Installation Issues regarding security during installation.
Many DBA’s leave this as default, running the two services for the instance under the system user
account. Although fine for most installations, in a production environment this should be altered to
another NT domain user account with restricted OS privileges if required. If changing the account,
do not forget to check the auto-start service check box.
The above can be altered by editing the services within NT, and also within SQL Server Enterprise
Manager by selecting properties at the top level of the instance tree and for the SQL Server agent.
See below.
52
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Once the service accounts have been specified, we tell SQL Server about the authentication method
it should use. See the Chapter on Security. The Windows Authentication mode is the same as
OPS$ (external Oracle authentication) only, and Mixed is both Database and Windows
Authentication. Mixed mode will require you to enter the sa account password to complete mixed
authentication, guard this login/password religiously, it is equivalent to the sys login with Oracle.
The service account in which SQL Server is installed will be the Windows Authentication user, and
you will be able to connect to the instance with no password (OS managed). The
BUILTIN/Administrators SQL Server login will provide this seamless authentication via the
equivalent OS group that can be removed to provide better security.
I recommend Mixed Mode where possible with a complex SA password that is rarely used. This
ensures that a DBA inadvertently locking themselves out when altering windows authentication
privileges or server configuration is not a completely lost cause.
The final BIG question asked of the DBA is the collation and sort order. This single question results
in numerous postings in newsgroups and forums, and rightly so. The language and sort order is
covered in the Chapter on NLS and Sort Orders. The installation screen is shown below.
53
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
To complete the installation, the setup will finally prompt you for the default server network
(listener) properties and the supported network libraries that can be used. The standard libraries
include named pipes and TCP/IP (a port of 0 equates to port 1433 or SQL Server will pick a random
port on first ever connection and retain it). The named pipe will be \\. \pipe\MSSQL[$]<instance-
name>. The server will not be hidden from the network. See the Chapter on Networking SQL
Server. Leave the displayed options as default in a majority of cases.
Please read the Chapter on Networking regarding listener set-up and configuration.
You will need to apply additional services packs as need be to the installation (highly
recommended).
WARNING – Applying SQL Server patches or installing SQL Server will alter your MDAC
level. Take are in multi-server environments where this can cause differences in MDAC
between servers.
54
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Alter the registry entries, stop the instance service, including SQL Agent, move the master
database files to the new location and re-start the instance. The DBA can alter these within
Enterprise Manager by selecting properties of the instance and altering the start-up parameters.
This will call an extended stored procedure to alter the registry settings above.
55
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The backup and restore option is the most simplistic and is covered in the Backup and Recovery
chapter. The instance will require less downtime and is a safer option overall.
To move these database via the sp_attach and sp_deattach commands, we require a little more
work to be done.
1. Open the service control window for the instance, and add the start parameter -T3608
4. Run the following command, writing down the name, fileid and filename displayed
use msdb
go
sp_helpfile
go
use master
go
sp_detach_db 'msdb'
56
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
go
6. Refresh enterprise manager, you will notice that MSDB has now disappeared.
7. Copy or Move the database files listed in 4 to their new destination
8. Run the following command to re-attach the MSDB database files
use master
go
sp_attach_db 'msdb','C:\msdbdata.mdf','c:\msdblog.ldf'
go
9. Go back to the service control window, shutdown service, clear the trace flag and re-start
the service.
10. Refresh Enterprise Manager or re-start.
11. Re-run step 4 to verify the new file location
WARNING - if doing both databases at the same time attach the MODEL database before
MSDB.
Moving TEMPDB
The TEMPDB database is the same as the temporary tablespace option within Oracle. This
database is used for sorting and temporary tables. It is common practice, where possible, to
move this database to its own RAID 1 or RAID 10 set. This needs to be carefully evaluated to
determine if the use of the database and the set of disks it is residing on is a bottleneck. To
move the database files for this system database:
1. Run query analyser, check existing location of the tempdb database files
use tempdb
go
sp_helpfile
go
2. Get the destination directory ready and document the results above, re-check the
location.
Restart the instance for the files to be re-created at the new location.
Consider trace flag 3608 or 3609 (skips tempdb creation) if you have issues with the new
destination or with the model database (from which its created).
You can also resize the tempdb database via the SIZE option in the alter database statement.
57
3
Chapter
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
T
hroughout this chapter we will focus on the GUI and command line utilities installed with
SQL Server. The tools are simple to use and all they require is time trying out their
numerous options. We will not explore each and every option, but provide a high level
summary of the tool and its use.
What is installed?
On installation, SQL Server 2k comes with a variety of tools sets. Some of the tools are:
58
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The EM tool itself is very easy to use and requires very little discussion; it is a simple a matter
of trying its features and learning from there. But all that said, we will highlight some issues
with the interface and how EM can make life of the DBA a lot easier.
Registering Servers
Registering database instances within EM is a fundamental task for managing multiple instances
from the single console. Right click properties on the Microsoft SQL Server group and select New
SQL Server Group:
59
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The name must of course be unique within its hierarchy; groups are sorted by name. Select the
new group, right click properties and choose new SQL Server registration:
Going through the wizard, it will show a screen of available servers. If yours is not listed ( which is
likely) then simply type in:
b) or use the alias created for the instance via the Client Network Utility.
Option b) is the standard selection, especially when connecting to named instances, or instances on
non-standard ports and/or protocols. The alias method also allows you to register the same
instance multiple times.
60
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Interface Overview
61
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
62
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The meta data repository is not a small topic by any means. Its API and associated open interfaces
are designed to hook into case and designer tools, and follow this onto the implementation with
documenting the physical data model, tracking DTS data loads and providing some great
documentation on top of the standard E-R model. Unfortunately, we are not covering this topic in
detail but will look at the snap-in.
The meta data services snap in is the key to administering meta data services. To use the snap in
(which is not available in EM) you need to:
a) Run mmc.exe
b) File --> “Add/Remove Snapin”, dialog is shown, click on the “Add” button
c) Select the Meta Data Services snap-in and others as need be, close when finished
d) Ok
e) Save the console, setting yourself up with a custom admin management console
To register a instance and set administrative properties, you must have a database with the
repository tables. This database is the msdb system database.
b) Filling in the standard registration database property using the SQL Server OLE-DB provider
(which you cannot change).
d) Based on the user access, the DBA can remove, edit and refresh the repository and
properties, this is not possible in EM.
63
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
e) The DBA can also view the information models available for tracking and managing within
the repository.
Some DBA’s talk about task pad in SQL Server, this is simply a type of view you can have within EM
when looking at an instance or individual database. An example is shown below.
64
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
To insert a NULL into a database table column within EM, use CTRL-0 (zero) and tab to the next
column. Also take care having the table view open, EM is a classic for taking out escalated table
locks. A CTRL-N will close the EM window and you will have to re-start EM.
DBVERIFY
There is no database checking utility that operates whilst the SQL Server database instance is
down. Once up, the SQL Server DBA can use the DBCC (database consistency checking) routines,
namely DBCC CHECKDB, DBCC CHECKALLOC within query analyser or consider creating a database
maintenance plan and selecting the integrity checking options.
SVRMGRL
The closest SQL Server has to the server manager executable (svrmgr23 in 7.3, svrmgr30 in 8.0,
svrmgrl in 8.1 and replaced with extended functionality in SQL*Plus for 9i) is sqlservr.exe. This is
the core process running the instance and its associated databases and worker threads.
In most cases, the DBA will utilise the Service Control Manager (also see the NT services and open
the properties of the service to interact with startup parameters) and Enterprise Manager. The DBA
may also consider using Query Analyser (SQL*Plus).
65
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
SQL Loader
There is no equivalent to SQL Loader command line. Running Enterprise Manager, the DBA can use
the DTS Import / Export wizard and its variety of options to script databases and move data, but it
is still limited, i.e. cannot script linked servers etc). The GUI is reasonably powerful, but the DBA
may feel inclined to use other 3rd party products for better coverage of all database elements. The
DBA should not script the system databases as a method of restoring.
The DBA should also consider the BCP command line tool and the bulk insert DML command. The
bulk copy process allows the DBA to dump data to text files using defined column and line
separators.
Here is an example of using bulk insert in a stored procedure to load a temporary table:
set @v_sql = 'BULK INSERT #lodgement_enrolment FROM ''' + @filename + ''' WITH (FORMATFILE =
''c:\lodgement.fmt'')'
exec(@v_sql)
The bulk insert command requires the user to be a member of the bulk admin fixed server role.
The user must also be the owner of the object they are inserting the data into. The command is
very fast and is well worth exploring. If you still have issues running the command, try and making
the user a dbowner of the tempdb database.
66
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
SQL Trace
The ORACLE DBA can utilise SQL Trace to write out performance statistics for statements being
executed for a session or all connection database sessions. This may typically involve the setup of
the trace parameters in the init.ora (SQL_TRACE, TIMED_STATISTICS, USER_DUMP_DEST etc),
and invoked from SQL*Forms, SQL*Plus, PL/SQL sub-routine and other methods, using commands
such as:
a) SQL Profiler GUI for tracing and the subsequent reading of trace data files. The GUI
may skip trace records depending on the load running against the database. This was
apparently was by design.
b) Use the T-SQL stored procedures to run the trace, these are stored in the master
system database.
a. sp_trace_create
b. sp_trace_setevent
c. sp_trace_setfiler
d. sp_trace_setstatus
67
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Compared to Oracle, the listener configuration in SQL Server is simple and is generally an error free
process. The options available are somewhat restrictive though in terms on failure alternatives and
encryption etc.
68
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
SRVCTL
There is no equivalent to srvctl (manage ORAC environment via the command line) in Oracle. This
may be closer to the Cluster Manager utility in Windows and to a lesser degree SQL Server
Enterprise Manager.
Log Miner
There is no equivalent to log miner utility in Oracle. Consider 3rd party tools.
ISQL
ISQL is invoked on the command line with isql.exe, the GUI version is called “query analyser” and
is discussed later in this chapter. The command line version help is called by isql.exe -? or
isql.exe /?, the screen shown for a SQL Server 2k installation is:
69
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
70
4
Chapter
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
A
s with any modern DBMS, SQL Server supports complete or full backups, differential
backups and transaction log backups (equivalent to archived log backups)
The key difference between Oracle and SQL Server is not so much the commands and
recovery models affecting the type of backup, but the number of backups required to
completely recover a database instance verses an individual database. Of course,
architecturally, backup and recovery is very different under both DBMS.
We will explore backup and recovery in SQL Server with a variety of scenarios.
Backup
As mentioned in the architecture section, a SQL Server instance consists of a number of system
databases, these, just like the system tablespace in Oracle, is essential for recovery. For the
instance to start, the system databases must be available. It is critical that full backups are
performed on a regular basis for your master, msdb, model and distribution (if replication enabled),
then of course, the users databases are just as important. We will cover backup and recovery in
some detail.
Hot Backup – all full backups in SQL Server are HOT backups
Full Backup (shutdown instance and backup database files) – although possible, it is not
recommended, the full backup is typically used in all cases
RMAN – no equivalent in SQL Server. Closest option is Database Maintenance Plans but
these are simply wizards that generate scheduled jobs to make life much easier.
Import/Export (full) – no equivalent utility that is even close to Oracle’s. The best SQL
Server has database scripting (manually run) and BCP (bulk copy data). Oracle is way
ahead in this area.
71
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
REMEMBER – Treat the master, msdb, model and distribution databases as your system
tablespace data files and control files all mixed into one. They are critical in Oracle recovery
and are subsequently critical in SQL Server database instance recovery. The tempdb is rebuilt
from the model database on instance startup.
Recovery Interval
The recovery interval is set at an instance level and affects the checkpoint timeout period for all
databases in the SQL Server instance. This of course has flow on effects for instance recovery in
terms of the number of possible transactions SQL Server must rollback (uncommitted transactions)
and roll forward (committed but not written to the physical database data files) during its recovery
cycle on instance startup.
The default value is zero (SQL Server managed) or any value greater than zero in minutes and
when altered its value takes affected immediately. In a majority of circumstances leave the setting
at the default.
The value can be set via Enterprise Manager, or via a SQL statement:
Trying to pre-empt the actual goings-on with the DBMS architecture in terms of this value is difficult
to predict and the SQL Server documentation is some vague. Use performance monitor counters to
monitor checkpoints and alter the recovery interval to review the impact to the instance, this may
72
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
take some time to be reflected. It is important to remember that performance monitor wont
measure instance recovery time which, in some circumstances, can effect your SLA if you are not
careful.
Recovery Models
Setting a recovery model is like the Oracle DBA tuning on or off archived log mode for the database
instance. In SQL Server, each database has a recovery model which determines what statements
are logged or not and if point in time recovery is possible. The models are:
b) Full – transaction log entries are retained and the log file will grow until the DBA back’s
up the transaction log and flushed the committed log data to disk (archived log mode in
Oracle).
c) Bulk Logged – as per full but selected commands are not fully logged (therefore not
recoverable), these include select into, bcp and bulk insert, create index and indexed
view creation, text and image operations (write and update text).
Do not alter recovery model properties for any system database. Again the DBA can alter the
recovery model properties for user databases via Enterprise Manager or a SQL statement:
73
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The alteration will take immediate affect. The DBA should issue a full backup and if using full or
bulk-logged options, continue with planned transaction log backups as need be.
Backup Devices
A “backup device” in SQL Server 2k is simply a logical name (alias) for a physical file that may be a
disk location (physical or UNC) or tape device. The device is visible to all databases within the
instance.
The device is not necessarily required, but is there for convenience and does allow backup scripts to
separate themselves from the physical location of data files. Altering a script to backup elsewhere
can be done by changing the destination of the back device.
74
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The above dialog will run exec xp_fileexist "e:\dbbackups\mydevice.BAK" to verify the location and
warn the DBA accordingly.
The device has some flow on affects within the Enterprise Manager in terms of viewing their content
and selecting the device as a drop down item when backing up databases via the EM.
IMPORTANT – The Database Maintenance Plan wizards do not utilise these backup devices
for some strange reason.
RMAN
There is no equivalent utility to RMAN in SQL Server. Recovery must be either manually instigated
by the DBA within Query Analyser or its equivalent command line utility, or via Enterprise Manager
and its GUI screens. Backups are performed via Database Maintenance Plans or via t-sql scripts
that DBA has custom written.
NOTE – Maintenance Plans are found under the Management folder within Enterprise
Manager.
The maintenance plan is simply a wizard that generates a series of MSDB jobs that are scheduled
and run by SQL*Agent. These jobs may include the following against one or more databases:
75
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
For backups, SQL Server will create one media set per backup set. This means one physical disk
file (media set) backup and inside it, a single log or full backup (backup set). It will NOT append
backup sets to existing media.
NOTE – Many of these items can be scheduled individually, away from the backup job times.
Note that SQL Server will not warn you of overlapping jobs or the fact that another
maintenance job already exists of that type.
When it comes to backups, the maintenance plan can be a little restrictive though, consider some of
these:
many of the backup options are not available, namely the password parameter
can not duplex backup files (copy to another disk or server as part of the backup)
does not support appended backups to an existing backup device (media set)
NOTE – Natively, SQL Server does no built in mechanism for compressing or zipping backup
files. Consider writing your own backup t-sql stored procedure and using the xp_cmdshell
extended stored procedure.
The maintenance plan backup screens are shown below. Remember that this point we have already
selected the databases to be included in this overall maintenance plan (first screen of the wizard).
76
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The next screen is related to transaction log backups. Be warned here that not all databases you
have selected in the first screen may be privy to log backups and can result in failure of the
scheduled maintenance plan.
The DBA can review and alter the maintenance plan at any time by simply selecting properties for
the generated plan and editing it as need be within Enterprise Manager.
77
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
It is important to understand the difference between a media set and a backup set. These
concepts are used throughout the following sections and within the online help for SQL Server.
A physical backup device is the media set, within the media we can store one or more logical
backup sets of one or more databases (typically its all the same database). This is shown
below with their properties:
BACKUP SET (NAME, SERVER, DATABASE, BACKUP TYPE, DATE, EXPIRES, SIZE, DESC)
BACKUP SET (NAME, SERVER, DATABASE, BACKUP TYPE, DATE, EXPIRES, SIZE, DESC)
Backup set
Media set
BACKUP DATABASE [mydb]
TO DISK = ‘e:\dbbackups\mydb\mydb_20020624_full.bak’
WITH INIT,
NAME = ‘Full Backup of MYDB on 24/06/2002’
78
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The backup information is recorded in the MSDB database, here is a snapshot of the physical data
model:
media_ backup
set_id _set_id
Backup Backup set Restore Restore_ Restore file
media set history history_id
Restore file
Backup Backup file Log mark group
media history
family
The DBA should purge this information on a regular basis. I have personally found that recovering
a database via the GUI with a large number of backup records can result in a huge delay (4+
minutes at times) as you wait for the GUI to return control back to you.
NOTE – rather than using msdb.. (which tells SQL Server that it will find the stored procedure
in the msdb system database and use the dbo owner), we could have entered use [msdb]
before we ran the procedure that also sets the current database.
If you append backups to a media set then we refer to each appended backup via the FILE
option as you will see in the examples presented throughout the chapter.
The tempdb system database is rebuilt automatically to the destination defined in the sysdatabases
system table in the master database on instance start-up.
79
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The GUI is very simple to understand and is not worth discussing. In most cases the DBA will
create a Database Maintenance Plan to schedule and manage the full database backup.
If we tried to run the above command again we get the error below due to the expiration date we
have set. To get over this and still use the INIT option then we need to use the SKIP option as
well.
NOTE – take a close look at the WITH clause syntax, the books online cover this command
very well and should be reviewed thoroughly.
The DBA should have a good understanding of all backup and recovery options, but some of
the key items are:
80
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The Enterprise Manager GUI is a little restrictive when it comes to restoring database backups when
the PASSWORD option has been used. It does not give you the option to specify it and comes up
with the error:
Differential Backups
The differential backup will backup any 64Kb extent that contains an altered page within the
database. Remember this when viewing the backup size of the media set as you may be surprised.
The tracking is managed by the SQL Server storage engine using the DCM (differential change
map) page present in each non-log data file. In Oracle, differential backups are known as
differential incremental backups that are supported within RMAN and it is also possible to do
cumulative database exports.
A differential backup is not supported in Database Maintenance Plans (should change in the next
version of SQL Server), therefore the DBA needs to resort to writing their own scripts that can be a
right pain. In many cases, full and log backups will suffice, but can slow the recovery process
when applying large numbers of archived log files. This is where differentials can be used to speed
the recovery process. The DBA will need to do their own performance tuning to determine if
differentials are required to meet their recovery SLA.
The differential backup will backup all extents modified since the last full backup, and NOT the last
differential. This is very important to understand, especially during recovery. The last differential
backup done must be used on recovery; they are not cumulative as log backups are.
81
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
To get these backups up and running quickly, write a T-SQL stored procedure and an associated
DTS to call it with an email notification for error tracking. Then simply schedule the package to run
as required.
Important – You cannot use differential backups to do point-in-time recovery (i.e. the STOP
AT clause is not valid to recover to a point in time for the period the differential backup
covers).
The database must be in full or bulk-logged recovery modes before attempting a transaction log
backup. If not you will receive the error:
Attempting to backup the log file for the master database will result in the error:
You can alter the recovery modes of the MSDB and MODEL databases if you like and do transaction
log backups, but it is not recommended unless there is an important requirement to do so.
Attempting to backup the log file for the tempdb database will result in the error:
Do not attempt a full or differential backup whilst a transaction log backup is running as it may
result in error. Even so, Microsoft documentation states that concurrent full and log backups are
compatible.
There are several important parameters the DBA should understand when using log backups. Note
that many of these parameters are NOT available when creating maintenance plans, therefore, for
the advanced DBA this may be too restrictive.
82
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Parameter Notes
NO_TRUNCATE Special parameter used when database is in a damaged state,
allows us to attempt a log backup without truncating the virtual log
files. This is important if we are still trying to recover the instance
whilst we attempt to build another (i.e. standby database).
NOTE – Remember that the databases transaction log will continue to fill as committed and
non-committed transactions execute against the database. The backup transaction log will
write (archive in Oracle) all committed transactions to your selected transaction log backup file
(an archived log).
The DBA can truncate the transaction log via the WITH NO_LOG or WITH TRUNCATE_ONLY option.
This is used in a variety of situations, the classic being when you accidentally used the full or bulk-
logged recovery model when you didn’t want transactions permanently logged for point in time
recovery and now the log has grown and typically results in full transaction log errors. This
command will remove all non-active transactions from the log, from there, the DBA can think shrink
the log files and change the recovery model as need be.
Remember - you cannot selectively truncate transactions in the log file, it’s all or nothing.
The DBA must do a full backup as you cannot recovery through a truncate (as you would
except).
NOTE – Your database must be using the full or bulk-logged recovery model
83
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Remember - copying a database will not take the logins with it, as this information is stored
in the master database.
Remember – If you have not database backups, but still have all the database files, the re-
attaching the database will be your last remaining hope to recovering your database.
Simply shutdown the SQL Server instance, taking care when running multiple instances on the
same server. When down, copy the database files to the other server (or copy/rename/move if it
will be attached to the same server). As the database was cleanly shutdown there will be no issues
with re-attaching so long as the copy and destination did not fail unexpectedly. If the instance did
fail unexpectedly and you have no backups, re-attaching may still be possible (with the added risk
of data corruption).
When using this method, the database will of course remain on the source server with no change
what-so-ever to the source database.
Once the database is “offline”, you can copy its database files to a new server and re-attach.
Use this method when shutting down the SQL Server instance is not desirable and you want to
retain the database on the source server.
Reminder – User sessions will not be disconnected; this is applicable for sp_dboption and the
ALTER database command.
84
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Using the alter database statement (SQL Server 2k and beyond) is the preferred method. The
rollback after statement will force currently executing statements to rollback after N seconds. The
default is to wait for all currently running transactions to complete and for the sessions to be
terminated. Use the rollback immediate clause to rollback transactions immediately.
When running the command with users connected you will get something like:
sp_dboption (does not wait like the alter database command, see below)
If you want to completely remove the database from the master database and the SQL Server
instance, use the deattach command rather than offlining the database.
When attempting to de-attach with Enterprise manager it will warn you when:
a) there are users connected to the database
b) replication is active
85
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
All user sessions must be disconnected and replication disabled before attempting the de-
attachment. The command is:
The second parameter denotes wether to include a statistics collection before de-attaching the
database. You must be a member of the sysadmin system role to issue this command. Also note
the error:
Funny enough, statistics are still updated before receiving this error.
The de-attachment will remove the database from the sysdatabases table in the master database.
The sysxlogins table will retain references to the de-attached database, therefore, you will need to
either remove the login(s) or alter their default database connections, this is shown below.
Dropping logins is not straight forward, you need to either orphan the login from its associated
database user or drop the user, otherwise you will get this message:
You cannot remove users that own database objects, the standard drop user command is:
use [mydb]
exec sp_dropuser N’myuser’
You should note that you cannot re-attach more than 16 files for a single database. Before
attaching the database, issue the following commands over the primary file-group data file to get a
listing of files that make up the database structure:
--Get a list of all files associated with the database. (original name)
dbcc checkprimaryfile (N'E:\SQLServerData\MSSQL\Data\mydb_Data.MDF', 3)
86
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The sp_attach_db command allows you to re-attach your database onto the SQL Server instance.
For example:
exec sp_attach_db
N'mydb' ,
N'E:\SQLServerData\MSSQL\Data\new_aa_Data.MDF',
N'E:\SQLServerData\MSSQL\Data\new_aa_Log.LDF'
The syntax is simple enough, the first being the name of the database to attach and its associated
database files you have checked via the methods outlined previously. The database being attached
must not already exist, you can also attach databases not previously de-attached so long as the
database was closed successfully.
After re-attaching, especially if its on different server, you will need to fix orphaned logins via the
command:
When re-attaching with this command, you have the ability for SQL Server to automatically
recreate your log file so long as it’s not available for SQL Server to automatically re-attach when it
looks up sysfiles. This method is handy when you want have massive log file and want to shrink it
back to a manageable size. For example:
This will not work if you have multiple log files thought, you will get an error like:
87
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
In this example, the database had a single data file with two log files. When I have only one file the
attachment works file and re-creates the log in the destination of the previous file (but has a
modified size). Two or more files will result in the error.
To detach the model or msdb system databases, you need to set the trace flag –T3608 on instance
startup. In all cases you must attach the model before the msdb database, remembering that
SQL*Agent for the instance must be stopped. As a side note, the attach command executes
something like the following:
The create database command has dependencies on the model database, therefore affecting it’s re-
attachment.
The DBA should also be aware of the master..sysdatabases system table and its value for dbid for
system databases. In some very rare occasions, it is possible that a restore results in a corruption,
or “mixup” in the dbid for the database, this may occur when restoring databases in the wrong
order. The flow on effect is some very strange errors and confusion all round. See reference (57)
for a great example of this.
1 Master
2 Tempdb
3 Model
4 Msdb
88
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Scripting Databases
The only option here is via Enterprise Manager. Right click properties on any database and the
following GUI is shown:
The screen is simplistic and requires no explanation but there are a few things to remember:
a) You must select objects (tables, views) in order to script
indexes/triggers/constraints/permissions. You cannot “generically” script all indexes for
example without selecting all tables/views first. This can be a pain as you need to filter
out what you need from the generated script.
b) You cannot script many databases at once
c) You cannot script logins specific to database (i.e. logins that map to a single user in one
database – typically the one you are scripting). You cannot script the sa login.
d) You cannot script linked or remote servers.
Use the preview option to view the generated script in mini-dialog windows (which you can cut
into the clipboard from).
89
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The diagrammer is also another handy place to generate scripts. As an example, if you need to
make a variety of schema changes, and then create a new (or use an existing) diagram, save,
make you changes and then hit the script button (see below). Once copied, you can apply the
changes as need be to the database. You can then use the saved script to apply on other identical
databases (i.e. test / support / prod databases) to mimic the changes and/or new objects.
One of the key problems with the diagrammer is that you cannot allocate object permissions whilst
editing tables. This can adversely complicate your script generation ideas.
NOTE – Be careful with generated scripts from the diagrammer, it can take the long route to
a simple change that can result in heartache for the DBA if the takes are very large. Always
review the generated script before running. In all cases though, in my experience EM has
never generated a script with errors.
If you select the “design table” option and alter the table, the same script option is available to the
DBA. Note that this is not the case for “design view” although the SQL statement is selectable.
90
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Another method for scripting is via EM and its listing pf tables, for example:
Select objects in
Enterprise Manager,
CTRL-C to copy.
Verifying Backups
To verify a backup, use the command:
The DBA can also load the backup history in the backup file into the MSDB database. This can
be handy when analysing the backup before attempting a recovery.
91
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Recovery
Recovery in Oracle is either:
a) manual via svrmgrl / sqlplus
b) via RMAN
c) via 3rd party product
d) Enterprise Manager
Recovery is potentially more complex that Oracle at times due to the fact that we are not
dealing with one database, but many system databases then associated user databases. This
section provides a summary by example in which the DBA can then base further tests to drill
down into this very important topic.
NOTE – Many of the examples use the GUI tools and at times, with reference to the
equivalent T-SQL command.
Killing off user connections is simple enough and there are endless scripts on the internet to do the
job. An example script by ruba.kumar@aurumtechnology.com is shown below:
OPEN CurrentProcesses
FETCH NEXT FROM CurrentProcesses INTO @ProcessId
CLOSE CurrentProcesses
DeAllocate CurrentProcesses
GO
Also consider the command to more elegantly terminate users and closing off the connection:
92
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
eg:
To stop further connections, consider altering the database to dbo access only, or disable the
database logins via sp_denylogin (NT logins only).
NOTE – When using EM for recovery, run profiler at the same time to trace the T-SQL
recovery routines being executed. This is the best way to learn the recovery commands and
the context in which they are being used.
93
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
WARNING – If you restore a database, say, Northwind, and restore it as a different name
(database), then be careful when removing the new database. It will ask if you want to
remove all backup history, if you say yes then kiss good-bye to the Northwind databases
MSDB backup entries.
We will cover some of the GUI options in brief. Remember that virtually ALL restore
operations require no users to be connected to the database.
Options - Leave database in non-operational state but able to restore additional logs
This option allows us to restore the instance to any specific point, but leave it in a state where we
can apply further backups as need be.
Selecting properties of the restored instance in loading state gives us the error:
If you realise that you have no further backups and want to complete the recovery of the instance,
then (note that exec sp_helpdb will not show the database):
A instance re-start will also issue the recovery statement. The non-operational state simply
executes the with norecovery option on restore of the last specified backup file.
Using EM can be a tad strange when restoring databases. If you attempt to restore the currently
selected database, it will never prompt you that you are trying to overwrite an existing databases
94
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
data files, even though (technically speaking here), you are! If we attempted to restore say the
northwind database as the pubs database, we will be promoted with the following dialog:
It seems be to something related to the MSDB backup and restore tables which determines
whether or not this dialog is shown. Anyhow, to get around this, we click on the options tab and
select the Force restore over existing database option.
The command is not different to a standard restore, there is no magical restore option related to
the prevention of file overrides.
Be very careful with this option in EM. Personally, I never use it unless I am 100% sure that
the files I am writing over are fine and I have already backed them up if possible.
Database: mydb
Data and Log files: c:\mydb.mdb, c:\mydb.ldf
Backups:
Full c:\mydb_full.bak
Diff c:\mydb_diff.bak
Log c:\mydb_log1.bak
Log c:\mydb_log2.bak
On selecting the restore in EM for the database, it magically lists all backups for a successful
restoration of my database up to the point of mydb_log2.bak. If we lost this information, then
suddenly our nice GUI dialog is not so helpful anymore.
To re-populate the MSDB database tables with the backup history I recommend that you do
not use the GUI, it is overly time consuming for such a simple task:
95
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
NOTE - if you backup media had multiple, appended backups, then you may also need to
use the WITH FILE = option.
Once done, using the EM restore option, we select the database and work off the restore
history to pick the best plan for restoration.
Remember, before restoring, always double check the database name and the options, ensuring
paths and names are correct.
The general recommendation here is the shrink the database before any full backup to reduce
the possibility of this error. If that doesn’t work, try and restore and move files as best you
can to distribute the space amongst many disks, then shrink after the restore, backup and try
to restore again with a more appropriate placement of database files.
96
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Restoration by Example
97
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
8. Close and reopen EM, connecting to the instance. Check the SQL Server error
logs on failure to start the instance.
This example is simplistic and there are scenarios where this operation can create further problems.
The key issue here is that the master database includes a variety of system tables, with the file
paths for the model and msdb and tempdb system databases. If you restore the master (which
stops your instance immediately), and attempt to re-start, unless those paths are still valid, the
instance will not start.
Consider the rebuildm.exe command (rebuild master) to assist in restoring back to a state where at
least the instance starts and then you can recover each system database thereafter.
98
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Suspect Database
A database may become suspect for a variety of reasons, such as device errors, missing files
etc, or another process (like a 3rd party backup program) has a lock on the database files
during instance startup etc.
First of all, check the error logs to better gauge the extent of the problem. In this particular case
the error is:
udopen: Operating system error 32(error not found) during the creation/opening of physical device
C:\Program Files\Microsoft SQL Server\MSSQL$MY2NDINSTANCE\data\northwnd.mdf.
If the physical device is missing, then a simple restore is required with the move option.
This is assuming we cannot quickly resolve the error otherwise. The DBA may need to use a
third party utility to determine if another process has the file open, there are many available
on the internet for example www.sysinternals.com. If the file is “open” but the process is
orphaned for whatever reason, we can attempt:
a) Attempt to kill off the rough process holding the file open and stop/start of the instance
b) Attempt to run: exec sp_resetstatus ‘northwind’
c) Reboot of the server
99
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
On any change of DB status related to recovery, the DBA should run the following on the
database :
dbcc checkdb
dbcc newalloc
dbcc textall
IMPORTANT - I should iterate that suspect databases must be carefully analysed, in some
cases I have found that, for some unexplained reason (i.e. no error log entries) the instance
starts and a user database is in suspect mode. If you have verified the existence of all
database files, then attempt to re-attach the database via the sp_deattach and sp_attach
commands. Always backup the database files before attempting any sort of recovery.
The DBA may also consider deattaching the suspect database (via EM is fine). Go to your file
system, move the missing files if need be and return back to EM and run the attach database
wizard. In the wizard window, you will see red crosses where the file name/path is invalid,
alter the path/filenames, set the “attach as” and set the owner to “dbo” (very rare that is not
dbo) and the database should be successfully re-attached and operational.
This typically occurs when the database has been restored to an inconsistent state in which it
is still pending full recovery. Attempting complete recovery may give you something like:
Verify your order of restore carefully before attempting the restoration again.
100
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
STATS = 10,
RECOVERY , MOVE N'nonefs_Log' TO N'f:\nonefs_Log.LDF'
Backups:
C:\mydb_full.bak Full
C:\mydb_log1.bak Log
C:\mydb_diff1.bak Differential
C:\mydb_log2.bak Log
C:\mydb_log3.bak Log
{failure occured}
If mydb_data file-group failed (the logical name of the filegroup and the logical name of the
file are the same in this case), we need to restore:
Following on from the above, we consider the situation where a database file has been added to the
database between transaction logs. Therefore we have this scenario:
Backups:
C:\mydb_full.bak Full backup
101
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The completed restore will show the newly added file with no further issues. Be aware though,
Microsoft Support document Q286280 states otherwise, and there may be a scenario where the
above does not work. Revise this support document for assistance.
Emergency Mode
This mode is undocumented and is technically unsupported, but is required on very rare
occasions. This mode allows the DBA to access a database without the log file being present.
-- If possible, attempt to set db in DBO only access mode (for safety sake)
exec sp_dboption N'Northwind', N'dbo use', N'true'
102
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Attempting a backup or any other operation that uses transactions will result in the error:
To export out the data and associated objects, create a blank database in the same or another
database instance. Once done, run the Export wizard, select the database in emergency mode and
follow the prompts. A DTS will be created and will happily export the database, typically, without
error so long as there are no underlying permission issues.
This is a very simplistic example but provides some direction towards dealing with the problem.
NOTE – Setting a database to emergency mode is very handy when suspect databases wont
allow you to investigate the problem via DBCC commands etc. Altering the status to
emergency mode and then running, say, DBCC CHECKDB will allow you access to the
database and a variety of commands to resolve the problem.
103
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
and the backupfinishdate column to determine the most appropriate log file to be used.
DBCC CHECKDB
DBCC TEXTALL
DBCC CHECKCATALOG
DBCC CHECKALLOC
These routines will report on allocation inconsistencies with tables and indexes that typically point
at data corruption. Even so, don’t be too quick to react. Before doing anything always full backup
the existing databases and try the following:
DBCC CHECKDB(‘mydatabase’, REPAIR_REBUILD)
If you are getting desperate, Microsoft has an undocumented command (typically suggested by
Microsoft support) called sp_fixindex. Before running this restart the instance in single user mode,
checkpoint, run sp_fixindex, checkpoint again and backup once more. Re-start the instance and re-
run the DBCC routines once more.
104
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
If you delete the tempdb and templog databases files, they are simply re-created on instance
startup, assuming of course the model database is available and the disk sub-system:
use tempdb
go
sp_helpfile
go
The DBA can move this location via the commands below and re-starting the instance.
use master
go
alter database tempdb modify file (name = tempdev, filename = 'c:\tempdb.mdf')
go
alter database tempdb modify file (name = templog, filename = 'c:\templog.ldf')
Go
File 'tempdev' modified in sysaltfiles. Delete old file after restarting SQL Server.
File 'templog' modified in sysaltfiles. Delete old file after restarting SQL Server.
Note that after the alter statement, the entries in master..sysaltfiles, master..sysdatabases and
master..sysdevices remains unchanged. On restart, the tempdb files have now moved to their new
location but the entry in master..sysdevices remains unchanged, only sysaltfiles and sysdatabases
has been altered.
If the device is no longer available in which the tempdb datafiles are created, the instance will not
start, as there is no other default value SQL Server will magically use. To resolve this problem we
need to use the rebuildm.exe (see Scenario 2.)
Scenario 2 - Rebuildm.exe
105
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
There comes a time in every DBA’s life where the rebuildm.exe (rebuild master) utility is used,
either to change the instances global collation or due to a disaster in which one or more system
databases need to be restored and we don’t have a valid or any full backup (this should never
happen for any reason).
The rebuildm.exe is found on the installation CD, cd-rom:\x86\binn. In the following example we
will run the command and highlight the subsequent steps to complete the recovery.
NOTE – If copying the CD to disk, make sure the files in ?:\x86\data\ are not read-only or
have their archive bit set.
When using disk 2 and running rebuildm.exe, I received the following error:
this was an authenticate CD, to get around this unforseen problem I copied it to disk and renamed
the directory c:\x86\binn\res\1033 to c:\x86\binn\Resources\3081. The utility then ran without a
problem.
REMEMBER – DON’T restore your master database after running rebuildm.exe if the
objective was to alter the server collation. Always backup as much as possible, and consider
scripting logins before attempting this process.
106
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
4. The database files are copied to the new destination and the “server configuration
progress” dialog is shown, this takes around 1-2mins maximum.
Try This – Run FileMonitor from www.sysinternals.com to view the file IO and thread
calls during this process.
5. Don’t be fooled, this process affects ALL system database, not just the master database.
107
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
6. Check data file properties before re-starting to ensure they are not read-only.
7. Start your instance
8. Review the previous and current error log. The previous log has some good information
about the tasks undertaken with the system databases rebuild.
9. Optionally re-apply service packs
10. Optionally restore your master, model, msdb databases as need be
Before your re-start the instance with the files copied by rebuildm.exe, double check they are
not read-only. This is a classic problem when the files are copied off the CD-ROM. If this
problem affects the use of rebuildm.exe then copy the files to disk and refer to point two
above.
Be careful when only restoring one or two of the system databases. All system databases
should be current with and single service pack, I have never been in a position where a
subsequent restore of the master database that had SP2 applied existed with the MSDB
database with no service packs. The DBA should think very carefully about this and apply the
service pack as required to ensure minimal amount of error.
Scenario 3 – Lost all (or have no) backups, only have database files
1. Backup all database files (if available) to another server and/or to tape.
2. Check the registry for the MASTER database, and alter and/or ensure the files are in
the correct registry entry HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Microsoft
SQL Server/<instance name>/MSSQLServer/Parameters/{SQLArg0 and 1}
i. If there are still errors with system databases, namely MSDB, MASTER or
MODEL, check error log carefully and attempt to place database files at these
locations.
108
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The DBA should revise trace flags on instance startup to assist in the task.
Scenario 4 - Disks lost, must restore all system and user databases from backup to new drive/file
locations
This is a difficult scenario. In order to start the instance, we require a valid master database;
this database also defines the subsequent location of the MSDB, MODEL and TEMPDB database
data files. If we restore the master database from our full backup (with the move option to
another disk), the sysdatabases, sysaltfiles and sysaltdevices system tables will still contain
invalid paths for the other system and user databases as we lost those particular disks. This is
made even worse, as any time you restore the master database the instance shuts down
immediately, therefore, an instance re-start will result in numerous file-missing errors and fail
to start.
This may bring mixed comments from DBA’s, but consider the following:
NOTE – SQL Server has no equivalent command to the RESETLOGS option when SQL Server
opens a database.
109
5
Chapter
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
O
ne of the most important concepts to grasp for any DBA, is transactions and
transaction management. In SQL Server, one of the biggest problems related to
overall system performance and stability is the poor handling of transactions,
especially long running ones. Throughout this chapter we will discuss this is in
depth. If you walk away with nothing else from this chapter, remember that it is
critically important for your OLTP systems under SQL Server to keep transactions as short as
possible to ensure blocking and lock escalation is kept to an absolute minimum.
The undo / rollback segment allows the Oracle DBMS to provide read-consistency for all
transactions and is therefore essential for a transaction to execute and subsequently complete
(commit/rollback). The DBA needs to specify the undo management strategy for the database ,
that being either:
NOTE - To distinguish between the two types of undo segments, ROLLBACK segments are
called UNDO segments when AUM is enabled.
At the start of a transaction, the DBMS assigns it a rollback segment and records the current SCN
(last completed commit point). As the transaction continues with any variety of DML, the DBMS
uses the rollback segment to:
110
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
assist the DBMS in constructing a read-consistent view of the database objects as at the
start of the transaction (defined by SCN). To do this, the DBMS will lookup existing and
other rollback segments to construct a read-consistent view.
This effectively allows transactions to be completely segregated from one another, to do whatever
they like to the data as at the SCN and when ready, commit or rollback. On the commit of the
transaction, the DBMS will utilise the buffer cache and rollback segments to complete the
transaction. At this point, locking is required to complete the transaction. All transactions in Oracle
require an explicit commit or rollback; the developer must issue one of the two statements (or end
their session to rollback automatically) to end the transaction, which is started when the first DML
statement is issued.
The user (programmer) may issue save point throughout the transaction to rollback to specific
points in time.
The type of undo method is used within the DBMS can be verified with:
select name,value
from v$parameter
where name in ('undo_management','undo_tablespace');
Transactions cannot
cross more than one
segment.
Programmers/DBA
can write code to
target a segment for
the transaction to
NEXT EXTENT SIZE Non-active extent within run under.
OFFLINE MINEXTENTS segment.
ONLINE MAXEXTENTS
INVALID OPTIMIAL SIZE
PARTLY AVAILABLE
NEEDS RECOVERY
ROLLBACK_SEGMENTS in init.ora specify
online segments on instance startup
111
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The concepts are the same in principal, but the DBA has no control over the sizing, online/offlining
(altering status) and number of segments within the undo (rollback) tablespace on startup. There
are a range of new database startup parameters and subsequent DDL to create and setup the new
undo tablespace. This paradigm of self-managed DBMS “smarts” is collectively known as Oracle
Managed Files.
Undo Tablespace
undo_management
undo_tablespace
undo_retention, undo_pool
On setting the startup parameter undo_managagement = auto, undo segments are managed
automatically within an undo tablespace. The segments are removed when the tablespace is
removed, online/offlined as the undo tablespace changes, and segments completely managed by
the DBMS. The DBA does not explicitly create or control undo segments (rollback segments), the
DBA only specifies:
one or more undo tablespaces (undo_tablespaces=), and the associated create undo
tablespace command. Undo tablespaces may only hold undo segments.
undo_retention – parameter, clock time to retain of committed undo data in the tablespace.
Required for the flashback option in 9i.
undo_pool – multiple pools with restrict undo properties can be created and allocated to
users to restrict usage.
112
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
data that has yet to be written to the actual database files. The DBA has full control over the
positioning, sizing, onlining / offlining, switching, limiting number of and the associated archive log
process.
The DBA must archive logs to prevent the database locking up and is the key to PITR (point in time
recovery).
Oracle supplies the log miner tool to analyse database activity via the reading of redo and archived
redo log files. This tool is implemented as a series of PL/SQL packages, views, utilities to the read
associated redo log dictionary objects, and the associated java based logminer GUI tool.
Oracle – Locking
Where possible, both Oracle and SQL Server attempt to allocate locks at the lowest level possible
(that being at the row). Also, like both DBMS’s, shared and exclusive locks exist, in which one and
only one exclusive lock can be taken out on a resource at any one time, whilst multiple shared locks
are possible. The only key difference here was described previously, where in Oracle reads are
never blocked by exclusive locks, in SQL Server they will be (especially update locks described
next).
All locks are held for the duration of the transaction as with SQL Server, which is completed via a
commit or rollback command (optionally to a save point as well). Oracle will not escalate locks,
but will do the appropriate lock conversion to obtain the most appropriate lock at the highest level
as possible (that being a row-exclusive lock - RX). The locks themselves are maintain via enqueue
processes in which the DBA via enqueue_resources can control this internal locking structure.
a) DDL
a. Protect the schema objects and their definition.
b) DML
a. Ensures only one row can be updated at any one time.
b. Objects cant be dropped whilst transactions are pending
c. Row or table level
i. TX – row level lock
1. readers do not wait for writers for the same data
2. writers not wait for readers (for update excluded)
3. writers wait for other writers over the same row
4. table level shared lock is also taken.
ii. TM – table level locks
1. RS (SS) – row share
2. RX (SX) – row exclusive
3. SRX – share row exclusive lock
4. X – exclusive
c) Latches
d) Distributed (OPS)
e) PCM (parallel cache management) used in the shared server configuration.
113
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The type of SQL statement will also determine the lock modes permitted against the resource (out
of scope for this book).
The key to rollback and redo for SQL Server is the transaction log that is present in each database
within the instance. The transaction log is a serial record of all transactions (DML and DDL)
executed against the database and is used to store:
The transaction log itself consists of one or more physical database files, the size of the first must
be greater than or equal to 512Kb in size. SQL Server breaks down the physical file into 2 or more
logical transaction logs. The size of the file and its auto-growth settings will influence the number
of virtual logs and their size. The DBA cannot control the number of or sizing of virtual logs.
Physical transaction log file (min size 512Kb with 2 virtual logs)
The log writer thread manages the writing of records to the transaction log. As pages are
requested and read into the buffer cache, changes are sent to the log-cache as a write-ahead
operation which log-writer must complete with a write to the transaction log before the committed
change is written to the data files as part of a check-point. In terms of an update, the before and
after images are written to the log; a delete the before image is written; an insert tracks only the
new records (not including many other record entries as mentioned previously as part of the
transaction). The log-writer allocates a LSN (log sequence number, similar to the as the SCN in
Oracle) to each statement including the transaction ID.
114
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Log Cache Log flushed, LSN allocated and Physical transaction log file
transaction id stamped with before/after
images of the records updated.
Buffer Cache
Dirty buffer pages,
log-write requested
The transaction entries (committed and uncommitted) in the transaction log are doubly linked lists
and each linked entry may contain a range of different (sequential) LSN’s. The transaction itself
remains in the active portion of the transaction log until it is either committed or rolled back and
the checkpoint process successfully completes.
Free space
Active Portion of
in virtual
Log
logs
Although not shown above, space is also allocated for each log entry record for rollback purposes;
therefore actual space utilisation can be significantly more than expected. Microsoft defines the
active part of the log to be the portion of the log file from the MinLSN to the last written log record
(end of logical log).
115
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
- active portion -
The MinLSN is the first of possibly many yet uncommitted (or rollbacked) transactions.
When the database is using a full or bulk-logged recovery model, the non-active portion of the log
will only become “free” (can be overwritten) when a full backup or transaction log (archived log
backup in Oracle) backup is executed. This ensures that recovery is possible if need be via the
backup and the DBMS can happily continue and overwrite the now free log space. If the database
is using the simple recovery model at a database checkpoint, any committed (and check pointed)
or rollback transactions log space will become immediately free for other records to use. Therefore,
point in time recovery is impossible.
The checkpoint process is key to completing the committed transactions and writing the dirty
buffers back to disk. In relation to the transaction log, this will:
This is far from definitive but you get the idea. The checkpoint will occur:
116
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Apart from the recovery interval and recovery mode parameters, the DBA has little control of
checkpointing. Although, it can be forced via the CHECKPOINT statement if need be.
To drill into the virtual logs and the position, status, size, MinLSN within the transaction log
files, use the commands:
dbcc loginfo
dbcc log(<db#>, TYPE=-1)
NOTE – The transaction log is a write-ahead log. Log writes are synchronous and single
threaded Actual DB writes are asynchronous, multi-threaded and as shown in the diagrams,
optimistic.
In Summary
Fundamentally, the two DBMS are very. The key differences are primarily highlighted with the
rollback segments, which effectively results in writers blocking readers with its default isolation level
(read-committed as with Oracle) as a database change cannot be dynamically re-constructed to a
point in time. As we will see next, the result is a more complex locking mechanism, more
transaction isolation levels and associated hints, and programmers needing to be much more strict
in keeping transactions as short as possible.
The following sections discuss locking and isolation levels for transaction management.
In terms of redo, the transaction log is the equivalent to the redo logs in Oracle. The DBA can only
control the number of logs used and cannot manipulate the virtual logs within them. As with
Oracle, the DBA needs to archive logs (backup log command) on a regular basis to prevent the
database from “stalling”. Functionally, the redo logs are identical in terms of their requirement for
database recovery.
117
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The isolation is very important in determining transaction concurrency (enforcing atomicity and
consistency in relation to other running transactions) and determining the locking required by the
DBMS to meet the isolation level. The SQL Server DBA does not explicitly set the isolation level and
cannot control a minimum global setting or restricted set of isolation levels that can be set against
the DBMS. The programmer can alter the databases default isolation level on connect (ADO, OLE-
DB, ODBC property), T-SQL or via a SQL hint.
DBCC USEROPTIONS
NOTE - that isolation level property is not shown if the default is in use.
The SQL Server locking schemes are completely automatic in context with the isolation level, with
lock escalation as need be to fulfill the request (Oracle never escalates locks). Where possible, SQL
Server will start at the lowest granularity of locking and in terms of exclusiveness, then use a
variety of other lock types at higher levels to pre-empt future intentions and escalations on the
underlying object. The lock types are divided into four modes:
118
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
IS Intent shared
IX Intent exclusive
SIX Shared with intent exclusive
The resources in which locks are applied (and escalated in order of) include rows, pages, keys
(index keys), range of keys, indexes, tables, and databases. These are of course abbreviated:
The status of the lock request against the resource may be:
Again, the duration of the lock will depend on the isolation level, hints, DML/DDL operation being
performed and the range of rows affected by the operation (some internal threshold being
exceeded that results in escalation).
The DBA can do very little to control the lock manager, the best we have (apart from isolation
levels and hints) is the lock option altered via the sp_configure stored procedure. The default
option is to let SQL Server manage the maximum number of lock structures (96Kb each), which in
99% of cases is the best option.
It is difficult to describe and summarize every example of locking, the DBA really needs to explore
the sp_lock procedure with a variety of different isolation levels and DML/DDL to view the locks
taken out not only against the database, but also against the master and tempdb databases.
119
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Table definition:
User SQL:
Example Results:
It should be noted that KEY locks are shown when the table has a clustered index rather than
showing rowlocks. For non-clustered indexes the KEY locks exist for the leaf nodes. Locks may be
retained until the transaction is complete; this is especially the case with shared locks over a
repeatable read isolation level. At the end of the day, the DBA must be very strict on the timing of
transactions, the operations being performed (DDL, DML), objects being affected (multiple indexed
tables etc), use of triggers, and keep the transactions as short as possible.
120
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Transactions
Drilling now into transactions, the syntax is similar to Oracle in some respects. The key
difference here is the in-ability for SQL Server to pause or re-start transactions as we can in
Oracle.
BEGIN TRAN[SACTION]
<SOME CODE HERE>
[COMMIT, ROLLBACK TRANS[ACTION]]
The transactions can be nested, be aware of the rollback transaction command as it does not give
you the result most would expect:
begin transaction
print @@trancount
begin transaction Transaction Count
print @@trancount
begin transaction 1
print @@trancount 2
commit transaction
3
commit transaction
print @@trancount 1
commit transaction 0
begin transaction
print @@trancount
begin transaction 1
print @@trancount 2
begin transaction 3
print @@trancount Server: Msg 3902, Level 16, State 1, Line 9
rollback transaction The COMMIT TRANSACTION request has no
commit transaction corresponding BEGIN TRANSACTION.
print @@trancount 0
commit transaction Server: Msg 3902, Level 16, State 1, Line 11
The COMMIT TRANSACTION request has no
corresponding BEGIN TRANSACTION.
In SQL Server 2k we can also mark transactions and set save points to rollback to. Marking
transactions can be very handy when tracking long running jobs and ease the rollback process on
transaction failure. The syntax is simple:
The transaction log marks are held in the MSDB database table logmarkhistory.
121
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
sp_lock – get some reasonably detailed information about locks and spids
dbcc stackdump - will generate a low level dump of processes,.dmp file is generated in
the log directory of the instance
The sum of the commands above is similar to utllockt.sql and catblock.sql scripts in Oracle (not
including EM and other 3rd party tools). In terms of DBMS_LOCK, apart from table level SQL
locking hints, there is no equivalent to this package.
Third party tools vary greatly in function and actual usefulness and like all things, require a lot of
evaluation and pre-thought before handing over your money. As an example in terms of
block/locking issues, Diagnostic manager from NetIQ returns to me SMTP emails:
2838: The monitor has determined that process ID 11 has been blocking another process for
longer than 30 seconds. The process is being executed by program 'SQLDMO_1', on computer
'MY-SERVER', by user 'sa'.
The blocking lock's details are : Database - msdb, Table ID - 213575799, Lock Type -
Blocking Intent Exclusive.
The statement being executed is :
dbcc checkdb WITH NO_INFOMSGS
16/08/2002 5:57:12 PM [MY_DB]
Within Enterprise Manager (EM), we have a small number of options. Some example screen shots
of EM and viewing blocking issues are shown below:
122
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Take a careful
look at the lock
modes, namely
X and U or
ranged
exclusive locks.
Like all locking, most are short and point in time events that at times can be hard to trace. This is
where profiler comes into play. Be aware that EM can take some time to refresh and at times the
DBA “thinks” its locked itself, only to return back with the results some minutes later. Here is a
classic error; right at the time we are trying to sort out the blocking issue:
123
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The blocking locks can be a real problem with SQL Server, even more so than deadlocking. The
DBA may really struggle to pin point the actual problem, as both profiler and DBCC input buffer
might not return the statement being blocked. As described by Q224453, “Blocking is an
unavoidable characteristic of any relational database management system (RDBMS) with lock-
based concurrency. On SQL Server, blocking occurs when one SPID holds a lock on a specific
resource and a second SPID attempts to acquire a conflicting lock type on the same resource.”.
Attempt to repeat the problem on a quiet server in which tracing the blocked and blocking
SPID’s and locks is much easier.
The developer will have an idea as to the code being executed, discuss the code and
consider a mini walkthrough (demand it if necessary), are we taking about COM+ with
transactions? How are transactions being used? Isolation levels? Are hints being used?
Attempt to trace and filter over the key tables involved with the lock. Rather than using
profiler, consider “command line” trace via sp_trace in Query Analyser to ensure events are
not missed in very busy databases.
Consider dbcc opentran to analyse long running open transactions that may be causing the
blocking and allow more effective (filtered) tracing via profiler.
Controlling Locks
Locks can be controlled at a SQL level via hints, I don’t like hints and am never comfortable
with them, but there are cases where they come in handy (especially bulk data loading and
concurrent data loading/selecting). The hints include:
HOLDLOCK
NOLOCK
PAGLOCK
READCOMMITED
READUNCOMMITED
REPEATABLEREAD
READPAST
ROWLOCK
TABLOCK
TABLOCKX
UPDLOCK
XLOCK
124
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
For example:
Apart from SQL hints, the DBA can use the sp_indexoption to set locking options at an index level.
The options are somewhat limited but include:
Do not use this option unless there is a very good reason too.
125
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Finally, we can set the isolation level (and thus control locking), via the begin transaction
command. For example:
In terms of lock timeout, the developer may use the LOCK_TIMEOUT command. Where possible the
DBA should discourage (i.e. DON’T USE) its use and opt for a more elegant solution. Here is an
example of its use:
Session 1 Session 2
Without it, session two will wait indefinitely until the session one completes.
Ideally its value is zero and/or a rare event. There are situations where this is difficult, especially
third party applications or your OLTP database that is also being used for reporting and other batch
type events out of your control. The DBA should follow up with SQL Profiler to better trace the
deadlocks occurring.
Profiler is a powerful tracing tool, but it does have some problems when tracing deadlocks as we
will see later. On starting a new trace, the DBA should include the events:
If you stayed with this, and waited for your expectant deadlock to occur, you will get very little
information of the objects affected or statements executed unless you select the data column
Object Id. From here you need to manually use OBJECT_NAME to determine the object affected.
Why is this a problem? to get more information you typically include the event T-SQL: SQL: Batch
Completed, if you run the trace with this option then you will be tracing ALL completed batches,
and in a busy system, this can mean thousands of entries within minutes; making tracing a difficult
126
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
and time consuming task. Even so, if you can deal with this, you will get a thorough list of
statements related to the deadlock; stop the trace after the deadlock occurred and use the find
dialog to search the columns for deadlock event, then search backwards from the SPIDS involved in
the trace to get a summary of the commands before the deadlock.
NOTE – Running profiler whilst locking is already underway and a problem, will do you no
good, and you may only get a small amount of relevant information about the issue (i.e.
profiler doesn’t magically trace already running processes before continuing on its way with
current events).
The client application involved in a deadlock will receive the error# 1205, as shown below:
Finally, the DBA can utilise trace flags. This is an effective method for debugging deadlocks and
provides some excellent error log data. The flags are:
The screen shots below illustrate the output from a deadlock with the traces enabled. I have no
statistics on the adverse effect to DBMS performance, but this is a very effective method for
debugging problem systems that are deadlocking frequently but you can never get a decent set of
data to debug it.
127
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The actual deadlock is around the customer and employer tables, in which two processes have
updated one of the two separately and have yet to commit the transaction; they attempted to
select each others locked resources resulting in the deadlock. This is not reflected in the log dump.
The ECID is the execution context ID of a thread for the SPID. The value of zero represents the
parent thread and other ECID values are sub-threads.
Check with http://support.microsoft.com for some excellent scripts to monitor blocking in SQL
Server.
We have a large COM+ based application that was experiencing deadlocking issues. The key issue
here is that COM+ transactions use an isolation level of serialisable, as such, locks of any sort can
be a real problem in terms of concurrency. To start resolving the problem we:
a) worked with the developers in working out how to repeat the error
a. this allows us to identify the code segments possible causing the error and assist of
course with re-testing.
c) Run Profiler
i. Lock:Deadlock
128
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
iii. SQL:StmtCompleted
iv. RPC:Completed
Lock:Deadlock identifies that SPID 67 was killed. Go back through the trace, to locate the
commands executed in sequence for the two SPIDS in the chain, take some time with this, you
need to go back through the chain of transaction begins (in this case they are COM+ transactions)
to clearly determine what has happened for each SPID’s transaction block.
To assist with further debugging, goto your instance error log and locate the deadlock dump chain:
IX lock wanting to
be taken out
129
6
Chapter
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Performance Tuning
T
he art of performance tuning requires good theoretical and practical knowledge of the
underlying operating system, physical hardware, applications components and of course,
the DBMS. Many of these skills can only be acquired with years of practical experience with
a variety of server’s configurations and, most importantly, applications. This chapter
attempts to highlight some of the key items of interest to the DBA.
Tracing (profiler)
Tracing database events and users sessions in SQL Server is done via the profiler utility. This is a
powerful tool that allows the DBA to:
Run the GUI and play with it against a development or test instance. The interface is simplistic and
like all things, read the screens carefully and you will find it self-explanatory. The utility, by default,
will trace all DML and DDL database activity within the instance you are connecting too.
There are numerous events you can trace via profiler, some of which are:
130
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Errors and warnings Missing column statistics, missing join predicates, oledb errors, tempdb
sorts over memory sorts, exceptions etc.
Objects Auto stats collection, objects accessed via DML, objects created and
objects dropped or deleted.
Security audit Numerous audit events, including password changes, failed logins,
adding and removing role members, adding/removing database users,
server starts and stops etc.
Stored procedures Recompiles, started and completed, procedure cache miss, removal
from the procedure cache, cache hit for stored procedures.
Within profiler, you can apply many filter conditions for a single trace event. In virtually all cases I
do not include system objects by checking the box provided:
The DBA may also want to filter on a specific database within the instance. Use the database ID as
the name will not work. Get the database ID by querying sysdatabases found in the master system
database.
131
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
132
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Use the predefined trace template called Filter on a specific database ID Use the
“SQLProfilerTuning”. as need be. The DBA may still Index Tuning
selectively apply filters for Wizard
specific types of SQL, namely:
The DBA may add further events to the trace, such as SQLTransaction to capture the begin and
subsequent commit/rollback sub-classes. Additionally, the DBA may also consider the RPC events
(remote procedure calls). I have to say that profiler is something Oracle is sorely missing in terms
of fast and easy to use tracing.
NOTE – the generic trace is a good start, use the default trace, exclude system processes,
and use the database ID filter (see sysdatabases in the master database or exec sp_helpdb,
filtering on database name may not work for you and in many cases will return a blank string).
This trace is an excellent start as it includes text data of submitted SQL and is a good basis for
further exploring the power of the tool.
IMPORTANT – Be very careful re-running saved traces through profiler, if they include a
range of inserts, updates, deletes, they will all be repeated against the database instance.
This is very handy in various debugging and tuning workloads, but you do not want to get it
wrong if you know what I mean.
The DBA should spend a good amount of time on profiler. It is a very powerful tool for not only
SQL performance tracing, but for auditing, error detection, cache misses and recompiles and much
more. For a good overview with some performance tuning tips, I highly recommend the e-book
“Start of Finish Guide to SQL Server Performance Monitoring”, Brian Kelly 2002.
NOTE – Take care with the duration column. This may not accurately reflect the execution
time of the actual SQL statement. For example, I had a large application where profiler
reported that the selected statements were taking 20sec to execute. Running them via query
analyser gave a different story and they were running under 1sec. Going back to the client
application and drilling into the code segment was the only way to more effectively time and
resolve the problem.
The DBA can choose to save a profiler trace to a database. The DBA can specify the name of the
database in which to create the table, and the name of the table. The tables’ columns are created
based on the data columns selected for tracing. The table has a single primary key called
RowNumber (identity) that is a clustered index. If the DBA selects an existing table, it will ask if it
is ok to overwrite it, which involves dropping an re-creating the table.
The greatest option in regard to profiler tracing, is that we can script out the trace script in T-SQL
code. For the DBA wanting to further customise the trace, this is an excellent feature. Once a
133
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
trace has been set and is running, select File Æ Script Trace Æ For SQL Server 2000 to generate a
.sql file of the sp_ stored procedures used to create the trace.
NOTE – Don’t assume the GUI is showing all commands executed. If you are relying on the
trace window be aware that it buffers trace data. On very busy systems this can result in a
loss of data in the trace window.
If you forgot to save the trace to a trace file or trace table, don’t fear, stop the trace and select File
Æ Save As Æ Trace File and specify your .trc filename. Be careful though, if you start again the
trace screen (buffer) is cleared and all will be lost, also, pausing the trace, altering event columns
and starting again will also clear the buffer of all previous tracing.
One handy feature in SQL Server is the ::fn_trace_gettable system function. After creating a trace
file via profiler, run the following and get a table representation of the files contents:
• ::fn_trace_setevent
• ::fn_trace_setfilter
• ::fn_trace_getfilterinfo(<id>)
• ::fn_trace_getinfo(0)
• ::fn_trace_geteventinfo(<id)
The wizard works hand-in-hand with the traced output file from profiler or a manual trace via
sp_trace.
134
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
135
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The index analysis will start when the next button is pressed. The existing database structure is
not altered in any way what so ever. If you traced inserts, deletes and updates they are not
actually run, they are only parsed and the tuning wizard will apply the rules previously set.
The analysis is reasonably well presented; the analysis screen provides a series of reports that can
be saved to disk for further checking. Be very careful though with the overall recommendations. A
classic example is shown below, where my three statements in the trace (which only covered 3 of
the total tables) result in the recommendation to drop all existing indexes off the non-utilised
tables. At the end of the day, the DBA should save all recommended changes to disk and evaluate
each one very carefully in context with the big picture.
The index wizard will also recommend statistics (histograms) for tables.
136
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
On clicking Next the DBA is asked if the recommendations should be saved to disk and/or for them
to be applied immediately or scheduled as a SQL*Agent job on the instance to be run later. Take
the time to re-check the individual table indexes, a classic example is with the sample northwind
database. Here in the Orders table we have two indexes over the CustomerID column, why? well
the index tuning wizard asked the same question and suggested that we remove the duplicate
indexes.
Explain Plan
Within Query Analyser the DBA has a variety of choices when it comes to viewing the optimiser’s
execution plan:
When using the Query menu options above, the only toggle item is the show execution plan, the
display estimated execution plan will be executed immediately based on the SQL selected, or, if
nothing is selected then all SQL is parsed and the plan displayed. A different plan of course will be
shown from top to bottom if there are multiple SQL statements.
Both query menu options show a graphical representation of the generated plan. This, like all
plans, should be read from bottom to top. Placing the cursor over each step within the plan
provides further statistical information.
137
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
If you set the showplan_text or showplan_all options, the graphical version of the plan is not
shown. A text version will shown instead and will continue to be shown until you set the options
off. Switch between Results in Text and Results in Grid to get a better view of the plan.
Microsoft Technet provides some good documentation related to SHOWPLAN and the optimiser in
general. Search in the books online for “Graphically Displaying the Execution Plan Using SQL Query
Analyzer” for a general overview of each displayed icon. See reference (45).
When performance-tuning queries, like all things, indexes and update statistics will play a major
part in the optimiser selecting the best execution path. The DBA should revise index and the query
joins and filter conditions carefully before choosing hints.
To obtain further statistics in terms of execution time and IO, we can set the following:
eg.
SQL Server Execution Times:
CPU time = 270 ms, elapsed time = 330 ms.
set statistics io on
eg.
Table 'Order Details'. Scan count 77, logical reads 4467, physical reads 0, read-ahead reads 0.
Table 'Categories'. Scan count 77, logical reads 154, physical reads 0, read-ahead reads 0.
Table 'Products'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0.
Table 'Orders'. Scan count 1, logical reads 3, physical reads 0, read-ahead reads 0.
Where:
Scan Count – #times that tables referenced in the query where accessed.
Logical Reads – database buffer cache page reads
Physical Reads – physical page disk read from disk into the data cache for processing
138
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Read Ahead Reads - read ahead cache manager page reads, is a separate asynchronous process (anticipated
page reads)
Switch to results in text to view the timings. Take care with statistics time as other server activity
can also skew the result set. The time displayed will also list parse and compile time when
appropriate. In all cases, ignore the first portion of the timing of the SQL statement being
analysed, this is not related to the command but previously run SQL.
NOTE – Developers can run explain plan and set the time and IO statistics on without any
special privileges. Also note that index pages are also read into the buffer cache.
Another method of timing is simply declaring datetime variables and printing the time difference
between the start and current time in each phase of your SQL. Be aware that you will be restricted
to seconds, rather than hundredths of a second.
A range of 3rd party tools I have used typically recommends the black box trace. The trace itself
will create the files blackbox.trc, blackbox_0n.trc (switches every 5Mb), of critical system error
message traces. This can be very helpful when working with Microsoft support in diagnosing
system errors. The trace is activated via:
-- ###########################
-- Start the black box trace
-- ###########################
declare @traceID int
If you want to start the trace every time SQL Server starts, then place the code into a stored
procedure within the master database and set the option:
USE master
139
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
GO
SELECT * FROM ::fn_trace_getinfo(1)
GO
Latch Statistics
The term latch is synonymous to that used in Oracle. To monitor latch based statistics we can
use the command:
This will return cumulative data so we need to re-run this command and compare the
difference to determine the point-in-time (or an average) statistic. In a majority of cases the
DBA will be able to determine the performance problem via profiler and tracing poor
performing SQL, deadlocking, page-splitting and more without having to drill into latch
statistics.
Be aware that SQLPERF returns more than just latch statistics, the command can provide
some interesting lock architecture statistics.
Page Splits
The page splitting problem primarily occurs when new data insertions (over a non-sequenced key)
or updates result in the row not fitting into a page. This results in a page split, as the destination
page is split into two and requires the re-linking of the index pages in the b-tree and associated
linked leaf page list chain to accommodate the row. As you can imagine, this is a resource
intensive tasks that can affects overall system performance, longer latch waits and concurrency
issues.
NOTE – No matter the index (clustered or non-clustered), the leaf nodes are always kept in
order of the indexed key.
The fillfactor and padindex parameters can be altered to reflect the storage characteristics of
indexes only. The fill factor controls the table density, where a high value increases the number of
rows stored per page and enhances index-scan and read-ahead performance, but adversely affects
page splits on row updates or new insertions. The padindex setting controls free space higher up
140
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
in the b-tree structure, leaving space at the intermediate nodes in the b-tree based on the current
fill-factor setting (will always leave space for one row).
Monitoring page splits is tough, why? because there is not real way to tracing in real time
where the splits are occurring (especially on a very busy database).
To begin with we can use the NT performance monitor, select the Access Methods performance
object for the instance and choose the page splits/sec counter. There is no specific value as
such we should be looking for, I tend to look at an hourly average over a number of days to
determine the need for further concern. You may be experiencing bursts of splits based on
batch data loads and bulk record manipulation which will ease the process of identifying the
tables concerned.
To drill down further, I typically scour the internet for a script that will run DBCC SHOWCONTIG
over all tables in my database. It is important to note that page splitting not only occurs in your
user databases, but can occur frequently in the system tables (especially MSDB). Anyhow, this
DBCC command displays fragmentation information for data and indexes. This will assist in
determining the tables requiring index rebuilds (re-indexing). Saying that, online index
defragmentation should be a regularly scheduled job for virtually all databases (consider
maintenance plans or again, writing your own script). This of course is based on the premise that
page splitting will increase index and table fragmentation.
The DBA should not spend hours attempting to resolve page splitting. I have yet to see any SQL
Server database that doesn’t experience some page splitting. The DBA will find it very difficult to
get any indicative figure on the rate of page splitting vs the overarching system performance. As
such, you should refocus on data reorganisation, and setting padindex and fillfactor appropriately
for frequently updated tables.
CREATE UNIQUE
INDEX [PK_efs] ON [dbo].[efs] ([col1])
WITH
PAD_INDEX,
FILLFACTOR = 80,
DROP_EXISTING
ON [PRIMARY]
On a side note to page splits, defragmentation of clustered indexes provides the best
opportunity to resolve fragmentation on the index and the physical (data) pages. The online
defragmentation option allows the DBA to alter the fillfactor, therefore, assisting in reducing
page splitting for the table. As there is no specific trace for a page split (there is but it is very
difficult to use), we need to proactively monitor fragmentation historically to determine the
effect of our change.
At the end of the day, the DBA needs to have a good understanding about:
a) database hot spots
b) indexing currently in place
c) frequency of de-fragmentation jobs
d) types of operations performed against the hardest hit tables
141
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Read the section on Index Skewing for more information on page splitting.
Important – Page splitting does not occur on clustered indexes only, any page that is near
full and a subsequent update cannot be accommodated in the page, resulting in a split. The
point is, index structure maintenance adds to total time to complete the split.
In Oracle, the counters are also applicable per database instance. The DBA can utilise the
command line utility operfcfg.exe as shown below:
This utility alters selected entries in the registry for Oracle, namely:
HKEY_LOCAL_MACHINE\SYSTEM\CURRENTCONTROLSET\SERVICES\ORACLE?\PERFORMANCE
The SQL Server counteres are automatically installed with the instance. If they are not, then
try to re-register sqlctr80.dll and run the file sqlctr.ini, both located in the binn directory for the
instance. The DBA should also try the command lodctr.exe sqlctr.ini, and the unlodctr
command.
It is assumed that the DBA knows how to use performance monitor (perfmon.exe) and will not
be discussed in detail. Some important items to remember though:
142
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
c) you can monitor a server remotely, if you are having problems, map a drive or
authenticate to the remote domain first then try again, try the server IP then the host-
name (\\163.222.12.11 for example). You may need to re-start performance monitor
after authenticating as you can continue to have authentication problems.
d) use a scheduled collection of statistics over a period of time, attempt to get a “typical”
series of working days as a base line for analysis. Watch out for pay periods in HR
systems and key events for financial systems that can see dramatic variances in
performance.
e) attempt to understand the applications running against the database and associated
server architecture well in advance, this can take some time in complex environment
but is essential in the overall interpretation of performance monitor statistics.
f) don’t just rely on performance monitor, real-time analysis for a short period may see
dramatic spiking in CPU, IO and other counters that, when averaged out, may not be
evident in collected statistics.
g) get a list of all software installed and running (especially scheduled applications) on all
servers in the domain you are analysing. Relate these back to counters and counter
processes where possible.
i) be carefully when selecting counters and test with a small collection (a few minutes) to
be 100% sure you are collecting all counter data you require. This sounds obvious, but
never take it for granted as it is not worth the trouble.
j) to enable disk counters, execute the following from the command line and re-boot the
server. Run diskperf.exe /? for list of all options.
diskperf -y
To assist with performance analysis via the NT counters, the following are discussed:
Counter Meaning Category
Processor Utilization of each CPU of all threads for a specified process (or CPU
(_Total): % all processes if selected). Is total elapsed time that all threads
Processor Time of the process used the processor to execute instructions.
Anything over 75% over a sustained period needs to be
(or single process) investigated, users may be experiencing response time issues at
lower figures though.
Filter on the sqlservr process if need be. This can also be used
to determine if SQL Server is using all CPU’s.
143
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
if this exceeds max/cpu and CPU utilization is not high. Use this
counter and one above to get overall CPU utilization.
Processor (_Total) This is the time spent running Kernal mode (privileged) code. If CPU
: % Privileged this counter is >= 20% over a period in relation to %UserTime,
Time this may indicate IO (paging) and disk array problems. Re-
and check % Disk Time counter (over 55%?) and other disk related
Processor (_Total) counters (such as queue length) to determine is this is not the
: % User Time cause.
System : Context How often NT switches context from one thread to another. If CPU
Switches/Sec >15000/sec for over 5-10mins then consider NT fibres. Re-
evaluate CPU performance by checking queue lengths.
For the drive being analysed, you need to divide the value by
the number of spindles in the drive, remember this, especially
for your RAID arrays. As an example, a RAID-5 array of 4 disks,
means you need to divide the value returned by 4, but a
RAID0+1 array of 10 disks means a division of 5, so a queue
length any greater than 10 (10/5 = 2) may be a problem.
Physical Disk: % How busy the physical array is. Should be <90%, use two I/O
Disk Time counters below to determine where the majority of the work
may be (on the read or on the write)
Physical Disk: % % IO Read performance. I/O
Disk Read
Physical Disk: % % IO Write performance I/O
Disk Write
Soft Paging – A value >0 indicates paging, both hard and soft. Soft paging is Soft Paging
Memory : Page applications referring to page file memory pages in RAM rather
Faults / sec than within the physical page files. Use for formula :
144
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
145
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Batch Requests/sec
-- query analyser, batch requests / sec = 1
select count(*) from sysprocesses
select count(*) from sysprocesses
select count(*) from sysprocesses
select count(*) from sysprocesses
select count(*) from sysprocesses
select count(*) from sysprocesses
select count(*) from sysprocesses
select count(*) from sysprocesses
146
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
SQLServer Backup How fast backups are performing. If going to disk also review Backups
Device: Device queue length and the RAID array configuration in conjunction
Throughput with the counter.
Bytes/sec
I should point out that it is easy to get “hooked up” with some of them, and one poor performing
figure may not correspond directly to the specific problem, only to find another counter is skewing
the result. There are a range of websites and good books that cover performance counters in detail
to provide further assistance with analysis.
The DBA should take a “baseline” data collection using these counters. The interval may range
from every five minutes to as little as every twenty seconds (ideally over a range of days). The
collection is essential for ongoing performance monitoring, and performance tuning.
Trace Flags
There are numerous trace flags available to the DBA but most are not formally documented. A
great source of information for the documented and undocumented trace events comes from the e-
book “Transact-SQL Language Reference Guide” (47). I highly recommend that you register this e-
book as it is an excellent introduction to T-SQL programming commands.
The T-SQL language reference lists 20+ trace flags, whilst the online documentation lists four.
Some of the flags are shown below.
Trace# Summary
147
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
3602 Record all error and warning messages send to the client
On startup, we use the –T or –t option, this can be set via Enterprise Manager as shown
below, or you can go to the registry and alter the startup options. You need a new –T[trace#]
for each flag being set, do not try separating them via commas or spaces.
148
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Important – Trace flags set with the –T startup option affect all connections.
To view the current enabled session and database wide traces, use the command:
DBCC TRACESTATUS(-1)
For the current connection we can use the DBCC TRACEON and DBCC TRACEOFF commands.
You can set multiple flags on and off via DBCC TRACEON(8722, 8602[,etc])
Use profiler to trace existing connections, even so, remember that these trace flags are not
the same as trace events as used by profiler (sp_trace_setevent).
NOTE – Use trace flags –T1024 and –T3605 to enable extended deadlock tracing.
149
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Indexing
It is worth mentioning indexing in terms of their use, performance, reorganisation and
statistical collection. It is important to remember that, no matter the DBMS, the indexing
mechanics are typically the same (in concept) and are critical for the overall performance of
your system.
Index Types
In SQL Server, we are somewhat restricted in terms of the types of indexes available when
compared to Oracle, this may change over time but the time being we only have:
b) Clustered indexes
a. Leaf nodes contain the actual row data pages
c) Non-clustered indexes
a. Leaf nodes are pointers to row data pages, or, if the table also includes a
clustered index then it will point to the clustered index leaf nodes (requires a
bitmap lookup step in the execution plan).
The first question we ask ourselves is when to use a clustered index verses the standard heap.
As you can only have one per table, this gets somewhat tricky as you need to understand the
types of queries being executed. There is no definitive answer, but consider the following:
a) clustered indexes are best suited to range queries rather that highly selective row
lookups. A range based query may be over a series of dates, category types etc.
b) clustered indexes are also beneficial for single key lookups, primarily when most of the
record will be retrieved. Remember that non-clustered indexes use the clustered index
to locate the data rows and hold the clustered keys in their leaf nodes (resulting in
more IO).
c) clustered indexes are ideal around columns used in order by and group by clauses
d) a tables data pages can only be defragmented online via its clustered index (row re-
allocation may occur with the command DBCC shrinkdatabase command, being a form
of re-organisation).
e) identity column primary keys, clustered indexes can be beneficial (so long as its not
being wasted on a more commonly used complex query).
With identity keys in general (clustered or not) the possibility of page splits is close to
zero (not taking into consideration subsequent row updates etc) as the in increasing
key value will be inserted in order. Be aware though, that the adverse affect is the
creation of “hot spots” over the last page that can result in locking/blocking issues.
150
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Although fine, such points are close to useless unless you have a good understanding of the
DML running against your DBMS.
NOTE - As with oracle, the more indexes on a table, the slower subsequent DML will be.
Consider this when bulk loading data especially or systems requiring high insert/update/delete
throughout over query speed.
Moving to non-clustered (heap) indexes, be aware that if you drop or re-created a clustered
index associated with the table, all non-clustered indexes must also be rebuilt. The DBA
should consider in non-clustered indexes over all foreign key columns not partaking in the
primary key. This is a common practice; even when there is poor selectivity in improving
merge join performance. Always remember the following statement from the SQL Server 2k
BOL:
“If the table does have a clustered index, or the index is on an indexed view, the row locator is the clustered index key for the row. If
the clustered index is not a unique index, SQL Server 2000 makes duplicate keys unique by adding an internally generated value. This
value is not visible to users; it is used to make the key unique for use in nonclustered indexes. SQL Server retrieves the data row by
searching the clustered index using the clustered index key stored in the leaf row of the nonclustered index.”
The non-clustered indexed as in Oracle are ideal for highly selective columns. As you expect, a
scan over a non-clustered index results in a scan over the clustered index to locate the
physical row. You will see this in your explain plans as:
In a bookmark lookup, we utilise the clustered index (over the primary key in this example), to
look up the rest of the table data. This can be a misnomer though, as the optimiser will also
shown this operation even though a clustered index does not exist, but we still need to locate
the rest of the column data to suffice the query. Also note that this lookup will occur if we
have a covering index.
WARNING – Take care with indexing, you can index the same column multiple times in SQL
Server.
The final index type is not really any different from the two mentioned, but in terms of Oracle,
is equivalent to materialised views.
Like Clause
Using a leading ‘%’ wildcard pattern character at the start of a string will not allow optimizer to use
indexes. Take are good think about what the end-user really wants, and consider full text indexing
for complex searching over string columns.
151
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Within Oracle, the Function Based Index was created to allow the DBA to index a column with a
function applied to it. A classic example is:
In SQL Server this is a problem that will result in indexes not being used. To get around this, take
a careful look at the where clauses, and determine if you can remove or reverse the call, here is a
classic example:
Composite Indexes
As with Oracle, a composite key will not be used unless the left most column is used in the where
predicate. Within the where, the column must also be first (top most) column to be used by the
optimizer. Such indexes are good for clustered indexes, especially where only some of the leading
columns are being used.
A view can be indexed, unfortunately there are a whole range of restrictions that can make the
option undesirable. Some of which are:
152
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
b. ANSI_PADDING
c. ANSI_WARNINGS
d. ARITHABORT
e. CONCAT_NULL_YEILDS_NULL
f. QUOTED_IDENTIFIERS
c) Session options set OFF
a. NUMERIC_ABORT
d) All columns must be named (column name with suffice but if using function calls the
explicitly name the column).
e) Cant index columns using indeterministic functions (eg. Getdate)
a. The view must be deterministic
f) Clustered index must exist before other non-clustered indexes are created. The
clustered index must be unique
g) Must refer to tables using the two part syntax
a. dbo.mytable – ok
b. mytable – fails
h) Must be bound to the schema (tables) in which the view is sourced from
Select sessionproperty('ARITHABORT')
or
DBCC USEROPTIONS
The schema binding option is the critical part to creating the materialized view. Once done, we will
create a clustered index over the view and optionally a number of non-clustered indexes. For
example:
Its not until you create the index will you get errors related to function calls used within the view.
For example, you may get something like:
select ObjectProperty(object_id('viewtest2'),'IsIndexable')
153
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Take care with hints, the optimizer will chose the optimal indexing path where possible based on
the expansion of the view, its tables and the tables underlying indexing and histograms. The index
on the view may simply be the wrong way to go to suffice the query.
In the above view created against the PUBS database, the expansion and nonexpansion gives some
interesting results:
set statistics io on
Table 'viewtest1'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0.
-- optimizer chooses, expand view forces the optimizer not to use indexed views
select * from viewtest1 option (expand views)
or
select * from viewtest1 -- even with no hint, the optimizer expanded the view
Table 'titles'. Scan count 25, logical reads 50, physical reads 0, read-ahead reads 0.
Table 'titleauthor'. Scan count 24, logical reads 48, physical reads 0, read-ahead reads 0.
Table 'authors'. Scan count 1, logical reads 1, physical reads 0, read-ahead reads 0.
To change the underlying tables in any way, the schema bound view must be dropped first.
Covering Indexes
A covering index is one in which the index includes all columns required for the index to resolve the
query without having to do a further lookup for the rest of the column data. An example is shown
below.
154
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Index Skewing
In Oracle, we have the concept of Reverse Key Indexes, which resolves index skewing in the b-
tree, where one side of the tree becomes a “hot spot” in terms of new insertions and whose depth
also increases (skewed to one side) with a monotonically increasing key values. For example:
101 201
101 102
So in the example above (very rough example mind you), the key value is reversed to produce a
more balanced tree structure, especially during deletions resulting in index browning. The only
option in SQL Server is the ASC or DESC options when creating the index, altering the sort order of
the key columns, this is not the same as reverse key indexes. To monitor index height, use the
INDEXPROPERTY command, for example:
In the case of identity columns, the depth increases slowly, with more intermediate index keys
being added (resulting in page splitting higher at these nodes). In the example below, the index
height remains at two, but during the bulk insertion of records over the clustered primary key
identity column, we see a large number of page splitting due to page allocations and the increased
number of intermediate nodes.
With 303104 rows, index depth 2, index size 216Kb, data 63816Kb, reserved 64064Kb
155
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The following commands can be used to view table indexes and subsequent statistical
information:
To rebuild indexes:
NOTE – As with composite keyed indexes in Oracle, the leading column must be used for the
index to be utilised by the optimiser. Also note that in non-clustered indexes (heaps), the leaf
nodes are not linearly linked listed.
You cannot alter the padindex parameter via the DBCC commands.
We know that DBCC DBREINDEX and INDEDDEFRAG can be used to defragment the index, but not
necessarily the table itself. We have assumed though, that a clustered index that is defragmented
will also defragment the table itself and not only the index. The following example attempts to test
this theory:
In the Northwind sample database, we have duplicated the products table, retained the identity
column used for its primary key and forced some fragmentation to occur. We will defragment with
the DBCC DBREINDEX command and review the subsequent storage characteristics of the table
and the associated index structure.
156
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
157
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
We see no change in the physical table storage with a heap index. Altering the index to a cluster,
deleting and inserting more data, we see that re-indexing will also defragment the underlying table as
well as the immediate nodes for the index. As we would expect.
Rebuilding Indexes
The DBA can use WITH DROP EXISTING clause to rebuild indexes. If a clustered index is rebuilt, so
will any other index. . SQL Server support parallel index rebuilds.
Performance Counters
There is no simple way of determining the relevancy of indexing. I tend to run profiler (trace) and
collect all DML being executed against the database of interest (or filter out specific tables). I then
run this data through the index-tuning wizard and carefully read the summary reports on table
access, columns accessed and recommended indexes. For in-house applications where you have
some control over indexing (without breaking your support agreement) this method works well on
your development and test servers to get a feel of the queries being executed and the most
commonly used tables.
The performance counters may compliment the tracing approach, but I find them somewhat limited
and very easy to misinterpret, as you will see in the comments below. The counters are:
158
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
determining the performance impact of too many indexes with heavy insert/delete/update
SQL. With no indexes but 6 rows, we see a single full tablescan but also 6 index scans.
The counters are for the entire instance and not database specific.
a) Database Diagrammer
b) Designing a table (right click on table, select design table and select index icon)
c) Manage Indexes option (right click on table, All Tasks Æ Manage Indexes)
Option c) is quite functional and has that sort of Oracle Enterprise Manager type feeling to it. Be
aware though that this option can be a little restrictive when shifting between clustered and non-
clustered index storage. As such, switch to b) to resolve the issue. Trace the output via profiler (or
view scripts generated via their menu options) to understand how to manage indexes via raw SQL
commands.
Summary
There is no magical wand for indexing. The DBA needs to have an intimate understanding of
the application(s) running against the database, and from there, make informed decisions on
the indexing paradigm. As a very broad rule, you can not go too wrong with:
159
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
-- 6 = DB ID, 1 = file id
select * from ::fn_virtualfilestats(6,1)
Take care with the NumberReads, these are physical IO’s, and will not measure buffer cache
lookups. The NumberWrites is another tricky one, as its very much dependent on the
checkpointing and flushing pages to disk. The IoStall MS represents IO waits in milliseconds
between refreshes. Here is an example, without the DBCC and checkpoint commands, you may
see little or no change in the figures returned by the file IO function call.
DBCC DROPCLEANBUFFERS
select * from ::fn_virtualfilestats(6,1)
select count(*) from products
delete from EmployeeTerritories
checkpoint -- flush the log buffer
select * from ::fn_virtualfilestats(6,1)
Wait Statistics
To view wait statistics, use the command:
DBCC SQLPERF(WAITSTATS)
160
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Also query sysprocesses where waittime > 0 and spid > 50, looking up waittype, waittime,
lastwaittype, wait resources.
Many of the wait types listed is related to the specific types of lock objects SQL Server can take out
(see Transaction Management chapter). Two key waits to review are related to transaction log
management, they are:
Microsoft poorly documents the figures. Carefully evaluate their use and always use in conjunction
with broader statistics from performance monitor.
STATSPAK
There is no equivalent utility to Oracle statspack in SQL Server. The analysis of the databases
overarching performance requires a range of tools but we can get “similar” statistics via
performance monitor and its numerous counters.
Server Configuration
• NTFS
o partitions <= 80% capacity
o cluster size to 64k
o format in NTFS 5.x or above
o don’t place database files on compressed NTFS partitions
• Control Panel
o Start -> settings -> control panel -> system -> performance, Set “Application
Performance” to None.
o Start -> settings -> control panel -> network -> services, set “maximize
throughput for network applications” as the default is “maximize throughout for file
sharing”. Reduces RAM usage.
o Remove unused network protocols
• Networking
o Windows 2k Server supports a larger MTU (1.5Kb to 9kb), consider altering it on
your network card based on careful analysis of network performance
o Check your network protocol list, if using, for example TCPIP, then ensures it is the
first protocol to be validated by Windows.
o Disable power management features for your network cards
• General
161
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
• Application code
o T-SQL stored procedure code performance, use of stored procs vs inline
(embedded) data access code at the business layer
o Cursors are notoriously bad performers, utilise single DML statements where
possible
o Architecture (tiered architecture on separate servers?)
o Not using native XML from SQLServer (or code managed/generated?)
o Poor selecting of connection provider
o Lengthy transactions resulting in blocks and deadlocks
o Mis-understanding of COM+ transaction handling
o Triggers and user defined function (check affect of DML performance carefully)
• SQL performance
o Use of cursors vs batch-sql statements
o Indexing scheme
o Length of transactions
o Batch processing during the day
o Mix of OLTP vs DSS vs Reporting requirements on server verses auditing
requirements (trigger driven?)
• SQL Server Configuration
o Disk and file layout
o Automatic statistics collection
o Memory configuration
o Isolation level and transaction processing
• Physical data model design
o Query plan reuse, use of cursors, adhoc reporting
o Middleware (COM, COM+, MSMQ), location of data tier code
o Database Design
o Indexing scheme vs actual usage patterns from programmers
o Backup/Recovery model vs database usage and recoverability
o Normalisation
o Trigger design and usage
• Client and Server Hardware
o Client and Server Operating System Settings and Configuration
o Network Hardware and Bandwidth
o Verify with network administrators –
162
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
• When running performance monitor, take care when setting the interval. The collection
and reporting is based on an average between the current and last collection, therefore,
if you are monitoring every 5mins, but your CPU time is spiking throughout this period,
the overall average may be somewhat low and will not reflect this in your graphs. A
consistent “spiking” in CPU time is typically related to poor performing application code
and/or SQL, if multiple users happen to hit the same code at the same time, this spike
will of course run longer but still may not reflect in the graphs. This may result in good
server performance statistics but poor application performance (end user experience).
• If you are using COM+ (component services), look at the properties for each installed
package, it will show:
o #objects instantiated
o #objects activated
o #objects pooled
o #objects in-call
o #objects call-time(ms)
this is very handy when tracking possible issues with DLLHOST.EXE processes going
wild with the CPU.
To locate the PID for a COM+ package, select properties for the “COM+ Applications”
folder within Component Services.
• Profiler is the key utility for collecting SQL and other SQLServer internal event
activities. It is important that the DBA has a good understanding on this trace utility
and the numerous parameters and events that can be monitored. Don’t run Profiler on
same server as you are monitoring.
• If collecting statistics to a file or a database, don’t write to the server you are
monitoring.
• Index tuning wizard
• Turn off the auto-close and auto-shrink options for your databases
• Manually configure database memory settings to control SQL Server memory usage and
its potential impact on the server.
• I rarely recommend any internal database setting changes unless there is a real,
testable need for it. Even so, setting such as max-async-io, recovery interval, min
memory per query, max degree of parallelism, max worker threads and common areas
that DBA’s consider altering.
• The DBA should put in place:
163
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
o Script (or use maintenance plan) to reindex user databases on a weekly basis
Dbcc Dbreindex
Dbcc indexdefrag
o Consider a script to manually update statistics daily
Dbcc updateusage
Update statistics..
o Do not alter locking and other advanced options without direction from Microsoft
OR you are completely satisfied that the change IS making a difference and is
repeatable on dev/test before moving to production. The DBA must be able to
monitor it over-time.
Use dbcc traceon and dbcc traceoff as required, some flags are at
instance startup only via –T parameter.
• Determine the requirements for fill-factors early. The fillfactor not only applies to
indexes but also affects the physical table themselves if clustered indexes used.
Consider the following settings:
o Very few updates/inserts (DSS/OLAP) – 0 or 100%
o Minor insert/delete/update activity – 90%
o OLTP system
Reference data – 90% to 100%
Other – 50 to 70%
Heavy inserts/updates – 25 to 45%
• Utilise file-groups (FG) with one or more physical data files (file-group striping) to
assist with separate data structures from one another, for example:
o PRIMARY – sys only objects
o DATA_FG – all tables (made default FG)
o INDEX_FG – all indexes
o AUDIT_FG – all audit tables
• File group considerations
o # files per group?
o what datafile should be placed on which storage set?
o what file groups do objects reside?
o FG backups vs other
• Do not use multiple files for transaction logs.
• A shorter row length = more data per page (also consider pad and fill-factors) = more
data in buffer cache per read
• Use varchar instead of char unless its:
o Always of a set, fixed length
o Very short (i.e. Y / N), if so, consider bit data type for 0 and 1 indicators
• Avoid uni-code data types where possible (eg. Nvarchar etc)
• Only make columns large enough (namely varchar data type) to support what is really
needed.
• Consider using the TEXT IN ROW feature for S2k. This allows you to control the storage
of smaller amounts of text and image data onto the data page. See article
http://www.sqlservercentral.com/columnists/bknight/textinrow.asp for a thorough
summary.
• Consider alternative datatypes for numerics based on the following:
164
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
o Bit (0 or 1)
o Tinyint (0 to 255)
o Smallint (-32768 to 32767)
o Integer (-2,147,483,648 to -2,147,483,647)
o Bigint (-9,223,372,036,854,775,808 to -9,223,372,036,854,775,807)
o Money (-922,337,203,685,477.5808 to +922,337,203,685,477.5807)
o Smallmoney (-214,748.3648 to +214,748.3647)
o Float (-1.79E + 308 to -2.23E – 308, 0, .23E + 308 to 1.79E + 308)
o Real (-3.40E + 38 to -1.18E - 38, 0, 1.18E - 38 to 3.40E + 38)
• Consider smalldatetime if the nearest minute is ok.
• Avoid GUIID columns, but may be unavoidable in some forms of replication
• Primary keys are, by default, clustered indexes. In many cases this may not be the
ideal candidate and other columns with range based scan characteristics may be a lot
more optimal.
• Index foreign keys not already part of the primary key to speed common table joins.
• For disconnected/stateless environment, consider the 3 columns:
o Last_updated_on
o Last_updated_by
o Update_count
for all tables to manage concurrency issues, but is also handy with applying batch
updates where you can use the last_updated_by column to “mark” the rows altered.
• Review auditing requirements as early as possible, retention periods, and the use of
these audit tables (in reporting and general lookup).
• Consider covering indexes (non-clustered index for every column in the table) for
selected tables with heavy read characteristics.
• Indexed views
o Can take a significant performance hit in write intensive applications
o Must create view with schemabinding option, when done, you cant alter table
structure until the indexed view dropped.
o In a situation where SELECT statements retrieve a result set that is an
aggregate, including summation or other calculations from one or more different
tables. In this case, a pre-aggregate result set stored as an indexed view speeds
up read performance tremendously.
• Consider using CREATE STATISTICS where you believe the optimizer may benefit from
information about data distribution
• Use non-clustered for highly selective columns (95% or more of results can be
eliminated) and clustered for range lookups. Remember that primary keys are, by
default, clustered indexes unless altered. This rule is not hard-and-fast, and should be
carefully considered early in the project as there is only 1 clustered index per table and
it can be difficult to alter this at a later point in time.
• Use identity columns carefully. Follow standard normalisation practices. Don’t us
identity because its simply convenience, sure, single column numerics keys are fast,
but can have adverse affects with:
a) replication
b) readability and maintainability
In the end, the “because its simple and easy” attitude should not be you key reason for
sequenced columns.
• Begin to evaluate the need for federated databases early in the design phase. It will be
very costly to change to this infrastructure later.
165
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
• Evaluate as soon as possible database links (local and or remote ones) to the network
and what applications will they be sharing the data lines with (also the server
performance of the remote connection).
• Consider indexed views and indexed computed columns, this may be a result of
denormalisation to some degree. This will impact insert performance.
• Consider computed columns over standard de-normalisation practices:
o Example:
create table mytab (col1 integer, col2 integer)
alter table mytab add mycalccol as col1 + col2
creates a new column with the formula property set of data type INT. If one
data type was a int and the other float, the calculated col will take on the float
datatype. You can now create an index on the computed column (known as a
function based index) so long as the calculation is deterministic.
• Will full-text indexing be used?
o Use timestamp datatype for all tables to track incremental updates
o Plan well ahead of time with server administrators on CPU and IO impacts, they
can be significant.
166
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
o Consider locking hints (in liaison with the DBA) where appropriate to reduce
locking issues.
• Describe the following concepts to developers
o Selectivity of indexes (# rows returned)
o Join types
o Index usage and control
o Storage (row/page/extents and logical vs physical page access)
• For concatenated index, the 1st column in the index must be used in order for the index
to be included as a valid option for the optimizer.
• In most cases, NOT EXISTS will out perform inner join and NOT IN alternatives (based
on appropriate indexing).
• Take care with the WITH COMPILE option for stored procedures, unless the stored
procedure uses dynamic SQL, there is no need to re-generate the execution plan.
• Don’t name stored procedures with sp_ for its prefix as a master db lookup will occur
first, then a dbo owner check, then a check based on the users DB login name.
• Objects that are called within the same stored procedure should the same owner,
preferably dbo, own all. If not, SQL Server may need to do further name resolution to
resolve the objects (all objects should be dbo owned as best practice).
• Developers should have some basic understanding on reading the plan output.
• Some notes on the SHOWPLAN option:
o Use SHOWPLAN_ALL in SS2k, but will not actually run the SQL, therefore IO and
TIME set options will return nothing.
o Query type (insert, update, delete, select)
o Tables listed in order of processing
o For each table the access method is indicated (table scan, index lookup etc)
o Parallelism is indicated
o Worktables may be included – temporary table in tempdb
o Aggregates may require many steps
Vector (group by used in conjunction with aggregate function)
Scalar (aggregate function used in select statement)
o Exists table – exists, in, or,>=, any used
o STEP’s, where SQLServer required many steps to retrieve or access data
Step may involve sorting
Getsorted – temp work table created for sorting
• Some notes on the STATISTICS IO option:
o Also see STATISTICS TIME option
o Logical reads – total # of pages accessed
o Physical reads - # pages read from disk into buffer cache
o Read ahead reads – # pages cached by read-ahead manager
o Scan count - # times table was accessed
• When attempting to tune queries, consider dbcc dropcleanbuffers and free proc cache
to clear out the data base buffer cache.
• Sorting
o Optimiser will sort when distinct, union or order by clauses are specified
o If no order by criteria is specified, records are returned randomly based on
buffer cache lookup.
o Default is ascending order
167
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
• Backup Destination
o Is this a dedicated disk or also used for database files?
o How many disk spindles are in use?
o Is the backup over a network connection that is already very busy
o If you are going directly to tape, ensure stream speed is not imposing on your
backup window.
• Restoring Databases
o Purge MSDB backup history on a regular basis. If you are using the GUI to
restore and you select a DB that has a lot of historical data, the GUI may take
some minutes to respond whilst it reads the sys tables.
• The SQL Server backup command is very slow and produces large files, as it uses very
little of the CPU. Consider SQL*Lightspeed (3rd party product) for a fantastic
performance increase and much smaller backup files.
CPU is a Bottleneck?
• Have you accurately determined where the CPU bottleneck is occurring?, can it be
repeated successful for further testing, and is it kernel related or user process related.
• Get faster CPUs or add additional CPUs (do not forget the licenses).
• Get CPUs with a larger L2 cache. In most cases, simple opt for faster or more CPU’s
• Re-check application components and try to get an accurate measure between
database activity vs business layer activity. For example, is the wrappering of record
sets with XML the real problem vs database query performance issues?
• Move some of the processing load to another SQL Server.
• Consider turning on Windows NT fibres.
• Be sure that both OLTP and OLAP queries are not being run on the same server. These
different database applications should be performed on separate servers.
• Re-check your statistic, namely kernel time, if kernel time is high recheck your paging
statistics and other IO statistics as this may be a flow-on affect.
I/O is a Bottleneck?
• Consider file-group striping, create one file per disk array and re-import data, data will
be evenly striped over the file-groups physical file set, for a sequential read a separate
thread is created for each file in parallel.
• Add additional physical RAM, checking paging.
• RAID level 10 is the fastest RAID level you can choose that supports redundancy.
• Add more physical drives to the current arrays. This helps to boost both read and write
access times. But don't add more drives to the array than your I/O controller can
support.
• Replace your current hard drives with faster drives. Review SCSI channel usage,
controller cache and the connection itself (i.e. fibre interconnect?)
• Add faster or additional I/O controllers. Consider adding more cache (of possible) to
your current controllers.
168
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
• Revisit SQL tuning and index utilisation. Revisit buffer cache hit ratios and memory
utilisation.
• Move transaction log to its own dedicated RAID-1 array.
• Move tempdb to RAID-1 or RAID-0 (no redundancy though).
Task Manager
This sounds obvious, but many people seem to draw a blank at times and race off to use profiler
and performance monitor when simply opening task manager can give you a good snapshot of the
state of the system and its running processes.
Selecting different tabs will alter the options available under the View menu option. The key
tabs are:
a) performance
b) processes
Select the process tab, the select columns option as shown below provides a good set of
columns to include for real-time process monitoring and problem identification. Sorting the
columns over, say, CPU or memory usage is a great start.
COM+
It is worthwhile spending a little time investigating how to view COM+ activity. The Component
Services (also known as DTC or Distributed Transaction Coordinator) program installed with the OS
allows the user to install and subsequently manage COM+ packages, an example screen shot is
shown below:
169
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
To view runtime statistics, highlight “COM+ Applications” in the left-hand panel and click the
properties icon in the top menu-bar. Shown is the list of COM+ packages installed and their
running stat with associated PID. To drill down, open up the Windows Task Manager:
170
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
We can drill further into COM+ and go to a class level within the package. This allows is to monitor
the number of instantiated objects, wether they are activated and pooled, in-call and the call time
in milliseconds.
Component Services under XP is a little different that Windows 2k Server and Advanced Server. In
XP the class strings (as found in the registry) are shown. Also, utilise the details display on
components at a variety of levels to view other information in regard to the user which the objects
are instantiated, their activation context etc.
Going any further requires intimate knowledge of the application, but further profiler tracing may
assist you.
Be aware that COM+ components utilise a isolation level of serialisable (Q215520). As with all
transactions in SQL Server, keep them small and fast as this sort of isolation level can destroy your
performance. In .Net Server and Enterprise Services (COM+ v1.5), this can be configured to
serializable, repeatable read, read committed, read uncommitted, or any.
The developer should consider altering the isolation level on connection to the instance where
possible to read committed.
There is a great article by Alan Gordan regarding COM 1.x titled “Generation 1.X: A New Era for
COM+” that is worth a read for all SQL Server DBA’s. Take time to understand the issues with
COM+ and the new features for enhanced scalability and manageability.
171
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
On monitoring your COM+ components, you may find some are hitting the servers harder than
others. Depending on your scenario in terms of server availability and your overarching server
infrastructure, consider proxying off you COM (known as DCOM) to another server. Here is an
example scenario:
Server A Server C
(WebServer) (Active Directory
Server)
UserSecurityAccess.dll UserSecurityAccess.dll
(proxy – very small (using 30-40% cpu time was moved from
CPU footprint) webserver and called via a COM+ proxy, turning
the AD box into an application server as well as
servicing its standard LDAP requests).
Stored Procedures
The use of stored procedures is the most effective way to:
a) reduce network bandwidth between the business layer and the database server
b) manage security – it is not uncommon in SQL Server applications to only grant stored
procedure access rather than access to the underlying tables/views.
c) Ease of administration, tuning and maintenance – much easier for the DBA to review SQL
and for developers to debug SQL problems or alter code without recompiling.
When you execute a stored procedure, a variety of information is sent back to the client indicating
the number of rows affected (and other information). Generally, it is rare that the client (or middle
tier COM’s) require this information, whose effect increases network traffic. This is especially
evident in large stored procedures with looping clauses and DML activity, sending a message for
each DML executed. Turning this feature off is always best practice unless there is a specific
application requirement for it to be left on.
172
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The DBA can turn this off globally via (current logins not affected):
Or via the instance startup flag 3640, eliminating the DONE_IN_PROC messages globally for all
connections.
Blocking, locked/waiting and long running transactions, incorrect use of COM+ transactions
or mix of OLTP and DSS based transactions, poor selection of isolation level.
Non-fixed database instance memory settings chewing all server memory, or very little
memory available for a very busy instance.
High recompilation and cache misses due to large numbers of adhoc queries or SQL using
hard-coded predicate parameters preventing reuse
Server shared with other applications resulting in a conflict of interest in terms of resource
usage.
Disk IO and IO distribution (affects associated RAID level, array cache and disk queue
lengths)
High page splitting due to a poor understanding of DML activity against user databases and
their clustered indexes.
SET NOCOUNT is not being used in your stored procedures, creating additional network
bandwidth between server and client (or middle tier).
173
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Not utilising stored procedures for the data tier or returning XML directly from the DBMS
and wrappering XML tags manually thereafter.
174
7
Chapter
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
High Availability
O
ne of the most important issues for many organisations revolves around disaster recovery
(DR), which goes hand-in-hand with the topic of high availability.
When we talk about high availability, we are primarily focused on seamless failover of our
servers hosting the applications they are running; and the technologies to support the continuation
of service with as little interruption to the business as possible. The solution you come up with will
be dictated by the realisation of its:
The problem you tend to have is that systems typically grow into this realisation rather than being
born with it. As such, the DBA and system architects must carefully consider the overarching
issues with application state, server configuration, OS and DBMS editions purchased, technologies
being used (clusterable?) and to some degree, “brail the future environment” in which the
application will live and breath.
Throughout this chapter, we will compare and contrast the high availability options to support your
DR plan and assist in realising the possible issues in advance.
175
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Clustering
Oracle RAC and Application Clustering
Trying to diagram the architecture is difficult, but the following provides a basic overview:
Interprocess
Communications (IPC)
The following key points (not definitive) should be noted about this architecture:
176
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
• Server vendors provide OSD (operating system dependent) cluster-ware to access the
underlying OS and for cluster communication regarding the database instance. The
OSD is made up of:
o Cluster manager (CM) – oversee inter-nodes communications
o Node monitor – polls status of cluster resources, include DB instances
o Interconnect – IPC controls messaging amongst the nodes
• Global Daemon Service (GSD) – runs on each node, this coordinates with the CM and
deals with client administrative tool requests. It is not an Oracle instance process.
• LMSn (Global Cache Service, GCS) – locate, prepare and transmit buffer cache blocks
to multiple instances. The same block may exist over multiple caches and can exist in
different modes (null, shared, exclusive). The GCS allocates roles and resource modes
to control concurrency and the instance will retain read-consistent block versions via
RBS entries.
• LMON (global enqueue service, GES) – monitor global enqueues and resources and
perform enqueue recovery.
• LMD (global enqueue service daemon) – manages incoming remote resource requests
• LCK (lock process) – manages non-cache fusion resource requests (library, row cache
requests)
• DIAG (diagnostic daemon) – diagnostics amount process failure and alert log
management.
• The GCS and GES maintain the Global Resource Directory to record resource
information. This is an in memory data structure that is distributed throughout the
cluster. Each instance has a part of the directory in the SGA.
• GCS and GES nominate one instance to manage all information about a particular
cluster resource, this instance is regarded as the resource master.
• Interprocess Communications (IPC) – asynchronous queued message model to route
messages and other comms traffic to coordinate other node resources. May be either
ethernet or fibre-interconnect.
• Multiple servers are working together against the same data files, offering great
scalability and performance.
• On NT servers, you still require the Quorum (voting) Disk, Oracle stores essential
cluster configuration information here. All administrative tools (Enterprise Manager
etc) must also be on a shared disk, typically the Quorum disk.
Taking this one step further in terms of a complete Enterprise solution, we have many alternatives
based on the environment we are running against. Oracle has made distinct strategic moves to
Java where possible, and in many cases, is the core development environment over PL/SQL and/or
Oracle Forms and Reports for medium to large scale development. As such, we have seen the
expansion of the Oracle Application Server and associated middle tier components (web servers,
caching servers etc) to encompass the Java suite of modules. Clustering in this environment is
complex and is out of scope of this e-book, even so, see references (54) and (55) as a starting
point.
177
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
There are many scenarios as you can imagine in the complete clustering solution in Oracle, but
here is an example:
The iAS Web Cache providers server-side caching for dynamic content over HTTP. This caching
takes into consideration cookies, http request headers, parameters and more. Result sets from
Java or PL/SQL procedures can also be cached and subsequently clustered.
The OC4J represents the possible J2EE cluster (Oracle Containers for J2EE). This includes the
clustering capabilities for Servlets, JSP and EJB’s. This also includes the Java Object Cache. The
OHS component represents the Oracle HTTP Server. This typically comprises of a webserver
(apache), Perl execution environment and PL/SQL and J2EE container routing.
In terms of Oracle and Microsoft Web Development, although not technically part of this chapter,
we typically see the following comparisons:
178
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
terms of incorporating high availability with a horizontally scalable performance gain (i.e.
many servers utilising the same database data files at once).
Before we begin, remember that SQL Server Clustering is designed to provide high availability, not a
load-balancing solution.
The Microsoft Windows and SQL Server cluster solution is a share nothing resource model, meaning
that one and only one database instance can run on any server in the cluster at any one time.
Therefore, if we had 4 nodes (servers) in the cluster, one and only one node can actually accept
connections and run against the database files for the instance. This adversely means that the
clustering solution does not provide horizontal scalability as Oracle does.
An example is shown below we have an Active/Active cluster which we will explain in more detail.
Node 1 Node 2
InstanceA InstanceA
(virtual failover (failover)
instance)
InstanceB InstanceB
(failover) failover (virtual Cluster Service
instance) (MSCS)
Heartbeat
(private network)
Interconnect
SAN or SCSI/Fibre
connected Disk Array
179
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
IMPORTANT – Remember that when we talk about an instance we don’t mean a specific
database. See the first chapter for more information if this confuses you.
The configuration of a cluster is not overly simple and I would highly recommend visiting
Microsoft’s website and reading up on their comprehensive technical manuals beforehand.
Here is a summary of the issues for installation and configuration:
b. all of which run in the same windows domain (cross-domain clustering is not
supported)
c. Each node has a minimum of two network cards. The public and private
networks must appear (or appear to be in) in a non-routed LAN.
i. One for the private network that interconnects all nodes in the cluster
1. disable NetBIOS for the private network cards.
ii. One for the public network connection
1. nodes may be “remote”, i.e. over an VPN so long as the ping rate
is <= 500ms
b) Disk array
a. One or more disk controllers installed on each of the nodes
b. SCSI or Fibre interconnect
c. NAS is not supported by MSCS
d. SCSI not supported by Data Center server (fibre channel only)
e. Dynamic disks are not supported by MSCS
i. This means cluster downtime when adding more disks to the cluster
f. File compression not supported by MSCS
g. Software RAID not supported by MSCS
h. Use RAID 0+1 for ultimate performance, be fully aware of your node
configuration and number of instances you want to support as the number of
drives can grow very quickly.
i. Only one node can control a disk at any one time.
j. Remember the disk configuration is based on the SQL Server cluster model
chosen (active/active or active/passives). Be very careful with your decision
and the capacity of the disk array.
180
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
c) The comclust.exe binary must be run after MSCS has been installed, this is used to
create the clustered MS DTC resource. This should occur after one node is installed.
b. the binaries of the instance are stored on the nodes local disks
c. the MSCS cluster must be installed, resource groups allocated and NIC’s
configured before attempting the SQL Server instance install.
d. on installation
i. select virtual server instance
1. virtual server name – virtual server name, this is not technically
the name of the actual database instance. This is the virtual sql-
server name, its like a logical server name.
2. virtual server IP – enter public IP address in which the node is
available for clients to connect, there may be multiple IP’s if there
are many connecting IP networks. The subnet mask comes from
the MSCS.
3. cluster group disk for data files (assumes MSCS cluster group of
resource disks setup previously)
a. don’t use the quorum disk for data files
b. all default instance databases (system and sample
database) data and log files are installed on the drive you
select.
4. pick other nodes in the cluster in which you want to partake in the
failover of the virtual instance (by default all nodes are selected).
This is also called the cluster management screen of the installer.
5. enter login credentials for the remote nodes, this account must
have administrator access to the other nodes. It is not
uncommon to use the domain administrator account. This MSCD
service account must have login privileges to SQL Server to
perform isalive checks. If it’s the Administrator account this will
naturally occur with the BUILTIN\Administrators domain group
login installed with SQL Server.
6. enter the database instance name, use a named instance rather
than the default to ease maintenance.
7. select destination path for the sql-server instance binaries.
8. enter the domain user name in which the database instance will
run. Using a local domain user can be a problem to administer
and its highly recommended using the domain administrator
account or equivalent.
The DBA should keep the Administrator and the SQL Server
service account separate where possible. The DBA should
181
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
consider using the same service account for SQL Sever and
SQL*Agent services. It should be a valid domain account.
9. select SA account authentication mode
10. select licensing mode
ii. use the VIRTUAL_SERVER\Instance-name string to connect to a clustered
instance
I cannot stress that it is important to understand that the virtual SQL Server, which maps 1:1 to a
single database instance, can not share disks with any other node, this is completely different to
the Oracle clustering model.
The active/active model allows the DBA to utilise the Node2 server with another SQL Server
virtual server and associated database. Therefore, both servers are actually working for us
and failing over to one another on failure. In this particular model, for example, I can run
DatabaseInstanceA on Node1 as my OLTP database, and on Node2 run my DSS/Reporting
DatabaseInstanceB simultaneously. Of course, if either server fails I will have a DSS and a
OLTP database on the same box, competing for CPU and memory resources which we need to
consider when purchasing the hardware solution.
NOTE – Always set the specific memory maximum the SQL Server database instance can
use. Also note that active/active and active/passive are functions of SQL Server clustering and
not the clustering service itself.
The SQL Server 2000 DBMS is a cluster aware application, in that it utilises the underlying
MSCS API. As such, it uses the heartbeat NIC to communicate between nodes to detect node
and sql-server instance failure (it cant detect a single database failure in the instance and
result in a fail over). The SQL Server instance “ping” (is-alive check) is a select
@@servername query. On five failures the instance is declared dead and a failover occurs.
This involves starting the next named instance that’s part of the virtual sql-server.
NOTE – If you need to alter the service account logins for SQL Server, use Enterprise
Manager rather than editing the NT services directly.
Going back to disk configuration, the quorum disk is critical to MSCS. DON’T use your quorum disk
for database backups/restores. The MS DTC is usually configured on this resource (500Mb free
required). See Q294209 on Microsoft Support for more information relating to MS DTC.
As for each database instance, standard database file placement strategies kick in based on
the database being installed and its IO characteristics. In general, this tends to mean:
a) separate disk for tempdb (if deemed an issue)
b) separate disk for database transaction log files
c) separate disk for database data files
a. this may extend one step further if we use different file-groups, i.e. DATA and
INDEX groups which may be place again on their own sub-set of disks.
Always remember that we are talking about an instance, not a single database.
To finish this section off before we get too carried away, some final notes:
a) SQL*Mail is not clusterable as the MAPI protocol is not clusterable
182
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Essentially, NLBS assigns a single IP address amongst the servers in your server farm, the set-up
of which is done via the network properties screen of each server partaking in the farm and
selecting the network load balancing properties. This does require a good understanding of IP
networking and I highly recommend getting your network administrator involved early in the
planning stage.
It is very important to understand that “routing requests based on SSL session IDs or cookies,
aren’t possible. This takes NLBS out of the running completely if your Web site uses sessions”
(35). Even so, the DBA needs to consider the client affinity settings for preserving client state
and test accordingly. The affinity settings are:
1. none – many requests from a client can go to any node in the NLB cluster
2. single - many requests from a client return back to the same node
3. class c – multiple requests from the same TCPIP class-c address range will use the
same node in the NLB cluster.
The incoming requests are balanced in terms of the percentage of requests they receive and of
course overall server availability.
183
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
In this scenario, (see CLB later), we may be running our business layer (typically COM+
components) on each individual web-server in the NLB server cluster, communicating directly to
the database cluster. After talking to a few DBA’s regarding the use of NLBS at the database
server, they have, apparently, used these scenario(s) below to achieve fail over:
100% load
184
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
I am not convinced of this option and it will require a fair amount of thought before running
with the architecture.
This model can be taken another step further with a separate COM+ routing cluster, this is not
discussed and is not recommend for web-based applications. Microsoft has some excellent
documentation related to NLB and CLB clusters, which can be found in the references.
185
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
We have concentrated primarily on SQL Server, but to bring clustering in context with a complete
highly available and scalable solution we have also discussed (albeit briefly) CLBS and NLBS. The
following diagrams show a complete solution utilising Microsoft technology that the SQL Server DBA
should be familiar with.
SAN or SCSI/Fibre
connected Disk Array
186
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Federated Databases
I personally do not regard database federation as a form of high availability, but it is pushed by
Microsoft as a key technology to enhance performance. The architecture for federation can vary
significantly between installations. An example is shown below.
Client
COM+ COM+
MyDB MyDB
DPV DPV
Table data is horizontally partitioned amongst the member databases which reside on two or more
physical database servers. Linked servers (database links) are created between each database
server instance and distributed partitioned views (DPV) are created on each member database, for
example:
187
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
With such simple views, they are naturally updateable and support all forms of DML. There are
ranges of conditions imposed on the view and the underlying table that are described in the books
online within SQL Server.
At the table level with each member database we apply check constraint conditions to ensure the
partitioning occurs correctly in terms of data integrity.
The key to the entire architecture is the business object layer, namely the COM+ routines.
The business layer must be “federated aware”. This can be done in a variety of ways:
a) Stored Procedures – if the COM+ routines utilise stored procedures for all DML, the
procedures can encapsulate the necessary logic to distribute data over member
databases.
b) COM+ routing – call a custom built routing component that has the necessary smarts to
communicate to the appropriate member database.
The trick here is the connection string used by the COM+ routines.
It can be very difficult to move an existing application to a federated model but it is not impossible.
If the application has been architected well (yes – that would be another ebook), and data access is
typically via stored procedures, then utilising distributed partitioned views within the procedures
should be completely seamless to the application.
188
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Log Shipping
Conceptually, log shipping in SQL Server and Oracle are the same. The process in SQL Server
works at a database level, not at a global instance level as you will see later. The aim here is the
create a warm standby server in which one or more databases are permanently in recovery mode.
The source database ships transaction log backup files to the destination server and we restore
(with no recovery option) the logs sequentially (in order). If there is a failure on the source server
we attempt to recover the last of the transaction logs, ship it to the destination server and complete
the database recovery. Once done, we send client connects to the new server and they continue to
work with little or no data loss.
Windows Domain
Server A Server B
(primary) (standby)
DatabaseA DatabaseA
Client
Connections
Backup Restore
Transaction Log with
Log to network norecovery on
share destination
server
NOTE - we have not diagrammed the full database backups that must also be log-shipped to
start the process.
The DBA can use a custom written script or the SQL Server Wizard to do the shipping. The
shipping in most cases will be to a server on the same Windows 2k network domain, but there is no
reason why VPN tunnels over large distances or other remote scenarios are not utilised.
189
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The supplied wizard provides all necessary steps to setup log shipping for selected databases.
Before doing so remember the following:
ensure instance names are the same on source and destination servers
pre-setup the transaction log backup directory via a network UNC path (referred to by both
source and destination DTS jobs)
create DTS packages on both servers and use the transfer logins job to facilitate the
transferring of login information between shipped servers.
Must run the wizard via a login that has sysadmin system privileges
Once the log shipping DTS (maintenance plan) has been created, go to the Management Folder in
EM and select properties of the log-shipping job to alter the process in place.
See reference (56) for a documented “How-To” for log shipping in a SQL Server 2k environment
using the Wizard.
190
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
This example revolves around a single server with two named instances:
i. Setup disk locations from primary to destination server and test with SQL Server service
account.
ii. Pre-determine what account will be used for doing the backups, establishing the linked
server and restoring backups on the primary and standby databases. I recommend that
you create a new account with sysadmin rights on both servers to facilitate this.
191
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
* If you are using EM, and have registered the server under an account no mapped in the linked server, then
the linked server will no work for you. Check your EM registration before attempting to view tables/view under
the linked server within EM.
This is completely optional and really depends on the backup model you are using. SQL
Server allows you to pre-create backup devices, once created, we can use the logical
name for the backup device (which maps to a physical file) rather than the using the
physical path and filename for the backup. This makes scripting much nicer and easier to
read/change.
Here we create two devices, one for full backups and the other for logs. See
management folder in EM and the backup item to create these.
v. Check primary server database recovery model. Select properties of the database via
EM. Ensure the model is in line with the backups you will be log-shipping.
192
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
vi. Write two stored procedures that will reside in the master database on the standby
server for recovery of the FULL and LOG backups. The standby restore option is what
tells SQL Server that the database is in warm standby mode.
vii. Write two DTS packages on the primary server, one to do a full backup and the other a
log backups.
193
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
viii. Test Full then Log DTS routines and debug as required
x. Monitor
-- Login to primary server (depends on failure), and attempt to backup last database log file
-- Ensure client connections are connection to the now live “standby” server.
194
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
a) The full and log backups are being appended to the same file, consider writing better
backup routine on the primary server than produces separate files for each backup with
a date/time stamp. Do this is a T-SQL stored procedure on the primary database and
consider replacing the DTS copy command with a call to xp_cmdshell within the stored
procedure.
b) If using a), parameterise the two recovery procedures on the standby server to accept
the file path/filename of the file to be recovered. The routine in a) will have all this
information and can pass it to the standby server without any problems.
e) Will the standby ever become the primary and effectively swap serve roles?
195
8
Chapter
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
W
ith the advent of Oracle 9i, the NLS (national language support) services has been
extended significantly and has been rebadged as Oracle Globalisation Support.
Previous NLS implementations could only support one national language and
character set per database, the architecture can now support many locales
(languages, character sets, sort orders etc) loaded at runtime. This effectively means that
single database instance implemented correctly can support error messages, sort orders,
date/time, monetary, numeric and calendar conventions of any native language and locale,
creating a truly “global” database.
This chapter provides a quick overview of Globalisation Support with Oracle and expands this
to encompass the equivalent SQL Server options.
NOTE – Oracle refers to locale as the “national language and the region in which the
language is spoken” (11). This consists of language (national language of the user) and territory
(region in which the language is spoken). We do not cover timezone specifics in Oracle.
196
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Oracle Architecture
Create database
statement we define..
character set – used to Multilingual Oracle Database
store data (OS (Unicode all or select columns)* Locale specific server behaviour
NLS Are via DB init parameters (NLS_)
dependent default
value or defined),
national character set NLS Runtime
(to manage nchar, Library (NLSRTL) Client environment variables (NLS_)
nclob, nvarchar2 etc)
* Unicode is required for ”true” globalisation and rendering of a content to many languages rather than a select few.
The DBA can check NLS parameters via the following dictionary objects:
NLS_SESSION_PARAMETER
NLS_INSTANCE_PARAMETER
NLS_DATABASE_PARAMETER
V$NLS_VALID_VALUES
SYS.PROPS$
In order for an Oracle database to be “global” (multi-lingual applications rendering content in the
countries native language), the database is created to encode stored data as Unicode (unique
character for any character regardless of platform/OS/language etc). The Oracle database is
encoded with a Unicode v3.1 UTF-8 compatible character set such as on its creation:
197
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
If the DBA does not want to encode the entire database with the Unicode character set (for
whatever reason), the table column data type NCHAR (or NVARCHAR2) can be used to store
exclusively Unicode characters. As shown in the architecture diagram, the client and server
can alter NLS_ parameters accordingly to utilise different cultural settings shared over a single
database and rendered appropriately.
Binary – sort sequence based on numeric value of characters defined by the encoding
scheme.
Linguistic – each character has a numeric value representing the characters position in
proper linguistic order, the kinds of include:
monolingual (eg. generic_m, thai_m, japanese_m)
multilingual (eg. Arabic, latin, ASCII7)
NOTE - There are significant differences between earlier versions of SQL Server Collation and
Sort Order. This chapter will not cover them but the DBA should be fully aware that it might
not be a straightforward task moving to SS2k.
First of all, SQL Server uses the term Collation rather than the “Globalisation Support” or
“National Language Support” (NLS). Even so, the related concepts are similar in meaning to
that of Oracle’s in most respects as all are based on ISO standards.
Collation is the rules governing the proper use of characters for a language or character set. This
includes the following three properties
198
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The sort order under SS2k is identical for both uni-code and non-unicode string data, the DBA can
not specify different sort orders (unlike previous SQL Server versions) for such string data. The
sort order defines rules for the interpretation, comparison and presentation of string data, this
includes case, accent, kana sensitivity or simple binary order.
NOTE – Unicode can be encoded as UCS-2, UTF-8 or UTF-16 (and others). UCS-2 is used by
NT v4.0 , SQL Server v7 and 2000, UTF-16 is used by Windows 2k. SQL Server 2k uses the
Unicode 2.0 standard.
Altering the collation of a database does not automatically rebuild existing string data to the new
collation (and possibly code-page), therefore, the DBA must BCP (or use DTS for import/export) out
the data and reimport to take up the new collation (remember - the DBA may need to alter the
collation for all table string columns individually).
Before we drill too deeply into SQL Server Collation, let us diagram the architecture. The
architecture is closely associated with the underlying operating system (known as Windows Locale)
as shown below:
199
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Server / PC
User DB (collation)
MODEL DB collation used if
not specified for user
TABLE databases on creation.
String-Column (collation)
SS2k
Server Defines the interpretation of
Network character data, keyboard
Utility locale, date/time, numeric,
(listener) currency etc..
Data access method defines
the rules for text
manipulation. SQLOLEDB
for example data is
converted to Unicode using Client
Internationally
the collation of the actual WINDOWS
aware app
data. LOCALE
• Collation & sort order on installation of the instance affects all system databases. The
model database collation is used for all users databases that don’t explicitly use a
collation on its creation, this can be altered if need be.
• Temporary objects created in TEMPDB will use this system databases collation. The
database is re-created on start-up from the model database, therefore, to alter simply
change the collation on the model database and re-start the SQL Server instance.
• The DBA cannot alter sort order after the installation of the SQL Server instance.
• SQL Server can support only code pages that are supported by the underlying
operating system.
• Multiple collations can use the same code page for non-Unicode data
200
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
• Code page is a character encoding system used when storing string data (char,
varchar, text) for different alphabets (non-unicode), it defines the bit-pattern for each
character.
• Client uses the code pages associated with the OS locale to interpret the character bit
stream from the database. An international aware application may include further
resource files to provide a truly international application without recoding.
• International system should utilise Unicode data to ensure all computers perform the
correct translation when interfacing to the OS code page.
A SQL Server collation is associated with one and only one code-page (which defines string data’s
physical storage), for each code page, one or more Windows Locates (identified by the LCID or
locale ID) are associated with it, and therefore, supports the code page translation. For example:
IMPORTANT - SQL Server can support only code pages that are supported by the
underlying operating system. SQL Server will give an error if there are compatibility issues.
The “Collation Name” is specified via a unique string, this is representative (to some degree)
to language and the sort-order and sometimes the code page for the language that forms the
colation, for example:
Just to be totally confusing, don’t rely on these coding to accurately reflect the actual collation. To
get a list of valid collations:
SELECT *
FROM ::fn_helpcollations()
201
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Example:
SQL_Scandinavian_CP850_CS_AS
Finnish-Swedish,
case-sensitive,
accent-sensitive,
kanatype-insensitive,
width-insensitive for Unicode Data,
SQL Server Sort Order 59 on Code Page 850 for non-Unicode Data
When we say “SQL Server Collation”, we mean all collations valid within SQL Server. Note that SQL
Server does present us with two key language designators, they being SQL and Windows, where
the SQL designators are provided for backward compatibility to previous SQL Server versions.
Some example SQL-specific code pages (also known as sort order) are:
SQL_Latin1_GeneralCP850
SQL_Ukrainian_SP1251
SQL_Polish_CP1250
All unicode strings utilise the SQL-92 standard N'' literal prefix, for example:
The instance collation will affect the language for all system databases, including the model
database. As new user databases are created they will, by default, get the model databases
collation. To alter the instance collation you need to use rebuildm.exe on the installation CD.
This is not a simplistic task, read the books online carefully and review the chapter on backup
and recovery.
202
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Collation – Database
Specifying the collation when creating a new database in EM is very simply and will not be
covered. To specify the collation at a SQL statement level:
The default database collation is sourced from the model database. All table columns (string
data only of course) will take on by default the databases collation setting.
This will not magically alter and port all subsequent column collation data to the new database
value.
Do not rely on selecting properties of the database via EM and get the databases collation.
Typically, the collation is shown under the maintenance section of the property dialog. In the
example below it is blank where we have used veitnamise over the Windows default for our
installation, that being latin general (latin1_general_ci_as).
The routine:
select DATABASEPROPERTYEX( 'mydb , 'Collation' ) -- returns NULL
This may be a bug under XP? Use the following command instead:
exec sp_helpdb
203
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
materialised views
check constraints
computed columns
-- Check constraint
Server: Msg 5075, Level 16, State 1, Line 1
The object 'CK_emp_id' is dependent on database collation.
The collation value for the column within EM is shown as a property of the column. The following
dialog is shown when altering the column. Remember that the databases collation is used by
default.
The DBA can alter the collation via SQL as the examples show below:
204
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
) ON [PRIMARY]
GO
Multi-lingual columns are not supported. The database collation is used if the column collation
is not specified.
205
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
a) Language
a. Printing documentation
b. Grammar
c. String data in UI (menu’s, dialogs, other GUI controls)
b) Locale Specifics
a. Date/time format
b. Numeric
c. Currency
d. Sort order / string comparison
The application architecture needs to divide UI (user interface) away from the application
components (code block or business logic) in order to produce a localised product that is
internationally aware.
The resource file (*.res, *.rc or *.resx) is the key for the UI, a separate resource file exists for all
supported languages and assists in localising the installation for the client in terms on string data
interpretation, bitmaps, icons and its link to the clients OS locale.
Any further discussion on this topic is out of scope , suffice to say that initial design is everything
and some first hand experience is required on the team to ensure a successful design an
subsequent implementation.
206
9
Chapter
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
OLAP
F
rom SQL Server v7, Microsoft bundled OLAP Services with its DBMS and was their first
(and reasonably good) attempt at a move into the OLAP market space. In SQL Server
2000 the product has been renamed to Analysis Services and provides a range of
enhancements that no-doubt pleased the OLAP gurus amongst us. In this chapter we
will cover some of the basics to get the DBA up to speed with its administration. I say basics,
as I am far from being an expert in this field, which I truly believe is a distinct skill in its own
right, therefore, I do very little comparison to Oracle and only skim the surface of the Microsoft
products capabilities. Do not let this put you off though as we cover a range of great tips and
tricks.
Terminology
It is assumed that the reader has some previous Oracle experience with OLAP. To be honest, I
have had little involvement with OLAP technologies under Oracle so will rely on you to draw the
necessary comparisons between the two companies implementations.
Terminology Summary
OLAP Online Analytical Processing
Microsoft have separated its OLAP technology away from the DBMS and
wrappered it into what they call Analysis Services (or OLAP Services in
v7 of the DBMS). The product includes
Star Schema Microsoft utilises a star schema for their cubes. A cube in such a
schema is based on a single fact table (or view) and 1 or more reference
data (dimension) tables connected to it.
Virtual Cube Is a view or 1 or more cubes. Basically we can build a variety of
physical cubes, and from there, create virtual cubes were we their fact
table and associated shared dimensions can work together for form a
single virtual cube. To the end-user there is no difference to standard
cubes.
Dimension Organised hierarchy of categories or levels that links to data within the
fact table of the cube. The dimension hierarchy (i.e. tree) is divided into
levels and each data element of the dimension is called a member.
Analysis services support regular, unbalanced and ragged dimension
hierarchies.
MDX Multiple dimension expression.
Calculated member Calculated field within a cube that is not physically part (calculated at
runtime) of the underlying tables/views feeding the cube. They are
written via MDX statements.
207
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Cell level security A cell is the smallest element of a cube, typically being the unique
element in which all dimensions (where applicable) intersect.
Administration
Installation
The installation options are very basic, we are simply asked:
a) what options we would like to install
a. note that Analysis Manager requires decision support objects (dso) and client
components.
b) where our OLAP data directory (cubes and their meta-data bases) are to be stored
(single directory location).
On completion, analysis services are installed with the SQL Server group as shown below. The
MDX (multi-dimensional expression) example VB application is a good place to trial MDX queries
used in OLAP, which you will soon find out are very different from standard SQL.
Always reboot after the installation, you may get some strange errors and it’s not worth the trouble
dealing with them.
The directory structure is as follows, the OLAP repository is, by default, a series of Microsoft
Access databases the core files being msmdrep.mdb and msmdqlog.mdb. The DBA should
ensure that these files and associated cube directories are regularly backed up.
In order to administer the OLAP repository and its cubes, you must be part of the olap
administrators NT group that is installed with Analysis Services. Of course, if the server is not
208
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
part of your typical login domain then you need to create a trust and ask the server
administrators to add your login to this group. Once this is done you can connect and
administer the cubes from your PC.
NOTE - Analysis Services does not have the same concept of multiple named instances,
therefore, multiple analysis servers running on the same box. Within a single analysis server
(single service) we run one or more OLAP databases.
NOTE - Reinstalling analysis services will not destroy or reconfigure your repository although
you must re-process all cubes in the repository. You may loose your sample OLAP database
(foodmart) on re-installation.
To allow Analysis Services to use over 3Gb (assuming the typical /3GB and other settings have
been set in the boot.ini), edit the HighMemoryLimit registry string under KEY Local
Machine\Software\Microsoft\Olap Server\Current Version and specify its decimal value
accordingly. Once done, from within the Analysis Services GUI, select properties for the server
and you can alter the minimum allocated memory settings.
Look through the properties of the server carefully. From here, you can administer the OLAP logs,
active directory registration, cube processing configuration and other general properties.
209
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The first key change is adding your windows networking domain login name to the olap
administrator domain group on the server in which we installed analysis services. The network
administrator may need to create a 1-way read-only trust to your server if its not a member server
of the domain you are logging into and/or is running in a different windows domain.
Once done, we need to repeat a similar operation with the MsOLAPRepository$ share that is
automatically created on the bin directory holding the Analysis Services binaries. This is very
important as you will get a variety of errors when attempting to edit and process cube data
structures. By default though, the OLAP Administrators group has permissions to the share so
changes directly to the share are rare.
NOTE – Clients using MDX via OLE-DB (includes Excel Pivot control, Office 2k web
components, ADOMD, etc) do not require access to the MSOLAPRepository$ share.
210
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The registry entries for OLAP include the remote access properties to manage your cubes, such
as:
There is apparently a bug (Microsoft support doc# Q293782) regarding the administration of
the cubes. Even with access to the OLAP Administrators group and the share, you may still
have problems and will require Administrator group access. I have not come across this
particular problem. Remember that cross domain access will require a trust between the
domains.
211
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
In the GUI dialog shown, it tends to “highly recommend” a straight migration to a SQL Server
database rather than utilising SQL Server’s meta-data services. The two types of migration are
essentially the same in terms of database objects that are created, they being the tables server
and olapobjects. The meta-data repository install option defaults to the MSDB database, which of
course you can change.
Personally, I am quite impressed with the SQL Server meta-data repository as it adds another
reporting element to the repository. The model utilises the XML nature of the olapobjects table.
Within EM we see something like the following (right click virtually anywhere in the tree and select
browse options to get a custom view of the many properties):
212
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
If, after migrating you have connection problems to the database and have altered SQL Server
login privileges accordingly, then go to the registry (regedit.exe) to fix the connectivity properties:
If, after you migrate the repository you can no longer administer the cubes from your PC, even
though you are part of the OLAP administrators NT group; then create a SQL Server login for each
user (or create a NT group at map the SQL Server login to it instead; whatever is easier) using
Windows Authentication, and allocate the database privilege db_owner to the user in the
OLAPRepository database you created. I believe db_writer and db_reader are also suitable if you
are not keen on allocating db_owner.
NOTE – Once you migrate away from the Access databases, there is no going back unless
you re-install.
OLAP Databases
You can only have one installed Analysis Server installed at any one time. Running inside of this we
have zero or more OLAP databases. When created, the databases are logical entities stored within
the OLAP repository (i.e. meta-data framework). For each database we define one or more data
sources (virtually any OLE-DB compatible source or ODBC link) in which we source data from for
cubes and/or dimensions.
213
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
OLAP Connectivity
Connectivity to analysis services varies, but is typically via is OLAP data provider or
In order for a client to task to analysis services, the MSSQLServerOLAPService must be running on
the server, this serves as the listener for the OLAP server. Connectivity is via the MSOLAPXX.dll
OLEDB provider from the client, as a connection string, this corresponds to the OLEDB provider
“Provider=msolap;”.
NOTE – Using the OLAP provider installed with SQL Server v7 OLAP services will not work
against Analysis Services cubes. This is especially evident when using Microsoft Excel and its
pivot control (Office 2000 web component), where virtual cubes (discussed later) are not
shown.
Search for msolap.dll to get versioning information. Be aware that in Excel, to connection to an
Analysis Servcies cube (SQL Server 2000 OLAP or OLAP v2.0), you need to use:
Security
We will not be going into any depth with programming OLAP, but even so, its worth spending a
little time exploring cell level security.
214
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
As with most things Microsoft, the fundamental security framework revolves around the Windows
Domain, its users and their NTFS and Domain (group-policy) privileges to determine what the
network user can and can not do. This flows into OLAP which only supports Windows
Authentication (can be very unfortunate for some installations). For the well-established Windows
Network, this allows seamless single-sign on to not only your databases (depending on the
application of course) but also to your OLAP cubes.
As a basic element of security, access to cubes and virtual cubes is via roles within OLAP. The role
can have any number of NT users or NT groups associated with it. On top of this, when allocated to
a cube, we can control a variety of security properties to further restrict the group’s users.
We manage cubes roles via the Cube Role Manager dialog that pops up when selecting role
properties for the cube. Note that you will get a different set of options if you select roles at the
cube level vs the entire analysis services database level.
IMPORTANT - remember that analysis services is a huge jump from OLAP Services released
with SQL Server v7, and as such, many of the options simply don’t exist or are only accessible
via ADO-MD API calls using VB or C++.
Security at the role level is very straight forward, but their comes a time where people will be
asking you to secure your cube at the cell level. A classic example that we will use is the
organisational chart, where we want staff members to only view their portion of data related to a
specific division/branch/section combination that the user selects from the cubes “organisational-
chart” dimension.
The user can select a specific Division, Branch or Section to get their current financial position
in terms of budget and expenditure. It is critical to the business that people can only view
data based on their position within the organisation, therefore, the CEO can see all divisions,
the General Managers can see all data related to their specific Division, Directors are restricted
at the Branch level and Managers at the section level.
In our SQL Server data warehouse, we have linked over to the HR system and extracted the
current organisation chart to populate the org-chart dimension for the cube, and have also
extracted out information related to all staff members and their position within the chart. These
215
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
have been mapped (magically) to their Windows NT logins for single sign-on to the OLAP cubes.
So, with all that done, we know exactly what data “User A” can view in the cube and what they
cannot.
Within the analysis services, we select the cube of concern and edit their roles we have allocated to
the cube. The roles are actually programmically created (shown later), and have a poor naming
convention, but you get the idea:
In this case, role EISHROrg_012 has been created with one member. This has allowed to user to
access the entire cube and all its data. Clicking on the lock, we can drill into cell security to further
restrict the users access to the cubes underlying data.
IIF ((
ancestor([HR Complete Org Chart].CurrentMember,
[Org Chart Division Name]).Name = "DivisionA")
AND (
ancestor([HR Complete Org Chart].CurrentMember,
[Org Chart Branch Name]).Name = "BranchB"
), 1, 0)
216
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Read/Write: Unrestricted
where [HR Complete Org Chart] is the dimension name, and [Org Chart Division Name] and
[Org Chart Branch Name] two of the three levels within the dimension that the user can filter
on to view cube data.
In this case, we are saying that if the user wants to read the data in BranchB which is part of
DivisionA, then they must be a member of this role, otherwise a value of 0 (false) is returned
and access is denied (no data shown to user).
IMPORTANT – Before testing the security for yourself, remove your NT login from the olap
administrators NT group, if you don’t the cell security will seem as though its not working for
you when it actually is.
In this particular example, we have generated the roles and applied the security strings to the
cubes via a chunk of VB code. The class has been implemented as a COM (dll) and it is called
via a scheduled DTS.
To programmatically manipulate Analysis Services, the programmer needs to utilise the DSO
(decision support library) of COM objects. With these and ADO-MD, you can basically re-create the
Analysis Service Manager GUI if you like, just as using SQL-DMO you can rebuild Enterprise
Manager for SQL Server.
From the example for cell-security, we utilise DSO code (the DSO objects are installed on
installation of Analysis Services) within a small VB COM to remove existing roles, then re-create
them from information stored in our data warehouse. The code below as been simplified to show
the essential DSO commands used:
varServer = "151.122.12.1"
varOLAPDatabase = "MyOLAPDB”
217
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
dsoDatabase.Roles.AddNew (sRole)
End If
dsoCubeRole.SetPermissions "CellRead", _
"IIF ((ancestor([HR Complete Org Chart].CurrentMember, [Org Chart Division
Name]).Name = "DivisionA") AND (ancestor([HR Complete Org
Chart].CurrentMember, [Org Chart Branch Name]).Name = " & Chr$(34) & "
BranchB" & Chr$(34) & "), 1, 0)"
dsoCube.Update
End If
dsoServer.CloseServer
http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/ado270/htm/ammscadoapireference.asp
http://msdn.microsoft.com/library/en-us/olapdmpr/prabout_84a4.asp
218
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Backup
To backup Analysis Services, the DBA must:
b) Backup the repository data files, even if you migrate the repository to SQL Server you
should backup the bin directory to ensure maximum recoverability. This includes the
msmdrep.mdb database (unless you have migrated the repository to SQL Server).
If you select a ROLAP storage model for your OLAP cubes, this can complicate your backup as the
aggregations will be stored in the data-source in which your cube is utilising to source its fact data.
This is not a major concern as the cubes storage structure can be rebuilt, but this may be
problematic with very large cubes.
Within Analysis Service manager you can export your cube database, this is the primary method for
backup that is probably the most reliable. This will export the aggregations, security privileges, not
the actual processed cubes with their data. On restoring the OLAP database you will need to do a
complete re-process of the OLAP database (repository).
Look at the command line executable msmdarch.exe to archive a specific database into a single
.cab file. The DBA should extend this backup to include the items discussed above.
219
10
Chapter
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
U
nder UNIX, the Oracle DBA writes numerous scripts for managing database backups,
instance re-starts, statistic collections, space management, the list goes on. These are
Typically scheduled tasks via cron (AT in Windows) and are written in a variety of
languages, including Unix scripting (whatever shell the DBA prefers), C, Perl etc. In
the SQL Server environment, the DBA has a range of methods to use that typically benefit the DBA
with a good knowledge of VB-Script and VB programming, these methods include:
a) Creating and scheduling DTS packages (run via SQL*Agent) that call T-SQL stored
procedures, VB-Script and any other COM or defined task they like to call.
b) Custom written COM, COM+ or standard executables routines that utilise SQL-DMO,
called via a scheduled VB-Script file scheduled via at from the command line or within a
DTS.
c) Simple VB-Script (.vbs files) scheduled via at from the command line.
d) Consider Perl and other scripting languages, so long as they communicate via OLE-DB,
ADO, ODBC etc.
e) For those “ill die without my grep” Unix phreaks, seriously consider downloading a unix-
toolkit for DOS (NT), there are some excellent ports and offer all the functionality
required to re-produce some great scripts under Windows. Lets face it, you cant beat
Unix for scripting.
As I am not a VB programmer by any means, I tend to use DTS packages calling T-SQL stored
procedures that I store in the master database. I then schedule them and SQL*Agent does the
rest. To enhance them, I may opt for some simple vb-script or callouts to existing DLL classes.
This is very simple to implement and with SQL*Agent it allows me to utilise its inbuilt notification
service on failure and to historically track its progress.
Some find that T-SQL procedures lack the features they require for more complex tasks. In this
case, I would recommend writing COM classes that utilise the SQL-DMO API calls to interact with
SQL Server. A range of examples are shown throughout this chapter.
NOTE – Consider 3rd party scheduling software if you are not utilising SQL*Agent and
associated jobs, as the OS scheduler’s smallest granularity for running jobs is daily.
220
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
T-SQL Routines
With the power of the sysadmin server privilege (system or sys account in Oracle), the DBA
can code some powerful T-SQL routines to assist with ongoing administrative tasks. Some of
the key commands of interest:
a) master..xp_cmdshell (to call out to an OS command)
b) master..sp_OA* procedures - call external COM and COM+ components
c) using temporary tables (table datatype and the create table #mytab statements)
d) using dynamic SQL (sp_executesql and exec())
e) using SQL*Agent and Jobs
XP_CMDSHELL Example
Here are a couple of simple examples of using xp_cmdshell to perform file OS file manipulation and
get a directory listing into a database table:
-- Get File list from directory for further processing (like unzipping them)
DTS
To call your DTS package you can:
b) review the command sp_start_job to force the running of a scheduled DTS package
d) see the “execute package task” within the DTS package designer for cross calling of
between separate DTS packages (is version dependent on each save of the package, so be
warned).
Remember that scheduled jobs are managed by SQL*Agent which utilities the MSDB database as
its repository.
There can be issues with a packaged jobs not running when scheduled. Some of the areas to try:
a) the user in which the SQL*Agent service is running has insufficient database access
221
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
b) calling xp_cmdshell? And the user is not part of the sysadmin role? If so, if you fail to get
up the proxy account the step will fail. This “may” have flow on effects resulting in this
error.
c) Try forcing the first schedule to run, and see if SQL Server will correctly set the data/time
for the next scheduled run
ISQL / OSQL
The DBA can utilise the command line equivalents to query analyser (SQL*Plus GUI) to run scripts
and pipe the results to a standard ASCII file. An example is shown below:
cd g:\scripts
osql -S SECA\MYINSTANCE -Usa -Pking /Q "EXIT(dbcc checkalloc('mydb1'))" -og:\scripts\mydb1_dbcc.txt
osql -S SECA\MYINSTANCE -Usa -Pking /Q "EXIT(dbcc checkalloc('mydb2'))" -og:\scripts\mydb2_dbcc.txt
osql -S SECA\MYINSTANCE -Usa -Pking /Q "EXIT(dbcc checkcatalog('master'))" -og:\scripts\master_catalog.txt
osql -S SECA\MYINSTANCE -Usa -Pking /Q "EXIT(dbcc checkcatalog('msdb'))" -og:\scripts\msdb_catalog.txt
Here we run a variety of DBCC commands and pipe the results to associated text files. Utilising
the sa account is not recommended in such a way and where possible, always opt for Windows
authentication for sysadmin access. From here, we can do a variety of things, such as using
Perl to extract and massage data from the file and produce appropriate reports, do a call to
some visual basic script or call an emailer to send the results directly to the DBA. In the
example below, we are utilising a command line emailer called smtpsend.exe to email the file
direct to the DBA:
cd g:\scripts
smtpsend.exe -fMyDBServer -tckempster@amcon.com.au -h163.232.x.xxx -s"PROD DB LOGSPACE STATS" -
ag:\scripts\dblogspace.txt
VB Script
With a VBS file (*.vbs) or VB Script within a DTS, the DBA can utilise many of the classic VB
commands, the key one being the file system objects library for OS file manipulation. I will leave it
up to the internet to give you a large range of examples, even so, here are some handy commands
to start you going.
NOTE – Variable declarations in VBScript are not explicitly typed (i.e. integer, float etc).
’ This is a comment, below is a CONSTANT
Const SUCCESS = 0
’ declare variables
Dim WshShell
Dim FSO
Dim oMsg
Dim lSMTPServer
222
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
‘ Moving a file
The .vbs file can be called directly via AT. If you have issues with running it then try using the
wscript or script commands, for example:
VB / COM Example
The example below is not really related to a specific SQL Server problem, but gives you an idea of
the possibilities. We have written a small DLL that copies a series of files from one destination to
another with a date-stamp, and is called via a small VBS that we schedule via AT.
The key item here is that the experienced VB or C++ developer in the Microsoft realm can basically
do anything they like in terms of “scripted” programming. Most will argue that this is going a little
to far but offers a lot of functionality. Personally, the DBA will find that they can resolve most
problems elegantly with T-SQL routines / DTS package scheduled via SQL*Agent.
-- INI File
[database_backup]
database_location="C:\database\MyDB.mdb"
destination_folder="C:\database\backup\"
223
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Option Explicit
Implements COMSVCSLib.ObjectControl
FUNCTION_RETURN:
'Vote on transaction.
If lngError = 0 Then
If Not GetObjectContext Is Nothing Then Call GetObjectContext.SetComplete
Else
If Not GetObjectContext Is Nothing Then Call GetObjectContext.SetAbort
End If
BackupDatabase = lngError
Exit Function
ERR_HANDLER:
224
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
lngError = Err.Number
'Call off to a custom emailer or log to NT event log or text file…
-- Call SendEmail("Database backup failed.", Err.Description)
GoTo FUNCTION_RETURN
End Function
'********************************************************************
' COM PLUS METHODS
'********************************************************************
Private Function ObjectControl_CanBePooled() As Boolean
ObjectControl_CanBePooled = False
End Function
Private Sub ObjectControl_Activate()
'
End Sub
Private Sub ObjectControl_Deactivate()
'
End Sub
225
11
Chapter
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Managing Databases
T
hroughout this chapter we discuss a wide variety of topics related to everyday
database management. Where appropriate we will draw comparisons with Oracle but
will not discuss in depth the differences, preferring to focus on practical SQL Server
examples.
In SQL Server the DBA utilises one or more of the database consistency checking (DBCC)
routines, some of the commonly used ones are:
a) DBCC CHECKALLOC -- check disk space integrity for a database
b) DBCC CHECKCATALOG -- check consistency of system tables in a database
c) DBCC CHECKCONSTRAINTS -- check constraint integrity
d) DBCC CHECKTABLE -- check table page integrity
e) DBCC CHECKDB – check allocation and structural integrity
f) DBCC DBREINDEX -- rebuild table indexes
g) DBCC INDEXDEFRAG -- defragment clustered and heaps indexes for a table
h) DBCC OPENTRAN -- oldest open transaction dump
i) DBCC SHOWCONTIG -- get fragmentation information of a table
j) DBCC PINTABLE -- mark table as pinned in buffer cache
k) DBCC UPDATEUSAGE – update storage statistics
Other DBCC commands have been discussed throughout this e-book. See books online for
good coverage of these commands.
226
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
From within EM, we can right click the instance for global properties and view the start-up
parameters rather then searching the registry:
The management folder in EM allows the DBA to view the contents of the log files. I say files
because SQL Server will cycle through six different log files (default setting), the cycling of the files
will occur on each re-start of the SQL Server instance, or via exec sp_cycle_errorlog.
The DBA can control the number of cycled logs via a registry change, this change can be done
within Query analyser if you like or via EM by right click for properties in the SQL Server Logs
item under the Management folder.
Exec xp_instance_regwrite
N'HKEY_LOCAL_MACHINE',
N'SOFTWARE\Microsoft\MSSQLServer\MSSQLServer',
N'NumErrorlogs', REG_DWORD, 6
The DBA can view error logs within query analyser using:
227
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
exec sp_enumerrorlogs
There is no equivalent destination for user traces as defined by the user_dump_dest parameter.
The error log for SQL*Agent is best managed via EM. With SQL*Agent shutdown, select its
properties and you can control a range of log settings:
228
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The linked server supports any valid OLE-DB provider; this includes a variety of bundled providers
such as Oracle and OLE-DB and standard ODBC drivers (therefore, any source supporting ODBC
connectivity drivers). An example of Oracle vs. SQL Server db link creation:
exec sp_addlinkedserver
N'MYORACLEDB' ,
@srvproduct = N'' ,
@provider = N'mylink' ,
@datasrc = N'ZEN' ,
@provstr = N'ZEN'
NOTE – Don’t assume that creating the link without error means the link actually works.
The SQL Server link includes a host of additional properties the DBA can manipulate. One of the
key benefits is the mapping of user accounts over the database link. In Oracle, the database link is
user centric, where we identified the CONNECT TO myuserid IDENTIFIED BY mypassword
properties in which the connection is established. In SQL Server, we can map one or more
accounts over the linked server; this allows the DBA to specify the local database user accounts
that can utilise the linked server and define how this user account is mapped to the remote system
over the link. An example is shown below later.
SQL Server supports the three part convention for referencing database objects in SQL, namely
[database].[owner].[objectname]. A linked server query requires four parts to be listed and we
cant create synonyms for them either (although we can create local views that refer to the linked
objects). So the convention now changes to
[linkedserver].[remotedatabase].[owner].[objectname]. Oracle DBA’s will hate this. Even worse,
it can restrict you in SQL queries and other DML operations, for example:
select mydb.dbo.mytable.col1
from mydb.dbo.mytable -- this is OK
select mylinkedserver.mydb.dbo.mytable.col1
from mylinkedserver.mydb.dbo.mytable -- this is NOT
229
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
This presents some issues with inserts/delete/updates or complex recursive queries over the same
tables and column names where aliasing tables is not possible.
NOTE – If creating a linked server to another SQL Server instance and you are still having
connectivity problems, try: using the servers IP rather than the hostname, check remote
server listener is configured, try using the source service client network utility to configure an
alias to the remote server, ping or trace route to the server, verify providers.
From there, you can get a list of databases over the linked server by using:
You can go another step further and get a list of tables over the linked server via:
Read the BOL for further information, and like all things, test for your installation:
exec sp_serveroption 'SECA\MY2NDINSTANCE', 'lazy schema validation', 'true'
The 'lazy schema validation' option is ignored in this edition of SQL Server.
230
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
231
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
IMPORTANT - In the above example we map the SA account, don’t assume that just
because we listed the database in the linked servers creation that its only database we can
access. Since SA on the remote server as sysadmin access and access to all other databases,
we can utilise the linked server to access any remote database.
IMPORTANT – There may be issues with manipulating BLOB objects from Oracle with the
Provider. Query the Microsoft support website for the latest information when resolving these
issues.
In this example we have a SQL Server 2k SP2 database and a Oracle 8.1.5 database installed on
the same server. We are creating a database link via the standard OLE-DB Oracle provider from
the SQL instance to the Oracle database.
232
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
ZEN =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)
(HOST = seca)
(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = ZEN)
)
)
\SOFTWARE\Microsoft\MSSQLServer\Providers\MSDAORA
In order to establish the connection between the two servers, we need to enter the login
mappings via the security tab:
233
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
NOTE – You cannot profile (trace SQL via profiler) the addition of logins (linked servers or
local users) to the instance.
-- attempt to get a list of tables on remote server via the linked server
exec master..sp_tables_ex N'MYORACLEDB' , null, null, null, '''SYSTEM TABLE'''
The following options should be set for your SQL Server session to ensure SQL-92
compatibility:
SET ANSI_NULLS ON
SET CURSOR_CLOSE_ON_COMMIT ON
SET ANSI_NULL_DFLT_ON ON
SET IMPLICIT_TRANSACTIONS ON
SET ANSI_PADDING ON
SET QUOTED_IDENTIFIER ON
SET ANSI_WARNINGS ON
SET XACT_ABORT ON -- auto rollback current trans on runtime failure
The SQL Server books online covers these options very well.
234
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
An example is shown below from one linked instance to another on the same server:
SELECT aa.*
FROM
OPENROWSET('MSDASQL','DRIVER={SQL Server};
SERVER=SECA\MY3RDINSTANCE;
UID=sa;PWD=king', select * from pubs.dbo.authors) AS aa
ORDER BY a.au_lname, a.au_fname
We can specify a query, table name or view name within the OPENROWSET command. On the
source and destination instance we see the following:
-- Source instance
Execution Tree
Sort(ORDER BY:([a].[au_lname] ASC, [a].[au_fname] ASC))
|--Remote Query(SOURCE:(<UNKNOWN>), QUERY:(SELECT a."au_id" Col1013,a."au_lname"
Col1014,a."au_fname" Col1015,a."phone" Col1016,a."address" Col1017,a."city" Col1018,a."state" Col1019,a."zip"
Col1020,a."contract" Col1021 FROM "pubs"."dbo"."authors" a))
-- Remote instance
Execution Tree
Clustered Index Scan(OBJECT:([pubs].[dbo].[authors].[UPKCL_auidind] AS [a]))
When compared to a linked server connection, we see the following, it is essentionally the same
with additional schema locking on the remote server.
-- Source instance
Execution Tree
Remote Query(SOURCE:(MyLinkedServer), QUERY:(SELECT a."au_id" Col1002,a."au_lname"
Col1003,a."au_fname" Col1004,a."phone" Col1005,a."address" Col1006,a."city" Col1007,a."state" Col1008,a."zip"
Col1009,a."contract" Col1010 FROM "pubs"."dbo"."authors" a))
-- Remote instance
RPC:Starting declare @P1 int
set @P1=NULL
declare @P2 bigint
set @P2=NULL
exec sp_getschemalock @P1 output, @P2 output, N'"pubs"."dbo"."authors"'
select @P1, @P2 Microsoft SQL Server sa 3736 51
2002-06-30 20:29:09.640
235
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
set @P2=8670987119726518
exec sp_getschemalock @P1 output, @P2 output, N'"pubs"."dbo"."authors"'
select @P1, @P2
exec sp_unprepare 3
exec sp_releaseschemalock 1
We also have OPENQUERY. This takes a pre-created linked server and a SQL string (if more than 1
query it used in the query string, only the first is actually returned). An example is shown below:
SELECT AA.*
FROM OPENQUERY(LinkServer, 'SELECT * FROM pubs.dbo.authors') as AA
The first thing you will notice on tracing this command, is that no schema locking is done on the
remote server which doesn’t occur using a traditional 4-part query via the linked server.
Finally, we have OPENDATASOURCE. Do not use this command, but rather create a proper linked
server or utilise OPENROWSET. This command will execute a range of remote calls on the remote
server that will affect overall performance. As an example:
SELECT *
FROM OPENDATASOURCE(
'SQLOLEDB',
'Data Source=SECA\MY3RDINSTANCE;User ID=sa;Password=king').Pubs.dbo.authors
With this simple query, total execution time doubled verses linked servers and open row source
alternatives.
Remote Servers
The remote server option is a form of Linked Server but is SQL Server to SQL Server only and you
can only execute stored procedures over the link. In most cases, utilise linked servers rather than
remote servers.
236
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
DTS Packages
Data transformation service (DTS) is a fantastic feature of SQL Server. The books online gives a
overall description, that being “an organized collection of connections, DTS tasks, DTS
transformations, and workflow constraints assembled either with a DTS tool or programmatically
and saved to Microsoft® SQL Server™, SQL Server 2000 Meta Data Services, a structured storage
file, or a Microsoft Visual Basic® file”. We will drill into them throughout this section.
At the lowest level, a single DTS “package” is a range of record entries in the MSDB database table
sysdtspackages, the schema is shown below:
sysdtspackages
sysdtspackagelog sysdtssteplog
(the actual
package code)
sysdtscategories sysdtstasklog
(DB storage type)
NOTE – The above tables are not applicable to meta-data services packages. They are
stored in the MSDB database within the table prefixed with RTbl.
The key tool for managing (i.e. creating, deleting, updating) DTS packages is Enterprise Manager.
The GUI is not hard to understand and simply requires you to experiment with its variety of
supplied active-x controls that, via their interactive dialogs, utilise SQL-DMO and the DTS object
model to graphically present zero or more steps of programming logic. This may include any
variety of tasks (packagedata column in sysdtspackages), such as loading data from a spreadsheet
or another database, or processing a OLAP cube, calling an OS command, calling a VB COM we
previously created or running some VB-Script, the possibilities are endless.
237
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
We will discuss meta-data services later in this section, suffice to say that a majority of packages
will be local packages and if you need to generate meta-data about the running of a package, it
must be stored as a meta-data services package (it is not an actual service in NT speak).
Right click local packages and select the new package option. The designer is shown and exposes
many of the underlying DTS object model calls to the end-user through the supplied connection and
task active-x objects supplied, coupled with package properties etc. The DBA should simply
experiment with the GUI via right-clicking properties, trying the supplied active-x controls. An
example package is shown below.
A variety of tasks, one being an active-x (vb or j-script) task, command line call-out to
an OS command, OLAP cube refresh, FTP (cant FTP from the server, only too it
unfortunately), SQL Mail mailer and a variety of others.
IMPORTANT – Check the properties of all objects very carefully, especially the
transformation task as it includes items such as automatic connection closing after data
transformation.
It is not until you save a package with actual package content will the packagedata column in
sysdtspackages will be populated. Each save will create a new “version” of the package in the
same sysdtspackages table, see the version id column (which is a unique-identity data type). You
are presented with the dialog on save:
238
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
To get the packages version (and go back versions!), right click the package and select version.
This will run the following using the unique-identity column value within sysdtspackages:
NOTE – To transfer a package to another server, consider save-as and entering the remote
host-name and security information (if you have trouble connecting, use the client networking
utility and create an alias then try again). Another option is saving the package as a
structured file, to restore, right click properties of the “Data Transformation Services” folder in
Enterprise Manager and select Open Package. Another unsupported method is simply bulk-
copying the contents of the sysdts tables over to the new server, good luck with this one. I
rare use the meta data services option so I wouldn’t even consider direct system table
transfers at that level.
As the data model describes, there is a variety of log information associated with each package.
This is very handy for drilling into runtime errors at each step within the DTS. Occasionally I have
experienced flow control problems where steps run when they are not supposed to, the logs are
handy when identifying such problems (re-create the workflow and/or transformation as need be).
The package logging will not be activated until you enable it within the package designer, right
clicking on the blank pane and selecting properties:
239
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Some of the key stored procedure for DTS manipulation are, including viewing the log are:
To lock down DTS, the DBA can revoke execute access to these to prevent DTS creation and
viewing. The security paradigm for DTS packages is crazy and Microsoft really need to this one up.
For example, if User1 created a DTS package called “user1 package”, then any other user can run
and schedule the package. The user can assign a password to the package that will prevent other
users from running, scheduling and editing the package. Note that SQL Sever is not smart enough
to associate this with your login and/or security group and it will also ask the creator of the package
for the password.
240
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The save-as dialog allows the user to enter the appropriate password information. User password
allows scheduling and execution, owner password allows editing.
If you want, say, user1 and user2 to edit the same package, then SQL Server takes a dive for the
worst. Unfortunately, no matter what you do in terms on the passwords above or playing with
windows or SQL Server authentication properties on the DTS package save, user2 will get the
error:
On saving the package, SQL Server does a lookup using SUSER_SID (owner_sid column in
sysdtspackages) and SUSER_SNAME (owner column in sysdtspackages), returning the security ID
for the DB login name, no matter your authentication (trusted or not) to the instance via EM, this
ID is entered in the owner column in msdb..sysdtspackages and is used as a lookup for users
attempting to save the package. If the name is not the same then saving will fail.
User1 SUSER_SID:
0x680298C78C5ABC47B0216F035B3ED9CC
User2 SUSER_SID:
0xF1C954D9C9524C41A9ED3EA6E4EA82F4
Under EM, the owner of the package is represented by the users windows login DOMAIN/username.
The DBA can “turn-off” the check to allow many users to work on the same package by
uncomment’ing the following code from a system stored proc:
Source : msdb..sp_add_dtspackage
Of course, this is somewhat risky and Microsoft Support will not help you out with further MSDB
issues. To “switch” security, try to run the following with sysadmin privileges:
241
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
There is an undocumented procedure that can change the owner as well, the syntax is:
NOTE – If you restore a MSDB database from another server, be warned that the jobs will
need to be re-created and that each DTS package entry in msdb..sysjobs may also present
errors related to MSX (remote server management). Try altering the originating_server
column in sysjobs to get around the error.
A scheduled package will run under the security context defined by the users system privileges. If
the user does not have sysadmin fixed server role access, the package will execute via the
sqlagentcmdexec proxy account (as per calls to xp_cmdshell). The proxy setup can be managed
via EM by selecting properties of SQL Agent and going to the Job System tab.
To kill off a running package, the user must have the process administrator fixed server role or
sysadmin access.
242
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
All user databases include the ability to create “diagrams”, which are stored in the system
table dtproperties. The diagram editor in Enterprise Manager allows the DBA to create
physical data models, maintain tables, indexes and constraints (but not security privileges).
From there, SQL Server can generate SQL scripts based on your changes to be saved and run
later or to be applied immediately. A screen shot is shown below:
Manage tables,
indexes, add
annotations,
different views
etc. Some
classic Microsoft
Access GUI feel
in places.
NOTE – Before printing diagrams, double check the printer and page size match’s what you
set within the diagrammer, it has this ability to revert back to A4 when you were actually after
a completely different setting.
I found this tool to be an excellent feature, and although it is far from being a full featured
modelling tool, it can generate scripts that are reliable time after time. This is particularly helpful
when managing large data models and saves time when creating database alteration scripts. It
should be noted that the scripts, are not optimal in terms of locking/blocking and the statement
being used; the experienced DBA may be shocked what they see. This can have adverse effects for
heavily used 24x7 databases.
243
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Transferring Diagrams
a) Identify the diagrams to be transferred
Each diagram consists of 7 records, the DtgSchemaNAME property has the name of the
diagram, use this in conjunction with the objectid column to locate the diagram. We
need to transfer all 7 rows.
The objectid column of the source table is the most critical. We need to maintain its
value to successfully complete the transfer. From the query above, check that the
destination dtproperties does not already have the objectid. If it does, get the
maximum id from the destination table and use it within your select statement.
The key here is the objectid column, it must be unique, the id column is an identity and
does not need to be specified. If it is not, then editing one diagram will alter the other
that shared the same objectid and dropping one will drop the other ! you don’t want
this sort of trouble.
We wont risk this and will specify objectid value 2 as we are 100% sure its unique
within the dtproperties table in the destination database.
Then rename it with a simple update statement before or after the insertion is made.
244
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Row Migration is known as Page Splitting, and will primarily occur when an existing row is updated
but can not fit in its current page.
As the Oracle DBA can move tablespaces, so the SQL Server DBA can move and manage
filegroups.
exec sp_helpfile
This will return all necessary information to manage your filegroup and its associated datafiles. The
examples below we will use the following database structure (as reported by sp_helpfile):
You cannot place the PRIMARY filegroup into read-only (and other) mode; the entire database must
be set if the primary filegroup is to change as its initial data file houses the sys files for the
database. Also remember that the transaction log files have no concept of file groups.
NOTE – If you attempt to create a new database via EM and have query analyser open with
the Model database set in context, you will get an unable to obtain exclusive lock error.
245
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
You need to use the sp_attach and sp_deattach commands to keep the entire instance up.
Of course, the database will be down during this period and will invalidate logins to this
database for the cutover period.
Tables must be re-created, use EM to alter the table and see the generated code. For
indexes, use the DROP_EXISTING clause, for example:
CREATE
INDEX [myindex] ON [dbo].[ourtest] ([col1])
WITH
DROP_EXISTING
ON [FG2] -- the new filegroup
To drop a filegroup:
246
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Pinning Tables
As with Oracle, we can pin tables into the buffer cache and reduce the possibility of pages being
aged out and adding to the IO round trips to the database files.
USE mydb
or
EXEC sp_tableoption 'mydb', 'mytable', 1
Take care when moving databases between servers where tables have been pinned. I have come
across a variety of examples where, on servers with less RAM, the pinning can result in buffer
cache errors and subsequent cache trashing (resulting in a reboot!).
Triggers
Some general information on triggers in SQL Server:
a. INSTEAD OF [INSERT, DELETE, UPDATE], only one per action and as the name
states, replaces the normal processing, can support text,ntext, image column data.
b. AFTER [INSERT, DELETE, UPDATE], can have multiple per action, can specify order
of action, trigger code cant refer to text,ntext,image column data.
d) You can enable and disable triggers, either named or ALL for a table, for example:
alter table dbo.mytest disable trigger all
e) An error in the trigger will rollback the entire transaction. Transactions in triggers are
actually nested transactions to its parent. Cursors are also closed and deallocated in
247
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
context to the parent transaction. Consider the SAVE TRANSACTION (marked transactions)
to do a partial rollback.
f) Mutated triggers are supported – where the trigger fires DML against its own table
Constraints
a) primary keys
b) foreign keys
To check data integrity in term of foreign key constraint consistency, consider the command:
DBCC CHECKCONSTRAINTS
NOTE – Always name your constraints. As with Oracle and its system naming convention,
SQL Server’s equivalent is no better and can result in major problems when attempting to run
so called “common” scripts over many servers.
248
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
From here, use sp_who2, sp_lock or trace the session to determine the ongoing activity for the
session. Consider the dbcc inputbuffer command for a dump of the SPID.
SQL Timeouts
A client timeout may be the result of:
Rename Database
Use the command master..sp_renamedb. Be aware that logins whose default database was
set may also change, this can be a problem for the DBA when renaming to only replace with
another version of the same database for testing purposes (or other reason). Check logins
and verify that you do not need to alter their default database property. After renaming, it is
a good idea to set the DBO only property if it is not to be used by end-users, this can assist
with debugging login issues.
249
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
User Management
Login vs User
In SQL Server 2000, a single login maps to a single user in one or more databases within the
instance. The login defines a basic set of properties for the connection to the instance, the EM
screens encapsulate these options as shown in the screen shot below:
a. authenticating domain must be available (via trust or the server is a member of the
domain)
Defining database access will create a user entry in the sysusers table for the database. The
syslogins table in the master database is loosely coupled to the databases sysusers table via the
SID column. See orphaned logins next for more information.
All security for the user should be granted by database roles to simplify overall privilege
administration.
250
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Orphaned Logins
At times, the DBA will restore a database from one instance to another, in doing so, even
though the login exists for the instance, the SID (varbinary security ID) for the login is
different to that in the other instance. This effectively “orphans” the database user from the
database login due to this relationship between master..syslogins and mydb..sysusers.
syslogins sysusers
SELECT SUSER_SID('user1')
In most cases, simply running the command below will fix the relationship and allow the login to
access the user database (must run against every database in which to login is valid against).
This will only work for SQL logins and not fully integrated logins (which is a down right pain). Write
your own script (or search the web) to resolve this problem.
If you are still getting errors, consider removing the user from the sysusers table in the restored
database, and re-add the user to the
EXEC sp_validatelogins
NOTE – Do not use ALIASES; this allowed the DBA to map a single login to many database
user.
Microsoft released a great support document related to the scripting of logins, including the original
password. The script is not complete in terms of all possible options, but is very handy:
Example: (http://support.microsoft.com/default.aspx?scid=kb;[LN];Q246133)
/* sp_help_revlogin script
** Generated Nov 17 2002 12:14PM on SECA\MY2NDINSTANCE */
-- Login: BUILTIN\Administrators
EXEC master..sp_grantlogin 'BUILTIN\Administrators'
-- Login: user1
251
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
-- Login: user2
SET @pwd = CONVERT (varbinary(256),
0x01006411A2058599E4BE5A57528F64B63A2D50991BC14CC59DB0D429A9E9A24CA5606353B317F4D4CA10D19A2E
82)
EXEC master..sp_addlogin 'user2', @pwd, @sid = 0xF1C954D9C9524C41A9ED3EA6E4EA82F4, @encryptopt =
'skip_encryption'
Change DB Owner
USE MyDatabase
EXEC sp_changedbowner 'MyUser'
GO
This requires the sysadmin instance privilege, and the user will logically replace the dbo user. You
cannot run this command against the system databases. In 99% of cases, this command should
not be used.
SQL Server has no concept of user quotas or resource allocation restrictions as in Oracle. The best
bet is to restrict the growth of the entire database. There is also no concept of account expiry,
forcing password changes, account locking etc.
The DBA should consider QUERY GOVENER, read up the books online for a good overview. This can
only be set via the client on connection to the instance (we have no on-login triggers).
exec sp_grantlogin
exec sp_denylogin
exec sp_revokelogin
Unfortunately this only works for Windows NT logins and/or associated groups:
The equivalent to the OPS$ login for SQL Server is a fully integrated windows login.
252
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Unless you are the dbo (have db_owner or db_ddladmin privileges), you cannot create objects as
another user, for example, if I am logged in as user1 cant issue the statement create table
user2.mytable (col1 int). As its best practice to have all objects owned by DBO, the DBA may
from time to time change the objects owner, we do this via the command:
After running the command, refresh enterprise manager and check the object and its privileges. If
it’s a stored procedure, make sure that the actual create statement is not referring to the old user.
This is a classic problem that will ruin you plans for faultless scripting of the object.
-- Get user ID
DECLARE @userid smallint
SET @userid = (SELECT uid FROM sysusers WHERE name = 'myuser')
-- Check ownership
exec dbo.sp_MScheck_uid_owns_anything @userid
As there are no “on login” triggers and very few login properties that can be automatically set for a
new connection, the DBA has to rely on the developer to do the work. One of these properties is
LOCK_TIMEOUT. The value is in milliseconds and zero represents no wait time for locks. A timeout
will cancel the SQL statement being executed and must be trapped by the developer:
I recommend that you do not use this setting as standard practice; it does not take into
considerating a heavily worked instance or “once off” locking issues that can result in a ripple effect
of application errors if the property was set. If you are in a multi-tier environment (i.e. asp,
com+), in which their own timeouts can be set, then consider making the DBMS connection timeout
the lowest to capture the DBMS error rather than at a higher level.
To transfer logins between servers and retain the logins password (SQL Logins), consider utilising
the DTS task to transfer logins between servers, or the following SQL statements:
select 'sp_addlogin @loginame = ' + name + ', @passwd = "' + password + '",
@encryptopt = skip_encryption, @deflanguage = "' + language + '"' + char(13) +
'go' from syslogins
where name in ('user1', 'user2')
253
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The key to this script is the skip encryption option. Note that we still need to:
Use the command sp_password for SQL logins only (not applicable for NT logins of course), for
example:
Rename a Login
You cannot rename logins in SQL Server. Actually, you can, but this means changing some entries
in the sys tables so good luck with that one. The process involves:
Killing Sessions
Within Oracle the DBA can kill user sessions via looking up v$session for the particular user or
other status, and issuing the command (just examples of syntax):
At the OS level for rouge Oracle processes, the Oracle DBA on Unix can issue the “kill”
command or on NT can use orakill.exe.
Within SQL Server, each connections is allocated a spid (system server process identifier and
worker thread). To identify them we can execute the system stored procedures:
exec sp_who
or
exec sp_who2
The DBA can also use the current activity option under the Management Group folder and
select Process Info.
254
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
NOTE - Be warned, I have experienced major performance problems when forcing the
refresh of current activity via Enterprise Manager to a point where the CPU’s hit a solid 50%
for 5 minutes before returning back to me. This is not funny when running against a hard
working production system.
Once the SPID has been identified, we use the KILL command to remove the session. For
example:
The DBA should reissue sp_who2 to monitor the SPID after the kill to ensure success. Also
consider looking at and joining over the tables:
• sysprocesses
• syslock
• syslockinfo
You cannot kill your own processes. Be very careful you do not kill system processes. The
processadmin fixed system role will allow a user to kill SQL Server sessions.
NOTE - Killing SPID’s running extended stored procedures or did a call-out to a user created
DLL may take some time to kill and, in some cases, seem to have stopped but remain as a
running process.
For example:
This is an undocumented command. For a good coverage consider see reference (46).
255
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Orphaned “Sessions”
An orphaned session has a SPID of –2, this may be caused by a variety of things (though rarely)
and is typically linked to the distributed transaction coordinator (DTC). A DTC related problem will
show up in the SQL Server log files with an error such as “SQL Server detected a DTC in-doubt
transaction for UOW <value>”. If the transaction issue can not be resolved, then a kill statement
can be issued over the UOW code. For example:
Kill 'FD499C76-F345-11DA-CD7E-DD8F16748CE'
NOTE – Use Component Services when appropriate to drill into COM+ classes and their
instantiations to locate UOW to assist with killing the correct SPID at the database.
TEMPDB
The tempdb is utilised for a variety of reasons, such as:
The DBA can manage all tempdb functions through EM, even so, here are some important
commands to remember
Task Command
Check DB Size exec sp_spaceused
Shrink DB DBCC shrinkdatabase(N'tempdb')
Move files alter database tempdb
modify file (name=tempdev,filename = 'c:\dbdata\tempdb\tempdb.mdf')
go
alter database tempdb modify file
(name=templog, filename=' c:\dblog\tempdb\templog.ldf')
go
Space Usage exec sp_tempdbspace (undocumented command)
Size of Using the alter command with the SIZE option
Usage of Consider querying sysobjects in the tempdb database to monitor the creation of
# and ## temporary table objects. Also condsider the SQLServer:Databases
performance monitor counter and also profiler (filtering out the database by ID).
You should keep the standard database options with tempdb. You may want to pre-empt the
increase of the database size and alter growth rates as you feel appropriate. As a very general
256
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
indicator, my production DB with 800 online users, 4Gb data with lots of OLTP activity and standard
DBCC functions at night, see’s tempdb growing to a maximum of 800Mb.
It is not recommended that you run DBCC commands (like CHECKDB) against tempdb. There is a
good chance that errors will be returned depending on what is happening at the time. Remember
that tempdb is rebuilt on instance restart, if you do suspect errors, it may be reported on instance
startup or further investigation of the underlying file system.
The Backup and Recovery section covers the movement of the tempdb datafiles.
Instance UPTIME
There is not specific function to get the uptime of your instance. Consider the query as the next
best thing:
To manually restart the SQL Server NT services, use the NET STOP/START command, for example:
257
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Raw Partitions
I hate raw partitions, they are difficult to use and are restrictive in terms of the underlying NT
commands (copy, move, delete etc are not possible) and backups you can perform. I also
question the real performance benefits you are getting and have yet to read any white paper that
justifies the associated management issues.
I am not covering raw partitions and ask you to spend more time with application performance
instead.
SQL*Mail
The SQL*Mail service utilises a MAPI compliant client to send and receive email. The client is
typically Microsoft Outlook (not Outlook Express), and configuring “Mail” (profile) in control panel to
setup either an SMTP mail account or hook into Exchange.
MAPI SQL
Interface Server 2k
(xp_sendmail, sp_processmail,
xp_deletemail, xp_findnextmsg etc..)
I have had varied success with SQL*Mail, and at the end of the day, I opt not to use it, but have
written a small COM component (DLL) and a stored procedure to call a SMTP send email method.
There are numerous articles on the internet and at Microsoft for configuring sql*mail and not using
it at all. Have a good read before progressing any further.
NOTE – This may sound like a contradiction, but I have read a variety of forum posts from
DBA’s regarding the real need for a MAPI client. To get the low down from Microsoft check
http://support.microsoft.com/default.aspx?scid=kb;en-us;Q306962
Automatic data and log file growth are default options via Enterprise Manager when creating a
database. The default growth is by 10% with an unrestricted maximum size.
Space Tracking
Space management tracking is simple enough. The core commands for tracking database space
usage are:
258
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
exec sp_spaceused
To encapsulate the DBCC command in a table for subsequent querying and historical tracking,
utilise the T-SQL command below:
At an object level for each database, lookup a variety of sys tables and apply the following logic:
To get broad file growth data, do not forget master..sysfiles and DBCC SHOWFILESTATS.
Unlike Oracle, statistics collection is fully automated by default at the database level. This is
configured via the GUI or command line as shown below:
A statistics collection is synonymous with histograms in Oracle. This is different to physical indexes
which naturally have statistical properties (updated on the creation of the index and automatically
thereafter based on DB settings). Indexes and statistics collections are critical in enabling the
query optimiser to best determine the execution plan.
259
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
At the database level, the auto create statistics option is an interesting one. This tells SQL Server
to create a statistics collection (stored in the databases sysindexes table) for SQL predicates not
already indexed. For example:
Note that running exec sp_statistics ’bb’ will return a list of all indexes and statistics for our
table in the example. I personally find this procedure useless for statistic collections as you may
find with its output. Use exec sp_helpstats 'bb' to get a listing of statistics for the table, pass
this into dbcc show_statistics ('bb', '_WA_Sys_col2_29572725') for example to get a
further analysis of the collection. Note that the collection can be replaced with the index name of
the table if need be as we will see later.
NOTE – Statistics cannot be created for text, ntext and image column datatyes.
Both indexes and collections include histogram (distribution) statistical information in the statblob
column within the sysindexes column.
Throughout in this chapter we will cover both the autocreation and autoupdate statistics options,
along with analysing the statistical data collected.
EXECUTE DBMS_STATS.GATHER_TABLE_STATS
('myuser','mytable', METHOD_OPT => 'FOR COLUMNS SIZE 10 mycol');
Funny enough, Oracle state that histograms must be carefully chosen as they can impact
performance, and should, generally, only be used on columns with highly skewed data so as the
cost-based optimiser can make well formed decisions over uniformity of the data.
In SQL Server this thinking is somewhat different and statistics are used widely throughout the
database instances with little impact. These statistics (especially if auto-stats option is on) can
occur over uniformly distributed data for example and in most cases, seem to help the perhaps less
complex optimiser compared in SQL Server.
260
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
In Oracle, the histogram min/max values and distribution data is stored in “buckets” that the DBA
specifies. In SQL Server the histogram and associated density group is stored in the statblob
column that is an image blob datatype.
The DBA can utilise the WITH NORECOMPUTE option to prevent SQL Server from subsequent
updates to the statistics. This is not recommended.
NOTE – A statistics collection is regarded as an index against the table although its not a
physically one, therefore, query sysindexes where locating statistic collections.
As the Oracle DBA will quickly realise, the SQL Server histogram is very simplistic when compared
to Oracle.
use mydb
exec master..sp_updatestats -- update statistics for all objects in mydb
Such statistical information can be recollected for the entire table or index, the DBA can also
selectively re-sample a specific index or collection within the object.
The DBA can also create a Database Maintenance Plan to schedule the update statistics of statistics.
Most DBA’s will opt for this as it’s simple and works very well. Those requiring finer control will use
a custom t-sql.
Monitoring Statistics
The most effective way to monitor the automatic updating of statistics is via Profiler. Select the
following (not definitive by any means but a good start):
An example screen shot is shown below. The update runs asynchronously to the users execution of
261
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
the query. After some testing I still find it difficult to predict the actual logic being used, as a large
row count change doesn’t necessarily cause a stats update but different queries against the table
with different predicates does. Keep an eye on regularity, associated locking (if any) and its impact
on CPU time.
Here is an example output, use OBJECT_NAME to get the actual table name:
This option is available within Enterprise Manager when editing your indexes and statistic
collections. Be careful, as any manual or automatic statistic collection will skip these objects, which
can be a problem when debugging performance issue or strange execution plans.
The command is very helpful when drilling down through and index to determine its selectivity and
subsequently its usefulness. Classic examples are comparing existing non-clustered (heap) and
clustered indexes to determine wether another index is better suited to range scans and therefore
clustering.
The core purpose of the command is to display information about index density. Providing the DBA
with an insight into the key distribution within the index, and therefore its selectivity.
262
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Use the formula all-density * rows = key selectivity to calculate wether the key combination is
highly selective. In the case above, we have a composite index over addr_locality and addr_id, we
are shown the two sets of figures for us to calculate the density for each combination of index
lookup. In this case the values are:
of course, perfect selectivity is a value of 1. This is still no substitute for a thorough understanding
of your applications demographics and associated indexing requirements, but is still a very good
guide.
The other columns are self-explanatory. The next part of the statistics shows the sampled
histogram, each representing a step. The columns of interest are:
c) avg range rows (avg duplicate values within the step range)
I use a tool call Diagnostics Manager from NetIQ, a great management tool for drilling into such
statistics, here is a screen shot (versions will undoubtly differ):
263
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Please read the chapter on performance tuning and indexing issues to better understand and leaver
off the statistics presented above.
Synonyms
There are no synonyms in SQL Server, the best you can do is (perhaps) use views. In all
cases the owner of all user database objects should be dbo, then use roles to manage security.
So long as the DBA understands the application(s) running against the database, its growth “spurt”
periods and that a database running with a full recovery model requires log backups to occur (or
your transaction log file will keep growing), then a nightly, weekly or monthly database shrink is
more than enough.
264
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Examples:
WARNING – If you shrink specific files, DO NOT press the OK button to close the shrink
database dialog, if you do, it will run a shrink database for the entire database.
Under the FILES option of the shrink dialog, the empty filegroup option also exists. This option only
works for a single filegroup that has multiple data files. As you know, if you create an object on a
specific filegroup, SQL Server will distribute the objects storage over the group’s database files.
The EMPTYFILE option will move (migrate) all data from the specified file to the other file sharing
the same filegroup.
-- DB_DATA2 is the logical file name for my DB_DATA filegroup, all object data is move from this
-- database file to DB_DATA1, therefore allowing me to drop DB_DATA2
To track shrinking, consider the DBCC EXTENTINFO (‘mydb’) command as discussed in the
Microsoft Support document Q324432. This support document provides a great script for viewing
object space allocation and fragmentation. I have adapted the end-query a little to suit my needs:
265
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
go
-- Show possible fragmentation and reduction possibilities (run shrink later and compare the results)
select
FILE_NAME([file_id]) as DBFile,
OBJECT_NAME(obj_id) as ObjectName,
case index_id when 1 then 'ClusteredIndex'
when 255 then 'Text/Image'
else 'NonClustered' end as IndexType,
ext_size as ExtentSize,
'actual extent count'=count(*),
'actual page count'=sum(pg_alloc),
'possible extent count'=ceiling(sum(pg_alloc)*1.0/ext_size),
'possible extents / actual extents' = (ceiling(sum(pg_alloc)*1.00/ext_size)*100.00) / count(*)
from
extentinfo
where
ext_size != 1
group by
[file_id],obj_id, index_id, ext_size
266
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
SQL DMO
SQL Distributed Management Objects (SQL-DMO) is a COM layer whose relationship to the SQL
Server engine is such that it is an in-process OLE Server (in other words OLE automation
compatible COM objects). As such, it exposes many of the core methods for SQL Server object and
replication manipulation, both local and remotely.
NOTE – SQL DMO is fundamental to Enterprise Managers’ functionality. The DLL is called
sqldmo.dll. Select properties of the DLL via the OS to get its version information.
The object model is very thorough, and will cover close to all of your requirements for database
manipulation. A simple search of www.google.com will provide you with more than enough
examples to get started, especially for those experienced with VB.
The DBA and/or developer can use SQL-DMO in a variety of ways as shown below. An excellent
resource can be found at:
http://www.sqlservercentral.com/columnists/sjones/sqlserverdmoresources.asp
VB Example
Dim oServer As SQLDMO.SQLServer
oBackup.Files = “c:\nothwind.bak”
oBackup.Action = 0
oBackup.SQLBackup oSQLServer
Set oBackup = Nothing
oSQLServer.Disconnect
Set oSQLServer = Nothing
267
12
Chapter
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
T
hroughout this chapter we will discuss transact SQL (equivalent to PL/SQL) and common
SQL commands with examples. I will not give too many direct comparisons to Oracle but
will attempt to focus on providing you with good overall coverage to speed your
introduction to SQL Server.
PL/SQL (T-SQL)
The core programming language comparable to PL/SQL is T-SQL (Transact-SQL). This will change
in future releases of SQL Server when the .Net framework becomes embedded in the DBMS. The
affect of this is that any .net compatible language can use used instead of T-SQL.
The following sections summarise some of the core elements of T-SQL with comparisons with
Oracle as required.
/*
this is a
multi-line quote
*/
You cannot nest multi-line quotes, attempting to do so will result in error. The single line
quote can appear anywhere on the line, although once started all values after it until a newline
will be regarded as comment text.
T-SQL statements do not require the ; or any other character to denote the end of the
statement. If used at the end of a DML statement the command will not error.
268
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Understanding GO
The GO statement defines the end of a batch of T-SQL, although itself is not a T-SQL statement.
Using profiler (discussed later), we can see the affect that the GO statement has on batch
submission of SQL and T-SQL statements to the relational engine:
use pubs
declare @aa integer
set @aa = 1
print 'this is a test'
print @aa
GO
use pubs
GO
declare @aa integer
set @aa = 1
GO
print 'this is a test'
print @aa
GO
Of course, each of the statements between the GO are compiled as a single execution plan.
Take care, variables are not persistent between batches, the above actually gives us an error for
the below code, as @@aa is not declared within the batch.
Be careful using the GO statement in stored T-SQL code, the GO statement will define the end of
the code block so if you went a placed GO statements all through your stored procedure for
example and saved it successfully to the database, you may find that the rest of the code is missing
after the first GO statement. The entire stored procedure / UDF is a single block of code and you
cannot change this via GO’s.
269
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Block Structure
The Oracle block structure for functions, procedures, and anonymous blocks consists of the
format:
[declare [begin]
-- variable declarations] -- declaration and body code can be
begin -- anywhere after the declaration
-- body code and other statements -- of the procedure/function/trigger
[exception -- there is no enforced syntax
-- handler code]
end; [end]
[GO]
It should be noted that although optional in this particular case, the BEGIN and END statement is
used to define a logical block. The begin/end combinations are mandatory for multi-line control
statements (2 or more lines, i.e. IF, loops) as we will see later. The begin cant be used without the
end statement.
You can declare multiple variables of the one DECLARE statement, for example:
You cannot set default (initial) values for the local variables:
DECLARE @error_count INTEGER = 0
SQL Server T-SQL has no concept of constants, they are only string literals or other fixed values,
like 10, ‘Hello’ etc in code that is it.
Take care with declarations. If you do not initialise the variable the default value is NULL. This will
create adverse problems, for example:
270
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The BEGIN and END statements do not affect a variables scope. Therefore, once a variable is
declared ALL code below it (within the same batch of course, see the section on GO) can refer
to it. Nested calls to other stored procedures or UDF’s cannot use the variables declared.
SQL Server does support the INTO clause, but this is the same as the CREATE TABLE AS
<select-statement> clause in Oracle. The syntax is also a little back to front, for example:
It will inherit:
a) identity property
b) table structure
271
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
NOTE – Remember, stored procedures can utilise the RETURN statement to stop code
execution at the point of the RETURN, it is not restricted to user-defined functions.
-- Example 1
-- Example 2
IF @error_count <> 0
BEGIN
PRINT “An error occurred with the a range of statements”
END
-- Example 3
IF @@ERROR <> 0
BEGIN
RAISERROR (20067, 16, -1, ‘Critical Error’)
RETURN (1)
END
-- Example 4
IF @@ERROR <> 0
BEGIN
GOTO CriticalError
END
<other code>
RETURN 0 -- skip over labels below
CriticalError: -- place labels at the end of your stored procs for ease of maintainability
PRINT ‘Critical error message’
Rollback Transaction -- optional of course, implementation specific
RETURN 1
272
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
-- Example 5
CriticalError:
BEGIN
IF @@trancount <> 0
ROLLBACK TRAN
raiserror @ErrValue
NOTE – Apparently the next version of SQL Server will bring with it exception handling for T-
SQL, similar to that used in VB.
If you have issues with checking @@ERROR directly in an IF statement, then immediately after the
command you are verifying, assign @@ERROR to a variable and use this for checking. Be warned
that not checking @@ERROR immediately and executing other statements may affect the value
returned from @@ERROR.
By passing in @@ERROR, we can translate and appropriate error code into its equivalent severity
and description. The severity levels are:
We can maintain our own user-defined messages via the following stored procedures in the master
database:
273
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
sp_addmessage
sp_dropmessage
sp_altermessage
Example:
exec master..sp_addmessage 50006, 16, 'My Error parameter 1:%d, parameter 2: %s.'
RAISERROR (50006, 16, 1, 100, 'MyTest')
NOTE - Be warned though in stored procedures, if you were planning on using raiserror to
stop processing immediately you may be surprised, a classic example are foreign key errors
on an insert or update and the stored procedure continues to run. Always force the exit on
error via a RETURN statement and rollback otherwise the non-fatal error will be shown and the
code execution continues.
We can also log user–defined error messages to the SQL Server log and Windows NT event log
via the extended stored procedure xp_logevent.
Non-SQL Output
Calling DBCC commands and other system stored procedures (xp_ or sp_) , typically requires the
encapsulation of the result set into a temporary or static table for further manipulation. This
practice may also required when calling the stored procedure and returning the results to a record-
set from a VB or other application.
-- create the tempory table (stored in tempdb), also consider the TABLE datatype
CREATE TABLE #inputbuffer
(
EventType nvarchar(30),
Parameters int,
EventInfo nvarchar(255)
)
SELECT EventInfo
FROM #inputbuffer
Take care with the EXEC[UTE] statement, which may result in the error:
274
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Cursors
As in Oracle, the cursor is pretty well standard for the modern DBMS. In terms of T-SQL, the
cursor type and associated command set has a large number of options that is better covered in
the books online.
A very basic example is show below, you will probably use this example in a majority of cases for
simple record processing:
Use PUBS
GO
OPEN mycursor
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @empid + ' : ' + @fname
CLOSE mycursor
DEALLOCATE mycursor
If we altered data after the OPEN statement, the record will be reflected in the cursor. The cursor in
this particular case does not pre-fetch the data (as the plan shows above). Read carefully in the
books online about other options such as INSENSITIVE, STATIC and KEYSET that may change this,
for example, an INSENSITIVE cursor sees a single operation generated for the whole statement
rather than one for each fetch.
275
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Those cursor options that utilise the TEMPDB are not recommended (see STATIC cursors next
though for an example where its required). On top of this, don’t use options where you update
through the cursor, use a standard SQL update/delete command. A simple test with the above
statement and the SCROLL option for example:
This sees the appropriate locks taken out on the new tempdb object and an increase in turn-around
time of about 30%, not great on the already slow standard (dynamic) cursor.
In the discussions above, I have made a point of highlighting locking. One of the big issues with
SQL Server performance is locking and blocking. Be very careful with cursors, especially options
such as SCROLL_LOCKS. Unintended locking and the flow on effects in terms of overall
performance and time spent tracing the problem is something you would rather avoid than deal
with later.
So long as you close and deallocate, there is no reason why you cant alter the cursors SQL
statement, open and continue with your new set of work. Failure to deallocate will result in the
error:
276
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Be aware that many SET operations (such as setting dateformat) will result in error if a cursor has
been declared before it:
NOTE – Always opt for a bunch of DML statements if you can to do a bulk of the work.
Adversely, be careful trying out to completely “code out” cursors all together, depending on
the code, you may find a WHILE loop with multiple DML statements even slower ! test
carefully.
In terms of cursor functions, the equivalents between Oracle and SQL Server are:
STATIC Cursors
The DBA should spend some time reading up on the types of cursor. By default, all cursors are
dynamic, this means that each FETCH will retrieve the value from the database “as is”, not from
when the cursor was first opened. A classic example of where this can be a problem is when your
cursor SQL statement is using a not exists or not in clause. If on a fetch of one record, you alter
the data in the table that effectively cancels out the not exists/not in for subsequent records, then
unless you used s STATIC cursor, the next fetch may return no records. If you are experience this
sort of problem, consider STATIC cursors that pre-fetch the data into a temporary table.
277
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The linked server e) above is an interesting one. In the SQL Server Magazine, June 2002, Brian
Moran showed that utilising sp_addlinkedserver, you could subsequently query an external file (this
is also in the BOL). Here is an example:
Procedures/Functions/Packages
Lets be honest here, T-SQL is the poor mans PL/SQL and probably always will be. This of course
will all change when SQL Server Yukon is released and the power of VB, C++ and over 20+ other
languages that are embedded in the .Net framework, enter the SQL Server DBMS. Anyhow, back
to the topic, all we have in terms of code blocks in SQL Server are:
Stored Procedures
There are no T-SQL packages or concepts of private and public routines (control security via roles),
so like I said, it’s the poor mans PL/SQL.
As an Oracle DBA you will probably be surprised that the UDF is a new feature to SQL Server, I
would have thought this was a fundamental but apparently not. Anyhow, the concept and code is
very easy and there is no rocket science to it.
Basic Syntax
Example
278
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
print myfunction(1)
a) cannot be indexed
b) must be deterministic
c) concerned with speed? I am, test this very carefully as even a stub call results in some
interesting speed issues.
d) cannot call extended stored procedures that return data directly from the function (must
encapsulate the returned data into a temporary table first)
e) has many restrictions, such as not being able to call dynamic SQL inside it, or creating
temporary tables, eg:
Server: Msg 2772, Level 16, State 1, Procedure mytest, Line 5
Cannot access temporary tables from within a function.
The stored procedure is very common amongst SQL Server developers, and true for Oracle
database applications as well (but typically encapsulated in packages). The stored procedure is
the key for enhanced system performance and maintenance of DML that would otherwise be in the
COM+ tier (business layer).
Like UDF’s, the BOL provides thorough coverage of the syntax of the procedure. There are few
restrictions in the stored procedure unlike the UDF, and are relatively simple to implement and call
via VB. The basic syntax is:
{procedure code}
go
By default all parameters are IN only (read-only), unless the OUTPUT clause is used, for example:
279
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Like variables, all parameters must include the prefixed @ symbol. To specify a default value for
parameters, use the syntax:
Like the UDF, the stored procedure can return values, but only integers via the statement RETURN
[value].
The DBA can encrypt procedures (and functions) via the WITH ENCRYPTION option. This uses an
internal encryption routine and is further covered in the security chapter. This makes the
syscomments text column unreadable. Be warned that encrypted routines require script change
management as they can not be scripted from EM.
Finally, the last option worth mentioning is WITH RECOMPILE. This causes the recompilation of the
execution plan every time it is called. This is not normal practise and should be carefully
considered before using the option. To trace the recompilation, check for the event SP:CacheMiss,
this is the only indication followed by the SP:Starting (being the actual routine being called). These
events are found under the stored procedure group of events. An example trace:
I have had mixed success with the SP:Recompile event and I wouldn’t recommend it for tracing
recompiles.
To call, you must include ;1, therefore, it’s not really. You cannot overload stored procedures or
functions, which is another pain to deal with.
The DBA can grant create procedure or function access at the database level for which the user is a
member of; but cannot deny/grant the alter statement. By default, unless the user is part of
db_owner or ddl_admin database fixed roles, the user can not create or alter objects owned by
different users (such as DBO).
280
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
It is very important that ALL objects in a database are owned by the dbo user before moving into
production. During development, the DBA should let the developers (using defined logins), create
procedures, functions and views freely. The DBA can then alter the owner via
sp_changeobjectowner to dbo and allocate privileges via database roles, moving the routines
through to test and then into production.
When creating procedures and functions, avoid explicitly prefixing the owner, eg:
Doing so can be a nightmare for ongoing administration, where the textual definition of the
function/procedure is different to that defined in separate columns within sysobjects. The flow on
effect is that EM shows a procedure as owned by dbo for example, but when editing the procedure,
the create procedure statement has a different (original) user! not good when you rely on object
scripting to move between servers as the script will have the wrong user.
While all this is fine, there can be recompile and compile lock issues not prefixing calls to routines
with the owners name. I am not convinced this is a problem in terms of performance.
Assuming that userA in their database userdb, wanted to use xp_cmdshell to compress some
files in some predefined directory. The programmer, of course, has a variety of methods but
in this particular case must use a T-SQL stored procedure call. To give the user access to
xp_cmdshell we:
a) Run Enterprise Manager and connect to the instance
b) Goto the user folder for the master database and chose the add user option
a. Make userA a user of the master database
b. Grant execute permission to xp_cmdshell for the user
i. Optionally use a role rather than granting the privilege direct
By default, sysadmin users have xp_cmdshell execute access, and auto-proxies to the user running
the instance. For everyone else, you may need to set the "sqlagent" proxy via:
281
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Remember, this is completely different from the service account in which SQL*Agent is running,
selecting its properties via Enterprise Manager does not reflect the change above. Only setting this
if you are presented with a SQL error related to the SQL*Agent proxy account ("error at line
140 in xp_shell.cpp, no proxy").
A way to deal with security is to encapsulate the calls to xp_cmdshell in another stored
procedure that users are granted access to via the same paradigm mentioned above. Within
this we can audit user activity, encapsulate further validation to prevent certain actions from
occurring etc. In this way we only grant access to the wrappered stored procedure and not
xp_cmdshell direct.
GO
DBMS_SQL
Please read the section on Dynamic SQL.
DBMS_RANDOM
In Oracle, the PL/SQL developer can use the DBMS_RAMDON package to generate random
numbers. This is installed via:
• utlraw.sql
• prvtrawb.plb
• dbmsoctk.sql
• prvtoctk.plb
• dbmsrand.sql
• or review $ORACLE_HOME/rdbms/admin/catoctk.sql.
To generate random numbers in SQL Server we use the pseudo-random number generator
function RAND with a optional single parameter being the seed.
select rand()
282
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
As described in the SQL Server documentation, if you decide to specify a seed, then consider
utilising getdate() to assist with randomising the seed. A fixed value will return the same
random value every time (of course).
DBMS_OUTPUT
The DBMS_OUTPUT package allows the DBA to write out messages to the console (i.e.
SQL*Plus etc) whilst our stored procedure or other PL/SQL code executes. This is typically
used when debugging large routines, tracking progress or even for character based reporting.
Out of all the procedure calls you can make with the DBMS_OUTPUT package, the only
equivalent in SQL Server is the print command. Which is not necessarily a bad thing.
Example:
Each single print command has a maximum of 8000 characters. Also note that print does not
work in triggers.
DBMS_MAIL, UTL_SMTP
Within Oracle we can utilise the DBMS_MAIL package, or the UTL_SMTP package for sending
emails via a PL/SQL stored procedure. In SQL Server we can:
a) use SQL*Mail via a MAPI compliant emailer
b) write our own DLL and call out to it via the sp_OA procedures in the master database
DBMS_AQ
No packaged routines exist in SQL Server for queuing. Search on the web for MSMQ for more
information. The DBA can easily call its API if need be or talk to an MSMQ within the DTS pre-
packaged active-x controls for MSMQ.
There is no equivalent to the PSP and/or the PL/SQL web toolkit. The best we have is SQL Server
returning XML directly from a SQL statement (FOR XML clause). The MS development tools have
this area very well covered.
DBMS_METADATA
I rarely see DBA’s utilising this package in Oracle as most use their own custom scripts (many
sourced from web-sites) and typically provide all they require. Even so, this package provides high
283
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
level meta-data about the underlying database schemas rather than utilising the sys objects. In
SQL Server, we have a similar built-in) meta-data views called the information schema.
Listed below are a variety of information schema views available. The list is far from
comprehensive but does provide a general guide.
There are no special security restrictions for the views and they are accessible through the public
role. Be aware though that the schema views will only return data in which the user has access
too. This is determined within the views themselves via the permissions() function.
use master
exec sp_helptext 'information_schema.Referential_Constraints'
DBMS_JOB
The equivalent to DBMS_JOB for the scheduling of T-SQL stored procedures, is to use the
following MSDB stored procedures:
a) sp_add_job -- add defined job to be run by SQL Agent
b) sp_add_jobschedule -- creates a schedule for a job
c) sp_add_jobserver -- sets target server to run the job
d) sp_add_jobstep -- add step to the job (some work to be performed)
e) sp_update_job -- change job properties
f) sp_update_jobstep -- change job step properties
g) sp_update_schedule -- alter execution schedule for job
h) sp_delete_job -- remove job
i) sp_help_job -- get metadata about job
j) sp_help_jobhistory -- get execution history
k) sp_help_jobschedule -- get metadata about job schedule
l) sp_help_jobserver -- get metadata about job server
m) sp_help_jobstep -- get metadata about the job step
n) sp_add_category (optional) -- categorises the job
o) sp_update_category -- alter categorisation
284
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
These of course map to a range of MSDB system tables, the data model of which is shown
below:
sysservers
(linked servers) sysjobschedules sysjobhistory
An example of checking the existence, then scheduling a job is shown below. Remember that
the SQL*Agent service is responsible for the running on the job.
BEGIN
-- add the job
-- job step #1
285
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
RETURN
JobError:
PRINT ‘Error with our job example’
286
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Here is a screen shot from Enterprise Manager regarding the scheduled job.
DBMS_LOB
There are no built-in routines similar to DBMS_LOB. The SQL Server binary objects have a variety
of restrictions in terms of SQL (cannot check equality in a SQL statement without using LIKE, T-SQL
does not support TEXT datatypes etc). See the help of your associated language about
reading/writing to SQL Server for more information about dealing with LOB’s.
BFILE
There is no equivalent option to the BFILE type in SQL Server.
Tables
The syntax of Oracle and SQL Server for table creation and alteration is significantly different,
primarily due to the large number of additional options included for space and concurrently
management in Oracle. The syntax itself for SQL Server is simplistic and requires no explanation
that cannot be covered in the books online.
287
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The only issue here is when the table has a clustered index, where will the table reside? your index
or data filegroup?
When creating constraints (primary keys, foreign keys, defaults, unique, check), the DBA should
explicitly name them. The system generated name can create issues with scripting and make meta
data close to meaningless.
Finally, when querying sysobjects for user tables, consider the SQL statement:
The user defined function is similar to that of Oracle in the respect that they are what they say they
are. Even so, in SQL Server we support:
a) Scalar functions – return a scalar data type (singular), such as INT, FLOAT etc.
b) in-line table functions – returns type TABLE, used when the function contains a single SELECT
statement for example, eg. RETURN(<select-statement>)
c) multi-statement table functions – as above but can contain a variety of other statements are we
explicitly define the structure of the returning table.
The function returning a table can be utilised in standard SQL statements such as:
select A.*
from dbo.myfunction() as A
-- can also be used in WHERE, HAVING, GROUP BY clauses
• restricted use of many non-deterministic functions (i.e. cannot use - getdate(), RAND etc).
• cannot use temporary tables, can declare table datatype though (cant index table types
although you can declare a primary key that will create an index anyhow, table types are
also not considered part of a transaction).
• if calling an extended stored procedure, it must not return a result set to the client that
cannot be captured by the trigger code.
288
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Indexes
The performance and tuning chapter covers indexes. In broad terms, the indexing schemes in SQL
Server are very simple with few equivalents to Oracle:
Sequences
In SQL Server, the sequence is called an identity. There are no similarities what so ever
between sequences in Oracle and identities as we will explore throughout this section.
In Oracle, the sequence is a separate data structure in which the developer or DBA can select
unique values from within PL/SQL code or DML statement. When given the privilege, many
database users can concurrently select unique values from the sequence and as such, can service
more than one database object. The Oracle sequence is much more feature rich as shown below:
The first key difference is that a sequence in SQL Server is not its own database object as in
Oracle. The identity is an extended property of a table column, and only one column can
enable it. The valid data types for the column to include the identity property include tinyint,
smallint, int,and bigint, therefore defining the maximum and minimum values for the column.
Here is an example:
289
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
NOTE – The column using the identity property does not need to be a primary key but must
be non-nullable.
The DBMS will automatically populate the columns value, the programmer does not code a
trigger or use the .NEXTVAL or .CURRVAL clauses as in Oracle to populate the tables column.
When inserting data into the table, we simply do not specify the column in which the identity
property has been applied and the DBMS will do the rest, ensuring a unique value is inserted.
SELECT @@IDENTITY
SELECT SCOPE_IDENTITY()
-- at this point, the trigger will audit insertions into mytab into the mytabaudit table
insert into mytab (col2) values ('A')
As you can see, scope is vitally important to ensure consistency and data accuracy.
290
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The DBA can reseed, check the current value or reset the identity column value as need be via the
command:
NOTE – DO NOT assume that re-seeding will force SQL Server to magically “fill in” skipped
sequences. If for example you had a table whose primary key is an identity, and you
removed record 4 and then decided to re-seed back to 3, the new insert will do as you wanted
to insert the new record with identity value 4. Unfortunately for you the next insert will fail
with a primary key error as 5 is already taken.
This command requires sysadmin or db_owner or db_ddladmin privileges. To view the current seed
value for a table, use:
SELECT IDENT_SEED(‘mytab’)
or use EM.
To override SQL Server and force your own value into the column with the identity property set,
you need to use the SET IDENTITY command before and after the insertion. For example:
You MUST specify the column list for the insertion to work. SQL Server will continue on from the
value you inserted, in this case 123. This option can only be set for one table at a time for the
current session at any one time.
Finally, there is a function called IDENTITY that can be utilised in SQL statements to generate 1 or
more seeded sequence values from an initial seed and increment. Its very restrictive though as it
can only be used when creating new tables via a SQL statement (create table as in Oracle). Here is
an example:
If you try and use the SQL statement only without INTO, you will get:
To find all tables utilising the identity property, try this SQL statement:
SELECT
u.[name] AS Owner,
291
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
o.[name] AS [Table],
c.[name] AS [Column]
FROM
syscolumns c
INNER JOIN sysobjects o ON o.Id = c.Id
INNER JOIN sysusers u ON o.uid = u.uid
WHERE
c.status & 128 = 128 -- apply bitmap mask for identity property
Another name for unique identifiers is GUID (global unique identifier) that is guaranteed to be
unique no matter the server and/or location/time. The value is a large HEX string represented by
the format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, in which only no arithmetic functions are
allowed against it. To allocate a value to a GUID variable, you need to use the NEWID() function as
shown in the examples below:
Note one of the key differences is that we have no magic function to select the allocated
NEWID value as we can with identities using @@IDENTITY.
NOTE - Classic uses of GUID are with replication, uniquely identifying rows and to assist with
conflict resolution.
292
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Built in Functions
Numeric Functions
Some of these are not strictly numerical functions but have been listed due to their context of
usage.
293
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
SQUARE N/A
sysmessages SQLERRM
TAN TAN
TOP N/A
USER_NAME USER
In Oracle we can use TO_CHAR (numeric to a varchar2) and TO_NUMBER (varchar2 to numeric)
functions for translation and formatting of numerical data. The TO_CHAR function offers a wide
variety of number format masks for the resultant string value, this includes such things as
currency, suffix and prefix minis signs, commas, scientific notation and much more. We have no
equivalent functions in T-SQL for SQL Server, and are typically resolved via the application utilising
VB or C++. The DBA should consider CAST and CONVERT functions where applicable.
String Functions
294
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Date Functions
The SQL Server DBMS includes two datatypes for date/time data storage:
a) Datetime – accuracy of one three hundreds of a second – Jan 1 1753 to
b) Smalldatetime – accuracy to nearest minute – Jan 1990 to June 6 2079
IMPORTANT – SQL Server has no equivalent to the TIMESTAMP or TIMESTAMP WITH TIME
ZONE datatypes, do not confuse the SQL Server timestamp datatype with these. The closest
option you have is the datetime datatype.
As with oracle, the time component is embedded with the datatype and there is no specific
time datatype.
datediff MONTHS_BETWEEN Returns that date difference between two dates, we can
choose wether the date part is year, month etc.
295
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
There is no TRUNC() function is SQL Server, therefore, date comparisons over equality may require
the use of datepart or cast functions to trim the time component.
NOTE – SQL Server has no concept of JULIAN dates, i.e. the number of days since Jan 1,
4712 BC, for continuous dating from a common reference point. There is no format string (J)
for julian date conversion.
In Oracle we can utilise, amongst other things, the NEW_TIME function to assist it converting
datetime values between timezones. The closest we have in SQL Server is the getutcdate function,
that returns the current datetime in terms of GMT (greenwich mean time). The servers local-time
and the zone setting of the operating system can affect the value returned. Therefore, the
timezone of the server will influence the result set. Apart from this, there is not magical
NEW_TIME function available for time-zone conversions.
296
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
297
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
select col1, col2 from mytable Server’s lock escalation, even so, we
FOR UPDATE OF col1, col2 can get those via SQL Hints.
SET @myvar = 2
298
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
group by item, salesman with cube all possible values based on the
WITH CUBE columns specified (call
Item Sales Person Total dimensions).
----------------- ----------------- -------
15" Monitor Veronica 350.0 In the example, we can see that the
15" Monitor NULL 350.0 CUBE expression has pivoted over
Arm Chair Carl 120.0 the sum(total) column and produced
Arm Chair Chris 120.0 a result set that covers all valid
Arm Chair NULL 240.0 combinations of item and salesmen
Desk Carl 450.0 where data exists.
Desk Veronica 450.0
Desk NULL 900.0 The GROUPING clause can use used
Foot Stool Carl 25.0 to determine if a NULL will be
Foot Stool Chris 25.0 returned so the user can alter this
Foot Stool NULL 50.0 value and return something easier to
NULL NULL 1540.0 understand.
NULL Carl 595.0
NULL Chris 145.0
NULL Veronica 800.0
ROLLUP select item, salesman, sum(total) When compared to the query above
from sales and the with c8be option, the rollup
group by item, salesman with rollup clauses uses the same paradigm but
rolls up the summarised totals.
Item Sales Person Total
----------------- ----------------- -------
15" Monitor Veronica 350.0
15" Monitor NULL 350.0
Arm Chair Carl 120.0
Arm Chair Chris 120.0
Arm Chair NULL 240.0
Desk Carl 450.0
Desk Veronica 450.0
Desk NULL 900.0
Foot Stool Carl 25.0
Foot Stool Chris 25.0
Foot Stool NULL 50.0
NULL NULL 1540.0
UNION No example required. As per Oracle.
UNION ALL No example required. As per Oracle.
INTERSECT N/A There is no equivalent in SQL
Server.
MINUS N/A There is no equivalent in SQL
Server.
ASC, DESC No example required. Sorting conditions for order by
clause are as per Oracle, no example
required.
AS OF N/A Oracle – The FROM <list> AS OF
[SCN, TIMESTAMP] clause is used to
query data as it existed back in time,
this is done via Oracle’s automatic
undo tablespace and its settings to
control Oracle flash-back. There is
no equivalent in SQL Server. No SQL
Server equivalent.
SAMPLE N/A Oracle – can return a sampled
299
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
COALESCE SELECT COALESCE (col1, col2, col3) Returns the first non-null value from
FROM MYTABLE a list of values.
300
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Partitioned Tables
There is no concept in SQL Server of partitioning; there seems to be no plans from Microsoft to
support this great Oracle option in the next release of SQL Server
Parallel Query
Unlike Oracle, the parallel options in SQL Server seems to be a half hearted effort for
multiprocessor machines. There is only one hint available (DOP), and from a lot of work with
parallel queries, I have been a little disappointed with performance overall. But don’t let me
discourage you, I am not backing up my statement so you will need to try it yourself.
At an instance level, the DBA can “turn on and off” the CPU’s utilised by SQL Server. This is easily
managed via Enterprise Manager by right clicking properties at the instance level:
From here, the DBA can control basic instance parallelism options:
The cost estimate or threshold parameter is somewhat vague, its like the recovery interval, you
don’t really know what its doing under the covers. This value is in seconds and is used by the
optimiser to predicate a plans execution time; if it is greater than 5 seconds for example, it will
consider utilising intra-query parallelism.
301
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
To control parallelism at a SQL level, use the MAXDOP (DOP = degree of parallelism) hint, for
example:
select *
from products
option (maxdop 3)
Take care to monitor CPU utilisation along with logical and physical reads. You may find a
significant increase in CPU utilisation and with large, frequent queries you may see a reduction in
buffer cache hit ratios if the queries are large and adhoc.
Utilise the trace flag 8687 to disable parallelism globally for the DBMS on instance startup. Also
note that many internal DBCC commands will utilise parallel operations where possible; consider
the trace flag 2508 and 2528 to turning it off selected DBCC calls.
Parallel IO
With the installation of SQL Server 2k SP1 and above, the parallel affinity option has been
enhanced to include to specify what CPU’s are dedicated to run SQL Server IO operations. Without
the option, SQL Server disk IO will be scheduled to any of the eligible CPU’s as specified by the
affinity mask option.
sqlservr.exe –I0x00FF0000
Remember that this option goes hand in hand with the affinity mask option to split away CPU’s
dedicated to disk IO verses other thread tasks for the rest of the instance.
SQL Hints
As a general rule, do not use HINTS unless there is a real need too. They are hard to
administer and at times understand, and if not used correctly, can create adverse performance
problems due to changes in the underlying schema or row counts. This rules tends to flow
between both RDBMS’s.
In Oracle, the hint applies at the start of the select, insert, delete or update statement.
where [text] are one or more additional options for the actual hint.
There can be one or more hints specified that can work over any views/tables used in the from
clause of the statement. In all cases, the cost based optimiser will be used (except of course
when the RULE hint is used).
302
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
In SQL Server the optimiser is COST BASED (there is no other option) and as one would also
expect, the range and type of hints vary significantly between two DBMS’s. The SQL Server
hint categories are:
a) index hints
a. INDEX
b) join hints
a. LOOP
b. HASH
c. MERGE
d. REMOTE
c) locking & isolation level hints
a. granularity (one per table)
i. PAGLOCK
ii. NOLOCK
iii. ROWLOCK
iv. TABLOCK
v. TABLOCKX
vi. LOCKX
vii. UPDLOCKX
viii. READPAST
b. Isolation (can be mixed with selected granularity hints)
i. HOLDLOCK
ii. NOLOCK
iii. READCOMMITTED
iv. REPEATABLEREAD
v. SERIALIZABLE
d) query hints (affects all operators in the statement)
a. HASH GROUP
b. HASH ORDER
c. ROBUST PLAN
d. FORCE ORDER
e. MERGE UNION
f. HASH UNION
g. CONCAT UNION
e) table hints (one per table)
a. FASTFIRSTROW
b. + index hints
c. + granularity hints
f) view hints
a. EXPAND VIEWS
b. NOEXPAND
c. Selected index hints also apply
g) other hints
a. FAST n-rows
b. MAXDOP degree-of-parallelism
c. KEEP PLAN
d. KEEPFIXED PLAN
303
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
-- TABLE HINT
SELECT <columns>
FROM mytable WITH (<hint>)
[WHERE <predicate>]
-- QUERY HINT
SELECT <columns>
FROM mytable
[WHERE <predicate>]
OPTION (<option hint>)
-- JOIN HINT
SELECT *
FROM orders LEFT OUTER <hint> JOIN customers
ON orders.customerid = customers.customerid
From the syntax above, we see that the hints themselves are broken down into two styles:
1) WITH
i. Can be specified for each table referred to in the DML, within the
brackets of the WITH statement we can specify multiple hints. SQL
Server will report syntax errors but will not report on un-used hints
unless you carefully check the execution plan.
2) OPTION
i. Can only be specified once for each whole SQL statement, meaning that
the option applied to the entire statement and any sub-queries specified.
If a UNION is used, then the last statement can only include the option.
3) Join Hint
i. Will enforce the join strategy between two tables. The CROSS JOIN will
require the hint to be wrappered in brackets.
NOTE - Using hints for remote queries (queries over linked servers, otherwise known as
database links) are not supported in SQL Server 2k, you will get the error: Server: Msg 7377,
Level 16, State 1, Line 1 Cannot specify an index or locking hint for a remote data source.
Comparing HINTS is very difficult; the list below is by far complete and will require a significant
amount of testing when porting SQL statements from one DBMS to another. It is recommended
that hints are stripped when porting SQL and evaluate the need for a SQL Server equivalent as
performance or locking issues dictate. We will only list Oracle hints where I believe there is a vague
resemblance to an equivalent SQL Server one.
304
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
NOTE - The NOLOCK, READUNCOMMITTED, and READPAST table hints are not allowed for
tables that are targets of delete, insert, or update operations. Microsoft Support Doc Q235880
describes issues with NOLOCK and READ UNCOMMITTED hints and the generation of transient
error messages to do with the processes reading data that is being moved or altered by
another user (dirty read).
Example Hint
BEGIN TRANSACTION
SELECT *
FROM PRODUCTS WITH (HOLDLOCK, ROWLOCK)
WHERE PRODUCTID = 1
COMMIT TRANSACTION
305
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
See table below, to review data types in SQL Server also consider this query:
306
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
307
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The text data type can be very restrictive in terms of SQL and T-SQL. You can not declare data
types of type text (or other binary types), LEN and other functions will not work:
308
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Dynamic SQL
It is very rare that the modern DBMS does not support dynamic SQL statements in some form,
within Oracle we have a choice of two methods:
DBMS_SQL package
mysqlstr varchar2(100);
numrows NUMBER;
cursorhandle NUMBER;
numrows := dbms_sql.execute(cursorhandle);
DBMS_SQL.CLOSE_CURSOR(cursorhandle);
mysqlstr varchar2(100);
These statements support all forms of DDL, DML and anonymous PL/SQL blocks. In SQL Server we
also have a choice of two methods:
EXECUTE
execute sp_executesql
N'INSERT INTO mytable VALUES(@col1, @col2)',
N'@col1 int',
N'@col2 varchar(50)',
@col1 = 10,
@col2 = 'This is an example'
The SQL in both cases are not parsed until the command is executed. It is also important to
remember that if the database context is altered via a dynamic SQL statement, then it will only
persist whilst the dynamic routine is run, for example:
309
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The sp_executesql system stored procedure has a number of benefits over EXECUTE:
generates procedure cache plans that will more likely benefit from reuse due to its
parameterisation (when part of a loop condition or the stored procedure is called often with
different values, then sp_executesql with parameters will benefit tremendously).
In terms of transaction context, the following example shows that both calls will retain their context
in terms of the current open transaction. Note that a Unicode string is required for both dynamic
procedures.
BEGIN TRANSACTION
set @mysql =
N'insert into mytable values (2)'
310
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
mystring VARCHAR2(100);
DECLARE @mystring VARCHAR(100)
Dynamic DBMS_SQL sp_execute_sql
SQL EXECUTE IMMEDIATE EXECUTE
Stored CREATE OR REPLACE PROCEDURE CREATE PROCEDURE
Procedure myprod [(<parameters>)] [owner].myproc[;version] <parameters>
[WITH <options>]
[FOR REPLICATION]
IS AS
[<local variables>] [<local variables>]
BEGIN
<body code>; <body code>
[EXCEPTION GO
WHEN <code>;
THEN <code>; ALTER PROCEDURE myproc[;version]
[WHEN OTHERS] <parameters>
END; [WITH <options>]
[FOR REPLICATION]
AS
[<local variables>]
<body code>
GO
User Defined CREATE FUNCTION [owner].myfunc
Function (<parameters>) RETURNS <datatype>
AS
[<local variables>]
<body code>
RETURN (<variable or statement>)
GO
Set current N/A SET <dbname>, eg: SET master
database
Precompiler PRAGMA <instruction> N/A
Statement
IF IF <expression> THEN IF <expression>
<code> [BEGIN]
[ELSIF] <code>
END IF; [END]
[ELSE]
LOOP LOOP -- No FOR loops in SQL Server, only the
<code> -- WHILE loop
311
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
END LOOP;
WHILE <condition>
WHILE <condition> LOOP BEGIN
<code> <code>
END LOOP; END
312
14
Chapter
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
O
ne of the big topics discussed a lot within Oracle mailing lists and news groups
is SQL*Net and the Listener to manage DBMS connectivity. Throughout this
chapter we will cover the SQL Server equivalent and associated connectivity
issues the DBA may face from time to time.
due to this, any changes in the server network utility require the instance to be re-
started (not great for 24x7 environments).
The instance listener is managed via the Server Network Utility found under the
Microsoft SQL Server group, this is installed once on the server. The utility allows
the DBA to specify what protocols are enabled for each instance and provides the
ability to alter various protocol specific settings (such as ports, encryption etc):
313
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
To view the underlying DLL for each protocol click on Network Libraries. The ss
prefix on the dll’s represents a server based network library; the ssnetlib.dll (super
socket) will also manage SSL encryption where appropriate (covered later in the
chapter).
The configuration and setup is very simple and requires little discussion. See the chapter
on security for information about protocol encryption. One point noting though about
TCP/IP connections, is the default port number of 1433. On installation this is setup
unless you entered a value explicitly, if another instance is using port 1433 it will auto
select another port on the first connection to the instance through that protocol. The
DBA should not use default port 1433 as it is a classic port for hackers.
NOTE – Take a careful look at the first few lines of your SQL Server instance log,
you will see information regarding the listener and the protocols and ports
supported.
314
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Multi-Protocol
The multi-protocol library is worth mentioning on its own. The library utilises the NT
remote procedure call (RPC) in addition to its network library. This protocol supports the
standard IPC calls supported by NT, namely tcp/ip (nacn_up_tcp), ipx/spx and named
pipes (nacn_np):
On instance startup, we will see something like this in the SQL Server log:
The net library will utilise a random port making hacking a little harder but going through
a firewall can be problematic.
Registry Entries
To verify the last instance connection from the client, goto the register entry last connect
for either multiprotocol connections (rpcnetlib) or super sockets network library:
To get a good summary of registry entries related to the network library API, check out:
http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/dbnetlib/htm/dbnetlib.asp
315
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
a) underlying server does not have the appropriate network libraries installed to
facilitate communication with the server (installing the client will resolve the
issue)
b) to run SQL Server client tools (such as Query Analyser, Profiler, EM)
c) want finer control over dbnetlib.dll (which talks to the SQL Server equivalent
ssnetlib.dll – the server will return a packet via UDP port 1434 listing instances
and their listener protocols for the clients dbnetlib.dll to decide what to do with
the client request for connectivity).
A classic example of utilising the client utility is to specify an alias to a SQL Server
instance. If the server is hosting multiple instances (all of which will talk on different
ports for there defined listener protocols), you may need to create an entry clearly
specifying the protocol and its properties in order to successfully connect. If you have
issues connecting from your SQL Server client tools, then double check your client utility
alias and its protocol and port properties (or create one if you have not).
Another example is ODBC and the SQL Server driver. Without the client utility and an
alias, I have found that connecting to a named instance on a non-default port will not
work.
316
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
ODS
The ODS (open data services) API manages connections and disconnections to SQL
Server as defined by the protocols enabled via the server network library utility for the
instance. The ODS talks using the TDS (tabular data stream) which is an application
level protocol; the TDS is encapsulated in the protocol stack as defined by the net library
listener.
The ODS API can be used by C++ developers to build extended stored procedures
(discussed later) that talk natively to SQL Server and the client via TDS. The books
online cover the API reasonably well with code examples and the associated header
and object libraries.
Use the portqry.exe command line utility to assist in tracing issues with TCP/IP ports.
This tends to happen when other services are using default ports of SQL Server (namely
1433). The utility is available in the operating systems resource kit.
Use the command osql.exe –L or isql.exe –L the instances may not necessarily be
running.
There are some great SQL Server hacking tools to search the network for running
instances, such as sqlping, sqlscanner, sqlcracker, sqloverflowdata, sqldosstorm, freely
available on the internet.
317
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
a) run mcc.exe
b) Add/Remove snap-in
c) Add the certificates snapin
d) You will be prompted to manage certificates for
e) My user account
f) Service account
g) Computer account
h) Select the local computer when asked what server to manage
i) If you selected service account, you will be provided with a list of services to choose from
j) OK
If you have issues with installation and error related to opening a connection to the
server due to SSL security issues, then try and remove (via export then delete) all
computer account certificates and try again. Once installed, re-import the certificates
and re-start the instance (see Q309398). The installation and manage of certificates can
be subsequently managed through the snap-in screen:
NOTE – The certificate must be registered with the full DNS name of your server.
NOTE - Only 40bit and 128bit certificates are supported. This may vary though
based on your SQL Server release and other government restrictions.
318
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
To enable encryption for the instance, open the server network utility and check the force
protocol encryption option. Be aware though, it affects all enabled protocols.
It is important to note that client encryption is enabled via the client network utility,
creating an alias and specifying encryption via the checkbox provided. This will encrypt
all incoming traffic from the specific client to the instance. When setup at the server
though, all inbound connections and data transfers to the server will be encrypted.
The only protocol that can be set up individually for encryption is multi-protocol by
selecting the properties button for the enabled protocol:
The multi-protocol encryption does not use SSL but the Windows RPC API and will not
work for named instances. In virtually all circumstances the DBA should use certificates.
SQLOLEDB
Virtually all connections to SQL Server are via SQLOLEDB, and it’s rare that other
providers are used, especially in the world of large scale VB development. The
connection sting is simple enough, but care must be taken based on the libraries being
exposed via the listener (Server Network Utility); this is especially relevant when different
protocols are being used or you are changing port numbers.
319
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Provider=SQLOLEDB;
Data Source=server-name or IP-address or server-name\instance-name;
Network Library= see list below (optional)
Initial Catalog=database name;
User ID=username;
Password=password;
This information is typically stored in an INI file or within the registry by the developers.
An example reg file to add an entry into the registry is: (save with a .reg extension and
simply run it, Windows will prompt you to continue with the addition of the registry
item):
[HKEY_LOCAL_MACHINE\SOFTWARE\AppName\DBConnStrings]
"MyApp"="Provider=SqlOleDb;Data Source=myserver;Initial Catalog=mydb;User
ID=myuser;Password=myuserpassword"
The network library parameter is very important when you need to hook into a specific
protocol enabled within the listener. If you do not specify it then you may be using a
protocol you did not intend to, or have difficultly connecting (specially when Multiprotocol
is the only one enabled on the listener). The position of the network library option is also
important within the connection string, I have had a range of issues with this and its a
down right pain to debug. Use the parameter immediately after the data course
parameter is used. The values for the parameter are:
A simple search on google.com for “oledb connection strings” or even better check out
www.connectionstrings.com (I didn’t believe it, but yes, one exists). To save you the
trouble of searching as I know you will be asking the question, to specify a specific port
use the parameter data source=xxx.xxx.xxx.xxx,2433.
Network Monitoring
Within SQL Server we can utilise the sp_monitor command to track packets received,
sent and in-error between now and its last execution. The results also translate to the
@@ equivalents as shown below:
320
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
select @@PACK_RECEIVED
select @@PACK_SENT
select @@PACKET_ERRORS
The default TDS packetsize is 4096 bytes and may be limited/altered by the network
library connection to the instance. The DBA can control this for the instance as a
configurable parameter (sp_configure):
Other command line utilities, such as BCP, include the –a switch to control packet size,
this can be handy when pumping through large amounts of data to the instance. Take
care with the parameter, and very large settings may degrade performance.
In terms of performance and monitoring, the DBA needs to have a clear understanding
of:
Careful consideration of this typically comes into play with replication and/or distributed
sites. The DBA may also need to check on the duplexing of backup files between servers
during the day and its associated impact on overall network performance.
The key to monitoring is via performance monitor (perfmon.exe). Some key areas to
watch for:
a) SQL Server Network reads/sec or writes/sec – high values measure how network
intensive the instance is. Match up values with user connections and network
queue lengths; and check application components being executed at the time to
try and drill through to the issues.
b) Utilise the Network Interface performance object and its associated counters
carefully. There are a variety of counters and all should be used with a thorough
understanding on the issues outlined above.
Consult with your network administrator on possible network settings (server and domain
controller configuration) to assist with further tuning. They usually have a host of utilities
to monitor traffic.
321
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
SQLDiag
Registry Information
--------------------
SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo:
-----------------------------------------------
DSQUERY: DBNETLIB
163.232.xx.xx: DBMSSOCN,163.232.xx.xx
myserver: DBMSSOCN,163.232.xx.xx,1433
SOFTWARE\Microsoft\MSSQLServer\Client\DB-Lib:
--------------------------------------------
AutoAnsiToOem: ON
UseIntlSettings: ON
Version Information
-------------------
ntwdblib.dll: 8.00.194
ssmsad60.dll: N/A
ssmsde60.dll: N/A
ssmsrp60.dll: N/A
ssmsso60.dll: N/A
ssmssp60.dll: N/A
ssmsvi60.dll: N/A
ssnmpn60.dll: N/A
dbmsadsn.dll: 8.00.194
dbmsdecn.dll: N/A
dbmsrpcn.dll: 8.00.380
dbmssocn.dll: 7.00.819
dbmsspxn.dll: 7.00.819
dbmsvinn.dll: 8.00.194
dbnmpntw.dll: 8.00.194
sqlsrv32.dll: 3.80.0528.00
odbc32.dll: 03.52
odbc32 driver: 03.80.0528
322
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
15
Chapter
Security
T
he topic of security can be as simple or as complex as you like, and with any
DBMS, this tends to cover a whole range of issues. Throughout this chapter we
will provide a general overview of the issues within the SQL Server
environment and couple these with some best practice tips.
Secured Installation
How thorough the DBA is with installation is a tricky question. First of all, if you are new
to SQL Server, then install your instances under a user that is part of the Administrator
NT role. It is important to keep the installation user separate from other NT users as you
can tighten security later down the track.
d) Create DB data and log file directories for database files to be created in
g) Login as Administrator of the server and alter the new users rights as follows
HKEY_LOCAL_MACHINE\Software\Microsoft\MSSQLServer
323
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
HKEY_LOCAL_MACHINE \System\CurrentCOntrolset\Services\MSSQLServer
or MSSQL$<INSTANCE> for named instances
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Perflib
i) Login as the SQL Server user and attempt to re-start the database, debug as
required via the Windows Event viewer and the SQL Server and SQL Agent logs
Consider using EFS (encrypted file system) for the directories used by the instance whilst
logged in as the service user account. This NT feature will be discussed later.
The DBA should be using an NTFS file system in all cases to utilise its fine grained file
level security features. If the instance is partaking in replication, use a domain user
rather than a local user account. Note that EFS will only work for NTFS file systems.
324
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The DBA should be the only user ever creating/deleting/altering login accounts within the
instance, no matter what the reason, be it development, test and especially production
servers. As such, we should not have:
Authentication Modes
The SQL Server DBA can make use of only two forms of end-user authentication to the
instance, that being:
325
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Oracle adds another layer of functionality with Oracle Advanced Security; there is no
equivalent option in SQL Server.
Ideally, all user logins to the SQL Server user databases use Windows Authentication.
This should be implemented as:
• Application database roles hold object privileges, database login allocated to these
• Logins in SQL Server associated with Local NT Groups on the database server
The use of NT Groups offer a lot of flexibility but care must be taken when providing
access (ie. the name of them should be self documenting to prevent “mistakes”). Apart
from security, this also allows you to provide other team members with the responsibility
for managing security and even better, can utilise the NT password expiration and
management routines (that are missing for mixed logins).
What you use is really dependent on the application itself and how it is architected. Even
more so, the underlying network is a key factor in determining what path to take. I have
always opted for mixed mode authentication, and a small number of secured NT logins
for the application (that COM+ components instantiate themselves under) with a couple
of mixed mode authentication DBA logins for general administration.
BUILTIN/Administrator Login
When the instance is installed, the administrator group and its users will instantly have
sysadmin access to your DBMS via the BUILTIN/Administrator SQL Server Login account.
To alter this and we can:
b) Under NT, create another group called “SQL Server Administrators” or something
like that and place the SQL Server user that starts the SQL Server service in it.
Grant access to any other server administrators access if they need sysadmin
access.
c) In SQL Server, re-create the NT login account linked to the new “SQL Server
Administrators” NT group (don’t re-create BUILTIN\Administrators).
326
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
By default, the service will be started via the local system account and its SQL Server
connection via “windows authentication”. As such, altering the BUILTIN/Administrators
account and revoking sysadmin access will prevent the service from running jobs. Funny
enough, you will see no errors in the SQL Server log or SQL Agent log in relation to this.
Jobs will simply not start and their “next run date” will be “unknown”. In the BOL, it
clearly highlights the fact that the SQL Agent server connection must have sysadmin
access. If you alter the BUILTIN/Administrator login and revoke sysadmin, remember
that this adversely affects the SQL Agent database connection that must be altered
accordingly.
c) guard it religiously
d) ensure backup and recovery documents clearly document its use, how to get the
password and associated responsibilities of using the login
What makes the SA account powerful is simply the sysadmin (System Administrator)
fixed server role. Never grant this privilege to any other user, there is simply no reason
to use it other than for DBA administrative tasks.
The DBA can not remove the SA account, just like the Oracle DBA cannot remove the
SYS account. The SA account is inheriantly the dbo user.
In SQL Server it is possible to login with one name and be connected to a database with
another (strange I know). This is called aliasing logins and should never be used. The
routine used to do it is:
327
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
use mydb
EXEC sp_addalias 'mylogin', 'myuser'
Where mylogin is the login name I used, which maps to the user name myuser. This is a
nightmare to administer and also for security reasons it should never be used.
To locate these users, look at the command sp_helpuser and the UserNameAliasedTo
column that is returned.
In SQL Server the DBA cannot manage passwords too well; mainly because of the fact
that Microsoft pushes windows logins (OS managed login) rather than SQL Server logins
(database managed login). It is rare for the security conscious DBA that null or blank
passwords exist, but to find them run this query:
select
name,
password
from master..syslogins
where (password is null or password = ‘’)
and name is not null
DBO Access
I can think of no valid reason what so ever for DBO privilege access for any standard (ie.
non sysadmin or backup admin) user in production. There should be no DDL changes,
the auditing is all in place, and any calls to a predefined SQL Server extended stored
procedure has been sorted out the appropriate access granted. With proper role
management DBO is not an option for any application.
The only problem here can be third party software that utilises SQL Server as its security
or other repository in order to run. I have come across a few products that prompt to for
the SA password, then end up creating a database with no other user but SA, only to
spend hours reading documentation and testing to change it.
In Oracle we have a variety of commands to lock, unlock, expire passwords, set quota
limits, control password reuse, grace times etc for resource and access management.
We have nothing of the sort in SQL Server, apart from Windows Authenticated user that
will of course utilise password management features of the operating system.
Password File
The Oracle password file will store passwords for users with administrative privileges.
There is no equivalent option in SQL Server.
328
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
To allow developer access to creating stored procedures as dbo and granting execute
access to the appropriate roles the DBA has created and documented, consider giving
your developers access to the database roles:
db_ddladmin
db_securityadmin
These privileges should be revoked in the test and of course production server
environments.
Lookup grant in the books online for a excellent matrix of database and instance level fix
role privileges.
The first aim is to hide and/or secure the connection string used at the Web-Server in
order to connect to the database. This does not stop a hacker from installing their own
COM/COM+ objects that talk to your existing methods and utilise the business logic
exposed through them. But you do want to stop at all costs complete access to your
user database through an insecure connection string placed in an INI file on the server.
The second aim is to determine the access method to the database. We can either use
mixed mode or windows authentication.
NOTE - The ideas below can be cumulative, ie. they do not necessary describe a
complete solution, but a variety of ideas for securing general connectivity to the
database.
329
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Authentication Example
o Consider HTTPS where appropriate. I have worked with the Athelon SSL
accelerator (hardware) with great reliability and performance. Such
hardware can selectively encrypt/decrypt and supports hundreds of
simultaneous SSL connections per second but is a very expensive option
and is another “point of failure”. Remember that once on the Internet,
network sniffers can make short work of passwords and sensitive business
data (to and from your server).
o Under IIS, if all are selected then the highest to the lowest level of security
will be used in order based on what the client initially accepts. An NTFS
partition must be used for Digest and Integrated.
o Basic
330
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
o Digest
o Integrated
• COM+ (from a security context - there are also numerous other performance
and feature benefits to the programmer)
o Client authentication
331
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
c) Ideally, encrypt data where appropriate between client and webserver (out of scope
for this section)
d) Use only Windows Authentication for SQL Server login, deny local server login for
these accounts.
Presented below are a series of diagrams that provide a catalyst for ideas in achieving
this security. The examples all assume a COM+ (Component Services) business layer as
a default for Enterprise Computing. Substitute this for COM as required. I do not
recommend straight DB connection from ASP (global.asa variables etc) to the database
for any sort of internet based application.
2. Add registry entries and protect via regedit32.exe for database connection
strings. The COM+ package will run as a specific local domain user and
connects to the database via integrated security.
3. As per 1, but rather than using the registry with encrypt the INI file via
Windows 2k encrypted file system (EFS). As the encryption is based on a
specific user profile this can be a little more difficult to manage if the
COM+ package runs as a different user.
4. Set-up a series of User DSN’s that are only accessible by the Windows user
that created them. These typically map to a 1:1 SQL Server login.
5. Rather than using the registry, use Active Directory (Win 2k) for other 3rd
party LDAP directory to store connection strings. Access is restricted via
Windows Authentication and is always read-only.
7. COM+
332
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Over the years I have talked to a variety of people about application design and how data
models are simplified via views and stored procedures to access and manipulate data.
Although fine, it can be a hard sell to programmers, analysts and project managers.
Why? because many programmers want complete CRUD access to virtually all schema
tables, they want to code all DB access via the application and believe views are only for
reports and simplifying complex lookups.
When under pressure, the time to sit back and think “security” and “performance” is a
tough ask. This is very simplistic view of course as security at this level in the database
is typically dictated by:
333
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
e) Skills to implement
f) Ease of maintenance
I like to take the approach of not exposing more data than you have to in selected areas
within the application. Exposure to CRUD (create,read,update,delete) level can be
implemented by views, stored procedures, roles, table priviligies, instead-of triggers and
other object level and column privileges.
The use of views is an excellent method of implementing security and hiding schema
relationships and relational database complexities. Each table has an equivalent simple
or complex view; the views may include instead-of triggers to re-direct DML to other
"hidden" tables for complex views, for auditing or data partitioning. If instead-of triggers
to do appeal to you, another option for managing CUD (create/update/delete) access is
to grant select only access to the views and implement all CUD via predefined stored
procedures. Therefore, the database users view of the actual database structure may be
quite different from that of the schema owner and how they manipulate it is restricted by
the stored procedures (business rules).
Another approach is only using stored procedures for insert, delete, update and select
access and access to the database schema is only via these stored procedures. This can
have significant performance benefits also due to caching of procedure execution plans.
On top of this, you can lever the benefits of OPEN XML.
Getting back to security, you can effectively deny all access to tables, and implement all
CRUD through stored procedures. The only problem with this is a T-SQL one, which is its
poor exception handling (ie. none!).
The use of views and stored procedures also assist in application maintenance (no
embedded SQL statements in your COM+ and ASP code) and makes impact analysis of
schema change and performance tuning much simpler.
334
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
NOTE - It is important to remember that you do not need to grant CRUD access
to the tables and views and stored procedure is referring to, only to the procedure
itself.
The Oracle virtual private database option is managed via the DBMS_RLS (row level
security) package. This option allows fine grained access control (FGAC) to table and
view data, making sure a user only sees data they are allowed to see, no matter how
they access the data (SQL*Plus or a prewritten Application). There is no equivalent
option in SQL Server.
Label Security
The Label Security option use the virtual private database feature to implement row level
security. By creating policies, row data can be tagged (based on sensitivity) to assist in
managing and controlling access to table data.
This is a real tough command to administer. Why? every project I have worked on to
date has some need for it. Because of the fact that SA is the only user with sysadmin
access, rather than creating a special account or looking at other work-arounds, the SA
account is used to execute the task. Classic examples are stored procedures wrapped up
in DTS jobs or supposed global “administrative” functions. This is problematic because:
a) now “application” databases are using the SA account and rely on it to run their
jobs.
c) xp_cmdshell will be executed under the security context in which the SQL Server
service is running
Points a) and b) are obvious and the fix is a simple matter of explicitly granting execute
access to xp_cmdshell via a role and allocating that role to a managed and secure
database user whose actual login is rarely used (ie. DTS connectivity only to run the
command shell tasks).
Point c) is the very important. If the database user is a member of sysadmin then, more
than likely, the user will have “local administrative” privileges to the server, as this is the
user running the MS SQLServer and associated services. This is even more the reason
why not to use the SA account. If the user is not a sysadmin but has been granted
335
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
execute access as described above, then the SQL Server Agent proxy service user will be
used instead.
The SQL Server Agent proxy account can be altered via xp_sqlagent_proxy_account
(undocumented in BOL) which defines the account used to run the SQLServerAgent
service. This may be your SQLServer NT user if you are not using the Administrator
account (which is bad security practice), so you may decide to alter this to another user
with restricted access rights for finer control to the operating system.
In the end, xp_cmdshell should be carefully evaluated before using it. Ideally it should
be totally disabled (revoke execute permission) for ultimate security. Look at using isql
jobs scheduled via AT and look closer at the options available to you via DTS.
OLE Automation
Sp_OACreate
Sp_OADestroy
Sp_OAGetErrorInfo
Sp_OAGetProperty
Sp_OAMethod
Sp_OASetProperty
Sp_OAStop
Registry Access
Xp_regaddmultistring
Xp_regdeletekey
Xp_regdeletevalue
Xp_regenumvalues
Xp_regread
Xp_regremovemultistring
Xp_regwrite
Other routines
sp_sdidebug
xp_availablemedia
xp_cmdshell
xp_deletemail
xp_dirtree
xp_dropwebtask
xp_dsninfo
xp_enumdsn
xp_enumerrorlogs
xp_enumgroups
xp_enumqueuedtasks
xp_eventlog
xp_findnextmsg
xp_fixeddrives
xp_getfiledetails
xp_getnetname
xp_grantlogin
xp_logevent
xp_loginconfig
xp_logininfo
336
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
xp_makewebtask
xp_msver
xp_perfend
xp_perfmonitor
xp_perfsample
xp_perfstart
xp_readerrorlog
xp_readmail
xp_revokelogin
xp_runwebtask
xp_schedulersignal
xp_sendmail
xp_servicecontrol
xp_snmp_getstate
xp_snmp_raisetrap
xp_sprintf
xp_sqlinventory
xp_sqlregister
xp_sqltrace
xp_sscanf
xp_startmail
xp_stopmail
xp_subdirs
xp_unc_to_drive
It should be very rare that DTS creation and editing in production is required unless of
course during emergency fixes. You may have routines that dynamically create jobs, add
job steps (classic examples are backup routines) where the above may need to be
rethought, but in a majority of cases DTS can be safely locked out.
By default in SQL Server 2k the DTS job is encrypted but unless you specify a password
they remain editable.
It is important to remember that SQL Servers access model for DTS packages is, well,
limited. Meaning that only members of sysadmin can edit and save any package they
like, but all other users are restricted only to the packages they initially created
themselves. This holds true even when you try and give users dbo access to the MSDB
database in a vain attempt to “share” packages with other database users. To get
around some of these issues read the chapter on Managing Databases.
337
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Within the SQL Server architecture these privileges are wrapped up into server roles
that exist at a variety of “levels” within the instance. These are shown below:
The roles of course are similar to Oracle roles, where a fixed role allocation can
provide to user with numerous bundled system and object privileges.
BACKUP DATABASE
BACKUP LOG
CREATE DATABASE
CREATE DEFAULT
CREATE FUNCTION
CREATE PROCEDURE
CREATE RULE
CREATE TABLE
CREATE VIEW
CREATE INDEX
CREATE STATISTICS
<..etc..>
Typically, such statement privileges are naturally inherited from fixed server roles
and other fixed database roles. For example, CREATE DATABASE is granted
automatically
with the sysadmin and dbcreator fixed server roles. On top of this, you may also
get extended privilege (WITH ADMIN in Oracle) to grant this statement privilege to
other
users as the sysadmin and securityadmin fixed server roles can do. This can become
somewhat complex and its well worth exploring in details before allocating fixed
server and fixed database roles to any user.
We will not compare every Oracle system privilege with SQL Servers statement and
other privileges, but, we will compare SQL Server fixed server and database roles
with Oracle.
338
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
The fixed server roles in SQL Server are basically made up of the SYSDBA and SYSOPER
accounts and the grant DBA privilege in Oracle. The permissions are high level ones that
are really aimed at the DBA or the System Administrator. In no circumstance should you
allocate any other user to these accounts.
I do not grant any user these privileges, think long and hard account your senario before
giving an account access to these (typically the db_owner database privilege is the
highest I would grant).
To get an better idea as to what is included in the privilege, use EM, Security Æ
logins Æ select a user, properties, Server Roles tab, select a role and click
properties, for example:
339
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
RESOURCE
DBA
Db_datareader N/A Read access to any table or view
but not stored procs or UDF’s.
Db_datawriter N/A Write access to any table or view.
Db_ddladmin CONNECT Alter or create or drop any user
RESOURCE definable database object.
DBA
Db_backupoperator SYSDBA Can issue backup, checkpoint,
SYSOPER DBCC commands.
EXP_FULL_DATABASE
IMP_FULL_DATABASE
Db_securtityadmin CONNECT Deny, grant and revoke
RESOURCE permissions.
DBA
Db_accessadmin CONNECT Can add or remove users.
RESOURCE
DBA
Db_denydatareader N/A As per data reader by deny the
privilege.
Db_denydatawriter N/A As per data writer by deny the
privilege.
Oracle recommends you don’t use the predefined roles, but build a custom set of
privileges.
The name explains it all, they are the same in Oracle. They are simple enough to
manage and require no explanation. The DBA cannot alter fixed database and instance
roles.
Object Privileges
The management of object level privileges is Oracle and SQL Server are essentially the
same. The DBA can grant the basic select, insert, update, delete, execute, and
references (DRI) privileges to tables, views, stored procedures and user defined
functions. At a lower level, the DBA can also grant virtical security at a column level via:
Use the DENY command if you want to retain the permission in the role and/or user but
close off access temporarily.
The CASCADE option will revole the privilege for all users part of the role, in this case the
public role.
The public role should be left alone where possible, meaning that the DBA should create
their own version of the role and allocate privileges through that. The public role includes
these standard permissions begin tran, print, rollback tran, set, commit tran, raiserror,
save transaction.
340
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
No database user in SQL Server can create objects with being explicitly granted the
permission to do so. The DBA should carefully consider the implications of granting the
the db_ddladmin database role or explicity granting the create table or view statements.
The objects by default will be owned by the user unless explicitly prefixed with dbo.
This is unlike oracle where we would need to revoke access to say, create table etc
after allocating the 'connect' role.
Auditing
Application Auditing
There are no SYS$AUD objects as in Oracle to assist the SQL Server DBA with auditing of
user databases and its objects; this is a right pain as the classic fix is typically a range of
triggers that log inserts, updates, deletes against the table(s). Here is an example of
some simple auditing in action:
SET NOCOUNT ON
SET @current_time = GETDATE()
SET @insert_count = (SELECT COUNT(*) FROM INSERTED)
SET @delete_count = (SELECT COUNT(*) FROM DELETED)
/* A record is updated */
IF @insert_count > 0 AND @delete_count > 0
BEGIN
INSERT INTO Dbo.MyTable_Audit
341
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
(
col1_code,
col2_desc,
update_count,
last_updated_on,
last_updated_by,
Audit_Action, Modified_By, Modified_Time
)
SELECT
col1_code,
col2_desc,
update_count,
last_updated_on,
last_updated_by,
2, last_updated_by, @current_time
FROM INSERTED
END
/* A record is deleted */
IF @insert_count = 0 AND @delete_count > 0
BEGIN
INSERT INTO dbo.MyTable_Audit
(
col1_code,
col2_desc,
update_count,
last_updated_on,
last_updated_by,
Audit_Action, Modified_By, Modified_Time
)
SELECT
col1_code,
col2_desc,
update_count,
last_updated_on,
last_updated_by,
3, last_updated_by, @current_time
FROM DELETED
END
If you are using identity columns on your trigger tables as well as the sourse table, then
the application must use the @@SCOPE_IDENTITY() function to source the correct
identity value from an insertion. The last thing you want to do is to capture the identity
value from the trigger table.
342
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
Expanding on the trigger and tables above, the scenario we are using is this:
USERA
Mycom.ini
USERX
COM+ component
(business layer) connects
to DBMS via USERX in INI select only
file access
mytable mytable_audit
Trigger fires
This creates some issues the DBA must be aware of, namely:
• if triggers are off (disabled) whilst initially migrating data into the table, then you
will not record the first “insertion” audit entry for the record. This may have flow
on issues later down the track.
• The application layer must manage issues with concurrency in a stateless web
environments. This is typically done by columns for each table such as
update_count, last_updated_on, last_updated_by which can also be used for
auditing. As in the example above, last_updated_by must be passed in from the
application and not sourced from the DBMS.
• If you don’t update the record before deleting it, then you will capture the wrong
user who actually performed the deletion, as we are simply using the
last_updated_by column to record the user who performed the operation. As
mentioned in c), we can not use the USER_NAME() system function as all users
stream through a single (common) login via the applications business layer.
The DBA should work closely with the developers and establish the auditing schemes
early on in the project cycle, especially in terms of recording update by and updated on
information. The DBA should ask:
• how the end users will interact (search) over the audit data and the associated
indexing issues. How will the added indexing affect OLTP performance?
343
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
• how roles will be used to control CRUD access to the audit tables
• consider writing a generic audit display framework for your application rather than
writing custom reports
• remember the text, ntext and image restrictions within triggers and communicate
these to the analysts/developers
Profiler (trace)
The DBA can also audit via profiler, letting it run for a period of time collecting a variety
of events for the DBA to review (use sp_trace rather than the GUI, use the GUI to
generate the script for you). Although fine, this method may not be practical and may
drive down performance slightly.
The trace utility will not trace sp_addlogin and associated routines dealing with
passwords.
exec xp_instance_regwrite
N'HKEY_LOCAL_MACHINE',
N'SOFTWARE\Microsoft\MSSQLServer\M
SSQLServer',N'AuditLevel',
REG_DWORD,2
A restart may be required for the property to take affect due to the registry change. To
read the current value, use the command:
344
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
C2 Level Auditing
For detailed information on C2 level auditing in SQL Server see the books online. I would
not recommend it unless you have explicit requirement to do so.
See the chapter on Networking for more information on protocol encryption. Basically,
SQL Server supports 40 and 128bit SSL encryption of its listener protocols and of course
standard NOS encrypted Windows authentication (kerberos), whereas Oracle supports a
large range of other encryption methods through the Oracle Advanced Security option.
Most will agree that SSL is the better way to go.
Before using this option, the DBA should have their instance service(s) running under a
custom NT user rather than the Administrator account, see Secured Installation
previously discussed.
Login as the service account and shutdown all instance services. Once done, goto the
directory you want to EFS encrypt via Explorer, right client properties, advanced button
and check the encrypt contents to secure data option:
345
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
You may be prompted about encrypting the this folder only or this folder and all sub-
folders, and then asked about encrypting the parent folder (does all existing and any new
files in the folder) or just this file, in most cases you will want the entire folder:
To check on the status of encryption via the command line, utilise the cipher.exe
command with no parameters. The “U” of course meaning un-encrypted. Take a close
look at the command options via the /? Switch, namely the /E (encrypt) and the /D (de-
encrypt) switches.
The WITH ENCRYPTION option can be used with stored procedures and views to encrypt
their contents. I wanted to believe that SQL Server 2k under Windows 2000 was using
the Windows Crypto API and as such, was using a key complex enough to make hacking
very difficult. Then I came across this article from www.SecuriTeam.com:
346
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
http://www.securiteam.com/windowsntfocus/6Q00H2A3FY.html
I have to say that security specialists and hackers are some of the most sarcastic people
I know! but with good reason. The articles example, which I have tested under SQL
Server 2k, shows you all the code of a stored procedure created with the WITH
ENCRYPTION option.
“Here is how stored procedure (and view and trigger) encryption works on SQL Server 2000:
1. Take the database's GUID (generated when the db is created), the object id (from sysobjects) and the
colid (from syscomments) and concatenate them.
2. Hash the key using SHA.
3. Use the SHA hash as an RC4 key, generate a sequence of bytes equal in length to the stored procedure
text.
4. XOR this stream of bytes against the stored procedure text.”
The example given in the article works with any user that has priviligies to create and
alter procedures and select access against syscomments. To help mitigate the problem:
c) See previous notes on restricting DBO access and sysadmin access to your
database.
With all this said, I believe it is still worth the effort to encrypt code. It is though,
imperitive that your test t-sql code execution thoroughly to determine the CPU impact
this may have on execution (though I would imagine it to be very small).
T-SQL
There are no native encryption or obfuscation options available to the T-SQL developer
with SQL Server. In Oracle the developer may utilise the dbms_obfuscation_toolkit, but
in SQL Server the developer must either code their own, or utilise another language and
its API calls (OS or language dependent).
Some DBA’s actually regard database encryption as bad practice. I tend to disagree and
can think of a variety of reasons where, especially one way encryption, would be
required. The trick here is private key management and exposure of the de-encryption
functions/routines. This requires very careful planning and realisation of the security
risks and possible litigation if data is cracked. Developers in .Net will find the new system
calls very helpful.
347
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
INDEX
Data transformation service · 237
Data types in SQL Server · 306
A Database connection · 17
Database links · 229
ado-md · 217 DATABASEPROPERTYEX · 85
alert log · 227 Datafiles · 5
Archived redo log · 7 Date functions · 295
authentication · 325 DBCC · 65
DBCONTROL · 85
DBMS_JOB · 284
B DBMS_LOB · 287
DBMS_MAIL · 283
Backup DBO privilege · 328
history of · 95 dbrepair · 104
no more space · 96 DBVERIFY · 65
backup set · 78 DbwN · 20
BFILE · 287 Deadlocking · 126
Block size · 25 developer
boot.ini · 11 security rights · 329
Buffer cache · 12 diagrammer
BUILTIN/Administrator · 326 scripting · 90
BUILTIN/Administrators · 53 differential backup · 81
bulk insert · 66 dso · 217
Dynamic SQL · 309
C
E
cell security · 215
CHECKALLOC · 104 Editions · 37
CHECKDB · 104 Encrypted file system · 44
Checkpoint · 18 encryption
Ckpt · 20 multi-protocol · 319
Client Network Utility · 316 error log · 227
collation Explain plan · 137
database · 203 Extended stored procedures · 18
Collation Extents · 26
Column · 204
COM+ · 169
COM+ isolation level · 171 F
COM+ proxy · 172
command shell · 281 Federated databases · 187
component load balancing · 185 File IO statistics · 160
Connection · 17 Fillfactor · 26
Control file · 4 for xml · 283
Corrupt Fragmentation · 30
indexes · 104 FREELISTS · 26
Counters full backup · 80
performance monitor · 142 Functions
user defined · 278
Data dictionary · 5
348
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
G M
I
N
IAM · 28
identity · 289 network load balancing · 183
Index Network monitoring · 320
tuning wizard · 134 Northwind
index types compared · 289 re-install · 105
Indexes Numerical functions · 293
composite · 152
fragmentation · 156
function based · 152 O
rebuilding · 158
skewing · 155 Object
types of · 150 change owner · 253
information schema · 283 check ownership · 253
installation ODS · 317
security of · 323 olap
Installation · 37 administer · 210
Instance · 1 backup · 219
Named · 4 installation · 208
repository migration · 211
security · 215
J storage models · 213
Open Data Services · 317
JServer · 66 OPENQUERY · 236
OPENROWSET · 235
OPS$ login · 252
K Optimal Flexible Architecture · 48
orphaned session · 256
Kill user sessions · 254
Killing users · 92
P
L Package · 278
pad_index · 26
Label Security · 335 Page free space · 27
Latch statistics · 140 Page splitting · 140
Lgwr · 20 Page types · 25
License Manager · 40 Parallel
Licensing · 38 affinity option · 301
Linked Server · 229 IO · 302
Listener · 68, 313 query · 301
log miner · 69 password file · 328
log shipping · 189 passwords
login vs user · 325 finding null · 328
349
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
350
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
User V
database ownership · 252
orphaned · 251 Versions · 37
resource quota · 252 Virtual address space · 11
user accounts virtual private database · 335
quotes, resource restrictions · 328
user defined function · 288
W
351
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
References
Please take the time to refer to these references from DBA experts around the world.
(1) What is the Maximum page size in SQL Server 2000?, Steve Jones, 7/2/2002,
http://www.sqlservercentral.com/columnists/sjones/pagesize.asp
(2) SQL Server 7: Some Useful Undocumented DBCC Commands, Alexander Chigrik,
22/10/2001,http://www.sqlservercentral.com/columnists/achigrik/sqlserver7someusef
ulundocumenteddbcccommands.asp
(3) Oracle Concepts: The Instance and the Database, Joe Lax,
http://www.devx.com/dbzone/articles/laxseries/lax082001/lax082001.asp
(4) INF: Job to Monitor SQL Server 2000 Performance and Activity, Microsoft Support,
http://support.microsoft.com/default.aspx?scid=kb;en-us;Q283696
(5) http://support.microsoft.com/default.aspx?scid=kb;EN-US;q272428
(6) Memory Management, Can a readme file contain extra memory, Kalen Delaney, March
2001, http://www.sqlmag.com/Articles/Index.cfm?ArticleID=16522
(7) Technology Comparison Discussion, Microsoft,
http://www.microsoft.com/sql/evaluation/compare/discussion.asp
(8) How to Migrate Unix based Oracle Applications to Windows and SQL Server, Microsoft,
http://www.microsoft.com/windows2000/migrate/unix/unixoracle.asp
(9) MS SQL Server 2000 Books Online
(10) Oracle9i Database : The Power of Globalisation Technology, An Oracle Whitepaper
[February] [2002]
(11) Best Practices for Globalisation using the Oracle 9i Internet Application Server,
Simon Wong, July 12 2001, v1.0
(12) Oracle 8i/9i and Microsoft SQL Server 2000 A comparative Study from a
Developers and DBA Perspective, Sriram Kumar, April 2002.
(13) SQL Server: Enterprise vs. Standard, Rahul Sharma, 19/4/2002,
http://www.sqlservercentral.com/columnists/rsharma/enterprisevsstandardedition.asp
#_ftnref3
(14) http://msdb.microsoft.com/library/en-us/vbcon98/html/
(15) Data Concurrency and Consistency, Oracle Documentation, Oracle 9i database
concepts,
http://otn.oracle.com/docs/products/oracle9i/doc_library/release2/server.920/a96524
/c21cnsis.htm#2841
(16) PRB: How to recover SQL Server After a Tempdb Database is Marked Suspect,
Microsoft Support, http://support.microsoft.com/search/preview.aspx?scid=kb;en-
us;Q288809
(17) Transferring a SQL Server Diagram, Brian Knight, 24/5/2002,
http://www.sqlservercentral.com/columnists/bknight/transferdiagram.asp
(18) Managing Rollback/Undo Segments in AUM (Automatic Undo Management),
Note:135090.1
(19) Creating, Optimizing, and Understanding Rollback Segments, Note:62005.1
(20) Inside SQL Sever: Parse, Compile, and Optimize, Introduction to the query
processor, Kalan Delaney, December 1999,
http://www.sqlmag.com/Articles/Index.cfm?ArticleID=7446
(21) Oracle Bulletin – Checkpoint Tuning and Error Handling
(22) Query Recompilation in SQL Server 2000, Thomas Davidson, Microsoft Corporation,
May 2002 [http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/dnsql2k/html/sql_QueryRecompilation.asp]
(23) www.sql-server-performance.com
(24) www.sqlteam.com
(25) Optimizing SQL Server Performance by using File and Filegroups, Alexander Chigrick,
27/9/2001, http://www.sqlservercentral.com/columnists/achigrik/fileoptimtips.asp
352
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
(26) Improving text and image column performance, Brian Knight, 1/4/2002,
http://www.sqlservercentral.com/columnists/bknight/textinrow.asp
(27) Microsoft SQL Server 7.0 Performance Tuning Guide, Henry Lau, Microsoft
Corporation, October 1998,
http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/dnsql7/html/msdn_sql7perftune.asp
(28) Microsoft SQL Server 7.0, Storage Engine Capacity Planning Tips, Microsoft
Coorporation, March 1999,
http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/dnsql7/html/storageeng.asp
(29) “What rules of thumb you live by when programming?”, SQL Server Central forum
posting(s),http://www.sqlservercentral.com/forum/topic.asp?TOPIC_ID=2772&FORU
M_ID=61&CAT_ID=5&Topic_Title=What+rules+of+thumb+you+live+by+when+progr
amming%3F&Forum_Title=Anything+that+is+NOT+about+SQL%21
(30) Inside Microsoft SQL Server 7.0, Book Sale Site,
http://mspress.microsoft.com/prod/books/2394.htm
(31) INF: How to Use KEEPFIXED PLAN to Disable Stored Procedure Recompilations,
Microsoft Support, http://support.microsoft.com/search/preview.aspx?scid=kb;en-
us;Q276220
(32) Minimizing the Number of Log Backups, Andy Warren, 11/5/2001,
http://www.sqlservercentral.com/columnists/awarren/logbackup.asp
(33) Logins, Users, and Roles –Getting Started, Andy Warren, 20/11/2001,
http://www.sqlservercentral.com/columnists/awarren/loginsusersandrolesgettingstart
ed.asp
(34) Don’t shutdown that database! Use Oracle 9i Online Object Redefinition, Chris
Lawson, Copyright 2002 Database Specialists,
http://www.dbspecialists.com/presentations/online_redef.html
(35) Network Load Balancing Service, Tony Norhrup,
http://www.mcpmag.com/reviews/Services/article.asp?EditorialsID=1
(36) http://www.microsoft.com/ntserver/downloads/bin/nts/clustering_apps.exe
(37) INF: SQL Virtual Server Client Connections Must be Controlled by Clients, Microsoft
Support, http://support.microsoft.com/default.aspx?scid=kb;EN-US;q273673
(38) http://www.microsoft.com/israel/events/presentations/teched2002/inf305.ppt
(39) New SQL Server 2000 Data Types, Brian Knight, 14/5/2001,
http://www.sqlservercentral.com/columnists/bknight/sql2knewdatatypes.asp
(40) INF: How to enable Analysis Services to use 3 Gb of RAM, Microsoft Support,
http://support.microsoft.com/search/preview.aspx?scid=kb;en-us;Q295443
(41) Intro to User defined functions, Garth Wells, 8/1/2001,
http://www.sqlteam.com/item.asp?ItemID=1955
(42) Information Schema Views, Brian Kelley, 9/1/2002,
http://www.sqlservercentral.com/columnists/bkelley/informationschemaviews.asp
(43) Keep SQL Server Up and Running – Availability enhancements in SQL Server 2000
can keep your business going 24x7, Kalen Delaney, Dec 2000,
http://www.sqlmag.com/Articles/Index.cfm?ArticleID=15742
(44) DBCC SHOWCONTIG, SQLMag.com Forum Post,
http://www.sqlmag.com/Forums/messageview.cfm?catid=3&threadid=6878
(45) Understanding MS SQL Servers SHOWPLAN Output, Microsoft,
http://www.microsoft.com/technet/treeview/default.asp?url=/technet/prodtechnol/sql
/maintain/featusability/showplan.asp
(46) http://webtool.rte.microsoft.com/tutor/perf_NT4.htm
(47) Transact-SQL Language Reference Guide, Randy Dyess,
http://www.transactsql.com/Manuscripts/tslrg.html
(48) Microsoft T-SQL Performance Tuning, Part 1: Analysing and Optimizing T-SQL Query
Performance on Microsoft SQL Server using SET and DBCC, Kevin Kline, 2002, Quest
Software
(49) Understanding Execution Plans Part 1, Robert Marda, 26/7/2002,
http://www.sqlservercentral.com/columnists/rmarda/understandingexecutionplans.as
p
353
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
(50) INF: Moving SQL Server Databases to a New Location with Detach/Attach
http://support.microsoft.com/default.aspx?scid=kb;en-us;Q224071
(51) Microsoft SQL Server Administration FAQ,
http://vyaskn.tripod.com/administration_faq.htm
(52) MS SQL Server Performance Tuning and Optimisation for Developers, Part 3,
Configuring SQL Server for Performance, Adam Shapiro, 1997,
http://www.microsoft.com/technet/treeview/default.asp?url=/TechNet/prodtechnol/sq
l/maintain/optimize/dat412ef.asp
(53) Chapter 9 – Server Architecture, Microsoft,
http://www.microsoft.com/technet/treeview/default.asp?url=/TechNet/prodtechnol/sq
l/proddocs/intro/part3/75515c09.asp
(54) Oracle 9i Application Server: Availability, Scalability, and Manageability of J2EE and
Web Cache Clusters, An Oracle Whitepaper May 2002.
(55) Clustering Web Accelerators, Presented at IEEE WECWIS, San Diego, June 28th
2002, James Feenan, Patrick Fry, Ming Lei.
(56) How to Setup Log Shipping Microsoft SQL Server 2000, Purna Gathani.
(57) Like without model, Jasper Smith, 28/7/2002,
http://www.sqlteam.com/item.asp?ItemID=10060
(58) The FROM clause, Bill Graziano, 25/6/2002,
http://www.sqlteam.com/item.asp?ItemID=9867
(59) INF: Effect of Database File Additions or Deletions on Database Recovery, Microsoft
Support, http://support.microsoft.com/default.aspx?scid=kb;en-us;Q286280
(60) Quest – Knowledge Expert for Oracle Administration v6.1.1
(61) Developing Databases with Microsoft SQL Server 7.0 – Transaction Processing
(62) How to Diagnose and Fix Wait Locks, Cathan Kirkwood, 21/11/2002.
(63) Stored Procedures and Caching, Brian Kelly, 28/1/2002
(64) Managing Extended Properties, Bill Vaughan, July 2001, SQLMag.com
(65) Optimizing Stored Procedures to avoid recompiles,
http://www.transactsql.com/Articles/OSPR.html, Randy Dyess 2002
(66) Version Control for Stored Procedures, Andy Warren, 10/5/2002
(67) Understanding parallel queries in SQL Server v7.0, Scott Mauvais, May 2000,
http://www.mauvais.com/PubsCached/ZD-Parallel.htm
(68) Documented and Undocumented Trace Flags for SQL Server 2000 and 7.0, Randy
Dyess, 2002,
http://www.sqlservercentral.com/columnists/RDyess/traceflags_printversion.asp
(69) Indexed views in SQL Server 2000, Doug Carpenter, 18/10/2002
http://www.sqlteam.com/item.asp?ItemID=1015
(70) INF: How to Automate an Archive or Backup of OLAP Database, Microsoft Support,
http://support.microsoft.com/default.aspx?scid=kb;en-us;294287
(71) HOW TO: Setup and Troubleshoot a Linked Server to Oracle in SQL Server, Microsoft
Support, http://support.microsoft.com/search/preview.aspx?scid=kb;en-us;Q280106
(72) INFO: Limitations of Microsoft Oracle ODBC Driver for OLEDB Provider, Microsoft
Support, http://support.microsoft.com/default.aspx?scid=kb;en-us;Q244661
(73) Transact-SQL.com, http://www.transactsql.com/sprocs/sp_tempdbspace.html
(74) Index maintenance, Baya Pavliashvili, 06 Aug
2002,http://searchdatabase.techtarget.com/tip/0,289483,sid13_gci841586,00.html
(75) Using the SQL Server Transaction Log to Improve Database Availability and
Performance, Lev Vaitzblit, http://www.dbta.com/transactionlog/index.html
(76) How to restart SQL Server service at regular intervals?,
http://vyaskn.tripod.com/restart_sql_server_service.htm
(77) How to troubleshoot orphan users in SQL Server databases?,
http://vyaskn.tripod.com/troubleshooting_orphan_users.htm
(78) FIX: AUTO-SHRINK Option or DBCC SHRINKDATABASE May Slow Down SQL Server
2000 Performance, http://support.microsoft.com/default.aspx?scid=kb;en-us;296386
(79) Introducing Indexed Views – SQL Server 2000 unviels another path to peak
performance, May 2000, Kalen Delaney
(80) What's in an ADO Connection String?, John Peterson,
http://www.asp101.com/articles/john/connstring/default.asp
354
S Q L S E R V E R 2 0 0 0 F O R T H E O R A C L E D B A
(81) HOWTO: Set the SQL Server Network Library in an ADO Connection String,
Microsoft Support, http://support.microsoft.com/default.aspx?scid=kb;en-us;238949
(82) Securing your SQL Server, Brian Knight, 14/5/2001,
http://www.sqlservercentral.com/columnists/bknight/securitypitfalls.asp
(83) SQL Server Security FAQ, http://www.sqlsecurity.com/faq.asp
(84) Administering User and Security, Kevin Cox and William Jones, July 1997,
http://www.windowsitlibrary.com/Content/77/10/toc.html
(85) Are SQL Server userid’s and passwords passed in clear on the network?, Neil Pile,
5/2/2000, http://www.sqlmag.com/Articles/Index.cfm?ArticleID=14357
(86) http://www.microsoft.com/sql/techinfo/administration/2000/security.asp
(87) Permissions in SQL Server 7.0, Michael Deignan, June 1999,
http://www.sqlmag.com/Articles/Index.cfm?ArticleID=5392
(88) Multiple Vulnerabilities in Microsoft SQL Server 2000 and 7.0, Ken Pfeil, 2/1/2002,
http://www.ntsecurity.net/Articles/Index.cfm?ArticleID=23639
(89) SQL Server Security Checklist, SQLServerSecurity.com,
http://www.sqlsecurity.com/DesktopDefault.aspx?tabindex=3&tabid=4
(90) Microsoft SQL Server 2000 Security, Microsoft,
http://www.microsoft.com/technet/treeview/default.asp?url=/technet/prodtechnol/sql
/deploy/confeat/c05ppcsq.asp
(91) SA to be denied access, SQL Server Central Forum,
http://www.sqlservercentral.com/forum/topic.asp?TOPIC_ID=1978&FORUM_ID=5&CA
T_ID=1&Topic_Title=SA+to+be+denied+Access&Forum_Title=Administration
(92) Advanced Security Concepts, Nelson Howell and Ben Forta,
http://local.15seconds.com/issue/971130.htm
(93) http://www.microsoft.com/ntserver/techresources/webserv/iissecure.asp
(94) K-026: Microsoft SQL Server Admin Login Encryption Vulnerability, March 22 2000,
http://ciac.llnl.gov/ciac/bulletins/k-026.shtml
(95) Microsoft SQL Server Password Recovery, Password Crackers Inc,
http://www.pwcrack.com/sql.shtml
(96) How to I encrypt fields in SQL Server? Neil Pike, 5/2/2000,
http://www.sqlmag.com/Articles/Index.cfm?ArticleID=14035
(97) The SQL Server 7 hackers toolkit, Tom Sager, Xephon,
http://www.xephon.com/oldcode/Q016A01
(98) dSQLSRVD, SQL Server SysComments Decryptor, securiteam.com,
http://www.securiteam.com/tools/6J00S003GU.html
(99) Analysis of Microsoft SQL Server 2000 Stored Procedure Encryption,
securiteam.com, http://www.securiteam.com/windowsntfocus/6Q00H2A3FY.html
(100) Implementing row level security in SQL Server databases, Narayana Vyas
Kondreddi,
http://vyaskn.tripod.com/row_level_security_in_sql_server_databases.htm
355