NiFi Registry 1.14.0 을 MariaDB 를 메타데이터 저장소로 잡고 처음 기동하면 Flyway 가 V3 단계에서 멈추고 프로세스가 그대로 죽는다.
2021-07-30 12:55:04,674 ERROR [main] o.f.core.internal.command.DbMigrate Migration of schema `registry` to version 3 - AddExtensions failed! Please restore backups and roll back database and code!
...
Migration V3__AddExtensions.sql failed
--------------------------------------
SQL State : 42000
Error Code : 1059
Message : (conn=300) Identifier name 'UNIQUE__BUNDLE_VERSION_DEPENDENCY_BUNDLE_ID_GROUP_ARTIFACT_VERSION' is too long
Spring 쪽에서는 flywayInitializer 빈 생성 실패가 위로 전파되면서 databaseMetadataService → registryService → standardServiceFacade → accessPolicyResource 순으로 UnsatisfiedDependencyException 이 줄줄이 찍힌다. 실제 원인은 스택 맨 아래 Flyway 예외 하나뿐이므로 위쪽 빈 이름은 읽을 필요가 없다.
MariaDB 와 MySQL 은 데이터베이스 · 테이블 · 컬럼 · 인덱스 · 제약 이름을 최대 64자로 제한한다.[1][2] 오류에 찍힌 UNIQUE__BUNDLE_VERSION_DEPENDENCY_BUNDLE_ID_GROUP_ARTIFACT_VERSION 은 66자라 두 글자가 넘는다. 오류 코드 1059 · SQLSTATE 42000 이 바로 그 제한을 넘겼다는 신호다.
DDL 이 트랜잭션으로 묶이지 않으므로 이 문장 앞에서 만들어진 테이블은 이미 남아 있다. 뒤에서 다루는 스키마 정리가 필요한 이유다.
Registry 는 Flyway 마이그레이션 스크립트를 DB 별로 나눠 싣는다. db/migration/common 공통 위에 mysql · postgres · default 세 벌이 있고, 그중 default 는 내장 H2 를 겨냥한 것이다. 어느 벌을 쓸지는 기동 시점에 CustomFlywayConfiguration 이 Flyway 의 DB 타입 판정 결과를 보고 정한다.
1.14.0 의 판정 코드는 두 가지만 분기한다.
switch (databaseType) {
case MYSQL:
configuration.locations(LOCATIONS_MYSQL);
break;
case POSTGRESQL:
configuration.locations(LOCATIONS_POSTGRES);
break;
default:
configuration.locations(LOCATIONS_DEFAULT);
break;
}
그런데 이 버전이 싣는 Flyway 6.5.7 의 DatabaseType 열거형에는 MARIADB 가 MYSQL 과 별개 값으로 들어 있다.[3] jdbc:mariadb:// URL 이거나 제품 이름이 MariaDB 로 시작하면 MARIADB 로 판정되고, 위 switch 는 그 값을 받아 줄 case 가 없어 default 로 떨어진다. 결과적으로 MariaDB 에 H2 용 스크립트가 걸린다.
두 스크립트의 문제 지점을 나란히 놓으면 차이가 분명하다.
-- db/migration/default/V3__AddExtensions.sql (H2 용, 이름 66자)
CONSTRAINT UNIQUE__BUNDLE_VERSION_DEPENDENCY_BUNDLE_ID_GROUP_ARTIFACT_VERSION UNIQUE (BUNDLE_VERSION_ID, GROUP_ID, ARTIFACT_ID, VERSION)
-- db/migration/mysql/V3__AddExtensions.sql (이름 47자)
CONSTRAINT UNIQUE__BUNDLE_VERSION_DEPENDENCY_BUNDLE_ID_GAV UNIQUE (BUNDLE_VERSION_ID, GROUP_ID, ARTIFACT_ID, VERSION)
MySQL 용 스크립트는 같은 제약 이름을 ..._GAV 로 이미 줄여 두었다. 길이 제한에 걸리지 않는 벌이 배포본 안에 함께 들어 있는데 그것이 선택되지 않는 것, 그게 이 오류의 전부다.[4]
이 문제는 Apache JIRA 에 NIFI-9950 — NiFi Registry selecting incorrect DB scripts for MariaDB 로 등록돼 있고 Resolved / Fixed 상태다. fix version 은 1.16.1 과 1.17.0 이다.[5] 고친 코드는 판정 결과가 MySQLDatabaseType 이든 MariaDBDatabaseType 이든 모두 MySQL 스크립트를 쓰도록 조건을 넓힌 것이다.
if (databaseType instanceof MySQLDatabaseType || databaseType instanceof MariaDBDatabaseType) {
configuration.locations(LOCATIONS_MYSQL);
}
가장 확실한 길이다. Registry 관리자 가이드가 지원 대상으로 적어 둔 것은 H2 · PostgreSQL(10.x–13.x) · MySQL(8.0) 셋뿐이고 MariaDB 는 목록에 없다.[6] 버그를 피해 가더라도 MariaDB 는 애초에 검증 대상이 아니므로, 운영에 쓸 저장소라면 PostgreSQL 로 잡는 편이 낫다.
# nifi-registry.properties
nifi.registry.db.url=jdbc:postgresql://<PG_HOST>:5432/nifireg
nifi.registry.db.driver.class=org.postgresql.Driver
nifi.registry.db.driver.directory=/home/osc/registry/lib
nifi.registry.db.username=nifireg
nifi.registry.db.password=${DB_PASSWORD}
nifi.registry.db.maxConnections=10
드라이버 JAR 은 nifi.registry.db.driver.directory 에 둔다. 스키마와 계정은 미리 만들어 두고, 소유 권한을 주면 Flyway 가 첫 기동에 나머지를 만든다.
CREATE DATABASE nifireg;
CREATE USER nifireg WITH PASSWORD '<PASSWORD>';
GRANT ALL PRIVILEGES ON DATABASE nifireg TO nifireg;
외부 DB 를 둘 이유가 없는 단일 노드라면 주석 처리해 둔 내장 H2 설정을 되살리는 것으로 충분하다.
nifi.registry.db.url=jdbc:h2:./database/nifi-registry-primary;AUTOCOMMIT=OFF;DB_CLOSE_ON_EXIT=FALSE;LOCK_MODE=3;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE
nifi.registry.db.driver.class=org.h2.Driver
nifi.registry.db.driver.directory=
nifi.registry.db.username=nifireg
nifi.registry.db.password=${DB_PASSWORD}
H2 는 Registry 프로세스 안에서 돌기 때문에 Registry 를 이중화할 수 없고, 버킷 · 플로우 이력이 database/ 디렉터리 하나에 들어간다. 백업 대상이 그 디렉터리 하나로 줄어드는 대신 가용성은 프로세스 하나에 묶인다.
MariaDB 를 그대로 써야 한다면 NIFI-9950 이 반영된 1.16.1 이상으로 올린다. 다만 이것은 이 오류 하나를 치우는 조치일 뿐이고, MariaDB 가 지원 목록에 들어가는 것은 아니다.
여기에 더 큰 전제가 하나 있다. NiFi Registry 컴포넌트 자체가 2026년 2월 커뮤니티 투표로 폐기(deprecated) 됐고 3.0 에서 제거된다. 새로 올릴 버전을 고르는 자리라면 1.x 안에서 올리는 것보다 플로우 버전 관리 방식을 어디로 가져갈지 먼저 정하는 편이 낫다.
org.mariadb.jdbc.Driver 를 MySQL Connector/J 로 갈아 끼우고 URL 을 jdbc:mysql:// 로 바꾸면 MySQL 로 판정되지 않을까 싶지만, 그렇게 되지 않는다. Flyway 의 MariaDB 판정은 URL 접두사만 보는 것이 아니라 제품 이름과 버전 문자열까지 본다.
public boolean handlesDatabaseProductNameAndVersion(String databaseProductName, String databaseProductVersion, Connection connection) {
return databaseProductName.startsWith("MariaDB")
// Older versions of the driver report MariaDB as "MySQL"
|| (databaseProductName.contains("MySQL") && databaseProductVersion.contains("MariaDB"))
// Azure Database For MariaDB reports as "MySQL"
|| (databaseProductName.contains("MySQL") && getSelectVersionOutput(connection).contains("MariaDB"));
}
서버가 MariaDB 인 이상 드라이버가 MySQL 이라고 답해도 버전 문자열에 MariaDB 가 들어가므로 결국 MariaDB 로 판정된다. 드라이버 교체는 시간만 쓴다.
배포본 안의 V3__AddExtensions.sql 을 직접 고쳐 제약 이름을 줄이는 방법도 생각할 수 있으나, 스크립트가 WAR 안 JAR 에 들어 있어 재빌드가 필요하고 이후 업그레이드마다 다시 손봐야 한다. 지원 대상 DB 로 옮기거나 버전을 올리는 쪽이 싸다.
Flyway 는 실패한 마이그레이션을 이력 테이블에 success = 0 으로 남기고, 그 상태에서는 다음 기동에서 다시 시도하지 않는다. 설정만 고치고 재기동하면 Detected failed migration to version 3 류로 다시 막힌다. 그 자리에서 재시도하지 말고 스키마를 버리고 다시 만든다.
V3 는 EXTENSION_BUNDLE · BUNDLE_VERSION 을 만든 뒤 BUNDLE_VERSION_DEPENDENCY 에서 넘어졌으므로, 앞선 테이블들은 이미 생성돼 있고 뒤쪽은 없다. 어느 테이블이 어디까지 만들어졌는지 확인해 손으로 맞출 이유는 없다.
먼저 현재 상태를 확인한다. 이력 테이블 이름은 보통 flyway_schema_history 이고, 예전 설치에서 올라온 경우에만 schema_version 이다.
USE registry;
SHOW TABLES;
SELECT installed_rank, version, description, success FROM flyway_schema_history ORDER BY installed_rank;
Registry 가 이 스키마의 유일한 사용자라면 통째로 버리고 다시 만든다. 계정 권한은 스키마를 지우면 같이 날아가므로 다시 준다.
DROP DATABASE registry;
CREATE DATABASE registry DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
GRANT ALL PRIVILEGES ON registry.* TO 'registry'@'%';
FLUSH PRIVILEGES;
작업 전에 덤프를 떠 둔다. 첫 기동에서 실패한 경우라면 버려도 될 내용뿐이지만, 이미 버킷과 플로우를 넣어 쓰던 인스턴스라면 이야기가 다르다.
mysqldump -h <DB_HOST> -u registry -p --databases registry > registry_before_drop.sql
저장소를 PostgreSQL 이나 H2 로 옮기는 경우에는 이전 MariaDB 스키마를 되살릴 이유가 없다. 다만 Registry 는 DB 사이의 데이터 이관 도구를 제공하지 않는다. 이미 운영 중이던 데이터가 있다면 NiFi 쪽에서 프로세스 그룹을 플로우 정의로 내보낸 뒤 새 Registry 에 버킷을 다시 만들어 올리는 경로를 쓴다.
정리가 끝나면 로그에서 판정 결과 한 줄을 확인한다. 의도한 스크립트가 걸렸는지는 이 줄로 판단한다.
grep -E 'Determined database type|Setting migration locations' logs/nifi-registry-app.log
MariaDB 식별자 최대 길이 — "Databases, tables, columns, indexes, constraints, stored routines, triggers, events, views, tablespaces, servers and log file groups have a maximum length of 64 characters." https://mariadb.com/kb/en/identifier-names/ (2026-09-20 확인) ↩︎
MySQL 도 같은 64자 제한이다 (Database · Table · Column · Index · Constraint 모두 64). https://dev.mysql.com/doc/refman/8.4/en/identifier-length.html (2026-09-20 확인) ↩︎
Flyway 6.5.7 org.flywaydb.core.internal.jdbc.DatabaseType 에 MARIADB 와 MYSQL 이 별개 값으로 있다. Registry 1.14/1.15 계열이 이 버전을 싣는다. https://github.com/flyway/flyway/blob/flyway-6.5.7/flyway-core/src/main/java/org/flywaydb/core/internal/jdbc/DatabaseType.java (2026-09-20 확인) ↩︎
스크립트 원본 대조 — mysql 판 https://github.com/apache/nifi-registry/blob/main/nifi-registry-core/nifi-registry-framework/src/main/resources/db/migration/mysql/V3__AddExtensions.sql · default 판 https://github.com/apache/nifi-registry/blob/main/nifi-registry-core/nifi-registry-framework/src/main/resources/db/migration/default/V3__AddExtensions.sql (2026-09-20 확인) ↩︎
NIFI-9950 "NiFi Registry selecting incorrect DB scripts for MariaDB" — Resolved / Fixed, Fix Version 1.16.1 · 1.17.0, 2022-04-22 해결. https://issues.apache.org/jira/browse/NIFI-9950 (2026-09-20 확인) ↩︎
NiFi Registry System Administrator's Guide — "Currently, NiFi Registry supports using H2, Postgres (10.x - 13.x), and MySQL (8.0) for the relational database engine." https://nifi.apache.org/docs/nifi-registry-docs/html/administration-guide.html (2026-09-20 확인) ↩︎