Skip to content

Commit ba4dff6

Browse files
author
Marc Cousin
committed
Add support for incremental migration
1 parent 4b103fc commit ba4dff6

3 files changed

Lines changed: 1122 additions & 48 deletions

File tree

README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ It does two things:
1111
* convert a SQL Server schema to a PostgreSQL schema
1212
* produce a Pentaho Data Integrator (Kettle) job to migrate
1313
all the data from SQL Server to PostgreSQL. This second part is optionnal
14+
* produce an incremental version of this job to migrate what has changed in the database from the previous run. This is created
15+
when the migration job is also created.
1416

1517

1618
Notes, warnings:
@@ -90,6 +92,34 @@ the size of the scale of the numeric
9092
if no: they are created as not valid (enforced only for new rows)
9193
if after: they are created as not valid, but the statements to validate them are put in the unsure file
9294

95+
-sort_size=100000: sort size to use for incremental jobs. Default is 10000, to try to be on the safe side (see below).
96+
97+
We don't sort in databases for two reasons: the sort order can be different between SQL Server
98+
and PostgreSQL, and we don't want to stress the servers. But sorting a lot of data in Java can generate a Java Out of Heap Memory error.
99+
If you get Out of Memory errors, raise the Java Heap memory (in the kitchen script) as much as you can. If you still have the problem, reduce
100+
this sort size. You can also try reducing parallelism, having one on two sorts instead of 8 will of course consume less memory. The last problem is that
101+
if the sort_size is small, kettle is going to generate a very large amount of temporary files, and then read them back sorted. So you may hit the
102+
"too many open files" limit of your system (default 1024 on linux for instance). So you'll have to do some tuning here:
103+
- First, use as much Java memory as you can: set the JAVAXMEM environment variable to 4096 (megabytes) or more if you can afford it. The more the better.
104+
- If you still get Out Of Memory errors, put a smaller sort size, until you can do the sorts (decrease it tenfold each time for example). You'll obviously lose some performance
105+
- If then you get the too many open files error, raise the maximum number of open files. In most Linux distributions, this is editing /etc/security/limits.conf and putting
106+
@userName soft nofile 65535
107+
@userName hard nofile 65535
108+
(replace userName with your user name). Log in again, and verify with "ulimit -n" that you are now allowed to open 65535 files.
109+
You may also have to raise the maximum number of open files on the system: echo the new value to /proc/sys/fs/file-max.
110+
111+
You'll need a lot of temporary space on disk to do these sorts...
112+
113+
You can also edit only the offending transformation with Spoon (Kettle's GUI), so that only this one is slowed down.
114+
115+
When Kettle crashed on one of these problems, the temporary files aren't removed. They are usually in /tmp (or in your temp directory in Windows), and start with out_. Don't forget to remove them.
116+
117+
-use_pk_if_possible=0/1/public.table1,myschema.table2: enable the generation of jobs doing sorts in the databases (order by in the select part of Kettle's table inputs).
118+
119+
1 will ask to try for all tables, or you can give a list of tables (if for example, you cannot make these tables work with a reasonable sort size). Anyway, sqlserver2sql will only accept
120+
to do sorts in the database if the primary key can be guaranteed to be sorted the same way in PostgreSQL and SQL Server. That means that it only accepts if the key is made only of numeric
121+
and date/timestamp types. If not, the standard incremental job will be generated.
122+
93123
If you want to also import data:
94124

95125
> ./sqlserver2pgsql.pl -b before.sql -a after.sql -u unsure.sql -k kettledir \
@@ -127,6 +157,17 @@ You've generated everything. Let's do the import:
127157

128158
If you want to dig deeper into the kettle job, you can use kettle_report.pl to display the individual table's transfer performance. Then, if needed, you'll be able to modify the Kettle job to optimize it, using Spoon, Kettle's GUI
129159

160+
```
161+
You can also give a try to the incremental job:
162+
> ./kitchen.sh -file=full_path_to_kettle_job_dir/incremental.kjb -level=detailed
163+
164+
This one is highly experimental. I need your feedback ! :). You should only run an incremental job on an already loaded database.
165+
166+
It may fail for a variety of reasons, mainly out of memory errors. If you have other unique constraints beyond the primary key, the series of queries generated by sqlserver2pgsql may generate conflicting updates. So test it several times before the migration day, if you really want to try this method. The "normal" method is safer, but of course, you'll start from scratch, and have those long indexes builds at the end.
167+
168+
By the way, to be able to insert data into all tables, it deactivates triggers at the beginning and activates them back at the end of the job. So, if the job fails, those triggers won't be reactivated.
169+
170+
```
130171
You can also use a configuration file if you like:
131172

132173
> ./sqlserver2pgsql.pl -conf example_conf_file -f mydatabase_dump.sql

example_conf_file

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,6 @@ no relabel dbo=1 # set it to 0 to convert the dbo schema to public
2525
convert numeric to int=1 # set it to 0 to keep numeric(xx,0) as numeric(xx,0). Will be converted to smallint, int or bigint by default
2626
relabel schemas=dbo=>foo;schema1=>bar
2727
keep identifier case=1 # keep case of database objects
28+
# Incremental job
29+
sort size=10000 # drives the amount of memory and temporary files that will be created by an incremental job
30+
use pk if possible=0 # 1/list of tables, for tables where you want to try getting already sorted records

0 commit comments

Comments
 (0)