Skip to content

Commit

Permalink
Unify check attempt data type to uint32 already used somewhere
Browse files Browse the repository at this point in the history
A float isn't necessary as in Icinga 2 Checkable#max_check_attempts and
check_attempt are ints. But uint8 isn't enough for e.g. 1 check/s to get
HARD after 5m (300s > 255).
  • Loading branch information
Al2Klimov committed Apr 3, 2024
1 parent 2c46830 commit 204ef91
Show file tree
Hide file tree
Showing 12 changed files with 68 additions and 17 deletions.
8 changes: 4 additions & 4 deletions cmd/icingadb-migrate/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -724,8 +724,8 @@ type stateRow = struct {
StateTimeUsec uint32
State uint8
StateType uint8
CurrentCheckAttempt uint16
MaxCheckAttempts uint16
CurrentCheckAttempt uint32
MaxCheckAttempts uint32
LastState uint8
LastHardState uint8
Output sql.NullString
Expand Down Expand Up @@ -798,10 +798,10 @@ func convertStateRows(
HardState: row.LastHardState,
PreviousSoftState: row.LastState,
PreviousHardState: previousHardState,
CheckAttempt: uint8(row.CurrentCheckAttempt),
CheckAttempt: row.CurrentCheckAttempt,
Output: icingadbTypes.String{NullString: row.Output},
LongOutput: icingadbTypes.String{NullString: row.LongOutput},
MaxCheckAttempts: uint32(row.MaxCheckAttempts),
MaxCheckAttempts: row.MaxCheckAttempts,
CheckSource: icingadbTypes.String{NullString: row.CheckSource},
})

Expand Down
29 changes: 29 additions & 0 deletions doc/04-Upgrading.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,35 @@
Specific version upgrades are described below. Please note that version upgrades are incremental.
If you are upgrading across multiple versions, make sure to follow the steps for each of them.

## Upgrading to Icinga DB v1.1.2

Please apply the `1.1.2.sql` upgrade script to your database.
For package installations, you can find this file at `/usr/share/icingadb/schema/mysql/upgrades/` or
`/usr/share/icingadb/schema/pgsql/upgrades/`, depending on your database type.

As the daemon checks the schema version, the recommended way to perform the upgrade is to stop the daemon, apply the
schema upgrade and then start the new daemon version. If you want to minimize downtime as much as possible, it is safe
to apply this schema upgrade while the Icinga DB v1.1.1 daemon is still running and then restart the daemon with the
new version. Please keep in mind that depending on the distribution, your package manager may automatically attempt to
restart the daemon when upgrading the package.

### Upgrading the state_history Table (optional)

