diff --git a/product/en/docs-mtk/v2.0/faq/mtk-mssql-to-mogdb.md b/product/en/docs-mtk/v2.0/faq/mtk-mssql-to-mogdb.md new file mode 100644 index 0000000000000000000000000000000000000000..3948de48888bae1381eb28bf911d1c6b6e8dde94 --- /dev/null +++ b/product/en/docs-mtk/v2.0/faq/mtk-mssql-to-mogdb.md @@ -0,0 +1,638 @@ +--- +title: Migrating MSSQL to MogDB/openGauss +summary: Migrating MSSQL to MogDB/openGauss +author: Liu Xu +date: 2021-03-04 +--- + +# Migrating MSSQL to MogDB/openGauss + +## Supported Versions + +- 2017+ +- 2016 +- 2012 + +## How to + +1. Download And Install + + ```shell + tar -zxvf mtk__linux_.tar.gz + ``` + +2. Apply the license + + ```shell + cd mtk__linux_ + ./mtk license gen + License File Not Found (default license.json) + The License code is invalid, start applying + ? Email: xxxx@xxxx.com + >> please enter a valid email address + # copy mail file `license.json` to current dir + ``` + +3. MSSQL Create User + +4. MogDB Create Database And User + + ```shell + gsql + create database db DBCOMPATIBILITY='A' ENCODING='UTF8' LC_COLLATE='C' LC_CTYPE='C'; + \c db + create user mtk_mig with password "mtkMigAbc123" sysadmin; + ``` + + > Pay attention to DBCOMPATIBILITY + > Pay attention to the character set collation. Create a database syntax reference[create database](https://docs.mogdb.io/zh/mogdb/latest/CREATE-DATABASE) + +5. Init project + + ```bash + ./mtk init-project -s sqlserver -t mogdb -n sqlserver2mg + # will build a migration directory + sqlserver2mg + ├── config + │   └── mtk.json + ├── data + ├── report + └── schema + ``` + + Edit the configuration file in advance. For details, see [Configuration File](./../config/mtk-config.md) + + ```bash + vi sqlserver2mg/config/mtk.json + ``` + + 1. Edit `source` node to define the source database connection information. Configuration reference [source](./../config/mtk-config.md#source) + 2. Edit `target` node to define the target database connection information. Configuration reference [target](./../config/mtk-config.md#target) + + > Modify the connect and type information, and the parameter is adjusted according to the operation + + 3. Edit `object` node to define the migration object. Configuration reference [object](./../config/mtk-object.md#object) + + After editing, run [config-check](./../commands/mtk_config-check.md) + + ```shell + ./mtk config-check -c sqlserver2mg/config/mtk.json + ``` + + The configuration file will output type information normally + + ```shell + use config : sqlserver2mg/config/mtk.json + There is no error in the configuration file + ``` + +6. Run + + | Step |Desc| Command Desc | + |---------------------------------|---|------------------------------------------------| + | ./mtk mig-tab-pre -c sqlserver2mg/config/mtk.json |Migration table| [mig-tab-pre](./../commands/mtk_mig-tab-pre.md) | + | ./mtk mig-tab-data -c sqlserver2mg/config/mtk.json |Migration table data|| [mig-tab-data](./../commands/mtk_mig-tab-data.md) | + | ./mtk mig-tab-post -c sqlserver2mg/config/mtk.json |Migration index/cons|| [mig-tab-post](./../commands/mtk_mig-tab-post.md) | + | ./mtk mig-tab-other -c sqlserver2mg/config/mtk.json |Migration plsql|| [mig-tab-other](./../commands/mtk_mig-tab-other.md) | + +7. view Report + + Reports and run logs are generated in the `ora2og/report` directory. as follows + + ```bash + [2022-01-20 11:29:25.800978] INFO reportDir: sqlserver2mg/report/report_20220120110125 function=GenReport line=412 file=mtk/cmd/mtk/services/cmd.go + [2022-01-20 11:29:26.426822] INFO the text report : sqlserver2mg/report/report_20220120110125.txt function=PrintReport line=270 file=mtk/cmd/mtk/services/cmd.go + [2022-01-20 11:29:26.429545] INFO the warring report : sqlserver2mg/report/report_20220120110125.warring function=PrintReport line=281 file=mtk/cmd/mtk/services/cmd.go + [2022-01-20 11:29:26.430118] INFO the error report : sqlserver2mg/report/report_20220120110125.err file=mtk/cmd/mtk/services/cmd.go function=PrintReport line=292 + ``` + + | file name | description | + |---------------------------------------------|---------------------------------------------------| + | sqlserver2mg/report/report_20220120110125 | html report | + | sqlserver2mg/report/report_20220120110125.txt | text report | + | sqlserver2mg/report/report_20220120110125.warring | A text report that contains only warning messages | + | sqlserver2mg/report/report_20220120110125.err | A text report that contains only error messages | + +## Precautions + +### Sequence + +### Type + +- 自定义类型. [查询SQL](#type-1) + +### Table + +### Column + +#### Generated column + +The expression is not converted + +#### Gis + +- Geometry is converted to WKT by query colname.STAsText() + +#### Unsupported column types + +- GeoGraphy +- HIERARCHYID +- SqlVARIANT +- TimeStamp + +### Constraint + +### 索引 + +- Spatial index does not have Postgis installed, and an error is reported. + +#### Index + +- XML index +- Clustered column store index +- Nonclustered column store index +- Nonclustered hash index + +### Trigger + +- The ON DATABASE trigger does not translate overrides +- ON ALL SERVER triggers do not transform overrides +- The FOR XXX trigger does not convert overrides +- INSTEAD OF XXX changed to BEFORE XXX + +### Other Problem + +#### TLS Handshake failed: tls: server selected unsupported protocol version 301 + +Manually configured dsn added`?encrypt=disable` + +```json +{ + "source": { + "type": "sqlserver", + "connect": { + "dsn": "sqlserver://username:password@host/instance?encrypt=disable", + } + }, + "target": { + "type": "mogdb", + "connect": { + } + } +} +``` + +
+ +## Part query SQL statement + +### Schema + +```sql +SELECT name from sys.schemas where 1=1 +``` + +### Sequence + +#### 2012 + +```sql +select schema_name(s.schema_id) as schema_name, + s.name as seq_name, + s.minimum_value as MINVALUE, + s.maximum_value as MAXVALUE, + s.[increment] as INCREMENT, + -- '' as ORDER, + s.is_cycling as CYCLE , + s.cache_size as CACHE, + s.current_value as current_value, + s.current_value as LAST_NUMBER, + s.start_value as START, + s.[precision] as PRECISION +from sys.sequences s where 1=1 +``` + +#### 2017 + +```sql +select schema_name(s.schema_id) as schema_name, + s.name as seq_name, + s.minimum_value as MINVALUE, + s.maximum_value as MAXVALUE, + s.[increment] as INCREMENT, + -- '' as ORDER, + s.is_cycling as CYCLE , + s.cache_size as CACHE, + s.current_value as current_value, + s.last_used_value as LAST_NUMBER, + s.start_value as START, + s.[precision] as PRECISION +from sys.sequences s where 1=1 +``` + +### Type + +```sql +SELECT +s.name as schema_name, +t.name as type_name, +t.system_type_id, +t.user_type_id, +t.max_length, +t.precision, +t.scale, +s1.name as base_schema_name, +base.name as base_type_name, +t.is_nullable, +t.is_table_type, +t.is_user_defined, +t.is_assembly_type, +t.default_object_id, +t.rule_object_id +FROM sys.types as t +left join sys.schemas as s on t.schema_id = s.schema_id +left join sys.types as base on t.system_type_id = base.user_type_id +left join sys.schemas as s1 on base.schema_id = s1.schema_id +where t.is_user_defined=1 +``` + +### Table + +#### 2012 + +```sql +select schema_name(t.schema_id) as schema_name,t.name as table_name,0 as t.is_external, +0 as t.is_node, +0 as t.is_edge, +0 as t.temporal_type, +t.is_filetable, +ep.value, +ic.partition_ordinal +from sys.tables t +LEFT OUTER JOIN sys.extended_properties ep on ep.class = 1 AND ep.major_id = t.object_id AND ep.minor_id = 0 AND ep.name = 'MS_Description' +LEFT JOIN sys.indexes AS i ON t.object_id = i.object_id AND i.[type] <= 1 +LEFT JOIN sys.index_columns AS ic ON ic.[object_id] = i.[object_id] AND ic.index_id = i.index_id AND ic.partition_ordinal >= 1 +where 1=1 +``` + +#### 2016+ + +```sql +select schema_name(t.schema_id) as schema_name,t.name as table_name,t.is_external, +t.is_node, +t.is_edge, +t.temporal_type, +t.is_filetable, +ep.value, +ic.partition_ordinal +from sys.tables t +LEFT OUTER JOIN sys.extended_properties ep on ep.class = 1 AND ep.major_id = t.object_id AND ep.minor_id = 0 AND ep.name = 'MS_Description' +LEFT JOIN sys.indexes AS i ON t.object_id = i.object_id AND i.[type] <= 1 +LEFT JOIN sys.index_columns AS ic ON ic.[object_id] = i.[object_id] AND ic.index_id = i.index_id AND ic.partition_ordinal >= 1 +where 1=1 +``` + +### Partition + +```sql +SELECT sch.name AS SchemaName,t.name AS TableName,i.name AS IndexName,p.partition_number, + p.partition_id, + i.data_space_id, + f.function_id, + f.type_desc as partitioningType, + r.boundary_id, + r.value AS BoundaryValue, + ic.column_id AS PartitioningColumnID, + c.name AS PartitioningColumnName, + s.name as partition_scheme_name, + f.name as partition_function_name, + f.boundary_value_on_right +FROM + sys.tables AS t +JOIN sys.indexes AS i ON t.object_id = i.object_id AND i.[type] <= 1 +JOIN sys.partitions AS p ON i.object_id = p.object_id AND i.index_id = p.index_id +JOIN sys.partition_schemes AS s ON i.data_space_id = s.data_space_id +JOIN sys.index_columns AS ic ON ic.[object_id] = i.[object_id] AND ic.index_id = i.index_id AND ic.partition_ordinal >= 1 + -- because 0 = non-partitioning column +JOIN sys.columns AS c ON t.[object_id] = c.[object_id] AND ic.column_id = c.column_id +JOIN sys.partition_functions AS f ON s.function_id = f.function_id +LEFT JOIN sys.partition_range_values AS r ON f.function_id = r.function_id and r.boundary_id = p.partition_number +LEFT OUTER JOIN sys.schemas sch ON t.schema_id = sch.schema_id +WHERE 1=1 +``` + +### Table Size + +```sql +SELECT + s.Name AS TABLE_SCHEMA, + t.NAME AS TABLE_NAME, + p.partition_id , + a.type_desc , + p.rows AS RowCounts, + a.used_pages * 8 as UsedSpaceKB, + ic.partition_ordinal, + t.max_column_id_used +FROM + sys.tables t +INNER JOIN sys.indexes i ON t.OBJECT_ID = i.object_id and i.[type] <= 1 -- 只统计堆/聚集索引 +LEFT JOIN sys.index_columns AS ic ON ic.[object_id] = i.[object_id] AND ic.index_id = i.index_id AND ic.partition_ordinal >= 1 +INNER JOIN sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id +INNER JOIN sys.allocation_units a ON p.partition_id = a.container_id +LEFT OUTER JOIN sys.schemas s ON t.schema_id = s.schema_id +WHERE t.is_ms_shipped = 0 AND i.OBJECT_ID > 255 AND t.type = 'U' +``` + +### Column + +#### 2012 + +```sql +SELECT schema_name(tab.schema_id) as schema_name,tab.name as table_name,c.name as column_name, + c.column_id, + t.name as data_type, + c.max_length, + c.precision, + c.scale, + 0 as c.is_hidden, + c.is_nullable , + 0 as c.is_masked, + COLUMNPROPERTY(c.object_id,c.name,'charmaxlen') as char_max_length, + dc.definition as default_definition, + ep.value as description, + cc.definition, + c.is_identity , + ic.seed_value , + ic.last_value , + ic.increment_value, + t.is_user_defined +FROM + sys.all_columns c +left join sys.types as t on c.user_type_id = t.user_type_id +JOIN sys.tables tab ON tab.object_id = c.object_id +LEFT OUTER JOIN sys.default_constraints dc ON dc.parent_object_id = tab.object_id AND dc.parent_column_id = c.column_id +LEFT OUTER JOIN master.sys.extended_properties ep ON ep.class = 1 AND ep.major_id = tab.object_id AND ep.minor_id = c.column_id AND ep.name = 'MS_Description' +left join sys.computed_columns cc on cc.object_id = tab.object_id and cc.column_id = c.column_id +left join sys.identity_columns ic on ic.object_id = tab.object_id and ic.column_id = c.column_id +where 1=1 +``` + +#### 2016+ + +```sql +SELECT schema_name(tab.schema_id) as schema_name,tab.name as table_name,c.name as column_name, + c.column_id, + t.name as data_type, + c.max_length, + c.precision, + c.scale, + c.is_hidden, + c.is_nullable , + c.is_masked, + COLUMNPROPERTY(c.object_id,c.name,'charmaxlen') as char_max_length, + dc.definition as default_definition, + ep.value as description, + cc.definition, + c.is_identity , + ic.seed_value , + ic.last_value , + ic.increment_value, + t.is_user_defined +FROM + sys.all_columns c +left join sys.types as t on c.user_type_id = t.user_type_id +JOIN sys.tables tab ON tab.object_id = c.object_id +LEFT OUTER JOIN sys.default_constraints dc ON dc.parent_object_id = tab.object_id AND dc.parent_column_id = c.column_id +LEFT OUTER JOIN master.sys.extended_properties ep ON ep.class = 1 AND ep.major_id = tab.object_id AND ep.minor_id = c.column_id AND ep.name = 'MS_Description' +left join sys.computed_columns cc on cc.object_id = tab.object_id and cc.column_id = c.column_id +left join sys.identity_columns ic on ic.object_id = tab.object_id and ic.column_id = c.column_id +where 1=1 +``` + +### Constraint + +#### PK/UK + +```sql +select schema_name(t.schema_id) as schema_name,t.[name] as table_name, + case + when t.[type] = 'U' then 'Table' + when t.[type] = 'V' then 'View' + end as [object_type], + case + when c.[type] = 'PK' then 'P' + -- 'Primary key' + when c.[type] = 'UQ' then 'U' + --'Unique constraint' + when i.[type] = 1 then 'Unique clustered index' + when i.[type] = 2 then 'Unique index' + end as constraint_type, + c.name as constraint_name, + i.name as index_name, + substring(column_names, 1, len(column_names)-1) as columns +from + sys.objects t +inner join sys.indexes i on + t.object_id = i.object_id +inner join sys.key_constraints c on + i.object_id = c.parent_object_id + and i.index_id = c.unique_index_id cross apply ( + select + CAST(ic.key_ordinal AS varchar) + '||||' + + col.[name] + '||||' + + case + when ic.is_descending_key = 1 then 'desc' + else 'asc' + end + '||||' + + case + when col.is_nullable = 1 then '1' + else '0' + end + + '@ ' + from + sys.index_columns ic + inner join sys.columns col on + ic.object_id = col.object_id + and ic.column_id = col.column_id + where + ic.object_id = t.object_id + and ic.index_id = i.index_id + order by + ic.key_ordinal for xml path ('') ) D (column_names) +where + is_unique = 1 + and t.is_ms_shipped <> 1 + and t.[type] = 'U' +``` + +#### Check + +```sql +select schema_name(t.schema_id) as schema_name,t.[name] as table_name,'Table', + 'C', -- Check constraint + con.[name] as constraint_name, + col.name , + con.[definition] as SEARCH_CONDITION + from + sys.check_constraints con + left outer join sys.objects t on + con.parent_object_id = t.object_id + left outer join sys.all_columns col on + con.parent_column_id = col.column_id + and con.parent_object_id = col.object_id +``` + +#### FK + +```sql +select fk.object_id,schema_name(fk_tab.schema_id) as owner,fk_tab.name table_name, + fk.name as constraint_name, + fk.is_disabled as con_is_disabled, + fk.delete_referential_action_desc , + fk.update_referential_action_desc , + schema_name(pk_tab.schema_id) as R_OWNER, + pk_tab.name as R_TABLE_NAME, + fk_cols.constraint_column_id as no, + fk_col.name as fk_column_name, + fk_col.is_nullable as fk_column_is_nullable, + pk_col.name as pk_column_name, + pk_col.is_nullable as pk_column_is_nullable +from sys.foreign_keys fk + inner join sys.tables fk_tab + on fk_tab.object_id = fk.parent_object_id + inner join sys.tables pk_tab + on pk_tab.object_id = fk.referenced_object_id + inner join sys.foreign_key_columns fk_cols + on fk_cols.constraint_object_id = fk.object_id + inner join sys.columns fk_col + on fk_col.column_id = fk_cols.parent_column_id + and fk_col.object_id = fk_tab.object_id + inner join sys.columns pk_col + on pk_col.column_id = fk_cols.referenced_column_id + and pk_col.object_id = pk_tab.object_id +``` + +### Index + +```sql +select schema_name(t.schema_id) as schema_name,t.[name] as tab_name,i.[name] as index_name, + substring(column_names, 1, len(column_names)-1) as [columns], +-- case +-- when i.[type] = 1 then 'Clustered index' +-- when i.[type] = 2 then 'Nonclustered unique index' +-- when i.[type] = 3 then 'XML index' +-- when i.[type] = 4 then 'Spatial index' +-- when i.[type] = 5 then 'Clustered columnstore index' +-- when i.[type] = 6 then 'Nonclustered columnstore index' +-- when i.[type] = 7 then 'Nonclustered hash index' +-- end as index_type, + i.[type] as index_type, + i.is_unique, +-- case +-- when i.is_unique = 1 then 'Unique' +-- else 'Not unique' +-- end as [unique], + t.[type] as object_type, + i.is_disabled +-- case +-- when t.[type] = 'U' then 'Table' +-- when t.[type] = 'V' then 'View' +-- end as [object_type] +from + sys.objects t +inner join sys.indexes i on + t.object_id = i.object_id cross apply ( + select + CAST(ic.key_ordinal AS varchar) + '||||' + col.[name] + '||||' + + case + when ic.is_descending_key = 1 then 'desc' + else 'asc' + end + '||||' + + case + when col.is_nullable = 1 then '1' + else '0' + end + '@ ' + from + sys.index_columns ic + inner join sys.columns col on + ic.object_id = col.object_id + and ic.column_id = col.column_id + where + ic.object_id = t.object_id + and ic.index_id = i.index_id + order by + key_ordinal for xml path ('') ) D (column_names) +where + t.is_ms_shipped <> 1 + and index_id > 0 + and i.is_primary_key = 0 + and i.is_unique_constraint = 0 +``` + +### View + +```sql +select schema_name(v.schema_id), v.name, m.definition from + sys.views v join sys.sql_modules m on m.object_id = v.object_id + where 1=1 +``` + +### Materialized View + +```sql +``` + +### Function + +```sql +select + schema_name(obj.schema_id) as schema_name, + obj.object_id, + obj.name as function_name, + type, + mod.definition +from + sys.objects obj +join sys.sql_modules mod on mod.object_id = obj.object_id +where 1=1 AND obj.[type] in +('AF','FN','FS','FT','IF','TF') +``` + +### Procedure + +```sql +select + schema_name(obj.schema_id) as schema_name, + obj.object_id, + obj.name as function_name, + type, + mod.definition +from + sys.objects obj +join sys.sql_modules mod on mod.object_id = obj.object_id +where 1=1 AND obj.[type] in +('P','PC','RF','X') +``` + +### Trigger + +```sql +select t.object_id, + schema_name(o.schema_id) as trigger_owner, + t.name as trigger_name, + schema_name(tab.schema_id) as table_owner, + tab.name table_name, + t.is_disabled , + -- te.is_trigger_event , + case when is_instead_of_trigger = 1 then 'INSTEAD OF' else 'AFTER' end as [activation], + case when t.parent_class = 1 then 'TABLE' when t.parent_class = 0 then 'DATABASE' end [class], + -- te.type_desc , + mod.definition +from + sys.triggers t + -- join sys.trigger_events te on t.object_id = te.object_id +join sys.all_objects o on o.object_id = t.object_id +join sys.all_objects tab on tab.object_id = t.parent_id +join sys.sql_modules mod on mod.object_id = t.object_id +where 1=1 +``` diff --git a/product/en/docs-mtk/v2.0/releases/release-2.9.md b/product/en/docs-mtk/v2.0/releases/release-2.9.md index 394b36a466cb83852693228eff150fb7656b9233..09353db273d5910cba9d17fb01e12e538feb1b3b 100644 --- a/product/en/docs-mtk/v2.0/releases/release-2.9.md +++ b/product/en/docs-mtk/v2.0/releases/release-2.9.md @@ -10,6 +10,60 @@ date: 2021-09-17 - mtk command line tool - mtkd mtk background service process. used for specific scenarios +## v2.9.8 + +2024-05-09 + +### MTK + +- [mtk_2.9.8_windows_amd64.tar.gz](https://cdn-mogdb.enmotech.com/mtk/v2.9.8/mtk_2.9.8_windows_amd64.tar.gz) +- [mtk_2.9.8_linux_arm64.tar.gz](https://cdn-mogdb.enmotech.com/mtk/v2.9.8/mtk_2.9.8_linux_arm64.tar.gz) +- [mtk_2.9.8_linux_amd64.tar.gz](https://cdn-mogdb.enmotech.com/mtk/v2.9.8/mtk_2.9.8_linux_amd64.tar.gz) +- [mtk_2.9.8_darwin_amd64.tar.gz](https://cdn-mogdb.enmotech.com/mtk/v2.9.8/mtk_2.9.8_darwin_amd64.tar.gz) +- [mtk_2.9.8_darwin_arm64.tar.gz](https://cdn-mogdb.enmotech.com/mtk/v2.9.8/mtk_2.9.8_darwin_arm64.tar.gz) +- [mtk_2.9.8_linux_amd64_db2.tar.gz](https://cdn-mogdb.enmotech.com/mtk/v2.9.8/mtk_2.9.8_linux_amd64_db2.tar.gz) +- [mtk_2.9.8_darwin_amd64_db2.tar.gz](https://cdn-mogdb.enmotech.com/mtk/v2.9.8/mtk_2.9.8_darwin_amd64_db2.tar.gz) +- [mtk_2.9.8_windows_amd64_db2.tar.gz](https://cdn-mogdb.enmotech.com/mtk/v2.9.8/mtk_2.9.8_windows_amd64_db2.tar.gz) +- [mtk_checksums.txt](https://cdn-mogdb.enmotech.com/mtk/v2.9.8/mtk_checksums.txt) + +### MTKD + +- [mtkd_2.9.8_linux_amd64.tar.gz](https://cdn-mogdb.enmotech.com/mtk/v2.9.8/mtkd_2.9.8_linux_amd64.tar.gz) +- [mtkd_2.9.8_linux_amd64_db2.tar.gz](https://cdn-mogdb.enmotech.com/mtk/v2.9.8/mtkd_2.9.8_linux_amd64_db2.tar.gz) +- [mtkd_2.9.8_linux_arm64.tar.gz](https://cdn-mogdb.enmotech.com/mtk/v2.9.8/mtkd_2.9.8_linux_arm64.tar.gz) + +### Bug Fixes + +- **DM:** Modify query schema view to change from `DBA_USER` to `sysobject` +- **MVD:** Error message display issue +- **MogDB:** Configure `dropExistingObject=true` to migrate MySQL auto-increment table create table sequence does not exist issue +- **MogDB:** Migrate Oracle `Nchar/Nvarchar` to GBK/GB18030 A mode column length expanded by 4 times +- **MogDB:** Migrate Oracle primary key/unique key constraint reference index is not a unique index and is forced to be changed to a unique index +- **MogDB:** Migrate MySQL to MogDB B mode should not write `interval` syntax +- **MogDB:** Migrate MySQL to MogDB B mode should not write `ifnull` syntax +- **MogDB:** Rewrite `group_concat (select)` syntax problem +- **MogDB:** Rewrite the `if` control statement syntax problem in the MySQL function +- **MySQL:** Parsing function `time_format` format error +- **MySQL:** Migrate MySQL to MySQL `autoAddMySQLAutoIncr` not work issue +- **Oracle:** Generate `nchar/nvarchar` syntax error issue +- **Oracle:** Query view column information issue +- **Oracle:** The problem of losing temporary table index when migrating temporary table +- **PLSQL:** Split `union/union all` statement problem +- **PLSQL:** Extract function/stored procedure `create\n or replace` syntax issue +- **PostgreSQL:** Add SQL to ignore error encoding + +### Features + +- **DM:** Driver attempts to support `clientEncoding` setting. Unofficial DM driver support +- **MTKD:** Database password supports encryption +- **MogDB:** Index parallel creation ignores temporary table indexes +- **MogDB:** Support migrating MySQL column collate to MogDB +- **MogDB:** To migrate the MySQL view, first create it with the original statement. If it fails, rewrite it and create it. +- **MySQL:** Add `event` query. Only remind and not migrate +- **Oracle:** Add `DBA_JOBS/DBA_SCHEDULER_JOBS` query. Only remind and not migrate +- **Oracle:** Support Oracle column `default on null` syntax +- **PostgreSQL:** Support PostgreSQL 9.4 + ## v2.9.7 2024-03-08 diff --git a/product/en/docs-mtk/v2.0/releases/release-notes.md b/product/en/docs-mtk/v2.0/releases/release-notes.md index a0ea71a2da2d6cbff7d698dbd86bd2c14259f6c1..0d2672e3bcaa3472022fa206c1352d0af066cabd 100644 --- a/product/en/docs-mtk/v2.0/releases/release-notes.md +++ b/product/en/docs-mtk/v2.0/releases/release-notes.md @@ -15,6 +15,7 @@ date: 2021-09-13 ## 2.9 +- [2.9.8](./release-2.9.md#298) - [2.9.7](./release-2.9.md#297) - [2.9.6](./release-2.9.md#296) - [2.9.5](./release-2.9.md#295) diff --git a/product/en/docs-mtk/v2.0/toc.md b/product/en/docs-mtk/v2.0/toc.md index d13e958fdf88bac1d7182d6ce6548fc66d8469c4..a1d147c914efbabf750f37aa86ebee0811226d37 100644 --- a/product/en/docs-mtk/v2.0/toc.md +++ b/product/en/docs-mtk/v2.0/toc.md @@ -99,6 +99,7 @@ + [DB2 To MogDB](./faq/mtk-db2-to-openGauss.md) + [Informix To MogDB](./faq/mtk-informix-to-openGauss.md) + [DB2 To MySQL](./faq/mtk-db2-to-mysql.md) + + [MSSQL To MySQL](./faq/mtk-mssql-to-mogdb.md) + Release + [Release Notes](./releases/release-notes.md) + [2.9](./releases/release-2.9.md) diff --git a/product/zh/docs-mtk/v2.0/faq/mtk-mssql-to-mogdb.md b/product/zh/docs-mtk/v2.0/faq/mtk-mssql-to-mogdb.md new file mode 100644 index 0000000000000000000000000000000000000000..851cc4108be73166ee6dbab2c32a7401ee3cdca7 --- /dev/null +++ b/product/zh/docs-mtk/v2.0/faq/mtk-mssql-to-mogdb.md @@ -0,0 +1,637 @@ +--- +title: MTK 迁移 MSSQL 到 MogDB/openGauss +summary: MTK 迁移 MSSQL 到 MogDB/openGauss +author: Bin.Liu +date: 2024-05-09 +--- + +# 使用MTK迁移MSSQL到MogDB/openGauss + +## 支持版本 + +- 2017+ +- 2016 +- 2012 + +## How to + +1. 下载安装MTK + + ```shell + tar -zxvf mtk__linux_.tar.gz + ``` + +2. 申请授权 + + ```shell + cd mtk__linux_ + ./mtk license gen + License File Not Found (default license.json) + The License code is invalid, start applying + ? Email: xxxx@xxxx.com -- 填写邮箱信息 + >> please enter a valid email address + # 复制邮箱里的文件`license.json`到此目录 + ``` + +3. 准备MSSQL用户 +4. MogDB 创建数据库和用户 + + ```shell + gsql + create database db DBCOMPATIBILITY='A' ENCODING='UTF8' LC_COLLATE='C' LC_CTYPE='C'; + \c db + create user mtk_mig with password "mtkMigAbc123" sysadmin; + ``` + + > 注意兼容模式 + > 注意字符集排序规则. 创建数据库语法参考[create database](https://docs.mogdb.io/zh/mogdb/latest/CREATE-DATABASE) + +5. 初始化项目 + + ```shell + ./mtk init-project -s sqlserver -t mogdb -n sqlserver2mg + tree -f sqlserver2mg/ + sqlserver2mg + ├── sqlserver2mg/config + │ └── sqlserver2mg/config/mtk.json + ├── sqlserver2mg/data + ├── sqlserver2mg/report + └── sqlserver2mg/schema + ``` + + 编辑配置文件. 具体查看[MTK配置说明](./../config/mtk-config.md)章 + + ```bash + vi sqlserver2mg/config/mtk.json + ``` + + 1. 编辑`source`节点,定义源数据库连接信息. 配置参考[source](./../config/mtk-config.md#source) + 2. 编辑`target`节点,定义目标数据库连接信息. 配置参考[target](./../config/mtk-config.md#target) + + > 修改connect和type信息,parameter根据运行在进行调整 + + 3. 编辑`object`节点,定义迁移对象. 配置参考[object](./../config/mtk-object.md#object) + + 编辑完成后,运行[config-check](./../commands/mtk_config-check.md)检查配置文件是否正确 + + ```shell + ./mtk config-check -c sqlserver2mg/config/mtk.json + ``` + + 配置文件配置正常会输出类型信息 + + ```shell + use config : sqlserver2mg/config/mtk.json + There is no error in the configuration file + ``` + +6. 迁移 + + | 步骤 |描述| 命令 | + |---------------------------------|---|------------------------------------------------| + | ./mtk mig-tab-pre -c sqlserver2mg/config/mtk.json |迁移表| [mig-tab-pre](./../commands/mtk_mig-tab-pre.md) | + | ./mtk mig-tab-data -c sqlserver2mg/config/mtk.json |迁移表数据|| [mig-tab-data](./../commands/mtk_mig-tab-data.md) | + | ./mtk mig-tab-post -c sqlserver2mg/config/mtk.json |迁移索引约束|| [mig-tab-post](./../commands/mtk_mig-tab-post.md) | + | ./mtk mig-tab-other -c sqlserver2mg/config/mtk.json |迁移存储过程PLSQL相关|| [mig-tab-other](./../commands/mtk_mig-tab-other.md) | + +7. 查看报告 + + 报告和运行日志会生成在`ora2og/report`目录下. 如下 + + ```bash + [2022-01-20 11:29:25.800978] INFO reportDir: sqlserver2mg/report/report_20220120110125 function=GenReport line=412 file=mtk/cmd/mtk/services/cmd.go + [2022-01-20 11:29:26.426822] INFO the text report : sqlserver2mg/report/report_20220120110125.txt function=PrintReport line=270 file=mtk/cmd/mtk/services/cmd.go + [2022-01-20 11:29:26.429545] INFO the warring report : sqlserver2mg/report/report_20220120110125.warring function=PrintReport line=281 file=mtk/cmd/mtk/services/cmd.go + [2022-01-20 11:29:26.430118] INFO the error report : sqlserver2mg/report/report_20220120110125.err file=mtk/cmd/mtk/services/cmd.go function=PrintReport line=292 + ``` + + | 文件名 | 说明 | + |---------------------------------------------|--------------------------| + | sqlserver2mg/report/report_20220120110125 | html报告 | + | sqlserver2mg/report/report_20220120110125.txt | 文本报告 | + | sqlserver2mg/report/report_20220120110125.warring | 只包含警告信息的文本报告 | + | sqlserver2mg/report/report_20220120110125.err | 只包含错误信息的文本报告 | + +## 注意事项 + +### 序列 + +### Type + +- 自定义类型. [查询SQL](#type-1) + +### 表 + +- 分区表不支持迁移成分区表 + +### 列 + +#### 生成列 + +表达式未转换 + +#### Gis + +- Geometry 通过查询转换为WKT. colname.STAsText() + +#### 不支持的列 + +- GeoGraphy +- HIERARCHYID +- SqlVARIANT +- TimeStamp + +### 约束 + +### 索引 + +- Spatial index 没有安装Postgis会报错. + +#### 不支持的索引 + +- XML index +- Clustered column store index +- Nonclustered column store index +- Nonclustered hash index + +### Trigger + +- ON DATABASE 触发器不转换改写 +- ON ALL SERVER 触发器不转换改写 +- FOR XXX 触发器不转换改写 +- INSTEAD OF XXX 改成为 BEFORE XXX + +### 其他问题 + +#### TLS Handshake failed: tls: server selected unsupported protocol version 301 + +手工配置连接字符信息增加`?encrypt=disable` + +```json +{ + "source": { + "type": "sqlserver", + "connect": { + "dsn": "sqlserver://username:password@host/instance?encrypt=disable", + } + }, + "target": { + "type": "mogdb", + "connect": { + } + } +} +``` + +## 部分SQL语句 + +### Schema + +```sql +SELECT name from sys.schemas where 1=1 +``` + +### Sequence + +#### 2012 + +```sql +select schema_name(s.schema_id) as schema_name, + s.name as seq_name, + s.minimum_value as MINVALUE, + s.maximum_value as MAXVALUE, + s.[increment] as INCREMENT, + -- '' as ORDER, + s.is_cycling as CYCLE , + s.cache_size as CACHE, + s.current_value as current_value, + s.current_value as LAST_NUMBER, + s.start_value as START, + s.[precision] as PRECISION +from sys.sequences s where 1=1 +``` + +#### 2017 + +```sql +select schema_name(s.schema_id) as schema_name, + s.name as seq_name, + s.minimum_value as MINVALUE, + s.maximum_value as MAXVALUE, + s.[increment] as INCREMENT, + -- '' as ORDER, + s.is_cycling as CYCLE , + s.cache_size as CACHE, + s.current_value as current_value, + s.last_used_value as LAST_NUMBER, + s.start_value as START, + s.[precision] as PRECISION +from sys.sequences s where 1=1 +``` + +### Type + +```sql +SELECT +s.name as schema_name, +t.name as type_name, +t.system_type_id, +t.user_type_id, +t.max_length, +t.precision, +t.scale, +s1.name as base_schema_name, +base.name as base_type_name, +t.is_nullable, +t.is_table_type, +t.is_user_defined, +t.is_assembly_type, +t.default_object_id, +t.rule_object_id +FROM sys.types as t +left join sys.schemas as s on t.schema_id = s.schema_id +left join sys.types as base on t.system_type_id = base.user_type_id +left join sys.schemas as s1 on base.schema_id = s1.schema_id +where t.is_user_defined=1 +``` + +### Table + +#### 2012 + +```sql +select schema_name(t.schema_id) as schema_name,t.name as table_name,0 as t.is_external, +0 as t.is_node, +0 as t.is_edge, +0 as t.temporal_type, +t.is_filetable, +ep.value, +ic.partition_ordinal +from sys.tables t +LEFT OUTER JOIN sys.extended_properties ep on ep.class = 1 AND ep.major_id = t.object_id AND ep.minor_id = 0 AND ep.name = 'MS_Description' +LEFT JOIN sys.indexes AS i ON t.object_id = i.object_id AND i.[type] <= 1 +LEFT JOIN sys.index_columns AS ic ON ic.[object_id] = i.[object_id] AND ic.index_id = i.index_id AND ic.partition_ordinal >= 1 +where 1=1 +``` + +#### 2016+ + +```sql +select schema_name(t.schema_id) as schema_name,t.name as table_name,t.is_external, +t.is_node, +t.is_edge, +t.temporal_type, +t.is_filetable, +ep.value, +ic.partition_ordinal +from sys.tables t +LEFT OUTER JOIN sys.extended_properties ep on ep.class = 1 AND ep.major_id = t.object_id AND ep.minor_id = 0 AND ep.name = 'MS_Description' +LEFT JOIN sys.indexes AS i ON t.object_id = i.object_id AND i.[type] <= 1 +LEFT JOIN sys.index_columns AS ic ON ic.[object_id] = i.[object_id] AND ic.index_id = i.index_id AND ic.partition_ordinal >= 1 +where 1=1 +``` + +### Partition + +```sql +SELECT sch.name AS SchemaName,t.name AS TableName,i.name AS IndexName,p.partition_number, + p.partition_id, + i.data_space_id, + f.function_id, + f.type_desc as partitioningType, + r.boundary_id, + r.value AS BoundaryValue, + ic.column_id AS PartitioningColumnID, + c.name AS PartitioningColumnName, + s.name as partition_scheme_name, + f.name as partition_function_name, + f.boundary_value_on_right +FROM + sys.tables AS t +JOIN sys.indexes AS i ON t.object_id = i.object_id AND i.[type] <= 1 +JOIN sys.partitions AS p ON i.object_id = p.object_id AND i.index_id = p.index_id +JOIN sys.partition_schemes AS s ON i.data_space_id = s.data_space_id +JOIN sys.index_columns AS ic ON ic.[object_id] = i.[object_id] AND ic.index_id = i.index_id AND ic.partition_ordinal >= 1 + -- because 0 = non-partitioning column +JOIN sys.columns AS c ON t.[object_id] = c.[object_id] AND ic.column_id = c.column_id +JOIN sys.partition_functions AS f ON s.function_id = f.function_id +LEFT JOIN sys.partition_range_values AS r ON f.function_id = r.function_id and r.boundary_id = p.partition_number +LEFT OUTER JOIN sys.schemas sch ON t.schema_id = sch.schema_id +WHERE 1=1 +``` + +### Table Size + +```sql +SELECT + s.Name AS TABLE_SCHEMA, + t.NAME AS TABLE_NAME, + p.partition_id , + a.type_desc , + p.rows AS RowCounts, + a.used_pages * 8 as UsedSpaceKB, + ic.partition_ordinal, + t.max_column_id_used +FROM + sys.tables t +INNER JOIN sys.indexes i ON t.OBJECT_ID = i.object_id and i.[type] <= 1 -- 只统计堆/聚集索引 +LEFT JOIN sys.index_columns AS ic ON ic.[object_id] = i.[object_id] AND ic.index_id = i.index_id AND ic.partition_ordinal >= 1 +INNER JOIN sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id +INNER JOIN sys.allocation_units a ON p.partition_id = a.container_id +LEFT OUTER JOIN sys.schemas s ON t.schema_id = s.schema_id +WHERE t.is_ms_shipped = 0 AND i.OBJECT_ID > 255 AND t.type = 'U' +``` + +### Column + +#### 2012 + +```sql +SELECT schema_name(tab.schema_id) as schema_name,tab.name as table_name,c.name as column_name, + c.column_id, + t.name as data_type, + c.max_length, + c.precision, + c.scale, + 0 as c.is_hidden, + c.is_nullable , + 0 as c.is_masked, + COLUMNPROPERTY(c.object_id,c.name,'charmaxlen') as char_max_length, + dc.definition as default_definition, + ep.value as description, + cc.definition, + c.is_identity , + ic.seed_value , + ic.last_value , + ic.increment_value, + t.is_user_defined +FROM + sys.all_columns c +left join sys.types as t on c.user_type_id = t.user_type_id +JOIN sys.tables tab ON tab.object_id = c.object_id +LEFT OUTER JOIN sys.default_constraints dc ON dc.parent_object_id = tab.object_id AND dc.parent_column_id = c.column_id +LEFT OUTER JOIN master.sys.extended_properties ep ON ep.class = 1 AND ep.major_id = tab.object_id AND ep.minor_id = c.column_id AND ep.name = 'MS_Description' +left join sys.computed_columns cc on cc.object_id = tab.object_id and cc.column_id = c.column_id +left join sys.identity_columns ic on ic.object_id = tab.object_id and ic.column_id = c.column_id +where 1=1 +``` + +#### 2016+ + +```sql +SELECT schema_name(tab.schema_id) as schema_name,tab.name as table_name,c.name as column_name, + c.column_id, + t.name as data_type, + c.max_length, + c.precision, + c.scale, + c.is_hidden, + c.is_nullable , + c.is_masked, + COLUMNPROPERTY(c.object_id,c.name,'charmaxlen') as char_max_length, + dc.definition as default_definition, + ep.value as description, + cc.definition, + c.is_identity , + ic.seed_value , + ic.last_value , + ic.increment_value, + t.is_user_defined +FROM + sys.all_columns c +left join sys.types as t on c.user_type_id = t.user_type_id +JOIN sys.tables tab ON tab.object_id = c.object_id +LEFT OUTER JOIN sys.default_constraints dc ON dc.parent_object_id = tab.object_id AND dc.parent_column_id = c.column_id +LEFT OUTER JOIN master.sys.extended_properties ep ON ep.class = 1 AND ep.major_id = tab.object_id AND ep.minor_id = c.column_id AND ep.name = 'MS_Description' +left join sys.computed_columns cc on cc.object_id = tab.object_id and cc.column_id = c.column_id +left join sys.identity_columns ic on ic.object_id = tab.object_id and ic.column_id = c.column_id +where 1=1 +``` + +### Constraint + +#### PK/UK + +```sql +select schema_name(t.schema_id) as schema_name,t.[name] as table_name, + case + when t.[type] = 'U' then 'Table' + when t.[type] = 'V' then 'View' + end as [object_type], + case + when c.[type] = 'PK' then 'P' + -- 'Primary key' + when c.[type] = 'UQ' then 'U' + --'Unique constraint' + when i.[type] = 1 then 'Unique clustered index' + when i.[type] = 2 then 'Unique index' + end as constraint_type, + c.name as constraint_name, + i.name as index_name, + substring(column_names, 1, len(column_names)-1) as columns +from + sys.objects t +inner join sys.indexes i on + t.object_id = i.object_id +inner join sys.key_constraints c on + i.object_id = c.parent_object_id + and i.index_id = c.unique_index_id cross apply ( + select + CAST(ic.key_ordinal AS varchar) + '||||' + + col.[name] + '||||' + + case + when ic.is_descending_key = 1 then 'desc' + else 'asc' + end + '||||' + + case + when col.is_nullable = 1 then '1' + else '0' + end + + '@ ' + from + sys.index_columns ic + inner join sys.columns col on + ic.object_id = col.object_id + and ic.column_id = col.column_id + where + ic.object_id = t.object_id + and ic.index_id = i.index_id + order by + ic.key_ordinal for xml path ('') ) D (column_names) +where + is_unique = 1 + and t.is_ms_shipped <> 1 + and t.[type] = 'U' +``` + +#### Check + +```sql +select schema_name(t.schema_id) as schema_name,t.[name] as table_name,'Table', + 'C', -- Check constraint + con.[name] as constraint_name, + col.name , + con.[definition] as SEARCH_CONDITION + from + sys.check_constraints con + left outer join sys.objects t on + con.parent_object_id = t.object_id + left outer join sys.all_columns col on + con.parent_column_id = col.column_id + and con.parent_object_id = col.object_id +``` + +#### FK + +```sql +select fk.object_id,schema_name(fk_tab.schema_id) as owner,fk_tab.name table_name, + fk.name as constraint_name, + fk.is_disabled as con_is_disabled, + fk.delete_referential_action_desc , + fk.update_referential_action_desc , + schema_name(pk_tab.schema_id) as R_OWNER, + pk_tab.name as R_TABLE_NAME, + fk_cols.constraint_column_id as no, + fk_col.name as fk_column_name, + fk_col.is_nullable as fk_column_is_nullable, + pk_col.name as pk_column_name, + pk_col.is_nullable as pk_column_is_nullable +from sys.foreign_keys fk + inner join sys.tables fk_tab + on fk_tab.object_id = fk.parent_object_id + inner join sys.tables pk_tab + on pk_tab.object_id = fk.referenced_object_id + inner join sys.foreign_key_columns fk_cols + on fk_cols.constraint_object_id = fk.object_id + inner join sys.columns fk_col + on fk_col.column_id = fk_cols.parent_column_id + and fk_col.object_id = fk_tab.object_id + inner join sys.columns pk_col + on pk_col.column_id = fk_cols.referenced_column_id + and pk_col.object_id = pk_tab.object_id +``` + +### Index + +```sql +select schema_name(t.schema_id) as schema_name,t.[name] as tab_name,i.[name] as index_name, + substring(column_names, 1, len(column_names)-1) as [columns], +-- case +-- when i.[type] = 1 then 'Clustered index' +-- when i.[type] = 2 then 'Nonclustered unique index' +-- when i.[type] = 3 then 'XML index' +-- when i.[type] = 4 then 'Spatial index' +-- when i.[type] = 5 then 'Clustered columnstore index' +-- when i.[type] = 6 then 'Nonclustered columnstore index' +-- when i.[type] = 7 then 'Nonclustered hash index' +-- end as index_type, + i.[type] as index_type, + i.is_unique, +-- case +-- when i.is_unique = 1 then 'Unique' +-- else 'Not unique' +-- end as [unique], + t.[type] as object_type, + i.is_disabled +-- case +-- when t.[type] = 'U' then 'Table' +-- when t.[type] = 'V' then 'View' +-- end as [object_type] +from + sys.objects t +inner join sys.indexes i on + t.object_id = i.object_id cross apply ( + select + CAST(ic.key_ordinal AS varchar) + '||||' + col.[name] + '||||' + + case + when ic.is_descending_key = 1 then 'desc' + else 'asc' + end + '||||' + + case + when col.is_nullable = 1 then '1' + else '0' + end + '@ ' + from + sys.index_columns ic + inner join sys.columns col on + ic.object_id = col.object_id + and ic.column_id = col.column_id + where + ic.object_id = t.object_id + and ic.index_id = i.index_id + order by + key_ordinal for xml path ('') ) D (column_names) +where + t.is_ms_shipped <> 1 + and index_id > 0 + and i.is_primary_key = 0 + and i.is_unique_constraint = 0 +``` + +### View + +```sql +select schema_name(v.schema_id), v.name, m.definition from + sys.views v join sys.sql_modules m on m.object_id = v.object_id + where 1=1 +``` + +### Materialized View + +```sql +``` + +### Function + +```sql +select + schema_name(obj.schema_id) as schema_name, + obj.object_id, + obj.name as function_name, + type, + mod.definition +from + sys.objects obj +join sys.sql_modules mod on mod.object_id = obj.object_id +where 1=1 AND obj.[type] in +('AF','FN','FS','FT','IF','TF') +``` + +### Procedure + +```sql +select + schema_name(obj.schema_id) as schema_name, + obj.object_id, + obj.name as function_name, + type, + mod.definition +from + sys.objects obj +join sys.sql_modules mod on mod.object_id = obj.object_id +where 1=1 AND obj.[type] in +('P','PC','RF','X') +``` + +### Trigger + +```sql +select t.object_id, + schema_name(o.schema_id) as trigger_owner, + t.name as trigger_name, + schema_name(tab.schema_id) as table_owner, + tab.name table_name, + t.is_disabled , + -- te.is_trigger_event , + case when is_instead_of_trigger = 1 then 'INSTEAD OF' else 'AFTER' end as [activation], + case when t.parent_class = 1 then 'TABLE' when t.parent_class = 0 then 'DATABASE' end [class], + -- te.type_desc , + mod.definition +from + sys.triggers t + -- join sys.trigger_events te on t.object_id = te.object_id +join sys.all_objects o on o.object_id = t.object_id +join sys.all_objects tab on tab.object_id = t.parent_id +join sys.sql_modules mod on mod.object_id = t.object_id +where 1=1 +``` diff --git a/product/zh/docs-mtk/v2.0/releases/release-2.9.md b/product/zh/docs-mtk/v2.0/releases/release-2.9.md index e205b2ef46db68115f4022591af602cfcf68640e..8f18a745765c410289a00ab9426d78a55f830c6d 100644 --- a/product/zh/docs-mtk/v2.0/releases/release-2.9.md +++ b/product/zh/docs-mtk/v2.0/releases/release-2.9.md @@ -10,6 +10,60 @@ date: 2021-09-17 - mtk 命令行工具 - mtkd 封装mtk作为后端服务程序,针对特定场景 +## v2.9.8 + +2024-05-09 + +### MTK + +- [mtk_2.9.8_windows_amd64.tar.gz](https://cdn-mogdb.enmotech.com/mtk/v2.9.8/mtk_2.9.8_windows_amd64.tar.gz) +- [mtk_2.9.8_linux_arm64.tar.gz](https://cdn-mogdb.enmotech.com/mtk/v2.9.8/mtk_2.9.8_linux_arm64.tar.gz) +- [mtk_2.9.8_linux_amd64.tar.gz](https://cdn-mogdb.enmotech.com/mtk/v2.9.8/mtk_2.9.8_linux_amd64.tar.gz) +- [mtk_2.9.8_darwin_amd64.tar.gz](https://cdn-mogdb.enmotech.com/mtk/v2.9.8/mtk_2.9.8_darwin_amd64.tar.gz) +- [mtk_2.9.8_darwin_arm64.tar.gz](https://cdn-mogdb.enmotech.com/mtk/v2.9.8/mtk_2.9.8_darwin_arm64.tar.gz) +- [mtk_2.9.8_linux_amd64_db2.tar.gz](https://cdn-mogdb.enmotech.com/mtk/v2.9.8/mtk_2.9.8_linux_amd64_db2.tar.gz) +- [mtk_2.9.8_darwin_amd64_db2.tar.gz](https://cdn-mogdb.enmotech.com/mtk/v2.9.8/mtk_2.9.8_darwin_amd64_db2.tar.gz) +- [mtk_2.9.8_windows_amd64_db2.tar.gz](https://cdn-mogdb.enmotech.com/mtk/v2.9.8/mtk_2.9.8_windows_amd64_db2.tar.gz) +- [mtk_checksums.txt](https://cdn-mogdb.enmotech.com/mtk/v2.9.8/mtk_checksums.txt) + +### MTKD + +- [mtkd_2.9.8_linux_amd64.tar.gz](https://cdn-mogdb.enmotech.com/mtk/v2.9.8/mtkd_2.9.8_linux_amd64.tar.gz) +- [mtkd_2.9.8_linux_amd64_db2.tar.gz](https://cdn-mogdb.enmotech.com/mtk/v2.9.8/mtkd_2.9.8_linux_amd64_db2.tar.gz) +- [mtkd_2.9.8_linux_arm64.tar.gz](https://cdn-mogdb.enmotech.com/mtk/v2.9.8/mtkd_2.9.8_linux_arm64.tar.gz) + +### Bug Fixes + +- **DM:** 修改查询Schema试图从 `DBA_USER` 该为 `sysobject` +- **MVD:** 错误信息展示问题 +- **MogDB:** 配置 `dropExistingObject=true` 迁移 MySQL 自增列表遇到序列不存在问题 +- **MogDB:** 迁移 Oracle `Nchar/Nvarchar` 到 GBK/GB18030 A模式列长度扩充4倍 +- **MogDB:** 迁移 Oracle 主键/唯一键约束引用索引不是唯一索引强制改为唯一索引 +- **MogDB:** 迁移 MySQL 到 MogDB B模式不该写 `interval` 语法 +- **MogDB:** 迁移 MySQL 到 MogDB B模式不该写 `ifnull` 语法 +- **MogDB:** 改写 `group_concat (select)` 语法问题 +- **MogDB:** 改写 MySQL 函数里 `if` 控制语句语法问题 +- **MySQL:** 解析函数 `time_format` 格式错误 +- **MySQL:** 迁移 MySQL 到 MySQL `autoAddMySQLAutoIncr` 失效问题 +- **Oracle:** 生成 `nchar/nvarchar` 语法错误问题 +- **Oracle:** 查询视图列信息问题 +- **Oracle:** 迁移临时表丢失临时表索引问题 +- **PLSQL:** 拆分 `union/union all` 语句问题 +- **PLSQL:** 抽取 函数/存储过程 `create\n or replace` 语法问题 +- **PostgreSQL:** 增加SQL忽略错误编码 + +### Features + +- **DM:** 驱动尝试支持 `clientEncoding` 设置. 非官方DM驱动支持 +- **MTKD:** 数据库密码支持加密 +- **MogDB:** 索引并行创建忽略临时表索引 +- **MogDB:** 支持迁移 MySQL 列 collate 到 MogDB +- **MogDB:** 迁移MySQL视图先用原始语句创建,如果失败在改写创建 +- **MySQL:** 添加 `event` 查询. 只提醒不迁移 +- **Oracle:** 添加 `DBA_JOBS/DBA_SCHEDULER_JOBS` 查询. 只提醒不迁移 +- **Oracle:** 支持 Oracle 列 `default on null` 语法 +- **PostgreSQL:** 支持 PostgreSQL 9.4 + ## v2.9.7 2024-03-08 diff --git a/product/zh/docs-mtk/v2.0/releases/release-notes.md b/product/zh/docs-mtk/v2.0/releases/release-notes.md index 4f0f58e9c67d9895f1a1905c51219dde33f8bafc..811a3a422eae9335cde8eb7902aefdcedd52629c 100644 --- a/product/zh/docs-mtk/v2.0/releases/release-notes.md +++ b/product/zh/docs-mtk/v2.0/releases/release-notes.md @@ -15,6 +15,7 @@ date: 2021-09-17 ## 2.9 +- [2.9.8](./release-2.9.md#298) - [2.9.7](./release-2.9.md#297) - [2.9.6](./release-2.9.md#296) - [2.9.5](./release-2.9.md#295) diff --git a/product/zh/docs-mtk/v2.0/toc.md b/product/zh/docs-mtk/v2.0/toc.md index ea959f9cc093cef10077de3bffcf7390a708923d..8dacba789f9f929fc5ec1b6a5128aa33cd50940f 100644 --- a/product/zh/docs-mtk/v2.0/toc.md +++ b/product/zh/docs-mtk/v2.0/toc.md @@ -99,6 +99,7 @@ + [DB2 To MogDB](./faq/mtk-db2-to-openGauss.md) + [Informix To MogDB](./faq/mtk-informix-to-openGauss.md) + [DB2 To MySQL](./faq/mtk-db2-to-mysql.md) + + [MSSQL To MySQL](./faq/mtk-mssql-to-mogdb.md) + Release + [Release Notes](./releases/release-notes.md) + [2.9](./releases/release-2.9.md)