⚠️ Users should stick to 0.20.x releases. The 0.21.x releases are a set a development/feature releases that won't be supported on the public mailing list. Use with caution if you must, or stay away from it!
Installation and Upgrade Notes
- New feature release Git changelog.
- Addresses issues/features in Release-0.21.0
In addition to new feature/issues addresses in milestone Release-0.21.0, this release also contains lots of database optimizations:
- Reduce number of queries when creating invoices
- Insert invoice item and audits in batch.
- Switch to bulk insert for history entries
- Optimize Batch inserts codepath (@GetGeneratedKeys to avoid extra queries)
There is a also a workaround for issue #1095 and along with the workaround there is new WARN log enabled to have a chance to better understand what is happening.
Behavior Changes
There is also a port from 0.20.7 to address #1110, which modifies the catalog version logic when doing a change of plan. See release notes for 0.20.7.
DB Changes
There is a lot of new tables introduced in the context of #1076:
kpm migrations killbill killbill-0.20.7 killbill-0.21.0
DROP TABLE IF EXISTS subscription_event_history;
CREATE TABLE subscription_event_history (
record_id serial unique,
id varchar(36) NOT NULL,
target_record_id bigint /*! unsigned */ not null,
event_type varchar(15) NOT NULL,
user_type varchar(25) DEFAULT NULL,
effective_date datetime NOT NULL,
subscription_id varchar(36) NOT NULL,
plan_name varchar(255) DEFAULT NULL,
phase_name varchar(255) DEFAULT NULL,
price_list_name varchar(64) DEFAULT NULL,
billing_cycle_day_local int DEFAULT NULL,
is_active boolean default true,
change_type varchar(6) NOT NULL,
created_by varchar(50) NOT NULL,
created_date datetime NOT NULL,
updated_by varchar(50) NOT NULL,
updated_date datetime NOT NULL,
account_record_id bigint /*! unsigned */ not null,
tenant_record_id bigint /*! unsigned */ not null default 0,
PRIMARY KEY(record_id)
) /*! CHARACTER SET utf8 COLLATE utf8_bin */;
CREATE INDEX subscription_event_history_target_record_id ON subscription_event_history(target_record_id);
CREATE INDEX subscription_event_history_tenant_record_id ON subscription_event_history(tenant_record_id);
DROP TABLE IF EXISTS subscription_history;
CREATE TABLE subscription_history (
record_id serial unique,
id varchar(36) NOT NULL,
target_record_id bigint /*! unsigned */ not null,
bundle_id varchar(36) NOT NULL,
category varchar(32) NOT NULL,
start_date datetime NOT NULL,
bundle_start_date datetime NOT NULL,
charged_through_date datetime DEFAULT NULL,
migrated bool NOT NULL default FALSE,
change_type varchar(6) NOT NULL,
created_by varchar(50) NOT NULL,
created_date datetime NOT NULL,
updated_by varchar(50) NOT NULL,
updated_date datetime NOT NULL,
account_record_id bigint /*! unsigned */ not null,
tenant_record_id bigint /*! unsigned */ not null default 0,
PRIMARY KEY(record_id)
) /*! CHARACTER SET utf8 COLLATE utf8_bin */;
CREATE INDEX subscription_history_target_record_id ON subscription_history(target_record_id);
CREATE INDEX subscription_history_tenant_record_id ON subscription_history(tenant_record_id);
DROP TABLE IF EXISTS bundle_history;
CREATE TABLE bundle_history (
record_id serial unique,
id varchar(36) NOT NULL,
target_record_id bigint /*! unsigned */ not null,
external_key varchar(255) NOT NULL,
account_id varchar(36) NOT NULL,
last_sys_update_date datetime,
original_created_date datetime NOT NULL,
change_type varchar(6) NOT NULL,
created_by varchar(50) NOT NULL,
created_date datetime NOT NULL,
updated_by varchar(50) NOT NULL,
updated_date datetime NOT NULL,
account_record_id bigint /*! unsigned */ not null,
tenant_record_id bigint /*! unsigned */ not null default 0,
PRIMARY KEY(record_id)
) /*! CHARACTER SET utf8 COLLATE utf8_bin */;
CREATE INDEX bundle_history_target_record_id ON bundle_history(target_record_id);
CREATE INDEX bundle_history_tenant_record_id ON bundle_history(tenant_record_id);
DROP TABLE IF EXISTS blocking_state_history;
CREATE TABLE blocking_state_history (
record_id serial unique,
id varchar(36) NOT NULL,
target_record_id bigint /*! unsigned */ not null,
blockable_id varchar(36) NOT NULL,
type varchar(20) NOT NULL,
state varchar(50) NOT NULL,
service varchar(20) NOT NULL,
block_change bool NOT NULL,
block_entitlement bool NOT NULL,
block_billing bool NOT NULL,
effective_date datetime NOT NULL,
is_active boolean default true,
change_type varchar(6) NOT NULL,
created_date datetime NOT NULL,
created_by varchar(50) NOT NULL,
updated_date datetime DEFAULT NULL,
updated_by varchar(50) DEFAULT NULL,
account_record_id bigint /*! unsigned */ not null,
tenant_record_id bigint /*! unsigned */ not null default 0,
PRIMARY KEY(record_id)
) /*! CHARACTER SET utf8 COLLATE utf8_bin */;
CREATE INDEX blocking_state_history_target_record_id ON blocking_state_history(target_record_id);
CREATE INDEX blocking_state_history_tenant_record_id ON blocking_state_history(tenant_record_id);
DROP TABLE IF EXISTS invoice_tracking_id_history;
CREATE TABLE invoice_tracking_id_history (
record_id serial unique,
id varchar(36) NOT NULL,
target_record_id bigint /*! unsigned */ not null,
tracking_id varchar(128) NOT NULL,
invoice_id varchar(36) NOT NULL,
subscription_id varchar(36),
unit_type varchar(255) NOT NULL,
record_date date NOT NULL,
is_active boolean default true,
change_type varchar(6) NOT NULL,
created_by varchar(50) NOT NULL,
created_date datetime NOT NULL,
updated_by varchar(50) NOT NULL,
updated_date datetime NOT NULL,
account_record_id bigint /*! unsigned */ not null,
tenant_record_id bigint /*! unsigned */ not null default 0,
PRIMARY KEY(record_id)
) /*! CHARACTER SET utf8 COLLATE utf8_bin */;
CREATE INDEX invoice_tracking_id_history_target_record_id ON invoice_tracking_id_history(target_record_id);
CREATE INDEX invoice_tracking_id_history_tenant_record_id ON invoice_tracking_id_history(tenant_record_id);
DROP TABLE IF EXISTS invoice_item_history;
CREATE TABLE invoice_item_history (
record_id serial unique,
id varchar(36) NOT NULL,
target_record_id bigint /*! unsigned */ not null,
type varchar(24) NOT NULL,
invoice_id varchar(36) NOT NULL,
account_id varchar(36) NOT NULL,
child_account_id varchar(36),
bundle_id varchar(36),
subscription_id varchar(36),
description varchar(255),
product_name varchar(255),
plan_name varchar(255),
phase_name varchar(255),
usage_name varchar(255),
start_date date,
end_date date,
amount numeric(15,9) NOT NULL,
rate numeric(15,9) NULL,
currency varchar(3) NOT NULL,
linked_item_id varchar(36),
quantity int,
item_details text,
change_type varchar(6) NOT NULL,
created_by varchar(50) NOT NULL,
created_date datetime NOT NULL,
account_record_id bigint /*! unsigned */ not null,
tenant_record_id bigint /*! unsigned */ not null default 0,
PRIMARY KEY(record_id)
) /*! CHARACTER SET utf8 COLLATE utf8_bin */;
CREATE INDEX invoice_item_history_target_record_id ON invoice_item_history(target_record_id);
CREATE INDEX invoice_item_history_tenant_record_id ON invoice_item_history(tenant_record_id);
DROP TABLE IF EXISTS invoice_history;
CREATE TABLE invoice_history (
record_id serial unique,
id varchar(36) NOT NULL,
target_record_id bigint /*! unsigned */ not null,
account_id varchar(36) NOT NULL,
invoice_date date NOT NULL,
target_date date,
currency varchar(3) NOT NULL,
status varchar(15) NOT NULL DEFAULT 'COMMITTED',
migrated bool NOT NULL,
parent_invoice bool NOT NULL DEFAULT FALSE,
change_type varchar(6) NOT NULL,
created_by varchar(50) NOT NULL,
created_date datetime NOT NULL,
account_record_id bigint /*! unsigned */ not null,
tenant_record_id bigint /*! unsigned */ not null default 0,
PRIMARY KEY(record_id)
) /*! CHARACTER SET utf8 COLLATE utf8_bin */;
CREATE INDEX invoice_history_target_record_id ON invoice_history(target_record_id);
CREATE INDEX invoice_history_tenant_record_id ON invoice_history(tenant_record_id);
DROP TABLE IF EXISTS invoice_payment_history;
CREATE TABLE invoice_payment_history (
record_id serial unique,
id varchar(36) NOT NULL,
target_record_id bigint /*! unsigned */ not null,
type varchar(24) NOT NULL,
invoice_id varchar(36) NOT NULL,
payment_id varchar(36),
payment_date datetime NOT NULL,
amount numeric(15,9) NOT NULL,
currency varchar(3) NOT NULL,
processed_currency varchar(3) NOT NULL,
payment_cookie_id varchar(255) DEFAULT NULL,
linked_invoice_payment_id varchar(36) DEFAULT NULL,
success bool DEFAULT true,
change_type varchar(6) NOT NULL,
created_by varchar(50) NOT NULL,
created_date datetime NOT NULL,
account_record_id bigint /*! unsigned */ not null,
tenant_record_id bigint /*! unsigned */ not null default 0,
PRIMARY KEY(record_id)
) /*! CHARACTER SET utf8 COLLATE utf8_bin */;
CREATE INDEX invoice_payment_history_target_record_id ON invoice_payment_history(target_record_id);
CREATE INDEX invoice_payment_history_tenant_record_id ON invoice_payment_history(tenant_record_id);