Icinga DB crashes if hosts/services reach check attempt 256. The `check_attempt` column of the `state_history` table
is too small to fit values greater 255. ([#655](https://github.com/Icinga/icingadb/issues/655))
Databases created with the v1.1.2 schema are not affected, but upgraded ones are.

The schema upgrade required to fix this isn't included in `1.1.2.sql` as it re-writes the whole `state_history` table.
This can take a lot of time depending on the history size and the performance of the database.
During this time that table will be locked exclusively and can't be accessed otherwise.
This means that the existing history can't be viewed in Icinga Web and new history entries will be buffered in Redis.

That optional table re-write is performed by the upgrade script `optional/1.1.2-history.sql`.
It should be applied during the next longer maintenance window after `1.1.2.sql`.
Do not interrupt it! At best use tmux/screen not to lose your SSH session.
Until this upgrade you'll have to lower `max_check_attempts`. Optionally increase the respective `retry_interval`
not to change the timespan from an outage to a hard state (`max_check_attempts * retry_interval`).

## Upgrading to Icinga DB v1.1.1

Please apply the `1.1.1.sql` upgrade script to your database.
Expand Down
4 changes: 2 additions & 2 deletions pkg/icingadb/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ func NewDb(db *sqlx.DB, logger *logging.Logger, options *Options) *DB {
}

const (
expectedMysqlSchemaVersion = 4
expectedPostgresSchemaVersion = 2
expectedMysqlSchemaVersion = 5
expectedPostgresSchemaVersion = 3
)

// CheckSchema asserts the database schema of the expected version being present.
Expand Down
2 changes: 1 addition & 1 deletion pkg/icingadb/v1/checkable.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type Checkable struct {
IconImageAlt string `json:"icon_image_alt"`
IconImageId types.Binary `json:"icon_image_id"`
IsVolatile types.Bool `json:"is_volatile"`
MaxCheckAttempts float64 `json:"max_check_attempts"`
MaxCheckAttempts uint32 `json:"max_check_attempts"`
Notes string `json:"notes"`
NotesUrlId types.Binary `json:"notes_url_id"`
NotificationsEnabled types.Bool `json:"notifications_enabled"`
Expand Down
2 changes: 1 addition & 1 deletion pkg/icingadb/v1/history/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type StateHistory struct {
HardState uint8 `json:"hard_state"`
PreviousSoftState uint8 `json:"previous_soft_state"`
PreviousHardState uint8 `json:"previous_hard_state"`
CheckAttempt uint8 `json:"check_attempt"`
CheckAttempt uint32 `json:"check_attempt"`
Output types.String `json:"output"`
LongOutput types.String `json:"long_output"`
MaxCheckAttempts uint32 `json:"max_check_attempts"`
Expand Down
2 changes: 1 addition & 1 deletion pkg/icingadb/v1/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ type State struct {
EnvironmentMeta `json:",inline"`
AcknowledgementCommentId types.Binary `json:"acknowledgement_comment_id"`
LastCommentId types.Binary `json:"last_comment_id"`
CheckAttempt uint8 `json:"check_attempt"`
CheckAttempt uint32 `json:"check_attempt"`
CheckCommandline types.String `json:"check_commandline"`
CheckSource types.String `json:"check_source"`
SchedulingSource types.String `json:"scheduling_source"`
Expand Down
8 changes: 4 additions & 4 deletions schema/mysql/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ CREATE TABLE host_state (
hard_state tinyint unsigned NOT NULL,
previous_soft_state tinyint unsigned NOT NULL,
previous_hard_state tinyint unsigned NOT NULL,
check_attempt tinyint unsigned NOT NULL,
check_attempt int unsigned NOT NULL,
severity smallint unsigned NOT NULL,

output longtext DEFAULT NULL,
Expand Down Expand Up @@ -460,7 +460,7 @@ CREATE TABLE service_state (
hard_state tinyint unsigned NOT NULL,
previous_soft_state tinyint unsigned NOT NULL,
previous_hard_state tinyint unsigned NOT NULL,
check_attempt tinyint unsigned NOT NULL,
check_attempt int unsigned NOT NULL,
severity smallint unsigned NOT NULL,

output longtext DEFAULT NULL,
Expand Down Expand Up @@ -1147,7 +1147,7 @@ CREATE TABLE state_history (
hard_state tinyint unsigned NOT NULL,
previous_soft_state tinyint unsigned NOT NULL,
previous_hard_state tinyint unsigned NOT NULL,
check_attempt tinyint unsigned NOT NULL,
check_attempt int unsigned NOT NULL, -- may be a tinyint unsigned, see https://icinga.com/docs/icinga-db/latest/doc/04-Upgrading/#upgrading-to-icinga-db-v112
output longtext DEFAULT NULL,
long_output longtext DEFAULT NULL,
max_check_attempts int unsigned NOT NULL,
Expand Down Expand Up @@ -1343,4 +1343,4 @@ CREATE TABLE icingadb_schema (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin ROW_FORMAT=DYNAMIC;

INSERT INTO icingadb_schema (version, timestamp)
VALUES (4, UNIX_TIMESTAMP() * 1000);
VALUES (5, UNIX_TIMESTAMP() * 1000);
9 changes: 9 additions & 0 deletions schema/mysql/upgrades/1.1.2.sql
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
ALTER TABLE host_state MODIFY COLUMN check_attempt int unsigned NOT NULL;

ALTER TABLE service_state MODIFY COLUMN check_attempt int unsigned NOT NULL;

ALTER TABLE state_history MODIFY COLUMN check_attempt tinyint unsigned NOT NULL COMMENT 'optional schema upgrade not applied yet, see https://icinga.com/docs/icinga-db/latest/doc/04-Upgrading/#upgrading-to-icinga-db-v112';

UPDATE icingadb_schema SET timestamp = UNIX_TIMESTAMP(timestamp / 1000) * 1000 WHERE timestamp > 20000000000000000;

INSERT INTO icingadb_schema (version, timestamp)
VALUES (5, UNIX_TIMESTAMP() * 1000);
1 change: 1 addition & 0 deletions schema/mysql/upgrades/optional/1.1.2-history.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE state_history MODIFY COLUMN check_attempt int unsigned NOT NULL;
8 changes: 4 additions & 4 deletions schema/pgsql/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ CREATE TABLE host_state (
hard_state tinyuint NOT NULL,
previous_soft_state tinyuint NOT NULL,
previous_hard_state tinyuint NOT NULL,
check_attempt tinyuint NOT NULL,
check_attempt uint NOT NULL,
severity smalluint NOT NULL,

output text DEFAULT NULL,
Expand Down Expand Up @@ -675,7 +675,7 @@ CREATE TABLE service_state (
hard_state tinyuint NOT NULL,
previous_soft_state tinyuint NOT NULL,
previous_hard_state tinyuint NOT NULL,
check_attempt tinyuint NOT NULL,
check_attempt uint NOT NULL,
severity smalluint NOT NULL,

output text DEFAULT NULL,
Expand Down Expand Up @@ -1846,7 +1846,7 @@ CREATE TABLE state_history (
hard_state tinyuint NOT NULL,
previous_soft_state tinyuint NOT NULL,
previous_hard_state tinyuint NOT NULL,
check_attempt tinyuint NOT NULL,
check_attempt uint NOT NULL, -- may be a tinyuint, see https://icinga.com/docs/icinga-db/latest/doc/04-Upgrading/#upgrading-to-icinga-db-v112
output text DEFAULT NULL,
long_output text DEFAULT NULL,
max_check_attempts uint NOT NULL,
Expand Down Expand Up @@ -2181,4 +2181,4 @@ CREATE TABLE icingadb_schema (
ALTER SEQUENCE icingadb_schema_id_seq OWNED BY icingadb_schema.id;

INSERT INTO icingadb_schema (version, timestamp)
VALUES (2, extract(epoch from now()) * 1000);
VALUES (3, extract(epoch from now()) * 1000);
9 changes: 9 additions & 0 deletions schema/pgsql/upgrades/1.1.2.sql
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,12 @@ BEGIN
RETURN (100 * (total_time - problem_time)::decimal / total_time)::decimal(7, 4);
END;
$$;

ALTER TABLE host_state ALTER COLUMN check_attempt TYPE uint;

ALTER TABLE service_state ALTER COLUMN check_attempt TYPE uint;

COMMENT ON COLUMN state_history.check_attempt IS 'optional schema upgrade not applied yet, see https://icinga.com/docs/icinga-db/latest/doc/04-Upgrading/#upgrading-to-icinga-db-v112';

INSERT INTO icingadb_schema (version, timestamp)
VALUES (3, extract(epoch from now()) * 1000);
3 changes: 3 additions & 0 deletions schema/pgsql/upgrades/optional/1.1.2-history.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ALTER TABLE state_history ALTER COLUMN check_attempt TYPE uint;

COMMENT ON COLUMN state_history.check_attempt IS NULL;

0 comments on commit 204ef91

Please sign in to comment.