
背景
公司某内部系统属于商业产品,数据库性能已出现明显问题,服务经常卡死,员工经常反馈数据无法查询或不能及时查询,该系统所使用的数据库为SqlServer,SqlServer数据库属于商业数据库,依赖厂商的维护,且维护成本高,效率低,且存在版权等问题,考虑将该系统的数据库,迁移至PostGresql数据库,属于BSD的开源数据库,不存在版本问题,公司也有部分系统采用pg,维护成本也将大大减低。
迁移原理
SqlServer属于商业数据库,不可能像Mysql等数据库一样,去解析相关的数据库binlog,从而实现增量数据的回放,结合应用属性,最后确定采用离线迁移方式,从SqlServer中将表数据全部读出,然后将数据写入到pg中,采用此种方案的弊病就是程序端需停止写入(应用可将部分数据缓存到本地),等待数据库迁移完成后,程序端再迁移至PostGresql,迁移方法如下:

表结构迁移原理
表结构主要包含字段,索引,主键,外键等信息组成,主要采用开源工具sqlserver2pg进行表结构的转换
表结构转换
从SqlServer中读写表结构的字段信息,并对字段类型进行转换,转换核心代码如下
[code]sub convert_type{ my ($sqlstype, $sqlqual, $colname, $tablename, $typname, $schemaname) = @_; my $rettype; if (defined $types{$sqlstype}) { if ((defined $sqlqual and defined($unqual{$types{$sqlstype}})) or not defined $sqlqual) { # This is one of the few types that have to be unqualified (binary type) $rettype = $types{$sqlstype}; # but we might add a check constraint for binary data if ($sqlstype =~ 'binary' and defined $sqlqual) { print STDERR "convert_type: $sqlstype, $sqlqual, $colname\n"; my $constraint; $constraint->{TYPE} = 'CHECK_BINARY_LENGTH'; $constraint->{TABLE} = $tablename; $constraint->{TEXT} = "octet_length(" . format_identifier($colname) . ") |