<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Prune&#039;s Blog &#187; Sybase</title>
	<atom:link href="http://www.lecentre.net/blog/archives/category/database/sybase/feed" rel="self" type="application/rss+xml" />
	<link>http://www.lecentre.net/blog</link>
	<description>Internet, UNIX, Video, Leisure...</description>
	<lastBuildDate>Thu, 19 Jan 2012 20:38:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Sybase database migration / reduction</title>
		<link>http://www.lecentre.net/blog/archives/276</link>
		<comments>http://www.lecentre.net/blog/archives/276#comments</comments>
		<pubDate>Thu, 10 Apr 2008 15:27:42 +0000</pubDate>
		<dc:creator>Prune</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Sybase]]></category>

		<guid isPermaLink="false">http://www.lecentre.net/blog/?p=276</guid>
		<description><![CDATA[One of the main problem of sybase (and other database) is the way it handle disk space. You must create &#171;&#160;disk devices&#160;&#187;, which can be RAW or file on a filesystem. Then give some space of it to a database, and perhaps create or extend segments. Of course, this may sound a good way to [...]]]></description>
			<content:encoded><![CDATA[<p>One of the main problem of sybase (and other database) is the way it handle disk space. You must create &laquo;&nbsp;disk devices&nbsp;&raquo;, which can be RAW or file on a filesystem. Then give some space of it to a database, and perhaps create or extend segments.</p>
<p>Of course, this may sound a good way to deal with it. Then comes the time when you need some storage for something else, or another database.</p>
<p>You start realizing that the 15 Gb you added to your database, thinking your data will grow as you reach your 1.000.000.000 subscriber&#8230; but your stalled at 150 <img src='http://www.lecentre.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><span id="more-276"></span></p>
<p>So, using some sybase tools, you realize only 5% of the space is used. Then you wonder &laquo;&nbsp;how will I get the free space for something else ?&nbsp;&raquo;</p>
<p>The Sybase and Sybase support is simple : you can&#8217;t. But&#8230;</p>
<p>Of course you can. It&#8217;s only data after all. Your data.<br />
The solution is simpler to say than to do : backup data and schema, drop the database, drop the devices, re-create the devices, the database then import.</p>
<p>One would say : eaaassssyyyyyy.<br />
Then try to do it without using dump/load.</p>
<p>The fact is the dump/load Sybase command uses internal Sybase page structures. If you have a 15Gb database, even 5% filled, your dump will have a 15Gb size, minus the compression you set for the dump.<br />
When loading, each page will be put in a page of the new database device. Meaning, you need to have a new database the same size as the old one. The load tool will tell you that if you are wrong.<br />
And this is even worse than you may think : you need to have the same amount of data and log space (or more) !!</p>
<p>So&#8230; bcp out, then bcp in.</p>
<p>BCP is a command line tool provided by sybase. It load/unload data from/to a flat file.</p>
<p>First, get the schema out of the database.<br />
For this I use the dbschema perl tool. Get it at <a title="http://www.midsomer.org" href="http://www.midsomer.org" target="_blank">http://www.midsomer.org</a><br />
This is what I do :</p>
<pre lang="shell">
mkdir DB1_schema
cd DB1_schema
/opt/monitor/perl/bin/perl   /home/prune/dbschema/dbschema.pl -SDB1 -Usa -Ppassword -O1 -m -A -V -b --target-db my_new_db
</pre>
<p>You will get a directory per database inside DB1. In each directory you will have a file per type of object : table, stored procs, key, foreign key, view&#8230;</p>
<p>The use of &laquo;&nbsp;&#8211;target-db my_new_db&nbsp;&raquo; will create DBP in/out scripts with the right name to import data to a different database (my_new_db instead of my_old_db). See under for the BCP stuffs anyway.</p>
<p>Then, get the data out using <strong>bcp</strong>.<br />
You need to <strong>bcp out</strong> the data each table at a time.<br />
The database I&#8217;m using have almost a hundred tables. One solution is to use an option of the dbschema to create a bcp shell script. Or you can use the <strong>sp__bcp</strong> stored procedure from the awesom package you can find at <a title="http://www.edbarlow.com" href="http://www.edbarlow.com" target="_blank">http://www.edbarlow.com<br />
</a>sp__bcp need options so it can create the bcp command line :</p>
<ul>
<li>DSQUERY : the dataserver name</li>
</ul>
<ul>
<li>database_name : the database to dump from</li>
</ul>
<ul>
<li>sa : the login of the admin user or a user who can select every tables</li>
</ul>
<ul>
<li>password : &#8230;</li>
</ul>
<ul>
<li>out : in or out, depending of the script you want to create<a title="http://www.edbarlow.com" href="http://www.edbarlow.com" target="_blank"></a></li>
</ul>
<p>When creating the bcp in script, be sure to be in the right database you just have bcp out BUT put the database name where you will load the data, if different.</p>
<pre lang="SQL">
use my_old_db
go
sp__bcp "DB1", "my_old_db", "sa", "password", "out"
go
</pre>
<p>Also get the in script :</p>
<pre lang="SQL">
use my_old_db
go
sp__bcp "DB1", "my_new_db", "sa", "password", "in", "dat", "-b 10000"
go
</pre>
<p>This proc will not create any script. You need to copy the output to a file, make it executable.<br />
The last parameter will split the load in chuck of 10000 lines, which will help to not fill the logs. Maybe 50000 or 100000 would be better. please comment.<br />
Then you can create back your database on the right devices, with the right size, etc.</p>
<pre lang="SQL">
disk init
name      = 'NewdbData',
physname  = '/opt/db/dbdata/DB1_NewdbData',
vdevno    = 7,
size      = 2560000,
cntrltype = 0,
dsync = 'false'
go

disk init
name      = 'NewdbLog',
physname  = '/opt/db/dbdata/DB1_NewdbLog',
vdevno    = 8,
size      = 153600,
cntrltype = 0,
dsync = 'false'
go

CREATE DATABASE my_new_db ON NewdbData = 5000 LOG ON PhileasLog = 300
use master
go
sp_dboption phileas, 'single user', true
go
exec sp_logdevice phileas, PhileasLog
go
sp_dboption phileas, 'single user', false
go
</pre>
<p>You are ready to re-create the structure of the database. The &laquo;&nbsp;table structure&nbsp;&raquo; as Sybase support call it.</p>
<p>Go to the dbschema directory, in the db you want to create, and load the scripts one at a time, in the right order. Note that, if your developpers do fancy things in theire stored procs, the schema export from dbschema may not work. I had to use an extract from &laquo;&nbsp;CAST&nbsp;&raquo;, then use dos2unix to translate some french accents to unix code.<br />
Here is how I do it then :</p>
<pre lang="shell">
dos2unix procs-cast.sql procs.sql

isql -Usa -w512 -SDB1 -Ppassword &lt; defaults.sql &gt; defaults.sql.err
isql -Usa -w512 -SDB1 -Ppassword &lt; groups.sql &gt; groups.sql.err
isql -Usa -w512 -SDB1 -Ppassword &lt; types.sql &gt; types.sql.err
isql -Usa -w512 -SDB1 -Ppassword &lt; rules.sql   &gt; rules.sql.err
isql -Usa -w512 -SDB1 -Ppassword &lt; tables.sql &gt; tables.sql.err
isql -Usa -w512 -SDB1 -Ppassword &lt; keys.sql &gt; keys.sql.err
isql -Usa -w512 -SDB1 -Ppassword &lt; views.sql &gt; views.sql.err
isql -Usa -w512 -SDB1 -Ppassword &lt; indexes.sql &gt; indexes.sql.err
isql -Usa -w512 -SDB1 -Ppassword &lt; fkeys.sql &gt; fkeys.sql.err
isql -Usa -w512 -SDB1 -Ppassword &lt; trigs.sql &gt; trigs.sql.err
isql -Usa -w512 -SDB1 -Ppassword &lt; procs.sql &gt; procs.sql.err
</pre>
<p>Once this is done, just check you have all your stuffs :</p>
<pre lang="SQL">
select type, count(*) from sysobjects  group by type
go
 type
 ---- -----------
 D             16 types
 P           1072 procs
 R             15 rule
 RI           357 index
 S             26 system tables
 TR           538 trigger
 U            555 table
 V             94 view
</pre>
<p>You should have the same result as on your old database. In fact, I don&#8217;t <img src='http://www.lecentre.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
But the dev told me that it was normal. Some procs are &laquo;&nbsp;wrong&nbsp;&raquo; but they are never used on a history database, which is what I&#8217;m working on right now.</p>
<p>You can then load the data, using the bcp script.<br />
If your files are big, you may fill the logs. You need to set a procedure to dump them. This proc will automaticaly be run by a trigger. You can add it in your database, or in <strong>sybsystemprocs</strong>. This proc is made for logging the dump, and dumping to a file. I just changed it to dump with &laquo;&nbsp;no_log&nbsp;&raquo;, as we don&#8217;t care of the log during import.</p>
<p>Here is the proc :</p>
<pre lang="SQL">
CREATE PROC sp_thresholdaction   (
  @dbname varchar(30),
  @segmentname varchar(30),
  @space_left int,
  @status int )
AS
BEGIN
declare @msg  varchar(256),
        @date_actuelle  datetime,
        @nom_fichier  varchar(256),
        @date_fichier  varchar(20),
        @rep_sauve_log  varchar(40)

select @rep_sauve_log = 'compress::6::/DUMP_SYBASE/DB1/DumpDATA/'

select @date_actuelle = getdate()

select @date_fichier =
	convert (char(8), @date_actuelle, 112) +'-'+
	convert(varchar(2),datepart(hh,@date_actuelle)) +
	convert(varchar(2),datepart(mi,@date_actuelle)) +
	convert(varchar(2),datepart(ss,@date_actuelle))

select @nom_fichier = @rep_sauve_log + @dbname + @date_fichier + '.trn',
       @msg = @date_fichier + ' Warning: dump transaction for ' + @dbname + ':' + @segmentname  + ' (' + convert(varchar(12),@space_left) + ' free) on ' + @nom_fichier

print @msg

if @segmentname = 'logsegment'
     dump tran @dbname with no_log
return
END

go
</pre>
<p>Finaly, run you bcp in script, and you are all set. I hope&#8230; <img src='http://www.lecentre.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
Don&#8217;t forget to change the DB owner and options, but if you are that far I&#8217;m sure you can do it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lecentre.net/blog/archives/276/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Get the Page size in Sybase</title>
		<link>http://www.lecentre.net/blog/archives/117</link>
		<comments>http://www.lecentre.net/blog/archives/117#comments</comments>
		<pubDate>Wed, 26 Sep 2007 15:43:46 +0000</pubDate>
		<dc:creator>Prune</dc:creator>
				<category><![CDATA[Sybase]]></category>
		<category><![CDATA[UNIX]]></category>

		<guid isPermaLink="false">http://www.lecentre.net/blog/archives/117</guid>
		<description><![CDATA[Strange, I wasn&#8217;t able to find a way to get the database page size in a Sybase (12.x) server. Digging in sp_helpdb stored procedure gave me some more informations. To do this, or any stored proc, use this SQL command : use sybsystemprocs go sp_helptext sp_space_segment go You will get the stored proc as text. [...]]]></description>
			<content:encoded><![CDATA[<p>Strange, I wasn&#8217;t able to find a way to get the database page size in a Sybase (12.x) server.</p>
<p>Digging in sp_helpdb stored procedure gave me some more informations. To do this, or any stored proc, use this SQL command :</p>
<pre lang="sql">
use sybsystemprocs
go
sp_helptext  sp_space_segment
go
</pre>
<p>You will get the  stored proc as text.</p>
<p>Finaly, the solution to get the page size is :</p>
<pre lang="sql">
select v.low/1024  from master.dbo.spt_values v  where v.number = 1 and v.type = "E"
</pre>
<p>or the page size in octets:</p>
<pre lang="sql">
select v.low/1024  from master.dbo.spt_values v  where v.number = 1 and v.type = "E"
</pre>
<p>or how many pages there are in a mega-octet (Mo) :</p>
<pre lang="sql">
select (1048576 / v.low)
from master.dbo.spt_values v
where v.number = 1
and v.type = "E"
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.lecentre.net/blog/archives/117/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

