9 min read

Jira Version Upgrade 8.x to 9.x (req. MySQL 8.0)

이 글은 Atlassian Jira LTS 버전 기준 및 Docker 기반으로 진행하며 Atlassian Docs를 참고하여 작성하였습니다.

Jira 업그레이드 전 점검사항

Jira 9.x 버전으로 업그레이드 하기 위해서는 Atlassian Docs에서 지원 플랫폼을 확인할 수 있습니다.

주요 사항을 보자면
Jira 8.x 버전에서 사용 가능했던 MySQL 5.7 버전이 더 이상 지원되지 않고 MySQL 8.0 버전으로 업그레이드를 해야합니다.

기존 MySQL 5.7 버전에서 MySQL 8 버전으로 업그레이드 하는 과정도 설명하겠습니다.

docker-compose.ymal

본 가이드에서 사용될 파일입니다.

version: '3'
services:
  jira:
    image: atlassian/jira-software:8.20.18
    container_name: jira
    depends_on:
      - jira-db
    ports:
      - "8080:8080"
    volumes:
      - /var/atlassian/application-data/jira:/var/atlassian/application-data/jira

  jira-db:
    image: mysql:5.7
    container_name: jira-db
    volumes:
      - /root/jira-db:/var/lib/mysql
      # 테스트를 위해 신규 DB 설정
      #- /root/jira-db-config:/etc/mysql/conf.d
    environment:
      MYSQL_ROOT_PASSWORD: "admin"

신규 Jira 및 DB(MySQL 5.7)를 사용하여 테스트 하기 위한 가이드

신규로 Jira 컨테이너를 MySQL5.7 버전과 연결할 때 아래 사진과 같이 오류가 발생할 수 있습니다.

이렇게

이를 방지하고자 아래 파일들의 설정을 적용합니다. (신규 설치 기준)

[mysqld]
default-storage-engine=INNODB
innodb_default_row_format=DYNAMIC
innodb_large_prefix=ON
innodb_file_format=Barracuda
innodb_log_file_size=2G
sql_mode = NO_AUTO_VALUE_ON_ZERO

/root/jira-db-config/mysql-jira.cnf

<?xml version="1.0" encoding="UTF-8"?>
<jira-database-config>
  <name>defaultDS</name>
  <delegator-name>default</delegator-name>
  <database-type>mysql</database-type>
  <jdbc-datasource>
    <url>jdbc:mysql://dbserver:3306/jiradb?useUnicode=true&amp;amp;characterEncoding=UTF8&amp;amp;sessionVariables=default_storage_engine=InnoDB</url>
    <driver-class>com.mysql.jdbc.Driver</driver-class>
    <username>jiradbuser</username>
    <password>password</password>
    <pool-min-size>20</pool-min-size>
    <pool-max-size>20</pool-max-size>
    <pool-max-wait>30000</pool-max-wait>
    <pool-max-idle>20</pool-max-idle>
    <pool-remove-abandoned>true</pool-remove-abandoned>
    <pool-remove-abandoned-timeout>300</pool-remove-abandoned-timeout>
    
    <validation-query>select 1</validation-query>
    <validation-query-timeout>3</validation-query-timeout>
    <min-evictable-idle-time-millis>60000</min-evictable-idle-time-millis>
    <time-between-eviction-runs-millis>300000</time-between-eviction-runs-millis>
  
    <pool-test-while-idle>true</pool-test-while-idle>
    <pool-test-on-borrow>false</pool-test-on-borrow>    
  </jdbc-datasource>
</jira-database-config>

/var/atlassian/application-data/jira/dbconfig.xml

Jira 8.20.18 - MySQL 5.7 / utf8_bin 으로 테스트하기 적합한 환경이 구성됨

MySQL Connector

본 가이드에서는 아래 MySQL Connector를 사용합니다.

Jira 종료

DB를 업그레이드 해야함으로 Jira를 종료합니다.

docker-compose down

MySQL Version Upgrade(5.7 -> 8.0)

MySQL 버전 업그레이드는 Docker를 사용하기 때문에 이미지 태그만 바꿔주면 문제없이 8버전으로 업그레이드가 가능합니다.

docker-compose.yaml 수정

버전 태그만 변경하여 docker-compose restart 합니다.

