fix: inline primary keys in liquibase changelog for MySQL GIPK support - #1508
Open
fudianchn wants to merge 2 commits into
Open
fix: inline primary keys in liquibase changelog for MySQL GIPK support#1508fudianchn wants to merge 2 commits into
fudianchn wants to merge 2 commits into
Conversation
MySQL 8.0.30+ with sql_generate_invisible_primary_key=ON (the default on Azure MySQL Flexible Server, and not disable-able via SQL there) auto-generates an invisible primary key for any InnoDB table created without an explicit primary key. The liquibase changelog created each table without an inline PK and then added the PK via a separate <addPrimaryKey> change, so the second statement failed with "Multiple primary key defined" (1068) and the whole changeset aborted. Move the composite primary keys into the <createTable> definitions (mark the PK columns with primaryKey="true") and drop the now-redundant <addPrimaryKey> changes. The resulting schema is identical for databases without GIPK; on GIPK-enabled databases the PK is declared up front, so MySQL no longer injects an invisible one. Verified end-to-end against MySQL 8.0 with GIPK enabled: - before: `liquibase update` aborts with "Multiple primary key defined [Failed SQL: (1068) ALTER TABLE QRTZ_LOCKS ADD PRIMARY KEY ...]" (only QRTZ_LOCKS is created before the failure) - after: all 11 tables created with the intended composite PKs and no generated my_row_id invisible column. Note: this modifies the existing monolithic `quartz-init` changeset, so its checksum changes. Databases that already ran the previous version will report a checksum mismatch on the next `liquibase update` and need `liquibase clearCheckSums`; see the PR for alternatives (<validCheckSum> / splitting the changeset). Fixes quartz-scheduler#1489 Signed-off-by: 付典 <fudianchn@gmail.com>
melloware
approved these changes
Aug 8, 2026
Add a JDK XML-parser based test that asserts liquibase.quartz.init.xml declares every primary key inline in <createTable> and contains no standalone <addPrimaryKey>. A separate <addPrimaryKey> is exactly what collides with the invisible primary key MySQL 8.0.30+ auto-generates under sql_generate_invisible_primary_key=ON (issue quartz-scheduler#1489), so this locks the inline-PK structure in as a regression guard. Uses only the JDK XML parser, so it introduces no new dependencies. It fails against the pre-fix changelog (11 <addPrimaryKey> changes) and passes against the inlined version. Signed-off-by: 付典 <fudianchn@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
AI disclosure: this change was prepared with AI coding agents, reviewed and revised line by line by me.
What
Inline the composite primary keys into the
<createTable>definitions inliquibase.quartz.init.xml(and drop the now-redundant<addPrimaryKey>changes), so the changelog runs successfully on MySQL 8.0.30+ withsql_generate_invisible_primary_key=ON.Why
MySQL 8.0.30+ can generate an invisible primary key (
my_row_id) for any InnoDB table created without an explicit PK whensql_generate_invisible_primary_key=ON. This setting is on by default and cannot be disabled via SQL on Azure MySQL Flexible Server. With GIPK on, the current changelog fails on the first table:Each table is created without an inline PK (so MySQL injects the invisible one), then the separate
<addPrimaryKey>tries to add another PK →Multiple primary key defined(1068), aborting the whole changeset. Closes #1489.Root cause
<createTable>with no PK → GIPK auto-creates an invisible PK → the subsequent<addPrimaryKey>collides with it (error 1068).How
For each of the 11 tables, mark the primary-key columns with
<constraints nullable="false" primaryKey="true"/>inside<createTable>and remove the separate<addPrimaryKey>change. Liquibase then emits a single compositePRIMARY KEY (...)inside theCREATE TABLE, so MySQL sees the explicit PK at creation time and GIPK does not fire. The PK columns are the leading columns of every table (original order preserved), so the resulting schema is identical for non-GIPK databases.Testing
End-to-end against MySQL 8.0 (Docker,
sql_generate_invisible_primary_key=ON) vialiquibase update(Liquibase 4.29.2):Before (
main): the changeset aborts with exactly the reported error — onlyQRTZ_LOCKSis created before the failure:After (this PR): all 11 tables are created with the intended composite PKs and no generated invisible column, e.g.:
liquibase updateSQLconfirms the SQL change:mainemits 11ALTER TABLE ... ADD PRIMARY KEYstatements; this PR emits 0 (PKs are inline inCREATE TABLE).Note on existing installations (would appreciate the maintainer's call)
This modifies the existing monolithic
quartz-initchangeset, so its Liquibase checksum changes. Databases that already ran the previous version (necessarily non-GIPK ones, since it cannot run under GIPK) will report a checksum mismatch on the nextliquibase update. Options:liquibase clearCheckSumsfor upgraders (what this PR currently assumes).<validCheckSum>9:f3cf9344fdd4a3f171a42f112ce3d5f0</validCheckSum>for the prior checksum (computed with Liquibase 4.29.2) so existing runs validate — note checksums are Liquibase-version-specific.I went with the inline-PK change as the minimal, schema-identical fix and left the changeset id unchanged. Happy to add
<validCheckSum>or restructure the changeset if a different approach is preferred.Fixes #1489