破局与落地:一次大型Oracle系统向KingbaseES的无感迁移实战录!

104 阅读12分钟

正文开始——

在当今数字化转型的浪潮中,数据库国产化替代已成为国家信息安全战略的重要组成部分。随着Oracle数据库在国内市场的份额逐渐被国产数据库取代,越来越多的企业面临着将现有Oracle系统迁移至国产数据库的挑战。电科金仓推出的KingbaseES(Oracle兼容版)凭借其高度的Oracle兼容性和成熟的迁移工具链,成为许多企业的首选替代方案。

金仓数据库官网

由于 KingbaseES 内部提供了大量的 Oracle 兼容特性,因此,在实际应用中,一般只需很少甚至不做任何修改, 用户便可把 Oracle 数据库移植到 KingbaseES 环境中运行。不仅如此,用户还可利用 KDTS 等多种工具简化移植过 程。 本节重点描述了在实际应用中移植一个 Oracle 数据库系统的完整过程,以及其中的主要移植内容和关键移植步骤。

一、主要移植内容

数据库迁移是一个系统工程,需要全面考虑数据库对象、数据内容以及应用程序的适配性。成功的迁移项目必须遵循合理的迁移顺序,确保各环节之间的协调与衔接。

1.1 数据库、用户移植

数据库和用户是数据库系统的基础架构,在迁移过程中需要优先处理。正确的数据库和用户迁移策略能够为后续的对象迁移奠定坚实基础。

数据库创建与配置
在目标KingbaseES环境中创建与源Oracle数据库同名的数据库实例时,需要特别注意字符集的一致性。字符集不一致可能导致数据乱码或迁移失败。

用户与权限管理
用户迁移不仅包括创建同名用户,还需要确保权限的正确分配。KingbaseES与Oracle在权限体系上存在差异,需要进行适当的映射和调整。

-- 创建用户并授权
CREATE USER scott WITH PASSWORD 'scott123' 
VALID UNTIL '2025-12-31';

-- 授予基本权限
GRANT CONNECT, RESOURCE TO scott;

-- 授予特定模式权限
GRANT USAGE ON SCHEMA scott TO scott;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA scott TO scott;

-- 设置默认模式
ALTER USER scott SET search_path TO scott, public;

兼容性参数配置
KingbaseES提供了丰富的Oracle兼容性参数,正确配置这些参数可以显著减少应用程序的修改量。关键参数包括:

-- 设置Oracle兼容模式
ALTER DATABASE orcl SET compatible_mode TO oracle;

-- 配置长度语义(与Oracle保持一致)
ALTER SYSTEM SET nls_length_semantics TO 'BYTE';

-- 设置日期格式
ALTER SYSTEM SET datestyle TO 'ISO,YMD';

-- 启用OID伪列(兼容ROWID)
ALTER SYSTEM SET default_with_oids TO on;

1.2 Oracle数据迁移

数据迁移是整个迁移过程的核心环节,根据业务需求可以选择离线迁移或在线迁移方案。KingbaseES提供了KDTS(数据迁移工具)和KFS(数据同步工具)来满足不同场景的需求。

迁移方案选择标准

  • 离线迁移:适用于业务停机窗口充足、数据量适中(通常小于1TB)的场景
  • 在线迁移:适用于业务要求24×7连续运行、数据量巨大的场景
  • 混合迁移:结合离线迁移和在线迁移的优势,分阶段完成迁移

数据迁移前的准备工作
充分的前期准备是迁移成功的关键,包括数据量评估、对象分析、环境准备等。

-- 评估Oracle数据库数据量
SELECT 
    tablespace_name,
    SUM(bytes)/1024/1024/1024 AS size_gb,
    COUNT(*) AS segment_count
FROM dba_segments 
GROUP BY tablespace_name 
ORDER BY size_gb DESC;

-- 分析表数据分布
SELECT 
    owner,
    table_name,
    num_rows,
    avg_row_len,
    blocks,
    empty_blocks
FROM dba_tables 
WHERE owner = 'SCOTT'
ORDER BY num_rows DESC;

1.3 应用程序移植