version: '3'
services:
  jira:
    image: atlassian/jira-software:8.20.18
    container_name: jira
    depends_on:
      - jira-db
    ports:
      - "8080:8080"
    volumes:
      - /var/atlassian/application-data/jira:/var/atlassian/application-data/jira

  jira-db:
    image: mysql:8.0
    container_name: jira-db
    volumes:
      - /root/jira-db:/var/lib/mysql
      # 테스트를 위해 신규 DB 설정
      #- /root/jira-db-config:/etc/mysql/conf.d
    environment:
      MYSQL_ROOT_PASSWORD: "admin"

character set 및 collation 값 변경

Jira 9.x 버전대로 업그레이드 하면서 UTF8MB4를 필수적으로 사용해야합니다.
기존 사용하던 UTF8은 호환되지 않습니다.

안된다고 징징대는 모습

MySQL에서 쿼리문을 통해 기존 설정된 값을 확인합니다.

use <DB-NAME>;

# DB 캐릭터 셋 및 콜레이션 확인
SELECT @@character_set_database, @@collation_database;

# 테이블 콜레이션 확인
SELECT TABLE_SCHEMA
    , TABLE_NAME
    , TABLE_COLLATION 
FROM INFORMATION_SCHEMA.TABLES;	

# 컬럼 콜레이션 확인
SELECT TABLE_NAME 
    , COLUMN_NAME 
    , COLLATION_NAME 
FROM INFORMATION_SCHEMA.COLUMNS;
기존 utf8 및 utf8_bin으로 설정하였다면 위와 같이 나타나 집니다.

이제 Character Set 및 Collate 값을 utf8mb4로 변경해줍시다.

아래 명령어는 MySQL 내부에서 직접 쿼리문을 날려 데이터베이스의 Character Set 및 Collate 값을 변경합니다.

ALTER DATABASE <DB-NAME> CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;

<DB-NAME>에 Jira Database 명을 입력합니다.

쿼리문 실행이 완료되었다면 아래 파일들을 생성합니다.

  • table-change.sql
    특정 데이터베이스 내의 테이블을 utf8mb4와 utf8mb4_bin 로 변환하는 ALTER TABLE 문 입니다.
SELECT CONCAT('ALTER TABLE `',  table_name, '` CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;')
FROM information_schema.TABLES AS T, information_schema.`COLLATION_CHARACTER_SET_APPLICABILITY` AS C
WHERE C.collation_name = T.table_collation
AND T.table_schema = '<DB-NAME>'
AND
(
    C.CHARACTER_SET_NAME != 'utf8mb4'
    OR
    C.COLLATION_NAME != 'utf8mb4_bin'
);

<DB-NAME>에 Jira Database 명을 입력합니다.

  • column-change.sql
    특정 데이터베이스 내의 VARCHAR 데이터 형식의 열에 대해 utf8mb4와 utf8mb4_bin 로 변환하는 ALTER TABLE 문 입니다.
SELECT CONCAT('ALTER TABLE `', table_name, '` MODIFY `', column_name, '` ', DATA_TYPE, '(', CHARACTER_MAXIMUM_LENGTH, ') CHARACTER SET utf8mb4 COLLATE utf8mb4_bin', (CASE WHEN IS_NULLABLE = 'NO' THEN ' NOT NULL' ELSE '' END), ';')
FROM information_schema.COLUMNS 
WHERE TABLE_SCHEMA = '<DB-NAME>'
AND DATA_TYPE = 'varchar'
AND
(
    CHARACTER_SET_NAME != 'utf8mb4'
    OR
    COLLATION_NAME != 'utf8mb4_bin'
);

<DB-NAME>에 Jira Database 명을 입력합니다.

  • non-varchar.sql
    특정 데이터베이스 내의 VARCHAR 이외의 데이터 형식 열에 대해 utf8mb4와 utf8mb4_bin 로 변환하는 ALTER TABLE 문 입니다.
SELECT CONCAT('ALTER TABLE `', table_name, '` MODIFY `', column_name, '` ', DATA_TYPE, ' CHARACTER SET utf8mb4 COLLATE utf8mb4_bin', (CASE WHEN IS_NULLABLE = 'NO' THEN ' NOT NULL' ELSE '' END), ';')
FROM information_schema.COLUMNS 
WHERE TABLE_SCHEMA = '<DB-NAME>'
AND DATA_TYPE != 'varchar'
AND
(
    CHARACTER_SET_NAME != 'utf8mb4'
    OR
    COLLATION_NAME != 'utf8mb4_bin'
);

