moscow atlassian meetup. «МИГРАЦИЯ ДАННЫХ В jira ЧЕРЕЗ БД». Георгий...
TRANSCRIPT
Георгий Белоусов
Администратор группы автоматизации
МИГРАЦИЯ ДАННЫХ В JIRA ЧЕРЕЗ БД
• 3 системы, тесно интегрированные между собой
• Большое количество сущностей (~490к)
• Аттачи в BLOB (~140Gb)
• Ограниченный maintenance window (48 часов) на все
• Единовременный переход
• Перенос истории
• Интеграция в уже работающую JIRA
2
НАШ КЕЙС
• Основаны на API или REST API
• Поддерживаются только известные системы
• Много ограничений, не все можно перенести
• Низкая скорость
3
ОФИЦИАЛЬНЫЕ СПОСОБЫ
4
ПЕРВЫЙ ПОДХОД
Основной перенос
(4-6 дней)
Перенос истории
(14 дней)
Суммарное время: 18-20 дней
РИСКИ
• Отсутствие документации
• Валидация данных своими силами
• Подводные камни
БОНУСЫ
• Скорость
• Создание issue, не отличимых от созданных в JIRA
• Полный и детальный перенос
• Гибкое управление заложенной логикой
5
НОВЫЙ ПОДХОД
• Database Schema (https://developer.atlassian.com/jiradev/jira-platform/jira-
architecture/database-schema)
• Entity Model (WEB-INF/classes/entitydefs/entitymodel.xml)
• Анализ записываемых значений в DB
6
ИСХОДНЫЕ ДАННЫЕ
• Тело и «built-in» поля
• Текущее и предыдущие состояния (workflow)
• История изменений
• Кастомные поля
• Комментарии
• Issuelink
• Component, Version, FixVersion
• Aттачи
7
ВИД ISSUE В DB
id issuenum project reporter … issuetype priority resolution issuestatus … workflow_id
3212 123 13000 g_belousov 10500 4 3 6 4512
8
JIRAISSUE
ТЕЛО И “BUILT-IN” ПОЛЯ
id pname
13000 Example
id pname
10500 Service
id pname
4 Critical
id pname
3 Duplicate
id pname
6 Closed
lower_user_name
g_belousov
id name
4512 EXM WF
cwd_user priority issuestatus
project issuetype OS_WFENTRYresolution
id name initialized state
4512 EXM WF NULL 1
9
OS_WFENTRY
СОСТОЯНИЯ (WORKFLOW)
1 Open (Normal state)
4 Closed (End state)
id workflowname DESCRIPTOR
10001 EXM WF <?xml version="1.0" encoding="UTF-8"?>
jiraworkflows
10
WORKFLOW XMLWORKFLOW. DATABASE
<steps>
<step id=“2" name=“Reopened">
<actions>
<common-action id=“11" />
<common-action id=“21" />
</actions>
</step>
…
<step id=“3” name=“Dev”>
<actions>
<common-action id=“21”
<common-action id=“31”
</actions>
</step>
</steps>
11
OS_CURRENTSTEP
ТЕКУЩЕЕ СОСТОЯНИЕ
id name initialized state
4512 EXM WF NULL 1
id entry_id step_id action_id start_date status
7715 4512 2 0 2013-02-03 18:01:13.000 Done
OS_WFENTRY
12
OS_HISTORYSTEP
ПРЕДЫДУЩИЕ СОСТОЯНИЯ
id name initialized state
4512 EXM WF NULL 1
id entry
_id
step_i
d
action_
id
start_date finish_date status caller
7712 4512 1 11 2013-01-30 11:34:35.000 2013-02-01 11:13:07.000 null g_belousov
7713 4512 2 51 2013-02-01 11:13:07.000 2013-02-03 15:11:03.000 null g_belousov
7714 4512 6 41 2013-02-03 15:11:03.000 2013-02-03 18:01:13.000 null g_belousov
OS_WFENTRY
13
OS_CURRENTSTEP_PREV & OS_HISTORYSTEP_PREV
ТЕКУЩЕЕ И ПРЕДЫДУЩИЕ СОСТОЯНИЯ
id entry
_id
step_i
d
action_
id
start_date finish_date status caller
7712 4512 1 11 2013-01-30 11:34:35.000 2013-02-01 11:13:07.000 null g_belousov
7713 4512 2 51 2013-02-01 11:13:07.000 2013-02-03 15:11:03.000 null g_belousov
7714 4512 6 41 2013-02-03 15:11:03.000 2013-02-03 18:01:13.000 null g_belousov
OS_HISTORYSTEP
id previous_id
7713 7712
7714 7713
7715 7714
id previous_id
7713 7712
7714 7713
14
CHANGEGROUP & CHANGEITEM
ИСТОРИЯ ИЗМЕНЕНИЙ
id issueid AUTHOR CREATED
10970 3212 g_belousov 2013-02-01 11:13:07.000
10971 3212 g_belousov 2013-02-03 15:11:03.000
10972 3212 g_belousov 2013-02-03 18:01:13.000
id groupid fieldtype field oldvalue oldstring newvalue newstring fieldid
16970 10970 jira status 1 Open 2 In Progress NULL
16971 10971 jira status 2 In Progress 3 Postponed NULL
16972 10971 custom Amount NULL NULL 10 10 NULL
changeitem
changegroup
15
CUSTOMFIELDVALUE
КАСТОМНЫЕ ПОЛЯ
id issue customfield stringvalue numbervalue textvalue datevalue
23175 3212 12603 037.00 NULL NULL NULL
23176 3212 12308 NULL 224.000000 NULL NULL
23177 3212 12311 NULL NULL NULL 2013-05-28 11:42:12.000
id cfname
12308 Estimation man-days
12311 Date of resumption
12603 Release version
customfield
16
JIRAACTION
КОММЕНТАРИИ
id issueid AUTHOR actiontype rolelevel actionbod
y
created updateauthor updated
10285 3212 g_belousov comment NULL Hello 2013-05-28
11:42:12.000
g_belousov 2013-05-28
11:42:12.000
10412 3212 tester comment 10600 Test done 2014-01-28
17:31:32.000
tester 2014-01-28
17:32:07.000
10512 3212 admin_user comment 10200 Hidden
comment
2015-10-01
01:02:01.000
admin_user 2015-10-01
01:02:01.000
id name
10200 Project Administrator Role
10600 Beta Tester Role
projectrole
17
ISSUELINK
ISSUELINK
id linktype source destination
10001 10000 3212 3217
id linkname inward outward
10000 Blocks is blocked by blocks
issuelinktype
18
NODEASSOCIATION
COMPONENTS, VERSION, FIX VERSION
source_node_id source_node_entity sink_node_id sink_node_entity association_type
3212 Issue 10900 Component IssueComponent
3212 Issue 10203 Version IssueFixVersion
3212 Issue 10205 Version IssueVersion
id project name
10900 13000 Training
component
id project vname description
10203 13000 1.0.1 Интеграция
10205 13000 2.0.0 Релиз
projectversion
[jira@jira-app ~]# ls -la /home/jira/jira-data/data/attachments/EXM/EXM-123/
total 20
drwxrwxr-x 2 jira jira 4096 Jul 29 11:42 .
drwxrwxr-x 39 jira jira 4096 Oct 14 20:30 ..
-rw-rw-r-- 1 jira jira 11438 Jul 29 11:42 23579
FILEATTACHMENT
ФАЙЛЫ АТТАЧЕЙ
id issueid MIMETYPE filename created filesize author zip thumbnailable
23579 3212 application/msword Description.doc 2015-06-29 11:42:12 11438 test.user 0 0
19
ПРОЦЕСС ПЕРЕНОСА
• Подготовка
ДО
• Чтение
• Обработка
• Удаление
• Вставка
ВО ВРЕМЯ
• Создание связей
• Перенос аттачей
• Post Migration
Fixes
• Reindex
ПОСЛЕ
20
21
ЭТАПЫ ФОРМИРОВАНИЯ
ПОДГОТОВКА ДАННЫХ
DB View DB Materialized View DB Table
• Не требует большого объема
памяти
• Удобно при отладке
• Суммарная скорость выше
• Требует подготовки данных
ПОРЦИОННО
• Выполняется один раз
• Необходимо большее
количество памяти
• Удобно при небольшом объеме
исходных данных
ЦЕЛИКОМ
ЧТЕНИЕ
22
Integration Services (Oracle DB Mat. View -> MSSQL DB Table) – 2 hour
23
СКОРОСТЬ ЧТЕНИЯ. DB VIEW/DB TABLE
DB
Mat. View
DB Table
1 Issue 0.102 sec 0.014 sec
Total 4h 32min 37 min
24
ПЕРВИЧНАЯ ОБРАБОТКА
Preprocess Mapping Initial Objects
25
ФОРМИРОВАНИЕ ФИНАЛЬНЫХ ОБЪЕКТОВ
max(id) Set ID Increment Final Objects
• Первый подход – удаление данных из всех таблиц, вычисляя из
приложения (select + delete)
• Второй подход – создание хранимой процедуры (выигрыш в скорости
~10раз)
26
В ПРОЦЕССЕ РАЗРАБОТКИ ВОЗНИКАЕТ НЕОБХОДИМОСТЬ УДАЛЕНИЯ РАНЕЕ СОЗДАННЫХ ISSUE.
УДАЛЕНИЕ СУЩЕСТВУЮЩИХ ДАННЫХ
27
ПОСТРОЧНАЯ ВСТАВКА
ВСТАВКА
Ready
One IssueInsert Commit
28
COMMIT ЧЕРЕЗ ОПРЕДЕЛЕННОЕ КОЛИЧЕСТВО INSERT
ВСТАВКА
Ready
One Issue
Bulk
Insert
Commit
Every 5k
29
ФОРМИРОВАНИЕ ЗНАЧИТЕЛЬНОГО ПУЛА В ПАМЯТИ
ВСТАВКА
Ready
5k Issue
Bulk
InsertCommit
USE [jira-database]
GO
UPDATE jira.jiraaction
SET AUTHOR = (
SELECT user_key
FROM jira.app_user
WHERE lower_user_name = AUTHOR
)
WHERE EXISTS (
SELECT user_key
FROM jira.app_user
WHERE lower_user_name = AUTHOR
AND user_key <> lower_user_name
)
GO
30
ПЕРЕИМЕНОВАННЫЕ ПОЛЬЗОВАТЕЛИ
ПОСТМИГРАЦИОННЫЕ ДЕЙСТВИЯ
USE [jira-database]
GO
DECLARE @MAX_ISSUE_NUM_EXM DECIMAL;
SET @MAX_ISSUE_NUM_EXM = (
SELECT max(issuenum)
FROM jira.jiraissue
WHERE project = 13000
)
UPDATE jira.project
SET pcounter = @MAX_ISSUE_NUM_EXM
WHERE id = 13000
GO
31
СЧЕТЧИКИ ISSUE В ПРОЕКТАХ
ПОСТМИГРАЦИОННЫЕ ДЕЙСТВИЯ
USE [jira-database]
GO
DECLARE @NEW_CHANGEITEM DECIMAL, @NEW_CHANGEGROUP DECIMAL, @NEW_ISSUE DECIMAL, @NEW_OSWF DECIMAL, @NEW_OSCS DECIMAL, @NEW_JIRAACTION DECIMAL, @NEW_CFV DECIMAL, @NEW_FA DECIMAL, @NEW_RL DECIMAL, @NEW_IL DECIMAL, @NEW_LA DECIMAL
SET @NEW_LA = (select (floor((MAX(id) + 99) / 100) * 100) from jira.label)
SET @NEW_IL = (select (floor((MAX(id) + 99) / 100) * 100) from jira.issuelink)
SET @NEW_RL = (select (floor((MAX(id) + 99) / 100) * 100) from jira.remotelink)
SET @NEW_FA = (select (floor((MAX(id) + 99) / 100) * 100) from jira.fileattachment)
SET @NEW_CFV = (select (floor((MAX(id) + 99) / 100) * 100) from jira.customfieldvalue)
SET @NEW_JIRAACTION = (select (floor((MAX(id) + 99) / 100) * 100) from jira.jiraaction)
SET @NEW_OSCS = (select (floor((MAX(id) + 99) / 100) * 100) from jira.OS_CURRENTSTEP)
SET @NEW_OSWF = (select (floor((MAX(id) + 99) / 100) * 100) from jira.OS_WFENTRY)
SET @NEW_ISSUE = (select (floor((MAX(id) + 99) / 100) * 100) from jira.jiraissue)
SET @NEW_CHANGEITEM = (select (floor((MAX(id) + 99) / 100) * 100) from jira.changeitem)
SET @NEW_CHANGEGROUP = (select (floor((MAX(id) + 99) / 100) * 100) from jira.changegroup)
UPDATE jira.SEQUENCE_VALUE_ITEM set SEQ_ID = @NEW_LA where SEQ_NAME = 'Label'
UPDATE jira.SEQUENCE_VALUE_ITEM set SEQ_ID = @NEW_IL where SEQ_NAME = 'IssueLink'
UPDATE jira.SEQUENCE_VALUE_ITEM set SEQ_ID = @NEW_RL where SEQ_NAME = 'RemoteIssueLink'
UPDATE jira.SEQUENCE_VALUE_ITEM set SEQ_ID = @NEW_FA where SEQ_NAME = 'FileAttachment'
UPDATE jira.SEQUENCE_VALUE_ITEM set SEQ_ID = @NEW_CFV where SEQ_NAME = 'CustomFieldValue'
UPDATE jira.SEQUENCE_VALUE_ITEM set SEQ_ID = @NEW_OSCS where SEQ_NAME = 'OSCurrentStep'
UPDATE jira.SEQUENCE_VALUE_ITEM set SEQ_ID = @NEW_JIRAACTION where SEQ_NAME = 'Action'
UPDATE jira.SEQUENCE_VALUE_ITEM set SEQ_ID = @NEW_OSWF where SEQ_NAME = 'OSWorkflowEntry'
UPDATE jira.SEQUENCE_VALUE_ITEM set SEQ_ID = @NEW_ISSUE where SEQ_NAME = 'Issue'
UPDATE jira.SEQUENCE_VALUE_ITEM set SEQ_ID = @NEW_CHANGEGROUP where SEQ_NAME = 'ChangeGroup'
UPDATE jira.SEQUENCE_VALUE_ITEM set SEQ_ID = @NEW_CHANGEITEM where SEQ_NAME = 'ChangeItem'
32
SEQUENCE
ПОСТМИГРАЦИОННЫЕ ДЕЙСТВИЯ
• Удаление текущих индексов
[jira@jira-app ~]$ find /home/jira/jira-data/caches/indexes -type f –delete
• Старт Jira
[jira@jira-app ~]$ /home/jira/jira-server/bin/start-jira.sh
• Reindex
33
JIRA INDEXES
ПОСТМИГРАЦИОННЫЕ ДЕЙСТВИЯ
• Hard Code
• Перенос с Dev площадки
• Опечатки
34
ПРОБЛЕМЫПРОБЛЕМЫ. ОШИБКИ
• Reindex (после миграции) – потеря 9 часов (Agile - Lexorank)
35
ПРОБЛЕМЫПРОБЛЕМЫ. ОШИБКИ
New issueCalculate
LEXORANK
select * from
AO_60DB71_LEXORANK
ORDER BY RANK DESC
Add record
CREATE NONCLUSTERED INDEX
[index_ao_60db71_lexorank_rank] ON [jira].[AO_60DB71_LEXORANK]
([RANK] ASC)
DROP & CREATE WITH RANK DESC
36
РЕЗУЛЬТАТЫДВА ПОДХОДА. СРАВНЕНИЕ СКОРОСТИ
Подход с DB Время Скорость
• Один этап
• Полный перенос
• В рамках одного maintenance
window
30 часов5 – 78 issue
per/sec
Подход с REST API + DB Время Скорость
• Реализация в 2 этапа
• Неполный перенос
• Ежедневные даунтаймы для
переноса истории18-20 дней
0.28 - 0.32 issue
per/sec
ТО САМОЕ ЧУВСТВО,КОГДА ВСЕ СДЕЛАЛ…
… НА 19 ДНЕЙ РАНЬШЕ!
37
© 2015 ПЕТЕР-СЕРВИС
Все права защищены
Спасибо за внимание
Георгий Белоусов
Email: [email protected]
ВОПРОСЫ?