应用程序移植是迁移项目的最后阶段,但需要在前期就进行充分评估和规划。KingbaseES在SQL语法、PL/SQL功能和编程接口等方面提供了高度的Oracle兼容性,大大降低了应用程序的修改工作量。

应用程序兼容性评估
在开始移植前,需要对现有应用程序进行全面的兼容性评估,识别需要修改的代码部分。

修改策略

  • 直接兼容:对于KingbaseES原生支持的Oracle特性,无需修改或仅需少量调整
  • 适配修改:对于部分兼容的特性,需要进行适当的语法或接口调整
  • 重构实现:对于不兼容的特性,需要重新设计实现方案

二、关键移植步骤

作为一个典型的项目过程,Oracle 数据库移植应具有健全的项目团队和全面细致的的项目执行过程。通常,移植 一个 Oracle 数据库主要包括以下步骤: 

  • 确定移植目标
  • 评估移植任务
  • 准备迁移环境
  • 数据库用户迁移
  • 数据迁移 
  • 应用代码迁移
  •  测试与调试移植系统

这些准备工作是确保后续 Oracle 移植顺利进行的前提条件,而最后一步是保证最终移植系统正确性和可用性的关键步骤。 下面,分别对上述各个步骤进行详细说明。

2.1 确定移植目标

开始迁移前,应根据用户的实际需求,确定移植目标。这些目标诸如:

  • 迁移 Oracle 数据库的规模。
  • 迁移 Oracle 数据库对象的种类和特征,如简单和复杂迁移对象所占比例等。
  • 迁移的难易程度,如是否迁移大对象,是否迁移大量约束等。
  • 迁移的工期要求。
  • 迁移中业务系统是否可以处于停止服务状态。
  •  对目标系统的技术指标要求,诸如平台、版本、应用编程接口、工具、可用性、安全性和性能指标要求等。

明确移植目标以后,则可开始移植任务评估。

2.2 评估移植任务

当计划把一个 Oracle 数据库系统移植到 KingbaseES 环境时,如果不做评估或评估不充分的话,那么整个移植 工作会存在很多的潜在风险,额外增加移植工程师的工作量并且无法确认移植完成时间。因此,移植前对移植的可行 性、工作量、难易程度和工作进度等进行充分评估是非常必要的。 通常,移植评估主要包括以下内容:

  • 移植技术指标,如移植业务压力和性能指标等。
  • 移植数据规模,如移植各类数据库对象的数量,PL/SQL 程序的规模等。
  • 移植中 KingbaseES 不支持功能的种类和数量。
  • 移植的约束种类和数量。
  • 移植过程中可能遇到的其他问题。

2.3 组建移植团队

数据库迁移项目需要多学科团队的协作。合理的团队结构和明确的职责分工是项目成功的组织保障。

团队能力要求
迁移团队成员应当具备以下知识和技能:

  • 精通Oracle和KingbaseES数据库管理系统
  • 熟悉SQL和PL/SQL编程
  • 掌握数据库性能调优技术
  • 具备脚本编程和自动化工具使用能力
  • 拥有良好的沟通和团队协作能力

2.4 准备迁移环境

迁移环境的准备包括硬件资源配置、软件安装配置、网络环境优化等多个方面。良好的环境准备是高效迁移的基础。

硬件资源配置原则

  • 计算资源:KingbaseES服务器的CPU和内存配置应不低于原Oracle服务器
  • 存储资源:根据数据量和性能要求配置适当的存储系统
  • 网络资源:确保Oracle和KingbaseES服务器之间的网络带宽和稳定性

软件环境准备

# KingbaseES数据库安装示例
# 下载安装包
wget http://download.kingbase.com.cn/kingbasees/V9/KingbaseES_V9.0_Linux_x86_64.tar.gz

# 解压安装包
tar -xzf KingbaseES_V9.0_Linux_x86_64.tar.gz
cd KingbaseES_V9.0_Linux_x86_64

# 运行安装程序
./setup.sh -i console

# 初始化数据库实例
./bin/initdb -D /home/kingbase/data -U system -W --encoding=GBK

性能优化预配置
在迁移开始前,根据预估的数据量和性能要求对KingbaseES进行初步优化。

-- 调整共享缓冲区大小(建议为内存的1/4)
ALTER SYSTEM SET shared_buffers = '8GB';

