Sybase Frequently Asked Questions supported by Silicon Graphics
_Adaptive Server Enterprise FAQ, version 11.5.12 released 7/31/98_
_________________________________________________________________
Keyword and Phrase Search
Enter search words/phrases: ____________________ ___ Ignore case?
Help!
_________________________________________________________________
Index of Sections
* Section 0: Acknowledgements & What's New in this Release
* Section 1: SQL Server Administration
* Section 2: User Database Administration
* Section 3: DBCC's
* Section 4: isql
* Section 5: bcp
* Section 6: SQL Fundamentals
* Section 7: SQL Advanced
* Section 8: Performance and Tuning
* Section 9: Shareware
* Section 10: Sybase Technical News
* Section 11: Web Links
* Section 12: Miscellany
_________________________________________________________________
To get a text version of this FAQ:
ftp://sgigate.sgi.com/pub/Sybase_FAQ/FAQ_txt.Z [585K]
To get the HTML for this FAQ:
ftp://sgigate.sgi.com/pub/Sybase_FAQ/FAQ_html.tar.Z [773K]
_________________________________________________________________
SQL Server Administration
1.1) How do I start/stop SQL Server when the CPU reboots?
1.2) How do I clear a log suspend'ed connection?
1.3) What's the best value for cschedspins?
1.4) What traceflags are available?
1.5) How do I use traceflags 5101 and 5102?
1.6) What is cmaxpktsz good for? see also Q1.8
1.7) How do I move tempdb off of the master device?
1.8) What do all the parameters of a a buildmaster -d<device> -yall
mean?
1.9) How do I correct timeslice -201?
1.10) What is a SQL Server anyway?
1.11) The how's and why's on becoming a Certified Sybase Professional
(CSPDBA)?
1.12) RAID and Sybase
1.13) How to swap a db device with another
1.14) Server naming and renaming
1.15) How can I tell the datetime my Server started?
1.16) Raw partitions or regular files?
_________________________________________________________________
User Database Administration
2.1) Changing varchar(m) to varchar(n)
2.2) Frequently asked questions on Table partitioning 2.3) How do I
turn off marked suspect on my database?
2.4) How do I manually drop a table?
2.5) Why not create all my columns varchar(255)?
2.6) What's a good example of a transaction?
2.7) What's a natural key?
2.8) Making a Stored Procedure invisible
2.9) Saving space when inserting rows monotonically
2.10) How to compute database fragmentation
2.11) Tasks a DBA should do...
2.12) How to implement database security
2.13) How to shrink a database
_________________________________________________________________
DBCC's
3.1) How do I set TS Role in order to run DBCC ...?
3.2) What are some of the hidden/trick DBCC commands?
3.3) The unauthorized DBCC list with doco - see Q11.15
3.4) Fixing a Munged Log
3.5) Another site with DBCC commands - see Q11.1
_Performing any of the above may_ corrupt your SQL Server. Please do
_not_ call Sybase Technical Support after screwing up your SQL
Server. Remember, _always_ take a dump of the master database and
any other databases that are to be affected.
_________________________________________________________________
isql
4.1) How do I hide my password using isql?
4.2) How do I remove row affected and/or dashes when using isql?
4.3) How do I pipe the output of one isql to another?
_________________________________________________________________
bcp
5.1) How do I bcp null dates?
5.2) Can I use a named pipe to bcp/dump data out or in?
5.3) How do I exclude a column?
_________________________________________________________________
SQL Fundamentals
6.1) Are there alternatives to row at a time processing?
6.2) When should I execute an sp_recompile?
6.3) What are the different types of locks and what do they mean?
6.4) What's the purpose of using holdlock?
6.5) What's the difference between an _update in place_ versus a
_deferred update_? - see Q8.9
6.6) How do I find the oldest open transaction?
6.7) How do I check if log truncation is blocked?
6.8) The timestamp datatype
6.9) Stored Procedure Recompilation and Reresolution
_________________________________________________________________
SQL Advanced
7.1) How to emulate the Oracle decode function/crosstab
7.2) How to implement if-then-else within a select-clause.
7.3) _deleted due to copyright hassles by the publisher_
7.4) How to pad with leading zeros an int or smallint.
7.5) Divide by zero and nulls. 7.6) Convert months to financial
months. 7.7) Hierarchy traversal - BOMs. 7.8) Is it possible to call a
UNIX command from within a stored procedure or a trigger?
7.9) Information on Identities and Rolling your own Sequential Keys
_________________________________________________________________
Performance and Tuning
8.1) What are the nitty gritty details on Performance and Tuning?
8.2) What is best way to use temp tables in an OLTP environment?
8.3) What's the difference between clustered and non-clustered
indexes?
8.4) Optimistic versus Pessimistic locking?
8.5) How do I force an index to be used?
8.6) Why place tempdb and log on low numbered devices?
8.7) Have I configured enough memory for my SQL Server?
8.8) Why should I use stored procedures?
8.9) I don't understand showplan's output, please explain.
8.10) Poor man's sp_sysmon.
8.11) View MRU-LRU procedure cache chain. 8.12) Improving Text/Image
Type Performance
_________________________________________________________________
Shareware
9.1) sp_freedevice - lists device, size, used and free.
9.2) sp_whodo - augments sp_who by including additional columns: cpu,
I/O...
9.3) SQL and sh(1)to dynamically generate a dump/load database
command.
9.4) SybPerl - Perl interface to Sybase.
9.5) dbschema.pl - SybPerl script to take a logical snap of a
database.
9.6) Sybtcl - TCL interface to Sybase.
9.7) Augmented system stored procedures.
9.8) Examples of Open Client and Open Server programs -- see Q11.11.
9.9) SQL to determine the space used for an index.
9.10) xsybmon - an X interface to sp_monitor
9.11) sp_dos - This procedure graphically displays the scope of a
object
9.12) sqsh - a superset of dsql with local variables, redirection,
pipes and all sorts of goodies.
9.13) sp_getdays - returns days in current month.
9.14) ddl_insert.pl - creates insert DDL for a table.
9.15) sp_ddl_create_table - creates DDL for all user tables in the
current database
9.16) int.pl - converts interfaces file to tli
9.17) How to access a SQL Server using Linux see also Q11.6
9.18) sp__revroles - creates DDL to sp_role a mirror of your SQL
Server
9.19) sp__rev_configure - creates DDL to sp_configure a mirror of your
SQL Server
9.20) sp_servermap - overview of your SQL Server
9.21) sp__create_crosstab - simplify crosstable queries
9.220 upd_stats.csh
_________________________________________________________________
Sybase Technical News
10.1.1) Volume 3, Number 2
10.1.2) Volume 3, Number 3
10.1.3) Volume 3, Number 4
10.2.1) Volume 4, Number 1
10.2.2) Volume 4, Number 2
10.2.3) Volume 4, Number 3
10.2.4) Volume 4, Number 4
10.3.1) Volume 5, Number 1
10.3.2) Special Supplement -- Migration to System 11
10.3.3) Volume 5, Number 2
10.3.4) Volume 5, Number 3
10.3.5) Volume 5, Number 4
10.4.1) Volume 6, Number 1
10.4.2) Volume 6, Number 2
10.4.3) Volume 6, Number 3
10.4.4) Volume 6, Number 4
10.4.5) Volume 6, Number 5
10.4.6) Volume 6, Number 6
10.4.7) Volume 6, Number 7
10.4.8) Volume 6, Number 8
10.4.9) Volume 6, Number 9
10.5.1) Volume 7, Number 1
10.5.2) Volume 7, Number 2
10.5.3) Volume 7, Number 3
10.5.4) Volume 7, Number 4
10.5.5) Volume 7, Number 5
10.5.6) Volume 7, Number 6
_________________________________________________________________
Web Links
_Academia_
11.1.1) Yale Centre for Medical Informatics
http://paella.med.yale.edu/topics/database.html
11.1.2) NC State University http://www.acs.ncsu.edu:80/Sybase
11.1.3) Simon Fraser University
http://www.cs.sfu.ca/CourseCentral/Software/Sybase
11.1.4) University of California
http://www-act.ucsd.edu/webad/sybase.html
11.1.5) Rutgers http://paul.rutgers.edu/sybase.html
_Sybase Resources_
11.2.1) Pacific Rim Network Systems Inc Sybase Resource Links
http://www.alaska.net/~pacrim/sybase.html
11.2.2) The Sybase Contractors' Resource Page by Magnum Solutions
http://www.mag-sol.com/Sybase
11.2.3) The SQL Workshop http://www.sqlworkshop.com
11.2.4) SQL Server and Rep Server on NT
http://www.xs4all.nl/~reinoud/ntsqlrep.html
_Books, Magazines and Articles_
11.3.1) Sybase Books http://sybooks.sybase.com
11.3.2) Intro to Sybase Architecture -
http://www2.dgsys.com/~dcasug/sybintro/intro.html
11.3.3) Papers from SQL Forum http://www.sqlforum.com/sybart.htm
_Shareware_
11.4.1) The unauthorized documentation of DBCC by Al Huntley
http://user.icx.net/~huntley/dbccinfo.htm
11.4.2) More DBCC's by KaleidaTech Associates, Inc. -
http://www.kaleidatech.com/dbcc1.htm
11.4.3) sybinit4ever: Sybase ASE 11.5 ASCII-only server creation tool
http://www.euronet.nl/~syp_rob/si4evr.html
11.4.4) Sybase Freeware and Shareware
http://www.tiac.net/users/sqltech
11.4.5) Peter Thawley's '97 ISUG Talk
ftp://sgigate.sgi.com/pub/Sybase_FAQ/Thawleyhndout.ppt.ps.Z [3670K]
11.4.6) DBI/DBD:Sybase on Linux
http://www.brodeur.com/~pjacob/dbdsybase
11.4.7) BusinessObjects FAQ -
http://www.upenn.edu/computing/da/bo/busob-faq.html
11.4.8) Sybase Scheme Extensions -
http://www.cs.indiana.edu/scheme-repository/ext.html
11.4.9) SQShell SQL shell for Unix by Scott Gray
http://www.voicenet.com/~gray/sqsh.html
11.4.10) A login widget for Sybase
http://ftp.digital.com/pub/plan/perl/CPAN/CPAN.html#sybase
11.4.11) ISUG's Freeware Collection
http://www.sybase.com/ISUG/shareware.html
11.4.12) Sybase to HTML Converter
http://www.algonet.se/~bergkarl/lasse/scripts_eng.html
11.4.13) Tool to access Sybase server with line editing and history
recall http://www.mcs.net/~ivank/sybtool.html
11.4.14) Sybase connectivity libraries
http://www.sybase.com/products/samples/
11.4.15) A web to Sybase interface http://archive.eso.org/wdb/html/
_User Groups_
11.5.1) Indiana Sybase User's Group
http://www.cs.bsu.edu/homepages/sam/isug
11.5.2) Ontario Sybase User Group (OSUG) Website -
http://www.interlog.com/~osug
11.5.3) SUGBay, Bay Area Sybase User Group - http://www.sugbay.com
11.5.4) DCASUG, DC Area Sybase User Group -
http://www2.dgsys.com/~dcasug
11.5.5) International Sybase User Group - http://www.sybase.com/ISUG
The mother ship may be reached at http://www.sybase.com
_________________________________________________________________
Miscellany
12.1) What can Sybase IQ do for me?
12.2) Net-review of Sybase books
12.3) email lists
12.4) Finding Information at Sybase
_________________________________________________________________
Acknowledgements ...
Thanks to all the folks in comp.databases.sybase who have made this
FAQ possible. Furry instance, this release has two minor contributions
by me (although admining the thing can be a nightmare at times!) and
the rest has come from folks on the net and at Sybase. I've
degenerated into a brain stem. Add a little water and I'm your chia
pet.
Please mail pa...@sgi.com any changes, comments, complaints and/or
disagreements and I will respond in due time. Heck I may even fix
them.
Please abide by the following and include it if redistributing the
Sybase FAQ:
_Do not use this information for profit but do_ share it with
anyone.
So who is this guy?
_________________________________________________________________
Hall of Fame
The following people have made the _Sybase FAQ Hall of Fame_. Partly
because Sybase refuses to acknowledge the good work that these people
have done for _their_ product and sales but most importantly because
they have done it for us!
* Michael Peppler (mpep...@bix.com) - author of SybPerl and
provider of awesome support.
* Scott Gray (gr...@voicenet.com) - author of sqsh and
ultra-responsive developer. The best tool this side of the Ozarks.
_________________________________________________________________
What's New in this Release?
_A non-exhaustive list of contributors for 11.5 Changes through
11.5.6_
* Q2.11 - to...@cs.umbc.edu - Added ls -la my_sybase_disk_devices
* Q11.22 - siwa...@cix.compulink.co.uk - The SQL Workshop link
* Q9.18/.19 - clayto...@pobox.com - Reverse engineer user roles
and sp_configure data
* Q1.2 - jo...@lehman.com - Correction on using lct_admin command on
System 11
* Q9.5 - mpep...@mbay.net - Updated version of dbschema.pl by David
Whitmarsh: constraints/defaults/etc + primary/foreign keys
* Q6.9 - Michael_C...@dev.japan.ml.com - Corrections to bad
grammar and increased coverage from System 10 to anything below
and including System 10.
* Q6.9 - anonymous - Culled from the sybase-tuning list see Q12.3
* Q9.5 - ji...@sgi.com/mpep...@mbay.net - Updated link to SybPerl
FAQ
* Q9.20 - unknown author, provided by Mark.Meredith - sp_servermap,
gives an overview of your SQL Server
* Q10.4.[2-9] - Sybase Inc. - Sybase Technical News - I'm not doing
much formatting on these because I want to stay up to date with
the FAQ. Feedback from you, gentle reader, has told me that you
want the data so that you can take the entire FAQ to a client site
on your lap top.
* Q1.4 - doh...@itginc.com - Added traceflags 303 and 319
* Q9.16 - m...@beasys.com - Update e-mail address
* Q7.1 - clayto...@pobox.com - Submits his submission on
crosstabs. Implemented way before the supposed _copyrighted_
version.
* Q4.1 - br...@dhatt.com - Added warning to _script #7_
* Q1.13 - rle...@acm.org - Updates _his_ answer.
* Q6.7 - g...@zappa.informatics.jax.org - Fixed the title of the
answer
* Q2.13 - br...@sybase.com - His answer on how to shrink a database
* Q1.15 - pskri...@compuserve.com - An alternative method to
determining when your Server started - fixed!
* Q2.3 - west...@mfg.sgi.com - sp_configure "allow" wasn't specific
enough for System 10, fixed the FAQ
* Q11.1/Q3.5 - ji...@corp.sgi.com/in...@kaleidatech.com - Q11.1 was
Web pointer to PNL site... dead! I've replaced it with the DBCC
site for Q3.5
* Q2.4 - doh...@itginc.com - Moved _use master_ to the right spot
* Q7.8 - me - Updated to include 11.5 information
* Q7.9 - bo...@netcom.com - A beautiful writeup on using Identities
or your own Sequential Keys
* Q2.1 - mcvi...@sybase.com - Noted that these instructions can be
used for increasing not just shrinking
* index - me - removed that darn counter (it kept resetting), Ed
Barlow was catching up anyway... or so he thinks! :-)
* Q11.15 - br...@sybase.com/a...@ornl.gov - Updated DBCC web link
* Q2.4 - nee...@tc.fluke.com - Delete entries in sysdepends
* Q3.2 - ceas...@virtualogic.com - rebuild_log entry
* Q9.13 - Sam_V...@email.fpl.com/paul...@jpmorgan.come - spruced
up sp_getdays
* Q2.8 - rei...@xs4all.nl - Advised that 11.5 doesn't allow one to
delete the data in syscomments. Instead use sp's to encrypt.
* I cleaned up the Sybase links that I used to keep. Namely, I
removed them! :-) For the books, I simply have a link to the books
URL and folks should be able to navigate within The Mother Ship.
This makes it less probable of storing stale URL's Thanks!
* Q8.13 - me - nuked! It was a link to the Performance and Tuning
books. It was stale... see previous note on my reasoning.
* Q11.6/Q9.17 - pja...@brodeur.com - DBI/DBD:Sybase on linux how to
* Q1.7 - Miles...@nisa-csrn.x400.gc.ca - An alternative to moving
tempdb off of master, fill it! Neat trick, see writeup.
* Q12.4 - eb...@sybase.com - Self-help... from Sybase. :-)
* Q9.21 - clayto...@pobox.com - sp__create_crosstab
* Q9.6 - tpoi...@nyx.net - the ever-popular Sybtcl
_Changes in 11.5.7 - 2/9/98_
* Q1.7 - ms...@blackrock.com - we needed to fill with 1024 rows
* Q10.5.2 - sybase - added Sybase Technical News
_Changes in 11.5.8 - 2/19/98_
* Q7.7 - ngo...@incyte.com - provided a fix to the hierarchy
traversal
* Q4.1 - paul...@jpmorgan.com - yet another way to hide your
password
* Q3.2 - gil...@dssolutions.com - contributed _dbcc settrunc()_
* Q9.10 - dmon...@csd.sgi.com - alerted me that Q9.10's link is
dead. Thanks!
_Changes in 11.5.9 - 4/13/98_
* Q10.5.2/Q10.5.3 - Sybase Technical News
* Q6.4 - mdch...@Japan.ml.COM - asked that I provide an example. So
I did. It's more of an example how it works rather than a psuedo
real world example.
* Q6.9 - david.w...@dial.pipex.com - suggested I mention
traceflag 299 to Q6.9. So I did. Good suggestion.
* index - a...@agd.nsw.gov.au - corrected the correction. :-)
* Q7.9 - dav...@lexis-nexis.com - gave an update on where to find
the Malcolm Colton white paper
_Changes in 11.5.10 - 6.8.98_
* Q3.2 - joop.b...@bigfoot.com - dbrepair (dbid, ltmignore)
* Section 11 - mg...@fatsinc.com - various web links
* Q9.22 - flu...@hway.net - intelligent update statistics
* Q10.5.5/Q10.5.6 - Sybase Technical News
_Changes in 11.5.11 - 7.13.98_
* Q10.5.7 - Sybase Technical News
* Section 11 - MG...@fatsinc.com - reorg of this section
* Q3.2 - srama...@lucent.com - dbcc corrupt
_Changes in 11.5.12 - 7.31.98_
* Q11.2.4 - rei...@xs4all.nl - SQL Server and Rep Server on NT
_________________________________________________________________
--
Pablo Sanchez | Ph # (650) 933.3812 Fax # (650) 933.0822
pa...@sgi.com | Pg # (800) 930.5635 -or- pab...@pager.sgi.com
-------------------------------------------------------------------------------
I am accountable for my actions. http://reality.sgi.com/pablo
Q1.1: HOW TO START/STOP SQL SERVER WHEN CPU REBOOTS
_________________________________________________________________
Below is an example of the various files (on _Irix_) that are needed
to start/stop a SQL Server. The information can easily be extended to
any UNIX platform.
The idea is to allow as much flexibility to the two classes of
administrators that admin the machine:
* The System Administrator
* The Database Administrator
Any errors introduced by the DBA will not interfere with the System
Administrator's job.
With that in mind we have the system startup/shutdown file
_/etc/init.d/sybase_ invoking a script defined by the DBA:
_/usr/sybase/sys.config/{start,stop}.sybase_
_/etc/init.d/sybase_
On some operating systems this file must be linked to a corresponding
entry in _/etc/rc.0_ and _/etc/rc.2_ -- see _rc0(1M)_ and _rc2(1M)_
#!/bin/sh
# last modified: 10/17/95, sr.
#
# Make symbolic links so this file will be called during system stop/start.
# ln -s /etc/init.d/sybase /etc/rc0.d/K19sybase
# ln -s /etc/init.d/sybase /etc/rc2.d/S99sybase
# chkconfig -f sybase on
# Sybase System-wide configuration files
CONFIG=/usr/sybase/sys.config
if $IS_ON verbose ; then # For a verbose startup and shutdown
ECHO=echo
VERBOSE=-v
else # For a quiet startup and shutdown
ECHO=:
VERBOSE=
fi
case "$1" in
'start')
if $IS_ON sybase; then
if [ -x $CONFIG/start.sybase ]; then
$ECHO "starting Sybase servers"
/bin/su - sybase -c "$CONFIG/start.sybase $VERBOSE &"
else
<error condition>
fi
fi
;;
'stop')
if $IS_ON sybase; then
if [ -x $CONFIG/stop.sybase ]; then
$ECHO "stopping Sybase servers"
/bin/su - sybase -c "$CONFIG/stop.sybase $VERBOSE &"
else
<error condition>
fi
fi
;;
*)
echo "usage: $0 {start|stop}"
;;
esac
_/usr/sybase/sys.config/{start,stop}.sybase_
start.sybase
#!/bin/sh -a
#
# Script to start sybase
#
# NOTE: different versions of sybase exist under /usr/sybase/{version}
#
# Determine if we need to spew our output
if [ "$1" != "spew" ] ; then
OUTPUT=">/dev/null 2>&1"
else
OUTPUT=""
fi
# 10.0.2 servers
HOME=/usr/sybase/10.0.2
cd $HOME
# Start the backup server
eval install/startserver -f install/RUN_BU_KEPLER_1002_52_01 $OUTPUT
# Start the dataservers
# Wait two seconds between starts to minimize trauma to CPU server
eval install/startserver -f install/RUN_FAC_WWOPR $OUTPUT
sleep 2
eval install/startserver -f install/RUN_MAG_LOAD $OUTPUT
exit 0
stop.sybase
#!/bin/sh
#
# Script to stop sybase
#
# Determine if we need to spew our output
if [ -z "$1" ] ; then
OUTPUT=">/dev/null 2>&1"
else
OUTPUT="-v"
fi
eval killall -15 $OUTPUT dataserver backupserver sybmultbuf
sleep 2
# if they didn't die, kill 'em now...
eval killall -9 $OUTPUT dataserver backupserver sybmultbuf
exit 0
If your platform doesn't support _killall_, it can easily be simulated
as follows:
#!/bin/sh
#
# Simple killall simulation...
# $1 = signal
# $2 = process_name
#
#
# no error checking but assume first parameter is signal...
# what ya want for free? :-)
#
kill -$1 `ps -ef | fgrep $2 | fgrep -v fgrep | awk '{ print $1 }'`
_________________________________________________________________
Q1.2: HOW TO CLEAR A _LOG SUSPEND_
_________________________________________________________________
A connection that is in a _log suspend_ state is there because the
transaction that it was performing couldn't be logged. The reason it
couldn't be logged is because the database transaction log is full.
Typically, the connection that caused the log to fill is the one
suspended. We'll get to that later.
In order to clear the problem you must dump the transaction log. This
can be done as follows:
dump tran _db_name_ to _data_device_
go
At this point, any completed transactions will be flushed out to disk.
If you don't care about the recoverability of the database, you can
issue the following command:
dump tran _db_name_ with truncate_only
If that doesn't work, you can use the _with no_log_ option instead of
the _with truncate_only_.
After successfully clearing the log the suspended connection(s) will
resume.
Unfortunately, as mentioned above, there is the situation where the
connection that is suspended is the culprit that filled the log.
Remember that dumping the log _only_ clears out completed transaction.
If the connection filled the log with one large transaction, then
dumping the log isn't going to clear the suspension.
System 10
What you need to do is issue a SQL Server _kill_ command on the
connection and then unsuspend it:
select lct_admin("unsuspend", db_id("_db_name_"))
System 11
See Sybase Technical News Volume 6, Number 2
Retaining Pre-System 10 Behavior
By setting a database's _abort xact on log full_ option, pre-System 10
behavior can be retained. That is, if a connection cannot log its
transaction to the log file, it is aborted by the SQL Server rather
than suspended.
_________________________________________________________________
Q1.3: WHAT'S THE BEST VALUE FOR _CSCHEDSPINS_?
_________________________________________________________________
It is crucial to understand that _cschedspins_ is a tunable parameter
(recommended values being between 1-2000) and the optimum value is
completely dependent on the customer's environment. _cschedspins_ is
used by the scheduler only when it finds that there are no runnable
tasks. If there are no runnable tasks, the scheduler has two options:
1. Let the engine go to sleep (which is done by an OS call) for a
specified interval or until an event happens. This option assumes
that tasks won't become runnable because of tasks executing on
other engines. This would happen when the tasks are waiting for
I/O more than any other resource such as locks. Which means that
we could free up the CPU resource (by going to sleep) and let the
system use it to expedite completion of system tasks including
I/O.
2. Go and look for a ready task again. This option assumes that a
task would become runnable in the near term and so incurring the
extra cost of an OS context switch through the OS sleep/wakeup
mechanism is unacceptable. This scenario assumes that tasks are
waiting on resources such as locks, which could free up because of
tasks executing on other engines, more than they wait for I/O.
_cschedspins_ controls how many times we would choose option 2 before
choosing option 1. Setting _cschedspins_ low favors option 1 and
setting it high favors option 2. Since an I/O intensive task mix fits
in with option 1, setting _cschedspins_ low may be more beneficial.
Similarly since a CPU intensive job mix favors option 2, setting
_cschedspins_ high may be beneficial.
The consensus is that a single cpu server should have _cschedspins_
set to 1. However, I strongly recommend that users carefully test
values for _cschedspins_ and monitor the results closely. I have seen
more than one site that has shot themselves in the foot so to speak
due to changing this parameter in production without a good
understanding of their environment.
_________________________________________________________________
Q1.4: Trace Flag Definitions
----------------------------------------------------------------------------
To activate trace flags, add them to the RUN_* script. The following example
is using the 1611 and 260 trace flags.
Use of these traceflags is not recommended by Sybase. Please use
at your own risk.
% cd ~sybase/install
% cat RUN_BLAND
#!/bin/sh
#
# SQL Server Information:
# name: BLAND
# master device: /usr/sybase/dbf/BLAND/master.dat
# master device size: 25600
# errorlog: /usr/sybase/install/errorlog_BLAND
# interfaces: /usr/sybase
#
/usr/sybase/dataserver -d/usr/sybase/dbf/BLAND/master.dat \
-sBLAND -e/usr/sybase/install/errorlog_BLAND -i/usr/sybase \
-T1611 -T260
----------------------------------------------------------------------------
Trace Flags
Flag Description
200 Displays messages about the before image of the query-tree.
201 Displays messages about the after image of the query-tree.
241 Compress all query-trees whenever the SQL dataserver is started.
Reduce TDS (Tabular Data Stream) overhead in stored procedures.
Turn off done-in-proc packets. Do not use this if your application
is a ct-lib based application; it'll break.
260
Why set this on? Glad you asked, typically with a db-lib
application a packet is sent back to the client for each batch
executed within a stored procedure. This can be taxing in a WAN/LAN
environment.
This trace flag instructs the dataserver to not recompile a child
299 stored procedure that inherits a temp table from a parent
procedure.
302 Print information about the optimizer's index selection.
303 Display OR strategy
310 Print information about the optimizer's join selection.
311 Display the expected IO to satisfy a query. Like statistics IO
without actually executing.
317 Provide extra optimization information.
319 Reformatting strategies.
320 Turn off the join order heuristic.
324 Turn off the like optimization for ad-hoc queries using
@local_variables.
602 Prints out diagnostic information for deadlock prevention.
603 Prints out diagnostic information when avoiding deadlock.
699 Turn off transaction logging for the entire SQL dataserver.
1204* Send deadlock detection to the errorlog.
1205 Stack trace on deadlock.
1206 Disable lock promotion.
1603* Use standard disk I/O (i.e. turn off asynchronous I/O).
1605 Start secondary engines by hand
Create a debug engine start file. This allows you to start up a
debug engine which can access the server's shared memory for
running diagnostics. I'm not sure how useful this is in a
1606 production environment as the debugger often brings down the
server. I'm not sure if Sybase have ported the debug stuff to
10/11. Like most of their debug tools it started off quite strongly
but was never developed.
Startup only engine 0; use dbcc engine(online) to incrementally
1608 bring up additional engines until the maximum number of configured
engines.
1610* Boot the SQL dataserver with TCP_NODELAY enabled.
1611* If possible, pin shared memory -- check errorlog for
success/failure.
1613 Set affinity of the SQL dataserver engine's onto particular CPUs --
usually pins engine 0 to processor 0, engine 1 to processor 1...
1615 SGI only: turn on recoverability to filesystem devices.
2512 Prevent dbcc from checking syslogs. Useful when you are constantly
getting spurious allocation errors.
Display each log record that is being processed during recovery.
3300 You may wish to redirect stdout because it can be a lot of
information.
3500 Disable checkpointing.
3502 Track checkpointing of databases in errorlog.
3601 Stack trace when error raised.
3604 Send dbcc output to screen.
3605 Send dbcc output to errorlog.
3607 Do not recover any database, clear tempdb, or start up checkpoint
process.
3608 Recover master only. Do not clear tempdb or start up checkpoint
process.
3609 Recover all databases. Do not clear tempdb or start up checkpoint
process.
3610 Pre-System 10 behavior: divide by zero to result in NULL instead of
error - also see Q7.5.
3620 Do not kill infected processes.
4012 Don't spawn chkptproc.
4013 Place a record in the errorlog for each login to the dataserver.
4020 Boot without recover.
Forces all I/O requests to go thru engine 0. This removes the
5101 contention between processors but could create a bottleneck if
engine 0 becomes busy with non-I/O tasks. For more
information...5101/5102.
5102 Prevents engine 0 from running any non-affinitied tasks. For more
information...5101/5102.
7103 Disable table lock promotion for text columns.
8203 Display statement and transaction locks on a deadlock error.
* Starting with System 11 these are sp_configure'able
----------------------------------------------------------------------------
Q1.5: TRACE FLAGS -- 5101 AND 5102
_________________________________________________________________
5101
Normally, each engine issues and checks for its own Disk I/O on behalf
of the tasks it runs. In completely symmetric operating systems, this
behavior provides maximum I/O throughput for SQL Server. Some
operating systems are not completely symmetic in their Disk I/O
routines. For these environments, the server can be booted with the
5101 trace flag. While tasks still request disk I/O from any engine,
the actual request to/from the OS is performed by engine 0. The
performance benefit comes from the reduced or eliminated contention on
the locking mechanism inside the OS kernel. To enable I/O affinity to
engine 0, start SQL Server with the 5101 Trace Flag.
Your errorlog will indicate the use of this option with the message:
Disk I/O affinitied to engine: 0
This trace flag only provides performance gains for servers with 3 or
more dataserver engines configured and being significantly utilized.
_Use of this trace flag with fully symmetric operating systems will
degrade performance!_
5102
The 5102 trace flag prevents engine 0 from running any non-affinitied
tasks. Normally, this forces engine 0 to perform Network I/O only.
Applications with heavy result set requirements (either large results
or many connections issuing short, fast requests) may benefit. This
effectively eliminates the normal latency for engine 0 to complete
running its user thread before it issues the network I/O to the
underlying network transport driver. If used in conjuction with the
5101 trace flag, engine 0 would perform all Disk I/O and Network I/O.
For environments with heavy disk and network I/O, engine 0 could
easily saturate when only the 5101 flag is in use. This flag allows
engine 0 to concentrate on I/O by not allowing it to run user tasks.
To force task affinity off engine 0, start SQL Server with the 5102
Trace Flag.
Your errorlog will indicate the use of this option with the message:
I/O only enabled for engine: 0
_________________________________________________________________
_Warning: Not supported by Sybase. Provided here for your enjoyment._
Q1.6: WHAT IS _CMAXPKTSZ_ GOOD FOR?
_________________________________________________________________
_cmaxpktsz_ corresponds to the parameter "maximum network packet size"
which you can see through _sp_configure_. I recommend only updating
this value through _sp_configure_. If some of your applications send
or receive large amounts of data across the network, these
applications can achieve significant performance improvement by using
larger packet sizes. Two examples are large bulk copy operations and
applications reading or writing large text or image values. Generally,
you want to keep the value of default network packet size small for
users performing short queries, and allow users who send or receive
large volumes of data to request larger packet sizes by setting the
maximum network packet size configuration variable.
_caddnetmem_ corresponds to the parameter "additional netmem" which
you can see through _sp_configure_. Again, I recommend only updating
this value through _sp_configure_. "additional netmem" sets the
maximum size of additional memory that can be used for network packets
that are larger than SQL Server's default packet size. The default
value for additional netmem is 0, which means that no extra space has
been allocated for large packets. See the discussion below, under
maximum network packet size, for information on setting this
configuration variable. Memory allocated with additional netmem is
added to the memory allocated by memory. It does not affect other SQL
Server memory uses.
SQL Server guarantees that every user connection will be able to log
in at the default packet size. If you increase maximum network packet
size and additional netmem remains set to 0, clients cannot use packet
sizes that are larger than the default size: all allocated network
memory will be reserved for users at the default size. In this
situation, users who request a large packet size when they log in
receive a warning message telling them that their application will use
the default size. To determine the value for additional netmem if your
applications use larger packet sizes:
* Estimate the number of simultaneous users who will request the
large packet sizes, and the sizes their applications will request.
* Multiply this sum by three, since each connection needs three
buffers.
* Add 2% for overhead, rounded up to the next multiple of 512
_________________________________________________________________
Q1.7: HOW DO I MOVE _TEMPDB_ OFF OF THE MASTER DEVICE?
_________________________________________________________________
_Note:_ I received a message from Sybase TS recommending that the
FAQ no longer advocate the physical removal of entries from the
_sysusages/sysdatabases_ tables. It makes recovery _extremely_
painful.
After reviewing their write-up I agree.
A quick alternative - Sybase TS Preferred Method
This is the Sybase TS method of removing _most_ activity off of the
master device:
1. Alter tempdb on another device:
1> alter database tempdb on ...
2> go
2. Use the tempdb:
1> use tempdb
2> go
3. Drop the segments:
1> sp_dropsegment "default", tempdb, master
2> go
1> sp_dropsegment "logsegment", tempdb, master
2> go
1> sp_dropsegment "system", tempdb, master
2> go
Note that there is still _some_ activity on the master device. On a
three connection test that I ran:
while ( 1 = 1 )
begin
create table #x (col_a int)
drop table #x
end
there was one write per second. Not bad.
Yet another alternative
The idea of this handy script is to simply fill the first 2MB of
tempdb thus effectively blocking anyone else from using it. The
_slight_ gotcha with this script, since we're using model, is that all
subsequent database creates will also have _tempdb_filler_ installed.
This is easily remedied by dropping the table after creating a new
database.
This script works because tempdb is rebuilt every time the SQL Server
is rebooted. Very nice trick!
/* this isql script creates a table in the model database. */
/* Since tempdb is created from the model database when the */
/* server is started, this effectively moves the active */
/* portion of tempdb off of the master device. */
use model
go
/* note: 2k row size */
create table tempdb_filler(
a char(255) not null,
b char(255) not null,
c char(255) not null,
d char(255) not null,
e char(255) not null
)
go
/* insert 1024 rows */
declare @i int
select @i = 1
while (@i
__________________________________________________________________________
Q1.8: BUILDMASTER CONFIGURATION DEFINITIONS
_________________________________________________________________
_Attention!_ Please notice, be very careful with these parameters.
Use only at your own risk. Be sure to have a copy of the original
parameters. Be sure to have a dump of all dbs (include master)
handy.
_________________________________________________________________
The following is a list of configuration parameters and their effect
on the SQL Server. Changes to these parameters can affect performance
of the server. Sybase does not recommend modifying these parameters
without first discussing the change with Sybase Tech Support. This
list is provided for information only.
These are categorized into two kinds:
* Configurable through sp_configure and
* not configurable but can be changed through 'buildmaster
-y<variable>=value -d<dbdevice>'
Configurable variables:
crecinterval:
The recovery interval specified in minutes.
ccatalogupdates:
A flag to inform whether system catalogs can be updated or not.
cusrconnections:
This is the number of user connections allowed in SQL
Server. This value + 3 (one for checkpoint, network
and mirror handlers) make the number of pss configured
in the server.
_________________________________________________________________
cfgpss:
Number of PSS configured in the server. This value will
always be 3 more than cusrconnections. The reason is we
need PSS for checkpoint, network and mirror handlers.
THIS IS NOT CONFIGURABLE.
_________________________________________________________________
cmemsize:
The total memory configured for the Server in 2k
units. This is the memory the server will use for both
Server and Kernel Structures. For Stratus or any 4k
pagesize implementation of SQL Server, certain values
will change as appropriate.
cdbnum:
This is the number of databases that can be open in SQL
Server at any given time.
clocknum:
Variable that defines and controls the number of logical
locks configured in the system.
cdesnum:
This is the number of open objects that can be open at
a given point of time.
cpcacheprcnt:
This is the percentage of cache that should be used
for procedures to be cached in.
cfillfactor:
Fill factor for indexes.
ctimeslice:
This value is in units of milli-seconds. This value determines
how much time a task is allowed to run before it yields.
This value is internally converted to ticks. See below
the explanations for cclkrate, ctimemax etc.
ccrdatabasesize:
The default size of the database when it is created.
This value is Megabytes and the default is 2Meg.
ctappreten:
An outdated not used variable.
crecoveryflags:
A toggle flag which will display certain recovery information
during database recoveries.
cserialno:
An informational variable that stores the serial number
of the product.
cnestedtriggers:
Flag that controls whether nested triggers allowed or not.
cnvdisks:
Variable that controls the number of device structures
that are allocated which affects the number of devices
that can be opened during server boot up. If user
defined 20 devices and this value is configured to be
10, during recovery only 10 devices will be opened and
the rest will get errors.
cfgsitebuf:
This variable controls maximum number of site handler
structures that will be allocated. This in turn
controls the number of site handlers that can be
active at a given instance.
cfgrembufs:
This variable controls the number of remote buffers
that needs to send and receive from remote sites.
Actually this value should be set to number of
logical connections configured. (See below)
cfglogconn:
This is the number of logical connections that can
be open at any instance. This value controls
the number of resource structure allocated and
hence it will affect the overall logical connection
combined with different sites. THIS IS NOT PER SITE.
cfgdatabuf:
Maximum number of pre-read packets per logical connections.
If logical connection is set to 10, and cfgdatabuf is set
to 3 then the number of resources allocated will be
30.
cfupgradeversion:
Version number of last upgrade program ran on this server.
csortord:
Sort order of the SQL Server.
cold_sortdord:
When sort orders are changed the old sort order is
saved in this variable to be used during recovery
of the database after the Server is rebooted with
the sort order change.
ccharset:
Character Set used by the SQL server
cold_charset:
Same as cold_sortord except it stores the previous
Character Set.
_________________________________________________________________
cdflt_sortord:
page # of sort order image definition. This should
not be changed at any point. This is a server only
variable.
cdflt_charset:
page # of character set image definition. This should
not be changed at any point. This is a server only
variable.
cold_dflt_sortord:
page # of previous sort order image definition. This
should not be changed at any point. This is a server
only variable.
cold_dflt_charset:
page # of previous chracter set image definition. This
should not be changed at any point. This is a server
only variable.
_________________________________________________________________
cdeflang:
Default language used by SQL Server.
cmaxonline:
Maximum number of engines that can be made online. This
number should not be more than the # of cpus available on this
system. On Single CPU system like RS6000 this value is always
1.
cminonline:
Minimum number of engines that should be online. This is 1 by
default.
cengadjinterval:
A noop variable at this time.
cfgstacksz:
Stack size per task configured. This doesn't include the guard
area of the stack space. The guard area can be altered through
cguardsz.
_________________________________________________________________
cguardsz:
This is the size of the guard area. The Sql Server will
allocate stack space for each task by adding cfgstacksz
(configurable through sp_configure) and cguardsz (default is
2K). This has to be a multiple of PAGESIZE which will be 2k
or 4k depending on the implementation.
cstacksz:
Size of fixed stack space allocated per task including the
guard area.
_________________________________________________________________
Non-configurable values :
_________________________________________________________________
_TIMESLICE, CTIMEMAX ETC:_
_________________________________________________________________
1 millisecond = 1/1000th of a second.
1 microsecond = 1/1000000th of a second. "Tick" : Interval between two
clock interrupts occur in real time.
"cclkrate" :
A value specified in microsecond units.
Normally on systems where a fine grained timer is not available
or if the Operating System cannot set sub-second alarms, this
value is set to 1000000 milliseconds which is 1 second. In
other words an alarm will go off every 1 second or you will
get 1 tick per second.
On Sun4 this is set to 100000 milliseconds which will result in
an interrupt going at 1/10th of a second. You will get 6 ticks
per second.
"avetimeslice" :
A value specified in millisecond units.
This is the value given in "sp_configure",<timeslice value>.
Otherwise the milliseconds are converted to milliseconds and
finally to tick values.
ticks = <avetimeslice> * 1000 / cclkrate.
"timeslice" :
_________________________________________________________________
The unit of this variable is in ticks.
This value is derived from "avetimeslice". If "avetimeslice"
is less than 1000 milliseconds then timeslice is set to 1 tick.
"ctimemax" :
The unit of this variable is in ticks.
A task is considered in infinite loop if the consumed ticks
for a particular task is greater than ctimemax value. This
is when you get timeslice -201 or -1501 errors.
"cschedspins" :
For more information see Q1.3.
This value alters the behavior of the SQL Server scheduler.
The scheduler will either run a qualified task or look
for I/O completion or sleep for a while before it can
do anything useful.
The cschedspins value determines how often the scheduler
will sleep and not how long it will sleep. A low value
will be suited for a I/O bound SQL Server but a
high value will be suited for CPU bound SQL Server. Since
the SQL Server will be used in a mixed mode, this value
need to be fined tuned.
Based on practical behavior in the field, a single engine
SQL Server should have cschedspins set to 1 and a multi-engine
server should have set to 2000.
Now that we've defined the units of these variables what happens when
we change cclkrate ?
Assume we have a cclkrate=100000.
A clock interrupt will occur every (100000/1000000) 1/10th
milliseconds. Assuming a task started with 1 tick which can go upto
"ctimemax=1500" ticks can potentially take 1/10us * (1500 + 1) ticks
which will be 150 milliseconds or approx. .15 milliseconds per task.
Now changing the cclkrate to 75000
A clock interrupt will occur every (75000/1000000) 1/7th milliseconds.
Assuming a task started with 1 tick which can go upto ctimemax=1500
ticks can potentially take 1/7us * (1500 + 1) ticks which will be 112
milliseconds or approx. .11 milliseconds per task.
Decreasing the cclkrate value will decrease the time spent on each
task. If the task couldnot voluntarily yield within the time, the
scheduler will kill the task.
UNDER NO CIRCUMSTANCES the cclkrate value should be changed. The
default ctimemax value should be set to 1500. This is an empirical
value and this can be changed under special circumstances and strictly
under the guidance of DSE.
_________________________________________________________________
cfgdbname:
Name of the master device is saved here. This is 64
bytes in length.
cfgpss:
This is a derived value from cusrconnections + 3.
See cusrconnections above.
cfgxdes:
This value defines the number of transactions that
can be done by a task at a given instance.
Changing this value to be more than 32 will have no
effect on the server.
cfgsdes:
This value defines the number of open tables per
task. This will be typically for a query. This
will be the number of tables specified in a query
including subqueries.
Sybase Advises not to change this value. There
will be significant change in the size of per user
resource in SQL Server.
cfgbuf:
This is a derived variable based on the total
memory configured and subtracting different resource
sizes for Databases, Objects, Locks and other
Kernel memories.
cfgdes:
This is same as cdesnum. Other values will have no effect on it.
cfgprocedure:
This is a derived value. Based on cpcacheprcnt variable.
cfglocks:
This is same as clocknum. Other values will have no effect on it.
cfgcprot:
This is variable that defines the number of cache protectors per
task. This is used internally by the SQL Server.
Sybase advise not to modify this value as a default of 15 will
be more than sufficient.
cnproc:
This is a derived value based on cusrconnections + <extra> for
Sybase internal tasks that are both visible and non-visible.
cnmemmap:
This is an internal variable that will keep track of SQL Server
memory.
Modifying this value will not have any effect.
cnmbox:
Number of mail box structures that need to be allocated.
More used in VMS environment than UNIX environment.
cnmsg:
Used in tandem with cnmbox.
cnmsgmax:
Maximum number of messages that can be passed between mailboxes.
cnblkio:
Number of disk I/O request (async and direct) that can be
processed at a given instance. This is a global value for all
the engines and not per engine value.
This value is directly depended on the number of I/O request
that can be processed by the Operating System. It varies
depending on the Operating System.
cnblkmax:
Maximum number of I/O request that can be processed at any given
time.
Normally cnblkio,cnblkmax and cnmaxaio_server should be the same.
cnmaxaio_engine:
Maximum number of I/O request that can be processed by one engine.
Since engines are Operating System Process, if there is any limit
imposed by the Operating System on a per process basis then
this value should be set. Otherwise it is a noop.
cnmaxaio_server:
This is the total number of I/O request the SQL Server can do.
This value s directly depended on the number of I/O request
that can be processed by the Operating System. It varies
depending on the Operating System.
csiocnt:
not used.
cnbytio:
Similar to disk I/O request, this is for network I/O request.
This includes disk/tape dumps also. This value is for
the whole SQL Server including other engines.
cnbytmax:
Maximum number of network I/O request including disk/tape dumps.
cnalarm:
Maximum number of alarms including the alarms used by
the system. This is typically used when users do "waitfor delay"
commands.
cfgmastmirror:
Mirror device name for the master device.
cfgmastmirror_stat:
Status of mirror devices for the master device like serial/dynamic
mirroring etc.
cindextrips:
This value determines the aging of a index buffer before it
is removed from the cache.
coamtrips:
This value determines the aging of a OAM buffer before it
is removed from the cache.
cpreallocext:
This value determines the number of extents that will be
allocated while doing BCP.
cbufwashsize:
This value determines when to flush buffers in the cache
that are modified.
Q1.9: HOW DO I CORRECT _TIMESLICE -201_
_________________________________________________________________
Why Increase It?
Basically, it will allow for a task to be scheduled onto the CPU in a
longer time. Each task on the system is scheduled onto the CPU for a
fixed period of time, called the timeslice, during which it does some
work, which is resumed when its next turn comes around.
The process has up until the value of _ctimemax_ (a config block
variable) to finish its task. As the task is working away, the
scheduler counts down ctimemax units. When it gets to the value of
_ctimemax_ - 1, if it gets _stuck_ and for some reason cannot be taken
off the CPU, then a timeslice error gets generated and the process
gets infected.
On the other hand, SQL Server will allow a Server process to run as
long as it needs to. It will not swap the process out for another
process to run. The process will decide when it is "done" with the
Server CPU. If, however, a process goes on and on and never
relinquishes the Server CPU, then Server will timeslice the process.
Potential Fix
1. Shutdown the SQL Server
2. %buildmaster -d_your_device_ -yctimemax=2000
3. Restart your SQL Server. If the problem persists contact Sybase
Technical Support notifying them what you have done already.
_________________________________________________________________
Q1.10: What is a SQL Server?
----------------------------------------------------------------------------
Overview
Before Sybase System 10 (as they call it) we had Sybase 4.x. Sybase System
10 has some significant improvements over Sybase 4.x product line. Namely:
* the ability to allocate more memory to the dataserver without degrading
its performance.
* the ability to have more than one database engine to take advantage of
multi-processor cpu machines.
* a minimally intrusive process to perform database and transaction
dumps.
Background and More Terminology
A SQL Server is simply a Unix process. It is also known as the database
engine. It has multiple threads to handle asynchronous I/O and other tasks.
The number of threads spawned is the number of engines (more on this in a
second) times five. This is the current implementation of Sybase System 10,
10.0.1 and 10.0.2 on IRIX 5.3.
Each SQL dataserver allocates the following resources from a host machine:
* memory and
* raw partition space.
Each SQL dataserver can have up to 255 databases. In most implementations
the number of databases is limited to what seems reasonable based on the
load on the SQL dataserver. That is, it would be impractical to house all of
a large company's databases under one SQL dataserver because the SQL
dataserver (a Unix process) will become overloaded.
That's where the DBA's experience comes in with interrogation of the user
community to determine how much activity is going to result on a given
database or databases and from that we determine whether to create a new SQL
Server or to house the new database under an existing SQL Server. We do make
mistakes (and businesses grow) and have to move databases from one SQL
Server to another. And at times SQL Servers need to move from one CPU server
to another.
With Sybase System 10, each SQL Server can be configured to have more than
one engine (each engine is again a Unix process). There's one primary engine
that is the master engine and the rest of the engines are subordinates. They
are assigned tasks by the master.
Interprocess communication among all these engines is accomplished with
shared memory.
Some times when a DBA issues a Unix kill command to extinguish a
maverick SQL Server, the subordinate engines are forgotten. This
leaves the shared memory allocated and eventually we may get in to
situations where swapping occurs because this memory is locked. To
find engines that belong to no master SQL Server, simple look for
engines owned by /etc/init (process id 1). These engines can be
killed -- this is just FYI and is a DBA duty.
Before presenting an example of a SQL Server, some other topics should be
covered.
Connections
A SQL Server has connections to it. A connection can be viewed as a user
login but it's not necessarily so. That is, a client (a user) can spark up
multiple instances of their application and each client establishes its own
connection to the SQL dataserver. Some clients may require two or more per
invocation. So typically DBA's are only concerned with the number of
connections because the number of users typically does not provide
sufficient information for us to do our job.
Connections take up SQL Server resources, namely memory, leaving
less memory for the SQL Servers' available cache.
SQL Server Buffer Cache
In Sybase 4.0.1 there was a limit to the amount of memory that could be
allocated to a SQL Server. It was around 80MB, with 40MB being the typical
max. This was due to internal implementations of Sybase's data structures.
With Sybase System 10 there really is no limit. For instance, we have a SQL
Server cranked up to 300MB.
The memory in a SQL Server is primarily used to cache data pages from disk.
Consider that the SQL Server is a light weight Operating System: handling
user (connections), allocating memory to users, keeping track of which data
pages need to be flushed to disk and the sort. Very sophisticated and
complex. Obviously if a data page is found in memory it's much faster to
retrieve than going out to disk.
Each connection takes away a little bit from the available memory that is
used to cache disk pages. Upon startup, the SQL Server pre-allocates the
memory that is needed for each connection so it's not prudent to configure
500 connections when only 300 are needed. We'd waste 200 connections and the
memory associated with that. On the other hand, it is also imprudent to
under configure the number of connections; users have a way of soaking up a
resource (like a SQL Server) and if users have all the connections a DBA
cannot get into the server to allocate more connections.
One of the neat things about a SQL Server is that it reaches (just like a
Unix process) a working set. That is, upon startup it'll do a lot of
physical I/O's to seed its cache, to get lookup information for typical
transactions and the like. So initially, the first users have heavy hits
because their requests have to be performed as a physical I/O. Subsequent
transactions have less physical I/O and more logical I/O's. Logical I/O is
an I/O that is satisfied in the SQL Servers' buffer cache. Obviously, this
is the preferred condition.
DSS vs OLTP
We throw around terms like everyone is supposed to know this high tech
lingo. The problem is that they are two different animals that require a SQL
Server to be tuned accordingly for each.
Well, here's the low down.
DSS
Decision Support System
OLTP
Online Transaction Processing
What do these mean? OLTP applications are those that have very short orders
of work for each connection: fetch this row and with the results of it
update one or two other rows. Basically, small number of rows affected per
transaction in rapid sucession, with no significant wait times between
operations in a transaction.
DSS is the lumbering elephant in the database world (unless you do some
tricks... out of this scope). DSS requires a user to comb through gobs of
data to aggregate some values. So the transactions typically involve
thousands of rows. Big difference than OLTP.
We never want to have DSS and OLTP on the same SQL Server because the nature
of OLTP is to grab things quickly but the nature of DSS is to stick around
for a long time reading tons of information and summarizing the results.
What a DSS application does is flush out the SQL Server's data page cache
because of the tremendous amount of I/O's. This is obviously very bad for
OTLP applications because the small transactions are now hurt by this
trauma. When it was only OLTP a great percentage of I/O was logical
(satisfied in the cache); now transactions must perform physical I/O.
That's why it's important in Sybase not to mix DSS and OLTP, at least until
System 11 arrives.
Sybase System 11 release will allow for the mixing of OLTP and DSS
by allowing the DBA to partition (and name) the SQL Server's
buffer cache and assign it to different databases and/or objects.
The idea is to allow DSS to only affect their pool of memory and
thus allowing OLTP to maintain its working set of memory.
Asynchronous I/O
Why async I/O? The idea is in a typical online transaction processing (OLTP)
application you have many connections (over 200 connections) and short
transactions: get this row, update that row. These transactions are
typically spread across different tables of the databases. The SQL Server
can then perform each one of these asynchronously without having to wait for
others to finish. Hence the importance of having async I/O fixed on our
platform.
Engines
Sybase System 10 can have more than one engine (as stated above). Sybase has
trace flags to pin the engines to a given CPU processor but we typically
don't do this. It appears that the master engine goes to processor 0 and
subsequent subordinates to the next processor.
Currently, Sybase does not scale linearly. That is, five engines doesn't
make Sybase perform five times as fast however we do max out with four
engines. After that, performs starts to degrade. This is supposed to be
fixed with Sybase System 11.
Putting Everything Together
As previously mentioned, a SQL Server is a collection of databases with
connections (that are the users) to apply and retrieve information to and
from these containers of information (databases).
The SQL Server is built and its master device is typically built over a
medium sized (50MB) raw partition. The tempdb is built over a cooked
(regular - as opposed to a raw device) file system to realize any
performance gains by buffered writes. The databases themselves are built
over the raw logical devices to ensure their integrity.
Physical and Logical Devices
Sybase likes to live in its own little world. This shields the DBA from the
outside world known as Unix (or VMS). However, it needs to have a conduit to
the outside world and this is accomplished via devices.
All physical devices are mapped to logical devices. That is, given a
physical device (such as /lv1/dumps/tempdb_01.efs or /dev/rdsk/dks1ds0) it
is mapped by the DBA to a logical device. Depending on the type of the
device, it is allocated, by the DBA, to the appropriate place (vague
enough?).
Okay, let's try and clear this up...
Dump Device
The DBA may decide to create a device for dumping the database nightly. The
DBA needs to create a dump device.
We'll call that logically in the database datadump_for_my_db but we'll map
it to the physical world as /lv1/dumps/in_your_eye.dat So the DBA will write
a script that connects to the SQL Server and issues a command like this:
dump database my_stinking_db to datadump_for_my_db
go
and the backupserver (out of this scope) takes the contents of
my_stinking_db and writes it out to the disk file /lv1/dumps/in_your_eye.dat
That's a dump device. The thing is that it's not preallocated. This special
device is simply a window to the operating system.
Data and Log Devices
Ah, now we are getting into the world of pre-allocation. Databases are built
over raw partitions. The reason for this is because Sybase needs to be
guaranteed that all its writes complete successfully. Otherwise, if it
posted to a file system buffer (as in a cooked file system) and the machine
crashed, as far as Sybase is concerned the write was committed. It was not,
however, and integrity of the database was lost. That is why Sybase needs
raw partitions. But back to the matter at hand...
When building a new SQL Server, the DBA determines how much space they'll
need for all the databases that will be housed in this SQL Server.
Each production database is composed of data and log.
The data is where the actual information resides. The log are where the
changes are kept. That is, every row that is updated/deleted/inserted gets
placed into the log portion then applied to the data portion of the
database.
That's why DBA strives to place the raw devices for logs on
separate disks because everything has to single thread through the
log.
A transaction is a collection of SQL statements (insert/delete/update) that
are grouped together to form a single unit of work. Typically they map very
closely to the business.
I'll quote the Sybase SQL Server System Administration guide on the role of
the log:
The transaction log is a write-ahead log. When a user issues a
statement that would modify the database, SQL Server automatically
writes the changes to the log. After all changes for a statement
have been recorded in the log, they are written to an in-cache
copy of the data page. The data page remains in cache until the
memory is needed for another database page. At that time, it is
written to disk. If any statement in a transaction fails to
complete, SQL Server reverses all changes made by the transaction.
SQL Server writes an "end transaction" record to the log at the
end of each transaction, recording the status (success or failure)
of the transaction
As such, the log will grow as user connections affect changes to the
database. The need arises to then clear out the log of all transactions that
have been flushed to disk. This is performed by issuing the following
command:
dump transaction my_stinking_db to logdump_for_my_db
go
The SQL Server will write to the dumpdevice all transactions that have been
committed to disk and will delete the entries from its copy, thus freeing up
space in the log. Dumping of the transaction logs is accomplished via cron.
We schedule the heavily hit databases every 20 minutes during peak times.
A single user can fill up the log by having begin transaction with
no corresponding commit/rollback transaction. This is because all
their changes are being applied to the log as an open-ended
transaction, which is never closed. This open-ended transaction
cannot be flushed from the log, and therefore grows until it
occupies all of the free space on the log device.
And the way we dump it is with a dump device. :-)
An Example
If the DBA has four databases to plop on this SQL Server and they need a
total of 800MB of data and 100MB of log (because that's what really matters
to us), then they'd probably do something like this:
1. allocate sufficient raw devices to cover the data portion of all the
databases
2. allocate sufficient raw devices to cover the log portion of all the
databases
3. start allocating the databases to the devices.
For example, assuming the following database requirements:
Database
Requirements
DB Data Log
a 300 30
b 400 40
c 100 10
and the following devices:
Devices
Logical Physical Size
dks3d1s2_data /dev/rdsk/dks3d1s2 500
dks4d1s2_data /dev/rdsk/dks4d1s2 500
dks5d1s0_log /dev/rdsk/dks5d1s0 200
then the DBA may elect to create the databases as follows:
create database a on dks3d1s2_data = 300 log on dks5d1s0_log = 30
create database b on dks4d1s2_data = 400 log on dks5d1s0_log = 40
create database c on dks3d1s2_data = 50, dks4d1s2_data = 50 log on
dks5d1s0_log = 10
Some of the devices will have extra space available because out database
allocations didn't use up all the space. That's fine because it can be used
for future growth. While the Sybase SQL Server is running, no other Sybase
SQL Server can re-allocate these physical devices.
TempDB
TempDB is simply a scratch pad database. It gets recreated when a SQL Server
is rebooted. The information held in this database is temporary data. A
query may build a temporary table to assist it; the Sybase optimizer may
decide to create a temporary table to assist itself.
Since this is an area of constant activity we create this database over a
cooked file system which has historically proven to have better performance
than raw - due to the buffered writes provided by the Operating System.
Port Numbers
When creating a new SQL Server, we allocate a port to it (currently, DBA
reserves ports 1500 through 1899 for its use). We then map a host name to
the different ports: hera, fddi-hera and so forth. We can actually have more
than one port number for a SQL Server but we typically don't do this.
----------------------------------------------------------------------------
Q1.11: CERTIFIED SYBASE PROFESSIONAL - _CSPDBA_
_________________________________________________________________
Here's a list of commonly asked questions about becoming a _CSPDBA_:
What are the exams like?
The exams are administered by Drake Testing and Technologies and are
given at Drake authorized testing centers. The Environment and
Operations exams each take an hour, and the Fundamentals exam takes an
hour and a half. Each exam contains between 60 and 90 questions. Many
of the questions are _multiple choice_, some are _select all that
apply_ and some are _fill in the blank_. Depending on the exam, a
score of 67% - 72% is required to pass. The exams are challenging, but
fair.
Before taking an exam, Drake provides you with a short _tutorial exam_
that you can take to get an idea of the format of the exam questions.
You receive a report each time you complete an exam. The report shows
the passing score, your total score, and your score in various
sections of the exam. (You aren't told which specific questions you
answered correctly or incorrectly.)
How do I register for the exams?
Call 1-800-8SYBASE, select option 2, then option 2 again. You will be
connected to a Drake representative. Currently each exam costs $150.
What happens once I pass?
You will receive a certificate in the mail about a month after you've
passed all the exams. When you receive your certificate, you'll also
have the opportunity to enter into a licensing agreement that will
allow you to use the Certified Sybase Professional service mark (logo)
in your office and on your business cards. If your company is an Open
Solutions partner, your certification is acknowledged by the
appearance of the CSP logo with your company's name in the Open
Solutions Directory. If you have a CompuServe account, you can obtain
access to a private section of _Sybase OpenLine_, a technical forum on
CompuServe.
What topics are covered?
* Sybase SQL Server Fundamentals Exam Topics:
+ Sybase client/server architecture
+ SQL Server objects
+ Use of tables
+ Use of indexes
+ Use of columns
+ Use of defaults
+ Use of triggers
+ Use of keys
+ Use of check constraints
+ Use of datatypes
+ Use of cursors
+ System datatypes
+ Views
+ Data integrity
+ Rules
+ Select statements
+ Transaction management
+ Locking
+ Stored procedures
+ Local and global variables
* Sybase SQL Server Environment Exam Topics:
+ Configuration and control
+ Starting the SQL Server
+ Accessing remote servers
+ Stopping the SQL Server
+ Using buildmaster
+ Installing the SQL Server
+ Using the standard databases
+ Admin Utilities and Tools
+ System stored procedures
+ Using system tables
+ Load and unload utilities
+ Resources
+ Disk mirroring
+ Creating databases
+ Managing segments
+ Managing transaction logs
+ Managing thresholds
+ Managing audit logs
+ Devices
+ Security
+ Establishing security
+ Roles
+ Managing user accounts
* Sybase SQL Server Operations Exam Topics:
+ Monitoring
+ Starting the Backup Server
+ Monitoring the errorlog
+ Diagnostics
+ Resolving contention and locking problems
+ Managing application stored procedures
+ Recovery
+ Backup
+ Load
+ Backup strategies
+ Security
+ Establishing security
+ Roles
+ Managing user accounts
+ Admin utilities and tools
+ System stored procedures
+ Using system tables
+ Load and unload utilities
_________________________________________________________________
Q1.12: RAID AND SYBASE
_________________________________________________________________
Here's a short summary of what you need to know about Sybase and RAID.
The newsgroup comp.arch.storage has a detailed FAQ on RAID, but here
are a few definitions:
RAID
RAID means several things at once. It provides increased performance
through disk striping, and/or resistance to hardware failure through
either mirroring (fast) or parity (slower but cheaper).
RAID 0
RAID 0 is just striping. It allows you to read and write quickly, but
provides no protection against failure.
RAID 1
RAID 1 is just mirroring. It protects you against failure, and
generally reads and writes as fast as a normal disk. It uses twice as
many disks as normal (and sends twice as much data across your SCSI
bus, but most machines have plenty of extra capacity on their SCSI
busses.)
_Sybase mirroring always reads from the primary copy, so it does not
increase read performance. _
RAID 0+1
RAID 0+1 (also called RAID 10) is striping and mirroring together.
This gives you the highest read and write performance of any of the
raid options, but uses twice as many disks as normal.
RAID 4/RAID 5
RAID 4 and 5 have disk striping and use 1 extra disk to provide
_parity_. Various vendors have various optimizations, but this RAID
level is generally much slower at writes than any other kind of RAID.
RAID 7
RAID 7 is a marketing slogan used by a company which unethically
advertises on Usenet. I would not advise doing business with them.
Details
Most hardware RAID controllers also provide a battery-backed RAM cache
for writing. This is very useful, because it allows the disk to claim
that the write succeeded before it has done anything. If there is a
power failure, the information will (hopefully) be written to disk
when the power is restored. The cache is very important because
database log writes cause the process doing the writes to stop until
the write is successful. Systems with write caching thus complete
transactions much more quickly than systems without.
What RAID levels should my data, log, etc be on? Well, the log disk is
_frequently written_, so it should not be on RAID 4 or 5. If your data
is _infrequently written_, you could use RAID 4 or 5 for it, because
you don't mind that writes are slow. If your data is frequently
written, you should use RAID 0+1 for it. Striping your data is a very
effective way of avoiding any one disk becoming a hot-spot.
Traditionally Sybase databases were divided among devices by a human
attempting to determine where the hot-spots are. Striping does this in
a straight-forward fashion, and also continues to work if your data
access patterns change.
Your tempdb is data but it is frequently written, so it should not be
on RAID 4 or 5.
If your RAID controller does not allow you to create several different
kinds of RAID volumes on it, than your only hope is to create a huge
RAID 0+1 set. If your RAID controler does not support RAID 0+1, you
shouldn't be using it for database work.
_________________________________________________________________
Q1.13: HOW TO SWAP A DB DEVICE WITH ANOTHER
_________________________________________________________________
Here are four approaches. Before attempting _any_ of the following:
Backup, Backup, Backup.
1. Dump and Restore
1. Backup the databases on the device, drop the databases, drop
the devices. and
2. Rebuild the devices
3. Rebuild the databases (Make sure you recreate the fragments
correctly - See Ed Barlows scripts for a sp that helps you do
this if you've lost your notes. Failure to do this will
possibly lead to log pages in data pages, and vice versa).
4. Reload the database dumps!
2. Twiddle the Data Dictionary - for brave _experts_ only.
1. Shut down the server.
2. Do a physical dump (using _dd(1)_, or such utility) of the
device to be moved.
3. Load the dump to the new device
4. Edit the data dictionary (sysdevices.physname) to point to
the new device.
3. The Mirror Trick
1. Create a mirror of the old device, on the new device.
2. Unmirror the primary device, thereby making the _backup_ the
primary device.
3. Repeat this for all devices until the old disk is free.
4. (Unix only) This option is no use if you need to move a device
now, rather if you anticipate moving a device at some point in the
future.
You may want to use this approach for creating _any_ database.
Create (or use) a directory for symbolic links to the devices you
wish to use. Then create your database, but instead of going to
/dev/device, go to /directory/symlink - When it comes time to move
your devices, you shut down the server, simply _dd(1)_ the data
from the old device to the new device, recreate the symbolic links
to the new device and restart the SQL Server. Simple as that.
_Backups are a requisite in all cases, just in case_.
_________________________________________________________________
Q1.14: SERVER NAMING AND RENAMING
_________________________________________________________________
There are three totally separate places where SQL Server _names_
reside, causing much confusion.
SQL Server Host Machine _interfaces_ File
A _master_ entry in here for server _TEST_ will provide the network
information that the server is expected to listen on. The -S parameter
to the dataserver executable tells the server which entry to look for,
so in the RUN_TEST file, -STEST will tell the dataserver to look for
the entry under TEST in the interfaces file and listen on any network
parameters specified by 'master' entries.
TEST
master tcp ether hpsrv1 1200
query tcp ether hpsrv1 1200
Note that preceding the _master/query_ entries there's a tab.
This is as far as the name _TEST_ is used. Without further
configuration the server does not know its name is _TEST_, nor do any
client applications. Typically there will also be _query_ entries
under _TEST_ in the local _interfaces_ file, and client programs
running on the same machine as the server will pick this connection
information up. However, there is nothing to stop the _query_ entry
being duplicated under another name entirely in the same _interfaces_
file.
ARTHUR
query tcp ether hpsrv1 1200
_isql -STEST_ or _isql -SARTHUR_ will connect to the same server. The
name is simply a search parameter into the _interfaces_ file.
Client Machine _interfaces_ File
Again, as the server name specified to the client is simply a search
parameter for Open Client into the _interfaces_ file, SQL.INI or
WIN.INI the name is largely irrelevant. It is often set to something
that means something to the users, especially where they might have a
choice of servers to connect to. Also multiple query entries can be
set to point to the same server, possibly using different network
protocols. Eg. if _TEST_ has the following master entries on the host
machine:
TEST
master tli spx /dev/nspx/ \xC12082580000000000012110
master tcp ether hpsrv1 1200
Then the client can have a meaningful name:
ACCOUNTS_TEST_SERVER
query tcp ether hpsrv1 1200
or alternative protocols:
TEST_IP
query tcp ether hpsrv1 1200
TEST_SPX
query tli spx /dev/nspx/ \xC12082580000000000012110
sysservers
This system table holds information about remote SQL Servers that
local one might want to connect to, and also provides a method of
naming the local server.
Entries are added using the sp_addserver system procedure - add a
remote server with this format:
sp_addserver server_name, null, network_name
server_name is any name you wish to refer to a remote server by, but
network_name must be the name of the remote server as referenced in
the interfaces file local to your local server. It normally makes
sense to make the server_name the same as the network_name, but you
can easily do:
sp_addserver LIVE, null, ACCTS_LIVE
When you execute for example, exec LIVE.master..sp_helpdb the local
SQL Server will translate LIVE to ACCTS_LIVE and try and talk to
ACCTS_LIVE via the ACCTS_LIVE entry in the local interfaces file.
Finally, a variation on the sp_addserver command:
sp_addserver LOCALSRVNAME, local
names the local server (after a restart). This is the name the server
reports in the errorlog at startup, the value returned by
@@SERVERNAME, and the value placed in Open Client server messages. It
can be completely different from the names in RUN_SRVNAME or in local
or remote interfaces - it has _no_ bearing on connectivity matters.
_________________________________________________________________
Q1.15: HOW CAN I TELL THE DATETIME MY SERVER STARTED?
_________________________________________________________________
Method #1
The normal way would be to look at the errorlog, but this is not
always convenient or even possible. From a SQL session you find out
the server startup time to within a few seconds using:
select "Server Start Time" = crdate
from master..sysdatabases
where name = "tempdb"
Method #2
Another useful query is:
select * from sysengines
which gives the address and port number at which the server is
listening.
_________________________________________________________________
Q1.16: RAW PARTITIONS OR REGULAR FILES?
_________________________________________________________________
Hmmm... as always, this answer depends on the vendor's implementation
on a cooked file system for the SQL Server...
Performance Hit (synchronous vs asynchronous)
If on this platform, the SQL Server performs file system I/O
synchronously then the SQL Server is blocked on the read/write and
throughput is decreased tremendously.
The way the SQL Server typically works is that it will issue an I/O
(read/write) and save the I/O control block and continue to do other
work (on behalf of other connections). It'll periodically poll the
workq's (network, I/O) and resume connections when their work has
completed (I/O completed, network data xmit'd...).
Performance Hit (bcopy issue)
Assuming that the file system I/O is asynchronous (this can be done on
SGI), a performance hit may be realized when bcopy'ing the data from
kernel space to user space.
Cooked I/O typically (again, SGI has something called directed I/O
which allows I/O to go directly to user space) has to go from disk, to
kernel buffers and from kernel buffers to user space; on a read. The
extra layer with the kernel buffers is inherently slow. The data is
moved from kernel buffers to/fro user space using bcopy(). On small
operations this typically isn't that much of an issue but in a RDBMS
scenario the bcopy() layer is a significant performance hit because
it's done so often...
Performance Gain!
It's true, using file systems, at times you can get performance gains
assuming that the SQL Server on your platform does the I/O
asynchronously (although there's a caveat on this too... I'll cover
that later on).
If your machine has sufficient memory and extra CPU capacity, you can
realize some gains by having writes return immediately because they're
posted to memory. Reads will gain from the anticipatory fetch
algorithm employed by most O/S's.
You'll need extra memory to house the kernel buffered data and you'll
need extra CPU capacity to allow bdflush() to write the dirty data out
to disk... eventually... but with everything there's a cost: extra
memory and free CPU cycles.
One argument is that instead of giving the O/S the extra memory (by
leaving it free) to give it to the SQL Server and let it do its
caching... but that's a different thread...
Data Integrity and Cooked File System
If the Sybase SQL Server is _not_ certified to be used over a cooked
file system, because of the nature of the kernel buffering (see the
section above) you may face database corruption by using cooked file
system anyway. The SQL Server _thinks_ that it has posted its changes
out to disk but in reality it has gone only to memory. If the machine
halts without bdflush() having a chance to flush memory out to disk,
your database _may_ become corrupted.
Some O/S's allow cooked files to have a _write through_ mode and it
really depends if the SQL Server has been certified on cooked file
systems. If it has, it means that when the SQL Server opens a device
which is on a file system, it fcntl()'s the device to write-through.
When to use cooked file system?
I typically build my tempdb on cooked file system and I don't worry
about data integrity because tempdb is _rebuilt_ everytime your SQL
Server is rebooted.
Q2.1: CHANGING VARCHAR(M) TO VARCHAR(N)
_________________________________________________________________
Before you start:
select max(datalength(column_name)) from _affected_table_
In other words, _please_ be sure you're going into this with your head
on straight.
How To Change System Catalogs
This information is _Critical To The Defense Of The Free World_, and
you would be _Well Advised To Do It Exactly As Specified_:
use master
go
sp_configure "allow updates", 1
go
reconfigure with override /* System 10 and below */
go
use _victim_database_
go
select name, colid
from syscolumns
where id = object_id("_affected_table_")
go
begin tran
go
update syscolumns
set length = _new_value_
where id = object_id("_affected_table_")
and colid = _value_from_above_
go
update sysindexes
set maxlen = maxlen + _increase/decrease?_
where id=object_id("_affected_table_")
and indid = 0
go
/* check results... cool? Continue... else _rollback tran_ */
commit tran
go
use master
go
sp_configure "allow updates", 0
go
reconfigure /* System 10 and below */
go
_________________________________________________________________
Q2.2: FAQ ON PARTITIONING
_________________________________________________________________
Index of Sections
* What Is Table Partitioning?
+ Page Contention for Inserts
+ I/O Contention
+ Caveats Regarding I/O Contention
* Can I Partition Any Table?
+ How Do I Choose Which Tables To Partition?
* Does Table Partitioning Require User-Defined Segments?
* Can I Run Any Transact-SQL Command on a Partitioned Table?
* How Does Partition Assignment Relate to Transactions?
* Can Two Tasks Be Assigned to the Same Partition?
* Must I Use Multiple Devices to Take Advantage of Partitions?
* How Do I Create A Partitioned Table That Spans Multiple Devices?
* How Do I Take Advantage of Table Partitioning with bcp in?
* Getting More Information on Table Partitioning
What Is Table Partitioning?
Table partitioning is a procedure that creates multiple page chains
for a single table.
The primary purpose of table partitioning is to improve the
performance of concurrent inserts to a table by reducing contention
for the last page of a page chain.
Partitioning can also potentially improve performance by making it
possible to distribute a table's I/O over multiple database devices.
Page Contention for Inserts
By default, SQL Server stores a table's data in one double-linked set
of pages called a page chain. If the table does not have a clustered
index, SQL Server makes all inserts to the table in the last page of
the page chain.
When a transaction inserts a row into a table, SQL Server holds an
exclusive page lock on the last page while it inserts the row. If the
current last page becomes full, SQL Server allocates and links a new
last page.
As multiple transactions attempt to insert data into the table at the
same time, performance problems can occur. Only one transaction at a
time can obtain an exclusive lock on the last page, so other
concurrent insert transactions block each other.
Partitioning a table creates multiple page chains (partitions) for the
table and, therefore, multiple last pages for insert operations. A
partitioned table has as many page chains and last pages as it has
partitions.
I/O Contention
Partitioning a table can improve I/O contention when SQL Server writes
information in the cache to disk. If a table's segment spans several
physical disks, SQL Server distributes the table's partitions across
fragments on those disks when you create the partitions.
A fragment is a piece of disk on which a particular database is
assigned space. Multiple fragments can sit on one disk or be spread
across multiple disks.
When SQL Server flushes pages to disk and your fragments are spread
across different disks, I/Os assigned to different physical disks can
occur in parallel.
To improve I/O performance for partitioned tables, you must ensure
that the segment containing the partitioned table is composed of
fragments spread across multiple physical devices.
Caveats Regarding I/O Contention
Be aware that when you use partitioning to balance I/O you run the
risk of disrupting load balancing even as you are trying to achieve
it. The following scenarios can keep you from gaining the load
balancing benefits you want:
* You are partitioning an existing table. The existing data could be
sitting on any fragment. Because partitions are randomly assigned,
you run the risk of filling up a fragment. The partition will then
steal space from other fragments, thereby disrupting load
balancing.
* Your fragments differ in size.
* The segment maps are configured such that other objects are using
the fragments to which the partitions are assigned.
* A very large bcp job inserts many rows within a single
transaction. Because a partition is assigned for the lifetime of a
transaction, a huge amount of data could go to one particular
partition, thus filling up the fragment to which that partition is
assigned.
Can I Partition Any Table?
No. You cannot partition the following kinds of tables:
1. Tables with clustered indexes
2. SQL Server system tables
3. Work tables
4. Temporary tables
5. Tables that are already partitioned. However, you can unpartition
and then re-partition tables to change the number of partitions.
How Do I Choose Which Tables To Partition?
You should partition heap tables that have large amounts of concurrent
insert activity. (A heap table is a table with no clustered index.)
Here are some examples:
1. An "append-only" table to which every transaction must write
2. Tables that provide a history or audit list of activities
3. A new table into which you load data with bcp in. Once the data is
loaded in, you can unpartition the table. This enables you to
create a clustered index on the table, or issue other commands not
permitted on a partition table.
Does Table Partitioning Require User-Defined Segments?
No. By design, each table is intrinsically assigned to one segment,
called the default segment. When a table is partitioned, any
partitions on that table are distributed among the devices assigned to
the default segment.
In the example under "How Do I Create A Partitioned Table That Spans
Multiple Devices?", the table sits on a user-defined segment that
spans three devices.
Can I Run Any Transact-SQL Command on a Partitioned Table?
No. Once you have partitioned a table, you cannot use any of the
following Transact-SQL commands on the table until you unpartition it:
1. create clustered index
2. drop table
3. sp_placeobject
4. truncate table
5. alter table table_name partition n
How Does Partition Assignment Relate to Transactions?
A user is assigned to a partition for the duration of a transaction.
Assignment of partitions resumes with the first insert in a new
transaction. The user holds the lock, and therefore partition, until
the transaction ends.
For this reason, if you are inserting a great deal of data, you should
batch it into separate jobs, each within its own transaction. See "How
Do I Take Advantage of Table Partitioning with bcp in?", for details.
Can Two Tasks Be Assigned to the Same Partition?
Yes. SQL Server randomly assigns partitions. This means there is
always a chance that two users will vie for the same partition when
attempting to insert and one would lock the other out.
The more partitions a table has, the lower the probability of users
trying to write to the same partition at the same time.
Must I Use Multiple Devices to Take Advantage of Partitions?
It depends on which type of performance improvement you want.
Table partitioning improves performance in two ways: primarily, by
decreasing page contention for inserts and, secondarily, by decreasing
i/o contention. "What Is Table Partitioning?" explains each in detail.
If you want to decrease page contention you do not need multiple
devices. If you want to decrease i/o contention, you must use multiple
devices.
How Do I Create A Partitioned Table That Spans Multiple Devices?
Creating a partitioned table that spans multiple devices is a
multi-step procedure. In this example, we assume the following:
* We want to create a new segment rather than using the default
segment.
* We want to spread the partitioned table across three devices,
data_dev1, data_dev2, and data_dev3.
Here are the steps:
1. Define a segment:
sp_addsegment newsegment, my_database,data_dev1
2. Extend the segment across all three devices:
sp_extendsegment newsegment, my_database, data_dev2
sp_extendsegment newsegment, my_database, data_dev3
3. Create the table on the segment:
create table my_table
(names, varchar(80) not null)
on newsegment
4. Partition the table:
alter table my_table partition 30
How Do I Take Advantage of Table Partitioning with bcp in?
You can take advantage of table partitioning with bcp in by following
these guidelines:
1. Break up the data file into multiple files and simultaneously run
each of these files as a separate bcp job against one table.
Running simultaneous jobs increases throughput.
2. Choose a number of partitions greater than the number of bcp jobs.
Having more partitions than processes (jobs) decreases the
probability of page lock contention.
3. Use the batch option of bcp in. For example, after every 100 rows,
force a commit. Here is the syntax of this command:
bcp table_name in filename -b100
Each time a transaction commits, SQL Server randomly assigns a new
partition for the next insert. This, in turn, reduces the
probability of page lock contention.
Getting More Information on Table Partitioning
For more information on table partitioning, see the chapter on
controlling physical data placement in the SQL Server Performance and
Tuning Guide.
_________________________________________________________________
Q2.3: HOW DO I TURN OFF _MARKED SUSPECT_ ON MY DATABASE?
_________________________________________________________________
Say one of your database is marked suspect as the SQL Server is coming
up. Here are the steps to take to unset the flag.
_Remember to fix the problem that caused the database to be marked
suspect after switching the flag. _
Pre System 10
1. sp_configure "allow updates", 1
2. reconfigure with override
3. select status - 320 from sysdatabases where dbid =
db_id("my_hosed_db") - save this value.
4. begin transaction
5. update sysdatabases set status = _-32767_ where dbid =
db_id("my_hosed_db")
6. commit transaction
7. you should be able to access the database for it to be cleared
out. If not:
1. shutdown
2. startserver -f RUN_*
8. _fix the problem that caused the database to be marked suspect_
9. begin transaction
10. update sysdatabases set status = _saved_value_ where dbid =
db_id("my_hosed_db")
11. commit transaction
12. sp_configure "allow updates", 0
13. reconfigure
System 10
1. sp_configure "allow updates", 1
2. reconfigure with override
3. select status - 320 from sysdatabases where dbid =
db_id("my_hosed_db") - save this value.
4. begin transaction
5. update sysdatabases set status = _-32768_ where dbid =
db_id("my_hosed_db")
6. commit transaction
7. shutdown
8. startserver -f RUN_*
9. _fix the problem that caused the database to be marked suspect_
10. begin transaction
11. update sysdatabases set status = _saved_value_ where dbid =
db_id("my_hosed_db")
12. commit transaction
13. sp_configure "allow updates", 0
14. reconfigure
15. shutdown
16. startserver -f RUN_*
_________________________________________________________________
Q2.4: HOW TO MANUALLY DROP A TABLE
_________________________________________________________________
Occasionally you may find that after issuing a _drop table_ command
that the SQL Server crashed and consequently the table didn't drop
entirely. Sure you can't see it but that sucker is still floating
around somewhere.
Here's a list of instructions to follow when trying to drop a corrupt
table:
1.
sp_configure allow, 1
go
reconfigure with override
go
2. Write _db_id_ down.
use _db_name_
go
select db_id()
go
3. Write down the _id_ of the _bad_table_:
select id from sysobjects where name = _bad_table_name_
go
4. You will need these index IDs to run _dbcc extentzap_. Also,
remember that if the table has a clustered index you will need to
run _extentzap_ on index "0", even though there is no sysindexes
entry for that indid.
select indid from sysindexes where id = _table_id_
go
5. This is not required but a good idea:
begin transaction
go
6. Type in this short script, this gets rid of all system catalog
information for the object, including any object and procedure
dependencies that may be present.
Some of the entries are unnecessary but better safe than sorry.
declare @obj int
select @obj = id from sysobjects where name =
delete syscolumns where id = @obj
delete sysindexes where id = @obj
delete sysobjects where id = @obj
delete sysprocedures where id in
(select id from sysdepends where depid = @obj)
delete sysdepends where depid = @obj
delete syskeys where id = @obj
delete syskeys where depid = @obj
delete sysprotects where id = @obj
delete sysconstraints where tableid = @obj
delete sysreferences where tableid = @obj
delete sysdepends where id = @obj
go
7. Just do it!
commit transaction
go
8. Gather information to run _dbcc extentzap_:
use master
go
sp_dboption _db_name_, read, true
go
use _db_name_
go
checkpoint
go
9. Run _dbcc extentzap_ once for _each_ index (including index 0, the
data level) that you got from above:
use master
go
dbcc traceon (3604)
go
dbcc extentzap (_db_id_, _obj_id_, _indx_id_, 0)
go
dbcc extentzap (_db_id_, _obj_id_, _indx_id_, 1)
go
Notice that extentzap runs _twice_ for each index. This is because
the last parameter (the _sort_ bit) might be 0 or 1 for each index,
and you want to be absolutely sure you clean them all out.
10. Clean up after yourself.
sp_dboption _db_name_, read, false
go
use _db_name_
go
checkpoint
go
sp_configure allow, 0
go
reconfigure with override
go
_________________________________________________________________
Q2.5: WHY NOT MAX OUT ALL MY COLUMNS?
_________________________________________________________________
People occasionally ask the following valid question:
Suppose I have varying lengths of character strings none of which
should exceed 50 characters.
_Is there any advantage of last_name varchar(50) over this last_name
varchar(255)?_
That is, for simplicity, can I just define all my varying strings to
be varchar(255) without even thinking about how long they may
actually be? Is there any storage or performance penalty for this.
There is no performance penalty by doing this but as another netter
pointed out:
If you want to define indexes on these fields, then you should
specify the smallest size because the sum of the maximal lengths of
the fields in the index can't be greater than 256 bytes.
and someone else wrote in saying:
Your data structures should match the business requirements. This
way the data structure themselves becomes a data dictionary for
others to model their applications (report generation and the like).
_________________________________________________________________
Q2.6: WHAT'S A GOOD EXAMPLE OF A TRANSACTION?
_________________________________________________________________
This answer is geared for Online Transaction Processing (OTLP)
applications.
To gain maximum throughput all your transactions should be in stored
procedures - see Q8.8. The transactions within each stored procedure
should be short and simple. All validation should be done outside of
the transaction and only the modification to the database should be
done within the transaction. Also, don't forget to name the
transaction for _sp_whodo_ - see Q9.2.
The following is an example of a _good_ transaction:
/* perform validation */
select ...
if ... /* error */
/* give error message */
else /* proceed */
begin
begin transaction acct_addition
update ...
insert ...
commit transaction acct_addition
end
The following is an example of a _bad_ transaction:
begin transaction poor_us
update X ....
select ...
if ... /* error */
/* give error message */
else /* proceed */
begin
update ...
insert ...
end
commit transaction poor_us
This is bad because:
* the first update on table X is held throughout the transaction.
The idea with OLTP is to get in and out _fast_.
* If an error message is presented to the end user and we await
their response, we'll maintain the lock on table X until the user
presses return. If the user is out in the can we can wait for
hours.
_________________________________________________________________
Q2.7: WHAT'S A NATURAL KEY?
_________________________________________________________________
Let me think back to my database class... okay, I can't think that far
so I'll paraphrase... essentially, a _natural key_ is a key for a
given table that uniquely identifies the row. It's natural in the
sense that it follows the business or real world need.
For example, assume that social security numbers are unique (I believe
it is strived to be unique but it's not always the case), then if you
had the following employee table:
employee:
ssn char(09)
f_name char(20)
l_name char(20)
title char(03)
Then a natural key would be _ssn_. If the combination of __name_ and
_l_name_ were unique at this company, then another _natural key_ would
be _f_name, l_name_. As a matter of fact, you can have many _natural
keys_ in a given table but in practice what one does is build a
surrogate (or artificial) key.
The surrogate key is guaranteed to be unique because (wait, get back,
here it goes again) it's typically a monotonically increasing value.
Okay, my mathematician wife would be proud of me... really all it
means is that the key is increasing linearly: i+1
The reason one uses a surrogate key is because your joins will be
faster.
If we extended our employee table to have a surrogate key:
employee:
id identity
ssn char(09)
f_name char(20)
l_name char(20)
title char(03)
Then instead of doing the following:
where a.f_name = b.f_name
and a.l_name = a.l_name
we'd do this:
We can build indexes on these keys and since Sybase's atomic storage
unit is 2K, we can stash more values per 2K page with smaller indexes
thus giving us better performance (imagine the key being 40 bytes
versus being say 4 bytes... how many 40 byte values can you stash in a
2K page versus a 4 byte value? -- and how much wood could a wood chuck
chuck, if a wood chuck could chuck wood?)
Does it have anything to do with natural joins?
Um, not really... from "A Guide to Sybase..", McGovern and Date, p.
112:
The equi-join by definition must produce a result containing two
identical columns. If one of those two columns is eliminated, what
is left is called the natural join.
_________________________________________________________________
Q2.8: MAKING A STORED PROCEDURE INVISIBLE
_________________________________________________________________
System 11.5 and above
It is now possible to encrypt your stored procedure code that is
stored in the syscomments table. This is preferred than the old method
of deleting the data as deleting will impact future upgrades. You can
encrypt the text with the sp_hidetext system procedure.
Pre-System 11.5
Perhaps you are trying to not allow the buyer of your software
_defncopy_ all your stored procedures. It is perfectly safe to delete
the syscomments entries of any stored procedures you'd like to
protect:
sp_configure "allow updates", 1
go
reconfigure with override /* System 10 and below */
go
use _affected_database_
go
delete syscomments where id = object_id("_procedure_name_")
go
use master
go
sp_configure "allow updates", 0
go
I believe in future releases of Sybase we'll be able to _see_ the SQL
that is being executed. I don't know if that would be simply the
stored procedure name or the SQL itself.
_________________________________________________________________
Q2.9: SAVING SPACE WHEN INSERTING ROWS MONOTONICALLY
_________________________________________________________________
If the columns that comprise the clustered index are monotonically
increasing (that is, new row key values are greater than those
previously inserted) the following System 11 dbcc tune will not split
the page when it's half way full. Rather it'll let the page fill and
then allocate another page:
dbcc tune(ascinserts, 1, "_my_table_")
By the way, SyBooks is wrong when it states that the above needs to be
reset when the SQL Server is rebooted. This is a permanent setting.
To undo it:
dbcc tune(ascinserts, 0, "_my_table_")
_________________________________________________________________
Q2.10: HOW TO COMPUTE DATABASE FRAGMENTATION
_________________________________________________________________
Command
dbcc traceon(3604)
go
dbcc tab(production, _my_table_, 0)
go
Interpretation
A delta of one means the next page is on the same track, two is a
short seek, three is a long seek. You can play with these constants
but they aren't that important.
A table I thought was unfragmented had L1 = 1.2 L2 = 1.8
A table I thought was fragmented had L1 = 2.4 L2 = 6.6
How to Fix
You fix a fragmented table with clustered index by dropping and
creating the index. This measurement isn't the correct one for tables
without clustered indexes. If your table doesn't have a clustered
index, create a dummy one and drop it.
_________________________________________________________________
Q2.11: Tasks a DBA should do...
----------------------------------------------------------------------------
I was asked by a poster to list what a DBA's tasks ought to be. Here's what
I believe (this will evolve as time progresses):
DBA Tasks
Task Reason Period
If your SQL Server permits,
I consider daily before your database
dbcc checkdb, these the dumps. If this is not possible
checkcatalog, minimal dbcc's due to the size of your
checkalloc to ensure the databases, then try the
integrity of different options so that the
your database end of, say, a week, you've run
them all.
Disaster recovery Always be
scripts - scripts prepared for
to rebuild your SQL the worst. Make
Server in case of sure to test
hardware failure them.
scripts to
logically dump your
master database,
that is bcp the You can
critical system selectively
tables: rebuild your
sysdatabases, database in Daily
sysdevices, case of
syslogins, hardware
sysservers, failure
sysusers,
syssegments,
sysremotelogins
A system
%ls -la upgrade is After any change as well as
disk_devices known to change daily
the
permissions.
dump the user
databases CYA Daily
dump the
transaction logs CYA Daily
dump the master After any change as well as
database CYA daily
System 11 and This is the
beyond - save the configuration After any change as well as
$DSQUERY.cfg to that you've daily
tape dialed in, why
redo the work?
Depending on how often your
major tables change. Some tables
are pretty much static (e.g.
lookup tables) so they don't
update statistics need an update statistics, other
on frequently To ensure the tables suffer severe trauma
changed tables and performance of (e.g. massive
sp_recompile your SQL Server updates/deletes/inserts) so an
update stats needs to be run
either nightly/weekly/monthly.
This should be done using
cronjobs.
create a dummy SQL
Server and do bad
things to it: See disaster
delete devices, recovery! When time permits
destroy
permissions...
Talk to the It's better to
application work with them As time permits.
developers. than against
them.
Learn new tools So you can As time permits.
sleep!
Read c.d.s Passes the Priority One!
time.
----------------------------------------------------------------------------
Q2.10: HOW TO IMPLEMENT DATABASE SECURITY
_________________________________________________________________
This is a brief run-down of the features and ideas you can use to
implement database security:
Logins, Roles, Users, Aliases and Groups
* sp_addlogin - Creating a login adds a basic authorisation for an
account - a username and password - to connect to the server. By
default, no access is granted to any individual databases.
* sp_adduser - A user is the addition of an account to a specific
database.
* sp_addalias - An alias is a method of allowing an account to use a
specific database by impersonating an existing database user or
owner.
* sp_addgroup - Groups are collections of users at the database
level. Users can be added to groups via the sp_adduser command.
A user can belong to only one group - a serious limitation that
Sybase might be addressing soon according to the ISUG enhancements
requests. Permissions on objects can be granted or revoked to or
from users or groups.
* sp_role - A role is a high-level Sybase authorisation to act in a
specific capacity for administration purposes. Refer to the Sybase
documentation for details.
Recommendations
Make sure there is a unique login account for each physical person
and/or process that uses the server. Creating generic logins used by
many people or processes is a _bad idea_ - there is a loss of
accountability and it makes it difficult to track which particular
person is causing server problems when looking at the output of
sp_who. Note that the output of sp_who gives a hostname - properly
coded applications will set this value to something meaningful (ie.
the machine name the client application is running from) so you can
see where users are running their programs. Note also that if you look
at master..sysprocesses rather than just sp_who, there is also a
program_name. Again, properly coded applications will set this (eg. to
'isql') so you can see which application is running. If you're coding
your own client applications, make sure you set hostname and
program_name via the appropriate Open Client calls. One imaginative
use I've seen of the program_name setting is to incorporate the
connection time into the name, eg APPNAME-DDHHMM (you have 16
characters to play with), as there's no method of determining this
otherwise.
Set up groups, and add your users to them. It is much easier to manage
an object permissions system in this way. If all your permissions are
set to groups, then adding a user to the group ensures that users
automatically inherit the correct permissions - administration is
*much* simpler.
Objects and Permissions
Access to database objects is defined by granting and/or revoking
various access rights to and from users or groups. Refer to the Sybase
documentation for details.
Recommendations
The ideal setup has all database objects being owned by the dbo,
meaning no ordinary users have any default access at all. Specific
permissions users require to access the database are granted
explicitly. As mentioned above - set permissions for objects to a
group and add users to that group. Any new user added to the database
via the group then automatically obtains the correct set of
permissions.
Preferably, no access is granted at all to data tables, and all read
and write activity is accomplished through stored procedures that
users have execute permission on. The benefit of this from a security
point of view is that access can be rigidly controlled with reference
to the data being manipulated, user clearance levels, time of day, and
anything else that can be programmed via T-SQL. The other benefits of
using stored procedures are well known (see Q8.8). Obviously whether
you can implement this depends on the nature of your application, but
the vast majority of in-house-developed applications can rely solely
on stored procedures to carry out all the work necessary. The only
server-side restriction on this method is the current inability of
stored procedures to adequately handle text and image datatypes (see
Q8.12). To get around this views can be created that expose only the
necessary columns to direct read or write access.
Views
Views can be a useful general security feature. Where stored
procedures are inappropriate views can be used to control access to
tables to a lesser extent. They also have a role in defining row-level
security - eg. the underlying table can have a security status column
joined to a user authorisation level table in the view so that users
can only see data they are cleared for. Obviously they can also be
used to implement column-level security by screening out sensitive
columns from a table.
Triggers
Triggers can be used to implement further levels of security - they
could be viewed as a last line of defence in being able to rollback
unauthorised write activity (they cannot be used to implement any read
security). However, there is a strong argument that triggers should be
restricted to doing what they were designed for - implementing
referential integrity - rather being loaded up with application logic.
Administrative Roles
With Sybase version 10 came the ability to grant certain
administrative roles to user accounts. Accounts can have sa-level
privilege, or be restricted to security or operator roles - see
sp_role.
Recommendations
The use of any generic account is not a good idea. If more than one
person requires access as sa to a server, then it is more accountable
and traceable if they each have an individual account with sa_role
granted.
_________________________________________________________________
Q2.13: HOW TO SHRINK A DATABASE
_________________________________________________________________
_Warning: This document has not been reviewed. Treat it as
alpha-test quality information and report any problems and
suggestions to br...@sybase.com _
It has historically been difficult to shrink any database except
tempdb (because it is created fresh every boot time). The two methods
commonly used have been:
1. Ensure that you have scripts for all your objects (some tools like
SA Companion or DB Artisian can create scripts from an existing
database), then bcp out your data, drop the database, recreate it
smaller, run your scripts, and bcp in your data.
2. Use a third-party tool such as DataTool's SQL Backtrack, which in
essence automates the first process.
This technote outlines a third possibility that can work in most
cases.
An Unsupported Method to Shrink a Database
This process is fairly trivial in some cases, such as removing a
recently added fragment or trimming a database that has a log fragment
as its final allocation, but can also be much more complicated or time
consuming than the script and bcp method.
General Outline
The general outline of how to do it is:
1. Make a backup of the current database
2. Migrate data from sysusages fragments with high lstart values to
fragments with low lstart values.
3. Edit sysusages to remove high lstart fragments that no longer have
data allocations.
4. Reboot sql server.
Details
1. Dump your database. If anything goes wrong, you will need to
recover from this backup!
2. Decide how many megabytes of space you wish to remove from your
database.
3. Examine sysusages for the database. You will be shrinking the
database by removing the fragments with the highest lstart values.
If the current fragments are not of appropriate sizes, you may
need to drop the database, recreate it so there are more
fragments, and reload the dump.
A trivial case: An example of a time when you can easily shrink a
database is if you have just altered it and are sure there has been
no activity on the new fragment. In this case, you can directly
delete the last row in sysusages for the db (this row was just added
by alter db) and reboot the server and it should come up cleanly.
4. Change the segmaps of the fragments you plan to remove to 0. This
will prevent future data allocations to these fragments.
Note: If any of the fragments you are using have user defined
segments on them, drop those segments before doing this.
sp_configure "allow updates", 1
go
reconfigure with override
go
update sysusages set segmap = 0
where dbid = <dbid> and lstart = <lstart>
go
dbcc dbrepair(<dbname>, remap)
go
Ensure that there is at least one data (segmap 3) and one log
(segmap 4) fragment, or one mixed (segmap 7) fragment.
If the server has been in use for some time, you can shrink it by
deleting rows from sysusages for the db, last rows first , after
making sure that no objects have any allocations on the usages.
5. Determine which objects are on the fragments you plan to remove.
dbcc traceon(3604)
go
dbcc usedextents( dbid,0,0,1)
go
Find the extent with the same value as the lstart of the first
fragment you plan to drop. You need to migrate every object
appearing from this point on in the output.
6. Migrate these objects onto earlier fragments in the database.
Objids other than 0 or 99 are objects that you must migrate or
drop. You can migrate a user table by building a new clustered
index on the table (since the segmap was changed, the new
allocations will not go on this fragment).
You can migrate some system tables (but not all) using the
sp_fixindex command to rebuild it's clustered index. However,
there are a few system tables that cannot have their clustered
indexes rebuilt, and if they have any allocations on the usage,
you are out of luck.
If the objid is 8, then it is the log. You can migrate the log by
ensuring that another usage has a log segment (segmap 4 or 7). Do
enough activity on the database to fill an extents worth of log
pages, then checkpoint and dump tran.
Once you have moved all the objects, delete the row from sysusages
and reboot the server.
Run dbcc checkdb and dbcc checkalloc on the database to be sure
you are ok, then dump the database again.
Q3.1: HOW TO SET _TS ROLE_
_________________________________________________________________
Some _DBCC_ commands require that you set _TS Role_ in order to run
them. Here's how to set it:
Login to Server as _sa_ and perform the following:
sp_role "grant", sybase_ts_role, sa
go
set role "sybase_ts_role" on
go
_________________________________________________________________
Q3.2: DBCC COMMAND REFERENCE
_________________________________________________________________
If you know of any more DBCC Commands, please mail to pa...@sgi.com.
For your consumption here they are, use at your own risk:
* allocdump( dbid, page )
* bhash( { print_bufs | no_print }, bucket_limit )
* buffer( [ dbid ][, objid ][, nbufs ], printopt = { 0 | 1 | 2 },
buftype )
* bytes( startaddress, length )
* checkalloc[( dbname [, fix | nofix ] ) ]
* checkcatalog[( dbname )]
* checkdb[( dbname [, skip_ncindex ] ) ]
* checktable( tablename | tabid [, skip_ncindex ] )
* corrupt( tablename, indid, error )
+ 1133 error demonstrates that a page we think is an oam is not
+ 2502 error shows multiple references to the same page
+ 2503 error shows a breakage in the page linkage
+ 2521 error shows that the page is referenced but is not
allocated on the extent page
+ 2523 error shows that the page number in the page or catalog
entries are out-of-range for the database
+ 2525 error shows that an extent objid/indid do not match what
is on the page
+ 2529 error shows a page number out-of-range for the database
or a 605 style scenario
+ 2540 error occurs when a page is allocated on an extent but
the page is not referenced in the page chain
+ 2546 error occurs when an extent is found for an object
without an of its pages being referenced (a stranded extent)
+ 7939 error occurs when an allocation page which has extents
for an object are not reflected on the OAM page
+ 7940 error occurs when the total counts in the OAM page
differ from the actual count of pages in the chain
+ 7949 error is similar to a 7940 except that the counts are on
an allocation page basis
* cursorinfo(cursor_level, cursor_name) where
+ cursor_level - level of nesting. -1 is all nesting levels
* dbinfo( [ dbname ] )
* dbrepair( dbid, option = { dropdb | fixindex | fixsysindex },
table, indexid )
* dbrepair( dbid, ltmignore)
* dbtable( dbid )
* delete_row( dbid, pageid, delete_by_row = { 1 | 0 }, rownum )
* des( [ dbid ][, objid ] )
* engine(eng func) where _eng func_ may be:
+ "online"
+ "offline"
* extentcheck( dbid, objid, indexid, sort = {1|0} )
* extentdump( dbid, page )
* extentzap( dbid, objid, indexid, sort )
* findnotfullextents( dbid, objid, indexid, sort = { 1 | 0 } )
* fix_al( [ dbname ] )
* help( dbcc_command )
* ind( dbid, objid, printopt = { 0 | 1 | 2 } )
* indexalloc(tablename|tabid, indid, [full | optimized | fast],[fix
| nofix])
* listoam(dbid, table_id, indid) - may supply dbname/tablename
rather than id
* locateindexpgs( dbid, objid, page, indexid, level )
* lock - print out lock chains
* log(
[dbid][,objid][,page][,row][,nrecords][,type={-1..36}],printopt={0
|1} )
* memusage
* netmemshow( option = {1 | 2 | 3} )
* netmemusage
* newalloc( dbname, option = { 1 | 2 | 3 } )
* page( dbid, pagenum [, printopt={0|1|2} ][, cache={0|1} ][,
logical={1|0} ] )
* pglinkage( dbid, start, number, printopt={0|1|2}, target,
order={1|0} )
* pktmemshow( option = {spid} )
* procbuf( dbid, objid, nbufs, printopt = { 0 | 1 } )
* prtipage( dbid, objid, indexid, indexpage )
* pss( suid, spid, printopt = { 1 | 0 } )
* rebuildextents( dbid, objid, indexid )
* rebuild_log( dbid, 1, 1) - careful as this will cause large jumps
in your timestamp values used by log recovery.
* resource
* setkeepalive(# minutes) - for use on Novell with TCP/IP.
* settrunc('ltm','ignore') - this command may be usefull for a dba
who is dumping and loading a database that has replication set on
for the original db.
* show_bucket( dbid, pageid, lookup_type )
* tab( dbid, objid, printopt = { 0 | 1 | 2 } )
* tablealloc(tablename|tabid, [full | optimized | fast],[fix |
nofix])
* traceoff( tracenum [, tracenum ... ] )
* traceon( tracenum [, tracenum ... ] )
* tune( option, value ) - switch on any option immediately without
having to reboot the SQL Server. Switches correspond to the old
(pre-System 11) _buildmaster -yall_ minus the _c_ prefix
For example _option_ may be:
+ indextrips
+ oamtrips
+ datatrips
+ schedspins
+ bufwashsize
+ sortbufsize
+ sortpgcount
+ maxscheds
+ max_retries
* undo( dbid, pageno, rowno )
_________________________________________________________________
Q3.4: FIXING A MUNGED LOG
_________________________________________________________________
_Sybase Technical Support states that this is extremely dangerous as
it "jacks up the value of the timestamp" which is used for recovery
purposes. This may cause potential database corruption if the system
fails while the timestamp rolls over.
In 4.9.2, you could only run the dbcc rebuild_log command once and
after that you would have to use bcp to rebuild the database
In System 10, you can run this command about 10 times.
In System 11 I (FAQ maintainer) tried it about 20 times and no
problem. _
1> use master
2> go
1> select count(*) from _your_database_..syslogs
2> go
-----------
_some number_
1> sp_configure "allow updates",1
2> go
1> reconfigure with override /* for system 10 and below */
2> go
1> begin tran
2> go
_/* Save the following status to be used later... */_
1> select _saved_status_=status from sysdatabases where name = "_your_database_
"
2> go
1> update sysdatabases set status = -32768 where name = "_your_database_"
2> go
1> commit tran
2> go
1> shutdown
2> go
1> dbcc rebuild_log (_your_database_, 0, 0)
2> go
DB-LIBRARY error (severity 9):
Unexpected EOF from SQL Server.
1> dbcc rebuild_log (_your_database_, 1, 1)
2> go
DBCC execution completed. If DBCC printed error messages, see your System
Administrator.
1> use _your_database_
2> go
1> select count(*) from syslogs
2> go
-----------
1
1> begin tran
2> go
1> update sysdatabases set status = _saved_status_ where name = "_your_database_
"
2> go
(1 row affected)
1> commit tran
2> go
1> shutdown
2> go
Q4.1: HIDING YOUR PASSWORD TO _ISQL_
_________________________________________________________________
Here are a menagerie (I've always wanted to use that word) of
different methods to hide your password. Pick and choose whichever
fits your environment best:
Single SQL Server on host
Script #1
Assuming that you are using bourne shell _sh(1)_ as your scripting
language you can put the password in a file and substitute the file
where the password is needed.
#!/bin/sh
# invoke say ISQL or something....
( cat $HOME/dba/_password_file_
cat
Script #2
#!/bin/sh
umask 077
cat
Script #3
#!/bin/sh
umask 077
cat
Script #3
#!/bin/sh
umask 077
isql -Umyuserid -Smyserver
Script #4
#!/bin/sh
umask 077
isql -Umyuserid -Smyserver
Script #5
#!/bin/sh
echo 'mypassword
use mydb
go
sp_who
go' | isql -Umyuserid -Smyserver
Script #6
#!/bin/sh
echo "`myScriptForGeneratingPasswords myServer`
use mydb
go
sp_who
go" | isql -Umyuserid -Smyserver
Script #7
Apparently solaris precludes hiding passwords. While
_isql_
tries, solaris is too smart for it and puts them back on the command
line. We just came up with a clever option for this:
isql -w000000000000000000000000000000000001 -Pmypass ... Apparently
solaris' _ps(1)_ is too brain dead to to wrap and will only show the
first 40 characters or so of the command so you need to guarantee
that the password is after that. I think this is 100%, but we will
be fooling around with it a bit more. Confirm that the above does
work by executing _/usr/ucb/ps -auxw_ and ensure that you can't see
the password.
Multiple SQL Servers on host
Again, assuming that you are using bourne shell as your scripting
language, you can do the following:
1. Create a _global file_. This file will contain passwords, generic
functions, master device for the respective DSQUERY.
2. In the actual scripts, source in the _global file_.
Script #8
#!/bin/sh
echo "Password :\c "
stty -echo
read PASSWD
stty echo
echo "$PASSWD
waitfor delay '0:1:00'
go
" | $SYBASE/bin/isql -U sa -S $DSQUERY
_Global File_
SYBASE=/usr/sybase
my_password()
{
case $1 in
SERVER_1) PASSWD="this";;
SERVER_2) PASSWD="is";;
SERVER_3) PASSWD="bogus;;
*) return 1;;
esac
return 0
}
Generic Script
#!/bin/sh -a
#
# Use "-a" for auto-export of variables
#
# "dot" the file - equivalent to csh() "source" command
. $HOME/dba/_global_file_
DSQUERY=$1
# Determine the password: sets PASSWD
my_password $DSQUERY
if [ $? -ne 0 ] ; then # error!
echo ""
exit 1
fi
# invoke say ISQL or something....
echo "$PASSWD
dbcc ...
go" | $SYBASE/bin/isql -U sa -S $DSQUERY -w1000
_______________________________________________________________
Q4.2: HOW TO REMOVE _ROW AFFECTED_ AND DASHES
_________________________________________________________________
If you pipe the output of _isql_ then you can use _sed(1)_ to remove
this extraneous output:
echo "$PASSWD
sp_who
go" | isql -U sa -S MY_SERVER | sed -e '/affected/d' -e '/---/d'
If you simply wish to eliminate the _row affected_ line use the _set
nocount on_ switch.
_________________________________________________________________
Q4.3: HOW DO I PIPE THE OUTPUT OF ONE _ISQL_ TO ANOTHER?
_________________________________________________________________
The following example queries _sysdatabases_ and takes each database
name and creates a string of the sort _sp_helpdb dbname_ and sends the
results to another _isql_. This is accomplished using bourne shell
_sh(1)_ and _sed(1)_ to strip unwanted output (see Q4.2):
#!/bin/sh
PASSWD=yuk
DSQUERY=GNARLY_HAIRBALL
echo "$PASSWD
print \"$PASSWD\"
go
select 'sp_helpdb ' + name + char(10) + 'go' from sysdatabases
go" | isql -U sa -S $DSQUERY -w 1000 | \
sed -e '/affected/d' -e '/---/d' -e '/Password:/d' | \
isql -U sa -S $DSQUERY -w 1000
To help you understand this you may wish to comment any series of
pipes and see what output is being generated.
Q5.1: HOW DO I BCP NULL DATES?
_________________________________________________________________
As long as there is _nothing_ between the field delimiters in your
data, a null will be entered. If there's a space, the value will be
Jan 1, 1900.
You can use _sed(1)_ to squeeze blanks out of fields:
sed -e 's/|[ ]*|/||/g' old_file > new_file
_________________________________________________________________
Q5.2: CAN I USE A NAMED PIPE TO _BCP/DUMP_ DATA OUT OR IN?
_System 10 and above._
_________________________________________________________________
If you would like to _bcp_ copy from one table to a named pipe and
compress:
1. %mknod bcp.pipe p
2. %compress sysobjects.Z &
3. %bcp master..sysobjects out bcp.pipe -c -U .. > bcp.pipe
4. Use _ps(1)_ to determine when the _compress_ finishes.
To bcp _from_ my1db..dummy_table_1 _to_ my2db..dummy_table_2:
1. %mknod bcp.pipe p
2. %bcp my2db..dummy_table_2 in bcp.pipe -c -U .. &
To avoid confusion between the above _bcp_ and the next, you may
choose to either use a separate window or redirect the output to a
file.
3. %bcp my1db..dummy_table_1 out bcp.pipe -c -U ..
_________________________________________________________________
Q5.3: HOW DO I EXCLUDE A COLUMN?
_________________________________________________________________
The documentation _Utility programs for Unix_ describes the use of
format files, including the field _Server Column Order._ _Server
Column Order_ must equal the _colid_ of the column, or 0 if the host
file field will not be loaded into any table column.
I don't know if anyone has got this feature to work. So, here is
another way of _removing_ the column. In your example, you want to
remove the last column. I am going to include another example to
remove the second column and include a fourth column. Why? Because it
is harder. First example will deal with _removing_ the last column.
Removing the Last Column
Edit your _bcpout.fmt_ file and look for the changes I made below.
Using the following bcpout.fmt file to dump the data:
--- bcpout.fmt
10.0
2 <------------------ Changed number of columns to BCP to two
1 SYBINT4 0 4 "<**>" 1 counter
2 SYBCHAR 1 512 "\n" 2 text1 <--- Replace <**> with \n
3 SYBCHAR 1 512 "\n" 3 text2 <--- DELETE THIS LINE
Now recreate the table with the last column removed and use the same
_bcpout.fmt_ file to BCP back in the data.
Now let's try removing the second column out four columns on a table.
Removing the Second out of Four Columns
Edit the _bcpout.fmt_ file and look for the changes I made below.
Using the following _bcpout.fmt_ file to dump the data:
--- bcpout.fmt
10.0
3 <------------------ Changed number of columns to BCP to three
1 SYBINT4 0 4 "<**>" 1 counter
2 SYBCHAR 1 512 "<**>" 2 text1 <--- DELETE THIS LINE
2 SYBCHAR 1 512 "<**>" 3 text2 <--- Change number items to 2
3 SYBCHAR 1 512 "\n" 4 text3 <--- Change number items to 3
---
Including the Fourth Column
Now copy the _bcpout.fmt_ to _bcpin.fmt_, recreate table with col 2
removed, and edit _bcpin.fmt_ file:
--- bcpin.fmt
10.0
3
1 SYBINT4 0 4 "<**>" 1 counter
2 SYBCHAR 1 512 "<**>" 2 text2 <-- Change column id to 2
3 SYBCHAR 1 512 "\n" 3 text3 <-- Change column id to 3
---
Q6.1: ALTERNATIVE TO ROW AT A TIME PROCESSING
_________________________________________________________________
Someone asked how they could speed up their processing. They were
batch updating/inserting gobs of information. Their algorithm was
something as follows:
... In another case I do:
If exists (select record) then
update record
else
insert record
I'm not sure which wa[y] is faster or if it makes a difference. I am
doing this for as many as 4000 records at a time (calling a stored
procedure 4000 times!). I am interesting in knowing any way to
improve this. The parameter translation alone on the procedure calls
takes 40 seconds for 4000 records. I am using _exec_ in DB-Lib.
Would RPC or CT-Lib be better/faster?
A netter responded stating that it was faster to ditch their algorithm
and to apply a set based strategy:
The way to take your approach is to convert the row at a time
processing (which is more traditional type of thinking) into a batch
at a time (which is more relational type of thinking). Now I'm not
trying to insult you to say that you suck or anything like that, we
just need to dial you in to think in relational terms.
The idea is to do batches (or bundles) of rows rather than
processing a single one at a time.
So let's take your example (since you didn't give exact values
[probably out of kindness to save my eyeballs] I'll use your generic
example to extend what I'm talking about):
Before:
if exists (select record) then
update record
else
insert record
New way:
1. Load _all_ your rows into a table named _new_stuff_ in a separate
work database (call it _work_db_) and load it using _bcp_ -- no
third GL needed.
1. truncate _new_stuff_ and drop all indexes
2. sort your data using UNIX sort and sort it by the clustered
columns
3. load it using _bcp_
4. create clustered index using _with sorted_data_ and any
ancillary non-clustered index.
2. Assuming that your target table is called _old_stuff_
3. Do the _update_ in a single batch:
begin tran
/* delete any rows in old_stuff which would normally
** would have been updated... we'll insert 'em instead!
** Essentially, treat the update as a delete/insert.
*/
delete old_stuff
from old_stuff,
new_stuff
where old_stuff.key = new_stuff.key
/* insert entire new table: this adds any rows
** that would have been updated before and
** inserts the new rows
*/
insert old_stuff
select * from new_stuff
commit tran
You can do all this _without_ writing 3-GL, using _bcp_ and a shell
script.
A word of caution: _Since these inserts/updates are batched
orientated you may blow your log if you attempt to do too many at a
time. In order to avoid this use the set rowcount_ directive to
create _bite-size_ chunks.
_________________________________________________________________
Q6.2: WHEN SHOULD I EXECUTE AN _SP_RECOMPILE?_
_________________________________________________________________
An _sp_recompile_ should be issued any time a new index is added or an
update statistics. Dropping an index will cause an automatic recompile
of all objects that are dependent on the table.
The _sp_recompile_ command simply increments the _schemacnt_ counter
for the given table. All dependent object counter's are checked
against this counter and if they are different the SQL Server
recompiles the object.
_________________________________________________________________
Q6.3: WHAT ARE THE DIFFERENT TYPES OF LOCKS?
_________________________________________________________________
First of, just to get it out of the way, there is no method to perform
row level locking. If you think you need row level locking, you
probably aren't thinking set based -- see Q6.1 for set processing.
The SQL Server uses locking in order to ensure that sanity of your
queries. Without locking there is no way to ensure the integrity of
your operation. Imagine a transaction that debited one account and
credited another. If the transaction didn't lock out readers/writers
then someone can potentially see erroneous data.
Essentially, the SQL Server attempts to use the least intrusive lock
possible, page lock, to satisfy a request. If it reaches around 200
page locks, then it escalates the lock to a table lock and releases
all page locks thus performing the task more efficiently.
There are three types of locks:
* page locks
* table locks
* demand locks
Page Locks
There are three types of page locks:
* shared
* exclusive
* update
shared
These locks are requested and used by readers of information. More
than one connection can hold a shared lock on a data page.
This allows for multiple readers.
exclusive
The SQL Server uses exclusive locks when data is to be modified. Only
_one_ connection may have an exclusive lock on a given data page. If a
table is large enough and the data is spread sufficiently, more than
one connection may update different data pages of a given table
simultaneously.
update
A update lock is placed during a _delete_ or an _update_ while the SQL
Server is hunting for the pages to be altered. While an update lock is
in place, there can be shared locks thus allowing for higher
throughput.
The update lock(s) are promoted to exclusive locks once the SQL Server
is ready to perform the _delete/update_.
Table Locks
There are three types of table locks:
* intent
* shared
* exclusive
intent
Intent locks indicate the intention to acquire a shared or exclusive
lock on a data page. Intent locks are used to prevent other
transactions from acquiring shared or exclusive locks on the given
page.
shared
This is similar to a page level shared lock but it affects the entire
table. This lock is typically applied during the creation of a
non-clustered index.
exclusive
This is similar to a page level exclusive lock but it affects the
entire table. If an _update_ or _delete_ affects the entire table, an
exclusive table lock is generated. Also, during the creation of a
clustered index an exclusive lock is generated.
Demand Locks
A demand lock prevents further shared locks from being set. The SQL
Server sets a demand lock to indicate that a transaction is next to
lock a table or a page.
This avoids indefinite postponement if there was a flurry of readers
when a writer wished to make a change.
_________________________________________________________________
Q6.4: WHAT'S THE PURPOSE OF USING _HOLDLOCK_?
_________________________________________________________________
All _select/readtext_ statements acquire shared locks (see Q6.3) to
retrieve their information. After the information is retrieved, the
shared lock(s) is/are released.
The _holdlock_ option is used within _transactions_ so that after the
_select/readtext_ statement the locks are held until the end of the
transaction:
* commit transaction
* rollback transaction
If the _holdlock_ is not used within a transaction, the shared locks
are released.
Example
Assume we have the following two transactions and that each
where-clause qualifies a single row:
tx #1
begin transaction
/* acquire a shared lock and hold it until we commit */
_1:_ select col_1 from table_a _holdlock_ where id=1
_2:_ update table_b set col_3 = 'fiz' where id=12
commit transaction
tx #2
begin transaction
_1:_ update table_a set col_2 = 'a' where id=1
_2:_ update table_c set col_3 = 'teo' where id=45
commit transaction
If tx#1, line 1 executes prior to tx#2, line 1, tx#2 waits to acquire
its exclusive lock until tx#1 releases the shared level lock on the
object. This will not be done until the commit transaction, thus
slowing user throughput.
On the other hand, if tx#1 had not used the holdlock attribute, tx#2
would not have had to wait until tx#1 committed its transaction. This
is because shared level locks are released immediately (even within
transactions) when the holdlock attribute is not used.
Note that the holdlock attribute does not stop another transaction
from acquiring a shared level lock on the object (i.e. another
reader). It only stops an exclusive level lock (i.e. a writer) from
being acquired.
_________________________________________________________________
Q6.6: HOW DO I FIND THE OLDEST OPEN TRANSACTION?
_________________________________________________________________
select h.spid, u.name, p.cmd, h.name, h.starttime,
p.hostname, p.hostprocess, p.program_name
from master..syslogshold h, master..sysprocesses p, master..sysusers u
where h.spid = p.spid
and p.suid = u.suid
and h.spid != 0 /* not replication truncation point */
_________________________________________________________________
Q6.7: HOW DO I CHECK IF LOG TRUNCATION IS BLOCKED?
_________________________________________________________________
System 11 and beyond:
select h.spid, convert(varchar(20), h.name), h.starttime
from master..syslogshold h, sysindexes i
where h.dbid = db_id()
and h.spid != 0
and i.id = 8 /* syslogs */
and h.page in (i.first, i.first+1)/* first page of log = page of oldest xact
*/
_________________________________________________________________
Q6.8: THE _TIMESTAMP_ DATATYPE
_________________________________________________________________
The timestamp datatype is user-defined datatype supplied by Sybase,
defined as:
varbinary(8) NULL
It has a special use when used to define a table column. A table may
have at most one column of type timestamp, and whenever a row
containing a timestamp column is inserted or updated the value in the
timestamp column is automatically updated. This much is covered in the
documentation.
What isn't covered is what the values placed in timestamp columns
actually represent. It is a common misconception that timestamp values
bear some relation to calendar date and/or clock time. They don't -
the datatype is badly-named. SQL Server keeps a counter that is
incremented for every write operation - you can see its current value
via the global variable @@DBTS (though don't try and use this value to
predict what will get inserted into a timestamp column as every
connection shares the same counter.)
The value is maintained between server startups and increases
monotonically over time (though again you cannot rely on it this
behaviour). Eventually the value will wrap, potentially causing huge
problems, though you will be warned before it does - see Sybase
Technical News Volume 5, Number 1 (see Q10.3.1). You _cannot_ convert
this value to a datetime value - it is simply an 8-byte integer.
Note that the global timestamp value is used for recovery purposes
in the event of an RDMBS crash. As transactions are committed to the
log each transaction gets a unique timestamp value. The checkpoint
process places a marker in the log with its unique timestamp value.
If the RDBMS crashes, recovery is the process of looking for
transactions that need to be rolled forward and/or backward from the
checkpoint event. If a transaction spans across the checkpoint event
and it never competed it too needs to be rolled back.
Essentially, this describes the _write-ahead log protocol_ described
by _C.J. Date_ in _An Introduction to Database Systems_ - see Q12.2.
So what is it for? It was created in order to support the browse-mode
functions of DB-Library (and for recovery as mentioned above). This
enables an application to easily support optimistic locking by
guaranteeing a _watch_ column in a row will change value if any other
column in that row is updated. The browse functions checked that the
timestamp value was still the same as when the column was read before
attempting an update. This behaviour is easy to replicate without
necessarily using the actual client browse-mode functions - just read
the timestamp value along with other data retrieved to the client, and
compare the stored value with the current value prior to an update.
_________________________________________________________________
Q6.9: STORED PROCEDURE RECOMPILATION AND RERESOLUTION
_________________________________________________________________
When a stored procedure is created, the text is placed in syscomments
and a parse tree is placed in sysprocedures. At this stage there is no
compiled _query plan_.
A compiled _query plan_ for the procedure only ever exists in memory
(that is, in the procedure cache) and is created under the following
conditions:
1. A procedure is executed for the first time.
2. A procedure is executed by a second or subsequent user when the
first plan in cache is still in use.
3. The procedure cache is flushed by server restart or cache LRU
flush procedure.
4. The procedure is executed or created using the _with recompile_
option.
If the objects the procedure refers to change in some way - indexes
dropped, table definition changed, etc - the procedure will be
_reresolved_ - which updates sysprocedures with a modified tree.
Before 10.x the tree grows and in extreme cases the procedure can
become too big to execute. This problem disappears in Sybase System
11. This reresolution will _always_ occur if the stored procedure uses
temporary tables (tables that start with "#").
There is apparently no way of telling if a procedure has been
reresolved.
Traceflag 299 offers some relief, see Q1.4 for more information
regarding traceflags.
The Official Explanation -- Reresolution and Recompilation Explained
When stored procedures are created, an entry is made in sysprocedures
that contains the query tree for that procedure. This query tree is
the resolution of the procedure and the applicable objects referenced
by it. The syscomments table will contain the actual procedure text.
No query plan is kept on disk. Upon first execution, the query tree is
used to create (compile) a query plan (execution plan) which is stored
in the procedure cache, a server memory structure. Additional query
plans will be created in cache upon subsequent executions of the
procedure whenever all existing cached plans are in use. If a cached
plan is available, it will be used.
Recompilation is the process of using the existing query tree from
sysprocedures to create (compile) a new plan in cache. Recompilation
can be triggered by any one of the following:
* First execution of a stored procedure,
* Subsequent executions of the procedure when all existing cached
query plans are in use,
* If the procedure is created with the recompile option, CREATE
PROCEDURE sproc WITH RECOMPILE
* If execution is performed with the recompile option, EXECUTE sproc
WITH RECOMPILE
Re-resolution is the process of updating the query tree in
sysprocedures AND recompiling the query plan in cache. Re-resolution
only updates the query tree by adding the new tree onto the existing
sysprocedures entry. This process causes the procedure to grow in size
which will eventually cause an execution error (Msg 703 - Memory
request failed because more than 64 pages are required to run the
query in its present form. The query should be broken up into shorter
queries if possible). Execution of a procedure that has been flagged
for re-resolution will cause the re-resolution to occur. To reduce the
size of a procedure, it must be dropped which will remove the entries
from sysprocedures and syscomments. Then recreate the procedure.
Re-resolution can be triggered by various activities most of which are
controlled by SQL Server, not the procedure owner. One option is
available for the procedure owner to force re-resolution. The system
procedure, sp_recompile, updates the schema count in sysobjects for
the table referenced. A DBA usually will execute this procedure after
creating new distribution pages by use of update statistics. The next
execution of procedures that reference the table flagged by
sp_recompile will have a new query tree and query plan created.
Automatic re-resolution is done by SQL Server in the following
scenarios:
* Following a LOAD DATABASE on the database containing the
procedure,
* After a table used by the procedure is dropped and recreated,
* Following a LOAD DATABASE of a database where a referenced table
resides,
* After a database containing a referenced table is dropped and
recreated,
* Whenever a rule or default is bound or unbound to a referenced
table.
Forcing automatic compression of procedures in System 10 is done with
trace flag 241. System 11 should be doing automatic compression,
though this is not certain.
When are stored procedures compiled?
Stored procedures are in a database as rows in sysprocedures, in the
form of parse trees. They are later compiled into execution plans.
A stored procedures is compiled:
1. with the first EXECute, when the parse tree is read into cache
2. with every EXECute, if CREATE PROCEDURE included WITH RECOMPILE
3. with each EXECute specifying WITH RECOMPILE
4. if the plans in cache for the procedure are all in use by other
processes
5. after a LOAD DATABASE, when all procedures in the database are
recompiled
6. if a table referenced by the procedure can not be opened (using
object id), when recompilation is done using the table's name
7. after a schema change in any referenced table, including:
1. CREATE INDEX or DROP INDEX to add/delete an index
2. ALTER TABLE to add a new column
3. sp_bindefault or sp_unbindefault to add/delete a default
4. sp_bindrule or sp_unbindrule to add/delete a rule
8. after EXECute sp_recompile on a referenced table, which increments
sysobjects.schema and thus forces re-compilation
What causes re-resolution of a stored procedure?
When a stored procedure references an object that is modified after
the creation of the stored procedure, the stored procedure must be
re-resolved. Re-resolution is the process of verifying the location of
referenced objects, including the object id number. Re-resolution will
occur under the following circumstances:
1. One of the tables used by the stored procedure is dropped and
re-created.
2. A rule or default is bound to one of the tables (or unbound).
3. The user runs sp_recompile on one of the tables.
4. The database the stored procedure belongs to is re-loaded.
5. The database that one of the stored procedure's tables is located
in is re-loaded.
6. The database that one of the stored procedure's tables is located
in is dropped and re-created.
What will cause the size of a stored procedure to grow?
Any of the following will result in a stored procedure to grow when it
is recompiled:
1. One of the tables used in the procedure is dropped and re-created.
2. A new rule or default is bound to one of the tables or the user
runs sp_recompile on one of the tables.
3. The database containing the stored procedure is re-loaded.
Other things causing a stored procedure to be re-compiled will not
cause it to grow. For example, dropping an index on one of the tables
used in the procedure or doing EXEC WITH RECOMPILE.
The difference is between simple recompilation and re-resolution.
Re-resolution happens when one of the tables changes in such a way
that the query trees stored in sysprocedures may be invalid. The
datatypes, column offsets, object ids or other parts of the tree may
change. In this case, the server must re-allocate some of the query
tree nodes. The old nodes are not de-allocated (there is no way to do
this within a single procedure header), so the procedure grows. In
time, trying to execute the stored procedure will result in a 703
error about exceeding the 64 page limit for a query.
Q7.1: HOW TO EMULATE THE ORACLE DECODE FUNCTION/CROSSTAB
_________________________________________________________________
There is a neat way to use boolean logic to perform cross-tab or
rotation queries easily, and very efficeintly. Using the aggregate
'Group By' clause in a query and the ISNULL(), SIGN(), ABS(),
SUBSTRING() and CHARINDEX() functions, you can create queries and
views to perform all kinds of summarizations.
_This technique does not produce easily understood SQL statements._
The trick is to create a statement for a column that evaluate to the
value you are looking for, or zero.
If you want to test a field to see if it is equal to a value, say 100,
use the following code:
SELECT (1- ABS( SIGN( ISNULL( 100 - <field>, 1))))
The innermost function will return 1 when the field is null, a
positive value if the field 100 and will return 0 if the field = 100.
This example is for Sybase or Microsoft SQL server, but other servers
should support most of thse functions or the COALESCE() function,
which is the ANSI equivalent to Isnull.
The SIGN() function returns zero for a zero value, -1 for a negative
value, 1 for a positive value The ABS() function returns zero for a
zero value, and 1 for any non-zero value.
Put it all together and you get '0' if the value match, and '1' if
they don't. This is not that useful, so we subtract this return value
from '1' to invert it, giving us a TRUE value of '1' and a false value
of '0'. These return values can then be multiplied by the value of
another column, or used within the parameters of another function like
SUBSTRING() to return a conditional text value.
For example, to create a grid from a student registration table
containing STUDENT_ID and COURSE_ID columns, where there are 5 courses
(101, 105, 201, 210, 300) use the following query:
SELECT STUDENT_ID,
(1- ABS( SIGN( ISNULL( 101 - COURSE_ID, 1)))) COURSE_101,
(1- ABS( SIGN( ISNULL( 105 - COURSE_ID, 1)))) COURSE_105,
(1- ABS( SIGN( ISNULL( 201 - COURSE_ID, 1)))) COURSE_201,
(1- ABS( SIGN( ISNULL( 210 - COURSE_ID, 1)))) COURSE_210,
(1- ABS( SIGN( ISNULL( 300 - COURSE_ID, 1)))) COURSE_300
GROUP BY STUDENT_ID
ORDER BY STUDENT_ID
_________________________________________________________________
Q7.2: HOW TO IMPLEMENT _IF-THEN-ELSE_ IN A _SELECT_ CLAUSE
_________________________________________________________________
If you need to implement the following condition in a _select_ clause:
if @val = 'small' then
print 'petit'
else
print 'grand'
fi
do the following:
select isnull(substring('petit', charindex('small', @val), 255), 'grand')
To test it out, try the following T-SQL:
declare @val char(20)
select @val = 'grand'
select isnull(substring('petit', charindex('small', @val), 255), 'grand')
_________________________________________________________________
Q7.4: HOW TO PAD WITH LEADING ZEROS AN _INT_ OR _SMALLINT_.
_________________________________________________________________
By example:
declare @Integer int
/* Good for positive numbers only. */
select @Integer = 1000
select "Positives Only" =
right( replicate("0", 12) + convert(varchar, @Integer), 12)
/* Good for positive and negative numbers. */
select @Integer = -1000
select "Both Signs" =
substring( "- +", (sign(@Integer) + 2), 1) +
right( replicate("0", 12) + convert(varchar, abs(@Integer)), 12)
select @Integer = 1000
select "Both Signs" =
substring( "- +", (sign(@Integer) + 2), 1) +
right( replicate("0", 12) + convert(varchar, abs(@Integer)), 12)
go
Produces the following results:
Positives Only
--------------
000000001000
Both Signs
-------------
-000000001000
Both Signs
-------------
+000000001000
_________________________________________________________________
Q7.5: DIVIDE BY ZERO AND NULLS
_________________________________________________________________
During processing, if a divide by zero error occurs you will not get
the answer you want. If you want the result set to come back and null
to be displayed where divide by zero occurs do the following:
1> select * from total_temp
2> go
field1 field2
----------- -----------
10 10
10 0
10 NULL
(3 rows affected)
1> select field1, field1/(field2*convert(int,
substring('1',1,abs(sign(field2))))) from total_temp
2> go
field1
----------- -----------
10 1
10 NULL
10 NULL
_________________________________________________________________
Q7.6: CONVERT MONTHS TO FINANCIAL MONTHS
_________________________________________________________________
To convert months to financial year months (i.e. July = 1, Dec = 6,
Jan = 7, June = 12 )
Method #1
select ... ((sign(sign((datepart(month,GetDate())-6) * -1)+1) *
(datepart(month, GetDate())+6))
+ (sign(sign(datepart(month, GetDate())-7)+1) *
(datepart(month, GetDate())-6)))
...
from ...
Method #1
select charindex(datename(month,getdate()),
" July August September October November December
January Febuary March April May June "
) / 10
In the above example, the embedded blanks are significant.
_________________________________________________________________
Q7.7: HIERARCHY TRAVERSAL - BOMS
_________________________________________________________________
Alright, so you wanna know more about representing hierarchies in a
relational database? Before I get in to the nitty gritty I should at
least give all of the credit for this algorithm to:
"_Hierarical_Structures:_The_Relational_Taboo!_, _(Can_
Transitive_Closure_Queries_be_Efficient?)_", by Michael J. Kamfonas as
published in 1992 "Relational Journal" (I don't know which volume or
issue).
The basic algorithm goes like this, given a tree (hierarchy) that
looks roughly like this (forgive the ASCII art--I hope you are using a
fixed font to view this):
a
/ \
/ \
/ \
b c
/ \ /|\
/ \ / | \
/ \ / | \
d e f | g
Note, that the tree need not be balanced for this algorithm to work.
The next step assigned two numbers to each node in the tree, called
left and right numbers, such that the left and right numbers of each
node contain the left and right numbers of the ancestors of that node
(I'll get into the algorithm for assigning these left and right
numbers later, but, _hint: use a depth-first search_):
1a16
/ \
/ \
/ \
2b7 8c15
/ \ /|\
/ \ / | \
/ \ / | \
3d4 5e6 9f10 11g12 13h14
Side Note: The careful observer will notice that these left and
right numbers look an awful lot like a B-Tree index.
So, you will notice that all of the children of node 'a' have left and
right numbers between 1 and 16, and likewise all of the children of
'c' have left and right numbers between 8 and 15. In a slightly more
relational format this table would look like:
Table: hier
node parent left_nbr right_nbr
----- ------ -------- ---------
a NULL 1 16
b a 2 7
c a 8 15
d b 3 4
e b 5 6
f c 9 10
g c 11 12
h c 13 14
So, given a node name, say @node (in Sybase variable format), and you
want to know all of the children of the node you can do:
SELECT h2.node
FROM hier h1,
hier h2
WHERE h1.node = @node
AND h2.left_nbr > h1.left_nbr
AND h2.left_nbr
If you had a table that contained, say, the salary for each node
in your hierarchy (assuming a node is actually a individual in a company)
you could then figure out the total salary for all of the people
working underneath of @node by doing:
SELECT sum(s.salary)
FROM hier h1,
hier h2,
salary s
WHERE h1.node = @node
AND h2.left_nbr > h1.left_nbr
AND h2.right_nbr > h1.right_nbr
AND s.node = h2.node
Pretty cool, eh? And, conversly, if you wanted to know how much it
cost to manage @node (i.e. the combined salary of all of the boss's
of @node), you can do:
SELECT sum(s.salary)
FROM hier h1,
hier h2,
salary s
WHERE h1.node = @node
AND h2.left_nbr h1.right_nbr
AND s.node = h2.node
Now that you can see the algorithm in action everything looks peachy,
however the sticky point is the method in which left and right numbers
get assigned. And, unfortunately, there is no easy method to do this
relationally (it can be done, it just ain't that easy). For an real-
world application that I have worked on, we had an external program
used to build and maintain the hierarchies, and it was this program's
responsibility to assign the left and right numbers.
But, in brief, here is the algorithm to assign left and right
numbers to every node in a hierarchy. Note while reading this
that this algorithm uses an array as a stack, however since arrays
are not available in Sybase, they are (questionably) emulated using
a temp table.
DECLARE @skip int,
@counter int,
@idx int,
@left_nbr int,
@node varchar(10)
/*-- Initialize variables --*/
SELECT @skip = 1000, /* Leave gaps in left & right numbers */
@counter = 0, /* Counter of next available left number */
@idx = 0 /* Index into array */
/*
* The following table is used to emulate an array for Sybase,
* for Oracle this wouldn't be a problem. :(
*/
CREATE TABLE #a (
idx int NOT NULL,
node varchar(10) NOT NULL,
left_nbr int NOT NULL
)
/*
* I know that I always preach about not using cursors, and there
* are ways to get around it, but in this case I am more worried
* about readability over performance.
*/
DECLARE root_cur CURSOR FOR
SELECT h.node
FROM hier h
WHERE h.parent IS NULL
FOR READ ONLY
/*
* Here we are populating our "stack" with all of the root
* nodes of the hierarchy. We are using the cursor in order
* to assign an increasing index into the "stack"...this could
* be done using an identity column and a little trickery.
*/
OPEN root_cur
FETCH root_cur INTO @node
WHILE (@@sqlstatus = 0)
BEGIN
SELECT @idx = @idx + 1
INSERT INTO #a VALUES (@idx, @node, 0)
FETCH root_cur INTO @node
END
CLOSE root_cur
DEALLOCATE CURSOR root_cur
/*
* The following cursor will be employed to retrieve all of
* the children of a given parent.
*/
DECLARE child_cur CURSOR FOR
SELECT h.node
FROM hier h
WHERE h.parent = @node
FOR READ ONLY
/*
* While our stack is not empty.
*/
WHILE (@idx > 0)
BEGIN
/*
* Look at the element on the top of the stack.
*/
SELECT @node = node,
@left_nbr = left_nbr
FROM #a
WHERE idx = @idx
/*
* If the element at the top of the stack has not been assigned
* a left number yet, then we assign it one and copy its children
* on the stack as "nodes to be looked at".
*/
IF (@left_nbr = 0)
BEGIN
/*
* Set the left number of the current node to be @counter + @skip.
* Note, we are doing a depth-first traversal, assigning left
* numbers as we go.
*/
SELECT @counter = @counter + @skip
UPDATE #a
SET left_nbr = @counter
WHERE idx = @idx
/*
* Append the children of the current node to the "stack".
*/
OPEN child_cur
FETCH child_cur INTO @node
WHILE (@@sqlstatus = 0)
BEGIN
SELECT @idx = @idx + 1
INSERT INTO #a VALUES (@idx, @node, 0)
FETCH child_cur INTO @node
END
CLOSE child_cur
END
ELSE
BEGIN
/*
* It turns out that the current node already has a left
* number assigned to it, so we just need to assign the
* right number and update the node in the actual
* hierarchy.
*/
SELECT @counter = @counter + @skip
UPDATE h
SET left_nbr = @left_nbr,
right_nbr = @counter
WHERE h.node = @node
/*
* "Pop" the current node off our "stack".
*/
DELETE #a WHERE idx = @idx
SELECT @idx = @idx - 1
END
END /* WHILE (@idx > 0) */
DEALLOCATE CURSOR child_cur
While reading through this, you should notice that assigning the
left and right numbers to the entire hierarchy is very costly,
especially as the size of the hierarchy grows. If you put the
above code in an insert trigger on the hier table, the overhead
for inserting each node would be phenominal. However, it is possible
to reduce the overall cost of an insertion into the hierarchy.
1. By leaving huge gaps in the left & right numbers (using the @skip
variable), you can reduce the circumstances in which the numbers
need to be reassigned for a given insert. Thus, as long as you can
squeeze a new node between an existing pair of left and right
numbers you don't need to do the re-assignment (which could affect
all of the node in the hierarchy).
2. By keeping an extra flag around in the hier table to indicate
which nodes are leaf nodes (this could be maintained with a
trigger as well), you avoid placing leaf nodes in the array and
thus reduce the number of updates.
Deletes on this table should never cause the left and right numbers
to be re-assigned (you could even have a trigger automagically
re-parent
orphaned hierarchy nodes).
All-in-all, this algorithm is very effective as long as the structure
of the hierarchy does not change very often, and even then, as you can
see, there are ways of getting around a lot of its inefficiencies.
__________________________________________________________________________
Q7.8: CALLING UNIX FROM A _TRIGGER_ OR A _STORED PROCEDURE_
_________________________________________________________________
11.5 and above
The Adaptive Server (11.5) will allow O/S calls from within stored
procedures. These stored procedures are known as _extended stored
procedures_
Pre-11.5
Periodically folks ask if it's possible to make a system command or
call a UNIX process from a Trigger or a Stored Procedure.
Guaranteed Message Processing
The typical ways people have implemented this capability is:
1. Buy Open Server and bind in your own custom stuff (calls to
system() or custom C code) and make Sybase RPC calls to it.
2. Have a dedicated client application running on the server box
which regularly scans a table and executes the commands written
into it (and tucks the results into another table which can have a
trigger on it to gather results...). It is somewhat tricky but
cheaper than option 1.
Sybase SQL Server 10.0.2.5 and Above - syb_sendmsg()
This release includes a new built-in function called syb_sendmsg().
Using this function you can send a message up to 255 bytes in size to
another application from the SQL Server. The arguments that need to be
passed to syb_sendmsg() are the IP address and port number on the
destination host, and the message to be sent. The port number
specified can be any UDP port, excluding ports 1-1024, not already in
use by another process. An example is:
1> select syb_sendmsg("120.10.20.5", 3456, "Hello")
2> go
This will send the message "Hello" to port 3456 at IP address
'120.10.20.5'. Because this built-in uses the UDP protocol to send the
message, the SQL Server does not guarantee the receipt of the message
by the receiving application.
_Also, please note that there are no security checks with this new
function. It is possible to send sensitive information with this
command and Sybase strongly recommends caution when utilizing
syb_sendmsg to send sensitive information across the network. By
enabling this functionality, the user accepts any security problems
which result from its use (or abuse). _
To enable this feature you should run the following commands as the
System Security Officer.
1. Login to the SQL Server using 'isql'.
2. Enable the syb_sendmsg() feature using sp_configure.
1> sp_configure "allow sendmsg", 1
2> go
1> sp_configure "syb_sendmsg port number",
2> go
1> reconfigure with override
2> go
Using syb_sendmsg() with Existing Scripts
Since syb_sendmsg() installs configuration parameter "allow
sybsendmsg", existing scripts that contain the syntax
1> sp_configure allow, 1
2> go
to enable updates to system tables should be altered to be fully
qualified as in the following:
1> sp_configure "allow updates", 1
2> go
If existing scripts are not altered they will fail with the following
message:
1> sp_configure allow, 1
2> go
Configuration option is not unique.
duplicate_options
----------------------------
allow updates
allow sendmsg
(return status = 1)
Backing Out syb_sendmsg()
The syb_sendmsg() function requires the addition on two config values.
If it becomes necessary to roll back to a previous SQL Server version
which does not include syb_sendmsg(), please follow the instructions
below.
1. Edit the RUNSERVER file to point to the SWR SQL Server binary you
wish to use.
2. isql -Usa -P -S_server_name_ -n -iunconfig.sendmsg -o_output_file_
Sample C program
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
main(argc, argv)
int argc; char *argv[];
{
struct sockaddr_in sadr;
int portnum,sck,dummy,msglen;
char msg[256];
if (argc < 2) {
printf("Usage: udpmon <udp portnum>\n");
exit(1);
}
if ((portnum=atoi(argv[1])) < 1) {
printf("Invalid udp portnum\n");
exit(1);
}
if ((sck=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)) < 0) {
printf("Couldn't create socket\n");
exit(1);
}
sadr.sin_family = AF_INET;
sadr.sin_addr.s_addr = inet_addr("0.0.0.0");
sadr.sin_port = portnum;
if (bind(sck,&sadr,sizeof(sadr)) < 0) {
printf("Couldn't bind requested udp port\n");
exit(1);
}
for (;;)
{
if((msglen=recvfrom(sck,msg,sizeof(msg),0,NULL,&dummy)) < 0)
printf("Couldn't recvfrom() from udp port\n");
printf("%.*s\n", msglen, msg);
}
}
_________________________________________________________________
Q7.9: IDENTITIES AND SEQUENTIAL KEYS
This has several sections, culled from various sources. It is better
described as "Everything you've ever wanted to know about identities."
It will serve to answer the following frequently asked questions: What
are the Features and Advantages of using Identities?
What are the Problems with and Disadvantages of Identities?
Common Questions about Identities
* Is Identity the equivalent of Oracle's Auto-sequencing?
* How do I configure a table to use the Identity field?
* How do I configure the burn factor?
* How do I find out if my tables have Identities defined?
* What is my current identity burn factor vulnerability?
How do I optimize the performance of a table that uses Identities?
How do I recover from a huge gap in my identity column?
How do I fix a table that has filled up its identity values?
OK, I hate identities. How do I generate sequential keys without using
the Identity feature?
How do I optimize a hand-made sequential key system for best
performance?
- Question 8.1 of the comp.database.sybase FAQ has a quick blurb about
identities and sequential numbers. Search down in the page for the
section titled, "Generating Sequential Numbers." Question 8.1 is a
general document describing Performance and Tuning topics to be
considered and thus doesn't go into as much detail as this page.
- There's a white paper by Malcolm Colton available from the sybase
web site. Goto the Sybase web site http://www.sybase.com and type
_Surrogate_ in the search form. Select the _Surrogate Primary Keys,
Concurrency, and the Cache Hit Ratio_ document.
_________________________________________________________________
Advantages/Features of Using Identities
There's an entire section devoted to Identity columns in the SQL
Server Reference manual, Chapter 5
Sybase System 10 introduced many changes over the 4.9.x architecture.
One of these changes was the Identity feature. The identity column is
a special column type that gets automatically updated by the server
upon a new row insert. Its purpose is to guarantee a unique row
identifier not based on the other data in the row. It was integrated
with the server and made memory based for fast value retrieval and no
locking (as was/is the case with homegrown sequential key generation
schemes). The Advantages and Features of Identities include:
* A non-SQL based solution to the problem of having an default
unique value assigned to a row. SQL Server prefetches identity
values into cache and adds them automatically to rows as they're
inserted into tables that have a type Identity column. There's no
concurrency issues, no deadlocking in high-insert situations, and
no possibility of duplicate values.
* A high performance Unique identifier; SQL server's optimizer is
tuned to work well with Unique indexes based on the identity
value.
* The flexibility to insert into the identity field a specific value
in the case of a mistaken row deletion. (You can never update
however). You accomplish this by:
1> set identity_insert [datababase]..[table] on
2> go
Note however that the System will not verify the uniqueness of the
value you specifically insert (unless of course you have a unique
index existing on the identity column).
* The flexibility during bcp to either retain existing identity
values or to reset them upon bcping back in. To retain the
specific identity values during a bcp out/in process, bcp your
data out normally (no special options). Then create your bcp in
target table with ddl specifying the identity column in the
correct location. Upon bcp'ing back in, add the "-E" option at the
end of the bcp line, like this (from O/S prompt):
% bcp [database]..[new_table] in [bcp datafile] -Usa -S[server] -f [fmt file] -
E
For procedures on resetting indentity values during a bcp, see the
section regarding Identity gaps.
* Databasewide Identity options: 1) The ability to set Sybase to
automatically create an Identity column on any table that isn't
created with a primary key or a unique constraint specified. 2)
Sybase can automatically include an Identity field in all indexes
created, guaranteeing all will be unique. These two options
guarantee increased index performance optimization and guarantees
the useof updatable cursors and isolation level 0 reads.
These features are set via sp_dboption, like this:
1> sp_dboption [dbname], "auto identity", true
2> go
or
1> sp_dboption [dbname], "identity in nonunique index", true
2> go
To tune the size of the auto identity (it defaults to precision 10):
1> sp_configure "size of auto identity", [desired_precision]
2> go
(the identity in nonunique index db_option and the size of auto
identity sp_configure value are new with System 11: the auto
identity existed with the original Identity feature introduction
in System 10)
Like other dboptions, you can set these features on the model
database before creating new databases and all your future
databases will be configured. Be warned of the pitfalls of large
identity gaps however; see the question regarding Burn Factor
Vulnerability in the Common Questions about Identities section.
* The existance of the @@identity global variable, which keeps track
of the identity value assigned during the last insert executed by
the server. This variable can be used programming SQL around
tables that have identity values (in case you need to know what
the last value inserted was). If the last value inserted in the
server was to a non-identity table, this value will be "0."
Back to top
_________________________________________________________________
Disadvantages/Drawbacks of Using Identities
Despite its efficacy of use, the Identity has some drawbacks:
*
The mechanism that Sybase uses to allocate Identities involves a
memory based prefetch scheme for performance. The downside of this
is, during non-normal shutdowns of the SQL server (shutdown with
nowait or flat out crashes) the SQL server will simply discard or
"burn" all the unused indentity values it has pre-allocated in
memory. This sometimes leaves large "gaps" in your monotonically
increasing identity columns and can be unsettling for some
application developers and/or end users.
NOTE: Sybase 11.02.1 (EBF 6717) and below had a bug (bugid 96089)
which would cause "large gaps to occur in identity fields after
polite shutdowns." The Sybase 11.02.2 rollup (EBF 6886) fixed this
problem. If you're at or below 11.02.1 and you use identities, you
should defenitely upgrade.
* (paraphrased from Sybooks P&T guide, Chapter 6): If you do a large
number of inserts and you have built your clustered index on an
Identity column, you will have major contention and deadlocking
problems. This will instantly create a hot spot in your database
at the point of the last inserted row, and it will cause bad
contention if multiple insert requests are received at once.
Instead, create your clustered index on a field that will somewhat
randomize the inserts across the physical disk (such as last name,
account number, social security number, etc) and then create a
non-clustered index based on the identity field that will "cover"
any eligible queries.
The drawback here, as pointed out in the Identity Optimization
section in more detail, is that clustering on another field
doesn't truly resolve the concerrency issues. The hot spot simply
moves from the last data page to the last non-clustered index page
of the index created on the Identity column.
* If you fill up your identity values, no more inserts can occur.
This can be a big problem, especially if you have a large number
of inserts and you have continually crashed your server. However
this problem most often occurs when you try to alter a table and
add an Identity column thats too small, or if you try to bcp into
a table with an identity column thats too small. If this occurs,
follow the procedures for recovering from identity gaps.
* I've heard (but not been able to reproduce) that identities jump
significantly when dumping and loading databases. Not confirmed.
NOTE: there are several other System 11 bugs related to
Identities. EBF 7312 fixes BugId 97748, which caused duplicate
identity values to be inserted at times. EBF 6886 fixed (in
addition to the above described bug) an odd bug (#82460) which
caused a server crash when bcping into a table w/ an identity
added via alter table. As always, try to stay current on EBFs.
Back to top
_________________________________________________________________
Common questions about Identities
_Is the Identity the equivalent of Oracle's auto-sequencing?_:
Answer: More or less yes. Oracle's auto-sequencing feature is somewhat
transparent to the end user and automatically increments if created as
a primary key upon a row insert. The Sybase Identity column is
normally specified at table creation and thus is a functional column
of the table. If however you set the "auto identity" feature for a
database, the tables created will have a "hidden" identity column that
doesn't even appear when you execute a select * from [table]. See the
Advantages of Identities for more details.
_How do I configure Identities?_: You can either create your table
initially with the identity column:
1> create table ident_test
2> (text_field varchar(10),
3> ident_field numeric(5,0) identity)
4> go
Or alter an existing table and add an identity column:
1> alter table existing_table
2> add new_identity_field numeric(7,0) identity
3> go
When you alter a table and add an identity column, the System locks
the table while systematically incrementing and adding unique values
to each row. IF YOU DON'T SPECIFY a precision, Sybase defaults the
size to 18! Thats 1,000,000,000,000,000,000-1 possible values and some
major major problems if you ever crash your SQL server and burn a
default number of values... (10^18 with the default burn factor will
burn 5^14 or 500,000,000,000,000 values...yikes).
_How do I Configure the burn factor?_: The number of identity values
that gets "burned" upon a crash or a shutdown can by found by logging
into the server and typing:
1> sp_configure "identity burning set factor"
2> go
the Default value set upon install is 5000. The number "5000" in this
case is read as ".05% of all the potential identity values you can
have in this particular case will be burned upon an unexpected
shutdown." The actual number depends on the size of the identity field
as you specified it when you created your table.
To set the burn factor, type:
1> sp_configure "identity burning set factor", [new value]
2> go
This is a static change; the server must be rebooted before it takes
effect.
_How do I tell which tables have identities?_: You can tell if a table
has identities one of two ways:
1. sp_help [tablename]: there is a field included in the sp_help
output describing a table called "Identity." It is set to 1 for
identity fields, 0 otherwise.
2. Within a database, execute this query:
1> select object_name(id) "table",name "column", prec "precision"
2> from syscolumns
3> where convert(bit, (status & 0x80)) = 1
4> go
this will list all the tables and the field within the table that
serves as an identity, and the size of the identity field.
_What is my identity burn factor vulnerability right now?_:
In other words, what would happen to my tables if I crashed my server
right now?
Identities are created type numeric, scale 0, and precision X. A
precision of 9 means the largest identity value the server will be
able to process is 10^9-1, or 1,000,000,000-1, or 999,999,999.
However, when it comes to Burning identities, the server will burn
(based on the default value of 5000) .05% of 1,000,000,000 or 500,000
values in the case of a crash. (You may think an identity precision
allowing for 1 Billion rows is optomistic, but I once saw a precision
set at 14...then the database crashed and their identity values jumped
5 TRILLION. Needless to say they abandoned their original design. Even
worse, SQL server defaults precision to 18 if you don't specify it
upon table creation...thats a MINIMUM 10,000,000,000 jump in identity
values upon a crash with the absolute minumum burn factor)
Lets say you have inserted 5 rows into a table, and then you crash
your server and then insert 3 more rows. If you select all the values
of your identity field, it will look like this:
1> select identity_field from id_test
2> go
identity_field
--------------
1
2
3
4
5
500006
500007
500008
(8 rows affected)
Here's your Identity burning options (based on a precision of 10^9 as
above):
Burn value % of values # values burned during crash
5000 .05% 500,000
1000 .01% 100,000
100 .001% 10,000
10 .0001% 1,000
1 .00001% 100
So, the absolute lowest amount of numbers you'll burn, assuming you
configure the burn factor down to 1 (sp_configure "identity burning
set factor", 1) and a precision of 9, is 100 values. Back to top
_________________________________________________________________
Optimizing your Identity setup for performance and maintenance
If you've chosen to use Identities in your database, here are some
configuration tips to avoid typical Identity pitfalls:
* Tune the burn factor!: see the vulnerabilty section for a
discussion on what happens to identity values upon SQL server
crashes. Large jumps in values can crash front ends that aren't
equipped to handle and process numbers upwards of 10 Trillion.
I've seen Powerbuilder applications crash and/or not function
properly when trying to display these large identity values.
* _Run update statistics often on tables w/ identities_: Any index
with an identity value as the first column in the search condition
will have its performance severely hampered if Update statistics
is not run frequently. Running a nightly update
statistics/sp_recompile job is a standard DBA task, and should be
run often regardless of the existance of identities in your
tables.
* _Tune the "Identity Grab Size"_: SQL server defaults the number of
Identity values it pre-fetches to one (1). This means that in high
insert environments the Server must constantly update its internal
identity placeholder structure before adding the row. By tuning
this parameter up:
1> sp_configure "identity grab size", [number]
2> go
You can prefetch larger numbers of values for each user as they log
into the server an insert rows. The downside of this is, if the
user doesn't use all of the prefetched block of identity values,
the unused values are lost (seeing as, if another user logs in the
next block gets assigned to him/her). This can quickly accelerate
the depletion of identity values and can cause gaps in Identity
values.
(this feature is new with System 11)
* _Do NOT build business rules around Identity values_. More
generally speaking the recommendation made by DBAs is, if your end
users are EVER going to see the identity field during the course
of doing their job, then DON'T use it. If your only use of the
Identity field is for its advertised purpose (that being solely to
have a uniquely identifying row for a table to index on) then you
should be fine.
* _Do NOT build your clustered index on your Identity field_,
especially if you're doing lots of inserts. This will create a hot
spot of contention at the point of insertion, and in heavier OLTP
environments can be debilitating.
- There is an excellent discussion located in the whitepapers section
of Sybase's home page discussing the performance and tuning aspects of
Identities. It suppliments some of the information located here (Note:
this will open in a new browser window). Back to top
_________________________________________________________________
Recovery from Large Identity value gaps or
Recovery from Identity insert errors/Full Identity tables
This section will discuss how to re-order the identity values for a
table following a crash/abnormal shutdown that has resulted in huge
gaps in the values. The same procedure is used in cases where the
identity field has "filled up" and does not allow inserts anymore.
Some applications that use Identities are not truly candidates for
this process (i.e., applications that depend on the identity field for
business purposes as opposed to simple unique row identifiers).
Applications like this that wish to rid their dependence on identities
will have to re-evaluate their database design.
* Method 1:bcp out and in:
- First, (from O/S command line):
% bcp database..table out [data_file] -Usa -S[server] -N
This will create a binary bcp datafile and will force the user to
create a .fmt file. The -N option tells the server to skip the
identity field while bcp'ing out.
- drop and recreate the table in question from ddl (make sure your
table ddl specifies the identity field).
- Now bcp back in:
% bcp database.table in [data_file -Usa -S[server] -f[fmt file] -N
The -N option during bcp in tells the server to ignore the data file's
placeholder column for the defined identity column.
Coincidentally, if you bcp out w/o the -N option, drop the table,
recreate from ddl specifying the identity field, and bcp back in
w/o the -N option, the same effect as above occurs.
(note: if you bcp out a table w/ identity values and then want to
preserve the identity values during the bcp back in, use the "-E"
option.)
* Method 2: select into a new table, adding the identity column as
you go : Follow this process:
1> select [all columns except identity column]
2> [identity column name ] = identity(desired_precision)
3> into [new_table]
4> from [old table]
5> go
* There are alternate methods that perform the above in multi steps,
and might be more appropriate in some situations.
+ You can bcp out all the fields of a table except the identity
column (create the bcp format file from the original table,
edit out the identity column, and re-bcp). At this point you
can create a new table with or without the identity column;
if you create it with, as you bcp back in the Server will
assign new identity values. If you create it without, you can
bcp back in normally and then alter the table and add the
identity later.
+ You can select all columns but the identity into a new table,
then alter that table and add an identity later on.
Back to top
_________________________________________________________________
How do I generate Sequential Keys w/o the Identity feature?
There are many reasons not to use the Identity feature of Sybase. This
section will present several alternative methods, along with their
advantages and drawbacks. The methods are presented in increasing
order of complexity. The most often implemented is Method 3, which is
a more robust version of Method 2 and which uses a surrogate-key
storage table. Throughout this section the test table i'm adding lines
to and generating sequential numbers for is table inserttest, created
like this:
1> create table inserttest
2> (testtext varchar(25), counter int)
3> go
* Method 1: Create your table with a column called counter of type
int. Then, each time you insert a row, do something like this:
1> begin tran
2> declare @nextkey int
3> select @nextkey=max(counter)+1 from inserttest holdlock
4> insert inserttest (testtext,counter) values ("test_text,@nextkey")
5> go
1> commit tran
2> go
This method is rather inefficient, as large tables will take minutes
to return a max(column) value, plus the entire table must be
locked for each insert (since the max() will perform a table
scan). Further, the select statement does not guarantee an
exclusive lock when it executes unless you have the "holdlock"
option; so either duplicate values might be inserted to your
target table or you have massive deadlocking.
* Method 2: See Question 10.1.1 of the comp.database.sybase FAQ is
the May 1994 (Volume 3, Number 2) Sybase Technical Note (these
links will open in a new browser window). Search down in the tech
note for the article titled, "How to Generate Sequential Keys for
Table Key Columns." This has a simplistic solution that is
expanded upon in Method 3.
* Method 3: Create a holding table for keys in a common database:
Here's our central holding table.
1> create table keystorage
2> (tablename varchar(25),
4> lastkey int)
5> go
And initially populate it with the tablenames and last values inserted
(enter in a 0 for tables that are brand new).
1> insert into keystorage (tablename,lastkey)
2> select "inserttest", max(counter) from inserttest
3> go
Now, whenever you go to insert into your table, go through a process
like this:
1> begin tran
2> update keystorage set lastkey=lastkey+1 where tablename="inserttest"
3> go
1> declare @lastkey int
2> select @lastkey = lastkey from keystorage where tablename="inserttest"
3> insert inserttest (testtext,counter) values ("nextline",@lastkey)
4> go
1> commit tran
2> go
There is plenty of room for error checking with this process: for
example (code adapted from Colm O'Reilly
(co...@mail.lk.blackbird.ie) post to Sybase-L 6/20/97):
1> begin tran
2> update keystorage set lastkey=lastkey+1 where tablename="inserttest"
3> if @@rowcount=1
4> begin
5> declare @lastkey int
6> select @lastkey=lastkey from keystorage where tablename="inserttest"
7> end
8> commit tran
9> begin tran
10> if @lastkey is not null
11> begin
12> insert inserttest (testtext,counter) values ("third line",@lastkey)
13> end
14> commit tran
15> go
This provides a pretty failsafe method of guaranteeing the success of
the select statements involved in the process. You still have a
couple of implementation decisions though:
+ One transaction or Two? The above example uses two
transactions to complete the task; one to update the
keystorage and one to insert the new data. Using two
transactions reduces the amount of time the lock is held on
keystorage and thus is better for high insertion
applications. However, the two transaction method opens up
the possibility that the first transaction will commit and
the second will roll back, leaving a gap in the sequential
numbers. (of course, this gap is small potatos compared to
the gaps that occur in Identity values). Using one
transaction (deleting lines 8 and 9 in the SQL above) will
guarantee absolutely no gaps in the values, but will lock the
keystorage table longer, reducing concurrency in high insert
applications.
+ Update first or select first? The examples given generally
update the keystorage table first, THEN select the new value.
Performing the select first (you will have to rework the
creation scheme slightly; by selecting first you're actually
getting the NEXT key to add, where as by updating first, the
keystorage table actually holds the LAST key added) you allow
the application to continue processing while it waits for the
update lock on the table. However, performing the update
first guarantees uniqueness (selects are not exclusive).
Some DBAs experienced with this keystorage table method warn of
large amounts of blocking in high insert activity situations, a
potential drawback.
* Method 4: Enhance the above method by creating an insert trigger
on your inserttest table that performs the next-key obtainment
logic. Or you could create an insert trigger on keystorage which
updates the table and obtains your value for you. Integrating the
trigger logic to your application might make this approach more
complex. Also, because of the nature of the trigger you'll have to
define the sequence number columns as allowing NULL values (a bad
thing if you're depending on the sequential number as your primary
key). Plus, triggers will slow the operation down because after
obtaining the new value via trigger, you'll have to issue an extra
update command to insert the rest of your table values.
* Other Methods: there are several other implementation alternatives
available that involve more complex logic but which might be good
solutions. One example has a central table that stores
pre-inserted sequential numbers that are deleted as they're
inserted into the production rows. This method allows the sequence
numbers to be recycled if their associated row is deleted from the
production table. An interesting solution was posted to Sybase-L
6/20/97 by Matt Townsend (mto...@concentric.net) and is based on
the millisecond field of the date/time stamp. His solution
guarantees uniqueness without any surrogate tables or extra
inserts/updates, and is a superior performing solution to other
methods described here (including Identities), but cannot support
exact sequential numbers. Some other solutions are covered in a
white paper available at Sybase's Technical library discussing
Sequential Keys (this will open in a new browser window).
Back to top
_________________________________________________________________
Optimizing your home grown Sequential key generating process for any
version of Sybase
* max_rows_per_page/fillfactor/table padding to simulate row level
locking: This is the most important tuning mechanism when creating
a hand -made sequence key generation scheme. Because of Sybase's
page level locking mechanism, your concurrency performance in
higher-insert activity situations could be destroyed unless the
server only grabs one row at a time. However since Sybase doesn't
currently have row-level locking, we simulate row-level locking by
creating our tables in such a way as to guarantee one row per 2048
byte page.
+ For pre-System 11 servers; Calculate the size of your rows,
then create dummy fields in the table that get populated with
junk but which guarantee the size of the row will fill an
entire page. For example (code borrowed from Gary Meyer's
5/8/94 ISUG presentation (gme...@netcom.com)):
1> create table keystorage
2> (tablename varchar(25),
3> lastkey int,
4> filler1 char(255) not null,
5> filler2 char(255) not null,
6> filler3 char(255) not null,
7> filler4 char(255) not null,
8> filler5 char(255) not null,
9> filler6 char(255) not null,
9> filler7 char(255) not null)
10> with fillfactor = 100
11> go
We use 7 char(255) fields to pad our small table. We also specify
the fillfactor create table option to be 100. A fillfactor of
100 tells the server to completely fill every data page. Now,
during your initial insertion of a line of data, do this:
1> insert into keystorage
2> (tablename,lastkey,
3> filler1,filler2,filler3,filler4,filler5,filler6,filler7)
4> values
5> ("yourtable",0,
6> replicate("x",250),replicate("x",250),
7> replicate("x",250),replicate("x",250),
8> replicate("x",250),replicate("x",250),
9> replicate("x",250))
10> go
This pads the row with 1750 bytes of junk, almost guaranteeing
that, given a row's byte size limit of 1962 bytes (a row
cannot span more than one page, thus the 2048 page size minus
server overhead == 1962), we will be able to simulate row
level locking.
+ In Sybase 11, a new create table option was introduced:
max_rows_per_page. It automates the manual procedures above
and guarantees at a system level what we need to achieve; one
row per page.
1> create table keystorage
2> (tablename varchar(25),
3> lastkey int)
4> with max_rows_per_page = 1
5> go
* _Create unique clustered indexes_ on the tablename/entity name
within your keystorage table. This can only improve its
performance. Remember to set max_rows_per_page or the fillfactor
on your clustered index, as clustered indexes physically reorder
the data.
* _Break up the process into multiple transactions_ wherever
possible; this will reduce the amount of time any table lock is
held and will increase concurrency in high insertion environments.
* _Use Stored Procedures_: Put the SQL commands that update the
keystorage table and then insert the updated key value into a
stored procedure. Stored procedures are generally faster than
individual SQL statements in your code because procedures are
pre-compiled and have optimization plans for index usage stored in
Sybase's system tables.
* _Enhance the keystorage table to contain a fully qualified table
name_ as opposed to just the tablename. This can be done by adding
fields to the table defenition or by just expanding the entity
name varchar field defenition. Then place the keystorage table in
a central location/common database that applications share. This
will eliminate muliple keystorage tables but might add length to
queries (since you have to do cross-database queries to obtain the
next key).
- There is an excellent discussion located in the whitepapers
section of Sybase's home page discussing the performance and
tuning aspects of any type of Sequential key use. It suppliments
the information here (note: this page will open in a new browser
window). Back to top
Q8.1: SYBASE SQL SERVER PERFORMANCE AND TUNING
_________________________________________________________________
All Components Affect Response Time & Throughput
We often think that high performance is defined as a fast data server,
but the picture is not that simple. Performance is determined by all
these factors:
* The client application itself:
+ How efficiently is it written?
+ We will return to this later, when we look at application
tuning.
* The client-side library:
+ What facilities does it make available to the application?
+ How easy are they to use?
* The network:
+ How efficiently is it used by the client/server connection?
* The DBMS:
+ How effectively can it use the hardware?
+ What facilities does it supply to help build efficient fast
applications?
* The size of the database:
+ How long does it take to dump the database?
+ How long to recreate it after a media failure?
Unlike some products which aim at performance on paper, Sybase aims at
solving the multi-dimensional problem of delivering high performance
for real applications.
_OBJECTIVES_
To gain an overview of important considerations and alternatives for
the design, development, and implementation of high performance
systems in the Sybase client/server environment. The issues we will
address are:
* Client Application and API Issues
* Physical Database Design Issues
* Networking Issues
* Operating System Configuration Issues
* Hardware Configuration Issues
* SQL Server Configuration Issues
_Client Application and Physical Database Design design decisions
will account for over 80% of your system's "tuneable" performance so
... plan your project resources accordingly ! _
It is highly recommended that every project include individuals who
have taken Sybase Education's Performance and Tuning course. This
5-day course provides the hands-on experience essential for success.
Client Application Issues
* Tuning Transact-SQL Queries
* Locking and Concurrency
* ANSI Changes Affecting Concurrency
* Application Deadlocking
* Optimizing Cursors in v10
* Special Issues for Batch Applications
* Asynchronous Queries
* Generating Sequential Numbers
* Other Application Issues
Tuning Transact-SQL Queries
* Learn the Strengths and Weaknesses of the Optimizer
* One of the largest factors determining performance is TSQL! Test
not only for efficient plans but also semantic correctness.
* Optimizer will cost every permutation of accesses for queries
involving 4 tables or less. Joins of more than 4 tables are
"planned" 4-tables at a time (as listed in the FROM clause) so not
all permutations are evaluated. You can influence the plans for
these large joins by the order of tables in the FROM clause.
* Avoid the following, if possible:
+ What are SARGS?
This is short for search arguments. A search argument is
essentially a constant value such as:
o "My company name"
o 3448
but not:
o 344 + 88
o like "%what you want%"
+ Mathematical Manipulation of SARGs
SELECT name FROM employee WHERE salary * 12 > 100000
+ Use of Incompatible Datatypes Between Column and its _SARG_
Float &Int, Char &Varchar, Binary & Varbinary are Incompatible;
Int &Intn (allow nulls) OK
+ Use of multiple "OR" Statements - especially on different
columns in same table. If any portion of the OR clause
requires a table scan, it will! OR Strategy requires
additional cost of creating and sorting a work table.
+ Not using the leading portion of the index (unless the query
is completely covered)
+ Substituting "OR" with "IN (value1, value2, ... valueN)
Optimizer automatically converts this to an "OR"
+ Use of Non-Equal Expressions (!=) in WHERE Clause.
* Use Tools to Evaluate and Tune Important/Problem Queries
+ Use the "set showplan on" command to see the plan chosen as
"most efficient" by optimizer. Run all queries through during
development and testing to ensure accurate access model and
known performance. Information comes through the Error
Handler of a DB-Library application.
+ Use the "dbcc traceon(3604, 302, 310)" command to see each
alternative plan evaluated by the optimizer. Generally, this
is only necessary to understand why the optimizer won't give
you the plan you want or need (or think you need)!
+ Use the "set statistics io on" command to see the number of
logical and physical i/o's for a query. Scrutinize those
queries with high logical i/o's.
+ Use the "set statistics time on" command to see the amount of
time (elapsed, execution, parse and compile) a query takes to
run.
+ If the optimizer turns out to be a "pessimizer", use the "set
forceplan on" command to change join order to be the order of
the tables in the FROM clause.
+ If the optimizer refuses to select the proper index for a
table, you can force it by adding the index id in parentheses
after the table name in the FROM clause.
SELECT * FROM orders(2), order_detail(1) WHERE ...
_This may cause portability issues should index id's vary/change by
site ! _
Locking and Concurrency
* The Optimizer Decides on Lock Type and Granularity
* Decisions on lock type (share, exclusive, or update) and
granularity (page or table) are made during optimization so make
sure your updates and deletes don't scan the table !
* Exclusive Locks are Only Released Upon Commit or Rollback
* Lock Contention can have a large impact on both throughput and
response time if not considered both in the application and
database design !
* Keep transactions as small and short as possible to minimize
blocking. Consider alternatives to "mass" updates and deletes such
as a v10.0 cursor in a stored procedure which frequently commits.
* Never include any "user interaction" in the middle of
transactions.
* Shared Locks Generally Released After Page is Read
* Share locks "roll" through result set for concurrency. Only
"HOLDLOCK" or "Isolation Level 3" retain share locks until commit
or rollback. Remember also that HOLDLOCK is for read-consistency.
It doesn't block other readers !
* Use optimistic locking techniques such as timestamps and the
tsequal() function to check for updates to a row since it was read
(rather than holdlock)
ANSI Changes Affecting Concurrency
* Chained Transactions Risk Concurrency if Behavior not Understood
* Sybase defaults each DML statement to its own transaction if not
specified ;
* ANSI automatically begins a transaction with any SELECT, FETCH,
OPEN, INSERT, UPDATE, or DELETE statement ;
* If Chained Transaction must be used, extreme care must be taken to
ensure locks aren't left held by applications unaware they are
within a transaction! This is especially crucial if running at
Level 3 Isolation
* Lock at the Level of Isolation Required by the Query
* Read Consistency is NOT a requirement of every query.
* Choose level 3 only when the business model requires it
* Running at Level 1 but selectively applying HOLDLOCKs as needed is
safest
* If you must run at Level 3, use the NOHOLDLOCK clause when you can
!
* Beware of (and test) ANSI-compliant third-party applications for
concurrency
Application Deadlocking
Prior to SQL Server 10 cursors, many developers simulated cursors by
using two or more connections (dbproc's) and divided the processing
between them. Often, this meant one connection had a SELECT open while
"positioned" UPDATEs and DELETEs were issued on the other connection.
The approach inevitably leads to the following problem:
1. Connection A holds a share lock on page X (remember "Rows Pending"
on SQL Server leave a share lock on the "current" page).
2. Connection B requests an exclusive lock on the same page X and
waits...
3. The APPLICATION waits for connection B to succeed before invoking
whatever logic will remove the share lock (perhaps dbnextrow). Of
course, that never happens ...
Since Connection A never requests a lock which Connection B holds,
this is NOT a true server-side deadlock. It's really an "application"
deadlock !
Design Alternatives
1. Buffer additional rows in the client that are "nonupdateable".
This forces the shared lock onto a page on which the application
will not request an exclusive lock.
2. Re-code these modules with CT-Library cursors (aka. server-side
cursors). These cursors avoid this problem by disassociating
command structures from connection structures.
3. Re-code these modules with DB-Library cursors (aka. client-side
cursors). These cursors avoid this problem through buffering
techniques and re-issuing of SELECTs. Because of the re-issuing of
SELECTs, these cursors are not recommended for high transaction
sites !
Optimizing Cursors with v10.0
* Always Declare Cursor's Intent (i.e. Read Only or Updateable)
* Allows for greater control over concurrency implications
* If not specified, SQL Server will decide for you and usually
choose updateable
* Updateable cursors use UPDATE locks preventing other U or X locks
* Updateable cursors that include indexed columns in the update list
may table scan
* SET Number of Rows for each FETCH
* Allows for greater Network Optimization over ANSI's 1- row fetch
* Rows fetched via Open Client cursors are transparently buffered in
the client:
FETCH -> Open Client < N rows
Buffers
* Keep Cursor Open on a Commit / Rollback
* ANSI closes cursors with each COMMIT causing either poor
throughput (by making the server re-materialize the result set) or
poor concurrency (by holding locks)
* Open Multiple Cursors on a Single Connection
* Reduces resource consumption on both client and Server
* Eliminates risk of a client-side deadlocks with itself
Special Issues for Batch Applications
SQL Server was not designed as a batch subsystem! It was designed as
an RBDMS for large multi-user applications. Designers of
batch-oriented applications should consider the following design
alternatives to maximize performance :
Design Alternatives :
* Minimize Client/Server Interaction Whenever Possible
* Don't turn SQL Server into a "file system" by issuing single table
/ single row requests when, in actuality, set logic applies.
* Maximize TDS packet size for efficient Interprocess Communication
(v10 only)
* New SQL Server 10.0 cursors declared and processed entirely within
stored procedures and triggers offer significant performance gains
in batch processing.
* Investigate Opportunities to Parallelize Processing
* Breaking up single processes into multiple, concurrently
executing, connections (where possible) will outperform single
streamed processes everytime.
* Make Use of TEMPDB for Intermediate Storage of Useful Data
Asynchronous Queries
Many, if not most, applications and 3rd Party tools are coded to send
queries with the DB-Library call dbsqlexec( ) which is a synchronous
call ! It sends a query and then waits for a response from SQL Server
that the query has completed !
Designing your applications for asynchronous queries provides many
benefits:
1. A "Cooperative" multi-tasking application design under Windows
will allow users to run other Windows applications while your long
queries are processed !
2. Provides design opportunities to parallize work across multiple
SQL Server connections.
Implementation Choices:
* System 10 Client Library Applications:
* True asynchronous behaviour is built into the entire library.
Through the appropriate use of call-backs, asynchronous behavior
is the normal processing paradigm.
* Windows DB-Library Applications (not true async but polling for
data):
* Use dbsqlsend(), dbsqlok(), and dbdataready() in conjunction with
some additional code in WinMain() to pass control to a background
process. Code samples which outline two different Windows
programming approaches (a PeekMessage loop and a Windows Timer
approach) are available in the Microsoft Software Library on
Compuserve (GO MSL). Look for _SQLBKGD.ZIP_
* Non-PC DB-Library Applications (not true async but polling for
data):
* Use dbsqlsend(), dbsqlok(), and dbpoll() to utilize non-blocking
functions.
Generating Sequential Numbers
Many applications use unique sequentially increasing numbers, often as
primary keys. While there are good benefits to this approach,
generating these keys can be a serious contention point if not
careful. For a complete discussion of the alternatives, download
Malcolm Colton's White Paper on Sequential Keys from the SQL Server
Library of our OpenLine forum on Compuserve.
The two best alternatives are outlined below.
1. "Primary Key" Table Storing Last Key Assigned
+ Minimize contention by either using a seperate "PK" table for
each user table or padding out each row to a page. Make sure
updates are "in-place".
+ Don't include the "PK" table's update in the same transaction
as the INSERT. It will serialize the transactions.
_BEGIN TRAN_
UPDATE pk_table SET nextkey = nextkey + 1
[WHERE table_name = @tbl_name]
_COMMIT TRAN_
/* Now retrieve the information */
SELECT nextkey FROM pk_table
WHERE table_name = @tbl_name]
+ "Gap-less" sequences require additional logic to store and
retrieve rejected values
2. IDENTITY Columns (v10.0 only)
+ Last key assigned for each table is stored in memory and
automatically included in all INSERTs (BCP too). This should
be the method of choice for performance.
+ Choose a large enough numeric or else all inserts will stop
once the max is hit.
+ Potential rollbacks in long transactions may cause gaps in
the sequence !
Other Application Issues
* Transaction Logging Can Bottleneck Some High Transaction
Environments
* Committing a Transaction Must Initiate a Physical Write for
Recoverability
* Implementing multiple statements as a transaction can assist in
these environment by minimizing the number of log writes (log is
flushed to disk on commits).
* Utilizing the Client Machine's Processing Power Balances Load
* Client/Server doesn't dictate that everything be done on Server!
* Consider moving "presentation" related tasks such as string or
mathematical manipulations, sorting, or, in some cases, even
aggregating to the client.
* Populating of "Temporary" Tables Should Use "SELECT _INTO"_ -
balance this with dynamic creation of temporary tables in an OLTP
environment. Dynamic creation may cause blocks in your tempdb.
* "SELECT INTO" operations are not logged and thus are significantly
faster than there INSERT with a nested SELECT counterparts.
* Consider Porting Applications to Client Library Over Time
* True Asynchronous Behavior Throughout Library
* Array Binding for SELECTs
* Dynamic SQL
* Support for ClientLib-initiated callback functions
* Support for Server-side Cursors
* Shared Structures with Server Library (Open Server 10)
Physical Database Design Issues
* Normalized -vs- Denormalized Design
* Index Selection
* Promote "Updates-in-Place" Design
* Promote Parallel I/O Opportunities
Normalized -vs- Denormalized
* Always Start with a Completely Normalized Database
* Denormalization should be an optimization taken as a result of a
performance problem
* Benefits of a normalized database include :
1. Accelerates searching, sorting, and index creation since
tables are narrower
2. Allows more clustered indexes and hence more flexibility in
tuning queries, since there are more tables ;
3. Accelerates index searching since indexes tend to be narrower
and perhaps shorter ;
4. Allows better use of segments to control physical placement
of tables ;
5. Fewer indexes per table, helping UPDATE, INSERT, and DELETE
performance ;
6. Fewer NULLs and less redundant data, increasing compactness
of the database ;
7. Accelerates trigger execution by minimizing the extra
integrity work of maintaining redundant data.
8. Joins are Generally Very Fast Provided Proper Indexes are
Available
9. Normal caching and cindextrips parameter (discussed in Server
section) means each join will do on average only 1-2 physical
I/Os.
10. Cost of a logical I/O (get page from cache) only 1-2
milliseconds.
There Are Some Good Reasons to Denormalize
1. All queries require access to the "full" set of joined data.
2. Majority of applications scan entire tables doing joins.
3. Computational complexity of derived columns require storage for
SELECTs
4. Others ...
Index Selection
* Without a clustered index, all INSERTs and "out-of-place" UPDATEs
go to the last page. The lock contention in high transaction
environments would be prohibitive. This is also true for INSERTs
to a clustered index on a monotonically increasing key.
* High INSERT environments should always cluster on a key which
provides the most "randomness" (to minimize lock / device
contention) that is usable in many queries. Note this is generally
not your primary key !
* Prime candidates for clustered index (in addition to the above)
include :
+ Columns Accessed by a Range
+ Columns Used with Order By, Group By, or Joins
* Indexes Help SELECTs and Hurt INSERTs
* Too many indexes can significantly hurt performance of INSERTs and
"out-of-place" UPDATEs.
* Prime candidates for nonclustered indexes include :
+ Columns Used in Queries Requiring Index Coverage
+ Columns Used to Access Less than 20% (rule of thumb) of the
Data.
* Unique indexes should be defined as UNIQUE to help the optimizer
* Minimize index page splits with Fillfactor (helps concurrency and
minimizes deadlocks)
* Keep the Size of the Key as Small as Possible
* Accelerates index scans and tree traversals
* Use small datatypes whenever possible . Numerics should also be
used whenever possible as they compare faster than strings.
Promote "Update-in-Place" Design
* "Update-in-Place" Faster by Orders of Magnitude
* Performance gain dependent on number of indexes. Recent benchmark
(160 byte rows, 1 clustered index and 2 nonclustered) showed 800%
difference!
* Alternative ("Out-of-Place" Update) implemented as a physical
DELETE followed by a physical INSERT. These tactics result in:
1. Increased Lock Contention
2. Increased Chance of Deadlock
3. Decreased Response Time and Throughput
* Currently (System 10 and below), Rules for "Update-in-Place"
Behavior Include :
1. Columns updated can not be variable length or allow nulls
2. Columns updated can not be part of an index used to locate
the row to update
3. No update trigger on table being updated (because the
inserted and deleted tables used in triggers get their data
from the log)
In v4.9.x and below, only one row may be affected and the optimizer
must know this in advance by choosing a UNIQUE index. System 10
eliminated this limitation.
Promote Parallel I/O Opportunities
* For I/O-bound Multi-User Systems, Use A lot of Logical and
Physical Devices
* Plan balanced separation of objects across logical and physical
devices.
* Increased number of physical devices (including controllers)
ensures physical bandwidth
* Increased number of logical Sybase devices ensures minimal
contention for internal resources. Look at SQL Monitor's Device
I/O Hit Rate for clues. Also watch out for the 128 device limit
per database.
* Create Database (in v10) starts parallel I/O on up to 6 devices at
a time concurrently. If taken advantage of, expect an 800%
performance gain. A 2Gb TPC-B database that took 4.5 hours under
4.9.1 to create now takes 26 minutes if created on 6 independent
devices !
* Use Sybase Segments to Ensure Control of Placement
This is the only way to guarantee logical seperation of objects on
devices to reduce contention for internal resources.
* Dedicate a seperate physical device and controller to the
transaction log in tempdb too.
* optimize TEMPDB Also if Heavily Accessed
* increased number of logical Sybase devices ensures minimal
contention for internal resources.
* systems requiring increased log throughput today must partition
database into separate databases
Breaking up one logical database into multiple smaller databases
increases the number number of transaction logs working in
parallel.
Networking Issues
* Choice of Transport Stacks
* Variable Sized TDS Packets
* TCP/IP Packet Batching
Choice of Transport Stacks for PCs
* Choose a Stack that Supports "Attention Signals" (aka. "Out of
Band Data")
* Provides for the most efficient mechanism to cancel queries.
* Essential for sites providing ad-hoc query access to large
databases.
* Without "Attention Signal" capabilities (or the urgent flag in the
connection string), the DB-Library functions DBCANQUERY ( ) and
DBCANCEL ( ) will cause SQL Server to send all rows back to the
Client DB-Library as quickly as possible so as to complete the
query. This can be very expensive if the result set is large and,
from the user's perspective, causes the application to appear as
though it has hung.
* With "Attention Signal" capabilities, Net-Library is able to send
an out-of-sequence packet requesting the SQL Server to physically
throw away any remaining results providing for instantaneous
response.
* Currently, the following network vendors and associated protocols
support the an "Attention Signal" capable implementation:
1. NetManage NEWT
2. FTP TCP
3. Named Pipes (10860) - Do not use urgent parameter with this
Netlib
4. Novell LAN Workplace v4.1 0 Patch required from Novell
5. Novell SPX - Implemented internally through an "In-Band"
packet
6. Wollongong Pathway
7. Microsoft TCP - Patch required from Microsoft
Variable-sized TDS Packets
Pre-v4.6 TDS Does Not Optimize Network Performance Current SQL Server
TDS packet size limited to 512 bytes while network frame sizes are
significantly larger (1508 bytes on Ethernet and 4120 bytes on Token
Ring).
The specific protocol may have other limitations!
For example:
* IPX is limited to 576 bytes in a routed network.
* SPX requires acknowledgement of every packet before it will send
another. A recent benchmark measured a 300% performance hit over
TCP in "large" data transfers (small transfers showed no
difference).
* Open Client Apps can "Request" a Larger Packet Shown to have
significant performance improvement on "large" data transfers such
as BCP, Text / Image Handling, and Large Result Sets.
+ clients:
o isql -Usa -Annnnn
o bcp -Usa -Annnnn
o ct_con_props (connection, CS_SET, CS_PACKETSIZE,
&packetsize, sizeof(packetsize), NULL)
+ An "SA" must Configure each Servers' Defaults Properly
o sp_configure "default packet size", nnnnn - Sets default
packet size per client connection (defaults to 512)
o sp_configure "maximum packet size", nnnnn - Sets maximum
TDS packet size per client connection (defaults to 512)
o sp_configure "additional netmem", nnnnn - Additional
memory for large packets taken from separate pool. This
memory does not come from the sp_configure memory
setting.
Optimal value = ((# connections using large packets
large packetsize * 3) + an additional 1-2% of the above
calculation for overhead)
Each connection using large packets has 3 network
buffers: one to read; one to write; and one overflow.
# Default network memory - Default-sized packets come
from this memory pool.
# Additional Network memory - Big packets come this
memory pool.
If not enough memory is available in this pool, the
server will give a smaller packet size, down to the
default
TCP/IP Packet Batching
* TCP Networking Layer Defaults to "Packet Batching"
* This means that TCP/IP will batch small logical packets into one
larger physical packet by briefly delaying packets in an effort to
fill the physical network frames (Ethernet, Token-Ring) with as
much data as possible.
* Designed to improve performance in terminal emulation environments
where there are mostly only keystrokes being sent across the
network.
* Some Environments Benefit from Disabling Packet Batching
* Applies mainly to socket-based networks (BSD) although we have
seen some TLI networks such as NCR's benefit.
* Applications sending very small result sets or statuses from
sprocs will usually benefit. Benchmark with your own application
to be sure.
* This makes SQL Server open all connections with the TCP_NODELAY
option. Packets will be sent regardless of size.
* To disable packet batching, in pre-Sys 11, start SQL Server with
the 1610 Trace Flag.
$SYBASE/dataserver -T1610 -d /usr/u/sybase/master.dat ...
Your errorlog will indicate the use of this option with the
message:
SQL Server booted with TCP_NODELAY enabled.
Operating System Issues
* Never Let SQL Server Page Fault
* It is better to configure SQL Server with less memory and do more
physical database I/O than to page fault. OS page faults are
synchronous and stop the entire dataserver engine until the page
fault completes. Since database I/O's are asynchronous, other user
tasks can continue!
* Use Process Affinitying in SMP Environments, if Supported
* Affinitying dataserver engines to specific CPUs minimizes overhead
associated with moving process information (registers, etc)
between CPUs. Most implementations will preference other tasks
onto other CPUs as well allowing even more CPU time for dataserver
engines.
* Watch out for OS's which are not fully symmetric. Affinitying
dataserver engines onto CPUs that are heavily used by the OS can
seriously degrade performance. Benchmark with your application to
find optimal binding.
* Increase priority of dataserver engines, if supported
* Give SQL Server the opportunity to do more work. If SQL Server has
nothing to do, it will voluntarily yield the CPU.
* Watch out for OS's which externalize their async drivers. They
need to run too!
* Use of OS Monitors to Verify Resource Usage
* The OS CPU monitors only "know" that an instruction is being
executed. With SQL Server's own threading and scheduling, it can
routinely be 90% idle when the OS thinks its 90% busy. SQL Monitor
shows real CPU usage.
* Look into high disk I/O wait time or I/O queue lengths. These
indicate physical saturation points in the I/O subsystem or poor
data distribution.
* Disk Utilization above 50% may be subject to queuing effects which
often manifest themselves as uneven response times.
* Look into high system call counts which may be symptomatic of
problems.
* Look into high context switch counts which may also be symptomatic
of problems.
* Optimize your kernel for SQL Server (minimal OS file buffering,
adequate network buffers, appropriate KEEPALIVE values, etc).
* Use OS Monitors and SQL Monitor to Determine Bottlenecks
* Most likely "Non-Application" contention points include:
Resource Where to Look
--------- --------------
CPU Performance SQL Monitor - CPU and Trends
Physical I/O Subsystem OS Monitoring tools - iostat, sar...
Transaction Log SQL Monitor - Device I/O and
Device Hit Rate
on Log Device
SQL Server Network Polling SQL Monitor - Network and Benchmark
Baselines
Memory SQL Monitor - Data and Cache
Utilization
* Use of Vendor-support Striping such as LVM and RAID
* These technologies provide a very simple and effective mechanism
of load balancing I/O across physical devices and channels.
* Use them provided they support asynchronous I/O and reliable
writes.
* These approaches do not eliminate the need for Sybase segments to
ensure minimal contention for internal resources.
* Non-read-only environments should expect performance degradations
when using RAID levels other than level 0. These levels all
include fault tolerance where each write requires additional reads
to calculate a "parity" as well as the extra write of the parity
data.
Hardware Configuration Issues
* Number of CPUs
* Use information from SQL Monitor to assess SQL Server's CPU usage.
* In SMP environments, dedicate at least one CPU for the OS.
* Advantages and scaling of VSA is application-dependent. VSA was
architected with large multi-user systems in mind.
* I/O Subsystem Configuration
* Look into high Disk I/O Wait Times or I/O Queue Lengths. These may
indicate physical I/O saturation points or poor data distribution.
* Disk Utilization above 50% may be subject to queuing effects which
often manifest themselves as uneven response times.
* Logical Volume configurations can impact performance of operations
such as create database, create index, and bcp. To optimize for
these operations, create Logical Volumes such that they start on
different channels / disks to ensure I/O is spread across
channels.
* Discuss device and controller throughput with hardware vendors to
ensure channel throughput high enough to drive all devices at
maximum rating.
General SQL Server Tuning
* Changing Values with sp_configure or buildmaster
_It is imperative that you only use sp_configure to change those
parameters that it currently maintains because the process of
reconfiguring actually recalculates a number of other buildmaster
parameters. Using the Buildmaster utility to change a parameter
"managed" by sp_configure may result in a mis-configured server and
cause adverse performance or even worse ... _
* Sizing Procedure Cache
+ SQL Server maintains an MRU-LRU chain of stored procedure
query plans. As users execute sprocs, SQL Server looks in
cache for a query plan to use. However, stored procedure
query plans are currently not re-entrant! If a query plan is
available, it is placed on the MRU and execution begins. If
no plan is in memory, or if all copies are in use, a new copy
is read from the sysprocedures table. It is then optimized
and put on the MRU for execution.
+ Use dbcc memusage to evaluate the size and number of each
sproc currently in cache. Use SQL Monitor's cache statistics
to get your average cache hit ratio. Ideally during
production, one would hope to see a high hit ratio to
minimize the procedure reads from disk. Use this information
in conjuction with your desired hit ratio to calculate the
amount of memory needed.
* Memory
+ Tuning memory is more a price/performance issue than anything
else ! The more memory you have available, the greater than
probability of minimizing physical I/O. This is an important
goal though. Not only does physical I/O take significantly
longer, but threads doing physical I/O must go through the
scheduler once the I/O completes. This means that work on
behalf of the thread may not actually continue to execute for
quite a while !
+ There are no longer (as of v4.8) any inherent limitations in
SQL Server which cause a point of diminishing returns on
memory size.
+ Calculate Memory based on the following algorithm :
Total Memory = Dataserver Executable Size (in bytes) +
Static Overhead of 1 Mb +
User Connections x 40,960 bytes +
Open Databases x 644 bytes +
Locks x 32 bytes +
Devices x 45,056 bytes +
Procedure Cache +
Data Cache
* Recovery Interval
+ As users change data in SQL Server, only the transaction log
is written to disk right away for recoverability. "Dirty"
data and index pages are kept in cache and written to disk at
a later time. This provides two major benefits:
1. Many transactions may change a page yet only one
physical write is done
2. SQL Server can schedule the physical writes "when
appropriate"
+ SQL Server must eventually write these "dirty" pages to disk.
+ A checkpoint process wakes up periodically and "walks" the
cache chain looking for dirty pages to write to disk
+ The recovery interval controls how often checkpoint writes
dirty pages.
* Tuning Recovery Interval
+ A low value may cause unnecessary physical I/O lowering
throughput of the system. Automatic recovery is generally
much faster during boot-up.
+ A high value minimizes unnecessary physical I/O and helps
throughput of the system. Automatic recovery may take
substantial time during boot-up.
Audit Performance Tuning for v10.0
* Potentially as Write Intensive as Logging
* Isolate Audit I/O from other components.
* Since auditing nearly always involves sequential writes, RAID
Level 0 disk striping or other byte-level striping technology
should provide the best performance (theoretically).
* Size Audit Queue Carefully
* Audit records generated by clients are stored in an in memory
audit queue until they can be processed.
* Tune the queue's size with sp_configure "audit queue size", nnnn
(in rows).
* Sizing this queue too small will seriously impact performance
since all user processes who generate audit activity will sleep if
the queue fills up.
* Size Audit Database Carefully
* Each audit row could require up to 416 bytes depending on what is
audited.
* Sizing this database too small will seriously impact performance
since all user processes who generate audit activity will sleep if
the database fills up.
_________________________________________________________________
Q8.2: TEMP TABLES AND OLTP
_________________________________________________________________
Our shop would like to inform folks of a potential problem when using
_temporary tables in an OLTP environment._ Using temporary tables
dynamically in a OLTP production environment may result in blocking
(single-threading) as the number of transactions using the temporary
tables increases.
Does it affect my application?
This warning only applies for SQL, that is being invoked frequently in
an OLTP production environment, where the use of _"select into..." or
"create table #temp"_ is common. Application using temp tables may
experience blocking problems as the number of transactions increases.
This warning does not apply to SQL that may be in a report or that is
not used frequently. _Frequently_ is defined as several times per
second.
Why? Why? Why?
Our shop was working with an application owner to chase down a problem
they were having during peak periods. The problem they were having was
severe blocking in tempdb.
What was witnessed by the DBA group was that as the number of
transactions increased on this particular application, the number of
blocks in tempdb also increased.
We ran some independent tests to simulate a heavily loaded server and
discovered that the data pages in contention were in tempdb's
_syscolumns'_ table.
This actually makes sense because during table creation entries are
added to this table, regardless if it's a temporary or permanent
table.
We ran another simulation where we created the tables before the
stored procedure used it and the blocks went away. We then performed
an additional test to determine what impact creating temporary tables
dynamically would have on the server and discovered that there is a
33% performance gain by creating the tables once rather than
re-creating them.
Your mileage may vary.
How do I fix this?
To make things better, do the 90's thing -- _reduce and reuse your
temp tables._ During one application connection/session, aim to create
the temp tables only once.
Let's look at the lifespan of a temp table. If temp tables are created
in a batch within a connection, then all future batches and stored
procs will have access to such temp tables until they're dropped; this
is the reduce and reuse strategy we recommend. However, if temp tables
are created in a stored proc, then the database will drop the temp
tables when the stored proc ends, and this means repeated and multiple
temp table creations; you want to avoid this.
Recode your stored procedures so that they assume that the temporary
tables already exist, and then alter your application so that it
creates the temporary tables at start-up -- once and not every time
the stored procedure is invoked.
That's it! Pretty simple eh?
Summary
The upshot is that you can realize roughly a 33% performance gain and
not experience the blocking which is difficult to quantify due to the
specificity of each application.
Basically, you cannot lose.
Solution in pseudo-code
If you have an application that creates the same temp table many times
within one connection, here's how to convert it to reduce and reuse
temp table creations. Raymond Lew has supplied a detailed example for
trying this.
Old
open connection
loop until time to go
exec procedure vavoom_often
/* vavoom_often creates and uses #gocart for every call */
/* eg: select * into #gocart from gocart */
go
.
.
.
loop-end
close connection
New
open connection
/* Create the temporary table outside of the sproc */
select * into #gocart from gocart where 1 =2 ;
go
loop until time to go
exec procedure vavoom_often
/* vavoom_often reuses #gocart which */
/* was created before exec of vavoom_often */
/* - First statement may be a truncate table #gocart */
/* - Execute _with recompile_ */
/* if your table will have more than 10 data pages */
/* as the optimizer will assume 10 data pages for temp tables */
go
.
.
.
loop-end
close connection
Note that it is necessary to call out the code to create the table and
it becomes a pain in the butt because the create-table statement will
have to be replicated in any stored proc and in the initialization
part of the application - this can be a maintenance nuisance. This can
be solved by using any macro package such as _m4_ or _cpp_. or by
using and adapting the scripts from Raymond Lew.
_________________________________________________________________
From: Raymond Lew
At our company, we try to keep the database and the application
loosely coupled to allow independent changes at the frontend or the
backend as long as the interface stays the same. Embedding temp table
definitions in the frontend would make this more difficult.
To get away from having to embed the temp table definitions in the
frontend code, we are storing the temp table definitions in the
database. The frontend programs retrieve the definitions and declare
the tables dynamically at the beginning of each session. This allows
for the change of backend procedures without changes in the frontend
when the API does not change.
Enclosed below are three scripts. The first is an isql script to
create the tables to hold the definitions. The second is a shell
script to set up a sample procedure named vavoom. The third is shell
script to demonstrate the structure of application code.
I would like to thank Charles Forget and Gordon Rees for their
assistance on these scripts.
--start of setup------------------------------------------------------
/* Raymond Lew - 1996-02-20 */
/* This isql script will set up the following tables:
gocart - sample table
app_temp_defn - where temp table definitions are stored
app_temp_defn_group - a logical grouping of temp table definitions
for an application function
*/
/******************************/
/* gocart table - sample table*/
/******************************/
drop table gocart
go
create table gocart
(
cartname char(10) null
,cartcolor char(30) null
)
go
create unique clustered index gocart1 on gocart (cartname)
go
insert into gocart values ('go1','blue ')
insert into gocart values ('go2','pink ')
insert into gocart values ('go3','green ')
insert into gocart values ('go4','red ')
go
/****************************************************************/
/* app_temp_defn - definition of temp tables with their indexes */
/****************************************************************/
drop table app_temp_defn
go
create table app_temp_defn
(
/* note: temp tables are unique only in first 13 chars */
objectname char(20) not null
,seq_no smallint not null
,defntext char(255) not null
)
go
create unique clustered index app_temp_defn1
on app_temp_defn (objectname,seq_no)
go
insert into app_temp_defn
values ('#gocart',1,'select * into #gocart')
insert into app_temp_defn
values ('#gocart',2,' from gocart where 1=2 ')
go
insert into app_temp_defn
values ('#gocartindex',1,
"create unique index gocartindex on #gocart (cartname) ")
go
insert into app_temp_defn
values ('#gocart1',1, 'select * into #gocart1 from gocart where 1=2')
go
/***********************************************************************/
/* app_temp_defn_group - groupings of temp definitions by applications */
/***********************************************************************/
drop table app_temp_defn_group
go
create table app_temp_defn_group
(
appname char(8) not null
,objectname char(20) not null
)
go
create unique clustered index app_temp_defn_group1
on app_temp_defn_group (appname,objectname)
go
insert into app_temp_defn_group values('abc','#gocart')
insert into app_temp_defn_group values('abc','#gocartindex')
go
/***********************************************************/
/* get_temp_defn - proc for getting the temp defn by group */
/***********************************************************/
drop procedure get_temp_defn
go
create procedure get_temp_defn
(
@appname char(8)
)
as
if @appname = ''
select defntext
from app_temp_defn
order by objectname, seq_no
else
select defntext
from app_temp_defn a
, app_temp_defn_group b
where a.objectname = b.objectname
and b.appname = @appname
order by a.objectname, a.seq_no
return
go
/* let's try some tests */
exec get_temp_defn ''
go
exec get_temp_defn 'abc'
go
--end of setup --------------------------------------------------
--- start of make.vavoom --------------------------------------------
#!/bin/sh
# Raymond Lew - 1996-02-20
#
# bourne shell script for creating stored procedures using
# app_temp_defn table
#
# demo procedure vavoom created here
#
# note: you have to change the passwords, id and etc. for your site
# note: you might have to some inline changes to make this work
# check out the notes within the body
# get the table defn's into a text file
#
# note: next line :you will need to end the line immediately after eot \
isql -Ukryten -Pjollyguy -Sstarbug -w255 <lt eot \
| grep -v '\-\-\-\-' | grep -v 'defntext ' | grep -v ' affected' >tabletext
exec get_temp_defn ''
go
eot
# note: prev line :you will need to have a newline immediately after eot
# go mess around in vi
vi tabletext
#
# create the proc vavoom after running the temp defn's into db
#
isql -Ukryten -Pjollyguy -Sstarbug -e <lt eot |more
`cat tabletext`
go
drop procedure vavoom
go
create procedure vavoom
(
@color char(10)
)
as
truncate table #gocart1 /* who knows what lurks in temp tables */
if @color = ''
insert #gocart1 select * from gocart
else
insert #gocart1 select * from gocart where cartcolor=@color
select @color '@color', * from #gocart1
return
go
exec vavoom ''
go
exec vavoom 'blue'
go
eot
# note: prev line :you will need to have a newline immediately after eot
exit
# end of unix script
--- end of make.vavoom --------------------------------------------
--- start of defntest.sh -------------------------------------------
#!/bin/sh
# Raymond Lew 1996-02-01
#
# test script: demonstrate with a bourne shell how an application
# would use the temp table definitions stored in the database
#
# note: you must run setup and make.vavoom first
#
# note: you have to change the passwords, id and etc. for your site
# note: you might have to some inline changes to make this work
# check out the notes within the body
# get the table defn's into a text file
#
# note: next line :you will need to end the line immediately after eot \
isql -Ukryten -Pjollyguy -Sstarbug -w255 <lt eot \
| grep -v '\-\-\-\-' | grep -v 'defntext ' | grep -v ' affected' >tabletext
exec get_temp_defn ''
go
eot
# note: prev line :you will need to have a newline immediately after eot
# go mess around in vi
vi tabletext
isql -Ukryten -Pjollyguy -Sstarbug -e <lt eot | more
`cat tabletext`
go
exec vavoom ''
go
exec vavoom 'blue'
go
eot
# note: prev line :you will need to have a newline immediately after eot
exit
# end of unix script
--- end of defntest.sh -------------------------------------------
That's all, folks. Have Fun
_________________________________________________________________
Q8.3: DIFFERENCES BETWEEN _CLUSTERED_ AND _NON-CLUSTERED_
_________________________________________________________________
Preface
I'd like to talk about the difference between a clustered and a
non-clustered index. The two are _very_ different and it's very
important to understand the difference between the two to in order to
know when and how to use each.
I've pondered hard to find the best analogy that I could think of and
I've come up with ... the phone book. Yes, a phone book.
Imagine that each page in our phone book is equivalent to a Sybase 2K
data page. Every time we read a page from our phone book it is
equivalent to one disk I/O.
Since we are imagining, let's also imagine that our mythical SQL
Server (that runs against the phone book) has only enough data cache
to buffer 200 phone pages. When our data cache gets full we have to
flush an old page out so we can read in a new one.
Fasten your seat belts, because here we go...
Clustered Index
A phone book lists everyone by last name. We have an _A_ section, we
have a _B_ section and so forth. Within each section my phone book is
clever enough to list the starting and ending names for the given
page.
The phone book is clustered by last name.
create clustered index on phone_book (last_name)
It's fast to perform the following queries on the phone book:
* Find the address of those whose last name is _Cisar_.
* Find the address of those whose last name is between _Even_ and
_Fa_
Searches that don't work well:
* Find the address of those whose phone number is _440-1300_.
* Find the address of those whose prefix is _440_
In order to determine the answer to the two above we'd have to search
the entire phone book. We can call that a table scan.
Non-Clustered Index
To help us solve the problem above we can build a non-clustered index.
create nonclustered index on phone_book (phone_number)
Our non-clustered index will be built and maintained by our Mythical
SQL Server as follows:
1. Create a data structure that will house a _phone_number_ and
information where the _phone_number_ exists in the phone book:
page number and the row within the page.
The phone numbers will be kept in ascending order.
2. Scan the _entire_ phone book and add an entry to our data
structure above for _each_ phone number found.
3. For each phone number found, note along side it the page number
that it was located _and_ which row it was in.
any time we insert, update or delete new numbers, our M-SQL Server
will maintain this secondary data structure. It's such a nice Server.
Now when we ask the question:
Find the address of those whose phone number is _440-1300_
we don't look at the phone book directly but go to our new data
structure and it tells us which page and row within the page the above
phone number can be found. Neat eh?
Draw backs? Well, yes. Because we _probably_ still can't answer the
question:
Find the address of those whose prefix is _440_
This is because of the data structure being used to implement
non-clustered indexes. The structure is a list of ordered values
(phone numbers) which point to the actual data in the phone book. This
indirectness can lead to trouble when a range or a match query is
issued.
The structure may look like this:
------------------------------------
|Phone Number | Page Number/Row |
====================================
| 440-0000 | 300/23 |
| 440-0001 | 973/45 |
| 440-0002 | 23/2 |
| ... | |
| 440-0030 | 973/45 |
| 440-0031 | 553/23 |
| ... | |
------------------------------------
As one can see, certain phone numbers may map to the same page. This
makes sense, but we need to consider one of our constraints: our
Server only has room for 200 phone pages.
What may happen is that we re-read the same phone page many times.
This isn't a problem if the phone page is in memory. We have limited
memory, however, and we may have to flush our memory to make room for
other phone pages. So the re-reading may actually be a disk I/O.
The Server needs to decide when it's best to do a table scan versus
using the non-clustered index to satisfy mini-range type of queries.
The way it decides this is by applying a heuristic based on the
information maintained when an _update statistics_ is performed.
In summary, non-clustered indexes work really well when used for
highly selective queries and they may work for short, range type of
queries.
Suggested Uses
Having suffered many table corruption situations (with 150 SQL servers
who wouldn't? :-)), I'd say _always_ have a clustered index. With a
clustered index you can fish data out around the _bad_ spots on the
table thus having minimal data loss.
When you cluster, build the cluster to satisfy the largest percentage
of range type queries. Don't put the clustered index on your primary
key because typically primary keys are increasing linearly. What
happens is that you end up inserting all new rows at the end of the
table thus creating a hot spot on the last data page.
For detail rows, create the clustered index on the commonly accessed
foreign key. This will aid joins from the master to it.
Use nonclustered index to aid queries where your selection is _very_
selective. For example, primary keys. :-)
_________________________________________________________________
Q8.4: OPTIMISTIC VERSUS PESSIMISTIC LOCKING?
_________________________________________________________________
This is the same problem another poster had ... basically locking a
record to ensure that it hasn't changed underneath ya.
fca...@ix.netcom.com has a pretty nifty solution if you are using
ct-lib (I'll include that below -- hope it's okay Francisco ... :-))
...
Basically the problem you are facing is one of being a pessimist or an
optimist.
I contend that your business really needs to drive this.
Most businesses (from my experience) can be optimistic.
That is, if you are optimistic that the chances that someone is going
to change something from underneath the end-user is _low_, then do
_nothing_ about it.
On the other hand, if you are pessimistic that someone may change
something underneath the end-user, you can solve it at least as
follows:
Solution #1
Use a timestamp on a header table that would be shared by the common
data. This timestamp field is a Sybase datatype and has nothing to do
with the current time. Do not attempt to do any operations on this
column other than comparisons. What you do is when you grab data to
present to the end-user, have the client software also grab the
timestamp column value. After some _thing time_, if the end-user
wishes to update the database, compare the client timestamp with
what's in the database and it it's changed, then you can take
appropriate action: again this is dictated by the business.
Problem #1
If users are sharing tables but columns are not shared, there's no way
to detect this using timestamps because it's not sufficiently
granular.
Solution #2 (presented by fcasas)
... Also are you coding to ct-lib directly? If so there's something
that you could have done, or may still be able to do if you are using
cursors.
With ct-lib there's a ct_describe function that lets you see _key
data_. This allows you to implement optimistic locking with cursors
and not need timestamps. Timestamps are nice, but they are changed
when any column on a row changes, while the ct_describe mechanism
detects changes at the columns level for a greater degree of
granularity of the change. In other words, the timestamp granularity
is at the row, while ct_describes CS_VERSION_KEY provides you with
granularity at the column level.
Unfortunately this is not well documented and you will have to look at
the training guide and the manuals very closely.
Further if you are using cursors _do not_ make use of the
[for {read only | update [of column_name_list]}]
of the _select_ statement. Omitting this clause will still get you
data that can still be updated and still only place a shared lock on
the page. If you use the _read only_ clause you are acquiring shared
locks, but the cursor is not updatable. However, if you say
update [of ...
will place updated locks on the page, thus causing contention. So, if
you are using cursors _don't use_ the above clause. So, could you
answer the following three questions:
1. Are you using optimistic locking?
2. Are you coding to ct-lib?
3. Are you using cursors?
Problem #2
You need to be coding with ct-lib ...
Solution #3
Do nothing and be optimistic. We do a lot of that in our shop and it's
really not that big of a problem.
Problem #3
Users may clobber each other's changes ... then they'll come looking
for you to clobber you! :-)
_________________________________________________________________
Q8.5: HOW DO I FORCE AN INDEX TO BE USED?
_________________________________________________________________
Sybase 4.x and Sybase System 10
All indexes have an ordinal value assigned to them. For example, the
following query will return the ordinal value of all the indexes on
_my_table_:
select name, indid from sysindexes where id = object_id("my_table")
Assuming that we wanted to force the usuage of index numbered three:
select ... from my_table(3)
note that using a value of zero is equivalent to a _table scan_.
_You should heavily document any indexed that are forced. _
System 11
In System 11, the binding of the internal ordinal value is alleviated
so that instead of using the ordinal index value, the index name can
be used instead:
select ... from my_table (_index_ my_first_index)
Note that you should _still_ document that the index is being forced.
_________________________________________________________________
Q8.6: WHY PLACE TEMPDB AND LOG ON LOW NUMBERED DEVICES?
_System 10 and below._
_________________________________________________________________
In System 10 and Sybase 4.X, the I/O scheduler starts at logical
device (_ldev_) zero and works up the _ldev_ list looking for
outstanding I/O's to process. Taking this into consideration, the
following device fragments (_disk init_) should be added before any
others:
1. tempdb
2. log
_________________________________________________________________
Q8.7: How much memory to configure?
System 10 and below.
----------------------------------------------------------------------------
Overview
At some point you'll wonder if your SQL Server has been configured with
sufficient memory. We hope that it's not during some crisis but that's
probably when it'll happen.
The most important thing in setting up memory for a SQL Server is that it
has to be large enough to accomodate:
* concurrent user connections
* active procedures
* and concurrent open databases.
By not setting the SQL Server up correctly it will affect the performance of
it. A delicate balance needs to be struck where your SQL Server is large
enough to accommodate the users but not too large where it adversely affects
the CPU Server (such as causing swapping).
Assumptions made of the reader:
* The reader has some experience administering SQL Servers.
* All queries have been tuned and that there are no unnecessary table
scans.
Preface
As the SQL Server starts up, it pre-allocates its structures to support the
configuration. The memory that remains after the pre-allocation phase is the
available cache.
The available cache is partitioned into two pieces:
1. buffer cache - data pages to be sent to a user connection or flushed to
disk.
2. procedure cache - where query plans live.
The idea is to determine if the buffer cache and the procedure cache are of
adequate size. As a DBA you can use dbcc memusage to ascertain this.
The information provided from a dbcc memusage, daunting at first, but taken
in sections, is easy to understand and provides the DBA with the vital
information that is necessary to determine if more memory is required and
where it is required.
If the procedure cache is too small, user connections will get sporadic
701's:
There is insufficient system memory to run this query.
If the buffer cache is too small, response time may be poor or spiky.
The following text describes how to interpret the output of dbcc memusage
and to correlate this back to the fundamental question:
Does my SQL Server have enough memory?
Definitions
Before delving into the world of dbcc memusage some definitions to get us
through.
Buffer Cache (also referred to as the Data Cache)
Area of memory where SQL Server stores the most recently used data
pages and index pages in 2K page units. If SQL Server finds a data page
or index page in the buffer cache, it doesn't need to perform a
physical I/O (it is reported as a logical I/O). If a user connection
selects data from a database, the SQL Server loads the 2K data page(s)
here and then hands the information off to the user connection. If a
user connection updates data, these pages are altered, and then they
are flushed out to disk by the SQL Server.
This is a bit simplistic but it'll do. Read on for more info
though.
The cache is maintained as a doubly linked list. The head of
the list is where the most recently used pages are placed.
Naturally towards the tail of the chain are the least
recently used pages. If a page is requested and it is found
on the chain, it is moved back to the front of the chain and
the information is relayed, thus saving a physical I/O.
But wait! this recycling is not done forever. When a
checkpoint occurs any dirty pages are flushed. Also, the
parameter cbufwashsize determines how many times a page
containing data can be recycled before it has to be flushed
out to disk. For OAM and index pages the following parameters
apply coamtrips and cindextrips respectively.
Procedure Cache
Area of memory where SQL Server stores the most recently used query
plans of stored procedures and triggers. This procedure cache is also
used by the Server when a procedure is being created and when a query
is being compiled. Just like the buffer cache, if SQL Server finds a
procedure or a compilation already in this cache, it doesn't need to
read it from the disk.
The size of procedure cache is determined by the percentage of
remaining memory configured for this Server parameter after SQL Server
memory needs are met.
Available Cache
When the SQL Server starts up it pre-allocates its data structures to
support the current configuration. For example, based on the number of user
connections, additional netmem, open databases and so forth the dataserver
pre-allocates how much memory it requires to support these configured items.
What remains after the pre-allocation is the available cache. The available
cache is divided into buffer cache and procedure cache. The sp_configure
"procedure cache" parameter determines the percentage breakdown. A value of
20 would read as follows:
20% of the available cache is dedicated to the procedure cache and
80% is dedicated to the buffer cache.
Your pal: dbcc memusage
dbcc memusage takes a snapshot of your SQL Server's current memory usage and
reports this vital information back to you. The information returned
provides information regarding the use of your procedure cache and how much
of the buffer cache you are currently using.
An important piece of information is the size of the largest query plan.
We'll talk about that more below.
It is best to run dbcc memusage after your SQL Server has reached a working
set. For example, at the end of the day or during lunch time.
Running dbcc memusage will freeze the dataserver while it does its
work. The more memory you have configured for the SQL Server the
longer it'll take. Our experience is that for a SQL Server with
300MB it'll take about four minutes to execute. During this time,
nothing else will execute: no user queries, no sp_who's...
In order to run dbcc memusage you must have sa privileges. Here's a sample
execution for discussion purposes:
1> /* send the output to the screen instead of errorlog */
2> dbcc traceon(3604)
3> go
1> dbcc memusage
2> go
Memory Usage:
Meg. 2K Blks Bytes
Configured Memory:300.0000 153600 314572800
Code size: 2.6375 1351 2765600
Kernel Structures: 77.6262 39745 81396975
Server Structures: 54.4032 27855 57045920
Page Cache:129.5992 66355 135894640
Proc Buffers: 1.1571 593 1213340
Proc Headers: 25.0840 12843 26302464
Number of page buffers: 63856
Number of proc buffers: 15964
Buffer Cache, Top 20:
DB Id Object Id Index Id 2K Buffers
6 927446498 0 9424
6 507969006 0 7799
6 959446612 0 7563
6 116351649 0 7428
6 2135014687 5 2972
6 607445358 0 2780
6 507969006 2 2334
6 2135014687 0 2047
6 506589013 0 1766
6 1022066847 0 1160
6 116351649 255 987
6 927446498 8 897
6 927446498 10 733
6 959446612 7 722
6 506589013 1 687
6 971918604 0 686
6 116351649 6 387
Procedure Cache, Top 20:
Database Id: 6
Object Id: 1652357121
Object Name: lp_cm_case_list
Version: 1
Uid: 1
Type: stored procedure
Number of trees: 0
Size of trees: 0.000000 Mb, 0.000000 bytes, 0 pages
Number of plans: 16
Size of plans: 0.323364 Mb, 339072.000000 bytes, 176 pages
----
Database Id: 6
Object Id: 1668357178
Object Name: lp_cm_subcase_list
Version: 1
Uid: 1
Type: stored procedure
Number of trees: 0
Size of trees: 0.000000 Mb, 0.000000 bytes, 0 pages
Number of plans: 10
Size of plans: 0.202827 Mb, 212680.000000 bytes, 110 pages
----
Database Id: 6
Object Id: 132351706
Object Name: csp_get_case
Version: 1
Uid: 1
Type: stored procedure
Number of trees: 0
Size of trees: 0.000000 Mb, 0.000000 bytes, 0 pages
Number of plans: 9
Size of plans: 0.149792 Mb, 157068.000000 bytes, 81 pages
----
Database Id: 6
Object Id: 1858261845
Object Name: lp_get_last_caller_new
Version: 1
Uid: 1
Type: stored procedure
Number of trees: 0
Size of trees: 0.000000 Mb, 0.000000 bytes, 0 pages
Number of plans: 2
Size of plans: 0.054710 Mb, 57368.000000 bytes, 30 pages
...
1> /* redirect output back to the errorlog */
2> dbcc traceoff(3604)
3> go
Dissecting memusage output
The output may appear overwhelming but it's actually pretty easy to parse.
Let's look at each section.
Memory Usage
This section provides a breakdown of the memory configured for the SQL
Server.
Memory Usage:
Meg. 2K Blks Bytes
Configured Memory:300.0000 153600 314572800
Code size: 2.6375 1351 2765600
Kernel Structures: 77.6262 39745 81396975
Server Structures: 54.4032 27855 57045920
Page Cache:129.5992 66355 135894640
Proc Buffers: 1.1571 593 1213340
Proc Headers: 25.0840 12843 26302464
Number of page buffers: 63856
Number of proc buffers: 15964
The Configured Memory does not equal the sum of the individual
components. It does in the sybooks example but in practice it
doesn't always. This is not critical and it is simply being noted
here.
The Kernel Structures and Server structures are of mild interest. They can
be used to cross-check that the pre-allocation is what you believe it to be.
The salient line items are Number of page buffers and Number of proc
buffers.
The Number of proc buffers translates directly to the number of 2K pages
available for the procedure cache.
The Number of page buffers is the number of 2K pages available for the
buffer cache.
As a side note and not trying to muddle things, these last two pieces of
information can also be obtained from the errorlog:
... Number of buffers in buffer cache: 63856.
... Number of proc buffers allocated: 15964.
In our example, we have 15,964 2K pages (~32MB) for the procedure cache and
63,856 2K pages (~126MB) for the buffer cache.
Buffer Cache
The buffer cache contains the data pages that the SQL Server will be either
flushing to disk or transmitting to a user connection.
If this area is too small, the SQL Server must flush 2K pages sooner than
might be necessary to satisfy a user connection's request.
For example, in most database applications there are small edit tables that
are used frequently by the application. These tables will populate the
buffer cache and normally will remain resident during the entire life of the
SQL Server. This is good because a user connection may request validation
and the SQL Server will find the data page(s) resident in memory. If however
there is insufficient memory configured, then these small tables will be
flushed out of the buffer cache in order to satisfy another query. The next
time a validation is requested, the tables will have to be re-read from disk
in order to satisfy the request. Your performance will degrade.
Memory access is easily an order of magnitude faster than performing a
physical I/O.
In this example we know from the previous section that we have 63,856 2K
pages (or buffers) available in the buffer cache. The question to answer is,
"do we have sufficient buffer cache configured?"
The following is the output of the dbcc memusage regarding the buffer cache:
Buffer Cache, Top 20:
DB Id Object Id Index Id 2K Buffers
6 927446498 0 9424
6 507969006 0 7799
6 959446612 0 7563
6 116351649 0 7428
6 2135014687 5 2972
6 607445358 0 2780
6 507969006 2 2334
6 2135014687 0 2047
6 506589013 0 1766
6 1022066847 0 1160
6 116351649 255 987
6 927446498 8 897
6 927446498 10 733
6 959446612 7 722
6 506589013 1 687
6 971918604 0 686
6 116351649 6 387
Index Legend
Value Definition
0 Table data
1 Clustered index
2-250 Nonclustered indexes
255 Text pages
* To translate the DB Id use select db_name(#) to map back to the
database name.
* To translate the Object Id, use the respective database and use the
select object_name(#) command.
It's obvious that the first 10 items take up the largest portion of the
buffer cache. Sum these values and compare the result to the amount of
buffer cache configured.
Summing the 10 items nets a result of 45,263 2K data pages. Comparing that
to the number of pages configured, 63,856, we see that this SQL Server has
sufficient memory configured.
When do I need more Buffer Cache?
I follow the following rules of thumb to determine when I need more buffer
cache:
* If the sum of all the entries reported is equal to the number of pages
configurd and all entries are relatively the same size. Crank it up.
* Note the natural groupings that occur in the example. If the difference
between any of the groups is greater than an order of magnitude I'd be
suspicious. But only if the sum of the larger groups is very close to
the number of pages configured.
Procedure Cache
If the procedure cache is not of sufficient size you may get sporadic 701
errors:
There is insufficient system memory to run this query.
In order to calculate the correct procedure cache one needs to apply the
following formula (found in SQL Server Troubleshooting Guide - Chapter 2,
Procedure Cache Sizing):
proc cache size = max(# of concurrent users) * (size of the
largest plan) * 1.25
The flaw with the above formula is that if 10% of the
users are executing the largest plan, then you'll
overshoot. If you have distinct classes of connections
whose largest plans are mutually exclusive then you need
to account for that:
ttl proc cache = proc cache size * x% + proc
cache size * y% ...
The max(# of concurrent users) is not the number of user connections
configured but rather the actual number of connections during the peak
period.
To compute the size of the largest [query] plan take the results from the
dbcc memusage's, Procedure Cache section and apply the following formula:
query plan size = [size of plans in bytes] / [number of plans]
We can compute the size of the query plan for lp_cm_case_list by using the
output of the dbcc memusage:
...
Database Id: 6
Object Id: 1652357121
Object Name: lp_cm_case_list
Version: 1
Uid: 1
Type: stored procedure
Number of trees: 0
Size of trees: 0.000000 Mb, 0.000000 bytes, 0 pages
Number of plans: 16
Size of plans: 0.323364 Mb, 339072.000000 bytes, 176 pages
----
...
Entering the respective numbers, the query plan size for lp_cm_case_list is
21K:
query plan size = 339072 / 16
query plan size = 21192 bytes or 21K
The formula would be applied to all objects found in the procedure cache and
the largest value would be plugged into the procedure cache size formula:
Query Plan Sizes
Query
Object Plan
Size
lp_cm_case_list 21K
lp_cm_subcase_list 21K
csp_get_case 19K
lp_get_last_caller_new 28K
The size of the largest [query] plan is 28K.
Entering these values into the formula:
proc cache size = max(# of concurrent users) * (size of the
largest plan) * 1.25
proc cache size = 491 connections * 28K * 1.25
proc cache size = 17,185 2K pages required
Our example SQL Server has 15,964 2K pages configured but 17,185 2K pages
are required. This SQL Server can benefit by having more procedure cache
configured.
This can be done one of two ways:
1. If you have some headroom in your buffer cache, then sp_configure
"procedure cache" to increase the ratio of procedure cache to buffer
cache or
procedure cache =
[ proposed procedure cache ] /
( [ current procedure cache ] + [ current buffer cache ]
)
The new procedure cache would be 22%:
procedure cache = 17,185 / ( 15,964 + 63,856 )
procedure cache = .2152 or 22%
2. If the buffer cache cannot be shrunken, then sp_configure "memory" to
increase the total memory:
mem size =
([ proposed procedure cache ]) /
([ current procedure cache ] / [ current configured
memory ])
The new memory size would be 165,399 2K pages, assuming that
the procedure cache is unchanged:
mem size = 17,185 / ( 15,964 / 153,600 )
mem size = 165,399 2K pages
----------------------------------------------------------------------------
Q8.8: WHY SHOULD I USE _STORED PROCEDURES_?
_________________________________________________________________
There are many advantages to using stored procedures (unfortunately
they do not handle the _text/image_ types):
* Security - you can revoke access to the base tables and only allow
users to access and manipulate the data via the stored procedures.
* Performance - stored procedures are parsed and a query plan is
compiled. This information is stored in the system tables and it
only has to be done once.
* Network - if you have users who are on a WAN (slow connection)
having stored procedues will improve throughput because less bytes
need to flow down the wire from the client to the SQL server.
* Tuning - if you have all your SQL code housed in the database,
then it's easy to tune the stored procedure without affecting the
clients (unless of course the parameters change).
* Modularity - during application development, the application
designer can concentrate on the front-end and the DB designer can
concentrate on the SQL Server.
_________________________________________________________________
Q8.9: YOU AND _SHOWPLAN_ OUTPUT
_________________________________________________________________
Microsoft SQL Server includes a very intelligent cost-based query
optimizer which, given an ad-hoc query, can quickly determine the best
access method for retrieving the data, including the order in which to
join tables and whether or not to use indexes that may be on those
tables. By using a cost-based query optimizer, the System
Administrator or end user is released from having to determine the
most efficient way of structuring the query to get optimal performance
-- instead, the optimizer looks at all possible join orders, and the
cost of using each index, and picks the plan with the least cost in
terms of page I/O's.
Detailed information on the final access method that the optimizer
chooses can be displayed for the user by executing the Transact-SQL
"SET SHOWPLAN ON" command. This command will show each step that the
optimizer uses in joining tables and which, if any, indexes it chooses
to be the least-cost method of accessing the data. This can be
extremely beneficial when analyzing certain queries to determine if
the indexes that have been defined on a table are actually being
considered by the optimizer as useful in getting to the data. This
document will define and explain each of the output messages from
SHOWPLAN, and give example queries and the output from SHOWPLAN to
illustrate the point. The format will be consistent throughout: a
heading which corresponds to the exact text of a SHOWPLAN statement,
followed by a description of what it means, a sample query which
generates that particular message, and the full output from executing
the query with the SHOWPLAN option on. Wherever possible, the queries
will use the existing tables and indexes, unaltered, from the SQL
Server "Pubs" sample database.
STEP n
This statement will be included in the SHOWPLAN output for every
query, where n is an integer, beginning with "STEP 1". For some
queries, SQL Server cannot effectively retrieve the results in a
single step, and must break the query plan into several steps. For
example, if a query includes a GROUP BY clause, the query will need to
be broken into at least two steps: one step to select the qualifying
rows from the table, and another step to group them. The following
query demonstrates a singlestep query.
Query: SELECT au_lname, au_fname
FROM Authors
WHERE city = "Oakland"
SHOWPLAN: STEP 1
The type of query is SELECT
FROM TABLE
authors
Nested iteration
Table Scan
The type of query is SELECT (into a worktable)
This SHOWPLAN statement indicates that SQL Server needs to insert some
of the query results into an intermediate worktable, and later in the
query processing will then select the values out of that table. This
is most often seen with a query which involves a GROUP BY clause, as
the results are first put into a work table, and then the qualifying
rows in the work table are grouped based on the given column in the
GROUP BY clause. The following query returns a list of all cities and
indicates the number of authors that live in each city. The query plan
is composed of two steps: the first step selects the rows into a
worktable, and the second step retrieves the grouped rows from the
worktable:
Query: SELECT city, total_authors = count(*)
FROM Authors
GROUP BY city
SHOWPLAN: STEP 1
The type of query is SELECT (into a
worktable)
GROUP BY
Vector Aggregate
FROM TABLE
authors
Nested iteration
Table Scan
TO TABLE
Worktable
STEP 2
The type of query is SELECT
FROM TABLE
Worktable
Nested iteration
Table Scan
The type of query is <query type>
This statement describes the type of query for each step. For most
user queries, the value for <query type> will be SELECT, INSERT,
UPDATE, or DELETE. If SHOWPLAN is turned on while other commands are
issued, the <query type> will reflect the command that was issued. The
following examples show various outputs for different
queries/commands:
Query 1: CREATE TABLE Mytab (col1 int)
SHOWPLAN 1: STEP 1
The type of query is TABCREATE
Query 2: INSERT Publishers
VALUES ("9904", "NewPubs", "Seattle", "WA")
SHOWPLAN 2: STEP 1
The type of query is INSERT
The update mode is direct
Table Scan
TO TABLE
publishers
The update mode is deferred
There are two methods or "modes" that SQL Server can use to perform
update operations such as INSERT, DELETE, UPDATE, and SELECT INTO.
These methods are called deferred update and direct update. When the
deferred method is used, the changes are applied to all rows of the
table by making log records in the transaction log to reflect the old
and new value of the column(s) being modified (in the case of UPDATE
operations), or the values which will be inserted or deleted (in the
case of INSERT and DELETE, respectively). When all of the log records
have been constructed, the changes are then applied to the data pages.
This method generates more log records than a direct update (discussed
later), but it has the advantage of allowing the execution of commands
which may cascade changes throughout a table. For example, consider a
table which has a column "col1" with a unique index on it, and data
values numbered consecutively from 1 to 100 in that column. Assume an
UPDATE statement is executed to increase the value in each row by 1:
Query 1: UPDATE Mytable
SET col1 = col1 + 1
SHOWPLAN 1: STEP 1
The type of query is UPDATE
The update mode is deferred
FROM TABLE
Mytable
Nested iteration
Table Scan
TO TABLE
Mytable
Consider the consequences of starting at the first row in the table,
and updating each row, through the end of the table. Updating the
first row (which has an initial value of 1) to 2 would cause an error,
as the unique index would be violated since there is already a value
of 2 in the table; likewise, updating the second row (which has an
initial value of 2) to 3 would also cause a unique key violation, as
would all rows through the end of the table, except for the last row.
By using deferred updates, this problem is easily avoided. The log
records are first constructed to show what the new values for each row
will be, the existing rows are deleted, and the new values inserted.
Just as with UPDATE commands, INSERT commands may also be deferred for
very similar reasons. Consider the following query (there is no
clustered index or unique index on the "roysched" table):
Query 2: INSERT roysched SELECT * FROM roysched
SHOWPLAN 2: STEP 1
The type of query is INSERT
The update mode is deferred
FROM TABLE
roysched
Nested iteration
Table Scan
TO TABLE
roysched
Since there is no clustered index on the table, the new rows will be
added to the end of the table. The query processor needs to be able to
differentiate between the existing rows that are currently in the
table (prior to the INSERT command) and the rows which will be
inserted, so as to not get into a continuous loop of selecting a row,
inserting it at the end of the table, selecting that row that it just
inserted, and re-inserting it again. By using the deferred method of
inserting, the log records can be first be constructed to show all of
the currently-existing values in the table, then SQL Server will
re-read those log records to insert them into the table.
The update mode is direct
Whenever possible, SQL Server will attempt to use the direct method of
applying updates to tables, since it is faster and requires fewer log
records to be generated than the deferred method. Depending on the
type of command, one or more criteria must be met in order for SQL
Server to perform the update using the direct method. Those criteria
are:
* INSERT: For the direct update method to be used for INSERT
operations, the table into which the rows are being inserted
cannot be a table which is being read from in the same command.
The second query example in the previous section demonstrates
this, where the rows are being inserted into the same table in
which they are being selected from. In addition, if rows are being
inserted into the target table, and one or more of the target
table's columns appear in the WHERE clause of the query then the
deferred method, rather than the direct method, will be used.
* SELECT INTO: When a table is being populated with data by means of
a SELECT INTO command, the direct method will always be used to
insert the new rows.
* DELETE: For the direct update method to be used for DELETE
operations, the query optimizer must be able to determine that
either 0 or 1 rows qualify for the delete. The only means for it
to verify this is to check that there is a unique index on the
table, which is qualified in the WHERE clause of the DELETE
command, and the target table is not joined with any other
table(s).
* UPDATE: For the direct update method to be used for UPDATE
operations, the same criteria apply as for DELETE: a unique index
must exist such that the query optimizer can determine that no
more than 1 row qualifies for the update, and the only table in
the UPDATE command is the target table to update. In addition, all
columns that are being updated must be datatypes that are
fixedlength, rather than variable-length. Note that any column
that allows NULLs is internally stored by SQL Server as a
variable-length datatype column.
Query 1: DELETE
FROM authors
WHERE au_id = "172-32-1176"
SHOWPLAN 1: STEP 1
The type of query is DELETE
The update mode is direct
FROM TABLE
authors
Nested iteration
Using Clustered Index
TO TABLE
authors
Query 2: UPDATE titles
SET type = "popular_comp"
WHERE title_id = "BU2075"
SHOWPLAN 2: STEP 1
The type of query is UPDATE
The update mode is direct
FROM TABLE
titles
Nested iteration
Using Clustered Index
TO TABLE
titles
Query 3: UPDATE titles
SET price = $5.99
WHERE title_id = "BU2075"
SHOWPLAN 3: STEP 1
The type of query is UPDATE
The update mode is deferred
FROM TABLE
titles
Nested iteration
Using Clustered Index
TO TABLE
titles
Note that the only difference between the second and third example
queries is the column of the table which is being updated. In the
second query, the direct update method is used, whereas in the third
query, the deferred method is used. This difference is due to the
datatype of the column being updated: the titles.type column is
defined as "char(12) NOT NULL", while the titles.price column is
defined as "money NULL". Since the titles.price column is not a
fixed-length datatype, the direct method cannot be used.
GROUP BY
This statement appears in the SHOWPLAN output for any query that
contains a GROUP BY clause. Queries that contain a GROUP BY clause
will always be at least two-step queries: one step to select the
qualifying rows into a worktable and group them, and another step to
return the rows from the worktable. The following example illustrates
this:
Query: SELECT type, AVG(advance),
SUM(ytd_sales)
FROM titles
GROUP BY type
SHOWPLAN: STEP 1
The type of query is SELECT (into a
worktable)
GROUP BY
Vector Aggregate
FROM TABLE
titles
Nested iteration
Table Scan
TO TABLE
Worktable
STEP 2
The type of query is SELECT
FROM TABLE
Worktable
Nested iteration
Table Scan
Scalar Aggregate
Transact-SQL includes the aggregate functions:
* AVG()
* COUNT()
* COUNT(*)
* MAX()
* MIN()
* SUM()
Whenever an aggregate function is used in a SELECT statement that does
not include a GROUP BY clause, it produces a single value, regardless
of whether it is operating on all of the rows in a table or on a
subset of the rows defined by a WHERE clause. When an aggregate
function produces a single value, the function is called a "scalar
aggregate", and is listed as such by SHOWPLAN. The following example
shows the use of scalar aggregate functions:
Query: SELECT AVG(advance), SUM(ytd_sales)
FROM titles
WHERE type = "business"
SHOWPLAN: STEP 1
The type of query is SELECT
Scalar Aggregate
FROM TABLE
titles
Nested iteration
Table Scan
STEP 2
The type of query is SELECT
Table Scan
Notice that SHOWPLAN considers this a two-step query, which is very
similar to the SHOWPLAN from the GROUP BY query listed earlier. Since
the query contains a scalar aggregate, which will return a single
value, SQL Server keeps internally a "variable" to store the result of
the aggregate function. It can be thought of as a temporary storage
space to keep a running total of the aggregate function as the
qualifying rows from the table are evaluated. After all rows have been
evaluated from the table (Step 1), the final value from the "variable"
is then selected (Step 2) to return the scalar aggregate result.
Vector Aggregate
When a GROUP BY clause is used in a query which also includes an
aggregate function, the aggregate function produces a value for each
group. These values are called "vector aggregates". The "Vector
Aggregate" statement from SHOWPLAN indicates that the query includes a
vector aggregate. Below is an example query and SHOWPLAN which
includes a vector aggregate:
Query: SELECT title_id, AVG(qty)
FROM sales
GROUP BY title_id
SHOWPLAN: STEP 1
The type of query is SELECT (into a
worktable)
GROUP BY
Vector Aggregate
FROM TABLE
sales
Nested iteration
Table Scan
TO TABLE
Worktable
STEP 2
The type of query is SELECT
FROM TABLE
Worktable
Nested iteration
Table Scan
FROM TABLE
This SHOWPLAN step indicates the table that the query is reading from.
In most queries, the "FROM TABLE" will be followed on the next line by
the name of the table which is being selected from. In other cases, it
may indicate that it is selecting from a worktable (discussed later).
The main importance of examining the table names after the "FROM
TABLE" output is to determine the order in which the query optimizer
is joining the tables. The order of the tables listed after the "FROM
TABLE" statements in the SHOWPLAN output indicate the same order that
the tables were joined; this order may be (and often times is)
different than the order that they are listed in the FROM clause of
the query, or the order that they appear in the WHERE clause of the
query. This is because the query optimizer examines all different join
orders for the tables involved, and picks the join order that will
require the least amount of I/O's.
Query: SELECT authors.au_id, au_fname, au_lname
FROM authors, titleauthor, titles
WHERE authors.au_id = titleauthor.au_id
AND titleauthor.title_id = titles.title_id
AND titles.type = "psychology"
SHOWPLAN: STEP 1
The type of query is SELECT
FROM TABLE
titles
Nested iteration
Table Scan
FROM TABLE
titleauthor
Nested iteration
Table Scan
FROM TABLE
authors
Nested iteration
Table Scan
This query illustrates the order in which the SQL Server query
optimizer chooses to join the tables, which is not the order that they
were listed in the FROM clause or the WHERE clause. By examining the
order of the "FROM TABLE" statements, it can be seen that the
qualifying rows from the titles table are first located (using the
search clause <titles.type = "psychology">). Those rows are then
joined with the titleauthor table (using the join clause
<titleauthor.title_id = titles.title_id>), and finally the titleauthor
table is joined with the authors table to retrieve the desired columns
(using the join clause <authors.au_id = titleauthor.au_id>).
TO TABLE
When a command is issued which makes or attempts to make a
modification to one or more rows of a table, such as INSERT, DELETE,
UPDATE, or SELECT INTO, the "TO TABLE" statement will show the target
table which is being modified. For some operations which require an
intermediate step which inserts rows into a worktable (discussed
later), the "TO TABLE" will indicate that the results are going to the
"Worktable" table, rather than a user table. The following examples
illustrate the use of the "TO TABLE" statement:
Query 1: INSERT sales
VALUES ("8042", "QA973", "7/15/92", 7,
"Net 30", "PC1035")
SHOWPLAN 1: STEP 1
The type of query is INSERT
The update mode is direct
Table Scan
TO TABLE
sales
Query 2: UPDATE publishers
SET city = "Los Angeles"
WHERE pub_id = "1389"
SHOWPLAN 2: STEP 1
The type of query is UPDATE
The update mode is deferred
FROM TABLE
publishers
Nested iteration
Using Clustered Index
TO TABLE
publishers
Notice that the SHOWPLAN for the second query indicates that the
publishers table is used both as the "FROM TABLE" as well as the "TO
TABLE". In the case of UPDATE operations, the optimizer needs to read
the table which contains the row(s) to be updated, resulting in the
"FROM TABLE" statement, and then needs to modify the row(s), resulting
in the "TO TABLE" statement.
Worktable
For some types of queries, such as those that require the results to
be ordered or displayed in groups, the SQL Server query optimizer may
determine that it is necessary to create its own temporary worktable.
The worktable is used to hold the intermediate results of the query,
at which time the result rows can be ordered or grouped, and then the
final results selected from that worktable. When all results have been
returned, the worktable is automatically dropped. The worktables are
always created in the Tempdb database, so it is possible that the
system administrator may have to increase the size of Tempdb to
accomodate that queries which require very large worktables. Since the
query optimizer creates these worktables for its own internal use, the
names of the worktables will not be listed in the tempdb..sysobjects
table.
Worktables will always need to be used when a query contains a GROUP
BY clause. For queries involving ORDER BY, it is possible that the
ordering can be done without the use of the worktable. If there is a
clustered index on the column(s) in the ORDER BY clause, the optimizer
knows that the rows are already stored in sorted order, so a sort in a
worktable is not necessary (although there are exceptions to this,
depending on the sort order which is installed on the server). Since
the data is not stored in sorted order for nonclustered indexes, the
worktable will not be necessary if the cheapest access plan is by
using the nonclustered index. However, if the optimizer determines
that scanning the entire table will require fewer I/Os than using the
nonclustered index, then a worktable will need to be created for the
ordering of the results. The following examples illustrate the use of
worktables:
Query 1: SELECT type, AVG(advance), SUM(ytd_sales)
FROM titles
GROUP BY type
SHOWPLAN 1: STEP 1
The type of query is SELECT (into a
worktable)
GROUP BY
Vector Aggregate
FROM TABLE
titles
Nested iteration
Table Scan
TO TABLE
Worktable
STEP 2
The type of query is SELECT
FROM TABLE
Worktable
Nested iteration
Table Scan
Query 2: SELECT *
FROM authors
ORDER BY au_lname, au_fname
SHOWPLAN 2: STEP 1
The type of query is INSERT
The update mode is direct
Worktable created for ORDER BY
FROM TABLE
authors
Nested iteration
Table Scan
TO TABLE
Worktable
STEP 2
The type of query is SELECT
This step involves sorting
FROM TABLE
Worktable
Using GETSORTED
Table Scan
Query 3: SELECT *
FROM authors
ORDER BY au_id
SHOWPLAN 3: STEP 1
The type of query is SELECT
FROM TABLE
authors
Nested iteration
Table Scan
In the third example above, notice that no worktable was created for
the ORDER BY clause. This is because there is a unique clustered index
on the authors.au_id column, so the data is already stored in sorted
order based on the au_id value, and an additional sort for the ORDER
BY is not necessary. In the second example, there is a composite
nonclustered index on the columns au_lname and au_fname. However,
since the optimizer chose not to use the index, and due to the sort
order on the SQL Server, a worktable needed to be created to
accomodate the sort.
Worktable created for SELECT_INTO
SQL Server's SELECT INTO operation performs two functions: it first
creates a table with the exact same structure as the table being
selected from, and then it insert all rows which meet the WHERE
conditions (if a WHERE clause is used) of the table being selected
from. The "Worktable created for SELECT_INTO" statement is slightly
misleading, in that the "worktable" that it refers to is actually the
new physical table that is created. Unlike other worktables, it is not
dropped when the query finishes executing. In addition, the worktable
is not created in Tempdb, unless the user specifies Tempdb as the
target database for the new table.
Query: SELECT *
INTO seattle_stores
FROM stores
WHERE city = "seattle"
SHOWPLAN: STEP 1
The type of query is TABCREATE
STEP 2
The type of query is INSERT
The update mode is direct
Worktable created for SELECT_INTO
FROM TABLE
stores
Nested iteration
Table Scan
TO TABLE
Worktable
Worktable created for DISTINCT
When a query is issued which includes the DISTINCT keyword, all
duplicate rows are excluded from the results so that only unique rows
are returned. To accomplish this, SQL Server first creates a worktable
to store all of the results of the query, including duplicates, just
as though the DISTINCT keyword was not included. It then sorts the
rows in the worktable, and is able to easily discard the duplicate
rows. Finally, the rows from the worktable are returned, which insures
that no duplicate rows will appear in the output.
Query: SELECT DISTINCT city
FROM authors
SHOWPLAN: STEP 1
The type of query is INSERT
The update mode is direct
Worktable created for DISTINCT
FROM TABLE
authors
FROM TABLE
authors
Nested iteration
Table Scan
TO TABLE
Worktable
STEP 2
The type of query is SELECT
This step involves sorting
FROM TABLE
Worktable
Using GETSORTED
Table Scan
Worktable created for ORDER BY
As discussed previously, queries which include an ORDER BY clause will
often require the use of a temporary worktable. When the optimizer
cannot use an available index for the ordering, it creates a worktable
for use in sorting the result rows prior to returning them. Below is
an example which shows the worktable being created for the ORDER BY
clause:
Query: SELECT *
FROM authors
ORDER BY city
SHOWPLAN: STEP 1
The type of query is INSERT
The update mode is direct
Worktable created for ORDER BY
FROM TABLE
authors
FROM TABLE
authors
Nested iteration
Table Scan
TO TABLE
Worktable
STEP 2
The type of query is SELECT
This step involves sorting
FROM TABLE
Worktable
Using GETSORTED
Table Scan
Worktable created for REFORMATTING
When joining tables, SQL Server may in some cases choose to use a
"reformatting strategy" to join the tables and return the qualifying
rows. This strategy is only considered as a last resort, when the
tables are large and neither table in the join has a useful index to
use. The reformatting strategy inserts the rows from the smaller of
the two tables into a worktable. Then, a clustered index is created on
the worktable, and the clustered index is then used in the join to
retrieve the qualifying rows from each table. The main cost in using
the reformatting strategy is the time and I/Os necessary to build the
clustered index on the worktable; however, that cost is still cheaper
than joining the tables with no index. If user queries are using the
reformatting strategy, it is generally a good idea to examine the
tables involved and create indexes on the columns of the tables which
are being joined. The following example illustrates the reformatting
strategy. Since none of the tables in the Pubs database are large
enough for the optimizer to consider using this strategy, two new
tables are used. Each table has 5 columns defined as "char(200)". Tab1
has 500 rows and Tab2 has 250 rows.
Query: SELECT Tab1.col1
FROM Tab1, Tab2
WHERE Tab1.col1 = Tab2.col1
SHOWPLAN: STEP 1
The type of query is INSERT
The update mode is direct
Worktable created for REFORMATTING
FROM TABLE
Tab2
Nested iteration
Table Scan
TO TABLE
Worktable
STEP 2
The type of query is SELECT
FROM TABLE
Tab1
Nested iteration
Table Scan
FROM TABLE
Worktable
Nested iteration
Using Clustered Index
This step involves sorting
This SHOWPLAN statement indicates that the query must sort the
intermediate results before returning them to the user. Queries that
specify DISTINCT will require an intermediate sort, as well as queries
that have an ORDER BY clause which cannot use an available index. As
stated earlier, the results are put into a worktable, and the
worktable is then sorted. The example on the following page
demontrates a query which requires a sort:
Query: SELECT DISTINCT state
FROM stores
SHOWPLAN: STEP 1
The type of query is INSERT
The update mode is direct
Worktable created for DISTINCT
FROM TABLE
stores
FROM TABLE
stores
Nested iteration
Table Scan
TO TABLE
Worktable
STEP 2
The type of query is SELECT
This step involves sorting
FROM TABLE
Worktable
Using GETSORTED
Table Scan
Using GETSORTED
This statement indicates one of the ways in which the result rows can
be returned from a table. In the case of "Using GETSORTED", the rows
will be returned in sorted order. However, not all queries which
return rows in sorted order will have this step. In the case of a
query which has an ORDER BY clause, and an index with the proper sort
sequence exists on those columns being ordered, an intermediate sort
may not be necessary, and the rows can simply be returned in order by
using the available index. The "Using GETSORTED" method is used when
SQL Server must first create a temporary worktable to sort the result
rows, and then return them in the proper sorted order. The following
example shows a query which requires a worktable to be created and the
rows returned in sorted order:
Query: SELECT au_id, au_lname, au_fname, city
FROM authors
ORDER BY city
SHOWPLAN: STEP 1
The type of query is INSERT
The update mode is direct
Worktable created for ORDER BY
FROM TABLE
authors
FROM TABLE
authors
Nested iteration
Table Scan
TO TABLE
Worktable
STEP 2
The type of query is SELECT
This step involves sorting
FROM TABLE
Worktable
Using GETSORTED
Table Scan
Nested iteration
The "Nested iteration" is the default technique used to join tables
and/or return rows from a table. It simply indicates that the
optimizer is using one or more sets of loops to go through a table and
retrieve a row, qualify the row based on the search criteria given in
the WHERE clause, return the row to the front-end, and loop again to
get the next row. The method in which it gets the rows (such as using
an available index) is discussed later. The following example shows
the optimizer doing nested iterations through each of the tables in
the join:
Query: SELECT title_id, title
FROM titles, publishers
WHERE titles.pub_id = publishers.pub_id
AND publishers.pub_id = '1389'
SHOWPLAN: STEP 1
The type of query is SELECT
FROM TABLE
publishers
Nested iteration
Using Clustered Index
FROM TABLE
titles
Nested iteration
Table Scan
EXISTS TABLE : nested iteration
This SHOWPLAN step is very similar to the previous one of "Nested
iteration". The difference, however, is that this step indicates a
nested iteration on a table which is part of an existence test in a
query. There are several ways an existence test can be written in
Transact-SQL, such as "EXISTS", "IN", or "=ANY". Prior to SQL Server
version 4.2, queries which contained an IN clause followed by a
subquery were treated as table joins. Beginning with version 4.2,
these queries are now treated the same as if they were written with an
EXISTS clause. The following examples demonstrate the SHOWPLAN output
with queries which test for existence of values:
Query 1: SELECT au_lname, au_fname
FROM authors
WHERE EXISTS
(SELECT *
FROM publishers
WHERE authors.city = publishers.city)
SHOWPLAN 1: STEP 1
The type of query is SELECT
FROM TABLE
authors
Nested iteration
Table Scan
FROM TABLE
publishers
EXISTS TABLE : nested iteration
Table Scan
Query 2: SELECT title
FROM titles
WHERE pub_id IN
(SELECT pub_id
FROM publishers
WHERE city LIKE "B%")
SHOWPLAN 2: STEP 1
The type of query is SELECT
FROM TABLE
titles
Nested iteration
Table Scan
FROM TABLE
publishers
EXISTS TABLE : nested iteration
Table Scan
Table Scan
This SHOWPLAN statement indicates which method was used to retrieve
the physical result rows from the given table. When the "table scan"
method is used, the execution begins with the first row in the table;
each row is then retrieved and compared with the conditions in the
WHERE clause, and returned to the front-end if it meets the given
criteria. Regardless of how many rows qualify, every row in the table
must be looked at, so for very large tables, a table scan can be very
costly in terms of page I/Os. If a table has one or more indexes on
it, the query optimizer may still choose to do a table scan instead of
using one of the available indexes if the optimizer determines that
the indexes are too costly or are not useful for the given query. The
following query shows a typical table scan:
Query: SELECT au_lname, au_fname
FROM authors
SHOWPLAN: STEP 1
The type of query is SELECT
FROM TABLE
authors
Nested iteration
Table Scan
Using Clustered Index
This SHOWPLAN statement indicates that the query optimizer chose to
use the clustered index on a table to retrieve the rows. Unlike a
table scan, using an index to retrieve rows does not require the
optimizer to examine every row in the table (unless the WHERE clause
applies to all rows). For queries which return a small percentage of
the rows from a large table, the savings in terms of I/Os of using an
index versus doing a table scan can be very significant. The following
query shows the clustered index being used to retrieve the rows from
the table:
Query: SELECT title_id, title
FROM titles
WHERE title_id LIKE "PS2%"
SHOWPLAN: STEP 1
The type of query is SELECT
FROM TABLE
titles
Nested iteration
Using Clustered Index
Index : <index name>
Like the previous statement with the clustered index, this statement
indicates that the optimizer chose to use an index to retrieve the
rows instead of doing a table scan. The <index namethat follows the
"Index :" label will always be the name of a nonclustered index on the
table. Remember that each table can have no more than one clustered
index, but can have up to 249 nonclustered indexes. The following
query illustrates the use of a nonclustered index to find and return
rows. This query uses the sysobjects table in the master database as
an example, rather than a table in Pubs, since using a nonclustered
index on the Pubs tables is generally more costly in terms of I/O than
a straight table scan, due to the fact that most of the tables are
only 1 page in size.
Query: SELECT *
FROM master..sysobjects
WHERE name = "mytable"
AND uid = 5
SHOWPLAN: STEP 1
The type of query is SELECT
FROM TABLE
master..sysobjects
Nested iteration
Index : ncsysobjects
Using Dynamic Index
This SHOWPLAN statement indicates that the query optimizer has chosen
to build its own index during the execution of the query, for use in
its "OR strategy". Since queries involving OR clauses are generally
not very efficient in terms of being able to quickly access the data,
the SQL Server optimizer may choose to use the OR strategy. When the
OR strategy is used, the optimizer makes several passes through the
table -- one pass for each argument to each OR clause. The results of
each pass are added to a single worktable, and the worktable is then
sorted to remove any duplicate rows. The worktable does not contain
the actual data rows from the table, but rather it contains the row
IDs for the matching rows. The row IDs are simply a combination of the
page number and row number on that page for each of the rows. When the
duplicates have been eliminated, the optimizer considers the worktable
of row IDs to be, essentially, its own index ("Dynamic Index")
pointing to the table's data rows. It can then simply scan through the
worktable, get each row ID, and return the data row from the table
that has that row ID.
The OR strategy is not limited only to queries that contain OR
clauses. When an IN clause is used to list a group of possible values,
SQL Server interprets that the same way as though the query had a
separate equality clause for each of the values in the IN clause. To
illustrate the OR strategy and the use of the Dynamic Index, the
queries will be based on a table with 10,000 unique data rows, a
unique nonclustered index on column "col1", and a unique nonclustered
index on column "col2".
Query 1: SELECT *
FROM Mytable
WHERE col1 = 355
OR col2 = 732
SHOWPLAN 1: STEP 1
The type of query is SELECT
FROM TABLE
Mytable
Nested iteration
Index : col1_idx
FROM TABLE
Mytable
Nested iteration
Index : col2_idx
FROM TABLE
Mytable
Nested iteration
Using Dynamic Index
Query 2: SELECT *
FROM Mytable
WHERE col1 IN (700, 1503, 311)
SHOWPLAN 2: STEP 1
The type of query is SELECT
FROM TABLE
Mytable
Nested iteration
Index : col1_idx
FROM TABLE
Mytable
Nested iteration
Index : col1_idx
FROM TABLE
Mytable
Nested iteration
Index : col1_idx
FROM TABLE
Mytable
Nested iteration
Using Dynamic Index
SQL Server does not always resort to using the OR strategy for every
query that contains OR clauses. The following conditions must be met
before it will choose to use the OR strategy:
* All columns in the OR clause must belong to the same table.
* If any portion of the OR clause requires a table scan (due to lack
of index or poor selectivity of a given index), then a table scan
will be used for the entire query, rather than the OR strategy.
* The decision to use the OR strategy is made after all indexes and
costs are evaluated. If any other access plan is less costly (in
terms of page I/Os), SQL Server will choose to use the plan with
the least cost. In the examples above, if a straight table scan
would result in less page I/Os than using the OR strategy, then
the queries would be processed as a table scan instead of using
the Dynamic Index.
_________________________________________________________________
Q8.10: POOR MAN'S SP_SYSMON
_________________________________________________________________
This is needed for System 10 and Sybase 4.9.2 where there is no
_sp_sysmon_ command available.
Fine tune the _waitfor_ for your application. You may need _TS Role_
-- see Q3.1.
use master
go
dbcc traceon(3604)
dbcc monitor ("clear", "all", "on")
waitfor delay "00:01:00"
dbcc monitor ("sample", "all", "on")
dbcc monitor ("select", "all", "on")
dbcc traceon(8399)
select field_name, group_name, value from sysmonitors
dbcc traceoff(8399)
go
dbcc traceoff(3604)
go
_________________________________________________________________
Q8.11: VIEW MRU-LRU PROCEDURE CACHE CHAIN
_________________________________________________________________
_dbcc procbuf_ gives a listing of the current contents of the
procedure cache. By repeating the process at intervals it is possible
to watch procedures moving dowm the MRU-LRU chain, and so to see how
long procedures remain in cache. The neat thing about this approach is
that you can size your cache according to what is actually happening,
rather than relying on estimates based on assumptions that may not
hold on your site.
To run it:
dbcc traceon(3604)
go
dbcc procbuf
go
If you use sqsh it's a bit easier to grok the output:
dbcc traceon(3604);
dbcc procbuf;|fgrep pbname
See Q8.7 regarding procedure cache sizing.
_________________________________________________________________
Q8.12: IMPROVING TEXT/IMAGE TYPE PERFORMANCE
_________________________________________________________________
If you know that you are going to be using a text/insert column
immediately, insert the row setting the column to a non-null value.
There's a noticeable performance gain.
Unfortunately, text and image datatypes cannot be passed as parameters
to stored procedures. The address of the text or image location must
be created and returned where it is then manipulated by the calling
code. This means that transactions involving both text and image
fields and stored procedures are not atomic. However, the datatypes
can still be declared as _not null_ in the table definition.
Given this example -
create table key_n_text
(
key int not null,
notes text not null
)
This stored procedure can be used -
create procedure sp_insert_key_n_text
@key int,
@textptr varbinary(16) output
as
/*
** Generate a valid text pointer for WRITETEXT by inserting an
** empty string in the text field.
*/
insert key_n_text
(
key,
notes
)
values
(
@key,
""
)
select @textptr = textptr(notes)
from key_n_text
where key = @key
return 0
go
The return parameter is then used by the calling code to update the
text field, via the dbwritetext() function if using DB-Library for
example.
_________________________________________________________________
Sybase Frequently Asked Questions supported by Silicon Graphics
_Adaptive Server Enterprise FAQ, version 11.5.12 released 7/31/98_
_________________________________________________________________
Keyword and Phrase Search
Enter search words/phrases: ____________________ ___ Ignore case?
Help!
_________________________________________________________________
Index of Sections
_/usr/sybase/sys.config/{start,stop}.sybase_
start.sybase
#!/bin/sh -a
exit 0
stop.sybase
#!/bin/sh
exit 0
#!/bin/sh
_________________________________________________________________
----------------------------------------------------------------------------
----------------------------------------------------------------------------
Trace Flags
Flag Description
303 Display OR strategy
319 Reformatting strategies.
1206 Disable lock promotion.
3500 Disable checkpointing.
4020 Boot without recover.
----------------------------------------------------------------------------
engine 0, start SQL Server with the 5101 Trace Flag.
Your errorlog will indicate the use of this option with the message:
Disk I/O affinitied to engine: 0
This trace flag only provides performance gains for servers with 3 or
more dataserver engines configured and being significantly utilized.
_Use of this trace flag with fully symmetric operating systems will
degrade performance!_
5102
The 5102 trace flag prevents engine 0 from running any non-affinitied
tasks. Normally, this forces engine 0 to perform Network I/O only.
Applications with heavy result set requirements (either large results
or many connections issuing short, fast requests) may benefit. This
effectively eliminates the normal latency for engine 0 to complete
running its user thread before it issues the network I/O to the
underlying network transport driver. If used in conjuction with the
5101 trace flag, engine 0 would perform all Disk I/O and Network I/O.
For environments with heavy disk and network I/O, engine 0 could
easily saturate when only the 5101 flag is in use. This flag allows
engine 0 to concentrate on I/O by not allowing it to run user tasks.
To force task affinity off engine 0, start SQL Server with the 5102
Trace Flag.
Your errorlog will indicate the use of this option with the message:
I/O only enabled for engine: 0
1> sp_dropsegment "logsegment", tempdb, masines and not per engine value.
cnblkmax:
cnmaxaio_engine:
cnmaxaio_server:
csiocnt:
not used.
cnbytio:
cindextrips:
coamtrips:
cpreallocext:
cbufwashsize:
----------------------------------------------------------------------------
Overview
10 has some significant improvements over Sybase 4.x producct all that
+ Managing audit logs
+ Devices
Create (or use) a directory for symbiseconds per task.
cfgpss:
cfgxdes:
cfgbuf:
cnproc:
cnmemmap:
cnmbox:
dump transaction my_stinking_db to logdump_for_my_db
go
The SQL Server will write to the dumpdevice all transactions that have been
committed to disk and will delete the entries from its copy, thus freeing up
space in the log. Dumping of the transaction logs is accomplished via cron.
We schedule the heavily hit databases every 20 minutes during peak times.
A single user can fill up the log by having begin transaction with
no corresponding commit/rollback transaction. This is because all
their changes are being applied to the log as an open-ended
transaction, which is never closed. This open-ended transaction
cannot be flushed from the log, and therefore grows until it
occupies all of the free space on the log device.
And the way we dump it is with a dump device. :-)
An Example
If the DBA has four databases to plop on this SQL Server and they need a
total of 800MB of data and 100MB of log (because that's what really matters
to us), then they'd probably do something like this:
1. allocate sufficient raw devices to cover the data portion of all the
databases
2. allocate sufficient raw devices to cover the log portion of all the
databases
Database
Requirements
DB Data Log
a 300 30
b 400 40
c 100 10
Logical Physical Size
dks3d1s2_data /dev/rdsk/dks3d1s2 500
dks4d1s2_data /dev/rdsk/dks4d1s2 500
dks5d1s0_log /dev/rdsk/dks5d1s0 200
TempDB
Port Numbers
of the questions are _multiple choice_, some are _seleou'll
need extra CPU capacity to allow bdflush() to write the dirty data out
to disk... eventually... but with everything there's a cost: extra
memory and free CPU cycles.
One argument is that instead of giving the O/S the extra memory (by
leaving it free) to give it to the SQL Server and let it do its
caching... but that's a different thread...
Data Integrity and Cooked File System
If the Sybase SQL Server is _not_ certified to be used over a cooked
file system, because of the nature of the kernel buffering (see the
section above) you may face database corruption by using cooked file
system anyway. The SQL Server _thinks_ that it has posted its changes
out to disk but in reality it has gone only to memory. If the machine
halts without bdflush() having a chance to flush memory out to disk,
your database _may_ become corrupted.
Some O/S's allow cooked files to have a _write through_ mode and it
really depends if the SQL Server has been certified on cooked file
systems. If it has, it means that when the SQL Server opens a device
which is on a file system, it fcntl()'s the device to write-through.
When to use cooked file system?
I typically build my tempdb on cooked file system and I don't worry
about data integrity because tempdb is _rebuilt_ everytime your SQL
Server is rebooted.
_________________________________________________________________
-----------
_some number_
2> go
1> reconfigure with override /* for system 10 and below */
2> go
1> begin tran
2> go
_/* Save the following status to be used later... */_
1> select _saved_status_=status from sysdatabases where name = "_your_database_
"
2> go
1> update sysdatabases set status = -32768 where name = "_your_database_"
2> go
1> commit tran
2> go
1> shutdown
2> go
1> dbcc rebuild_log (_your_database_, 0, 0)
2> go
DB-LIBRARY error (severity 9):
Unexpected EOF from SQL Server.
1> dbcc rebuild_log (_your_database_, 1, 1)
2> go
DBCC execution completed. If DBCC printed error messages, see your System
Administrator.
1> use _your_database_
2> go
1> select count(*) from syslogs
2> go
-----------
1
1> begin tran
2> go
1> update sysdatabases set status = _saved_status_ where name = "_your_database_
"
2> go
(1 row affected)
1> commit tran
2> go
1> shutdown
2> go
#!/bin/sh
Script #2
#!/bin/sh
umask 077
cat
Script #3
#!/bin/sh
umask 077
cat
Script #3
Script #4
Script #5
Script #6
_Global File_
SYBASE=/usr/sybase
return 0
}
Generic Script
#!/bin/sh -a
DSQUERY=$1
_______________________________________________________________
#!/bin/sh
PASSWD=yuk
DSQUERY=GNARLY_HAIRBALL
Q2.1: CHANGING VARCHAR(M) TO VARCHAR(N)
_________________________________________________________________
Before you start:
select max(datalength(column_name)) from _affected_table_
In other words, _please_ be sure you're going into this with your head
on straight.
How To Change System Catalogs
This information is _Critical To The Defense Of The Free World_, and
you would be _Well Advised To Do It Exactly As Specified_:
use master
go
sp_configure "allow updates", 1
_________________________________________________________________
Q2.2: FAQ ON PARTITIONING
_________________________________________________________________
Index of Sections
2. Write _db_id_ down.
begin transaction
go
7. Just do it!
commit transaction
go
_________________________________________________________________
employee:
employee:
id identity
ssn char(09)
we'd do this:
sp_configure "allow updates", 1
_________________________________________________________________
Interpretation
Task Reason Period
----------------------------------------------------------------------------
automatically inherit the correct permissions - administration is
*much* simpler.
Objects and Permissions
sp_configure "allow updates", 1
_________________________________________________________________
begin tran
commit tran
tx #2
_________________________________________________________________
_________________________________________________________________
Any of the following will result in a stored procedure to grow when it
is recompiled:
1. One of the tables used in the procedure is dropped and re-created.
2. A new rule or default is bound to one of the tables or the user
runs sp_recompile on one of the tables.
3. The database containing the stored procedure is re-loaded.
Other things causing a stored procedure to be re-compiled will not
cause it to grow. For example, dropping an index on one of the tables
used in the procedure or doing EXEC WITH RECOMPILE.
The difference is between simple recompilation and re-resolution.
Re-resolution happens when one of the tables changes in such a way
that the query trees stored in sysprocedures may be invalid. The
datatypes, column offsets, object ids or other parts of the tree may
change. In this case, the server must re-allocate some of the query
tree nodes. The old nodes are not de-allocated (there is no way to do
this within a single procedure header), so the procedure grows. In
time, trying to execute the stored procedure will result in a 703
error about exceeding the 64 page limit for a query.
_________________________________________________________________
do the following:
declare @val char(20)
select @val = 'grand'
_________________________________________________________________
declare @Integer int
select @Integer = 1000
go
Produces the following results:
Positives Only
--------------
000000001000
Both Signs
-------------
-000000001000
Both Signs
-------------
+000000001000
_________________________________________________________________
_________________________________________________________________
Jan = 7, June = 12 )
Method #1
select ... ((sign(sign((datepart(month,GetDate())-6) * -1)+1) *
Method #1
__________________________________________________________________________
2> go
1> reconfigure with override
2> go
(return status = 1)
_________________________________________________________________
(8 rows affected)
5> go
1> commit tran
2> go
This method is rather inefficient, as large tables will take minutes
4> go
1> commit tran
2> go
_BEGIN TRAN_
Your errorlog will indicate the use of this option with the
message:
New
return
go
select ... from my_table(3)
Overview
Preface
Definitions
Available Cache
Your pal: dbcc memusage
Meg. 2K Blks Bytes
Buffer Cache, Top 20:
Procedure Cache, Top 20:
Dissecting memusage output
Memory Usage
Memory Usage:
Meg. 2K Blks Bytes
Buffer Cache
Buffer Cache, Top 20:
Index Legend
Value Definition
0 Table data
1 Clustered index
2-250 Nonclustered indexes
255 Text pages
Procedure Cache
Query Plan Sizes
Query
Object Plan
Size
lp_cm_case_list 21K
lp_cm_subcase_list 21K
csp_get_case 19K
lp_get_last_caller_new 28K
----------------------------------------------------------------------------
_________________________________________________________________
return 0
go
Q9.1: SP_FREEDEVICE
_________________________________________________________________
use master
go
drop proc sp_freedevice
go
create proc sp_freedevice
@devname char(30) = null
as begin
declare @showdev bit
declare @alloc int
if @devname = null
select @devname = "%"
, @showdev = 0
else
select @showdev = 1
select @alloc = low
from master.dbo.spt_values
where type = "E"
and number = 1
create table #freedev
(name char(30),
size float,
used float)
insert #freedev
select dev.name,
((dev.high - dev.low) * @alloc + 500000) / 1048576,
sum((usg.size * @alloc + 500000) / 1048576)
from master.dbo.sysdevices dev, master.dbo.sysusages usg
where dev.low <= usg.size + usg.vstart - 1
and dev.high >= usg.size + usg.vstart - 1
and dev.cntrltype = 0
group by dev.name
insert #freedev
select name,
((high - low) * @alloc + 500000) / 1048576,
0
from master.dbo.sysdevices
where cntrltype = 0
and not exists (select * from #freedev
where name = master.dbo.sysdevices.name)
if @showdev = 1 begin
select
devname = dev.name,
size = convert(varchar(10),f.size) + " MB",
used = convert(varchar(10),f.used) + " MB",
free = convert(varchar(10),f.size - f.used) + " MB"
from master.dbo.sysdevices dev, #freedev f
where dev.name = f.name
and dev.name like @devname
select
dbase = db.name,
size = convert(varchar(10),((usg.size * @alloc)
+ 500000) / 1048576) + " MB",
usage = vl.name
from master.dbo.sysdatabases db,
master.dbo.sysusages usg,
master.dbo.sysdevices dev,
master.dbo.spt_values vl
where db.dbid = usg.dbid
and usg.segmap = vl.number
and dev.low <= usg.size + usg.vstart - 1
and dev.high >= usg.size + usg.vstart - 1
and dev.status & 2 = 2
and vl.type = "S"
and dev.name = @devname
end
else
begin
select total = convert(varchar(10), sum(size)) + " MB",
used = convert(varchar(10), sum(used)) + " MB",
free = convert(varchar(10), sum(size) - sum(used)) + " MB"
from #freedev
select devname = dev.name,
size = convert(varchar(10),f.size) + " MB",
used = convert(varchar(10),f.used) + " MB",
free = convert(varchar(10),f.size - f.used) + " MB"
from master.dbo.sysdevices dev, #freedev f
where dev.name = f.name
end
end
go
grant execute on sp_freedevice to public
go
_________________________________________________________________
Q9.2: SP_WHODO
_________________________________________________________________
Sybase System 10.x
use master
go
drop procedure sp_whodo
go
create procedure sp_whodo @loginame varchar(30) = NULL as
declare @low int
declare @high int
declare @spidlow int
declare @spidhigh int
select @low = 0, @high = 32767, @spidlow = 0, @spidhigh = 32767
if @loginame is not NULL
begin
select @low = suser_id(@loginame), @high = suser_id(@loginame)
if @low is NULL
begin
if @loginame like "[0-9]%"
begin
select @spidlow = convert(int, @loginame),
@spidhigh = convert(int, @loginame),
@low = 0, @high = 32767
end
else
begin
print "No login exists with the supplied name."
return (1)
end
end
end
select
spid,
status,
substring(suser_name(suid),1,12) loginame,
hostname,
convert(char(3),blocked) blk,
convert(char(7),isnull(time_blocked, 0)) blk_sec,
convert(char(16),program_name) program,
convert(char(7),db_name(dbid)) dbname,
convert(char(16),cmd) cmd,
convert(char(6),cpu) cpu,
convert(char(7),physical_io) io,
convert(char(16),isnull(tran_name, "")) tran_name
from master..sysprocesses
where suid >= @low and suid <= @high
and spid >= @spidlow and spid <= @spidhigh
return (0)
go
grant execute on sp_whodo to public
go
Sybase 4.x
use master
go
drop procedure sp_whodo
go
create procedure sp_whodo @loginame varchar(30) = NULL as
declare @low int
declare @high int
declare @spidlow int
declare @spidhigh int
select @low = 0, @high = 32767, @spidlow = 0, @spidhigh = 32767
if @loginame is not NULL
begin
select @low = suser_id(@loginame), @high = suser_id(@loginame)
if @low is NULL
begin
if @loginame like "[0-9]%"
begin
select @spidlow = convert(int, @loginame),
@spidhigh = convert(int, @loginame),
@low = 0, @high = 32767
end
else
begin
print "No login exists with the supplied name."
return (1)
end
end
end
select
spid,
status,
substring(suser_name(suid),1,12) loginame,
hostname,
convert(char(3),blocked) blk,
convert(char(16),program_name) program,
convert(char(7),db_name(dbid)) dbname,
convert(char(16),cmd) cmd,
convert(char(6),cpu) cpu,
convert(char(7),physical_io) io
from master..sysprocesses
where suid >= @low and suid <= @high
and spid >= @spidlow and spid <= @spidhigh
return (0)
go
grant execute on sp_whodo to public
go
_________________________________________________________________
Q9.3: GENERATING DUMP/LOAD DATABASE COMMAND.
_________________________________________________________________
#!/bin/sh
#
# This script calls the function gen_dumpload_command to generate
# either a dump or a load command.
#
# This function works for both System 10 and Sybase 4.x
# installations. You simply need to change your method of thinking.
# In Sybase 4.x, we only had a single stripe. In System 10, most
# of the time we define a single stripe but in our bigger databases
# we define more stripes.
#
# Therefore, everything is a stripe. Whether we use one stripe or
# many... cool? Right on!
#
#
# The function gen_dumpload_command assumes that all dump devices
# adhere to the following naming convention:
#
# stripe_NN_database
#
# NOTE: If your shop is different search for "stripe" and replace
# with your shop's value.
#
#
# gen_dumpload_command():
#
# purpose: to generate a dump/load to/from command based on
# what is defined in sysdevices. The environment
# variable D_DEV is set.
#
# return: zero on success, non-zero on failure.
#
# sets var: D_DEV is set with the actual dump/load command;
# stripe devices are also handled.
#
# calls: *none*
#
# parms: 1 = DSQUERY
# 2 = PASSWD
# 3 = DB
# 4 = CMD -> "dump" or "load"
#
gen_dumpload_command()
{
LOCAL_DSQUERY=$1
LOCAL_PASSWD=$2
DB_TO_AFFECT=$3
CMD=$4 # dump/load
if [ "$CMD" = "dump" ] ; then
VIA="to"
else
VIA="from"
fi
# Check for a dump device
echo "Checking for standard $CMD device"
D_DEV=`echo "$LOCAL_PASSWD
select name from sysdevices where name like \"stripe%_$DB_TO_AFFECT\"
go" | $SYBIN/isql -U sa -S $LOCAL_DSQUERY -w1000 | sed -n -e '/stripe/p' | \
nawk '{ if (NR == 1) print "'$CMD' database '$DB_TO_AFFECT' '$VIA'", $0
else print "stripe on", $0
}'`
if [ -z "$D_DEV" ] ; then # nothing defined... :(
return 1
fi
return 0
}
SYBIN=$SYBASE/bin
gen_dumpload_command MAG_LOAD_2 thissux wcid "dump"
if [ $? -eq 1 ] ; then
echo "Error..."
fi
# so what does this generate? :-)
echo $D_DEV
# ... and it can be used as follows:
echo "$PASSWD
$D_DEV
go" | isql ....
exit 0
_________________________________________________________________
Q9.4: SYBPERL FAQ
_This is Michael Peppler's mpep...@bix.com FAQ._
_________________________________________________________________
http://www.mbay.net/~mpeppler/Sybperl/sybperl-faq.html
_________________________________________________________________
Q9.5: DBSCHEMA.PL
_________________________________________________________________
In order to use this script you must have Sybperl installed -- see
Q9.4 for more information.
#!/usr/local/bin/perl -w
#
# @(#)dbschema.pl 1.16 04/09/97
#
# dbschema.pl A script to extract a database structure from
# a Sybase database
#
# Written by: Michael Peppler (mpep...@itf.ch)
# Substantially rewritten by David Whitmarsh from a partial
# System 10 implementation by Ashu Joglekar
# Last Mods: 9 April 1997
#
# Usage: dbschema.pl -d database -o script.name -t pattern -s server -v
# where database is self-explanatory (default: master)
# script.name is the output file (default: script.isq
l)
# pattern is the pattern of object names (in sysobjec
ts)
# that we will look at (default: %), and server is
# the server to connect to (default, the value of $EN
V{DSQUERY}).
#
# -v turns on a verbose switch.
#
# Changes: 11/18/93 - bpapp - Put in interactive SA password prompt
# 11/18/93 - bpapp - Get protection information for views and
# stored procedures.
# 02/22/94 - mpeppler - Merge bpapp's changes with itf version'
# 09/15/94 - mpeppler - Minor changes for use with Sybperl2
# alpha1
# 13/10/95 - Ashu Joglekar - System 10 w/o RI
# 11/11/96 - David Whitmarsh -
# Use Sybase::DBlib
# System 10 declarative RI
# constraints
# Eliminate key truncation problems
# Optional password command line
# Debugged and strictified
# Some index/key options
# 17/2/97 - Michael Peppler
# Fixed small ',' problem in printKeys()
# 11/3/97 - David Whitmarsh
# bug handling user defined types used as
# identity columns.
# addtype now has scale, prec
# removed spurious addtypes for nchar etc.
# null/not null/identity on types
# 12/3/97 - Michael Peppler
# Added -i switch to set an alternate interfaces
# file.
#
# If anyone knows a way to distinguish between key and reference
# declarations made at column and table level, let me know.
#------------------------------------------------------------------------------
use strict;
use Sybase::DBlib;
use Getopt::Std;
require 'ctime.pl';
sub getPerms;
sub getObj;
sub printKeys;
sub getComment;
sub PrintCols;
sub DumpTable;
my ($dbproc, @dat, $dat, $udflt, $urule, %udflt, %urule, %tables, @tabnames, @c
ol);
my ($rule, $dflt, $date, $name);
select (STDOUT); $| = 1; # make unbuffered
getopts ('u:p:d:t:o:s:i:v');
$Getopt::Std::opt_u = `whoami` unless $Getopt::Std::opt_u;
$Getopt::Std::opt_d = 'master' unless $Getopt::Std::opt_d;
$Getopt::Std::opt_o = 'script.isql' unless $Getopt::Std::opt_o;
$Getopt::Std::opt_t = '%' unless $Getopt::Std::opt_t;
$Getopt::Std::opt_s = $ENV{DSQUERY} unless $Getopt::Std::opt_s;
open(SCRIPT, "> $Getopt::Std::opt_o") || die "Can't open $Getopt::Std::opt_o: $
!\n";
open(LOG, "> $Getopt::Std::opt_o.log") || die "Can't open $Getopt::Std::opt_o.l
og: $!\n";
#
# Log us in to Sybase as '$Getopt::Std::opt_u' and prompt for password.
#
if (!$Getopt::Std::opt_p) {
print "\nPassword: ";
system("stty -echo");
chop($Getopt::Std::opt_p =
); system("stty echo"); } if($Getopt::Std::opt_i) {
dbsetifile($Getopt::Std::opt_i); } $dbproc = new Sybase::DBlib
("$Getopt::Std::opt_u", $Getopt::Std::opt_p, $Getopt::Std::opt_s);
$dbproc->dbuse ($Getopt::Std::opt_d); # # Just in case you compiled
with dbNullIsUndef defaulting to FALSE # (Are you reading this, Ashu?)
# $dbproc->{"dbNullIsUndef"} = TRUE; $date = scalar(localtime); print
"dbschema.pl on Database $Getopt::Std::opt_d\n"; print LOG "Error log
from dbschema.pl on Database $Getopt::Std::opt_d on $date\n\n"; print
LOG "The following objects cannot be reliably created from the script
in $Getopt::Std::opt_o. Please correct the script to remove any
inconsistencies.\n\n"; print SCRIPT "/* This Isql script was generated
by dbschema.pl on $date. */\n"; print SCRIPT "\nuse
$Getopt::Std::opt_d\ngo\n"; # Change to the appropriate database #
first, Add the appropriate user data types: # print "Add user-defined
data types..."; print SCRIPT "/* Add user-defined data types: */\n\n";
$dbproc->dbcmd ( 100 and st.usertype dbsqlexec; $dbproc->dbresults;
while((@dat = $dbproc->dbnextrow)) { print SCRIPT "sp_addtype $dat[1],
"; ($dat[2] =~ /char|binary/ and print SCRIPT "'$dat[2]($dat[0])'") or
($dat[2] =~ /numeric|decimal/ and print SCRIPT
"'$dat[2]($dat[5],$dat[6])'") or print SCRIPT "$dat[2]"; (($dat[8] ==
1) and print SCRIPT ", 'identity'") or (($dat[7] == 1) and print
SCRIPT ", 'null'") or print SCRIPT ", 'not null'"; print SCRIPT
"\ngo\n"; # Now remember the default & rule for later. $urule{$dat[1]}
= $dat[4] if defined($dat[4]); $udflt{$dat[1]} = $dat[3] if
defined($dat[3]); } print "Done\n"; print "Create rules..."; print
SCRIPT "\n/* Now we add the rules... */\n\n"; getObj('Rule', 'R');
print "Done\n"; print "Create defaults..."; print SCRIPT "\n/* Now we
add the defaults... */\n\n"; getObj('Default', 'D'); print "Done\n";
print "Bind rules & defaults to user data types..."; print SCRIPT "/*
Bind rules & defaults to user data types... */\n\n"; while(($dat,
$dflt)=each(%udflt)) { print SCRIPT "sp_bindefault $dflt, $dat\ngo\n";
} while(($dat, $rule) = each(%urule)) { print SCRIPT "sp_bindrule
$rule, $dat\ngo\n"; } print "Done\n"; print "Create Tables &
Indices..."; print "\n" if $Getopt::Std::opt_v; # the fourth column
set to 'N' becomes the indicator that this table has been # printed
$dbproc->dbcmd (dbsqlexec; $dbproc->dbresults; while((@dat =
$dbproc->dbnextrow)) { $tables{@dat[1] . "." . @dat[0]} = [ @dat ];
@tabnames = ( @tabnames, @dat[1] . "." . @dat[0] ); } foreach $name
(@tabnames) { DumpTable ($tables{$name}, ()); } print "Done\n"; # #
The key definitions - sp_primarykey etc, not constraints # Primary
keys first, then foreign and common # printKeys (); # # Now create any
views that might exist # print "Create views..."; print SCRIPT "\n/*
Now we add the views... */\n\n"; getObj('View', 'V'); print "Done\n";
# # Now create any stored procs that might exist # print "Create
stored procs..."; print SCRIPT "\n/* Now we add the stored
procedures... */\n\n"; getObj('Stored Proc', 'P'); print "Done\n"; # #
Now create the triggers # print "Create triggers..."; print SCRIPT
"\n/* Now we add the triggers... */\n\n"; getObj('Trigger', 'TR');
print "Done\n"; print "\nLooks like I'm all done!\n"; close(SCRIPT);
close(LOG); dbexit; sub getPerms { my ($obj) = $_[0]; my ($ret, @dat,
$act, $cnt); $dbproc->dbcmd ("sp_helprotect '$obj'\n");
$dbproc->dbsqlexec; $cnt = 0; while(($ret = $dbproc->dbresults) !=
NO_MORE_RESULTS && $ret != FAIL) { while(@dat = $dbproc->dbnextrow) {
$act = 'to'; $act = 'from' if $dat[0] =~ /Revoke/; print SCRIPT
"$dat[2] $dat[3] on $obj $act $dat[1]\n"; ++$cnt; } } $cnt; } sub
getObj { my ($objname, $obj) = @_; my (@dat, @items, @vi, $found,
$text); $dbproc->dbcmd (dbsqlexec; $dbproc->dbresults; while((@dat =
$dbproc->dbnextrow)) { push (@items, [ @dat ]); # and save it in a
list } foreach (@items) { @vi = @$_; $found = 0; $dbproc->dbcmd
("select text from dbo.syscomments where id = $vi[2]");
$dbproc->dbsqlexec; $dbproc->dbresults; print SCRIPT "/* $objname
$vi[0], owner $vi[1] */\n"; while(($text) = $dbproc->dbnextrow) {
if(!$found && $vi[1] ne 'dbo') { ++$found if($text =~ /$vi[1]/); }
print SCRIPT $text; } print SCRIPT "\ngo\n"; if(!$found && $vi[1] ne
'dbo') { print "**Warning**\n$objname $vi[0] has owner $vi[1]\nbut
this is not mentioned in the CREATE PROC statement!!\n"; print LOG
"$objname $vi[0] (owner $vi[1])\n"; } if ($obj eq 'V' || $obj eq 'P')
{ getPerms("$vi[0]") && print SCRIPT "go\n"; } } } sub printKeys {
print "Create sp_*key definitions..."; print SCRIPT "\n/* Now create
the key definitions ...*/\n\n"; $dbproc->dbcmd (dbsqlexec;
$dbproc->dbresults; while((@dat = $dbproc->dbnextrow)) { if ($dat[0]
eq "primary") { print SCRIPT "sp_primarykey $dat[1],"; PrintCols
(@dat[3..10]); print SCRIPT "\ngo\n"; } if ($dat[0] eq "foreign") {
print SCRIPT "sp_foreignkey $dat[1], $dat[2],"; PrintCols
(@dat[11..18]); print SCRIPT "\ngo\n"; } if ($dat[0] eq "common") {
print SCRIPT "sp_commonkey $dat[1], $dat[2],"; PrintCols
(@dat[3..10]); print SCRIPT "\ngo\n"; } } print "done\n" } sub
getComment { my ($objid) = @_; my ($line, $text); $dbproc->dbcmd (
qq(select text from dbo.syscomments where id = $objid));
$dbproc->dbsqlexec; $dbproc->dbresults; $text = ""; while(($line) =
$dbproc->dbnextrow) { $text = $text . $line; } return $text; } sub
PrintCols { my ($col, $first); $first = 1; while ($col = shift (@_)) {
last if ($col eq '*'); print SCRIPT ", " if !$first; $first = 0; print
SCRIPT "$col"; } } # Note: this is a recursive subroutine. # If the
current table references another that is in the list of # tables to be
dumped, and if that table has not yet been dumped, # then DumpTable is
called to dump it before proceeding sub DumpTable { my ($tabref,
@referers) = @_; return if @$tabref[3] eq "Y"; my @nul = ('not
null','null'); my (@dat, $dat, @col); my (@refcols, @reflist, @field,
$rule, $dflt, %rule, %dflt, $ddlrule, $ddldflt); my ($refname, $first,
$matchstring, $field, @constrids, $constrid); my ($frgntabref); my
($nultype); # first, get any reference and ensure that dependent
tables have already been # created $dbproc->dbcmd (dbsqlexec;
$dbproc->dbresults; while((@refcols = $dbproc->dbnextrow)) { push
(@reflist, [ @refcols ]); } foreach (@reflist) { @refcols = @$_; # if
the foreign table is in a foreign database or is not in # our table
list, then don't do any more than add it to the list next if
$refcols[0] ne $Getopt::Std::opt_d; $refname = $refcols[3] . "." .
$refcols[2]; next if not defined ($tables{$refname}); $frgntabref =
$tables{$refname}; # otherwise check if it's already been dumped, if
so, continue next if @$frgntabref[3] eq "Y"; # make sure we aren't in
a refernce loop by checking to see if this table is # already in the
heirarchy of refering tables that led to the current invocation grep
($refname, @referers) && print SCRIPT "/* WARNING: circular foreign
key reference to $refname */\n" && print LOG "@$tabref[1].@$tabref[0]
in circular foreign key reference to $refname\n"; # so dump the
referenced tables first DumpTable ($frgntabref, @referers, $refname);
} print "Creating table @$tabref[0], owner @$tabref[1]\n" if
$Getopt::Std::opt_v; print SCRIPT "/* Start of description of table
@$tabref[1].@$tabref[0] */\n\n"; $dbproc->dbcmd (dbsqlexec;
$dbproc->dbresults; undef(%rule); undef(%dflt); print SCRIPT
"\n\nCREATE TABLE @$tabref[1].@$tabref[0] (\n"; $first = 1; @col = ();
while (@field = $dbproc->dbnextrow) { push @col, [ @field ]; } foreach
(@col) { @field = @$_; print SCRIPT ",\n" if !$first; # add a , and a
\n if not first field in table # get the declarative rule and default
(if set) if ($field[9] != 0) { $ddldflt = getComment ($field[11]); }
else { $ddldflt = ""; } if ($field[10] != 0) { $ddlrule = getComment
($field[12]); } else { $ddlrule = ""; } # Check if its an identity
column if ($field[8] == 1) { $nultype = "identity"; } else { $nultype
= $nul[$field[5]]; } print SCRIPT "\t$field[0] \t$field[1]"; print
SCRIPT "($field[2])" if $field[1] =~ /char|bin/; print SCRIPT
"($field[3],$field[4])" if $field[1] =~ /numeric|decimal/; print
SCRIPT " $ddldflt $nultype $ddlrule"; if (defined ($field[7]) &&
((!defined ($urule{$field[1]})) || $urule{$field[1]} ne $field[7]) &&
($field[10] == 0)) { $rule{"@$tabref[0].$field[0]"} = $field[7]; } if
(defined ($field[6]) && ((!defined ($udflt{$field[1]})) ||
$udflt{$field[1]} ne $field[6]) && ($field[9] == 0)) {
$dflt{"@$tabref[0].$field[0]"} = $field[6]; } $first = 0 if $first; }
# references foreach (@reflist) { @refcols = @$_; print SCRIPT ",";
$refname = $refcols[3] . "." . $refcols[2]; if ($refcols[0] ne
$Getopt::Std::opt_d) { print SCRIPT "\n/* The following reference is
in database ** $refcols[0], edit the script to create the reference
manually "; print LOG "Reference for @$tabref[1].@$tabref[0] in
foreign database\n\t"; $refname = $refcols[0] . "." . $refname; }
print SCRIPT "\n\t"; $matchstring = substr($refcols[1], 0, 8) .
"[_0-9][_0-9]*"; $refcols[1] !~ /$matchstring/ && print SCRIPT
"CONSTRAINT $refcols[1] "; print SCRIPT "FOREIGN KEY ("; PrintCols
(@refcols[4..19]); print SCRIPT ") REFERENCES $refname ("; PrintCols
(@refcols[20..35]); print SCRIPT ")"; if ($refcols[0] ne
$Getopt::Std::opt_d) { print SCRIPT "*/"; } } # now get the indexes
and keys... # print "Indexes for table @$tabref[1].@$tabref[0]\n" if
$Getopt::Std::opt_v; $dbproc->dbcmd (dbsqlexec; $dbproc->dbresults;
@col = (); while((@field = $dbproc->dbnextrow)) { # if this is a key
or unique constraint, print out the details # otherwise buffer it up
to print as an index afterwards if ($field[3] & 2) { print (SCRIPT
",\n\t"); print SCRIPT "CONSTRAINT $field[0] " unless ($field[3] & 8);
if ($field[2] & 2048) { print SCRIPT "PRIMARY KEY "; print SCRIPT
"NONCLUSTERED " if ($field[1] != 1); } else { print SCRIPT "UNIQUE ";
print SCRIPT "CLUSTERED " if ($field[1] == 1); } print SCRIPT "(";
PrintCols (@field[4..19]); print SCRIPT ")"; } else { push @col, [
@field ]; } } # Now do the table level check constraints @constrids =
(); $dbproc->dbcmd (dbsqlexec; $dbproc->dbresults; while (@field =
$dbproc->dbnextrow) { @constrids = (@constrids, $field[0]); } foreach
$constrid (@constrids) { print SCRIPT ",\n\t" . getComment
($constrid); } print SCRIPT "\n)\ngo\n"; # end of CREATE TABLE foreach
(@col) { # now print the indexes @field = @$_; print SCRIPT "\nCREATE
"; print SCRIPT "UNIQUE " if $field[2] & 2; print SCRIPT "CLUSTERED "
if $field[1] == 1; print SCRIPT "INDEX $field[0]\n"; print SCRIPT "ON
@$tabref[1].@$tabref[0] ("; PrintCols (@field[4..19]); print SCRIPT
")"; $first = 1; if ($field[2] & 64) { print SCRIPT " WITH
ALLOW_DUP_ROW"; $first = 0; } if ($field[2] & 1) { print SCRIPT
(($first == 0) ? ", " : " WITH ") . "IGNORE_DUP_KEY"; $first = 0; } if
($field[2] & 4) { print SCRIPT (($first == 0) ? ", " : " WITH ") .
"IGNORE_DUP_ROW"; $first = 0; } print SCRIPT "\ngo\n"; }
getPerms("@$tabref[1].@$tabref[0]") && print SCRIPT "go\n"; print
"Bind rules & defaults to columns...\n" if $Getopt::Std::opt_v; print
SCRIPT "/* Bind rules & defaults to columns... */\n\n"; if(@$tabref[1]
ne 'dbo' && (keys(%dflt) || keys(%rule))) { print SCRIPT "/* The owner
of the table is @$tabref[1]. * I can't bind the rules/defaults to a
table of which I am not the owner. * The procedures below will have to
be run manualy by user @$tabref[1]. */"; print LOG "Defaults/Rules for
@$tabref[1].@$tabref[0] could not be bound\n"; } while(($dat,
$dflt)=each(%dflt)) { print SCRIPT "/* " if @$tabref[1] ne 'dbo';
print SCRIPT "sp_bindefault $dflt, '$dat'"; if(@$tabref[1] ne 'dbo') {
print SCRIPT " */\n"; } else { print SCRIPT "\ngo\n"; } } while(($dat,
$rule) = each(%rule)) { print SCRIPT "/* " if @$tabref[1] ne 'dbo';
print SCRIPT "sp_bindrule $rule, '$dat'"; if(@$tabref[1] ne 'dbo') {
print SCRIPT " */\n"; } else { print SCRIPT "\ngo\n"; } } print SCRIPT
"\n/* End of description of table @$tabref[1].@$tabref[0] */\n";
@$tabref[3] = "Y"; }
_________________________________________________________________
Q9.6: SYBTCL FAQ
_This is Tom Poindexter http://www.nyx.net/~tpoindex/ FAQ._
_________________________________________________________________
Index of Sections
* Overview
* The enabling language platform
* Design and commands
* Applications
* Information Sources
* Download
* About the Author
_________________________________________________________________
Overview
Sybtcl is an extension to Tcl (Tool Command Language) that allows Tcl
programs to access Sybase databases. Sybtcl adds additional Tcl
commands to login to a Sybase server, send SQL statements, retrieve
result sets, execute stored procedures, etc. Sybtcl simplifies Sybase
programming by creating a high level interface on top of DB-Library.
Sybtcl can be used to program a wide variety of applications, from
system administration procedures to end-user applications.
Sybtcl runs on Unix, Windows NT and 95, and Macintosh platforms.
_________________________________________________________________
The enabling language platform
Tool Command Language, often abbreviated "Tcl" and pronounced as
"tickle", was created by Dr. John Ousterhout at the University of
California-Berkeley. Tcl is an interpreted script language, similar to
Unix shell, Awk, Perl, and others. Tcl was designed to be easily
extended, where new commands are added to the base interpreter to
provide additional functionality. Core Tcl commands contain all of the
usual constructs provided by most programming languages: setting and
accessing variables, file read/write, if-then-else, do-while, function
calls. Tcl also contains many productivity enhancing commands: list
manipulation, associative arrays, and regular expression processing.
Tcl has several features that make it a highly productive language.
First, the language is interpreted. Interpreters allow execution
without a compile and link step. Code can be developed with immediate
feedback. Second, Tcl has a single data type: string. While this might
at first glance seem to a deficiency, it avoids problems of data
conversion and memory management. (This feature doesn't preclude Tcl
from performing arithmetic operations.) Last, Tcl has a consistent and
simple syntax, much the same as the Unix shell. Every Tcl statement is
a command name, followed by arguments.
Dr. Ousterhout also developed a companion Tcl extension, called Tk. Tk
provides simplified programming of X11 applications with a Motif look
and feel. X11 applications can be programmed with 60%-80% less code
than equivalent Xt, Motif, or Xview programs using C or C++.
Dr. Ousterhout now leads Tcl/Tk development at Sun Microsystems.
_________________________________________________________________
Design and commands
Sybtcl was designed to fill the gap between pure applications
development tools (e.g. Apt, Powerbuilder, et.al.) and database
administration tools, often Unix shell scripts consisting of 'isql'
and Awk pipelines. Sybtcl extends the Tcl language with specialized
commands for Sybase access. Sybtcl consists of a set of C language
functions that interface DB-Library calls to the Tcl language.
Instead of a simple one-to-one interface to DB-Library, Sybtcl
provides a high-level Sybase programming interface of its own. The
following example is a complete Sybtcl program that illustrates the
simplified interface. It relies on the Tcl interpreter, "tclsh", that
has been extended with Sybtcl.
#!/usr/local/bin/tclsh
set hand [sybconnect "mysybid" "mysybpasswd"]
sybuse $hand pubs2
sybsql $hand "select au_lname, au_fname from authors order by au_lname"
sybnext $hand {
puts [format "%s, %s" @1 @2]
}
sybclose $hand
exit
In this example, a Sybase server connection is established
("sybconnect"), and the "pubs" sample database is accessed ("sybuse").
An SQL statement is sent to the server ("sybsql"), and all rows
returned are fetched and printed ("sybnext"). Finally, the connection
is closed ("sybclose").
The same program can be made to display its output in an X11 window,
with a few changes. The Tcl/Tk windowing shell, "wish", also extended
with Sybtcl is used.
#!/usr/local/bin/wish
listbox .sql_output
button .exit -text exit -command exit
pack .sql_output .exit
set hand [sybconnect "mysybid" "mysybpasswd"]
sybuse $hand pubs2
sybsql $hand "select au_lname, au_fname from authors order by au_lname"
sybnext $hand {
.sql_output insert end [format "%s, %s" @1 @2]
}
sybclose $hand
In addition to these commands, Sybtcl includes commands to access
return column names and datatypes ("sybcols"), return values from
stored procedures ("sybretval"), reading and writing of "text" or
"image" columns ("sybreadtext", "sybwritetext"), canceling pending
results ("sybcancel"), and polling asynchronous SQL execution
("sybpoll").
Full access to Sybase server messages is also provided. Sybtcl
maintains a Tcl array variable which contains server messages, output
from stored procedures ("print"), DB-Library and OS error message.
_________________________________________________________________
Applications
The Sybtcl distribution includes "Wisqlite", an X11 SQL command
processor. Wisqlite provides a typical windowing style environment to
enter and edit SQL statements, list results of the SQL execution in a
scrollable listbox, save or print output. In addition, menu access to
the Sybase data dictionary is provided, listing tables in a database,
the column names and datatypes of a table, text of stored procedures
and triggers.
For a snapshot of Wisqlite in action, look here.
Other applications included in the Sybtcl distribution include:
* a simple graphical performance monitor
* a version of "sp_who", with periodic refresh
Sybtcl users have reported a wide variety of applications written in
Sybtcl, ranging from end user applications to database administration
utilities.
_________________________________________________________________
Information Sources
Sybtcl is extensively documented in "Tcl/Tk Tools", edited by Mark
Harrison, published by O'Reilly and Associates, 1997, ISBN:
1-56592-218-2.
Tcl/Tk is described in detail in "Tcl and the Tk Toolkit" by Dr. John
Ousterhout, Addison-Wesley Publishing 1994 ISBN: 0-201-63337-X .
Another recent publication is "Practical Programming in Tcl and Tk" by
Brent Welch, Prentice Hall 1995 ISBN 0-13-182007-9.
A wealth of information on Tcl/Tk is available via Internet sources:
news:comp.lang.tcl
http://sunscript.sun.com/
http://www.neosoft.com/tcl/
http://www.sco.com/Technology/tcl/Tcl.html
ftp://ftp.sunlabs.com/pub/tcl
ftp://ftp.neosoft.com/pub/tcl/
_________________________________________________________________
Download
Download Sybtcl in tar.gz format for Unix.
Download Sybtcl in zip format for Windows NT and 95.
Tcl/Tk and Sybtcl are both released in source code form under a "BSD"
style license. Tcl/Tk and Sybtcl may be freely used for any purpose,
as long as copyright credit is given to the respective owners. Tcl/Tk
can be obtained from either anonymous FTP site listed above.
Tcl/Tk and Sybtcl can be easily configured under most modern Unix
systems including SunOS, Solaris, HP-UX, Irix, OSF/1, AIX, SCO, et.al.
Sybtcl also runs under Windows NT and 95; pre-compiled DLL's are
include in the distribution. Sybtcl requires Sybase's DB-Library, from
Sybase's Open Client bundle.
Current versions are:
* Sybtcl 2.5: released January 8, 1998
* Tcl 8.0: released August 13, 1997
* Tk 8.0: released August 13, 1997
The Internet newsgroup comp.lang.tcl is the focal point for support.
The group is regularly read by developers and users alike. Authors may
also be reached via email. Sun has committed to keeping Tcl/Tk as
freely available software.
_________________________________________________________________
About the Author
Tom Poindexter is a consultant with expertise in Unix, relational
databases, systems and application programming. He holds a B.S. degree
from the University of Missouri, and an M.B.A. degree from Illinois
State University. He can be reached at tpoi...@nyx.net.
_________________________________________________________________
Q9.7: Extended Stored Procedures
----------------------------------------------------------------------------
The following stored procedures were written by Ed Barlow sql...@tiac.net
and can be fetched from the following site:
http://www.tiac.net/users/sqltech
Here's a pseudo-man page of what you get:
Modified Sybase Procedures
Command Description
sp__help Better sp_help
sp__helpdb Database Information
sp__helpdevice Break down database devices into a nice
report
sp__helpgroup List groups in database by access level
sp__helpindex Shows indexes by table
sp__helpsegment Segment Information
sp__helpuser Lists users in current database by group
(include aliases)
sp__lock Lock information
sp__who sp_who that fits on a page
Audit Procedures
Command Description
sp__auditsecurity Security Audit On Server
sp__auditdb Audit Current Database For Potential
Problems
System Administrator Procedures
Command Description
sp__block Blocking processes.
sp__dbspace Summary of current database space
information.
sp__dumpdevice Listing of Dump devices
sp__helpdbdev Show how Databases use Devices
sp__helplogin Show logins and remote logins to server
sp__helpmirror Shows mirror information, discover broken
mirrors
sp__segment Segment Information
sp__server Server summary report (very useful)
sp__vdevno Who's who in the device world
DBA Procedures
Command Description
sp__badindex give information about bad indexes (nulls,
bad statistics...)
sp__collist list all columns in database
sp__indexspace Space used by indexes in database
sp__noindex list of tables without indexes.
sp__helpcolumns show columns for given table
sp__helpdefault list defaults (part of objectlist)
sp__helpobject list objects
sp__helpproc list procs (part of objectlist)
sp__helprule list rules (part of objectlist)
sp__helptable list tables (part of objectlist)
sp__helptrigger list triggers (part of objectlist)
sp__helpview list views (part of objectlist)
sp__trigger Useful synopsis report of current database
trigger schema
Reverse Engineering
Command Description
sp__revalias get alias script for current db
sp__revdb get db creation script for server
sp__revdevice get device creation script
sp__revgroup get group script for current db
sp__revindex get indexes script for current db
sp__revlogin get logins script for server
sp__revmirror get mirroring script for server
sp__revuser get user script for current db
Other Procedures
Command Description
sp__bcp Create unix script to bcp in/out database
sp__date Who can remember all the date styles?
sp__quickstats Quick dump of server summary information
----------------------------------------------------------------------------
Q9.9: SQL TO DETERMINE SPACE USED FOR AN INDEX
_________________________________________________________________
OK, here's _sp_spaceused_ reduced to bare essentials:
set nocount on
declare @objname varchar(30)
select @objname = "your table"
select index_name = i.name,
i.segment,
rowtotal = rowcnt(i.doampg),
reserved = (reserved_pgs(i.id, i.doampg) +
reserved_pgs(i.id, i.ioampg)),
data = data_pgs(i.id, i.doampg),
index_size = data_pgs(i.id, i.ioampg),
unused = ((reserved_pgs(i.id, i.doampg) +
reserved_pgs(i.id, i.ioampg)) -
(data_pgs(i.id, i.doampg) + data_pgs(i.id,
i.ioampg)))
into #space
from sysindexes i
where i.id = object_id(@objname)
You can analyse this in a number of ways:
1. This query should tally with _sp_spaceused @objname_:
select 'reserved KB' = sum(reserved) * 2,
'Data KB' = sum(data) * 2,
'Index KB' = sum(index_size) * 2,
'Unused KB' = sum(unused) * 2
from #space
2. This one reports space allocation by segment:
select 'segment name' = s.name,
'reserved KB' = sum(reserved) * 2,
'Data KB' = sum(data) * 2,
'Index KB' = sum(index_size) * 2,
'Unused KB' = sum(unused) * 2
from #space t,
syssegments s
where t.segment = s.segment
group by s.name
3. This one reports allocations by index:
select t.index_name,
s.name,
'reserved KB' = reserved * 2,
'Data KB' = data * 2,
'Index KB' = index_size * 2,
'Unused KB' = unused * 2
from #space t,
syssegments s
where t.segment = s.segment
If you leave out the where clause in the initial _select into_, you
can analyse across the whole database.
Hope this points you in the right direction.
_________________________________________________________________
Q9.10: _XSYBMON_
_________________________________________________________________
The original site, NSCU, no longer carries these bits. If you feel
that it's useful to have xsybmon and you know where the new bits are,
please drop me an e-mail: pa...@sgi.com
_________________________________________________________________
Q9.11: SP_DOS
_________________________________________________________________
/*>>>>>>>>>>>>>>>>>>>>>>>>>>> sp_dos <<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
IF OBJECT_ID('dbo.sp_dos') IS NOT NULL
DROP PROCEDURE sp_dos
GO
CREATE PROCEDURE sp_dos
@vcObjectName varchar(30) = NULL
AS
/***********************************************************************
* sp_dos - Display Object Scope
* This procedure graphically displays the scope of a object in
* the database.
*
* Copyright 1996, all rights reserved.
*
* Author: David W. Pledger, Strategic Data Systems, Inc.
*
* Parameters
* ----------------------------------------------------------------
* Name In/Out Description
* ----------------------------------------------------------------
* @vcObjectName In Mandatory - The exact name of a single
* database object for which the call
* hierarchy is to be extracted.
*
* Selected Data
* A sample report follows:
* ----------------------------------------------------------------
*
* SCOPE OF EFFECT FOR OBJECT: ti_users
* +------------------------------------------------------------------+
* (T) ti_users (Trigger on table 'users')
* |
* +--(P) pUT_GetError
* | |
* | +--(U) ui_error
* |
* +--(U) BGRP
* |
* +--(U) user_information (See Triggers: tu_user_information)
* |
* +--(U) users (See Triggers: ti_users, tu_users, td_users)
* |
* +--(P) pUT_LUDVersion
* |
* +--(P) pUT_GetError
* | |
* | +--(U) ui_error
* |
* +--(U) BGRP_LUDVersion
*
* <End of Sample>
*
* Return Values
* ----------------------------------------------------------------
* Value Description
* ----------------------------------------------------------------
* < -99 Unexpected error - should never occur.
*
* -99 to -1 Sybase **reserved** return status values.
*
* 0 Execution succeeded
*
* 1 Execution of this procedure failed.
*
* > 1 Unexpected error - should never occur.
*
***********************************************************************/
BEGIN
/*------------------- Local Declarations -------------------------*/
DECLARE @iObjectID int /* System ID of object */
DECLARE @cObjectType char(1) /* System Object Type code */
DECLARE @vcName varchar(30) /* System Object name */
DECLARE @vcMsg varchar(255) /* Error Message if needed */
DECLARE @iInsTrigID int /* Insert Trigger ID */
DECLARE @iUpdTrigID int /* Update Trigger ID */
DECLARE @iDelTrigID int /* Delete Trigger ID */
DECLARE @vcErrMsg varchar(255) /* Error Message */
/* Local variables to facilitate descending the parent-child
** object hierarchy.
*/
DECLARE @iCurrent int /* Current node in the tree */
DECLARE @iRoot int /* The root node in the tree */
DECLARE @iLevel int /* The current level */
/* Local variables that contain the fragments of the text to
** be displayed while descending the hierarchy.
*/
DECLARE @iDotIndex int /* Index for locating periods */
DECLARE @cConnector char(3) /* '+--' */
DECLARE @cSibSpacer char(3) /* '| ' */
DECLARE @cBar char(1) /* '|' */
DECLARE @cSpacer char(3) /* ' ' */
DECLARE @cPrntStrng1 char(255) /* The first string to print */
DECLARE @cPrntStrng2 char(255) /* The second string to print */
DECLARE @iLoop int /* Temp var used for loop */
DECLARE @vcDepends varchar(255) /* Dependency String */
DECLARE @iDependsItem int /* Index to a string item */
/* Create a temporary table to handle the hierarchical
** decomposition of the task parent-child relationship. The Stack
** table keeps track of where we are while the leaf table keeps
** track of the leaf tasks which need to be performed.
*/
CREATE TABLE #Stack
(iItem int,
iLevel int)
/*------------------- Validate Input Parameters --------------------*/
/* Make sure the table is local to the current database. */
IF (@vcObjectName LIKE "%.%.%") AND (SUBSTRING(@vcObjectName, 1,
CHARINDEX(".", @vcObjectName) - 1) != DB_NAME())
GOTO ErrorNotLocal
/* Now check to see that the object is in sysobjects. */
IF OBJECT_ID(@vcObjectName) IS NULL
GOTO ErrorNotFound
/* ---------------------- Initialization -------------------------*/
/* Do print any rowcounts while this is in progress. */
SET NOCOUNT ON
/* Retrieve the object ID out of sysobjects */
SELECT @iObjectID = O.id,
@cObjectType = O.type
FROM sysobjects O
WHERE O.name = @vcObjectName
/* Make sure a job exists. */
IF NOT (@@rowcount = 1 and @@error = 0 and @iObjectID > 0)
GOTO ErrorNotFound
/* Initialize the print string pieces. */
SELECT @cConnector = "+--",
@cSibSpacer = "|..",
@cBar = "|",
@cSpacer = "...",
@cPrntStrng1 = "",
@cPrntStrng2 = ""
/* Print a separator line. */
PRINT " "
PRINT "** Utility by David Pledger, Strategic Data Systems, Inc. **"
PRINT "** PO Box 498, Springboro, OH 45066 **"
PRINT " "
PRINT " SCOPE OF EFFECT FOR OBJECT: %1!",@vcObjectName
PRINT "+------------------------------------------------------------------+
"
/* -------------------- Show the Hierarchy -----------------------*/
/* Find the root task for this job. The root task is the only task
** that has a parent task ID of null.
*/
SELECT @iRoot = @iObjectID
/* Since there is a root task, we can assign the first
** stack value and assign it a level of one.
*/
SELECT @iCurrent = @iRoot,
@iLevel = 1
/* Prime the stack with the root level. */
INSERT INTO #Stack values (@iCurrent, 1)
/* As long as there are nodes which have not been visited
** within the tree, the level will be > 0. Continue until all
** nodes are visited. This outer loop descends the tree through
** the parent-child relationship of the nodes.
*/
WHILE (@iLevel > 0)
BEGIN
/* Do any nodes exist at the current level? If yes, process them.
** If no, then back out to the previous level.
*/
IF EXISTS
(SELECT *
FROM #Stack S
WHERE S.iLevel = @iLevel)
BEGIN
/* Get the smallest numbered node at the current level. */
SELECT @iCurrent = min(S.iItem)
FROM #Stack S
WHERE S.iLevel = @iLevel
/* Get the name and type of this node. */
SELECT @cObjectType = O.type,
@vcName = O.name,
@iInsTrigID = ISNULL(O.instrig, 0),
@iUpdTrigID = ISNULL(O.updtrig, 0),
@iDelTrigID = ISNULL(O.deltrig, 0)
FROM sysobjects O
WHERE O.id = @iCurrent
/*
* *=================================================* *
* * Print out data for this node. (Consider * *
* * making this a separate procedure.) * *
* *=================================================* *
*/
/* Initialize the print strings to empty (different from NULL).
** @cPrntStrng1 is used to 'double space' the output and
** contains the necessary column connectors, but no data.
** @cPrntStrng2 contains the actual data at the end of the
** string.
*/
SELECT @cPrntStrng1 = ""
SELECT @cPrntStrng2 = ""
/* Level 1 is the root node level. All Jobs have a single
** root task. All other tasks are subordinate to this task.
** No job may have more than one root task.
*/
IF @iLevel = 1
BEGIN
/* Print data for the root node. */
SELECT @cPrntStrng1 = "",
@cPrntStrng2 = "(" + @cObjectType + ") " + @vcName
END
ELSE /* Else part of (IF @iLevel = 1) */
BEGIN
/* Initialize loop variable to 2 since level one has
** already been processed for printing.
*/
SELECT @iLoop = 2
/* Look at the values on the stack at each level to
** determine which symbol should be inserted into the
** print string.
*/
WHILE @iLoop <= @iLevel
BEGIN
/* While the loop variable is less than the current
** level, add the appropriate spacer to line up
** the printed output.
*/
IF @iLoop < @iLevel
BEGIN
/* Is there a sibling (another node which exists
** at the same level) on the stack? If so, use
** one type of separator; otherwise, use another
** type of separator.
*/
IF EXISTS(SELECT * FROM #Stack WHERE iLevel = @iLoop)
BEGIN
SELECT @cPrntStrng1 = rtrim(@cPrntStrng1) +
@cSibSpacer
SELECT @cPrntStrng2 = rtrim(@cPrntStrng2) +
@cSibSpacer
END
ELSE
BEGIN
SELECT @cPrntStrng1 = rtrim(@cPrntStrng1) + @cSpacer
SELECT @cPrntStrng2 = rtrim(@cPrntStrng2) + @cSpacer
END
END
ELSE /* Else part of (IF @iLoop < @iLevel) */
BEGIN
SELECT @cPrntStrng1 = rtrim(@cPrntStrng1) + @cBar
SELECT @cPrntStrng2 = rtrim(@cPrntStrng2) +
@cConnector + "(" + @cObjectType + ") " +
@vcName
END
/* Increment the loop variable */
SELECT @iLoop = @iLoop + 1
END /* While @iLoop <= @iLevel */
END /* IF @iLevel = 1 */
/* Spaces are inserted into the string to separate the levels
** into columns in the printed output. Spaces, however, caused
** a number of problems when attempting to concatenate the
** two strings together. To perform the concatenation, the
** function rtrim was used to remove the end of the string.
** This also removed the spaces we just added. To aleviate
** this problem, we used a period (.) wherever there was
** supposed to be a space. Now that we are ready to print
** the line of text, we need to substitute real spaces
** wherever there is a period in the string. To do this,
** we simply look for periods and substitute spaces. This
** has to be done in a loop since there is no mechanism to
** make this substitution in the whole string at once.
*/
/* Find the first period. */
SELECT @iDotIndex = charindex (".", @cPrntStrng1)
/* If a period exists, substitute a space for it and then
** find the next period.
*/
WHILE @iDotIndex > 0
BEGIN
/* Substitute the space */
SELECT @cPrntStrng1 = stuff(@cPrntStrng1, @iDotIndex, 1, " ")
/* Find the next. */
SELECT @iDotIndex = charindex (".", @cPrntStrng1)
END
/* Do the same thing for the second print string. */
SELECT @iDotIndex = charindex (".", @cPrntStrng2)
WHILE @iDotIndex > 0
BEGIN
SELECT @cPrntStrng2 = stuff(@cPrntStrng2, @iDotIndex, 1, " ")
SELECT @iDotIndex = charindex (".", @cPrntStrng2)
END
SELECT @vcDepends = NULL
IF @iInsTrigID > 0
SELECT @vcDepends = OBJECT_NAME(@iInsTrigID) + " (Insert)"
IF @iUpdTrigID > 0
IF @vcDepends IS NULL
SELECT @vcDepends = OBJECT_NAME(@iUpdTrigID) + " (Update)"
ELSE
SELECT @vcDepends = @vcDepends + ", " +
OBJECT_NAME(@iUpdTrigID) + " (Update)"
IF @iDelTrigID > 0
IF @vcDepends IS NULL
SELECT @vcDepends = OBJECT_NAME(@iDelTrigID) + " (Delete)"
ELSE
SELECT @vcDepends = @vcDepends + ", " +
OBJECT_NAME(@iDelTrigID) + " (Delete)"
IF @vcDepends IS NOT NULL
IF @cObjectType = "T"
SELECT @cPrntStrng2 = @cPrntStrng2 +
" (Trigger on table '" + @vcDepends + "')"
ELSE
SELECT @cPrntStrng2 = @cPrntStrng2 +
" (See Triggers: " + @vcDepends + ")"
/* Remove trailing blanks from the first print string. */
SELECT @cPrntStrng1 = rtrim(@cPrntStrng1)
SELECT @cPrntStrng2 = rtrim(@cPrntStrng2)
/* Print the two strings. */
PRINT @cPrntStrng1
PRINT @cPrntStrng2
/* Remove the current entry from the stack (Pop) */
DELETE #Stack
WHERE #Stack.iLevel = @iLevel
AND #Stack.iItem = @iCurrent
/* Add (push) to the stack all the children of the current
** node.
*/
INSERT INTO #Stack
SELECT D.depid,
@iLevel + 1
FROM sysdepends D
WHERE D.id = @iCurrent
/* If any were added, then we must descend another level. */
IF @@rowcount > 0
BEGIN
SELECT @iLevel = @iLevel + 1
END
END
ELSE
BEGIN
/* We have reached a leaf node. Move back to the previous
** level and see what else is left to process.
*/
SELECT @iLevel = @iLevel - 1
END
END /* While (@iLevel > 0) */
PRINT " "
RETURN (0)
/*------------------------ Error Handling --------------------------*/
ErrorNotLocal:
/* 17460, Table must be in the current database. */
EXEC sp_getmessage 17460, @vcErrMsg OUT
PRINT @vcErrMsg
RETURN (1)
ErrorNotFound:
/* 17461, Table is not in this database. */
EXEC sp_getmessage 17461, @vcErrMsg OUT
PRINT @vcErrMsg
PRINT " "
PRINT "Local object types and objecs are:"
SELECT "Object Type" = type,
"Object Name" = name
FROM sysobjects
WHERE type IN ("U","TR","P","V")
ORDER BY type, name
RETURN (1)
END
GO
grant execute on sp_dos to public
go
_________________________________________________________________
_________________________________________________________________
Q9.12: SQSH, RELEASE 1.4
_Last Modified: Oct 16, 1996 at 21:24:52 EST_
_________________________________________________________________
Sybase-FAQ Notice
You are currently reading a special Sybase-FAQified version of my home
page. I will attempt to keep it as up-to-date as possible, however
there is a chance that it may lag somewhat behind my personal page
(http://www.voicenet.com/~gray/sqsh.html). Also, this version has
been stripped of changelog and status information in order to shorten
it up a bit for the plain-text version of the FAQ.
What is SQSH?
Sqsh (pronounced skwish) is short for SQshelL (pronounced s-q-shell),
it is intended as a replacement for the venerable 'isql' program
supplied by Sybase. It came about due to years of frustration of
trying to do real work with a program that was never meant to perform
real work.
Sqsh is much more than a nice prompt (a la 'dsql', from David B.
Joyner), it is intended to provide much of the functionality provided
by a good shell, such as variables, redirection, pipes,
back-grounding, job control, history, command completion, and dynamic
configuration. Also, as a by-product of the design, it is remarkably
easy to extend and add functionality.
Sqsh was designed with portability in mind and has been successfully
compiled on most major UNIX platforms supported by Sybase, such as
HP-UX, AIX, IRIX, SunOS, Solaris, Dynix, OSF/1, DEC Unix, SCO, NeXT,
and CP/M (just kidding). It has also been compiled on most free
versions of UNIX, Linux, NetBSD, and FreeBSD, using the -DNO_DB flag
(which turns off database support). It should build relatively easily
on most POSIX and X/OPEN compliant systems.
JOIN THE SQSH MAILING LIST
Thanks to the tireless efforts of Pablo Sanchez (our fearless
maintainer of the Sybase FAQ), and the excellent people at SGI, the
sqsh mailing list is now available for use! Keep track of the latest
developments. Offer suggestions for future additions. Offer me money
(grin).
To subscribe, send mail to external-...@postofc.corp.sgi.com
With a _body_ of:
subscribe sqsh-users [optional e-mail address]
Or with a _body_ of just:
help
for a list of commands. Once subscribed you may send mail to the
sqsh-users mailing list by addressing your mail to:
WHERE TO GET SQSH
Sqsh may be found on the following sites:
* http://www.voicenet.com/~gray/sqsh-1.4.tar.gz
* ftp://poseidon.csci.unt.edu/pub/sqsh
* ftp://ftp.netcom.com/pub/he/heyjude/gray
* ftp://davox2.davox.com/pub/sqsh
Keep in mind that sometimes the different sites become out of sync, so
at times the latest version may be be available at one of them.
If you are wondering what the funny '.gz' extension is on the end of
some of the files, I highly recommend that you grab a copy of
ftp://prep.ai.mit.edu/pub/gnu/gzip-1.2.4.tar or you can get a regular
UNIX compressed version http://www.voicenet.com/~gray/sqsh-1.4.tar.Z.
I also try to keep around the previous release
http://www.voicenet.com/~gray/sqsh-1.3.tar.gz, just in case I royally
screw up the current release (which could happen).
If you have trouble reaching any of the sites above, you can send me
e-mail at gr...@voicenet.com, I am typically pretty good about
responding.
SQSH FEATURES
Commands
Sqsh provides all commands provided by isql (such as go, reset,
etc.)-- which wasn't hard, there aren't many of them--along with a
large base of extended commands. Typically all commands in sqsh are
prefixed with a '\' to avoid collision with the TSQL syntax. For
example:
1> \help
Available commands:
\abort \alias \buf-append \buf-copy \buf-edit
\buf-get \buf-load \buf-save \buf-show \connect
\done \echo \exit \go \help
\history \jobs \kill \loop \quit
\read \reconnect \redraw \reset \set
\shell \show \sleep \unalias \wait
\warranty emacs vi
Use '\help command' for more details
However, for those of you that just can't stand the '\', all commands
may be aliased to any other name that you wish via the '\alias'
command (see Aliasing, below).
Variables
Variables are provided in sqsh, much in the same way they are used
within a standard shell. They may be used for storing and retrieving
information, both within a sqsh command as well as within a SQL batch.
For example, lets say that you have a long table name that you don't
like to type over and over again, you can use a variable in place of
the table name:
1> \set t="a_really_long_table_name"
1> SELECT "Count" = COUNT(*) FROM $t
2> go
Count
-----------
1123
(1 row affected)
Variables may also be used anywhere within a sqsh command, such as:
1> \set g="go"
1> SELECT "Count" = COUNT(*) FROM $t
2> $g
Count
-----------
1123
(1 row affected)
And, since virtually every aspect of sqsh is configurable through
variables, the \set command may also be used to adjust the behavior of
sqsh without having to exit and re-run with a different command line
argument (like isql):
1> \set colsep="|"
1> SELECT id, COUNT(*) FROM syscolumns GROUP BY id
2> go
|id | |
|-----------|-----------|
| 1| 19|
| 2| 23|
...
This is the equivalent of exiting isql, and re-running it with the -c
flag (which is also supported by sqsh).
Redirection and Pipes
How many times have you watched a result set disappear from your
screen because you didn't hit ^S fast enough? Well, no more. Now, any
command available in sqsh may be redirected to/from a file or
pipelined to another process. For example, it is now legal to type:
1> SELECT * FROM sysobjects
2> go | grep test | more
You may also redirect output to files and (if you are careful) can
redirect input from files:
1> select * from sysobjects
2> go 2>/dev/null >/tmp/objects.txt
Aliasing
As of release 1.2, sqsh supports full csh-style command aliasing.
Aliasing provides a mechanism for supplying an alternate name for any
given internal sqsh command, as well as a way of supplying additional
argument to any given command. For example:
1> \alias mo="\go !* | more"
1> SELECT * FROM syspickles
2> mo -h
Is exactly the same as if you had typed:
1> SELECT * FROM syspickles
2> go -h | more
The !* acts as a placeholder that indicates to sqsh that the
parameters supplied to the alias should be inserted at this location.
If the !* is not supplied, the parameters to the alias are appended on
the end of the alias body..
Command Substitution
With the 1.0 release, sqsh is slowly beginning to look more-and-more
like a real shell with the addition of command substitution. This
feature allows a UNIX command to substituted anywhere within a sqsh
command or within a SQL batch simply by placing the command within
backquotes (or ` -- this may not come out to be a backquote depending
on which font your web browser is using). For example:
1> SELECT COUNT(*) FROM `echo syscolumns`
2> go | `echo more`
Currently, sqsh allows a multi-line command within a SQL batch,
however this is not support for command line functions as of yet. For
example you can do:
1> SELECT COUNT(*) FROM `echo
2> syscolumns`
3> go
Whereas you _cannot_ do:
1> SELECT COUNT(*) FROM syscolumns
2> go | `echo
more`
Hopefully, in the near future I'll make sqsh smart enough to support
line-continuations with sqsh commands. Believe it or not, it isn't
that easy to do.
Backgrounding And Job Control
Suppose you want to run a long complex query and continue to work
while waiting for the results. With isql, the most effective way to do
this was to run two copies of isql. With sqsh you can now do:
1> SELECT ... /* big nasty select */
2> go &
Job #1 started
1>
After typing 'go &', sqsh launches a child process, which reconnects
to the database and performs the desired query. This is similar to job
control within a standard shell except that, by default, in sqsh the
background job's output will be deferred until the job completes. So
when the big nasty query, above, completes you will see a message
like:
1> sp_helptext ....
Job #1 completed (output pending)
2>
and to show the output of the job you can do:
1> \show 1 | more
Once again, the behavior of output deferral may be turned on and off
via the $defer_bg variable.
Sqsh also provides the commonly used job control commands available in
such shells as csh and bash, such as \jobs (to display running jobs)
and \kill (to terminate jobs).
SQL Batch History
Sqsh provides two methods for history control, line-by-line history
using either vi or emacs styles (via
ftp://prep.ai.mit.edu/pub/gnu/readline-2.0.tar.gz), it also provides
batch history, so that entire statements may be re-run or edited:
1> \history
...
(12) SELECT name, id
FROM syscolumns
WHERE name LIKE "%$name%"
(13) SELECT DISTINCT title, type
FROM titles
WHERE title IN
(SELECT title
FROM titles, titleauthor, authors
WHERE titles.title_id = titleauthor.title_id
AND authors.state = "CA")
..
Most commands support a csh-style reference to history entries via
'!!', or '!n'.
1> \vi !!
Configurable Exit Status
One of the major complaints most people have with isql is its
inability to react to or report any sort of error condition generated
within a SQL batch. Sqsh provides a somewhat complex but very flexible
for configuring what is considered an error, which errors are to be
displayed, and how to report them back to the operating system.
Five internal variables are used to control sqsh's behavior to error
conditions reported by SQL Server, $thresh_display, $thresh_fail,
$thresh_failcount, $thresh_exit, and $exit_failcount all of which are
configurable at run time as well as via command line flags. The
following briefly outlines these variables and their relationship to
each other:
* _$thresh_display_
This variable is used to determine at which severity level a SQL
Server message is to be displayed. Setting this to 0 displays all
message, and setting it to 22 suppresses all error messages.
* _$thresh_fail_
This variable is used by the error handler to determine which
severity levels are considered by sqsh to be error conditions. The
next variable will explain the importance of this value.
* _$batch_failcount_
Each time sqsh receives an message of a severity level that is
considered an error (determined by $thresh_fail) this value is
incremented to keep track of the total number of batches that have
failed.
* _$thresh_exit_
This variable is used by sqsh to determine how many error
conditions may be encountered before it will exit. In other words,
when $batch_failcount is equal to $thresh_exit, sqsh will abort.
Setting the variable to 0 disables this feature.
* _$exit_failcount_
If this variable is set to 1 (or On), then sqsh will exit with an
operating system exit status equal to the total number of errors
that have been encountered (the value of $batch_failcount).
Inter-Server BCP
Using the \bcp command, sqsh supports the ability to transfer the
result set from any command batch to another server (or even the same
server) via the Sybase bcp protocol. This feature is particulary nice
because current the standard Sybase bcp program does not support being
able to transfer directly between server, or the ability to specify
which rows from the source server are to be copied.
1> SELECT customer_id, item, SUM(qty)
2> FROM orders
3> GROUP BY customer_id, item
4> \bcp -S SYB_DSS shipping.dbo.order_summary
Starting...
Batch successfully bulk-copied to SQL Server
Batch successfully bulk-copied to SQL Server
Batch successfully bulk-copied to SQL Server
...
The \bcp command can deal with multiple result sets, and thus multiple
commands in a batch or multiple results coming back from a single
stored procedure (as long as the data types in all result sets are
identical).
Remote Procedure Calls
With sqsh, it is possible to directly envoke a stored procedure
without resorting to language calls (e.g. "EXEC proc_name ..."). This
feature is of particular interest for controlling and Open Server that
does not have language support built in. For example, to invoke the
sp_who stored procedure, simply run:
1> \rpc sp_who gray
...
Sqsh also supports the ability to place the results of an OUTPUT
parameter directly into a sqsh variable, for example, lets say we
create a stored procedure that like so:
1> CREATE PROCEDURE test_output
2> @x int OUTPUT
3> AS
4> SELECT @x
5> SELECT @x=20
6> go
We may then invoke the _test_output_ procedure like this:
1> \rpc test_output @x:my_x=10
-----------
10
(0 rows affected)
1> \echo $my_x
20
The \rpc command can be a little bit awkward and non-intuitive, so
make sure you read the manual page closely before working with it.
Semicolon "go"
As of release 0.5, sqsh now supports a form of in-line go, via a ;
placed anywhere within the current line, such as:
1> sp_who ;
And, anything that can follow the "go" command may also follow the
inline ;
1> sp_who ; | more
Sqsh even attempts to be relatively smart, and ignores semicolons
found within single or double quotes of a single command, although it
currently does deal with semicolons located in comments. Note, in
order to turn this feature on, execute:
1> \set semicolon_hack=1
Simple Scripting
Although sqsh does not have a full flow-of-control language (yet), it
is possible to build simple self-executable scripts using the using #!
notation, and sqsh's support for positional parameters. For example,
to create a UNIX sp_who program, you simply need to create an
executable file containing:
#!/usr/local/bin/sqsh -i
sp_who ${1}
go
The ${1} parameter to sp_who will expand to whatever argument is given
when the script is run. Currently sqsh does not support more advanced
positional paramters, such as $* or $@, like most shells.
Multiple Display Styles
Ever get tired of wading through isql's messy output when dealing with
very wide result sets? Sqsh currently supports three separate display
styles, _horizontal_ (standard isql style), _vertical_, and _bcp_,
that are switchable at any time while running via the $style variable
or by the -m flag to the \go command.
With the vertical display style, all data is displayed as column/value
pairs virtically down the left side. The style also nicely deals with
performing word-wrapping on very wide text and varchar column outputs.
1> SELECT * FROM my_table
2> go -m vert
int_col: 1
varchar_col: You will notice that both varchar and text columns gracefully
word-wrap and line up with the widest column name.
float_col: 1.23
text_col: This text column would look really hideous on isql's output
but fortunately sqsh make things look great with the vertical
display style!
int_col: 2
varchar_col: Not much text here.
float_col: 3.141592654
text_col:
(2 rows affected)
And, if you want to simply generate a result set that is easily
BCP'able into another server, the _bcp_ display style is for you. This
style throws out all formatting and simply separates all columns by
the value of the $colsep parameter (by default "|").
1> SELECT * FROM my_other_table
2> go -m bcp
1|Scott|11/03/96 12:59:56|0|||
1|Bob|11/19/96 12:59:56|7||32.5|
This mode pretty much only makes sense when redirecting the output to
a file (see Redirection and Pipes, above),
Miscellaneous
The following touches on a more of the less prominent features of
sqsh. It is by no means a comprehensive list, for more details please
refer to the manual page.
* _Configurable Prompt Variable_
The sqsh prompt is defined by the $prompt variable which is
expanded prior to reading input from the user. Because sqsh keeps
track of its current state in various variables, the prompt can be
used to display such information as the current database, user,
line number, etc.
* _Named Buffers_
In addition to the SQH History Buffer, sqsh also allows the
current work buffer or any history buffer to be copied to and from
named buffers for future use. Named buffers may also be edited and
run.
* _Reconnection_
The SQL Server to which sqsh is connected may be dynamically
changed without exiting using the \reconnect command.
* _Configurable Keyword Completion_
With GNU Readline support, sqsh adds keyword completion. By
default sqsh will use its internal database of 237 TSQL keywords
for tab-keyword completion. This completion can be configured to
be performed in upper case, lower case, or auto-detect. If the
file ~/.sqsh_keywords exists then the contents of this file is
used in place of the internal keyword list.
* _Session Locking_
Using the \lock command, you may safely walk away from your
current sqsh session without worrying about someone tampering with
the database while you are away.
SQSH SUPPORTED PLATFORMS
The following table outlines platforms that sqsh has successfully been
compiled on. In theory each of these platforms should have been
compiled painlessly, but in practice the odder operating systems trend
to require a few tweaks. However, I am always working to make sqsh as
easily portable as possible (not always an easy task).
If you have any additional platforms that you would like to have added
to this list, please send me e-mail, I always interested in hearing
what people are doing with sqsh.
Hardware OS Compiler Comments
------------------- ------------------- --------- ----------------
Sun Sparc 1000 Solaris 2.4 gcc
HP/9000 E35 HP-UX 10.x gcc, cc
HP/9000 755 HP-UX 9.01 ? gcc -static
SGI Indy IRIX 5.x, 6.x cc 3.19 See README.SGI
NCR System 3000 SVR4 cc
Sequent ? Dynix/ptx 2.1.0 ?
? NeXT ?
150Mhz Pentium SCO ? ?
DEC Alpha OSF/1 ? ?
IBM RS/6000 AIX 3.2 gcc -ltermcap, no -ltli
* Sun IPX SunOS 4.1.2 gcc
* Sun Sparc 4c SunOS 4.1.4 gcc
* HP/300 NetBSD 1.1A gcc
* 486DX/50 Linux 1.3.45 gcc
* Indicates that it has been compiled with -DNO_DB turned on, therefore
the actual database access has not been tested, however 99% of Sqsh
has nothing to do with database activity.
And, for those of you that are interested in such things, sqsh is
developed primarily on Linux 1.3.95 with the -DNO_DB flag on (I
haven't managed to port DB-Lib to Linux yet), and tested on a Sun
Sparc Server 1000 running Solaris 2.4.
SQSH LICENSING POLICY
99% of the software that I use is free, therefore I like to give back
in kind. Sqsh is held under the GNU General Public License (GPL) and
therefore may be freely distributed under the terms of this license.
_________________________________________________________________
_Last Modified on Oct 16, 1996 at 21:24:52 EST by Scott C. Gray _
Q9.13: SP_GETDAYS
_________________________________________________________________
use sybsystemprocs
go
if object_id("sp_days") is not NULL
drop proc sp_days
go
create proc sp_days @days tinyint OUTPUT, @month tinyint, @year smallint
as
declare @date datetime
select @date=convert(char,@month)+"/01/"+convert(char, @year)
select @days=datediff(dd,@date, dateadd(mm,1,@date))
select @days
go
grant exec on sp_days to public
go
_________________________________________________________________
Q9.14: ddl_insert.pl
----------------------------------------------------------------------------
In order to use this script you must have Sybperl installed -- see Q9.4 for
more information.
#!/usr/local/bin/perl
# Author: Vincent Yin (um...@mctrf.mb.ca) Aug 1994 Last Modified: May 1996
chomp($basename = `basename $0`);
$usage = <<EOF;
USAGE
$basename database userid passwd pattern [ pattern... ]
DESCRIPTION
Prints isql scripts that would insert records into the
tables whose names match any of the patterns in command line. In
other words, this program reverse engineers the data in a given
table(s). Roughly, it `select * from <table>', analyses the data
and table structure, then prints out a bunch of
insert <table> values ( ... )
statements that would re-populate the table. It's an alternative
to `bcp'. `bcp' has its limitations (e.g. one often needs to turn on
'select into/bulk copy' option in the database before running bcp.)
Table names are matched to <pattern> with Transact-SQL's LIKE clause.
When more than one pattern is specified on command line, the LIKE
clauses are OR'ed. In any case, the LIKE clause(s) is logged to
the beginning of the output as a comment, so that you'll see how this
program interprets the command line.
The SQL script is printed to stdout. Since it only prints out the SQL
but doesn't submit it to the SQL server, this procedure is safe to run.
It doesn't modify database in any way.
EXAMPLES
To print this usage page:
% $basename
To print SQL that populates the table master..sysobjects and systypes:
% $basename master userid passwd 'sysobjects' 'systypes'
To print SQL that populates all system tables in master db:
% $basename master userid passwd 'sys%'
BUGS
Embedded line breaks in strings are allowed in Sybase's isql, but not
allowed in SQLAnywhere's isql. So this script converts embedded line
breaks (both DOS styled and UNIX styled) to blank characters.
EOF
$batchsize = 10; # The number of INSERTs before a `go' is issued.
# This is to make the output compact.
# .................... No change needed below this line ........................
use Sybase::DBlib;
die $usage unless $#ARGV >= 3;
($db, $user, $passwd, @pattern) = @ARGV;
$likeclause = &sql_pattern_to_like_clause('name', @pattern);
print <<EOF;
-- This script is created by $0.
-- It would generate INSERT statements for tables whose names match the
-- following pattern:
/* $likeclause
*/
set nocount on
go
EOF
$dbh = new Sybase::DBlib $user, $passwd;
$dbh->{dbNullIsUndef} = 1;
$dbh->dbuse($db);
# Get the list of tables.
$tablelist = $dbh->sql("select name from sysobjects
where type in ('S','U') and $likeclause
order by name
");
foreach $tableref (@$tablelist) {
$table = @$tableref[0];
print "\n\n/*.............. $table ...............*/\n";
print "-- ", `date`, "\n";
print "declare \@d datetime\n";
print "select \@d = getdate()\n";
print "print ' %1! $table', \@d\ngo\n\n";
print "truncate table $table -- Lookout !!!!!!\ngo\n\n";
$dbh->dbcmd("select * from $table");
$dbh->dbsqlexec;
$dbh->dbresults;
while (@row = $dbh->dbnextrow()) {
print "insert $table values(";
for ($i=0; $i <= $#row; $i++) { # build the INSERT statement
# Analyse datatype to decide if this column needs to be quoted.
$coltype = $dbh->dbcoltype($i+1);
if (!defined($row[$i])) {
print 'NULL'; # Never quote NULL regardless of datatype
}
elsif ($coltype==35 or $coltype==39 or $coltype==47 or
$coltype==58 or $coltype==61 or $coltype==111 ){
# See systypes.type/name for explanation of $coltype.
$row[$i] =~ s/\r|\n/ /g; # Handles both DOS and UNIX line breaks
$row[$i] =~ s/"/""/g; # Stuff double quotes
print "\"" . $row[$i] . "\"";
}
else {
print $row[$i];
}
print ", " unless $i == $#row;
}
print ")\n"; # wrap up the INSERT statement.
# print `go' at every $batchsize interval.
print "go\n" unless $dbh->DBCURROW % $batchsize;
}
print "\ngo\n\n"; # print a `go' after the entire table is done.
print "-- ### End for $table: rowcount = ", $dbh->DBCURROW, "\n";
}
# ................................. sub ........................................
sub main'sql_pattern_to_like_clause {
local($field_name, @pattern) = @_;
$like_clause = "\t( 1 = 0 ";
foreach (@pattern) {
$like_clause .= "\n or $field_name like '" . $_ . "' ";
}
$like_clause .= "\n\t) \n";
}
----------------------------------------------------------------------------
Q9.15: SP_DDL_CREATE_TABLE
_________________________________________________________________
use master
go
drop proc sp_ddl_create_table
go
create proc sp_ddl_create_table
as
-- Creates the DDL for all the user tables in the
-- current database
select right('create table ' + so1.name + '(' + '
', 255 * ( abs( sign(sc1.colid - 1) - 1 ) ) )+
sc1.name + ' ' +
st1.name + ' ' +
substring( '(' + rtrim( convert( char, sc1.length ) ) + ') ', 1,
patindex('%char', st1.name ) * 10 ) +
substring( '(' + rtrim( convert( char, sc1.prec ) ) + ', ' + rtrim(
convert( char, sc1.scale ) ) + ') ' , 1, patindex('numeric', st1.name ) *
10 ) +
substring( 'NOT NULL', ( convert( int, convert( bit,( sc1.status &
8 ) ) ) * 4 ) + 1, 8 * abs(convert(bit, (sc1.status & 0x80)) - 1 ) ) +
right('identity ', 9 * convert(bit, (sc1.status & 0x80)) ) +
right(',', 5 * ( convert(int,sc2.colid) - convert(int,sc1.colid) ) ) +
right(' )
' + 'go' + '
' + '
', 255 * abs( sign( ( convert(int,sc2.colid) - convert(int,sc1.colid) ) ) -
1 ) )
from sysobjects so1,
syscolumns sc1,
syscolumns sc2,
systypes st1
where so1.type = 'U'
and sc1.id = so1.id
and st1.usertype = sc1.usertype
and sc2.id = sc1.id
and sc2.colid = (select max(colid)
from syscolumns
where id = sc1.id)
order by so1.name, sc1.colid
go
grant execute on sp_ddl_create_table to public
go
_________________________________________________________________
Q9.16: INT.PL
_________________________________________________________________
Background
Please find included a copy of int.pl, the interfaces file conversion
tool. It should work with perl 4 and 5, but some perl distributions
don't seem to support gethostbyname which you need for the solaris,
ncr, and vms file format.
You may need to adjust the first line to the path of perl on your
system, and may need to set the PERLLIB environment variable so that
it finds the getopts.pl module.
While it may not be 100% complete (e.g. it ignores the timeout field)
you're free to add any functionality you may need at your site.
int.pl -h will print the usage, typical invocation is
int.pl -f sun4-interfaces -o sol > interfaces.sol
Note that I can't offer any kind of support, but I welcome comments,
feedback, improvements, bug fixes, etc., just m...@beasys.com The usual
disclaimers apply.
Also, let me know whether it made your job easier, how often you use
it, and how much time you save by using it.
Code
#!/usr/local/perl/bin/perl
# $Date: 1995/11/04 03:16:38 $ - $Author: mm $
# $Id: int.pl,v 1.4 1995/11/04 03:16:38 mm Exp mm $
# convert a sun4 interfaces file to a different format (see @modelist)
# limitations:
# - does not handle tli/spx entries (yet)
# - drivers for desktop platform hard coded
# - no sanity checks (duplicate names, incomplete entries)
# - ignores extraneous tokens silently (e.g. a 6th field)
# - don't know whether/how to convert decnet to tli format
# - ???
require "getopts.pl";
sub usage
{
local(@token) = @_;
if (!($token[0] eq "short" || $token[0] eq "long"))
{
printf STDERR "Environment variable(s) @token not defined.\n";
exit (1);
}
print STDERR <<EOM;
Usage: $progname -f <sun4 interfaces file>
-o { $modetext1 }
[-V] [-v] [-h]
EOM
if ($token[0] eq "long")
{
print STDERR <<EOM;
where
-f <file> input file to process
-o <mode> specify output mode
(e.g. $modetext2)
-V turn on verbose mode
-v print version string
-h print this message
EOM
}
else
{
print STDERR "For more details run $progname -h\n";
}
exit(1);
} # end of usage
# FUNCTION NAME: parse_command_line
# DESCRIPTION: call getopts and assign command line arguments or default
# values to global variables
# FORMAL PARAMETERS: none
# IMPLICIT INPUTS: command line arguments
# IMPLICIT OUTPUTS: $inputfile, $mode, $verbose
# RETURN VALUE: none, exits (in usage) if -h was specified (help option).
# SIDE EFFECTS: none
sub parse_command_line {
&Getopts("f:o:hvV") || &usage("short");
$inputfile = $opt_f;
$mode = $opt_o;
$verbose = $opt_V ? 1 : 0;
print("$progname version is: $version\n"), exit 0 if $opt_v;
&usage("long") if $opt_h;
&usage("short") if ! $inputfile || ! $mode;
&usage("short") if ! grep($mode eq $_, @modelist);
} # end of parse_command_line
# FUNCTION NAME: process_file
# DESCRIPTION: parse file, try to convert it line by line.
# FORMAL PARAMETERS: $file - file to process
# IMPLICIT INPUTS: none
# IMPLICIT OUTPUTS: none
# RETURN VALUE: none
# SIDE EFFECTS: none
sub process_file {
local($file) = @_;
open(INPUT, "<$file") ||
die "can't open file $file: $!\nExit.";
local($line) = 0;
local($type, $prot, $stuff, $host, $port, $tmp);
print $os2_header if $mode eq "os2";
while (<INPUT>)
{
$line++;
# handle empty lines (actually lines with spaces and tabs only)
#print("\n"), next if /^\s*$/;
next if /^\s*$/;
chop;
# comments, strip leading spaces and tabs
s/^\s*//, print("$_$lf{$mode}\n"), next if /^\s*#/;
#s/^\s*//, next if /^\s*#/;
# server names
if (/^\w+/)
{
if ($mode eq 'sol' || $mode eq 'ncr'
|| $mode eq 'vms' || $mode eq 'nw386')
{
print "$_$lf{$mode}\n";
next;
}
elsif ($mode eq "os2")
{
$server = $_;
next;
}
else {
print "[$_]$lf{$mode}\n" if !(/SPX$/);
next;
}
}
if (/^\tmaster|^\tquery|\tconsole/)
{
# descriptions
# parse first whitespace delimited word and
# following space(s)
# quietly ignore any extraerraneous characters
# I actually tried to catch them, but - believe
# it or not - perl would chop off the last digit of
# $port. vvvv
# /^\t(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\d+)(.+)$/;
if (!(($type, $prot, $stuff, $host, $port) =
/^\t(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/))
{
print STDERR "line $line: unknown format: $_";
next;
}
#print ("line $line: more than 5 tokens >$etc<, \n"),
# next if $etc;
if (!($type eq "master" || $type eq "query"
|| $type eq "console"))
{
# unknown type
print STDERR "line $line: unknown type $type\n"
;
next;
}
if ($prot eq 'tli')
{
#print STDERR "line $line: can't handle tli",
# " entries (yet)\n";
# adjust to tli format
($layer, $prot, $device, $entry) =
($prot, $stuff, $host, $port);
print "\t$type tli $prot $device ",
"$entry$lf{$mode}\n" if $mode ne 'win3'
;
next;
}
if (!($prot eq "tcp" || $prot eq "decnet"))
{
# unknown protocol
print STDERR
"line $line: unknown protocol $prot\n";
next;
}
if ($mode eq 'sol' || $mode eq 'ncr' || $mode eq 'nw386
')
{
$ip = &get_ip_address($host, 'hex');
$hexport = sprintf("%4.4x", $port);
print "\t$type tli $prot $device{$prot} \\x",
"$prefix{$mode}$hexport$ip$nulls{$mode}\n";
next;
}
if ($mode eq 'vms')
{
$ip = &get_ip_address($host, 'dot');
print "\t$type $prot $stuff $ip $port\n";
next;
}
if ($mode eq 'nt386')
{
$type =~ tr/a-z/A-Z/;
print "\t$type=$sock{$mode},$host,",
"$port$lf{$mode}\n";
next;
}
if ($mode eq 'dos' || $mode eq 'win3')
{
next if $type ne "query";
print "\t${mode}_$type=$sock{$mode},",
"$host,$port$lf{$mode}\n";
next;
}
if ($mode eq 'ntdoswin3')
{
($tmp = $type) =~ tr/a-z/A-Z/;
# watch out for this local($mode) !!
# its scope is this BLOCK only and
# (within this block) overrides the
# other $mode!!! But we can still access
# the array %sock.
local($mode) = 'nt386';
print "\t$tmp=$sock{$mode},$host,$port",
"$lf{$mode}\n";
next if $type ne "query";
$mode = 'dos';
print "\t${mode}_$type=$sock{$mode},",
"$host,$port$lf{$mode}\n";
$mode = 'win3';
print "\t${mode}_$type=$sock{$mode},",
"$host,$port$lf{$mode}\n";
next;
}
if ($mode eq 'os2')
{
print " \"$server\" \"$type\" \"$sock{'os2'}",
",$host,$port\"\n";
next;
}
}
printf STDERR "line $line is ->%s<-\n", chop($_);
}
close(INPUT);
print $os2_tail if $mode eq "os2";
} # end of process_file
# FUNCTION NAME: print_array
# DESCRIPTION: print the array
# FORMAL PARAMETERS: *array - array to be printed, passed by reference
# IMPLICIT INPUTS: none
# IMPLICIT OUTPUTS: none
# RETURN VALUE: none
# SIDE EFFECTS: none
sub print_array {
local(*array) = @_;
foreach (sort keys %array)
{
printf STDERR "%-16s %s\n", $_, $array{$_};
}
} # end of print_array
# FUNCTION NAME: get_ip_address
# DESCRIPTION: get the ip address of a host specified by name, return it
# as a string in the requested format, e.g.
# requested format == 'dot' --> return 130.214.140.2
# requested format == 'hex' --> return 82d68c02
# In order to avoid repeated calls of gethostbyname with the same host,
# store (formatted) results of gethostbyname in array %map.
# FORMAL PARAMETERS: name of host, requested return type: hex or dot format
# IMPLICIT INPUTS: %map
# IMPLICIT OUTPUTS: none
# RETURN VALUE: ip address
# SIDE EFFECTS: maintains %map, key is host name, value is ip address.
sub get_ip_address {
local($host, $mode) = @_;
if (!$map{$host})
{
#print "calling gethostbyname for $host";
($name, $aliases, $addrtype, $length, @addrs) =
gethostbyname($host);
$map{$host} = join(".", unpack("C4", $addrs[0]));
if ($mode eq 'hex')
{
$map{$host} = sprintf("%2.2x%2.2x%2.2x%2.2x",
split(/\./, $map{$host}));
}
#print " - $map{$host}\n";
}
return $map{$host};
} # end of get_ip_address
$version = "\$Id: int.pl,v 1.4 1995/11/04 03:16:38 mm Exp mm \$";
$| = 1;
($progname = $0) =~ s#.*/##g;
@modelist = ('sol', 'ncr', 'vms', 'nw386', 'os2',
'nt386', 'win3', 'dos', 'ntdoswin3');
$modetext1 = join('|', @modelist);
$modetext2 = join(', ', @modelist);
# tli on solaris needs more zeroes
$nulls{'sol'} = "0000000000000000";
$nulls{'nw386'} = "0000000000000000";
$nulls{'ncr'} = "";
$nulls{'nt386'} = "";
# prefix for tli entries
$prefix{'sol'} = "0002";
$prefix{'nw386'} = "0200";
$prefix{'ncr'} = "0002";
$prefix{'nt386'} = "0200";
# protocol devices
$device{'tcp'} = '/dev/tcp';
$device{'spx'} = '/dev/nspx';
$device{'decnet'} = '/dev/tcp';
# socket driver names
$sock{'nt386'}="NLWNSCK";
$sock{'dos'}="NLFTPTCP";
$sock{'win3'}="WNLWNSCK";
$sock{'os2'}="nlibmtcp";
# linefeed's (^M) for the MS world
$lf{'nt386'}="";
$lf{'dos'}="";
$lf{'win3'}="";
$lf{'ntdoswin3'}="";
$lf{'os2'}="";
$lf{'vms'}="";
$lf{'sol'}="";
$lf{'ncr'}="";
$lf{'nw386'}="";
$os2_header = sprintf("STRINGTABLE\nBEGIN\n%s", " \"\"\n" x 10);
$os2_tail = "END\n";
&parse_command_line;
&process_file($inputfile);
&print_array(*map) if $verbose;
_________________________________________________________________
Q9.17: HOW TO ACCESS A SQL SERVER USING LINUX
_________________________________________________________________
Some time back, Sybase released a binary distribution of ctlib for
Linux. This is just the header and libraries files for ctlib only, not
dblib, not isql, not bcp, not the dataserver and not the OpenServer.
This was done as a _skunk works_ internal project at Sybase, for the
good of the Linux community, and not supported by Sybase in any
official capacity. This version of ctlib identifies itself as 10.0.3.
At the time, the binary format for Linux libraries was a format called
_a.out_. Since then, the format has changed to the newer, _ELF_
format. _ELF_ libraries and .o files cannot be linked with a.out
libraries and .o files. Fortunately, a.out libraries and .o files can
easily be converted to _ELF_ via the objdump(1) program.
Getting a useable ctlib for Linux isn't that easy, though. Another
compatibility problem has arisen since these old libraries were
compiled. The byte-order for the ctype macros has changed. One can
link to the (converted-to-ELF) ctlib, but running the resulting
executable will result in an error message having to do with missing
localization files. The problem is that the ctype macros in the
compiled ctlib libraries are accessing a structure in the shared C
library which has changed its byte order.
I've converted the a.out library, as distributed by Sybase to ELF, and
added the old tables directly to the library, so that it won't find
the wrong ones in libc.
Using this library, I can link and run programs on my Linux machines
against Sybase databases (It also can run some programs against
Microsoft SQL server, but that's another FAQ). However, you must be
running Linux 2.0 or later, or else the link phase will core dump.
This library is available for ftp at:
* ftp://mudshark.sunquest.com/pub/ctlib-linux-elf/sybperl.tar.gz
*
ftp://mudshark.sunquest.com/pub/ctlib-linux-elf/ctlib-linux-elf.tgz
is a compiled version of sybperl 2.0, which is built with the above
library. Obviously, only the ctlib module is in this distribution.
In order to use this code, you will need a Sybase dataserver, a Sybase
interfaces file (in the non-TLI format -- see Q9.16), a user named
_sybase_ in your /etc/passwd file, whose home directory is the root of
the distrubtion, and some application code to link to.
As far as an isql replacement goes, use sqsh - Q9.12.
One of the libraries in the usual Sybase distribution is a _libtcl.a_
This conflicts with the library on Linux which implements the TCL
scripting language, so this distribution names that library
_libsybtcl.a_, which might cause some porting confusion.
_The above conflict problem is addressed by SybPerl - Q9.4 and sqsh
- Q9.12 _
More information
See Q11.4.6 for more information on setting up DBI/DBD:Sybase
_________________________________________________________________
Q9.18: SP__REVROLES
_________________________________________________________________
/*
* DROP PROC dbo.sp__revroles
*/
IF OBJECT_ID('dbo.sp__revroles') IS NOT NULL
BEGIN
DROP PROC dbo.sp__revroles
PRINT '<<< DROPPED PROC dbo.sp__revroles >>>'
END
go
create procedure sp__revroles
as
/* Created 03/05/97 by Clayton Groom
creates a reverse engineered set of commands to restore user roles
*/
select "exec sp_role grant, " + u.name + ", " + s.name + char(13) +char(10) + "
go"
from master..syssrvroless,
sysroles r,
sysusers u
where r.id = s.srid
and r.lrid = u.uid
and s.name
u.name go IF OBJECT_ID('dbo.sp__revroles') IS NOT NULL PRINT '>>' ELSE
PRINT '>>' go
_________________________________________________________________
Q9.19: SP__REV_CONFIGURE
_________________________________________________________________
use sybsystemprocs
go
drop procedure sp__rev_configure
go
create procedure sp__rev_configure
as
declare @sptlang int /* current sessions language */
declare @whichone int /* using english or default lang ? */
if @@trancount = 0
begin
set transaction isolation level 1
set chained off
end
select @whichone = 0
select @sptlang = @@langid
if @@langid != 0
begin
if not exists (
select * from master.dbo.sysmessages where error
between 17015 and 17049
and langid = @@langid)
select @sptlang = 0
else
if not exists (
select * from master.dbo.sysmessages where error
between 17100 and 17109
and langid = @@langid)
select @sptlang = 0
end
if @sptlang = 0
begin
select "-- sp_configure settings"
= "sp_configure '" + name + "', "
+ convert( char(12), c.value)
+ char(13) + char(10) + "go"
from master.dbo.spt_values a,
master.dbo.syscurconfigs c
where a.type = "C"
and a.number *= c.config
and a.number >= 0
end
else
begin
select "-- sp_configure settings"
= "sp_configure '" + name + "', "
+ convert(char(12), c.value)
+ char(13) + char(10) + "go"
from master.dbo.spt_values a,
master.dbo.syscurconfigs c,
master.dbo.sysmessages d
where type = "C"
and a.number *= c.config
and a.number >= 0
and msgnum = error and isnull(langid, 0) = @sptlang
end
return (0)
go
_________________________________________________________________
Q9.20: SP_SERVERMAP
_________________________________________________________________
USE sybsystemprocs
go
/*
* DROP PROC dbo.sp_servermap
*/
IF OBJECT_ID('dbo.sp_servermap') IS NOT NULL
BEGIN
DROP PROC dbo.sp_servermap
PRINT '<<< DROPPED PROC dbo.sp_servermap >>>'
END
go
create proc sp_servermap (@selection varchar(10) = "ABCDEF")
as
/* produces 6 "reports" against all possible data in
master..sysdatabases
master..sysdevices
master..sysusages
sp_servermap help
produces a list of the six reports.
A subset of the complete set of reports can be requested by passing
an argument that consists of a string containing the letters of the
desired report.
This procedure was developed on 4.9.1 server. It will run on 4.8
and 10.0 servers, but it has not been verified that the results
produced are correct.
*/
declare @atitle varchar(40),
@btitle varchar(40),
@ctitle varchar(40),
@dtitle varchar(40),
@etitle varchar(40),
@ftitle varchar(40),
@stars varchar(40),
@xstars varchar(40)
set nocount on
select @atitle = "A - DATABASE SEGMENT MAP",
@btitle = "B - DATABASE INFORMATION",
@ctitle = "C - DEVICE ALLOCATION MAP",
@dtitle = "D - DEVICE NUMBER, DEFAULT & SPACE USAGE",
@etitle = "E - DEVICE LOCATION",
@ftitle = "F - MIRRORED DEVICES",
@selection = upper(@selection),
@stars = replicate("*",40)
if @selection = "HELP" begin
print @atitle
print @btitle
print @ctitle
print @dtitle
print @etitle
print @ftitle
print ""
print "select any combination of reports by entering a string of"
print "report letters as the argument to sp_servermap:"
print " sp_servermap acd"
print "will select reports A,C and D."
print "calling sp_servermap with no argument will produce all reports"
return
end
select @@servername, "Current Date/Time" = getdate()
select "Version" = @@version
if charindex("A",@selection) > 0
begin
print ""
print @atitle
select @xstars = substring(@stars,1,datalength(@atitle))
print @xstars
select db=substring(db.name,1,15),db.dbid,
usg.segmap,
segs = substring(" U",sign(usg.segmap/8)+1,1) +
substring(" L",(usg.segmap & 4)/4+1,1) +
substring(" D",(usg.segmap & 2)/2+1,1) +
substring(" S",(usg.segmap & 1)+1,1),
"device fragment"=substring(dev.name,1,15),
"start (pg)" = usg.vstart,"size (MB)" = str(usg.size/512.,7,2)
from master.dbo.sysusages usg,
master.dbo.sysdevices dev,
master.dbo.sysdatabases db
where vstart between low and high
and cntrltype = 0
and db.dbid = usg.dbid
order by db.dbid, usg.lstart
print ""
print"Segment Codes:"
print "U=User-defined segment on this device fragment"
print "L=Database Log may be placed on this device fragment"
print "D=Database objects may be placed on this device fragment by DEFAULT"
print "S=SYSTEM objects may be placed on this device fragment"
print ""
end
if charindex("B",@selection) > 0
begin
print ""
print @btitle
select @xstars = substring(@stars,1,datalength(@btitle))
print @xstars
select db=substring(db.name,1,15),
db.dbid,
"size (MB)" = str(sum(usg.size)/512.,7,2),
"db status codes " = substring(" A",(status & 4)/4+1,1) +
substring(" B",(status & 8)/8+1,1) +
substring(" C",(status & 16)/16+1,1) +
substring(" D",(status & 32)/32+1,1) +
substring(" E",(status & 256)/256+1,1) +
substring(" F",(status & 512)/512+1,1) +
substring(" G",(status & 1024)/1024+1,1) +
substring(" H",(status & 2048)/2048+1,1) +
substring(" I",(status & 4096)/4096+1,1) +
substring(" J",(status & 16384)/16384+1,1) +
substring(" K",(status & 64)/64+1,1) +
substring(" L",(status & 128)/128+1,1) +
substring(" M",(status2 & 1)/1+1,1) +
substring(" N",(status2 & 2)/2+1,1) +
substring(" O",(status2 & 4)/4+1,1) +
substring(" P",(status2 & 8)/8+1,1) +
substring(" Q",(status2 & 16)/16+1,1) +
substring(" R",(status2 & 32)/32+1,1),
"created" = convert(char(9),crdate,6) + " " +
convert(char(5),crdate,8),
"dump tran" = convert(char(9),dumptrdate,6) + " " +
convert(char(5),dumptrdate,8)
from master.dbo.sysdatabases db,
master.dbo.sysusages usg
where db.dbid =usg.dbid
group by db.dbid
order by db.dbid
print ""
print "Status Code Key"
print ""
print "Code Status"
print "---- ----------------------------------"
print " A select into/bulk copy allowed"
print " B truncate log on checkpoint"
print " C no checkpoint on recovery"
print " D db in load-from-dump mode"
print " E db is suspect"
print " F ddl in tran"
print " G db is read-only"
print " H db is for dbo use only"
print " I db in single-user mode"
print " J db name has been changed"
print " K db is in recovery"
print " L db has bypass recovery set"
print " M abort tran on log full"
print " N no free space accounting"
print " O auto identity"
print " P identity in nonunique index"
print " Q db is offline"
print " R db is offline until recovery completes"
print ""
end
if charindex("C",@selection) > 0
begin
print ""
print @ctitle
select @xstars = substring(@stars,1,datalength(@ctitle))
print @xstars
select "device fragment"=substring(dev.name,1,15),
"start (pg)" = usg.vstart,"size (MB)" = str(usg.size/512.,7,2),
db=substring(db.name,1,15),
lstart,
segs = substring(" U",sign(usg.segmap/8)+1,1) +
substring(" L",(usg.segmap & 4)/4+1,1) +
substring(" D",(usg.segmap & 2)/2+1,1) +
substring(" S",(usg.segmap & 1)+1,1)
from master.dbo.sysusages usg,
master.dbo.sysdevices dev,
master.dbo.sysdatabases db
where usg.vstart between dev.low and dev.high
and dev.cntrltype = 0
and db.dbid = usg.dbid
group by dev.name, usg.vstart, db.name
having db.dbid = usg.dbid
order by dev.name, usg.vstart
print ""
print "Segment Codes:"
print "U=USER-definedsegment on this device fragment"
print "L=Database LOG may be placed on this device fragment"
print "D=Database objects may be placed on this device fragment by DEFAULT"
print "S=SYSTEM objects may be placed on this device fragment"
print ""
end
if charindex("D",@selection) > 0
begin
print ""
print @dtitle
select @xstars = substring(@stars,1,datalength(@dtitle))
print @xstars
declare @vsize int
select @vsize = low
from master.dbo.spt_values
where type="E"
and number = 3
select device = substring(name,1,15),
vdevno = convert(tinyint,substring(convert(binary(4),low),@vsize,1)),
"default disk?" = " " + substring("NY",(status & 1)+1,1),
"total (MB)" = str(round((high-low)/512.,2),7,2),
used = str(round(isnull(sum(size),0)/512.,2),7,2),
free = str(round(abs((high-low-isnull(sum(size),0))/512.),2),7,2)
from master.dbo.sysusages,
master.dbo.sysdevices
where vstart between low and high
and cntrltype=0
group by all name
having cntrltype=0
order by vdevno
end
if charindex("E",@selection) > 0
begin
print ""
print @etitle
select @xstars = substring(@stars,1,datalength(@etitle))
print @xstars
select device = substring(name,1,15),
location = substring(phyname,1,60)
from master.dbo.sysdevices
where cntrltype=0
end
if charindex("F",@selection) > 0
begin
if exists (select 1
from master.dbo.sysdevices
where status & 64 = 64)
begin
print ""
print @ftitle
select @xstars = substring(@stars,1,datalength(@ftitle))
print @xstars
select device = substring(name,1,15),
pri =" " + substring("* **",(status/256)+1,1),
sec = " " + substring(" ***",(status/256)+1,1),
serial = " " + substring(" *",(status & 32)/32+1,1),
"mirror" = substring(mirrorname,1,35),
reads = " " + substring(" *",(status & 128)/128+1,1)
from master.dbo.sysdevices
where cntrltype=0
and status & 64 = 64
end
else
begin
print ""
print "NO DEVICES ARE MIRRORED"
end
end
set nocount off
go
IF OBJECT_ID('dbo.sp_servermap') IS NOT NULL
BEGIN
PRINT '<<< CREATED PROC dbo.sp_servermap >>>'
grant execute on dbo.sp_servermap to sa_role
END
ELSE
PRINT '<<< FAILED CREATING PROC dbo.sp_servermap >>>'
go
_________________________________________________________________
Q9.21: SP__CREATE_CROSSTAB
_________________________________________________________________
use sybsystemprocs
go
CREATE PROCEDURE sp__create_crosstab
@code_table varchar(30) -- table containing code lookup rows
,@code_key_col varchar(30) -- name of code/lookup ID column
,@code_desc_col varchar(30) -- name of code/lookup descriptive text
column
,@value_table varchar(30) -- name of table containing detail rows
,@value_col varchar(30) -- name of value column in detail table
,@value_group_by varchar(30) -- value table column to group by.
,@value_aggregate varchar(5) -- operator to apply to value being agg
regated
AS
/*
Copyright (c) 1997, Clayton Groom. All rights reserved.
Procedure to generate a cross tab query script
Reqires:
1. A lookup table with a code/id column and/or descriptive text column
2. A data table with a foreign key from the lookup table & a data value
to aggregate
3. column(s) name from data table to group by
4. Name of an aggregate function to perform on the data value column.
*/
set nocount on
if sign(charindex(upper(@value_aggregate), 'MAX MIN AVG SUM COUNT')) = 0
BEGIN
print "@value_aggregate value is not a valid aggregate function"
-- return -1
END
declare @value_col_type varchar(12) -- find out data type for aggre
gated column.
,@value_col_len int -- get length of the value colu
mn
,@str_eval_char varchar(255)
,@str_eval_int varchar(255)
-- constants
,@IS_CHAR varchar(100) -- character data types
,@IS_NOT_ALLOWED varchar(100) -- data types not allowed
,@IS_NUMERIC varchar(255) -- numeric data type names
,@NL char(2) -- new line
,@QUOTE char(1) -- ascii character 34 '"'
--test variables
,@value_col_is_char tinyint -- 1 = string data type, 0 = nu
meric or not allowed
,@value_col_is_ok tinyint -- 1 = string or numeric type,
0 = type cannot be used.
,@value_col_is_num tinyint -- 1 = numeric data type, 0 = s
tring or not allowed
select @IS_CHAR = 'varchar char nchar nvarchar text sysname'
,@IS_NOT_ALLOWED= 'binary bit varbinary smalldatetime datetime datetimn
image timestamp'
,@IS_NUMERIC = 'decimal decimaln float floatn int intn money moneyn
numeric numericn real smallint smallmoney tinyint'
,@NL = char(13) + char(10)
,@QUOTE = '"' -- ascii 34
-- get the base data type & length of the value column. Is it a numeric type or
a string type?
-- need to know this to use string or numeric functions in the generated select
statement.
select @value_col_type = st.name
,@value_col_len = sc.length
from syscolumns sc
,systypes st
where sc.id = object_id(@value_table)
and sc.name = @value_col
and sc.type = st.type
and st.usertype = (select min(usertype)
from systypes st2
where st2.type = sc.type)
--select @value_col_type, @value_col_len
select @value_col_is_char = sign(charindex( @value_col_type, @IS_CHAR))
,@value_col_is_ok = 1 - sign(charindex( @value_col_type, @IS_NOT_ALLOWE
D))
,@value_col_is_num = sign(charindex( @value_col_type, @IS_NUMERIC))
IF @value_col_is_ok = 1
BEGIN
if @value_col_is_char = 1
begin
select @str_eval_char = ''
end
else
if @value_col_is_num = 1
begin
select @str_eval_char = ''
end
else
begin
print " @value_col data type unnown. must be string or numeric"
-- return -1
end
END
ELSE --ERROR
BEGIN
print " @value_col data type not allowed. must be string or numeric"
-- return -1
END
-- template. first level expansion query.
-- result must be executed to generate final output query.
SELECT "select 'select " + @value_group_by + "'"
IF @value_col_is_char = 1
BEGIN
SELECT "select '," + @QUOTE + "' + convert(varchar(40), " + @code_desc_
col+ " ) + '" + @QUOTE + @NL
+ " = "
+ @value_aggregate
+ "(isnull( substring("
+ @value_col
+ ", 1, ( "
+ convert(varchar(3), @value_col_len )
+ " * charindex( "
+ @QUOTE
+ "'+"
+ @code_key_col
+ "+'"
+ @QUOTE
+ ", "
+ @code_key_col
+ " ))), "
+ @QUOTE + @QUOTE
+ "))'"
END
ELSE IF @value_col_is_num = 1
BEGIN
SELECT "select '," + @QUOTE + "' + convert(varchar(40), " + @code_desc_
col+ " ) + '" + @QUOTE + @NL
+ " = "
+ @value_aggregate
+ "("
+ @value_col
+ " * charindex( "
+ @QUOTE
+ "'+"
+ @code_key_col
+ "+'"
+ @QUOTE
+ ", "
+ @code_key_col
+ "))'"
END
SELECT "from " + @code_table + @NL
+ "select 'from " + @value_table + "'" + @NL
+ "select 'group by " + @value_group_by + "'"
-- end
go
_________________________________________________________________
Q9.22: UPD_STATS.CSH
_________________________________________________________________
#!/bin/csh
# ########################################################################
# #
# # SCCS Keyword Header
# # -------------------
# #
# # Module Name : update_stats.csh
# # Version : 1.8
# # Last Modified: 2/16/98 at 17:19:38
# # Extracted : 2/16/98 at 17:19:39
# # Archived as : <host>:/u/sybase/SCCS/s.update_stats.csh
# #
# ########################################################################
# upd_stats.csh
# ------------------
#
# Shell to update the distribution pages for each table in a database.
#
# Requires sqlsa (script w/ the proper isql login for dbo of a database)
# ex:
# #!/bin/csh -f
# isql -U<dbusr> -P<dbpw> -S<dbsvr> -w265 $*
# exit($$status)
#
# Author: FJ Lundy, 2/96
ARGS:
set progname = `basename $0`
if ($#argv != 2) then
goto USAGE
endif
set dbdb = $1
set parallel_jobs = $2
INIT:
# Declare intermediate files
set filebase = /tmp/$progname:r.-D$dbdb
set cmdfile = $filebase.sql
set awkfile = $filebase.awk
set tblfile = $filebase.tbl
set workflag = $filebase.working
set logfile = $filebase.log
set runningflag = $filebase.running
# Check for another running copy of this process
if ( -f $runningflag ) goto ERROR
# Set the running flag to prevent multiple copies of
onintr DONE
# Clean up from previous runs
rm -f $filebase.* >& /dev/null
# Set the "running flag" (this step must FOLLOW the "clean-up from previous
# runs" step!
touch $runningflag
# Which OS are we running on?
set os = `uname`
switch ($os)
case "IRIX":
case "IRIX64":
case "HP-UX":
set splitFlag = "-l"
breaksw
case "SunOS":
set splitFlag = "-"
breaksw
default:
echo "ERROR: $progname- Unsupported Os($os). Aborting"
exit(-1)
endsw
MAIN:
# Start the Log
rm -f $logfile
echo "$0 $*" > $logfile
echo "NOTE: $progname- (`date`) BEGIN $progname" >> $logfile
# Create the awk command file.
cat << *EOF* > $awkfile
\$0 !~ /^\$/ {
tblname = \$1
printf("declare @msg varchar(255), @dt_start datetime, @dt_end
datetime\n")
printf("select @msg = \"Updating Statistics for: Db(%s)\"\n", "
$dbdb")
printf("print @msg\n")
printf("select @dt_start = getdate()\n")
printf("update statistics %s\n", tblname)
printf("exec sp_recompile '%s'\n", tblname)
printf("select @dt_end = getdate()\n")
printf("select @msg = \"Table(%s)\"\n", tblname)
printf("print @msg\n")
printf("select @msg = \"\tstart(\" + convert(varchar, @dt_start
) + \")\"\n")
printf("print @msg\n")
printf("select @msg = \"\t end(\" + convert(varchar, @dt_end)
+ \")\"\n")
printf("print @msg\n")
printf("print \"\"\n")
printf("go\n\n")
}
*EOF*
# Create a list of tables to update the stats for
sqlsa << *EOF* | tail +3 | sed 's/^[ ]*//g' | cut -f1 -d\ > $tblfile
set nocount on
use $dbdb
go
select u.name + "." + o.name "Table",
sum((reserved_pgs(i.id, i.doampg) + reserved_pgs(i.id, i.ioamp
g)) * 2) "Kb"
from sysindexes i, sysobjects o, sysusers u
where (o.id = i.id) and (o.uid = u.uid) and (o.type = "U" or o.type
= "S")
group by u.name, o.name
order by Kb desc
go
*EOF*
# Split the files into equal-sized chunks based on the passed
# parameter for the number of parallelized jobs
@ ct = 0
foreach tbl (`cat $tblfile`)
@ i = $ct % $parallel_jobs
echo "$tbl" >> $tblfile.$i
@ ct = $ct + 1
end
# For each of the created table lists:
# 1) create TSQL, 2) set a work flag 3) background the job
@ i = 0
set all_work_flags = ""
foreach file ( $tblfile.* )
# Create the T-SQL command file
@ i = $i + 1
echo "set nocount on" > $cmdfile.$i
echo "use $dbdb" >> $cmdfile.$i
echo "go" >> $cmdfile.$i
awk -f $awkfile $file >> $cmdfile.$i
# Spawn a subshell and remove the working flag when done
# Log output to a log file commonto all threads. This can possibly cau
se
# lost information in the log file if all the threads come crashing in
# at once. Oh well...
set all_work_flags = ( $all_work_flags $workflag.$i )
touch $workflag.$i
(sqlsa < $cmdfile.$i >>& $logfile ; rm -f $workflag.$i) &
end
# Loop until all of the spawned processes are finished (as indicated by the
# absence of working flags
while ( 1 )
set num_working = `ls $workflag.* | wc -l`
if ( $num_working == 0 ) break
sleep 10
end # end-while: wait for work to finish
DONE:
rm $awkfile $cmdfile.* $tblfile $tblfile.*
rm $runningflag
echo "NOTE: $progname- (`date`) END $progname" >> $logfile
cat $logfile
exit(0)
USAGE:
echo ""
echo "USAGE : $progname <db> <# of parallel jobs>"
echo " Updates the distribution pages for each user and system table
in"
echo " the specified database."
echo "REQUIRES: sqlsa"
echo ""
exit(-1)
ERROR:
echo ""
echo "ERROR: $progname- This process is already running for $dbdb. Aborting"
echo ""
exit(-2)
# *EOF*
Q10.1.1: TECHNICAL NEWS
Volume 3, Number 2
May, 1994
_________________________________________________________________
Disclaimer: No express or implied warranty is made by SYBASE or its
subsidiaries with regard to any recommendations or information
presented in SYBASE Technical News. SYBASE and its subsidiaries hereby
disclaim any and all such warranties, including without limitation any
implied warranty of merchantability of fitness for a particular
purpose. In no event will SYBASE or its subsidiaries be liable for
damages of any kind resulting from use of any recommendations or
information provided herein, including without limitation loss of
profits, loss or inaccuracy of data, or indirect special incidental or
consequential damages. Each user assumes the entire risk of acting on
or utilizing any item herein including the entire cost of all
necessary remedies.
Staff
Principal Editor: Leigh Ann Hussey
Contributing Writers:
John Blair, James Gath, Karen Hogoboom, Jeff Lichtman, Steve Olson,
Benjamin von Ullrich, Elton Wildermuth, Sybase Engineering, Sybase
Tech Support Send comments and suggestions to:
SYBASE Technical News
6475 Christie Avenue
Emeryville, CA 94608
This issue of the SYBASE Technical News contains new information about
your SYBASE software. If needed, duplicate this newsletter and
distribute it to others in your organization. Keep this newsletter
with your SYBASE Troubleshooting Guide.
Get Certified!
A new program has been recently announced which will allow Sybase
customers, employees, partners and others to demonstrate official
competence in the SYBASE architecture and product set. The Certified
SYBASE Professional (CSP) Program is targeted at client/server
architects, designers, developers, systems and database administrators
and support engineers. The first CSP certification is the Certified
Sybase DBA. This certification program will be beta tested in North
America and the UK in January. Other likely certifications will
include Open Interfaces Developer, Application Developer and
Architect. Professional Services is working with Customer Services and
Support to ensure that Sybase offers a single integrated certification
program for both development and support professionals. For more
information contact Wendy Washington at Sybase, 510-922-0959, and ask
for the CSP Brochure.
Troubleshooting Guide Update
Troubleshooting Guide Goes Online
The new version of the Sybase Troubleshooting Guide is on its way! It
includes over 60 new error messages, as well as new and revised
material on many Sybase products. Due to the increasing amount of
information, it now comes in two volumes: a Server volumen, and a
Tools and Connectivity volume.
The new Troubleshooting Guide will be available in both paper and
electronic form. Both volumes will be included on the AnswerBase
CD-ROM support product. The Server volume will be included on the
first SyBooks CD-ROM publications product. Both AnswerBase and SyBooks
CDs will be available in Q3/Q4.
Mass updates of future versions of the Troubleshooting Guide will be
provided free of charge in AnswerBase and SyBooks formats. Paper
manuals will still be available for purchase (or print your own from
the electronic version!).
Getting Your Troubleshooting Guide Feedback
The goal of the Sybase Troubleshooting Guide is to help you better use
(and support) Sybase products, and to do so more self-sufficiently. To
accomplish this, we need your feedback. To this end, a mail alias
called tsg has been established. The intention of this alias is to
allow Sybase customers and employees to comment on the Troubleshooting
Guide by mailing t...@sybase.com with:
* Corrections
* Requests for specific additions
* Additions (i.e., written material)
* Comments about which sections are particularly helpful
* Comments about which sections are not clear
* Any other input you might have
tsg will not be a forum for answering questions best taken to
Technical Support, but will be your chance to make the
Troubleshooting Guide more useful for everyone who uses it.
The next issue of the Troubleshooting Guide will be slightly
different from previous issues. It will come in two volumes, a
Server volume, and a Connectivity volume, and will be released in
both hardcopy and electronic versions (Answerbase and SyBooks).
Sybase Support Publications is considering releasing future issues
of the Troubleshooting Guide only in electronic format; customers
are requested to mail t...@sybase.com to give us feedback on this
topic.
803 Error Installing from CD-ROM
Numerous customers have called about receiving 803 errors when they
try to install SYBASE products from CD-ROM. Here are the complete
instructions for such installations; please disseminate this
information as widely as you wish.
Step 1: Login as root.
Step 2: Mount the CD as a filesystem in a UNIX machine. The exact
mount
command differs between platforms. In the following examples,
* /dev/sr0 stands for your CD-ROM device name.
* /cdrom is a local directory you have created.
* mount usually exists in the /etc directory. You may have to cd
/etc before you can issue the command. Sun 4
# mount -rt hsfs /dev/sr0 /cdrom Sun_SVR4 (Solaris)
# mount -o ro -F hsfs /dev/sr0 /cdrom _DEC AXP OSF_
# mount -rt cdfs -o noversion /dev/sr0 /cdrom Be sure that the
directory is writable by the world, and large enough for the
install to complete! Don't forget to log out as root before
continuing installation. SYBASE software should be installed by
the sybase user in order for permissions to be set correctly. Step
3: After you have mounted the CD, go to the directory in which it
is mounted. Step 4: Run sybload -D, which is the disk-install
version:
% cd /cdrom % ls sybload sybimage % ./sybload -D sybload is an
executable; sybimage is the global file containing the suite of
products. sybload will prompt you for the file used for disk
installation. Step 5: Give it the name /cdrom/sybimage. From there
onward, the
process is the same as installation from tape.
Hanging, Sleeping, and the "Zombie" Process
What are the different states of SLEEP? When all processes are shown
as SLEEPING by sp_who except the one which issued the sp_who command,
how can a user tell the difference between hanging versus running
processes? What is a "zombie" process and how can it be dealt with?
Definitions
In pre-4.9.2 SQL Servers, the output of sp_who could be difficult to
interpret. Processes showed only one type of SLEEP status, "sleeping".
In System 10, and 4.9.2 Rollup 2115 and above, sp_who shows four types
of sleep along with the other possible statuses:
Value Meaning
----- -------
infected The server erred with a stack trace, and the process
got an error that would normally kill it. The process
is infected instead of killed.
background This process is in the background.
recv sleep The process is waiting for input from the client.
send sleep The process is waiting for a write to the client to complete.
alarm sleep The process is waiting for an alarm (usually means the
process is waiting for a waitfor command to complete).
lock sleep The process is waiting for a lock to be granted.
sleeping The process is waiting for something not listed above.
This is "normal" sleep.
runnable The process is not waiting for anything, and is ready
to run, but is not the currently running process.
running The process is currently running (in a multiprocessing
system, there can be more than one such process).
stopped The process is stopped. In ancient history (before
version 4.0.1), all processes stopped during a
checkpoint. Now the only time a process is in the
stopped state is when someone is using the kill command
on it.
bad status There is a bad value for the status of this process.
In uniprocessor hardware there can be only one process RUNNING and all
other processes are either SLEEPING or RUNNABLE. The next RUNNABLE
process gets scheduled to run after sp_who finishes. Processes sleep
for certain events like disk I/O, network I/O, alarm, etc. If all the
threads are shown as SLEEPING, at least one of them will become
RUNNABLE after an event on which the thread is waiting.
On a multi-processor machine, if more than one SQL Server engine is
started, you can see more than one thread in the RUNNING state. The
number of processes running can not exceed the number of SQL engines
running.
It is not possible to find out from sp_who output which client process
is hung waiting for Server response. But it is possible to find out if
any process (i.e. thread) is blocked by another by looking at the
"blk" field of sp_who. For more details please refer to the Commands
Reference Manual.
Before System 10 -- Night of the Zombie Process
Pre-System 10 SQL Servers can end up with "zombie" (unkillable
hanging) processes if the event on which a thread is sleeping never
happens. In this case, the thread does not run and cannot be killed.
This anomaly existed right from the first release of 4.0 SQL Server
until a recent Rollup of 4.9.2 (2115 and above).
The problem is that the SQL Server scheduler is non-preemptive. This
means that tasks cannot be put to sleep or woken up arbitrarily by the
SQL Server scheduler; all task context switching is done voluntarily
by running tasks.
Pre-System 10 SQL Servers handle attention through a signal handler
set up to catch OUT-OF-BAND data which sets a status bit in the PSS
(Process Status Structure). This is an asynchronous event. For
example: a task is about to go to sleep waiting for input, but the
client cancels the query with dbcancel(). If the signal handler sets
the bit between the time the task is going to sleep and the time it is
actually put to sleep, then the server task sleeps forever waiting for
the client to send some data, and the client sleeps waiting for the
server to acknowledge the cancel request. This is the well-known
"dbcancel problem." Another source of trouble can be a DBMS task in
the Server which is sleeping on a network I/O from a client that just
isn't there any more (maybe because somebody rebooted the PC on which
the front end was running).
This kind of task cannot be killed because:
* The task must be in RUNNABLE state so that the scheduler can
kill the task the next time it runs.
* The task cannot be preempted because its state is unknown.
To complicate the above scenario, if the eternally-sleeping task
started a transaction, it may potentially hold locks on different
pages. The only solution for older versions is to reboot the SQL
Server.
A Wooden Stake for the Zombie Process
As of the 10.0 SQL Server, and 4.9.2 SQL Server Rollup 2115 and above,
zombie processes can now be killed. The new kill command not only sets
the bit in the PSS as it used to, but also wakes up the task if it
determines that the task is sleeping in one of four states:
* waiting to receive something from the client, a common state
_(RECV SLEEP)_
* waiting for a send to be completed by the network service task
_(SEND SLEEP)_
* waiting on an alarm because user did a waitfor delay command
_(ALARM SLEEP)_
* waiting on a lock (resource, logical, semaphore, etc.) (LOCK
SLEEP)
This means that any task can be cleaned up properly as if an exception
has occurred while the task was running, provided the task is in one
of the RECV, SEND, LOCK and ALARM sleep states. The new kill command
can kill infected processes as well, also a new feature.
The kill command can almost instantaneously kill a task that is
sleeping on any one of the events except the fifth state: normal sleep
(where the task is waiting for a resource to post network or disk
I/O). This was true for older versions of SQL Server, and is still
true. The reason for this is that all sleeps except "normal sleep"
have well-known and well-understood backout paths; however, tasks
sleeping on resources have a variety of different backout paths.
The new kill command will:
* set the "kill yourself" bit on the task
* wake up the task normally
* put the task into the runnable queue
When the scheduler is ready to run the task it finds the "kill
yourself" bit and aborts the task. For tasks that are in normal
sleep or for running tasks, the new kill command acts exactly as
the old kill command: it sets the kill bit in the PSS and it is up
to the task to wake up and test the bit and decide to kill itself.
Note that this means that the new kill command may not have an
effect on all tasks.
NOTE! If a killed task is in the midst of a transaction, the entire
transaction will abort. All resource cleanup will occur in the task
backout path so that no inconsistent resources are left hanging around
that might cause the SQL Server to hang in a hibernating state and
eventually have to be rebooted.
There were regressions, caused by the new kill command's original
implementation, which could cause the server to hang (bug 51270) or
not completely kill the process under certain conditions (bug 48964).
These bugs were fixed as of Rollup 2359, and can be ordered from Tech
Support.
This fix is not available on the SQL Server NLM release for Netware.
Instead, Netware sites must use a different method for avoiding zombie
processes.
How to Eliminate Zombie Processes on SQL Server NLM
To eliminate Zombie processes from the Novell SQL Server:
1. Download from Compuserv, from the NOVLIB forum (Currently in
forum 1) the STRTLI.EXE file.
2. Execute the file STRTLI.EXE - this expands to 8 NLMs and 2
documents. The NLMs are: STREAMS.NLM, TLI.NLM, SPXS.NLM,
SPXLISFIX.NLM, SPXFSFIX.NLM, SPXSIX2.NLM, IPXS.NLM, and
PATCHMAN.NLM. The documents are: STRTLI.DOC and PCHMN230.DOC.
3. STRTLI.DOC contains instructions on how to load the files. Load
4.2.2 of the NLM SQL Server first, then the new files from Novell.
If you load SNLMINST after loading the new files, you will have
written over several of the new files and will need to reload
them.
DECnet Errors and Hanging Processes
This past spring, a customer running the 4.8 version of SQL Server for
VMS encountered a problem with hanging/sleeping server processes left
after network/router errors caused disconnects. A change in the AST
networking strategy for DECnet solved this problem (bug 40459 on VMS,
bug 38156 on AXP).
The behavior exhibited was that users would switch off their PC front
ends without properly logging out of connections to the SQL Server.
The Server would not deassign the channel and delete the mailbox on
error exit from its connection accepting system call. The customer's
router and the design of the client application caused so many errors
that the Server ran out of I/O channels.
Sybase Engineering modified the VMS SQL Server so that it now
deassigns the channel and deletes the mailbox after rejecting the
connection. This change, originally made in the System 10 release of
SQL Server, was back-ported to the 4.9.x codeline and is available as
part of the latest Rollup.
The Problem of Null Column Names
How does one refer, if at all, to an undefined column name resulting
from a select into of a built-in function? In 10.0 SQL Servers, NULL
column names are not allowed (see last issue's Special Supplement). In
earlier SQL Servers, when a name is defined as NULL in syscolumns the
following situation ensues:
1> select title_id, title, price, convert(varchar(30), total_sales)
2> into scratchdb..titletab
3> from pubs2..titles group by title_id, convert(varchar(30),
total_sales)
4> go
(18 rows affected)
This creates a table with four columns, one with no name. Attempts to
use the null name fail.
1> use scratchdb
2> go
1> create clustered index x on titletab (title_id, "")
2> with ignore_dup_row
3> go
Msg 102, Level 15, State 1:
Server `SYBASE', Line 1:
Incorrect syntax near ` `.
1> select convert (varbinary, name) from syscolumns where
id=object_id("ben")
2> go
--------------------------------------------------
0x636173656e756d
0x6c6f675f6964
0x74696d65696e
NULL
(4 rows affected)
In order to get around this problem, you may use sp_rename in an
intuitive way, to get rid of the NULL column name as follows:
1> sp_rename "titletab.", request_status
2> go
Column name has been changed.
return status = 0)
"Too Many Open Files" on Solaris
If you have a Sun_SVR4 (Solaris) SQL Server that reports the error
"Too many open files" from a kernel subsystem, you will need to change
the maximum number of file descriptors per process (NOFILES kernel
parameter on most systems). There are two ways to reset this value:
1. Modify your RUNSERVER script as follows, depending on your shell:
sh or ksh RUNSERVER script: ulimit -n ## csh RUNSERVER script:
limit descriptors ##
where ## = the new value for file descriptors
2. Run a program which calls setrlimit() to increase the
maximum number of file descriptors and then invoke a process
which requires a large number of fd's (file descriptors).
Here are a sample program and makefile called set_nofiles.c to show
you how to do this.
1. Build the executable by typing the command (assuming you
named the makefule set_nofiles.mk): make -f set_nofiles.mk
2. Run the executable by giving it the name of any program
to run along with its command line options, for example:
set_nofiles foobar x. You can have it run startserver -fRUNSERVER
or the dataserver program.
You must run the ulimit/limit or makefule commands as root in order to
set the maximum number of file descriptors > 1024.
Note: This Procedure is Documented Under System-10 SAG Supplement for
SunOS Release 5.x (SVR4) Page 4-1.
***************source for
set_nofiles.c**************************************
/* set_nofiles.c, set_nofiles, Customer Service group, 07/02/93 /*
routine to increase the maximum number of file descriptors per process
/* Copyright (c) 1993, Sybase, Inc., Burlington, MA 01760 /* All
Rights Reserved /*
/* TITLE: set_nofiles
/*
_/* START-HISTORY:_
/*
/* 02 Jul 93 edit 0 - Lance Andersen. /* Initial coding.
/*
_/* END-HISTORY_
/*
_/* START-DESCRIPTION:_
/*
/* set_nofiles is a program which can be run to execute the RUNSERVER
/* file (or any other executable) in order to increase in number of /*
file descriptors available per process inorder to avoid the OS /*
error EMFILE (Too many open files): /* To use this program:
/* Build as follows:
/* cc set_nofiles.c -o set_nofiles
/*
/* While logged in as root, set the following ownership and
permissions: /* chmod u+s set_nofiles
/* chown root set_nofiles
/*
/* To execute:
/* set_nofiles command
/*
/* When set_nofile executes, it will set the max file descriptors to
the /* value defined by the MAX_FD #define. The program will run under
root /* ownership while file descriptors are being changed and then
ownership /* will revert back to the user who invoked the program (in
order to /* prevent security breaches).
_/* END-DESCRIPTION_
/*
_/* START-DESIGN:_
/*
_/* END-DESIGN_
/*
_/* START-FUTURES:_
/*
_/* END-FUTURES_
/*
_/* START-CODE:_
*/
/*
**********************************************************************
*/ /* Define OS include files */ /*
**********************************************************************
*/
#include <stdio.h>
#include <ulimit.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <errno.h>
/*
**********************************************************************
*/ /* Define constants */ /*
**********************************************************************
*/
#define MAX_FD 3000 /* set max number of fd's per process (NOFILES) */
main(argc, argv)
int argc; /* Number of arguments */
char **argv; /* arguments */
{
struct rlimit rlim; /* soft & hard resource limits */
/* ****************************************************************** *
/
/* Set the maximum and current value for fd's per procesess (NOFILES) *
/
/* ****************************************************************** *
/
rlim.rlim_max= MAX_FD; /* hard limit */
rlim.rlim_cur= MAX_FD; /* soft limit */
if(setrlimit(RLIMIT_NOFILE, &rlim)==-1)
{
/* Oops, we failed, print error msg and OS error number */
fprintf(stderr,
"OS error %d encountered while changing RLIMIT_NOFILE to %d\n",
errno,MAX_FD);
exit(-1);
}
/* ****************************************************************** *
/
/* reset the uid to the user who invoked the program so that the *
/
/* process does not run as root. *
/
/* ****************************************************************** *
/
setuid( getuid() );
/* ****************************************************************** *
/
/* Now execute our program passing required arguments *
/
/* ****************************************************************** *
/
if(argc >1)
execv(*++argv, argv);
else
fprintf(stderr,"Warning, no argument passed to set_nofiles\n");
} /* END -- MAIN */
* Now the makefile *******
# set_nofiles.mk
#
# Makefile to create set_nofiles command # Note: to run the install
portion, you must be logged in as root
_DEFAULT_CFLAGS=_
_LIBRARIES= _
CFLAGS= -c $(DEFAULT_CFLAGS) $(EFFLAGS) _INCLUDE= _
OBJECT = set_nofiles.o
BUILD_NAME=set_nofiles
INSTALL_DIR=$(HOME)/bin
OWNER=root
#
# Default rule to delete, build and install set_nofiles #
all: clean build install
#
# Build the binary
#
build : $(OBJECT)
$(CC) $(OBJECT) $(LIBRARIES) -o $(BUILD_NAME)
#
# build the binaries
#
$(OBJECT): $(OBJECT:.o=.c)
$(CC) $(INCLUDE) $(CFLAGS) $<
#
# Remove all object files
#
clean:
rm -f $(OBJECT) $(BUILD_NAME)
#
# install the product
#
install:
cp $(BUILD_NAME) $(INSTALL_DIR)/$(BUILD_NAME); cd $(INSTALL_DIR);
chown $(OWNER) $(BUILD_NAME); chmod u+s $(BUILD_NAME)
_________________________________________________________________
Specifying TCP Port in System 10 for Solaris
A customer installing Sybase 10.0 on Sun_SVR4 (Solaris) ran into an
odd problem. With an original specification of TCP port 2000 for the
SYBASE Server process, the installation failed. When the port number
was changed to 2025, as shown in the example in the Install Guide, the
installation worked fine. The manual suggests that any port not
currently used between 1024 and 65535 can be specified -- what caused
this failure?
It appears that 2000 was listed in /etc/services. Round numbers like
2000, 6000, etc. are often used for network services. We recommend,
therefore, that you avoid using round numbers for your port numbers.
Solaris 2.3, Intimate Shared Memory, and Server EBFs Revisited
Sun Support has been passing along information to our mutual customer
base that either EBF 2592 or EBF 2594 are required, along with their
patch 101318-35+, to prevent certain system panics. As a result,
customers are calling Sybase Technical Support and requesting one of
these EBFs. Further, the 10.0.1 Server Release Notes claim that our
customers will need EBF 2594 and Sun's patch to prevent Sun OS panics
while running SQL Server. This article will clarify the issue and make
some important amendments to Sun Support's information.
The majority of customers will not encounter a problem after
installing only the Solaris patch. Most customers' Servers will boot
and run just fine. Customers who have memory configured to a value
near (or greater than) the physical memory on the machine may
experience problems. Generally speaking, very few customers fall into
this group, and those that do would probably be better off configuring
memory to a level that Intimate Shared Memory can again be used and
the old Server booted successfully (see Summary notes).
First, a word on Sybase's EBFs. There will be no EBF 2592 for 4.9.2.
The reason is that ISM use is not a feature of our 4.9.2 Server. The
only way ISM can be used is if the system forces all user applications
to use ISM. If that is the case, and the Sun patch has been applied,
the Server simply will not boot. In that case, disable this Solaris
kernel feature.
This is not the default behavior, and will only be an issue for
customers who have modified a system startup file to enable this
feature.
In a future 4.9.2 Rollup, we may add support for ISM use via this
Solaris feature. However, since this is a product enhancement rather
than a bug, there will be no one-off EBF.
The EBF for 10.0.1 will be EBF 2917, not EBF 2594 as was reported in
the 10.0.1 Release Notes.
Here are answers to some common questions about this issue, followed
by a summary.
Common Questions and Answers
Q: What is ISM and why is it important?
1. ISM (Intimate Shared Memory) is an enhancement in Solaris 2.X
which allows multiple processes to share certain low level data
structures in the Solaris Virtual Memory (VM) system. These data
structures are not normally shared and are used for
virtual-to-physical address translation. These translation
mappings are loaded into the hardware Memory Management Unit (MMU)
as required. Sharing these data structures means that less loading
and unloading of the MMU will be required during a context switch.
Depending on the number of engines which are running and the
overall system load, not having to load and unload the MMU can
have a considerable positive impact on performance.
One other benefit of using ISM is that the virtual memory is
actually locked into physical memory by the operating system. This
means that the Server has true control over what is in memory when
doing memory management. It also means that a user starting up an
editor or compiler won't steal memory from the Server resulting in
the operating system throwing the Server memory pages out to the
system swap space. Again, this can have a considerable positive
impact on Server performance.
2. I assumed that as long as the Server would start up (with the Sun
patch installed), we would see no more panics, regardless of
whether or not the EBF is installed. Is that correct?
3. If you have the Sun patch installed, this particular panic
condition will not occur. User applications such as our Server
aren't an issue. Our EBF is only required to allow for the change
in the shmat() system call behavior to allow the Server to boot.
4. Do you foresee any major system performance issues involved with
the _EBF?_
5. No. There may be two extra shmat() system calls at Server boot
time, the performance affect of which is negligible and only a
one-time occurrence. Of course, the Server may not use ISM in some
instances which will affect performance. For example, right now
the OS is letting you use ISM even when it can't lock down the
memory. It shouldn't do that because the system will later panic
when it tries to unlock the pages. However, you do get the
benefits of ISM at the cost of system panics. With Sun's fix, you
won't be using ISM as the system will be able to detect that it
can't lock down the memory. This could have a very visible impact
on performance. It is preferable to configure the Server to use an
amount of memory which will allow for ISM use. No Server EBF is
required in this case.
6. We have received and installed a patch from Sun 101318-35+ which
is supposed to fix Sun's half of the problem. The engineer with
whom I spoke said that the Sun patch would not stop the panics. He
said that only applying a Sybase EBF or changing an ISM
configuration parameter would stop panics.
7. This is incorrect. No user application can panic an OS. All our
EBF will do is to allow the Server to boot.The ISM parameter the
engineer referred to probably simply turns off ISM use altogether.
8. The Sun engineer said that the ISM configuration change would slow
Sybase performance appreciably and that another customer
experiencing the same bug had chosen not to make the change.
9. The only performance implication is that the Server won't use ISM
if the Solaris kernel cannot lock down the memory as it needs to
in order to prevent a later system panic.
It's a simple question of resources. SQL Server 10.0 can use an OS
feature such as ISM if the OS can supply the resource. Whether or
not the OS can supply the resource depends on how the Server is
configured. That is, you can't configure the Server to use 256MB
of memory on a machine with only 128MB of physical memory and
expect it to use ISM. If the Server won't start after installing
the Sun fix with a given memory configuration value, then decide
whether you want to decrease the memory to the point at which it
will still use ISM, or if you want to skip the use of ISM
altogether. If you choose the first option, you can use the stock
Server and Sun's patch and your system shouldn't panic unless
there are other Solaris bugs showing up. If you choose the second
option, then you probably need EBF 2594 (or 2917, depending on
your Server version).
You should certainly decide whether you want to use ISM or not and
configure memory usage accordingly. Sybase Technical Support
recommends configuring memory to a point where ISM can be used so
that the Server truly has control of paging activity.
Summary
In all cases, customers should install version 35 or later of Sun
patch 101318. If you are running version 4.9.2 of SQL Server, you must
not force ISM use through the Solaris kernel. If you are running a
System 10 Server and want to use ISM, you must configure the Server to
use an amount of memory that the Solaris kernel can lock into physical
memory. No EBF is needed in this case. If you would rather skip ISM
use and want to configure the Server memory to a value too large to be
locked down by the Solaris kernel, then you'll need EBF 2594 or 2917.
Generally speaking, it is preferable to configure the Server to use
ISM memory rather than running either EBF. If the non-EBF Server will
notÃ… boot after installing the Sun patch, the sp_configure value for
memory is set too high. To allow for ISM use and get the Server to
boot, configure the Server to use memory equal to 90 percent of the
physical memory in the machine. If the Server still will not boot,
decrease the requested memory in 10 percent increments until the
Server will boot.
Important Differences in Interfaces File, TLI vs.Sockets
Customers who receive the Release Bulletin for Solaris 2.x (SunOS
5.x), under the section 2.4 "Installation Compatibility" find the
following information:
2.4.3. Migration from SunOS 4.x(BSD) to SunOS 5.x(SVR4) Avoid sharing
interfaces files among servers and clients running on different
operating systems. If your SQL Server and all of the machines on your
network formerly ran on SunOS 4.x, the migration of some of the
machines to run on SunOS 5.x creates a heterogeneous network
environment.
The executable files created on SunOS 4.x will not run on SunOS 5.x,
and file locations and formats will be different. When you create an
interfaces file entry for a SQL Server running on SunOS 5.x, the
interfaces file is written in TLI format, and any existing entries in
the SQL Server's interfaces file are converted to this format. This
article will explain some of the implications of this Release Bulletin
entry.
On Sun4 the interfaces file entries look like this:
#
_SQLSRV_SUN4_
query tcp sun-ether barracuda 3060
> tcp sun-ether barracuda 3060
console tcp sun-ether barracuda 3061
On Solaris, they look like this:
#
_SQLSRV_SOL_
query tli tcp /dev/tcp \x00020bf482d6dcb8
master tli tcp /dev/tcp \x00020bf482d6dcb8
console tli tcp /dev/tcp \x00020bf582d6dcb8
The hex translates as follows:
\x | xxxxxxxx | xxxxxxxx | 0000000000000000
| port # | network node address | trailing zeros (optional)
In the above example, then, the port number would be 8383 (8384 for
console) and the network node address would be 193.749.884.72.
The conversion from "old" format to "new" or TLI format is done
automatically by sybinit. It even saves a copy of the old file. Bear
in mind that sybinit converts all the entries in the interfaces file,
so don't try to share the interfaces file between the "old" and the
"new" formats by making two entries in the file. The solution is to
have separate interfaces files as indicated below.
This is likely to be an issue only for customers that currently have a
homogeneous environment of all SunOS 4 (Solaris 1) when they upgrade
some hosts to SunOS 5 (Solaris 2). This upgrade will give such
customers a heterogeneous network environment. In other words, the
executable files from SunOS 4 will not run on SunOS 5, the locations
of files probably will be different, and the file formats probably
will also be different. You should be aware of this regardless of
applications you plan to run. This may also be noticed more from the
Client side than from the Server side.
For the Server side it should not be a problem. The installation and
conversion of interfaces file from SunOS 4 to SunOS 5 will be handled
by sybinit. The new format for specifying host addresses for TLI is
common on SVR4-based systems. If you have upgraded a host to SunOS 5,
you will already be familiar with this method for specifying
addresses.
If client workstations are not being upgraded to SunOS 5 at the same
time, client workstations must continue to execute SunOS 4 binaries
and also use the old-style interfaces file. When client workstations
are upgraded to SunOS 5, they will need to use the new-style
interfaces file along with their new binary executables.
Backup Server: Load from a Single Device of a Striped Dump
Backup Server customers may wonder if it is possible to do a striped
dump but then load from a single device. The answer is "yes", but only
when the dump is to tape or floppy devices and those devices are
local.
Specific steps to do this are:
1. Install the first tape to load and execute:
load database <dbname> from `/dev/nrst0'
2. Follow the prompts when Backup Server asks for subsequent
mounts, issuing sp_volchanged as appropriate.
sp_volchanged must be issued from a separate server login than the one
doing the dump or load. SQL Server is not set up to pause in the
middle of command execution, so the sp_volchanged command (which is a
separate command) must be issued by a separate server session.
Stripes may be loaded in any order, but if any stripe spans volumes,
the volumes of that stripe must be loaded in sequential order.
Backup Server Dump Tracking and Naming Strategies
Different sites use different strategies for tracking dumps on a
particular piece of media. One perfectly valid way is to put known
labels on a group of tapes, and recycle them over time. If you do full
dumps once a week, with transaction dumps in between, you could call
them "xxx.monday", "xxx.tuesday", etc.
How would you choose a particular dump to load? Use the file=name
qualifier on the load command. Even if you choose not to name files
when dumping, Backup Server prints the name of the file it mounts at
each dump. Customers can (and should) write them down for future
reference. You know which file to specify for the load because you
have a convention for naming files, and/or wrote down the name that
Backup Server printed. Here is a possible method:
1. On dump, input the following:
dump database foo to `/dev/nrst0' file='foo.dump'
2. Input the following to load:
load database foo from `/dev/nrst0' file='foo.dump'
Subsequent transaction files will be "foo.x.1", "foo.x.2", etc. (where
the "x" stands for "xact").
The Dangers of dump transaction with no_log
In the Commands Reference Manual, under dump transaction with no_log,
there is a warning message stating that you should only use this
command as a last resort. But what exactly does "last resort" mean?
What happens when you use the command? What should you use instead?
And finally, if this command is so bad, why does Sybase provide it?
Sybase Technical Support recommends that you dump your transaction log
regularly. You must determine the dump schedule by the amount of
logged activity your databases get, and how large your databases are.
Some sites dump transaction monthly; some sites dump transaction
nightly.
_NOTE!_
If you are running SQL Server 10.0, you may use sp_thresholdaction to
dump tran automatically before space becomes critical; additionally,
the Backup Server now ensures that tasks will not hang while dumps are
in progress. Please see your SQL Server Reference Manual for more
details. The remainder of this article applies only to sites running
pre-System 10 versions of SQL Server.
If you never dump transaction, the transaction log eventually fills
up. SQL Server uses the log for recovery purposes. When the log fills,
the server stops allowing transactions to go through, because it can
no longer write to the log, and the server cannot recover unrecorded
transactions. Inserts, updates and deletes hang. At this point, you
can't even run most of the dump tran commands, because SQL Server logs
these as well!
This is the "last resort" situation that dump transaction with no_log
was designed for. This command removes the inactive portion of the
log, freeing up log space and letting database changes proceed, by
writing no log records itself. This is why no_log runs when other dump
tran commands can't.
But think for a moment about the environment in which dump transaction
with no_log is designed to run. All the changes being made to the
database are hung. No transactions are occurring. So dump transaction
with no_log does no concurrency checking. If you use dump transaction
with no_log while changes are being made to the database, you run the
risk of corrupting the database. Most often, these are reflected as
813 or 605 errors.
To remove the inactive portion of the transaction log while changes
are being made to the database, use dump transaction with
truncate_only. This command is written to the transaction log, and it
also does the necessary concurrency checking.
Both of these commands have warnings associated with them, which can
be found in the Commands Reference Manual. Be sure that you understand
the warnings and the instructions that accompany them before you use
either command.
Sybase provides dump transaction with no_log to handle a very specific
emergency situation. To help ensure the integrity of your database,
you should use it only as a "last resort".
Hiding the isql sa Password from a ps Command
How do you run isql scripts without having to specify the -Ppasswd
option on the command line? Because the command line is visible from
the ps command, running isql -Ppasswd is a security breach. In newer
versions of SQL Server, we delete the password from the command line
by copying it into an internal buffer and setting the password in argv
to all blanks. Unfortunately, this technique does not work for all
versions of UNIX; some versions of UNIX give the program a copy of
argv, but display the original version in the ps output. Even on Sun,
our method of blanking out the password on the command line does not
provide security. If one uses the -c option with ps, it will print the
original command line, not the copy that was given to the program. ps
-e will show the password if it has been saved as an environment
variable.
There are two possible solutions to this problem, one for batched and
another for non-batched sessions, both requiring that the isql
password be saved in an external file.
Method 1: Non-batched Sessions:
1. Save the password in a file that is readable only by the owner,
as follows (you need type this one time only, from the command
line):
cat > scratchfile mypassword ^D chmod og-rwx,u+rw scratchfile
2. Run the session from the command line, or as a shell script:
isql -Uusername <<EOSQL `cat $passwdfile` use db go select ...
.
. go _EOSQL_
isql will prompt for a password. The "<<EOSQL" tells the script to use
all lines that follow as input to the isql command up to, but not
including the line that begins with "EOSQL".
Method 2: Batched Sessions:
1. Create the scratch file as described above, and set the
protections. Then run all scripts as follows:
cat scratchfile | isql -Uuser -i script-file-name
These methods should be secure enough for the majority of users, as
they have the following properties:
* The password never appears on the command line, which always seems
to be open to security breach.
* The location of the password will be known to anyone using ps, but
they cannot see it because the file permissions have been set
against them.
* Users can run as many scripts as they like without typing their
password for each script. All they must do is to follow the second
method for all script executions.
* The password is kept in a scratch file, privately controlled by
the programmer using that method.
* The programmer can change the password easily because it is
changed in one file only.
* The password is not hard-coded into script files which are shared
by an entire organization.
Indexing Null Columns = Poor Performance
Using an index on a column consisting of all (or mostly) NULLs causes
very poor performance.
Suppose you have a table with 638K rows x 200 bytes with an index on
an int column which is all NULL values. A select in this table, using
the index on the NULL column, takes over four minutes to say that no
value in this column matches the where clause. If you change just one
value from a NULL to a number, select takes only three milliseconds to
return, although inserts (and updates) still take exceedingly long.
This only happens with a clustered index on this column; if the index
is nonclustered, it seems to run fine.
A clustered index on over 600K rows of NULLs means that it is all on
overflow pages. These are sequentially scanned, since they are all the
same value. The long insert time is spent deciding where in the sea of
NULLs to put the next row. Any design that uses a clustered index on a
mostly NULL column should be reconsidered.
When an Index "Covers" a Query
Customers have asked if SQL Server will use an index to satisfy a
query if all the columns requested by the query are contained in that
index, rather than reading the columns from the data table.
As of the 4.9.2 release, a non-clustered index will be used when all
the columns of the table referenced in the query are in that index. In
such an instance, the index is said to "cover" the query. What this
means is that before the 4.9.2 release, an index would only be used
with a qualifying clause (such as a WHERE clause). This example is
from a production 4.9.1 version of SQL Server:
1> select au_lname from authors
2> where au_lname = "Ringer"
3> go
STEP 1
The type of query is SELECT
FROM TABLE
authors
Nested iteration
Index : aunmind
1> select au_lname from authors
2> go
STEP 1
The type of query is SELECT
FROM TABLE
authors
Nested iteration
Table Scan
Since 4.9.2, even a simple SELECT FROM table will use the index if the
SELECT is from an indexed column, as in this example from a production
4.9.2 version of SQL Server:
1> select au_lname from authors
2> go
STEP 1
The type of query is SELECT
FROM TABLE
authors
Nested iteration
Index : aunmind
4.9.1 SQL Server EBFs above 1690, that bring the Server to the 4.9.2
level, also have this feature.
If there is more than one index that covers a query, the smallest will
be used. Also, since a non-clustered index has at the bottom of its
tree one index row for each data row, the index will also be used for
a simple SELECT COUNT(*) FROM enormous_table query.
How to Generate Sequential Keys for Table Key Columns
Many customers wish to generate sequential, unique keys for a key
column in a particular table. The objective is simple, to be sure each
key is unique. This implies the following:
* The key must be updated by each user accessing it.
* The table containing the key must be locked during update, so
that no duplicates may occur. In System 10, you can both create
new tables with the new IDENTITY column, and add the IDENTITY
column to existing tables. The next issue of this newsletter will
explain this new column in more detail. For Server releases before
System 10, there are a number of possible methods for generating
sequential keys; this article will illustrate only one of the
possible options.
The basic idea here is to use one table as the storage area for
the sequential key as it is generated and modified. This key can
then be selected into a key column in the appropriate table.
For example, first create the storage table, which will contain
one column and one row:
1> create table KeyStorage (NextKey int) 2> go 1> insert
KeyStorage values (0) 2> go (1 row affected) Here is a sample
table that will be the eventual destination of the keys.
1> create table foo (key int, text char(5)) 2> go First, we update
the stored key, conveniently locking it against other users in the
process:
1> begin tran 2> go 1> update KeyStorage set NextKey = NextKey + 1
2> go (1 row affected) A simple check shows the table is now
locked (this list has been edited slightly to save space -- many
other locks may exist):
1> sp_lock 2> go spid locktype table_id page dbname
_____________________________________________________________
1 Ex_page 5 894 master ... 1 Ex_table 640005311 0 foo (26 rows
affected, return status = 0) 1> select object_name(640005311) 2>
go
_____________________________________________________________
KeyStorage (1 row affected)
Now you can select the new key safely, and insert it into the target
table:
1> declare @newkey int
2> select @newkey = NextKey from KeyStorage
3> insert foo values (@newkey, `test')
4> go
(1 row affected)
Remember to commit tran!
You can test to be sure the insert worked:
1> select * from foo
2> go
key text
----------- -----
1 test
(1 row affected)
You can generate the new key by stored procedure, thus giving at least
reasonable assurance that the key continues to be incremented by one.
Put the begin transaction statement in the stored procedure -- SQL
Server will remind you that you must commit the transaction "by hand":
1> create procedure get_newkey as
2> begin tran
3> update KeyStorage set NextKey = NextKey + 1
4> go
1> exec get_newkey
2> go
Msg 266, Level 16, State 1:
Server `REL492_SUN4', Line 1:
Transaction count after EXECUTE indicates that a COMMIT or
ROLLBACK TRAN is missing. Previous count = 0, Current count = 1.
(return status = 0)
1> declare @newkey int
2> select @newkey = NextKey from KeyStorage
3> insert foo values (@newkey, `test2')
4> go
(1 row affected)
(1 row affected)
1> commit tran
2> go
1> select * from foo
2> go
key text
----------- -----
1 test
2 test2
(2 rows affected)
Other portions of this method may be automated as desired by the more
meticulous DBA, but the basic method remains simple and
straightforward.
Timestamps Will Roll Over
Tech Support customers asked us, "Is the value of a timestamp
guaranteed to be monotonically increasing within a database?"
These customers wanted to use a timestamp field to identify rows that
have changed since the last time they looked, with a where clause like
where timestamp > @previous_timestamp.
The wanted just to add a timestamp field to their existing tables, so
that SQL Server would maintain the values, and they wouldn't have to
change any of their own code to identify newly inserted/updated rows.
(Deleted rows would need to be treated differently.)
The answer is that the timestamp is not guaranteed to increase
indefinitely. A timestamp is a 56-bit integer that will eventually
roll over, though it takes a very long time to do so. The only numbers
that won't roll over are ones with unbounded storage; there is no such
datatype in SQL Server.
However, Sybase does guarantee that if the row has changed, the
timestamp will differ from the one in the cached copy of the row.
SQL Monitor Client/Server and SQL Server Compatibility
The following table is a compatibility matrix for various SQL Monitor
Client, SQL Monitor Server and SYBASE SQL Server versions.
SQL Monitor Client | SQL Monitor Server | SYBASE SQL Server
UNIX -- sqlmon | |
PC -- servmon.exe | monserver | dataserver
=================================================================
any UNIX version 10.0.1 | 4.9.1 | 4.9.1 or 4.9.2
-----------------------------------------------------------------
any UNIX version 10.0.2* | 4.9.1 | 4.9.1 or 4.9.2
-----------------------------------------------------------------
PC version 10.1.0 | 4.9.1 | 4.9.1 or 4.9.2
-----------------------------------------------------------------
PC version 10.1.2* | 4.9.1 | 4.9.1 or 4.9.2
-----------------------------------------------------------------
any UNIX version 10.0.1, | 10.0.0 | 4.9.1, 4.9.2 or 10.0.0
10.0.2
(monserver 10.0.0 can monitor a 4.9.x SQL Server but must have
a SQL Server 10.0.0 directory installed)
-----------------------------------------------------------------
PC version 10.1.0 | 10.0.0 for Sun4, | 4.9.1, 4.9.2, or 10.0.0
| Solaris, NCR, AIX |
(this row not certified but can connect)
(monserver 10.0.0 can monitor a 4.9.x SQL Server but must have
a SQL Server 10.0.0 directory installed)
_________________________________________________________________
PC version 10.1.0, 10.1.2| 10.0.0 EBF 2714, | 4.9.1., 4.9.2, or 10.0.0
| HP only |
(this client will now connect) |
-----------------------------------------------------------------
PC version 10.1.2* | 10.0.0 for Sun4, | 4.9.1, 4.9.2, or 10.0.0
| Solaris, NCR, AIX |
-----------------------------------------------------------------
any UNIX version 10.0.1, | 10.0.1* | 10.0.1*
10.0.2 | |
-----------------------------------------------------------------
PC version 10.1.2 | 10.0.1* | 10.0.1*
* = available Q2, '94
The current PC SQL Monitor Client is not certified against any 10.0.0
SQL Monitor Servers. There are pieces of data that are unmonitorable
with this configuration, for example the Device I/O and Network
Traffic graphs in the Performance Summary and Performance Trends
windows will display `0'. The PC SQL Monitor Client 10.1.2 (due in May
1994) addresses this and will be certified against 10.0.0 Monitor
Servers.
The version of Monitor Server should go hand in hand with the version
of SQL Server. If you need to monitor a 10.0.1 SQL Server, get a
10.0.1 Monitor Server; use a 4.9.1 Monitor Server to monitor a 4.9.x
SQL Server.
* HP Monitor Server 10.0.0 EBF 2714 enables PC clients to
connect successfully to it.
* Solaris Monitor Server 10.0.0 EBF 2715 enables re-starting
of the Monitor Server while remote client connections are still
connected to it.
* AIX Monitor Server 4.9.1 EBF 2496 corrects a problem
resulting in 100% CPU usage.
* HP Monitor Client 10.0.1 EBF 2507 eliminates dependency on
libC.sl.
The following table shows combinations that will not work, nor are
they intended to:
SQL Monitor Server | SYBASE SQL Server
_________________________________________________________________
4.9.1 | 10.0.0 (this combination may work, but is not certified)
_________________________________________________________________
4.9.1 | 10.0.1
_________________________________________________________________
10.0.1 | 10.0.1
_________________________________________________________________
10.0.1 | 4.9.x or 10.0.0
SQL Monitor Memory Allocation
SQL Monitor Client, upon initial start-up, may cause a noticeable
strain on heavily loaded SQL Servers or SQL Servers configured for
large size. The strain is due to the client trying to construct the
Memory Allocation Chart that occurs by default on UNIX clients and
upon request on PC clients.
New connections to the SQL Server may hang, currently running tasks
may temporarily hang, and the SQL Monitor Server may automatically
shut down, on the assumption that the SQL Server has also shut down.
See the following information to prevent this automatic shutdown.
If this strain is noticeable and unacceptable, then request that the
Memory Allocation Chart not be created.
* For UNIX clients: invoke sqlmon with the -nomem flag on the
command line.
* For PC clients: do not select the Obtain memory allocation
check box option.
Additional Command Line Options for UNIX & VMS
To prevent SQL Monitor Server from automatically shutting down, the
time interval that the SQL Monitor Server checks to see if the SQL
Server is active needs to be increased. The default configuration is
120 seconds. To change the interval, you must use an undocumented
monserver command line parameter (which is supported, and will be
documented in upcoming releases of the manual).
* For UNIX, the parameter is -L<config file>, where <config
file> is a file in the current directory that contains only this
line:
heartbeat_interval nn where nn is a value in seconds.
* For VMS, the parameter is /localconfig=<config_file> where
<config_file> would have the same line in it:
heartbeat_interval nn
For example, to start up a SQL Monitor Server that will poll every 10
minutes for the presence of its SQL Server, the UNIX command is:
monserver -Usa -Ppassword -MMON_1001 -SSYB_1001 -n5 -0 \
-Lmonserver_config_file &
where monserver_config_file has the following line in it:
heartbeat_interval 600
One drawback to using a large time interval is that when the SQL
Server actually does shut down, the SQL Monitor Server will remain
running longer, and will be holding onto the SQL Server's shared
memory segment. You may need to shutdown SQL Monitor Server manually
in order to start SQL Server again.
Net-Gateway Security
Administrators considering the issue of Net-Gateway Security must ask
themselves two questions:
First, do I want to pass some flavor of userid and/or password to the
Mainframe? And second, if so, which userid and password should be
passed?
First of all, you can pass a userid and/or password to the mainframe
over Net Gateway via the sgw_addrpc stored procedure:
exec sgw_addrpc rpc_name, tran_id, remote_lu, security
The security parameter has one of these three values:
* none -- no userid or password will be passed to CICS.
* userid -- userid only will be passed to CICS.
NOTE! If you specify userid and you are running the Net-Gateway
on OS/2, be aware of the interaction with OS/2's Communication
Manager. Examine the NFG file (in the \cm\appn subdirectory)
that describes your network to the Communication Manager; check
the DEFINE_PARTNER_LU entry corresponding to your host and be
sure that the configuration allows CONV_SECURITY_VERIFICATION
with the right remote LU.
o both -- both userid and password will be passed to CICS.
So, having chosen userid or both under the security parameter, you are
ready to decide which userid (and, optionally, which password) is to
be passed. There are three possible choices, two associated with user
login, and one with transaction grouping. Notice the syntax of the
following procedures:
exec sgw_addlog login, <-- source-1
pwd, <-- source-1
host_login, <-- source-2
host_pwd, <-- source-2
tran_group, con_group, gwctrl
exec sgw_addtrngrp tran_group,
group_login, <-- source-3
group_pwd, <-- source-3
langrpc, langpwdlevel
exec sgw_addrpctogrp tran_group,
rpc_name, rpcpwdlevel
Method 1: Taking userid/pwd from "source-1"
If the Net-Gateway is started with the -O flag ("security Override"),
the identifying information passed to the mainframe will be taken from
the login and pwd columns of the user's Net-Gateway login record. That
is, the identification by which the user logged onto the Net-Gateway
(or upstream SQL Server, if any) will be propagated to CICS.
Notice that all discussion involving "transaction grouping" or
"connection grouping" -- that is, the security enforcement machinery
of Net-Gateway itself -- becomes irrelevant when the security override
is in effect. All security enforcement is deferred downstream to the
mainframe (and upstream to the SQL Server, if any).
Method 2: Taking userid/pwd from "source-2"
If the Net-Gateway is started without the security override flag, each
user must be associated with a "Transaction Group" in order to execute
any RPCs on the Net-Gateway. The transaction group is tied to the user
via sgw_addlog.
RPCs are tied to the transaction group via sgw_addrpctogrp. Specify
user as the rpcpwdlevel when you add an RPC to the transaction group,
if you wish to pass on the values in the host_login and host_pwd
columns from the user's login record as userid and password.
Method 3: Taking userid/pwd from "source-3"
Specify "group" as the rpcpwdlevel when you add an RPC to the
transaction group, if you wish to pass on the values in the host_login
and host_pwd columns from the user's login record as userid and
password.
Special Case: The Language RPC
The Language RPC is executed whenever a user request is not an
explicit RPC request. none, user, or group must be specified as the
langpwdlevel when the Language RPC is associated with a transaction
group via the sgw_addtrngrp stored procedure.
Omni SQL Server and RMS Locking Strategy
It is important for customers to understand the manner in which Omni
SQL Server accesses RMS files, since often Omni SQL Server is used in
an environment where other processes are accessing the same files Omni
SQL Server is expected to access.
When Omni SQL Server requires access to an RMS file, Omni SQL Server
must first determine which access and share modes to use before it can
open the file. Two separate attempts are made by Omni SQL Server
before an open failure is reported. The first attempt is performed
with all RMS access and share modes enabled, as follows:
access = FAB$M_SHRGET | FAB$M_SHRPUT | FAB$M_SHRDEL | FAB$M_SHRUPD;
share = FAB$M_GET | FAB$M_PUT | FAB$M_UPD | FAB$M_DEL | FAB$M_TRN;
If the file cannot be opened using these access modes, then a second
attempt is performed with the following access and share modes
enabled:
access = FAB$M_GET;
share = FAB$M_SHRGET;
If this access mode fails, then the open attempt will fail and Omni
SQL Server will not be able to use the file.
(In the above statements, access corresponds to an element in an RMS
data structure called the File Access Block, or FAB. The element is
named fab$b_fac. share corresponds to the element named fab$b_shr in
the FAB).
Once a successful open request has been performed on a file, the
access and share modes are cached in memory so that the second time
the file is opened, Omni SQL Server will not have to establish them
again.
It should be noted that this has nothing to do with the configuration
parameter read regardless. This parameter determines Omni SQL Server
behavior after a file has been opened, and an Omni SQL Server thread
is attempting to read a record from that file. If read regardless is
enabled (set to `1'), then Omni SQL Server will be able to read a
record even if it is locked for exclusive use by another VMS process.
Please refer to the Omni SQL Server System Administration Guide,
Chapter 6, for a discussion of this configuration parameter.
Bugs Fixed in Latest Rollup for 4.9.2 SQL Server
The following is a list of bugs which have been fixed in recent EBF
Rollups for the 4.9.2 SQL Server. (The EBF# at the top of each list is
for the Sun4 platform.)
The current EBF Rollups available now are: Platform | Rollup Number
_________________________________________________________________
Sun4 | 2825
HP 9000 Series 800 | 2826
IBM RS6000 | 2827
NCR SVR4 | 2828
VMS | 2829
Sun SVR4 | 2830
AXP VMS 1.5 | 2831
Previous Rollups, released since the previous issue of Sybase
Technical Newsletter, are specified in the tables below and consist
of: Platform | Rollup Number
_________________________________________________________________
Sun4 | 2359, 2560
HP 9000 Series 800 | 2360, 2561
IBM RS6000 | 2361, 2561
NCR SVR4 | 2362, 2563
VMS | 2363, 2564
Sun SVR4 | 2364, 2565
AXP VMS 1.5 | 2365, 2566
This list is not inclusive; only the fixes new and specific to this
release, and introduced since the last publication in Sybase Technical
Newsletter, are included. Some bugs which do not visibly affect
product behavior have been omitted from this list for clarity. This
information is also available on Insight and the OpenLine Sybase
Compuserve forum.
Bug Fixes New to Rollup 2359-2365
Bug#
Description
51270
`Process infected with 11' error can occur when using kill for a
process which has a status of `send sleep'. 51269
Error: 5150, Severity:16, State:1, occurs during attempts to switch
from a failed mirrored device to good secondary device. 50912
If a table contains at least 2 BIT-type columns and at least 1
NULL-able column, the SQL Server will fail to send the table's log
information to the Replication Server.
50543
If a server process dies when it has created a worktable, and locks
have not been acquired on the worktable yet, the server can generate a
stack trace and shut down.
50263
RPC causes multiple IO's thru one socket. This was causing corruption
of the TDS stream.
50111
Writetext fails with 1127/1129 errors.
50075
When using isnull(rtrim(""),"TEST") we just get the first letter "T"
instead of "TEST". This problem has been reproduced on System 10 GA
50029
Any correlated subquery containing a min or a max aggregate in the
inner subquery on a binary or char type fixed column will not return
correct rows when doing a join using the same table in the outer and
inner query.
49958
Error 804 occurs when a non-sa user who belongs to a group that has
been granted CREATE DATABASE permission issues create database
command.
49790
System stored procedure, sp_spaceused, returns an arithmetic overflow
on large tables, for example: 600000 rows, 70 meg. 49734
Group by with lower on varchar column values returns an incorrect
number of rows.
49295
Process infected with 11 error during null text update. The update
statement will cause Segmentation violation 49294
If the table has text column and a unique nonclustered index, then the
direct mode update to that text field will result in 644 error. 49177
A regression produced by bugfix 44623 broke `disk remirror'. 49082
Error 8402 when using a union and a view that references another view
on another database.
49065
When run, sp_reportstats receives: "Msg 232, Level 16 State 11: server
`server name', Procedure `sp_reportstats', Line 67: Arithmetic
overflow error for type varchar, value=0.003090. Arithmetic overflow
occurred." 49011
When a POLLNVAL error is received, the polling fd is not removed and
this can result in continuous errors being sent to the errorlog for
the same fd.
49005
Server does not prevent a raw mirror device from being used to mirror
two primary devices.
49002
When a non-clustered index is chosen for a temp table, index name is
not getting printed in the `showplan' output. 48964
Kill command does not work for tasks that are not sleeping under one
of the valid conditions. The old semantics allowed these processes to
get killed provided they woke up.
48882
@@rowcount does not have correct value for an update statement when
the update involves a join, and @@rowcount is referenced upon entering
an update trigger. The value is much higher than the actual number of
rows updated.
48505
Frequent POLLERRs are reported in the errorlog. Error handling needs
to be enhanced inorder to explain cause of error. 48273
Msg 611 "Attempt made to end a transaction that is idle or in the
middle of an update" when an attempt to create a temp table (from
within a stored procedure) aborts on an interrupt. Happens for alter
table which involves temp table from within a sproc. 48169
After a LOAD TRANS is performed, the value of the generation ID of the
log records sent to the Replication Server should be preserved and not
reset to zero.
48034
When dropping and recreating the temp table, any store procedure using
that table will not be able to find it during opt/compile time and
thus using the default values for number of rows and columns. Bug:
Range table must be updated to the new tmp_def_id. 47989
Certain queries take significantly longer to compile under 4.9.1/4.9.2
compared with production 4.8, as a result of many more join strategies
being considered.
47984
Server can kill process or otherwise mishandle connection if cancel is
received while sending data to client.
47909
Speed up communication with a remote server (at the expense of i
ncreased network traffic) by setting the TCP_NODELAY flag. This fix is
only applicable to operating systems using sockets, not TLI. 47826
Buildmaster -m now requires -s option also. If it is not given,
installmaster cannot run because it cannot alter master db on master
device.
47694
During weekly dump to disk file, dump database task hangs. No errors
are reported.
47614
When the PROBE process is invoked from a task running on a
single-engine server which is both participating in, and is the commit
server for, a distributed transaction, then the server may go 100% CPU
bound and all user activity on the server will hang. 47361
Server stacktraces on the qry 1)create table t(a float) 2)select
str(avg(a)) from t. This because we are adding an implicit conversion
node between two same type of nodes (FLT8). This happens for `real'
datatype also.
47354
When 512 error is raised and a dynamic index has been built, the
current process is infected with 11, errors 605/6103 are raised during
the rollback in tempdb. Any further attempt to access the tempdb page
listed in the 605 error will return an 813 error. 47300
After receiving an 823 error (IO error) on a disk read, 605 errors
occur thereafter whenever the same page is accessed. 47298
Certain doubly-nested subqueries can result in the thread being
infected.
47294
Grant/revoke fails with stack trace and kills process when the same
user is included twice in the user list. e.g., grant execute on sproc
to user1, user1. Server should be more friendly to user than killing
him & dumping ugly stack to errorlog.
47129
noobhandler has a forever loop which can fail to terminate if ioctl
doesn't return the expected value. We should also check for no data on
the socket.
46896
Group by on 16 columns and distinct expression in the select list on
17th column causes error 415 to be raised 46629
Upgrading from 1225 to 1614, get more logical read on worktable for
the same query. Applies to OR strategy when only one row qualifies.
46059
When a create index deadlocks, the descriptor information (doampg,
first, root) may not be restored properly, leading to 605 errors.
44635
If a table exists with multiple bit columns, and an update trigger is
tied to one of the bit columns, an update to any of the bit columns
will cause the trigger to be fired.
44598
Getting Msg 806 and stack traces when doing "commit tran". 44129
Bugid 24506 has caused regression by raising 157 error even for
standard queries
43990
If enough objects are created in a d.b. to cause the root page of
index ncsysobjects to split, and then sp_dboption for autotrunc log is
issued against that d.b., and the server is rebooted before checkpoint
in d.b., dropping objects results in 644 errs. 43427
Getting Msg 1265 followed by Msg 804 and stack trace when trying to
delete or update tables with non-clustered indexes. 42459
An application using two dbprocs concurrently can become blocked
eventhough the two tasks hold compatible locks. sp_lock will show that
the second task is blocked by a (compatible) lock held by the first
task.
41886
Msg 8412 and stacktraces when using "create table" and "select for
browse" statements in the same batch..
37006
Message 5704 is getting printed even if the client and server
character-sets are same and they don't need char-set conversion. This
should be suppressed in those situations. 36524
Sysindexes First entry is not accurate. 33871
smalldatetime does not accept format <num> <sep> <num> <sep> etc. that
datetime does, in an implicit convert. gets syntax error. 32183
"the statement ""create clustered index index_name on table (column)
with sorted_data, allow_dup_row"" generates error 1508 and does not
create the index when a duplicate row is encountered" 31915
A select query with union having a compute list at the end gives Msg
411.
27640
Queries containing correlated subqueries other that IN or ANY that
appear under an OR get incorrect results if there are no matching rows
from the outer query.
27452
SELECT INTO from a user table to a temporary table that converts a
character column datatype to a tinyint datatype results in an "intn -
length 1" datatype which is incorrect. It should be a tinyint. 17271
An aggregate query that does an `exists' subquery will sometimes
return the wrong answer if there are duplicates. 13495
In many cases, we process subqueries as joins where it gives the wrong
answer. Existence checks should not be done as joins - they return
dups where they should not, and the construction OR x in (select a
from b) will not work when b is empty.
Bug Fixes New to Rollup 2560-66
Bug#
Description
53601
I/O errors can lead to infected processes or erroneous 821 errors.
53118
Allow for load to continue with a warning message if the dump was done
prior to bugfix #52181, stop the load otherwise. 52943
Modification to bugfix #51454 to handle str(-0.483700,10,2) correctly
on hp800, ncr_svr4, avms & vms platforms. 52850
Recompiling a stored procedure which creates a table results in a 3703
error with stack trace.
52530
On tli based platforms, clients can hang after receipt of a POLLERR,
POLLNVAL or POLLHUP on any connected socket. It is also possible that
no new logins will be accepted.
52447
Update Message #277 to reflect bugfix 19418. 52406
During OAM cleanup, pages being unlinked and deallocated are not
unkept resulting in 803 errors, stack traces & the need for a server
reboot. 52332
gets message kernel: nrpacket: t_rcv(). no message currently
available. The site handler hangs and no further rpcs can be made.
52181
4308 errors(State: 4), intermittently occur when doing a load
transaction or load database. This can only happen if the dump was
made when the server was very active.
52179
A server panic (ulowncheck) occurs if a load transaction is done while
running the diagserver.
52060
When recompiling a system stored procedure while in a user database,
the sysdepends table in the user database gets updated instead of the
sysdepends table in the master database. 51959
Site handler tasks may hang under heavy RPC load between Open Server
and SQL Server. This can result in all logical connections hanging.
51946
Modification to bugfix #51454 to handle str(float) correctly. 51893
If the SQL/LTI thread has reached the end of the log and is sleeping
waiting for more log records to be written, a timeslice error will
occur if the SQL/LTI client receives a network attention. 51892
The VMS implimentation of the SQL Server's Replication Server Support
Facility (RSSF) does not correctly set the internal SQL Server bitmap
which indicates to the RSSF which log records should be sent to the
Replication Server.
51804
Correct stack trace produced by calling a stored procedure which
performs a select from a view based on a database in another database.
51725
A space in an image column of a `bcp' file causes a NULL to be
inserted into the table. Subsequent deletion of row(s) from that table
will result in 605 errors. The deletion operation should be done
before the update to the text/image column.
51701
The process that holds the update page lock also holds an ex_page
lock. This is sets up a deadlock case.
51595
Modifications to datetime.h to include some ot the new defines.
Required for bugfix #51191.
51508
If the server process dies when executing a query with an OR that
creates a worktable, a stack trace occurs and the server shuts down.
51454
The str() function has been re-written to give percission of upto 6
decimal places.
51240
Return status from optlookip() was not correctly checked. As a result,
the parser was considering anything after the constant token as an
option.
51215
In rollup 1790, certain kinds of aggregate subqueries, with one or
more views, may generate a different access plan. Typically, table
scans are generated inspite of a useful index being present.
Performance of such queries can be very slow.
51191
Modify millisecond arithmetic from 1/300th of a second precision to
1/1000th of a second.
51174
SQL Server error 513 can occur upon Domain rule checking. This will
Only occur if there is an implicit server datatype convertion between
the datatype to insert and the datatype for the column referenced
within the table.
51072
Timeslice errors will occansionaly occur while compiling and executing
queries. A typical stack trace will have s_mustrecompile in the stack
frame.
50911
Unbalanced transactions occur in the syslogs table at times when a
stored procedure is recompiled. This can cause the replication of the
database via the replication server to fail. 50786
When estimating the cost for join density, we want to exclude NULL
values if any keys in the set is NULL. This will make the selectivity
much smaller for a table that has a lot of NULL key-rows and thus
optimizer will use index instead of table scan. 50783
Correct several 821 & 605 error situations by saving page hdr before
calling bufpagedestroy().
50781
Errors 226, 277 & 266 have been reported when running a stored
procedure that calls another one which has been dropped then
recreated.
50499
Initialize the "victim" when using trace LOCKM,4. 49653
Network checking delays can occur on heavily used servers even if the
platform supports SIGPOLL notification. 49505
Fix to do proper `round'ing when the number of integral digis in
numeric_expr is equal to the negative of the number specified in the
integral_expr (eg. round(5550.00, -3)). 49010
REUSEADDR should not be set in nopen(), as we are not specifying the
local address for the new endpoint; it is being chosen for us by the
network provider.
49009
The event handling code after the t_accept() in nopen() is flawed. It
doesn't recognize when the currently active connection request has
disconnected and can thus result in issuance of a t_accept which won't
be successfull.
49008
The event handling code after the t_listen() in nopen() is flawed. It
incorrectly assumes that a disconnect event will clear the currently
alloc'd T_CALL struct which results in another t_alloc, wasting the
initial con_req and T_CALL struct.
49007
The errors reported within nopen() are not clear and cause alarm at
customer sites without lending insight into the problem. 48886
When processing connection requests, no further polling should occur
on a given listener endpoint until all current connection requests
have been satisfied.
48197
When the server multiplies a negative floating point number to a
floating point zero, it evaluates to a negative floating point zero
and stores it in the row. Subsequently, all qualifier with positive or
negative floating point zero fails to select row 47615
A large sproc contains a syntax error towards the end (missing , on
2nd to last field in insert statement) isql fails to report any errors
and does not create the sproc
47301
The linger option is not set on client sockets resulting in loss of
data if the server closes the connection before the client has
finished receiving sent data.
44329
With a very heavy update load on the system, it is possible for alll
processes accessing a particular database to hang on disk i/o. This
may occur more frequently if the DB has the `trunc. log on chkpt'
option turned on.
43595
Certain selects with subqueries can result in infected processes.
39688
Correct 203 error (sysdatabases not found) when `ins_syn_sql is run.
36963
If `select *' is present in both aggregate subqueries participating in
an OR clause, the we seem to combine both of them together even if
they reference different tables. This produces incorrect results in
some situations.
Bug Fixes New to Rollup 2825-31
Bug#
Description
54191
Temporary tables are not automatically dropped when a stored procedure
returns. This may cause 2714 errors.
54126
When the SQL Server re-uses some structures it is possible that Msg.
7134 errors may occur.
53896
The upgrade application needs to be modified to not perform the
upgrade of the `upgrade version' to `493' until the actual maintenance
modifications are made.
53699
Added missing or modified error messages to upgrade.c as reported in
bug 52666. Included: 305,595,596,2778,2780,6108,6227,8010,7719,
17965,17966. Also verified 9119,9139,9141,9123,9138,9137,4403. 53603
Errorlog gets "kernel: nrpacket: t_rcv(), No message currently
available"
53563
[REPSRV] Add comments to `include/trace.h' which document existing
LTUTIL trace flags.
53494
This problem is observed for triggers getting renormalized immediately
after load database which results in the updating of sysprocedures
being done in the same user transaction 53492
Cannot print the stack of a sleeping process. 53356
SQL queries using text/image column in a where clause which is part of
an OR clause can cause 7134 or 804 errors. Example: select id from
table1,table2 where txtcol not like "% " or intcol not null. 53234
The SQL Server unexpectedly unreserves the database's LTCONTEXT while
the LTM is still actively scanning the database's log. A 9120 SQL
Server error will be generated causing the LTM to shutdown. 53163
select col1, diff1 = sum(datediff(dd,col2,@var1)), diff2 =
sum(datediff(dd,col2,@var2)) from tab group by col1" produces the same
value for both of the sums when run from a stored procedure. Also
sometimes fails for adhoc queries.
53068
Certain XACTs generate duplicate key errors when applied to the
replicant SQL Server (via the Replication Server) even though the same
XACT did not generate duplicate key errors when originally applied to
the primary SQL Server.
53053
Exceptions generated while within the RPC relay code could cause a
signal 10 in the user process. This was most noticeable in the
handling of the attention signals (CTRL/C).
52870
os_create_keyfile should have enhanced error messages to better
explain what "Segment {segmentname} is in use" means. It should better
reflect a conflict that could involve removing these files if the
server is not currently running due to an
52705
In file instmsgs.ebf, for message 6227 there is a typo in line which
drops message from german catalog. It has been written as 6627. 52704
When a st.proc references a view, and the view/underlying table is
dropped and recreated, executing the st.proc can result in wrong
columns being returned.
52695
Server crashes due to stack corruption and stack guardword corrupted
message while trying to do select into a table from a view whose
underlying table is dropped and recreated with different schema. 52666
Provide new 277 error message text for upgrade. 52651
The SIGURG & SIGIO is set for all processes within the same process
group instead of just the server process. 52629
During update of a text col if error 7105 is raised we print
"TEXT/IMAGE page 0 does not have a next page, although it should"
based on pnextpg field. We should rather print the page # which has
the problem (broken text chain).
52371
Attention packets received while processing multiple connection
requests can lead to the scheduler process becoming infected. Stack
trace output shows signal 11 occuring in nmskget called from
nrecvattn.
52268
insert into table1 select string from table2 order by table2.column
inserts bogus characters into table1 when there is a clustered index
on table2.column
52199
Improper synchronization of cancel processing with outstanding I/O's
could result in channel closure before I/O completion. 52190
1129 errors may occur due to a MP window in page allocation. 52129
Assuming procedure proc1 call proc2 and view view1 is built on view2.
when ownership chain is not broken, explicit revokation on proc2 will
raise error 229 when user executes proc1, while after explicit
revokation on view2 user can still select on view1. 52059
Data translation for type float between certain platforms (depending
on byte-swapping) is done incorrectly and gives unexpected results.
52030
Dumping database to disk can be aborted with "dbsspacket, write
interrupted system call" message.
51785
When using a order by or a group by clause that creates a work table
and the query has an assignment to a local variable the server crashed
and kills the session.
51712
MP Configurations use clock interrupt to periodically wakeup secondary
engines to find work. However, since clock interrupts are tied to
actual CPU time consumed, secondary CPU's which are idle are not woken
up as often as required.
51389
When a smalldatetime is used in a rule, the rule may work incorrectly,
by either reporting a rule violation when there should not be, or not
reporting when there should be.
51287
Incorrect arguments are passed to ex_callprint routine to report error
7220 "Site `%s' not found in interfaces file." resulting in cryptic
message "Error: 72, Severity: 20, State: 11". Error 502 must have the
same problem.
47467
With an empty table that has an index on a char column, if the sort
order is changed on the server and then dbcc reindex is run, an error
is received on the subsequent select indicating that the index is
suspect. If table has a row then all is fine 47049
Share memory segment sizes on IBM AIX 3.2 are limited to 256MB, this
limits the maximum size of memory that Sybase can use on a machine.
45962
If an insert or update query that has a subquery which can return
null, the query inserts or updates columns that are not supposed to
have null.
41730
"kernel: nspacket: send, Invalid argument" messages in the errorlog.
34889
821 error is not useful, and renders server unusable. 821 often occurs
after 605 errors and prevents other user processes from obtaining a
free page.
26285
Trigger attempts to query inserted/deleted table for textdata using a
builtin "datalength" leading to a 605 error. This is no corruption but
the user connection gets disconnected.
22150
Correlated subqueries returning count(*) do not return values where
the count is zero.
Q10.1.2
Technical News Volume 3, Number 3 August, 1994
Document ID 50005-1-0300-03
This issue of the SYBASE Technical News contains new information about
your SYBASE software. If needed, duplicate this newsletter and
distribute it to others in your organization. Keep this newsletter
with your SYBASE Troubleshooting Guides. All issues of the Sybase
Technical News and the Troubleshooting Guides are included on the
AnswerBase CD.
IN THIS ISSUE
* Technical Support News/Features
+ Communicating with Technical News Staff
+ How to Get the SYBASE Technical News
+ Technical Support Customer Satisfaction Survey
* SQL Server
+ Avoiding Server Catastrophe
+ Changing Sort Order Manually When sybinit Fails
+ sysdevices `status' Control Bits
+ Use Database Hanging After Upgrade
+ Float and Money Display Methods
+ Disk Mirroring Clarification
+ Limitation on RPCs Called from Threshold Procedures
+ Backup Server Context Allocation Errors
+ TLI Address Translation Addendum
+ OpenVMS Mount from CD-ROM
+ Sybase Compatibility with RAID
+ SYBASE Async I/O and RAID
+ Certification Issues
+ bcp Programming and Paging
* Connectivity / Tools / PC
+ SQL Monitor Server and ceventbuf
+ SQL Monitor Cheat Sheet
+ Special Notes for PC Users - SQL Monitor Client
+ SQL Monitor Incompatibility Table
+ Corrections to NetWare Installation Manual
+ Recommended list of NLMs to Load for NetWare 3.11
+ Recommended List of NLMs to Load for NetWare 3.12
+ Correction to NetWare "Zombie" Article
+ Changes in PC Open Client/C Packaging
* Certification and Bug Reports
+ Bug 54192/34245 - Optimizer
+ The Nature of the Bug
+ Bug 55721 - sp_estspace
+ Bug 56619 - sp_columns
_________________________________________________________________
Communicating with Technical News Staff
There is now a mail alias through which both customers and Sybase
employees may contact the Sybase Technical News team. Send mail to
tech...@sybase.com to make suggestions or to submit articles. At
present, due to legal issues, we are only accepting article
submissions from Sybase employees; however, we welcome ideas for
articles from everyone.
The tsg alias, announced in Volume 3 Number 2, is a similar channel
set up for the Troubleshooting Guide. Customers and employees can
comment on the Troubleshooting Guide with corrections, additions, and
other input. As with the tsg alias, technews is not a place to mail
questions that would better be asked of Technical Support. Please call
1-800-8-SYBASE to contact Technical Support.
How to Get the SYBASE Technical News
The SYBASE Technical News is automatically distributed to all
registered Sybase support contacts. If you are one of your company's
registered support contacts, and you do not receive this newsletter
directly, please call Customer Service at 1-800-8-SYBASE to correct
this.
Whether or not you are a Sybase support contact, if you would like to
receive your SYBASE Technical News in text format by email, send mail
to tech...@sybase.com to be added to the automatic distribution list.
You will receive your newsletter by email at the same time as copies
are distributed to comp.databases.sybase and the Sybase OpenLine forum
of CompuServe.
If you would like to receive hard copy of the SYBASE Technical News
and are not a registered support contact, you may order it from Sybase
Customer Fulfillment, as you do other documents. U.S. and Canadian
customers may call 1-800-685-8225 or fax 1-617-229-9845. International
customers with a U.S license agreement may use the fax number; all
other international customers should contact their Sybase subsidiary
or local distributor. Ask for document ID 50005-1-0300-03 (this
issue). Document ID numbers for future issues will change by volume
and issue number, for example:
* 50005-1-0300-04 is volume 3 number 4
* 50005-1-0400-01 is volume 4 number 1
Back issues prior to Volume 3 are not currently available; indeed,
much Technical News information is volatile in nature, and items
printed in very old issues may well be out of date.
Technical Support Customer Satisfaction Survey
Since August 1993, Customer Service and Support (CS&S) has been
sending monthly case closure satisfaction surveys to customers who
have used Technical Support services. About 23 percent of these
customers have responded to the surveys, and we appreciate your
willingness to do so. Some of the responses have included questions
about what we are doing with your feedback and suggestions. We will
try to answer those questions in this article.
Your ratings from the questions asked are entered and tabulated at the
end of each month. We then compile statistical reports to give us a
general picture of how we are doing relative to each of the service
attributes addressed in the survey. We also distribute the returned
surveys to a review team comprised of Technical Support Engineers, who
review each month's returns for consistent and critical narrative
comments. These comments give us additional data about attributes
addressed in the survey, and provide data about attributes that we do
not specifically address. The combined general picture and narrative
comment data is used by the review team to recommend specific
corrective actions to CS&S management. Some of the recommendations
made by the review team are taken directly from suggestions given in
the survey responses. CS&S management reviews and prioritizes the
recommendations and acts on the according to their priority. We have
already begun to implement improvements based on those
recommendations.
The statistical reports indicate that 80 percent of you are generally
satisfied with the support that you receive. We are pleased, because
this is significantly better than we were doing a year ago. However,
your written comments identify areas where we can and will further
improve our support to you.
In future issues of this newsletter, we will be providing more
specific information on actions we are taking in response to your
feedback, so stay tuned. In the meantime, please keep the feedback and
suggestions coming.
Avoiding Server Catastrophe
Server catastrophe is the inability to recover from a database failure
in a timely manner or the inability to recover at all. If your
business relies on your SQL Server being operational, then you must be
prepared for situations in which your database, your major tables, or
your entire Server fail.
Familiarize yourself with the backup and restore commands and
procedures for your SQL Server. The documentation provided with your
SYBASE software is a good starting point. In particular, make sure
that you read chapters within the System Administration Guide
concerning the use of dbcc commands and procedures for recovering a
lost master device or lost master database.
This article contains a checklist of some important precautions that
should be taken in order to avoid a server catastrophe.
SQL Server is a large and sophisticated piece of software. It is not
within the scope of this article to describe all possible failure
scenarios. However, we hope to help you avoid some of the most common
failures that have been reported to the Sybase Technical Support
Response Team (the team responsible for handling the most urgent
customer SQL Server problems).
Checklist
* Can you rebuild your master database from scratch
* Can you rebuild your user databases from scratch
* Can you rebuild your largest index in each database
* Can you be certain that your backups are good
* Would your backups be useful in the event of a failure
* Will your system automatically warn you of problems
* Are your devices mirrored
If you answered "no" to any of the questions above or you are
uncertain of the answer or uncertain as to the reason for their
importance, then you are at risk of experiencing a Server catastrophe.
The following sections of this article will help you to answer "yes"
to all of the questions listed above. They will also go some way in
describing why you should be able to answer "yes" to every question.
Can you rebuild your master database from scratch
There is a large quantity of important information stored in your
master database including information about the master database
itself! There are also many ways to lose your master database and the
backups that you have kept so carefully. As an example, consider this
real-life scenario:
You have just spent the entire day (12 hours) creating new databases
for your developers. Among other things, this procedure involved
setting up devices, logins, passwords, and a number of modifications
to the sp_configure parameters. You dutifully back up all of your work
by doing a database dump of your master database, then leave for home.
When you return the following morning, you discover two things: (1)
your System Administrator accidently repartitioned the disk on which
your master device was created, and (2) the tape on which you stored
last night's backup was overwritten by the same person because he
"couldn't find another tape to use."
Keep up-to-date hard copies of the following tables:
* sysdatabases
* sysusages
* sysdevices
* syslogins
It's also a good idea to use the bcp utility to keep on-line copies of
these tables. Be sure to use the -c option of bcp; the resulting
output is human-readable. An additional reason to use the -c option is
that the output can sometimes be reloaded straight into a freshly
created master database, but you will need to delete some rows before
using bcp to reinsert the information, and this can only be done to
output generated under the -c option. These rows are:
* syslogins: row for the sa login
* sysdatabases: rows for master, model, tempdb, sybsystemprocs
* sysusages: rows for master, model, tempdb
* sysdevices: the row for master device
Keep a hard copy of your sp_configure parameters (and, optionally, the
output from buildmaster -yall). This is usually not critical, but a
hard copy could save you lots of headaches when you try to regain the
optimized performance you spent hours attaining.
Can you rebuild your user databases from scratch
Can you rebuild your largest index in each database
Some seemingly simple errors can be corrected only by dropping and
re-creating objects or dropping and re-creating your entire database.
Plan for it.
Issue #1 - size of database
If your database is too large to back up effectively, consider going
to the expense of setting up a "hot backup" server. As soon as a dump
tran is completed on your production server, it is immediately loaded
onto a duplicate server via a load tran. If your production server
fails, your "hot backup" server immediately becomes your production
server. Ideally, your "hot backup" server should be located on a
separate machine.
Sybase's Replication Server is also a option in this situation. With
Replication Server, you have the added benefit of automated backups.
Issue #2 - size of objects within database
Try to ensure that none of your tables are so large that you would not
have time to re-create/restore it before your users demanded that the
system be available.
If your current database design includes any table so large that you
can't rebuild it before the next business period, you might consider
breaking it into separate tables based on some part of the information
already being stored in one or more of the table columns. This may not
be feasible for some installations, but we strongly recommend that you
look for information within the table that is static and that, with
some redesign, can be isolated. Once the static information is
isolated, backing up that information is a one-time issue. When
failure occurs, it will happen in a much smaller table and can be
handled much more easily.
Issue #3 - disk space
Ideally, you should have enough free disk space that you could
replicate your largest database. This may be necessary in situations
where a failing device makes it impossible to produce a good database
dump, but you need to retrieve as much of the information within the
database as possible. The fastest solution could be to create a new
database and use the select into command to move the information from
the original database to the new database. The original database can
then be dropped and the new database renamed, using the sp_renamedb
stored procedure.
At the very minimum, it is desirable to have enough free space within
each of your databases to rebuild your largest index (see your System
Administration Guide for details on how to calculate this space).
Can you be certain that your backups are good
Your backups are not useful if they contain corruption.
For performance reasons, consistency checks are not performed during
the dump of a database. A database dump can appear to have completed
successfully, and still contain corruption. The corruption won't
become apparent until you do a load database.
Make sure that you perform dbcc checks regularly. Ideally, you should
be checking your entire database immediately before each backup. dbcc
checks should contain all of the following checks:
* dbcc checkdb(database_name)
* dbcc checkalloc(database_name)
* dbcc checkcatalog(database_name)
Reviewing the output of your dbcc checks can also be automated to some
degree (see "Scanning the Error Log Automatically" below).
If your database is too large to be checked before each backup,
consider using one of the following methods:
1. Perform dbcc checktable and dbcc tablealloc instead of dbcc
checkdb and dbcc checkalloc, respectively. Identify tables that
are more volatile than others and check those tables more
frequently.
2. Perform dbcc checks on a duplicate database. This could be either
a "hot backup" server or a one-off copy of the database.
3. If an individual table is too large for regular checking, consider
redesigning your database. It is likely that much of the contents
of your table consists of static information. Isolate static
information; you will not be able to check once and then ignore it
completely - hardware errors may corrupt your static information -
but you can perform dbcc checks and backups much less often on
that information.
Would your backups be useful in the event of a failure
When their systems fail, some customers are not able to load their
backups because they would lose all work done between completion of
the backup and the time of failure. These customers are not backing up
often enough.
You will need to do backup as often as it takes to be able to say, "I
can afford to lose the data. I always have a backup that I can load
and then continue operations normally".
Doing regular transaction dumps and saving the output will help to
ensure that you can use your backups to restore your system to an
up-to-the-minute condition. Discarding even one transaction dump will
guarantee that you cannot.
Will your system automatically warn you of problems
The most obvious means of checking for server problems is by scanning
the error log visually, but there are methods that are easier and less
error prone. On most systems you can pipe your error log through a
filter to detect exception messages. This is not a Sybase supplied
feature, but is not a difficult thing to do (see "Scanning the Error
Log Automatically" below).
Some corruptions, if fixed immediately, will cause few problems. It's
the corruption that is allowed to fester for long periods of time that
leads to a situation where recovery is difficult.
Are your devices mirrored
Mirroring your devices can help to ensure that recovery from some
types of system failure will take seconds or minutes instead of hours
or days.
A disk fragment cannot be dropped from a Sybase database. A disk
fragment cannot be rebuilt separately from the rest of the database.
If one of your devices fails and you have not mirrored that device,
you will be forced to drop and recreate that entire database. Can you
afford to have your users wait that long Most probably, it would be
far less expensive to maintain mirrored devices.
Scanning the Error Log Automatically
Following is an example of a UNIX C shell script that might be used to
form part of an "early warning system". You might also wish to add
some code to ensure that the DBA is not alerted for certain common or
informational messages that appear in your error log (hint: use the -v
option of the grep or egrep utility).
Example:
#!/bin/csh
# file: scan_log
# author: Greg Klinder # Sybase, Inc.
#
# purpose: A C shell script for warning the Database Administrator # about pote
ntial problems with the Sybase SQL Server.
#
# The reliability of this script for alerting the DBA to potential # server pro
blems depends entirely on the contents of the WORRIES
# file. This file contains a list of regular expressions which,
# hopefully, can be used to correctly identify *most* serious
# errors that might appear in the error log.
set DBA_ALIAS=(our...@oursite.com othe...@theirsite.com)
set ERRORLOG=/usr/sybase/install/errorlog
set FERR_FILE=/tmp/filtered_err set WORRIES=/usr/ourdba/regexp
# -------------------------------------------------------------
# Check to see whether temporary file exists. If so, remove it.
# -------------------------------------------------------------
if (-f ${FERR_FILE} ) then rm ${FERR_FILE} endif
# ---------------------------------------------------------
# Filter out all messages within the errorlog that might be
# of concern to the database administrator. Save them to a
# temporary file.
# ---------------------------------------------------------
if (-f ${WORRIES} && -f ${ERRORLOG} ) then
egrep -f ${WORRIES} ${ERRORLOG} >${FERR_FILE}
else
echo ${ERRORLOG} | mail -s "scan of server error log failed"
${DBA_ALIAS}
exit 1
endif
# -----------------------------------------------------------
# If the temporary file is not empty, then we know that there
# are messages within the errorlog that should be examined.
# Alert the database administrator(s) by email.
# -----------------------------------------------------------
if ( ! -z ${FERR_FILE} ) then
mail -s "problems in error log ${ERRORLOG}" ${DBA_ALIAS}
<${FERR_FILE}
endif
Here is an example of what you might put in the WORRIES file:
WARNING:
WARNING -
Error:
Msg
Most Commonly Made Serious Mistakes
* Using dump tran ... with no_log in some situations can cause
corruptions. Whenever possible, use dump tran ... with
truncate_only instead. If the log is 100 percent full and
truncate_only produces an 1105 error, then use no_log.
* Doing dump tran ... with truncate_only or dump tran ... with
no_log will render all subsequent dump tran useless. Each dump
tran is only as good as the previous one.
* Backing up your SYBASE devices at operating system level is
useless unless the backup was done while SQL Server was down and
you plan to restore all devices simultaneously. Additionally,
OS-level device backup is not supported.
* Your server will not be very forgiving when it comes to mismatches
between the contents of the sysusages table at the time of dump
database and the contents of the sysusages table at the time of
load database. In Servers before System 10, you will get 2558
errors from dbcc checkalloc; in SQL Server 10.0, the load will
change sysusages and you may not find the output useful.
* By dropping a user database, recreating it, and then loading the
most recent dump, you will still be missing all of the information
generated when you used the sp_extendsegment stored procedure (the
information is stored in the sysusages table in master, not in any
tables within the user database). You will need to repeat all of
the sp_extendsegment commands. If you neglect to do so, you may
end up with occurrences of the 1105 error. If you created
user-defined segments, you must recreate them before you attempt
to reload.
* In general, we recommend that you put the log for any user
database on its own device.
Syntax Change for RAISERROR
Under the old raiserror syntax, it is very difficult to distinguish
where the parameters for the message string end and where the Extended
Error Data (EED) arguments begin. They are distinguishable only by the
presence or absence of a comma. A new syntax change planned for an
upcoming System 10 SQL Server Rollup results in an error message that
is more readable and more easily maintained by customers and Technical
Support staff.
The old syntax was:
raiserror error_number
[{format_string | @local_variable}] [, arg_list]
[extended_value = extended_value [{extended_value
= extended_value}...]]
The new syntax is:
raiserror error_number
[{format_string | @local_variable}] [, arg_list}
[with errordata restricted_select_list]
where restricted_select_list can follow the standard select_list
syntax rules as mentioned in the raiserror section of Volume 1 of the
SQL Server Reference Manual, with the restriction that no from, where,
or other select clauses can be included. This means that wildcard
characters cannot be used.
Use of EED, as described in the SQL Server Reference Manual, will stay
the same. The third example in the examples section of that manual
should now read:
3. raiserror 20100 "Login must be at least 5
characters long" with errordata "column" = "login",
"server" = @@servername
According to the new syntax, the following variants of raiserror are
allowed, have been exercised, and are verified as functional:
raiserror 25001
raiserror 25001 "formatted string"
raiserror 25001 @variable
raiserror 25001 "formatted string %1!","foo"
raiserror 25001 @variable,"foo"
raiserror 25001 "formatted string %1! with %2!","foo",@bar with
errordata ExtendedValue=5,"ExtVal"="Extval",3+4
raiserror 25001 @variable,"foo",@bar with errordata
ExtendedValue=5,"ExtVal"="ExtVal",3+4
raiserror 25001,"foo"
raiserror 25001,"foo",@bar
raiserror 25001,"foo",@bar with errordata ExtendedValue=5
raiserror 25001,"foo",@bar with errordata
ExtendedValue=5,"ExtVal"="Extval",3+4
raiserror 25001 with errordata ExtendedValue=5
raiserror 25001 with ExtendedValue=5,"ExtVal"="ExtVal",3+4
This change will be effective with a Rollup scheduled for release
later in 1994. When inquiring for the status of this Rollup, mention
bug # 51600.
Changing Sort Order Manually When sybinit Fails
During a new install of SQL Server 10.0.1 for HP9000/800, some
customers have encountered a bug, 56745, when attempting to change the
default sort order from binary to dictionary case insensitive in
sybinit. The following errors are raised:
CONNECTIVITY ERROR: Error sending SQL to server `SYBASE'
SERVER ERROR: `sp_configure default sortorder id' failed.
If you encounter this problem, you must change the sort order manually
according to the following method. The example below demonstrates
conversion of the sort order from binary to nocase under the roman8
character set. The available sort orders for a character set may be
found in $SYBASE/charset/charset_name, where charset_name is the name
of your character set. For example:
cd $SYBASE/charsets
alder% ls -C
ascii_8 cp437 cp850 eucjis iso_1 mac roman8 sjis
alder% ls -C roman8
binary.srt dictionary.srt nocase.srt
charset.loc noaccents.srt nocasepref.srt
The available sort orders have a .srt filename extension.
The steps to change the sort order are:
1. At the isql prompt, execute the command dump tran master with
truncate_only. Make sure you have some space available in master
so that you will not have problems rebuilding the system table
indexes. If space is tight then alter database master before
proceeding further.
2. Shut down the SQL Server.
3. If your SYBASE devices are on UNIX file systems, issue three sync
commands at the shell prompt so that the OS buffer cache gets
flushed.
4. Reboot the SQL Server in single-user mode.
5. Execute the following commands in isql:
1> select name, id, type from syscharsets
2> go
Your output should look something like this:
name id type
------------------------------ --- ------
ascii_8 0 1001
roman8 4 1001
nocase_roman8 22 2001
bin_roman8 50 2001
If you see "nocase_roman8" then type:
1> sp_reconfigure `default sortorder id', 22
2> go
1> reconfigure with override
If you do not see "nocase_roman8"' then:
+ Exit isql
+ Execute this command from the shell prompt:
$SYBASE/bin/charset -Usa -Ppassword -Sservername nocase.srt
roman8 · Go into isql and type:
1> sp_reconfigure `default sortorder id', 22
2> go
1> reconfigure with override
6. Shut down the SQL Server
7. If your SYBASE devices are on UNIX file systems, issue three sync
commands at the shell prompt so that the OS buffer cache gets
flushed.
8. Reboot the SQL Server. This will rebuild the system indexes and
shut down SQL Server automatically.
9. Reboot the SQL Server again.
At this point the Server should be configured for nocase for the
roman8 sort order. Verify this by looking at the errorlog after the
boot.
You will need to run sp_indsuspect against each database to see if
there are any indexes that must be rebuilt because of the sort order
change. Please refer to Chapter 17 of your System Administration Guide
for instructions.
sysdevices `status' Control Bits
The status column in the sysdevices table is a bit map indicating the
type of device, default, and mirror status. The status control bits
are:
Decimal Hex Status
1 0x01 Default disk
2 0x02 Physical disk
4 0x04 Logical disk
8 0x08 Skip header
16 0x10 Dump device
32 0x20 Serial writes
64 0x40 Device mirrored
128 0x80 Reads mirrored
256 0x100 Secondary mirror side only
512 0x200 Mirror enabled
1024 0x400 Device information in configuration area
2048 0x800 Mirror disabled
Examples: A value of 2275 (0x8E3) in the status column of sysdevices
means that the device is:
2048 0x800 Mirror disabled
128 0x080 Reads mirrored
64 0x040 Device mirrored
32 0x020 Serial writes
2 0x002 Physical disk
1 0x001 Default disk
A value of 2242 in the status column of sysdevices represents the
following:
2048 0x800 Mirror disabled
128 0x080 Reads mirrored
64 0x040 Device mirrored
2 0x002 Physical disk
Bug fix 31027 introduced the new status bit value 2048.
Use Database Hanging After Upgrade
A few customers are experiencing intermittent hanging after upgrading
to 10.0 SQL Server when they execute a use database command. No bug
has yet been assigned to this behavior, because so far the problem is
intermittent enough that we have not been able to reproduce it either
at the customers' sites or in Technical Support. To avoid the
possibility of this problem occurring, make sure that the
configuration value for open databases is at least equal to the number
of actual databases present on your SQL Server. You can change this
value with sp_configure; refer to Chapter 12 of your System
Administration Guide for further details.
Float and Money Display Methods
Occasionally, a customer may want to display more than the default six
significant digits to the right of the decimal point of a float or
money value. One method that a customer might find intuitive, select
convert (char(20), floatcol), does not work. However, as of the 4.9.1
release of SQL Server, there is a way to display more digits. Using
the str function documented in the Commands Reference Manual, you can
display more digits like this:
select str(floatcol, length1, length2) from table
length1 is the total number of characters to return, including the
decimal point, blank spaces, and digits to the right and left of the
decimal. length2 is the number of digits to the right of the decimal
point. For example, the command:
select str(discount,14,11) from pubs2..salesdetail
where title_id = `PC1035' and ord_num = `124152'
will return the string 50.500000000000. The function adds extra zeros
to the end of the number as padding if there are fewer than the
requested number of digits to the right of the decimal point.
Disk Mirroring Clarification
The System Administration Guide for SQL Server release 4.9.2 contains
the following statement:
"... SQL Server reads from the disk where the last I/O was `closest'
to the current read request.
This statement is not in the System Administration Guide for release
10.0, leading to the frequently asked question, "Is this true for
System 10 Has it ever been true How could this work"
In fact, this feature was planned for release 4.8, but was never
implemented, due to the differences in hardware from platform to
platform. The plan was mentioned in some marketing documents, and
slipped into pre-System 10 System Administration Guide manuals. The
System 10 System Administration Guide corrects this erroneous
information.
Limitation on RPCs Called from Threshold Procedures
Threshold procedures in System 10 can make remote procedure calls to a
remote Server, but only if it that Server is an Open Server. A remote
procedure called from a threshold procedure cannot reside on a SQL
Server.
The reason is that a valid user/password combination must be provided
to the remote SQL Server. SQL Server no longer stores passwords in
plain text; rather, it encrypts them with a one-way algorithm. A
threshold procedure executes with the user ID (uid) of the user that
called sp_addthreshold, not the uid of the user that caused the
threshold to be exceeded. The calling server is unable to provide the
called server with a valid user/password combination, as it cannot
decrypt the encrypted version of the password kept in syslogins for
that uid.
Remote Open Servers, which do not use this user/password mechanism,
can execute RPCs from threshold procedures.
Backup Server Context Allocation Errors
Sybase Technical Support gets many calls from customers who see the
following messages:
Backup Server: 1.20.4.1: CS_CONTEXT allocation failed
Backup Server: 1.15.4.1: UNRECOVERABLE CONDITION: ALL
SESSIONS WILL TERMINATE ABNORMALLY. THE BACKUP SERVER
MUST EXIT
This error indicates that the context allocation routine failed when
it tried to load localization files. One or more of the following
problems may have caused these errors:
* The SYBASE environment variable may be incorrectly set.
* The LANG environment variable may be set to "C" (the default),
which does not exist in your locales.dat file.
There are two ways to correct this second situation:
* the UNIX command unsetenv LANG, or
* Add the following line to your $SYBASE/locales/locales.dat file:
locale = C, us_english, iso_1
TLI Address Translation Addendum
In Volume 3, Issue 2 of SYBASE Technical News, a section on TLI
network addressing incompletely explains the translation of the
hexadecimal address number. This is the actual translation of the
following example:
\x000207d082d6330d0000000000000000
* \x is the hex indicator
* 0002 is the address family
* 07d0 is the port number
* 82d6330d is the network node (IP) address
The optional trailing zeros are present in this example.
The address family identifies the format of the network address. "2"
means "internetwork" (UDP, TCP, and so on). The entire set of families
is given in /usr/include/sys/socket.h. For example, DECnet is 12;
AppleTalk is 16. This does not mean that a machine supports all of
these protocols; it simply identifies the format of the address.
While the byte order of the port number and network address is defined
in some specifications for IP address (and does not vary from platform
to platform), the byte order of the "address family" is not fixed.
Some machines with the opposite byte order from the Sun4 (DEC and
Intel machines) may have 0200 rather than 0002 (the bytes are
swapped).
OpenVMS Mount from CD-ROM
In Volume 3, Issue 2 of the SYBASE Technical News, we described how to
avoid 803 errors when installing from CD-ROM by ensuring that you use
the correct mount command. As of the System 10 release of SQL Server,
distribution of software by CD-ROM is available for OpenVMS as well as
OSF. The mount command is:
mount device_name sybase cdrom
Please refer to Volume 3, Issue 2 of the SYBASE Technical News for
further information about the 803 error.
Sybase Compatibility with RAID
There has been some confusion about whether Sybase software works with
RAID disk technology. This issue has two sides:
* Will the software's asynchronous I/O code work with RAID disks
* Has Sybase certified products on a platform using RAID disks
SYBASE Async I/O and RAID
The way SQL Server uses asynchronous I/O on the AT&T (NCR) platform,
for example, is simply to use supplied system calls to issue an
asynchronous I/O request. Then it polls for the I/O completion in a
prescribed manner; if an I/O error is returned, the SQL Server reports
and corrects for it. You configure, with disk init, the device to
which the I/O is actually done; it is usually also a device entry in
/dev.
From the SQL Server's perspective, there is a device file (/dev/xxxx)
that it can open and to which it can direct I/O requests. The SQL
Server has no knowledge of the type of device that is represented by
the device entry in /dev. It could be a single partition of a disk or
some other abstraction such as a RAID disk. As with any device,
buffered I/O may cause complications for data recovery.
Certification Issues
After an operating system vendor, such as SunSoft, tests and certifies
its new hardware devices for a new OS version, Sybase tests SQL Server
to ensure that it is compatible with the new OS. If a RAID device is
supported by the OS as a standard disk device, then SQL Server will
support the RAID disk subsystem, since SQL Server is certified against
the OS rather than against the disk subsystem. It is not possible to
recommend one RAID system over another, since the results are system
and application dependent.
bcp Programming and Paging
Using bcp_init, bcp_bind, and bcp_done in a 3GL program can cause each
row to be started on a new page, even though the row might not be a
full page in length. If your function to load the data into the
database is called for each row until EOF, and in that same function
are bcp_init, bcp_bind(s), and bcp_done, you may see this problem.
This is because having initialization (bcp_init) occur each time a row
is to be added causes each row to be stored on a new page. This is not
documented in the OpenClient/DB-Lib Reference Manual.
Instead of using all three calls in the same function, run bcp_init
and bcp_done outside the function that does the bcp_bind(s). Be aware
that now either all the data is sent when bcp_done is executed, or
nothing is sent if the program crashes before bcp_done.
SQL Monitor Server and ceventbuf
Although it is documented only in the "Special Considerations" section
of the SQL Monitor Server Supplement, changing the ceventbuf value on
the SQL Server is a required step in setting up the SQL Monitor
Server.
It is important that you heed the information regarding ceventbuf
values in the SQL Monitor Server Supplement; there is an algorithm
listed there that will help you calculate the size to which you should
set your ceventbuf value. The default ceventbuf value for SQL Server
is 100; we suggest a minimum of 2000 for ceventbuf in order to use SQL
Monitor. Changing this value is required by SQL Monitor, not by SQL
Server.
For windows that depend on the event buffer size (see the SQL Monitor
Server Supplement for this information), we recommend a low sample
interval for SQL Monitor Client of 5-10 seconds.
SQL Monitor Cheat Sheet
The order in which to start the three processes involved in monitoring
your SQL Server is: 1) SQL Server, 2) SQL Monitor Server, 3) SQL
Monitor Client. If SQL Server is rebooted, then both the SQL Monitor
Server and Client must be rebooted. The process details are:
1. Start the SQL Server as user "sybase". Use the -M flag to specify
the lo cation of the server_name.krg file. (See the SQL Server
Installation Guide for y our platform.) For example:
setenv SYBASE /usr/local/system10
setenv DSLISTEN SYBASE10
$SYBASE/bin/dataserver -d/sun4db/system10db/SYBASE10_master.dat \
-e$SYBASE/install/errorlog_SYBASE10 -M$SYBASE &
2. Start up the SQL Monitor Server as the same "sybase" user, on the
same host machine, with no spaces between the flag and the flag's
value. Using the -i flag, point to an interfaces file that has
both the SQL Server entry and the SQL Monitor Server entry;
specify the same location of the SQL Server .krg memory file using
the -m flag. Be sure to start SQL Monitor Server on the same
machine as SQL Server because SQL Monitor Server has to access the
same shared memory region.
$SYBASE/bin/monserver -MMON10_SYBASE10 -SSYBASE10 \
-Usa -Ppassword -i$SYBASE/interfaces \
-l$SYBASE/install/MON10_SYBASE10.LOG -n -m$SYBASE -O &
The two flags, -M and -m have different meanings. See the SQL
Monitor Server Supplement for complete start-up instructions
3. Start the client as any user, on any client machine, using spaces
between each flag and its value. The -i flag must point to an
interfaces file that has both the SQL Monitor Server entry and the
corresponding SQL Server entry that was passed on the monserver
command line. The SQL Server name must be the same name that
appears in the interfaces file (or .INI for PCs). It cannot be an
entry that has the same host and port number but a different SQL
Server name. (See the SQL Monitor Release Reference Manual for
complete start-up instructions)
UNIX:
/usr/directory/bin/sqlmon -M MON10_SYBASE10 \
-U sa -P password -I\x11/usr/directory/interfaces &
PC:
C:\SERVMON\SERVMON.EXE
The Sybase-supplied sqldl.dll library is installed in
\WINDOWS\SYSTEM with SQL Monitor version 10.1.0 for Windows, but
in \SERVMON with SQL Monitor version 10.1.2 for Windows.
A user must have sa_role privilege to access release 10.0 or
10.0.1 SQL Monitor Server or SQL Server. Use the following command
to grant that privilege to a user: exec sp_role `grant', sa_role,
`username'
Special Notes for PC Users - SQL Monitor Client
SQL Monitor Client opens up two network connections for each open
window: one to SQL Monitor Server and one to SQL Server. PC users will
be affected most and will need to configure their network software to
handle more network connections.
For example, if you are using FTP's PC/TCP, with its default
configuration of six network connections, this limit will be reached
with three SQL Monitor windows. An attempt to open a fourth window
will result in an error:
SERVMON Cannot access Server - retry after closing an
existing Monitor Window
You may also see the above error message when the number of open
connections for the SQL Monitor Server has been exceeded. In that
case, you must restart the SQL Monitor Server with a larger -n value.
Please refer to your network documentation for specific information on
how to increase your network connections. To continue the FTP PC/TCP
example, you must edit the "tcp-connection=" entry in the [pctcp
kernel] section of the \PCTCP\PCTCP.INI file and then reboot your PC.
SQL Monitor Incompatibility Table
In Volume 3, Issue 2 of the SYBASE Technical News, we published a
table of uncertified combinations of SQL Server and SQL Monitor Server
that contained a typographical error. Here is the corrected table:
SQL Monitor Server SYBASE SQL Server
4.9.1 10.0.0
(this combination may work, but is not certified)
4.9.1 10.0.1
10.0.0 10.0.1
10.0.1 4.9.x or 10.0.0
Corrections to NetWare Installation Manual
According to the SQL Server Installation Guide for Novell NetWare, the
first step of the installation process is to update the NetWare
operating system NLMs. This step is necessary if the NetWare NLMs that
are currently running, prior to installation, are older then the NLM
versions listed in the Release Bulletin.
This step is not required if you have more recent NetWare NLMs. This
includes the newer versions of NetWare 3.12 and 4.01.
When SQL Server 4.2.2 for NetWare was released in March 1993, most
customers were installing on NetWare 3.11. When Sybase came out with
this version, Sybase included more current versions of the NetWare
NLMs on the distributed diskettes so that customers could easily
upgrade to 4.2.2 without having to track down the correct NetWare
NLMs.
Today, one year later, the NetWare NLMs have gone through many
revisions, and the NetWare NLMs on the Sybase diskettes are no longer
the most current. Therefore, you should skip that updating step so as
not to override the newer NLMs.
The recommended installation steps should begin with the section
entitled "Step Two: Start SQL Server Installation."
After the SQL Server is installed and configured, we recommend you
copy over the most recent Sybase Rollup (Rollup 3183 as of July 1,
1994), and download the following files from Compuserve to bring your
NetWare fileserver up to the latest NetWare NLM versions. The tables
which follow the lists of files show the specific NLMs to download for
each NetWare version.
Recommended list of NLMs to Load for NetWare 3.11
Download these files from CompuServe:
* STRLI2.exe (novlib forum)
* LIBUP2.exe (novlib forum)
* DFS108.exe (novlib forum)
DIR Listing Information MODULES List
NLM Name Size Date Module Date
sys:\system directory:
clib 328,124 2/24/94 3.12f 2/24/93
mathlib 12,458 2/24/94 or 3.12f 2/24/93
mathlibc 16,832 2/24/94 3.12f 2/24/93
a3112 11,371 1/7/94 4.00a 1/7/94
after311 14,411 1/7/94 4.00a 1/7/94
streams 53,566 7/20/93 3.12 7/20/93
spxs 24,145 9/14/93 3.12a 9/14/93
tli 12,474 9/14/93 3.12a 9/14/93
ipxs 8,149 8/10/93 3.12a 8/10/93
spxddfix 1,636 9/20/93 1.00 9/20/93
spxfix2 1,599 8/20/93 2.10 8/20/93
spxfsfix 1,155 8/20/93 2.10 8/20/93
spxlisfx 1,016 8/20/93 1.10 8/20/93
xmdfix 1,496 9/15/92 1.02 9/15/92
patchman 9,632 2/04/93 2.30 2/4/93
directfs 16,740 7/14/93 1.08 7/14/93
sybstubs 901 n/a 4.22 3/16/93
sys:\sybase\nlms directory
sqlsrvr 1,192,998 n/a 4.22 1/18/94
Recommended List of NLMs to Load for NetWare 3.12
Download these files from CompuServe:
* STRLI2.exe (novlib forum)
* LIBUP2.exe (novlib forum)
* DFS108.exe (novlib forum)
* 312IT1.exe (nsd forum)
DIR Listing Information MODULES Listing
NLM Name Size Date Module Date
sys:\system directory:
clib 328,124 2/24/94 3.12f 2/24/93
mathlib 12,458 2/24/94 or 3.12 2/24/93
mathlibc 16,832 2/24/94 3.12f 2/24/93
a3112 11,371 1/7/94 4.00a 1/7/94
after311 14,411 1/7/94 4.00a 1/7/94
streams 53,566 7/20/93 3.12 7/20/93
spxs 24,145 9/14/93 3.12a 9/14/93
tli 12,474 9/14/93 3.12a 9/14/93
ipxs 8,149 8/10/93 3.12a 8/10/93
spxddfix 1,254 9/20/93 1.00 9/20/93
pm312 8,909 11/11/93 1.11 11/11/93
directfs 16,740 7/14/93 1.08 7/14/93
sybstubs 901 n/a 4.22 3/16/93
sys:\sybase\nlms directory:
sqlsrvr 1,192,998 n/a 422 1/18/94
These files are as of March 1994; NetWare NLMs will continually need
to be updated, and we recommend monitoring CompuServe for any release
notices.
Please refer to the *.txt files included with the downloaded files
from CompuServe for detailed information on the purpose of each
NetWare NLM.
Correction to NetWare "Zombie" Article
As the above article shows, the name of STRTLI.EXE has been changed to
STRLI2.EXE. This file is one of the files recommended for download to
forestall the appearance of "zombie" processes on the SQL Server NLM.
We apologize for any confusion this may have caused.
Changes in PC Open Client/C Packaging
Customers will shortly be seeing a change in the way Open Client/C
release 10.0.1 is packaged for MS-DOS, Windows, OS/2, and Windows NT.
The new packaging includes all System 10 Net-Libraries. This
eliminates the need to order a separate package of Net-Libraries for
each platform and brings packaging for PC platforms in line with the
existing method of packaging for UNIX and OpenVMS platforms.
All repackaging should be complete before the desktop mass-shipment
scheduled for maintenance release 10.0.3 and after completion and
release of DB-Library release 10.0.1 for each platform. The 10.0.3
maintenance release and mass update, and the final production release
of DB-Library 10.0.1 are scheduled for Q4 of 1994.
Bug 54192/34245 - Optimizer
In the latest 4.9.2 SQL Server Rollup, the query optimizer looks at
the new multi-column densities only if a special trace flag is set; in
SQL Server release 10.0, the optimizer always looks at the new
multi-column densities.
A fix for bug 34245 in the 4.9.2 SQL Server addressed an optimizer
problem with multi-column joins by providing multiple densities for
multi-column indexes. Prior to this fix, the join selectivity
(proportion of the table to be scanned for each outer row) was
estimated by a number referred to as the join's "density": the average
proportion of duplicates in the index. The density took the entire
index key into account, regardless of whether the query was joining on
the entire index key or a subset of the index key columns.
This fix for bug 34245 greatly improved performance for some
queries-those for which the optimizer had previously selected very
costly indexes because of the density limitation. On the other hand,
the fix did occasionally cause the optimizer to generate some
potentially less effective plans. A new bug was entered for this
problem, 54192, which makes the multiple-density feature available
only if the SQL Server is started with trace flag 321.
Customers upgrading to System 10 should be aware that trace flag 321
is not a part of System 10, and that they may encounter the problems
for which bug 54192 was entered. Following are an explanation and
suggestions to work around the problem.
The Nature of the Bug
Customers doing queries with one or more joins may now see that an
index is much less selective on the join columns of some or all
indexes. This can result in the index not being used, and an alternate
plan being chosen such as using a different index, choosing a
different join order, or reformatting to a work table.
In some cases, the new plan can be slower than a previously chosen
plan, often as the result of "join skew". Join skew occurs when the
optimizer does not know the specific values that will be joined at run
time, and must use an estimate for the average number of rows that
will join to a typical value. If the actual number of rows that join
is significantly less than the average number used by the optimizer,
then the new plan may not be as fast as the plan chosen before this
fix.
The resolution to these problems is to determine which indexes are
demonstrating very poor join selectivity, and modify the schema to
include indexes that have good join selectivity on the joining columns
of the query. For example, using this schema:
create index idx on tab (col1,col2,col3,col4)
this index will have four sets of densities, on:
col1
col1,col2
col1,col2,col3
col1,col2,col3,col4
For a query joining on col1, col3, and col4, a density of (col1)will
be used to estimate join selectivity for tab. If col1 has 100 percent
density (all duplicates), the join selectivity will be very poor, and
the optimizer will not select this index even though (col3,col4) may
be very selective.
Modify the schema as follows:
create index idx_c3c4 on tab (c1,c3,c4,c2)
This way, for a query joining on col1,col3,col4 the density of
(col1,col3,col4) will be used to estimate join selectivity for tab.
Regardless of the poor join selectivity of (col1), the index will be
regarded as highly selective by the optimizer because (col1,col3,col4)
is very selective.
Bug 55721 - sp_estspace
A customer discovered that entering a different value for iosec in
sp_estspace has no impact on the time_mins value. For example
1> sp_estspace titles,10000,50,
2> "title,notes",0,10000
returns a value of 13 in the time_mins column. Changing the iosec
value to 25:
1> sp_estspace titles,10000,50,
2> "title,notes",25,10000
causes no change in the time_mins column. This is because when iosec
is initially declared, it is set to 30. The solution is to delete that
line in the code. A new version of sp_estspace, included in the
comp.databases.sybase FAQ on Usenet news, contains this correction.
Bug 56619 - sp_columns
Bug 56619 was recently reported in SQL Server 10.0.1, for the case in
which sp_columns does not report on columns with user-defined
datatypes. Customers who encounter this bug can contact Technical
Support for a new script to create sp_columns; additionally, the
script is available on the OpenLine forum of CompuServe (GO SYBASE).
Isolate the create sp_columns script from the installmaster script
provided with 10.0.1 and make the following changes:
* Remove the line AND t.name = d.type_name
* Replace it with AND t.type = d.ss_dtype
This line appears in the sp_columns definition, just below this
comment:
We need an equality with sybsystemprocs.dbo.spt_datatype_info here so
that there is only one qualified row returned from
sybsystemprocs.dbo.spt_datatype_info.
Drop sp_columns and run the new script.
Disclaimer: No express or implied warranty is made by SYBASE or its
subsidiaries with regard to any recommendations or information
presented in SYBASE Technical News. SYBASE and its subsidiaries hereby
disclaim any and all such warranties, including without limitation any
implied warranty of merchantability of fitness for a particular
purpose. In no event will SYBASE or its subsidiaries be liable for
damages of any kind resulting from use of any recommendations or
information provided herein, including without limitation loss of
profits, loss or inaccuracy of data, or indirect special incidental or
consequential damages. Each user assumes the entire risk of acting on
or utilizing any item herein including the entire cost of all
necessary remedies.
(C) 1994, Sybase, Inc. All Rights Reserved. SYBASE is a trademark of
Sybase, Inc. registered in the U.S. Patent and Trademark office and in
other countries. SQL Server, Open Client, Open Server, Backup Server,
SQL Monitor Client, and SQL Monitor Server are trademarks of sybase,
Inc. Other company and product names may be trademarks of the
respective company with which they are associated.
Staff
* Principal Editor: Leigh Ann Hussey
* Contributing Writers:
+ Donna Sams-Nyirendah
+ Greg Klinder
+ Ray Rankins
+ Aimee Grimes
+ Marc Sugiyama
+ Cris Gutierrez
+ Bob Perry
+ John Blair
+ Guy Moore
+ Danielle Scherer
+ Marian Macartney
+ Gary Sturgeon
+ Bret Halford
+ Sybase Engineering
Send comments and suggestions to:
SYBASE Technical News
6475 Christie Avenue
Emeryville, CA 94608 USA
For more info send email to tech...@sybase.com
Copyright 1995 © Sybase, Inc. All Rights Reserved.
Q10.1.3
Technical News Volume 3, Number 4 November, 1994
Document ID: 50005-01-0300-04
This issue of the SYBASE Technical News contains new information about
your SYBASE software. If needed, duplicate this newsletter and
distribute it to others in your organization. Keep this newsletter
with your SYBASE Troubleshooting Guides. All issues of the Sybase
Technical News and the Troubleshooting Guides are included on the
AnswerBase CD.
IN THIS ISSUE
* Distribution Changes for Technical News
* Technical News by E-Mail Update
* OpenLine Update
* 1105 Errors on Boot
* Large SQL Server Upgrade Fails with Timeout
* Variable Database Object Names and Parsing Issues
* Threshold Management with @@thresh_hysteresis
* Methods for Monitoring Space
* Dead/Infected Processes and the Stack Trace
* sp_columns Script on CompuServe
* AIX: isql Connect to Backup Server Hangs
* HP: installasync80 and SAM Problems
* HP: Swap Space and Memory
* AT&T (NCR): 1605 and "Illegal Calling Sequence"
* Solaris: Sunlink, "Master Network Listeners Failed"
* VMS: MTI 4mm HSC Tape Drive No Longer Supported
* bcp: Determining Data Logged
* DB-Library: dbcursoropen() Returns NULL
* dbcursoropen(dbproc,"select type from pubs2..titles,...)
* DB-Library: dbclose() and File Descriptors
* Embedded SQL: Target of INTO Clause
* Embedded SQL: EXEC PROC Enhancement
* Embedded SQL/COBOL: Memory Leak in libcobct.a
* Mainframe Access Products: Latest EBFs
* Server Documentation Bugs Fixed
* Connectivity Documentation Bugs Fixed
* Latest Server Certification Report
* Bugs Fixed in 10.0.2 SQL Server Release
* Bugs Fixed in Latest Connectivity Maintenance Releases
Distribution Changes for Technical News
Beginning with Volume 4 Number 1, the SYBASE Technical News will be
sent to you on the quarterly AnswerBase CD. You may print as many
copies as you need for your site. To find and print the SYBASE
Technical News from AnswerBase, follow these steps:
1. Do a Full-Text Query (under the "Search" menu) on the following
string (include the angle brackets in your string): <title
Technical News> This will, incidentally, provide you with all the
issues of the SYBASE Technical News that have been published to
date.
2. Double-click on the title you want to open, or select it and click
"Open".
3. From the File menu, choose Print.
The SYBASE Technical News is automatically distributed to all
registered Sybase support contacts. If you are one of your company's
registered support contacts and you do not receive the AnswerBase CD
directly, please call Customer Service at 1-800-SYBASE to correct
this.
The SYBASE Technical News will continue to be distributed to
comp.databases.sybase, the Sybase OpenLine forum of CompuServe, and
the automatic e-mail distribution list.
Technical News by E-Mail Update
Whether or not you are a Sybase support contact, if you would like to
receive your SYBASE Technical News in text format by e-mail, send mail
to tech...@sybase.com. We will add you to the automatic distribution
list and you will receive your letter by e-mail at the same time that
copies are distributed to the other online services.
With over 200 subscribers added since August, the e-mail subscription
program to SYBASE Technical News is a great success! However, for the
moment, list administration is still handled by a human being, not a
program. What this means to you, the customer, is that in order to
subscribe successfully to the SYBASE Technical News e-mail
distribution list, you must send, in the body of your letter, a valid
e-mail address.
If you subscribed since the last issue was printed and have not
received an e-mail acknowledgment, send your request again, with a
valid e-mail address. We have had the acknowledgment bounce from
several addresses because the address was not valid, and those
addresses have been removed from the list.
OpenLine Update
Sybase OpenLine has 24 sections now. We are accepting proposals for
other new sections. If you have a suggestion or know of a Sybase
product or service that should be supported on OpenLine, contact
Chandra Krishnan (72662, 1331).
The new International Sybase User Group (ISUG) private section goes
live in October for ISUG members only. You may communicate online with
other ISUG members and the ISUG Board of Directors, receive ISUG
benefits and benefit information online, talk with Sybase, and much
more. Specific details will be sent out to all ISUG members in
October. Susie Cabral, User Group Program Manager, is the section
manager and Teresa Larson, ISUG Electronic Media Chair, is the
moderator. You can contact Susie at 510-922-4422 (voice), 510-922-0882
(fax), or susie....@sybase.com (e-mail).
The Open Solutions section is being revamped. Please contact Tom
Barrett, the section manager, for more details at 510-922-8534 or
tom.b...@sybase.com (e-mail).
The OpenLine CompuServe forum is available to Sybase customers who are
also CompuServe subscribers. More than 12,000 users have joined the
forum, and more than 17,000 messages have been posted in the forum.
For a full description of the items and activities available through
the Sybase OpenLine Forum, call your sales representative or Customer
Service at 1-800-8-SYBASE and ask for the OpenLine collateral. This
collateral will be mass-mailed in Europe and included in all outgoing
shipments worldwide.
1105 Errors on Boot
Problem: Customers who have upgraded from 4.9.x or previous releases
of SQL Server-> to release 10.x may run into a situation where, every
time SQL Server is rebooted, some database reports an 1105 error (no
space in segment) with state 4. Recovery reports "can't write
checkpoint record" for this database. Checking the segments, you may
discover that a few of the segments contain a value other than NULL
for the unreservedpgs column in sysusages.
Explanation: State 4 indicates that the error was produced by the
threshold manager in response to a "log almost full" condition. This
happens because the SQL Server recovers the database before counting
the free space in it and therefore is depending on whatever numbers
are present in memory. The numbers in memory are random because
unreservedpgs is NULL for most disk pieces in the database. The values
are NULL for those disk pieces because unreservedpgs was added during
the upgrade to System 10 and (for whatever reason) the values were not
initialized during the upgrade.
To solve this problem, you must change the NULL values in
unreservedpgs to non-NULL values. The threshold manager itself cannot
change them because changes to the unreservedpgs column of sysusages
are not logged (to prevent updates from filling the log); therefore,
it can't change the size of the column.
Action: To fix this problem, take the following steps:
1. Allow updates to system catalogs:
1> sp_configure allow, 1
2> go
1> reconfigure with override
2> go
2. Check the number of rows where unreservedpgs has a NULL value:
1> select count(1)
2> from sysusages
3> where unreservedpgs is null
4> go
3. Update the unreservedpgs column to give it a value of 0 in place
of the NULL value.
1> begin transaction
2> update sysusages
3> set unreservedpgs = 0
4> where unreservedpgs is null
5> go
4. Inspect the results! If the "rows affected" message matches the
count returned in step 2, then:
1> commit tran
2> go
Otherwise, roll back the transaction and try again.
5. When everything works as you intend, disallow updates to system
catalogs:
1> sp_configure allow, 0
2> go
1> reconfigure
2> go
This should resolve the problem.
Large SQL Server Upgrade Fails with Timeout
Question: When upgrading an extremely large SQL Server (multi GBs) to
release 10.x, if the SQL Server requires more than 9 minutes to go
through recovery, the upgrade script fails with an error that the SQL
Server is not responding. The typical recovery time for a large SQL
Server is more than 9 minutes. I have to rerun sybinit; how do I keep
this from happening again
Answer: This problem can be avoided by increasing the TIMEOUTCOUNT
parameter in the upgrade100 script to a larger number. The upgrade100
script is in the upgrade subdirectory of your SYBASE home directory.
This will increase the number of times the script will check to see if
the SQL Server is running before aborting the upgrade with an error.
The line in the file looks like this:
TIMEOUTCOUNT=108 # try the check 108 times (9 minutes)
The value of TIMEOUTCOUNT should be set to the number of minutes you
want to allow for recovery, times 12. So, for example, to increase the
check time to 15 minutes, increase the TIMEOUTCOUNT value to 180. You
can then rerun the upgrade through sybinit.
Variable Database Object Names and Parsing Issues
Question: I can use a variable for the database name in a dump tran,
so why can't I use one as a table name in select
Answer: This is because of the way our parser, variables, and
protection scheme were implemented. When the parser encounters a
variable in the batch, it temporarily assigns that variable to an
element of the query tree that is the explicit NULL, which gets
created as the initial target when variables are declared. It does
this even when the variable has been previously declared and has had a
value assigned to it, because assigning values happens during
execution, not during parsing.
Protection checking, however, happens in between parsing and
optimization. Thus, a table name represented by a variable has no
value when it comes time to check protections. Attempting to check
protections causes an access violation because of the null pointer in
the variable's value.
In order to allow variables as table names, protection checks would
have to be deferred until execution time. This has been done for
Backup Server-> in order to allow variables to be used as database
names in the dump/load commands. We don't do this for table names
because it would change the way stored procedures work: normally, a
procedure has whatever privileges its creator had at the time of its
creation, but if protection checks are deferred to execution time,
those checks get only get the privileges of the person running the
procedure.
Question: It's supposed to be legal to use variables for database
names, so why don't I see the result of the print statement in this
example
1> set flushmessage on
2> declare @dbname varchar(30)
3> select @dbname="pubs2"
4> print @dbname
5> select count(*) from @dbname.dbo.sysobjects
6> go
Msg 102, Level 15, State 1:
Server `REL1001_SUN4', Line 5:
Incorrect syntax near `@dbname'.
Answer: Your SQL contained a parse error, so the batch was never
executed. Steps in executing a query are:
1. Read the batch.
2. Parse the batch.
3. Optimize the batch.
4. Execute the batch.
Any failing step ends processing of the query.
Threshold Management with @@thresh_hysteresis
Question: The SQL Server Reference Manual Volume 2 (for release 10.x)
section on sp_addthreshold reads: "When you add a threshold, it must
be at least 2 times @@thresh_hysteresis pages from the next closest
threshold." Why is this
Answer: The "2 times" number is arbitrary. Any number greater than
@@thresh_hysteresis would do the same job. Why must the distance be
greater than @@thresh_hysteresis Because there must be a "buffer zone"
above the hysteresis cutoff of a threshold and below the next
threshold above it.
If two thresholds are closer together than the buffer zone, and:
* The higher threshold is "inactive" (that is, it has fired and is
now waiting to cross its hysteresis distance before being
reactivated),
* Space in the database is rising, and
* The free space has just gone above the inactive threshold,
Then it is impossible to determine the correct action. The three
possibilities are: to reactivate the lower threshold (which never
actually fired), to fire the higher threshold (which shouldn't fire
because its hysteresis distance hasn't been exceeded), or to do
nothing.
This "buffer zone" works out to a minimum of 128 pages-1/4MB on most
systems.
Methods for Monitoring Space
Question: What is the best way to monitor space in 10.x
Answer: There are four possible answers to this question, depending on
what you want to monitor (devices, databases, segments, and so on).
1. To monitor space on a device, execute the following query:
select "free pages"=
sum(curunreservedpgs(dbid,lstart,unreservedpgs))
from sysusages u, sysdevices d
where u.vstart between d.low and d.high
and d.name = "this device name"
2. To monitor space in a database on a device, add this line to the
above query:
and u.dbid = db_id("my database name")
3. To monitor space in a database, use:
select "free pages"=
sum(curunreservedpgs(dbid,lstart,unreservedpgs))
from sysusages
where dbid = db_id("my database name")
4. If you want a display for one database organized by segments, use:
select name, "free pages"=
curunreservedpgs(dbid,lstart,unreservedpgs))
from sysusages u, test..syssegments s
where u.dbid = db_id("test")
and u.segmap & power(2,s.segment) != 0
order by s.name
The stored procedures sp_helpdb and sp_helpsegment also give you space
information. sp_helpdb gives you free space per database fragment, and
sp_helpsegment gives you free space per segment.
Dead/Infected Processes and the Stack Trace
Question: Your SQL client dies and prints the message: "DBPROCESS dead
or not enabled." You investigate a little further and find, the
message "Current process infected" in the SQL Server error log. The
server itself may have shut down without warning. What just happened,
and how can you make your server healthy again
Answer: The "current process infected" message is a very general
message that indicates the occurrence of a serious error that the
server couldn't identify or handle in a more elegant fashion. To
handle the error, the server "infects" the responsible user process to
remove it from the internal queues. The three most common versions of
this message are "infected with Signal 10" which means the server
encountered a bus error, "infected with Signal 11" for a segment
violation, and "timeslice" which indicates a runaway user process. In
some cases, the server will also do a shutdown, but usually only the
user process is killed.
The root cause can be transient memory corruption, compiled object
(procedure, view, trigger, and so on) corruption, or a bug in SQL
Server or the operating system.
The SYBASE error log will usually contain the "current process
infected" message followed by a stacktrace. Sometimes the stack trace
is nonexistent or truncated to only a line or two, but usually it runs
between 10 and 25 lines. Here is a sample from the error log:
kernel: current process (0xab0004) infected with Signal 11
kernel: pc: 0x177d5c bcopy (0x1b6000,0x454680,0x100,0x1d,0x6bd06f,0x58b
2e0
kernel: ************************************
kernel: SQL causing error: update ipaddress
kernel: curdb = 5 pstat = 0x10100 lasterror = 0
kernel: preverror = 0 curcmd = 197 program = isql
kernel: 0x14809c ucbacktrace(0xab0004, 0x1, 0x41cf40, 0x0, 0x41e7d4, 0x
54cd48)
kernel: 0x700c terminate_process(0x0, 0xffffffff, 0x5f2d80, 0x0, 0x96,
0x0)
...
kernel: 0x160818 _coldstart(0x6, 0x0, 0xc6cb0, 0x0, 0x0, 0x0)
kernel: end of stack trace, spid 8, kpid 11206660, suid 6
Time-slice errors occur because SQL Server does its own process
management, giving each user process CPU time in small slices. There
are two server parameters for this, ctimemax and ctimeslice.
ctimeslice is the recommended maximum time that a process should run
before yielding, ctimemax is the absolute maximum amount of time a
process can run without yielding before SQL Server infects it.
ctimemax is usually set to 200 milliseconds (or 1500 milliseconds on
pre-4.9.x SQL Servers), although the exact setting doesn't matter. If
the server does infect a process that exceeds ctimemax, the message
"kernel timeslice -201 current process infected" appears in the log
(indicating that the process ran for 201 milliseconds) followed by a
stack trace.
Raising the ctimemax value can sometime alleviate the problem (that
is, if the process is not truly runaway, but just requires 347
milliseconds to complete, raising ctimemax to 400 will give it time to
complete and all will be well). However, because of the possibility of
further complications, this should be considered a temporary
workaround and should be done only under the direction of Technical
Support.
One particular type of time-slice error sometimes occurs at sites that
use remote servers. When a remote procedure call is made to the remote
server, the local server gets a time-slice error. The stack trace
indicates a call to the system function gethostbyname(), which reads
the /etc/hosts file to find the IP address of the specified computer.
If the /etc/hosts file is very long, gethostbyname() can take longer
than ctimemax to return, and SQL Server will infect the process. One
solution to this is to edit the /etc/hosts file and place the names of
the desired hosts near the beginning, which helps ensure that
gethostbyname() will return in a timely fashion.
There is usually little you can do to directly solve these problems
except to call Technical Support and send in your error log. Our first
step is to compare your stack trace with known bugs reported in
previous cases. Often, incoming stack trace cases can be identified
and already have a fix available. If the stack trace does not match a
known problem and is recurring, Technical Support will work with you
to try to create a reproducible case that can be submitted for a bug
fix. Often, however, the trace is spurious (as in the case of memory
corruption) and never recurs.
sp_columns Script on CompuServe
Please note that the fix for the sp_columns problem (mentioned in
volume 3 number 3) is in the customer-only section (Library 15,
OpenLine Technical) on CompuServe.
CompuServe members do not have access to this section without
application and approval.
To gain access to this library, you must fill out a form located in
Library 1 (General Technical) and return it to the person indicated on
the form. After validation, which takes about one business day, you
will be given access to Library 15.
If you are planning to download the sp_columns file as a fix, please
be aware that there is a lag time for account validation before you
will have access. If you cannot wait, please get the new script
directly from your Technical Support engineer.
AIX: isql Connect to Backup Server Hangs
Problem: Sybase Technical Support recently had several cases in which
a customer with System 10 upgraded to AIX version 3.2.5. Despite the
fact that they installed the recommended patches per certifications,
any dump or load command, for either a database or a transaction log,
to any media, would hang. Backup Server was up and running, and sp_who
showed the dump/load process in a state of RECV SLEEP. Testing
revealed that this error occurred with releases 10.0, 10.01P1, and
10.01P2.
Explanation: Socket connections were not being provided to the Backup
Server as expected. In cooperation with IBM, Sybase Technical Support
determined that additional patches from IBM are required. The
following table lists the patches installed, along with a brief
description of what each patch addresses:
Patch Number Description
U432 635 Addresses system crash
U432 692 Object directory missing objects and memory usage
accounting overflows
U432 696 Same as 692
U432 699 Same as 692
U432 713 Fixes C2X (X.25) adapter to available state
U432 839 System crash on auto start / add missing fields to
crash / crash print missing
U432 841 CSX (X.25) won't execute polling inside quotes
U432 875 Copy to raw logical volume will exit if write fails
U432 877 Watchdog set to 10 seconds
U432 949 errpt -t truncates labels to 10 columns
U432 973 tli: t_listen does not set tno data. This is the patch
that Sybase Technical Support thinks made the real
difference for the hanging isql problem.
HP: installasync80 and SAM Problems
Problem: If you use installasync80 to rebuild your HP-UX 9.04 kernel,
and then use SAM to change a kernel parameter, SAM rebuilds the kernel
and reboots the system, losing the changes made by installasync80.
Explanation: Hewlett-Packard has informed us that the SAM utility does
not see the changes made by the installasync80 script, and
asynchronous I/O is not a documented feature of HP-UX. To avoid
problems, re-run installasync80 after each time you use SAM.
HP: Swap Space and Memory
Problem: You can't start SQL Server on a Hewlett-Packard machine when
you have turned off Pseudo-Swap by setting the swapmem_on kernel
parameter to false.
Explanation: SQL Server uses lockable memory, and there is not enough.
You cannot increase lockable memory via the unlockable_mem kernel
parameter because swapmem_on, if set to true, automatically sets
lockable memory to 75 percent of available memory, thus overriding the
unlockable_mem parameter. Setting swapmem_on to true enables what
Hewlett-Packard calls "Pseudo-Swap", which allows an effective
swap-reserve space equal to all of the traditional swap plus 75
percent of available memory. This works well as long as swapping
activity does not exceed real swap space. If real swap space is
exceeded, performance falls off drastically. The reason SQL Server can
get the needed shared memory segments with swapmem_on set is because
of this Pseudo-Swap feature. When you set swapmem_on to false, there
is no longer enough swap space to reserve the shared memory segments,
but the lockable memory is close to its maximum possible value.
Solution: You want 75 percent of total available memory to equal 95
percent of actual physical memory. One solution is to add a small
(1GB) third-party disk drive to your machine. This will allow enough
reserve swap space to handle the requirements of the dataserver.
Increasing the 75 percent side of the equation with the added disk
drive should increase the 95 percent side so that swapping never
happens and memory is never written to that disk drive. Monitor the
machine to ensure that you do not use so much memory in shared memory
segments that it causes swapping to occur. Also monitor physical
memory utilization and do not push it above 95 percent.
AT&T (NCR): 1605 and "Illegal Calling Sequence"
If you encounter an "Illegal Called/Calling Sequence" message along
with the 1605 error in the Sybase error log, AT&T (NCR) recommends
that you install TCP patch PTCP201-F. Make sure that you are running
the most recent 2.01 version of TCP, currently 2.01.01.08.
You can contact your AT&T (NCR) representative for detailed
information about this patch.
Solaris: Sunlink, "Master Network Listeners Failed"
Problem: You tried to install SQL Server on top of Sunlink Token
Interface/Sbus (TRI/S) 3.0 firmware and saw the following sequence in
your error log:
00:94/06/14 14:39:39.66 server Number of buffers in buffer cache: 1584
.
00:94/06/14 14:39:39.66 server Number of proc buffers allocated: 396.
00:94/06/14 14:39:39.66 server Number of blocks left for proc headers:
341.
00:94/06/14 14:39:39.66 server Opening Master Database ...
00:94/06/14 14:39:39.70 server Loading SQL Server's default sort order
and character set
00:94/06/14 14:39:39.94 kernel ninit:0: listener type: master
00:94/06/14 14:39:39.94 kernel ninit:0: listener endpoint:/dev/tcp
00:94/06/14 14:39:39.94 kernel ninit:0: listener raw address: cx000280
03bf0d00320000000000000000
00:94/06/14 14:39:39.94 kernel ninit:0: transport provider: T_COTS_ORD
00:94/06/14 14:39:39.94 kernel ninit: t_bind, No Error
00:94/06/14 14:39:39.94 kernel ninitconn_free: t_close,fd =5, Illegal
file descriptor
00:94/06/14 14:39:39.94 kernel ninit: All master network listeners hav
e failed. Shutting down.
00:94/06/14 14:39:39.94 kernel ueshutdown: exiting
Solution: Here is a workaround that will enable you to install and
start SQL Server on the Token Ring. You must disable the Token Ring
capabilities so that you can start SQL Server, and then restart the
Token Ring, as follows:
1. Log in as "root" and then execute the command ifconfig tr0 down to
disconnect the TRI/S from SunOS.
2. Install SQL Server, making sure that the port selected is an even
number greater than 1020.
3. Connect the Token Ring board back to the operating system by using
the command ifconfig tr0 netmask tcp/ip address -trailers up. You
must have trailers up as it is used in the LLC packet
encapsulation.
4. Start SQL Server.
On Solaris, SYBASE supports TLI as the network API with a TCP/IP
network protocol by using the /dev/tcp network type device. This is
done by using the standard TLI calls. Furthermore, the mechanism that
SQL Server uses to attach port numbers is dynamic, which is part of
standard TLI interface. This means that the your network architecture
must support this implementation. You can use different low-level
architecture, such as X25 protocol or Token Ring or Ethernet links,
but you must configure the network to support standard TLI calls.
VMS: MTI 4mm HSC Tape Drive No Longer Supported
Problem: If you use the MTI 4mm HSC tape drive you will experience
problems using SQL Server 10.0.2. A VMS DATAOVERUN error is returned
at load time.
Explanation: The 10.0.2 Backup Server has been modified to increase
dump/load performance. This was accomplished by changing the I/O
strategy to the archive device from fixed 2K to varying length I/O up
to 54K.
While testing this new strategy in-house, Sybase Engineering
discovered a bug with a 4mm device made by the third party vendor
Micro Technology (MTI). You can work around it by dumping the database
using the BLOCKSIZE=2048 parameter. However, performance will be poor.
As a result, Sybase cannot support the MTI 4mm HSC tape drive; in
fact, the manufacturer, MTI, no longer supports it. Sybase does
support 4mm drives on DEC; testing has been successful with the DEC
4mm (rlz06) tape drive.
bcp: Determining Data Logged
Question: Sybase Technical Support recently received a call from a
customer who was bulk copying 1 million rows of data, 885 bytes each,
with no indexes or triggers (so fast bcp was being used), resulting in
about 21MB of data being logged. The customer thought this was
unusually high and that there might be a bug. However, this is normal
behavior, even for fast bcp.
Answer: Most of the added records (except for the physical
begin/commit tran) are records having to do with changing the column
sysindexes.last; this logging is done to track the allocation of pages
and which is the last page, so that SQL Server can roll back an
incomplete bcp if the machine crashes or if a shutdown occurs in the
middle of the bcp. This accounts for the growth in syslogs.
Adding 2000 rows to a table causes syslogs to grow by about 43 pages.
Adding 1 million rows would be about 21500 (43MB) pages of log, which
is higher than the customer's figure, but the 21500 figure is only an
estimate.
DB-Library: dbcursoropen() Returns NULL
Problem: Opening a cursor in the 10.0 release of Open Client
DB-Library->/C with the following statement:
dbcursoropen(dbproc,"select type from pubs2..titles,...)
results in a return of NULL values. On Sun4/OS4, SQL Server crashes
with a stack trace; on RS6000 the cursor-open attempt just fails.
Changing the database context to pubs2 and then opening the cursor
without the full table address succeeded. This was logged as bug
53143.
Solution: The use of table aliases and full table-name recognition has
been added to DB-Library cursors. It is available with the latest
one-off EBF for DB-Library (#3197 for RS6000, # 3198 for Sun4, #3199
for HP9800) and will be included in subsequent rollups.
DB-Library: dbclose() and File Descriptors
Question: File descriptors appear not to be reused when I try to
re-establish a SQL Server connection. Does DB-Library close a file
descriptor when a connection is broken or does dbclose() have to be
called, regardless
Answer: DB-Library marks a DBPROCESS DBDEAD when a connection goes
bad. You should call dbclose() to close out the file descriptor.
Embedded SQL: Target of INTO Clause
Problem: According to the Open Client Embedded SQL Programmer's Guide,
the target of an into clause can be either a table, as in
Transact-SQL®, or a list of host variables. However, users of the
10.0.1 release of Embedded SQL-> attempting the following command:
EXEC SQL select * into table1 from table2
or
EXEC SQL select * into #table1 from table2
receive the following run-time error message:
**SQLCODE=(-25006)
** SQL Server Error
** Unexpected CS_ROW_RESULT received.
Solution: This behavior was determined to be a bug, numbered 54619,
and has been fixed. The fix will be available to customers in a future
Rollup.
Embedded SQL: EXEC PROC Enhancement
In releases prior to 10.0.2, it was not possible to execute a stored
procedure that returned data rows in Embedded SQL. As of 10.0.2,
however, the EXEC PROC statement has been enhanced to allow a single
select statement in the procedure.
You can declare a procedure:
create procedure myproc (@p1 int, @p2 out) as
select c1, c2 from t1 where c3 > @p1
select @p2 = count(*) from t1 where c3 <= @p1
and then use Embedded SQL to execute it:
exec sql exec :retval = myproc (:hv1, :hv2 out)
into :hv3, :hv4;
The same rules apply to the into hv-list clause in this example as
apply to a straight select statement -if you select more than one row,
you must have array host variables or you will get a cardinality
error.
The latest Embedded SQL EBFs support this feature (feature # 56616),
and it will be in the 10.0.2 Rollup.
Embedded SQL/COBOL: Memory Leak in libcobct.a
Users of the 10.0 or 10.0.1 release of the Embedded SQL/COBOL
precompiler may encounter this problem: a program runs successfully
for more than 100,000 rows of cursor processing and then begins to
fail. This is a known bug involving a memory leak in libcobct.a (the
COBOL interface to Client-Library and CS-Library, in the veneer
layer). The latest precompiler EBF fixes this problem (starting with
EBF 2887). The EBF is from the 10.0.1 P2 mass ship code line, and you
need the 10.0.1 SQL Server to run it.
On UNIX, you can check for memory leaks by using ps -v to examine your
program's memory size; if it keeps growing, you may have a leak.
Mainframe Access Products: Latest EBFs
Here is the latest list of available rollup Mainframe Access Products
(MAP->) EBFs as of 11/14/94. This list replaces all previous lists. Be
sure to read the important notes after it. Mainframe Access Product
Catalog # Rel. 2.x EBF # Rel. 3.0 EBF # Open Client(tm)/Mainframe for
CICS/LU6.2 19320 2932 N/A Open Server/Mainframe for CICS/LU6.2 19300
2218 3528 Open Server/Mainframe for CICS/TCP_IP 19350 N/A 3529 Open
Server/Mainframe for IMS/LU6.2 19315 N/A 3527 OmniSQL Access
Module(tm) for DB2 (CICS/LU6.2) 19311 1971 3961 OmniSQL Access Module
for CICS/TCP_IP 19360 N/A 3962 OmniSQL Access Module for IMS/LU6.2
19370 N/A 3526
* Open Client/Mainframe is at release 2.0, and is supported for
CICS/LU6.2 only.
* Open Server/Mainframe is at release 3.0 and is supported for
CICS/LU6.2, CICS/TCP-IP, and IMS/LU6.2.
* OmniSQL Access Module (OSAM) for DB2 is currently at release 10.1.
4.
* All mainframe products currently in release require use of the
product Net-Gateway(tm), thus the references to Net-Gateway EBFs
required for OS/MF or OC/MF or OSAM to perform correctly.
* All Trinzic (InfoHub) customers need the latest 3.0 Net-Gateway
and Open\x11Server/CICS EBF.
* Some Open Client/CICS customers using EBF 2932 or below may need
the latest Net-Gateway EBF for their particular platform; it
contains a SQL Server name-length fix.
Here is the latest list of all available rollup Net-Gateway EBFs as of
11/14/94:
Net-Gateway
Platform Catalog # Rel. 2.x EBF # Rel. 3.0 EBF #
HP9000/800 17700 N/A 3518
OS/2 16230 3882 3.0 GA
RS6000 12670 3887 3517
Solaris 12950 N/A 3772
SunOS 18600 3843 3516
MAP Notes
EBF 3961 (available now) replaces two EBFs, 3830 (which was
mass-shipped) and 3524 (whose shipping was stopped); it will mass-ship
soon. EBF 3962 will also mass-ship soon, to replace EBF 3525. EBFs
3528, and 3529 mass shipped to all licensed customers around the week
of 10 October 1994. Please make sure you have these EBFs and plan to
install them with your 3.0 MAP products soon. All EBFs have been
through complete QA and regression testing and constitute the latest
maintenance codeline for 3.0/10.1 MAP customers.
If you received EBF 3830 or 3524, you should not install them, but
instead, wait for 3961.
Please note that these Mainframe EBFs now ship automatically as part
of any new product order. They do not ship automatically for trial
licenses.
The following errors have been corrected with current or upcoming
EBFs:
1. With EBF 3050 or 3051 applied (OSAM/DB2 CICS only), the following
occurs:
If a query selects more than 2 decimal columns, the third and
subsequent column of DB2 decimal types are not sent to the client.
The problem occurs with decimal columns defined using NOT NULL or
NOT NULL WITH DEFAULT. There doesn't seem to be a problem with
decimal columns defined as "nullable" (the default). Fixed on EBFs
3528 and 3529.
2. For customers using PL/I only, EBFs 3005 and 3006 have a syntax
error in the INCLUDE library member SYGWPLI that causes a compile
error. Fixed on EBFs 3528 and 3529.
The SYGWPLI source in question: DECLARE TDS_INPUTVALUE FIXED
BIN(31) INIT(0) STATIC; TDS_RETURNVALUE FIXED BIN(31) INIT(1)
STATIC; Should read: DECLARE TDS_INPUTVALUE FIXED BIN(31) INIT(0)
STATIC, TDS_RETURNVALUE FIXED BIN(31) INIT(1) STATIC;
The semicolon ending TDS_INPUTVALUE is replaced with a comma.
3. In EBFs 3005 and 3006, the commentary header in the INCLUDE
library member SYGWPLI, and the commentary header in the MACLIB
library member SYGWASM, read "Rel 2.0". In fact, this is the
latest Rel. 3.0. Fixed on EBFs 3528 and 3529.
4. All MAP EBFs now support RPC parameters that are greater than 32K
but less than 64K, without needing the latest Net-Gateway EBFs.
5. All MAP EBFs now support RPC parameters greater than 64K, if you
also have the latest Net-Gateway EBF 3516 or higher, depending on
your platform, and if you use the new Net-Gateway start-up option
-E to enable this support. The new OS/2 GA about to be released
has this support built in.
6. VS/COBOL (old COBOL) programs no longer abend (new problem with
MAP release 3.0).
7. Open Server/Mainframe for CICS applications can run with the 3.0
stub without having to relink.
Net-Gateway Notes
* A release 2.x Net-Gateway can run with a CICS LU6.2 MAP product at
the 3.0 or 10.1 release level, but it cannot utilize any new
functionality. For migration purposes, always upgrade the
mainframe code first, then the Net-Gateway.
* The new 3.0 Net-Gateway EBFs include:
+ memory leaks fixed;
+ group password no longer displayed;
+ new -C start-up option to roll lowercase userid/passwords
into uppercase before sending to mainframe;
* The new 2.0 Net-Gateway EBFs include:
* group password no longer displayed;
* new -C start-up option, as described above;
* sygc gateway control program fixed.
Server Documentation Bugs Fixed
4.9.2 SQL Server documentation bug #46986, clarifying the use of
sp_logdevice, has been fixed for the 10.0 release. If a database log
is on a log-only segment and you execute the command sp_logdevice
mydb, newlogdev, nothing moves, and you end up with two log devices.
The current documentation clarifies that if you used the log on option
of create database to put the log on its own segment, you must use
sp_extendsegment to increase the size of the log segment.
Also fixed is 10.0 SQL Server documentation bug #54342 pertaining to
sp_rename in the SQL Server Reference Manual. It is now specified that
if the object to be renamed is an index, the object name must be in
the form table.indexname. Please make a note of these corrections
until you receive the revised documentation.
Connectivity Documentation Bugs Fixed
Here are some recent documentation bug fixes for 10.0 documents:
DB-Library Reference Manual
Bug #, Description
59529
Found in release 10.0; may apply earlier. In the dbfcmd
section, in the table "dbfcmd Conversions", the entry "char"
should read "char* (null-terminated string)".
49039, 54084
(Duplicate bugs) BCP_SETL Between releases 4.x and 10.0, the
BCP_SETL macro became bcp_setl in the reference manual. The
macro name itself was not changed.
53814
10.0. Two-Phase Commit Service (Chapter 4). SQL Server 10.0 is
not compatible with pre-10.0 probe versions. This is not stated
in early copies of the 10.0 reference manual, however, a note
has been added to the section entitled "The Probe Process" in
the latest revision of the 10.0 reference manual, dated August
5 1994.
59918
In Table 2-29 ("Common Errors" for dberrhandle()), the error
handler cannot return INT_CONTINUE for "timeout on login"
errors as indicated in footnote c. When you return
INT_CONTINUE, DB-Library does a check; if the error was other
than SYBETIME, DB-Library prints an informational message, then
treats it as though INT_EXIT was returned. The footnote still
applies to SYBETIME errors.
Common Libraries Reference Manual (release 10.0.x)
Bug #, Description
61570, 57794
cs_set_convert, "Parameters" section, "func": Parameter "func"
is a pointer to a CS_CONV_FUNC variable. In the explanation,
both uses of the "func" should be "*func". "*func" is the
address of the custom conversion routine. Note that
CS_CONV_FUNC is itself a pointer to a function. See code sample
following this table.
61793
cs_convert "Parameters" section: (Under srcfmt) maxlength: The
length of the data in the srcdata buffer. This field is ignored
for fixed-length source datatypes.
srcdata - A pointer to the source data. To indicate that the
source data represents a null value, pass srcdata as NULL. If
srcdata is NULL, the null-substitution value for the datatype
indicated by destfmt is placed in *destdata.
The simplest way to use cs_set_convert is to declare a program
variable as a CS_CONV_FUNC type, and then pass the address of
the variable to cs_set_convert. Here is some sample code:
/*
** This code assumes that MyEncrypt is a custom conversion routine
** defined according to the documented guidelines. In this case,
** MyEncrypt converts from the CS_CHAR to the user-defined type
** indicated by ENCRYPT_TYPE. This fragment installs MyEncrypt.
*/
CS_CONV_FUNC myfunc;
myfunc = MyEncrypt;
if (cs_set_convert(cp, CS_SET, CS_CHAR_TYPE,ENCRYPT_TYPE,
&myfunc) != CS_SUCCEED)
{
fprintf(stdout, "cs_set_convert(ENCRYPT_TYPE failed!\n");
(CS_VOID)ct_exit(cp, CS_UNUSED);
(CS_VOID)cs_ctx_drop(cp);
exit(1);
}
Open Client/Server Supplemen
The 10.0 UNIX version of the Client/Server Supplement has an error in
Appendix A, in the reference pages for the cpre and cobpre utilities.
The -g flag was incorrectly left in the syntax statement for these
utilities. The -g flag is no longer supported and should be deleted
from the syntax statement.
Latest Server Certification Report
The latest SQL Server Certification Report is available on the
CompuServe OpenLine Sybase forum and will be available with the next
AnswerBase release (due in February of 1995).
Bugs Fixed in 10.0.2 SQL Server Release
This is a list of selected bugs in the 10.0.1 release of SQL Server
that have been fixed in the 10.0.2 maintenance release. We encourage
you to upgrade to 10.0.2 as soon as you receive that release!
Bug #, Description
51229
Can't dump data from a data device that exists on a device
defined as a hard link to a raw partition created by the UNIX
command ln. dump database fails with the message "Backup
Server: 4.56.2.1: device validation error: couldn't validate
tape drive characteristics for drive %s: invalid argument."
55379
If the dump device and the database device are both character
special devices, dump fails with vague errors like
"Multibuffering subprocess died." On the OS console, you will
see errors like "get_membuf: shmget, Invalid argument."
46958
Views can't be created on tables with more than 46 columns.
create view returns without error, but the view does not appear
in sysobjects.
49012
After a dump and a load, a table with an identity field gets
its identity value starting from 1 again, instead of continuing
from the last generated value.
50703
A query involving divide by zero gets error 3621 and is
aborted, even when arithabort option is set to off; hence, no
result is generated from the query. For example: select 10/0,
name from sysusers returns 0 rows.
50932
Subqueries and aggregates that require an initial "bylist
projection" step can be processed inefficiently, and, in some
cases, can return the wrong results. This is due to creating a
cross product internally or adding qualifications for this
setup.
50946
select isnull(column,10) from table where column is
numeric(5,0) with identity will give the following message:
"Illegal precision returned from SQL Server." (General case is
a select isnull(54321.9865,5.6781).)
51723
sp_addsegment accepts dbname as a parameter, but performs
sanity checks and adds the segment to the current database,
whether or not it is the one named.
51815
sybsystemprocs is treated as a required database for SQL Server
recovery, and will prevent recovery if the procs device becomes
unavailable.
51979
Updating a column that has a rule or check constraint causes
the "infected with 11" message, and the connection is broken.
52294
Optimizer can choose a table scan over a unique index when the
index is on a numeric column and the column is compared to
constant or dissimilar precision column in join.
52558
Defining a cursor using a statement like declare cursor_name
cursor for select field from table where field like @pattern
for read only gets DBPROCESS DEAD and stack trace with signal
11. The pattern has to be some declared variable.
52636
Getting a 225 error ("Referenced object %s dropped during query
optimization") when using a procedure to insert data into a
table with constraints. The table is defined in another
database.
52669
With unnamed constraints, given an alter table...drop
constraint statement, the constraint appears to drop, but
actually remains in place. This seems to happen only where
table name lengths are >= 10 characters.
52936
Incorrectly placed decimal in select list of query causes SQL
Server to stack trace with "current process infected with 11."
Repeating this can cause SQL Server to hang.
53028
SQL Server crashes with 8211 error when running client cursor
that generates too many work table IDs. It might happen with
any kind of cursor.
53080
Executing a stored procedure with auditing turned on as an RPC
results in DBPROCESS DEAD OR NOT ENABLED message and
termination of connection.
53273
create table x (i int nul); insert x values (null+null) results
in infection with 11 and stack trace.
53373
A table with multiple referential constraints does not enforce
the latter constraints in the case where a NULL happens to be
inserted in any column of the first constraint.
53772
Running a simple ESQL/C query using host variables gives stack
trace. For example: declare cursor idlo for select logon_id
from table where logon_id > :logon_id
54367
Creating a stored procedure that accesses a temporary table
created by a parent-level procedure (see SQL Server 10.0 System
Administration Guide pg. 13-12), the data is inaccessible to
the child-level procedure; rows are affected, but the data is
"invisible".
55813
SQL Server process seg faults (infected with 11) in appnd_log()
and leaves behind a semaphore lock; the process holding the
lock does not show up in sp_who. sp_lock shows a non-existent
process.
55862
Deleting rows from a table containing text data via a
multi-table join may result in 1129 error and subsequent 2540
errors. This is the same as 21529 and 50353 in 4.0.1 and 4.9.x.
56127
Range levels are incorrect when a subquery selects from a view.
56186
A query that selects into a temporary table but fails with a
303 error causes a temporary table to be left in tempdb. It
cannot be dropped without directly updating system tables.
56226
3307 errors occur when an error such as a duplicate key occurs
while inserting into a temporary table with a unique index.
56540
sp_lock: on a system with thousands of locks in use,
overflowing the temporary buffer used to insert into syslocks
can also result in stack corruption and subsequent seg fault
(infected with 11 message).
57238
Stored procedure containing create table with primary key
clause generates 2620 and stack trace when executed for the
third time (happens with temporary tables and user tables).
57340
convert function produces incorrect results if its argument is
the result of an aggregate that evaluates to NULL. The result
is garbled.
57590
Executing a stored procedure via RPC, with auditing enabled,
results in DBPROCESS DEAD and lost isql connection. Error log
shows infected with 11 in prot_search function. Refer to bug
53080, a previous version of this problem.
57694
sp_columns incorrectly reports a precision of NULL for char,
varchar, and other types. This is a regression of 4.9
functionality, in which the length of the field was reported
when the precision in spt_datatype_info was NULL.
58138
ctrl-c (^c) behavior is random. It is sometimes ignored and
sometimes causes core dump.
58332
dbcc checkdb(dbname, skip_ncindex) fails with 603 error if the
database has more than 16 tables with clustered indexes in
them.
58563
sp_columns incorrectly returns datatype, precision, etc.,
causing Microsoft ODBC driver to indicate errors. Also, a
duplicate key in spt_datatype_info can cause sp_columns to
return two rows for a column, resulting in ODBC errors.
59436
When chained transaction mode is on, there is a possibility
that a bogus ENDXACT record with xactid(0,0) could be written.
This would lead to 605 error during recovery.
Bugs Fixed in Latest Connectivity Maintenance Releases
The following tables contain a selection of bugs fixed for the 10.0.2
maintenance release of Sybase connectivity products. This is not a
comprehensive list; the complete list is available on the Sybase forum
on CompuServe.
Bugs Fixed in Open Client/Open Server Common Libraries 10.0.2
Bug #, Description
56638
The MACROs _MSC_VER and __STDC__ are not consistently protected
by #if defined() in csconfig.h. This causes warnings when the
compiler doesn't define the macros.
50044
cs_objects(CLEAR) when fnlen = CS_UNUSED, lnlen = CS_WILDCARD,
type = CS_CONNECTION, threadlen = CS_UNUSED, scopelen =
CS_UNUSED does not remove all connections.
46893
comn_chartonum-if CS_SRC_VALUE is specified for
precision/scale, the leading zeros of the converted
(dest->array) are not stripped after the conversion, which
usually results in the CS_NUMERIC having a value of 0.000.
Bugs Fixed in Open Client Client-Library 10.0.2
Bug #, Description
61407
blk_sendrow used a static variable, causing it not to be
thread-safe. Multiple client blk_sendrow sent another client's
row to the SQL Server, causing database corruption
58019
RPC return parameter of type NUMERIC or DECIMAL always returns
0.
57450
Password encryption causes ct_connect() to hang.
53793
When statistics io/time is on, ct_send core dumps.
57732
Client-Library application crashes because of memory
corruption.
58008
Client-Library reports an internal state machine error when an
update is done on a table with timestamp and a trigger.
53508
Fetching between multiple cursors can cause assertions after
one of the cursors gets to end-of-data. If this end-of-data
cursor does not call ct_results() immediately after
ct_fetch()->END_DATA, an assertion occurs when another cursor
fetches.
Bugs Fixed in Open Client DB-Library 10.0.2
Bug #, Description
59551
Memory leak in isql.
58703
Memory leak when dbopen() fails.
58576
bcp crashes when copying in numeric columns in character
format.
58103
Memory leak in the DB-Library cursor code. The memory allocated
during cursor operation never gets released.
54965
bcp (and isql) crashes if a character set is specified and a
larger-than-default packet size is specified.
57333
When there is holdlock in select statement, dbcursoropen fails
with `incorrect syntax near keyword holdlock'.
53604
DB-Library hangs in an Open Server for AT&T (NCR), RS6000, HP,
and Solaris platforms due to not being set up properly for
signals.
53815
When a table has a composite primary key, repeated calls to
dbcursorfetch() produce incorrect result sets. Some rows are
missed and others are repeated.
58138
ctrl-c (^c) behavior is random. It is either ignored or
sometimes causes core dump.
Bugs Fixed in Embedded SQL/C 10.0.2
Bug #, Description
52939
sqlca.sqlerrd[2] should be set to rowcount on a successful
fetch.
53129
-G beginning of .sql script should drop the procedure it is
about to create if it exists- otherwise, developer has to drop
it manually each time a file is precompiled.
53255
char * host variables used as descriptor names cause ASSERT
(M_INTERNA L_ERROR) in cdgsvs.c line 156.
53798
When selecting into an array, the number of the row selected is
not returned in the sqlca.
54506
The get descriptor always returns 0 (even for the "nullable"
column).
54619
Using EXEC SQL SELECT... INTO TABLE gives error "-25006
Unexpected CS _ROW_RESULT received."
55190
-G and open cursor (static). If there is any static dml
statement (which we generate a stored procedure for) in the
source file between the CURSOR DECLARE statement and the CURSOR
OPEN statement, the wrong procedure number is generated for the
OPEN.
55761
Use of the :indvar = INDICATOR clause of the get descriptor
statement does not work- indvar is not referenced in the
generated code.
56351
-G and NUMERIC datatypes-the generated procedure parameters do
not have a precision/scale in their declaration. The default
precision an d scale you get in this case is (18,0).
56616
Add an into clause to the exec stproc statement so you can have
1 result set in a user-defined stored procedure.
56732
Indicators are not supported with host variable in the
parameter list of an EXEC_PROCEDURE statement.
59448
ESQL/C raises a syntax error if you de-reference a structure
pointer's element. If the host variable is a structure, a.b is
legal syntax, but if it is a pointer to a structure, a->b is
not legal.
59814
paraming a 0-length null terminated string host variable to SQL
Server used to be interpreted as a single space in 4.0.4;
however, it is interpreted as a NULL value in 10.0. Make the
10.0 ESQL behavior the same as 4.0.4
61469
PREPARE and ALLOCATE DESCRIPTOR each allocate a connection
every time they are called, but DROP PREPARE/DESCRIPTOR does
not free this connection. Results in big memory leak.
Bugs Fixed in Embedded SQL/COBOL 10.0.2
Bug #, Description
49210
PIC strings for number type variables without "s" are not
accepted. For example: 01 max-1000 pic 9(3)v9(2)
53129
-G beginning of .sql script should drop the procedure it is
about to create if it exists- otherwise, the developer has to
manually drop it each time a file is precompiled.
53236
The pic, usage, sign, synchronized, justified, blank, and value
clauses can be specified in any order in standard DOBOL-cobpre
requires them in the order listed above.
53678
ESQL/COBOL does not support "level 88" condition names.
Precompiler should gobble and ignore everything following 88,
up to the end of that declaration (terminating period, ignoring
periods in decimal literals, etc.).
53798
When selecting into an array, the number of the row selected is
not returned in the sqlca.
54322
-b (no re-bind) option is broken. If you use -b no binds are
done. The cursor fetch appears to work, but no values are moved
into host variables.
54619
Using EXEC SQL SELECT... INTO TABLE give error "-25006
Unexpected CS _ROW_RESULT received."
55297
You get "M_INTERNAL_ERROR, Fatal Internal Error at Line
162...symtab/littype.c" error when you use SQL Server to do
syntax checking at precompile time, and you have an
ESQL-statement with COBOL host variables as input parameters.
56351
-G and NUMERIC datatypes-the generated procedure parameters do
not have a precision/scale in their declaration. Default
precision and scale in this case is (18,0).
56616
Add an into clause to the exec stproc statement so that you can
have one result set in a user-defined stored procedure.
56732
Indicators are not supported with the host variable in the
parameter list of an EXEC_PROCEDURE statement.
60105
Dynamic execute USING SQL DESCRIPTOR always sends a NULL
regardless of how DATA was set.
61469
PREPARE and ALLOCATE DESCRIPTOR each allocate a connection
every time they're called, but DROP PREPARE/DESCRIPTOR does not
free this connection. Results in big memory leak.
61755
Fetch into arrays for money and float datatypes doesn't work
when occurs is > 1.
62007
4.0.4 allowed underscores in host variable names. This was
dropped in 10.0. We've put it back for compatibility reasons.
62102
CS-DATETIME and CS-DATETIME4 ESQL/COBOL declarations are
incorrectly treated as STRING_TYPE variables in cobpre logic.
This causes the precompiler to raise the M_SCALAR_CHAR error if
an application attempts to use the declarations in an ESQL
statement.
Bugs Fixed in Open Server Library 10.0.2
Bug #, Description
55984
Re-entrant malloc problem... when accepting client connections
at interrupt level, t_open() is called which mallocs space. If
user is doing malloc we crash. 53416
On the VAX/VMS platform, Open Server does not use the KEEPALIVE
feature when communicating via TCP/IP. Hence, OMNI cannot
detect PC connections that have been abnormally disconnected.
57146
Open Server doesn't send the parameters associated with the
cursors.
53799
Increases the maximum number of RPC parameters to 32768 to
greater than 255.
58285
Open Server crashes with segmentation fault when
srv_lockmutex() is called inside stop handler.
58734
srv_dbg_stack() API always returns the stack of the current
thread instead of the srvproc argument passed to it.
52555
If an attention comes in, there is no way to wake up a srvproc
sleeping on a message queue without killing the srvproc.
53862
SRV_IODEAD isn't upward compatible. In 202, SRV_IODEAD returns
TRUE for non-client threads, but in 10.0, it returns CS_FALSE.
53172
sp_serverinfo does not format the image information returned to
the client correctly for either 1- or 2-byte character
definitions.
61612
ct_cancel() to an Open Server does not work when it is in pass
through mode. Open Server gets a fatal 16300 (SRV_EBADTOKEN)
error.
61785
The srv_event was issued on a thread that is not event-driven.
The Open Server does not do any error checking, regardless of
whether or not the thread has a message queue associated with
it.
_________________________________________________________________
Staff
* Principal Editor: Leigh Ann Hussey
* Contributing Writers:
+ Lance Andersen
+ Perry Bent
+ Dave Clegg
+ William Green
+ Bret Halford
+ Gerald Soulos
+ Elton Wildermuth
+ Anderson Consulting
+ Sybase Engineering
Send comments and suggestions to:
SYBASE Technical News
6475 Christie Avenue
Emeryville, CA 94608 USA
Disclaimer: No express or implied warranty is made by SYBASE or its
subsidiaries with regard to any recommendations or information
presented in SYBASE Technical News. SYBASE and its subsidiaries hereby
disclaim any and all such warranties, including without limitation any
implied warranty of merchantability of fitness for a particular
purpose. In no event will SYBASE or its subsidiaries be liable for
damages of any kind resulting from use of any recommendations or
information provided herein, including without limitation loss of
profits, loss or inaccuracy of data, or indirect special incidental or
consequential damages. Each user assumes the entire risk of acting on
or utilizing any item herein including the entire cost of all
necessary remedies.
For more info send email to tech...@sybase.com
Copyright 1995 © Sybase, Inc. All Rights Reserved.
Q10.2.1
Technical News Volume 4, Number 1, February, 1995
This issue of the SYBASE Technical News contains new information about
your SYBASE software. If needed, duplicate this newsletter and
distribute it to others in your organization. All issues of the SYBASE
Technical News and the Troubleshooting Guides are included on the
AnswerBase CD.
IN THIS ISSUE
* Technical Support News/Features
+ Customer Site Visits Planned
+ Troubleshooting Guide Update
* SQL Server
+ Error 428 or 4408: Referential Integrity and the 16-Table
Limit
+ The Identity Column, Definition and Purpose
+ Problems with sybload on Solaris
+ Note on Intel Pentium Floating Point Bug
+ Problems with Backup Server and AIX 3.2.5
+ Hazards of Copying Dumps with AIX Utilities
* Connectivity / Tools / PC
+ Open Client/MF: Undocumented Return Code
+ PowerBuilder AutoCommit and Open Transactions
+ Stratus VOS and TCP
* Certification and Fixed Bug Reports
+ Bug 63348 - kill on Multiprocessor Servers
+ Bug 62149 - Stored Procedure with Variable and compute Clause
Raises Error 411
+ MAP Doc Corrections
+ Latest Rollups for SQL Server 4.9.2
+ Bugs Fixed in Latest Rollup, SQL Server 4.9.2
+ Latest Rollups for SQL Server 10.0.2
+ Bugs Fixed in Latest Rollup, SQL Server 10.x
Customer Site Visits Planned
Technical Support Publications wants to learn how you use Sybase
products and documents, so that we can give you better technical
documentation. If you are located in the Bay Area and would be willing
to have Sybase employees visit your workplace, send mail to
tech...@sybase.com.
If a visit is arranged, a small group of writers and engineers will
visit your site and observe how our products and documents work (or
don't work) for you.
We want to hear your concerns. We're here to help!
Troubleshooting Guide Update
The format of the SQL Server Troubleshooting Guide has changed, to be
more useful to you. The next edition will appear in two volumes, SQL
Server Error Messages, and the SQL Server Troubleshooting Guide (for
general troubleshooting information). Both manuals are available on
the volume 2, number 2 AnswerBase CD (due for shipment in May). Both
manuals will also be available in the SyBooks System 10 CD update.
The Tools and Connectivity Troubleshooting Guide, last updated in
December, makes its final appearance as a single volume in the Q2
AnswerBase CD. Because of the diversity of products covered by this
guide, and the expansion of some of the sections, in the future we
will publish separate AnswerBase FAQ lists for each product. We will
introduce this format in the Q3 AnswerBase CD.
Error 428 or 4408: Referential Integrity and the 16-Table Limit
Question
Update to a single table in SYBASE SQL Server release 10.x fails with
Error 428:
Too many table names or referential constraints in the query,
maximum allowed table references is '16'.
In 4.9.x, Error 4408 may be raised:
The query and the views in it exceed the limit of 16 tables.
Why does this happen, if I am only updating one table?
Answer
The limit on the number of tables any given query can touch is 16. A
query on a table with referential constraints, that is, many primary
and foreign keys, can refer to more tables than the limit allows. When
you hit the limit with such a table, the update fails. For example,
suppose there are 15 tables, named c1-c15, each one of which has one
primary key, a reference to another table, p, and a foreign key
constraint referring to one of 16 other tables. Each one of the tables
c1-c15 is built like this:
create table c1
(ccol1 smallint, ccol2 smallint, primary key (ccol1),
constraint pc1 foreign key (ccol2) references p (pcol1))
go
p is built like this:
create table p
(pcol1 smallint, pcol2 smallint, primary key (pcol1))
go
And the remaining 16 tables (p1-p16) are built like this:
create table p1
(pcol1 smallint, pcol2 smallint, primary key (pcol1))
go
Now build another table, c, that refers to all 31 other tables, like
this:
create table c
(pcol1 smallint, ccol2 smallint, ccol3 smallint, ccol4 smallint,
ccol5 smallint, ccol6 smallint, ccol7 smallint, ccol8 smallint,
ccol9 smallint, ccol10 smallint, ccol11 smallint,
ccol12 smallint, ccol13 smallint, ccol14 smallint,
ccol15 smallint, ccol16 smallint, ccol17 smallint,
primary key (pcol1),
constraint c2p1 foreign key (ccol2) references p1 (pcol1),
constraint c3p2 foreign key (ccol3) references p2 (pcol1),
constraint c4p3 foreign key (ccol4) references p3 (pcol1),
constraint c5p4 foreign key (ccol5) references p4 (pcol1),
constraint c6p5 foreign key (ccol6) references p5 (pcol1),
constraint c7p6 foreign key (ccol7) references p6 (pcol1),
constraint c8p7 foreign key (ccol8) references p7 (pcol1),
constraint c9p8 foreign key (ccol9) references p8 (pcol1),
constraint c10p9 foreign key (ccol10) references p9 (pcol1),
constraint c11p10 foreign key (ccol11) references p10 (pcol1),
constraint c12p11 foreign key (ccol12) references p11 (pcol1),
constraint c13p12 foreign key (ccol13) references p12 (pcol1),
constraint c14p13 foreign key (ccol14) references p13 (pcol1),
constraint c15p14 foreign key (ccol15) references p14 (pcol1),
constraint c16p15 foreign key (ccol16) references p15 (pcol1),
constraint c17p16 foreign key (ccol17) references p16 (pcol1))
go
sp_helpconstraint on p gives this output:
name defn
--------------- --------------------------------------------
pc1 c1 FOREIGN KEY (ccol2) REFERENCES p(pcol1)
pc10 c10 FOREIGN KEY (ccol2) REFERENCES p(pcol1)
pc11 c11 FOREIGN KEY (ccol2) REFERENCES p(pcol1)
pc12 c12 FOREIGN KEY (ccol2) REFERENCES p(pcol1)
pc13 c13 FOREIGN KEY (ccol2) REFERENCES p(pcol1)
pc14 c14 FOREIGN KEY (ccol2) REFERENCES p(pcol1)
pc15 c15 FOREIGN KEY (ccol2) REFERENCES p(pcol1)
pc2 c2 FOREIGN KEY (ccol2) REFERENCES p(pcol1)
pc3 c3 FOREIGN KEY (ccol2) REFERENCES p(pcol1)
pc4 c4 FOREIGN KEY (ccol2) REFERENCES p(pcol1)
pc5 c5 FOREIGN KEY (ccol2) REFERENCES p(pcol1)
pc6 c6 FOREIGN KEY (ccol2) REFERENCES p(pcol1)
pc7 c7 FOREIGN KEY (ccol2) REFERENCES p(pcol1)
pc8 c8 FOREIGN KEY (ccol2) REFERENCES p(pcol1)
pc9 c9 FOREIGN KEY (ccol2) REFERENCES p(pcol1)
p_7325296431 PRIMARY KEY INDEX ( pcol1) : CLUSTERED,
FOREIGN REFERENCE
(16 rows affected, return status = 0)
sp_helpconstraint on c gives this output:
name defn
--------------- ----------------------------------------------
c10p9 c FOREIGN KEY (ccol10) REFERENCES p9(pcol1)
c11p10 c FOREIGN KEY (ccol11) REFERENCES p10(pcol1)
c12p11 c FOREIGN KEY (ccol12) REFERENCES p11(pcol1)
c13p12 c FOREIGN KEY (ccol13) REFERENCES p12(pcol1)
c14p13 c FOREIGN KEY (ccol14) REFERENCES p13(pcol1)
c15p14 c FOREIGN KEY (ccol15) REFERENCES p14(pcol1)
c16p15 c FOREIGN KEY (ccol16) REFERENCES p15(pcol1)
c17p16 c FOREIGN KEY (ccol17) REFERENCES p16(pcol1)
c2p1 c FOREIGN KEY (ccol2) REFERENCES p1(pcol1)
c3p2 c FOREIGN KEY (ccol3) REFERENCES p2(pcol1)
c4p3 c FOREIGN KEY (ccol4) REFERENCES p3(pcol1)
c5p4 c FOREIGN KEY (ccol5) REFERENCES p4(pcol1)
c6p5 c FOREIGN KEY (ccol6) REFERENCES p5(pcol1)
c7p6 c FOREIGN KEY (ccol7) REFERENCES p6(pcol1)
c8p7 c FOREIGN KEY (ccol8) REFERENCES p7(pcol1)
c9p8 c FOREIGN KEY (ccol9) REFERENCES p8(pcol1)
c_3610523221 PRIMARY KEY INDEX ( pcol1) : CLUSTERED
(17 rows affected, return status = 0)
An attempt to insert or delete will give the following result:
1> delete p where pcol1 = 1
2> go
Msg 428, Level 16, State 1:
Line 1:
Too many table names or referential constraints in the query,
maximum allowed table references is '16'.
1> insert c values (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17)
2> go
Msg 428, Level 16, State 1:
Line 1:
Too many table names or referential constraints in the query,
maximum allowed table references is '16'.
UPDATE commands will produce similar results.
An update through a view can also trigger this error if the view
includes more than 16 tables.
When setting up constraints on your tables, look at the maximum number
of tables that might be touched by an update, insert, or delete
statement before you set up your constraints.
When setting up views, be careful not to include more than 16 tables
in a view if you plan to update through it.
The Identity Column, Definition and Purpose
Customers have for some time wanted a way to have an incrementing
unique key column in a table.
The 10.0 release of SQL Server provides this functionality with a
unique key column; the user defines a column as IDENTITY, and it is
updated automatically.
Characteristics of the IDENTITY Property
IDENTITY is a column property, like NULL or NOT NULL. Its
characteristics are:
* Only positive integers are allowed. The column may not contain
zero (0) or NULL, or any fraction.
* The column's value starts with 1 and always increments by 1 to the
maximum value.
* When the maximum value is reached, there is no wraparound; the
next attempt to insert raises an error message.
* The identity column is not updatable; upon update of a row, the
value in its identity column does not change.
* When you insert a new row, you need not insert an identity value;
the identity value is automatically generated and inserted for
you.
* If you need unique identity column values, put a unique index on
the identity column. Identity column values are automatically
unique, unless you insert a value directly.
* Gaps may occur upon system crash or shutdown with nowait. See
"Preburn Issues" below.
* Gaps may also exist between identity column values because of
rollback or delete operations; identity values are not reused. In
the example below, counter_id is the identity column in the table
running_counter:
1> select * from running_counter
2> go
counter_id next_number
---------- -----------
1 2
2 5
(2 rows affected)
1> begin tran
2> select * from running_counter
3> insert running_counter (next_number) values (10)
4> select * from running_counter
5> rollback tran
6> go
counter_id next_number
---------- -----------
1 2
2 5
(2 rows affected)
(1 row affected)
counter_id next_number
---------- -----------
1 2
2 5
3 10
(3 rows affected)
1> insert running_counter (next_number) values (10)
2> go
(1 row affected)
1> select * from running_counter
2> go
counter_id next_number
---------- -----------
1 2
2 5
4 10
(3 rows affected)
Setting Up Identity Columns
The identity column of a table is a numeric datatype with the IDENTITY
property. Because the numeric datatype allows for digits to the right
of the decimal place in its definition, but the identity column does
not, you must define the number of decimal digits as zero, as in the
following example:
create table sales_daily
(stor_id char(4) not null,
ord_num numeric(10,0)identity,
ord_amt money null)
The maximum number of digits permitted for the identity column is 38.
Be very careful of large identity column values. As shown in the
following section, "Preburn Issues", large values can make for very
large gaps. The larger your gaps, the sooner you hit your maximum
value.
Preburn Issues
How does SQL Server keep track of the next value generated for the
identity column?
There is a SQL Server configuration value, set with sp_configure,
called IDENTITY BURNING SET FACTOR, that works like this:
* Initially, a set of n values is preburned or stored in memory.
These values are reserved to be used up by the next n inserts.
* Each identity column on SQL Server has its own set of preburned
values.
* Each insert gets its value out of the preburned set.
* When the set is exhausted, the next set of n values is made
available for use by the next n inserts.
Note: You may wonder why this method was chosen, rather than having
SQL Server write the maximum column value to storage and log it for
insert. The answer is that the store-and-log method is performance
intensive, requiring two extra writes per insert.
The identity burning set factor is based on a percentage of the
maximum value that can be held in an identity column. The default
percentage is 0.05%, or 0.0005; however, sp_configure must contain
integers and cannot hold decimal places. Therefore, to turn the factor
into an integer for sp_configure, multiply it by 107. To get the
default factor:
0.0005 * 10**7 = 5000
sp_configure stores the value 5000. The value for sp_configure
identity burning set factor can be between 1 and 9,999,999.
To determine the sp_configure value based on the number of values you
wish to preburn, use the following formula:
preburned_set/(maximum+1)=percentage
percentage * 10**7 = identity burning set factor
For example, given a table with an identity column containing a
maximum of four digits, the highest value it can hold is 9999. If you
want to preburn 10 values for that column, use the following formula:
10/(9999+1) = .001 (.01%)
.001 * 10**7 = 10000
So you should configure identity burning set factor as follows:
sp_configure "identity burning set factor", 10000
reconfigure
There are two major implications with this system:
* Because it is a value set with sp_configure, the same preburn
factor is server wide, applying to all its tables.
* Large preburn sets can cause large gaps if there is a system
crash.
Preburn Factor is Server Wide
You may have identity columns on your server with different sizes. To
find out, given a set preburn factor, how many values will be burned
for a given table, use the formula:
preburned set size = (maximum + 1) * (preburning factor * 10**-7)
For example, given the default preburning factor of 5000:
* A table with an identity column defined as numeric(4,0) will burn
(9999 + 1) * (5000 * 10**-7) = 5. After five insertions, a new set
of the next five higher values is reserved to be used by the next
five insertions.
* A table with an identity column defined as numeric(6,0) will burn
(999999 + 1) * (5000 * 10**-7) = 500.
You can mitigate the impact of this situation somewhat if you are able
to standardize the size of your identity columns by setting up a
user-defined datatype to use as the datatype for identity columns, for
example:
sp_addtype sitekey, numeric(6,0), "identity"
With this key in place, the example table created above would look
like this:
create table sales_daily
(stor_id char(4) not null,
ord_num sitekey,
ord_amt money null)
You should determine if the needs of your particular site can support
this method, and use it if so. Set up the datatype for your identity
column in model to propagate it to each new database created.
Large Preburn Sets Can Cause Large Gaps
If there is a system crash, the larger your preburned set, the larger
the gap in your identity values will be, because all unused, preburned
numbers kept in memory will be lost.
For example, if you define your identity column with the maximum value
of numeric(38,0), even with the smallest possible preburn factor of 1,
you potentially lose millions of values in a system crash.
shutdown with nowait causes these values to be lost in exactly the
same way as in a system crash. Use a regular shutdown to avoid loss.
Be aware that there are also some circumstances under which dump/load
can cause loss of identity values. Object Allocation Manager (OAM)
pages store the page numbers of pages used, or allocated but not yet
used, for every object. The Backup Server reads directly from the
disk; the OAM page stores the maximum reserved identity value, while
the maximum used value and the maximum reserved value are being
tracked in the memory structure for the table. SQL Server writes the
maximum used value back to the OAM page when the memory structure is
scavenged or the server is shutdown without nowait. If the maximum
reserved value is not the same as the maximum used value at the time
of the dump, then the maximum reserved value gets written out and
restored on a load, causing a loss of identity values.
Sybase is currently looking at ways to correct these issues. SYBASE
Technical News will keep you informed of any changes!
Problems with SYBLOAD on Solaris
Some of our customers are having problems using the Sybase
installation utility sybload on Sun Solaris 2.x, when installing
products from tape. After entering all the information requested by
sybload they get the message "permission denied" when sybload tries to
access the tape.
Some instructions were left out of the Release Bulletin SYBASE SQL
Server Release 10.0 for SunOS Release 5.x (SVR4). This will be
remedied. In the meantime, all new SQL Server for Solaris shipments
include a fluorescent flyer with the missing instructions.
If you are experiencing permission problems accessing the tape on
Solaris, add the local machine's host name to the $HOME/.rhosts file
of the user running sybload, and also to the /etc./host equivalent
file for your site.
Note on Intel Pentium Floating Point Bug
An AnswerBase TechNote, dated December 7, 1994, "Test for Intel
Pentium Floating Point Bug," describes some Transact-SQL commands that
can be used to demonstrate the Pentium bug. This test is valid for SQL
Server 4.8.x, 4.9.x, and 10.0.x
If the described Transact-SQL commands are executed on a 4.2.2 server,
they will execute correctly, even if the processor has the bug. The
bug can be detected only by using a program which takes advantage of
floating point operations.
These commands will not replicate the problem on the 4.2.2 SQL Server
on Novell because the chip's floating point capability was not
available at the time of the 4.2 Server release. The Pentium floating
point problem is not an issue in the 4.2.x SQL Server release on the
Novell platform.
Problems with Backup Server and AIX 3.2.5
Question
I have difficulty connecting to Backup Server 10.0.x when running on
new RS6000 platforms preloaded with AIX 3.2.5. The symptom is that
Backup Server seems to hang.
Answer
The problem may be a communication time-out. It has been fixed by IBM
in PTF U435001, which addresses APARs IX46162 and IX44358:
* APAR IX46162: process hang while waiting for sockbuf lock
* APAR IX44358: fcntl does not create nonblocking sockets
Since September 28, 1994, three rolled up releases of AIX 3.2.5 have
been shipped; AIX 3.2.5.2(E1) through AIX 3.2.5.5(E4). If you have any
of these releases you may be affected by this IBM bug.
Contact IBM for fix PTF U435001 (or the current version IBM
recommends).
Note
Do not confuse the problem described above with an intermittent Backup
Server hang. If SQL Server normally connects to Backup Server, but
periodically the connection fails, verify that you have the following
fixes installed:
* IBM APAR IX45257 (PTF U432973)
* Sybase EBF 3580 (recommended)
Sybase EBF 3580 is included with the 10.0.2 Backup Server.
Hazards of Copying Dumps with AIX Utilities
The System Administration Guide for SYBASE SQL Server Release 10.0
(dated September 14, 1993) reads,
Dumps to a file or disk can be copied to tape for off-line storage.
However, Sybase does not recommend using any UNIX operating system
commands except tar, dd, cpio or dumps to copy files to tape.
Specifically there seems to be a problem with the AIX backup utility,
and with Logical Volume Manager (LVM) utilities like cplv and
importlv. Using these utilities to copy dump files to tape, or to move
data from one logical device to another, may lead to database
corruption.
Explanation
LVM creates a logical device of type "copy" when you invoke cplv,
specifying sector 0 as the control block. When you copy your data to
the new device, sector 0 on the original device becomes sector 1 on
the new device. If you specify a device type unknown to AIX, AIX will
initialize sector 1. If you have installed a database on a device that
does not have sector 0 initialized as the control block for the
device, and use cplv to move data, SQL Server will be confused about
the address of the control block, and you will get these errors in the
error log:
kernel: dconfig: unable to read primary master device
kernel: kiconfig: read of config block failed
This particular error can be avoided if you do disk init with the
vstart option to skip the first sectors, making sure to set size 1
page smaller than normal for every block vstart is from 0:
disk init name = "skip_dev", physname = "/dev/something",
vdevno = ##, size = ###-1, vstart = 1
The backup utility can also change blocks, rendering your backups
unreadable.
To avoid backup problems, use tar or dd to copy dump files to tape,
and dd to move a dump file from one device to another.
Open Client/MF: Undocumented Return Code
Open Client/Mainframe (OC/MF) for CICS can return an undocumented
return code:
-25 (TDS_GWLIB_FUNCTION_NOT_AVAILABLE)
If this code is returned, it means that the transaction is requesting
a function that is not part of the OC/MF API. The OC/MF API is a
subset of generic Open Client; it does not include all Open Client
calls.
If you get this return code, check your application code for Open
Client calls that are not documented in the Open Client/Mainframe
Programmer's Guide. It contains a list of all supported functions.
PowerBuilder AutoCommit and Open Transactions
SQL Server may experience problems because of long-running
transactions started by PowerBuilder applications. These problems
could include extended recovery times or users waiting on locks. For
this reason, it's generally recommended when using PowerBuilder with
SQL Server that you allow SQL Server to handle transaction management.
PowerBuilder AutoCommit
PowerBuilder defines information regarding a connection to a database
in a transaction object. PowerBuilder defines a transaction object as:
a non-visual object that identifies a specific database connection
within a PowerBuilder application.
In other words, a transaction object is a set of attributes defining
the connection. An application can instantiate (define) its own
transaction object or use the default transaction object, SQLCA.
One of the transaction object attributes that causes confusion for
Sybase users is AutoCommit. To set the AutoCommit attribute for a
transaction object, you must define:
transaction_object_name.AutoCommit = TRUE
or
transaction_object_name.AutoCommit = FALSE
The default value for AutoCommit is "FALSE". A value of "FALSE" for
AutoCommit means that when the connect statement is used within a
PowerBuilder application, PowerBuilder executes a begin\x11transaction
upon making the database connection. If AutoCommit has a value of
"TRUE", then no transaction is started upon the completion of the
connection to the database.
The following table shows how AutoCommit affects other PowerBuilder
statements:
Table 1: Effect of AutoCommit on other PowerBuilder statements
Statement Description
COMMIT If AutoCommit is "FALSE", PowerBuilder will issue a
commit transaction and then a begin transaction. If
AutoCommit is "TRUE", an error will occur.
DISCONNECT If AutoCommit is "FALSE", PowerBuilder will issue a
commit transaction.
ROLLBACK If AutoCommit is "FALSE", PowerBuilder will issue a
rollback transaction and then a begin transaction. If
AutoCommit is "TRUE", an error will occur.
Having AutoCommit set to "FALSE" can result in long-running
transactions and the possibility of locks being held that a user is
unaware of. If you don't clearly understand the ramifications of
setting AutoCommit to "FALSE", it's better to set it to "TRUE" and
allow your application to use the implicit transaction management
provided by SQL Server.
Stratus VOS and TCP
Question
I am running SQL Server on Stratus VOS. I find I cannot connect to
TCP, and the following errors appear in the SYBASE errorlog:
os_init 0 tcp connections configured. At least 2 are required
to run the tcp network
Error 1602 Unable to initialize network 9
Answer
This error is generally caused by the parameter ctcpconnections being
set incorrectly in the SQL Server configuration block. This parameter
is only available in Stratus VOS implementations. The first default
network type for Stratus VOS SQL Server was a proprietary type; TCP
was added later, for greater convenience.
Solution
You must set ctcpconnections to 2 plus the maximum concurrent TCP
connections to the SQL Server, as follows:
buildmaster -ddevicename -yctcpconnections=2[+n]
where n is your maximum concurrent TCP connections.
Warning! buildmaster -y is not documented in the standard documents;
please use it only under the direction of Sybase Technical Support.
Bug Reports
The following sections describe some current bugs, and are followed by
the full reports of bugs fixed in the latest EBFs for SQL Server 10.0
and 4.9.2.
Bug 63348 - KILL on Multiprocessor Servers
The symptoms of bug 63348 are: the SQL Server seems to stop for a
while, then suddenly becomes active again; and a task locks up until
another task is executed, or checkpoint is run. A degradation in
performance may be noticed for the server.
The problem is caused by the use of the kill command.
The problem will only occur when a thread that is running is killed.
This can only happen on a multiprocessor server; there must be more
than one engine. This bug affects multiprocessor servers on all
platforms.
Explanation
When kill is used, the internal variable used to track the number of
running threads is decremented by one. When kill is used on a running
thread, this variable becomes out of sync with the actual number of
runnable threads on the queue; the variable's count goes to zero, and
the server incorrectly thinks there is nothing to schedule.
However, as soon as something else becomes runnable (such as an extra
request over the network, or checkpoint running), then the server
wakes up again.
Rebooting SQL Server clears the problem temporarily.
The problem does not occur on single-engine servers, because on a
single-engine server, only one thread can be running at once. If that
thread is executing the kill, the server cannot be running another
thread.
This bug has been fixed, and the fix is being tested prior to
incorporation in a future Rollup. If you are experiencing this bug,
please contact Technical Support to get on the waiting list for the
fix.
Bug 62149 - Stored Procedure with Variable and COMPUTE Clause Raises Error
411
A stored procedure with an input parameter, a different declared
variable inside the procedure, and a select query inside the procedure
which selects the declared variable and then has a compute clause on
the variable, gets a 411 error. For example:
create procedure foo
@inarg int /* input parameter */
as
declare @localarg int /* declared variable */
select @localarg = 1 /* that selects the decl.var. */
select dbid, name, @localarg
from master.dbo.sysdatabases
order by 3, 1 /* required in conjunction with compute/*
compute sum(@localarg) /* compute clause on the variable */
go
Msg 411, Level 16, State 1:
Server 'testserver', Procedure 'foo', Line 8:
Compute clause #1, aggregate expression #1 is not in the select list.
All the listed parts must be present for the bug to appear:
* If you remove the (unused) input parameter, the procedure works.
* If you compute sum(dbid) rather than sum(variable) the procedure
works.
This bug is fixed for 4.9.2, and a port is due for 10.0.2.
MAP Doc Corrections
Please note the following corrections to your Mainframe Access
Products (MAP) manuals:
OmniSQL Access Module Installation and Administration for DB2-CICS
(Doc ID 34245-01-1010-01)
In Chapter 7, under "Installation Checklist", step 5 should read
"DFHRPL concatenation" instead of "STEPLIB concatenation".
OmniSQL Access Module Installation and Administration for DB2-IMS (Doc
ID 34369-01-1010-01)
In Chapter 6, under "Installation Checklist", step 8 should be put
after steps 9-11.
EBF News
The following tables list the latest Rollup numbers for SQL Server
4.9.2 and 10.x on selected platforms, and selected bugs fixed in them.
Latest Rollups for SQL Server 4.9.2
Platform Rollup Number
SunOS Release 4.x (BSD) 4152
HP 9000 Series 800 HP-UX 4253
IBM RISC System/6000 AIX 4154
AT&T; System 3000 UNIX SVR4 MPRAS 4155
Digital OpenVMS VAX 4156
Sun Solaris 2.x 4157
Digital OpenVMS Alpha 1.5 4158
Digital OpenVMS Alpha 1.0 2121
Bugs Fixed in Latest Rollup, SQL Server 4.9.2
63393
The server crashes after the errorlog message "current process
infected with 10". The trace information which follows shows
that the error occurred in the routine des__hashcheck, and that
the Resource->rdesmgr_spin spinlock is currently being held.
63030
Views get corrupted under certain conditions. Selecting from
the corrupted view returns wrong values until the view is
dropped and re-created. The corrupted view returns same data
for all the columns.
62149
See full description above
61902
539 errors result in orphaned locks. Stack trace shows
indexsplit as one of the routines called.
61850
Insert into a table with a timestamp column in a stored
procedure causes Error 207(invalid column) for the timestamp
column when the procedure gets renormalized. This also causes
Error 273 for the timestamp column if you try to insert a NULL
value for the timestamp.
61168
Certain aggregate expressions are incorrectly regarded as being
identical. As a result, one of the expressions gets thrown
away, and the other is used instead.
60980
SQL Server fails to perform a switch from a failed disk device
to a good device when disk mirroring is enabled.
60809
Added support for the TCP_NODELAY option, which can be enabled
via the 1610 trace flag. Server should be booted with `-T1610'
to turn on this option.
60122
[REPSRV] Fix 58464 tries to reduce the restart latency time of
the SQL/LTI log scan during a sharp increase in XACT log
activity. However, the fix causes a 30 percent performance
reduction with asynchronous disk I/O facilities which do `page
hiding' (such as IBM RS6000).
60099
When attention is received while executing Remote Procedure
Calls on another server, the endpoint is prematurely cleaned
up. This prevents the attention from being forwarded to cancel
the RPC on the remote server, which is left suspended.
59308
Certain insert into statements with use of union and view may
fail with stack trace and the isql connection gets aborted.
58509
A signal 11 segment violation produced a stack trace during a
query dealing with views.
58464
If there is a sharp increase in XACT log activity (such as from
several large bulk copies) after a short period (5 minutes) of
no XACT log activity, the SQL Server may delay the sending of
the new XACT log information to the Replication Server for as
much as 10 minutes.
58411
"if exists" generates segmentation violation when the where
clause contains concatenation of convert with subqueries. This
occurs during parse time.
58192
Mirroring a device onto the master device should not be
allowed, a warning should be generated.
58047
If a temporary table is dropped and created in one batch, it's
not accessible and not dropped even after the isql session is
over.
57989
diagserver panics while killing SERVER tasks.
57873
Server returns duplicate rows when query has a group by clause
and a having clause which in turn has aggregates and an or
clause.
57756
DBCC checkalloc resets the 3604/3605 flags at the end of
execution even if the Server was started with traceflags
3604/3605 in the command-line.
57673
[REPSRV] The log scan thread sometimes is not awakened when
there are records to be read in the log.
57592
Server shuts down with messages "ubfree: block 0x62a9800
already free", "Stack overflow detected" and stack trace while
resolving a huge stored procedure.
57576
LOAD TRAN recovery always aborts a 2-phase XACT in PREP but
(wrongly) leaves the XEND log record in PREP. If the XEND log
record is seen again by boot time recovery, error 3429 occurs
if the 2-phase XACT commits after the LOAD TRAN but before
reboot.
57338
Error 407 is raised when issuing select distinct with a view.
("Unable to allocate ancillary table for query
optimization....")
57273
Server could reject previously accepted large queries with 703
error ("Memory request failed because more than 64 pages are
required to run the query") if the query uses explicit/implicit
CONCAT nodes.
57002
When using a group by clause in a select statement, the
matching of the select list and the group by list reshuffles
the query tree too early and causes an erroneous result in
queries whose pattern is of the kind: select col_a, col_a +
col_b from some_table where some_selectivity_condition group by
col_a, col_a + col_b
56959
select str(value,n,2) statement returns -0.-0 instead of -0.00
when used on datatype float containing value `-0.0'.
56927
load database results in stack trace:
lddb_main->lddb_fixdbosuid->update->insert->cinsert->
datasplit->linksplit->ncrid_update->delirow->bufdirty
56652
2805 and 2812 errors with stored procedures containing compute
clauses when multiple copies in cache being used.
56635
select substring(@@version,12,2) returns NULL.
56540
sp_lock: On a system with thousands of locks in use,
overflowing the temporary buffer used to insert into syslocks
also can result in process infection and stack trace.
56430
When performing outer join and qualifying inner table is NULL,
returned values for inner table column are NULLs (when they in
fact are not).
56393
When commiting the DEALLOC records for text-delete, a small
window exists in which the deallocated first text-page could be
allocated again to some other object before original
transaction completes & locks are released.
56283
Timeslice error occurs while recovering transaction log.
56185
ex_raise from routine sort of worktable with dynamic index
results in 1129 on the OAM page of worktable being sorted.
Worktables not being handled as temporary tables when they
should be.
56127
Range levels are incorrect when a subquery selects from a view.
56064
The detection of KILLYOURSELF status in the lock manager is
disabled, until all code paths have been examined for proper
handling of lock interrupts. Killing a task waiting on a lock
will only succeed if the lock can be granted.
56014
A few long-running XACTs and/or a multitude of shorter XACTs
can cause detection delays of up to 10 minutes.
56013
select from table order by... from a table that has text
columns holds shared page locks (as if it is doing level 3
locking) and eventually run out of locks with error 1204.
55799
Search density is not used in the case where a search value is
in multiple steps or outside the step range, and therefore it
should not include those values.
55756
When executing sp_dropmessage for a user who is not the
database owner, not creator of the message and does not have
the System Security Officer role, gets error saying "unmatching
argument list to PRINT command".
55180
Reformatting of work table not done as a result of wrong page
and row estimate for a temporary table created in the same
batch and used later in a join with a user table in the same
batch. 302 trace output shows (rows: 1 pages: 1)
55017
When a truncate table is interrupted due to an attention, the
transactions in progress are not cleared.
54952
When lock manager trace 1204 is active, the display of a single
chain deadlock generates time-slice errors.
54471
Inserting into a view using a select statement with a group by
clause in which no aggregate is specified in the select list,
causes the client to be killed and a "process infected with
Signal 10" error is reported in the server's error log.
54388
Inserting into a very large table causes 1127 errors when
maximum number of OAM page entries is reached.
54367
Unable to reference temporary tables created by a parent stored
procedure in the child stored procedure. The data returned from
the child stored procedure is corrupted.
53879
Dropping a work table using the full object name (such as
tempdb..#tbl) doesn't free the memory associated with the
temporary table. If a process creates and drops lots of
temporary tables, it may eventually die with a 703 error.
53837
If you create a table with more than 8 columns, insert some
values, revoke update on one column of the table, and then try
to update the eighth or higher columns of the table, error 230
is raised ("permission denied on column col9 of object
foo...").
53532
When a PC Windows client machine is turned off while OMNI is in
the process of a select to DB2 returning a very large result
set, OMNI does not detect the loss of the client, disconnect
the user, or close the thread to a Net-Gateway.
52733
Executing a procedure which declares a variable @var and
assigns a procedure name to it and then tries to exec @var may
result in a stack trace.
52174
Add limited conversion functionality between EUCJIS SQL Server
and SJIS clients.
51604
The SQL/LTI thread assumes a stored procedure's EXECBEGIN log
record is written into the same database where the sproc is
stored. This is not true if the procedure executes from within
a user XACT started in another database. A 9141 error will
result.
50987
select x = null into table returned error msg `Column `x'
specifies storage type 31, which does not currently exist.' The
column `x' should be created with a default datatype of
nullable int.
49514
Different presentation format (exponential) of the output (if
big enough) from sp_spaceused.
45987
System stored procedure sp_remove_xact has a parameter @commid
defined as a smallint, and it should be defined as an int.
35593
cmastmirror configuration value of the master device. If the
user had done a buildmaster -r before disk remirror the server
would not activate the mirror with the message "dopen : "" is a
directory."
33368
An order by of a union of two select statements that contain
text columns previously gave a 420 error (Image/Text not
allowed in order by), although the Text/Image column was only
in the select list.
17738
SERVER error message 4207 should read "Dump transaction is not
allowed because a non-logged operation was performed on the
database. Dump your database or use dump transaction with
truncate_only until you can dump your database."
Latest Rollups for SQL Server 10.0.2
Platform Rollup Number
SunOS Release 4.x (BSD) 4009
HP 9000 Series 800 HP-UX 4010
IBM RISC System/6000 AIX 4011
AT&T; System 3000 UNIX SVR4 MPRAS 4012
Digital OpenVMS VAX 4013
Sun Solaris 2.x 4014
Digital OpenVMS Alpha 1.5 4015
Digital OSF/1 4019
Bugs Fixed in Latest Rollup, SQL Server 10.x
17668
count(*) is not returning correct results in a view on three
tables, three columns updating two columns of another table
with the count from the view. Works when done one at a time and
using the table directly (select into).
18345
sp_renamedb fails to change the internal dbi_dbname variable.
This causes incorrect 3508 messages, among other possible side
effects.
19144
When inserting from a table that allows NULL values to a table
that is defined as not NULL, convert "sneaks" NULL values in.
When you select distinct on the new table, the discrepancy
shows up.
25462
Use of a table correlation name within a correlated subquery
does not correspond to ANSI 1989 SQL standard page 46; non-use
of table alias within an inner select statement does not revert
table queried to that used in outer select
25844
"looping 2714s" sample stack: _kisignal sigtramp.o sigtramp.o
_s_free _s_pop _s_cleanframe _clean_process _kill_proc
__ex_cleanup _kisignal sigtramp.o sigtramp.o _s_free _s_pop
_s_cleanframe _clean_process.
28221
Recovery modifications needed to avoid recompleting
transactions from the earliest BEGIN RID record in the log to
the checkpoint record.
29069
When updating a single column of one row on which there exists
a unique nonclustered index, excessive number of pages are
locked. Exact scenario using a unique clustered index will lock
the correct number of pages.
31730
When the server is stopped, a "%SYSGEN-E-CONFIGERR, CONFIGURE
process" error is reported on the operator's console. The
operator's console is left in a hung state, not allowing any
logins.
32566
When the error message for error 821 is printed, a newline
character is missing which makes the user errorlog difficult to
read.
33151
During iterative bcp data in sessions, seg. fault occurs with
an incomplete stack trace and time slice results in Error 1501.
33398
Cannot use full name of temporary table to drop it in 4.8.
Results in 3701 error: create table #CM2746 (col1 char(1)) use
tempdb select name from sysobjects where col1 like "#CM2746%"
drop table #CM2746____000000100077667955.
33475
Unmirroring permanently should not attempt to set affinity on
debug engine.
33726
update tablea set tablea.fielda=tableb.fireldb where
dbname.dbo.tablea.fieldc=dbname2.dbo.tableb.field3 - loops on
writing to syslogs. When tables to be joined are in the same
database, all is OK.
33769
When deadlock occurs while inserting a row on an overflow page,
an attempt is made to unkeep a buffer twice.
34124
Attempt to drop database raises error 834. There is no error
message associated with 834.
35139
Using bcp in on a table with index that has ignore dup key set
may cause Errors 1129, 813, 2525, 2521, and data corruption.
35287
The Navigation Server needs to read the distribution pages for
tables for help in optimization. Change TDS 5.0 to allow this.
36404
Procedure sybase_manager.com should include foreign symbol
definition for `upgrade' which will allow easy execution of the
upgrade program for phase 4 of the upgrade process. See
Appendix A of the Installation Guide for examples of using the
program for recovery purposes
37829
The following SQL statement produces a parse tree that is
incorrect. In addition the syntax is illegal in ANSI. "declare
@v1 int, @v2 int
select @v1 order by @v2".
37934
There is a bug in installasync70. First: the asynchronous
driver isn't shipped with 700s (HP-UX 8.07), the customer must
get PHKL_1017. Next, the script assumes the driver ends up in
/hpux_install - but it usually doesn't after applying patch.
38574
The sp_auditobject (and sp_auditsproc) procedures expect a
table or view (or stored procedure/trigger) name as the first
argument. We allow the owner.name format, but they provided
dbname.owner.name, and the command failed later than it should
have.
39246
Customer had a problem with isql on VMS 5.5. /colwidth did not
work. This is a reported bug in the documentation (27341). It
was supposed to be fixed in 4.8.0.1, but it was not fixed in
the 4.9.1 docs. Also /separator should be /colsepa.
39736
startserver problems: an extra # on first line of script
created for -m causes shell specification to be ignored,
causing script to fail on platforms using csh. m_ is prefixed
to runserver file name without regard to whether it is a full
path or not. runserver script won't work unless the full path
is given or script is found in PATH directory. A previous
workaround conflicted with -m.
39801
When command text auditing is disabled, a memory structure
isn't being cleared. Thus, the parser thinks we should be
saving the text, and we end up segfaulting.
41854
Install sybsyntax db by running ins_syn_sql script, issue
sp_syntax get error `server user id is not a valid user in db
sybsyntax'. The same problem happens with ins_syn_dblib also.
42132
executing sp_clearstats and sp_reportstats by "sa" before any
user logins are created gives error "divided by zero".
42269
shutdown SYB_BACKUP with nowait, while a dump is in progress,
causes Backup Server to dump core.
42514
Dump of a database to 8-mm tape without the init option will
overwrite what is on the tape. Dump should fail. The init
option should be used to overwrite. If you dd a file to the
tape, the dump will succeed and overwrite the file.
42901
Error 813 "logical page already hashed" after a bcp, running
concurrently with another process, aborts.
43282
Both 491 on solaris21 and sys10beta on sunos412 show error 102
returned when attempting to pass `+3' as int parameter to a
stored procedure, although it succeeds in dynamic variables and
direct inserts.
43661
Assignments of the "sybase_ts" role do not take effect in the
same login session. This means that many diagnostic tools
cannot be used unless the server is healthy enough to let
someone log in twice, once to assign the role and a second time
to use it.
44275
select "column_heading" = column_name or select column_heading
= column_name or select column_name as column_heading works but
select column_name as "column_heading" doesn't.
44667
shutdown with nowait of a Backup Server while a dump is in
progress results in a Backup Server core dump with "assertion
failed".
44680
Backup Server can not perform dump/load database when the
database device is on a character special device. Backup Server
returns Error 4.56.2.1
45492
Customer is getting an inexplicable 224 error when inserting
into a table that has both a reference constraint and check
constraints.
45723
create table, alter table then add constraint, drop constraint,
and add constraint raises error 1923: "..table cannot have more
than one primary key...", but there is no primary key.
45837
Identity problem: create table t1 (f1 numeric(2,0) identity)
then create view vident as select f1 from t1, insert into
vident values() results in stack trace with the message
"current process(0x80008) infected with Signal 11 ... The SQL
Server is terminating this process."
_________________________________________________________________
Disclaimer: No express or implied warranty is made by SYBASE or its
subsidiaries with regard to any recommendations or information
presented in SYBASE Technical News. SYBASE and its subsidiaries hereby
disclaim any and all such warranties, including without limitation any
implied warranty of merchantability of fitness for a particular
purpose. In no event will SYBASE or its subsidiaries be liable for
damages of any kind resulting from use of any recommendations or
information provided herein, including without limitation loss of
profits, loss or inaccuracy of data, or indirect special incidental or
consequential damages. Each user assumes the entire risk of acting on
or utilizing any item herein including the entire cost of all
necessary remedies.
Staff
Principal Editor: Leigh Ann Hussey
Contributing Writers:
Brijesh Agarwal, Perry Bent, Siva Chandrasekharan, Scott Duncan, Aimee
Grimes, Cris Gutierrez, Leigh Ann Hussey, Chandrika Krishnan, Cristina
Nitescu, Daniel O'Rourke, Pearl Ong, Chuck Pavelka, Gerald Soulos,
Loretta Vibberts, Robert Weaver, Elton Wildermuth, Melissa Yeary
SYBASE Technical News
6475 Christie Avenue
Emeryville, CA 94608 USA
For more info send email to tech...@sybase.com
Copyright 1995 © Sybase, Inc. All Rights Reserved.
Q10.2.2
Technical News Volume 4, Number 2, May 1995
This issue of SYBASE Technical News contains new information about your
SYBASE software. If needed, duplicate this newsletter and distribute it to
others in your organization. All issues of SYBASE Technical News and the
troubleshooting guides are included on the AnswerBase CD.
To receive this document by regular email, send name, full internet address
and customer ID to tech...@sybase.com.
IN THIS ISSUE
* Tech Support News/Features
o How Technical Support Uses Case Survey Metrics
* SQL Server
o HP: Mirror Fail-Over and installasynch80
o buildmaster -y and -r Options to Become Obsolete
o dump transaction Fails to Truncate Log
o How to Read dbcc checkalloc Output
o Replication Server System Database Recovery
o min() and max() Functionality
o Viewing all Decimal Digits in a select from money_column
o Dump/Load Compatibility, 10.0.1 vs. 10.0.2
* Connectivity / Tools / PC
o keepalive Redux
o Setting up Borland IDE to Compile Client-Library
o Macintosh Think-C and ct_init Routine
* Certification and Fixed Bug Reports
o SQL Debug Certified for DEC OSF/1
o IPX/SPX Certification for Solaris
o Certification Report for All Platforms
o Bug 61483 - Duplicate Rows in syskeys
How Technical Support Uses Case Survey Metrics
Sybase Technical Support has been sending out a Technical Support Case
Closure Satisfaction Survey for 16 months (September 1993 through January
1995). In October 1994, based on feedback from customers who had responded
to the survey, we modified the survey process such that:
* Customers receive surveys no more frequently than twice a year.
* Customers are asked to respond about one completed case instead of
multiple cases.
* Customers who request it continue to receive monthly case status
reports.
The feedback received is being used in the following manner to drive
corrective action and process improvements:
* Returned surveys that include concerns about the handling and/or status
of cases are regularly forwarded to Technical Support managers to
ensure follow-up and, if required, corrective action.
* A team of 10 to 12 Technical Support engineers met monthly for several
months to carefully review customer narrative comments on the quality
of our support and to document the concerns and suggestions for senior
management review and action.
* Documentation developers met to review customer comments on the quality
of our documentation to determine what improvements could be made.
* Senior managers are using the information to develop plans for support
process improvements and are taking ownership for follow-up on these
plans.
We want to thank all of you who have taken the time to respond to our survey
and ask that you continue. We have heard very clearly that electronic
delivery of surveys would make it easier for you to continue to respond and
we are pursuing that capability.
HP: Mirror Fail-Over and installasynch80
Question
In testing mirror fail-over on HP, I cannot get the server to switch over
when the primary device is powered off. What is the problem?
Answer
This problem has been tracked to the installasynch80 script. The mknod
command for async is in error. The incorrect command included in the script
is as follows:
/etc/mknod /dev/async c 101 0
The command should read as follows:
/etc/mknod /dev/async c 101 0x7
Here is the corrected section in the installasynch80 script, which you will
find in your $SYBASE/install directory:
#
# create_devices creates the async i/o devoce file
#
create_devices()
{
echo ""
echo " We are about to create the asynchronous raw disk i/o device."
echo " If this device already exists, it will be replaced. "
# prompt user for continuation
#
checkanswer
echo " Creating asynchronous i/o device....."
rm -f /dev/async /dev/asynch[0-9]*
/etc/mknod /dev/async c 101 0x7
chmod 0660 /dev/async
chown sybase /dev/async
chgrp $GROUP /dev/async
echo ""
echo " Async device has been created. "
}
buildmaster -y and -r Options to Become Obsolete
A new configuration interface for the next generation of SQL Servers after
System 10[TM] will render both the -y and -r command line flags to
buildmaster obsolete.
All configurable options (cdbnum, cmemsize, cfgxdes, and so on) will be
placed in a configuration file, which is in a text format.
In System 10 and earlier releases, buildmaster -y and -r are used to change
the values of options in the config block of SQL Server. They will no longer
be needed because the new configuration interface will allow users to modify
the values in a flat text config file. Also, the names in the config file
will not be cdbnum, cmemsize, and the like, but will be "number of
databases", "total memory", and so forth, rendering the information more
understandable.
If the config file cannot be booted, SQL Server will still be able to start
under the default settings (formerly the -r option) by not specifying a
configuration file.
In addition, the dynamically tunable parameters will be changed with the
sp_configure command, not when reconfigure is run.
Watch your Technical News for more information as it becomes available.
dump transaction Fails to Truncate Log
------------------------------------------------------------------
WARNING! Although the following procedure has been tested
rigorously and used at many customer sites, it uses undocumented
and unsupported dbcc commands.
------------------------------------------------------------------
If you are issuing a dump transaction command and find that the log is not
being truncated, it is possible that an open transaction is preventing the
log from being cleared. This occurs because dump transaction will only
truncate the log up to, but not including, the log page that contains the
begin transaction for the oldest active transaction. You can use the
following procedure to determine the spid, suid, and time of the open
transaction (you must be the "sa" user or have the sa role to use this
procedure):
1. Enable dbcc command output to appear on the screen:
dbcc traceon(3604)
go
2. Print the oldest outstanding checkpoint record.
dbcc log(dbid,0,0,0,-1,17,0)
go
3. The output from this allows you to find the ID of the oldest active
transaction. Output will be similar to the following:
LOG RECORDS:
CHECKPOINT(262 ,12)
attcnt=1 rno=3 op=17 padlen=0 xactid=(262 ,12) len=60
status=0x0000 /* ^^^ length field */
rows=11407892, pages=79 extents=288
status=4096 timestamp=0x0001 0x0000811d
active xacts:(262,3) /* oldest active xact ID */
-------------------------------------------------------------
NOTE: This technique is not valid if the length field has a
value of 52 or less. In this case, execute a checkpoint and
try again.
-------------------------------------------------------------
4. Display the begin transaction record associated with the output active
transaction ID. Note that the third and fourth parameter values of the
following command come from the active xacts field above:
dbcc log(dbid,1,262,3,1,0,1)
go
Output in the example case looks like this:
LOG RECORDS:
BEGINXACT(262 , 3)
attcnt=1 rno=3 op=0 padlen=3 xactid=(262,3) len=76
status=0x2C20
masterid=(0,0) lastrec=(0,0) xstat=XBEG_ENDXACT
>>>>>> spid=5 suid=1 uid=1 masterdbid=0 mastersite=0 endstat=3
^ name=user_transaction time=Sep 20 1991 1:02PM
^
^ SPID and SUID of process owning outstanding xact
5. Get the login name that matches the suid:
use master
go
select name from syslogins where suid = suid
go
Now run sp_who to see if there is an entry that contains both the SPID and
login name obtained above. If so, follow up with the user to find out what
their transaction is and if they can exit their program or isql session or
issue a commit tran. Alternatively, you can immediately kill the process
yourself. This should terminate the process and resolve the blocking
transaction. Issuing the dump transaction command again should clear the
log.
If the log is still not being cleared, or if there is not a matching entry
in sp_who, then the user that issued the blocking begin tran is no longer
logged onto SQL Server but SQL Server is unaware of this. This occurs
primarily when a user connecting from a PC client has powered off the PC in
the middle of a transaction, has exited a third-party application by
pressing ctrl-C, or has encountered network errors on terminating the
connection to SQL Server. In this case, if kill did not work, the only
recourse is to reboot SQL Server.
If a user was not knowingly holding an open transaction, you can examine
your SQL Server error log for clues to help you diagnose why the transaction
was left open. Messages to look for include "current process infected",
"network error was encountered" (Error 1608), "host process disconnected,"
and stack traces. Sybase Technical Support can help you analyze these
errors. If you have a UNIX environment where this problem is occurring
frequently, you may want to adjust your keepalive kernel parameter to a
lower value. See your SYBASE System Administration Guide Supplement,
operating system documentation, or contact your operating system vendor for
more information on the keepalive parameter and how to set it. If your
environment consists of a number of users utilizing a single login to access
SQL Server, Sybase Technical Support can give you trace flags to help track
down the user who is causing the problem.
------------------------------------------------------------------
NOTE: PowerBuilder users: When keepalive fails to clear a
connection, it may have occurred because PowerBuilder had a
General Protection Fault and the user simply restarted Windows.
This leaves the LAN transport software/firmware holding the
connection open to SQL Server. keepalive will not clear the
connection, since the client side LAN is still holding the old
connection. When the user starts PowerBuilder again, it will get a
new connection to SQL Server.
You can use sp_who or netstat to see if the old user connection is
still active.
The only way to clean up the connection is to turn off the PC that
opened the connection; this resets the connection and allows
keepalive to do the proper cleanup on the SQL Server side.
------------------------------------------------------------------
How to Read dbcc checkalloc Output
Question
When examining the output of a dbcc checkalloc command, I notice that only
one page seems to be used per extent on many allocation pages. Why?
Here is a sample of the output:
[...]
Alloc page 16128 (# of extent=1 used pages=1 ref pages=1)
Alloc page 16384 (# of extent=1 used pages=1 ref pages=1)
Alloc page 16640 (# of extent=1 used pages=1 ref pages=1)
[...]
Answer
An extent is a group of eight pages. Every 256th page in a database is an
allocation page, which is used to track the space being used.
The above output does not show that one page is used per extent on many
allocation units; it shows that one extent is in use and that, on that
extent, one page is allocated. That is, exactly one page is allocated out of
that group of 256 pages.
That page is, of course, the allocation page itself, which is always
allocated. The other 255 pages on each such allocation unit are available to
whatever object needs the space.
------------------------------------------------------------------
NOTE: Normally an extent is owned by whatever object/index
combination first grabs space on it. The first extent on each
allocation unit, which controls the allocation page itself, is an
exception: the allocation page is always allocated, but the extent
is considered free if that page is the only one allocated.
------------------------------------------------------------------
Replication Server System Database Recovery
Following the recovery procedure outlined in the Replication Server
Administration Guide dated October 21, 1993, for Replication Server System
Database (RSSD) recovery could possibly put the Log Transfer Manager (LTM)
into an infinite loop.
Please substitute the following revised sections for the sections that
appear in the chapter, "Replication System Recovery" of any Replication
Server Administration Guide dated prior to March 15, 1995.
Recovering an RSSD from Dumps
The procedure you use to recover an RSSD depends on how much RSSD activity
there has been since the last RSSD dump. There are four increasingly severe
levels of RSSD failure, with corresponding recovery requirements. Use Table
1: Recovering from RSSD failures to locate the RSSD recovery procedure you
need.
Table 1: Recovering from RSSD failures
Activity Since Last Dump Use This Procedure
No DDL activity Basic RSSD Recovery Procedure
DDL activity, but no new routes or
subscriptions were created Subscription Comparison Procedure
DDL activity, but no new
subscriptions were created Subscription Re-Creation Procedure
New routes were created Deintegration/Reintegration Procedure
Basic RSSD Recovery Procedure
Use the basic RSSD recovery procedure to restore the RSSD if you have
executed no DDL commands since the last RSSD dump. DDL commands in RCL
include those for creating, altering, or deleting routes, replication
definitions, subscriptions, function strings, functions, function string
classes, or error classes.
Certain steps in this procedure are also referenced by other RSSD recovery
procedures in this article and in the Replication Server Administration
Guide.
------------------------------------------------------------------
WARNING! Do not execute any DDL commands until you have completed
this recovery procedure.
------------------------------------------------------------------
The current Replication Server refers to the one with the RSSD you are
recovering. An upstream Replication Server is a Replication Server that has
a direct or indirect route to the current Replication Server. A downstream
Replication Server is a Replication Server to which the current Replication
Server has a direct or indirect route.
To perform basic RSSD recovery, follow these steps:
1. Shut down all LTMs that connect to the current Replication Server.
2. Since its RSSD has failed, the current Replication Server is down. If
for some reason it is not down, log into it and use the shutdown
command to shut it down.
-----------------------------------------------------------------------
NOTE: Some messages may still be in the Replication Server stable
queues. Data in those queues may be lost when you rebuild these queues
in later steps.
-----------------------------------------------------------------------
3. Restore the RSSD by loading the most recent RSSD database dump and all
transaction dumps.
4. Restart the Replication Server in standalone mode, using the -M flag.
You must start the Replication Server in standalone mode, because the
stable queues are now inconsistent with the RSSD state. When the
Replication Server starts in standalone mode, reading of the stable
queues is not automatically activated.
5. Log into the Replication Server, and get the generation number for the
RSSD, using the admin get_generation command:
admin get_generation, data_server, rssd_name
For example, the Replication Server may return a generation number of
100.
6. In the Replication Server, rebuild the queues with the following
command:
rebuild queues
See "Rebuilding Queues Online" in the Replication Server Administration
Guide for a description of this process.
7. Start all LTMs (except the RSSD LTM) that connect to the current
Replication Server. Start in recovery mode, using the -M flag. Wait
until each LTM logs a message that it is finished with the current log.
8. Check the loss messages in the Replication Server log and in the logs
of all the Replication Servers with direct routes from the current
Replication Server.
If all your routes were active at the time of failure, you probably
will not experience any real data loss.
However, loss detection may indicate real loss. Real data loss may be
detected if the database logs were truncated at the primary databases,
so that the rebuild process did not have enough information to recover.
If you have real data loss, reload database logs from old dumps. See
"Recovering from Truncated Primary Database Logs" in the Replication
Server Administration Guide.
See "Loss Detection After Rebuilding Stable Queues" in the Replication
Server Administration Guide for background and details on loss
detection.
9. Shut down the LTMs for all primary databases managed by the current
Replication Server.
10. Execute the dbcc settrunc command at the SQL Server for the restored
RSSD. Move up the LTM truncation point.
use rssd_name
go
dbcc settrunc('ltm', 'ignore')
go
begin tran commit tran
go 40
dbcc settrunc('ltm', 'valid')
go
-------------------------------------------------------------
Note: The go 40 command moves the SQL Server log onto the
next page.
11. Execute the dbcc settrunc command at the SQL Server for the restored
RSSD to set the generation number to one higher than the number
returned by admin get_generation in step 5.
use rssd_name
go
dbcc settrunc('ltm', 'gen_id', 101)
go
Make a record of this generation number and of the current time, so
that you can return to this RSSD recovery procedure, if necessary. Or,
you can dump the database after setting the generation number.
12. Restart the Replication Server in normal mode.
If you performed this procedure as part of the subscription comparison
or subscription re-creation procedure, note that the upstream RSI
outbound queue may contain transactions bound for the RSSD of the
current Replication Server that have already been applied by using
rs_subcmp. If this is the case, after starting the Replication Server,
the error log may contain warnings referring to duplicate inserts. You
can safely ignore these warnings.
13. Restart the LTMs for the RSSD and for user databases in normal mode. If
you performed this procedure as part of the subscription comparison or
subscription re-creation RSSD recovery procedure, you should expect to
see messages regarding RSSD losses being detected in all Replication
Servers that have routes from the current Replication Server.
Subscription Comparison Procedure
Follow this RSSD recovery procedure if you have executed some DDL commands
since the last transaction dump, but you have not created any new
subscriptions or routes. DDL commands in RCL include those for creating,
altering, or deleting routes, replication definitions, subscriptions,
function strings, functions, function string classes, or error classes.
------------------------------------------------------------------
WARNING! Do not execute any DDL commands until you have completed
this recovery procedure.
------------------------------------------------------------------
Following this procedure makes the failed RSSD consistent with upstream
RSSDs or consistent with the most recent database and transaction dumps (if
there is no upstream Replication Server). It then makes downstream RSSDs
consistent with the recovered RSSD.
The current Replication Server refers to the one with the RSSD you are
recovering. An upstream Replication Server is a Replication Server that has
a direct or indirect route to the current Replication Server. A downstream
Replication Server is a Replication Server to which the current Replication
Server has a direct or indirect route.
If DDL commands have been executed at the current Replication Server since
the last transaction dump, you may have to re-execute them.
To restore an RSSD with subscription comparison, follow these steps:
1. To prepare the failed RSSD for recovery, perform steps 1-4 of "Basic
RSSD Recovery Procedure"
2. To prepare for recovery the RSSDs for all upstream Replication Servers,
execute the admin quiesce_force_rsi command at each upstream
Replication Server.
o This step ensures that all committed transactions bound for the
current Replication Server have been applied before you execute
the rs_subcmp program.
o Execute this command sequentially, starting with the Replication
Server that is furthest upstream from the current Replication
Server.
o Make sure that RSSD changes have been applied, that is, that the
RSSD DSI outbound queues are empty.
o The Replication Server that is directly upstream from the current
Replication Server cannot be quiesced.
3. To prepare for recovery the RSSDs for all downstream Replication
Servers, execute the admin quiesce_force_rsi command at each downstream
Replication Server.
o This step ensures that all committed transactions bound for the
current Replication Server have been applied before you execute
the rs_subcmp program.
o Execute this command sequentially, starting with Replication
Servers that are immediately downstream from the current
Replication Server.
o Make sure that RSSD changes have been applied, that is, that the
RSSD DSI outbound queues are empty.
4. Reconcile the failed RSSD with all upstream RSSDs, using the rs_subcmp
program.
o First execute rs_subcmp without reconciliation to get an idea of
what operations it will perform. When you are ready to reconcile,
use the -r flag to reconcile the replicate data with the primary
data.
o You must execute rs_subcmp as the maintenance user. See "Managing
Replication Server Security" in the Replication Server
Administration Guide for more information on the maintenance user.
o In each instance, specify as the replicate database the failed
RSSD.
o In each instance, specify as the primary database the RSSD of each
upstream Replication Server.
o Start with the Replication Server that is furthest upstream, and
proceed downstream for all other Replication Servers with routes
(direct or indirect) to the current Replication Server.
o Reconcile each of the following RSSD system tables: rs_classes,
rs_columns, rs_databases, rs_erroractions, rs_functions,
rs_funcstrings, rs_objects, and rs_systext.
o When you execute rs_subcmp on replicated RSSD tables, the where
and order by clauses of the select statement must select all rows
to be replicated. See "Using rs_subcmp on Replicated RSSD System
Tables" for more information.
The failed RSSD should now be recovered.
5. Reconcile all downstream RSSDs with the RSSD for the current
Replication Server, which was recovered in the previous step, using the
rs_subcmp program.
o First execute rs_subcmp without reconciliation to get an idea of
what operations it will perform. When you are ready to reconcile,
use the -r flag to reconcile the replicate data with the primary
data.
o You must execute rs_subcmp as the maintenance user. See "Managing
Replication Server Security" in the Replication Server
Administration Guide for more information on the maintenance user.
o In each instance, specify the recovered RSSD as the primary
database.
o In each instance, specify the RSSD of each downstream Replication
Server as the replicate database.
o Start with the Replication Servers that are immediately
downstream. Then proceed downstream for all other Replication
Servers with routes (direct or indirect) from the current
Replication Server.
o Reconcile each of the following RSSD system tables: rs_classes,
rs_columns, rs_databases, rs_erroractions, rs_functions,
rs_funcstrings, rs_objects, and rs_systext.
o When you execute rs_subcmp on replicated RSSD tables, the where
and order by clauses of the select statement must select all rows
to be replicated. See "Using rs_subcmp on Replicated RSSD System
Tables" for more information.
All downstream RSSDs should now be fully recovered.
6. If the recovering Replication Server is an ID Server, you must restore
the Replication Server and database IDs in its RSSD.
o For every Replication Server, check the rs_databases and rs_sites
system tables for their IDs.
o Insert the appropriate rows in the recovering RSSDs rs_idnames
system table if they are missing.
o Delete from the recovering RSSDs rs_idnames system table any IDs
of databases or Replication Servers that are no longer part of the
replication system.
o To ensure that the rs_ids system table is consistent, execute the
following stored procedure in the RSSD of the current Replication
Server:
rs_mk_rsids_consistent
7. If the recovering Replication Server is not an ID Server, and a
database connection was created at the recovering Replication Server
after the last transaction dump, delete the row corresponding to that
database connection from the rs_idnames system table in the ID Server's
RSSD.
8. Perform steps 5-13 of "Basic RSSD Recovery Procedure".
9. To complete RSSD recovery, re-execute any DDL commands that have been
executed at the current Replication Server since the last transaction
dump.
Using rs_subcmp on Replicated RSSD System Tables
When you execute rs_subcmp on replicated RSSD tables, for the subscription
comparison and subscription re-creation RSSD recovery procedures, for each
system table, the where and order by clauses of the select statement must be
formulated to select all rows that must be replicated.
Table 2 illustrates the general form of these select statements.
Table 2: select statements for rs_subcmp procedure
RSSD Table Name select Statement
rs_classes select * from rs_classes where prsid in sub_select order by
primary_keys
rs_columns select * from rs_columns where prsid in sub_select and
rowtype = 1 order by primary_keys
rs_databases select * from rs_databases where prsid in sub_select and
rowtype = 1 order by primary_keys
rs_erroractionsselect * from rs_erroractions where prsid in sub_select
order by primary_keys
rs_funcstrings select * from rs_funcstrings where prsid in sub_select and
rowtype = 1 order by primary_keys
rs_functions select * from rs_functions where prsid in sub_select and
rowtype = 1 order by primary_keys
rs_objects select * from rs_objects where prsid in sub_select and
rowtype = 1 order by primary_keys
rs_systext select * from rs_systext where prsid in sub_select and
texttype in ('O', 'S') order by primary_keys
In the select statements in Table 2, sub_select represents the following
statement, which selects all site IDs that are the source Replication
Servers for the current Replication Server:
(select source_rsid from rs_routes
where
(through_rsid = PRS_site_ID
or through_rsid = RRS_site_ID)
and
dest_rsid = RRS_site_ID)
where PRS_site_ID is the site ID of the Replication Server managing the
primary RSSD, and RRS_site_ID is the site ID of the Replication Server
managing the replicate RSSD for the rs_subcmp operation.
For the rs_columns, rs_databases, rs_funcstrings, rs_functions, and
rs_objects system tables, if rowtype = 1, then the row is a replicated row.
Only replicated rows need be compared using rs_subcmp.
For each system table, the primary_keys are its unique indexes.
Classes and System Tables
The default function string class rs_sqlserver_function_class and the
default error class rs_sqlserver_error_class do not initially have a
designated primary site, that is, their site ID = 0.
If the recovering Replication Server was made primary for a function string
class or error class since the last transaction dump, the rs_subcmp
procedure described earlier in this section would find orphaned rows in
downstream RSSDs.
In that event, run rs_subcmp again on the rs_classes, rs_erroractions,
rs_funcstrings, and rs_systext system tables. Set prsid = 0, in order to
repopulate these tables with the necessary default settings. For example,
use the following select statement for the rs_classes table:
select * from rs_classes where prsid = 0
order by primary_keys
Example
Suppose you have the following Replication Server sites in your replication
system, where an arrow (-->) indicates a route. Site B is the failed site,
and there are no indirect routes.
A-->B
C-->B
C-->D
B-->E
The preceeding Replication Server sites have the following site IDs:
A = 1
B = 2
C = 3
D = 4
E = 5
In this example, to bring the RSSDs to a consistent state, you would perform
the following tasks, in the order presented, on the rs_classes,
rs_erroractions, rs_funcstrings, and rs_systext system tables.
Reconciling with Upstream RSSDs
1. Run rs_subcmp against the above tables, specifying site B as the
replicate and site A as the primary, with prsid = 1 in the where
clauses. For example, the select statement for rs_columns should look
like the following:
select * from rs_columns where prsid in
(select source_rsid from rs_routes
where
(through_rsid = 1 or through_rsid = 2)
and dest_rsid = 2)
and rowtype = 1
order by objid, colname
2. Run rs_subcmp against the above tables, specifying site B as the
replicate and site C as the primary, with prsid = 3 in the where
clauses. For example, the select statement for rs_columns should look
like the following:
select * from rs_columns where prsid in
(select source_rsid from rs_routes
where
(through_rsid = 3 or through_rsid = 2)
and dest_rsid = 2)
and rowtype = 1
order by objid, colname
Reconciling Downstream RSSDs
1. Run rs_subcmp against the above tables, specifying site B as the
primary and site D as the replicate, with prsid = 2 in the where
clauses. For example, the select statement for rs_columns should look
like the following:
select * from rs_columns where prsid in
(select source_rsid from rs_routes
where
(through_rsid = 2 or through_rsid = 4)
and dest_rsid = 4)
and rowtype = 1
order by objid, colname
2. Run rs_subcmp against the above tables, specifying site B as the
primary and site E as the replicate, with prsid = 2 in the where
clauses. For example, the select statement for rs_columns should look
like the following:
select * from rs_columns where prsid in
(select source_rsid from rs_routes
where
(through_rsid = 2 or through_rsid = 5)
and dest_rsid = 5)
and rowtype = 1
order by objid, colname
See the Replication Server Commands Reference for more information
about the rs_subcmp program and the RSSD system tables.
Subscription Re-Creation Procedure
Follow this RSSD recovery procedure if you have created new subscriptions
since the last transaction dump, and if you have executed some other DDL
commands, but you have not created any new routes. DDL commands in RCL
include those for creating, altering, or deleting routes, replication
definitions, subscriptions, function strings, functions, function string
classes, or error classes.
------------------------------------------------------------------
WARNING! Do not execute any DDL commands until you have completed
this recovery procedure.
------------------------------------------------------------------
As with the subscription comparison RSSD recovery procedure, following this
procedure makes the failed RSSD consistent with upstream RSSDs, or
consistent with the most recent database and transaction dumps (if there is
no upstream Replication Server). It then makes downstream RSSDs consistent
with the recovered RSSD.
In this procedure, however, you also either delete or re-create
subscriptions that are in a limbo state due to the loss of the RSSD.
The current Replication Server refers to the one with the RSSD you are
recovering. An upstream Replication Server is a Replication Server that has
a direct or indirect route to the current Replication Server. A downstream
Replication Server is a Replication Server to which the current Replication
Server has a direct or indirect route.
If DDL commands have been executed at the current Replication Server since
the last transaction dump, you may have to re-execute them.
To restore an RSSD that requires that lost subscriptions be re-created,
follow these steps:
1. To prepare the failed RSSD for recovery, perform steps 1-4 of "Basic
RSSD Recovery Procedure"
2. To prepare for recovery the RSSDs for all upstream and downstream
Replication Servers, perform steps 2-3 of "Subscription Comparison
Procedure"
3. Shut down all upstream and downstream Replication Servers affected by
the previous step. Use the shutdown command.
4. Restart all upstream and downstream Replication Servers in standalone
mode, using the -M flag.
All LTMs connecting to these Replication Servers shut down
automatically when you restart the Replication Servers in standalone
mode.
5. To reconcile the failed RSSD with all upstream RSSDs, perform step 4 of
"Subscription Comparison Procedure".
The failed RSSD should now be recovered.
6. To reconcile all downstream RSSDs with the RSSD for the current
Replication Server, perform step 5 of "Subscription Comparison
Procedure".
7. If the recovering Replication Server is an ID Server, to restore the
IDs in its RSSD, perform step 6 of "Subscription Comparison Procedure".
8. If the recovering Replication Server is not an ID Server, and a
database connection was created at the recovering Replication Server
after the last transaction dump, perform step 7 of "Subscription
Comparison Procedure".
9. Query the rs_subscriptions system table for the current Replication
Server.
o Also query all Replication Servers with subscriptions to primary
data managed by the current Replication Server, or with primary
data to which the current Replication Server has subscriptions.
o You can query the rs_subscriptions system table by using the
rs_helpsub stored procedure.
10. For each user subscription in the rs_subscriptions system table,
execute the check subscription command.
o Execute this command at the current Replication Server and at all
Replication Servers with subscriptions to primary data managed by
the current Replication Server, or with primary data to which the
current Replication Server has subscriptions.
o Subscriptions with a status other than VALID must be deleted or
re-created, as described below.
11. For each Replication Server that has a non-VALID subscription with the
current Replication Server as the primary:
o Note its subid, and delete the appropriate row from the primary
rs_subscriptions system table.
o Use the subid from rs_subscriptions to find the corresponding rows
in the rs_rules system table, and also delete those rows.
For each system table, rs_subscriptions and rs_rules:
o If a subscription is in the primary table and not in the replicate
table (because it was dropped), delete the subscription row from
the primary table.
o If a subscription is in the replicate table and not in the primary
table, delete the subscription row from the replicate table. After
completing the rest of this procedure, re-create the subscription,
as described in steps 17-19.
o If a subscription is in both the primary and replicate tables, but
not VALID at one of the sites, delete the rows from both tables.
After completing the rest of this procedure, re-create the
subscription, as described in steps 17-19.
12. For each primary Replication Server for which the current Replication
Server has a non-VALID user subscription:
o Note its subid, and delete the appropriate row from the primary
rs_subscriptions system table.
o Use the subid from rs_subscriptions to find the corresponding rows
in the rs_rules system table, and also delete those rows.
For each system table, rs_subscriptions and rs_rules:
o If a subscription is in the primary table and not in the replicate
table, delete the subscription row from the primary table. After
completing the rest of this procedure, re-create the subscription,
as described in steps 17-19.
o If a subscription is in the replicate table and not in the primary
table (because it was dropped), delete the subscription row from
the replicate table.
o If a subscription is in both the primary and replicate tables, but
not VALID at one of the sites, delete the rows from both tables.
After completing the rest of this procedure, re-create the
subscription, as described in steps 17-19.
13. Execute the sysadmin drop_queue command at both the primary and
replicate Replication Server, for all existing materialization queues
for subscriptions deleted in steps 17-19.
14. Restart in normal mode all Replication Servers, and their LTMs, that
had subscriptions to primary data managed by the current Replication
Server, or with primary data to which the current Replication Server
had subscriptions.
15. Perform steps 5-13 of "Basic RSSD Recovery Procedure"
16. Re-execute any DDL commands executed at the current Replication Server
since the last transaction dump.
17. Enable autocorrection for each replication definition.
18. Re-create the missing subscriptions using the bulk materialization
method.
Use the define subscription, activate subscription, validate
subscription, and check subscription commands for bulk materialization.
19. For each re-created subscription, restore consistency between the
primary and replicate data in either of two ways:
o Drop a subscription using the drop subscription command and the
with purge option. Then re-create the subscription.
o Use the rs_subcmp program with the -r flag to reconcile replicate
and primary subscription data.
See the Replication Server Commands Reference for more information about the
rs_subcmp program and the RSSD system tables.
Deintegration and Reintegration Procedure
If you created routes since the last time the RSSD was dumped, you are
required to perform the following tasks before you can finish recovering the
RSSD:
1. Remove the current Replication Server from the replication system.
See "Modifying a Replication System," in the Replication Server
Administration Guide for details.
2. Reinstall the Replication Server.
See the Replication Server Installation Guide for complete information
about reinstalling Replication Server.
3. Re-create Replication Server routes and subscriptions.
See the Replication Server Administration Guide Chapter 6, "Subscribing
to Replicated Tables," and Chapter 7, "Managing Routes," for details.
See the Replication Server Commands Reference for more information about the
rs_subcmp program and the system tables.
min() and max() Functionality
Question
How can I find min or max of two int or float columns forall rows in a
table? Is it possible to do min or max ontwo columns at once?
Answer
It is entirely possible to do min or max on two columnsat once. Given a
table that was created as follows:
create table MINMAX( a int, b int)
you can use the following sequence of Transact-SQL commands to get
theresults you want:
1> select a,b, 2> "max" = (a+b)/2.0 + abs((a-b)/2.0), 3> "min" = (a+b)/2.0 - abs((a-b)/2.0) 4> from MINMAX 5> go a b maxmin ------
You may also add convert(int....) if necessary.
Viewing all Decimal Digits in a select frommoney_column
Question
How do I convert a money field so that an entire entry, with allfour decimal
digits, is visible?
Answer
The following example shows one way to display all the digits in asingle
string (preserving leading zeros in decimals), given a tablewith one money
column loaded as follows:
1> insert into lvmoney2 values ($12345678901.0087) 2> insert into lvmoney2 values ($11170305027104.1195) 3> go
Structure your query like this:
select str(floor(m1),15,0) + convert (char(4), replicate("0", 4 - datalength(convert(varchar(4), convert(int, (10000*(m1-floor(m1))) ) ))) + convert(varchar(4), (convert(int, (10000*(m1-floor(m1))) ) ))) from lvmoney2
The output will look like this:
------------------- 123456789010087 111703050271041195 (2 rows affected)
For further information, see "Float and Money Display Methods" inVolume 3,
Number 3 of the SYBASE Technical News (available inAnswerBase when you do a
full-text query of the form <title technicalnews>).
Dump/Load Compatibility, 10.0.1 vs. 10.0.2
Question
Can a backup done by a release 10.0.1 Backup Server be loaded onto arelease
10.0.2 SQL Server?
Answer
There are really two issues here, but the short answer is, yes,10.0.1 dumps
are compatible with 10.0.2. The two issues are:
* Can you to load a 10.x dump to a 10.0.2 SQL Server?
* Can you use different versions of Backup Server and SQL Server?
Loading Dumps from 10.0 or 10.0.1 P1 SQL Server to 10.0.1 P2 or 10.0.2
If you want to load a dump from a 10.0 SQL Server or from an earlierrelease
10.0.1 SQL Server to a 10.0.1 P2 or 10.0.2 SQL Server, youmust execute a
script to update all system tables and user databasescontained in the load.
This script is necessary because of changesto the sysreferences table for
release 10.0.1 P2 or later.
------------------------------------------------------------------
NOTE: Do not use the script if you are loading a dump from 10.0.1
P2 to 10.0.2. 10.0.1 P2 is completely compatible with 10.0.2, and
no additional steps are needed.
------------------------------------------------------------------
Use an editor like vi to edit the upgradesysrefperdb.sqlscript, which is
located in the $SYBASE/upgrade directory.Insert the following lines at the
beginning of the script:
use database_name go
where database_name is the name of the database to be updated.
After you have completed the load, execute theupgradesysrefperdb.sql script
as System Administrator:
% isql -Usa -Ppassword -Sserver_name < $SYBASE/upgrade/upgradesysrefperdb.sql
where sa is the name of a System Administrator account,password is the
password for that account, and server_nameis the name of the 10.0.1/P2 or
later SQL Server where you loaded the database.
Repeat steps 1 and 2 for every 10.0 or earlier 10.0.1 databaseloaded on a
10.0.1/P2 or later SQL Server, including the systemdatabases.
Back up all of your databases.
Backup Server vs. SQL Server Versions
If you use a 10.0 Backup Server with a 10.0.1 SQL Server, you willget this
error message:
Open Server Session Fatal Error: 16227.15.0: Unknown token TDS stream received by spid
If you are using the Backup Server that is compatible with your10.0.2 SQL
Server, you should be able to load dumps from 10.0 and10.0.1. Be sure to use
the compatible Backup Server with your SQLServer: 10.0 with 10.0; 10.0.1
with 10.0.1; 10.0.2 with 10.0.2.
------------------------------------------------------------------
NOTE: An exception to this is the beta SQL Server and Backup
Server release. Changes occurred between the beta and production
releases that render dumps made by a beta Backup Server unreadable
to a production Backup Server. See "Error 16227.15.0" in Chapter
3, "Backup Server", of the SYBASE SQL Server Troubleshooting Guide
dated February 14, 1995 for more details.
------------------------------------------------------------------
keepalive Redux
SQL Server users who have started networking with PC clients oftenquestion
the issue of "ghost" connections and keepalive timing that cancause a server
to run out of connections rapidly.
The problem is that the PC user is used to running the PC in standalonemode.
If the user submits a query to SQL Server which takes too long tofinish, or
has made a mistake, the user is likely to reboot the PC, orclose the
application with a Ctrl-Alt-Del. The aborted process hangsaround in SQL
Server and finishes after about four hours.
While this may seem like a db_cancel problem--that is, that the querydoes
not get cancelled when the PC goes down--it is actually due toincomplete
coding in the application combined with the value to whichthe keepalive
timeout is set on the SQL Server host machine.
Ideally, an application allows the PC user to cancel the query and doesa
db_cancel when the user chooses this option. Due to aspects both
ofapplication design and of Windows itself, this is not always possible.
Network connections are always peer to peer, meaning that both sidesknow
that the other side could go away at any time. However, because ofnetwork
traffic and processing considerations, it may take some timefor a machine to
respond. This is where keepalive comes in.
The keepalive timer controls how long the machine will wait for aconnected
machine to respond; the keepalive interval controls how longthe host will
wait between pings to the remote machine; the keepalivecount controls how
many times the host will ping the remote machinebefore it gives up and
clears the connection.
The problem in the PC-to-UNIX world is that the PC expects everythingto
behave as though it is local, while UNIX expects WAN-typeconnections. What
this means is that a PC generally has keepalive hardcoded at about one
minute. A UNIX machine has a keepalive timer whosedefault setting makes more
sense in a world of WAN and low-speedconnections-somewhere around two hours.
To close the connections more quickly, you must decrease the UNIXkeepalive
timer to match that of the PC more closely. Depending onnetwork traffic
constraints, one to five minutes should be adequate.See your System
Administration Guide Supplement oroperating system documentation to find out
how to setkeepalive.
Setting Up Borland IDE to Compile Client-Library
To compile Open Client Client-Library[TM] applications under BorlandC++ for
Windows, you can either modify the Sybase-supplied samplemakefile,
borland.mak, for your program or start a new InteractiveDevelopment
Environment (IDE) project. This article explains how to dothe latter.
1. Open a new project for the program: for example, choose Project-->New
Project from the menu bar. Browse to where the program is located (for
example, $SYBASE\sample\ctlib), and enter the target name (for example,
rpc). For our sample programs, change the Target Type to EasyWin[.exe].
2. Make sure that the Class Library and BWCC checkboxes are not selected,
and choose OK.
3. Choose Options-->Project. Select Directories, and make sure the
following directories are listed:
Include: %BORLAND%\include; %SYBASE%\include; %SYBASE%\sample\ctlib Library: %BORLAND%\lib; %SYBASE%\lib
Where %BORLAND% is the Borland compiler home directory and %SYBASE% is
the Sybase home directory (this can be set up as default for the
compiler).
4. Highlight the topic "Compiler/Defines". In the "Defines" window, you
must have the following:
WIN3;CS_FORCE_PROTOTYPES
These can be included in your header files as well. CS_FORCE_PROTOTYPES
causes prototype functions to be generated, eliminating warning
messages about functions being used without prototypes.
5. Select Linker-->General and make sure that the Case sensitive link
checkbox is selected.
6. Choose OK to accept all of the changes to the project. It is a good
idea to select Options-->Save and save the new project at this point.
7. Choose View-->Project and add the following libraries:
wcomnlib.lib wintllib.lib wcslib.lib wctlib.lib
------------------------------------------------------------------
NOTE: You will also need to add wblklib.lib if you areusing bulk
copy routines.
------------------------------------------------------------------
For the example programs, you will also need to add exutils.c tothe project.
Macintosh Think-C and ct_init Routine
If you are running the Open Client/C Developer's Kit for Macintosh andare
having trouble with the ct_init routine failing, even thoughyour LANG
variable is set correctly and ctlib.loc isavailable, it may be because the
default project size for Think-C istoo small. The default value is 396; try
setting its value to at least4000 and compiling your application again.
Certification Reports
The following certification reports have been passed along to
SYBASETechnical News by the appropriate Sybase engineering groups.
SQL Debug Certified for DEC OSF/1
SQL Debug® has been certified to work with SQL Server release 10.0.2 forDEC
OSF/1. This corrects an existing problem between SQL Debug and DECOSF/1 SQL
Server release 10.0.1 or earlier where a control-of-flowlanguage statement,
such as if...else or while, causesSQL Debug to hang.
IPX/SPX Certification for Solaris
As of the 10.0.2 release of SQL Server on Solaris 2.x, IPX/SPX iscertified
and supported. You need to apply Rollup 4222 for thiscombination to be
certified; you may order the Rollup from TechnicalSupport in the usual way.
IPX/SPX is certified at the current release level of Solaris 2.3.
Certification Report for All Platforms
<<<<<<<<
Platform Operating Server Date Notes
System Version
Passed. Tape device is
supported on all OS levels
QIC tape device 10.01 08/94 currently supported for
10.0x. OS patch required:
PSCSI version 94.04.25.19
SVR4 2.00.02 Passed. Certified with
(SMP) 4.9.1 04/93 WIN-TCP/IP 2.00.04. Requires
ASYNCH I/O patch P2ASYNC.
SVR4 2.00.02 Passed. Certified with
(UP model) 4.9.1 04/93 WIN-TCP: (i386) 02.00.04.02
SVR4 2.01 10.0 02/94 N/A. No plans to certify.
SVR4 2.01 4.9.1 04/93 Passed. Certified with
WIN-TCP 2.00.05.
SVR4 2.01.01 + Passed. Certified with
Pentium 4.9.1 07/93 WIN-TCP 2.01.00.12
SVR4 2.02 10.0 02/94 Passed. certified with
WIN-TCP 2.01.01.08.
Passed. certified with
SVR4 2.02 4.9.2 12/93 WIN-TCP 2.01.01.08. and
Rollup 2025 (built on OS
2.00.01 with patched libdbt).
SVR4 2.02 +
pentium 10.0 02/94 Passed.
Passed. Certified w/WIN-TCP
2.02.00.07. OS patch PSCSI203
is required for any customer
AT&T SVR4 2.03 10.01 08/94 planning to use the HP DAT
(NCR) 4mm tape drive for
backupserver.
Passed. Rollup 3165 is built
with a new libdbt.a so that
SQL Server would work with
SVR4 2.03 4.9.2 09/94 AT&T UNIX 2.02 and later
releases without problems and
make use of improved system
calls.
SVR4 2.03 +
EISA bus 10.01 11/94 Passed.
SVR4 2.03 +
EISA bus 4.9.2 12/94 Passed.
Passed. Bugs entered:
sybinit(65591), doc(65604),
connectivity(65807,65 817).
SVR4 2.03 + PC Windows Net-Library EBF
SPX/IPX 10.0.2 01/95 #4316 is required for
connectivity bug #65807. PC
Windows DB-Library (4.2)
based clients can connect to
the Unix Server.
Passed. A series of patches
SVR4 2.03.01 10.01 12/94 are needed to support EISA
and MCA systems.
Passed. A series of patches
SVR4 2.03.01 4.9.2 12/94 are needed to support EISA
and MCA systems.
Supported. This was handled
as a maintenance rollup
AXP OpenVMS 1.5 4.9.2 release. All customers will
be shipped the EBF rollup
which supports AXP VMS 1.5.
AXP OpenVMS 1.5
+ UCX 4.9.2 N/A, No plans to certify.
Passed. UCX (ECO 2 or higher)
is required. SQL Server must
be configured for double the
AXP OpenVMS bytlm. In addition, if user
1.5+UCX 3.1 10.01 09/94 clients are put into a MUTEX
state we recommend doubling
the bytlm for the number of
users.
Passed. Network packages
AXP OpenVMS 6.1 10.01 12/94 certified: DECnet Phase IV,
UCX 3.2 and Multinet 3.3
DEC Alpha
Passed. Network packages
AXP OpenVMS 6.1 4.9.2 01/95 certified: DECnet Phase IV,
UCX 3.2 and Multinet 3.3
OSF/1 1.3 10.00 11/93 Passed.
OSF/1 2.0 10.01 09/94 Passed.
Passed. The "b" in the OS
OSF/1 2.0b 10.01 09/94 version indicates that the OS
is for the new DEC 2100 sable
machines.
OSF/1 2.1 10.01 11/94 Supported.
A new product release is
required to support OSF/1
3.0. It will be only sent to
OSF/1 3.0 10.0.2 01/95 those customers who request
it via the new PID issued as
19555. Contact Sybase
Customer Service.
Ultrix 4.3 4.2 11/92 Passed.
DEC RISC Ultrix 4.3a 4.2 06/94 Passed. Requires ebf# 2005.
Ultrix 4.4 4.2 10/94 Certified. EBF 2005 or higher
required.
Passed. To run UCX, SQL
Server must be configured via
the VMS AUTHORIZE utility for
OpenVMS 5.4 + double the bytlm stated in
UCX 3.1 10.01 08/94 the SAG Supplement. In
addition the INET device
emulator must be loaded
before starting SQL Server.
Passed. Known problem: The
OpenVMS 5.4 + SQL Server runs out of AST
Wollongong 10.01 06/94 quota. This problem has been
reported against Wollongong.
OpenVMS 5.5-2 10.0 02/94 Passed.
DEC VAX OpenVMS 5.5-2 4.9.1 Supported.
Passed. As noted in the
Release Bulletin customers
must install System10 product
OpenVMS 6.0 10.0 04/94 O/S version 5.4 before
upgrading to OpenVMS 6.0.
VMSINSTALL is not supported
at this OS level.
Passed. Network packages
OpenVMS 6.1 10.01 01/95 certified: DECnet Phase IV,
UCX 3.2 and Multinet 3.2
Passed, Network packages
OpenVMS 6.1 4.9.2 certified: DECnet Phase IV,
UCX 3.2 and Multinet 3.2
DGUX 5.4 4.2 Passed, This does not include
DGUX 5.41 or 5.42
Failed. We recommend upgrade
DGUX 5.4.2 4.2 10/92 to 4.9 after upgrading O/S to
DGUX 5.4.2
DGUX 5.4.2 4.9 Passed.
DGUX 5.4.2.01 10.0 Passed.
DGUX 5.4R2 4.9.0S Passed.
Data
General DGUX5.4R2.1 10.0.1 Passed.
DGUX5.4R2.1 10.0sq Passed.
Passed. Users with 4-mm and
8-mm tapes must have Rollup
3963 to run this combination.
DGUX5.4R3.10 10.0.1 11/94 For 8-mm you also need DGUX
patch NSQA-18785-0. See
technical details in the
Release Bulletin for Rollup
3963.
4.0.1
HP300 HP-UX 8.0 10/92
Passed.
HP-UX 8.01 4.2 Passed.
HP-UX 8.05 4.2 Passed.
HP-UX 8.05 4.9.1 Passed.
HP-UX 8.07 4.2 09/92 Passed.
HP-UX 8.07 4.9 Passed.
HP-UX 8.07 4.9.1 Passed.
HP-UX 9.0 4.9.1 Failed.
HP-UX 9.0.1 10.0 02/94 N/A, no plans to certify.
HP-UX 9.0.1 4.9.1 03/93 Passed, ASYNC I/O patch
PHKL_2162 is required.
HP700 HP-UX 9.03 10.01 03/94 Passed.
Passed. Requires HP700
HP-UX 9.03 4.9.2 03/94 Asynchronous I/O patch#
PHKL_3660
Passed, Requires patch
PHKL_4334 and patch PHKL_4269
HP-UX 9.05 10.0.1 12/94 - Bug 64656 has been entered
for 'installasync70' script
incompatibility.
Passed, Requires patch
PHKL_4334 and patch PHKL_4269
HP-UX 9.05 4.9.2 12/94 - Sybase Bugid 64656 has been
entered for 'installasync70'
script incompatibility.
HP-UX 8.0 4.2 Passed.
HP-UX 8.0 4.9 Passed.
HP-UX 8.02 4.9 Passed.
HP-UX 8.02 4.9.1 Passed.
HP-UX 8.06 4.9 Passed.
N/A, No plans for
HP-UX 8.08 BLS certification because BLS
(Secure) 4.9.1 does not support asychronous
I/O.
HP-UX 8mm tape
device 10.0 10/94 Passed.
HP800 HP-UX 9.0 4.9.1 Passed.
Passed. Bug #41610 reported -
HP-UX 9.0 using 'disk init' will only
LVM 4.9.1 05/93 initialize Logical Volume
devices %lt;= 2GB.
HP-UX 9.04 10.0 03/94 Passed.
HP-UX 9.04 4.9.2 Passed.
HP-UX 9.04 Passed. Requires Asynch I/O
using LVM 10.01 10/94 patch PHKL_3624 & LVM Sybase
Mirroring patch PHKL_4418
HP-UX 9.04 Passed, Requires Asynch I/O
using LVM 4.9.2 10/94 patch PHKL_3624 & LVM Sybase
Mirroring patch PHKL_4418
Passed. 4mm 2GB (7206-001)
has full Backup Server
feature support. 4mm 4GB
(7206-005) supports all
4mm tape device 10.01 11/94 Backup Server features except
the ability to write multiple
file/volume dumps to a single
tape. Bug #63636 has been
entered to track this product
enhancement.
AIX 3.2 4.2 Passed.
AIX 3.2.1 4.9.1 N/A, No plans for
certification
AIX 3.2.2 4.9.1 N/A, No plans for
certification
AIX 3.2.3e 4.9.1 05/93 Passed. IBM PTF U418109 is
required for AIX 3.2.3e
AIX 3.2.4 4.9.2 08/93 Passed.
Passed. IBM PTFs (Patches)
AIX 3.2.5 10.0 02/94 are required for the
following IBM APARs: IX45257,
IX41600, IX38605, IX43714
Passed. IBM PTFs (Patches)
AIX 3.2.5 4.9.2 12/93 are required for the
following IBM APARs: IX45257,
IBM IX41600, IX38605, IX43714
RS6000 Passed. IBM PTFs (Patches)
AIX 3.2.5 + are required for the
PowerPC Chip 4.9.2 12/93 following IBM APARs: IX45257,
IX41600, IX38605, IX43714
Passed. SQL Server EBF 4283
is required. Bugs entered:
sybinit(65590), doc(65603),
connectivity(65807,65 817).
AIX 3.2.5 - PC Windows Net-Library EBF
SPX/IPX 10.02 01/95 #4316 is required for
connectivity bug #65807. PC
Windows DB-Library (4.2)
based clients can connect to
the UNIX SQL Server.
AIX 3.2.X SP/1
SP/2 10.01 Supported.
AIX 3.2.X SP/1
SP/2 4.9.2 Supported.
No certification is planned.
A new product release is
AIX 4.1.1 (SMP) 10.0 01/95 required to support the SMP
version of AIX 4.1.1, planned
for a later date.
Passed. This certification is
AIX 4.1.1 (UP) 10.01 12/94 based on the uniprocessor
version of the AIX 4.1.1
release.
ICL DRS
6000 DRS/NX V7L2 10.0.0 Passed.
Motorola SVR4 R$V4.1 10.0.0 Passed.
NEC SVR4 R6.1 10.0.1 Passed.
NetWare v 4.02 10.0.2 Supported.
Netware 3.1.1 + Failed. Severe OS problems
SFT III 4.2 05/93 were encountered during the
certification.
Passed. This certification
Netware 386 v also includes the maintenance
3.11 4.2 release of SQL Server 4.2.1 &
4.2.2
Netware 386 v Passed. Requires EBF# 2388.
3.12 4.2.2 03/94 See release bulletin for NLMs
and versions.
Passed. Requires EBF #2404
Netware 386 v and new CLIB.NLM versions.
4.0.1 4.2.2 12/93 See ebf coverletter forthe
CLIB.NLM version numbers and
dates.
Netware 4.0.2 4.2.2 12/94 Passed. Requires EBF 3617 or
PC higher.
OS/2 1.2.1 4.2 Passed.
OS/2 1.3x.x 4.2 Passed.
OS/2 2.0 4.2 Passed. CSD 6055 recommended
OS/2 2.1 4.2 N/A, No plans to certify.
SCO 3.2.4 4.2 Passed.
Passed. Requires Rollup 1980
and SCO SLS patch UOD378a.
Rollup resolves error 611
SCO 3.2.4.2 4.2 11/93 encountered during testing.
Also includes support for SCO
Open Server Enterprise System
Release 3.0, and SCO Open
Desktop Release 3.0.
Passed, The following
Windows NT 3.5 10.01 12/94 certification test run
problems have been recorded
in BTS: 64109 & 64110.
PC SCO R3.2 V4.2 10.0.1 Passed.
1.1 93d067 10.0.1 Passed.
Pyramid N
94d079 10.0.1 In Progress.
Passed. Binaries built on
Pyramid S/C062 will run on
Pyramid this OS version, but binaries
Nile D067 10.0 built on Pyramid Nile/D067
are not certified to run on
Pyramid ES/C062.
1.1 93c062 10.0.1 Passed.
1.1 93c062 4.9.1 Passed.
Pyramid S SVR4 C034 4.9 Passed.
SVR4 C044 4.9 Passed.
SVR4 C062 4.9 Passed.
5.1a 93a060 4.8 Passed.
Pyramid T
OSx 5.1A 4.8 Passed.
SCO R3.2 V4.2 10.0.0 Passed.
DYNIX 1.2 4.8 Passed.
DYNIX 1.4 4.8 09/92 Passed.
Passed. EBF binaries built on
DYNIX 2.0 4.8 this OS version will not run
on PTX 1.4 and below.
Passed, EBF binaries built on
Sequent DYNIX 2.0.1 4.8 PTX 2.0 and above will not
run on PTX 1.4 and below.
DYNIX 2.1 4.8 N/A, No plans to certify.
DYNIX 2.1.0 10.0.0 Passed.
DYNIX 2.1.0 4.8 Passed.
DYNIX 4.0 10.0.1 Passed.
IRIX 3.2 4.0.1 Passed.
Silicon IRIX 5.1 10.0 Passed.
Graphic IRIX 5.1.1.1 10.0.1 Passed.
IRIX 5.2 10.0.1 07/94 Passed.
Sony NEWS R6.0.1 10.0.1 Passed.
FTX 2.2.2(y) 10.01 Passed.
Stratus VOS 10.5 4.8 Passed.
VOS 11.6 4.9 Passed.
Stratus
68K VOS VOS 10.5 4.8 Passed.
Stratus FTX 2.2.2 10.0 Passed.
FTX FTX 2.2.2.3 10.0.1 Passed.
Passed. Requires Rollup 1794
Solaris 2.2 4.9.1 06/93 or higher and SunOS patches
100999-09 and 101095-01.
Solaris 2.3 10.00 11/93 Passed.
Solaris 2.3 4.9.2 12/93 Passed.
Solaris 2.3 + Passed. Required Sun patches:
SPARCstor 10.0.1 12/94 102198-01 & 102199-02 for use
with Sun's Volume Manager
Solaris 2.3 + Passed, Required Sun patches:
SPARCstor 4.9.2 12/94 102198-01 & 102199-02 for use
with Sun's Volume Manager
Passed. Requires Rollup 4222.
Bugs entered: sybinit(65592),
doc(65605),
connectivity(65807,65 817).
Solaris 2.3 + PC Windows Net-Library EBF
SPX/IPX 10.0.2 01/95 #4316 is required for
connectivity bug #65807. PC
Windows DB-Library (4.2)
based clients can connect to
the UNIX SQL Server.
Solaris
2.3-A+Edition 1 10.0 N/A, No Plans to certify
SunOS 4.1.1 4.2 Passed.
SunOS 4.1.1 4.8 Passed.
SunOS 4.1.1 + Passed. requires SunOS 4.1.1
DBE 1.1 4.8 patch #100293 or SunDBE 1.1
patch #100322.
SunOS 4.1.1 +
DBE 1.1 4.9 02/92 Passed.
SunOS 4.1.2 4.0.1 Passed.
SunOS 4.1.2 4.2 Passed.
SunOS 4.1.2 4.8 Passed. requires SunOS 4.1.2
Kernel patch #100495
Sun4 SunOS 4.1.2 +
DBE 1.2 4.2 08/92 Passed.
SunOS 4.1.2 +
DBE 1.2 4.9 02/92 Passed.
SunOS 4.1.2 +
DBE 1.2 4.9.1 Passed.
SunOS 4.1.3 4.2 N/A, No plans to certify.
SunOS 4.1.3 4.8 02/93 Failed. We recommend upgrade
to the 4.9.1 server.
SunOS 4.1.3 4.9 03/93 Passed.
Passed. requires SunOS 4.1.3
SunOS 4.1.3 4.9.1 10/92 Sun-4m Supplement patch
#100743-01. Patch is for
multi-processor systems only.
SunOS 4.1.3 + Passed. EBF #4403 is
DBE 1.3 10.02 02/95 required.
SunOS 4.1.3 +
DBE 1.3 4.9 N/A, No plans to certify.
Passed. requires Sun-4m
SunOS 4.1.3 + Supplemental patch
DBE 1.3 4.9.1 04/93 #100743-01. Patch is for
multi-processors and Sparc 10
systems only.
Passed. requires SunOS 4.1.3
SunOS Sun-4m Supplement patch
4.1.3/sparc10 4.9.1 #100743-01. Patch for
multi-process systems only.
Passed. The 'X' in 4.1.3X
SunOS 4.1.3X 10.01 12/94 indicates all of the 4.1.3
based releases. (eg 4.1.3c,
4.1.3.u1, 4.1.3u1b, etc.)
Passed. The 'X' in 4.1.3X
SunOS 4.1.3X 4.9.2 03/94 indicates all of the 4.1.3
based releases. (eg 4.1.3c,
4.1.3.u1, 4.1.3.u1b).
SVR4 Ver 1.2 10.0.1 Passed.
Unisys 65
SVR4 Ver 1.2 4.9.2 Passed.
Unisys 75 Dynix 1.3.1 4.8 Passed.
Unisys
U6000 75 SVR4 1.3 4.8 Passed.
Unisys
U6000/65 SRV4 1.2 4.9.2 Passed.
Bug 61483 - Duplicate Rows in syskeys
Problem
select * from syskeys shows apparent duplicate rows. This should, intheory,
not be possible, since syskeys has a clustered index on it,which should
prevent duplicate rows. These duplicates mean that somestored procedures do
not report errors when they should.
Explanation
When an insert is done to a table on which there is a clustered index, SQL
Server does a byte-by-byte comparison of the entire row. If it finds a
duplicate row, it rejects the insert. SQL Server assumes that the complete
area between the start and the end of the data is valid. This assumption
turns out to be correct for all tables, except syskeys.
The system catalog for syskeys contains a column that can't be displayed,
which contains random or uninitialized data. It is possible for two rows
with identical data in the visible columns to differ in the contents of the
hidden column.
This problem occurs on 4.9.x, 10.0.1, and 10.0.2 SQL Servers.
Solution
You can correct this problem by running a script that exposes the column (it
is called spare1, and is a 2-byte integer column) and binds a default of
zero to it. This prevents any future occurrences; the script also corrects
any existing duplicates in syskeys.
The change made by this script will not break any of the system stored
procedures that refer to syskeys; this is because the default on the new
column ensures that any insert that does not specify the new column gets a
default value of zero.
The script also does sanity checks to see if it has already been run.
The scripts are available as Rollups for the following platforms and
releases:
Table 4: Rollups correcting bug 61483
Rollup Number Platform Release Number
3938 SunOS Release 4.x (BSD) 10.0.2
3939 Sun Solaris 2.x 10.0.2
3940 HP 9000 Series 300 HP-UX 10.0.2
3941 AT&T (NCR) System 3000 10.0.2
3942 IBM RISC System/6000 AIX 10.0.2
3943 DEC OSF/1 10.0.2
3944 SunOS Release 4.x (BSD) 4.9.2
3945 Sun Solaris 2.x 4.9.2
3947 HP 9000 Series 300 HP-UX 4.9.2
3948 AT&T (NCR) System 3000 4.9.2
3949 IBM RISC System/6000 AIX 4.9.2
These scripts are available only as controlled releases. Many customersare
not doing operations that directly involve syskeys, and SybaseEngineering
prefers that the problem be sorted out for youtransparently on upgrade to
10.0.3. If you cannot wait, however, Sybasehas provided the script as a
Rollup that you can order from TechnicalSupport.
In order to minimize confusion, the scripts are all the same and
willautomatically sort out differences between the SQL Server
releases.Release 10.0.2 will run against all 10.0.1 P2 and 10.0.2 SQL
Servers.
For Windows NT, Novell NetWare, and other PC platforms, there are norecorded
instances of this problem.
----------------------------------------------------------------------------
Disclaimer: No express or implied warranty is made by SYBASE or its
subsidiaries with regard to any recommendations or information presented in
SYBASE Technical News. SYBASE and its subsidiaries hereby disclaim any and
all such warranties, including without limitation any implied warranty of
merchantability of fitness for a particular purpose. In no event will SYBASE
or its subsidiaries be liable for damages of any kind resulting from use of
any recommendations or information provided herein, including without
limitation loss of profits, loss or inaccuracy of data, or indirect special
incidental or consequential damages. Each user assumes the entire risk of
acting on or utilizing any item herein including the entire cost of all
necessary remedies.
Staff
Principal Editor: Leigh Ann Hussey Contributing Writers:
Lance Anderson, Paul Dow, Ken Duffy, Aimee Grimes, Joseph Hui, Greg Klinder,
Andrzej Sarapuk, Gerald Soulos, Loretta Vibberts, Rob Weaver, Elton
Wildermuth
Send comments and suggestions to:
SYBASE Technical News
6475 Christie Avenue
Emeryville, CA 94608
or send mail to tech...@sybase.com
Copyright 1996 © Sybase, Inc. All Rights Reserved.
Q10.2.3
Technical News Volume 4, Number 3, August 1995
This issue of the SYBASE Technical News contains new information about your
SYBASE software. If needed, duplicate this newsletter and distribute it to
others in your organization. All issues of the SYBASE Technical News and the
Troubleshooting Guides are included on the AnswerBase CD.
To receive this document by regular email, send name, full internet address
and customer ID to tech...@sybase.com.
IN THIS ISSUE
* Technical Support News/Features
o OpenLine News
o Technical Support North American Holidays
o Sybase Character Sets CD-ROM Available
* SQL Server
o Performance Tip for Inserts with Non-Unique Clustered Indexes
o How to Read syscolumns.status
o Patches Required to Run SQL Server 10.0.2 with DEC OSF/1 Version
3.0
o Additional Information for 1605 Workaround
o DBCC LOG with truncate log set Raises Spurious 813 and 605 Errors
o Two New HP Patches for SQL Server 10.0.1
o Enabling Asynchronous I/O for HP-UX 10.0
o Moving Log Off a Device
o Query to List All Objects & Sizes on Segment
o How to Read SQL Server Version Strings
o Generating Templates for Non-interactive Install with ^W
o Optimizer Frequently Asked Questions
o Currently Supported Backup Server Devices
* Connectivity / Tools / PC
o MS Access Errors with Intersolv Sybase System 10 ODBC Driver
o Workaround for non-char NULLs in OmniSQL Server
o Dynamic Parameter Markers in Embedded SQL
* Certification and Fixed Bug Reports
o Bug 69427 - sp_rename Syntax
o Bugs 31229 and 58701 - sp_addmessage
o SQL Server 4.9.2 EBFs 4152 and 4659 and Bugs 54367 and 68128
o Connectivity Documentation Corrections
o Latest Rollups for SQL Server 4.9.2
o Bugs Fixed in Latest Rollup, SQL Server 4.9.2
o Latest Rollups for SQL Server 10.0.2
o Bugs Fixed in Latest Rollup, SQL Server 10.x
OpenLine News
On April 5th, Sybase OpenLine on CompuServe unveiled a new section called
"EBF EXPRESS." This section allows customers with current support contracts
who have licensed Sybase PC Client products to view the latest EBF Cover
Letters and download the latest EBFs for those products. The sections
covered are:
Status Section Number Section Name Description
open 23 PC Client Windows, DOS, OS/2 Client EBFs
soon 22 Novell Novell Workgroup Server EBFs
soon 21 NT NT Server EBFs
planned20 UnixWare
Note: if this does not appear as a table to you, you may want to start using
the Netscape browser.
The sections are accessible by application only. Sybase OpenLine members may
download the file called ACC-23.APP in the General Technical (#1) library,
fill it out, and return it to the SysOp via CompuServe Mail. Applications
are usually processed the same day, but allow 24 to 48 hours for a response
by CompuServe Mail.
There is also a corresponding message base for EBF EXPRESS to report
problems or ask questions about the EBFs or Cover Letters.
The Sybase OpenLine Team is pleased to be able to offer a new level of
self-sufficiency to our customers through EBF EXPRESS; we have already
received very positive comments about the service!
As of April 10th, over 19,400 CompuServe members have joined the Sybase
OpenLine forum, and over 28,700 messages have been posted (a rate of about
72 per workday). There are over 1,200 technical tips and informational files
in the Sybase OpenLine libraries; over 106,900 downloads have been recorded.
Sybase OpenLine continues to be a great tool for networking with other
Sybase customers, analysts, consultants, and employees to solve customer
problems.
To join CompuServe, in the United States call (800) 848-8990; outside the
U.S., dial (+1) 614-529-1340
To join the Sybase OpenLine Forum, type:
GO SYBASE
Questions about the Sybase OpenLine forum or EBF Express may be addressed
to: Perry Bent, 7332...@compuserve.com
Technical Support North American Holidays
Sybase Technical Support is open on all holidays and provides full service
on many holidays. On the holidays shown below, Technical Support provides
limited service. During limited-service holidays, the following Technical
Support coverage will be provided:
* SupportPlus Preferred and Advantage Customers may log all cases;
priority 1 and 2 cases will be worked on over the holiday.
* 24x7 and 24x5 Support Customers may log priority 1 (down server) cases
which will be worked on over the holiday.
* SupportPlus Standard, Desk Top, and Regular Support Customers may
purchase Extended-hour Technical Support for coverage over the holiday.
Sybase Technical Support
limited-service holidays - U.S.
customers
Holiday Date
New Year's Day January 2
President's Day February 20
Memorial Day May 29
Independence Day July 4
Labor Day September 4
Thanksgiving November 23
Christmas December 25
Sybase Technical Support
limited-service holidays - Canadian
customers
Holiday Date
New Year's Day January 2
Good Friday April 14
Victoria Day May 22
Canada Day (observed) June 30
Labour Day September 4
Canadian Thanksgiving October 9
Christmas Day December 25
Boxing Day December 26
Sybase Character Sets CD-ROM Available
The Sybase Character Sets CD-ROM provides new character sets and sort order
files that enable SQL Server to handle data in 26 different character sets.
This new product allows you to create applications in your local language(s)
and handle them correctly from a cultural and lexical point of view.
One or more sort order files are provided for use with each character set,
allowing you to correctly sort the data in your SYBASE database. In
addition, the character sets are compatible with the automatic character set
conversion feature available in SYBASE SQL Server(™) release 10.0.2
and later.
The initial release of the Sybase Character Sets CD-ROM contains character
sets for the following regions and languages:
* Arabic
* Chinese (Simplified and Traditional)
* Cyrillic (Russian and other Cyrillic-based languages)
* Central and Eastern European
* Greek
* Hebrew
* Japanese
* Korean
* Turkish
* Western European
The product order number for the Sybase Character Sets CD-ROM is
10490-55-0100-41.
Frequently Asked Questions
Question: Are JLE and KLE supported?
Answer: Yes. The Sun Japanese Language Environment (JLE) and Sun Japanese
Feature Package (JFP) are supported by the eucjis character set. The Sun
Korean Language Environment (KLE) and Sun Korean Feature Package (KFP) are
supported by the eucksc character set.
Question: I thought Sybase already supported Chinese--why do I need this
product too?
Answer: The Chinese character sets provided on the Sybase Character Sets
CD-ROM provide a more robust support for both traditional and simplified
Chinese character sets than has been possible in the past using the ascii_8
character set. For example, pattern matches using the like SQL statement on
multibyte characters are now handled properly.
Question: What are the disk and RAM requirements?
Answer: The entire content of the CD-ROM is less than 6MB. A typical user
will install only a few of the character sets and sort orders, requiring
only five or six files. A small amount (one to five 2K pages) of additional
memory may be required when moving from ascii_8 to an Asian character set.
In most cases, the additional memory use is insignificant.
Question: What SQL Server versions support Sybase Character Sets?
Answer: The character sets and sort orders are supported on any System 10
server. However, code set conversions for these new character sets are only
supported in SQL Server 10.0.2 or later.
Question: What standards were used to create the character sets and sort
orders?
Answer: Character sets are standardized by organizations such as the
International Standards Organization (ISO), national bodies such as the
Arabic Standards and Metrology Organization (ASMO) and the Hellenic
Organisation for Standardization (ELOT), and software vendors. Each
character set description file references the organizational standard or
vendor standard on which it is based.
Performance Tip for Inserts with Non-Unique Clustered Indexes
In order to avoid hotspots on tables, many customers choose a clustered
index that will spread inserts across data pages, instead of adding all of
them on the last page. When this index is non-unique, you can achieve a
significant performance benefit by adding an IDENTITY column to the index
and making it unique.
Example
This example was tested using SQL Server 10.0.2 on an HP9000 E-Series
machine:
create table nu
( spid smallint not null
, something float not null
)
go
create unique clustered index nu_ix on nu (spid, spreader)
go
Two stored procedures were written to insert records.
create proc insert_nu
( @count int)
as
begin
declare @tmp int
select @tmp = 0
while @tmp < @count
begin
insert into nu (spid, something, padding)
values (@@spid, @count, " ")
select @tmp = @tmp + 1
end
end
go
create proc insert_u
( @count int)
as
begin
declare @tmp int
select @tmp = 0
while @tmp < @count
begin
insert into u (spid, something, padding)
values (@@spid, @count, " ")
select @tmp = @tmp + 1
end
end
go
Both tables were populated with 5000 records.
Test #1
One process performing 5000 inserts:
* Non-unique index: 5 minutes, 14 seconds
* Unique index: 12 seconds
Test #2
Two concurrent processes, each performing 5000 inserts:
* Non-unique index:
o Process 1: 9 minutes, 53 seconds
o Process 2: 9 minutes, 42 seconds
* Unique index:
o Process 1: 20 seconds
o Process 2: 21 seconds
How to Read syscolumns.status
Question
How is the status column used in the syscolumns table, what does it mean,
and what are its possible values?
Answer
Here is a sample of output containing syscolumns.status:
1> select name, status from syscolumns where id=object_id("tab1")
2> go
name status
------------------------------ ------
pub_id 0
pub_name 8
city 8
state 8
bio 0
According to the header file that defines syscolumns:
* Bits 0 - 2 indicate bit position in a byte (bit 0 - 7).
o If you have bit columns in your table, as many as 8 of them will
share the same offset, because 8 bits fit in a byte. The status
column lets SQL Server find the actual position of those bits in
that byte.
* Bit 3 is set if NULL is allowed in this column.
o If status contains an 8, this column allows NULL.
* Bit 4 is set if there is more than one check constraint on the column.
o If status contains a 16, this column has more than one check
constraint. SQL Server stores the first check constraint in
syscolumns.domain, but if there's a second one, SQL Server simply
notes that fact by setting the status bit.
Patches Required to Run SQL Server 10.0.2 with DEC OSF/1 Version 3.0
There are two sets of official operating system patches required in order to
run SQL Server 10.0.2 for DEC OSF/1v3.0 (product ID 19555).
You must request these patches from Digital. V3.0 and V3.0b require
different sets of patches. The newly shipped V3.2 does not need any patches.
* DEC patches for V3.0
o OSFV30-068-2
o OSFV30-094-1
* DEC patches for V3.0b
o OSFV305-068-1
o OSFV305-094-1
------------------------------------------------------------------
Note: Patch OSFV30-094-1 (for V 3.0) is required for all
multiprocessor machines, machines running SYBASE database
applications, and all machines using the "ITIMER_VIRTUAL" timer
kernel feature. Without this patch various panics may occur, the
most likely of which is: "simple_lock: time limit exceeded".
The problem happens because multiple Asynchronous System Traps
(AST) functions are mapped to the same bits of the AST dispatch
field in the process control block (PCB). The fix removes the
collision of bit usages for ASTs.
------------------------------------------------------------------
You must rebuild your kernel after installing these patches.
Additional Information for 1605 Workaround
Question
The SQL Server Error Messages manual describes a workaround for Error 1605
that involves an adjustment to cnsocket. After using those instructions, I
got the following error message in the SQL Server error log:
00:95/04/13 19:58:51.91 kernel kiconfig: configured number of
processes (60) is insufficient for kernel disk and network
processes (1032 needed).
What is going on here?
Answer
SQL Server administrators configure SQL Server through the sp_configure
stored procedure and the buildmaster -y mechanism. Many of the parameters in
buildmaster -y are direct copies of parameters displayed by sp_configure.
Some values in buildmaster -y are calculated (cnsocket), while others are
preset "at the factory" (cschedspins).
In certain situations, the values computed for the calculated configuration
values are incorrect and lead to errors during startup or operation of SQL
Server.
For SQL Server to accept a connection it must have:
* An available network socket
* An available "sybase kernel process," also called a "task"
cnsocket defines the maximum number of network sockets SQL Server may have
open at one time. This value is further constrained by the limitations of
the operating system. Each network socket requires a file descriptor from
the operating system. SQL Server automatically sets cnsocket to the maximum
number of file descriptors allowed if you try to set cnsocket to a value
greater than the maximum number of file descriptors allowed.
cnsocket is calculated as:
cnsocket = cusrconnections + cfgsitebuf + XTRA_SOCKETS;
where
* cusrconnections - number of configured user connections
* cfgsitebuf - number of connections reserved for site handlers
* XTRA_SOCKETS - extra connections for utility sorts of things (for
example, network listeners)
cnproc defines the maximum number of SYBASE kernel tasks that can run at a
time. cnproc is calculated as:
cnproc = cnsocket + 6 + (number of network types)
where
* cnsocket - as calculated above
* 6 - magic number; extra processes that do not require network
connections (for example, checkpoint)
* number of network types - number of network listeners
If, during SQL Server startup, cnproc is less than the expected value, you
get the error message shown above.
This means SQL Server will run out of SYBASE kernel tasks (set at 60) before
it runs out of sockets (set at about 1032).
------------------------------------------------------------------
Note: The processes referred to in the SYBASE kernel message above
refer to SYBASE SQL Server kernel processes (tasks), not operating
system processes. Changing the operating system nproc won't solve
the problem.
nproc is not a configuration value in all operating systems, but
is common enough that some may confuse it with cnproc in the
SYBASE configuration. The operating system kernel is not the SQL
Server kernel.
------------------------------------------------------------------
cnsocket and cnproc should be configured to values appropriate for the
number of concurrent connections required in your SQL Server. You are not
expected to set this value, and any calculated value that you set by hand
may be lost if you do a reconfigure command.
Adjusting cnsocket is really a workaround; using buildmaster -ycnsocket
should not actually be necessary. Sybase Technical Support has logged a bug
(#70028) to change the way the "reconfigure" code and the startup code
adjust these parameters.
SYBASE Technical News will keep you informed of any new developments in this
matter.
DBCC LOG with truncate log set Raises Spurious 813 and 605 Errors
As an addendum to the article in SYBASE Technical News, Volume 4, Number 2,
concerning dump transaction failing to truncate the log, customers should be
aware that the use of dbcc log in databases with the dboption truncate log
on checkpoint set can result in spurious 813 and 605 errors.
To avoid this, turn off truncate log on checkpoint before you run dbcc log.
Two New HP Patches for SQL Server 10.0.1
The certification report in SYBASE Technical News, Volume 4, Number 2,
reported under "HP-UX 9.0.4 using LVM with SQL Server 10.0.1," that two
patches were required. These have been superseded, as follows:
* Patch PHKL_3624 has been superseded by PHKL_5139
* Patch PHKL_4418 has been superseded by PHKL_5394
This change is reflected in the current certification report.
Enabling Asynchronous I/O for HP-UX 10.0
Question
I have upgraded to HP-UX 10.0, and wish to enable asynchronous I/O in order
to run SQL Server, but the installasync80 script is only for HP-UX 8 and 9.
Does a script exist for this new version, or must I configure asynchronous
I/O manually?
Answer
You need to order EBF 4605 from Sybase Technical Support. This EBF contains
both a new asynchronous I/O driver, as well as a fix for the problem of the
Backup Server not recognizing non-rewinding tape devices.
Moving Log Off a Device
Question
I need to have one of my users change the device that the log is on, but I
am not sure of the appropriate procedure.
The sysusages looks like this:
1> select * from sysusages where dbid=db_id("user_db")
2> go
dbid segmap lstart size vstart pad unreservedpgs
------ --------- --------- -------- --------- ---- -------------
7 3 0 51200 83887104 NULL 3800
7 3 51200 20480 83963904 NULL 20480
7 4 71680 4096 83984384 NULL 4088
7 4 75776 10240 151006208 NULL 10240
From this it appears that the user built the database as follows:
create database user_db on dev1 = 100,
dev1 = 40
log on dev1 = 8
(using the with override option if using System 10, since in System 10 you
cannot by default create a database with its log on a device that has data
allocation) and then gave the command:
alter database user_db log on dev2 = 20 mb
Answer
The desired end result is not clear. If you simply want to have the log on a
separate device with no change in the amount of allocation for that
database, then follow these steps:
1. Execute sp_dropsegment to get the log segment off dev1.
2. Execute sp_extendsegment to put system and default segments onto the 8
MB of dev1 previously used for the log. You need to do this, because if
there are any pages still allocated for the log on that device, you
will get misleading information from sp_helplog, which checks on the
location of the log's first page.
3. Make some changes within the database, such as an insert of some dummy
records. This puts some log records on at least one page of dev2 which
is now the one and only log device. Note that dev2 is a dedicated log
device, as indicated by the segmap value of 4.
4. Execute dump transaction with truncate_only.
Query to List All Objects and Sizes on a Segment
Question
Is there a way to list all the objects on a segment and the amount of space
they use on that segment by a query against system catalogs?
Answer
Use the following query:
select object=o.name, 'index'= i.indid, segment=s.name,
size=reserved_pgs(i.id, i.doampg) + reserved_pgs(i.id, i.ioampg)
from sysobjects o, syssegments s, sysindexes i
where o.id = i.id
and s.segment = i.segment
order by s.name, o.name, i.indid
compute sum(reserved_pgs(i.id, i.doampg) + reserved_pgs(i.id, i.ioampg))
by s.name
Size is reported by this query in pages; see the "System Functions" section
of Chapter 2, "Transact-SQL Functions", in Volume 1 of the SQL Server
Reference Manual for more details about the reserved_pgs function.
To restrict the query to a given segment or object, add that segment or
object to the where clause. Also, this query does the compute sum by
segment, not by object and segment; to change to by object and segment, add
o.name to the by clause.
------------------------------------------------------------------
Note: Because syslogs (object 8) has no object allocation map
(OAM), the system function reserved_pgs() looks for it explicitly,
and the query as written will return double the actual size of the
log segment. For all other objects, the size value returned by
this query is correct.
------------------------------------------------------------------
How to Read SQL Server Version Strings
Question
The dataserver, backupserver, and isql binaries return version information
when executed with a -v flag. What do the different fields mean? For
example, in UNIX:
/usr/sybase/bin/dataserver -v
SQL Server/4.9.2/EBF 1795 Rollup/Sun_svr4/OS 5.1/1/OPT/Fri Jul 30
20:01:16 PDT 1993
/usr/sybase10/bin/dataserver -v
SQL Server/10.0/P/Sun_svr4/OS 5.2/1/OPT/Thu Sep 23 12:28:52 PDT 1993
/usr/sybase10/bin/backupserver -v
Backup Server/10.0.2.1/P/Sun4/4.1.x/EBF 4009/OPT/Tue Nov 15 14:27:37
PST 1994
/usr/sybase10/bin/isql -v
isql/10.0/P/sun_svr4/Solaris 2.2/1/Mon Aug 30 12:11:43 PDT 1993
Or on VAX:
server :== $sybase_system:[sybase.bin]dataserver.exe
server/version
SQL Server/4.9.2/P/VMS/5.4-1A+/1/OPT/28-JUN-1993 18:37:38.53
Answer
The fields, in order, are:
1. Product
2. Release number
3. Release type: production (P), beta, or EBF version
4. Platform identifier
5. Operating system version under which the binary was compiled. This
number is hard coded; products do not look it up from your OS.
6. "Build number"; a SYBASE internal reference only
7. Mode: optimized or debug
8. Compilation date and time
Generating Templates for Non-interactive Install with ^W
Question
I am installing a large number of identical release 10.x SQL Servers at my
branch offices. What is the easiest way to do this?
Answer
Once you have configured one SQL Server using an interactive sybinit
session, you may dump the attributes out to a file, which you can then edit
to suit each individual site.
Go through a full interactive configuration session using sybinit, so that
each of the nine steps on the screen are marked "Complete":
SQL SERVER CONFIGURATION
1. CONFIGURE SERVER'S INTERFACES FILE ENTRY Complete
2. MASTER DEVICE CONFIGURATION Complete
3. SYBSYSTEMPROCS DATABASE CONFIGURATION Complete
4. SET ERRORLOG LOCATION Complete
5. CONFIGURE DEFAULT BACKUP SERVER Complete
6. CONFIGURE LANGUAGES Complete
7. CONFIGURE CHARACTER SETS Complete
8. CONFIGURE SORT ORDER Complete
9. ACTIVATE AUDITING Complete
At this prompt:
Enter the number of your choice and press return:
type Ctrl-w, and the prompt line will change to look like this:
Enter the number of your choice and press return: Dump out current attributes?y
"y" is the default, so just hit return, and you'll be prompted for a file
name; you can either enter a new one or accept the default.
Once you have this resource file, consult Appendix A, "sybinit Resource
Files", of the SYBASE SQL Server Installation Guide for your platform, for
information on how to use it for future, non-interactive installations. You
will need to edit some of the attributes, as the appendix instructs.
Generate a second resource file for your Backup Server(™), if you wish
to handle Backup Server installation similarly.
Optimizer Frequently Asked Questions
Question
I've heard that the optimizer works out the cost, on the fly, of actually
producing the best plan, as well as the cost of getting the data. Once the
cost of actually working out the best plan becomes greater than the cost of
performing the data access from the best plan found so far, it stops
optimizing.
Therefore, if it costs the optimizer 1 CPU second to determine that a given
plan will require 1/2 CPU second, it stops optimizing, since 1 is bigger
than 1/2, even though a plan it hadn't yet analyzed might require only 1/4
CPU second.
Is this true?
Answer
The SYBASE optimizer does not work like this, though a competitor's does.
There are very good reasons not to optimize this way:
* Queries that are in stored procedures and triggers get optimized once
and executed many times. For example:
1. Optimizer takes 1 second to find best query plan, which takes 0.1
seconds to execute.
2. Optimizer takes 1/2 second to find a sub-optimal query plan, which
takes 1/2 second to execute. Scenario 1 will take 1.1 seconds if
it is executed once, while scenario 2 will take 1 second. But if
the query is in a stored procedure that is executed 1000 times,
scenario 1 will take 101 seconds, while scenario 2 will take 500.5
seconds.
* The competitor's method limits the time the optimizer spends analyzing
different query plans depending on the load on the server and the
machine. If the machine is heavily loaded, the optimization process
takes longer and looks at fewer query plans before giving up. Thus, the
heavier the load, the worse the query plan, which is exactly the
opposite of what you want.
Question
Isn't it the case that, once the number of tables in a join exceeds four,
the optimizer starts taking short cuts and will not evaluate all the
possible plans? If so, is it a good idea to write my query with the
"driving" tables first, when a query has a large number of joins?
Answer
Changing the order of the tables in the from clause will normally have no
effect on the query plan.
When you have more than four tables in the from clause, the optimizer will
optimize each subset of four tables. Then it remembers the outer table from
the best plan involving four tables, eliminates it from the set of tables in
the from clause, and optimizes the best set of four tables taken out of the
remaining tables. It continues with this until there are only four tables
remaining, at which point it optimizes those four tables normally.
For example, suppose you have a select with the following from clause:
FROM T1, T2, T3, T4, T5, T6
The optimizer looks at all sets of four tables taken from these six tables.
The sets are:
T1, T2, T3, T4
T1, T2, T3, T5
T1, T2, T3, T6
T1, T2, T4, T5
T1, T2, T4, T6
T1, T2, T5, T6
T1, T3, T4, T5
T1, T3, T4, T6
T1, T3, T5, T6
T1, T4, T5, T6
T2, T3, T4, T5
T2, T3, T4, T6
T2, T3, T5, T6
T2, T4, T5, T6
T3, T4, T5, T6
For each one of these combinations, it looks at all the join orders
(permutations). For example, the join orders for T2, T3, T5, T6 are:
T2, T3, T5, T6
T2, T3, T6, T5
T2, T5, T3, T6
T2, T5, T6, T3
T2, T6, T3, T5
T2, T6, T5, T3
T3, T2, T5, T6
T3, T2, T6, T5
T3, T5, T2, T6
T3, T5, T6, T2
T3, T6, T2, T5
T3, T6, T5, T2
T5, T2, T3, T6
T5, T2, T6, T3
T5, T3, T2, T6
T5, T3, T6, T2
T5, T6, T2, T3
T5, T6, T3, T2
T6, T2, T3, T5
T6, T2, T5, T3
T6, T3, T2, T5
T6, T3, T5, T2
T6, T5, T2, T3
T6, T5, T3, T2
The optimizer remembers the best of all the join orders, for all the
combinations. Let's say that the best join order is:
T5, T3, T6, T2
Once the optimizer has figured this out, it remembers the outer table of
this join order (T5) as the outermost table in the whole query. It
eliminates this table from consideration as it chooses the rest of the join
order. Now it has to decide where T1, T2, T3, T4, and T6 will go in the rest
of the join order. It looks at all the combinations of four tables chosen
from these five:
T1, T2, T3, T4
T1, T2, T3, T6
T1, T2, T4, T6
T1, T3, T4, T6
T2, T3, T4, T6
It looks at all the join orders for each of these combinations. It remembers
that T5 is the outer table in the join when it makes this decision. Let's
say that the best join order is T3, T6, T2, T4. It remembers T3 as the next
table after T5 in the join order for the entire query, and eliminates it
from consideration as it chooses the rest of the join order. The remaining
tables are:
T1, T2, T4, T6
Now there are only four tables, so it looks at all the join orders for all
the remaining tables. Let's say the best join order is:
T6, T2, T4, T1
This means that the join order for the entire query is:
T5, T3, T6, T2, T4, T1
Note that the four outermost tables are not the first four tables in the
from clause. As you can see, even though the optimizer looks at the join
orders for only four tables at a time, doing this for all combinations of
four tables taken out of the from clause makes the order of tables in the
from clause irrelevant.
There is only one known circumstance in which the order of tables in the
from clause can make any difference: if the optimizer comes up with the same
cost estimate for two join orders, it will choose the first of the two join
orders that it encounters. The order of tables in the from clause affects
the order in which the optimizer evaluates the join orders, so in this one
case, table order can have an effect on the query plan.
Currently Supported Backup Server Devices
As of April 26, 1995, the following devices are supported by Backup Server:
------------------------------------------------------------------
Note: this article has been removed from the Web version of
Technical News in favor of your checking out this much more
frequently-updated table provided by Lance Andersen.
------------------------------------------------------------------
MS Access Errors with Intersolv Sybase System 10 ODBC Driver
Question
I'm using the Intersolv Sybase System 10 ODBC driver with a Windows PC
client. When I try to set up a new data source, edit an existing one, or
edit a connection to a database within Microsoft Access, I get the following
error:
The setup routines for the INTERSOLV Sybase System 10 ODBC driver could
not be loaded. You may be low on memory and need to quit a few
applications.
What can I do?
Answer
This error is misleading. It doesn't usually have anything to do with
memory, but instead happens when wsybset.bat has not been run. wsybset.bat
sets up the correct paths to the Sybase 10.0.x Open Client (™) Dynamic
Load Libraries (DLL) wcslib.dll and wctlib.dll.
It can also happen if the path to the ODBC driver, QESYB06.dll, is not set
up. This is because when the ODBC driver gets set up, it sets a DLL name in
the odbc.ini file for the control panel application to use. Then, when
Windows tries to load the DLL, it fails if the program or any DLLs needed by
that program cannot be loaded. Lack of memory can cause this, as the message
suggests, or it can occur because Windows cannot find one or more of the
DLLs.
Windows looks for DLLs by searching the current directory, then the
WINDOWS/SYSTEM directory, and finally the path. If either the SYBASE DLL
directory or the Intersolv DLL directory is not in the path, you will see
this message.
Refer to your operating system manual for further instructions on how to set
paths.
Workaround for non-char NULLs in OmniSQL Server
Question
I have a problem with OmniSQL Server(™). I'm going to DB2, but the
problem could appear for any source. Omni SQL Server, as it is based on
C-ISAM files, does not support NULLs for anything other than character
fields. So this query:
SELECT mydatefield FROM mytable
produces correct answers, but this one:
SELECT mydatefield FROM mytable ORDER BY ...
produces the value of "1 Jan 1900" for any NULL dates. The difference is
that OmniSQL Server is producing a worktable (in C-ISAM) to perform the
order by. Is there a workaround for this?
Answer
Yes. You must create an Open Server(™) gateway that sits in front of
Omni. The client's requests are passed up to OmniSQL Server unchanged, but
any "1/1/1900" dates are changed to NULL on the way back down.
This workaround will be unnecessary when OmniCONNECT release 10.5 (formerly
known as OmniSQL Server) is available, because at that point Sybase plans to
replace C-ISAM with SQL Server-style storage structures.
The code for this Open Server is easily produced. Add the following code to
the gateway Open Server sample file, $SYBASE/sample/srvlibrary/ctosdemo.c,
to the row processing in gw_procrows() (about line 4297):
if((fmtp[i].datatype == CS_DATETIME_TYPE) &&
(fmtp[i].status & CS_CANBENULL ) )
{
if (0==dp[i][0])
if (0==dp[i][1])
if (0==dp[i][2])
if (0==dp[i][3])
if (0==dp[i][4])
if (0==dp[i][5])
if (0==dp[i][6])
if (0==dp[i][7])
ind[i]=CS_NULLDATA;
}
if((fmtp[i].datatype == CS_DATETIME4_TYPE) &&
(fmtp[i].status & CS_CANBENULL ) )
{
if (0==dp[i][0])
if (0==dp[i][1])
if (0==dp[i][2])
if (0==dp[i][3])
ind[i]=CS_NULLDATA;
}
The code could be extended in many ways, for example to perform srv_props()
for NUM_CONNECTIONS and other variables.
Note that this code does not handle NULLable numeric values.
Dynamic Parameter Markers in Embedded SQL
The following addition will shortly be appearing in the Release Bulletin for
all Embedded SQL products:
When processing an Embedded SQL query, SQL Server determines the datatype of
each dynamic parameter marker by examining the marker's context-where the
marker is used in the query. An Embedded SQL query must not contain a
dynamic parameter marker in a position that can cause SQL Server to
determine that the marker's datatype is text or image.
Bug 69427 - sp_rename Syntax
If you have both a table column and an index with the same name, and execute
the command sp_rename `table.column/index', newname, sp_rename will always
rename the column. You cannot rename the index directly in this case.
This problem, that the syntax is the same for renaming a column or index,
has been filed as bug 69427; SYBASE Technical News will keep you abreast of
its progress.
Bugs 31229 and 58701 - sp_addmessage
Two bugs have recently been reported against sp_addmessage:
Bug 31229
If you specify us_english as the language parameter to sp_addmessage, the
langid column of sysusermessage gets set to NULL. A later retrieval via
sp_getmessage without a language specified (where the session is using
us_english) fails to find the message.
The problem is that there are two legal values for langid that represent
us_english: 0 and NULL. @@langid will always return 0, while sp_addmessage
and sp_getmessage set langid to NULL if the user specified us_english
directly to the procedure.
Bug 58701
A related problem reported under bug 58701 resulted in a change to the
procedure sp_addmessage for the 10.0.2 maintenance release.
The problem is that sp_addmessage inserts a value of 0 into langid instead
of NULL when using us_english.
Apparently the change required to fix this bug has caused bug 31229 to
appear again. If a message is added with sp_addmessage and no language is
specified, later attempts to get that message with sp_getmessage will fail
with error 17202, "Message number nn does not exist in the language
language."
To work around these bugs, manually update rows in sysusermessages, setting
langid values from NULL to 0.
SQL Server release 4.9.2 - EBFs 4152 and 4659 and Bugs 54367 and 68128
Some customers have encountered problems on SQL Server 4.9.2 that can be
resolved by the fix for bug 54367. This fix has been released in two
different modes, however, which may confuse some customers. A customer who
received EBF 4152 in order to obtain the fix for bug 54367 may find the EBF
4659 seems to no longer address the problem. Here's why:
EBF 4152 (and related EBFs for non-Sun4 platforms) was a recent 4.9.2
rollup, containing a fix for bug 54367. For reasons unrelated to this bug
fix, shipment was stopped for EBF 4152.
EBF 4659 is the replacement EBF for the 4152 rollup. It also contains a fix
for bug 54367-but this fix is not identical to the fix in EBF 4152. The
difference between the two fixes is that, with EBF 4659, trace flag 299 must
be turned ON in order to activate the fix. This feature was added to EBF
4659 under the fix for bug 68128. If this trace flag is not turned on, EBF
4659 behaves just like all pre-4152 releases of the 4.9.2 codeline (except
for a few EBFs that contain a fix for bug 54367).
You should find similar behavior in the following cases:
* EBF 4152
* EBF 4659 with trace flag 299 turned on
At this time, there is no plan to modify the 4.9.2 codeline to apply the fix
for bug 54367 without invoking trace flag 299, because this fix also incurs
a small, but possibly significant, amount of processing overhead. Since most
customers do not require this fix, Sybase decided to make application of the
fix optional, and to put control over whether or not it is applied in the
customer's hands, with a trace flag.
------------------------------------------------------------------
Note: A problem similar to bug 54367 was reported against System
10 under bug 55952. A fix for this problem is contained in the
10.0.2 release. An additional fix has been made recently to the
System 10 codeline to mitigate some of the performance and
contention problems caused by the fix for bug 55952. This problem
and fix is reported under bug 65416. There is no 299 trace flag in
the System 10 releases. The fixes are always active.
------------------------------------------------------------------
Connectivity Documentation Corrections
Embedded SQL Documentation Bugs
* 48379: The Open Client Embedded SQL Reference Manual now indicates that
the parameter list for the statement declare cursor for execute
stored_procedure must be enclosed in parentheses. The correct syntax
is:
exec sql
declare cursor_name cursor for
execute procedure_name ([[@param =]:hv]
[,[@param =]:hv]...)
* 49230: In the Open Client Embedded SQL Reference Manual, the SET
DESCRIPTOR example has been corrected: The lines beginning "value 1,"
"value 2," and "value 3" were previously inverted. They now read as
follows:
exec sql prepare get_royalty
from "select royalty from roysched
where title_id = ? and lorange <= ? and
hirange > ?";
exec sql allocate descriptor roy_desc with max 3;
exec sql set descriptor roy_desc
value 1 data = :tid;
exec sql set descriptor roy_desc
value 2 data = :sales;
exec sql set descriptor roy_desc
value 3 data = :sales;
exec sql execute get_royalty into :royalty
using sql descriptor roy_desc;
* 53686: In the Open Client Embedded SQL Reference Manual, a misspelled
keyword has been corrected in two commands-declare cursor(dynamic) and
declare cursor(static). The correct spelling is "read only" (two words,
instead of one).
* 57291: In Table 2-3 of the Open Client Embedded SQL Reference Manual,
each value under the heading "CLIENT-LIBRARY CODE" has been decremented
by one. That is, -8 is now -9; -9 is now -10, and so on. (Note: The
values under the heading "CODE" are not affected.)
That part of the table is now as follows:
SYBASE-DEFINED DATATYPECLIENT-LIBRARY CODE
smalldatetime -9
money -10
smallmoney -11
text -3
image -4
tinyint -8
binary -5
varbinary -6
longbinary -7
longchar -2
* 56472: On page 6-17 of the Open Client Embedded SQL/COBOL Guide, the
code fragment now reads:
exec sql include "myfile" end-exec.
The argument "myfile" must be enclosed in quotation marks.
* 52189: In the Open Client Embedded SQL/C Guide and Open Client Embedded
SQL/COBOL Guide, the cancel statement has been added to the list (p.
1-7) of Embedded SQL statements not supported in System 10.
* 59348: In the Open Client Embedded SQL/C Guide and Open Client Embedded
SQL/COBOL Guide, the descriptions of the sqlwarn flags (capitalized
SQLWARN in COBOL) have been corrected.
The sqlwarn (SQLWARN) flags are as follows:
sqlwarn SQLWARN
Flag, C Flag, Cobol Description
If blank, no warning condition of any kind
occurred, and all other sqlwarn flags are
sqlwarn[0] SQLWARN[1] blank. If sqlwarn[0](C) or SQLWARN[1](Cobol)
is set to "W", one or more warning
conditions occurred, and at least one other
flag is set to "W".
If set to "W", the character string variable
that you designated in a fetch statement was
too short to store the statement's result
sqlwarn[1] SQLWARN[2] data, so the result data was truncated. You
designated no indicator variable to receive
the original length of the data that was
truncated.
If set to "W", the input sent to SQL Server
contained a NULL value in an illegal
sqlwarn[2] SQLWARN[3] context, such as in an expression or as an
input value to a table that prohibits null
values.
The number of columns in a select
sqlwarn[3] SQLWARN[4] statement's result set exceeds the number of
host variables in the statement's into
clause.
sqlwarn[4] SQLWARN[5] Reserved.
sqlwarn[5] SQLWARN[6] SQL Server generated a conversion error
while attempting to execute this statement.
sqlwarn[6] SQLWARN[7] Reserved.
sqlwarn[7] SQLWARN[8] Reserved.
Client-Library Documentation Bugs
* 67847: The Open Client Client-Library/C Reference Manual gives the
following misleading and incorrect statement in the "Security Features"
topics pages, under the heading, "Encrypted Password Security
Handshakes":
"Most applications are not aware of SQL Server's password
encryption because Client-Library automatically handles it."
The "Properties" topic page, under "Security Encryption
(CS_SEC_ENCRYPTION", will now say:
"Applications which require password encryption must enable
the CS_SEC_ENCRYPTION connection property. The default is
CS_FALSE, which disables password encryption."
For most applications, this is all that is required for password
encryption-Client-Library has a default handler that performs the
encryption expected by SQL Server.
Applications in the following categories need to define and install an
encryption handler (in addition to setting the property) to perform
password encryption:
o Open Server gateways
o Clients which connect to an Open Server application that performs
some customized form of password encryption
The code fragment below enables password encryption:
CS_BOOL boolval;
/*
** Enable password encryption for the connection
** attempt.
*/
boolval = CS_TRUE;
if (ct_con_props(conn, CS_SET,
CS_SEC_ENCRYPTION,
(CS_VOID *)&boolval,
CS_UNUSED,(CS_INT *)NULL)
!= CS_SUCCEED)
{
fprintf(stdout,
"ct_con_props(SEC_ENCRYPTION) failed. Exiting\n"
);
(CS_VOID)ct_con_drop(conn);
(CS_VOID)ct_exit(ctx, CS_FORCE_EXIT);
(CS_VOID)cs_ctx_drop(ctx);
exit(1);
}
An example gateway encryption handler can be found in the Open Server
sample program ctosdemo.c.
* 66733: The issue of dynamic SQL vs. stored procedures has been
clarified with an example. The Open Client Client-Library/C Reference
Manual, in the "Dynamic SQL" topic page section, "Alternatives to
Dynamic SQL," will include the following updated information:
Dynamic SQL and application stored procedures offer identical
functionality except that:
o Stored procedures offer no direct means to get a description of
input parameter formats. Dynamic SQL allows the application to
request a description of prepared statement input from the remote
server.
o Stored procedures offer no direct means to get a description of
their output, unless you execute them and incur any side effects.
o Stored procedures are not automatically dropped when their creator
logs off the remote server. Prepared dynamic SQL statements
created within a SQL Server login session are automatically
deallocated at the end of the session.
They offer identical functionality in that any prepared dynamic SQL
statement can be implemented as a stored procedure which returns the
same set of results (plus the procedure return status result). For
example, the following dynamic SQL statement queries the pubs2..titles
table for books of a certain type in a certain price range:
select * from titles
where type = ?
and price between ? and ?
Here, the dynamic SQL statement has dynamic parameter markers (?) for a
type value and two price values. An equivalent stored procedure could
be created as follows:
create proc titles_type_pricerange
@type char(12),
@price1 money,
@price2 money
as
select * from titles
where
type = @type
and price between @price1 and @price2
When executed with the same input parameter values, the prepared
statement and the stored procedure will return the same rows. In
addition, the stored procedure will return a return status result.
* 60116: Documentation has been added to state that Client-Library cannot
be run in asynchronous mode inside an Open Server, only in synchronous
or deferred mode. The Open Client Client-Library/C Reference Manual
"Properties" topic page, under "Network I/O (CS_NETIO)," and the
"Asynchronous Programming" topic page, will include the following
information (The Open Server Server-Library/C Reference Manual already
notes the fact in the "Gateway Applications" topic page):
The CS_NETIO property cannot be set to CS_ASYNC_IO when
Client-Library is used with Open Server. Open Server is
multi-threaded and the thread scheduler provides concurrency
among multiple threads.
* 66860: Documentation has been added to show how ct_cursor can be used
to execute a stored procedure containing only one statement, a select.
It is not possible to get return status. The Open Client
Client-Library/C Reference Manual, ct_cursor Reference Page, section
"Client-Library Cursor Declare," will include the following
information:
Here's an example of creating a Client-Library execute
cursor. Please note the restrictions listed below the
example.
The following pseudocode declares an execute cursor on the
stored procedure title_cursor_proc:
ct_cursor (cmd, CS_CURSOR_DECLARE,
"mycursor", CS_NULLTERM,
"exec title_cursor_proc", CS_NULLTERM,
CS_UNUSED);
ct_send(cmd);
In this case, the body of the cursor is the text that makes
up the stored procedure. The stored procedure text must
contain a single select statement only. In the example above,
title_cursor_proc could be created as:
create proc title_cursor_proc as
select * from titles for read only
A stored procedure used with an execute cursor must consist
of a single select statement. The stored procedure's return
status is not available to the client program. Output
parameter values are also not available to the client
program.
* 59290: Documents now clarify that ct_options(CS_OPT_GETDATA) should not
be used. The Open Client Client-Library/C Reference Manual, "Options"
topic page and ct_options reference page, will include the following
updated information:
Don't use ct_options(CS_OPT_GETDATA). This option is for
Sybase internal use only.
* 70692: The Open Client Client-Library/C Reference Manual, "Properties"
topic page, section "Cursor Status" (CS_CUR_STATUS) and ct_cmd_props()
reference page, will include the following updated information:
The CS_CUR_STATUS property value is either:
o CS_CURSTAT_NONE to indicate no cursor exists on the
command structure.
or
o A bit-masked status value for an existing cursor. The
value is composed of the status bit-masks
CS_CURSTAT_CLOSED, CS_CURSTAT_DECLARED,
CS_CURSTAT_RDONLY, CS_CURSTAT_UPDATEABLE.
The meanings of these are correctly described under "Cursor
Status" in the "Properties" topic page.
The following code fragment illustrates use of the cursor
status property to display the status of the Client-Library
cursor (if any) declared on a command structure:
#define RETURN_IF(a,b) if (a != CS_SUCCEED)\
{ fprintf(stderr, "Error in: %s line %d\n", \
b, __LINE__); return a ;}
/*
** cursor_status() -- Print status information about the
** Client-Library cursor (if any) declared on a CS_COMMAND
** structure.
**
** PARAMETERS:
** cmd -- an allocated CS_COMMAND structure.
**
**
** RETURNS
** CS_FAIL if an error occurred.
** CS_SUCCEED if everything went ok.
*/
CS_RETCODE
cursor_status(cmd)
CS_COMMAND *cmd;
{
CS_RETCODE ret;
CS_INT cur_status;
CS_INT cur_id;
CS_CHAR cur_name[CS_MAX_NAME];
CS_CHAR updateability[CS_MAX_NAME];
CS_CHAR status_str[CS_MAX_NAME];
CS_INT outlen;
/*
** Get the cursor status property.
*/
ret = ct_cmd_props(cmd, CS_GET, CS_CUR_STATUS, &cur_status,
CS_UNUSED, (CS_INT *) NULL);
RETURN_IF(ret, "cursor_status: ct_cmd_props(CUR_STATUS)");
/*
** Is there a cursor?
** Note that CS_CURSTAT_NONE is not a bit mask, but the
** other values are.
*/
if (cur_status == CS_CURSTAT_NONE)
fprintf(stdout,
"cursor_status: no cursor on this command structure\n");
else
{
/*
** A cursor exists, so check its state. Is it
** declared, opened, or closed?
*/
if ((cur_status & CS_CURSTAT_DECLARED)
== CS_CURSTAT_DECLARED)
strcpy(status_str, "declared");
if ((cur_status & CS_CURSTAT_OPEN) == CS_CURSTAT_OPEN)
strcpy(status_str, "open");
if ((cur_status & CS_CURSTAT_CLOSED) == CS_CURSTAT_CLOSED)
strcpy(status_str, "closed");
/*
** Is the cursor updateable or read only?
*/
if ((cur_status & CS_CURSTAT_RDONLY) == CS_CURSTAT_RDONLY)
strcpy(updateability, "read only");
else if ((cur_status & CS_CURSTAT_UPDATABLE)
== CS_CURSTAT_UPDATABLE)
strcpy(updateability, "updateable");
else
updateability[0] = '\0';
/*
** Get the cursor id.
*/
ret = ct_cmd_props(cmd, CS_GET, CS_CUR_ID, &cur_id,
CS_UNUSED, (CS_INT *) NULL);
RETURN_IF(ret, "cursor_status: ct_cmd_props(CUR_ID)");
/*
** Get the cursor name.
*/
ret = ct_cmd_props(cmd, CS_GET, CS_CUR_NAME, cur_name,
CS_MAX_NAME, &outlen);
RETURN_IF(ret, "cursor_status: ct_cmd_props(CUR_NAME)");
/*
** Null terminate the name.
*/
if (outlen < CS_MAX_NAME)
cur_name[outlen] = '\0';
else
RETURN_IF(CS_FAIL, "cursor_status: name too long");
/* Print it all out */
fprintf(stdout, "Cursor '%s' (id %d) is %s and %s.\n",
cur_name, cur_id, updateability, status_str);
}
return CS_SUCCEED;
} /* cursor_status */
CS-Library Documentation Bug
* 64520: The documentation and examples for callback error handling have
been improved. The Common Libraries Reference Manual chapter,
"Introducing CS-Library" and the cs_config reference page, will include
the following information:
Here is a CS-Library error handler:
/*
** cslib_err_handler() - CS-Library error handler.
**
** This routine is the CS-Library error handler used by this
** application. It is called by CS-Library whenever an error
** occurs. Here, we simply print the error and return.
**
** Parameters:
** context
** A pointer to the context handle for context
** in which the error occurred.
** error_msg
** The structure containing information about the
** error.
**
** Returns:
** CS_SUCCEED
*/
CS_RETCODE CS_PUBLIC cslib_err_handler(context, errmsg)
CS_CONTEXT *context;
CS_CLIENTMSG *errmsg;
{
/*
** Print the error details.
*/
fprintf(stdout, "CS-Library error: ");
fprintf(stdout, "LAYER = (%ld) ORIGIN = (%ld) ",
CS_LAYER(errmsg->msgnumber),
CS_ORIGIN(errmsg->msgnumber) );
fprintf(stdout, "SEVERITY = (%ld) NUMBER = (%ld)\n",
CS_SEVERITY(errmsg->msgnumber),
CS_NUMBER(errmsg->msgnumber) );
fprintf(stdout, "\t%s\n", errmsg->msgstring);
/*
** Print any operating system error information.
*/
if( errmsg->osstringlen > 0 )
{
fprintf(stdout, "CS-Library OS error %ld - %s.\n",
errmsg->osnumber, errmsg->osstring);
}
/*
** All done.
*/
return (CS_SUCCEED);
} /* cslib_err_handler */
Here is the code to install it:
/*
** Install the function cslib_err_handler as the
** handler for CS-Library errors.
*/
if (cs_config(context, CS_SET, CS_MESSAGE_CB,
(CS_VOID *)cslib_err_handler,
CS_UNUSED, NULL)
!= CS_SUCCEED)
{
/* Release the context structure. */
(void)cs_ctx_drop(context);
fprintf(stdout,
"Can't install CS-Lib error handler.\
Exiting.\n");
exit(1);
}
The error severities are the same as those explained in the Open Client
Client-Library/C Reference Manual, on the "Client-Library Messages"
topic page.
Bulk Library Documentation Bugs
* 69977: The documentation has been clarified to specify that only one
CS_BLKDESC or one CS_COMMAND can be active on a connection at one time.
The Common Libraries Reference Manual, blk_init reference page, will
say:
Multiple CS_BLKDESC and CS_COMMAND structures can be exist on
the same connection, but only one CS_BLKDESC or CS_COMMAND
structure can be active at once.
o A bulk-copy operation begun with blk_init must be
completed before the connection can be used for any
other operation.
o A bulk-copy operation can not be started when the
connection is being used to initiate, send, or process
the results of other Client-Library or Bulk-Library
commands.
* 69153: Documentation has been added on how Bulk Library errors are
handled. The Common Libraries Reference Manual chapter, "Introducing
Bulk Copy", will say:
Bulk-Library errors are reported as Client-Library errors for
Client-Library bulk-copy routines and as Server-Library
errors for Server-Library bulk-copy routines. Server-Library
routines are those routines that take a SRV_PROC pointer as
an argument.
Client applications should handle Bulk-Library errors by
installing a Client-Library error handler or handle them
inline with ct_diag(). Applications should also install a
remote server message handler, because errors detected by the
SQL server will be reported as server messages.
To handle Bulk-Library errors, Open Server gateway
applications should install a Server-Library error handler in
addition to the handlers listed above.
EBF News
The following tables list the latest rollup numbers for SQL Server 4.9.2 and
10.x on selected platforms, and selected bugs fixed in them.
Latest Rollups for SQL Server 4.9.2
Platform Rollup Number
SunOS Release 4.x (BSD) 4659
HP 9000 Series 800 HP-UX 4660
IBM RISC System/6000 AIX 4661
AT&T System 3000 UNIX SVR4 MPRAS 4662
Digital OpenVMS VAX 4663
Sun Solaris 2.x 4664
Digital OpenVMS Alpha 1.5 4665
Digital OpenVMS Alpha 1.0 2121
Bugs Fixed in Latest Rollup, SQL Server 4.9.2
This list is additive, that is, only the bugs fixed in the latest series of
rollups are included. Please see SYBASE Technical News, Volume 4, Number 1,
for the list of earlier bugs fixed.
Bug
Number Description
Reverse the behavior of 299 trace flag (trigger recompilation of
68128 stored procedures) for temporary table schema changes only if
command line trace flag 299 is set.
The "dbqual" in DB-Library returns NULL for where clause in
browse mode, because SQL Server sends the wrong table number in
67868 the TDS stream. This could cause data inconsistency because
update/insert might affect the wrong rows due to a NULL where
clause.
Subquery in select list raises multiple results instead of
54376 raising an error (depending on if this is deemed a legal syntax,
docs aren't clear) that either the subquery in the select list
is illegal or Error 512 (multiple results).
Latest Rollups for SQL Server 10.0.2
Platform Rollup Number
SunOS Release 4.x (BSD) 4009
HP 9000 Series 800 HP-UX 4010
IBM RISC System/6000 AIX 4011
AT&T System 3000 UNIX SVR4 MPRAS 4012
Digital OpenVMS VAX 4013
Sun Solaris 2.x 4014
Digital OpenVMS Alpha 1.5 4015
Digital OSF/1 4019
NetWare none
OS/2 none
Windows NT 4996
Bugs Fixed in Latest Rollup, SQL Server 10.x
There has been no change in this list since SYBASE Technical News, Volume 4,
Number 1.
----------------------------------------------------------------------------
Disclaimer: No express or implied warranty is made by SYBASE or its
subsidiaries with regard to any recommendations or information presented in
SYBASE Technical News. SYBASE and its subsidiaries hereby disclaim any and
all such warranties, including without limitation any implied warranty of
merchantability of fitness for a particular purpose. In no event will SYBASE
or its subsidiaries be liable for damages of any kind resulting from use of
any recommendations or information provided herein, including without
limitation loss of profits, loss or inaccuracy of data, or indirect special
incidental or consequential damages. Each user assumes the entire risk of
acting on or utilizing any item herein including the entire cost of all
necessary remedies.
Staff
Principal Editor: Leigh Ann Hussey
Contributing Writers:
Lance Andersen, Perry Bent, Chris Curvey, Sandra Dellafiora, Jennifer Doman,
Peter Dorfman, Roy Halbreich, Dan Haywood, Marcus Jordan, Greg Klinder, Jeff
Lichtman, Rosemary Morrison, Greg Roody, Marc Sugiyama, Loretta Vibberts,
Rob Weaver, Robert Weeks, Elizabeth Whitehouse, Elton Wildermuth
For more info send email to tech...@sybase.com
Copyright 1995 © Sybase, Inc. All Rights Reserved.
Q10.2.4
Technical News Volume 4, Number 4, November 1995
This issue of SYBASE Technical News contains new information about your
SYBASE software. If needed, duplicate this newsletter and distribute it to
others in your organization. All issues of SYBASE Technical News and the
troubleshooting guides are included on the AnswerBase CD.
To receive this document by regular email, send name, full internet address
and customer ID to tech...@sybase.com.
IN THIS ISSUE
* Tech Support News/Features
o Technical Support Holiday Schedule for Q4 `95
* SQL Server
o System 11 Subquery Processing Performance Improvements
o Tuning to Prevent Time-Slice Errors
o 605 Errors on load database master
o System Database Recovery in System
o Understanding sysusages.unreservedpgs
o Understanding Spinlocks
o Patches for Hard / Transient 605 Errors on HP
* Connectivity / Tools / PC
o Localization Problems and cs_ctx_alloc Failure
o End-of-Life Plan for APT and DWB
* Certification and Fixed Bug Reports
o Mainframe EBF Information
o Net-Gateway EBF Information
o Bug 69332: Timeslice Disables Automatic Checkpoint and waitfor
Command
Technical Support Holiday Schedule for Q4 `95
Sybase Technical Support is open on all holidays and provides full service
on many holidays. On the holidays shown below, Technical Support provides
limited service. During limited-service holidays, the following Technical
Support coverage will be provided:
* SupportPlus Preferred and Advantage Customers may log all cases;
priority 1 and 2 cases will be worked on over the holiday.
* 24x7 and 24x5 Support Customers may log priority 1 (down server) cases
which will be worked on over the holiday.
* SupportPlus Standard, Desk Top, and Regular Support Customers may
purchase Extended-hour Technical Support for coverage over the holiday.
Sybase Technical Support
limited-service holidays - U.S.
customers
Holiday Date
Labor Day September 4
Thanksgiving November 23
Christmas December 25
Sybase Technical Support
limited-service holidays - Canadian
customers
Holiday Date
Labour Day September 4
Canadian Thanksgiving October 9
Christmas Day December 25
Boxing Day December 26
System 11 Subquery Processing Performance Improvements
For System 11, the query processor was substantially rewritten, in order to
meet the following goals:
* Solve subquery performance problems in System 10(TM)
* Solve subquery correctness problems in System 10
* Maintain compatibility with existing views and procedures
System 10 Performance Issues
System 10 used two subquery processing strategies, "inside-out" and
"unnest." In the "inside-out" strategy, SQL Server(TM) built the subquery
result set first, then joined it with the outer query. In the "unnest"
strategy, SQL Server changed the subquery to an existence join. The
following performance issues existed as a result of these strategies:
* The "inside-out" processing strategy gave good throughput (length of
time it takes SQL Server to get to the last row of a query), but poor
response time (length of time it takes SQL Server to return the first
row of a query).
* "Inside-out" processing required two joins: one to form the subquery
result and one for the outer result.
* If there was a restrictive join in an outer query, the result set for a
subquery could be bigger than necessary.
* Internal use of the group by all clause forced an extra pass over the
grouping table.
* A join with a subquery result could not be optimized if the subquery
was part of an or clause, because of the resulting cartesian product.
System 10 Correctness Issues
There were several known problems in System 10 having to do with nulls,
empty tables, and duplicates, none of which were easy to fix under the
"inside-out" system.
Problems Solved by System 11
In System 11, subqueries are now modeled as nested loops, which has the
added advantage of matching the ISO/ANSI definition of subqueries. Some
unnesting can take place, in the form of flattening to joins and
materialization. Unflattened subqueries are treated as expressions in this
system.
There is no need to build the entire subquery result set up front; subquery
results are only calculated when necessary, so that there is no more
assembling of subquery results that end up not being used. Likewise, there
is no longer a need to join subquery results back to the outer query. All of
this results in better response time.
A few other features also improve performance:
* Quantified predicates no longer use group by all
* Subqueries in or clauses no longer use non-optimized joins
* Some not in and all subqueries are optimized better
Correctness problems also go away with the new system, because the
processing closely matches the ANSI-standard SQL definition.
Performance Enhancements
The new system uses several performance enhancements:
* "Short circuiting"
In "short circuiting," evaluation of and lists stops early if any part
is false, and evaluation of or lists stops early if any part is true.
where clauses are automatically shuffled to put the subquery at the
end, forestalling unnecessary execution of subqueries. For example, the
following query:
select a from t
where NOT EXISTS
(select * from s
where b=t.c)
AND d=2
is transformed to:
select a from t
where d=2
AND NOT EXISTS
(select * from s
where b=t.c)
In this case, the subquery will not execute for rows in t where d is
not equal to 2.
* Better flattening
* More efficient materialization
* Caching
An in-memory cache is used for subqueries that are not flattened or
materialized. This cache stores the result values for previous
executions of the subquery; values in the correlation columns of
subsequent executions are used as look-up keys for the cache. The cache
starts off big and shrinks to the appropriate size depending on the
cache hit rate. Caching improves performance in cases where there are
duplicates in correlation columns, especially when the values are
ordered.
* Elimination of sort for distinct expression queries
In System 10, select distinct subqueries forced SQL Server to perform a
sort step to eliminate duplicates; in the new system, no such step is
used. Instead, SQL Server uses a special system-internal aggregate,
once unique, to raise an error if more than one distinct value is
encountered. Eliminating the sort step saves time.
View materialization has been made more efficient for views containing
aggregates.
Tidbits and New Features
The following limitations have been removed:
* distinct and group by not allowed in same query
* Correlation column and noncorrelation column not allowed on the same
side of an equal sign.
showplan output has been made more readable and has been enhanced to show:
* Line numbers to help locate statements in query text
* Subquery numbers and nesting levels for each subquery's plan
* Type of subquery
* Where each subquery is nested
* Types of scans
* Index coverage
* Index keys used to limit scan
* Worktable numbers
* Clustered index name
The sort step for distinct will no longer be necessary in some cases where
there is an index on the selected columns.
Effects for the User
Some subqueries, in and exists for example, will continue to perform as they
have for you in the past. On the other hand, some subqueries, especially not
in, not exists, all, and subqueries in or clauses, will perform considerably
better. For almost all non-flattened subqueries, you will see improved
response time.
One final advantage to the new system is that it leaves more leeway for
future performance improvements. SYBASE Technical News will keep you
informed of further progress in this area as it is made.
Tuning to Prevent Time-Slice Errors
If you have stored procedures that take a long time to complete, you may
have encountered the time-slice error, where SQL Server kills the running
process, sometimes shutting down with a stack trace in the error log. In
order to prevent this from happening, you can tune certain SQL Server
configuration parameters, but there are risks involved with each along with
the benefits.
Understanding Timeslice Errors
To make the most informed decision on configuration tuning, first you have
to understand what causes timeslice errors. Each task on your system gets a
fixed period of CPU time, called a time slice. During this timeslice, the
task is expected to complete a "unit" of work and then yield the CPU.
Sometimes, the task will not complete all its work in one time slice; in
this case, if the task does not volunteer to be put to sleep so that another
task can run, SQL Server will allot it one more amount of time to complete.
SQL Server is non-preemptive, which means that if a process fails to
complete, even with the extra time allotted, SQL Server will simply kill the
process rather than putting it on hold to give another process to the CPU.
This is the time-slice error.
In SQL Server releases 4.9.x and 10.x, the time-slice value is specified by
the buildmaster parameter ctimeslice and the extra time value by the
parameter ctimemax; in System 11, the time slice and extra time values are
part of the flat configuration file mentioned elsewhere in this issue.
When Timeslice Causes SQL Server Crash
There are hard-coded yields written into some of SQL Server's own most
CPU-consuming functions. This gives the scheduler a chance to reset and give
the process another chunk of time once the process queue is empty. If the
queue is not empty, a process with a yield coded into it will yield
voluntarily and SQL Server will not kill it.
If there is no yield coded into a SQL Server function holding a spinlock,
SQL Server will write the kernel error "timeslice -201" to the error log and
kill itself, resulting in a server crash with stack trace. Sybase
Engineering can sometimes use this stack trace to determine where in the
dataserver code it would be useful to insert a yield statement. To help
Engineering in this process, if you are getting SQL Server crashing with
time-slice errors, you should collect several such stack traces so that they
can better pinpoint the best yield location.
Time-Slice Errors on User Applications
More commonly, it is a user application, stored procedure, or query that
gets the time-slice error. In this case, SQL Server kills the offending
process but does not crash.
Reading the Timeslice Error Message
While a task is running, the scheduler counts down the amount of time that
the process has been running in ticks. The number of milliseconds
represented by each tick is platform-dependent; you can check how many
milliseconds SQL Server thinks a tick is by entering the command select
@@timeticks. In SQL Server releases prior to and including 10.x, the
buildmaster parameter cclkrate defines this number. On most systems, the
value for cclkrate is rounded to the nearest 10,000. On some systems, the
value is rounded to the nearest 1,000,000, or one second.
Both ctimeslice and ctimemax (and their equivalent entries in the System 11
configuration file) are defined in ticks. A value of 1 for ctimeslice is
equivalent to 1 tick. If cclkrate is set to 100,000 ctimeslice, this means
that a process will get a timeslice of 1/tenth of second. If ctimemax is set
to 200 ticks, the process will then get another 20 seconds of time on the
CPU (100,000 milliseconds * 200 = 20 seconds).
In the time-slice error message,you will see a negative number, for example:
00:95/07/16 01:54:08.94 kernel timeslice -3601, current process
infected
This is the total number of ticks that the process accumulated on the CPU
during this one "trip" before being terminated (ctimeslice + ctimemax). When
this combined value is exceeded, the timeslice error is generated,
indicating that SQL Server has infected the process preparatory to killing
it.
Parameter Tuning
From the above information, you may have deduced that if you increase
ctimeslice and ctimemax, you will experience fewer time-slice errors. This
is, in fact, the case, but there are two risks that you must take into
account before you decide to increase those values:
* Increasing ctimeslice and ctimemax means that a process will run for
the full time allotted without yielding, and will hold up other
processes. The result is that, without any message to the user, SQL
Server will come to an apparent halt for the full span of ctimeslice +
ctimemax.
* More seriously, increasing ctimeslice and ctimemax to fend off
time-slice errors may mask a deeper SQL Server problem.
Bearing these in mind, then, the way to adjust the two parameters is as
follows:
For release 10.x and earlier, the buildmaster commands are:
buildmaster -yctimeslice=value_in_ticks
buildmaster -yctimemax=value_in_ticks
When System 11 is released, these will be the commands:
sp_configure "time slice", value_in_milliseconds
sp_configure "cpu grace time", value_in_milliseconds
Note that unlike the earlier parameters, these are valued in milliseconds
rather than ticks. You must have the "sa" role to change these parameters.
It is theoretically possible to set ctimemax to some very high value, say
1,000, but you must decide for yourself if the benefits of having no
timeslice errors outweigh the possible performance degradation. We recommend
that you leave these values at the default unless you are getting time-slice
errors. If you are seeing these sorts of problems, you can tinker with the
timeslice and grace time (timemax) values to find the best balance of
performance and time- slice error avoidance for your site.
605 Errors on load database master
When you attempt to load a dump of your master database and get a 605 error,
check the sysusages table. It may be that the sysusages entries for master
are different between the dump and the database into which you are loading.
Overview
If sysusages.vstart values don't match between the dump and the recieving
database, SQL Server will raise a 605 error. You can either reconstruct
sysusages through a sequence of create database and alter database commands,
or you can follow the process outlined in the "System Database Recovery"
chapter of the SQL Server Troubleshooting Guide for rebuilding the master
database when no valid dump exists.
Technical Details
For example, say that the command select * from sysusages on your SQL Server
gives the following output:
dbid segmap lstart size vstart pad unreservedpgs
------ ---------- --------- --------- ----------- ------ -------------
1 7 0 1536 4 NULL 0
1 7 1536 1024 7172 NULL 0
2 7 0 1024 2564 NULL 672
2 4 1024 512 134217728 NULL 512
2 7 1536 512 117441024 NULL 512
3 7 0 1024 1540 NULL 664
3 3 1024 512 117440512 NULL 512
4 7 0 6144 16777216 NULL 1528
5 7 0 5120 33554432 NULL NULL
5 4 5120 2560 50331648 NULL NULL
6 7 0 1024 3588 NULL 648
7 7 0 1024 4612 NULL 528
8 7 0 1024 67108864 NULL 0
8 3 1024 3072 67109888 NULL 0
8 4 2560 1024 83886080 NULL 0
9 7 0 1536 100663296 NULL 1176
10 7 0 1536 5636 NULL 1184
11 7 0 1536 100664832 NULL 1176
(18 rows affected)
In the above output, lstart is the starting location of the logical page.
Logical pages in the database are numbered starting at 0, in an unbroken
stream. They are mapped to actual storage through the vstart values; virtual
pages are coded structures containing the device number and the page number
offset on the device. The mapping occurs like this:
1. SQL Server, looking for a particular page number (for example, 2000),
selects the lstart closest to but not greater than that number (say,
1536).
2. SQL Server subtracts the selected lstart number from the number of the
page it is looking for; this is how far away that page is from the
start of the disk piece where it is stored.
3. SQL Server adds that difference to vstart, then masks off the device
number encoded in vstart. The resulting value is the page offset from
the actual starting address on the device.
4. Finally, SQL Server multiplies that offset by the size of a Sybase page
to get the location where it should actually start reading.
The device number, as already mentioned, is encoded in vstart; dividing
vstart by 2**24 gives the device number. You can use the following query to
look at all objects on the master device (device number 0):
1> select * from sysusages
2> where vstart/power(2,24) = 0
3> order by vstart
4> go
Here is an example of output from that query:
dbid segmap lstart size vstart pad unreservedpgs
------ ---------- --------- --------- ----------- ------ -------------
1 7 0 1536 4 NULL 208
3 7 0 1024 1540 NULL 664
2 7 0 1024 2564 NULL 664
6 7 0 1024 3588 NULL 648
7 7 0 1024 4612 NULL 528
10 7 0 1536 5636 NULL 1184
1 7 1536 1024 7172 NULL 1024
(7 rows affected)
sysusages shows that usage on the master device is arranged as shown in
Figure 1.:
vstart 0 4 1540 2564 3588 4612 5636 7172 8196
size | | 3mb | 2mb | 2mb | 2mb | 2mb | 3mb | 2mb |
.....................................................................
dbid | | 1 | 3 | 2 | 6 | 7 | 10 | 1 |
| | | | | | | | |
lstart | | 0 - 1535 |0-1023 |0-1023 |0-1023 |0-1023 | 0 - 1535 |1536- |
| | | | | | | |2559 |
|...|...........|.......|.......|.......|.......|..........|.......|.
device
fragment 1 2 3 4 5 6 7 8
lstart = logical page number
Fig. 1
In the master database (dbid = 1), whenever a page is requested, for example
(logical page number) 1536, sysusages is used to convert this page number's
lstart into the corresponding vstart.
1> select vstart = vstart + 1536 - lstart
2> from sysusages
3> where dbid = 1
4> and lstart <= 1536
5> and size > 1536 - lstart
6> go
vstart
-----------
7172
Then SQL Server accesses the next 2048 bytes, starting at vstart=7172,
considering them as logical page 1536.
When you run dump database master, all allocated pages between lstart = 0
through 2559 or between vstart = 4 through 1539 and 7172 through 8195 are
copied to the dump device.
Suppose that after the dump you execute buildmaster to create new master,
model, and tempdb databases. sysusages now looks like this:
1> select * from sysusages
2> where vstart/power(2,24) = 0
3> order by vstart
4> go
dbid segmap lstart size vstart pad unreservedpgs
------ ---------- --------- --------- ----------- ------ -------------
1 7 0 1536 4 NULL 208
3 7 0 1024 1540 NULL 664
2 7 0 1024 2564 NULL 664
The layout for the master device is shown in the following figure.
vstart 0 4 1540 2564 3588
size | | 3mb | 2mb | 2mb |
.....................................................................
dbid | | 1 | 3 | 2 |
| | | | |
lstart | | 0 - 1535 |0-1023 |0-1023 |
| | | | |
|...|...........|.......|.......|....................................
Fig. 2
Figure 3 shows the layout after you an alter database master to add 2MB.:
vstart 0 4 1540 2564 3588 4612
8196
size | | 3mb | 2mb | 2mb | 2mb |
.....................................................................
dbid | | 1 | 3 | 2 | 1 |
| | | | | |
lstart | | 0 - 1535 |0-1023 |0-1023 |1536- |
| | | | |2559 |
|...|...........|.......|.......|.......|............................
Fig. 3
Now, vstart for logical page 1536 for the master database is 3588, as shown
in the following:
1> select vstart = vstart + 1536 - lstart
2> from sysusages
3> where dbid=1
4> and lstart <= 1536
5> and size > 1536 - lstart
6> go
vstart
-----------
3588
When you load the dump you made earlier onto master, all the pages for
master are copied from the dump device to the master device in the correct
place. However, at the same time, whatever was in sysusages before this load
is overwritten by what is in the dump. This means that the master device is
now laid out as shown in Figure 3, but sysusages shows it to be as shown in
Figure 1.
Therefore, immediately after the load, vstart for logical page 1536 for
master is 7172 which is incorrect as is clear from Figure 3.
This raises a 605 error as the load completes and recovery occurs:
Attempt to fetch logical page 1536 in database `master' belongs to object id
`0', not to object `'.
SQL Server consequently shuts down.
Action
You can confirm that the source of your 605 error is indeed the wrong vstart
for a logical page in master by booting SQL Server with trace flag 3607.
This brings up SQL Server without recovering any databases. Edit the
dataserver command line in your runserver file to add the trace flag.
* In UNIX, the file is usually $SYBASE/install/RUN_SVR where SVR is your
SQL Server name. Add the option -T3607 to the dataserver command line
in your runserver file, for example:
$SYBASE/bin/dataserver -T3607 other_qualifiers
-------------------------------------------------------------
Note: Be aware that the flag is invoked with -T (uppercase),
not -t (lowercase).
-------------------------------------------------------------
* In OpenVMS, the file is usually
SYBASE_SYSTEM:[SYBASE.INSTALL]RUN_servername.COM. Add the option
/trace=3607 to the dataserver command line in your runserver file, for
example:
$ server :== $sybase_system:[sybase.bin]dataserver.exe
$ server /trace=3607 /other_qualifiers
Look at sysusages, and run this query to find vstart for the offending page,
in this case page 1536:
1> select vstart = vstart + 1536 - lstart
2> from sysusages
3> where dbid=1
4> and lstart <= 1536
5> and size > 1536 - lstart
6> go
vstart
-----------
7172
In this case, page 1536 for master was copied at the correct place, but when
SQL Server tries to access it, it calculates a wrong vstart based on the
incorrect value in sysusages and accesses 2048 bytes from the wrong location
on the master device. This causes SQL Server to raise the 605 error.
The best solution is to construct a sequence of create database and alter
database commands that create sysusages as it appears after you load your
dump of master. Based on the original output:
1> select * from sysusages
2> where vstart/power(2,24) = 0
3> order by vstart
4> go
dbid segmap lstart size vstart pad unreservedpgs
------ ---------- --------- --------- ----------- ------ -------------
1 7 0 1536 4 NULL 208
3 7 0 1024 1540 NULL 664
2 7 0 1024 2564 NULL 664
6 7 0 1024 3588 NULL 648
7 7 0 1024 4612 NULL 528
10 7 0 1536 5636 NULL 1184
1 7 1536 1024 7172 NULL 1024
(7 rows affected)
You can recreate sysusages by following these steps:
1. Run buildmaster to get the first three rows in sysusages.
2. Create the fourth row by creating a database of 1024 pages.
3. Create the fifth row by creating a database of 1024 pages.
4. Create the sixth row by creating a database of 1536 pages.
5. Finally, alter master by 1024 pages to create the seventh row in
sysusages.
As mentioned at the beginning of this article, instead of re-creating
sysusages, you can follow the process outlined in the "System Database
Recovery" chapter of the SQL Server Troubleshooting Guide for rebuilding the
master database when no valid dump exists.
The fact that load database master generates 605 errors if sysusages.vstart
values don't match has been registered under bug number 45426, which has not
yet been fixed.
System Database Recovery in System 10
This article supplements two sections in the "System Database Recovery"
chapter of the SQL Server Troubleshooting Guide: "Master Device Completely
Lost" and "Master Database Corrupt and SQL Server Will Not Start."
Master Device Completely Lost
If a Valid Dump of the master Database Does Not Exist
For 10.0 and Later SQL Servers
Steps 1 through 5 are fine, but step 6 should read:
Execute sp_helpdb sybsystemprocs to make sure that the system
database sybsystemprocs is present. If so, then proceed to step 7.
If it is not, rebuild sybsystemprocs as follows:
1. Execute disk init to initialize a new device for
sybsystemprocs.
o If you are running 10.0, the device size should be 10MB.
o If you are running 10.0.2, the device size should be
12MB.
o If you running System 11, the device size should be
16MB, unless you are on Digital UNIX (OSF), in which
case the size should be 19MB.
2. Execute create database sybsystemprocs, with the sizes as
above.
3. Run installmaster by executing the command isql -Usa
-Ppassword < installmaster.
master Database Corrupt and SQL Server Will Not Start
If a Valid Dump of the master Database Exists
For 10.0 and Later SQL Servers
Take out step 10. There is no reason to run installmaster if you are
recovering with dumps--everything will be there.
If a Valid Dump of the master Database Does Not Exist
For 10.0 and Later SQL Servers
Steps 1 through 4 are fine, but step 5 should read:
Execute sp_helpdb sybsystemprocs to make sure that the system
database sybsystemprocs is present. If so, then proceed to step 7.
If it is not, rebuild sybsystemprocs as above.
Understanding sysusages.unreservedpgs
Question
How does SQL Server use the column unreservedpgs in the sysusages table and
when is it updated?
Answer
unreservedpgs contains the count of unreserved pages for that disk piece
during the time that the database is "closed". (A database is "closed" when
SQL Server has no in-memory structure describing it. If SQL Server does have
in-memory structures, it uses them in preference to the sysusages row
because access is thousands of times faster.) sysusages.unreservedpgs is
updated in these circumstances:
* When the database is automatically checkpointed
* When the database changes state from "open" to "closed"
Note that the update only occurs when the database is automatically
checkpointed-a user issuing the checkpoint command won't cause it to happen;
it must be the system doing it. Because this column is only updated
occasionally, it is inaccurate most of the time. Sybase provides a built in
function for the purpose of getting the accurate number; it should be used
like this:
select curunreservedpgs(dbid, lstart, unreservedpgs)
from master.dbo.sysusages
[ other clauses ]
This function is used by stored procedures such as sp_helpdb and
sp_helpsegment to display space usage.
------------------------------------------------------------------
Note: This information applies only to releases 10.x and later.
------------------------------------------------------------------
Understanding Spinlocks
Spinlock Defined
The lowest level of synchronization in a multiprocessor SQL Server is the
spinlock. SQL Server uses the spinlock to synchronize access to the critical
data used to control semaphores, page locks, and other thread management
tasks.
------------------------------------------------------------------
Note: Spinlocks and semaphores are only used in multiprocessor
servers, since otherwise a process is not allowed to schedule out
(or yield) while holding one.
------------------------------------------------------------------
In general, a spinlock works like this:
1. A thread or engine obtains a spinlock before attempting to change data.
2. While that thread or engine has the spinlock, if another thread or
engine attempts to obtain the same spinlock, that thread "spins" on the
lock until the lock is released.
3. Once it is safe for others to access or change the data, the original
thread releases the spinlock.
A spinlock might perform code protection or data protection. For example,
SQL Server always uses one particular spinlock for modifying a particular
object. A spinlock protecting code protects only a very small fragment of
the code, allowing it to be executed only in a single-threaded fashion.
Spinlocks are the most basic form of locking protocol, usually requiring
hardware support, an atomic instruction across the bus. Spinlocks are used
in favor of more complex semaphores or page style locks to control access to
frequently changed data structures because they are so basic; it doesn't
take long to acquire a spinlock.
Spinlocks and Server Panic
SQL Server "panics" when a thread dies holding a spinlock because the data
structure protected by the spinlock is in an unknown state. Other threads
cannot know how far the first thread got in changing the data structure
before it died. For example, suppose SQL Server needs to delete an object,
b, from a doubly linked list:
a<->b<->c
SQL Server grabs a spinlock and proceeds toward this state:
a<->c
Suppose, then, that there is a crash in the middle of the operation. The
states of the queue and the links are unknown.
a??b??c
It's hard either to undo what the crashed task was doing or to complete it.
The safest strategy is to shut down. This is because if SQL Server continues
to run with the lock held, eventually all of the other threads will block on
the held lock and the server will hang. An orderly shutdown is preferable.
A typical spinlock error in the error log will look like the following:
01:95/07/25 11:22:53.04 kernel timeslice -1501, current process infected
(The lock-holding process dies.)
01:95/07/25 11:22:53.11 kernel ************************************
01:95/07/25 11:22:53.13 kernel SQL causing error : execute master..lp_catch_wcid_user
01:95/07/25 11:22:53.13 kernel curdb = 1 pstat = 0x10100 lasterror = 0
01:95/07/25 11:22:53.13 kernel preverror = 0 transtate = 1
01:95/07/25 11:22:53.13 kernel curcmd = 197 program = isql
01:95/07/25 11:22:53.15 kernel Spinlocks held by kpid 21626922
01:95/07/25 11:22:53.15 kernel Spinlock Resource->rbufmgr_spin at address 102c6700 owned by
14a002a
01:95/07/25 11:22:53.15 kernel End of spinlock display.
(SQL Server recognizes that the process was holding a spinlock.)
01:95/07/25 11:22:53.16 kernel Begin BackTrace .....
01:95/07/25 11:22:53.17 kernel pc: 0x6b0368 os_backtrace+0xf8(0x6f20756c, 0x6c6f636b)
01:95/07/25 11:22:53.20 kernel pc: 0x69f060 ucbacktrace+0xa0(0x2e65d, 0x1)
01:95/07/25 11:22:53.20 kernel pc: 0x4344cc terminate_process+0x218(0x0, 0xffffffff)
01:95/07/25 11:22:53.20 kernel pc: 0x6a7884 kaclkintr+0x2ec(0x1c, 0x0)
01:95/07/25 11:22:53.22 kernel pc: 0xfb16a88 etext+0xf4417f8(0x1056c6e8, 0xfb1bf98)
01:95/07/25 11:22:53.22 kernel end of stack trace, spid 9, kpid
21626922, suid 1
01:95/07/25 11:22:53.22 kernel ueshutdown: exiting
(Finally, SQL Server shuts down.)
Patches for Hard / Transient 605 Errors on HP
Customers running SQL Server under HP-UX 9.04, who have encountered hard and
transient 605 errors, should call the HP Response Center for the following
patches:
* PHKL_3658
* PHKL_3981
* PHKL_4117
* PHKL_4316
* PHKL_4732
* PHKL_4764
* PHKL_4890
* PHKL_5139 <- Includes Rollup of Async I/O patches
* PHKL_5356 <-|
* PHKL_5394
* PHKL_5398 <- LVM and bad block relocation fixes
* PHKL_5532 <-|
* PHKL_5576
Verify with HP to make sure that you need these, but if you have fast/wide
SCSI and the A3232A or A3231A arrays, this is what you will need at least to
get your system stable.
Localization Problems and cs_ctx_alloc Failure
This article describes common problems when using Open Client(tm) in Windows
that can lead to the generic message "cs_ctx_alloc failure," and the steps
for correcting the problem. This is especially critical with any customers
using the internationalization features of Windows itself.
Open Client is based on a set of dynamic libraries, which take a modular
approach to messaging and internationalization. One of the most confusing
messages for both Technical Support and the customer is the "cs_ctx_alloc
failure." This message means that something happened when the client
libraries were trying to allocate the context for a connection.
There are a number of things that can cause this message:
1. Improper setup of the Sybase environment.
2. Missing or corrupted localization files.
3. Resource allocation problems.
4. Actual network problems.
In the first case, the problem can be as simple as the failure to have run
the WSYBSET.BAT batch file before entering Windows. It is important to make
sure that the $SYBASE system variable (at a minimum) is set to point to the
directory where the Open Client product is installed.
The location of DLLs (dynamic link libraries) is also important, since
failure to load a DLL may cause a misleading error message like the
cs_ctx_alloc error. Make sure that any DLLs (such as network software, and
Open Client) are located along the $PATH, or in the Windows system
directory.
Localization is done during context allocation, so if the localization files
are missing or corrupted, the context allocation will fail. This could be
due to improper setup of the Sybase environment (described above), an actual
installation problem, disk file corruption, or a conflict between the PC's
localization and that used by Sybase.
The localization routines look at the $SYBASE/LOCALES directory for the file
LOCALES.DAT. This file tells the localization routines which files contain
which messages for each character set and language. It also looks for a
locale name by searching the environment for the $LC_ALL environment
variable. If this environment variable is not defined, it looks for the
$LANG variable. If neither of those are defined, it looks for the Language
setting in the WIN.INI file. If none of these are set, it uses the locale
name of "default". Whatever the value is determined to be is then searched
for in the LOCALES.DAT file to determine which language and character set
are associated with it.
This seems to be the most common problem, and is usually solved by adding
the following line to either the AUTOEXEC.BAT file or the WSYBSET.BAT file:
set LANG=enu
------------------------------------------------------------------
Note: The righthand side of the equal sign must be in lower case.
------------------------------------------------------------------
In Europe, set LANG=enu in WSYBSET.BAT usually does the trick.
The "cs_ctx_alloc failure" occurs when the locale name that has been
determined does not exist in LOCALES.DAT. See Chapter 2 of the Open
Client/Server Supplement for Windows for more information on localization.
The other failures can normally be determined by examining the contents of
the SYBINIT.ERR file located in either your root directory, or the directory
of the executable which caused the allocation failure. It is very often a
problem with the configuration of the network software, which can require
modification of that software's initialization files.
End-of-Life Plan for APT and DWB
Sybase supports many different products on many different operating systems
and environments. Over time, we review the ongoing investments required to
continue supporting each product. We analyze market trends, our customers'
requirements as indicated in customer surveys, buying trends, and continued
use of Sybase products. We also review our overall product strategy to
ensure that we are providing the right mix of products to our customers.
Over the last few years, the trend in the market has been away from
character-based development tools such as APT Workbench(tm) and Data
Workbench® We have seen demand for these products diminish as customers turn
to graphical-based tools.
As a result of our review and analysis, we have decided to end enhancement
and support for Sybase's APT, Data Workbench, and Report-Execute(tm)
products. Low demand for these products no longer justifies the investment
in new product engineering.
To help Sybase customers continue to support their applications based upon
these products and to transition to alternative development environments,
Sybase will provide the following end-of-life plan:
1. Sybase will continue to provide full product support for five (5) years
for APT, Data Workbench and Report Execute to customers who have
purchased support contracts for these products. Although we will not be
enhancing the products to take advantage of new features of SQL Server,
we will ensure upward compatibility with future SQL Server releases. On
June 30, 2000, we will stop accepting support calls on all APT, Data
Workbench and Report-Execute products and will no longer provide any
software changes.
2. To our APT Workbench and Data Workbench customers with active support
agreements, we are offering a special promotion. You may receive 50
percent off the purchase price of any Sybase SQL Server or Powersoft®
product, including PowerBuilder® up to the value of your APT Workbench
and Data Workbench active licenses (based upon current list price).
When you no longer require support for your APT, Data Workbench or
Report-Execute products, you may request this discount by calling
1-800-685-8225. The Sybase representative will determine your discount
amount, and apply that amount towards the purchase of other Sybase
products. At the time you exercise this discount option, support for
your APT and Data Workbench products used in the calculation of the
discount will be terminated. This promotional offer will remain in
effect until June 30, 2000, and applies only to APT Workbench and Data
Workbench licenses that (a) are covered by active support agreements at
the time you take advantage of the promotional offer and (b) were
purchased (or deployed against a secondary copy pool) prior to June 30,
1995.
3. We understand that you have applications that you have developed using
APT and may need to add additional licenses as you deploy these
applications. You will be able to purchase additional licenses for all
APT, Data Workbench and Report-Execute products during this end-of-life
period. However, support for these new licenses will end on June 30,
2000, regardless of the date of purchase.
The specific products included in this end-of-support notice are:
* APT Workbench
* APT-Execute(tm)
* Data Workbench (which includes Report Workbench)
* Report Execute
* PC APT 32-bit Deployment Toolkit
* all APT-Libraries (for a variety of languages)
* APT Translator for Motif (previously obsoleted)
* APT Display for Motif (previously obsoleted)
------------------------------------------------------------------
Note: This end-of-life plan does not affect the Japanese codeline:
5.1.x.
------------------------------------------------------------------
We do hope that the extended period of time for support of these products
will help you in the transition from APT, Data Workbench and Report-Execute.
If you would like to take advantage of the promotional offer described
above, please call your local Sybase support group or 1-800-685-8225 (U.S.
and Canada) and a Sybase representative will be glad to help you.
The current releases of the toolset products (APT-Execute, APT Workbench,
Data Workbench and Report-Execute), versions 5.2.2 and 5.2.3 have been
available for well over a year, and Sybase is in the process of introducing
a new release, version 5.3, during Q2 and Q3 of 1995. With the availability
of releases 5.2.2, 5.2.3, and 5.3 of the toolset products, and the limited
number of customers using the older versions, Sybase can no longer provide
support for older versions.
Effective June 30, 1995, support has been discontinued for all releases of
these products that precede version 5.2.2.
When planning for the current releases of the toolset products, Sybase
reviewed the demand for these products on all supported platforms. For a
limited number of hardware platforms, demand has declined to less than 10
customers. For this reason, Sybase has no plans to provide release 5.2.2,
5.2.3 or 5.3 on the platforms listed below. Support of the last release (4.x
and 5.0) of these products provided for these platforms will continue until
June 30, 1996 and will not be available after that date. Customers are
encouraged to transfer their licenses that are covered by current support
agreements to a platform for which release 5.3 is provided. Support for
release 5.3 will continue until June 30, 2000.
This table shows the combinations of platform and release that will be
supported under current contracts until June 30, 1996:
Platform Operating System APT/DWB Release
386 PC UNIX OSF 4.0.3
AT&T 3B2 UNIX 5.3.2 4.0.0
Bull DPX BOS 1.0 4.0.3
IBM RT AIX 2.2.1 4.0.0
Stratus XA/2000 VOS 9.0R 4.0.2
Stratus XA/R I860VOS 11.5 5.0.0
If you have any questions, please call your local Sybase support group or
our US corporate offices at (510) 922-3500 or 1-800-8-SYBASE (U.S. and
Canada).
Mainframe EBF Information
Here is the latest list of all AVAILABLE rollup Mainframe Access Products
EBFs as of 8/23/95. This list replaces any previous list sent. Be sure to
read the important notes at the end, especially note 1:
Mainframe Access Products EBFs
MAP Product Catalog Number version 2.x version 3.0
EBF number EBF number
Open Client/CICS/LU6.2 19320 4686 n/a
Open Server/CICS/LU6.2 19300 2218 3528
Open Server/CICS/TCP_IP 19350 n/a 3529
Open Server/IMS/LU6.2 19315 n/a 4983
OSAM/DB2/CICS/LU6.2 19311 1971 4899
OSAM/DB2/CICS/TCP_IP 19360 n/a 4608
OSAM/DB2/IMS/LU6.2 19370 n/a 4609
Important Notes
Please note that these Mainframe EBFs ship automatically as part of any new
product order.
1. EBFs 4983 and 4609 will allow you to run Open Server(tm) and OSAM/DB2
under native MVS, with no transaction manager. It is packaged as part
of the IMS products, not as a standalone. We recommend that you run the
Open Server API product as read only, unless you wish to code your own
commit and rollback logic. The OmniSQL Access Module(tm) for DB2 can be
read/write. For installation, it is a separate download file, with
different names than IMS, and nothing shared with IMS. You need not
actually have IMS to use it, but it must be ordered via the IMS
products (19315 &/or 19370).
2. All MAP(tm) EBFs now support RPC parameters >32k but <64k, without
needing any of the latest Net-Gateway(tm) EBFs.
3. All MAP EBFs now support RPC parameters >64K, if you also have the
latest Net-Gateway EBF 3516 or higher, depending on your platform, and
additionally start up Net-Gateway with the new option -E to enable this
support. The OS/2 GA already has this support built in.
4. Open Server for CICS 1.0 applications can run with the 3.0 stub without
having to relink.
5. EBFs 4899, 4608, and 4609 fix failed rollbacks in long running
transactions when a quit or disconnect occurs. All customers doing
replication into DB2 will need this EBF. Rollups from prior EBFs cure
batched SQL (multiple input lines separated by semi- colons ; )
problems encountered when a comma is part of the input line, such as
found in names like O'Malley. This behavior is not fixed on 2.0
codeline on top of 1971 (and there are no plans to), though a 1-off
based on 2.0 GA was done (4607).
6. All Trinzic (InfoHub) customers need the latest Net-Gateway and OS/CICS
EBF.
7. Some Open Client/CICS customers using the latest EBF will need the
latest Net-Gateway EBF for their platform if they are using SQL Server
names longer than 8 characters with OC/CICS (bug 57967) or are
re-linking their applications with the new stub that contains the
memory leak fix (bug 56162). Check the Net-Gateway cover letter to be
sure the fix has been ported for your Net-Gateway platform.
Net-Gateway EBF Information
Here is the latest list of all rollup Net-Gateway EBFs which will become
available during August and throughout September and early October 1995.
This list replaces any previous lists sent:
Net-Gateway EBFs
Net-Gateway version 2.x version 3.x
Platform Catalog Number EBF Number EBF number
HP9000/800 17700 n/a 5361 (see note 4)
OS/2 16230 5420 4836
RS6000 12670 5419 5401 (see note 5)
Solaris 12950 n/a 5402 (see note 6)
SunOS 18600 5365 (see note 7) 5400 (see note 7)
Important Notes
1. A version 2.x Net-Gateway can run with a CICS LU6.2 MAP product at 3.0
or 10.1 version level, but it cannot take advantage of any new
functionality. For migration purposes, always update the mainframe code
first, then Net-Gateway second.
2. All Trinzic (InfoHub) customers need a 3.0 Net-Gateway EBF plus the
latest MAP 3.0 EBF before using the product (that is, GA MAP plus
latest valid mainframe EBF).
3. Some Open Client/CICS customers using the latest EBF 4686 will need a
Net-Gateway EBF if they use long SQL Server name lengths (bug 57967) or
re-link their applications with the stub fixed for the memory leak
problem (bug 56162); check the EBF cover letter to verify your platform
has the fix ported.
4. This EBF is built on HP-SNAplus patch PHNE_5329. All customers are
required to install this HP patch in order to use EBF 5361.
5. This EBF is built on AIX 3.2.3 and SNA Server. EBF 5401 also contains
support for IBM's Password Expiration Manager.
6. This EBF is built on Solaris 2.2 and Sunlink Peer-to-Peer 8.0, with
patches 101524-01, 102146-02 and 102147-01 applied.
7. All SunOS customers must apply base patch 100916-06, plus 100916-07 by
contacting Sun Engineering.
General Information
The new 3.0 Net-Gateway EBFs include the following features:
* Memory leaks fixed.
* Group password is no longer displayed.
* New -C Net-Gateway start-up option to roll lowercase userids and
* passwords into uppercase before sending to mainframe.
* RPCs >32K supported.
* RPCs >64K supported using new -E Net-Gateway start-up option and MAP
EBF 3525 or higher.
The new 2.0 Net-Gateway EBFs include the following features:
* Group password is no longer displayed.
* New -C Net-Gateway start-up option to roll lowercase userids and
passwords into uppercase before sending to mainframe.
* sygc gateway control program broken by previous 2.0 EBFs fixed
Bug 69332: Timeslice Disables Automatic Checkpoint and waitfor Command
------------------------------------------------------------------
Note:This bug is specific to IBM RS6000.
------------------------------------------------------------------
Sybase Technical Support recently encountered a case where a customer's
tempdb database was filling up. The customer was able to run a manual dump
transaction in tempdb, indicating that there were no open transactions.
Further investigation revealed that the automatic checkpoint process was not
dumping tempdb, even though the process was visible through sp_who. The
customer also noticed that the waitfor command no longer worked.
The problem turned out to be a large stored procedure that tended to raise a
time slice error. Further testing showed that when any process on the
customer's server suffered a time slice error, the waitfor command and
automatic checkpoint process no longer functioned until the customer
rebooted SQL Server.
If you get a time slice error in your errorlog and subsequently get hung
processes or notice that the waitfor command and automatic checkpoint no
longer function, you may call Sybase Technical Support to get a one-off EBF
containing the fix for bug 69332. The fix for this bug has not yet been
incorporated into a Rollup, but will be in the future.
----------------------------------------------------------------------------
Disclaimer: No express or implied warranty is made by SYBASE or its
subsidiaries with regard to any recommendations or information presented in
SYBASE Technical News. SYBASE and its subsidiaries hereby disclaim any and
all such warranties, including without limitation any implied warranty of
merchantability of fitness for a particular purpose. In no event will SYBASE
or its subsidiaries be liable for damages of any kind resulting from use of
any recommendations or information provided herein, including without
limitation loss of profits, loss or inaccuracy of data, or indirect special
incidental or consequential damages. Each user assumes the entire risk of
acting on or utilizing any item herein including the entire cost of all
necessary remedies.
Staff
Principal Editor: Leigh Ann Hussey
Contributing Writers:
Sandra Dellafiora, Aimee Grimes, Louise Kirby, Jeff Lichtman, John McVicker,
Pat Mullin, Rahul Upadhyaya, Rob Weaver, James White, Elton Wildermuth
Send comments and suggestions to:
SYBASE Technical News,
6475 Christie Avenue,
Emeryville, CA 94608 USA
For more info send email to tech...@sybase.com
Copyright 1995 © Sybase, Inc. All Rights Reserved.
Q10.3.1
SYBASE Technical News, Volume 5, Number 1
February, 1996
This issue of SYBASE Technical News contains new information about your
Sybase software. If needed, duplicate this newsletter and distribute it to
others in your organization. All issues of SYBASE Technical News and the
troubleshooting guides are included on the AnswerBase CD. Send comments to
tech...@sybase.com. To receive this document by regular email, send name,
full internet address and customer ID to tech...@sybase.com.
In this Issue
Tech Support News/Features
* 1996 Technical Support North American Holiday Schedule
SQL Server 11.0
* Database "Online" Questions
* Dump Compatibility Issues
* Lock Promotion Changes in SQL Server 11.0
* Changes to Thresholds Behavior in SQL Server 11.0
SQL Server General
* Threshold Process Fails to Fire
* Maximum Timestamp Value
* Dumping Multiple Products to One Tape
* Dump Transaction and Error 4207
* Trace Flags 322 and 323 in 4.9.x & 10.x
* Installing Async I/O on HP-UX 10.0 via SAM
* Ultrix: 4.4 vs. 4.3a Compatibility
Connectivity / Tools / PC
* Latest Rollups for PC Platforms
Certification and Bug Reports
* Latest Rollups for SQL Server
1996 Technical Support North American Holiday Schedule
Sybase Technical Support is open on all holidays and provides full service
on many. During the limited-service holidays shown below, Technical Support
will provide the following coverage:
* SupportPlus Preferred and Advantage customers may log all cases; we
will work on priority 1 and 2 cases over the holiday.
* 24x7 and 24x5 Support customers may log priority 1 cases; we will work
on these over the holiday.
* SupportPlus Standard, Desk Top, and Regular Support customers may
purchase Extended-hour Technical Support for coverage over the holiday.
Table 1: Sybase Technical Support limited service
holidays - U.S. customers
Holiday Date
New Year's Day January 1
President's Day February 19
Memorial Day May 27
Independance Day July 4
Labor Day September 2
Thanksgiving November 28
Christmas December 25
Table 2: Sybase Technical Support limited service
holidays - Canadian customers
Holiday Date
New Year's Day January 1
Good Friday April 5
Victoria Day May 20
Canada Day July 1
Labour Day September 2
Canadian Thanksgiving October 11
Christmas Day December 25
Boxing Day December 26
If you have questions, please contact Technical Support.
Database "Online" Questions
Sybase SQL Server release 11.0 includes a new online database command. This
article contains a few commonly asked questions about the "online" state of
a database and the use of the online database command. For more information,
please see What's New in Sybase SQL Server Release 11.0?, the System 11 SQL
Server Migration Checklist supplement to this Sybase Technical News, and the
SQL Server Reference Manual.
Question
Executing a load database leaves the database offline; does load transaction
leave a database online or not?
Answer
load transaction leaves the database the way it found it: if it was offline,
it remains offline; if it was online, it comes online again. A customer
doing a sequence of load database, load tran, load tran ... will have to use
the online database command at the end of the load sequence. A customer who
has already brought the database online and who then loads another
transaction dump will not have to repeat online database.
Question
If a database becomes corrupt during boot time recovery and I am able to fix
whatever caused the problem, can I just bring the database online with the
online command, or will I have to reboot SQL Server?
Answer
Using the online database command in this context will bring the database
online; you won't have to reboot. Note, however, that if the database has
been marked suspect, online database will have no effect.
Question
Can I run dbcc checkalloc or tablealloc with the fix option when a database
is offline, instead of having to put the database in single user mode?
Answer
Yes. You can also do any other dbcc commands in an offline database.
Question
What causes a database to go offline?
Answer
There are three things that take a database offline:
* load database. This causes a "persistent" offline state, that is, the
database stays offline until you issue an online database command.
* load transaction. As mentioned above, if the database was online before
the load transaction, it comes back online automatically; if it was
offline, it stays offline.
* Database recovery. This causes a "temporary" offline state, that is,
the database comes back online automatically when recovery is finished,
unless an error occurs during recovery.
------------------------------------------------------------------
Note
The "persistent" offline state overrides a "temporary" offline
state. Thus, if you do a load database followed by a load
transaction, the offline state set up by the load database
persists after the load transaction. That's the mechanism by which
load transaction "leaves the database the way it found it" as in
the first question above. That's also the way SQL Server detects
that a database should remain offline even if the server should
crash while the database is in a load sequence.
------------------------------------------------------------------
Dump Compatibility Issues
Question
What dumps are compatible between SQL Server 11.0 and earlier releases?
Answer
The following table shows what SQL Server releases can read dumps from other
SQL Server releases.
Destination -->
Source SQL Server SQL Server SQL Server SQL Server
v 4.9.x 10.0.x 10.1 11.x
Dump Level 4.9.x Yes No No No
Dump Level 10.0.xNo Yes Yes Yes
Dump Level 10.1 No No Yes Yes
Dump Level 11.x No No No Yes
------------------------------------------------------------------
Note
This table applies to the compatibility of physical dumps
themselves, rather than Backup Server compatibility. Backup Server
releases are only compatible with the SQL Server of the same or
previous release level.
------------------------------------------------------------------
Here are a few important issues regarding dump compatibility between SQL
Server releases.:
* In general, you should never assume backward compatibility: a
lower-numbered version of a product probably can't read a
higher-numbered version's files. However, higher-numbered versions
should be able to read files from lower-numbered versions. You can dump
from 10.0.2 and load to 10.1.
* 10.1 dump headers have a field in them that can't be read by 10.0.x
servers. The new "log version" field was added so that System 11 could
distinguish a 10.1 release database by reading the dump header. 10.0.x
doesn't recognize this, so 10.0.x can't read 10.1 dumps.
* While SQL Server can read several flavors of log record, it can only
write log records at its own release level; and if it writes an 11.0
log record into a section of log that currently contains 10.x records,
the new records will not be readable during a subsequent load or
boot-time recovery because the log reader expects all log records to be
in a single format until SQL Server tells it to switch formats.
Consequently, when you start up SQL Server 11, one of two things will
happen:
* If boot-time recovery succeeds, your databases will be online, but SQL
Server will refuse to do a logged dump transaction until you do a dump
database. This means that until you dump database, you can only do dump
transaction with no_log or with truncate_only, because other kinds of
dump transaction actually write some log records. truncate_only is
allowed because the database is online and therefore writable, and
since you aren't trying to dump log records to be read later it's okay
to write an 11.x log record.
* If boot-time recovery fails for some reason, or if the database is
replicated (in which case it will be offline only until replication is
finished), you can only do dump transaction with no_log or with
no_truncate. The database is offline and unavailable for writing, but
no_truncate is allowed because it is not a logged operation and you or
Sybase Technical Support (in the case of recovery failure) may find a
copy of the log useful. If you are able to bring the database online by
executing online database, you will still have to dump database before
you can do a logged operation.
In both of these cases, you will see Error 4225:
This database has not been dumped since it was created or
upgraded. You must perform a dump database before you can dump its
transaction log.
You may also see Error 4226:
Logged DUMP TRANSACTION cannot run in database %.*s, because that
database's log version (%d) disagrees with the SQL Server's log
version (%d); use DUMP TRANSACTION WITH NO_LOG. Versions will agree
once ONLINE DATABASE has run.
To clear this condition, again, just do dump database.
Lock Promotion Changes in SQL Server 11
Question
Is lock promotion calculated on a per statement basis, or on a per
transaction basis? I have a single process executing several thousand update
statements to the same table in a transaction, and the EX_PAGE locks are not
being promoted to a table-level lock. Is this the behavior I should expect?
Answer
Lock promotion is performed on a per-statement basis. Additionally, there
may be some complex statements for which lock promotion will not be
performed at all. We do not take the transaction into account.
In System 11, however, you can configure the lock promotion threshold for
tables, databases, and servers. This will give you the ability to guarantee
that updates use table level locks. For more information about setting the
lock promotion threshold, please see Chapter 11, "Locking on SQL Server," in
the SQL Server Performance and Tuning Guide.
Changes to Thresholds Behavior in SQL Server 11.0
In SQL Server 11.0, there are some important changes in the way that
thresholds behave on the log segment.
Thresholds and the syslogshold Table
In the situation where you or a threshold process cannot truncate the log
because of an open transaction, SQL Server 11.0 provides a new table,
syslogshold, which includes information on what process has the open
transaction. You can use information in this table to set up a threshold
process to deal with the open transaction.
For more information on the syslogshold table, please see the SQL Server
Reference Supplement. For information about using it in conjunction with
threshold procedures, see the chapter "Managing Free Space with Thresholds"
in the System Administration Guide.
Private Log Cache Feature
As a performance enhancement, 11.0 introduces the Private Log Cache (PLC).
This feature maintains log records in memory, rather than writing them
directly to the log. However, SQL Server must guarantee that space is
available in the log to flush these records when the time comes.
Consequently, the PLC "reserves" log pagesÅ» that is, it marks space as used
before actually writing to it. Presently, this reservation equals three
pages per open transaction per database.
This reserved space counts as "used pages" toward triggering the threshold
procedure, even though under some circumstances that space won't actually be
written. The effect for you is that in the log segment, thresholds will
trigger sooner than it looks like they should: there may appear to be more
empty space in the log segment than the threshold claims there is. This
occurs because SQL Server reports pages actually written, while it acts on
pages reserved.
This will be particularly noticeable if your site has many users with open
transactions in a single database.
------------------------------------------------------------------
Note
Remember that the rule is three pages reserved per transaction per
database: a thousand users with a transaction open in one database
will have reserved 3000 pages in the log for that database.
------------------------------------------------------------------
Threshold Process Fails to Fire
Question
Sometimes a threshold process that dumps the transaction log when the
threshold is overrun fails to actually do the dump tran. Why did it fail?
Answer
There are many reasons the threshold procedure can fail to start. SQL Server
checks all of the following, in order:
1. That it can allocate memory for the information the threshold procedure
will need.
2. That it can create a task to execute the procedure.
3. That the threshold procedure can use the database.
4. That the systhresholds table exists.
5. That there is an entry in systhresholds for the threshold in question.
6. That the threshold owner is a valid user in the database.
7. If the database is usable by the database owner only, that the user who
bound the threshold is the database owner.
8. That the threshold owner is a valid server login.
9. That the procedure named in the threshold is valid.
The step that concerns us here is step 3. If your procedure failed, check to
be sure that the database is not in single-user mode. If a database is in
single-user mode, and the user overruns a threshold, the threshold process
won't succeed in doing any work in that database, because the maximum number
of users allowed in the database is one and the user who overran the
threshold is that one.
The threshold procedure must be in the database before it starts work; if it
cannot use the database, SQL Server prints Error 7403 and stops:
Threshold task could not use database %d, and so
cannot execute the threshold procedure for segment
%d, free space %ld.
This behavior affects all threshold procedures, regardless of whether they
do any work that is not directly involved with the database.
Maximum Timestamp Value
Question
Is there a maximum value for the timestamp in the log? If there is, what
happens when that number is reached?
Answer
Yes, there is a maximum timestamp value. If we ever reach that value, the
next assigned timestamp value would be 0 (not 1). If the timestamp does roll
over, corruption might result; however, before this happens, you will be
warned.
SQL Server attempts to warn you that the database is approaching the maximum
timestamp value by checking that the current database timestamp value is
less than 0xffff 0xfefffffff. This validation check occurs each time the
dbtable is created for the database. If the timestamp is greater than 0xffff
0xfefffffff, SQL Server raises Error 935:
WARNING - the timestamp in database `%.*s' is approaching the maximum allowed.
When you receive Error 935, you should do one of the following as soon as
possible:
* Create a new database the same size as the old, execute sp_dboption
"select into" for that database, then use select into to recreate the
tables.
* Bulk copy your data out, drop and re-create the database, then bulk
copy the data back in.
Explanation
Sybase timestamps are an unsigned 48-bit number; that is, they can hold
integer values from 0 through 248 -1 or 281,474,976,710,655. In recovery,
SQL Server decides what has and hasn't been done by comparing timestamps; if
the timestamp on the page is smaller than the one in the log record, then
this change hasn't been made, so SQL Server makes it.
If the timestamp were ever to roll over, the timestamp in a log record might
well be something like 0xffff.ffffffac, and the timestamp on the page
something like 0x0000.00000013. Logically, the timestamp on the page should
be later than the one in the log, because the timestamps have wrapped
around, but SQL Server won't detect that. All SQL Server knows is that the
page timestamp is smaller than the log record timestamp, so it will make the
change specified by the log record, thus corrupting the data page.
Bear in mind that timestamp can take quite a long time to roll over. For
instance, suppose that your server makes a change in the database every
millisecond (1000 changes per second), all day every day. At that rate, it
will take more than 8,900 years for the timestamp to roll over. (248 / (1000
* 60 * 60 * 24 * 365.25) = 8919.4) However, improper use of dbcc rebuild_log
or dbcc save_rebuild_log could result in the timestamp reaching the maximum
value. When this occurs, SQL Server will generate Error 6901:
Overflow on High component of timestamp occurred in database %d. Database table possibly corrupt.
Again, if you receive this error, use one of the methods described above to
re-create your database.
------------------------------------------------------------------
Note
This information applies to SQL Server 11.0 as well as to previous
releases.
------------------------------------------------------------------
Dumping Multiple Products to One Tape
Question
I want to back up all my databases, both Sybase and Oracle, onto the same
tape each night in a batch. How do I do this?
Answer
You can't. Backup Server expects a tape to conform to a format similar to
ANSI standard, where the first record on the tape is a "volume header",
followed by some "file header" records. Because other vendors do not try to
use ANSI standard format, Backup Server cannot use tapes that contain other
vendors' data.
Sybase has no plans to change this in the foreseeable future.
Dump Transaction and Error 4207
Question
When I try to dump transaction in my database, I get error 4207, which says
that dump transaction is not allowed while the select into/bulk copy option
is enabled. The problem is, that option isn't actually enabled in that
database. What happened?
Answer
What you're seeing is the old text of error 4207. It caused a lot of
confusion, so Sybase changed it. As of SQL Server 11.x, it says:
Dump transaction is not allowed because a non-logged operation was performed on the database.
Dump your database or use dump transaction with truncate_only until you can dump your database.
What happened to you is one of several things:
* You performed a fast (unlogged) bulk copy into your database.
* You performed a select into a table in your database.
* You used dump transaction with truncate_only or no_log in your
database.
All of these operations make changes that are not recorded in the
transaction log. Because the log doesn't have a record of those changes, it
isn't possible to rebuild your database from only the log. Thus, as soon as
one of those things happen in a database, SQL Server disallows dump
transaction until the next dump database has been performed. The database
dump gives the server the necessary information to re-create those changes,
so it is then possible to use transaction log dumps to re-create the rest of
the changes.
Trace Flags 322 and 323 in 4.9.x & 10.x
Question
I have two 4.9.2 SQL Servers running at different Rollup levels. Certain
queries containing subqueries run much more slowly on the newer Rollup than
on the older one. The showplan output reveals that the newer Rollup uses a
four-step plan where the older one uses only two steps. I have heard that
two SQL Server trace flags, 322 and 323, might help me. What do these trace
flags do?
Answer
A fix for an optimizer bug, 13495 (also listed as 17230), changed the
behavior of the optimizer. 13495 ensures that subqueries under ors are not
unnested, so that correct results are returned in all cases. The following
table lists the platforms and Rollup numbers in which this change first
appeared:
Platform 4.9.2. Rollup Number
SunOS Release 4.x (BSD) 4152
HP 9000 Series 800 HP-UX 4153
IBM RISC System/6000 AIX 4154
AT&T System 3000 UNIX SVR4 MPRAS4155
Digital OpenVMS VAX 4156
Sun Solaris 2.x 4157
Digital OpenVMS Alpha 1.5 4158
Digital UNIX n/a
If you are running one of these Rollups, or any Rollup released later, you
may find that you now get poor performance with certain queries containing
subqueries. To fix this, you can try using trace flags 322 or 323. Trace
flag 322 is to be used at SQL Server startup; trace flag 323 is the
interactive version, invoked with the command dbcc traceon(323). Both trace
flags disable the fix for bug 13495.
------------------------------------------------------------------
WARNING!
Disabling this fix may return performance for these queries to
your previous levels, but may also cause SQL Server to return two
sorts of incorrect results:
* Because subqueries are processed as joins, existence checks
may
return duplicates where they should not.
* The construction or x in this statement:
select a from b where...
will not work when b is empty.
------------------------------------------------------------------
If you are running SQL Server release 10.x and encountering this particular
performance problem, you may use EBFs 4428 and higher, which include these
trace flags.
These trace flags are not available in SQL Server 11.0 because subquery
processing has been substantially rewritten.
Installing Async I/O on HP-UX 10.0 via SAM
Release 10.0 of HP-UX allows for the installation of the asynchronous driver
using SAM (System Administration Manager). This alleviates the need to run
the installasync script which is currently shipped with Sybase SQL Server
Releases 10.0 and below for HP- UX. To install async with SAM, follow these
steps:
1. Invoke SAM and select Kernel Configuration.
2. Select Drivers within the Kernel Configuration menu.
3. Change the Pending State for asyncdsk to In.
4. Rebuild the Kernel and Reboot the system (using the Actions menu
option).
5. Execute the following statements as "root":
/etc/mknod /dev/async c 101 5
chmod 0660 /dev/async
chown sybase /dev/async
chgrp sybase /dev/async
-------------------------------------------------------------
Note
Step 5 may also be performed prior to step 1.
-------------------------------------------------------------
In fact, as of System 11, Sybase will no longer ship an installasync script.
Instead, use the steps described above.
If you have questions abut SAM, please call HP Technical Support.
Ultrix: 4.4 vs. 4.3a Compatibility
Sybase has determined that Digital Ultrix 4.4 is not binary compatible with
Ultrix 4.3a, and we do not recommend that customers run the 4.2 SQL Server
under Ultrix 4.4. Sybase has no plans to recompile the SQL Server on Ultrix
4.4; any further issues relating to the compatibility of Ultrix 4.4 should
be addressed directly to Digital Equipment Corp.
Latest Rollups for SQL Server
The following table lists the latest Rollups for SQL Server on all
platforms.
Platform Release Number Rollup Number
Sun OS Release 4.x (BSD) 10.0.2 5539
Sun OS Release 4.x (BSD) 4.9.2 5631
HP 9000 Series 800 HP-UX 10.0.2 5540
HP 9000 Series 800 HP-UX 4.9.2 5632
IBM RISC System/6000 AIX 10.0.2 5541
IBM RISC System/6000 AIX 4.9.2 5633
AT&T (NCR) System 3000 UNIX SVR4 MPRAS10.0.2 5542
AT&T (NCR) System 3000 UNIX SVR4 MPRAS4.9.2 5634
Digital VAX OpenVMS 10.0.2 5543
Digital VAX OpenVMS 4.9.2 5635
Sun Solaris 2.x 10.0.2 5544
Sun Solaris 2.x 4.9.2 5636
Digital OpenVMS Alpha 1.5 10.0.2 5545
Digital OpenVMS Alpha 1.5 4.9.2 5637
Digital OSF/1 10.0.2 5549
Digital OpenVMS Alpha 1.0 4.9.2 5637
Novell Netware 10.0.2 5547
OS/2 10.0.2 4726
Windows NT 10.0.2 5546
In the case of 4.9.2 Rollups, there are subsequent one-off SWRs (formerly
EBFs) that you may order for specific bug fixes, but Sybase recommends you
upgrade rather than ordering a one-off SWR at this point.
Latest Rollups for PC Platforms
The following tables list the latest rollups of Sybase products other than
SQL Server for PC platforms.
Table 3: EBFs for DOS Platforms
Product Group Release Number SWR Number
Open Client/C Developers Kit 10.0.2 4907
DB-Library 4.2.5 4987
DB-Library 4.2.6 4987
Net-Library FTP PC/TCP 1.0.3 3666
Net-Library Microsoft TCP 1.0.3 5408
Net-Library Named Pipes 1.0.2 2387
Net-Library Novell IPX/SPX 1.0.2 3661
Net-Library Novell LAN Workplace1.0.3 3665
SQR Workbench 2.5 2489
SQR Execute 2.5 2490
Table 4: EBFs for Netware Platforms
Product Group Release Number SWR Number
Open Client/C Developer's Kit10.0.3 5509
DB-Library 4.6 2849
Replication Server 10.1 4922
Table 5: EBFs for OS2 Platforms
Product Group Release Number SWR Number
Open Client/C Developer's Kit 10.0.3 5677
DB-Library 10.0.2 4146
DB-Library 4.2 4721
Net-Library Named Pipes 1.0.2 3904
Net-Library Named Pipes 2.0 2698
Net-Library Novell SPX/IPX 1.0.2 3982
Net-Library Novell IPX/SPX 2.0 1612
Net-Library Novell LAN WorkPlace1.0.2 2534
Net-Library IBM TCP 10.0.1 3184
SQR 2.4 1822
Open Server 10.0.2 3905
Open Server 2.0 3436
Table 6: EBFs for PC Windows Platforms
Product Group Release Number SWR Number
Open Client/C 10.0.3 5735
DB-Library 4.2.5 5185
Net-Library FTP PC/TCP 10.0.1 3777
Net-Library Named Pipes 10.0.1 5303
Net-Library NEWT 1.0.3 3158
Net-Library Novell LAN WorkPlace1.0.2 2472
Net-Library WinSock 1.0.3 5146
ODBC 10.0.1 5736
Embedded SQL/C Precompiler 10.0.2 4653
Embedded SQL/Cobol Precompiler 10.0.2 4269
Embedded SQL/C Precompiler 4.0.4 3607
SQL Monitor Client 10.1.2 4723
SQR Workbench 2.5 2492
SQL Server Manager 10.3 5099
Table 7: EBFs for Windows NT Platforms
Product Group Release Number SWR Number
Open Client/C Developer's Kit10.0.3 5655
Replication Server 10.1 5112
Open Server 10.0.3 5513
Manager Server 10.1 4117
----------------------------------------------------------------------------
Disclaimer: No express or implied warranty is made by Sybase or its
subsidiaries with regard to any recommendations or information presented in
SYBASE Technical News. Sybase and its subsidiaries hereby disclaim any and
all such warranties, including without limitation any implied warranty of
merchantability of fitness for a particular purpose. In no event will Sybase
or its subsidiaries be liable for damages of any kind resulting from use of
any recommendations or information provided herein, including without
limitation loss of profits, loss or inaccuracy of data, or indirect special
incidental or consequential damages. Each user assumes the entire risk of
acting on or utilizing any item herein including the entire cost of all
necessary remedies.
Staff
Principal Editor: Leigh Ann Hussey
Contributing Writers:
Lance Andersen, Peter Dorfman, Sekhar Prabhakar, Loretta Vibberts, Elton
Wildermuth
Send comments and suggestions to:
SYBASE Technical News
6475 Christie Avenue
Emeryville, CA 94608
or send mail to tech...@sybase.com
Copyright 1996 © Sybase, Inc. All Rights Reserved.
Q10.3.2: TECHNICAL NEWS
Special Supplement
February, 1996
_________________________________________________________________
This supplement to the SYBASE Technical News contains important
information for those about to migrate to the System 11 release. If
needed, duplicate this supplement and distribute it to others in your
organization. These changes are also documented in more detail in the
SQL Server Reference Manual released with System 11, in What's New in
Sybase SQL Server Release 11.0?, and in the Release Bulletin.
SQL Server 11 Database and Application Migration Checklist
If you plan to upgrade to SQL Server release 11.0, keep in mind the
following changes and new features as you prepare your existing
installation for the upgrade.
Migration Issues from System 10 and Earlier Releases
* Databases Online / Offline
* New File for Configuration Values
* Deadlock Checking Period
* New page utilization percent Parameter
* Query Processing Changes
* Memory and Cache
* sybsystemprocs Changes
* New and Changed Error Messages
* New Keywords
* Backup Server Changes
* New Output from System Stored Procedures
Migration issues from releases prior to System 10 only
* Dumps and Loads are Handled Differently
* Remote Connections are Automatic
* Backup Server Must be Started/Stopped
* Backup Server in the Interfaces File
* The null Device Goes Away
* Changes to Dump Scripts
* Loading from Multiple-Tape Devices
* No dump tran to Device After Non-Logged Text Writes
* No Dumps from Within Transaction
* "Run" File Name Change
* New Database for Stored Procedures
* Thresholds
* New Login/Password Protocols
* New create table Permission
* New numeric Datatype
* Display Format Changes
* Online Datatype Hierarchy
* Conversion Changes
* Change to set arithabort/arithignore
* Changes in Subquery Processing
* Change in Comment Protocol
* Change in Permitted Syntax
* No more NULL Column Headings
* More Consistency Required for Correlation Names
Last Minute Checklist
Important Steps After the Upgrade
_MIGRATION ISSUES FROM SYSTEM 10 AND EARLIER RELEASES_
This section applies to you if you are migrating from SQL Server
release 10.0, or any release prior to 10.0, to release 11.0.
_DATABASES ONLINE / OFFLINE_
Beginning with SQL Server release 11.0, as part of the automatic
upgrade mechanism, a database has two states, online and offline.
Issuing a load database command takes a database offline. If you have
scripts that load databases, you must add an online database command
to your script to make the database available again after the load
sequence completes. A load sequence consists of a load database
execution and a complete set of load transaction statements.
_NEW FILE FOR CONFIGURATION VALUES_
In releases prior to SQL Server release 11.0, SQL Server stored
configuration values in the first page of the master device, known as
the "config block". Most of these values have been moved to a flat
file known as the configuration file. As you upgrade, there are
several things to keep in mind regarding this file.
* Backing up the master database does not back up the configuration
file. You must either back up your configuration file separately
and restore it when you load your database, or else, after loading
a master database, you must issue sp_configure with the restore
option and shutdown and restart SQL Server.
* Some of the configuration parameters available through
sp_configure have new names. For example, memory is now called
total memory. If you run sp_configure memory, value, you will get
this error: "Configuration option is not unique." If you have
scripts that use sp_configure to set or report on configuration
parameters, you will need to change them if the names have
changed. You should test all your scripts that use parameter names
listed in the table "New configuration parameter names" in Chapter
3, "Changes That May Affect Existing Applications," of What's New
in Sybase SQL Server Release 11.0?
* The reconfigure command is no longer required after running
sp_configure. Any of your scripts that include reconfigure will
continue to work; the reconfigure command is ignored. You may want
to consider removing reconfigure commands from your scripts now,
however, as they may not be supported in future releases.
* If you currently set a trace flag in your runserver file, it may
now need to be set using sp_configure or by editing the
configuration file. For example; if you use a trace flag to print
deadlock information to your error log (-T1204 in your runserver
file on UNIX), you must remove it from your runserver file and set
deadlock information printing with sp_configure or by editing your
configuration file. The 1204 trace flag in the runserver file will
no longer work. You should check whether other trace flags you are
currently using have been converted to the configuration file and
reset them after you upgrade. Some of these trace flags are 1603,
1610, and 1611. Trace flags that are now configuration parameters
are listed in Table 3-2, "New configuration parameter names" in
Chapter 3, "Changes That May Affect Existing Applications," of
What's New in Sybase SQL Server Release 11.0?
* The buildmaster executable no longer supports the -y and -r flags.
You must use sp_configure or the configuration file in place of
these flags. If you have scripts that use these flags, you must
rewrite them using sp_configure, or save and edit copies of the
configuration file.
Refer to "Setting Configuration Parameters" in the System
Administration Guide for information about the configuration file and
sp_configure options.
_DEADLOCK CHECKING PERIOD_
SQL Server release 11.0 introduces a new configuration parameter,
deadlock checking period. SQL Server performs deadlock checking after
a minimum period of time for any process waiting for a lock to be
released. By default, this minimum period of time is 500 milliseconds,
but you can change this parameter with deadlock checking period. If
you expect your applications to deadlock infrequently, you can reduce
overhead cost by delaying deadlock checking. However, increasing
deadlock checking period causes longer delays before deadlocks are
detected.
SQL Servers prior to release 11.0 initiated deadlock checks as soon as
a task had to wait for a lock. To get the same behavior in release
11.0, set the deadlock checking period to 0 in the configuration file.
_NEW PAGE UTILIZATION PERCENT PARAMETER_
A new configuration option, page utilization percent, saves time by
allocating new extents rather than searching the OAM page chain. This
makes page allocation faster, but may waste space.
The default behavior of previous versions of SQL Server is always to
search the OAM page chain for unused pages before allocating a new
extent. To keep this behavior in SQL Server release 11.0, set the page
utilization percent to 100 in the configuration file.
_QUERY PROCESSING CHANGES_
A new strategy known as MRU (most recently used or fetch-and-discard)
is available to the optimizer. This strategy is used in cases where a
large query would overwrite heavily used pages in cache.
For example, on SQL Server releases prior to 11.0, users running small
transactions often find the necessary pages in cache (avoiding
physical I/O). When another user runs select * from a very large
table, the cache is overwritten with pages from this table. This
forces the other users' queries to use more physical I/O because their
pages are no longer in cache.
The MRU strategy is designed to reuse the same buffers in cache and to
avoid overwriting all existing pages. You can execute set showplan on
and then run your query to see what plan the optimizer chooses. If you
see LRU (least recently used), your SQL Server is running with
pre-11.0 behavior; if you see MRU, you are running with the new
behavior. You may override the MRU plan if you are unhappy with its
performance by using the lru option in queries, as described in the
section on select in the SQL Server Reference Manual. To get pre-11.0
behavior for your queries, construct it as follows:
select * from table (index table prefetch 2 lru)
_SUBQUERY PERFORMANCE CHANGES_
Subquery handling has been improved for SQL Server release 11.0. For
most subqueries, SQL Server 11.0 should give you better performance
than 10.x. You may see different results in some cases because of bugs
that were fixed in SQL Server release 11.0. Test all your subqueries
under SQL Server release 11.0 before transferring production databases
to the new system.
_________________________________________________________________
Note
If you notice performance degradation after upgrade, check your
data cache and increase it if necessary. SQL Server 11.0 needs
more memory than 10.0, and will take memory from the data cache if
it doesn't have enough, causing the cache to shrink.
Subqueries are no longer allowed in updatable cursors.
One type of subquery may be slower in 11.0 than 10.x: this involves an
expression subquery where the outer table is very large and has few
duplicate correlation values, the inner table is small, and the
subquery contains an aggregate. In this case, the optimizer will not
flatten the query to be processed as a join. Such a query might look
like this:
select * from huge_table where x=
(select sum(a) from tiny_table
where b = huge_table.y)
To get faster results, you can reformulate the query to mimic the
behavior of System 10, as follows:
select huge_table.y, s=sum(a)
into #t
from huge_table, tiny_table
where b=huge_table.y
group by huge_table.y
select huge_table.*
from huge_table, #t
where x=#t.s
and huge_table.y=#t.y
If you have stored procedures, triggers or views that contain
subqueries, they will not automatically be upgraded to take advantage
of the new subquery changes. Until you drop and re- create the
compiled object, it will continue to behave as it did in earlier
releases. Once you drop and re-create it you will see the new
performance and results expected from an 11.0 subquery. If you are
upgrading a test system you may want to rename your old stored
procedure, create the new 11.0 style procedure and run tests to see
the differences in performance and results.
_________________________________________________________________
_WARNING!_
After upgrading a production system, drop, re-create, and test the
behavior of all compiled objects containing subqueries. If you
leave your procedure with the old behavior and then have to drop
and re- create for some reason, you will see the new 11.0
behavior. There is no way to go back to the old behavior once the
procedure is dropped and re-created. If the new behavior does not
work well for your production system, you are stuck. It is best to
test out procedures that contain subqueries and make any changes
necessary for your application before upgrading your production
system.
Once the upgrade is complete, drop and re-create all compiled objects
containing subqueries.
To determine which compiled objects contain subqueries and whether
they are running at 11 level or pre-11 level, use the stored procedure
sp_procqmode. Refer to the SQL Server Reference Manual for details.
The output for set showplan on has been changed. If you have any
applications that rely on the output generated by this command, they
may need to be changed.
set dup in subquery No Longer Supported
The set dup in subquery command introduced in SQL Server 10.0 will no
longer be supported. If you have applications that use it you will
receive a warning message and your subqueries will no longer return
duplicates. You may have used this option to obtain better
performance. Because of subquery processing changes introduced in this
release, if you really want duplicates, rewrite your query as a join.
You should see better performance in SQL Server release 11.0 for these
types of queries.
Only 16 Subqueries on One Side of a union
A new restriction has been imposed. You are now allowed only 16
subqueries on one side of a union. This should not affect most
customers because you are only allowed 16 tables within one query.
This should affect you only if you have more than 16 subqueries and
some of them have no from clauses.
Subqueries and NULL Results
Prior to SQL Server release 11.0, a correlated expression subquery in
the set clause of an update returned 0 instead of NULL when there were
no matching rows. SQL Server release 11.0 correctly returns NULL when
there are no matching rows, and raises an error. If you have
applications that depend on the pre-11.0 behavior, you will need to
rewrite them.
For example, the following trigger tries to update a column that does
not permit NULL values:
update t1
set c1 = (select max(c1)
from inserted where t1.c2 = inserted.c2)
The correct trigger is:
update t1
set c1 = (select isnull(max(c1), 0)
from inserted
where t1.c2 = inserted.c2)
The where clause updates t1.c1 to 0, if the subquery does not return
any correlation values from the outer table t1.
Memory and Cache
More memory is used for the Sybase kernel and for internal structures
including the new user log cache. You may need to add more total
memory to your server to maintain the same performance as your
previous release.
Also, compiled objects have grown in SQL Server release 11.0 and grew
considerably in 10, so you may need to enlarge your procedure cache to
maintain the same performance.
sybsystemprocs Changes
Your sybsystemprocs database will need to be larger than it was for
release 10.x SQL Server, to make room for the new system stored
procedures in release 11. Check your SQL Server Installation Guide for
the correct size, and alter sybsystemprocs before beginning the
upgrade. If sybsystemprocs is not the correct size, sybinit will fail.
During upgrade from System 10 to SQL Server release 11.0, all system
stored procedures are dropped from sybsystemprocs. If you have
customized any of your system stored procedures, you will lose them in
this process unless you rename them before the upgrade. If you do not
rename them, you will have to re-customize them after the upgrade.
_NEW AND CHANGED ERROR MESSAGES_
Many error messages have been added and some have had their text
changed to improve their intelligibility. If you rely on the text of
any error messages within your applications, you should check to be
sure they have not changed. You can select * from sysmessages on SQL
Server release 11.0 to see the text changes.
_NEW KEYWORDS_
Many new keywords were added to the SQL Server release 10, most to
support ANSI 89 features. There are also two new keywords added in SQL
Server release 11.
* Any database whose name is a new keyword must have its name
changed before you upgrade.
* Any object (table, column, and so on) whose name conflicts with a
new keyword will yield a syntax error when accessed under a
release 11 SQL Server. We recommend that you change their names
before upgrade; you will also have to change any applications that
reference those objects. For example:
select user from table_x
will yield a syntax error because "user" is a keyword as of System
10.
SQL Server release 11 includes a stored procedure, sp_checkreswords,
which checks for identifier names that are keywords. Use sybinit to
run this stored procedure before you start the upgrade itself. Load
the Sybase files with sybload, begin a sybinit session (as described
in the SQL Server Installation Guide), and select "Check for reserved
word conflicts" from the "SQL Server Upgrade" menu. If your existing
databases use any of the new keywords as identifiers, sybinit displays
the following message, including the number of conflicts it found:
_Warning:_ x conflicts with 10.0 reserved
words were found.
Sybase suggests that you resolve these conflicts before
upgrading the SQL Server. Run `sp_checkreswords' on each
database for more info.
You must change database names that conflict with reserved words
immediately, because the upgrade will fail if database names conflict
with reserved words.
We also recommend that you change any other object names (tables,
columns, and so on) that are reserved words before upgrading. Remember
that you will have to change all applications that reference that
object also. See the SQL Server Reference Manual for information on
changing object names.
If you choose not to change other object names, you can use the set
quoted_identifier option. You must add the following set command to
all your applications and put quotes around all keywords when you
issue your T-SQL statements. For example:
set quoted_identifier on
select "user" from table_x
_WARNING!_
The sp_checkreswords procedure will not check the contents of
stored procedures. For example, if you have a procedure such as
the following:
create procedure x as
create table user (a int)
you will receive a syntax error on running the procedure. Test all
your stored procedures and triggers to be certain that they use no
keywords as identifiers.
sybinit installs sp_checkreswords automatically. If you subsequently
want to run reserved word checks, use the following command sequence
for each database you want to check:
% isql -Usa -Ppassword -Sservername
1> use database_name
2> go
1> sp_checkreswords
2> go
_NEW OUTPUT FROM SYSTEM STORED PROCEDURES_
Many of the existing system stored procedures provide new and improved
output. If you are currently running them within your applications,
you should check to see what they report under SQL Server release
11.0.
_BACKUP SERVER CHANGES_
The Backup Server has a new feature to deal with tape devices
unfamiliar to it. If you dump a database to a tape device that is not
one of the devices mentioned in the System Administration Guide
Supplement for your platform, and Backup Server cannot determine the
device type, the dump command fails.
Consequently, when you first dump to a new tape device, you should use
the with init option to the dump command. It will take some time for
the Backup Server to read and write to the tape in order to determine
how to communicate with it. When Backup Server finishes this first
test, it will write a line to the new tape configuration file, called
$SYBASE/backup-tape.cfg by default, which is created during upgrade or
install. You should manage this file as part of the backup strategy
for your site.
_MIGRATION ISSUES FROM RELEASES PRIOR TO SYSTEM 10 ONLY_
This section applies specifically to you if you are migrating to SQL
Server release 11.0 from a SQL Server release prior to 10.0. You
should review both this section and the previous section, ``Migration
Issues from System 10 and Earlier Releases''. These features were
added in System 10, and also exist in SQL Server release 11.0.
_DUMPS AND LOADS ARE HANDLED DIFFERENTLY_
Dumps and loads are now handled by a separate process called the
Backup Server. This runs in addition to SQL Server, so you may need to
increase memory limits. When upgrading your database, you must install
a Backup Server through the install procedure (sybinit) or you will be
unable to do dumps and loads on your System 10 or 11 SQL Server.
On UNIX platforms, additional small processes called sybmultbuf will
be started by the Backup Server to communicate with your database and
dump devices.
You should run some tests with dump and load to be sure your scripts
work and to monitor the additional machine resources needed to do a
dump or load on your system.
Recovery procedures on system databases have changed with the Backup
Server and the sybsystemprocs database. Consult your System
Administration Guide and test your procedures for recovery.
_REMOTE CONNECTIONS ARE AUTOMATIC_
Remote connections are now automatically enabled when SQL Server is
upgraded or installed. This is necessary so that SQL Server can
communicate with Backup Server. However, the `allow remote access"
configuration parameter is now dynamic, so you will no longer have to
reboot SQL Server in order to change this behavior.
_BACKUP SERVER MUST BE STARTED/STOPPED_
You must now start and stop Backup Server, as well as the SQL Server.
The install or upgrade program will set up the appropriate scripts to
start Backup Server.
There is an option in the shutdown command to stop Backup Server:
shutdown [backup_server] [with {wait|nowait}]
You should initiate your own procedures for starting and stopping the
Backup Server process as appropriate. If you will be using threshold
procedures to dump transaction to a device, you should always have
Backup Server running.
_BACKUP SERVER IN THE INTERFACES FILE_
You must now maintain entries in your interfaces files for Backup
Servers you use. The install or upgrade program will make the
necessary entry for your local machine, but you may need to determine
if those entries need to be distributed to other copies of your
interfaces file.
_THE NULL DEVICE GOES AWAY_
The device /dev/null on UNIX or NL on VMS will no longer be available.
sybinit will remove the default entries for these devices from the
sysdevices table. Check any scripts that do dumps to be sure you are
not using one of these default devices or any other dump device that
points to /dev/null or NL. If you do not change these scripts, your
dumps will fail with the following error:
Backup Server: 4.56.2.1: Device validation error: couldn't obtain
tape drive characteristics for device /dev/null, error: Invalid
argument
_CHANGES TO DUMP SCRIPTS_
Backup facilities have changed as of SQL Server release 10.0. This
section describes the minimum changes you must make to existing dump
scripts.
The single feature that can most affect your current use of tapes and
dump commands is Backup Server's ability to make multiple dumps to a
single tape. The new dump is placed after the last existing file on
the current tape volume.
Here are some guidelines for backing up your databases immediately
after upgrading:
* If you use new tapes, or tapes without ANSI labels, your pre-10.0
dump scripts overwrite the entire tape.
* If you use single-file media (for example, quarter-inch cartridge)
with ANSI labels, and the expiration dates on the tapes have
expired, pre-10.0 dump scripts will overwrite the tapes.
* If the expiration date on a single-file tape has not been reached,
you will be asked to confirm the overwrite; a positive response
will overwrite the existing tape; a negative response initiates a
request for a volume change, and tests are repeated on the new
volume.
* If you use multi-file tape media, and do not change your dump
scripts, the dump will be appended to the existing files on the
tape.
* If you want to overwrite existing tapes that have ANSI labels, you
must append the with init clause to existing dump commands:
dump database mydb
to datadump1
with init
You can also use operating system commands to erase or truncate the
tape.
_LOADING FROM MULTIPLE TAPE DEVICES_
A second connection to SQL Server is now required when loading a
database to a tape device that spans multiple tapes. This allows you
to issue the sp_volchanged stored procedure (which notifies Backup
Server that the tape operator has finished handling a volume, such as
changing a tape).
If you execute the command load database master to a tape device that
requires a volume change, you will need a second running SQL Server to
issue the sp_volchanged stored procedure. This is because SQL Server
must be in single user mode to load master so you cannot login a
second time to send the volume change request. For this reason, Sybase
Technical Support strongly recommends you ensure your tape device has
enough space to hold the full dump of master before you dump the
master database, or else that you use a disk device for your master
backups.
_CHANGES TO RENAMING DATABASES_
If any table in the database referencesŻor is referenced byŻa table in
another database, sp_renamedb cannot rename the database. It produces
the following error message:
Database `database_name' has references to other
databases. Drop those references and try again.
Execute the following query to determine which tables and external
databases have foreign key constraints on primary key tables in the
current database:
select object_name(tableid), db_name(frgndbid)
from sysreferences
where frgndbname is not null
Execute the following query to determine which tables and external
databases have primary key constraints for foreign key tables in the
current database:
select object_name(reftabid), db_name(pmrydbid)
from sysreferences
where pmrydbname is not null
Before renaming the database, you must use alter table to drop the
cross-database constraints in these tables. See sp_renamedb in the SQL
Server Reference Manual for more information about renaming databases.
No dump tran to Device After Non-Logged Text Writes
dump tran to a device is no longer allowed after a non-logged text
operation.
If you use both on the same database, you must change your text writes
to be logged or you will be unable to use dump tran as part of your
backup scheme. For details on changing your text writes, consult the
SQL Server Reference Manual (writetext command), and either the
DB-Library Reference Manual (dbwritetext(), and so on) or Open Client
Client-Library Reference Manuals (ct_send_data(), and so on), as
needed.
_NO DUMPS FROM WITHIN TRANSACTION_
dump database and dump transaction are no longer allowed within a
userdefined transaction.
_"RUN" FILE NAME CHANGE_
On UNIX platforms, the default file that startserver looks for to
start your server is now called RUN_SYBASE rather than RUNSERVER. If
you have a file called RUNSERVER in your install directory, during
upgrade sybinit will change its name to RUN_SYBASE. If you use the
startserver -fRUNSERVER command to start your server, you must change
it to startserver -fRUN_SYBASE. If you are starting your server
automatically when you boot your machine, make sure you change your
system startup file if necessary.
_NEW DATABASE FOR STORED PROCEDURES_
System stored procedures are stored in a new database called
sybsystemprocs. Find space for it on an existing device or find a new
physical device to give to sybinit before you upgrade. You may also
need to modify your dbcc, backup and recovery procedures to include
this database.
If you have your own system stored procedures, you may want to move
them to the new database, although it is not required. If you do
decide to move them, you must add the database name to any tables you
reference that exist in master. You also need to include a check such
as:
if @@trancount > 0
begin
print "Can't run this procedure from within a transaction"
return 1
end
In addition, you should not have any changes to master database tables
within a transaction. Doing so can cause recovery problems on the
master database.
_THRESHOLDS_
The threshold manager is a new tool for managing space in segments,
particularly the log segment, but you need to decide how to use it
before you upgrade. In particular you should deal with the "last
chance threshold" on the log before you upgrade. The default behavior
is to suspend all users when the last chance threshold is reached; if
you encounter the last chance threshold, all users will just hang
until some action is taken, instead of getting the 1105 error. Decide
whether that is the behavior you want and test a last chance threshold
procedure before you upgrade your production databases.
You must use the sp_thresholdaction stored procedure to define an
action, such as dump transaction, when the last chance threshold is
reached. If you do not do so, when you run out of space in your log,
all users will hang indefinitely. Below is a sample threshold
procedure that you can tune to suit your installation. This example
creates a threshold procedure that dumps the transaction log to a tape
device when the last chance threshold is reached:
create procedure sp_thresholdaction
@dbname varchar(30),
@segmentname varchar(30),
@space_left int,
@status int
as
dump transaction @dbname to "/dev/rmt4"
Remember, even if you have a last chance threshold procedure to dump
the log, you will have a problem if you have an open transaction
filling the log. The dump transaction command will not clear the log
because of the open transaction, and the user who has the open
transaction will be in suspend state and so will keep the transaction
open. If this occurs, you can use the lct_admin function documented in
the "System Functions" section of the SQL Server Reference Manual.
That document also describes how to set thresholds with
sp_addthreshold.
You will know that users are hung and have reached the last chance
threshold because sp_who shows a status of "LOG SUSPEND." In addition,
SQL Server will write messages to the error log listing how many tasks
are sleeping because the log is full.
You can change the last chance threshold behavior for a database to
the old behavior of "abort the transaction with an 1105 error" by
setting "abort xact when log is full" on with sp_dboption.
Tip for Bulk Copy Users
Bulk Copy handles input records in "batches" which are transactions.
This is true whether or not the bcp inserts are logged. When loading a
large number of records, use the bcp ... in ... -b records batch
option, and set the number of records to some reasonable value. This
reduces the chance that a bcp command will hold a long transaction and
block dump transaction from clearing enough log space.
_NEW LOGIN/PASSWORD PROTOCOLS_
New logins and password changes require a minimum 6-byte password.
Existing passwords less than 6 bytes are left alone during upgrade,
but new password changes will enforce the 6-byte minimum.
_NEW CREATE TABLE PERMISSION_
Beginning with the System 10 SQL Server, create table permission is
explicitly granted for all users on tempdb. This permission is granted
at server startup time.
_NEW NUMERIC DATATYPE_
A new numeric datatype is now available in the System 10 SQL Server.
Unlike float, it is platform independent and exact.
If you give the System 10 SQL Server a constant such as:
5.1
it will be assigned the numeric datatype rather than float.
If you want float, you must represent your constant as:
5.1e0
The following mathematical functions now return a value of type
numeric rather than float:
* abs
* ceiling
* degrees
* floor
* power
* radians
* round
* sign
If you are running a pre-System 10 front end with a System 10 Server,
numeric datatype value will be mapped to float on the front end.
_DISPLAY FORMAT CHANGES_
The isql display format for approximate-numeric datatypes now displays
additional digits of precision. Maximum units of precision for storage
and display are machine dependent. real values now display up to 9
digits of precision; float values, up to 17 digits. Values are rounded
to the last digit on display. Previously, only six places to the right
of the decimal were displayed.
All values requiring more digits than the maximum are displayed in
scientific notation, that is, a float value "1e18" is displayed as
such, rather than 1000000000000000000.000000. Note that the new exact
numeric types, decimal and numeric, display the entire number.
_ONLINE DATATYPE HIERARCHY_
You can get the datatype hierarchy for SQL Server release 11.0 by
running the following query:
select name, hierarchy
from systypes
order by hierarchy
name hierarchy
---------------------------- ---------
floatn 1
float 2
datetimn 3
datetime 4
real 5
numericn 6
numeric 7
decimaln 8
decimal 9
moneyn 10
money 11
smallmoney 12
smalldatetime 13
intn 14
int 15
smallint 16
tinyint 17
bit 18
varchar 19
sysname 19
nvarchar 19
char 20
nchar 20
varbinary 21
timestamp 21
binary 22
text 23
image 24
(28 rows affected)
In pre-System 10 SQL Servers, money was above float in the hierarchy.
It is now below both float and numeric. The following query:
select $12*8.9
returns a result of type numeric. In pre-System 10 SQL Servers it
returned money. Likewise, the following query:
select $12*8.9e0
returns a result of type float. In pre-System 10 SQL Servers it
returned money.
If you want the pre-System 10 behavior you must use convert:
select $12*convert(money,$12*8.9e0)
_CONVERSION CHANGES_
As of System 10, all conversions to character succeed only if no
decimal digits are lost. In previous versions of the server, floating
point to character conversions allowed some truncation without
warning.
Change in Money Conversion
All conversions to money datatypes round to four places.
When an explicit conversion of one numeric value to another results in
loss of scale, the results are truncated without warning. For example,
explicitly converting a float to an integer causes SQL Server to
truncate all values to the right of the decimal point.
Change in Integer-to-Character Conversion
Conversions from integer to character now return an error if an
overflow occurs. They formerly returned a buffer of "*".
Change to set arithabort/arithignore
The set arithabort and set arithignore commands have changed behavior
in some cases. If you are using these set commands, you should test
and understand the behavior.
_CHANGES IN SUBQUERY PROCESSING_
Changes were made in subquery processing to support full ANSI
compatibility as well as fix some bugs in the SQL Server. These
changes may result in different results, as well as performance
differences. These changes are detailed below.
You should test subqueries used in your applications to understand the
new behavior.
Changes to Subqueries Using IN/ANY
In pre-System 10 SQL Servers, subqueries using in or any would return
duplicates if the values being select contained duplicates.
For example, using the pubs database:
select pub_name
from publishers
where pub_id in
(select pub_id
from titles)
In pre-System 10 SQL Servers this query returned:
pub_name
-------------------
New Age Books
New Age Books
New Age Books
New Age Books
New Age Books
Binnet & Hardley
Binnet & Hardley
Binnet & Hardley
Binnet & Hardley
Binnet & Hardley
Binnet & Hardley
Binnet & Hardley
Algodata Infosystems
Algodata Infosystems
Algodata Infosystems
Algodata Infosystems
Algodata Infosystems
Algodata Infosystems
As of System 10, this query returns:
pub_name
-------------------
New Age Books
Binnet & Hardley
Algodata Infosystems
Change in Evaluation of not in
ANSI states that if a subquery returns a NULL, a not in should
evaluate to UNKNOWN or FALSE. Here is an example, using the pubs
database:
select pub_id
from publishers
where $100.00 not in
(select price
from titles
where titles.pub_id=publishers.pub_id)
In pre-System 10 SQL Servers, this query returns:
pub_id
--------
0736
0877
1389
In the System 10 SQL Server, this query returns:
pub_id
--------
0736
Change in Results of Subquery with or...exists/in/any
The pre-System 10 SQL Server returned the wrong results when an
exists, in, or any subquery appeared under an or.
Given the following tables and contents:
full_table: x y empty_table: z
---- ---- -----
5 2
with the following example query:
select x
from full_table
where y in
(select z
from empty_table)
or y = 2
In pre-System 10 SQL Servers, this query returns:
x
-----
no rows returned
As of System 10, this query returns:
x
-----
5
Change in Evaluation of >ALL and <ALL
ANSI states that >ALL and <ALL should be TRUE when a subquery returns
no rows. Here is an example against the pubs database:
select title
from titles
where advance > all
(select advance
from publishers, titles
where titles.pub_id = publishers.pub_id
and pub_name="No Such Publisher")
In pre-System 10 SQL Servers, this query returns:
title
---------------------------
no rows returned
As of System 10, this query returns all rows in the titles table:
title
---------------------------
But Is It User Friendly?
Computer Phobic and Non-Phobic Individuals: Behavior Variations
Cooking with Computers: Surreptitious Balance Sheets
Emotional Security: A New Algorithm
Fifty Years in Buckingham Palace Kitchens
Is Anger the Enemy?
Life Without Fear
Net Etiquette
Onions, Leeks, and Garlic: Cooking Secrets of the Mediterranean
Prolonged Data Deprivation: Four Case Studies
Secrets of Silicon Valley
Silicon Valley Gastronomic Treats
Straight Talk About Computers
Sushi, Anyone?
The Busy Executive's Database Guide
The Gourmet Microwave
The Psychology of Computer Cooking
You Can Combat Computer Stress!
Change in Evaluation of Aggregates with exists
In pre-System 10 SQL Servers, queries that have both aggregates and
exists subqueries sometimes return the wrong answer. This happens for
correlated subqueries, where there are duplicates in the subquery.
Here is an example from the pubs database:
select count(*)
from publishers
where exists
(select * from titles
where titles.pub_id = publishers.pub_id)
In pre-System 10 SQL Servers, this query returns 18; as of System 10,
this query returns 3.
Change in Evaluation of in Subqueries with select distinct
Prior to System 10, correlated in subqueries using distinct would
cause the outer query not to return any rows. Here is an example from
the pubs database:
select pub_name
from publishers
where pub_id in
(select distinct pub_id
from titles
where titles.pub_id = publishers.pub_id)
In pre-System 10 SQL Servers, this query returns:
pub_name
---------------------------
no rows returned
In the System 10 SQL Server, this query returns:
pub_name
---------------------------
New Age Books
Binnet & Hardley
Algodata Infosystems
Change In Evaluation of between
ANSI standard states that a between predicate of the form:
expr1 between expr2 and expr3
is equivalent to:
expr1 >= expr2 and expr1 <= expr3
The pre-System SQL SQL Server switches expr2 and expr3 automatically
if it knows that expr2 > expr3 at compile time. As of System 10, SQL
Server will no longer do that switch.
For example:
create table demo (id int)
insert into demo values (250)
select id from demo where id between 400 and 200
In pre-System 10 SQL Servers, this query returns:
id
---------------------------
250
As of System 10, this query returns:
id
---------------------------
no rows returned
_CHANGE IN COMMENT PROTOCOL_
ANSI comments are started with two or more consecutive hyphens (--)
and are terminated by a <newline>.
ANSI comments co-exist with the Transact-SQL® comments as of the
System 10 SQL Server.
Certain mathematical expressions will return different results in the
System 10 SQL Server because of the support of ANSI comments.
For example:
select 5--2
In pre-System 10 Servers, this query returns 7.
As of System 10, this query returns 5 because --2 is considered a
comment.
You can use the following query to get back the value 7 under the
System 10 SQL Server:
select 5-(-2)
Alternately, you can construct the query with extra spaces:
select 5 - -2
_CHANGE IN PERMITTED SYNTAX_
In pre-System 10 SQL Servers the following syntax was allowed:
select * from table1, table1
where clause
ANSI states this syntax is invalid; therefore this query will return a
syntax error in System 10. The correct syntax in System 10 is:
select * from table1 t1, table1 t2
where clause
The following update statement also returns a syntax error in System
10:
update table1
set a = a + 1
from table1
where b = 5
The correct syntax is:
update table1
set a = a + 1
from table1 t1
where t1.b=5
_NO MORE NULL COLUMN HEADINGS_
Previous SQL Server releases allowed NULL column headings in tables
created using select into. As of System 10, you must provide a column
heading that is a valid SQL identifier. Check all applications that
use select into.
Examples of select list items that require column headings are:
* An aggregate function, such as avg(advance)
* An arithmetic expression, such as colname * 2
* String concatenation, such as au_lname + ", " + au_fname
* A built-in function, such as substring(au_lname,1,5)
* A constant, such as "Result"
There are three ways to specify column headings:
select title_id, avg_advance = avg(advance)
into #tempdata
from titles
select title_id, avg(advance) avg_advance
into #tempdata
from titles
select title_id, avg(advance) as avg_advance
into #tempdata
from titles
_MORE CONSISTENCY REQUIRED FOR CORRELATION NAMES_
In pre-System 10 releases, statements that specified correlation names
but did not use them consistently still returned results. The
following statement now returns errors in accordance with ANSI:
select title_id
from titles t
where titles.type = "trad_cook"
The correct query is:
select title_id
from titles t
where t.type = "trad_cook"
When a subquery includes this correlation, no error is reported, but
queries may return different results than a pre-System 10 Server:
select *
from mytable
where columnA =
(select min(columnB) from mytable m
where mytable.columnC = 10)
In pre-System 10 releases, mytable.columnC in the above subquery would
have referred to the mytable in the subquery. In System 10,
mytable.columnC refers to the outer table mytable.
If the query needs to refer to mytable in the subquery, construct it
as follows:
select *
from mytable
where columnA =
(select min(columnB) from mytable m
where m.columnC = 10)
_LAST MINUTE CHECKLIST_
The information in this section applies to upgrades from 10.x and
earlier releases of SQL Server. Perform the tasks listed below to
avoid known causes of failure.
Read the Documentation
Read the following documents for important information about your
upgrade:
* What's New in Sybase SQL Server Release 11.0?
* Release Bulletin
* SQL Server installation and configuration guide
If you are upgrading from a pre-10.x SQL Server, the installation and
upgrade utility, sybinit, will not be familiar to you. It is explained
in the SQL Server installation and configuration guide.
Backup All Databases
Back up all databases in case of upgrade failure. A failed upgrade may
corrupt your databases, so complete backups are essential.
Mirror and Unmirror
In addition to your backups, we recommend mirroring SQL Server if your
environment permits. Restoring your databases from the mirror is much
quicker than restoring from backups. Use the following syntax:
disk mirror
name = "device_name", mirror = "physical_name"
Then, unmirror all Sybase mirrors before upgrading. Use the following
syntax:
disk unmirror
name = "device_name", mode = remove
See the SQL Server System Administration Guide for instructions on
mirroring. See the SQL Server Reference Manual for information about
the disk mirror, unmirror, and remirror commands.
Increase SQL Server Memory
Various changes in SQL Server 11.0 have increased its memory
requirements. These changes include:
* New user log cache
* Larger dataserver binary
* Previously existing structures which are now larger (such as
locks)
We recommend the following approach to adjusting your memory for
upgrade:
1. Before making any upgrade-related changes, look at the error log
to get a profile of the memory usage on your production SQL
Server. Look for messages that give the buffer cache, procedure
cache, and procedure header sizes. Record these values to use
after the upgrade.
2. Next, to ensure that you have enough memory to successfully
complete the upgrade to 11.0, use sp_configure to change the
following configuration parameters to their default values:
Configuration Parameter Default Value
user connections 25
locks 500
open objects 5000
memory at least 7680 (15 MB)
Use commands like the following to change the parameters:
sp_configure "user connections", 25
3. After making these changes to maximize available memory, check the
error log again and record how much cache you have now. You will
use this information to configure your cache after the upgrade.
4. If you are upgrading from a pre-10.x SQL Server and your user
databases have a lot of stored procedures, triggers, views, or
rules, you may need to increase the stack size because remapping
stored procedures during upgrade requires extra stack space. Do
the following:
+ Record your current stack size.
+ Increase stack size. For example, to increase stack size to
200K, enter:
sp_configure 'stack size', 204800
5. After the upgrade, perform the tasks described in ``Important
Steps After the Upgrade'' below to return your memory to its
normal configuration.
See the "How SQL Server Uses Memory" in the SQL Server Troubleshooting
Guide for a discussion of tools for assessing memory usage. See the
System Administration Guide and the Performance and Tuning Guide for
more information about SQL Server memory usage.
_ADDITIONAL PRE-UPGRADE TASKS_
Perform the following additional tasks before beginning your upgrade:
* If you are upgrading from a pre-10.x SQL Server, check that you
have extra space in all your databases for stored procedures and
other objects. Compiled objects, such as stored procedures,
triggers and rules, will be remapped and will take up more disk
space than previously.
* If you are upgrading from release 10.x, disable replication. If
replication is enabled and your log has not been cleared, the
upgrade will fail. The Release Bulletin details the steps
necessary to disable replication. See also the Replication Server
Commands Reference.
* Run the following dbccs on all databases: checkdb, checkalloc, and
checkcatalog. See the SQL Server Reference Manual for instructions
on running dbccs.
* Truncate transaction logs on all databases before running sybinit.
This is a precaution against failure.
* Verify that you have enough space for system tables. If you are
upgrading from SQL Server 10.x, slightly more disk space is
required for the creation of new system tables. Use the "Test
upgrade eligibility" option in sybinit to check that you have
enough disk space. Follow the instructions in the SQL Server
installation and configuration guide.
* Turn off all options on your all databases, with the exception of
tempdb, using sp_dboption. The upgrade requires that you set
select into/bulk copy to true for tempdb. To turn off an option,
use this syntax:
sp_dboption database_name, "option", false
To set select into/bulk copy for tempdb, use the following command:
sp_dboption tempdb, "select into/bulkcopy", true
See the SQL Server Reference Manual for information on sp_dboption.
* If you are upgrading from a pre-10.x SQL Server, check that you
have enough devices configured to create the sybsystemprocs
device. For example, if you have 10 devices configured, and all of
them are already in use, increase devices by 1 as follows:
sp_configure devices, 11
See the SQL Server Reference Manual for information on sp_configure.
* Be sure SQL Server is running and all users are off before
beginning the upgrade.
_IMPORTANT STEPS AFTER THE UPGRADE_
After performing the upgrade according to instructions in the SQL
Server Installation and Configuration Guide, be sure to perform all
the tasks in the following sections.
Reconfigure Memory for Normal Usage
Follow these steps to return your memory parameters to their normal
configurations. Use the record of memory usage you created in the
section "Increase SQL Server Memory".
1. Check the error log to see how much memory is left in cache. By
subtracting this number from the amount you recorded in Step 3 of
``Increase SQL Server Memory'', you can determine how much
additional memory is required by the 11.x SQL Server.
2. Using the baseline information you obtained in Step 1 of
``Increase SQL Server Memory'', reconfigure the memory parameter
as needed to support your usual number of user connections, open
objects, and locks.
3. Use the sp_configure command to reconfigure the resources you
changed in Step 2 back to the usual values needed for your
production environment.
4. Reset your stack size to the size you recorded in Step 4 of
``Increase SQL Server Memory''.
Perform Backup Tasks
Perform the following tasks to back up your databases:
* Install Backup Server. If you upgraded from 10.x and you want to
keep the same port number for your 11.0 Backup Server, shut down
the 10.x Backup Server before you start the 11.0 Backup Server.
See the SQL Server installation and configuration guide for
complete instructions on installing Backup Server.
* After you install Backup Server, verify that SQL Server's default
Backup Server name matches the name you gave Backup Server when
you installed it. If you performed an upgrade from a pre-10.0 SQL
Server, you must be especially careful that SQL Server knows the
name you gave Backup Server. SQL Server needs the name in order to
perform dumps and loads. The upgrade program automatically sets
SQL Server's default Backup Server to SYB_BACKUP. However, you may
have given your Backup Server a different name when you installed
it. If so, use sybinit to reconfigure SQL Server and enter the
correct Backup Server name as the default. Follow the instructions
in the SQL Server Installation and Configuration Guide for
installing a Backup Server and configuring an existing SQL Server.
* Backup all databases immediately so that your dumps are at the
right release level. If necessary, you can load 10.x dumps to a
release 11.0 SQL Server, but you cannot load 4.9.x or 4.2 dumps.
_________________________________________________________________
Disclaimer: No express or implied warranty is made by Sybase or its
subsidiaries with regard to any recommendations or information
presented in SYBASE Technical News. Sybase and its subsidiaries hereby
disclaim any and all such warranties, including without limitation any
implied warranty of merchantability of fitness for a particular
purpose. In no event will Sybase or its subsidiaries be liable for
damages of any kind resulting from use of any recommendations or
information provided herein, including without limitation loss of
profits, loss or inaccuracy of data, or indirect special incidental or
consequential damages. Each user assumes the entire risk of acting on
or utilizing any item herein including the entire cost of all
necessary remedies.
_STAFF_
Principal Editor: Leigh Ann Hussey
Contributing Writers:
Kathy Saunders, Cris Gutierrez
Send comments and suggestions to:
SYBASE Technical News
6475 Christie Avenue
Emeryville, CA 94608
or send mail to tech...@sybase.com
Copyright 1996 © Sybase, Inc. All Rights Reserved.
Q10.3.3
Sybase Technical News Volume 5 Number 2, February 1996
This issue of Sybase Technical News contains new information about your
Sybase software. This newsletter is intended for Sybase customers with
support contracts. You may distribute it within a supported site; however,
it contains proprietary information and may not be distributed publicly. All
issues of Sybase Technical News and the troubleshooting guides are included
on the AnswerBase CD, SupportPlus Online Services Web pages, and the Sybase
PrivateLine forum of CompuServe. Send comments to tech...@sybase.com.
To receive this document by regular email, send name, full internet address
and customer ID to tech...@sybase.com.
In this Issue
Tech Support News/Features
* 1996 Technical Support North American Holiday Schedule
* Change in Publication of Certification/Rollup Information
SQL Server 11.0
* SQL Server 11.0 Network Affinity Feature
* Identity Enhancement
* Creating and Configuring I/O Buffer Pools with sp_poolconfig
* Large I/O for Log and User Log Cache
* How to Use syslogshold
* New Backup Server Auto Tape Configuration Feature
* Dump to Remote Backup Server
* Tape Stacker Support
SQL Server General
* Problems Installing on OpenVMS 6.2
* Problems Parsing Column Name
* Indexes and Dirty Reads
Connectivity / Tools / PC
* Cursor Integrity
* Replication Server NLM Compatibility
1996 Technical Support North American Holiday Schedule
Sybase Technical Support is open on all holidays and provides full service
on many. During the limited-service holidays shown below, Technical Support
will provide the following coverage:
* SupportPlus Preferred and Advantage customers may log all cases; we
will work on priority 1 and 2 cases over the holiday.
* 24x7 and 24x5 Support customers may log priority 1 cases; we will work
on these over the holiday.
* SupportPlus Standard, Desk Top, and Regular Support customers may
purchase Extended-hour Technical Support for coverage over the holiday.
Sybase Technical Support
limited-service holidays Â
U.S. customers
Holiday Date
Memorial Day May 27
Independence Day July 4
Labor Day September 2
Thanksgiving November 28
Christmas December 25
Sybase Technical Support
limited-service holidays  Canadian
customers
Holiday Date
Canada Day July 1
Labour Day September 2
Canadian Thanksgiving October 14
Christmas Day December 25
Boxing Day December 26
If you have questions, please contact Technical Support.
Change in Publication of Certification/Rollup Information
As of this issue, Sybase Technical News will no longer be printing
Certification or Rollup information, in the interest of providing customers
with more up-to-date information than is possible given its quarterly
release schedule. Instead, you can get the information on the CompuServe
Sybase PrivateLine forum and through the SupportPlus Online Services web
pages.
To reach the SupportPlus Online Services web pages, follow these steps:
1. Go to the following URL using Netscape Navigator or any other browser
that supports Secure Sockets Layer (SSL):
https://www-es1.sybase.com/plus/
------------------------------------------------------------------
Note
If you are behind a firewall, your proxy server must also support
SSL.
------------------------------------------------------------------
1. When prompted for your user ID and password, enter them.
2. If you don't have an ID and password for SupportPlus Online Services,
go to the following URL and follow directions there to register
yourself for SupportPlus Online Services:
https://www-es1.sybase.com/registergw.html
You must supply your customer number and email address.
SQL Server 11.0 Network Affinity Feature
SQL Server release 11.0 is informally known as "the performance release"
because many new features have been added to increase performance.
One such new feature is the support for multiple network engines (MNE),
which means that SQL Server processes (referred to as engines) share the
nework I/O load, with the engine that has the fewest connections taking up
the job of network I/O regardless of other tasks that engine may be
performing.
It has been possible, since release 4.8 of SQL Server, to configure for
multiple engines; as of 11.0 , configuring for multiple engines buys you
more in performance, so it may be to your advantage to configure more
engines than you have in the past.
Understanding Network Affinity
Network affinity is the term used to describe how a task is assigned to the
engine that performs its network I/O. For example, say Task1 (an isql
connection or application) logs into SQL Server through Engine 0, but Engine
2 has the fewest actual connections at that moment; Engine 0 assigns Task1
to Engine 2 for its network affinity. Task1 can use any other engine for
subsequent disk I/O, but when it needs to do network I/O, Task1 must do it
from Engine 2, the one for which it has network affinity.
One process of moving network I/O from one engine to another is called
"network affinity migration," and is supported on these SMP systems:
* Digital UNIX
* RS/6000 AIX
* Sun Solaris
* HP-UX
Other platforms, such as Windows NT, also support handling network I/O
through multiple engines, but the actual method is different.
Configuring Multiple Engines
MNE is automatic if you have configured your SQL Server for multiple
engines. Having MNE can improve performance, but you must determine whether
or not to implement multiple engines based on an analysis of your own
system's performance.
Before you add engines, monitor the system to determine baseline
performance; then add engines and measure subsequent performance to
determine the impact of MNE on system performance. You can use SQL Monitor
or sp_sysmon to measure server performance.
Monitor these areas and take them into account when you configure engines:
* CPU usage  If CPU usage on all engines is over 85 percent, adding an
engine can be beneficial
* User connections  If the SMP system supports network affinity
migration, then each engine will handle the network I/O for its
connections, which allows the potential for more user connections
* Memory  Adding engines uses memory; if Error 701 appears frequently in
the error log or at the client terminal, you may wish to increase the
amount of available memory
The number of online engines is configurable with sp_configure. The syntax
is:
sp_configure "max online engines", value
You must reboot SQL Server after any changes to the max online engines
value, as that value is not dynamically configurable.
Considerations in Configuring Engines
Consider these guidelines when you configure for multiple engines:
* Start with a few engines and add additional ones when the active CPUs
are over 85 percent utilized
* Add engines if the current performance is not adequate for an
application and there are enough CPUs on the machine
* Decrease engines if a hardware failure disables CPUs on the machine
* Configure only as many engines as you have usable CPUs; configuring for
more engines may slow performance
* If your machine also hosts non-SQL Server processes, or there is a lot
of processing by a client, then one engine per CPU may be excessive.
Multiple Network Engines and User Connections
In releases earlier than 11.0, user connections were limited by the
operating system, file descriptors (in the case of UNIX; other platforms
differ), and the SQL Server configuration parameter @@max_connections. With
the introduction of MNE in release 11.0, however, because each additional
engine allows a number of user connections, SQL Server allows you to
increase the number of user connections based on the number of additional
engines in your system.
@@max_connections now represents the maximum number of file descriptors
allowed by the operating system for your process, minus a few file
descriptors used by SQL Server itself. For example, if SQL Server is
configured for one engine and the value of @@max_connections is 1019, adding
a second engine increases that value to 2039, assuming that there is only
one master network listener.
Given the increase in @@max_connections, you can now configure for more user
connections using sp_configure:
sp_configure "number of user connections", value
------------------------------------------------------------------
Note
Conversely, if you decrease the number of engines on your system,
you may also have to decrease the number of user connections
accordingly.
------------------------------------------------------------------
Remember that increasing or decreasing user connections is not dynamic; you
must reboot SQL Server after any such changes.
Identity Enhancement
The IDENTITY column feature allows you to create a column with
system-generated values that uniquely identify each row in a table. Release
11.0 provides the following enhancements to IDENTITY columns.
Identity Enhancement for "Dirty Reads"
For tables with no unique indexes, the identity in nonunique index database
option instructs SQL Server to add an IDENTITY column to any index created
in the database, in order to make it unique.
Unique indexes are required for isolation level 0 ("dirty") reads and
updatable cursors, so if you use these in your installation, this database
option may be useful to you. Implement it with the following commands:
sp_dboption "identity in nonunique index", true
use database database_name
checkpoint
------------------------------------------------------------------
Note
You may have optimization problems after setting this database
option. Because SQL Server treats all indexes as unique with this
option set, the formulas for calculating the usefulness of a
particular index may no longer be accurate, causing the optimizer
to pick an index that may not be the fastest.
------------------------------------------------------------------
Identity Enhancement to Reduce Spinlock Contention
The identity grab size configuration parameter allows each SQL Server
process in a multiprocessor environment to reserve a specified number of
IDENTITY column values when you add rows to tables that contain IDENTITY
columns.
Setting this configuration parameter can increase performance on
multi-engine servers, because it reduces spinlock contention on the memory
structure that contains the next identity value. Use sp_configure to set it,
as follows:
sp_configure "identity grab size", n
where n is the number of reserved values.
For example, if you set the identity grab size to 20, when a user does an
insert to a table with an IDENTITY column, SQL Server reserves a block of 20
values for that user, and the next 20 rows that user inserts will have
sequential identity values. If a second user starts inserting rows while the
first user is still doing inserts, SQL Server reserves another block of 20
values for the second user.
------------------------------------------------------------------
Note
If you set the identity grab size to a large value, and a user
logs out before using all the values SQL Server has reserved for
that user, those values are not released and thus are lost,
causing a large gap in the identity values. Additionally, if the
value for sp_configure "identity burning set factor" is
inappropriate, server failure can cause large gaps. Large gaps
mean that your identity values may max out sooner. Take this into
account when you set these configuration values; see "The IDENTITY
Column" in Sybase Technical News, volume 4 number 1, for more
information.
------------------------------------------------------------------
Enhancement to Auto Identity Database Option
In SQL Server 10.0 we introduced the auto identity database option, which
signalled SQL Server to add an IDENTITY column to any new table it created.
You can set auto identity for the session using the command set auto
identity on, or for all sessions in the database with this command:
sp_dboption database_name, "auto identity", true
use database database_name
checkpoint
Setting auto identity "on" means that when a user creates a table in the
affected database with no primary key, unique constraint, or IDENTITY
column, SQL Server automatically generates an IDENTITY column for the table.
In release 10.0, the size of the IDENTITY column so generated was always 10
digits. As of release 11.0, you can use the size of auto identity
configuration parameter to set the precision of the IDENTITY columns that
SQL Server generates. The command syntax is:
sp_configure "size of auto identity", n
where n is the number of digits you want your automatically- generated
IDENTITY columns to have. For example, if you want the automatic IDENTITY
columns to have 15 digits, the command is:
sp_configure "size of auto identity", 15
The default setting is still 10 digits.
More Information
For more information about the enhancements to IDENTITY columns, see
"IDENTITY Columns" in the SQL Server Reference Manual.
Creating and Configuring I/O Buffer Pools with sp_poolconfig
As of release 11.0, SQL Server includes a stored procedure, sp_poolconfig,
to help you take advantage of the new option to use large I/Os, by creating
and manipulating I/O buffer pools in cache.
Large I/Os have been implemented for two reasons:
* Large I/Os minimize physical I/O by reducing the number of times SQL
Server must go to disk to obtain a data page
* Large I/Os give you better throughput by grabbing up to eight 2K pages
in one operation rather than one page at a time.
Large I/Os are useful for decision support systems (DSS) applications such
as:
* Running regular maintenance tasks such as bcp
* Batch updates to large numbers of rows
* Joins on large tables
* Loading data into a table using insert statements
* Scans of large tables and range scans of large tables
Large I/Os are also useful when your log disk is a bottleneck; for more
information on sizing the log I/O, see "Large I/Os for Log" on page 12.
About Buffer Pools
An I/O buffer is a memory structure that tracks a page or set of pages in
buffer cache.
One buffer pool can contain as many I/O buffers as its size permits; you
specify what the I/O size is for any given buffer pool. Valid I/O sizes are
2K, 4K, 8K, 16K. A given buffer pool can only accomodate the one size of I/O
with which it was configured, so we speak of a 2K buffer pool (which
consists of 2K I/O buffers) or a 4K buffer pool (which consists of 4K I/O
buffers), and so forth.
Every named cache contains at least one 2K buffer pool (which cannot be
deleted), and can contain at most four buffer pools (one of each: 2K, 4K, 8K
and 16K).
Using sp_poolconfig
sp_poolconfig is a dynamic command, meaning that when you invoke it, your
changes occur immediately without your having to reboot SQL Server. The
syntax for sp_poolconfig is as follows:
sp_poolconfig cache_name, "pool_size [P|K|M|G]",
"first_io_sizeK"[, "second_io_sizeK"]
Here is an explanation of each variable:
* cache_name is the named cache for which you want to create the buffer
pool. Note that if you don't explicitly create a buffer pool for a
named cache, SQL Server automatically creates the default 2K buffer
pool for it, and allocates all memory configured for that cache to the
default buffer pool. For more information on named caches, see the SQL
Server System Administration Guide and the SQL Server Performance and
Tuning Guide.
* pool_size is the size of the pool Å» you specify whether that size is in
pages (P), kilobytes (K), megabytes (M), or gigabytes (G).
* first_io_size is the I/O buffer size. Valid values are 2K, 4K, 8K and
16K (on Stratus, 4K, 8K, 16K, and 32K).
* second_io_size is only used if you are moving memory from one buffer
pool to another. If the first buffer pool is smaller than the size you
wish to make it, SQL Server takes memory from the second buffer pool
and gives it to the first. If the first buffer pool is larger than the
size you wish to make it, SQL Server takes memory from the first buffer
pool and gives it to the second.
The following command creates a buffer pool for the named cache pub_cache,
which is 4MB in size and whose I/O buffers are 4K each:
sp_poolconfig pub_cache, "4M", "4K"
Here is an example command to modify that same buffer pool. If the 4K pool
is smaller than 2MB, SQL Server takes 2MB of memory from the 16K buffer pool
and applies it to the 4K buffer pool; if the 4K pool is already larger than
2MB, SQL Server takes the extra memory and applies it to the 16K pool
sp_poolconfig pub_cache, "2M", "4K", "16K"
------------------------------------------------------------------
Note
If SQL Server detects that it cannot move memory from one buffer
pool to another, it will return message 18145:
Less memory moved than requested in cache '%1!'. Requested size =
%2! Kb: from pool = %3!, to pool = %4!, actual memory moved = %5!
Kb.
------------------------------------------------------------------
You can use sp_poolconfig to delete a buffer pool as well, by setting the
I/O size to 0. Here is an example command to delete the buffer pool we
modified above:
sp_poolconfig pub_cache, "0", "4K"
The memory removed is reassigned to the default (2K) pool. You can also
delete a buffer pool by deleting its entry in the configuration file.
Why Modify Buffer Pools?
There are two reasons why you might need to modify a buffer pool:
* The pool is too small. This can cause queries to wait or to use
different buffer pool sizes, or may result in more physical I/O due to
pages being flushed from the cache
* The pool is too large, using up memory that could be better applied
elsewhere
You can determine if either of these is true by monitoring your system's
performance with sp_sysmon (see page 16 for details).
Tuning Buffer Pools for Type of Processing
If you have an application that requires online transaction processing
(OLTP) during the day and DSS processing during the evening, you must
configure your buffer pools accordingly. Sybase recommends a 16K buffer pool
for the DSS jobs, and a 2K buffer pool for the OLTP jobs.
Create two separate configuration files with the correct buffer pool
configuration and load them into SQL Server as necessary (note that you
cannot delete the 2K buffer pool, but you can allot it less memory than the
16K pool for the DSS configuration).
For more information on using the configuration file, see the System
Administration Guide for release 11.0.
Restrictions
There are a few restrictions on creating, modifying and deleting buffer
pools:
* The sum of all buffers in the pool must be less than the total memory
size of the cache.
* You cannot delete the 2K buffer pool in any cache.
* Pool sizes must be in increments of 2K, 4K, 8K or 16K.
* Unless you specify otherwise, new buffer pools use memory from the
default source 2K pool. To create a new buffer pool using memory from a
pool other than the 2K pool, specify that pool in the second_io_sizeK
position, as in the following example:
sp_poolconfig pub_cache, "4M", "4K", "8K"
In the example, SQL Server creates the 4K pool by taking 4MB of memory
from the 8K pool.
* The minimum pool size is 512K.
* The maximum I/O buffer size is 16K.
More Information
For more information on using sp_poolconfig, see the SQL Server Reference
Manual and the SQL Server Performance and Tuning Guide.
Large I/O for Log and User Log Cache
To relieve the transaction log I/O bottleneck and improve transaction
throughput, SQL Server 11.0 now allows a configurable log I/O buffer size,
ranging from 2K to 16K. If there is a 4K buffer pool, SQL Server will use it
by default for the log; if you have not configured a 4K buffer pool,
however, SQL Server will use a 2K pool.
There are two ways in which SQL Server recognizes the buffer pool size:
* At boot time, SQL Server reads the log I/O buffer size value from the
sysattributes table. If a buffer pool at the specific log I/O size is
not available in the named cache to which the log is bound, SQL Server
displays error 18128 and does not change the log size:
Unable to change the log I/O size. The memory pool
for the specified log I/O size does not exist.
When this error occurs, SQL Server takes 2K to be the default.
* At run time, you can set or alter the log I/O buffer size with the
system procedure sp_logiosize, which updates sysattributes. The change
is dynamic, taking effect without your having to reboot SQL Server.
How to Configure Log I/O Buffer Size
The syntax for sp_logiosize is as follows:
sp_logiosize {"default" | "value"}
If you execute sp_logiosize "default", the log I/O size will be set to the
4K default. Otherwise, you can specify a value. The following command, for
example, sets the log I/O size to 8K:
sp_logiosize "8"
------------------------------------------------------------------
Note
Log I/O size is set at the database level. You must run
sp_logiosize in the database for which you wish to set the log I/O
size.
------------------------------------------------------------------
You can run sp_logiosize without parameters to see the log I/O size of the
database in which you run it, as follows:
sp_logiosize
The transaction log for database 'master' will use
I/O size of 2 Kbytes.
(return status = 0)
Use sp_poolconfig, as shown in ``Creating and Configuring I/O Buffer Pools
with sp_poolconfig'' on page 9, to create a buffer pool for the cache to
which the log is bound.
Considerations in Configuring Log I/O Buffer Size
You should take these factors into consideration when setting your log I/O
size:
* The processing type of your application
* If your application is DSS, a large log I/O size is more useful
* If your application is OLTP, a smaller log I/O size is preferable
* I/O characteristics of your disk device, such as track size, access
time, and disk caching
* The power, speed and number of processes of your CPU
------------------------------------------------------------------
Note
Setting the log I/O value too high can affect SQL Server
performance. SQL Server does not wait for pages to fill up before
flushing log pages to disk; when the log page finally does fill,
it will have to be written again. Writing the same page multiple
times slows the server down.
------------------------------------------------------------------
We encourage you to experiment with different log I/O sizes and appropriate
buffer pools in a development environment before you set the value in a
production environment.
User Log Cache
In releases prior to 11.0, there could be significant contention as each
database process waited to aquire a spinlock to protect the log pages in
memory and then waited to write to the last page of the log. As of release
11.0, SQL Server has a user log cache (ULC) layer to accumulate log records.
It flushes those records to log pages under the following circumstances:
* At the end of a transaction (commit / rollback)
* On a write to a different database
* When the ULC is running out of space
* When a checkpoint occurs
On a single-processor system, logging with the ULC is at least as fast as it
was in release 10.x; and on multiprocessor systems you'll see significant
reductions in contention.
Configuring User Log Cache
User log cache size is a parameter configurable with sp_configure. The
syntax is:
sp_configure "user log cache size", value_in_bytes
The value you configure is the same for every user's log cache, and ranges
from 2048 (2K) to 2,147,483,647. It must be at least 2048, but does not have
to be a multiple of 2K.
------------------------------------------------------------------
Note
For every user connection you have configured, SQL Server takes at
least the 2K minimum from the available memory in the default data
cache, and more if you have specified more. Configure your total
memory accordingly, to ensure that there is enough memory to
accommodate this.
------------------------------------------------------------------
Here are some guidelines for setting ULC size:
* Do not set ULC size larger than your largest transaction, because it
uses memory that might be better used elsewhere
* Do not configure for long-running transactions
* Do not set the size too small, or SQL Server will flush the ULC to the
log more frequently, increasing spinlock contention on the log pages
ULC Spinlock Ratio
Another configurable parameter, user log cache spinlock ratio, specifies the
number of user log caches per ULC spinlock. Its syntax is:
sp_configure "user log cache spinlock ratio", value
We strongly recommend you leave it at the default, which is 20.
------------------------------------------------------------------
Note
If max on-line engines is set to one, the value for user log cache
spinlock ratio is ignored and there is only one spinlock.
------------------------------------------------------------------
More Information
For more information on the user log cache, refer to the SQL Server System
Administration Guide. For more information on tuning the ULC size, and on
how to use sp_sysmon to monitor ULC usage and log I/O, refer to the SQL
Server Performance and Tuning Guide.
How to Use syslogshold
As of SQL Server release 11.0, you can use the new syslogshold table to help
you identify what process has the oldest active transaction and how long
that transaction has been open. An active transaction is one which has
written at least one record to the database's transaction log and has not
yet been committed.
Here is an example of output from a query to syslogshold:
dbid reserved spid page xactid masterxactid
starttime
name
------ ----------- ------ ----------- -------------- ------------
--------------------------
---------------------------------------------------------
5 0 1 411 0x0000019b000d 0x000000000000
Feb 22 1996 6:39PM
$user_transaction
Any given database will have zero, one or two rows in syslogshold:
* zero rows: no active transaction or replication
* one row: an active transaction or replication
* two rows: both an active transaction and replication
The columns in syslogshold are as follows:
* dbid  the ID of the database where the oldest transaction is open
* reserved  a column that isn't actually used in this version
* spid  the ID of the process holding the open transaction
* page  the starting page of the active portion of syslogs
* xactid  the ID of the open transaction
* starttime  the time at which the transaction was opened
* name  the transaction name
If you are using Secure Server, there is an additional column in syslogshold
for sensitivity.
------------------------------------------------------------------
Note
syslogshold is dynamically created when it is queried, so its
output is only accurate as of the instant it is collected.
------------------------------------------------------------------
Using syslogshold to Identify Process Blocking Log Truncation
To find the spid and transaction name of a process blocking truncation of
the log, execute the following query in each of your databases:
select H.spid, H.name
from master..syslogshold H, sysindexes I
where H.dbid = db_id() and I.id = 8
and H.page = I.first and H.spid !=0
This query tells SQL Server to look for the row in the current database
where the first page of the log for this transaction is equal to the current
first page of syslogshold.
The use of H.spid != 0 indicates to SQL Server that the row is for the
oldest active transaction, rather than for a Replication Server truncation
point.
Output from this query will look something like this example:
spid name
------ --------------------------------------------
7 $user_transaction
If there is a row in syslogshold meeting the query constraints, the presence
of the oldest active transaction is on the oldest page of the log, and as a
result is limiting the ability of SQL Server to truncate the log.
It may be appropriate to kill the offending process, if either of the
following is true:
* You believe that you have only short transactions
* Your transaction log is very large
To kill the process in the above example, you would execute the command:
kill 7
------------------------------------------------------------------
Note
You cannot execute the query select @spid=H.spid and then kill
@spid; this syntax is not allowed.
------------------------------------------------------------------
Using syslogshold to Identify User and Application
To find the application that owns the oldest active transaction in a given
database, use the following command:
select P.hostname, P.hostprocess, P.program_name,
H.name, H.starttime
from master..sysprocesses P, master..syslogshold H
where P.spid = H.spid and H.dbid = db_id()
and H.spid != 0
Here is an example of output from the above command:
hostname hostprocess program_name name
starttime
---------- ----------- ---------------- -------------------------
------------------
--------------------------
fnord 12081 isql $user_transaction
Feb 22 1996 6:53PM
New Backup Server Auto Tape Configuration Feature
Backup Server release 11.0 includes a new feature which allows for automatic
configuration of any unknown tape device.
Historically, SQL Server (and Backup Server when it was first introduced)
was very device-dependent; for any given platform, a 4mm drive from one
vendor would not work in the same way as a 4mm drive made by a different
vendor. Backup Server supported a limited number of tape drives for which it
knew the characteristics.
As of release 11.0, however, when you execute a dump command to a device for
which Backup Server doesn't already know the characteristics, Backup Server
searches the tape device configuration file. If it finds no entry there for
that device, one of two things happens next:
* If you have not specified dump ... with init, Backup Server returns the
following message and aborts the dump:
Device not found in configuration file. INIT
needs to be specified to configure the device.
In this case, you should re-execute the dump command with the init
qualifier:
dump [database | transaction] to device_name with init
* If you have specified dump ... with init, Backup Server returns this
informational message:
Device %s has not been configured by the Backup
Server; configuration may take additional time.
When you execute dump ... with init to an unknown tape device, Backup Server
runs some tests against the device to determine its characteristics, stores
the information in the tape device configuration file for future reference,
and proceeds with the dump.
Tape Device Configuration File
The tape device configuration file is a text file, $SYBASE/backup_tape.cfg
by default. It is created the first time Backup Server writes an entry to
it. Entries in this file are of the form:
hostname dev_name filemarks append_strategy
blocksize ostype fm_type cls_rdtpmk
Here is what the fields mean:
* hostname  the name of the machine where the device is located
* dev_name  the name of the tape device, for example /dev/nrst1
* filemarks  the number of filemarks written before the dump file is
closed
* append_strategy  an integer representing different strategies used to
append a new dump to the volume set, as follows:
* 0 Â device supports only one dump file per tape
* 1 Â back skip file strategy. This is used when the tape device supports
over-writing tape marks, and is the most efficient way to append. The
tape is positioned to append between the last two filemarks on the
volume set.
* 2 Â seek to end strategy. The volume is first read to determine that it
is the last volume in the volume set, then the device is rewound and
the "seek to end of written data" system call is used for append
positioning.
* 3 Â skip n filemarks strategy. This strategy skips forward the exact
number of filemarks currently written on the tape.
* 4 Â skip n+1 filemarks strategy. This strategy skips forward one more
than the number of filemarks currently on the tape. This strategy and
the skip n filemarks strategy both use the "forward skip file" system
call; the number of filemarks on the media is determined when the
system reads one volume looking for the end of the volume set.
* blocksize  the maximum block size of the device in bytes, ranging from
2K to 64K
* ostype  code used by the operating system to determine device type
* fm_type  the type of filemarks for which the device is configured
* cls_rdtpmk  an integer representing the read tape mark behavior, as
follows:
* 0 Â BSD UNIX
* 1 Â SVR4 UNIX BSD tape mark behavior is to position past the tape mark
after reading it. SVR4 does not reposition the tape, so a close must be
inserted in order to position past the tape mark.
Here is an example entry:
svribmseng2 /dev/rmt5.1 1 3 65536 7 1 0
In normal circumstances, only Backup Server ever writes to this file.
However, if you happen to change devices, for example in the case of
hardware failure, and you install a tape device with different
characteristics but the same device name as the original, the next time you
try to dump, Backup Server will return this error and terminate the dump
command:
Device %1!: the operating system device type is
different than what is in the configuration file
%2!. Please remove entry for this device in the
configuration file and reconfigure the device by
issuing a DUMP with the INIT qualifier.
In this case, you can use any text editor to delete the entry for that
device, and run the dump command with the init option, as if the device were
an unknown device. Backup Server will make a new entry for that device in
the configuration file.
Dump to Remote Backup Server
Since release 10.0, it has been possible to dump to a Backup Server running
on a remote machine. There are a number of advantages to this strategy,
especially for users of SQL Server on SunOS machines who want to upgrade to
Solaris, as well as a number of disadvantages. In addition, some
restrictions apply.
Configuring Devices for Remote Backup Servers
You can configure as many devices on remote Backup Servers as you need to,
up to the stripe limit of 32 devices total. Here is the process for
configuring remote backup servers.
Set Up Local Machine
1. Make sure the local SQL Server and Backup Server are running.
2. Make sure the local interfaces file contains an entry for the remote
machine's Backup Server. Only the "query" line is required. No aliases
are allowed.
------------------------------------------------------------------
Note
You can check the name of the remote Backup Server by looking in
its runserver file for the flag -S (UNIX) or /server (VMS).
------------------------------------------------------------------
1. Execute sp_helpserver SYB_BACKUP to verify the proper network name for
your local Backup Server. There doesn't need to be an entry in
sysservers for the remote Backup Server, but it makes testing easier.
------------------------------------------------------------------
WARNING!
Do not modify SYB_BACKUP to point to your remote Backup Server's
name.
------------------------------------------------------------------
Set Up Remote Machine
1. Make sure the remote Backup Server is running.
2. Make sure the remote Backup Server does not have the same network name
as the one displayed in step 3 above.
------------------------------------------------------------------
Note
There doesn't need to be an entry in the remote interfaces file
for any of the servers on the local machine.
------------------------------------------------------------------
Remote Dump Syntax
The syntax for dumping to a remote Backup Server is as follows:
dump [database | transaction] dbname to remote_dev
at remote_BSvr_name
where remote_dev is the physical name of the device configured at the remote
Backup Server, and remote_BSvr_name is the name of the remote Backup Server.
------------------------------------------------------------------
Note
You must always use the absolute pathname of the device in remote
dumps; you cannot use a logical device name.
------------------------------------------------------------------
Likewise, you can load from the remote Backup Server using the following
syntax:
load [database | transaction] dbname from
remote_dev at remote_BSvr_name
Remote Use of sp_volchanged
To execute sp_volchanged at the remote Backup Server, add the remote_device
at remote_BSvr syntax to the command, for example:
sp_volchanged 11, '/dev/0mn' at remote_BSvr_name,
'PROCEED'
Advantages of Dumping to Remote Backup Server
Dumping to a device (disk or tape) on a remote machine can be useful in the
following circumstances:
* The local tape drive fails
* You need to store your dump on different media; for example, your local
machine has a 4mm drive but you need the dump on an 8mm tape
* You wish to dump to a disk file, but the only available space is on
another machine
* The local machine has no tape drive
Disadvantages of Dumping to Remote Backup Server
There are two primary disadvantages to remote dump and load:
* It is much slower, due to the network I/O involved
* Because it is implemented through DB-Library (which uses blocking I/O),
it causes the local Backup Server to wait until network I/O is done,
resulting in performance degradation
Bear this in mind when you consider setting up remote dump and load for your
site; you may wish to do remote dumps and loads when there is no or little
other activity on the local Backup Server.
SunOS (BSD) to Sun Solaris Dumps and Loads
Customers running on SunOS machines may use this feature to upgrade their
databases to Solaris (because SQL Server 11.0 is not available for SunOS).
There are two ways to do this:
* Do a local dump on the SunOS side and a remote load on the Solaris side
* Do a remote dump on the SunOS side and a local load on the Solaris side
In either case, you can then use online database and the databases will
upgrade automatically.
------------------------------------------------------------------
WARNING!
You cannot use this method to load master.
------------------------------------------------------------------
Restrictions on Cross-Platform Dumps/Loads
------------------------------------------------------------------
WARNING!
Be aware that cross-platform dumps/loads other than SunOS to
Solaris have not been tested and Sybase does not support them Å»
you try them entirely at your own risk.
------------------------------------------------------------------
SunOS to Solaris is one of the few possible cross-platform dump/load
actions; most others are not supported. You can do cross-platform dump/load
only if the platforms are compatible, as follows:
* The byte ordering must be the same (least significant vs. most
significant byte first)
* The floating point format must be the same
* The page size must be the same
* Both platforms must compile any stored procedures in the same way
Additionally, all stripes in the dump must be either UNIX or VMS, there may
be no mixing.
It is possible to dump to a remote Backup Server on a different platform
than the one on which your database resides, and then to remote load from
that remote Backup Server to the original database or to another database on
the same platform from which you made the original dump.
------------------------------------------------------------------
Note
Sybase definitely does not support dumping to a tape, moving that
tape physically to a different platform, and trying to load from
that tape, because there is no guarantee that the device drivers
are the same between platforms.
------------------------------------------------------------------
Tape Stacker Support
Question
Does Sybase support tape stackers, also called autoloading tape devices or
robot systems?
Answer
Currently, Sybase does not plan to support tape stackers directly. Tape
stackers require additional software to be fully functional, since there is
as yet no operating system that provides native stacker support.
We are currently working with several VARs that support tape stackers, and
integrations are planned. Sybase Technical News will keep you updated on
this front.
Problems Installing on OpenVMS 6.2
Question
I've been unable to install Sybase products from global media on my system
running OpenVMS 6.2. I get access violation errors when I run the VMSINSTAL
process. What's wrong?
Answer for 10.x and Later
Check the global part number of your media. If it is any of the following,
order a reshipment of the products by calling Sybase Customer Service at
1-800-8-SYBASE:
* 61500-xx-0002-96 TID: 296
* 61500-xx-0407-01 TID: 407
* 61500-xx-0419-01 TID: 419
The above part numbers may have shipped up until 9/95. At that time the
latest TID (419) was re-released with an unloader program fixed to run on
OpenVMS 6.2.
When your reshipment arrives, check to be sure it contains new global media
with this part number:
* 61500-xx-0419-02 TID: 419
------------------------------------------------------------------
Note
The new version of TID 419 has 02 as the last digits of its part
number, rather than 01.
------------------------------------------------------------------
This should solve your problem.
Answer for 4.9.2
If you are experiencing access violations running VMSINSTAL, order a
reshipment of products from Sybase Customer Service at 1-800-8- SYBASE. When
your reshipment arrives, check to be sure it contains new global media with
this part number:
* 61500-xx-0435-01 TID: 435
You should be able to unload from this new media without trouble.
Problems Parsing Column Name
Question
I have a query in SQL Server 10.x of the form:
select * from t1 where dbo.t1.c1 = ...
Why is it that if the dbo executes this command there is no problem, but if
other users execute this command, SQL Server returns this error:
Msg 107, Level 15, State 1:
Server `SYBASE', Line 1:
The column prefix `dbo.t1' does not match with a
table name or alias name used in the query.
Answer
The parser is complaining about the mismatch between "t1" and "dbo.t1". Try
reforming your query as follows:
select * from dbo.t1 where dbo.t1.c1 = ...
Tables are specified in the from clause of a query. References in other
clauses refer back to the specification in order to figure out what table is
being talked about. The name by which a table will be known is in the from
clause: the specified name if given alone, or its alias if given with an
alias. Every other clause must use the name that appears in that clause. The
from clause names the table as "t1",so the where clause must refer to "t1" Å»
it may not use "dbo.t1", because the latter refers to a table that doesn't
appear in the from clause.
Explanation
Tables owned by different owners can have the same name, so dbo.t1 in the
from clause might refer to fred.t1 when executed by user "fred". In that
case, dbo.t1 is different for a user not "fred"; going ahead with the query
would return a cartesian product from fred.t1, with one row from fred.t1 for
every row in dbo.t1 where dbo.t1.c1 satisfies the search conditions, because
there is no join between it and dbo.t1.
The fact that dbo can run this query at all is an extension to ANSI SQL.
Indexes and Dirty Reads
Question
Given an employee table containing 100,000 rows with two indices:
* a unique index on empnum
* a non-unique index on lastname
when I execute the following query interactively, in isql,
select * from employees where lastname = "SMITH"
I get an immediate response. When I execute it in an application, the
response time is much slower. Why is this?
Answer
Check the isolation level of your session versus your application by using
the command select @@isolation for the session and looking at the query in
the application to see if it includes an isolation change. In the context of
isolation level 0, also known as "read uncommitted" or "dirty read,"
optimizer will only consider unique indexes. You can give the command set
showplan on and then run your query to see what indexes are being used
If you have set the isolation level to 0 for the transaction in your
application, the optimizer will not use the index on lastname, resulting in
a table scan using the empnum index.
Cursor Integrity
Problem
I declared a cursor for select * from a table in one isql session, fetched a
few records, then inserted some more records from another isql session.
Under SQL Server version 10, the new records are inserted at the end of the
last page and the cursor can fetch those records.
But under SQL Server version 11, if the same table is partitioned, and after
a few fetches, if the cursor is at the last page and the insert happens on
previous pages, the fetch doesn't get those newly inserted records.
It seems as though partitioning is the problem, because the cursor finds the
newly-inserted rows meeting the search condition if the table isn't
partitioned.
Is this a bug?
Answer
This behavior isn't a bug. It is, however, a factor you must consider in
deciding whether or not to partition a table. In release 10, SQL Server
didn't use partitioned tables, so if you are counting on the old behavior,
you should not partition your table.
In a partitioned table, inserts are distributed; in that respect it acts as
though it had an index on some key that directs the insert point. Inserts
can go to the end of any of the page chains (partitions), so there are
multiple insertion points (though not as many as an indexed table actually
has). Here is a thumbnail sketch to give you an idea of what this looks
like:
[Image]
From a logical perspective, there is no guaranteed way to force the cursor
to see the new rows. From a physical perspective, there are ways in SQL
Server release 11 to force this behavior, but they are non-standard and
subject to change. These ways include:
* Revert back to a non-partitioned heap.
* Add an identity column, a nonclustered index on that column and force
the cursor to use that index with forceindex. Note that this method
will probably affect performance negatively.
Replication Server NLM Compatibility
Question
According to the release bulletin for Replication Server 10.1 on Netware,
the Replication Server NLM was built with Open Client/Open Server 10.0.2 and
therefore cannot be installed in the same directory or run at the same time
as earlier versions of Open Client/Open Server or SQL Server 10.0.1 or
earlier.
I thought SQL Server was not built on Open Server Å» is this just a concern
for Backup Server?
Is the restriction lifted with SQL Server 10.0.2.3 or 10.0.2.4?
Answer
The problem here is that Netware doesn't have the concept of static linking.
A library is just another style of NLM with additional features.
As only one copy of an NLM can be loaded at a time, the Replication Server
must run using the same libraries as the SQL Server.
So if Replication Server requires libraries at 10.0.2, SQL Server must be
able to run on those libraries as well, and SQL Server 10.0.1 cannot run on
10.0.2 connectivity libraries.
This restriction will not be lifted with future releases, because it is a
restriction imposed by the operating system, not by Sybase.
----------------------------------------------------------------------------
Disclaimer: No express or implied warranty is made by Sybase or its
subsidiaries with regard to any recommendations or information presented in
SYBASE Technical News. Sybase and its subsidiaries hereby disclaim any and
all such warranties, including without limitation any implied warranty of
merchantability of fitness for a particular purpose. In no event will Sybase
or its subsidiaries be liable for damages of any kind resulting from use of
any recommendations or information provided herein, including without
limitation loss of profits, loss or inaccuracy of data, or indirect special
incidental or consequential damages. Each user assumes the entire risk of
acting on or utilizing any item herein including the entire cost of all
necessary remedies.
Staff
Principal Editor: Leigh Ann Hussey
Contributing Writers:
Jerold Brenner, Joel Brown, Ian Cairns, Dwayne Chung, Leigh Ann Hussey,
Howard Sardis, Kathy Saunders
Send comments and suggestions to:
Sybase Technical News
6475 Christie Avenue
Emeryville, CA 94608
or send mail to tech...@sybase.com
Copyright 1996 © Sybase, Inc. All Rights Reserved.
Q10.3.4
Sybase Technical News Volume 5 Number 3, August 1996
This issue of Sybase Technical News contains new information about your
Sybase software. This newsletter is intended for Sybase customers with
support contracts. You may distribute it within a sup ported site; however,
it contains proprietary information and may not be distributed publicly.
Sybase Techni cal News and the troubleshooting guides are included on the
AnswerBase CD, SupportPlus Online Services Web pages, and the Sybase
PrivateLine forum of CompuServe. Send comments to tech...@sybase.com. To
receive this document by regular email, send name, full internet address and
customer ID to tech...@sybase.com.
In this Issue
Tech Support News/Features
* 1996 Technical Support North American Holiday Schedule
* Download EBFs and Information from
Sybase ESD
SQL Server General
* Guidelines for Using dbcc with System 11
* SQL Server and Serialized Log Writes
* sp_who Showing loginame Field Change
* Backup Server Performance
* OpenVision High Availability Configuration
and SQL Server
Scripts, Procedures & Code
* Passing a UNIX Variable to a SQL Script
* Size Conversion Stored Procedures
* tli_mapper Script and User Guide
Connectivity / Tools / PC
* Urgent Data Setup Requirements
* Explanation of "nrpacket: recv,
Connection timed out"
Bug Reports
* Bug 66639/73421 - alter database in VLDB May Cause 605 Errors
1996 Technical Support North American Holiday Schedule
Sybase Technical Support is open on all holidays and provides full service
on many. During the limited-service holidays shown below, Technical Support
will provide the following coverage:
* SupportPlus Preferred and Advantage customers may log all cases; we
will work on priority 1 and 2 cases over the holiday.
* 24x7 and 24x5 Support customers may log priority 1 cases; we will work
on these over the holiday.
* SupportPlus Standard, Desk Top, and Regular Support customers may
purchase Extended-hour Technical Support for coverage over the holiday.
Sybase Technical Support
limited-service holidays
 U.S. customers
Holiday Date
Labor Day September 2
ThanksgivingNovember 28
Christmas December 25
Sybase Technical Support
limited-service holidays Â
Canadian customers
Holiday Date
Labour Day September 2
Canadian ThanksgivingOctober 14
Christmas Day December 25
Boxing Day December 26
If you have questions, please contact Technical Support.
Download EBFs and Information from Sybase ESD
The Sybase Electronic Software Distribution (ESD) System lets Sybase
customers with active support agreements download bug fixes and information
via the World Wide Web. This article describes how to do it.
Register for SupportPlus Online Services
If you have not done so already, you must register for SupportPlus Online
Services before you can access Sybase ESD.
1. Connect to the Sybase Web page at http://www.sybase.com
2. Click on Services & Support.
3. Click on Sybase Enterprise Technical Support.
4. Click on SupportPlus On-line Services Registration.
5. On the registration screen, fill in your contact ID (leave blank if you
do not know your contact ID), your Internet e-mail address, your
(user-defined) password, your company name, your Sybase customer
number, your name, and your telephone number.
6. Click on the Submit Registration Form button.
Your registration form is then electronically checked. If it is correct, you
may immediately begin using SOS. If any information is missing from the form
or information does not correspond with our records, a Sybase customer
service representative will verify the information, complete the
registration and either contact you or send you an e-mail to inform you of
your registration status.
Accessing Sybase ESD
To access Sybase ESD, follow these steps:
1. Follow the hyperlinks from the Sybase, Inc. homepage to the SupportPlus
Online Services login screen and log in.
2. Select Electronic Software Distribution from the list of options.
3. Select the EBF you wish to download from the list generated for you.
------------------------------------------------------------------
Note
This list shows all available EBFs for products for which you are
licensed. It is updated regularly. Selecting and downloading an
EBF creates a log entry which Sybase uses to update your customer
profile.
------------------------------------------------------------------
Where to Find Current EBF and Bug Information
You can use ESD to find out current EBF availability on your licensed
products and platforms, and to view cover letters.
Finding Bugs Fixed in a Particular EBF
If you have an EBF number and wish to find out if a particular bug is fixed
in it, follow these steps:
1. If you are on the first page, enter the EBF number in the field
provided. If you have loaded a page with EBFs applicable to you, go to
step 2.
2. Click on View Cover Letter - on the first page, it is a button:
[Image]
On your custom EBF list, it is a field in a table:
[Image]
3. Select Edit[Image]Find from the browser menus.
4. Enter the bug ID number and click Find.
Site Requirements for Sybase ESD
You need the following things in order to use Sybase ESD successfully.
An Internet Connection
ESD is accessible only through the World Wide Web (WWW), which is reachable
only through an established Internet connection.
Netscape Navigator
Sybase ESD requires Netscape Navigator software, or any other browser that
supports Secure Sockets Layer, to provide a secure link between your
workstation and the Sybase Technical Support database.
Netscape Navigator is available for the following platforms:
* 386/486/Pentium (BSDI)
* Apple Macintosh Å» MacOS 7.x, (Power PC optional)
* Digital AXP (Digital UNIX 2.0)
* Windows 3.1, Windows 95, Windows NT, Windows for Workgroups
* HP 9000/800 (HP-UX 9.03)
* IBM RS/6000 (AIX 3.2)
* Silicon Graphics (IRIX 5.2)
* Sun SPARC (Solaris 2.3, SunOS 4.1.3)
The following table lists the hardware requirements for Netscape Navigator
on various platforms:
Netscape Navigator hardware requirements
Platform/Processor Disk Space Recommended Memory Minimum Memory
MS Windows/386sx 1MB 1MB 1MB
Macintosh/68020 2MB 8MB 4MB
UNIX/not applicable3MB 16MB 16MB
------------------------------------------------------------------
Note
A 14.4 Kbps or higher speed modem is recommended.
------------------------------------------------------------------
If you do not already have Netscape Navigator installed, you can send an
e-mail to sa...@netscape.com or call Netscape at (415) 528-2555 for
purchasing information (Netscape Navigator list price: $39.00). Netscape
Navigator is supported by Netscape Communications Corporation.
A Proxy Server
If there is a firewall between your system and the Internet connection, you
must use a proxy server that supports Secure Sockets Layer (SSL) protocol,
or use an approved NSC SOCKS server. Check with your network administrator
to get the details on the SOCKS or proxy server being used at your location.
------------------------------------------------------------------
Note
Sybase provides an on-line FAQ regarding SSL when you click on the
registration option for SupportPlus Online Services.
------------------------------------------------------------------
Guidelines for Using dbcc with System 11
Sybase offers a suite of utilities for system operations. The fundamental
system maintenance utilities are dump, load, and dbcc. These are your
building blocks for developing a system maintenance and operations strategy.
Customers have wondered whether they should run dbcc prior to every backup.
This is the same issue faced by all large system designers: when, in what
manner, and how often does the application need to have a database backup?
The application design challenge is to balance the amount of data exposure
risk against the time and capital required to maintain the system. System
backups and data consistency checking are a part of the overall system
design.
About dbcc
The dbcc utility has many diagnostic features, including data and index
consistency features. You can use dbcc proactively to detect small problems
before they become larger problems.
When you execute dbcc utility prior to a system backup, it notifies you of
potential problems that must be corrected before backup may occur. If a
database has corrupt data pages and the corruption is not fixed prior to a
backup, under very rare circumstances recovery from that backup could fail.
When to Use dbcc
While the quality initiative implemented with SQL Server 11 allows you
greater flexibility in system maintenance, it should be considered that the
dbcc utility has repeatedly been proven to be a useful tool in identifying
both hardware and other software problems which in turn could affect the
integrity of a Sybase database. For stable systems with large databases, you
should run dbcc periodically, depending on your system situation, the data
volatility, and the data exposure risk for the project as a whole.
The following summarizes when to use dbcc:
* To determine the extent of possible damage after a system error occurs.
* If you are experiencing a period of hardware or computer facility
failures.
* If you suspect that a database is damaged. For example, if using a
particular table generates the message "Table corrupt," the dbcc
utility can determine whether other tables in the database are also
damaged.
* After installing new revisions of software, both database and
application. You may want to run the dbcc utility for a few days or
weeks just to be sure that everything is running smoothly.
* Periodically, as part of your business continuity plan.
SQL Server and Serialized Log Writes
Question
What is the advantage of serial over parallel log writes? Why does SQL
Server use serial writes by default?
Answer
When devices are mirrored on a system, the system can perform I/O in
parallel (with asynchronous I/O completion) or in serial (where one I/O must
complete before the next one begins).
By default, SQL Server uses serialized, rather than parallel, writes to
mirrored log devices, in order to guarantee that at least one log will be
uncorrupted on recovery. Here are two examples of how serialized log writes
reduce the risk of corruption from hardware failure:
* SQL Server writes in 2k pages, but most controllers write in 512-byte
blocks. Thus, one log could be corrupted if a hardware error occurred
which interrupted a SQL Server page write.
* Most smart controllers write blocks in the fastest order, which may not
be 1-2-3-4. If the controller can write 3-4 now and can wait to write
1-2 when the disk spins around again, it will. In this case, a failure
that interrupts the controller might leave the last log page partially
written, for that log.
With serial writes, in both these cases, the other log will still be
uncorrupted. SQL Server knows which is the uncorrupted log because the side
of the mirror that failed is so flagged.
sp_who Showing loginame Field Change
Question
Why does sp_who show the procedure owner, instead of the current user, in
the loginame field when that user executes a stored procedure?
For example, suppose user "john" is logged in and sp_who shows the loginame
as "john". When "john" executes a stored procedure owned by "sa", sp_who
shows "sa" as the value for loginame even though "john" is executing that
stored procedure. Why is this?
Answer
When recompiling, the procedure is put into creation time context, and the
user is set to owner of the procedure. This is expected behavior and is
required to resolve the name of referenced objects.
Backup Server Performance
Sybase has received many different questions about dump/load performance.
This article is a brief summary of the information you need to solve
dump/load performance problems.
Backup Server Data Flow
Imagine the flow of dump/load data as water in a pipe. On one end of the
pipe are the the database disks, on the other, the archive devices:
[Image]
If any section of the pipe is narrower than the others, the total flow will
be no greater than can pass through that section.
Depending on your hardware, the areas in which to look for bottlenecks are:
* Disk I/O throughput
* SCSI database disk controller throughput
* Archive device I/O throughput
* SCSI archive device controller throughput
* Main bus
* SCSI adapters
* CPU usage
Finding Data Flow Bottlenecks
In order to determine where the bottlenecks are, you must:
* Monitor system statistics
* Determine the number of I/Os and the I/O rate through the various
hardware components.
Use utilities like sar or iostat (both for UNIX) to monitor system
statistics. On most platforms you can monitor disk I/O rate, number of I/Os
per disk, and system CPU utilization. The amount of time in system, process
and waiting for I/O is important.
You need the exact hardware configuration and published I/O rates for the
various I/O subsystem components. Some typical numbers that have been
measured in dump/load benchmarks are shown in the following table
I/O rates from benchmarks
System Component Rates/Limits
50 I/Os per second.2000K/second (using up to 8
database disk stripes).1600K/second (using 8-16 stripes).Fast and
wide SCSI has the highest rate. SCSI II has the next
highest rate. SCSI has the lowest.
SCSI controller No more than 3 tape devices on one controller.No more
than 4 database disks on one controller.
adapter and main
bus Actual rate is 25% of the published figure.
8mm tape 500K/second.
8mm compressing
tape (Exabyte 1000K/second.
8505)
4mm tape 183K/second.
4mm compressing
tape 366K/second.
Additional Information
Here are two additional items to consider, both of them from the standpoint
of Backup Server itself, rather than the hardware:
* The dump algorithm does not load balance over stripes. Each stripe gets
approximately the same amount of data.
* Mixing fast and slow archive devices is not good from a performance
standpoint, since the same amount of data will be written to both
devices and will not complete until all data is written to the slow
device.
Example Analysis
Suppose a database is resident on one disk. Assume that the database disk
SCSI controller, bus adapter, main bus, and archive device SCSI adapter have
unlimited throughput. The archive devices are 8mm compressing tape drives.
You should consider two questions:
* How many stripes should I use to get the quickest dump time?
* How long will it take to dump 1GB of data?
Here are your datapoints for analysis:
* Since the database resides only on one disk, the fastest that data can
come off the disk is 2000K/second.
* Given that the 8mm compressing tape drive can run at 1000K/second, the
configuration that will yield the fastest dump rate would be a two
stripe dump.
* Adding more stripes will yield no better results; the disk becomes the
bottleneck in that case (actually, using more stripes will slow the
dump down since the tapes may not be able to stream).
Thus, to dump a 1GB database using two stripes should take about eight
minutes, at the rate of 2000K/second.
OpenVision High Availability Configuration and SQL Server
The following is an advisory about using the to OpenVision High Availability
software configuration application with Open Client Client-Library and SQL
Server.
History of the Issue
During testing of a System 10 Client-Library application on AIX, connecting
to various 4.9.2 (EBF 4157) Solaris-based SQL Servers, a customer noticed
that ct_cancel, dbcancel, or Ctrl-C calls (all out-of-band dataŻOOBDŻcalls)
would hang the application if directed to certain SQL Servers.
All machines involved were running Solaris 2.3. The SQL Servers that hung
had one thing in common: they were also running OpenVision High Availablity
(HA) software.
OpenVision HA provides for automatic and transparent retargeting of one SQL
Server's processing to another in the event of a failure in the primary
machine. Two or more machines are connected to a common set of dual ported
disk drives. An OpenVision HA process runs on each machine in the
configuration, and detects and allows for failover of Sybase operations to
the remaining machine(s).
Explanation and Action
The source of the problem turned out to be that an OpenVision HA script was
setting the TCP/IP parameter tcp_old_urp_interpretation to a value of 0.
When this value was changed to 1, and the application reconnected to the
server, ct_cancel events no longer caused a hang. The 1 setting allowed SQL
Server to interpret and handle OOBD properly.
If your Solaris platform includes OpenVision HA, DB-Library or
Client-Library, and SQL Server, check the value of
tcp_old_urp_interpretation and be sure it is set to 1, by following these
steps:
1. Execute the following command:
/usr/sbin/ndd -get /dev/tcp tcp_old_urp_interpretation
2. If the value returned is not 1, execute the following command:
ndd -set /dev/tcp tcp_old_urp_interpretation 1
For more information on OpenVision High Availability software, please visit
their URL, http://www.ov.com.
Passing a UNIX Variable to a SQL Script
Question
How can I pass a UNIX variable to a SQL script?
Answer
Use UNIX level variables with isql inside a shell script file.
Example
In the following example, a database name is passed to a script that gets
sp_helpdb information and directs it to a file, /tmp/helpdb_dbname.
#!/bin/sh
#---------------------------------------------------------------
# name: sql_var_passer [v1.0]
# usage: sql_var_passer <dbname>
#
# comments:
# - This program invokes isql, which reads input from this
# file down to the line that says "EOF".
# - $1 is the argument <dbname> -- that is, the first arg to
# the program.
# - $pwd is on a line by itself inside the input for isql in
# order to prevent the password from being echoed in the
# output from "ps", as a security precaution.
#----------------------------------------------------------------
SYBASE=/usr/sybase
server="myserver"
user="sa"
pwd=""
$SYBASE/bin/isql -U${user} -S${server} <<EOF >/tmp/helpdb_$1
$pwd
sp_helpdb $1
go
EOF
echo ""
cat /tmp/helpdb_$1
echo ""
#=================== END OF SCRIPT==========================
Here is a sample run of the example script:
sql_var_passer master
name db_size owner dbid created status
-------- -------- -------- ------ ------------- ---------------
master 3.0 MB sa 1 Jan 01, 1900 no options set
device_fragments size usage free kbytes
----------------------- --------- -------------- -----------
master 3.0 MB data and log 896
device segment
---------------------------------------------- ----------------
master default
master logsegment
master system
(return status = 0)
Size Conversion Stored Procedures
Summary
The following stored procedures provide tools for doing a variety of size
conversions, as follows:
* sp_convertpages  accepts an argument representing a given number of 2k
pages, and will return the equivalent units of bytes, kilobytes,
megabytes and blocks
* sp_convertmegs  accepts an argument representing a given number of
megabytes, and will return the equivalent units of bytes, kilobytes,
blocks and pages
* sp_convertkbs  accepts an argument representing a given number of
kilobytes, and will return the equivalent units of bytes, megabytes,
blocks and pages
* sp_convertbytes  accepts an argument representing a given number of
bytes, and will return the equivalent units of kilobytes, megabytes,
blocks and pages
------------------------------------------------------------------
Note
If you are running on a Stratus platform, which uses 4k pages, you
will have to edit the sp_convertpages script accordingly.
------------------------------------------------------------------
Save the scripts to a file named sp_convertprocs, and then execute the
following command to add the stored procedures to sybsystemprocs:
isql -Usa -Ppassword < sp_convertprocs
------------------------------------------------------------------
WARNING!
Thes scripts are neither maintained nor supported by Sybase
Technical Support. You may modify them to suit your installation.
------------------------------------------------------------------
The Scripts
/* FileName:
sp_convertprocs
To Implement:
isql -Usa -P < sp_convertprocs
History:
22-Jan-96 v1.0 Creation [wg]
*/
use sybsystemprocs
go
/* The sp_convertpages procedure starts here */
create proc sp_convertpages @num_pgs_in int as
set nocount on
declare @total_byts_of_pgs int
declare @num_meg int
declare @num_blks int
declare @num_pages int
declare @num_kb int
declare @blockstring char(35)
declare @pagestring char(35)
declare @megstring char(35)
declare @kbstring char(35)
declare @bytstring char(35)
select @num_pages=@num_pgs_in
select @total_byts_of_pgs=(@num_pages * 2048)
select @num_blks=@total_byts_of_pgs/512
select @num_meg=@total_byts_of_pgs/1048576
/* where 1048576 is 1024*1024 bytes/meg) */
select @num_kb=@total_byts_of_pgs/1024
select @pagestring= "Total Pages Input : " + convert(char(35),@num_pages)
select @blockstring="Number of Blocks : " + convert(char(35),@num_blks)
select @megstring= "Number of Megabytes : " + convert(char(35),@num_meg)
select @bytstring="Number of Bytes : " + convert(char(35),@total_byts_of_pgs)
select @kbstring="Number of Kilobytes : " + convert(char(35),@num_kb)
create table #space_convert_table(Storage_Conversion_Utility char(35))
insert #space_convert_table values (@pagestring)
insert #space_convert_table values ("--------------------------")
insert #space_convert_table values (@bytstring)
insert #space_convert_table values (@kbstring)
insert #space_convert_table values (@blockstring)
insert #space_convert_table values (@megstring)
select * from #space_convert_table
go
grant execute on sp_convertpages to public
go
/* The sp_convertmegs procedure starts here */
create proc sp_convertmegs @num_megs_in int as
set nocount on
declare @total_byts_of_megs int
declare @num_megs int
declare @num_blks int
declare @num_pages int
declare @num_kb int
declare @blockstring char(35)
declare @pagestring char(35)
declare @megstring char(35)
declare @kbstring char(35)
declare @bytstring char(35)
select @num_megs=@num_megs_in
select @total_byts_of_megs=@num_megs * 1048576
/* where 1048576 is 1024*1024 bytes/meg) */
select @num_blks=@total_byts_of_megs/512
select @num_pages=@total_byts_of_megs/2048
select @num_kb=@total_byts_of_megs / 1024
select @megstring= "Total Megs Input : " + convert(char(35),@num_megs)
select @pagestring="Number of Pages : " + convert(char(35),@num_pages)
select @blockstring="Number of Blocks : " + convert(char(35),@num_blks)
select @bytstring= "Number of Bytes : " + convert(char(35),@total_byts_of_megs)
select @kbstring= "Number of Kilobytes : " + convert(char(35),@num_kb)
create table #space_convert_table(Storage_Conversion_Utility char(35))
insert #space_convert_table values (@megstring)
insert #space_convert_table values ("--------------------------")
insert #space_convert_table values (@bytstring)
insert #space_convert_table values (@kbstring)
insert #space_convert_table values (@blockstring)
insert #space_convert_table values (@pagestring)
select * from #space_convert_table
go
grant execute on sp_convertmegs to public
go
/* The sp_convertkbs procedure starts here */
create proc sp_convertkbs @num_kb_in int as
set nocount on
declare @total_byts_of_kb int
declare @num_megs int
declare @num_blks int
declare @num_pages int
declare @num_kb int
declare @blockstring char(35)
declare @pagestring char(35)
declare @megstring char(35)
declare @kbstring char(35)
declare @bytstring char(35)
select @num_kb=@num_kb_in
select @total_byts_of_kb=@num_kb * 1024
select @num_blks=@total_byts_of_kb/512
select @num_pages=@total_byts_of_kb/2048
select @num_megs=@num_kb/1024
select @megstring= "Number of Megs : " + convert(char(35),@num_megs)
select @pagestring="Number of Pages : " + convert(char(35),@num_pages)
select @blockstring="Number of Blocks : " + convert(char(35),@num_blks)
select @bytstring= "Number of Bytes : " + convert(char(35),@total_byts_of_kb)
select @kbstring= "Total Kilobytes : " + convert(char(35),@num_kb)
create table #space_convert_table(Storage_Conversion_Utility char(35))
insert #space_convert_table values (@kbstring)
insert #space_convert_table values ("--------------------------")
insert #space_convert_table values (@bytstring)
insert #space_convert_table values (@megstring)
insert #space_convert_table values (@blockstring)
insert #space_convert_table values (@pagestring)
select * from #space_convert_table
go
grant execute on sp_convertkbs to public
go
/* The sp_convertbytes procedure starts here */
create proc sp_convertbytes @num_blks_in int as
set nocount on
declare @total_byts_of_blks int
declare @num_meg int
declare @num_blks int
declare @num_pages int
declare @num_kb int
declare @blockstring char(35)
declare @pagestring char(35)
declare @megstring char(35)
declare @kbstring char(35)
declare @bytstring char(35)
select @num_blks=@num_blks_in
select @total_byts_of_blks=@num_blks * 512
select @num_pages=@num_blks/ 4
select @num_meg=@total_byts_of_blks/1048576 /* where 1048576 is 1024*1024 bytes/meg)*/
select @num_kb=@total_byts_of_blks / 1024
select @blockstring="Total Blocks Input : " + convert(char(35),@num_blks)
select @pagestring= "Number of Pages : " + convert(char(35),@num_pages)
select @megstring= "Number of Megabytes : " + convert(char(35),@num_meg)
select @bytstring= "Number of Bytes : " + convert(char(35),@total_byts_of_blks)
select @kbstring= "Number of KiloBytes : " + convert(char(35),@num_kb)
create table #space_convert_table(Storage_Conversion_Utility char(35))
insert #space_convert_table values (@blockstring)
insert #space_convert_table values ("-----------------------------------")
insert #space_convert_table values (@bytstring)
insert #space_convert_table values (@kbstring)
insert #space_convert_table values (@megstring)
insert #space_convert_table values (@pagestring)
select * from #space_convert_table
go
grant execute on sp_convertblocks to public
go
Procedure to Drop Size Conversion Procedures
The sp_dropconverts stored procedure allows for the orderly drop of the size
conversion procedures.
create proc sp_dropconverts as
if exists (select * from sysobjects where name = "sp_convertblocks")
begin
drop proc sp_convertblocks
end
if exists (select * from sysobjects where name = "sp_convertpages")
begin
drop proc sp_convertpages
end
if exists (select * from sysobjects where name = "sp_convertmegs")
begin
drop proc sp_convertmegs
end
if exists (select * from sysobjects where name = "sp_convertkbs")
begin
drop proc sp_convertkbs
end
if exists (select * from sysobjects where name = "sp_convertbytes")
begin
drop proc sp_convertbytes
end
go
grant execute on sp_dropconverts to public
go
tli_mapper Script and User Guide
The script included in this article is distributed to assist DBAs with the
translation of various IP addresses and port numbers to TLI (Transport Layer
Interface) strings, and back again. You may find it most handy during large
scale network addressing changes.
------------------------------------------------------------------
Note
The mapping of TLI strings may contain platform specific address
family and padding values (explained below). Check your current
interfaces file to confirm those values and make any changes
necessary to tli_mapper.
Also note that this utility requires a running SQLServer to
perform the calculations. Update tli_mapper accordingly to reflect
your $SYBASE and $DSQUERY values.
------------------------------------------------------------------
------------------------------------------------------------------
WARNING!
This script is neither maintained nor supported by Sybase
Technical Support. You may modify it to suit your installation.
------------------------------------------------------------------
TLI Creation/Change Implications
TLI address strings refer to an access path across which the SQL Server and
clients communicate. These strings are embedded in the interfaces file, and
reflect hex-translated references to the IP address and port number, along
with some TLI structure-specific information.
You ordinarily use sybinit to create the interfaces file. However, when
local network designations or internal addresses change, you can make
changes two ways:
* Delete and add SQL Servers with sybinit
* Converte the existing TLI addresses manually
------------------------------------------------------------------
WARNING!
Be very careful when you consider manually editing the interfaces
file. Each line is highly sensitive to the tab and positional
format references. If you inadvertantly insert a space or
character the SQL Server may be unable to start up, or clients may
be unable to communicate with it. When you must translate and
change long, cryptic TLI numeric strings like this one:
x00021E6C9D0E7D240000000000000000
the chance for error increases yet again.
------------------------------------------------------------------
The tli_mapper Utility
The tli_mapper utility has been created to ease the transition of SQL
Servers to new network addresses.
When invoked, tli_mapper accepts either of the following:
* IP address/port number combination, in which case it produces a
translated TLI Address string, or
* TLI Address string, in which case translates it to a specific IP
address and port number.
If you have to change a large number of SQL Servers to new addresses, you
can simply pass each address/port number combination to tli_mapper, and use
the return value to update the interfaces file accordingly. The process
should significantly lower the risk of making a transition to a new network
addressing scheme.
Further Noteworthy Items
Any change you make to the interfaces file should be consistent with the
current address and port of the machine. Make sure that any tests of a new
interface file target a machine running the new address location.
In a production environment, the time window to perform the changeover might
not be long enough to perform the conversions and edits. You may want to
consider making a copy of the interfaces file and use that as a source for
your changes. During tests, you may be able to selectively change targets
and connect to them using the
-Iinterfacesfilename option of isql. When it is time for the actual cutover,
you can simply rename the file to reflect the true interfaces file name.
The tli_mapper utility was developed for a Solaris machine, which uses an
"address family" value of 0002 and 16 zeros as TLI address padding
(explained in more detail below). This numbering scheme is fairly common on
other TLI-based platforms. Please review your current interfaces file, note
the address family/pad spaces in use, and if different, update the variables
ADDRESS_FAMILY and PAD_SPACES in tli_mapper accordingly.
Note also that tli_mapper can interrogate a particular IP address to detect
activity on the port. This option is handy to check for a SQL Server's
ability to respond to client requests.
The Interfaces File and TLI Structure
Here is a typical interfaces file entry:
SERVERNAME
query tli tcp /dev/tcp x00021E6C9D0E7D240000000000000000
master tli tcp /dev/tcp x00021E6C9D0E7D240000000000000000
The lines which begin with query and master are referred to as service
lines. This table describes the parts of the service line:
Interfaces file entry line breakdown
Line
Part Value Description
query, Identifies the service:query  where clients connect
1 master, or to find the servermaster  where servers listen for
console connectionsconsole - used for the dump/load process
(not in versions 10.x and after)
2 tli Indicates that this is an entry for a machine with a
TLI-based programming interface.
Used by utility programs, including sybtli, to
3 tcp indicate an entry for a TCP/IP interface rather than
SPX (Novell) or StarLan.
The device file which acts as an interface between
4 /dev/tcp the user program and the networking software; the
network "end point."
The TLI
5 network See Table 7.
address
Here is the breakdown of the parts of the TLI network address
00021E6C9D0E7D240000000000000000:
TLI Network Address Breakdown
Address Part Description
Denotes that this entry is a TLI "address family". This is
always at the start of a TLI address. TCP/IP is family
2.Depending on the network vendor and the byte order of
the machine, this works out as a hexadecimal "0002" (most
0002 common) or "0200" (the format is dependent on whether the
machine is "little endian" or "big endian"). Take a look
at how your current interfaces file is structured to
confirm your address family number format, and make a
change to the variable ADDRESS_FAMILY in tli_mapper
accordingly.
This is the hexadecimal equivalent of the port number. In
1E6C this example, the hexadecimal address 1E6C translates to
the decimal address 7788.
This 8-digit hexadecimal address is the translation of the
decimal IP address equivalent. The address is formed by
translating each decimal portion of the IP address,
separated by the period, to its hexidecimal
equivalent(minus the periods). Single digits are entered
9D0E7D24 with a leading zero.
* 9D [Image] 157
* 0E [Image] 14
* 7D [Image] 125
* 24 [Image] 36
This closes out the TLI address. This 16 zero set serves
to pad the remaining TLI address and is mandatory at the
0000000000000000end of the address string. Note that the number of padded
zeros is platform specific. Please check the number of
padded zeros in your current interfaces file, and adjust
the variable PAD_SPACES in tli_mapper accordingly.
Sample Runs of tli_mapper Utility
This section contains some examples of tli_mapper in action.
No Line Arguments
Executing tli_mapper with no line arguments returns the usage information.
tli_mapper
_____________________________
| |
| *** >> TLI-IP Mapper << *** |
|_____________________________|
Usage:
------
tli_mapper [-t]
[-i]
[-x]
where
[-t] translates a TLI string to IP/PORT number
[-i] translates an IP/PORT number to a TLI string
[-x] examines an IP/PORT combination for activity
Input Format Examples:
----------------------
HOSTADDRESS >> 157.14.125.36
PORTNUMBER >> 7756
TLISTRING >> 00021E4C9D0E7D240000000000000000
Using the -t Flag
Executing tli_mapper with the -t flag returns an address and port number
based on the TLI string you enter. The computer prompts are included in this
example; user input is indicated by boldface.
tli_mapper -t
_____________________________
| |
| *** >> TLI-IP Mapper << *** |
|_____________________________|
Enter TLI String >> 00021E4C9D0E7D240000000000000000
=================================
Completed IP Translation String :
IPADDRESS : 157.14.125.36
PORT : 7756
=================================
... program exiting.
Using the -i Flag
Executing tli_mapper with the -i flag returns a TLI string based on the
address and port number you enter. The computer prompts are included in this
example; user input is indicated by boldface.
tli_mapper -i
_____________________________
| |
| *** >> TLI-IP Mapper << *** |
|_____________________________|
Enter IP Address >> 157.14.125.36
Enter Port Number >> 7788
=================================
Completed IP Translation String :
x00021E6C9D0E7D240000000000000000
=================================
... program exiting.
Using the -x Flag
Executing tli_mapper with the -x flag tests the address and port number you
enter for activity. The computer prompts are included in this example; user
input is indicated by boldface.
tli_mapper -x
_____________________________
| |
| *** >> TLI-IP Mapper << *** |
|_____________________________|
Enter IP Address >> 157.14.125.36
Enter Port Number >> 7788
*** Testing for IP and PORT activity :
==========================================
IP Address : 157.14.125.36
Port Number : 7788
is ACTIVE and in a LISTEN state.
==========================================
... program exiting.
Closing Comments
tli_mapper requires that a SQL Server be up and running to perform the
translations, but there is no error checking in this version for the
existence of such a server.
Before you run tli_mapper, make sure that the variables $SYBASE and $DSQUERY
reflect your operating environment and edit them if necessary.
Make the script executable with the following command before you try to run
it:
chmod +x tli_mapper
The Script
#!/bin/csh -f
# Name: tli_mapper
# Generic UNIX script to take perform IP Address
# and Port Number translations to a TLI String,
# or perform TLI to IP/Port Number translations.
# This script can also interrogate a particular
# IP Address/Port number combination to see if
# a process is listening on the port.
#------------------------------------------------
# History:
# 22-Jan-96 v1.0 creation [wg]
# 18-Jun-96 v1.1 slight mods to embedded isql
# command lines [am & lah], addition
# of formatting help lines [am]
#+++++++++++++++++++++++++++++++++++++++++++++++++
umask 0
setenv SYBASE /usr/u/sybase
setenv DSQUERY SYBASE
echo ""
echo " _____________________________"
echo "| |"
echo "| *** >> TLI-IP Mapper << *** |"
echo "|_____________________________|"
echo ""
if ($#argv == 0) then
set SW = "0"
else
set SW = "`echo $argv[1] | cut -d"-" -f2`"
endif
if ($SW != "i" && $SW != "t" && $SW != "x") then
echo "Usage: "
echo "------"
echo " tli_mapper [-t]"
echo " [-i]"
echo " [-x]"
echo "where"
echo ""
echo " [-t] translates a TLI string to IP/PORT number "
echo " [-i] translates an IP/PORT number to a TLI string"
echo " [-x] examines an IP/PORT combination for activity"
echo ""
echo "Input Format Examples:"
echo "----------------------"
echo "HOSTADDRESS >> 157.14.125.36"
echo "PORTNUMBER >> 7756"
echo "TLISTRING >> 00021E4C9D0E7D240000000000000000"
echo ""
exit
endif
if ($SW == "t") then
echo ""
echo "Enter TLI String in the format: "
# Help with format...
echo "AdrfPortIpIpIpIp0000000000000000"
echo -n ">> "
set tlist = ($<)
echo $tlist | grep "x" > /dev/null
if ($status == 0) then
echo ""
echo "... please leave off the leading x"
echo ""
exit
endif
if ($tlist == "") then
echo ""
echo "*** No String Input - TLI String. Exiting. "
echo ""
exit
endif
set ct=1
set tlistring=${tlist}
set total_ip_address=""
$SYBASE/bin/isql -Usa -P <<EOS >! /tmp/vrstring
set nocount on
select substring("${tlistring}",5,4)
select substring("${tlistring}",9,2)
select substring("${tlistring}",11,2)
select substring("${tlistring}",13,2)
select substring("${tlistring}",15,2)
go
EOS
foreach BASEVALS ('cat /tmp/vrstring | grep -v "-" ')
$SYBASE/bin/isql -Usa -P <<SYBMARK >! /tmp/holder
set nocount on
select hextoint("${BASEVALS}")
go
SYBMARK
set individual_entry=`cat /tmp/holder|grep -v "-" `
if ($ct == 1) then
set port_number=$individual_entry
else if ($ct == 2) then
set total_ip_address=$individual_entry
else
set total_ip_address=$total_ip_address.$individual_entry
endif
set ct=`expr $ct + 1`
end
echo ""
echo "================================= "
echo "Completed IP Translation String : "
echo ""
echo "IPADDRESS : $total_ip_address "
echo "PORT : $port_number"
echo ""
echo "================================= "
echo ""
else if ($SW == "i") then
echo ""
echo "Enter IP Address in the following format:"
# Help with format
echo "nnn.nnn.nnn.nnn"
echo -n ">> "
set ipa = ($<)
if ($ipa == "") then
echo ""
echo "*** No String Input - IP Address. Exiting. "
echo ""
exit
endif
echo "Enter Port Number in the following format:"
echo "AdrfPortIpIpIpIp0000000000000000"
echo -n ">> "
set iport=($<)
if ($iport == "") then
echo ""
echo "*** No String Input - Port Number. Exiting. "
echo ""
exit
endif
set DOM="`echo $ipa | cut -d. -f1\Q"
set ARE="\Qecho $ipa | cut -d. -f2\Q"
set LOC="\Qecho $ipa | cut -d. -f3\Q"
set MAC="\Qecho $ipa | cut -d. -f4\Q"
set ct=1
$SYBASE/bin/isql -Usa -P <<EOS >! /tmp/port
set nocount on
select right((select inttohex(${iport})),5)
go
EOS
set ronport=\Qcat /tmp/port | grep -v "-" \Q
foreach IPSTRING ( ${DOM} ${ARE} ${LOC} ${MAC} )
$SYBASE/bin/isql -Usa -P <<SYBMARK >! /tmp/holder
set nocount on
select right((select inttohex(${IPSTRING})),3)
go
SYBMARK
set individual_entry=\Qcat /tmp/holder|grep -v "-" \Q
if ($ct == 1) then
set total_ip_address=$individual_entry
else
set total_ip_address=$total_ip_address$individual_entry
endif
set ct=\Qexpr $ct + 1\Q
end
echo ""
echo "================================= "
echo "Completed IP Translation String : "
echo ""
echo "x0002${ronport}${total_ip_address}0000000000000000"
echo ""
echo "================================= "
echo ""
else if ($SW == "x") then
echo ""
echo "Enter IP Address in the following format: "
echo "nnn.nnn.nnn.nnn"
echo -n ">> "
set ipa = ($<)
if ($ipa == "") then
echo ""
echo "*** No String Input - IP Address. Exiting. "
echo ""
exit
endif
echo "Enter Port Number in the following format: "
echo "AdrfPortIpIpIpIp0000000000000000"
echo -n ">> "
set iport=($<)
if ($iport == "") then
echo ""
echo "*** No String Input - Port Number. Exiting. "
echo ""
exit
endif
echo ""
echo ""
echo "*** Testing for IP and PORT activity : "
echo ""
rsh ${ipa} netstat -a | grep ${iport} | grep LISTEN > /dev/null
if ($status == 1) then
echo "=========================================="
echo "WARNING: Selected Port Number ${iport}"
echo "is not active on IP Address ${ipa}"
echo "=========================================="
echo ""
else
echo "=========================================="
echo "IP Address : ${ipa} "
echo "Port Number : ${iport} "
echo "is active and in a LISTEN state."
echo "=========================================="
echo ""
endif
echo "... program exiting. "
Urgent Data Setup Requirements
Question
How do I set up out-of-band or urgent data for SQL Server with a PC client?
Answer
In order for the "urgent" flag to have an effect, both the PC and the host
must use out-of-band data (OOBD) per the RFC 793 specification.
There are two standards for OOBD, RFC 793 (single bit), and RFC 1122 (seven
bit). Sybase software uses only the single bit version. Operating system and
other software vendors vary in which standard they use. Solaris, for
example, implements RFC 1122 as the default for OOBD. This means that
Net-Library will not be able to pass the correct data, since it is using an
urgent bit instead of an urgent byte. ODBC uses RFC 1122 as well, but you
can also implement the RFC 793 style of OOBD with the 34cancel parameter.
------------------------------------------------------------------
Note
RFC stands for Request For Change, which is how changes to IEEE
standards are tracked.
------------------------------------------------------------------
The following vendors support OOBD:
Vendors supporting OOBD
Vendor Comments
FTP Supports RFC 793, but the default standard is RFC 1122. You must
PC/TCP load ethdrv.exe with the -b option (it stands for BSD style,
another name for RFC 793) to use RFC 793 style urgent data.
Almost all TCP/IP protocol stacks support RFC 793 in their
TCP/IP current implementations. Some older versions of the software
(for example, LWP 4.0) did not have this style of OOBD
implemented and needed a patch in order to do so.
IPX/SPX Supports RFC 793.
Named
Pipes Supports RFC 793.
DECNet does not support OOBD.
Most hosts that have TCP/IP support RFC 793, and need no modifications to
use this style of urgent data. The exceptions are:
* Solaris 2.2 Â needs patch 101018-06 & -04
* Solaris 2.3 Â needs patch 101346-03
In both these versions of Solaris, you may need to execute this command:
/usr/sbin/ndd -set /dev/tcp tcp_rexmit_interval_max XXXX
where XXXX is the number of milliseconds (500 for 1/2 second) by which to
increase the TCP retransmit interval.
If you are running on NCR Unix System V.4 2.0.2, you must change the
following parameter in the file /etc/conf/pack.d/tcp/space.c:
int tcp_bsd42_urgent = 0
to
int tcp_bsd42_urgent = 1
You must then recompile, rebuild the kernel, and restart the operating
system.
Question
How do SQL Server 11.0 and 10.x differ from 4.9.x in their handling of
out-of-band data?
Answer
In-band urgent data is sent in the normal stream of communications. SQL
Server versions prior to 10.x use only RFC 793 OOBD and don't use in-band
attention signals. Version 10.x and later SQL Servers use in-band attention
signals, and can also respond to OOBD by using the RFC 793 style urgent bit.
This means that clients running DB-Library versions older than 10.x can
communicate a dbcancel() to a version 10.x and later SQL Server. However,
because a System 10 client does not use RFC 793 at all, it will not send
urgent data to a pre-System 10 server.
Net-Library versions prior to 10.x use OOBD, and can't do in-band attention.
Net-Library versions 10.x and later will do only in-band attention, and will
not send OOBD.
Explanation of "nrpacket: recv, Connection timed out"
Question
I occasionally see the following message in my error log:
nrpacket: recv, Connection timed out.
What does it mean?
Answer
This is an OS error message. It is raised when SQL Server calls the recv
function, but the connection has failed either before or during the recv
function. It is not a SQL Server error; SQL Server merely reports it.
Explanation
There are a few reasons why the connection might have failed:
* The client exited without going through a disconnect, as when someone
switches off their PC. (This is the most likely cause.)
* The network is extremely busy and is dropping packets.
* KEEPALIVE is disabled for the OS, so TCP/IP times out the connection
when the client has been idle for some time.
Bug 66639/73421 - alter database in VLDB May Cause 605 Errors
Question
Some time after executing alter database in a very large database, I got a
605 error referring to the system table sysgams:
Attempt to fetch logical page 0 in database my_huge_db belongs to object id 99, not to object sysgams
There seems to be no database corruption. What's going on?
Answer
While there are other causes of 605 errors, the reference to sysgams in the
605 error points to the cause being bug 66639 (SQL Server 10.x) or the
related bug 73421 (SQL Server 11.x), both of which have been fixed recently.
------------------------------------------------------------------
Note
The bug only occurs with alter database and not with create
database.
------------------------------------------------------------------
Explanation
The error might occur any time after you use alter database to increase the
size of a database through a boundary which is a multiple of 63GB (63, 126,
189 or 252). The sysgams table is used to manage new allocations. Using
alter database to extend the size of the database through the 63GB boundary
fails to extend the sysgams table as it should. The 605 error occurs as SQL
Server looks for the non-existent page in sysgams.
While there should be no data corruption as a result of this bug, no new
allocations can take place without raising a 605, rendering the database
unusable for writing.
The only workaround known at present, should you encounter this bug, is to
bcp the data out, drop and re-create the database with the larger size, and
bcp the data back in. If this is not feasible, it is possible for Sybase
Technical Support to patch a new sysgams extent.
Are You at Risk?
There are two types of customers who are at risk for this bug:
* Those who will want to alter the size of their database past one of the
63GB boundaries in the near future.
* Those who have already altered the database through one of the 63GB
boundaries but who have not yet had any 605 errors.
Again, this bug has been fixed both in 11.x and 10.0.x. If you think you are
at risk for this bug, Sybase recommends you get EBF 6201 and above for SQL
Server 10.x (Bug #66639). Bug #73421 appeared only in beta releases of SQL
Server 11.x and was fixed for the GA release.
------------------------------------------------------------------
Note
Once the alter database has been done with an EBF not containing
the fix, the problem will persist (if you have it at all) until
patched out. Get the EBF and install it before you do the alter
database.
------------------------------------------------------------------
Disclaimer: No express or implied warranty is made by Sybase or its
subsidiaries with regard to any recommendations or information presented in
SYBASE Technical News. Sybase and its subsidiaries hereby disclaim any and
all such warranties, including without limitation any implied warranty of
merchantability of fitness for a particular purpose. In no event will Sybase
or its subsidiaries be liable for damages of any kind resulting from use of
any recommendations or information provided herein, including without
limitation loss of profits, loss or inaccuracy of data, or indirect special
incidental or consequential damages. Each user assumes the entire risk of
acting on or utilizing any item herein including the entire cost of all
necessary remedies.
Staff
Principal Editor: Leigh Ann Hussey
FAQ Administrative Note: The credits gif was whacked so I'm
missing some Sybase folks who contributed to this document. Sorry.
Send comments and suggestions to:
Sybase Technical News
6475 Christie Avenue
Emeryville, CA 94608
or send mail to tech...@sybase.com
Copyright 1996 © Sybase, Inc. All Rights Reserved.
Q10.3.5
Sybase Technical News Volume 5 Number 4, October 1996
This issue of Sybase Technical News contains new information about your
Sybase software. This newsletter is intended for Sybase customers with
support contracts. You may distribute it within a supported site; however,
it contains proprietary information and may not be distributed publicly.
Sybase Technical News and the troubleshooting guides are included on the
AnswerBase CD, SupportPlus Online Services Web pages, and the Sybase
PrivateLine forum of CompuServe. Send comments to tech...@sybase.com.To
receive this document by regular email, send name, full internet address and
customer ID to tech...@sybase.com.
In this Issue
Tech Support News/Features
* Changes to Technical News
* Download EBFs and Information from
Sybase ESD
* Tech Info Library Reports
* 1996 Technical Support North American Holiday Schedule
SQL Server General
* Installing Sybase Products from CD-ROM on AIX 3.2.5
* Additional Space Needed When Creating Database Devices on AIX
* Dump Option "with retaindays" Explanation
* Char(N) Variables Appear not to Concatenate
Connectivity / Tools / PC
* Using the BCP_IN Sample Script to load bcp Files
* Using the BCP_OUT Sample Script to Archive Table Data
----------------------------------------------------------------------------
Changes to Technical News
Sybase documentation is undergoing a massive restructuring in order to make
it more useful to customers both internal and external. After five years and
hundreds of articles, Sybase Technical Newsis changing along with the rest
of Sybase's documentation.
For the last several issues Sybase Technical News has been mailedto
customers only on AnswerBase CD (though it has been available through a
number of online systems), with the option to order hardcopy; however, as
there have been no orders for hardcopy in the last year, we will be
discontinuing the option to order it.
Sybase Technical News will continue to be a vehicle for hottopics, and will
eventually be even more useful to you, as it will bedynamically generated
according to parameters specified by you.
After this issue, Sybase Technical News will go on a briefhiatus, but look
for its return in a new, dynamic format, on the WorldWide Web and through
our new Knowledge Base.
Accessing SupportPlus Online Services
Sybase SupportPlus Online Services (SOS) is your World Wide Web connection
to many of Sybase's services, including our Tech Info Library and Electronic
Software Distribution (ESD).
Register for SupportPlus Online Services
Follow these steps to register for SOS:
1. Connect to the Sybase Web page athttp://www.sybase.com
2. Click on Services & Support.
3. Click on Sybase Enterprise Technical Support.
4. Click on SupportPlus On-line Services Registration.
5. On the registration screen, fill in your contact ID (leave blank if you
do not know your contact ID), your Internet e-mail address, your
(user-defined) password, your company name, your Sybase customer
number, your name, and your telephone number.
6. Click on the Submit Registration Form button.
Your registration form is then electronically checked. If it is correct, you
may immediately begin using SOS. If any information is missing from the form
or information does not correspond with our records, a Sybase customer
service representative will verify the information, complete the
registration and either contact you or send you an e-mail to inform you of
your registration status.
ESD
The ESD system lets Sybase customers with active support agreements download
bug fixes and information via the World Wide Web. Follow these steps to
reach it:
1. Follow the hyperlinks from the Sybase, Inc. homepage to the SupportPlus
Online Services login screen and log in.
2. Select Electronic Software Distribution from the list of options.
From there, you can download EBFs for your licensed platforms, or view EBF
coverletters to see which bugs are fixed in a particular EBF.
Tech Info Library Reports
Standard reports regularly updated in the Tech Info Library area of SOS
include:
* Product Availability Reports
* Bug List (updated weekly)
* Certification Reports for these Sybase products:
* SQL Server
* Replication Server
* Connectivity products
* System Management produts
1996 Technical Support North American Holiday Schedule
Sybase Technical Support is open on all holidays and provides full service
on many. During the limited-service holidays shown below, Technical Support
will provide the following coverage:
* SupportPlus Preferred and Advantage customers may log all cases; we
will work on priority 1 and 2 cases over the holiday.
* 24x7 and 24x5 Support customers may log priority 1 cases; we will work
on these over the holiday.
* SupportPlus Standard, Desk Top, and Regular Support customers may
purchase Extended-hour Technical Support for coverage over the holiday.
Sybase Technical Support
limited-service holidays
 U.S. customers
Holiday Date
ThanksgivingNovember 28
Christmas December 25
Sybase Technical Support
limited-service holidays Â
Canadian customers
Holiday Date
Canadian ThanksgivingOctober 14
Christmas Day December 25
Boxing Day December 26
If you have questions, please contact Technical Support.
Masthead
Staff
Principal Editor: Leigh Ann HusseyContributing Writers: Sybase CS&S InfoComm
Team, Sybase Technical Support
Send comments and suggestions to Sybase Technical News,6475 Christie Avenue,
Emeryville, CA 94608, or email to tech...@sybase.com.
This issue of Sybase Technical News contains newinformation about your
Sybase software. This newsletter is intended forSybase customers with
support contracts. You may distribute it withina supported site; however, it
contains proprietary information and maynot be distributed publicly. All
issues of Sybase TechnicalNews and the troubleshooting guides are included
on theAnswerBase CD, SupportPlus Online Services Web pages, and theSybase
PrivateLine forum of CompuServe.
To receive this document by regular email, send name, full internetaddress
and customer ID to tech...@sybase.com.
Disclaimer
No express or implied warranty is made by Sybase or its subsidiarieswith
regard to any recommendations or information presented inSybase Technical
News. Sybase and its subsidiaries herebydisclaim any and all such
warranties, including without limitation anyimplied warranty of
merchantability of fitness for a particularpurpose. In no event will Sybase
or its subsidiaries be liable fordamages of any kind resulting from use of
any recommendations orinformation provided herein, including without
limitation loss ofprofits, loss or inaccuracy of data, or indirect special
incidental orconsequential damages. Each user assumes the entire risk of
acting onor utilizing any item herein including the entire cost of all
necessaryremedies.
Installing Sybase Products from a CD-ROM Attached to an IBM RS/6000 Running
AIX 3.2.5
------------------------------------------------------------------
Note
This technote is a correction of the earlier version, which
referred to the install program as "sybinstall", instead of
"sybsetup".
------------------------------------------------------------------
Summary
AIX 3.2.5 cannot correctly read a CD formatted using the Rockridge
Extensions standard common to many platforms. Due to this incompatibility,
the sybsetup program is not recognized. Consequently, you cannot run
sybsetup from a CD on an AIX 3.2.5 machine to install Sybase products.
Instead, use the non- GUI sybload utility.
AIX 4.x is capable of reading the Sybase CD correctly.
Attributes
OS: AIX 3.2.5 Version: 10.x, 11.0
Platform: IBM RS/6000 Last Revision: 29-Aug-96
Product: n/a ID: 2370
Contents
This section steps you through unloading Sybase products from a CD-ROM with
the sybload utility.
Before You Begin
Complete the following tasks before you begin:
Fill out the worksheet in the product installation guide. You will use some
of this information in certain steps below. Make sure the SYBASE environment
variable is set to the correct release directory.
Unloading with sybload -D
To unload Sybase software from the CD-ROM to your machine:
1. Place the CD-ROM in the drive.
2. Log in as the "root" superuser.
3. Mount the CD-ROM with a command like the following:
/etc/mount -v cdrfs -r /dev/device_entry /cdrom
Where device_entry names the CD-ROM drive, and cdrom names the
directory where the drive is mounted.
4. Log out and then log in as the System Administrator recorded on your
worksheet, usually "sybase".
5. Move to the SYBASE root directory:
cd $SYBASE
6. Start the sybload utility:
/cdrom/sybload -D
7. sybload prompts you for the following information:
Prompt Value
Confirm that the current directory is the
SYBASE directory SYBASE root directory, or specify the correct
directory path.
Local or remote Enter "L" for local. You cannot execute a
installation remote installation from CD-ROM using
sybload.
Name of disk file of Enter the CD_ROM disk name recorded on your
global archive worksheet, usually /cdrom/sybimage.
Customer Authorization Enter the string from the software packaging
String (CAS) that allows you to access your products.
Select the products you want to install from
the sybload menu:
* Enter the number of each product.
Sybase products * Press Return after each number.
* When done making selections, press
Return twice which creates a blank line.
sybload lists the products you chose. Enter:
* yŻto confirm that the list is correct
Product confirmation
* qŻto quit
* any other character to display the menu
and select more products
8. Do not interrupt the software unloading.
Depending on the size of each product and the number of products you
select, this process can take anywhere from a few minutes to half an
hour. During the process sybload lists the files it is unloading. On
completion, sybload displays a list of the unloaded products.
9. Log out, and then log in as the "root" superuser.
10. Unmount the CD-ROM:
/etc/umount /cdrom
11. Remove the CD from the drive.
What's Next
Install, configure, and upgrade each product according to the the
corresponding installation and configuration documentation.
Additional Space Needed When Creating Database Devices on AIX
----------------------------------------------------------------------------
Summary
Allow 1MB for the Logical Volume Control Block when creating SQL Server
11.0.x devices on IBM RISC System/6000 AIX. This TechNote describes why and
points out a common disk-space issue that occurs.
Attributes
OS: AIX Version: 11.0.x
Platform: RS6000 Last Revision: 10/11/96
Product: SQL Server ID: 1383
Contents
Allow Space for LVCB
When you create a database device with disk init, you must allow 1MB on the
device for the LVCB, because of the way that AIX and Sybase together manage
space.
Factors that Affect Disk Space Allocation
Several factors affect how disk space is allocated:
* SQL Server allocates space for databases in units of 256 pages, or
1/2MB.
* AIX creates logical volumes in physical partitions (PP), typically 4MB.
* The LVCB uses 512 bytes allocated to a logical volume.
* Sybase reserves the first 4K (2 pages) on a database device for the
LVCB by setting vstart to 2.
* Sybase's create and alter database commands use whole megabytes only.
When you try to create a database the same size as the logical volume, SQL
Server creates a smaller database than you requested because of the reserved
space. You must make the logical volume at least 1MB larger than the size of
the database you wish to put on it. The example in the next section
describes each step and its effect.
Example: Creating a Logical Volume
[Image]
The table below describes steps in creating a 20MB device.
Step Description Action
AIX requires that you create logical
Create a volumes, known as physical partitions Create a 20MB
logical (PP). Physical partitions must be at logical volume on
volume least 2MB, but typically are 4MB. For AIX.
example, you could create a logical
volume of 16MB, 20MB, 24MB, and so on.
Subtract 2 pages
from the page size
of the logical
volume.
disk init offsets the device by 2 pages
by automatically setting vstart (the 10,240 pages - 2
Run disk device's starting page number) to 2. SQL =10,238 pages.
init Server does this to avoid overwriting
AIX's Logical Volume Control Block disk init
(LVCB). name = "device1",
physname =
"physname1",
vdevno = 5,
size =10238
device1 is less than
20MB. Therefore,
Round down to the nearest 1MB to avoid create a 19MB
Create the fragmentation. The create and alter database:
database database commands allow you to specify
database size in whole megabytes only. create database
database1 on device1
= 19
The Mysterious 1/2MB
In our example, we created a 20MB logical volume, and had less than 20MB for
disk init because of the LVCB.
We created a 19MB database on the device, even though disk init will allow
more.
If you create a larger database:
create database database2 on device1 = 20
Sybase tries to give you all the space possible, so it allocates to the
nearest 1/2MB for the database, resulting in 19.5MB. This causes
fragmentation later if you have to re-load the database: You cannot alter or
re-create a 19.5MB database, because the create and alter database commands
only accept whole-megabyte sizes.
For details on avoiding database fragmentation, see TechNote 1324, Segment
Remapping with load database When Moving a Database.
How disk init and buildmaster Set Disk Space
On AIX, SQL Server release 11.0.x disk init and buildmaster set vstart to 2
if vstart is unspecified or if vstart is specified as 0. vstart is the
starting page for the device. Setting vstart to 2 allows Sybase to skip the
first 2 pages to avoid overwriting AIX's Logical Volume Control Block
(LVCB).
The following table shows the effect of SQL Server on the logical volume.
Command Behavior Required Action
Sets vstart to 2 if vstart is
Subtract the vstart setting
disk init either: from the disk init size
* Set to 0
* Unspecified parameter.
(Used during SQL Server Subtract the vstart setting
buildmaster installation) Offsets data in the from the buildmaster -s
master device by 2 pages. (size) parameter.
Your database device will be smaller than the size of your logical volume by
the number of pages set by vstart. The default setting is 2.
If you do not adjust the disk init size for vstart, error 5123 can occur:
disk init encountered an error while
attempting to open/create the physical file...
------------------------------------------------------------------
Note
See the Sybase SQL Server System Administration Guide for
information about disk init and vstart.
------------------------------------------------------------------
Dump Option "with retaindays" Explanation
----------------------------------------------------------------------------
Summary
This Tech Note explains the function and use of dump with retaindays.
Attributes
OS: All Version: 11.0.x
Platform: All Last Revision: 16-Sep-96
Product: Backup Server ID: 2600
Contents
Question
What is the dump option with retaindays? Can I use it on any platform?
Answer
The dump option retaindays is usable on all platforms, and works the same
way everywhere, but is really only meaningful in the case of dumps to disk
or to single-file tape (such as QIC).
If you dump to a disk or single-file tape device using the option with
retaindays and then try to overwrite it before its retention period has
expired without specifying with init on the subsequent command, Backup
Server will query whether to quit or continue.
If you dump to a multi-file tape device and do not specify with init, Backup
Server always appends, never overwrites, so the dump is not destroyed no
matter what. If you do specify with init, Backup Server always overwrites
without checking, regardless of whether the target has expired.
------------------------------------------------------------------
Note
There is a configurable "tape retention" parameter for
sp_configure; the with retaindays option overrides that retention
period. The default retention period is zero days - that is,
"already expired".
------------------------------------------------------------------
Char(N) Variables Appear Not to Concatenate
----------------------------------------------------------------------------
Summary
Given two fixed char(N) strings of different length, the shorter string will
be padded with blanks to equal the length of the longer string. The result
gets assigned to the variable.
Attributes
OS: All Version: All
Platform: All Last Revision: 16-Sep-96
Product: SQL Server ID: 2601
Contents
Question
Given the following declaration:
declare @var1 char(5)
If I perform the query select @var1 = @var1 + "A", the result has only one
"A" in @var1. It's not concatenating the char variable.
Is this a bug?
Answer
The result that you see is correct. Suppose, given @var1 char(5), you
execute a simple select:
select @var1 = "A"
The result of that select is "A " (an `A' with 4 blank spaces after it). If
you then execute select @var1 = @var1 + "A", this is what happens:
1. A temporary result is created, "A A", that is 6 characters long.
2. That temporary result is truncated on the right so that it is 5
characters long, yielding "A " - that is, no change from the original
value of @var.
This behavior for char(N) strings is consistent with ANSI: given two fixed
strings of different length, the shorter string will be padded with blanks
to equal the length of the longer string. The result gets assigned to the
variable.
If you want to have strings that don't get padded with blanks, you must use
varchar(N).
Using the BCP_IN Sample Script to Load bcp Files
----------------------------------------------------------------------------
Summary
This document details the BCP_IN sample script. You can use BCP_IN to
automate loading bcp files of user database tables. You edit the sample to
suit your environment.
For information on automated creation of table data in databases, see the
companion TechNote, "Using the BCP_OUT Sample Script to Create Tables".
Attributes
OS: UNIX Version: 4.9.2, 10.x, 11.x
Platform: All Last Revision: 6/26/96
Product: SQL Server ID: 993
Contents
The BCP_IN sample script's command lines and routines are intended for you
to use as a model for creating a script that is easy to maintain and
troubleshoot.
------------------------------------------------------------------
Note
You can copy the sample script, contained in the BCP_IN file on
Compuserve OpenLine. Search on the keyword "bcp".
------------------------------------------------------------------
Edit Considerations
In tailoring the sample script to your needs, consider these characteristics
of the script:
* Only user databases (type="U") qualify. System databases do not
qualify, including master, model, tempdb, and sybsystemprocs.
* The bcp batch size during data input is set to 100. To change it,
search on the string BATCHER.
* BCP_IN does not check whether the log/data space is full during the
bulk copy process.
* BCP_IN does not check whether the bcp option, select into/bulkcopy, is
being set in the target database.
You must review the output carefully for any errors. This script does not
detect all processing failures that may occur at runtime, such as privilege
errors or running out of space within the bcp target directory.
------------------------------------------------------------------
Note
Sybase Technical Support does not support this script.
------------------------------------------------------------------
Debugging Tip
Use the C-shell option "-xvf" instead of "-f" in the line at the top of bcp
files to aid in debugging. For example, "#!/bin/csh -xvf".
Editing Environment Variables
Once you have copied or created the script, edit the environment variables
to reflect your current operating configuration.
To find the section to edit, search on the string ENVIRONMENTAL VARIABLE
SECTION. Each variable is commented to aid you in editing. The following
topics provide additional edit information.
Usage Switches
A usage statement is returned if you invoke BCP_IN without any switches. The
usage switches are:
* [-a] to bcp all qualifying bcpfiles
* [-s] to bcp select databases from user input
* [-s <db1> <db2> ...] to bcp the listed databases To perform bcp..in for
one or more databases, invoke the script with the -s switch. Follow
this switch with a list of select databases for bcp..in. If you do not
provide a list of databases, the script prompts you for one.
By default, BCP_IN performs a bcp command for each qualifying file
(<database>.<tablename>.bcpfile) in the "holding" directory. You can
change the <database>.<tablename>.bcpfile syntax to match your file
naming conventions.
* [-t] to bcp a single file for a specific table
* [-d] to echo variables in use To check the current environment
settings, invoke the BCP_IN script with the -d switch. This switch
shows the active settings.
BCPFILEDIR Variable
Be sure to point the BCPFILEDIR environment variable to a directory that has
enough free space to store the bulk copy data.
Confirmation Options
Two confirmation options are available:
* CONF_SELECT, which allows you to confirm the database choices before
performing bcp commands
* BCP_OVERWRITE, which prompts you when there are previous bcp files in
the target directory
Enable these options by changing their default value to 1.
------------------------------------------------------------------
Note
Changing CONF_SELECT and BCP_OVERWRITE to 1 may cause unexpected
results in cron jobs.
------------------------------------------------------------------
bcp Command Settings
To change the column or row terminators or any other bcp command setting,
edit the bcp command line. Search for the string "$BCP $DBNAME.." .
cron Submission
BCP_IN allows for submission of bcp commands via the UNIX cron command.
For example, you could schedule bcp of the pubs2 database for every Sunday,
one minute after midnight, in cron as follows:
[Image]
The actual cron command file syntax depends on your UNIX environment.
Run a Test First!
Once you have edited the sample script to reflect your current environment,
we recommend that you test and fine-tune it before using it in a production
environment.
Example Scenario
For example, you could create a test server with two or three small
databases where each of the databases contains a few tables with minimal
data. Let us say that you have a 300 MB database called testdb where:
* 250 MB of data space is reserved
* 100 MB of data is actually used
* Log uses 50 MB
In this example, you need disk space for other applications, so you have
decided to recreate testdb to reflect 250 MB (200 MB data/50 MB log).
The normal dump/load database process does not allow you to load a larger
database into a smaller one. YUse your edited version of BCP_IN and BCP_OUT
to transfer the data as follows:
1. Change the file permissions mode to executable:
chmod +x bcp_in
chmod +x bcp_out
2. Bulk copy out the data using the single database switch:
bcp_out -s testdb
For details, see the companion TechNote, "Using the BCP_OUT Sample
Script to Create Tables."
3. Invoke isql and perform the following tasks:
>> isql -Usa -P
1> use master
2> go
1> sp_dboption "testdb","select into","true"
2> go
1> use testdb
2> go
1> checkpoint
2> go
1> quit
These tasks do as follows:
* Drop testdb and recreate it using the new sizes.
* Recreate all database tables and accompanying schema.
* Turn on the select into/bulkcopy option.
1. Bulk copy in the data, using the -s switch:
bcp_in -s testdb
2. Dump the database. You can optionally turn off the select into/bulkcopy
option.
After completing the steps in this example, you are ready to perform
subsequent backups/recovery.
BCP_IN Sample Script
# -----------------------------------------------------
# ENVIRONMENTAL VARIABLE SECTION
# -----------------------------------------------------
# Specify where to place the bcp files.
setenv BCPFILEDIR "/tmp"
# SYBASE and DSQUERY reflect the operating environment
# for your server.
setenv SYBASE "/sybase"
setenv DSQUERY "my_servername"
# PASSWD most likely needs to reflect the sa.
setenv PASSWD "-Usa -P "
# Set BCP to the path for the bcp executable, which
# inherits the $SYBASE variable.
setenv BCP "$SYBASE/bin/bcp"
# ISQL reflects a valid path for both the isql
# executable and a valid command string.
setenv ISQL "$SYBASE/bin/isql $PASSWD -S$DSQUERY"
# Set the batch size for bcp in.
set BATCHER=100
# If you want a prompt to confirm your database
# choices, set the CONF_SELECT flag to 1.
setenv CONF_SELECT "0"
# If you want a prompt when bcp outfiles already exist
# for the database/table qualifiers chosen, set the
# BCP_OVERWRITE flag to 1. If the flag is set to
# "0"(default), existing bcp files will be overwritten.
setenv BCP_OVERWRITE "0"
# Do not modify the umask setting.
umask 0
# -----------------------------------------------------
# SELECT DATABASE PROCESSING SECTION
# -------------------------------------------------
# Set SELECT_DB to "1" for automatic lookup of values
# in sel_dblist. Otherwise, use the default "0".
setenv SELECT_DB "0"
I recommend deleting this:
# You can type in the names of databases to bcp out by placing
# the names between the quotes of sel_dblist.
# Make sure there are spaces between databases. This is
# only activated if select_db = 1 (above), and may not work
# properly anyway. On second thought, don't fool with this.
setenv SEL_DBLIST ""
# Do not modify the counter variables NO_TABLES FOUND
# and NOARGS.
set NO_TABLES_FOUND = 0
set NOARGS=1
if (-e /tmp/db_list) rm /tmp/db_list
if (-e /tmp/db_list1) rm /tmp/db_list1
if (-e /tmp/table_list) rm /tmp/table_list
if (-e /tmp/table_list1) rm /tmp/table_list1
if (-e /tmp/tmp_bcpdbs) rm /tmp/tmp_bcpdbs
# -----------------------------------------------------
# STARTING MENU
# -------------------------------------------------
echo ""
echo " ________________________________________"
echo "| |"
echo "| >>> SYBASE BCPFILE INPUT AUTOMATOR <<< |"
echo "|________________________________________|"
echo ""
if ($#argv == 0) then
set SW = "0"
else
set SW = "\Qecho $argv[1] | cut -d"-" -f2\Q"
endif
if ($SW != "a" && $SW != "s" && $SW != "d" && $SW !=
"t") then
echo "Usage: "
echo "------"
echo " bcp_in [-a]"
echo " [-s]"
echo " [-s] <dbname1> <dbnameX> ... "
echo " [-t]"
echo " [-d]"
echo "where"
echo ""
echo " [a] bcp in all qualifying bcpfiles "
echo " [-s] bcp in select databases from user input"
echo " [-s <db1> <dbX> ...] bcp in listed databases"
echo " [-t] bcp in one file for a specific table"
echo " [-d] echos variables in use"
echo ""
exit
else if ($SW == "s" && "$#argv" >= "2") then
set RCT = "1"
while ($#argv > $RCT )
set SELECT_DB = 1
set VARCT=\Qexpr $RCT + 1\Q
set SEL_DBLIST=($SEL_DBLIST $argv[$VARCT])
set RCT = \Qexpr $RCT + 1\Q
end
else if ($SW == "s" || $SW == "t") then
set SELECT_DB = 1
else if ($SW == "d") then
set YCK = 1
if (! $?SYBASE) then
set SYBASE = "<Value not set - edit file>"
set YCK = 0
endif
if (! $?DSQUERY) then
set DSQUERY = "<Value not set - edit file>"
set YCK = 0
endif
if (! $?ISQL) then
set ISQL = "<Value not set - edit file>"
set YCK = 0
endif
if (! $?PASSWORD) then
set PASSWORD = "<Value not set - edit file>"
set YCK = 0
endif
if (! $?BCPFILEDIR) then
set BCP DIRECTORY = "<Value not set - edit
file>"
set YCK = 0
endif
echo " Variable List"
echo "------------------------------"
echo ""
echo "SYBASE = $SYBASE"
echo "DSQUERY = $DSQUERY"
echo "ISQL = $ISQL"
echo "PASSWORD = $PASSWD"
echo "BCP DIRECTORY = $BCPFILEDIR"
echo ""
exit
endif
# Confirm database choice.
if ($SELECT_DB == 1 && $SW != "t") then
echo ""
echo "Selective Database Option Enabled."
echo ""
if ($SW == "s" && $#argv < 2) then
echo "Enter Database Names (one at a time)"
echo "and terminate list with a <CR>."
echo ""
set ct=1
set CHKIT=1
set TWOSTRIKES = 1
if (-e /tmp/qualify) rm /tmp/qualify
while ($ct == 1)
echo -n "DBNAME >> "
set QUALIFY=($<)
ls ${BCPFILEDIR}/${QUALIFY}* 2>&1
if ($status != 0) then
echo ""
echo "*** Warning: No files found for"
echo "   that Database. Please try again."
echo ""
set CHKIT=0
set TWOSTRIKES = 0
else if ("$QUALIFY" == "" && $CHKIT == 1) then
echo ""
echo "*** Warning : please input a valid"
echo " Database name <or x to exit>."
echo ""
set CHKIT=0
set TWOSTRIKES = 0
else if ("$QUALIFY" == "x") then
echo ""
echo "... Program exiting ..."
echo ""
exit
else if ("$QUALIFY" == "") then
if ($CHKIT == 0 && $TWOSTRIKES == 0) then
echo ""
echo "... Program exiting ..."
echo ""
exit
endif
set ct=0
else
echo $QUALIFY >> /tmp/qualify
set CHKIT=0
endif
end
set SEL_DBLIST=\Qcat /tmp/qualify\Q
endif
echo ""
else if ($SW == "t") then
echo ""
echo "Single Table Option Enabled"
echo ""
set SELECT_DB=1
echo -n "ENTER DBNAME >>"
set QUALDB=($<)
set SEL_DBLIST="${QUALDB}"
echo -n "ENTER TABLENAME >>"
set QUALTBL=($<)
echo ""
if (! -e ${BCPFILEDIR}/${QUALDB}.${QUALTBL}.bcpfile)
then
echo ""
echo "*** Warning: No bcp files found for"
echo " that table. Please try again."
echo ""
ls ${BCPFILEDIR}
echo ""
echo "... program exiting ..."
echo ""
exit
endif
echo ${QUALDB} > /tmp/db_list
else if ($SELECT_DB != 1 ) then
echo ""
echo "All User Databases Option Enabled."
echo ""
ls ${BCPFILEDIR}/*.bcpfile 2>&1
if ($status != 0) then
echo ""
echo "*** Warning: No qualifying files found for"
echo "  any Database. Please confirm choices
echo "  and invoke script again."
echo ""
echo "... program exiting ..."
echo ""
exit
endif
if (-e /tmp/bcpdbs) rm /tmp/bcpdbs
touch /tmp/tmp_bcpdbs
foreach file (\Qls ${BCPFILEDIR}/*bcpfile\Q)
echo $file:t | cut -d. -f1 >> /tmp/bcpdbs
end
uniq /tmp/bcpdbs > /tmp/db_list
endif
# Obtain select database list, if enabled.
if ($SELECT_DB == "1") then
foreach MANUAL_DB (\Qecho $SEL_DBLIST\Q)
if (-e /tmp/sdb_list) rm /tmp/sdb_list
$ISQL $PASSWD << ENDCMDS > /tmp/sdb_list
if not exists(select name from master..sysdatabases
where name = "$MANUAL_DB") print "DBNOTFOUND"
go
ENDCMDS
grep "DBNOTFOUND" /tmp/sdb_list > /dev/null
if ($status == "0") then
echo ""
echo "*** Warning.. Incorrect Database Name. ***"
echo ""
echo "DATABASE : $MANUAL_DB"
echo ""
echo "Processing of BCP files terminated. Please"
echo "confirm proper spelling and invoke script"
echo "again."
echo ""
echo "... Program Exiting ..."
echo ""
exit
endif
# Close out database selection list verification.
end
# Restore the selective database list.
if (-e /tmp/db_list1) rm /tmp/db_list1
touch /tmp/db_list1
foreach SELDBNAME (\Qecho $SEL_DBLIST\Q)
echo $SELDBNAME >> /tmp/db_list1
end
# Otherwise, validate the entire database list.
else
set TMPCHK=0
foreach DB_FILE_NAMED (\Qcat /tmp/db_list\Q)
$ISQL $PASSWD << ENDCMDS >/tmp/db_list1
if not exists (select name from master..sysdatabases
where name= "${DB_FILE_NAMED}") print "DBDOESNOTEXIST"
go
ENDCMDS
grep "DBDOESNOTEXIST" /tmp/db_list1 > /dev/null
if ($status == 0) then
echo ""
echo "*** Warning.. Database Does Not Exist. ***"
echo ""
echo "DATABASE : $DB_FILE_NAMED"
echo ""
echo "... continuing with next database ..."
echo ""
set TMPCHK=1
else
set TMPCHK=0
endif
end
if (${TMPCHK} == 1) then
echo "*** Warning.. No Databases Qualify ***"
echo ""
echo "Processing of BCP files terminated. Please"
echo "confirm proper spelling and invoke script"
echo "again."
echo ""
echo "... Program Exiting ..."
echo ""
exit
endif
cp /tmp/db_list /tmp/db_list1
# Complete the database selection processing.
endif
echo "-----------------------------------------"
echo "The following Database list qualifies for"
echo "bcp operations:"
echo "-----------------------------------------"
cat /tmp/db_list1
echo ""
if ($CONF_SELECT == 1) then
echo -n "*** Press "y" to continue >>>"
set p_cont=($<)
if ($p_cont != "y" && $p_cont != "Y") then
echo ""
echo "... Program exiting ..."
echo ""
exit
endif
endif
set TMPCHK=0
foreach DBNAME (\Qcat /tmp/db_list1\Q)
echo ""
echo "================================="
echo ">>>>> DATABASE: $DBNAME "
echo "================================="
echo ""
echo "... confirming bcp table files for $DBNAME..."
# Get bcp files and confirm tables in each database.
# First, obtain bcp files.
if (-e /tmp/bcptbl1) rm /tmp/bcptbl1
if (-e /tmp/tbl_list2) rm /tmp/tbl_list2
if ($SW != "t") then
foreach BCPFQUAL
(\Qls ${BCPFILEDIR}/${DBNAME}*bcpfile\Q)
else
foreach BCPFQUAL
(\Qls ${BCPFILEDIR}/${DBNAME}.${QUALTBL}.bcpfile\Q)
endif
set BT=\Qecho ${BCPFQUAL}:t | cut -d. -f2
| cut -d. -f1\Q
echo ""
echo "---------------------------------"
echo " * BCP file input for : $BCPFQUAL"
echo "-------------------------------"
$ISQL $PASSWD << ENDCMDS >/tmp/tbl_list2
if not exists (select name from ${DBNAME}..sysobjects
where name="${BT}") print "TABLEDOESNOTEXIST"
go
ENDCMDS
grep "TABLEDOESNOTEXIST" /tmp/tbl_list2 > /dev/null
if ($status == 0) then
echo ""
echo "*** Warning.. Table Does Not Exist. ***"
echo ""
echo "DATABASE : $DBNAME"
echo "TABLE : $BT"
echo ""
echo "... continuing with next table ... "
echo ""
set TMPCHK=1
else
set TMPCHK=0
endif
$BCP $DBNAME..$BT in $BCPFQUAL $PASSWD -b $BATCHER -c
# Go to the next table.
end
echo ""
echo "==================================="
echo ">>>>> BCP file input processing for"
echo ">>>>> $DBNAME completed."
echo "==================================="
echo ""
# Continue processing if no tables were found.
endif
# Go to the next database.
end
# Clean up.
#if (-e /tmp/db_list) rm /tmp/db_list
#if (-e /tmp/db_list1) rm /tmp/db_list1
#if (-e /tmp/table_list) rm /tmp/table_list
#if (-e /tmp/table_list1) rm /tmp/table_list1
Should "#" precede the above "if" statements?
echo ""
echo "... Program Exiting ..."
echo ""
Using BCP_OUT Sample Script to Archive Table Data
----------------------------------------------------------------------------
Summary
This document details the BCP_OUT sample script. You can use BCP_OUT to
automate creating bcp files of table data in all user databases.
For information on automated creation of table data in databases, see the
companion TechNote, "Using the BCP_IN Sample Script to Load bcp Files".
Attributes
OS: UNIX Version: 4.9.x, 10.x, 11.x
Platform: All Last Revision: 7/22/96
Product: SQL Server ID: 994
Contents
The BCP_OUT sample script's command lines and routines are intended for you
to use as a model for creating a script that is easy to maintain and
troubleshoot.
------------------------------------------------------------------
Note
You can copy the sample script, contained in the BCP_OUT file on
Compuserve Openline. Search on the keyword "bcp".
------------------------------------------------------------------
Edit Considerations
In tailoring the sample script to your needs, consider these characteristics
of the script:
* Only user databases (type="U") qualify. System databases do not
qualify, including master, model, tempdb, and sybsystemprocs.
* The bcp batch size during data input is set to 100. To change it,
search on the string BATCHER.
* BCP_OUT does not monitor operating system space during the bulk copy
process. OS commands, such as df, enable you to monitor disk space.
You must review the output carefully for any errors. This script does not
detect all processing failures that may occur at runtime, such as privilege
errors or running out of space within the bcp target directory.
------------------------------------------------------------------
Note
Sybase Technical Support does not support this script.
------------------------------------------------------------------
Debugging Tip
Use the C-shell option "-xvf" instead of "-f" in the line at the top of bcp
files to aid in debugging. For example, "#!/bin/csh -xvf".
Editing Environment Variables
Once you have copied or created the script, edit the environment variables
to reflect your current operating configuration.
To find the section to edit, search on the string ENVIRONMENTAL VARIABLE
SECTION. Each variable is commented to aid you in editing. The following
topics provide additional edit information.
Usage Switches
A usage statement is returned if you invoke BCP_OUT without any switches.
The usage switches are:
* [-a] to bcp all nonsystem required databases
* [-s] to bcp select databases from user input
* [-s <db1> <db2> ...] to bcp the listed databases To perform bcp..out
for one or more databases, invoke the script with the -s switch. Follow
this switch with a list of select databases for bcp..out. If you do not
provide a list of databases, the script prompts you for one.
* [-t] to bcp a single table
* [-d] to echo variables in use To check the current environment
settings, invoke the BCP_OUT script with the -d switch. This switch
shows the active settings.
BCPFILEDIR Variable
Be sure to point the BCPFILEDIR environment variable to a directory that has
enough free space to store the bulk copy data.
Confirmation Options
Two confirmation options are available:
* CONF_SELECT, which allows you to confirm the database choices before
performing bcp commands
* BCP_OVERWRITE, which prompts you when there are previous bcp files in
the target directory
Enable these options by changing their default value to 1.
------------------------------------------------------------------
Note
Changing CONF_SELECT and BCP_OVERWRITE to 1 may cause unexpected
results in cron jobs.
------------------------------------------------------------------
bcp Command Settings
To change the column or row terminators or any other bcp command setting,
edit the bcp command line. Search for the string "$BCP $DBNAME..".
cron Submission
BCP_OUT allows for submission of bcp commands via the UNIX cron command.
For example, you could schedule bcp of the pubs2 database for every Sunday,
one minute after midnight, in cron as follows:
[Image]
Replace bcp_in with bcp_out
The actual cron command file syntax depends on your UNIX environment.
Run a Test First!
Once you have edited the sample script to reflect your current environment,
we recommend that you test and fine-tune it before using it in a production
environment.
Example Scenario
For example, you could create a test server with two or three small
databases where each of the databases contains a few tables with minimal
data. Let us say that you have a 300 MB database called testdb where:
* 250 MB of data space is reserved
* 100 MB of data is actually used
* Log uses 50 MB
In this example, you need disk space for other applications, so you have
decided to recreate testdb to reflect 250 MB (200 MB data/50 MB log).
The normal dump/load database process does not allow you to load a larger
database into a smaller one. Use your edited version of BCP_IN and BCP_OUT
to transfer the data as follows:
1. Change the file permissions mode to executable:
chmod +x bcp_in
chmod +x bcp_out
2. Bulk copy out the data using the single database switch:
bcp_out -s testdb
For details, see the companion TechNote, "Using the BCP_IN Sample
Script to Load bcp Files."
3. Invoke isql and perform the following tasks:
>> isql -Usa -P
1> use master
2> go
1> sp_dboption "testdb","select into","true"
2> go
1> use testdb
2> go
1> checkpoint
2> go
1> quit
These tasks do as follows:
* Drop testdb and recreate it using the new sizes.
* Recreate all database tables and accompanying schema.
* Turn on the select into/bulkcopy option.
1. Bulk copy in the data, using the -s switch:
bcp_in -s testdb
2. Dump the database. You can optionally turn off the select into/bulkcopy
option.
After completing the steps in this example, you are ready to perform
subsequent backups/recovery.
BCP_OUT Sample Script
# -----------------------------------------------------
# ENVIRONMENTAL VARIABLE SECTION
# -------------------------------------------------
# Specify where to place the bcp files.
setenv BCPFILEDIR "/tmp"
# SYBASE and DSQUERY reflect the operating environment
# for your server.
setenv SYBASE "/sybase" setenv DSQUERY "my_servername"
# PASSWD most likely needs to reflect the sa.
setenv PASSWD "-Usa -P "
# Set BCP to the path for the bcp executable, which
# inherits the $SYBASE variable.
setenv BCP "$SYBASE/bin/bcp"
# ISQL reflects a valid path for the isql executable
# and valid command string.
setenv ISQL "$SYBASE/bin/isql $PASSWD -S$DSQUERY"
# If you want a prompt to confirm your database
# choices, set the CONF_SELECT flag to 1.
setenv CONF_SELECT "0"
# If you want a prompt when bcp outfiles already exist
# for the database/table qualifiers chosen, set the
# BCP_OVERWRITE flag to 1. If set to "0" (default),
# existing bcp files will be overwritten.
setenv BCP_OVERWRITE "0"
# Do not modify the umask setting.
umask 0
# -----------------------------------------------------
# SELECT DATABASE PROCESSING SECTION
# -------------------------------------------------
# Set SELECT_DB to "1" for automatic lookup of values
# in sel_dblist. Otherwise, use the default "0".
setenv SELECT_DB "0"
# Do not modify the counter variables NO_TABLES FOUND
# and NOARGS.
set NO_TABLES_FOUND = 0
set NOARGS=1
# -----------------------------------------------------
# STARTING MENU
# -------------------------------------------------
echo ""
echo " ________________________________________"
echo "|                        |"
echo "| >> SYBASE BCPFILE OUTPUT AUTOMATOR << |"
echo "|________________________________________|"
echo ""
if ($#argv == 0) then
set SW = "0"
else
set SW = "\Qecho $argv[1] | cut -d"-" -f2\Q"
endif
if ($SW != "a" && $SW != "s" && $SW != "d" &&
$SW != "t") then
echo "Usage: "
echo "------"
echo "   bcp_out [-a]"
echo "        [-s]"
echo "        [-s] <dbname1> <dbnameX> ... "
echo "        [-t]"
echo "        [-d]"
echo "where"
echo ""
echo " [a] bcp all nonsystem required databases"
echo " [-s] bcp select databases from user input"
echo " [-s <db1> <dbX> ...] bcp listed databases"
echo " [-t] bcp out a single table"
echo " [-d] echos variables in use"
echo ""
exit
else if ($SW == "s" && "$#argv" >= "2") then
set RCT = "1"
while ($#argv > $RCT )
set SELECT_DB = 1
set VARCT=\Qexpr $RCT + 1\Q
set SEL_DBLIST=($SEL_DBLIST $argv[$VARCT])
set RCT = \Qexpr $RCT + 1\Q
end
else if ($SW == "s" || $SW == "t") then
set SELECT_DB = 1
else if ($SW == "d") then
set YCK = 1
if (! $?SYBASE) then
set SYBASE = "<Value not set - edit file>"
set YCK = 0
endif
if (! $?DSQUERY) then
set DSQUERY = "<Value not set - edit file>"
set YCK = 0
endif
if (! $?ISQL) then
set ISQL = "<Value not set - edit file>"
set YCK = 0
endif
if (! $?PASSWORD) then
set PASSWORD = "<Value not set - edit file>"
set YCK = 0
endif
if (! $?BCPFILEDIR) then
set BCP DIRECTORY = "<Value not set - edit
file>"
set YCK = 0
endif
echo " Variable List"
echo "------------------------------"
echo ""
echo "SYBASE = $SYBASE"
echo "DSQUERY = $DSQUERY"
echo "ISQL = $ISQL"
echo "PASSWORD = $PASSWD"
echo "BCP DIRECTORY = $BCPFILEDIR"
echo ""
exit
endif
# Confirm database choice.
if ($SELECT_DB == 1 && $SW != "t") then
echo ""
echo "Selective Database Option Enabled."
echo ""
if ($SW == "s" && $#argv < 2) then
echo "Enter Database Names (one at a time)"
echo "and terminate list with a <CR>."
echo ""
set ct=1
set CHKIT=1
set TWOSTRIKES = 1
if (-e /tmp/qualify) rm /tmp/qualify
while ($ct == 1)
echo -n "DBNAME >> "
set QUALIFY=($<)
if ("$QUALIFY" == "" && $CHKIT == 1) then
echo ""
echo "*** Warning : please input a valid"
echo " Database name <or x to exit>."
echo ""
set CHKIT=0
set TWOSTRIKES = 0
else if ("$QUALIFY" == "x") then
echo ""
echo "... Program exiting ..."
echo ""
exit
else if ("$QUALIFY" == "") then
if ($CHKIT == 0 && $TWOSTRIKES == 0) then
echo ""
echo "... Program exiting ..."
echo ""
exit
endif
set ct=0
else
echo $QUALIFY >> /tmp/qualify
set CHKIT=0
endif
end
set SEL_DBLIST=\Qcat /tmp/qualify\Q
endif
else if ($SW == "t") then
echo ""
echo "Single Table Option Enabled"
echo ""
set SELECT_DB=1
echo -n "ENTER DBNAME >> "
set SEL_DBLIST=($<)
echo -n "ENTER TABLENAME >> "
set QUALTBL=($<)
echo ""
else if ($SELECT_DB != 1) then
echo ""
echo "All User Databases Option Enabled."
echo ""
endif
if (-e /tmp/db_list) rm /tmp/db_list
if (-e /tmp/db_list1) rm /tmp/db_list1
if (-e /tmp/table_list) rm /tmp/table_list
if (-e /tmp/table_list1) rm /tmp/table_list1
# Obtain select database list, if enabled.
if ($SELECT_DB == "1") then
foreach MANUAL_DB (\Qecho $SEL_DBLIST\Q)
$ISQL $PASSWD << ENDCMDS > /tmp/db_list
use master
go
select ""=name from sysdatabases where name =
"$MANUAL_DB"
go
ENDCMDS
set CHK_OF_DBS = \Qtail -l /tmp/db_list | cut -d"
" -f1 | cut -d"(" -f2\Q
if ($CHK_OF_DBS == "0") then
echo ""
echo "*** Warning.. Incorrect Database Name. ***"
echo ""
echo "DATABASE : $MANUAL_DB"
echo ""
echo "Processing of BCP files terminated. Please"
echo "confirm proper spelling and invoke script"
echo "again. "
echo ""
echo "... Program Exiting ..."
echo ""
exit
endif
# Close out the database selection list verification.
end
# Restore the selective database list.
foreach SELDBNAME (\Qecho $SEL_DBLIST\Q)
echo $SELDBNAME >> /tmp/db_list1
end
# Otherwise, obtain the entire database list.
else
$ISQL $PASSWD << ENDCMDS > /tmp/db_list
use master
go
select ""=name from sysdatabases where name !=
"master" and name != "model" and name != "tempdb" and
name != "sybsystemprocs"
go
ENDCMDS
# Strip out the header, leading spaces, and blank
# lines from the result set.
sed s/---//g /tmp/db_list | sed s/" "//gp | grep -v
"affected" | grep -v ^$ > /tmp/db_list1
# Complete the database selection processing.
endif
echo "------------------------------------------"
echo "The following Databases will be candidates"
echo "for bcp operations:"
echo "------------------------------------------"
cat /tmp/db_list1
echo ""
if ($CONF_SELECT == 1) then
echo -n "*** Press "y" to continue >>> "
set p_cont=($<)
if ($p_cont != "y" && $p_cont != "Y") then
echo ""
echo "... Program exiting ..."
echo ""
exit
endif
endif
foreach DBNAME (\Qcat /tmp/db_list1\Q)
echo ""
echo "================================="
echo ">>>>> DATABASE: $DBNAME"
echo "==============================="
echo ""
echo "... starting table collection for $DBNAME..."
if ($SW != "t") then
# Get the tables in each database.
set NO_TABLES_FOUND = 0
$ISQL $PASSWD << ENDCMDS > /tmp/table_list
use $DBNAME
go
set nocount on
go
select ""=name from sysobjects where type="U"
ENDCMDS
sed s/---//g /tmp/table_list | sed s/" "//gp >
/tmp/table_list1
else
set NO_TABLES_FOUND = 0
$ISQL $PASSWD << ENDCMDS > /tmp/table_list
if not exists (select name from ${DBNAME}..sysobjects
where type="U" and name="${QUALTBL}") print
"NOTABLEFOUND"
go
ENDCMDS
grep "NOTABLEFOUND" /tmp/table_list > /dev/null
if ($status == 0) then
echo ""
echo "*** Warning : No Such Table Found. "
echo " Please try again. "
echo ""
echo "... program exiting ..."
exit
endif
echo ${QUALTBL} > /tmp/table_list1
endif
echo "... table collection for $DBNAME completed..."
echo ""
echo "---------------------------------"
echo ""
grep "Msg" /tmp/table_list > /dev/null
if ($status == "0") then
echo "*** Warning.. Error encountered ***"
echo ""
grep -n "Msg" /tmp/table_list > /tmp/table_err
foreach ERRMSG (\Qcat /tmp/table_err |
sed s/" "//gp\Q)
set ERRLN=\Qecho $ERRMSG | cut -d":" -f1\Q
sed -n $ERRLN,\Qexpr $ERRLN + 2\Qp /tmp/table_list
end
echo ""
echo " Continuing to process on next database."
echo ""
set NO_TABLES_FOUND = 1
endif
if ($SW != "t") then
set NUMBER_OF_TABLES = \Qtail -l /tmp/table_list
| cut -d" " -f1 | cut -d"(" -f2\Q
if ($NUMBER_OF_TABLES == "0") then
echo ""
echo "*** Warning.. no qualifying tables found ***"
echo " Continuing to process on next database."
echo ""
set NO_TABLES_FOUND = 1
endif
endif
if ($NO_TABLES_FOUND != 1) then
foreach TABLEZ ("\Qcat /tmp/table_list1\Q")
if ($TABLEZ == "") end
if ($BCP_OVERWRITE != 1) then
if (-e $BCPFILEDIR/$DBNAME.$TABLEZ.bcpfile) then
echo ""
echo "--------------"
echo "*** WARNING...
$BCPFILEDIR/$DBNAME.$TABLEZ.bcpfile EXISTS ***"
echo "--------------"
echo -n "Do you wish to overwrite file [y/n]? >>"
set ans=($<)
if ($ans != "y" && $ans != "Y") then
echo ""
echo "... Skipping $TABLEZ..."
echo ""
end
endif
endif
endif
# bcp command
echo ""
echo "----------------------------------"
echo " * BCP file creation for : $TABLEZ"
echo "-------------------------------"
$BCP $DBNAME..$TABLEZ out
$BCPFILEDIR/$DBNAME.$TABLEZ.bcpfile $PASSWD -c
# Go to the next table.
end
echo ""
echo "================================="
echo ">>>>> BCP file creation for"
echo ">>>>> $DBNAME completed. "
echo "================================="
echo ""
# Continue processing if no tables were found.
endif
# Go to the next database.
end
# Clean up.
#if (-e /tmp/db_list) rm /tmp/db_list
#if (-e /tmp/db_list1) rm /tmp/db_list1
#if (-e /tmp/table_list) rm /tmp/table_list
#if (-e /tmp/table_list1) rm /tmp/table_list1
echo ""
echo "... Program Exiting ..."
echo ""
----------------------------------------------------------------------------