<DB-NAME>에 Jira Database 명을 입력합니다.

파일 생성이 완료되었다면 Linux 쉘의 mysql명령어로 sql 파일을 실행하여 Character Set 및 Collate 값을 변경합니다.

mysql -u <DB-GRANT-USER> -p <DB-NAME> < table-change.sql
mysql -u <DB-GRANT-USER> -p <DB-NAME> < column-change.sql
mysql -u <DB-GRANT-USER> -p <DB-NAME> < non-varchar.sql

만일 에러가 난다면

mysql> ALTER TABLE AO_1FA2A8_SCRUM_POKER_SESSION CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
ERROR 3780 (HY000): Referencing column 'SESSION_ID' and referenced column 'ISSUE_KEY' in foreign key constraint 'fk_ao_1fa2a8_scrum_poker_vote_session_id' are incompatible.
mysql> ALTER TABLE AO_1FA2A8_SCRUM_POKER_VOTE CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
ERROR 3780 (HY000): Referencing column 'SESSION_ID' and referenced column 'ISSUE_KEY' in foreign key constraint 'fk_ao_1fa2a8_scrum_poker_vote_session_id' are incompatible.

와 같이 외래 키 값에 대한 오류가 발생한다면 .sql 파일 내부에 아래 내용을 삽입 후 다시 sql 파일을 실행합니다.

SET FOREIGN_KEY_CHECKS=0;
-- 여기에 쿼리문을 넣고 위아래가 이처럼 동일해야합니다
SET FOREIGN_KEY_CHECKS=1;

Jira Version Upgrade(8.20.18 -> 9.4.14 / LTS)

MySQL 버전 업그레이드 이후 Jira 시작 전 MySQL 업그레이드 사항을 적용해야합니다.
기존 Jira에 설정 되어있던 DB 버전 정보를 변경합니다.

dbconfig.xml 수정

여기서 변경할 부분은 <database-type> 및 <driver-class> 입니다.

mysql57 -> mysql8
com.mysql.jdbc.Driver
-> com.mysql.cj.jdbc.Driver

JDBC Connector 다운로드

JDBC 커넥터는 여기에서 다운로드 할 수 있습니다.
(본 가이드에서는 8.0.33 버전의 JDBC 커넥터를 사용합니다.)

docker-compose.yaml 파일 수정

Jira 이미지 태그를 변경하여 9.4.14 버전으로 시작합니다.

version: '3'
services:
  jira:
    image: atlassian/jira-software:9.4.14
    container_name: jira
    depends_on:
      - jira-db
    ports:
      - "8080:8080"
    volumes:
      - /var/atlassian/application-data/jira:/var/atlassian/application-data/jira

  jira-db:
    image: mysql:8.0
    container_name: jira-db
    volumes:
      - /root/jira-db:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: "admin"

Jira 시작

업그레이드를 위해서 docker-compose.yaml 파일을 수정하여 재기동 합니다.

docker-compose up -d

JDBC Connector 복사

docker cp 명령어로 다운로드 받은 JDBC 커넥터를 Jira Engine 디렉토리에 넣고 재기동 시켜줍니다.

docker cp mysql-connector-java-8.0.22.jar <container-id>:/opt/atlassian/jira/lib/
docker restart <container-id>
#업그레이드 #성공적

추가로

Jira 8.x 버전에서 9.x 버전으로 업그레이드 시 Index 버전이 변경됨에 따라 Index Rebuild(FULL)를 수행해야합니다.

Jira Issue가 상당히 많을 경우 Index Rebuild 시간을 최소화 하기 위한 솔루션은 아래 게시글을 참고하시면 됩니다.

Upgrading from 8.x to 9.x Indexing(indexesV2) solution
먼저 Jira 8.x버전에서 9.x버전으로 업그레이드 되며 가장 큰 문제가 발생합니다. 인덱싱 방식이 변경되며 cache 디렉토리 안의 indexesV1대신 indexesV2를 사용하게 됩니다. Jira 9.x버전에서 indexesV1에 들어가있는 인덱싱 정보는 완전히 소실되고 업그레이드 시 인덱싱을 하지 않으면 검색기능이 불가능합니다. 9.x버전으로 업그레이드하고난 후 Full re-index를 해야하며 그 시간동안은 검색 기능을 전혀