-- 设置工作内存
ALTER SYSTEM SET work_mem = '256MB';

-- 配置预写日志
ALTER SYSTEM SET wal_buffers = '16MB';
ALTER SYSTEM SET checkpoint_completion_target = 0.9;

-- 设置最大连接数
ALTER SYSTEM SET max_connections = 500;

2.5 数据库、用户迁移

数据库和用户迁移需要严格按照既定的顺序和规范进行操作,确保基础环境的正确性。

迁移流程

  1. 环境检查:验证源Oracle环境和目标KingbaseES环境的一致性
  2. 用户创建:在KingbaseES中创建对应的用户账号
  3. 权限分配:按照最小权限原则分配数据库权限
  4. 数据库创建:创建业务数据库并设置相关参数
  5. 模式对象准备:创建必要的模式对象和空间分配

自动化迁移脚本示例

-- 用户迁移脚本
BEGIN
    -- 创建用户
    EXECUTE IMMEDIATE 'CREATE USER ' || oracle_username || 
                     ' WITH PASSWORD ''' || oracle_password || '''';
    
    -- 授予基本权限
    EXECUTE IMMEDIATE 'GRANT CONNECT TO ' || oracle_username;
    EXECUTE IMMEDIATE 'GRANT RESOURCE TO ' || oracle_username;
    
    -- 设置默认表空间
    EXECUTE IMMEDIATE 'ALTER USER ' || oracle_username || 
                     ' SET default_tablespace = users';
    
    DBMS_OUTPUT.PUT_LINE('用户 ' || oracle_username || ' 迁移完成');
END;
/

-- 数据库创建脚本
CREATE DATABASE business_db
    OWNER business_user
    TEMPLATE template0
    ENCODING 'UTF8'
    LC_COLLATE 'zh_CN.UTF8'
    LC_CTYPE 'zh_CN.UTF8'
    TABLESPACE business_ts;

2.6 数据迁移

数据迁移是整个项目的核心环节,需要根据数据特点选择合适的迁移策略和工具。

KDTS迁移工具配置
KDTS(KingbaseES Data Transfer Service)是KingbaseES提供的高效数据迁移工具,支持全量和增量数据迁移。

BS版本配置示例

# 数据源配置
dataSource:
  source:
    type: oracle
    url: jdbc:oracle:thin:@//192.168.1.100:1521/ORCL
    username: scott
    password: tiger
    driverClassName: oracle.jdbc.OracleDriver
    
  target:
    type: kingbase
    url: jdbc:kingbase8://192.168.1.101:54321/business_db
    username: business_user
    password: business_pass
    driverClassName: com.kingbase8.Driver

# 迁移任务配置
migration:
  taskName: "oracle_to_kingbase_migration"
  includeSchemas: ["SCOTT", "HR"]
  excludeTables: ["AUDIT_%", "TEMP_%"]
  batchSize: 1000
  parallelThreads: 8
  lobBufferSize: 4194304

SHELL版本高级配置

# 启动KDTS迁移任务
#!/bin/bash

# 设置环境变量
export JAVA_HOME=/opt/kdts/jdk
export PATH=$JAVA_HOME/bin:$PATH

# 设置JVM参数
JAVA_OPTS="-Xms16g -Xmx16g -XX:MaxMetaspaceSize=1g"

# 启动迁移任务
java $JAVA_OPTS -jar kdts-cli.jar \
    --config=conf/migration-config.yaml \
    --source=oracle \
    --target=kingbase \
    --task=full_migration \
    --log-level=INFO

在线迁移实战
对于要求业务连续性的系统,需要采用在线迁移方案,确保数据实时同步。

-- 步骤1:启用Oracle归档日志
ALTER DATABASE ARCHIVELOG;
ALTER SYSTEM SET LOG_ARCHIVE_DEST_1='LOCATION=/u01/archivelog' SCOPE=SPFILE;

-- 步骤2:创建KFS同步用户
CREATE USER kfs_user IDENTIFIED BY kfs_password;
GRANT CONNECT, RESOURCE TO kfs_user;
GRANT SELECT ANY TABLE TO kfs_user;
GRANT EXECUTE ON DBMS_LOGMNR TO kfs_user;

-- 步骤3:配置KFS同步任务
BEGIN
    kfs_pkg.configure_service(
        service_name => 'oracle_to_kingbase',
        source_type => 'oracle',
        target_type => 'kingbase',
        parallel_degree => 8,
        batch_size => 5000
    );
END;
/

数据一致性验证
迁移完成后,必须进行严格的数据一致性验证,确保数据的完整性和准确性。

-- 数据量对比验证
SELECT 
    '源库' as db_type,
    table_name,
    count(*) as record_count
FROM oracle_table_stats
WHERE owner = 'SCOTT'
GROUP BY table_name

UNION ALL

SELECT 
    '目标库' as db_type,
    table_name,
    count(*) as record_count
FROM kingbase_table_stats
WHERE schema_name = 'scott'
GROUP BY table_name;

-- 数据内容抽样验证
SELECT 
    '数据一致性检查' as check_type,
    sum(case when ora_col = kb_col then 1 else 0 end) as match_count,
    count(*) as total_count,
    round(sum(case when ora_col = kb_col then 1 else 0 end) * 100.0 / count(*), 2) as match_rate
FROM (
    SELECT 
        t1.primary_key,
        t1.sample_column as ora_col,
        t2.sample_column as kb_col
    FROM oracle_sample_data t1
    FULL OUTER JOIN kingbase_sample_data t2 ON t1.primary_key = t2.primary_key
) data_comparison;

2.7 应用代码迁移

应用程序迁移需要系统化的方法和严格的测试验证,确保业务功能的完整性和性能要求。

PL/SQL代码迁移
KingbaseES对Oracle PL/SQL具有高度兼容性,但仍需注意一些差异点。

-- Oracle原生语法(大多数情况下可直接运行)
CREATE OR REPLACE PROCEDURE calculate_bonus(
    p_emp_id IN NUMBER,
    p_bonus OUT NUMBER
) AS
    v_salary NUMBER;
    v_rating NUMBER;
BEGIN
    SELECT salary, performance_rating 
    INTO v_salary, v_rating
    FROM employees 
    WHERE employee_id = p_emp_id;
    
    -- 计算逻辑
    p_bonus := v_salary * v_rating * 0.1;
    
EXCEPTION
    WHEN NO_DATA_FOUND THEN
        p_bonus := 0;
    WHEN OTHERS THEN
        RAISE;
END calculate_bonus;
/

-- 需要适配的语法(包中同名过程/函数)
-- Oracle允许,KingbaseES不支持
CREATE OR REPLACE PACKAGE employee_mgmt AS
    PROCEDURE process_employee(p_id NUMBER);
    -- FUNCTION process_employee(p_id NUMBER) RETURN VARCHAR2; -- 需要重命名
END employee_mgmt;
/

-- 修改为KingbaseES兼容版本
CREATE OR REPLACE PACKAGE employee_mgmt AS
    PROCEDURE process_employee(p_id NUMBER);
    FUNCTION process_employee_func(p_id NUMBER) RETURN VARCHAR2;
END employee_mgmt;
/

连接配置迁移
应用程序连接数据库的方式需要相应调整,确保连接字符串和驱动程序的正确性。

Java应用程序示例

// Oracle连接配置
// String url = "jdbc:oracle:thin:@//localhost:1521/ORCL";
// String driver = "oracle.jdbc.OracleDriver";

// KingbaseES连接配置
public class KingbaseConnection {
    private static final String URL = "jdbc:kingbase8://localhost:54321/business_db";
    private static final String DRIVER = "com.kingbase8.Driver";
    private static final String USERNAME = "business_user";
    private static final String PASSWORD = "business_pass";
    
    public Connection getConnection() throws SQLException {
        try {
            Class.forName(DRIVER);
        } catch (ClassNotFoundException e) {
            throw new SQLException("KingbaseES JDBC驱动未找到", e);
        }
        
        Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
        // 设置连接属性以增强兼容性
        conn.setClientInfo("ApplicationName", "Business System");
        return conn;
    }
}

ODBC配置详解
在不同操作系统环境下配置ODBC数据源,确保应用程序的正常连接。

Windows ODBC配置

ini

; odbc.ini 配置文件 [KingbaseBusiness] 
Description=KingbaseES Business Database 
Driver=KingbaseES 9 ODBC Driver 
Servername=192.168.1.101 
Port=54321 
Username=business_user 
Password=business_pass 
Database=business_db 
SSLmode=disable 
FetchBufferSize=100 
UseServerSidePrepare=1 
ByteaAsLongVarBinary=1

Linux ODBC配置

# 检查ODBC驱动配置
odbcinst -q -d

# 配置数据源
cat > /etc/odbc.ini << EOF
[KingbaseBusiness]
Description=KingbaseES Business Database
Driver=KingbaseES9
Servername=192.168.1.101
Port=54321
Username=business_user
Password=business_pass
Database=business_db
EOF

2.8 测试与调试移植系统

全面的测试是确保迁移成功的最后一道关卡,需要从功能、性能、安全等多个维度进行验证。

功能测试策略
建立完整的测试用例库,覆盖所有业务场景和边界条件。

-- 单元测试表示例
CREATE TABLE migration_test_cases (
    test_id NUMBER PRIMARY KEY,
    test_name VARCHAR2(100) NOT NULL,
    test_description VARCHAR2(500),
    source_sql CLOB,
    expected_result CLOB,
    actual_result CLOB,
    test_status VARCHAR2(20) DEFAULT 'PENDING',
    executed_at TIMESTAMP,
    comments VARCHAR2(1000)
);

-- 测试用例执行脚本
BEGIN
    FOR test_rec IN (
        SELECT test_id, test_name, source_sql, expected_result
        FROM migration_test_cases
        WHERE test_status = 'PENDING'
    ) LOOP
        BEGIN
            EXECUTE IMMEDIATE test_rec.source_sql;
            
            UPDATE migration_test_cases 
            SET test_status = 'PASSED',
                executed_at = CURRENT_TIMESTAMP
            WHERE test_id = test_rec.test_id;
            
        EXCEPTION
            WHEN OTHERS THEN
                UPDATE migration_test_cases 
                SET test_status = 'FAILED',
                    actual_result = SQLERRM,
                    executed_at = CURRENT_TIMESTAMP
                WHERE test_id = test_rec.test_id;
        END;
    END LOOP;
    COMMIT;
END;
/

性能测试方法
使用专业的性能测试工具模拟真实业务负载,验证系统性能指标。

-- 性能测试基线数据收集
-- Oracle性能基线
SELECT 
    sql_id,
    executions,
    elapsed_time,
    cpu_time,
    buffer_gets,
    disk_reads
FROM v$sqlstats 
WHERE parsing_schema_name = 'SCOTT'
ORDER BY elapsed_time DESC;

-- KingbaseES性能对比
SELECT 
    queryid,
    calls,
    total_time,
    mean_time,
    rows,
    shared_blks_hit
FROM pg_stat_statements 
WHERE dbid = (SELECT oid FROM pg_database WHERE datname = 'business_db')
ORDER BY total_time DESC;

性能优化技巧
针对测试中发现性能瓶颈,实施相应的优化措施。

-- 索引优化
-- 分析缺失索引
SELECT 
    table_name,
    column_name,
    usage_count
FROM (
    SELECT 
        table_name,
        column_name,
        COUNT(*) as usage_count
    FROM dba_ind_columns
    WHERE table_owner = 'SCOTT'
    GROUP BY table_name, column_name
) ORDER BY usage_count DESC;

-- 创建优化索引
CREATE INDEX idx_employee_dept_date 
ON employees(department_id, hire_date) 
TABLESPACE users_ts;

-- 查询优化
-- 使用KingbaseES特有的性能提示
EXPLAIN (ANALYZE, BUFFERS) 
SELECT /*+ leading(e d) use_nl(d) */
    e.employee_id,
    e.first_name,
    e.last_name,
    d.department_name
FROM employees e
JOIN departments d ON e.department_id = d.department_id
WHERE e.hire_date >= '2020-01-01';

系统调优参数
根据测试结果调整数据库参数,优化系统性能。

-- KingbaseES性能参数调整
-- 内存相关参数
ALTER SYSTEM SET shared_buffers = '16GB';
ALTER SYSTEM SET work_mem = '512MB';
ALTER SYSTEM SET maintenance_work_mem = '2GB';

-- 查询优化参数
ALTER SYSTEM SET random_page_cost = 1.1;
ALTER SYSTEM SET effective_cache_size = '48GB';
ALTER SYSTEM SET default_statistics_target = 500;

-- 并行处理参数
ALTER SYSTEM SET max_parallel_workers_per_gather = 8;
ALTER SYSTEM SET max_parallel_workers = 32;
ALTER SYSTEM SET parallel_setup_cost = 1000;
ALTER SYSTEM SET parallel_tuple_cost = 0.1;

三、迁移后维护与监控

迁移完成后的系统维护和监控同样重要,需要建立完善的运维体系。

3.1 监控指标体系
建立全面的监控指标体系,实时掌握系统运行状态。

-- 关键性能指标监控
CREATE VIEW system_monitoring_view AS
SELECT 
    '连接数' as metric_name,
    COUNT(*) as current_value,
    (SELECT setting FROM pg_settings WHERE name = 'max_connections') as max_value
FROM pg_stat_activity
WHERE datname = 'business_db'

UNION ALL

SELECT 
    '缓存命中率',
    ROUND(SUM(heap_blks_hit) * 100.0 / NULLIF(SUM(heap_blks_hit + heap_blks_read), 0), 2),
    95 as max_value
FROM pg_statio_user_tables

UNION ALL

SELECT 
    '事务提交率',
    ROUND(xact_commit * 100.0 / NULLIF(xact_commit + xact_rollback, 0), 2),
    99.9 as max_value
FROM pg_stat_database 
WHERE datname = 'business_db';

3.2 自动化运维脚本
开发自动化运维脚本,提高系统维护效率。

#!/bin/bash
# 数据库健康检查脚本

#!/bin/bash
# 数据库健康检查脚本

# 配置参数
DB_NAME="business_db"
DB_USER="monitor_user"
LOG_FILE="/var/log/kingbase_health_check.log"

# 健康检查函数
check_database_health() {
    echo "$(date): 开始数据库健康检查" >> $LOG_FILE
    
    # 检查数据库连接
    psql -d $DB_NAME -U $DB_USER -c "SELECT 1;" > /dev/null 2>&1
    if [ $? -ne 0 ]; then
        echo "$(date): 错误:数据库连接失败" >> $LOG_FILE
        return 1
    fi
    
    # 检查关键指标
    psql -d $DB_NAME -U $DB_USER -t -c "
    SELECT 
        '连接数: ' || COUNT(*) || '/' || setting,
        '缓存命中率: ' || ROUND(SUM(heap_blks_hit) * 100.0 / NULLIF(SUM(heap_blks_hit + heap_blks_read), 0), 2) || '%',
        '事务提交率: ' || ROUND(xact_commit * 100.0 / NULLIF(xact_commit + xact_rollback, 0), 2) || '%'
    FROM pg_stat_activity, pg_statio_user_tables, pg_stat_database, pg_settings
    WHERE datname = '$DB_NAME' AND name = 'max_connections'
    GROUP BY setting;
    " >> $LOG_FILE
    
    echo "$(date): 健康检查完成" >> $LOG_FILE
}

# 执行健康检查
check_database_health

四、总结

Oracle数据库迁移至KingbaseES是一个复杂的系统工程,需要周密的计划、严格的执行和全面的测试。本文基于官方迁移实践指南,详细阐述了从项目规划到系统上线的完整流程,提供了实用的技术方案和代码示例。

成功的数据库迁移不仅需要技术能力,还需要项目管理和风险控制的综合能力。建议在实际迁移项目中遵循以下原则:

  1. 充分准备:迁移前进行全面的评估和准备,识别潜在风险和挑战
  2. 分步实施:采用分阶段、迭代式的迁移策略,降低项目风险
  3. 全面测试:建立完整的测试体系,确保迁移质量和系统稳定性
  4. 持续优化:迁移完成后持续监控和优化系统性能
  5. 知识传承:建立完善的知识管理体系,积累迁移经验

通过系统化的方法和严谨的态度,企业可以顺利完成Oracle到KingbaseES的数据库迁移,实现数据库国产化的战略目标,同时确保业务系统的平稳运行和持续发展。