InfoGrab DocsInfoGrab Docs

중요 업그레이드 노트

요약

이 페이지 하단의 추가 업그레이드 노트 를 검토하는 것을 권장합니다. - For AWS customers on OpenSearch, you must modify Mattermost configuration from elasticsearch to opensearch and disable compatibility mode.

Mattermost Server v10.11 확장 지원 릴리즈 지원이 2026년 8월 15일로 수명 주기가 종료될 예정입니다. Mattermost Server v11.7 이상으로 업그레이드하는 것이 권장됩니다.

이 페이지 하단의 추가 업그레이드 노트 를 검토하는 것을 권장합니다.

If you're upgrading from a version earlier than...Then...
v11.8커스텀 프로필 속성(Custom Profile Attributes) 속성 그룹의 이름이 custom_profile_attributes에서 access_control로 변경되며, CPA 필드와 값은 레거시 속성 모델에서 v2 모델로 마이그레이션됩니다. CPA 기능 자체의 동작은 변경되지 않습니다. CPA를 사용하는 플러그인 개발자는 새 그룹 이름으로 다시 등록해야 합니다.
| | PSAv1(레거시) 그룹과 PSAv2 그룹을 구분하기 위해 PropertyGroups 테이블에 새로운 Version 컬럼이 추가되었습니다. 기존 그룹은 버전 1을 기본값으로 사용하여 모든 레거시 호출자에 대한 현재 동작을 그대로 유지합니다. PropertyGroups는 설정 정보에 가까운 작은 테이블이며, ADD COLUMN ... DEFAULT 1 NOT NULL은 PostgreSQL에서 메타데이터 전용 작업입니다 — 테이블 재작성이 발생하지 않으며 PropertyGroups에 대한 AccessExclusiveLock은 밀리초 단위로만 유지됩니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: | | |
|

|                                                    |    -- Pre-upgrade schema changes (Mattermost 11.8).                                                                                                              |

|                                                    |     ALTER TABLE PropertyGroups ADD COLUMN IF NOT EXISTS Version integer DEFAULT 1 NOT NULL;                                                                      |

|                                                    | <code>posts.rootid</code>와 <code>posts.channelid</code>에 대한 PostgreSQL 플래너 통계 목표치를 기본값 100에서 5000으로 높이고, <code>ANALYZE posts (rootid, channelid)</code>로 플래너 통계를 새로 고칩니다. <code>ALTER COLUMN ... SET STATISTICS</code> 문은 메타데이터 전용 작업으로 <code>SHARE UPDATE EXCLUSIVE</code> 잠금만 획득합니다 — 테이블 재작성이 발생하지 않으며 <code>posts</code>에 대한 동시 SELECT, INSERT, UPDATE, DELETE는 차단되지 않습니다. <code>ANALYZE</code> 단계는 더 큰 샘플 크기로 인해 대규모 <code>posts</code> 테이블(1억 건 이상)에서 수 분이 걸릴 수 있지만, 읽기나 쓰기를 차단하지는 않습니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: |

|                                                    | |
|                                                    |    ALTER TABLE posts ALTER COLUMN rootid SET STATISTICS 5000;                                                                                                    |
|                                                    |    ALTER TABLE posts ALTER COLUMN channelid SET STATISTICS 5000;                                                                                                 |
|                                                    |    ANALYZE posts (rootid, channelid);                                                                                                                            |
|                                                    | <code>channel_type</code> 열거형(enum)에 <code>'BO'</code>와 <code>'BP'</code> 두 개의 새 값이 추가되었습니다. <code>ALTER TYPE ... ADD VALUE</code> 문은 <code>channel_type</code> 타입에만 짧은 <code>AccessExclusiveLock</code>을 획득합니다 — 테이블 재작성이 발생하지 않으며 <code>channels</code> 테이블에 행 단위 잠금이 적용되지 않아 작업이 거의 즉시 완료됩니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: |
|                                                    ||
|                                                    |    ALTER TYPE channel_type ADD VALUE IF NOT EXISTS 'BO';                                                                                                         |
|                                                    |    ALTER TYPE channel_type ADD VALUE IF NOT EXISTS 'BP';                                                                                                         |
|                                                    | 동일한 릴리즈 주기의 일환으로 속성/애트리뷰트 시스템(<code>PropertyFields</code>, <code>PropertyGroups</code>, <code>AttributeView</code>)에 네 건의 스키마 마이그레이션이 도입되었습니다. 마이그레이션 000168과 000169는 <code>PropertyFields</code>에 nullable <code>LinkedFieldID varchar(26)</code> 컬럼과 이에 대한 부분 동시 인덱스를 추가하여 필드가 다른 필드를 링크로 참조할 수 있게 합니다. 마이그레이션 000176과 000177은 <code>PropertyFields</code> 행의 권한 컬럼을 업데이트하고, <code>PropertyGroups</code> 항목의 이름을 <code>custom_profile_attributes</code>에서 <code>access_control</code>로 변경하며, <code>AttributeView</code> 구체화 뷰(materialized view)를 사용자 범위 애트리뷰트로만 좁혀서 기존 커스텀 프로필 애트리뷰트 속성 그룹을 더 범용적인 <code>access_control</code> 그룹으로 승격시킵니다.<strong>마이그레이션 000176과 000177은 반드시 함께 배포되어야 합니다.</strong> 영향을 받는 테이블 중 대용량 테이블 목록에 속하는 것은 없습니다 — 속성 시스템 테이블은 규모가 작습니다. 참고: 롤링 업그레이드 기간 동안 그룹 조회 키로 <code>'custom_profile_attributes'</code>를 하드코딩한 구버전 ESR 노드는 CPA 프로필 읽기/쓰기 엔드포인트와 ABAC 정책 관리 관리자 UI에서 일시적인 오류를 겪게 됩니다. 최종 사용자 채널 접근과 멤버십 동기화 워커는 영향을 받지 않습니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: |

|                                                    | |
|                                                    |    -- 000168: Add LinkedFieldID column                                                                                                                           |
|                                                    |    ALTER TABLE PropertyFields ADD COLUMN IF NOT EXISTS LinkedFieldID varchar(26);                                                                                |
|                                                    |    -- 000169: Create partial index on LinkedFieldID                                                                                                              |
|                                                    |    CREATE INDEX CONCURRENTLY idx_propertyfields_linkedfieldid ON PropertyFields(LinkedFieldID) WHERE LinkedFieldID IS NOT NULL AND DeleteAt = 0;                 |
|                                                    |    -- 000176: Migrate CPA to access_control                                                                                                                      |
|                                                    |    UPDATE PropertyFields SET ObjectType = 'user' WHERE GroupID = (SELECT Id FROM PropertyGroups WHERE Name = 'custom_profile_attributes');                       |
|                                                    |    UPDATE PropertyGroups SET Name = 'access_control', Version = 2 WHERE Name = 'custom_profile_attributes';                                                      |
|                                                    |    -- 000177: Refresh AttributeView with user-scoped filter                                                                                                      |
|                                                    |    DROP MATERIALIZED VIEW AttributeView;                                                                                                                         |
|                                                    |    CREATE MATERIALIZED VIEW AttributeView ... WHERE pf.ObjectType = 'user';                                                                                      |
|                                                    | Mattermost v11.8에서는 <code>Recaps</code> 테이블에 새로운 <code>ViewedAt</code> 컬럼과 <code>(UserId, ViewedAt)</code>에 대한 새 인덱스 형태의 스키마 변경이 도입됩니다. 컬럼 추가는 메타데이터 전용 작업이며, 인덱스는 <code>CONCURRENTLY</code>를 사용해 생성되므로 테이블 잠금이 발생하지 않고 테이블에 대한 기존 작업에도 영향을 주지 않습니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: |
|                                                    ||
|                                                    |    -- 000172_add_recaps_viewed_at.up.sql                                                                                                                         |
|                                                    |    ALTER TABLE Recaps ADD COLUMN IF NOT EXISTS ViewedAt BIGINT NOT NULL DEFAULT 0;                                                                               |
|                                                    |    -- 000172_add_recaps_viewed_at.down.sql                                                                                                                       |
|                                                    |    ALTER TABLE Recaps DROP COLUMN IF EXISTS ViewedAt;                                                                                                            |
|                                                    |    -- 000173_create_recaps_user_id_viewed_at_index.up.sql                                                                                                        |
|                                                    |    -- morph:nontransactional                                                                                                                                     |
|                                                    |    CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_recaps_user_id_viewed_at ON Recaps(UserId, ViewedAt);                                                             |
|                                                    |    -- 000173_create_recaps_user_id_viewed_at_index.down.sql                                                                                                      |
|                                                    |    -- morph:nontransactional                                                                                                                                     |
|                                                    |    DROP INDEX CONCURRENTLY IF EXISTS idx_recaps_user_id_viewed_at;                                                                                               |
|                                                    | Mattermost v11.8에서는 새로운 채널 가입 요청 워크플로와 검색 가능한(discoverable) 비공개 채널을 지원하는 여섯 건의 스키마 변경이 도입됩니다. <code>Channels</code> 테이블에 <code>Discoverable</code> 불리언 컬럼(<code>DEFAULT FALSE</code>)이 추가되며, 이는 PostgreSQL 11 이상에서 즉시 완료되는 메타데이터 전용 작업입니다. 접근 요청 워크플로를 관리하기 위한 새로운 <code>ChannelJoinRequests</code> 테이블이 생성되어 요청 상태, 거부 사유, 검토자 정보를 추적합니다. 이어서 네 개의 동시(concurrent) 인덱스가 추가됩니다: 검색 가능한 팀 채널을 위한 <code>Channels</code>의 부분 인덱스(<code>idx_channels_discoverable_team</code>), 대기 중인 요청을 위한 <code>ChannelJoinRequests</code>의 고유 부분 인덱스(<code>idx_channeljoinrequests_pending_unique</code>), 그리고 각각 채널+상태, 사용자+상태 기준 쿼리를 최적화하는 두 개의 복합 인덱스입니다. 모든 인덱스 작업은 <code>CONCURRENTLY</code>를 사용하며 명시적 트랜잭션 블록 밖에서 실행해야 합니다. 이 마이그레이션들은 PostgreSQL 전용입니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: |
|                                                    ||
|                                                    |    -- Migration 000178: Add Discoverable column                                                                                                                  |
|                                                    |    ALTER TABLE Channels ADD COLUMN IF NOT EXISTS Discoverable BOOLEAN NOT NULL DEFAULT FALSE;                                                                    |
|                                                    ||
|                                                    |    -- Migration 000179: Partial index for discoverable channels                                                                                                  |                                                                                               
|                                                    |    -- Run outside a transaction block.                                                                                                                           |
|                                                    |    CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_channels_discoverable_team                                                                                        |
|                                                    |        ON Channels (TeamId)                                                                                                                                      |
|                                                    |        WHERE Discoverable = TRUE AND Type = 'P' AND DeleteAt = 0;                                                                                                |
|                                                    ||
|                                                    |    -- Migration 000180: Create ChannelJoinRequests table                                                                                                         |
|                                                    |    CREATE TABLE IF NOT EXISTS ChannelJoinRequests (                                                                                                              |
|                                                    |        Id           VARCHAR(26)  PRIMARY KEY,                                                                                                                    |
|                                                    |        ChannelId    VARCHAR(26)  NOT NULL,                                                                                                                       |
|                                                    |        UserId       VARCHAR(26)  NOT NULL,                                                                                                                       |
|                                                    |        Message      TEXT         NOT NULL DEFAULT '',                                                                                                            |
|                                                    |        Status       VARCHAR(16)  NOT NULL DEFAULT 'pending',                                                                                                     |
|                                                    |        DenialReason TEXT         NOT NULL DEFAULT '',                                                                                                            |
|                                                    |        CreateAt     BIGINT       NOT NULL,                                                                                                                       |
|                                                    |        UpdateAt     BIGINT       NOT NULL,                                                                                                                       |
|                                                    |        ReviewedBy   VARCHAR(26)  NOT NULL DEFAULT '',                                                                                                            |
|                                                    |        ReviewedAt   BIGINT       NOT NULL DEFAULT 0                                                                                                              |
|                                                    |    );                                                                                                                                                            |
|                                                    ||
|                                                    |    -- Migration 000181: Unique index for pending requests                                                                                                        |
|                                                    |    -- Run outside a transaction block.                                                                                                                           |
|                                                    |    CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS idx_channeljoinrequests_pending_unique                                                                         |
|                                                    |        ON ChannelJoinRequests (ChannelId, UserId)                                                                                                                |
|                                                    |        WHERE Status = 'pending';                                                                                                                                 |
|                                                    ||
|                                                    |    -- Migration 000182: Index for channel+status queries                                                                                                         |
|                                                    |    -- Run outside a transaction block.                                                                                                                           |
|                                                    |    CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_channeljoinrequests_channel_status_createat                                                                       |
|                                                    |        ON ChannelJoinRequests (ChannelId, Status, CreateAt DESC);                                                                                                |
|                                                    ||
|                                                    |    -- Migration 000183: Index for user+status queries                                                                                                            |
|                                                    |    -- Run outside a transaction block.                                                                                                                           |
|                                                    |    CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_channeljoinrequests_user_status_createat                                                                          |
|                                                    |        ON ChannelJoinRequests (UserId, Status, CreateAt DESC);                                                                                                   |
|                                                    | Mattermost v11.8에서는 기존 <code>none</code>, <code>sysadmin</code>, <code>member</code> 값에 더해 <code>admin</code> 값을 포함하도록 <code>permission_level</code> PostgreSQL 열거형(enum) 타입이 확장됩니다. 이는 순수한 카탈로그 변경입니다 <code>— ALTER TYPE ADD VALUE</code>는 <code>pg_type</code> 시스템 카탈로그만 갱신하며 <code>PropertyFields</code> 테이블이나 다른 애플리케이션 테이블은 건드리지 않습니다. up 마이그레이션에서는 컬럼, 인덱스, 테이블 데이터가 전혀 변경되지 않습니다. 이 변경으로 속성 필드 접근 제어 모델에 새로운 관리자 수준 권한 등급이 추가됩니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: |
|                                                    ||
|                                                    |    -- 000189_add_admin_to_permission_level.up.sql                                                                                                                |
|                                                    |    ALTER TYPE permission_level ADD VALUE IF NOT EXISTS 'admin';                                                                                                  |
<table><thead><tr><th>v11.7</th><th>FIPS 빌드는 비밀번호, atmos/camo 프록시 구성 및 공유 채널 시크릿에 최소 14자를 요구합니다. 기존 사용자의 짧은 비밀번호는 더 이상 유효하지 않으며 비밀번호 재설정이 필요합니다. 비 FIPS 빌드는 영향을 받지 않습니다.</th></tr></thead></table>
|                                                    | <code>AccessControlPolicies</code> 테이블에 (Name, Type)에 대한 새로운 부분 고유 인덱스(<code>idx_accesscontrolpolicies_name_type</code>)가 추가되어 <code>WHERE Type = 'parent'</code>로 필터링됩니다. 인덱스 생성 전에 중복 상위 정책 이름은 가장 오래된 항목을 제외하고 모두 정책 ID를 추가하여 해결됩니다. 이는 상위 정책 이름의 고유성을 강화하고 향후 중복 생성을 방지합니다. 마이그레이션은 1초 미만이 소요됩니다. 마이그레이션은 게시물이나 반응이 아닌 <code>AccessControlPolicies</code>를 대상으로 합니다. <code>AttributeBasedAccessControl</code>이 활성화되지 않은 배포에서는 테이블이 비어 있으며 마이그레이션이 1초 미만에 완료됩니다. 플래그가 활성화된 배포에서는 상위 정책 수가 적을 것으로 예상되므로 타이밍은 여전히 무시할 수 있는 수준입니다. <code>CREATE UNIQUE INDEX</code>(비동시)는 <code>AccessControlPolicies</code>에 <code>SHARE</code> 잠금을 획득하여 인덱스 빌드 기간 동안 동시 <code>INSERT/UPDATE/DELETE</code>를 차단합니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는:                                                            |
|                                                    ||
|                                                    |    -- PostgreSQL only (MySQL not supported in v11+):                                                                                                             |
|                                                    |      -- Deduplicate parent policy names before adding unique constraint.                                                                                         |
|                                                    |      -- The oldest policy (by CreateAt) keeps its original name; duplicates get ' (<id>)' appended.                                                              |
|                                                    |      UPDATE AccessControlPolicies AS p                                                                                                                           |
|                                                    |      SET Name = LEFT(p.Name, 128 - LENGTH(' (' || p.ID || ')')) || ' (' || p.ID || ')'                                                                           |
|                                                    |      FROM (                                                                                                                                                      |
|                                                    |          SELECT ID, Name, ROW_NUMBER() OVER (PARTITION BY Name ORDER BY CreateAt ASC) AS rn                                                                      |
|                                                    |          FROM AccessControlPolicies                                                                                                                              |
|                                                    |          WHERE Type = 'parent'                                                                                                                                   |
|                                                    |      ) AS dupes                                                                                                                                                  |
|                                                    |      WHERE p.ID = dupes.ID                                                                                                                                       |
|                                                    |        AND dupes.rn > 1;                                                                                                                                         |
|                                                    |      CREATE UNIQUE INDEX IF NOT EXISTS idx_accesscontrolpolicies_name_type                                                                                       |
|                                                    |        ON AccessControlPolicies (Name, Type)                                                                                                                     |
|                                                    |        WHERE Type = 'parent';                                                                                                                                    |
|                                                    | <code>PropertyFields</code> 테이블이 수정됩니다. 각 필드를 생성하고 마지막으로 수정한 사용자를 추적하는 두 개의 새로운 nullable 열, <code>CreatedBy</code> 및 <code>UpdatedBy</code>가 추가됩니다. 새로운 <code>ObjectType</code> 열이 <code>NOT NULL</code> 제약 조건과 빈 문자열 기본값으로 추가되어 레거시 및 타입이 지정된 속성 필드를 구분합니다. 새로운 <code>Protected</code> boolean 열이 <code>FALSE</code> 기본값으로 추가되고, 세 개의 새 열(<code>PermissionField</code>, <code>PermissionValues</code>, <code>PermissionOptions</code>)이 none, sysadmin, member 값을 가진 새 <code>permission_level</code> enum 타입과 함께 추가됩니다. (GroupID, TargetID, Name)에 대한 기존 고유 인덱스 <code>idx_propertyfields_unique</code>가 삭제되고 두 개의 새로운 부분 고유 인덱스로 교체됩니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는:                                                           |
|                                                    ||
|                                                    |   --- 160                                                                                                                                                        |
|                                                    |   ALTER TABLE PropertyFields                                                                                                                                     |
|                                                    |   ADD COLUMN IF NOT EXISTS CreatedBy varchar(26),                                                                                                                |
|                                                    |   ADD COLUMN IF NOT EXISTS UpdatedBy varchar(26);                                                                                                                |
|                                                    |   ALTER TABLE PropertyValues                                                                                                                                     |
|                                                    |   ADD COLUMN IF NOT EXISTS CreatedBy varchar(26),                                                                                                                |
|                                                    |   ADD COLUMN IF NOT EXISTS UpdatedBy varchar(26);                                                                                                                |
|                                                    |   --- 161                                                                                                                                                        |
|                                                    |   ALTER TABLE PropertyFields ADD COLUMN IF NOT EXISTS ObjectType varchar(255) NOT NULL DEFAULT '';                                                               |
|                                                    |   --- 162                                                                                                                                                        |
|                                                    |   DROP INDEX CONCURRENTLY IF EXISTS idx_propertyfields_unique;                                                                                                   |
|                                                    |   --- 163                                                                                                                                                        |
|                                                    |   CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS idx_propertyfields_unique_legacy                                                                                |
|                                                    |       ON PropertyFields (GroupID, TargetID, Name)                                                                                                                |
|                                                    |       WHERE DeleteAt = 0 AND ObjectType = '';                                                                                                                    |
|                                                    |   --- 164                                                                                                                                                        |
|                                                    |   CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS idx_propertyfields_unique_typed                                                                                 |
|                                                    |       ON PropertyFields (ObjectType, GroupID, TargetType, TargetID, Name)                                                                                        |
|                                                    |       WHERE DeleteAt = 0 AND ObjectType != '';                                                                                                                   |
|                                                    |   --- 165                                                                                                                                                        |
|                                                    |   DO $$                                                                                                                                                          |
|                                                    |   BEGIN                                                                                                                                                          |
|                                                    |     IF NOT EXISTS (SELECT * FROM pg_type typ                                                                                                                     |
|                                                    |                               INNER JOIN pg_namespace nsp ON nsp.oid = typ.typnamespace                                                                          |
|                                                    |                           WHERE nsp.nspname = current_schema()                                                                                                   |
|                                                    |                               AND typ.typname = 'permission_level') THEN                                                                                         |
|                                                    |       CREATE TYPE permission_level AS ENUM ('none', 'sysadmin', 'member');                                                                                       |
|                                                    |     END IF;                                                                                                                                                      |
|                                                    |   END;                                                                                                                                                           |
|                                                    |   $$                                                                                                                                                             |
|                                                    |   LANGUAGE plpgsql;                                                                                                                                              |
|                                                    |   ALTER TABLE PropertyFields                                                                                                                                     |
|                                                    |   ADD COLUMN IF NOT EXISTS Protected BOOLEAN NOT NULL DEFAULT FALSE,                                                                                             |
|                                                    |   ADD COLUMN IF NOT EXISTS PermissionField permission_level,                                                                                                     |
|                                                    |   ADD COLUMN IF NOT EXISTS PermissionValues permission_level,                                                                                                    |
|                                                    |   ADD COLUMN IF NOT EXISTS PermissionOptions permission_level;                                                                                                   |
|                                                    |   --- 166                                                                                                                                                        |
|                                                    |   CREATE TABLE IF NOT EXISTS Views (                                                                                                                             |
|                                                    |       Id          VARCHAR(26)  PRIMARY KEY,                                                                                                                      |
|                                                    |       ChannelId   VARCHAR(26)  NOT NULL,                                                                                                                         |
|                                                    |       Type        VARCHAR(32)  NOT NULL,                                                                                                                         |
|                                                    |       CreatorId   VARCHAR(26)  NOT NULL,                                                                                                                         |
|                                                    |       Title       VARCHAR(256) NOT NULL,                                                                                                                         |
|                                                    |       Description TEXT,                                                                                                                                          |
|                                                    |       SortOrder   INTEGER      NOT NULL DEFAULT 0,                                                                                                               |
|                                                    |       Props       jsonb,                                                                                                                                         |
|                                                    |       CreateAt    BIGINT       NOT NULL,                                                                                                                         |
|                                                    |       UpdateAt    BIGINT       NOT NULL,                                                                                                                         |
|                                                    |       DeleteAt    BIGINT       NOT NULL DEFAULT 0                                                                                                                |
|                                                    |   );                                                                                                                                                             |
|                                                    |   --- 167                                                                                                                                                        |
|                                                    |   CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_views_channel_id_delete_at ON Views(ChannelId, DeleteAt);                                                          |
|                                                    |   --- 171                                                                                                                                                        |
|                                                    |   DROP INDEX CONCURRENTLY IF EXISTS idx_propertyfields_protected;                                                                                                |
|                                                    | <code>role_updated</code> WebSocket 이벤트는 전역 브로드캐스트 대신 영향받는 팀/채널로 범위가 지정되어 성능이 향상되고 불필요한 네트워크 트래픽이 줄어듭니다. 업그레이드 중 마이그레이션이 자동으로 실행되므로 관리자의 수동 조치가 필요하지 않습니다. 다운타임이 예상되지 않으며 마이그레이션은 정상 운영 중에 실행될 수 있으므로 업그레이드를 위한 특별한 계획이 필요하지 않습니다. 모든 설치가 이 변경의 영향을 받지만 <code>roles</code> 테이블은 대규모 설치에서도 10k 행 미만으로 작기 때문에 영향은 최소화됩니다. 업그레이드에는 효율적인 역할-스키마 조회를 위해 <code>roles</code> 테이블에 <code>schemeid</code> 열을 추가하는 자동 데이터베이스 마이그레이션이 포함됩니다. 마이그레이션은 PostgreSQL의 비차단(non-blocking) 기법을 사용합니다. 먼저 짧은 ACCESS EXCLUSIVE 잠금(카탈로그 전용 작업)으로 컬럼을 추가하고, ROW EXCLUSIVE 잠금으로 기존 데이터를 백필한 다음, 다른 작업을 차단하지 않는 SHARE UPDATE EXCLUSIVE 잠금으로 인덱스를 동시에 생성합니다. <code>roles</code> 테이블 크기는 제한적이며 게시물(post), 반응(reaction) 등 대용량 데이터의 영향을 받지 않습니다. 마이그레이션은 완전히 하위 호환됩니다. |
|                                                    | v11.7에는 Agents 플러그인 v2가 포함됩니다. v1.x 릴리즈에서 v2.0.0으로 Mattermost Agents 플러그인을 업그레이드하는 방법에 대해 <code>이 가이드</code>를 참조하세요. 지원되는 버전 경로, v2.0.0 첫 시작 시 자동으로 실행되는 마이그레이션, 업그레이드 창 전에 관리자가 알아야 할 주요 변경 사항 및 기본 동작 변경, 그리고 업그레이드 성공을 확인하는 검증 단계를 다룹니다.                                                                                                                             |
<table><thead><tr><th>v11.6</th><th>단일 채널 게스트는 더 이상 기본 라이선스 시트 수에 포함되지 않으며, 라이선스 시트와 1:1 비율로 무료로 허용됩니다. 새로운 통계 카드, 라이선스 행, 관리자 배너가 추가되어 단일 채널 게스트 사용량 및 초과 경고를 확인할 수 있습니다.</th></tr></thead></table>
|                                                    | v11.6.2부터 <code>role_updated</code> WebSocket 이벤트는 전역 브로드캐스트 대신 영향받는 팀/채널로 범위가 지정되어 성능이 향상되고 불필요한 네트워크 트래픽이 줄어듭니다. 업그레이드 중 마이그레이션이 자동으로 실행되므로 관리자의 수동 조치가 필요하지 않습니다. 다운타임이 예상되지 않으며 마이그레이션은 정상 운영 중에 실행될 수 있으므로 업그레이드를 위한 특별한 계획이 필요하지 않습니다. 모든 설치가 이 변경의 영향을 받지만 <code>roles</code> 테이블은 대규모 설치에서도 10k 행 미만으로 작기 때문에 영향은 최소화됩니다. 업그레이드에는 효율적인 역할-스키마 조회를 위해 <code>roles</code> 테이블에 <code>schemeid</code> 열을 추가하는 자동 데이터베이스 마이그레이션이 포함됩니다. 마이그레이션은 PostgreSQL의 비차단(non-blocking) 기법을 사용합니다. 먼저 짧은 ACCESS EXCLUSIVE 잠금(카탈로그 전용 작업)으로 컬럼을 추가하고, ROW EXCLUSIVE 잠금으로 기존 데이터를 백필한 다음, 다른 작업을 차단하지 않는 SHARE UPDATE EXCLUSIVE 잠금으로 인덱스를 동시에 생성합니다. <code>roles</code> 테이블 크기는 제한적이며 게시물(post), 반응(reaction) 등 대용량 데이터의 영향을 받지 않습니다. 마이그레이션은 완전히 하위 호환됩니다. |
<table><thead><tr><th>v11.5</th><th><code>translations</code> 테이블에 새 컬럼 <code>translations.state</code>와 새 인덱스 <code>idx_translations_state</code>가 추가되었습니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는:ALTER TABLE translations ADD COLUMN IF NOT EXISTS state varchar(20) NOT NULL; CREATE INDEX IF NOT EXISTS idx_translations_state ON translations(state) WHERE state IN ('processing');</th></tr></thead></table>
|                                                    | <code>channelmembers</code> 테이블에 새 컬럼 <code>channelmembers.autotranslationdisabled</code>가 추가되었습니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: |
|                                                    ||
|                                                    |   ALTER TABLE channelmembers                                                                                                                                     | 
|                                                    |       ADD COLUMN IF NOT EXISTS autotranslationdisabled boolean NOT NULL DEFAULT false;                                                                           |
|                                                    | <code>translations</code> 테이블에서 <code>translations.objectType</code> 컬럼을 수정하고 기본 키를 <code>(objectId, dstLang)</code>에서 <code>(objectId, objectType, dstLang)</code>로 변경했습니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: |
|                                                    ||
|                                                    |   UPDATE translations SET objectType = 'post' WHERE objectType IS NULL;                                                                                          |
|                                                    |   ALTER TABLE translations ALTER COLUMN objectType SET NOT NULL;                                                                                                 |
|                                                    |   ALTER TABLE translations DROP CONSTRAINT translations_pkey;                                                                                                    |
|                                                    |   ALTER TABLE translations ADD PRIMARY KEY (objectId, objectType, dstLang);                                                                                      |
|                                                    | <code>translations</code> 테이블에 새 컬럼 <code>translations.channelid</code>가 추가되었습니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: |
|                                                    ||
|                                                    |   ALTER TABLE translations ADD COLUMN IF NOT EXISTS channelid varchar(26);                                                                                       |
|                                                    | <code>translations</code> 테이블에 새 인덱스 <code>idx_translations_channel_updateat</code>가 추가되었습니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: |
|                                                    ||
|                                                    |   -- morph:nontransactional                                                                                                                                      |
|                                                    |   CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_translations_channel_updateat                                                                                      |
|                                                    |       ON translations(channelid, objectType, updateAt DESC, dstlang);                                                                                            |
|                                                    | <code>translations</code> 테이블에서 인덱스 <code>idx_translations_updateat</code>가 삭제되었습니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: |
|                                                    ||
|                                                    |   -- morph:nontransactional                                                                                                                                      |
|                                                    |   DROP INDEX CONCURRENTLY IF EXISTS idx_translations_updateat;                                                                                                   |
|                                                    | v11.5.5부터 <code>role_updated</code> WebSocket 이벤트는 전역 브로드캐스트 대신 영향받는 팀/채널로 범위가 지정되어 성능이 향상되고 불필요한 네트워크 트래픽이 줄어듭니다. 업그레이드 중 마이그레이션이 자동으로 실행되므로 관리자의 수동 조치가 필요하지 않습니다. 다운타임이 예상되지 않으며 마이그레이션은 정상 운영 중에 실행될 수 있으므로 업그레이드를 위한 특별한 계획이 필요하지 않습니다. 모든 설치가 이 변경의 영향을 받지만 <code>roles</code> 테이블은 대규모 설치에서도 10k 행 미만으로 작기 때문에 영향은 최소화됩니다. 업그레이드에는 효율적인 역할-스키마 조회를 위해 <code>roles</code> 테이블에 <code>schemeid</code> 열을 추가하는 자동 데이터베이스 마이그레이션이 포함됩니다. 마이그레이션은 PostgreSQL의 비차단(non-blocking) 기법을 사용합니다. 먼저 짧은 ACCESS EXCLUSIVE 잠금(카탈로그 전용 작업)으로 컬럼을 추가하고, ROW EXCLUSIVE 잠금으로 기존 데이터를 백필한 다음, 다른 작업을 차단하지 않는 SHARE UPDATE EXCLUSIVE 잠금으로 인덱스를 동시에 생성합니다. <code>roles</code> 테이블 크기는 제한적이며 게시물(post), 반응(reaction) 등 대용량 데이터의 영향을 받지 않습니다. 마이그레이션은 완전히 하위 호환됩니다. |
<table><thead><tr><th>v11.4</th><th>Photoshop 문서(PSD) 파일은 더 이상 인라인으로 미리보기되지 않으며 일반 첨부 파일로 처리됩니다.</th></tr></thead></table>
|                                                    | 새 테이블 <code>Recaps</code>와 <code>RecapChannels</code>가 추가되었습니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: |
|                                                    ||
|                                                    |   -- Recaps table: stores recap metadata                                                                                                                         |
|                                                    |   CREATE TABLE IF NOT EXISTS Recaps (                                                                                                                            |
|                                                    |       Id VARCHAR(26) PRIMARY KEY,                                                                                                                                |
|                                                    |       UserId VARCHAR(26) NOT NULL,                                                                                                                               |
|                                                    |       Title VARCHAR(255) NOT NULL,                                                                                                                               |
|                                                    |       CreateAt BIGINT NOT NULL,                                                                                                                                  |
|                                                    |       UpdateAt BIGINT NOT NULL,                                                                                                                                  |
|                                                    |       DeleteAt BIGINT NOT NULL,                                                                                                                                  |
|                                                    |       TotalMessageCount INT NOT NULL,                                                                                                                            |
|                                                    |       Status VARCHAR(32) NOT NULL,                                                                                                                               |
|                                                    |       ReadAt BIGINT DEFAULT 0 NOT NULL,                                                                                                                          |
|                                                    |       BotID VARCHAR(26) DEFAULT '' NOT NULL                                                                                                                      |
|                                                    |   );                                                                                                                                                             |
|                                                    |   CREATE INDEX IF NOT EXISTS idx_recaps_user_id ON Recaps(UserId);                                                                                               |
|                                                    |   CREATE INDEX IF NOT EXISTS idx_recaps_create_at ON Recaps(CreateAt);                                                                                           |
|                                                    |   CREATE INDEX IF NOT EXISTS idx_recaps_user_id_delete_at ON Recaps(UserId, DeleteAt);                                                                           |
|                                                    |   CREATE INDEX IF NOT EXISTS idx_recaps_user_id_read_at ON Recaps(UserId, ReadAt);                                                                               |
|                                                    |   CREATE INDEX IF NOT EXISTS idx_recaps_bot_id ON Recaps(BotID);                                                                                                 |
|                                                    |   -- RecapChannels table: stores per-channel summaries                                                                                                           |
|                                                    |   CREATE TABLE IF NOT EXISTS RecapChannels (                                                                                                                     |
|                                                    |       Id VARCHAR(26) PRIMARY KEY,                                                                                                                                |
|                                                    |       RecapId VARCHAR(26) NOT NULL,                                                                                                                              |
|                                                    |       ChannelId VARCHAR(26) NOT NULL,                                                                                                                            |
|                                                    |       ChannelName VARCHAR(64) NOT NULL,                                                                                                                          |
|                                                    |       Highlights TEXT,                                                                                                                                           |
|                                                    |       ActionItems TEXT,                                                                                                                                          |
|                                                    |       SourcePostIds TEXT,                                                                                                                                        |
|                                                    |       CreateAt BIGINT NOT NULL,                                                                                                                                  |
|                                                    |       FOREIGN KEY (RecapId) REFERENCES Recaps(Id) ON DELETE CASCADE                                                                                              |
|                                                    |   );                                                                                                                                                             |
|                                                    |   CREATE INDEX IF NOT EXISTS idx_recap_channels_recap_id ON RecapChannels(RecapId);                                                                              |
|                                                    |   CREATE INDEX IF NOT EXISTS idx_recap_channels_channel_id ON RecapChannels(ChannelId);                                                                          |
<table><thead><tr><th>v11.3</th><th>v11.3.1부터 Photoshop 문서(PSD) 파일은 더 이상 인라인으로 미리보기되지 않으며 일반 첨부 파일로 처리됩니다.</th></tr></thead></table>
|                                                    | 사용자 속성을 별도 테이블로 집계하는 새 테이블(<code>ReadReceipts</code>, <code>TemporaryPosts</code>) 형태의 스키마 변경이 추가되었습니다. <code>Drafts</code>와 <code>ScheduledPosts</code> 모두에 <code>Type</code> 필드가 추가되었습니다. 이전 버전의 Mattermost도 새 스키마 변경과 함께 실행될 수 있습니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: |
|                                                    ||
|                                                    |   CREATE TABLE IF NOT EXISTS ReadReceipts (                                                                                                                      |
|                                                    |       PostId VARCHAR(26) NOT NULL,                                                                                                                               |
|                                                    |       UserId VARCHAR(26) NOT NULL,                                                                                                                               |
|                                                    |       ExpireAt bigint NOT NULL,                                                                                                                                  |
|                                                    |       PRIMARY KEY (PostId, UserId)                                                                                                                               |
|                                                    |   );                                                                                                                                                             |
|                                                    |   CREATE INDEX IF NOT EXISTS idx_read_receipts_post_id ON ReadReceipts(PostId);                                                                                  |
|                                                    |   CREATE INDEX IF NOT EXISTS idx_read_receipts_user_id_post_id_expire_at ON ReadReceipts(UserId, PostId, ExpireAt);                                              |
|                                                    |   CREATE TABLE IF NOT EXISTS TemporaryPosts (                                                                                                                    |
|                                                    |       PostId VARCHAR(26) PRIMARY KEY,                                                                                                                            |
|                                                    |       Type VARCHAR(26) NOT NULL,                                                                                                                                 |
|                                                    |       ExpireAt BIGINT NOT NULL,                                                                                                                                  |
|                                                    |       Message VARCHAR(65535),                                                                                                                                    |
|                                                    |       FileIds VARCHAR(300)                                                                                                                                       |
|                                                    |   );                                                                                                                                                             |
|                                                    |   CREATE INDEX IF NOT EXISTS idx_temporary_posts_expire_at ON TemporaryPosts(expireat);                                                                          |
|                                                    |   ALTER TABLE drafts ADD COLUMN IF NOT EXISTS Type text;                                                                                                         |
|                                                    |   ALTER TABLE scheduledposts ADD COLUMN IF NOT EXISTS Type text;                                                                                                 |             
|                                                    | 새 테이블 <code>translations</code>, 두 개의 새 컬럼(<code>channels.autotranslation</code>, <code>channelmembers.autotranslation)</code>), 그리고 네 개의 새 인덱스가 추가되었습니다. 마이그레이션은 완전히 하위 호환되며 테이블 재작성이 없습니다. 1초 미만의 다운타임이 필요합니다. 업그레이드 전에 <code>CREATE INDEX CONCURRENTLY</code>를 사용하면 완전한 무중단 업그레이드를 위한 제로 다운타임도 가능합니다. 표준 업그레이드는 모든 인스턴스 크기에서 안전하며, 제로 다운타임이 반드시 필요한 경우가 아니라면 특별한 수동 조치는 필요하지 않습니다. 완전한 제로 다운타임을 위한 SQL 쿼리는: |
|                                                    ||
|                                                    |  CREATE INDEX CONCURRENTLY IF NOT EXISTS                                                                                                                         |
|                                                    |  idx_channelmembers_autotranslation_enabled                                                                                                                      |
|                                                    |     ON channelmembers (channelid)                                                                                                                                |
|                                                    |     WHERE autotranslation = true;                                                                                                                                |
|                                                    |  CREATE INDEX CONCURRENTLY IF NOT EXISTS                                                                                                                         |
|                                                    |  idx_channels_autotranslation_enabled                                                                                                                            |
|                                                    |     ON channels (id)                                                                                                                                             |
|                                                    |     WHERE autotranslation = true;                                                                                                                                |
|                                                    |  CREATE INDEX CONCURRENTLY IF NOT EXISTS                                                                                                                         |
|                                                    |  idx_users_id_locale                                                                                                                                             |
|                                                    |     ON users (id, locale);                                                                                                                                       |
|                                                    | Mattermost v11.3부터 <code>registerRightHandSidebarComponent</code>를 사용해 우측 사이드바(RHS) 컴포넌트를 등록하는 일부 플러그인은, RHS 컴포넌트가 플러그인 전용 상태(state)에 의존하는 경우 RHS 팝아웃을 지원하기 위한 추가 코드를 구현해야 합니다. 자세한 내용은 <a href="https://forum.mattermost.com/t/rhs-popout-support-for-plugins/25626">이 포럼 게시물</a> 을 참조하세요. |
<table><thead><tr><th>v11.2</th><th>v11.2.3부터 Photoshop 문서(PSD) 파일은 더 이상 인라인으로 미리보기되지 않으며 일반 첨부 파일로 처리됩니다.</th></tr></thead></table>
|                                                    | <code>OAuthApps</code> 테이블에 <code>isdynamicallyregistered</code>라는 새 컬럼이 추가되었습니다. 기본값은 <code>false</code>입니다. 또한 <code>OAuthAuthData</code> 테이블에 <code>resource</code>, <code>codechallenge</code>, <code>codechallengemethod</code>라는 세 개의 새 컬럼이 추가되었으며, 모든 컬럼의 기본값은 <code>''</code>입니다. 그리고 <code>OAuthAccessData</code> 테이블에 <code>audience</code>라는 새 컬럼이 추가되었으며 기본값은 <code>''</code>입니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 테이블은 <code>ACCESS EXCLUSIVE LOCK</code>을 사용하지만 메타데이터를 추가/제거하는 용도일 뿐이며 명령은 즉시 반환됩니다. 포함된 SQL 쿼리는: |
|                                                    ||
|                                                    |   ALTER TABLE oauthapps ADD COLUMN IF NOT EXISTS isdynamicallyregistered BOOLEAN DEFAULT FALSE;                                                                  |
|                                                    |   ALTER TABLE oauthauthdata ADD COLUMN IF NOT EXISTS codechallenge varchar(128) DEFAULT '';                                                                      |
|                                                    |   ALTER TABLE oauthauthdata ADD COLUMN IF NOT EXISTS codechallengemethod varchar(10) DEFAULT '';                                                                 |
|                                                    |   ALTER TABLE oauthaccessdata ADD COLUMN IF NOT EXISTS audience varchar(512) DEFAULT '';                                                                         |
|                                                    |   ALTER TABLE oauthauthdata ADD COLUMN IF NOT EXISTS resource varchar(512) DEFAULT '';                                                                           |
<table><thead><tr><th>v11.1</th><th>Mattermost 웹 앱에서 사용하는 React 버전이 React 17에서 React 18로 업데이트되었습니다. 자세한 내용은 <a href="https://forum.mattermost.com/t/upgrading-the-mattermost-web-app-to-react-18-v11/25000">이 포럼 게시물</a> 을 참조하세요.</th></tr></thead></table>
|                                                    | 데이터 스필리지(Data Spillage) 설정을 저장하기 위한 세 개의 새 테이블 <code>ContentFlaggingCommonReviewers</code>, <code>ContentFlaggingTeamSettings</code>, <code>ContentFlaggingTeamReviewers</code>가 추가되었습니다. 팀 설정 조회를 최적화하기 위해 <code>ContentFlaggingTeamReviewers</code> 테이블에 인덱스가 추가되었습니다. 마이그레이션은 완전히 하위 호환됩니다. 이 업그레이드로 인해 테이블 잠금이나 기존 테이블 작업에 영향을 미치지 않습니다. 이 릴리즈로 업그레이드할 때 제로 다운타임이 예상됩니다. 포함된 SQL 쿼리는: |
|                                                    ||
|                                                    |   CREATE TABLE IF NOT EXISTS ContentFlaggingCommonReviewers (                                                                                                    |
|                                                    |       UserId VARCHAR(26) PRIMARY KEY                                                                                                                             |
|                                                    |   );                                                                                                                                                             |
|                                                    |   CREATE TABLE IF NOT EXISTS ContentFlaggingTeamSettings (                                                                                                       |
|                                                    |       TeamId VARCHAR(26) PRIMARY KEY,                                                                                                                            |
|                                                    |       Enabled BOOLEAN                                                                                                                                            |
|                                                    |   );                                                                                                                                                             |
|                                                    |   CREATE TABLE IF NOT EXISTS ContentFlaggingTeamReviewers (                                                                                                      |
|                                                    |       TeamId VARCHAR(26),                                                                                                                                        |
|                                                    |       UserId VARCHAR(26),                                                                                                                                        |
|                                                    |       PRIMARY KEY (TeamId, UserId)                                                                                                                               |
|                                                    |   );                                                                                                                                                             |
|                                                    |   CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_contentflaggingteamreviewers_userid ON ContentFlaggingTeamReviewers (userid);                                      |
<table><thead><tr><th>v11.0</th><th>Team Edition에서 GitLab SSO 지원이 폐기(deprecated)되었습니다. GitLab SSO를 사용하는 배포는 새로운 무료 제품인 Mattermost Entry로 전환하는 동안 v10.11 ESR(12개월 보안 업데이트 제공)에 남아 있거나, 상용/비영리 옵션을 검토할 수 있습니다. 자세한 내용은 <a href="https://forum.mattermost.com/t/mattermost-v11-changes-in-free-offerings/25126">이 포럼 게시물</a> 을 참조하세요.</th></tr></thead></table>
|                                                    | <code>TeamSettings.ExperimentalViewArchivedChannels</code> 설정이 폐기되었습니다. 보관된 채널은 일반 채널 멤버십 조건에 따라 항상 접근할 수 있습니다. 이 설정이 <code>false</code>로 지정되어 있으면 서버가 시작되지 않습니다. 보관된 채널에 대한 접근을 막으려면 해당 채널을 비공개로 표시하고 영향을 받는 채널 멤버를 제거하세요. 자세한 내용은 <a href="https://forum.mattermost.com/t/viewing-accessing-archived-channels-v11/22626">이 포럼 게시물</a> 을 참조하세요. |
|                                                    | Team Edition에서는 Playbooks가 더 이상 작동하지 않습니다. Entry, Professional, Enterprise, Enterprise Advanced 플랜은 다운타임 없이 자동으로 Playbooks v2로 업그레이드됩니다. 자세한 내용은 <a href="https://forum.mattermost.com/t/clarification-and-update-on-the-playbooks-plugin-v11/25192">이 포럼 게시물</a> 을 참조하세요. |
|                                                    | 실험적(Experimental) Bleve Search 기능이 종료되었습니다. Bleve가 활성화되어 있는 경우 <code>DisableDatabaseSearch</code>를 <code>false</code>로 설정하기 전까지는 검색이 작동하지 않습니다. 자세한 내용은 <a href="https://forum.mattermost.com/t/transitioning-from-bleve-search-in-mattermost-v11/22982">이 포럼 게시물</a> 을 참조하세요. |
|                                                    | MySQL 지원이 종료되었습니다. <a href="https://docs.mattermost.com/deployment-guide/postgres-migration.html">마이그레이션 가이드</a> 에서 PostgreSQL로 마이그레이션하는 데 필요한 단계, 도구, 지원 내용을 확인할 수 있습니다. 자세한 내용은 <a href="https://forum.mattermost.com/t/transition-to-postgresql/19551">이 포럼 게시물</a> 을 참조하세요. |
|                                                    | 웹 앱 플러그인 API의 <code>registerPostDropdownMenuComponent</code> 훅이 제거되고 <code>registerPostDropdownMenuAction</code>으로 대체되었습니다. 자세한 내용은 <a href="https://forum.mattermost.com/t/deprecating-a-post-dropdown-menu-component-plugin-api-v11/25001">이 포럼 게시물</a> 을 참조하세요. |
|                                                    | 웹 앱은 더 이상 웹 앱 플러그인이 사용할 수 있도록 <a href="https://styled-components.com/">Styled Components</a> 의존성을 노출하지 않습니다. 자세한 내용은 <a href="https://forum.mattermost.com/t/removing-styled-components-export-for-web-app-plugins-v11/25002">이 포럼 게시물</a> 을 참조하세요. |
|                                                    | Omnibus 지원이 폐기되었습니다. 마지막 <code>mattermost-omnibus</code> 릴리즈는 v10.12였습니다. 자세한 내용은 <a href="https://forum.mattermost.com/t/mattermost-omnibus-to-reach-end-of-life-v11/25175">이 포럼 게시물</a> 을 참조하세요. |
|                                                    | <code>api/v4/ldap/sync</code>의 폐기된 <code>include_removed_members</code> 옵션이 제거되었습니다. 관리자는 LDAP 설정 <code>ReAddRemovedMembers</code>를 사용할 수 있습니다. |
|                                                    | NPS 플러그인을 활성화한 고객은 더 이상 텔레메트리를 통해 피드백을 전송하지 않으므로 해당 플러그인을 제거해도 됩니다. |
|                                                    | <code>/api/v4/config/client</code> 엔드포인트의 format 쿼리 파라미터 요구사항이 폐기되었습니다. |
|                                                    | 폐기된 mmctl 명령과 플래그가 제거되었습니다: |
|                                                    |     - <code>channel add</code> - 대신 <code>channel users add</code>를 사용하세요 |
|                                                    |     - <code>channel remove</code> - 대신 <code>channel users remove</code>를 사용하세요 |
|                                                    |     - <code>channel restore</code> - 대신 <code>channel unarchive</code>를 사용하세요 |
|                                                    |     - <code>channel make-private</code> - 대신 <code>channel modify --private</code>를 사용하세요 |
|                                                    |     - <code>command delete</code> - 대신 <code>command archive</code>를 사용하세요 |
|                                                    |     - <code>permissions show</code> - 대신 <code>permissions role show</code>를 사용하세요 |
|                                                    |     - <code>mmctl user email</code> - 대신 <code>mmctl user edit email</code>을 사용하세요 |
|                                                    |     - <code>mmctl user username</code> - 대신 <code>mmctl user edit username</code>을 사용하세요 |
|                                                    | 실험적 인증서 기반 인증 기능이 제거되었습니다. 서버를 시작하려면 <code>ExperimentalSettings.ClientSideCertEnable</code>이 <code>false</code>여야 합니다. |
|                                                    | 비밀번호 해싱 방식을 bcrypt에서 PBKDF2로 마이그레이션하는 로직이 추가되었습니다. 이 마이그레이션은 점진적으로 진행되며, 사용자가 비밀번호를 입력하는 즉시(예: 로그인 시 또는 민감한 작업을 위해 비밀번호를 재확인할 때) 해당 사용자의 비밀번호가 마이그레이션됩니다. 사용자가 계정에서 잠길 수 있는 예외 상황이 있습니다. 서버가 v11로 업그레이드된 후 사용자 A가 로그인하면(즉, 비밀번호를 입력해야 함), 이후 서버가 v10.12 이전 버전으로 다운그레이드될 경우 사용자 A는 더 이상 로그인할 수 없습니다. 이 경우 관리자는 시스템 콘솔이나 <a href="https://docs.mattermost.com/administration-guide/manage/mmctl-command-line-tool.html#mmctl-user-reset-password">mmctl user reset-password [users]</a> 명령을 통해 해당 사용자의 비밀번호를 수동으로 재설정해야 합니다. 새 비밀번호 해싱 방식은 CPU를 더 많이 사용합니다. 비밀번호 기반 로그인을 사용하는 서버의 관리자는 많은 사용자가 동시에 로그인하는 시간대의 성능을 모니터링해야 합니다. |
|                                                    | <code>/api/v4/teams/{team_id}/channels/search_archived</code>가 폐기되고, deleted 파라미터를 사용하는 <code>/api/v4/channels/search</code>로 대체되었습니다. |
|                                                    | 기본 데이터베이스 연결 풀 설정이 변경되었습니다. <code>MaxOpenConns</code>는 300에서 100으로, <code>MaxIdleConns</code>는 20에서 50으로 변경되어 더 나은 데이터베이스 연결 관리를 위한 2:1 비율을 확립했습니다. |
|                                                    | 별도의 알림 로그 파일이 폐기되었습니다. 관리자가 알림 로그용 별도 로그 파일을 계속 사용하고자 한다면 <code>AdvancedLoggingJSON</code> 설정을 사용할 수 있습니다. 사용할 수 있는 예시 설정은 다음과 같습니다: |
|                                                    ||
|                                                    |   {                                                                                                                                                              |
|                                                    |     "LogSettings": {                                                                                                                                             |
|                                                    |       "AdvancedLoggingJSON": {                                                                                                                                   |
|                                                    |         "notifications_file": {                                                                                                                                  |
|                                                    |           "type": "file",                                                                                                                                        |
|                                                    |           "format": "json",                                                                                                                                      |
|                                                    |           "levels": [                                                                                                                                            |
|                                                    |               {"id": 300, "name": "NotificationError"},                                                                                                          |
|                                                    |               {"id": 301, "name": "NotificationWarn"},                                                                                                           |
|                                                    |               {"id": 302, "name": "NotificationInfo"},                                                                                                           |
|                                                    |               {"id": 303, "name": "NotificationDebug"},                                                                                                          |
|                                                    |               {"id": 304, "name": "NotificationTrace"}                                                                                                           |
|                                                    |           ],                                                                                                                                                     |
|                                                    |           "options": {                                                                                                                                           |
|                                                    |               "filename": "notifications.log",                                                                                                                   |
|                                                    |               "max_size": 100,                                                                                                                                   |
|                                                    |               "max_age": 0,                                                                                                                                      |
|                                                    |               "max_backups": 0,                                                                                                                                  |
|                                                    |               "compress": true                                                                                                                                   |
|                                                    |           },                                                                                                                                                     |
|                                                    |           "maxqueuesize": 1000                                                                                                                                   |
|                                                    |         }                                                                                                                                                        |
|                                                    |       }                                                                                                                                                          |
|                                                    |     }                                                                                                                                                            |
|                                                    |   }                                                                                                                                                              |
|                                                    | https://forum.mattermost.com/t/deprecation-notice-manual-plugin-deployment/21192 에 따라 수동으로 설치된 플러그인 지원이 중단되었습니다. |
|                                                    | PostgreSQL v13 지원이 제거되었습니다. 새로운 최소 PostgreSQL 버전은 v14 이상입니다. 자세한 내용은 <a href="https://docs.mattermost.com/deployment-guide/software-hardware-requirements.html#minimum-postgresql-database-support-policy">PostgreSQL 버전 정책</a> 문서를 참조하세요. |
<table><thead><tr><th>v10.12</th><th>v10.12 릴리즈에는 중요한 업그레이드 노트가 없습니다.</th></tr><tr><th>v10.11</th><th><code>>=10.11.17</code>에서 <code><=11.7.2</code>로 업그레이드하지 마세요. 데이터베이스 마이그레이션 번호 문제를 일으키는 버그가 있습니다. 이 버그는 v11.7.3에서 수정되었습니다.</th></tr></thead></table>
|                                                    | v10.11.11부터 Photoshop 문서(PSD) 파일은 더 이상 인라인으로 미리보기되지 않으며 일반 첨부 파일로 처리됩니다. |
|                                                    | Mattermost v10.11.4에서는 SSO 인증 흐름 보안 강화의 일환으로 새로운 API 엔드포인트 <code>/api/v4/users/login/sso/code-exchange</code>가 도입됩니다. SSO(예: SAML)를 사용하는 고객은 네트워크 설정에서 이 엔드포인트로의 트래픽을 허용하는지 확인해야 합니다. |
|                                                    | v10.11.17부터 <code>role_updated</code> WebSocket 이벤트는 전역 브로드캐스트 대신 영향받는 팀/채널로 범위가 지정되어 성능이 향상되고 불필요한 네트워크 트래픽이 줄어듭니다. 업그레이드 중 마이그레이션이 자동으로 실행되므로 관리자의 수동 조치가 필요하지 않습니다. 다운타임이 예상되지 않으며 마이그레이션은 정상 운영 중에 실행될 수 있으므로 업그레이드를 위한 특별한 계획이 필요하지 않습니다. 모든 설치가 이 변경의 영향을 받지만 <code>roles</code> 테이블은 대규모 설치에서도 10k 행 미만으로 작기 때문에 영향은 최소화됩니다. 업그레이드에는 효율적인 역할-스키마 조회를 위해 <code>roles</code> 테이블에 <code>schemeid</code> 열을 추가하는 자동 데이터베이스 마이그레이션이 포함됩니다. 마이그레이션은 PostgreSQL의 비차단(non-blocking) 기법을 사용합니다. 먼저 짧은 ACCESS EXCLUSIVE 잠금(카탈로그 전용 작업)으로 컬럼을 추가하고, ROW EXCLUSIVE 잠금으로 기존 데이터를 백필한 다음, 다른 작업을 차단하지 않는 SHARE UPDATE EXCLUSIVE 잠금으로 인덱스를 동시에 생성합니다. <code>roles</code> 테이블 크기는 제한적이며 게시물(post), 반응(reaction) 등 대용량 데이터의 영향을 받지 않습니다. 마이그레이션은 완전히 하위 호환됩니다. |
<table><thead><tr><th>v10.10</th><th>Added a new column <code>DefaultCategoryName</code> to the <code>Channels</code> table. This is nullable and stores a category name to be added/created when new users join a channel. This is only used if the <code>ExperimentalChannelCategorySetting</code> is enabled. The migrations are fully backwards-compatible and no table locks or existing operations on the table are impacted by this upgrade. Zero downtime is expected when upgrading to this release. The SQL queries included are: PostgreSQL: https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/postgres/000138_add_default_category_name_to_channel.down.sql and https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/postgres/000138_add_default_category_name_to_channel.up.sql MySQL: https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/mysql/000138_add_default_category_name_to_channel.down.sql and https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/mysql/000138_add_default_category_name_to_channel.up.sql</th></tr></thead></table>
|                                                    | Added new columns <code>RemoteId</code> and <code>ChannelId</code> to the <code>PostAcknowledgements</code> table. This is nullable, and stores the remote ID (if available) and channel ID |
|                                                    | to which the post was made when acknowledgements to posts were set. The migrations are fully backwards-compatible and no table locks or                          |
|                                                    | existing operations on the table are impacted by this upgrade. Zero downtime is expected when upgrading to this release. The SQL queries included are:           |
|                                                    | PostgreSQL:                                                                                                                                                      |
|                                                    | <code>000141_add_remoteid_channelid_to_post_acknowledgements.down.sql</code> and <code>000141_add_remoteid_channelid_to_post_acknowledgements.up.sql</code>                          |
|                                                    | MySQL:                                                                                                                                                           |
|                                                    | https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/mysql/000141_add_remoteid_channelid_to_post_acknowledgements.down.sql  |
|                                                    | and                                                                                                                                                              |
|                                                    | https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/mysql/000141_add_remoteid_channelid_to_post_acknowledgements.up.sql    |
|                                                    | Added a new column <code>LastMembersSyncAt</code> to the <code>SharedChannelRemotes</code> table and added <code>LastMembershipSyncAt</code> to <code>SharedChannelUsers</code>. This is nullable,   |
|                                                    | and stores the <code>LastMembersSyncAt</code> timestamp (if available) which tracks the last time channel membership data was synchronized between the local cluster and  |
|                                                    | each remote cluster. <code>LastMembershipSyncAt</code> timestamp tracks the last time a specific user's channel membership status was synchronized with a specific remote |
|                                                    | cluster. The migrations are fully backwards-compatible and no table locks or existing operations on the table are impacted by this upgrade. Zero downtime is     |
|                                                    | expected when upgrading to this release. The SQL queries included are:                                                                                           |
|                                                    | PostgreSQL:                                                                                                                                                      |
|                                                    | https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/postgres/000140_add_lastmemberssyncat_to_sharedchannelremotes.down.sql |
|                                                    | and                                                                                                                                                              |
|                                                    | https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/postgres/000140_add_lastmemberssyncat_to_sharedchannelremotes.up.sql   |
|                                                    | MySQL:                                                                                                                                                           |
|                                                    | https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/mysql/000140_add_lastmemberssyncat_to_sharedchannelremotes.down.sql    |
|                                                    | and https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/mysql/000140_add_lastmemberssyncat_to_sharedchannelremotes.up.sql  |
|                                                    | Added a new column <code>LastGlobalUserSyncAt</code> to the <code>RemoteClusters</code> table. This is nullable, and <code>LastGlobalUserSyncAt</code> tracks the timestamp of the last     |
|                                                    | successful global user sync for each remote cluster, enabling incremental syncing. The migrations are fully backwards-compatible and no table locks or existing  |
|                                                    | operations on the table are impacted by this upgrade. Zero downtime is expected when upgrading to this release. The SQL queries included are:                    |
|                                                    | PostgreSQL:                                                                                                                                                      |
|                                                    | https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/postgres/000139_remoteclusters_add_last_global_user_sync_at.down.sql   |
|                                                    | and                                                                                                                                                              |
|                                                    | https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/postgres/000139_remoteclusters_add_last_global_user_sync_at.up.sql     |
|                                                    | MySQL:                                                                                                                                                           |
|                                                    | https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/mysql/000139_remoteclusters_add_last_global_user_sync_at.down.sql and  |
|                                                    | https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/mysql/000139_remoteclusters_add_last_global_user_sync_at.up.sql        |
<table><thead><tr><th>v10.9</th><th>A new index to the <code>CategoryId</code> column in <code>SidebarChannels</code> table was added to improve query performance. No database downtime is expected for this upgrade. For PostgreSQL, it takes around 2s to add the index on a table with 1.2M rows with an instance size of 8 cores and 16GB RAM. For MySQL, it takes around 5s on a table with 300K rows on an instance size of 8 cores and 16GB RAM. The migrations are fully backwards-compatible and no table locks or existing operations on the table are impacted by this upgrade. Zero downtime is expected when upgrading to this release. The SQL queries included are:<strong>PostgreSQL</strong>: CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_sidebarchannels_categoryid ON sidebarchannels(categoryid);<strong>MySQL</strong>: CREATE INDEX idx_sidebarchannels_categoryid ON SidebarChannels(CategoryId);</th></tr></thead></table>
|                                                    | Schema changes in the form of a new materialized view (<code>AttributeView</code>) was added that aggregates user attributes into a separate table. No database downtime  |
|                                                    | is expected for this upgrade. A previous version of Mattermost can run with the new schema changes. The SQL queries included in the schema changes are below:    |
|                                                    | PostgreSQL: https://github.com/mattermost/mattermost/blob/release-10.9/server/channels/db/migrations/postgres/000137_update_attribute_view.up.sql                |
|                                                    | MySQL: https://github.com/mattermost/mattermost/blob/release-10.9/server/channels/db/migrations/mysql/000136_create_attribute_view.up.sql                        |
|                                                    | The objective of showing the SQL queries is not to reduce downtime, but to let the Admin make the schema changes without requiring to upgrade Mattermost.        |
|                                                    | Then when they actually upgrade Mattermost, it becomes instantaneous since the changes are already made.                                                         |
|                                                    | When <code>SamlSettings.EnableSyncWithLdap</code> is enabled, Mattermost will now check if a user exists on the connected LDAP server during login. If the user doesn't   |
|                                                    | exist on the LDAP server, login will fail. Previously, users not present on the LDAP server could login, but would be deactivated on the next LDAP sync.         |
<table><thead><tr><th>v10.8</th><th>New tables <code>AccessControlPolicies</code> and <code>AccessControlPolicyHistory</code> will be created. The migration is fully backwards-compatible, non-locking, and zero downtime is expected.</th></tr></thead></table>
|                                                    | Support for legacy SKUs E10 and E20 licenses was removed. If you need assistance, <a href="https://mattermost.com/contact-sales/">talk to a Mattermost expert</a>.       |
<table><thead><tr><th>v10.7</th><th>Added new column <code>BannerInfo</code> in the <code>Channels</code> table for storing metadata for an upcoming licensed feature. The migration is fully backwards-compatible, non-locking, and zero downtime is possible. Below are the SQL queries included in the schema changes:<strong>PostgreSQL</strong>: ALTER TABLE channels ADD COLUMN IF NOT EXISTS bannerinfo jsonb;<strong>MySQL</strong>: SET @preparedStatement = (SELECT IF( NOT EXISTS( SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'Channels' AND table_schema = DATABASE() AND column_name = 'BannerInfo' ), 'ALTER TABLE Channels ADD COLUMN BannerInfo json;', 'SELECT 1;' )); PREPARE addColumnIfNotExists FROM @preparedStatement; EXECUTE addColumnIfNotExists; DEALLOCATE PREPARE addColumnIfNotExists;</th></tr></thead></table>
|                                                    | Added support for cursor-based pagination on the property architecture tables, including SQL migration to create indices. The migration is fully                 |
|                                                    | backwards-compatible, non-locking, and zero downtime is possible. Below are the SQL queries included in the schema changes:                                      |
|                                                    | MySQL:                                                                                                                                                           |
|                                                    ||
|                                                    |  SET @preparedStatement = (SELECT IF(                                                                                                                            |
|                                                    |      (                                                                                                                                                           |
|                                                    |          SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS                                                                                                      |
|                                                    |          WHERE table_name = 'PropertyValues'                                                                                                                     |
|                                                    |          AND table_schema = DATABASE()                                                                                                                           |
|                                                    |          AND index_name = 'idx_propertyvalues_create_at_id'                                                                                                      |
|                                                    |      ) > 0,                                                                                                                                                      |
|                                                    |      'SELECT 1',                                                                                                                                                 |
|                                                    |      'CREATE INDEX idx_propertyvalues_create_at_id ON PropertyValues(CreateAt, ID);'                                                                             |
|                                                    |  ));                                                                                                                                                             |
|                                                    |  PREPARE createIndexIfNotExists FROM @preparedStatement;                                                                                                         |
|                                                    |  EXECUTE createIndexIfNotExists;                                                                                                                                 |
|                                                    |  DEALLOCATE PREPARE createIndexIfNotExists;                                                                                                                      |
|                                                    ||
|                                                    |  SET @preparedStatement = (SELECT IF(                                                                                                                            |
|                                                    |      (                                                                                                                                                           | 
|                                                    |          SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS                                                                                                      |
|                                                    |          WHERE table_name = 'PropertyFields'                                                                                                                     |
|                                                    |          AND table_schema = DATABASE()                                                                                                                           |
|                                                    |          AND index_name = 'idx_propertyfields_create_at_id'                                                                                                      |
|                                                    |      ) > 0,                                                                                                                                                      |
|                                                    |      'SELECT 1',                                                                                                                                                 |
|                                                    |      'CREATE INDEX idx_propertyfields_create_at_id ON PropertyFields(CreateAt, ID);'                                                                             |
|                                                    |  ));                                                                                                                                                             |
|                                                    |  PREPARE createIndexIfNotExists FROM @preparedStatement;                                                                                                         |
|                                                    |  EXECUTE createIndexIfNotExists;                                                                                                                                 |
|                                                    |  DEALLOCATE PREPARE createIndexIfNotExists;                                                                                                                      |
|                                                    | PostgreSQL:                                                                                                                                                      |
|                                                    ||
|                                                    |  CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_propertyvalues_create_at_id ON PropertyValues(CreateAt, ID)                                                         |
|                                                    ||
|                                                    |  CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_propertyfields_create_at_id ON PropertyFields(CreateAt, ID)                                                         | 
<table><thead><tr><th>v10.6</th><th>Support for PostgreSQL v11 and v12 have been removed. The new minimum PostgreSQL version is v13+. See the <a href="/docs/mattermost/deploy/requirements/#minimum-postgresql-database-support-policy" class="doc-ref">minimum supported PostgreSQL version policy</a> documentation for details.</th></tr></thead></table>
|                                                    | System Console statistics now perform faster on PostgreSQL. The <code>MaxUsersForStatistics</code> configuration setting now only disables the<strong>User counts with posts</strong> |
|                                                    | chart, while all other stats remain unaffected. The other stats remain unaffected because that configuration value is no longer needed to disable the other      |
|                                                    | queries since they are always fast now. Post and file counts update daily, so they may not always reflect real-time data. Advanced stats, such as line charts    |
|                                                    | and plugin data, are now hidden until clicked, reducing load time. No performance improvements apply to MySQL since it's scheduled for full deprecation in v11.  |
|                                                    | We recommend migrating to PostgreSQL for better performance and long-term support. Migration times: On a system with 12M posts, and 1M fileinfo entries, the     |
|                                                    | migration takes 15s, but could take several minutes depending on the server's table sizes and database specs. This migration is non-locking. Note that there is  |                                                                                                       
|                                                    | no migration for MySQL deployments because this optimization is only applicable for PostgreSQL. Below are the SQL queries included in the schema changes:        |

|                                                    | |
|                                                    |  CREATE MATERIALIZED VIEW IF NOT EXISTS posts_by_team_day as                                                                                                     |
|                                                    |  SELECT to_timestamp(p.createat/1000)::date as day, COUNT(*) as num, teamid                                                                                      |
|                                                    |  FROM posts p JOIN channels c on p.channelid=c.id                                                                                                                |
|                                                    |  GROUP BY day, c.teamid;                                                                                                                                         |
|                                                    |  CREATE MATERIALIZED VIEW IF NOT EXISTS bot_posts_by_team_day as                                                                                                 |
|                                                    |  SELECT to_timestamp(p.createat/1000)::date as day, COUNT(*) as num, teamid                                                                                      |
|                                                    |  FROM posts p                                                                                                                                                    |                                                                                                
|                                                    |  JOIN Bots b ON p.UserId = b.Userid                                                                                                                              | 
|                                                    |  JOIN channels c on p.channelid=c.id                                                                                                                             | 
|                                                    |  GROUP BY day, c.teamid;                                                                                                                                         | 
|                                                    |  CREATE MATERIALIZED VIEW IF NOT EXISTS file_stats as                                                                                                            | 
|                                                    |  SELECT COUNT(*) as num, COALESCE(SUM(Size), 0) as usage                                                                                                         | 
|                                                    |  FROM fileinfo                                                                                                                                                   | 
|                                                    |  WHERE DeleteAt = 0;                                                                                                                                             | 
<table><thead><tr><th>v10.5</th><th>Mattermost versions v10.5.0 and v10.5.1 include a bundled Jira plugin (v4.2.0) that contains a bug which may cause plugin configuration settings to disappear. We strongly advise against upgrading to these versions to avoid potential disruption. If you have already upgraded to v10.5.0 or v10.5.1, we recommend updating the Jira plugin to version v4.2.1, or preferably, upgrading both Mattermost and the Jira plugin to their latest available versions.</th></tr></thead></table>
|                                                    | The internal workings of the <a href="https://github.com/mattermost/mattermost-plugin-jira/pull/1145">PluginLinkComponent` in the web app have been changed to unmount link tooltips from the DOM by default, significantly improving    |
|                                                    | performance. Plugins that register link tooltips using `registerLinkTooltipComponent` will experience changes in how tooltip components are managed—they are     |
|                                                    | now only mounted when a link is hovered over or focused. As a result, plugins may need to update their components to properly handle mounting and unmounting     |
|                                                    | scenarios. For example, changes were made in `mattermost-plugin-jira</a>, where                   |
|                                                    | componentDidUpdate lifecycle hook was replaced with componentDidMount. If your plugin’s tooltip component is a functional React component, there is a high       |
|                                                    | chance that this behavior will be handled automatically, as it would be managed by useEffect with an empty dependency array.                                     |
|                                                    | The Mattermost server has stopped supporting manual plugin deployment. Plugins were deployed manually when an administrator or some deployment automation copies |
|                                                    | the contents of a plugin bundle into the server's working directory. If a manual or automated deployment workflow is still required, administrators can instead  |
|                                                    | prepackage the plugin bundles. See <a href="https://forum.mattermost.com/t/deprecation-notice-manual-plugin-deployment/21192">this forum post</a> for details.           |
|                                                    | Mattermost has stopped official Mattermost server builds for the Microsoft Windows operating system. Administrators should migrate existing Mattermost server    |
|                                                    | installations to use the official Linux builds. See more details in                                                                                              |
|                                                    | <a href="https://forum.mattermost.com/t/deprecation-notice-server-builds-for-microsoft-windows/21498">this forum post</a>.                                               |
|                                                    | v10.5 introduces updates to the Compliance Export functionality, which will modify how exported data is structured, stored and processed. These changes          |
|                                                    | primarily affect System Administrators and the main changes are outlined below. See more details in                                                              |
|                                                    | the <a href="https://docs.mattermost.com/administration-guide/comply/compliance-export.html">Compliance Export documentation</a>.                                         |
|                                                    | Output files and directories have changed - Previously we were exporting a single zip containing all the batch directories. Now we will export a single          |
|                                                    | directory, and under that directory each batch will be its own zip.                                                                                              |
|                                                    | Compliance exports performance improvements - Compliance exports should now be at least 50% faster, and possibly more.                                           |
|                                                    | Logic improvements - We’ve made improvements and fixed bugs that we found.                                                                                       |
|                                                    | Changes specific to each Export Type - The export output formats have been changed. Some fields’ semantic meaning has been clarified, and there are a number of  |
|                                                    | new fields. Our goal was to maintain backwards compatibility while fixing the logic bugs.                                                                        |
|                                                    | See the <a href="/docs/mattermost/comply/compliance-export/" class="doc-ref">compliance export</a> product documentation for details.                                             |
|                                                    | As part of the Property System Architecture feature, Mattermost v10.5 is going to run a set of migrations to add new tables to the schema. This migration only   |
|                                                    | creates new tables and indexes, so there is no impact on preexisting data.                                                                                       |
|                                                    | New tables <code>PropertyGroups</code>, <code>PropertyFields</code> and <code>PropertyValues</code> are going to be created.                                                                |
|                                                    | In the case of PostgreSQL, a new enum type <code>property_field_type</code> is going to be created, to be used in the <code>Type</code> column of the <code>PropertyFields</code> table.    |
|                                                    | The <code>PropertyFields</code> and <code>PropertyValues</code> tables have a unique constraint that will generate an index in MySQL, and in the case of PostgreSQL, they directly |
|                                                    | use a <code>UNIQUE INDEX</code> to enforce this constraint.                                                                                                               |
|                                                    | A new index <code>idx_propertyvalues_targetid_groupid</code> will be created for the <code>PropertyValues</code> table.                                                            |
|                                                    | The migration is only creating new tables with no data. The migration is backwards-compatible, and a previous version of Mattermost can run with the new schema  |
|                                                    | changes. No table locks or existing operations on the table are impacted by this upgrade. Zero downtime is possible when upgrading to this release.              |
|                                                    | Below are the SQL queries included in the schema changes:                                                                                                        |
|                                                    |<strong>MySQL</strong>:                                                                                                                                                       |

|                                                    | |
|                                                    |  CREATE TABLE IF NOT EXISTS PropertyGroups (                                                                                                                     |
|                                                    |   ID varchar(26) PRIMARY KEY,                                                                                                                                    |
|                                                    |   Name varchar(64) NOT NULL,                                                                                                                                     |
|                                                    |   UNIQUE(Name)                                                                                                                                                   |
|                                                    |  );                                                                                                                                                              |
|                                                    |  CREATE TABLE IF NOT EXISTS PropertyFields (                                                                                                                     |
|                                                    |   ID varchar(26) PRIMARY KEY,                                                                                                                                    |
|                                                    |   GroupID varchar(26) NOT NULL,                                                                                                                                  |
|                                                    |   Name varchar(255) NOT NULL,                                                                                                                                    |
|                                                    |   Type enum('text', 'select', 'multiselect', 'date', 'user', 'multiuser'),                                                                                       |
|                                                    |   Attrs json,                                                                                                                                                    |
|                                                    |   TargetID varchar(255),                                                                                                                                         |
|                                                    |   TargetType varchar(255),                                                                                                                                       |
|                                                    |   CreateAt bigint(20),                                                                                                                                           |
|                                                    |   UpdateAt bigint(20),                                                                                                                                           |
|                                                    |   DeleteAt bigint(20),                                                                                                                                           |
|                                                    |   UNIQUE(GroupID, TargetID, Name, DeleteAt)                                                                                                                      |
|                                                    |  );                                                                                                                                                              |
|                                                    |  CREATE TABLE IF NOT EXISTS PropertyValues (                                                                                                                     |
|                                                    |   ID varchar(26) PRIMARY KEY,                                                                                                                                    |
|                                                    |   TargetID varchar(255) NOT NULL,                                                                                                                                |
|                                                    |   TargetType varchar(255) NOT NULL,                                                                                                                              |
|                                                    |   GroupID varchar(26) NOT NULL,                                                                                                                                  |
|                                                    |   FieldID varchar(26) NOT NULL,                                                                                                                                  |
|                                                    |   Value json,                                                                                                                                                    |
|                                                    |   CreateAt bigint(20),                                                                                                                                           |
|                                                    |   UpdateAt bigint(20),                                                                                                                                           |
|                                                    |   DeleteAt bigint(20),                                                                                                                                           |
|                                                    |   UNIQUE(GroupID, TargetID, FieldID, DeleteAt)                                                                                                                   |
|                                                    |  );                                                                                                                                                              |
|                                                    |  SET @preparedStatement = (SELECT IF(                                                                                                                            |
|                                                    |   (                                                                                                                                                              |
|                                                    |      SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS                                                                                                          |
|                                                    |      WHERE table_name = 'PropertyValues'                                                                                                                         |
|                                                    |      AND table_schema = DATABASE()                                                                                                                               |
|                                                    |      AND index_name = 'idx_propertyvalues_targetid_groupid'                                                                                                      |
|                                                    |   ) > 0,                                                                                                                                                         |
|                                                    |   'SELECT 1',                                                                                                                                                    |
|                                                    |   'CREATE INDEX idx_propertyvalues_targetid_groupid ON PropertyValues (TargetID, GroupID);'                                                                      |
|                                                    |  ));                                                                                                                                                             |
|                                                    |  PREPARE createIndexIfNotExists FROM @preparedStatement;                                                                                                         |
|                                                    |  EXECUTE createIndexIfNotExists;                                                                                                                                 |
|                                                    |  DEALLOCATE PREPARE createIndexIfNotExists;                                                                                                                      |
|                                                    |<strong>PostgreSQL</strong>:                                                                                                                                                  |

|                                                    | |
|                                                    |  CREATE TABLE IF NOT EXISTS PropertyGroups (                                                                                                                     |
|                                                    |   ID varchar(26) PRIMARY KEY,                                                                                                                                    |
|                                                    |   Name varchar(64) NOT NULL,                                                                                                                                     |
|                                                    |   UNIQUE(Name)                                                                                                                                                   |
|                                                    |  );                                                                                                                                                              |
|                                                    |  DO                                                                                                                                                              |
|                                                    |  BEGIN                                                                                                                                                           |
|                                                    |    IF NOT EXISTS (SELECT * FROM pg_type typ                                                                                                                      |
|                                                    |                          INNER JOIN pg_namespace nsp ON nsp.oid = typ.typnamespace                                                                               |
|                                                    |                      WHERE nsp.nspname = current_schema()                                                                                                        |
|                                                    |                          AND typ.typname = 'property_field_type') THEN                                                                                           |
|                                                    |   CREATE TYPE property_field_type AS ENUM (                                                                                                                      |
|                                                    |      'text',                                                                                                                                                     |
|                                                    |      'select',                                                                                                                                                   |
|                                                    |      'multiselect',                                                                                                                                              |
|                                                    |      'date',                                                                                                                                                     |
|                                                    |      'user',                                                                                                                                                     |
|                                                    |      'multiuser'                                                                                                                                                 |
|                                                    |   );                                                                                                                                                             |
|                                                    |    END IF;                                                                                                                                                       |
|                                                    |  END;                                                                                                                                                            |
|                                                    |  LANGUAGE plpgsql;                                                                                                                                               |
|                                                    |  CREATE TABLE IF NOT EXISTS PropertyFields (                                                                                                                     |
|                                                    |   ID varchar(26) PRIMARY KEY,                                                                                                                                    |
|                                                    |   GroupID varchar(26) NOT NULL,                                                                                                                                  |
|                                                    |   Name varchar(255) NOT NULL,                                                                                                                                    |
|                                                    |   Type property_field_type,                                                                                                                                      |
|                                                    |   Attrs jsonb,                                                                                                                                                   |
|                                                    |   TargetID varchar(255),                                                                                                                                         |
|                                                    |   TargetType varchar(255),                                                                                                                                       |
|                                                    |   CreateAt bigint NOT NULL,                                                                                                                                      |
|                                                    |   UpdateAt bigint NOT NULL,                                                                                                                                      |
|                                                    |   DeleteAt bigint NOT NULL                                                                                                                                       |
|                                                    |  );                                                                                                                                                              |
|                                                    |  CREATE UNIQUE INDEX IF NOT EXISTS idx_propertyfields_unique ON PropertyFields (GroupID, TargetID, Name) WHERE DeleteAt = 0;                                     |
|                                                    |  CREATE TABLE IF NOT EXISTS PropertyValues (                                                                                                                     |
|                                                    |   ID varchar(26) PRIMARY KEY,                                                                                                                                    |
|                                                    |   TargetID varchar(255) NOT NULL,                                                                                                                                |
|                                                    |   TargetType varchar(255) NOT NULL,                                                                                                                              |
|                                                    |   GroupID varchar(26) NOT NULL,                                                                                                                                  |
|                                                    |   FieldID varchar(26) NOT NULL,                                                                                                                                  |
|                                                    |   Value jsonb NOT NULL,                                                                                                                                          |
|                                                    |   CreateAt bigint NOT NULL,                                                                                                                                      |
|                                                    |   UpdateAt bigint NOT NULL,                                                                                                                                      |
|                                                    |   DeleteAt bigint NOT NULL                                                                                                                                       |
|                                                    |  );                                                                                                                                                              |
|                                                    |  CREATE UNIQUE INDEX IF NOT EXISTS idx_propertyvalues_unique ON PropertyValues (GroupID, TargetID, FieldID) WHERE DeleteAt = 0;                                  |
|                                                    |  CREATE INDEX IF NOT EXISTS idx_propertyvalues_targetid_groupid ON PropertyValues (TargetID, GroupID);                                                           |
|                                                    |      ``                                                                                                                                                          |
<table><thead><tr><th>v10.4</th><th>There are no important upgrade notes in v10.4 release.</th></tr><tr><th>v10.3</th><th>The Classic Mobile App has been phased out. Please download the new v2 Mobile App from the <a href="https://apps.apple.com/us/app/mattermost/id1257222717">Apple App Store</a> or <a href="https://play.google.com/store/apps/details?id=com.mattermost.rn">Google Play Store</a>. See more details in the <a href="https://forum.mattermost.com/t/classic-mobile-app-deprecation/18703">classic mobile app deprecation</a> Mattermost forum post.</th></tr><tr><th>v10.2</th><th>Docker Content Trust (DCT) for signing Docker image artifacts has been replaced by Sigstore Cosign in v10.2 (November, 2024). If you rely on artifact verification using DCT, please <a href="https://edu.chainguard.dev/open-source/sigstore/cosign/how-to-install-cosign/">transition to using Cosign</a>. See the <a href="https://forum.mattermost.com/t/upcoming-dct-deprecation/19275">upcoming DCT deprecation</a> Mattermost forum post for more details.</th></tr><tr><th>v10.1</th><th>There are no important upgrade notes in v10.1 release.</th></tr><tr><th>v10.0</th><th>We no longer support new installations using MySQL starting in v10. All new customers and/or deployments will only be supported with the minimum supported version of the PostgreSQL database. End of support for MySQL is targeted for Mattermost v11.</th></tr></thead></table>
|                                                    | Apps Framework is deprecated for new installs. Please extend Mattermost using webhooks, slash commands, OAuth2 apps, and plugins.                                |
|                                                    | Mattermost v10 introduces Playbooks v2 for all Enterprise licensed customers. Professional SKU customers may continue to use Playbooks v1 uninterrupted which    |
|                                                    | will be maintained and supported until September 2025, followed by an appropriate grandfathering strategy. More detailed information and the discussion are      |
|                                                    | available on our <a href="https://forum.mattermost.com/t/clarification-on-playbooks-in-mattermost-v10/20563">forums here</a>.                                             |
|                                                    | Renamed <code>Channel Moderation</code> to <code>Advanced Access Control</code> in the channel management section in the<strong>System Console</strong>.                                       |

|                                                    | Renamed announcement banner feature to “system-wide notifications”.                                                                                              |

|                                                    | Renamed “Collapsed Reply Threads” to “Threaded Discussions” in the System Console.                                                                               |

|                                                    | Renamed “System Roles” to “Delegated Granular Administration” in the System Console.                                                                             |

|                                                    | Renamed "Office 365" to "Entra ID" for SSO logins.                                                                                                               |

|                                                    | Fully deprecated the <code>/api/v4/image</code> endpoint when the image proxy is disabled.                                                                                |

|                                                    | Pre-packaged <a href="https://github.com/mattermost/mattermost-plugin-calls/releases/tag/v1.0.1">Calls plugin v1.0.1</a>. This includes breaking changes including        | 
|                                                    | the removal of group calls from unlicensed servers in order to focus supportability and quality on licensed servers. Unlicensed servers can continue to use      |
|                                                    | Calls in direct message channels, which represent the majority of activity.                                                                                      |

|                                                    | Removed deprecated <code>Config.ProductSettings</code>, <code>LdapSettings.Trace</code>, and <code>AdvancedLoggingConfig</code> configuration fields.                                       |

|                                                    | Removed deprecated <code>pageSize</code> query parameter from most API endpoints.                                                                                         |

|                                                    | Deprecated the experimental Strict CSRF token enforcement. This feature will be fully removed in Mattermost v11.                                                 |
<table><thead><tr><th>v9.11</th><th>Added support for Elasticsearch v8. Also added Beta support for OpenSearch v1.x and v2.x. A new config setting <code>ElasticsearchSettings.Backend</code> has been added to differentiate between Elasticsearch and OpenSearch. The default value is <code>elasticsearch</code> which breaks support for AWS Elasticsearch v7.10.x since the official v8 client only works from Elasticsearch v7.11+ versions. 
Note

- For AWS customers on OpenSearch, you must modify Mattermost configuration from <code>elasticsearch</code> to <code>opensearch</code> and disable compatibility mode. See the <a href="https://docs.aws.amazon.com/opensearch-service/latest/developerguide/version-migration.html">OpenSearch documentation</a> for details on upgrading. - After upgrading the Mattermost server, use <a href="/docs/mattermost/manage/mmctl/#mmctl-config-set" class="doc-ref">mmctl</a> or edit the config manually, then restart the Mattermost server. - If you are using OpenSearch, you <strong>must</strong> set the backend to <code>opensearch</code>. Otherwise Mattermost will not work. If you are using Elasticsearch v8, be sure to set <code>action.destructive_requires_name</code> to <code>false</code> in <code>elasticsearch.yml</code> to allow for wildcard operations to work.</th></tr><tr><th>v9.10</th><th>There are no important upgrade notes in v9.10 release.</th></tr><tr><th>v9.9</th><th>There are no important upgrade notes in v9.9 release.</th></tr><tr><th>v9.8</th><th>There are no important upgrade notes in v9.8 release.</th></tr><tr><th>v9.7</th><th>There are no important upgrade notes in v9.7 release.</th></tr><tr><th>v9.6</th><th>There are no important upgrade notes in v9.6 release.</th></tr><tr><th>v9.5</th><th>We have stopped supporting MySQL v5.7 since it's at the end of life. We urge customers to upgrade their MySQL instance at their earliest convenience.</th></tr></thead></table> | | Added safety limit error message in compiled Team Edition and Enterprise Edition deployments when enterprise scale and access control automation features are | | | unavailable and count of users who are registered and not deactivated exceeds 10,000. | | | <a href="/docs/mattermost/manage/admin/error-codes/" class="doc-ref">ERROR_SAFETY_LIMITS_EXCEEDED</a>. | <table><thead><tr><th>v9.4</th><th>There are no important upgrade notes in v9.4 release.</th></tr><tr><th>v9.3</th><th>There are no important upgrade notes in v9.3 release.</th></tr><tr><th>v9.2</th><th>Fixed data retention policies to run jobs when any custom retention policy is enabled even when the global retention policy is set to "keep-forever". Before this fix, the enabled custom data retention policies wouldn't run as long as the global data retention policy was set to "keep-forever" or was disabled. After the fix, the custom data retention policies will run automatically even when the global data retention policy is set to "keep-forever". Once the server is upgraded, posts may unintentionally be deleted. Admins should make sure to disable all custom data retention policies before upgrading, and then re-enable them again after upgrading.</th></tr><tr><th>v9.1</th><th>Minimum supported Desktop App version is now v5.3. OAuth/SAML flows were modified to include <code>desktop_login</code> which makes earlier versions incompatible.</th></tr><tr><th>v9.0</th><th>Removed the deprecated Insights feature.</th></tr></thead></table> | | Mattermost Boards and various other plugins have transitioned to being fully community supported. See this | | | <a href="https://forum.mattermost.com/t/upcoming-product-changes-to-boards-and-various-plugins/16669">forum post</a> for more details. | | | The <code>channel_viewed</code> websocket event was changed to <code>multiple_channels_viewed</code>, and is now only triggered for channels that actually have unread messages. | <table><thead><tr><th>v8.1</th><th>In v8.1.2, improved performance on data retention <code>DeleteOrphanedRows</code> queries. New migration for a new table: <strong>MySQL</strong>: CREATE TABLE IF NOT EXISTS RetentionIdsForDeletion(Id VARCHAR(26) NOT NULL, TableName VARCHAR(64), Ids json, PRIMARY KEY (Id ), KEY idx_retentionidsfordeletion_tablename (TableName)) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4; <code><strong>PostgreSQL</strong>: CREATE TABLE IF NOT EXISTS retentionidsfordeletion(id VARCHAR(26) PRIMARY KEY, tablename VARCHAR(64), ids VARCHAR(26) []); CREATE INDEX IF NOT EXISTS idx_retentionidsfordeletion_tablename ON retentionidsfordeletion( tablename); </code> Hard deleting a user or a channel will now also clean up associated reactions. Removed feature flag <code>DataRetentionConcurrencyEnabled</code>. Data retention now runs without concurrency in order to avoid any performance degradation. Added a new configuration setting <code>DataRetentionSettings.RetentionIdsBatchSize</code>, which allows admins to configure how many batches of IDs will be fetched at a time when deleting orphaned reactions. The default value is 100.</th></tr><tr><th>v8.0</th><th>Insights has been deprecated for all new instances and for existing servers that upgrade to v8.0. See more details in <a href="https://forum.mattermost.com/t/proposal-to-revise-our-insights-feature-due-to-known-performance-issues/16212">this forum post</a> on why Insights has been deprecated.</th></tr></thead></table> | | The Focalboard plugin is now disabled by default for all new instances and can be enabled in the<strong>System Console > Plugin settings</strong>. | | | The Channel Export and Apps plugins are now disabled by default. | | | Apps Bar is now enabled by default for on-prem servers. <code>ExperimentalSettings.EnableAppBar</code> was also renamed to <code>ExperimentalSettings.DisableAppBar</code>. | | | See the :ref: `configuration settings <administration-guide/configure/experimental-configuration-settings:disable-apps-bar><a href="https://forum.mattermost.com/t/channel-header-plugin-changes/13551">documentation, and | | | `this forum article</a> for details. | | | In the main `server package`, the Go module path has changed from <code>github.com/mattermost/mattermost-server/server/v8</code> to | | | <code>github.com/mattermost/mattermost/server/v8</code>. But with the introduction of the <a href="https://github.com/mattermost/mattermost/tree/master/server/public">public` submodule, it should no longer be necessary for third-party code to | | | import this `server` package. | | | Introduced the `public</a> submodule, housing the familiar `model` and `plugin` packages, | | | but now discretely versioned from the server. It is no longer necessary to `go get` a particular commit hash, as Go programs and plugins can now opt-in to | | | importing `github.com/mattermost/mattermost-server/server/public` and managing versions idiomatically. While this submodule has not yet shipped a v1 and will | | | introduce breaking changes before stabilizing the API, it remains both forwards and backwards compatible with the Mattermost server itself. | | | As part of the `public` submodule above, a <code>context.Context</code> is now passed to <code>model.Client4</code> methods. | | | Removed support for PostgreSQL v10. The new minimum PostgreSQL version is now v11. | | | The Mattermost public API for Go is now available as a distinctly versioned package. Instead of pinning a particular commit hash, use idiomatic Go to add this | | | package as a dependency: go get `github.com/mattermost/mattermost-server/server/public`. This relocated Go API maintains backwards compatibility with Mattermost | | | v7. Furthermore, the existing Go API previously at github.com/mattermost/mattermost-server/v6/model remains forward compatible with Mattermost v8, but may not | | | contain newer features. Plugins do not need to be recompiled, but developers may opt in to using the new package to simplify their build process. The new public | | | package is shipping alongside Mattermost v8 as version 0.5.0 to allow for some additional code refactoring before releasing as v1 later this year. | | | Three configuration fields have been added, <code>LogSettings.AdvancedLoggingJSON</code>, <code>ExperimentalAuditSettings.AdvancedLoggingJSON</code>, and | | | <code>NotificationLogSettings.AdvancedLoggingJSON</code> which support multi-line JSON, escaped JSON as a string, or a filename that points to a file containing JSON. | | | The <code>AdvancedLoggingConfig</code> fields have been deprecated. | | | The Go MySQL driver has changed the <code>maxAllowedPacket</code> size from 4MiB to 64MiB. This is to make it consistent with the change in the server side default value | | | from MySQL 5.7 to MySQL 8.0. If your <code>max_allowed_packet</code> setting is not 64MiB, then please update the MySQL config DSN with an additional param of | | | <code>maxAllowedPacket</code> to match with the server side value. Alternatively, a value of 0 can be set to to automatically fetch the server side value, on every new | | | connection, which has a performance overhead. | | | Removed <code>ExperimentalSettings.PatchPluginsReactDOM</code>. If this setting was previously enabled, confirm that: | | | 1. All Mattermost-supported plugins are updated to the latest versions. | | | 2. Any other plugins have been updated to support React 17. See the section for v7.7 release for more information. | | | Removed deprecated <code>PermissionUseSlashCommands</code>. | | | Removed deprecated <code>model.CommandArgs.Session</code>. | | | For servers wanting to allow websockets to connect from origins other than the origin of the site URL, please set the <code>ServiceSettings.AllowCorsFrom</code> | | | <a href="/docs/mattermost/configure/integrations/#enable-cross-origin-requests-from" class="doc-ref">configuration setting</a>. Also ensure that | | | the <code>siteURL</code> is set correctly. | | | In v8.0 release, the following repositories are merged into one: <code>mattermost-server</code>, <code>mattermost-webapp</code> and <code>mmctl</code>. | | | Developers should read the updated <a href="https://developers.mattermost.com/contribute/developer-setup/">Developer Guide</a> for details. | | | Fixed an issue caused by a migration in the previous release. Query takes around 11ms on a PostgreSQL 14 DB t3.medium RDS instance. Locks on the preferences | | | table will only be acquired if there are rows to delete, but the time taken is negligible. | | | Fixed an issue where a user would still see threads in the threads view of channels they have left. Migration execution time in PostgreSQL: Execution time: | | | 58.11 sec, DELETE 2766690. Migration execution time in MySQL: Query OK, 2766769 rows affected (4 min 47.57 sec). | | | For servers wanting to allow websockets to connect from other origins, please set the <code>ServiceSettings.AllowCorsFrom</code> config setting. | | | The file info stats query is now optimized by denormalizing the <code>channelID</code> column into the table itself. This will speed up the query to get the file count | | | for a channel when selecting the right-hand pane. Migration times: | | | On a PostgreSQL 12.14 DB with 1731 rows in FileInfo and 11M posts, it took around 0.27s | | | On a MySQL 8.0.31 DB with 1405 rows in FileInfo and 11M posts, it took around 0.3s | <table><thead><tr><th>v7.10</th><th>In v7.10.1, fixed an issue caused by a migration in the previous release. Query takes around 11ms on a PostgreSQL 14 DB t3.medium RDS instance. Locks on the preferences table will only be acquired if there are rows to delete, but the time taken is negligible.</th></tr></thead></table> | | In v7.10.1, fixed an issue where a user would still see threads in the threads view of channels they have left. Migration execution time in MySQL: Query OK, | | | 2766769 rows affected (4 min 47.57 sec). Migration execution time in PostgreSQL: 58.11 sec, DELETE 2766690. | | | In v7.10.3, for servers wanting to allow websockets to connect from origins other than the origin of the site URL, please set the | | | <code>ServiceSettings.AllowCorsFrom</code> | | | <a href="/docs/mattermost/configure/integrations/#enable-cross-origin-requests-from" class="doc-ref">configuration setting</a>. Also ensure that | | | the <code>siteURL</code> is set correctly. | <table><thead><tr><th>v7.9</th><th>Added a new index on <code>Posts(OriginalId)</code>. For a database with 11.8 million posts, on a machine with a i7-11800H CPU (8 cores, 16 threads), 32GiB of RAM and SSD, the index creation takes 98.51s on MYSQL and 2.6s on PostgreSQL. - In PostgreSQL databases, the <code>Posts</code> table will be locked during index creation. To avoid locking this table, admins can create the index manually before performing the upgrade using the following non-blocking query: <code>CREATE INDEX CONCURRENTLY idx_posts_original_id ON Posts(OriginalId);</code>. - Admins managing PostgreSQL deployments containing fewer posts may prefer that the migration process creates the index, and accept that <code>Posts</code> table will remain locked until the migration is complete.</th></tr></thead></table> | | In v7.9.4, fixed an issue where a user would still see threads in the threads view of channels they have left. Migration execution time in MySQL: Query OK, | | | 2766769 rows affected (4 min 47.57 sec). Migration execution time in PostgreSQL: 58.11 sec, DELETE 2766690. | | | In v7.9.4, backported a fix related Oauth 2. Query times depend on if you have rows to delete or not. | | | With no rows to delete: | | | - MySQL v5.7.12: 9ms | | | - PostgreSQL v10: 21ms | | | 4 rows: | | | - MySQL v5.7.12: 17.2ms | | | - PostgreSQL v10: 9.9ms | | | Those times are based off the following table sizes: | | | - Preferences: 2 million records | | | - <code>oauthaccessdata</code> and sessions: 10 records | | | You can assess the number of impacted rows by running the following: | | | <strong>PostgreSQL</strong>: | | | | | | SELECT count(o.*) | | | FROM oauthaccessdata o | | | WHERE NOT EXISTS ( | | | SELECT p.* | | | FROM preferences p | | | WHERE o.clientid = p.name | | | AND o.userid = p. | | | userid | | | AND p.category = | | | 'oauth_app' | | | ); | | |<strong>MySQL</strong>: | | | | | | SELECT COUNT(o.`Token`) | | | FROM OAuthAccessData o | | | LEFT JOIN Preferences p ON o. | | | clientid = p.name | | | AND o.userid = p.userid | | | AND p.category = 'oauth_app' | | | INNER JOIN Sessions s ON o.token = s | | | .token | | | WHERE p.name IS NULL; | | | Locks on the <code>oauthaccessdata</code> and sessions table will only be acquired if there are rows to delete. | | | In v7.9.5, for servers wanting to allow websockets to connect from origins other than the origin of the site URL, please set the | | | <code>ServiceSettings.AllowCorsFrom</code> | | | <a href="/docs/mattermost/configure/integrations/#enable-cross-origin-requests-from" class="doc-ref">configuration setting</a>. Also ensure that | | | the <code>siteURL</code> is set correctly. | <table><thead><tr><th>v7.8</th><th><a href="/docs/mattermost/configure/site-configuration/#message-priority" class="doc-ref">Message Priority & Acknowledgement</a> is now enabled by default for all instances. You may disable this feature in the System Console by going to<strong>Posts > Message Priority</strong> or via the config <code>PostPriority</code> setting.</th></tr></thead></table> | | In v7.8.5, fixed an issue where a user would still see threads in the threads view of channels they have left. Migration execution time in MySQL: Query OK, | | | 2766769 rows affected (4 min 47.57 sec). Migration execution time in PostgreSQL: 58.11 sec, DELETE 2766690. | | | In v7.8.5, backported a fix related Oauth 2. Query times depend on if you have rows to delete or not. | | | With no rows to delete: | | | - MySQL v5.7.12: 9ms | | | - PostgreSQL v10: 21ms | | | 4 rows: | | | - MySQL v5.7.12: 17.2ms | | | - PostgreSQL v10: 9.9ms | | | Those times are based off the following table sizes: | | | - Preferences: 2 million records | | | - <code>oauthaccessdata</code> and sessions: 10 records | | | You can assess the number of impacted rows by running the following: | | | <strong>PostgreSQL</strong>: | | | | | | SELECT count(o.*) | | | FROM oauthaccessdata o | | | WHERE NOT EXISTS ( | | | SELECT p.* | | | FROM preferences p | | | WHERE o.clientid = p.name | | | AND o.userid = p. | | | userid | | | AND p.category = | | | 'oauth_app' | | | ); | | |<strong>MySQL</strong>: | | | | | | SELECT COUNT(o.`Token`) | | | FROM OAuthAccessData o | | | LEFT JOIN Preferences p ON o. | | | clientid = p.name | | | AND o.userid = p.userid | | | AND p.category = 'oauth_app' | | | INNER JOIN Sessions s ON o.token = s | | | .token | | | WHERE p.name IS NULL; | | | Locks on the <code>oauthaccessdata</code> and sessions table will only be acquired if there are rows to delete. | | | In v7.8.7, for servers wanting to allow websockets to connect from origins other than the origin of the site URL, please set the | | | <code>ServiceSettings.AllowCorsFrom</code> | | | <a href="/docs/mattermost/configure/integrations/#enable-cross-origin-requests-from" class="doc-ref">configuration setting</a>. Also ensure that | | | the <code>siteURL</code> is set correctly. | | | In v7.8.11, improved performance on data retention <code>DeleteOrphanedRows</code> queries. | | | New migration for a new table: | | |<strong>MySQL</strong>: | | | | | | CREATE TABLE | | | IF NOT EXISTS | | | RetentionIdsForDeletion(Id | | | VARCHAR(26) NOT NULL, | | | TableName VARCHAR(64), | | | Ids json, PRIMARY KEY (Id | | | ), KEY | | | idx_retentionidsfordeletion_tablename | | | (TableName)) ENGINE = | | | InnoDB DEFAULT CHARSET = | | | utf8mb4; | | | `` | | |<strong>PostgreSQL</strong>: | | | | | | CREATE TABLE | | | IF NOT EXISTS | | | retentionidsfordeletion(id | | | VARCHAR(26) PRIMARY KEY, | | | tablename VARCHAR(64), | | | ids VARCHAR(26) []); | | | CREATE INDEX | | | IF NOT EXISTS | | | idx_retentionidsfordeletion_tablename | | | ON retentionidsfordeletion( | | | tablename); | | | `` | | | Hard deleting a user or a channel will now also clean up associated reactions. | | | Removed feature flag <code>DataRetentionConcurrencyEnabled</code>. Data retention now runs without concurrency in order to avoid any performance degradation. | | | Added a new configuration setting <code>DataRetentionSettings.RetentionIdsBatchSize</code>, which allows admins to configure how many batches of IDs will be fetched at | | | a time when deleting orphaned reactions. The default value is 100. | <table><thead><tr><th>v7.7</th><th>Plugins with a webapp component may need to be updated to work with Mattermost v7.7 release and the updated <code>React v17</code> dependency. This is to avoid plugins crashing with an error about <code>findDOMNode</code> being called on an unmounted component. While our <a href="https://github.com/mattermost/mattermost-plugin-starter-template">starter template</a> depended on an external version of <code>React</code>, it did not do the same for <code>ReactDOM</code>. Plugins need to update their <code>webpack.config.js</code> directives to externalize <code>ReactDOM</code>. For reference, see https://github.com/mattermost/mattermost-plugin-playbooks/pull/1489. Server-side only plugins are unaffected. This change can be done for existing plugins any time prior to upgrading to Mattermost v7.7 and is backwards compatible with older versions of Mattermost. If you run into issues, you can either enable <code>ExperimentalSettings.PatchPluginsReactDOM</code> or just disable the affected plugin while it's updated.</th></tr></thead></table> | | Denormalized <code>Threads</code> table by adding the <code>ThreadTeamId</code> column. Even though it denormalizes the schema, we gain performance by removing the unnessesary | | | joins. | | | Test results for schema changes are outlined below: | | | instance: <code>db.r5.large</code> | | | size of <code>Threads</code> table: 846313 rows | | | number of posts: 12 million | | | number of reactions: 2.5 million | | |<strong>MySQL:</strong> | | | | | | -- Drop any existing TeamId column from 000094_threads_teamid.up.sql | | | SET @preparedStatement = (SELECT IF( | | | EXISTS(`` | | | SELECT 1 FROM INFORMATION_SCHEMA.STATISTICS | | | WHERE table_name = 'Threads' | | | AND table_schema = DATABASE() | | | AND column_name = 'TeamId' | | | ), | | | 'ALTER TABLE Threads DROP COLUMN TeamId;', | | | 'SELECT 1;' | | | )); | | | PREPARE removeColumnIfExists FROM @preparedStatement; | | | EXECUTE removeColumnIfExists; | | | DEALLOCATE PREPARE removeColumnIfExists; | | | SET @preparedStatement = (SELECT IF( | | | NOT EXISTS( | | | SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS | | | WHERE table_name = 'Threads' | | | AND table_schema = DATABASE() | | | AND column_name = 'ThreadTeamId' | | | ), | | | 'ALTER TABLE Threads ADD COLUMN ThreadTeamId varchar(26) DEFAULT NULL;', | | | 'SELECT 1;' | | | )); | | | PREPARE addColumnIfNotExists FROM @preparedStatement; | | | EXECUTE addColumnIfNotExists; | | | DEALLOCATE PREPARE addColumnIfNotExists; | | | Query OK, 0 rows affected (7.71 sec) | | | UPDATE Threads, Channels | | | SET Threads.ThreadTeamId = Channels.TeamId | | | WHERE Channels.Id = Threads.ChannelId | | | AND Threads.ThreadTeamId IS NULL; | | | Query OK, 846313 rows affected (51.32 sec) | | | Rows matched: 846313 Changed: 846313 Warnings: 0 | | |<strong>PostgreSQL:</strong> | | | | | | -- Drop any existing TeamId column from 000094_threads_teamid.up.sql | | | ALTER TABLE threads DROP COLUMN IF EXISTS teamid; | | | ALTER TABLE threads ADD COLUMN IF NOT EXISTS threadteamid VARCHAR(26); | | | ALTER TABLE | | | Time: 2.236 ms | | | UPDATE threads | | | SET threadteamid = channels. | | | teamid | | | FROM channels | | | WHERE threads.threadteamid IS | | | NULL | | | AND channels.id = threads. | | | channelid; | | | UPDATE 847646 | | | Time: 29744.608 ms (00:29.745) | | |<strong>Backwards-compatibility:</strong> | | | A previous version of Mattermost can run with the new schema changes | | | <strong>Table locks or impact to existing operations on the table:</strong> | | | Table locks - Threads table | | | Queries posted above can be run prior to upgrading Mattermost for both MySQL and PostgreSQL. After schema changes migration becomes instantaneous (0.78 sec). | | | Starting with the Calls version shipping with v7.7, there's now a minimum version requirement when using the external RTCD service. This means that if Calls is | | | configured to use the external service, customers need to upgrade RTCD first to at least version 0.8.0 or the plugin will fail to start. | | | In v7.7.2, <a href="/docs/mattermost/configure/site-configuration/#message-priority" class="doc-ref">Message Priority & Acknowledgement</a> is now enabled by | | | default for all instances. You may disable this feature in the System Console by going to <strong>Posts > Message Priority</strong> or via the config <code>PostPriority</code> | | | setting. | <table><thead><tr><th>v7.5</th><th>Added a new schema migration to ensure <code>ParentId</code> column is dropped from the <code>Posts</code> table. Depending on the table size, if the column is not dropped before, a significant spike in database CPU usage is expected on MySQL databases. Writes to the table will be limited during the migration.</th></tr></thead></table> | | For <code>PluginRegistry.registerCustomRoute</code>, when you register a custom route component, you must specify a CSS <code>grid-area</code> in order for it to be placed | | | properly into the root layout (recommended: <code>grid-area: center</code>). | <table><thead><tr><th>v7.3</th><th>Boards is moving from a channel-based to a role-based permissions system. The migration will happen automatically, but your administrator should perform a backup prior to the upgrade. We removed workspaces, so if you were a member of many boards prior to migration, they will now all appear under the same sidebar.</th></tr><tr><th>v7.2</th><th>Several schema changes impose additional database constraints to make the data more strict. All the commands listed below were tested on a 8 core, 16GB RAM machine. Here are the times recorded: <strong>PostgreSQL (131869 channels, 2 teams)</strong>: - <code>CREATE TYPE channel_type AS ENUM ('P', 'G', 'O', 'D');</code> took 14.114 milliseconds - <code>ALTER TABLE channels alter column type type channel_type using type::channel_type;</code> took 3856.790 milliseconds (3.857 seconds) - <code>CREATE TYPE team_type AS ENUM ('I', 'O');</code> took 4.191 milliseconds - <code>ALTER TABLE teams alter column type type team_type using type::team_type;</code> took 116.205 milliseconds - <code>CREATE TYPE upload_session_type AS ENUM ('attachment', 'import');</code> took 4.266 milliseconds - <code>ALTER TABLE uploadsessions alter column type type upload_session_type using type::upload_session_type;</code> took 37.099 milliseconds <strong>MySQL (270959 channels, 2 teams)</strong>: - <code>ALTER TABLE Channels MODIFY COLUMN Type ENUM("D", "O", "G", "P");</code> took 13.24 seconds - <code>ALTER TABLE Teams MODIFY COLUMN Type ENUM("I", "O");</code> took 0.04 seconds - <code>ALTER TABLE UploadSessions MODIFY COLUMN Type ENUM("attachment", "import");</code> took 0.03 seconds</th></tr><tr><th>v7.1</th><th>A new configuration option <code>MaxImageDecoderConcurrency</code> indicates how many images can be decoded concurrently at once. The default is -1, and the value indicates the number of CPUs present. This affects the total memory consumption of the server. The maximum memory of a single image is dictated by <code>MaxImageResolution <em> 24 bytes</code>. Therefore, we recommend that <code>MaxImageResolution </em> MaxImageDecoderConcurrency * 24</code> should be less than the allocated memory for image decoding.</th></tr></thead></table> | | Mattermost v7.1 introduces schema changes in the form of a new column and its index. Our test results for the schema changes are included below: | | | - MySQL 12M Posts, 2.5M Reactions - ~1min 34s (instance: PC with 8 cores, 16GB RAM) | | | - PostgreSQL 12M Posts, 2.5M Reactions - ~1min 18s (instance: db.r5.2xlarge) | | | You can run the following SQL queries before the upgrade to obtain a lock on <code>Reactions</code> table, so that users' reactions posted during this time won't be | | | reflected in the database until the migrations are complete. This is fully backwards-compatible. | | | MySQL: | | | - <code>ALTER TABLE Reactions ADD COLUMN ChannelId varchar(26) NOT NULL DEFAULT "";</code> | | | - <code>UPDATE Reactions SET ChannelId = COALESCE((select ChannelId from Posts where Posts.Id = Reactions.PostId), '') WHERE ChannelId="";</code> | | | - <code>CREATE INDEX idx_reactions_channel_id ON Reactions(ChannelId) LOCK=NONE;</code> | | | PostgreSQL: | | | - <code>ALTER TABLE reactions ADD COLUMN IF NOT EXISTS channelid varchar(26) NOT NULL DEFAULT '';</code> | | | - <code>UPDATE reactions SET channelid = COALESCE((select channelid from posts where posts.id = reactions.postid), '') WHERE channelid='';</code> | | | - <code>CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_reactions_channel_id on reactions (channelid);</code> | <table><thead><tr><th>v7.0</th><th><strong>IMPORTANT:</strong> Session length configuration settings have changed from using a unit of <em>days</em> to <em>hours</em>. Instances using a config.json file or a database configuration for the following values should be automatically migrated to the new units, but instances using environment variables must make the following changes: 1. replace <code>MM_SERVICESETTINGS_SESSIONLENGTHWEBINDAYS</code> with <code>MM_SERVICESETTINGS_SESSIONLENGTHWEBINHOURS</code> (x24 the value). 2. replace <code>MM_SERVICESETTINGS_SESSIONLENGTHMOBILEINDAYS</code> with <code>MM_SERVICESETTINGS_SESSIONLENGTHMOBILEINHOURS</code> (x24 the value). 3. replace <code>MM_SERVICESETTINGS_SESSIONLENGTHSSOINDAYS</code> with <code>MM_SERVICESETTINGS_SESSIONLENGTHSSOINHOURS</code> (x24 the value).</th></tr></thead></table> | | MySQL self-hosted customers may notice the migration taking longer than usual when having a large number of rows in FileInfo table. For MySQL, it takes around | | | 19 seconds for a table of size 700,000 rows. The time required for PostgreSQL is negligible. The testing was performed on a machine with specifications of | | | <code>CPU - Intel i7 6-cores @ 2.6 GHz</code> and <code>Memory - 16 GB</code>. | | | When a new configuration setting via <strong>System Console > Experimental > Features > Enable App Bar</strong> is enabled, all channel header icons registered by plugins | | | will be moved to the new Apps Bar, even if they do not explicitly use the new registry function to render a component there. The setting for Apps Bar defaults | | | to <code>false</code> for self-hosted deployments. | | | The value of <code>ServiceSettings.TrustedProxyIPHeader</code> defaults to empty from now on. A previous bug prevented this from happening in certain conditions. | | | Customers are requested to check for these values in their config and set them to nil if necessary. See more details | | | <a href="/docs/mattermost/configure/environment-configuration-settings/#trusted-proxy-ip-header" class="doc-ref">here</a>. | | | <a href="/docs/mattermost/collaborate/organize-conversations/" class="doc-ref">Collapsed Reply Threads</a> is now generally available and enabled by default for new | | | Mattermost servers. For servers upgrading to v7.0 and later, please reference | | | <a href="https://support.mattermost.com/hc/en-us/articles/6880701948564-Administrator-s-guide-to-enabling-Collapsed-Reply-Threads">this article</a> for more information | | | and guidance on enabling the feature. | <table><thead><tr><th>v6.7</th><th>New schema changes were introduced in the form of a new index. The following summarizes the test results measuring how long it took for the database queries to run with these schema changes: MySQL 7M Posts - ~17s (Instance: db.r5.xlarge) MySQL 9M Posts - 2min 12s (Instance: db.r5.large) Postgres 7M Posts - ~9s (Instance: db.r5.xlarge) For customers wanting a zero downtime upgrade, they are encouraged to apply this index prior to doing the upgrade. This is fully backwards compatible and will not acquire any table lock or affect any existing operations on the table when run manually. Else, the queries will run during the upgrade process and will lock the table in non-MySQL environments. Run the following to apply this index: For MySQL: <code>CREATE INDEX idx_posts_create_at_id on Posts(CreateAt, Id) LOCK=NONE;</code> For Postgres: <code>CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_posts_create_at_id on posts(createat, id);</code></th></tr></thead></table> | | In v6.7.1, the value of <code>ServiceSettings.TrustedProxyIPHeader</code> defaults to empty from now on. A previous bug prevented this from happening in certain | | | conditions. Customers are requested to check for these values in their config and set them to nil if necessary. See more details | | | <a href="/docs/mattermost/configure/environment-configuration-settings/#trusted-proxy-ip-header" class="doc-ref">here</a>. | <table><thead><tr><th>v6.6</th><th>The Apps Framework protocol for binding/form submissions has changed, by separating the single `call` into separate `submit`, `form`, `refresh` and `lookup` calls. If any users have created their own Apps, they have to be updated to the new system.</th></tr></thead></table> | | Channel admins can now configure <a href="/docs/mattermost/collaborate/create-channels/" class="doc-ref">certain actions</a> to be executed automatically based on trigger | | | conditions without writing any code. Users running an older Playbooks release need to upgrade their Playbooks instance to at least v1.26 to take advantage of | | | the channel actions functionality. | | | In v6.6.2, the value of <code>ServiceSettings.TrustedProxyIPHeader</code> defaults to empty from now on. A previous bug prevented this from happening in certain | | | conditions. Customers are requested to check for these values in their config and set them to nil if necessary. See more details | | | <a href="/docs/mattermost/configure/environment-configuration-settings/#trusted-proxy-ip-header" class="doc-ref">here</a>. | <table><thead><tr><th>v6.5</th><th>The <code>mattermost version</code> CLI command does not interact with the database anymore. Therefore the database version is not going to be printed. Also, the database migrations are not going to be applied with the version sub command. <a href="/docs/mattermost/manage/command-line/#mattermost-db-migrate" class="doc-ref">A new db migrate sub command</a> is added to enable administrators to trigger migrations.</th></tr></thead></table> | | In v6.5.2, the value of <code>ServiceSettings.TrustedProxyIPHeader</code> defaults to empty from now on. A previous bug prevented this from happening in certain | | | conditions. Customers are requested to check for these values in their config and set them to nil if necessary. See more details | | | <a href="/docs/mattermost/configure/environment-configuration-settings/#trusted-proxy-ip-header" class="doc-ref">here</a>. | <table><thead><tr><th>v6.4</th><th>A new schema migration system has been introduced, so we strongly recommend backing up the database before updating the server to this version. The new migration system will run through all existing migrations to record them to a new table. This will only happen for the first run in order to migrate the application to the new system. The table where the migration information is stored is called <code>db_migrations</code>. Additionally, a <code>db_lock</code> table is used to prevent multiple installations from running migrations in parallel. In case of an error while applying the migrations, please check this table first. Any downtime depends on how many records the database has and whether there are missing migrations in the schema. If you encounter an issue please file <a href="https://github.com/mattermost/mattermost-server/issues">an Issue</a> by including the failing migration name, database driver/version, and the server logs. On MySQL, if you encounter an error "Failed to apply database migrations" when upgrading to v6.4.0, it means that there is a mismatch between the table collation and the default database collation. You can manually fix this by changing the database collation with <code>ALTER DATABASE <YOUR_DB_NAME> COLLATE = 'utf8mb4_general_ci',</code>. Then do the server upgrade again and the migration will be successful. It has been commonly observed on MySQL 8+ systems to have an error <code>Error 1267: Illegal mix of collations</code> when upgrading due to changing the default collation. This is caused by the database and the tables having different collations. If you get this error, please change the collations to have the same value with, for example, <code>ALTER DATABASE <db_name> COLLATE = '<collation>'</code>.</th></tr></thead></table> | | The new migration system requires the MySQL database user to have additional <em>EXECUTE</em>, <em>CREATE ROUTINE</em>, <em>ALTER ROUTINE</em> and <em>REFERENCES</em> privileges to run | | | schema migrations. | <table><thead><tr><th>v6.3</th><th>In v6.3.3, the default for <code>ThreadAutoFollow</code> has been changed to <code>false</code>. This does not affect existing configurations where this value is already set to <code>true</code>.</th></tr></thead></table> | | In v6.3.9, the value of <code>ServiceSettings.TrustedProxyIPHeader</code> defaults to empty from now on. A previous bug prevented this from happening in certain | | | conditions. Customers are requested to check for these values in their config and set them to nil if necessary. See more details | | | <a href="/docs/mattermost/configure/environment-configuration-settings/#trusted-proxy-ip-header" class="doc-ref">here</a>. | <table><thead><tr><th>v6.2</th><th>Channel results in the channel autocomplete will include private channels. Customers using <a href="/docs/mattermost/configure/bleve-search/" class="doc-ref">Bleve</a> or <a href="/docs/mattermost/scale/elasticsearch/" class="doc-ref">Elasticsearch</a> for autocomplete will have to reindex their data to get the new results. Since this can take a long time, we suggest disabling autocomplete and running indexing in the background. When this is complete, re-enable autocomplete.

Note

Only channel members see private channel names in autocomplete results.</th></tr></thead></table> | | In v6.2.3, the default for <code>ThreadAutoFollow</code> has been changed to <code>false</code>. This does not affect existing configurations where this value is already set to | | | <code>true</code>. | | | Mattermost Boards requires <code>EnableReliableWebSockets</code> setting to be manually set to <code>true</code> for real-time updates to appear correctly. | <table><thead><tr><th>v6.1</th><th>Please refer to <a href="https://gist.github.com/streamer45/997b726a86b5d2a624ac2af435a66086">the schema migration analysis</a> when upgrading to v6.1.</th></tr></thead></table> | | The Bleve index has been updated to use the scorch index type. This new default index type features some efficiency improvements which means that the indexes | | | use significantly less disk space. To use this new type of index, after upgrading the server version, run a purge operation and then a reindex from the Bleve | | | section of the System Console. Bleve is still compatible with the old indexes, so the currently indexed data will work fine if the purge and reindex is not run. | | | A composite index has been added to the jobs table for better query performance. For some customers with a large jobs table, this can take a long time, so we | | | recommend adding the index during off-hours, and then running the migration. A table with more than 1 million rows can be considered as large enough to be | | | updated prior to the upgrade. | | | - For PostgreSQL: <code>create index concurrently idx_jobs_status_type on jobs (status,type);</code> | | | - For MySQL: <code>create index idx_jobs_status_type on Jobs (Status,Type);</code> | | | In v6.1.3, the default for <code>ThreadAutoFollow</code> has been changed to <code>false</code>. This does not affect existing configurations where this value is already set to | | | <code>true</code>. | | | Mattermost Boards requires <code>EnableReliableWebSockets</code> setting to be manually set to <code>true</code> for real-time updates to appear correctly. | <table><thead><tr><th>v6.0</th><th>Longer migration times can be expected. - See <a href="https://gist.github.com/streamer45/59b3582118913d4fc5e8ff81ea78b055">this document</a> for the estimated upgrade times with datasets of 10+ million posts. - See <a href="https://gist.github.com/streamer45/868c451164f6e8069d8b398685a31b6e">this document</a> for the estimated upgrade times with datasets of 70+ million posts. The field type of Data in <code>model.ClusterMessage</code> was changed to []byte from string. A v6 server is incompatible to run along with a v5 server in a cluster. Customers upgrading from 5.x to 6.x cannot do a High Availability upgrade. While upgrading, it is required that no other v5 server runs when a v6 server is brought up. A v6 server will run significant database schema changes that can cause a large startup time depending on the dataset size. Zero downtime will not be possible, but depending on the efforts made during the migration process, it can be minimized to a large extent. 1. Low effort, long downtime - This is the usual process of starting a v6 server normally. This has two implications: during the migration process, various tables will be locked which will render those tables read-only during that period. Secondly, once the server finishes migration and starts the application, no other v5 server can run in the cluster. 2. Medium effort, medium downtime - This process will require SQL queries to be executed manually on the server. To avoid causing a table lock, a customer can choose to use the pt-online-schema-change tool for MySQL. For Postgres, the table locking is very minimal. The advantage is that since there are a lot of queries, the customer can take their own time to run individual queries during off-hours. All queries except #11 are safe to be executed this way. Then the usual method of (1) can be followed. 3. High effort, low downtime - This process requires everything of (2), plus it tries to minimize the impact of query #11. We can do this by following step 2, and then starting v6 along with a running v5 server, and then monitor the application logs. As soon as the v6 application starts up, we need to bring down a v5 node. This minimizes the downtime to only a few seconds. It is recommended to start Mattermost directly and not through systemctl to avoid the server process getting killed during the migration. This can happen since the value of <code>TimeoutStartSec</code> in the provided systemctl service file is set to one hour. Customers using the Mattermost Kubernetes operator should be aware of the above migration information and choose the path that is most appropriate for them. If (1) is acceptable, then the normal upgrade process using the operator will suffice. For minimum downtime, follow (2) before using the operator to update Mattermost following the normal upgrade process.</th></tr></thead></table> | | While trying to upgrade to a Mattermost version >= 6.0.x, you might encounter the following error: ``Failed to alter column type. It is likely you have invalid | | | JSON values in the column. Please fix the values manually and run the migration again.`` | | | This means that the particular column has some invalid JSON values which need to be fixed manually. A common fix that is known to work is to wipe out all | | | <code>\u0000</code> characters. | | | Please follow these steps: | | | 1. Check the affected values by: <code>SELECT COUNT(*) FROM <table> WHERE <column> LIKE '%\u0000%';</code> | | | 2. If you get a count more than 0, check those values manually, and confirm they are okay to be removed. | | | 3. Remove them by <code>UPDATE <table> SET <column> = regexp_replace(<column>, '\u0000', '', 'g') where <column> like '%\u0000%';</code> | | | Then try to start Mattermost again. | | | Please see <a href="https://docs.mattermost.com/product-overview/unsupported-legacy-releases" target="_blank" rel="noopener noreferrer" class="doc-ref">unsupported legacy releases</a> documentation for a list of deprecations in this release. | | | Focalboard plugin has been renamed to Mattermost Boards, and v0.9.1 (released with Mattermost v6.0) is now enabled by default. | | | The advanced logging configuration schema changed. This is a breaking change relative to 5.x. See updated | | | <a href="/docs/mattermost/manage/logging/" class="doc-ref">documentation</a>. | | | The existing theme names and colors, including "Mattermost", "Organization", "Mattermost Dark", and "Windows Dark" have been updated to the new "Denim", | | | "Quartz", "Indigo", and "Onyx" theme names and colors, respectively. Anyone using the existing themes will see slightly modified theme colors after their | | | server or workspace is upgraded. The theme variables for the existing "Mattermost", "Organization", "Mattermost Dark", and "Windows Dark" themes will still be | | | accessible in <a href="https://docs.mattermost.com/end-user-guide/preferences/customize-your-theme" target="_blank" rel="noopener noreferrer" class="doc-ref">our documentation</a>. A custom theme can be created with these theme variables if desired. | | | Custom themes are unaffected by this change. | | | Some breaking changes to plugins are included: | | | - Support for left-hand side-specific bot icons was dropped. | | | - Removed a deprecated "Backend" field from the plugin manifest. | | | - Converted the "Executables" field in the plugin manifest to a map. | | | Mattermost Boards requires <code>EnableReliableWebSockets</code> setting to be manually set to <code>true</code> for real-time updates to appear correctly. | <table><thead><tr><th>v5.38.0</th><th>The “config watcher” (the mechanism that automatically reloads the <code>config.json</code> file) has been removed in favor of the <code>mmctl config reload</code> command, which must be run to apply configuration changes after they are made on disk. This change improves configuration performance and robustness.</th></tr></thead></table> | | v5.38 adds fixes for some of the incorrect mention counts and unreads around threads and channels since the introduction of Collapsed Reply Threads (Beta). This | | | fix is done through a SQL migration, and it may take several minutes to complete for large databases. The <code>fixCRTChannelMembershipCounts</code> fix takes 1 minute | | | and 20 seconds for a database containing approximately four million channel memberships and about 130,000 channels. The <code>fixCRTThreadCountsAndUnreads</code> fix | | | takes about 3 minutes and 30 seconds for a database containing 56367 threads, 124587 thread memberships, and 220801 channel memberships. These are on MySQL | | | v5.6.51. | | | Focalboard v0.8.2 (released with Mattermost v5.38.0) requires Mattermost v5.37+ due to the new database connection system. | <table><thead><tr><th>v5.37.0</th><th>The <code>platform</code> binary and “--platform” flag have been removed. If you are using the “--platform” flag or are using the <code>platform</code> binary directly to run the Mattermost server application via a systemd file or custom script, you will be required to use only the mattermost binary.</th></tr></thead></table> | | <a href="https://mattermost.com/blog/collapsed-reply-threads-beta/">Collapsed Reply Threads</a> are available as Beta in Mattermost Server | | | v5.37 and later. It’s expected that you may experience bugs as we stabilize the feature. In particular, please be aware of | | | <a href="/docs/mattermost/collaborate/organize-conversations/#known-issues" class="doc-ref">the known issues documented here</a>. | | | v5.37 adds support for emoji standard v13.0. If you have added a custom emoji in the past that uses one of the new system names, then it is going to get | | | overwritten by the system emoji. The workaround is to change the custom emoji name. | | | Parts of Incident Collaboration are now available to all Mattermost editions. As part of this update, Incident Collaboration will require a minimum server | | | version of v5.37. To learn more about what is available in each edition, visit <a href="https://mattermost.com/pricing">our pricing page</a>. | | | In v5.37.8, the default for <code>ThreadAutoFollow</code> has been changed to <code>false</code>. This does not affect existing configurations where this value is already set to | | | <code>true</code>. | <table><thead><tr><th>v5.36.0</th><th>Gossip clustering mode is now in General Availability and is no longer available as an option. All cluster traffic will always use the gossip protocol. The config setting <code>UseExperimentalGossip</code> has no effect and has only been kept for compatibility purposes. The setting to use gossip has been removed from the System Console.

Note

For High Availability upgrades, all nodes in the cluster must use a single protocol. If an existing system is not currently using gossip, one node in a cluster can't be upgraded while other nodes in the cluster use an older version. Customers must either use gossip for their High Availability upgrade, or customers must shut down all nodes, perform the upgrade, and then bring all nodes back up.</th></tr></thead></table> | | To enable Focalboard, open the Marketplace from the sidebar menu, install the Focalboard plugin, then click on <strong>Configure</strong>, enable it, and save. Update your | | | NGINX or Apache web proxy config. | <table><thead><tr><th>v5.35.0</th><th>Due to the introduction of backend database architecture required for upcoming new features, Shared Channels and Collapsed Reply Threads, the performance of the migration process for the v5.35 release (May 16, 2021) has been noticeably affected. Depending on the size, type, and version of the database, longer than usual upgrade times should be expected. This can vary from a couple of minutes (average case) to hours (worst case, MySQL 5.x only). A moderate to significant spike in database CPU usage should also be expected during this process. More details on the <a href="https://gist.github.com/streamer45/9aee4906639a49ebde68b2f3c0f924c1">performance impact of the migration and possible mitigation strategies</a> are available.</th></tr></thead></table> | | The existing password generation logic used during the bulk user import process was comparatively weak. Hence it's advised for admins to immediately reset the | | | passwords for all the users who were generated during the bulk import process and whose password has not been changed even once. | | | v5.35.0 introduces a new feature to search for files. Search results for files shared in the past may be incomplete until a | | | <a href="/docs/mattermost/manage/mmctl/#mmctl-extract" class="doc-ref">content extraction command</a> is executed to extract | | | and index the content of files already in the database. Instances running Elasticsearch or Bleve search backends will also need to execute a Bulk Indexing after | | | the content extraction is complete. Please see more details in <a href="https://mattermost.com/blog/file-search/">this blog post</a>. | <table><thead><tr><th>v5.34.1</th><th>v5.34.1 fixes an issue where upgrading to v5.34.0 runs a migration that can cause timeouts on MySQL installations. Upgrading to v5.34.1 may also execute missing migrations that were scheduled for v5.32.0. These additions can be lengthy on very big MySQL (version 5.x) installations. - Altering of <code>Posts.FileIds</code> type (PostgreSQL only) - Added new column <code>ThreadMemberships.UnreadMentions</code> - Added new column <code>Channels.Shared</code> - Added new column <code>Reactions.UpdateAt</code> - Added new column <code>Reactions.DeleteAt</code></th></tr><tr><th>v5.33.0</th><th>Deleting a reaction is now a soft delete in the <code>Reactions</code> table. A schema update is required and may take up to 15 seconds on first run with large data sets.</th></tr></thead></table> | | WebSocket handshakes done with HTTP version lower than 1.1 will result in a warning, and the server will transparently upgrade the version to 1.1 to comply with | | | the WebSocket RFC. This is done to work around incorrect Nginx (and other proxy) configs that do not set the <code>proxy_http_version</code> directive to 1.1. This | | | facility will be removed in a future Mattermost version and it is strongly recommended to fix the proxy configuration to correctly use the WebSocket protocol. | <table><thead><tr><th>v5.32.0</th><th><code>ExperimentalChannelOrganization</code>, <code>EnableXToLeaveChannelsFromLHS</code>, <code>CloseUnusedDirectMessages</code>, and <code>ExperimentalHideTownSquareinLHS</code> settings are only functional if the Legacy Sidebar (<code>EnableLegacySidebar</code>) is enabled since they are not compatible with the new sidebar experience. <code>ExperimentalChannelSidebarOrganization</code> has been deprecated, since the <a href="https://mattermost.com/blog/custom-collapsible-channel-categories/">new sidebar is now enabled for all users</a>.</th></tr></thead></table> | | Breaking changes to the Golang client API were introduced: <code>GetPostThread</code>, <code>GetPostsForChannel</code>, <code>GetPostsSince</code>, <code>GetPostsAfter</code>, <code>GetPostsBefore</code>, | | | and <code>GetPostsAroundLastUnread</code> now require an additional collapsedThreads parameter to be passed. Any client making use of these functions will need to update | | | them when upgrading its dependencies. | | | <a href="https://go.dev/doc/go1.15">A breaking change was introduced when upgrading the Go version to v1.15.5</a> where user logins fail with AD/LDAP Sync | | | when the certificate of the LDAP Server has no Subject Alternative Name (SAN) in it. Creating a new certificate on the AD/LDAP Server with the SAN inside fixes | | | this. | | | TLS versions 1.0 and 1.1 have been deprecated by browser vendors. Starting in Mattermost Server v5.32 (February 16), mmctl returns an error when connected to | | | Mattermost servers deployed with these TLS versions. System admins will need to explicitly add a flag in their commands to continue to use them. We recommend | | | upgrading to TLS version 1.2 or higher. | <table><thead><tr><th>v5.31.0</th><th>For Mobile Apps v1.42.0+, the minimum server version is set to v5.31.3 as v5.31.3 fixed an issue where the server version was reported as v5.30.0.</th></tr><tr><th>v5.29.0</th><th>A new configuration setting <code>ThreadAutoFollow</code> has been added to support Collapsed Reply Threads releasing in beta in Q1 2021. This setting is enabled by default and may affect server performance. It is recommended to review our <a href="/docs/mattermost/deploy/requirements/#hardware-requirements" class="doc-ref">documentation on hardware requirements</a> to ensure your servers are appropriately scaled for the size of your user base.</th></tr></thead></table> | | Disabled the xmlsec1-based SAML library in favor of the re-enabled and improved SAML library. | <table><thead><tr><th>v5.28.0</th><th>Now when the service crashes, it will generate a coredump instead of just dumping the stack trace to the console. This allows us to preserve the full information of the crash to help with debugging it. For more information about coredumps, please see: https://man7.org/linux/man-pages/man5/core.5.html.</th></tr></thead></table> | | In-product notices have been introduced to keep system admins and end users informed of the latest product enhancements available in new server and desktop | | | versions. <a href="/docs/mattermost/manage/in-product-notices/" class="doc-ref">Learn more about in-product notices</a> and how to disable them in our documentation. | | | Disabled the xmlsec1-based SAML library in favor of the re-enabled and improved SAML library. | <table><thead><tr><th>v5.27.0</th><th>Disabled the xmlsec1-based SAML library in favor of the re-enabled and improved SAML library.</th></tr><tr><th>v5.26.0</th><th>In v5.26, Elasticsearch indexes needed to be recreated. Admins should re-index Elasticsearch using the <strong>Purge index</strong> and then <strong>Index now</strong> button so that all the changes will be included in the index. Systems may be left with a limited search during the indexing, so it should be done during a time when there is little to no activity because it may take several hours.</th></tr></thead></table> | | An <code>EnableExperimentalGossipEncryption</code> option was added under <code>ClusterSettings</code>. If set to <code>true</code>, and <code>UseExperimentalGossip</code> is also <code>true</code>, | | | all communication through the cluster using the gossip protocol will be encrypted. The encryption uses <code>AES-256</code> by default, and it is not kept configurable | | | by design. However, if one wishes, they can set the value in Systems table manually for the <code>ClusterEncryptionKey</code> row. A key is a byte array converted to | | | base64. It should be either 16, 24, or 32 bytes to select AES-128, AES-192, or AES-256. | | | To update the key, one can execute: | | | <code>UPDATE Systems SET Value='<value>' WHERE Name='ClusterEncryptionKey';</code> in MySQL and | | | <code>UPDATE systems SET value='<value>' WHERE name='ClusterEncryptionKey'</code> for PostgreSQL. | | | For any change in this config setting to take effect, the whole cluster must be shut down first. Then the config change made, and then restarted. In a cluster, | | | all servers either will completely use encryption or not. There cannot be any partial usage. | | | SAML Setting "Use Improved SAML Library (Beta)" was forcefully disabled. | | | PostgreSQL ended long-term support for <a href="https://www.postgresql.org/support/versioning">version 9.4 in February 2020</a>. From v5.26 Mattermost officially | | | supports PostgreSQL version 10 as PostgreSQL 9.4 is no longer supported. New installs will require PostgreSQL 10+. Previous Mattermost versions, including our | | | current ESR, will continue to be compatible with PostgreSQL 9.4. PostgreSQL 9.4 and all 9.x versions are now fully deprecated in our v5.30 release | | | (December 16, 2020). Follow the Upgrading Section within <a href="https://www.postgresql.org/support/versioning/">the PostgreSQL documentation</a>. | <table><thead><tr><th>v5.25.0</th><th>Some incorrect instructions regarding SAML setup with Active Directory ADFS for setting the “Relying Party Trust Identifier” were corrected. Although the settings will continue to work, it is encouraged that you <a href="/docs/mattermost/onboard/sso-saml-adfs-msws2016/#add-a-relying-party-trust" class="doc-ref">modify those settings</a>.</th></tr></thead></table> | | Disabled the xmlsec1-based SAML library in favor of the re-enabled and improved SAML library. | <table><thead><tr><th>v5.24.0</th><th>A new configuration setting, <code>ExtendSessionLengthWithActivity</code> automatically extends sessions to keep users logged in if they are active in their Mattermost apps. It is recommended to enable this setting to improve user experience if compliant with your organization's policies. <a href="https://mattermost.com/blog/session-expiry-experience">Learn more here</a>.</th></tr></thead></table> | | The <code>mattermost_http_request_duration_seconds</code> histogram metric (in Enterprise Edition) has been removed. This information was already captured by | | | <code>mattermost_api_time</code>, which also contains the API handler name, HTTP method, and the response code. | | | As an example, if you are using | | | <code>rate(mattermost_http_request_duration_seconds_sum{server=~"$var"}[5m]) / rate(mattermost_http_request_duration_seconds_count{server=~"$var"}[5m])</code> | | | to measure average call duration, it needs to be replaced with | | | <code>sum(rate(mattermost_api_time_sum{server=~"$var"}[5m])) by (instance) / sum(rate(mattermost_api_time_count{server=~"$var"}[5m])) by (instance)</code>. | | | Due to fixing performance issues related to emoji reactions, the performance of the upgrade has been affected in that the schema upgrade now takes more time in | | | environments with lots of reactions in their database. These environments are recommended to perform the schema migration during low usage times and potentially | | | in advance of the upgrade. Since this migration happens before the Mattermost server is fully launched, non-High Availability installs will be unreachable | | | during this time. | | | The migration is a single line of SQL and can be applied directly to the database through the MySQL/PSQL command line clients if you prefer to decouple this | | | from restarting the Mattermost server. It is fully backwards compatible so the schema change can be applied to any previous version of Mattermost without issue. | | | During the time the schema change is running (~30s per million rows in the Reactions table), if end users attempt to react to posts, the emoji reactions will | | | not load for end users. | | | MySQL: <code>ALTER TABLE Reactions DROP PRIMARY KEY, ADD PRIMARY KEY (PostId, UserId, EmojiName);</code> | | | PostgreSQL: <code>ALTER TABLE reactions DROP CONSTRAINT reactions_pkey, ADD PRIMARY KEY (PostId, UserId, EmojiName);</code> | | | On mobile apps, users will not be able to see LDAP group mentions (E20 feature) in the autocomplete dropdown. Users will still receive notifications if they are | | | part of an LDAP group. However, the group mention keyword will not be highlighted. | | | SAML Setting "Use Improved SAML Library (Beta)" was forcefully disabled. Follow instructions at | | | https://docs.mattermost.com/administration-guide/onboard/sso-saml.html for enabling SAML using the feature-equivalent <code>xmlsec1</code> utility. | <table><thead><tr><th>v5.22.0</th><th>Due to fixing performance issues related to emoji reactions, the performance of the upgrade has been affected in that the schema upgrade now takes more time in environments with lots of reactions in their database. These environments are recommended to perform the schema migration during low usage times and potentially in advance of the upgrade. Since this migration happens before the Mattermost server is fully launched, non-High Availability installs will be unreachable during this time. The migration is a single line of SQL and can be applied directly to the database through the MySQL/PSQL command line clients if you prefer to decouple this from restarting the Mattermost server. It is fully backwards compatible so the schema change can be applied to any previous version of Mattermost without issue. During the time the schema change is running (~30s per million rows in the Reactions table), if end users attempt to react to posts, the emoji reactions will not load for end users. MySQL: <code>ALTER TABLE Reactions DROP PRIMARY KEY, ADD PRIMARY KEY (PostId, UserId, EmojiName);</code> Postgres: <code>ALTER TABLE reactions DROP CONSTRAINT reactions_pkey, ADD PRIMARY KEY (PostId, UserId, EmojiName);</code></th></tr></thead></table> | | The Channel Moderation Settings feature is supported on mobile app versions v1.30 and later. In earlier versions of the mobile app, users who attempt to post or | | | react to posts without proper permissions will see an error. | | | Direct access to the <code>Props</code> field in the <code>model.Post</code> structure has been deprecated. The available <code>GetProps()</code> and <code>SetProps()</code> methods should now be | | | used. Also, direct copy of the <code>model.Post</code> structure must be avoided in favor of the provided <code>Clone()</code> method. | | | SAML Setting "Use Improved SAML Library (Beta)" was forcefully disabled. Follow instructions at | | | https://docs.mattermost.com/administration-guide/onboard/sso-saml.html for enabling SAML using the feature-equivalent <code>xmlsec1</code> utility. | <table><thead><tr><th>v5.21.0</th><th>Honour key value expiry in KVCompareAndSet, KVCompareAndDelete, and KVList. We also improved handling of plugin key value race conditions and deleted keys in Postgres.</th></tr></thead></table> | | SAML Setting "Use Improved SAML Library (Beta)" was forcefully disabled. Follow instructions at | | | https://docs.mattermost.com/administration-guide/onboard/sso-saml.html for enabling SAML using the feature-equivalent <code>xmlsec1</code> utility. | <table><thead><tr><th>v5.20.0</th><th>Any <a href="https://developers.mattermost.com/integrate/admin-guide/admin-plugins-beta/#pre-packaged-plugins">pre-packaged plugin</a> that is not enabled in the <code>config.json</code> will no longer install automatically, but can continue to be installed via the <a href="https://developers.mattermost.com/integrate/admin-guide/admin-plugins-beta/#plugin-marketplace">Plugin Marketplace</a>.</th></tr></thead></table> | | Boolean elements from interactive dialogs are no longer serialized as strings. While we try to avoid breaking changes, this change was necessary to allow | | | both the web and mobile apps to work with the boolean elements introduced with v5.16. | <table><thead><tr><th>v5.19.0</th><th><code>LockTeammateNameDisplay</code> setting was moved to Enterprise Edition E20 as it was erroneously available in Team Edition and Enterprise Edition E10.</th></tr><tr><th>v5.18.0</th><th>Marking a post unread from the mobile app requires v1.26 or later. If using v5.18, but mobile is on v1.25 or earlier, marking a post unread from webapp/desktop will only be reflected on mobile the next time the app launches or is brought to the foreground.</th></tr></thead></table> | | The Go module path of <code>mattermost-server</code> was changed to comply with the Go module version specification. Developers using Go modules with | | | <code>mattermost-server</code> as a dependency must change the module and import paths to <code>github.com/mattermost/mattermost-server/v5</code> when upgrade this dependency | | | to `v5.18`. See `<https://go.dev/blog/v2-go-modules>`__ for further information. | | | Removed <code>Team.InviteId</code> from the related Websocket event and sanitized it on all team API endpoints for users without invite permissions. | | | Removed the ability to change the type of a channel using the <code>PUT /channels/{channel_id}</code> API endpoint. The new <code>PUT /channels/{channel_id}/privacy</code> | | | endpoint should be used for that purpose. | <table><thead><tr><th>v5.16.0</th><th>Support for Internet Explorer (IE11) is removed. See <a href="https://forum.mattermost.com/t/mattermost-is-dropping-support-for-internet-explorer-ie11-in-v5-16/7575">this forum post</a> to learn more.</th></tr></thead></table> | | The <a href="https://github.com/mattermost/desktop/blob/master/CHANGELOG.md">Mattermost Desktop v4.3.0</a> release includes a change to how desktop notifications are sent| | | sent from non-secure URLs <code>http://</code>. Organizations using non-secure Mattermost Servers <code>http://</code> will need to update to Mattermost Server versions 5.16.0+, | | | 5.15.1, 5.14.4 or 5.9.5 (ESR) to continue receiving desktop notifications when using Mattermost Desktop v4.3.0 or later. | | | When enabling <a href="/docs/mattermost/onboard/guest-accounts/" class="doc-ref">Guest Accounts</a>, all users who have the ability to invite users will be able to | | | invite guests by default. System admins will need to remove this permission on each role via <strong>System Console > Permissions Schemes</strong>. In Mattermost Server | | | version 5.17, the system admin will be the only role to automatically get the invite guest permission, however the fix will not be applicable in 5.16 due to | | | database migration processes. | <table><thead><tr><th>v5.14.0</th><th>Webhooks are now only displayed if the user is the creator of the webhook or a system administrator.</th></tr></thead></table> | | With the update from Google+ to Google People, system admins need to ensure the <code>GoogleSettings.Scope</code> config.json setting is set to <code>profile email</code> and | | | <code>UserAPIEndpoint</code> setting should be set to <code>https://people.googleapis.com/v1/people/me?personFields=names,emailAddresses,nicknames,metadata</code> per | | | <a href="/docs/mattermost/onboard/sso-google/" class="doc-ref">updated documentation</a>. | <table><thead><tr><th>v5.12.0</th><th>If your plugin uses the <code>DeleteEphemeralMessage</code> plugin API, update it to accept a <code>postId string</code> parameter. See <a href="https://developers.mattermost.com/extend/plugins/server/reference/#API.DeleteEphemeralPost">documentation</a> to learn more.</th></tr></thead></table> | | Image link and YouTube previews do not display unless <strong>System Console > Enable Link Previews</strong> is enabled. Please ensure that your Mattermost server is | | | connected to the internet and has network access to the websites from which previews are expected to appear. | | | <a href="https://forum.mattermost.com/t/link-previews-managed-server-side-in-v5-12-and-later/7712">Learn more here</a>. | | | <code>ExperimentalEnablePostMetadata</code> setting was removed. Post metadata, including post dimensions, is now stored in the database to correct scroll position and | | | eliminate scroll jumps as content loads in a channel. | | | Added the ability to enforce the administration of teams/channels with Group Sync. If Group Sync is enabled, all team and channel admin designations will be | | | lost upon upgrade. It is highly recommended that prior to upgrading, Team and channel admins are added to admin-specific LDAP groups corresponding to their | | | teams and channels. After upgrading, those groups will need to be role-synced to the Team or channel admin role. | <table><thead><tr><th>v5.11.0</th><th>If your integration uses <code>Update.Props == nil</code> to clear <code>Props</code>, this will no longer work in 5.11+. Instead, use <code>Update.Props == {}</code> to clear properties. This change was made because <code>Update.Props == nil</code> unintentionally cleared all <code>Props</code>, such as the profile picture, instead of preserving them.</th></tr><tr><th>v5.10.0</th><th><code>SupportedTimezonesPath</code> setting in config.json and changes to timezones in the UI based on the <code>timezones.json</code> file was removed. This was made to support <a href="/docs/mattermost/configure/configuration-in-your-database/" class="doc-ref">storing configurations in the database</a>.</th></tr><tr><th>v5.9.0</th><th>If <code>DisableLegacyMfa</code> setting in <code>config.json</code> is set to <code>true</code> and <a href="/docs/mattermost/onboard/mfa/" class="doc-ref">multi-factor authentication</a> is enabled, ensure your users have upgraded to mobile app version 1.17 or later. Otherwise, users who have MFA enabled may not be able to log in successfully. If the setting is not defined in the <code>config.json</code> file, the <code>DisableLegacyMfa</code> setting is set to <code>false</code> by default to ensure no breaking changes. We recommend setting <code>DisableLegacyMfa</code> to <code>true</code> for additional security hardening.</th></tr></thead></table> | | The public IP of the Mattermost application server is considered a reserved IP for additional security hardening in the context of untrusted external requests | | | such as Open Graph metadata, webhooks, or slash commands. | | | <a href="/docs/mattermost/configure/environment-configuration-settings/#allow-untrusted-internal-connections" class="doc-ref">See documentation</a> for additional information. | <table><thead><tr><th>v5.8.0</th><th>The local image proxy has been added, and images displayed within the client are now affected by the <code>AllowUntrustedInternalConnections</code> setting. <a href="https://docs.mattermost.com/deployment-guide/server/image-proxy#local-image-proxy" target="_blank" rel="noopener noreferrer" class="doc-ref">See documentation</a> for more details if you have trouble loading images.</th></tr><tr><th>v5.6.0</th><th>Built-in WebRTC is removed. See <a href="https://forum.mattermost.com/t/built-in-webrtc-video-and-audio-calls-removed-in-v5-6- in-favor-of-open-source-plugins/5998">here for more details</a>.</th></tr></thead></table> | | If <code>EnablePublicChannelsMaterialization</code> setting in <code>config.json</code> is set to <code>false</code>, an offline migration prior to upgrade may be required to synchronize | | | the materialized table for public channels to increase channel search performance in the channel switcher (CTRL/CMD+K), channel autocomplete (~), and elsewhere | | | in the UI. Use the following steps: | | | 1. Shut down your application servers. | | | 2. Connect to your Mattermost database. | | | 3. Execute the following queries: | | | | | | DELETE FROM PublicChannels; | | | INSERT INTO PublicChannels | | | (Id, DeleteAt, TeamId, DisplayName, Name, Header, Purpose) | | | SELECT | | | c.Id, c.DeleteAt, c.TeamId, c.DisplayName, c.Name, c.Header, c.Purpose | | | FROM | | | Channels c | | | WHERE | | | c.Type = 'O'; | | | The queries above rebuild the materialized <code>PublicChannels</code> table without modifying the authoritative <code>Channels</code> table. | | |

Note

| | | This migration is not required if the experimental <code>PublicChannels</code> feature was never disabled. This feature launched in Mattermost v5.4 with a | | | temporary flag to disable should an issue arise, but nothing prompted doing so. If you did not modify this setting, there is no need to perform this migration. | <table><thead><tr><th>v5.4.0</th><th>Mattermost mobile app version 1.13+ is required. File uploads will fail on earlier mobile app versions.</th></tr></thead></table> | | In certain upgrade scenarios the new<strong>Allow Team Administrators to edit others posts</strong> setting under <strong>General</strong> then <strong>Users and Teams</strong> may be | | | set to <strong>True</strong> while the Mattermost default in 5.1 and earlier and with new 5.4+ installations is <strong>False</strong>. | <table><thead><tr><th>v5.3.0</th><th>Those servers with Elasticsearch enabled will notice that hashtag search is case-sensitive.</th></tr><tr><th>v5.2.0</th><th>Those servers upgrading from v4.1 - v4.4 directly to v5.2 or later and have Jira enabled will need to re-enable the Jira plugin after an upgrade.</th></tr><tr><th>v5.1.0</th><th><code>mattermost export</code> CLI command is renamed to <code>mattermost export schedule</code>. Make sure to update your scripts if you use this command.</th></tr><tr><th>v5.0.0</th><th>All API v3 endpoints are removed. <a href="https://api.mattermost.com/#tag/APIv3-Deprecation">See documentation</a> to learn how to migrate your integrations to API v4.</th></tr></thead></table> | | <code>platform</code> binary is renamed to <code>mattermost</code> for a clearer install and upgrade experience. You should point your <code>systemd</code> service file at the new | | | <code>mattermost</code> binary. All command line tools, including the bulk loading tool and developer tools, are also be renamed from <code>platform</code> to <code>mattermost</code>. | | | A Mattermost user setting to configure desktop notification duration in <strong>Account Settings > Notifications > Desktop Notifications</strong> is removed. | | | Slash commands configured to receive a GET request will have the payload being encoded in the query string instead of receiving it in the body of the request, | | | consistent with standard HTTP requests. Although unlikely, this could break custom slash commands that use GET requests incorrectly. | | | A new <code>config.json</code> setting to whitelist types of protocols for auto-linking will be added. | | | If you rely on custom protocols auto-linking in Mattermost, whitelist them in <code>config.json</code> before upgrading. | | | A new <code>config.json</code> setting to disable the <a href="https://api.mattermost.com/#tag/teams%2Fpaths%2F~1teams~1%7Bteam_id%7D%2Fput">permanent APIv4 delete team parameter | | |</a> is added. The setting will be off by default for all new and existing | | | installs, except those deployed on GitLab Omnibus. If you reply on the APIv4 parameter, enable the setting in <code>config.json</code> before upgrading. | | | An unused <code>ExtraUpdateAt</code> field will be removed from the channel modal. | | | This release includes support for post messages longer than the default of 4000 characters, but may require a manual database migration. This migration is | | | entirely optional, and need only be done if you want to enable post messages up to 16383 characters. For many installations, no migration will be required, or | | | the old limit remains sufficient. | | | To check your current post limit after upgrading to 5.0.0, look for a log message on startup: | | | <code>[2018/03/27 09:08:00 EDT] [INFO] Post.Message supports at most 16383 characters (65535 bytes)</code> | | | As of 5.0.0, the maximum post message size is 16383 (multi-byte) characters. If your logs show a number less than this limit and you want to enable longer | | | post messages, you will need to manually migrate your database as described below. This migration can be slow for larger <code>Posts</code> tables, so it's best to | | | schedule this upgrade during off-peak hours. | | | To migrate a MySQL database, connect to your database and run the following: | | | <code>ALTER TABLE Posts MODIFY COLUMN Message TEXT;</code> | | | To migrate a PostgreSQL database, connect to your database and run the following: | | | <code>ALTER TABLE Posts ALTER COLUMN Message TYPE VARCHAR(65535);</code> | | | Restart your Mattermost instances. | | | Deployments on Enterprise E20 will need to enable <code>RunJobs</code> in the <code>config.json</code> and allow the permissions migration to complete before using <a href="/docs/mattermost/onboard/advanced-permissions/" class="doc-ref">Team | | | Override Schemes</a>. | <table><thead><tr><th>v4.10.0</th><th>Old email invitation links will no longer work due to a bug fix where teams could be re-joined via the link. Team invite links copied from the Team Invite Link dialog, password reset links and email verification links are not affected and are still valid.</th></tr></thead></table> | | Server logs written to <strong>System Console > Logs</strong> and to the <code>mattermost.log</code> file specified in <strong>System Console > Logging > File Log Directory</strong> | | | now use JSON formatting. If you have built a tool that parses the server logs and sends them to an external system, make sure it supports the JSON format. | | | Team icons with transparency will be filled with a white background in the Team sidebar. | | | Those servers with SAML authentication enabled should upgrade during non-peak hours. SAML email addresses are migrated to lowercase to prevent login issues, | | | which could result in longer than usual upgrade time. | | | If you use PostgreSQL database and the password contains special characters (e.g. <code>[]</code>), escape them in your password, e.g., xxx[]xxx will be xxx%5B%5Dxxx. | <table><thead><tr><th>v4.9.0</th><th>To improve the production use of Mattermost with Docker, the Docker image is now running a as non-root user and listening on port 8000. Please read the <a href="https://github.com/mattermost/mattermost-docker#upgrading-mattermost-to-49">upgrade instructions</a> for important changes to existing installations.</th></tr></thead></table> | | Several configuration settings have been migrated to roles in the database and changing their <code>config.json</code> values no longer takes effect. These permissions | | | can still be modified by their respective System Console settings as before. The affected <code>config.json</code> settings are: | | | - <code>RestrictPublicChannelManagement</code>, | | | - <code>RestrictPrivateChannelManagement</code>, | | | - <code>RestrictPublicChannelCreation</code>, | | | - <code>RestrictPrivateChannelCreation</code>, | | | - <code>RestrictPublicChannelDeletion</code>, | | | - <code>RestrictPrivateChannelDeletion</code>, | | | - <code>RestrictPrivateChannelManageMembers</code>, | | | - <code>EnableTeamCreation</code>, | | | - <code>EnableOnlyAdminIntegrations</code>, | | | - <code>RestrictPostDelete</code>, | | | - <code>AllowEditPost</code>, | | | - <code>RestrictTeamInvite</code>, | | | - <code>RestrictCustomEmojiCreation</code>. | | | The behavior of the <code>config.json</code> setting <code>PostEditTimeLimit</code> has been updated to accommodate the migration to a roles based permission system. | | | When post editing is permitted, set <code>"PostEditTimeLimit": -1</code> to allow editing anytime, or set <code>"PostEditTimeLimit"</code> to a positive integer to restrict | | | editing time in seconds. If post editing is disabled, this setting does not apply. | | | If using Let's Encrypt without a proxy server, the server will fail to start with an error message unless the <a href="/docs/mattermost/configure/environment-configuration-settings/#forward-port-80-to-443" class="doc-ref">Forward80To443 | | |</a> <code>config.json</code> setting is set to <code>true</code>. | | | If forwarding port 80 to 443, the server will fail to start with an error message unless the <a href="/docs/mattermost/configure/environment-configuration-settings/#web-server-listen-address" class="doc-ref">ListenAddress | | |</a> <code>config.json</code> setting is set to listen on port 443. | <table><thead><tr><th>v4.6.2</th><th>If using Let's Encrypt without a proxy server, forward port 80 through a firewall, with the <a href="/docs/mattermost/configure/environment-configuration-settings/#forward-port-80-to-443" class="doc-ref">Forward80To443</a> <code>config.json</code> setting set to <code>true</code> to complete the Let's Encrypt certification.</th></tr><tr><th>v4.4.0</th><th>Composite database indexes were added to the <code>Posts</code> table. This may lead to longer upgrade times for servers with more than one million messages.</th></tr></thead></table> | | LDAP sync now depends on email. Make sure all users on your AD/LDAP server have an email address or that their account is deactivated in Mattermost. | <table><thead><tr><th>v4.2.0</th><th>Mattermost now handles multiple content types for integrations, including plaintext content type. If your integration suddenly prints the JSON payload data instead of rendering the generated message, make sure your integration is returning the <code>application/json</code> content-type to retain previous behavior.</th></tr></thead></table> | | By default, user-supplied URLs such as those used for Open Graph metadata, webhooks, or slash commands will no longer be allowed to connect to reserved IP | | | addresses including loopback or link-local addresses used for internal networks. | | | This change may cause private integrations to break in testing environments, which may point to a URL such as http://127.0.0.1:1021/my-command. | | | If you point private integrations to such URLs, you may whitelist such domains, IP addresses, or CIDR notations via the | | | <a href="/docs/mattermost/configure/environment-configuration-settings/#allow-untrusted-internal-connections" class="doc-ref">Allowed Untrusted Internal Connections</a> | | | configuration setting in your local environment. Although not recommended, you may also whitelist the addresses in your production environments. See | | | <a href="/docs/mattermost/configure/environment-configuration-settings/#allow-untrusted-internal-connections" class="doc-ref">documentation to learn more</a>. | | | Push notification, OAuth 2.0 and WebRTC server URLs are trusted and not affected by this setting. | | | Uploaded file attachments are now grouped by day and stored in <code>/data/<date-of-upload-as-YYYYMMDD>/teams/...</code> of your file storage system. | | | Mattermost `/platform<code> repo has been separated to </code>/mattermost-webapp<code> and </code>/mattermost-server``. This may affect you if you have a private fork of the | | | <code>/platform</code> repo. <a href="https://forum.mattermost.com/t/mattermost-separating-platform-into-two-repositories-on-september-6th/3708">More details here</a>. | <table><thead><tr><th>v4.0.0</th><th>(High Availability only) You must manually add new items to the <code>ClusterSettings</code> section of your existing <code>config.json</code>.</th></tr><tr><th>v3.9.0</th><th>Old email invitation links, password reset links, and email verification links will no longer work due to a security change. Team invite links copied from the Team Invite Link dialog are not affected and are still valid.</th></tr><tr><th>v3.8.0</th><th>A change is required in the proxy configuration. If you’re using NGINX: 1. Open the NGINX configuration file as root. The file is usually <code>/etc/nginx/sites-available/mattermost</code> but might be different on your system. 2. Locate the line: <code>location /api/v3/users/websocket {</code> 3. Replace the line with <code>location ~ /api/v[0-9]+/(users/)?websocket$ {</code> If you are using a proxy other than NGINX, make the equivalent change to that proxy's configuration.</th></tr></thead></table> | | You need to verify settings in the System Console due to a security-related change. | | | 1. Go to the the GENERAL section of the System Console | | | 2. Click <strong>Logging</strong> | | | 3. Make sure that the <strong>File Log Directory</strong> field is either empty or has a directory path only. It must not have a filename as part of the path. | | | Backwards compatibility with the old CLI tool was removed. If you have any scripts that rely on the old CLI, they must be revised to use the | | | <a href="/docs/mattermost/manage/command-line/" class="doc-ref">new CLI</a>. | <table><thead><tr><th>v3.6.0</th><th>Update the maximum number of files that can be open. On RHEL6 and Ubuntu 14.04: - Verify that the line <code>limit nofile 50000 50000</code> is included in the <code>/etc/init/mattermost.conf</code> file. On RHEL7 and Ubuntu 16.04: - Verify that the line <code>LimitNOFILE=49152</code> is included in the <code>/etc/systemd/system/mattermost.service</code> file.</th></tr></thead></table> | | (Enterprise Only) | | | Previous <code>config.json</code> values for restricting Public and Private channel management will be used as the default values for new settings for restricting | | | Public and Private channel creation and deletion. | <table><thead><tr><th>v3.4.0</th><th>If public links are enabled, existing public links will no longer be valid. This is because in earlier versions, existing public links were not invalidated when the Public Link Salt was regenerated. You must update any place where you have published these links.</th></tr></thead></table> .. _000141_add_remoteid_channelid_to_post_acknowledgements.down.sql: https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/postgres/000141_add_remoteid_channelid_to_post_acknowledgements.down.sql .. _000141_add_remoteid_channelid_to_post_acknowledgements.up.sql: https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/postgres/000141_add_remoteid_channelid_to_post_acknowledgements.up.sql .. _this guide: https://github.com/mattermost/mattermost-plugin-agents/blob/master/docs/upgrading_to_2.0.md <h2 id="추가-업그레이드-노트">추가 업그레이드 노트</h2> <div class="admonition note"><div class="admonition-title">Note

중요 업그레이드 노트

Mattermost v11.8
원문 보기
요약

이 페이지 하단의 추가 업그레이드 노트 를 검토하는 것을 권장합니다. - For AWS customers on OpenSearch, you must modify Mattermost configuration from elasticsearch to opensearch and disable compatibility mode.

Mattermost Server v10.11 확장 지원 릴리즈 지원이 2026년 8월 15일로 수명 주기가 종료될 예정입니다. Mattermost Server v11.7 이상으로 업그레이드하는 것이 권장됩니다.

이 페이지 하단의 추가 업그레이드 노트 를 검토하는 것을 권장합니다.

If you're upgrading from a version earlier than...Then...
v11.8커스텀 프로필 속성(Custom Profile Attributes) 속성 그룹의 이름이 custom_profile_attributes에서 access_control로 변경되며, CPA 필드와 값은 레거시 속성 모델에서 v2 모델로 마이그레이션됩니다. CPA 기능 자체의 동작은 변경되지 않습니다. CPA를 사용하는 플러그인 개발자는 새 그룹 이름으로 다시 등록해야 합니다.
| | PSAv1(레거시) 그룹과 PSAv2 그룹을 구분하기 위해 PropertyGroups 테이블에 새로운 Version 컬럼이 추가되었습니다. 기존 그룹은 버전 1을 기본값으로 사용하여 모든 레거시 호출자에 대한 현재 동작을 그대로 유지합니다. PropertyGroups는 설정 정보에 가까운 작은 테이블이며, ADD COLUMN ... DEFAULT 1 NOT NULL은 PostgreSQL에서 메타데이터 전용 작업입니다 — 테이블 재작성이 발생하지 않으며 PropertyGroups에 대한 AccessExclusiveLock은 밀리초 단위로만 유지됩니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: | | |
|

|                                                    |    -- Pre-upgrade schema changes (Mattermost 11.8).                                                                                                              |

|                                                    |     ALTER TABLE PropertyGroups ADD COLUMN IF NOT EXISTS Version integer DEFAULT 1 NOT NULL;                                                                      |

|                                                    | <code>posts.rootid</code>와 <code>posts.channelid</code>에 대한 PostgreSQL 플래너 통계 목표치를 기본값 100에서 5000으로 높이고, <code>ANALYZE posts (rootid, channelid)</code>로 플래너 통계를 새로 고칩니다. <code>ALTER COLUMN ... SET STATISTICS</code> 문은 메타데이터 전용 작업으로 <code>SHARE UPDATE EXCLUSIVE</code> 잠금만 획득합니다 — 테이블 재작성이 발생하지 않으며 <code>posts</code>에 대한 동시 SELECT, INSERT, UPDATE, DELETE는 차단되지 않습니다. <code>ANALYZE</code> 단계는 더 큰 샘플 크기로 인해 대규모 <code>posts</code> 테이블(1억 건 이상)에서 수 분이 걸릴 수 있지만, 읽기나 쓰기를 차단하지는 않습니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: |

|                                                    | |
|                                                    |    ALTER TABLE posts ALTER COLUMN rootid SET STATISTICS 5000;                                                                                                    |
|                                                    |    ALTER TABLE posts ALTER COLUMN channelid SET STATISTICS 5000;                                                                                                 |
|                                                    |    ANALYZE posts (rootid, channelid);                                                                                                                            |
|                                                    | <code>channel_type</code> 열거형(enum)에 <code>'BO'</code>와 <code>'BP'</code> 두 개의 새 값이 추가되었습니다. <code>ALTER TYPE ... ADD VALUE</code> 문은 <code>channel_type</code> 타입에만 짧은 <code>AccessExclusiveLock</code>을 획득합니다 — 테이블 재작성이 발생하지 않으며 <code>channels</code> 테이블에 행 단위 잠금이 적용되지 않아 작업이 거의 즉시 완료됩니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: |
|                                                    ||
|                                                    |    ALTER TYPE channel_type ADD VALUE IF NOT EXISTS 'BO';                                                                                                         |
|                                                    |    ALTER TYPE channel_type ADD VALUE IF NOT EXISTS 'BP';                                                                                                         |
|                                                    | 동일한 릴리즈 주기의 일환으로 속성/애트리뷰트 시스템(<code>PropertyFields</code>, <code>PropertyGroups</code>, <code>AttributeView</code>)에 네 건의 스키마 마이그레이션이 도입되었습니다. 마이그레이션 000168과 000169는 <code>PropertyFields</code>에 nullable <code>LinkedFieldID varchar(26)</code> 컬럼과 이에 대한 부분 동시 인덱스를 추가하여 필드가 다른 필드를 링크로 참조할 수 있게 합니다. 마이그레이션 000176과 000177은 <code>PropertyFields</code> 행의 권한 컬럼을 업데이트하고, <code>PropertyGroups</code> 항목의 이름을 <code>custom_profile_attributes</code>에서 <code>access_control</code>로 변경하며, <code>AttributeView</code> 구체화 뷰(materialized view)를 사용자 범위 애트리뷰트로만 좁혀서 기존 커스텀 프로필 애트리뷰트 속성 그룹을 더 범용적인 <code>access_control</code> 그룹으로 승격시킵니다.<strong>마이그레이션 000176과 000177은 반드시 함께 배포되어야 합니다.</strong> 영향을 받는 테이블 중 대용량 테이블 목록에 속하는 것은 없습니다 — 속성 시스템 테이블은 규모가 작습니다. 참고: 롤링 업그레이드 기간 동안 그룹 조회 키로 <code>'custom_profile_attributes'</code>를 하드코딩한 구버전 ESR 노드는 CPA 프로필 읽기/쓰기 엔드포인트와 ABAC 정책 관리 관리자 UI에서 일시적인 오류를 겪게 됩니다. 최종 사용자 채널 접근과 멤버십 동기화 워커는 영향을 받지 않습니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: |

|                                                    | |
|                                                    |    -- 000168: Add LinkedFieldID column                                                                                                                           |
|                                                    |    ALTER TABLE PropertyFields ADD COLUMN IF NOT EXISTS LinkedFieldID varchar(26);                                                                                |
|                                                    |    -- 000169: Create partial index on LinkedFieldID                                                                                                              |
|                                                    |    CREATE INDEX CONCURRENTLY idx_propertyfields_linkedfieldid ON PropertyFields(LinkedFieldID) WHERE LinkedFieldID IS NOT NULL AND DeleteAt = 0;                 |
|                                                    |    -- 000176: Migrate CPA to access_control                                                                                                                      |
|                                                    |    UPDATE PropertyFields SET ObjectType = 'user' WHERE GroupID = (SELECT Id FROM PropertyGroups WHERE Name = 'custom_profile_attributes');                       |
|                                                    |    UPDATE PropertyGroups SET Name = 'access_control', Version = 2 WHERE Name = 'custom_profile_attributes';                                                      |
|                                                    |    -- 000177: Refresh AttributeView with user-scoped filter                                                                                                      |
|                                                    |    DROP MATERIALIZED VIEW AttributeView;                                                                                                                         |
|                                                    |    CREATE MATERIALIZED VIEW AttributeView ... WHERE pf.ObjectType = 'user';                                                                                      |
|                                                    | Mattermost v11.8에서는 <code>Recaps</code> 테이블에 새로운 <code>ViewedAt</code> 컬럼과 <code>(UserId, ViewedAt)</code>에 대한 새 인덱스 형태의 스키마 변경이 도입됩니다. 컬럼 추가는 메타데이터 전용 작업이며, 인덱스는 <code>CONCURRENTLY</code>를 사용해 생성되므로 테이블 잠금이 발생하지 않고 테이블에 대한 기존 작업에도 영향을 주지 않습니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: |
|                                                    ||
|                                                    |    -- 000172_add_recaps_viewed_at.up.sql                                                                                                                         |
|                                                    |    ALTER TABLE Recaps ADD COLUMN IF NOT EXISTS ViewedAt BIGINT NOT NULL DEFAULT 0;                                                                               |
|                                                    |    -- 000172_add_recaps_viewed_at.down.sql                                                                                                                       |
|                                                    |    ALTER TABLE Recaps DROP COLUMN IF EXISTS ViewedAt;                                                                                                            |
|                                                    |    -- 000173_create_recaps_user_id_viewed_at_index.up.sql                                                                                                        |
|                                                    |    -- morph:nontransactional                                                                                                                                     |
|                                                    |    CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_recaps_user_id_viewed_at ON Recaps(UserId, ViewedAt);                                                             |
|                                                    |    -- 000173_create_recaps_user_id_viewed_at_index.down.sql                                                                                                      |
|                                                    |    -- morph:nontransactional                                                                                                                                     |
|                                                    |    DROP INDEX CONCURRENTLY IF EXISTS idx_recaps_user_id_viewed_at;                                                                                               |
|                                                    | Mattermost v11.8에서는 새로운 채널 가입 요청 워크플로와 검색 가능한(discoverable) 비공개 채널을 지원하는 여섯 건의 스키마 변경이 도입됩니다. <code>Channels</code> 테이블에 <code>Discoverable</code> 불리언 컬럼(<code>DEFAULT FALSE</code>)이 추가되며, 이는 PostgreSQL 11 이상에서 즉시 완료되는 메타데이터 전용 작업입니다. 접근 요청 워크플로를 관리하기 위한 새로운 <code>ChannelJoinRequests</code> 테이블이 생성되어 요청 상태, 거부 사유, 검토자 정보를 추적합니다. 이어서 네 개의 동시(concurrent) 인덱스가 추가됩니다: 검색 가능한 팀 채널을 위한 <code>Channels</code>의 부분 인덱스(<code>idx_channels_discoverable_team</code>), 대기 중인 요청을 위한 <code>ChannelJoinRequests</code>의 고유 부분 인덱스(<code>idx_channeljoinrequests_pending_unique</code>), 그리고 각각 채널+상태, 사용자+상태 기준 쿼리를 최적화하는 두 개의 복합 인덱스입니다. 모든 인덱스 작업은 <code>CONCURRENTLY</code>를 사용하며 명시적 트랜잭션 블록 밖에서 실행해야 합니다. 이 마이그레이션들은 PostgreSQL 전용입니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: |
|                                                    ||
|                                                    |    -- Migration 000178: Add Discoverable column                                                                                                                  |
|                                                    |    ALTER TABLE Channels ADD COLUMN IF NOT EXISTS Discoverable BOOLEAN NOT NULL DEFAULT FALSE;                                                                    |
|                                                    ||
|                                                    |    -- Migration 000179: Partial index for discoverable channels                                                                                                  |                                                                                               
|                                                    |    -- Run outside a transaction block.                                                                                                                           |
|                                                    |    CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_channels_discoverable_team                                                                                        |
|                                                    |        ON Channels (TeamId)                                                                                                                                      |
|                                                    |        WHERE Discoverable = TRUE AND Type = 'P' AND DeleteAt = 0;                                                                                                |
|                                                    ||
|                                                    |    -- Migration 000180: Create ChannelJoinRequests table                                                                                                         |
|                                                    |    CREATE TABLE IF NOT EXISTS ChannelJoinRequests (                                                                                                              |
|                                                    |        Id           VARCHAR(26)  PRIMARY KEY,                                                                                                                    |
|                                                    |        ChannelId    VARCHAR(26)  NOT NULL,                                                                                                                       |
|                                                    |        UserId       VARCHAR(26)  NOT NULL,                                                                                                                       |
|                                                    |        Message      TEXT         NOT NULL DEFAULT '',                                                                                                            |
|                                                    |        Status       VARCHAR(16)  NOT NULL DEFAULT 'pending',                                                                                                     |
|                                                    |        DenialReason TEXT         NOT NULL DEFAULT '',                                                                                                            |
|                                                    |        CreateAt     BIGINT       NOT NULL,                                                                                                                       |
|                                                    |        UpdateAt     BIGINT       NOT NULL,                                                                                                                       |
|                                                    |        ReviewedBy   VARCHAR(26)  NOT NULL DEFAULT '',                                                                                                            |
|                                                    |        ReviewedAt   BIGINT       NOT NULL DEFAULT 0                                                                                                              |
|                                                    |    );                                                                                                                                                            |
|                                                    ||
|                                                    |    -- Migration 000181: Unique index for pending requests                                                                                                        |
|                                                    |    -- Run outside a transaction block.                                                                                                                           |
|                                                    |    CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS idx_channeljoinrequests_pending_unique                                                                         |
|                                                    |        ON ChannelJoinRequests (ChannelId, UserId)                                                                                                                |
|                                                    |        WHERE Status = 'pending';                                                                                                                                 |
|                                                    ||
|                                                    |    -- Migration 000182: Index for channel+status queries                                                                                                         |
|                                                    |    -- Run outside a transaction block.                                                                                                                           |
|                                                    |    CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_channeljoinrequests_channel_status_createat                                                                       |
|                                                    |        ON ChannelJoinRequests (ChannelId, Status, CreateAt DESC);                                                                                                |
|                                                    ||
|                                                    |    -- Migration 000183: Index for user+status queries                                                                                                            |
|                                                    |    -- Run outside a transaction block.                                                                                                                           |
|                                                    |    CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_channeljoinrequests_user_status_createat                                                                          |
|                                                    |        ON ChannelJoinRequests (UserId, Status, CreateAt DESC);                                                                                                   |
|                                                    | Mattermost v11.8에서는 기존 <code>none</code>, <code>sysadmin</code>, <code>member</code> 값에 더해 <code>admin</code> 값을 포함하도록 <code>permission_level</code> PostgreSQL 열거형(enum) 타입이 확장됩니다. 이는 순수한 카탈로그 변경입니다 <code>— ALTER TYPE ADD VALUE</code>는 <code>pg_type</code> 시스템 카탈로그만 갱신하며 <code>PropertyFields</code> 테이블이나 다른 애플리케이션 테이블은 건드리지 않습니다. up 마이그레이션에서는 컬럼, 인덱스, 테이블 데이터가 전혀 변경되지 않습니다. 이 변경으로 속성 필드 접근 제어 모델에 새로운 관리자 수준 권한 등급이 추가됩니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: |
|                                                    ||
|                                                    |    -- 000189_add_admin_to_permission_level.up.sql                                                                                                                |
|                                                    |    ALTER TYPE permission_level ADD VALUE IF NOT EXISTS 'admin';                                                                                                  |
<table><thead><tr><th>v11.7</th><th>FIPS 빌드는 비밀번호, atmos/camo 프록시 구성 및 공유 채널 시크릿에 최소 14자를 요구합니다. 기존 사용자의 짧은 비밀번호는 더 이상 유효하지 않으며 비밀번호 재설정이 필요합니다. 비 FIPS 빌드는 영향을 받지 않습니다.</th></tr></thead></table>
|                                                    | <code>AccessControlPolicies</code> 테이블에 (Name, Type)에 대한 새로운 부분 고유 인덱스(<code>idx_accesscontrolpolicies_name_type</code>)가 추가되어 <code>WHERE Type = 'parent'</code>로 필터링됩니다. 인덱스 생성 전에 중복 상위 정책 이름은 가장 오래된 항목을 제외하고 모두 정책 ID를 추가하여 해결됩니다. 이는 상위 정책 이름의 고유성을 강화하고 향후 중복 생성을 방지합니다. 마이그레이션은 1초 미만이 소요됩니다. 마이그레이션은 게시물이나 반응이 아닌 <code>AccessControlPolicies</code>를 대상으로 합니다. <code>AttributeBasedAccessControl</code>이 활성화되지 않은 배포에서는 테이블이 비어 있으며 마이그레이션이 1초 미만에 완료됩니다. 플래그가 활성화된 배포에서는 상위 정책 수가 적을 것으로 예상되므로 타이밍은 여전히 무시할 수 있는 수준입니다. <code>CREATE UNIQUE INDEX</code>(비동시)는 <code>AccessControlPolicies</code>에 <code>SHARE</code> 잠금을 획득하여 인덱스 빌드 기간 동안 동시 <code>INSERT/UPDATE/DELETE</code>를 차단합니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는:                                                            |
|                                                    ||
|                                                    |    -- PostgreSQL only (MySQL not supported in v11+):                                                                                                             |
|                                                    |      -- Deduplicate parent policy names before adding unique constraint.                                                                                         |
|                                                    |      -- The oldest policy (by CreateAt) keeps its original name; duplicates get ' (<id>)' appended.                                                              |
|                                                    |      UPDATE AccessControlPolicies AS p                                                                                                                           |
|                                                    |      SET Name = LEFT(p.Name, 128 - LENGTH(' (' || p.ID || ')')) || ' (' || p.ID || ')'                                                                           |
|                                                    |      FROM (                                                                                                                                                      |
|                                                    |          SELECT ID, Name, ROW_NUMBER() OVER (PARTITION BY Name ORDER BY CreateAt ASC) AS rn                                                                      |
|                                                    |          FROM AccessControlPolicies                                                                                                                              |
|                                                    |          WHERE Type = 'parent'                                                                                                                                   |
|                                                    |      ) AS dupes                                                                                                                                                  |
|                                                    |      WHERE p.ID = dupes.ID                                                                                                                                       |
|                                                    |        AND dupes.rn > 1;                                                                                                                                         |
|                                                    |      CREATE UNIQUE INDEX IF NOT EXISTS idx_accesscontrolpolicies_name_type                                                                                       |
|                                                    |        ON AccessControlPolicies (Name, Type)                                                                                                                     |
|                                                    |        WHERE Type = 'parent';                                                                                                                                    |
|                                                    | <code>PropertyFields</code> 테이블이 수정됩니다. 각 필드를 생성하고 마지막으로 수정한 사용자를 추적하는 두 개의 새로운 nullable 열, <code>CreatedBy</code> 및 <code>UpdatedBy</code>가 추가됩니다. 새로운 <code>ObjectType</code> 열이 <code>NOT NULL</code> 제약 조건과 빈 문자열 기본값으로 추가되어 레거시 및 타입이 지정된 속성 필드를 구분합니다. 새로운 <code>Protected</code> boolean 열이 <code>FALSE</code> 기본값으로 추가되고, 세 개의 새 열(<code>PermissionField</code>, <code>PermissionValues</code>, <code>PermissionOptions</code>)이 none, sysadmin, member 값을 가진 새 <code>permission_level</code> enum 타입과 함께 추가됩니다. (GroupID, TargetID, Name)에 대한 기존 고유 인덱스 <code>idx_propertyfields_unique</code>가 삭제되고 두 개의 새로운 부분 고유 인덱스로 교체됩니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는:                                                           |
|                                                    ||
|                                                    |   --- 160                                                                                                                                                        |
|                                                    |   ALTER TABLE PropertyFields                                                                                                                                     |
|                                                    |   ADD COLUMN IF NOT EXISTS CreatedBy varchar(26),                                                                                                                |
|                                                    |   ADD COLUMN IF NOT EXISTS UpdatedBy varchar(26);                                                                                                                |
|                                                    |   ALTER TABLE PropertyValues                                                                                                                                     |
|                                                    |   ADD COLUMN IF NOT EXISTS CreatedBy varchar(26),                                                                                                                |
|                                                    |   ADD COLUMN IF NOT EXISTS UpdatedBy varchar(26);                                                                                                                |
|                                                    |   --- 161                                                                                                                                                        |
|                                                    |   ALTER TABLE PropertyFields ADD COLUMN IF NOT EXISTS ObjectType varchar(255) NOT NULL DEFAULT '';                                                               |
|                                                    |   --- 162                                                                                                                                                        |
|                                                    |   DROP INDEX CONCURRENTLY IF EXISTS idx_propertyfields_unique;                                                                                                   |
|                                                    |   --- 163                                                                                                                                                        |
|                                                    |   CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS idx_propertyfields_unique_legacy                                                                                |
|                                                    |       ON PropertyFields (GroupID, TargetID, Name)                                                                                                                |
|                                                    |       WHERE DeleteAt = 0 AND ObjectType = '';                                                                                                                    |
|                                                    |   --- 164                                                                                                                                                        |
|                                                    |   CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS idx_propertyfields_unique_typed                                                                                 |
|                                                    |       ON PropertyFields (ObjectType, GroupID, TargetType, TargetID, Name)                                                                                        |
|                                                    |       WHERE DeleteAt = 0 AND ObjectType != '';                                                                                                                   |
|                                                    |   --- 165                                                                                                                                                        |
|                                                    |   DO $$                                                                                                                                                          |
|                                                    |   BEGIN                                                                                                                                                          |
|                                                    |     IF NOT EXISTS (SELECT * FROM pg_type typ                                                                                                                     |
|                                                    |                               INNER JOIN pg_namespace nsp ON nsp.oid = typ.typnamespace                                                                          |
|                                                    |                           WHERE nsp.nspname = current_schema()                                                                                                   |
|                                                    |                               AND typ.typname = 'permission_level') THEN                                                                                         |
|                                                    |       CREATE TYPE permission_level AS ENUM ('none', 'sysadmin', 'member');                                                                                       |
|                                                    |     END IF;                                                                                                                                                      |
|                                                    |   END;                                                                                                                                                           |
|                                                    |   $$                                                                                                                                                             |
|                                                    |   LANGUAGE plpgsql;                                                                                                                                              |
|                                                    |   ALTER TABLE PropertyFields                                                                                                                                     |
|                                                    |   ADD COLUMN IF NOT EXISTS Protected BOOLEAN NOT NULL DEFAULT FALSE,                                                                                             |
|                                                    |   ADD COLUMN IF NOT EXISTS PermissionField permission_level,                                                                                                     |
|                                                    |   ADD COLUMN IF NOT EXISTS PermissionValues permission_level,                                                                                                    |
|                                                    |   ADD COLUMN IF NOT EXISTS PermissionOptions permission_level;                                                                                                   |
|                                                    |   --- 166                                                                                                                                                        |
|                                                    |   CREATE TABLE IF NOT EXISTS Views (                                                                                                                             |
|                                                    |       Id          VARCHAR(26)  PRIMARY KEY,                                                                                                                      |
|                                                    |       ChannelId   VARCHAR(26)  NOT NULL,                                                                                                                         |
|                                                    |       Type        VARCHAR(32)  NOT NULL,                                                                                                                         |
|                                                    |       CreatorId   VARCHAR(26)  NOT NULL,                                                                                                                         |
|                                                    |       Title       VARCHAR(256) NOT NULL,                                                                                                                         |
|                                                    |       Description TEXT,                                                                                                                                          |
|                                                    |       SortOrder   INTEGER      NOT NULL DEFAULT 0,                                                                                                               |
|                                                    |       Props       jsonb,                                                                                                                                         |
|                                                    |       CreateAt    BIGINT       NOT NULL,                                                                                                                         |
|                                                    |       UpdateAt    BIGINT       NOT NULL,                                                                                                                         |
|                                                    |       DeleteAt    BIGINT       NOT NULL DEFAULT 0                                                                                                                |
|                                                    |   );                                                                                                                                                             |
|                                                    |   --- 167                                                                                                                                                        |
|                                                    |   CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_views_channel_id_delete_at ON Views(ChannelId, DeleteAt);                                                          |
|                                                    |   --- 171                                                                                                                                                        |
|                                                    |   DROP INDEX CONCURRENTLY IF EXISTS idx_propertyfields_protected;                                                                                                |
|                                                    | <code>role_updated</code> WebSocket 이벤트는 전역 브로드캐스트 대신 영향받는 팀/채널로 범위가 지정되어 성능이 향상되고 불필요한 네트워크 트래픽이 줄어듭니다. 업그레이드 중 마이그레이션이 자동으로 실행되므로 관리자의 수동 조치가 필요하지 않습니다. 다운타임이 예상되지 않으며 마이그레이션은 정상 운영 중에 실행될 수 있으므로 업그레이드를 위한 특별한 계획이 필요하지 않습니다. 모든 설치가 이 변경의 영향을 받지만 <code>roles</code> 테이블은 대규모 설치에서도 10k 행 미만으로 작기 때문에 영향은 최소화됩니다. 업그레이드에는 효율적인 역할-스키마 조회를 위해 <code>roles</code> 테이블에 <code>schemeid</code> 열을 추가하는 자동 데이터베이스 마이그레이션이 포함됩니다. 마이그레이션은 PostgreSQL의 비차단(non-blocking) 기법을 사용합니다. 먼저 짧은 ACCESS EXCLUSIVE 잠금(카탈로그 전용 작업)으로 컬럼을 추가하고, ROW EXCLUSIVE 잠금으로 기존 데이터를 백필한 다음, 다른 작업을 차단하지 않는 SHARE UPDATE EXCLUSIVE 잠금으로 인덱스를 동시에 생성합니다. <code>roles</code> 테이블 크기는 제한적이며 게시물(post), 반응(reaction) 등 대용량 데이터의 영향을 받지 않습니다. 마이그레이션은 완전히 하위 호환됩니다. |
|                                                    | v11.7에는 Agents 플러그인 v2가 포함됩니다. v1.x 릴리즈에서 v2.0.0으로 Mattermost Agents 플러그인을 업그레이드하는 방법에 대해 <code>이 가이드</code>를 참조하세요. 지원되는 버전 경로, v2.0.0 첫 시작 시 자동으로 실행되는 마이그레이션, 업그레이드 창 전에 관리자가 알아야 할 주요 변경 사항 및 기본 동작 변경, 그리고 업그레이드 성공을 확인하는 검증 단계를 다룹니다.                                                                                                                             |
<table><thead><tr><th>v11.6</th><th>단일 채널 게스트는 더 이상 기본 라이선스 시트 수에 포함되지 않으며, 라이선스 시트와 1:1 비율로 무료로 허용됩니다. 새로운 통계 카드, 라이선스 행, 관리자 배너가 추가되어 단일 채널 게스트 사용량 및 초과 경고를 확인할 수 있습니다.</th></tr></thead></table>
|                                                    | v11.6.2부터 <code>role_updated</code> WebSocket 이벤트는 전역 브로드캐스트 대신 영향받는 팀/채널로 범위가 지정되어 성능이 향상되고 불필요한 네트워크 트래픽이 줄어듭니다. 업그레이드 중 마이그레이션이 자동으로 실행되므로 관리자의 수동 조치가 필요하지 않습니다. 다운타임이 예상되지 않으며 마이그레이션은 정상 운영 중에 실행될 수 있으므로 업그레이드를 위한 특별한 계획이 필요하지 않습니다. 모든 설치가 이 변경의 영향을 받지만 <code>roles</code> 테이블은 대규모 설치에서도 10k 행 미만으로 작기 때문에 영향은 최소화됩니다. 업그레이드에는 효율적인 역할-스키마 조회를 위해 <code>roles</code> 테이블에 <code>schemeid</code> 열을 추가하는 자동 데이터베이스 마이그레이션이 포함됩니다. 마이그레이션은 PostgreSQL의 비차단(non-blocking) 기법을 사용합니다. 먼저 짧은 ACCESS EXCLUSIVE 잠금(카탈로그 전용 작업)으로 컬럼을 추가하고, ROW EXCLUSIVE 잠금으로 기존 데이터를 백필한 다음, 다른 작업을 차단하지 않는 SHARE UPDATE EXCLUSIVE 잠금으로 인덱스를 동시에 생성합니다. <code>roles</code> 테이블 크기는 제한적이며 게시물(post), 반응(reaction) 등 대용량 데이터의 영향을 받지 않습니다. 마이그레이션은 완전히 하위 호환됩니다. |
<table><thead><tr><th>v11.5</th><th><code>translations</code> 테이블에 새 컬럼 <code>translations.state</code>와 새 인덱스 <code>idx_translations_state</code>가 추가되었습니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는:ALTER TABLE translations ADD COLUMN IF NOT EXISTS state varchar(20) NOT NULL; CREATE INDEX IF NOT EXISTS idx_translations_state ON translations(state) WHERE state IN ('processing');</th></tr></thead></table>
|                                                    | <code>channelmembers</code> 테이블에 새 컬럼 <code>channelmembers.autotranslationdisabled</code>가 추가되었습니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: |
|                                                    ||
|                                                    |   ALTER TABLE channelmembers                                                                                                                                     | 
|                                                    |       ADD COLUMN IF NOT EXISTS autotranslationdisabled boolean NOT NULL DEFAULT false;                                                                           |
|                                                    | <code>translations</code> 테이블에서 <code>translations.objectType</code> 컬럼을 수정하고 기본 키를 <code>(objectId, dstLang)</code>에서 <code>(objectId, objectType, dstLang)</code>로 변경했습니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: |
|                                                    ||
|                                                    |   UPDATE translations SET objectType = 'post' WHERE objectType IS NULL;                                                                                          |
|                                                    |   ALTER TABLE translations ALTER COLUMN objectType SET NOT NULL;                                                                                                 |
|                                                    |   ALTER TABLE translations DROP CONSTRAINT translations_pkey;                                                                                                    |
|                                                    |   ALTER TABLE translations ADD PRIMARY KEY (objectId, objectType, dstLang);                                                                                      |
|                                                    | <code>translations</code> 테이블에 새 컬럼 <code>translations.channelid</code>가 추가되었습니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: |
|                                                    ||
|                                                    |   ALTER TABLE translations ADD COLUMN IF NOT EXISTS channelid varchar(26);                                                                                       |
|                                                    | <code>translations</code> 테이블에 새 인덱스 <code>idx_translations_channel_updateat</code>가 추가되었습니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: |
|                                                    ||
|                                                    |   -- morph:nontransactional                                                                                                                                      |
|                                                    |   CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_translations_channel_updateat                                                                                      |
|                                                    |       ON translations(channelid, objectType, updateAt DESC, dstlang);                                                                                            |
|                                                    | <code>translations</code> 테이블에서 인덱스 <code>idx_translations_updateat</code>가 삭제되었습니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: |
|                                                    ||
|                                                    |   -- morph:nontransactional                                                                                                                                      |
|                                                    |   DROP INDEX CONCURRENTLY IF EXISTS idx_translations_updateat;                                                                                                   |
|                                                    | v11.5.5부터 <code>role_updated</code> WebSocket 이벤트는 전역 브로드캐스트 대신 영향받는 팀/채널로 범위가 지정되어 성능이 향상되고 불필요한 네트워크 트래픽이 줄어듭니다. 업그레이드 중 마이그레이션이 자동으로 실행되므로 관리자의 수동 조치가 필요하지 않습니다. 다운타임이 예상되지 않으며 마이그레이션은 정상 운영 중에 실행될 수 있으므로 업그레이드를 위한 특별한 계획이 필요하지 않습니다. 모든 설치가 이 변경의 영향을 받지만 <code>roles</code> 테이블은 대규모 설치에서도 10k 행 미만으로 작기 때문에 영향은 최소화됩니다. 업그레이드에는 효율적인 역할-스키마 조회를 위해 <code>roles</code> 테이블에 <code>schemeid</code> 열을 추가하는 자동 데이터베이스 마이그레이션이 포함됩니다. 마이그레이션은 PostgreSQL의 비차단(non-blocking) 기법을 사용합니다. 먼저 짧은 ACCESS EXCLUSIVE 잠금(카탈로그 전용 작업)으로 컬럼을 추가하고, ROW EXCLUSIVE 잠금으로 기존 데이터를 백필한 다음, 다른 작업을 차단하지 않는 SHARE UPDATE EXCLUSIVE 잠금으로 인덱스를 동시에 생성합니다. <code>roles</code> 테이블 크기는 제한적이며 게시물(post), 반응(reaction) 등 대용량 데이터의 영향을 받지 않습니다. 마이그레이션은 완전히 하위 호환됩니다. |
<table><thead><tr><th>v11.4</th><th>Photoshop 문서(PSD) 파일은 더 이상 인라인으로 미리보기되지 않으며 일반 첨부 파일로 처리됩니다.</th></tr></thead></table>
|                                                    | 새 테이블 <code>Recaps</code>와 <code>RecapChannels</code>가 추가되었습니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: |
|                                                    ||
|                                                    |   -- Recaps table: stores recap metadata                                                                                                                         |
|                                                    |   CREATE TABLE IF NOT EXISTS Recaps (                                                                                                                            |
|                                                    |       Id VARCHAR(26) PRIMARY KEY,                                                                                                                                |
|                                                    |       UserId VARCHAR(26) NOT NULL,                                                                                                                               |
|                                                    |       Title VARCHAR(255) NOT NULL,                                                                                                                               |
|                                                    |       CreateAt BIGINT NOT NULL,                                                                                                                                  |
|                                                    |       UpdateAt BIGINT NOT NULL,                                                                                                                                  |
|                                                    |       DeleteAt BIGINT NOT NULL,                                                                                                                                  |
|                                                    |       TotalMessageCount INT NOT NULL,                                                                                                                            |
|                                                    |       Status VARCHAR(32) NOT NULL,                                                                                                                               |
|                                                    |       ReadAt BIGINT DEFAULT 0 NOT NULL,                                                                                                                          |
|                                                    |       BotID VARCHAR(26) DEFAULT '' NOT NULL                                                                                                                      |
|                                                    |   );                                                                                                                                                             |
|                                                    |   CREATE INDEX IF NOT EXISTS idx_recaps_user_id ON Recaps(UserId);                                                                                               |
|                                                    |   CREATE INDEX IF NOT EXISTS idx_recaps_create_at ON Recaps(CreateAt);                                                                                           |
|                                                    |   CREATE INDEX IF NOT EXISTS idx_recaps_user_id_delete_at ON Recaps(UserId, DeleteAt);                                                                           |
|                                                    |   CREATE INDEX IF NOT EXISTS idx_recaps_user_id_read_at ON Recaps(UserId, ReadAt);                                                                               |
|                                                    |   CREATE INDEX IF NOT EXISTS idx_recaps_bot_id ON Recaps(BotID);                                                                                                 |
|                                                    |   -- RecapChannels table: stores per-channel summaries                                                                                                           |
|                                                    |   CREATE TABLE IF NOT EXISTS RecapChannels (                                                                                                                     |
|                                                    |       Id VARCHAR(26) PRIMARY KEY,                                                                                                                                |
|                                                    |       RecapId VARCHAR(26) NOT NULL,                                                                                                                              |
|                                                    |       ChannelId VARCHAR(26) NOT NULL,                                                                                                                            |
|                                                    |       ChannelName VARCHAR(64) NOT NULL,                                                                                                                          |
|                                                    |       Highlights TEXT,                                                                                                                                           |
|                                                    |       ActionItems TEXT,                                                                                                                                          |
|                                                    |       SourcePostIds TEXT,                                                                                                                                        |
|                                                    |       CreateAt BIGINT NOT NULL,                                                                                                                                  |
|                                                    |       FOREIGN KEY (RecapId) REFERENCES Recaps(Id) ON DELETE CASCADE                                                                                              |
|                                                    |   );                                                                                                                                                             |
|                                                    |   CREATE INDEX IF NOT EXISTS idx_recap_channels_recap_id ON RecapChannels(RecapId);                                                                              |
|                                                    |   CREATE INDEX IF NOT EXISTS idx_recap_channels_channel_id ON RecapChannels(ChannelId);                                                                          |
<table><thead><tr><th>v11.3</th><th>v11.3.1부터 Photoshop 문서(PSD) 파일은 더 이상 인라인으로 미리보기되지 않으며 일반 첨부 파일로 처리됩니다.</th></tr></thead></table>
|                                                    | 사용자 속성을 별도 테이블로 집계하는 새 테이블(<code>ReadReceipts</code>, <code>TemporaryPosts</code>) 형태의 스키마 변경이 추가되었습니다. <code>Drafts</code>와 <code>ScheduledPosts</code> 모두에 <code>Type</code> 필드가 추가되었습니다. 이전 버전의 Mattermost도 새 스키마 변경과 함께 실행될 수 있습니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 포함된 SQL 쿼리는: |
|                                                    ||
|                                                    |   CREATE TABLE IF NOT EXISTS ReadReceipts (                                                                                                                      |
|                                                    |       PostId VARCHAR(26) NOT NULL,                                                                                                                               |
|                                                    |       UserId VARCHAR(26) NOT NULL,                                                                                                                               |
|                                                    |       ExpireAt bigint NOT NULL,                                                                                                                                  |
|                                                    |       PRIMARY KEY (PostId, UserId)                                                                                                                               |
|                                                    |   );                                                                                                                                                             |
|                                                    |   CREATE INDEX IF NOT EXISTS idx_read_receipts_post_id ON ReadReceipts(PostId);                                                                                  |
|                                                    |   CREATE INDEX IF NOT EXISTS idx_read_receipts_user_id_post_id_expire_at ON ReadReceipts(UserId, PostId, ExpireAt);                                              |
|                                                    |   CREATE TABLE IF NOT EXISTS TemporaryPosts (                                                                                                                    |
|                                                    |       PostId VARCHAR(26) PRIMARY KEY,                                                                                                                            |
|                                                    |       Type VARCHAR(26) NOT NULL,                                                                                                                                 |
|                                                    |       ExpireAt BIGINT NOT NULL,                                                                                                                                  |
|                                                    |       Message VARCHAR(65535),                                                                                                                                    |
|                                                    |       FileIds VARCHAR(300)                                                                                                                                       |
|                                                    |   );                                                                                                                                                             |
|                                                    |   CREATE INDEX IF NOT EXISTS idx_temporary_posts_expire_at ON TemporaryPosts(expireat);                                                                          |
|                                                    |   ALTER TABLE drafts ADD COLUMN IF NOT EXISTS Type text;                                                                                                         |
|                                                    |   ALTER TABLE scheduledposts ADD COLUMN IF NOT EXISTS Type text;                                                                                                 |             
|                                                    | 새 테이블 <code>translations</code>, 두 개의 새 컬럼(<code>channels.autotranslation</code>, <code>channelmembers.autotranslation)</code>), 그리고 네 개의 새 인덱스가 추가되었습니다. 마이그레이션은 완전히 하위 호환되며 테이블 재작성이 없습니다. 1초 미만의 다운타임이 필요합니다. 업그레이드 전에 <code>CREATE INDEX CONCURRENTLY</code>를 사용하면 완전한 무중단 업그레이드를 위한 제로 다운타임도 가능합니다. 표준 업그레이드는 모든 인스턴스 크기에서 안전하며, 제로 다운타임이 반드시 필요한 경우가 아니라면 특별한 수동 조치는 필요하지 않습니다. 완전한 제로 다운타임을 위한 SQL 쿼리는: |
|                                                    ||
|                                                    |  CREATE INDEX CONCURRENTLY IF NOT EXISTS                                                                                                                         |
|                                                    |  idx_channelmembers_autotranslation_enabled                                                                                                                      |
|                                                    |     ON channelmembers (channelid)                                                                                                                                |
|                                                    |     WHERE autotranslation = true;                                                                                                                                |
|                                                    |  CREATE INDEX CONCURRENTLY IF NOT EXISTS                                                                                                                         |
|                                                    |  idx_channels_autotranslation_enabled                                                                                                                            |
|                                                    |     ON channels (id)                                                                                                                                             |
|                                                    |     WHERE autotranslation = true;                                                                                                                                |
|                                                    |  CREATE INDEX CONCURRENTLY IF NOT EXISTS                                                                                                                         |
|                                                    |  idx_users_id_locale                                                                                                                                             |
|                                                    |     ON users (id, locale);                                                                                                                                       |
|                                                    | Mattermost v11.3부터 <code>registerRightHandSidebarComponent</code>를 사용해 우측 사이드바(RHS) 컴포넌트를 등록하는 일부 플러그인은, RHS 컴포넌트가 플러그인 전용 상태(state)에 의존하는 경우 RHS 팝아웃을 지원하기 위한 추가 코드를 구현해야 합니다. 자세한 내용은 <a href="https://forum.mattermost.com/t/rhs-popout-support-for-plugins/25626">이 포럼 게시물</a> 을 참조하세요. |
<table><thead><tr><th>v11.2</th><th>v11.2.3부터 Photoshop 문서(PSD) 파일은 더 이상 인라인으로 미리보기되지 않으며 일반 첨부 파일로 처리됩니다.</th></tr></thead></table>
|                                                    | <code>OAuthApps</code> 테이블에 <code>isdynamicallyregistered</code>라는 새 컬럼이 추가되었습니다. 기본값은 <code>false</code>입니다. 또한 <code>OAuthAuthData</code> 테이블에 <code>resource</code>, <code>codechallenge</code>, <code>codechallengemethod</code>라는 세 개의 새 컬럼이 추가되었으며, 모든 컬럼의 기본값은 <code>''</code>입니다. 그리고 <code>OAuthAccessData</code> 테이블에 <code>audience</code>라는 새 컬럼이 추가되었으며 기본값은 <code>''</code>입니다. 마이그레이션은 완전히 하위 호환되며 이 업그레이드에서 데이터베이스 다운타임은 예상되지 않습니다. 테이블은 <code>ACCESS EXCLUSIVE LOCK</code>을 사용하지만 메타데이터를 추가/제거하는 용도일 뿐이며 명령은 즉시 반환됩니다. 포함된 SQL 쿼리는: |
|                                                    ||
|                                                    |   ALTER TABLE oauthapps ADD COLUMN IF NOT EXISTS isdynamicallyregistered BOOLEAN DEFAULT FALSE;                                                                  |
|                                                    |   ALTER TABLE oauthauthdata ADD COLUMN IF NOT EXISTS codechallenge varchar(128) DEFAULT '';                                                                      |
|                                                    |   ALTER TABLE oauthauthdata ADD COLUMN IF NOT EXISTS codechallengemethod varchar(10) DEFAULT '';                                                                 |
|                                                    |   ALTER TABLE oauthaccessdata ADD COLUMN IF NOT EXISTS audience varchar(512) DEFAULT '';                                                                         |
|                                                    |   ALTER TABLE oauthauthdata ADD COLUMN IF NOT EXISTS resource varchar(512) DEFAULT '';                                                                           |
<table><thead><tr><th>v11.1</th><th>Mattermost 웹 앱에서 사용하는 React 버전이 React 17에서 React 18로 업데이트되었습니다. 자세한 내용은 <a href="https://forum.mattermost.com/t/upgrading-the-mattermost-web-app-to-react-18-v11/25000">이 포럼 게시물</a> 을 참조하세요.</th></tr></thead></table>
|                                                    | 데이터 스필리지(Data Spillage) 설정을 저장하기 위한 세 개의 새 테이블 <code>ContentFlaggingCommonReviewers</code>, <code>ContentFlaggingTeamSettings</code>, <code>ContentFlaggingTeamReviewers</code>가 추가되었습니다. 팀 설정 조회를 최적화하기 위해 <code>ContentFlaggingTeamReviewers</code> 테이블에 인덱스가 추가되었습니다. 마이그레이션은 완전히 하위 호환됩니다. 이 업그레이드로 인해 테이블 잠금이나 기존 테이블 작업에 영향을 미치지 않습니다. 이 릴리즈로 업그레이드할 때 제로 다운타임이 예상됩니다. 포함된 SQL 쿼리는: |
|                                                    ||
|                                                    |   CREATE TABLE IF NOT EXISTS ContentFlaggingCommonReviewers (                                                                                                    |
|                                                    |       UserId VARCHAR(26) PRIMARY KEY                                                                                                                             |
|                                                    |   );                                                                                                                                                             |
|                                                    |   CREATE TABLE IF NOT EXISTS ContentFlaggingTeamSettings (                                                                                                       |
|                                                    |       TeamId VARCHAR(26) PRIMARY KEY,                                                                                                                            |
|                                                    |       Enabled BOOLEAN                                                                                                                                            |
|                                                    |   );                                                                                                                                                             |
|                                                    |   CREATE TABLE IF NOT EXISTS ContentFlaggingTeamReviewers (                                                                                                      |
|                                                    |       TeamId VARCHAR(26),                                                                                                                                        |
|                                                    |       UserId VARCHAR(26),                                                                                                                                        |
|                                                    |       PRIMARY KEY (TeamId, UserId)                                                                                                                               |
|                                                    |   );                                                                                                                                                             |
|                                                    |   CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_contentflaggingteamreviewers_userid ON ContentFlaggingTeamReviewers (userid);                                      |
<table><thead><tr><th>v11.0</th><th>Team Edition에서 GitLab SSO 지원이 폐기(deprecated)되었습니다. GitLab SSO를 사용하는 배포는 새로운 무료 제품인 Mattermost Entry로 전환하는 동안 v10.11 ESR(12개월 보안 업데이트 제공)에 남아 있거나, 상용/비영리 옵션을 검토할 수 있습니다. 자세한 내용은 <a href="https://forum.mattermost.com/t/mattermost-v11-changes-in-free-offerings/25126">이 포럼 게시물</a> 을 참조하세요.</th></tr></thead></table>
|                                                    | <code>TeamSettings.ExperimentalViewArchivedChannels</code> 설정이 폐기되었습니다. 보관된 채널은 일반 채널 멤버십 조건에 따라 항상 접근할 수 있습니다. 이 설정이 <code>false</code>로 지정되어 있으면 서버가 시작되지 않습니다. 보관된 채널에 대한 접근을 막으려면 해당 채널을 비공개로 표시하고 영향을 받는 채널 멤버를 제거하세요. 자세한 내용은 <a href="https://forum.mattermost.com/t/viewing-accessing-archived-channels-v11/22626">이 포럼 게시물</a> 을 참조하세요. |
|                                                    | Team Edition에서는 Playbooks가 더 이상 작동하지 않습니다. Entry, Professional, Enterprise, Enterprise Advanced 플랜은 다운타임 없이 자동으로 Playbooks v2로 업그레이드됩니다. 자세한 내용은 <a href="https://forum.mattermost.com/t/clarification-and-update-on-the-playbooks-plugin-v11/25192">이 포럼 게시물</a> 을 참조하세요. |
|                                                    | 실험적(Experimental) Bleve Search 기능이 종료되었습니다. Bleve가 활성화되어 있는 경우 <code>DisableDatabaseSearch</code>를 <code>false</code>로 설정하기 전까지는 검색이 작동하지 않습니다. 자세한 내용은 <a href="https://forum.mattermost.com/t/transitioning-from-bleve-search-in-mattermost-v11/22982">이 포럼 게시물</a> 을 참조하세요. |
|                                                    | MySQL 지원이 종료되었습니다. <a href="https://docs.mattermost.com/deployment-guide/postgres-migration.html">마이그레이션 가이드</a> 에서 PostgreSQL로 마이그레이션하는 데 필요한 단계, 도구, 지원 내용을 확인할 수 있습니다. 자세한 내용은 <a href="https://forum.mattermost.com/t/transition-to-postgresql/19551">이 포럼 게시물</a> 을 참조하세요. |
|                                                    | 웹 앱 플러그인 API의 <code>registerPostDropdownMenuComponent</code> 훅이 제거되고 <code>registerPostDropdownMenuAction</code>으로 대체되었습니다. 자세한 내용은 <a href="https://forum.mattermost.com/t/deprecating-a-post-dropdown-menu-component-plugin-api-v11/25001">이 포럼 게시물</a> 을 참조하세요. |
|                                                    | 웹 앱은 더 이상 웹 앱 플러그인이 사용할 수 있도록 <a href="https://styled-components.com/">Styled Components</a> 의존성을 노출하지 않습니다. 자세한 내용은 <a href="https://forum.mattermost.com/t/removing-styled-components-export-for-web-app-plugins-v11/25002">이 포럼 게시물</a> 을 참조하세요. |
|                                                    | Omnibus 지원이 폐기되었습니다. 마지막 <code>mattermost-omnibus</code> 릴리즈는 v10.12였습니다. 자세한 내용은 <a href="https://forum.mattermost.com/t/mattermost-omnibus-to-reach-end-of-life-v11/25175">이 포럼 게시물</a> 을 참조하세요. |
|                                                    | <code>api/v4/ldap/sync</code>의 폐기된 <code>include_removed_members</code> 옵션이 제거되었습니다. 관리자는 LDAP 설정 <code>ReAddRemovedMembers</code>를 사용할 수 있습니다. |
|                                                    | NPS 플러그인을 활성화한 고객은 더 이상 텔레메트리를 통해 피드백을 전송하지 않으므로 해당 플러그인을 제거해도 됩니다. |
|                                                    | <code>/api/v4/config/client</code> 엔드포인트의 format 쿼리 파라미터 요구사항이 폐기되었습니다. |
|                                                    | 폐기된 mmctl 명령과 플래그가 제거되었습니다: |
|                                                    |     - <code>channel add</code> - 대신 <code>channel users add</code>를 사용하세요 |
|                                                    |     - <code>channel remove</code> - 대신 <code>channel users remove</code>를 사용하세요 |
|                                                    |     - <code>channel restore</code> - 대신 <code>channel unarchive</code>를 사용하세요 |
|                                                    |     - <code>channel make-private</code> - 대신 <code>channel modify --private</code>를 사용하세요 |
|                                                    |     - <code>command delete</code> - 대신 <code>command archive</code>를 사용하세요 |
|                                                    |     - <code>permissions show</code> - 대신 <code>permissions role show</code>를 사용하세요 |
|                                                    |     - <code>mmctl user email</code> - 대신 <code>mmctl user edit email</code>을 사용하세요 |
|                                                    |     - <code>mmctl user username</code> - 대신 <code>mmctl user edit username</code>을 사용하세요 |
|                                                    | 실험적 인증서 기반 인증 기능이 제거되었습니다. 서버를 시작하려면 <code>ExperimentalSettings.ClientSideCertEnable</code>이 <code>false</code>여야 합니다. |
|                                                    | 비밀번호 해싱 방식을 bcrypt에서 PBKDF2로 마이그레이션하는 로직이 추가되었습니다. 이 마이그레이션은 점진적으로 진행되며, 사용자가 비밀번호를 입력하는 즉시(예: 로그인 시 또는 민감한 작업을 위해 비밀번호를 재확인할 때) 해당 사용자의 비밀번호가 마이그레이션됩니다. 사용자가 계정에서 잠길 수 있는 예외 상황이 있습니다. 서버가 v11로 업그레이드된 후 사용자 A가 로그인하면(즉, 비밀번호를 입력해야 함), 이후 서버가 v10.12 이전 버전으로 다운그레이드될 경우 사용자 A는 더 이상 로그인할 수 없습니다. 이 경우 관리자는 시스템 콘솔이나 <a href="https://docs.mattermost.com/administration-guide/manage/mmctl-command-line-tool.html#mmctl-user-reset-password">mmctl user reset-password [users]</a> 명령을 통해 해당 사용자의 비밀번호를 수동으로 재설정해야 합니다. 새 비밀번호 해싱 방식은 CPU를 더 많이 사용합니다. 비밀번호 기반 로그인을 사용하는 서버의 관리자는 많은 사용자가 동시에 로그인하는 시간대의 성능을 모니터링해야 합니다. |
|                                                    | <code>/api/v4/teams/{team_id}/channels/search_archived</code>가 폐기되고, deleted 파라미터를 사용하는 <code>/api/v4/channels/search</code>로 대체되었습니다. |
|                                                    | 기본 데이터베이스 연결 풀 설정이 변경되었습니다. <code>MaxOpenConns</code>는 300에서 100으로, <code>MaxIdleConns</code>는 20에서 50으로 변경되어 더 나은 데이터베이스 연결 관리를 위한 2:1 비율을 확립했습니다. |
|                                                    | 별도의 알림 로그 파일이 폐기되었습니다. 관리자가 알림 로그용 별도 로그 파일을 계속 사용하고자 한다면 <code>AdvancedLoggingJSON</code> 설정을 사용할 수 있습니다. 사용할 수 있는 예시 설정은 다음과 같습니다: |
|                                                    ||
|                                                    |   {                                                                                                                                                              |
|                                                    |     "LogSettings": {                                                                                                                                             |
|                                                    |       "AdvancedLoggingJSON": {                                                                                                                                   |
|                                                    |         "notifications_file": {                                                                                                                                  |
|                                                    |           "type": "file",                                                                                                                                        |
|                                                    |           "format": "json",                                                                                                                                      |
|                                                    |           "levels": [                                                                                                                                            |
|                                                    |               {"id": 300, "name": "NotificationError"},                                                                                                          |
|                                                    |               {"id": 301, "name": "NotificationWarn"},                                                                                                           |
|                                                    |               {"id": 302, "name": "NotificationInfo"},                                                                                                           |
|                                                    |               {"id": 303, "name": "NotificationDebug"},                                                                                                          |
|                                                    |               {"id": 304, "name": "NotificationTrace"}                                                                                                           |
|                                                    |           ],                                                                                                                                                     |
|                                                    |           "options": {                                                                                                                                           |
|                                                    |               "filename": "notifications.log",                                                                                                                   |
|                                                    |               "max_size": 100,                                                                                                                                   |
|                                                    |               "max_age": 0,                                                                                                                                      |
|                                                    |               "max_backups": 0,                                                                                                                                  |
|                                                    |               "compress": true                                                                                                                                   |
|                                                    |           },                                                                                                                                                     |
|                                                    |           "maxqueuesize": 1000                                                                                                                                   |
|                                                    |         }                                                                                                                                                        |
|                                                    |       }                                                                                                                                                          |
|                                                    |     }                                                                                                                                                            |
|                                                    |   }                                                                                                                                                              |
|                                                    | https://forum.mattermost.com/t/deprecation-notice-manual-plugin-deployment/21192 에 따라 수동으로 설치된 플러그인 지원이 중단되었습니다. |
|                                                    | PostgreSQL v13 지원이 제거되었습니다. 새로운 최소 PostgreSQL 버전은 v14 이상입니다. 자세한 내용은 <a href="https://docs.mattermost.com/deployment-guide/software-hardware-requirements.html#minimum-postgresql-database-support-policy">PostgreSQL 버전 정책</a> 문서를 참조하세요. |
<table><thead><tr><th>v10.12</th><th>v10.12 릴리즈에는 중요한 업그레이드 노트가 없습니다.</th></tr><tr><th>v10.11</th><th><code>>=10.11.17</code>에서 <code><=11.7.2</code>로 업그레이드하지 마세요. 데이터베이스 마이그레이션 번호 문제를 일으키는 버그가 있습니다. 이 버그는 v11.7.3에서 수정되었습니다.</th></tr></thead></table>
|                                                    | v10.11.11부터 Photoshop 문서(PSD) 파일은 더 이상 인라인으로 미리보기되지 않으며 일반 첨부 파일로 처리됩니다. |
|                                                    | Mattermost v10.11.4에서는 SSO 인증 흐름 보안 강화의 일환으로 새로운 API 엔드포인트 <code>/api/v4/users/login/sso/code-exchange</code>가 도입됩니다. SSO(예: SAML)를 사용하는 고객은 네트워크 설정에서 이 엔드포인트로의 트래픽을 허용하는지 확인해야 합니다. |
|                                                    | v10.11.17부터 <code>role_updated</code> WebSocket 이벤트는 전역 브로드캐스트 대신 영향받는 팀/채널로 범위가 지정되어 성능이 향상되고 불필요한 네트워크 트래픽이 줄어듭니다. 업그레이드 중 마이그레이션이 자동으로 실행되므로 관리자의 수동 조치가 필요하지 않습니다. 다운타임이 예상되지 않으며 마이그레이션은 정상 운영 중에 실행될 수 있으므로 업그레이드를 위한 특별한 계획이 필요하지 않습니다. 모든 설치가 이 변경의 영향을 받지만 <code>roles</code> 테이블은 대규모 설치에서도 10k 행 미만으로 작기 때문에 영향은 최소화됩니다. 업그레이드에는 효율적인 역할-스키마 조회를 위해 <code>roles</code> 테이블에 <code>schemeid</code> 열을 추가하는 자동 데이터베이스 마이그레이션이 포함됩니다. 마이그레이션은 PostgreSQL의 비차단(non-blocking) 기법을 사용합니다. 먼저 짧은 ACCESS EXCLUSIVE 잠금(카탈로그 전용 작업)으로 컬럼을 추가하고, ROW EXCLUSIVE 잠금으로 기존 데이터를 백필한 다음, 다른 작업을 차단하지 않는 SHARE UPDATE EXCLUSIVE 잠금으로 인덱스를 동시에 생성합니다. <code>roles</code> 테이블 크기는 제한적이며 게시물(post), 반응(reaction) 등 대용량 데이터의 영향을 받지 않습니다. 마이그레이션은 완전히 하위 호환됩니다. |
<table><thead><tr><th>v10.10</th><th>Added a new column <code>DefaultCategoryName</code> to the <code>Channels</code> table. This is nullable and stores a category name to be added/created when new users join a channel. This is only used if the <code>ExperimentalChannelCategorySetting</code> is enabled. The migrations are fully backwards-compatible and no table locks or existing operations on the table are impacted by this upgrade. Zero downtime is expected when upgrading to this release. The SQL queries included are: PostgreSQL: https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/postgres/000138_add_default_category_name_to_channel.down.sql and https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/postgres/000138_add_default_category_name_to_channel.up.sql MySQL: https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/mysql/000138_add_default_category_name_to_channel.down.sql and https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/mysql/000138_add_default_category_name_to_channel.up.sql</th></tr></thead></table>
|                                                    | Added new columns <code>RemoteId</code> and <code>ChannelId</code> to the <code>PostAcknowledgements</code> table. This is nullable, and stores the remote ID (if available) and channel ID |
|                                                    | to which the post was made when acknowledgements to posts were set. The migrations are fully backwards-compatible and no table locks or                          |
|                                                    | existing operations on the table are impacted by this upgrade. Zero downtime is expected when upgrading to this release. The SQL queries included are:           |
|                                                    | PostgreSQL:                                                                                                                                                      |
|                                                    | <code>000141_add_remoteid_channelid_to_post_acknowledgements.down.sql</code> and <code>000141_add_remoteid_channelid_to_post_acknowledgements.up.sql</code>                          |
|                                                    | MySQL:                                                                                                                                                           |
|                                                    | https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/mysql/000141_add_remoteid_channelid_to_post_acknowledgements.down.sql  |
|                                                    | and                                                                                                                                                              |
|                                                    | https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/mysql/000141_add_remoteid_channelid_to_post_acknowledgements.up.sql    |
|                                                    | Added a new column <code>LastMembersSyncAt</code> to the <code>SharedChannelRemotes</code> table and added <code>LastMembershipSyncAt</code> to <code>SharedChannelUsers</code>. This is nullable,   |
|                                                    | and stores the <code>LastMembersSyncAt</code> timestamp (if available) which tracks the last time channel membership data was synchronized between the local cluster and  |
|                                                    | each remote cluster. <code>LastMembershipSyncAt</code> timestamp tracks the last time a specific user's channel membership status was synchronized with a specific remote |
|                                                    | cluster. The migrations are fully backwards-compatible and no table locks or existing operations on the table are impacted by this upgrade. Zero downtime is     |
|                                                    | expected when upgrading to this release. The SQL queries included are:                                                                                           |
|                                                    | PostgreSQL:                                                                                                                                                      |
|                                                    | https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/postgres/000140_add_lastmemberssyncat_to_sharedchannelremotes.down.sql |
|                                                    | and                                                                                                                                                              |
|                                                    | https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/postgres/000140_add_lastmemberssyncat_to_sharedchannelremotes.up.sql   |
|                                                    | MySQL:                                                                                                                                                           |
|                                                    | https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/mysql/000140_add_lastmemberssyncat_to_sharedchannelremotes.down.sql    |
|                                                    | and https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/mysql/000140_add_lastmemberssyncat_to_sharedchannelremotes.up.sql  |
|                                                    | Added a new column <code>LastGlobalUserSyncAt</code> to the <code>RemoteClusters</code> table. This is nullable, and <code>LastGlobalUserSyncAt</code> tracks the timestamp of the last     |
|                                                    | successful global user sync for each remote cluster, enabling incremental syncing. The migrations are fully backwards-compatible and no table locks or existing  |
|                                                    | operations on the table are impacted by this upgrade. Zero downtime is expected when upgrading to this release. The SQL queries included are:                    |
|                                                    | PostgreSQL:                                                                                                                                                      |
|                                                    | https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/postgres/000139_remoteclusters_add_last_global_user_sync_at.down.sql   |
|                                                    | and                                                                                                                                                              |
|                                                    | https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/postgres/000139_remoteclusters_add_last_global_user_sync_at.up.sql     |
|                                                    | MySQL:                                                                                                                                                           |
|                                                    | https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/mysql/000139_remoteclusters_add_last_global_user_sync_at.down.sql and  |
|                                                    | https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/mysql/000139_remoteclusters_add_last_global_user_sync_at.up.sql        |
<table><thead><tr><th>v10.9</th><th>A new index to the <code>CategoryId</code> column in <code>SidebarChannels</code> table was added to improve query performance. No database downtime is expected for this upgrade. For PostgreSQL, it takes around 2s to add the index on a table with 1.2M rows with an instance size of 8 cores and 16GB RAM. For MySQL, it takes around 5s on a table with 300K rows on an instance size of 8 cores and 16GB RAM. The migrations are fully backwards-compatible and no table locks or existing operations on the table are impacted by this upgrade. Zero downtime is expected when upgrading to this release. The SQL queries included are:<strong>PostgreSQL</strong>: CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_sidebarchannels_categoryid ON sidebarchannels(categoryid);<strong>MySQL</strong>: CREATE INDEX idx_sidebarchannels_categoryid ON SidebarChannels(CategoryId);</th></tr></thead></table>
|                                                    | Schema changes in the form of a new materialized view (<code>AttributeView</code>) was added that aggregates user attributes into a separate table. No database downtime  |
|                                                    | is expected for this upgrade. A previous version of Mattermost can run with the new schema changes. The SQL queries included in the schema changes are below:    |
|                                                    | PostgreSQL: https://github.com/mattermost/mattermost/blob/release-10.9/server/channels/db/migrations/postgres/000137_update_attribute_view.up.sql                |
|                                                    | MySQL: https://github.com/mattermost/mattermost/blob/release-10.9/server/channels/db/migrations/mysql/000136_create_attribute_view.up.sql                        |
|                                                    | The objective of showing the SQL queries is not to reduce downtime, but to let the Admin make the schema changes without requiring to upgrade Mattermost.        |
|                                                    | Then when they actually upgrade Mattermost, it becomes instantaneous since the changes are already made.                                                         |
|                                                    | When <code>SamlSettings.EnableSyncWithLdap</code> is enabled, Mattermost will now check if a user exists on the connected LDAP server during login. If the user doesn't   |
|                                                    | exist on the LDAP server, login will fail. Previously, users not present on the LDAP server could login, but would be deactivated on the next LDAP sync.         |
<table><thead><tr><th>v10.8</th><th>New tables <code>AccessControlPolicies</code> and <code>AccessControlPolicyHistory</code> will be created. The migration is fully backwards-compatible, non-locking, and zero downtime is expected.</th></tr></thead></table>
|                                                    | Support for legacy SKUs E10 and E20 licenses was removed. If you need assistance, <a href="https://mattermost.com/contact-sales/">talk to a Mattermost expert</a>.       |
<table><thead><tr><th>v10.7</th><th>Added new column <code>BannerInfo</code> in the <code>Channels</code> table for storing metadata for an upcoming licensed feature. The migration is fully backwards-compatible, non-locking, and zero downtime is possible. Below are the SQL queries included in the schema changes:<strong>PostgreSQL</strong>: ALTER TABLE channels ADD COLUMN IF NOT EXISTS bannerinfo jsonb;<strong>MySQL</strong>: SET @preparedStatement = (SELECT IF( NOT EXISTS( SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'Channels' AND table_schema = DATABASE() AND column_name = 'BannerInfo' ), 'ALTER TABLE Channels ADD COLUMN BannerInfo json;', 'SELECT 1;' )); PREPARE addColumnIfNotExists FROM @preparedStatement; EXECUTE addColumnIfNotExists; DEALLOCATE PREPARE addColumnIfNotExists;</th></tr></thead></table>
|                                                    | Added support for cursor-based pagination on the property architecture tables, including SQL migration to create indices. The migration is fully                 |
|                                                    | backwards-compatible, non-locking, and zero downtime is possible. Below are the SQL queries included in the schema changes:                                      |
|                                                    | MySQL:                                                                                                                                                           |
|                                                    ||
|                                                    |  SET @preparedStatement = (SELECT IF(                                                                                                                            |
|                                                    |      (                                                                                                                                                           |
|                                                    |          SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS                                                                                                      |
|                                                    |          WHERE table_name = 'PropertyValues'                                                                                                                     |
|                                                    |          AND table_schema = DATABASE()                                                                                                                           |
|                                                    |          AND index_name = 'idx_propertyvalues_create_at_id'                                                                                                      |
|                                                    |      ) > 0,                                                                                                                                                      |
|                                                    |      'SELECT 1',                                                                                                                                                 |
|                                                    |      'CREATE INDEX idx_propertyvalues_create_at_id ON PropertyValues(CreateAt, ID);'                                                                             |
|                                                    |  ));                                                                                                                                                             |
|                                                    |  PREPARE createIndexIfNotExists FROM @preparedStatement;                                                                                                         |
|                                                    |  EXECUTE createIndexIfNotExists;                                                                                                                                 |
|                                                    |  DEALLOCATE PREPARE createIndexIfNotExists;                                                                                                                      |
|                                                    ||
|                                                    |  SET @preparedStatement = (SELECT IF(                                                                                                                            |
|                                                    |      (                                                                                                                                                           | 
|                                                    |          SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS                                                                                                      |
|                                                    |          WHERE table_name = 'PropertyFields'                                                                                                                     |
|                                                    |          AND table_schema = DATABASE()                                                                                                                           |
|                                                    |          AND index_name = 'idx_propertyfields_create_at_id'                                                                                                      |
|                                                    |      ) > 0,                                                                                                                                                      |
|                                                    |      'SELECT 1',                                                                                                                                                 |
|                                                    |      'CREATE INDEX idx_propertyfields_create_at_id ON PropertyFields(CreateAt, ID);'                                                                             |
|                                                    |  ));                                                                                                                                                             |
|                                                    |  PREPARE createIndexIfNotExists FROM @preparedStatement;                                                                                                         |
|                                                    |  EXECUTE createIndexIfNotExists;                                                                                                                                 |
|                                                    |  DEALLOCATE PREPARE createIndexIfNotExists;                                                                                                                      |
|                                                    | PostgreSQL:                                                                                                                                                      |
|                                                    ||
|                                                    |  CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_propertyvalues_create_at_id ON PropertyValues(CreateAt, ID)                                                         |
|                                                    ||
|                                                    |  CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_propertyfields_create_at_id ON PropertyFields(CreateAt, ID)                                                         | 
<table><thead><tr><th>v10.6</th><th>Support for PostgreSQL v11 and v12 have been removed. The new minimum PostgreSQL version is v13+. See the <a href="/docs/mattermost/deploy/requirements/#minimum-postgresql-database-support-policy" class="doc-ref">minimum supported PostgreSQL version policy</a> documentation for details.</th></tr></thead></table>
|                                                    | System Console statistics now perform faster on PostgreSQL. The <code>MaxUsersForStatistics</code> configuration setting now only disables the<strong>User counts with posts</strong> |
|                                                    | chart, while all other stats remain unaffected. The other stats remain unaffected because that configuration value is no longer needed to disable the other      |
|                                                    | queries since they are always fast now. Post and file counts update daily, so they may not always reflect real-time data. Advanced stats, such as line charts    |
|                                                    | and plugin data, are now hidden until clicked, reducing load time. No performance improvements apply to MySQL since it's scheduled for full deprecation in v11.  |
|                                                    | We recommend migrating to PostgreSQL for better performance and long-term support. Migration times: On a system with 12M posts, and 1M fileinfo entries, the     |
|                                                    | migration takes 15s, but could take several minutes depending on the server's table sizes and database specs. This migration is non-locking. Note that there is  |                                                                                                       
|                                                    | no migration for MySQL deployments because this optimization is only applicable for PostgreSQL. Below are the SQL queries included in the schema changes:        |

|                                                    | |
|                                                    |  CREATE MATERIALIZED VIEW IF NOT EXISTS posts_by_team_day as                                                                                                     |
|                                                    |  SELECT to_timestamp(p.createat/1000)::date as day, COUNT(*) as num, teamid                                                                                      |
|                                                    |  FROM posts p JOIN channels c on p.channelid=c.id                                                                                                                |
|                                                    |  GROUP BY day, c.teamid;                                                                                                                                         |
|                                                    |  CREATE MATERIALIZED VIEW IF NOT EXISTS bot_posts_by_team_day as                                                                                                 |
|                                                    |  SELECT to_timestamp(p.createat/1000)::date as day, COUNT(*) as num, teamid                                                                                      |
|                                                    |  FROM posts p                                                                                                                                                    |                                                                                                
|                                                    |  JOIN Bots b ON p.UserId = b.Userid                                                                                                                              | 
|                                                    |  JOIN channels c on p.channelid=c.id                                                                                                                             | 
|                                                    |  GROUP BY day, c.teamid;                                                                                                                                         | 
|                                                    |  CREATE MATERIALIZED VIEW IF NOT EXISTS file_stats as                                                                                                            | 
|                                                    |  SELECT COUNT(*) as num, COALESCE(SUM(Size), 0) as usage                                                                                                         | 
|                                                    |  FROM fileinfo                                                                                                                                                   | 
|                                                    |  WHERE DeleteAt = 0;                                                                                                                                             | 
<table><thead><tr><th>v10.5</th><th>Mattermost versions v10.5.0 and v10.5.1 include a bundled Jira plugin (v4.2.0) that contains a bug which may cause plugin configuration settings to disappear. We strongly advise against upgrading to these versions to avoid potential disruption. If you have already upgraded to v10.5.0 or v10.5.1, we recommend updating the Jira plugin to version v4.2.1, or preferably, upgrading both Mattermost and the Jira plugin to their latest available versions.</th></tr></thead></table>
|                                                    | The internal workings of the <a href="https://github.com/mattermost/mattermost-plugin-jira/pull/1145">PluginLinkComponent` in the web app have been changed to unmount link tooltips from the DOM by default, significantly improving    |
|                                                    | performance. Plugins that register link tooltips using `registerLinkTooltipComponent` will experience changes in how tooltip components are managed—they are     |
|                                                    | now only mounted when a link is hovered over or focused. As a result, plugins may need to update their components to properly handle mounting and unmounting     |
|                                                    | scenarios. For example, changes were made in `mattermost-plugin-jira</a>, where                   |
|                                                    | componentDidUpdate lifecycle hook was replaced with componentDidMount. If your plugin’s tooltip component is a functional React component, there is a high       |
|                                                    | chance that this behavior will be handled automatically, as it would be managed by useEffect with an empty dependency array.                                     |
|                                                    | The Mattermost server has stopped supporting manual plugin deployment. Plugins were deployed manually when an administrator or some deployment automation copies |
|                                                    | the contents of a plugin bundle into the server's working directory. If a manual or automated deployment workflow is still required, administrators can instead  |
|                                                    | prepackage the plugin bundles. See <a href="https://forum.mattermost.com/t/deprecation-notice-manual-plugin-deployment/21192">this forum post</a> for details.           |
|                                                    | Mattermost has stopped official Mattermost server builds for the Microsoft Windows operating system. Administrators should migrate existing Mattermost server    |
|                                                    | installations to use the official Linux builds. See more details in                                                                                              |
|                                                    | <a href="https://forum.mattermost.com/t/deprecation-notice-server-builds-for-microsoft-windows/21498">this forum post</a>.                                               |
|                                                    | v10.5 introduces updates to the Compliance Export functionality, which will modify how exported data is structured, stored and processed. These changes          |
|                                                    | primarily affect System Administrators and the main changes are outlined below. See more details in                                                              |
|                                                    | the <a href="https://docs.mattermost.com/administration-guide/comply/compliance-export.html">Compliance Export documentation</a>.                                         |
|                                                    | Output files and directories have changed - Previously we were exporting a single zip containing all the batch directories. Now we will export a single          |
|                                                    | directory, and under that directory each batch will be its own zip.                                                                                              |
|                                                    | Compliance exports performance improvements - Compliance exports should now be at least 50% faster, and possibly more.                                           |
|                                                    | Logic improvements - We’ve made improvements and fixed bugs that we found.                                                                                       |
|                                                    | Changes specific to each Export Type - The export output formats have been changed. Some fields’ semantic meaning has been clarified, and there are a number of  |
|                                                    | new fields. Our goal was to maintain backwards compatibility while fixing the logic bugs.                                                                        |
|                                                    | See the <a href="/docs/mattermost/comply/compliance-export/" class="doc-ref">compliance export</a> product documentation for details.                                             |
|                                                    | As part of the Property System Architecture feature, Mattermost v10.5 is going to run a set of migrations to add new tables to the schema. This migration only   |
|                                                    | creates new tables and indexes, so there is no impact on preexisting data.                                                                                       |
|                                                    | New tables <code>PropertyGroups</code>, <code>PropertyFields</code> and <code>PropertyValues</code> are going to be created.                                                                |
|                                                    | In the case of PostgreSQL, a new enum type <code>property_field_type</code> is going to be created, to be used in the <code>Type</code> column of the <code>PropertyFields</code> table.    |
|                                                    | The <code>PropertyFields</code> and <code>PropertyValues</code> tables have a unique constraint that will generate an index in MySQL, and in the case of PostgreSQL, they directly |
|                                                    | use a <code>UNIQUE INDEX</code> to enforce this constraint.                                                                                                               |
|                                                    | A new index <code>idx_propertyvalues_targetid_groupid</code> will be created for the <code>PropertyValues</code> table.                                                            |
|                                                    | The migration is only creating new tables with no data. The migration is backwards-compatible, and a previous version of Mattermost can run with the new schema  |
|                                                    | changes. No table locks or existing operations on the table are impacted by this upgrade. Zero downtime is possible when upgrading to this release.              |
|                                                    | Below are the SQL queries included in the schema changes:                                                                                                        |
|                                                    |<strong>MySQL</strong>:                                                                                                                                                       |

|                                                    | |
|                                                    |  CREATE TABLE IF NOT EXISTS PropertyGroups (                                                                                                                     |
|                                                    |   ID varchar(26) PRIMARY KEY,                                                                                                                                    |
|                                                    |   Name varchar(64) NOT NULL,                                                                                                                                     |
|                                                    |   UNIQUE(Name)                                                                                                                                                   |
|                                                    |  );                                                                                                                                                              |
|                                                    |  CREATE TABLE IF NOT EXISTS PropertyFields (                                                                                                                     |
|                                                    |   ID varchar(26) PRIMARY KEY,                                                                                                                                    |
|                                                    |   GroupID varchar(26) NOT NULL,                                                                                                                                  |
|                                                    |   Name varchar(255) NOT NULL,                                                                                                                                    |
|                                                    |   Type enum('text', 'select', 'multiselect', 'date', 'user', 'multiuser'),                                                                                       |
|                                                    |   Attrs json,                                                                                                                                                    |
|                                                    |   TargetID varchar(255),                                                                                                                                         |
|                                                    |   TargetType varchar(255),                                                                                                                                       |
|                                                    |   CreateAt bigint(20),                                                                                                                                           |
|                                                    |   UpdateAt bigint(20),                                                                                                                                           |
|                                                    |   DeleteAt bigint(20),                                                                                                                                           |
|                                                    |   UNIQUE(GroupID, TargetID, Name, DeleteAt)                                                                                                                      |
|                                                    |  );                                                                                                                                                              |
|                                                    |  CREATE TABLE IF NOT EXISTS PropertyValues (                                                                                                                     |
|                                                    |   ID varchar(26) PRIMARY KEY,                                                                                                                                    |
|                                                    |   TargetID varchar(255) NOT NULL,                                                                                                                                |
|                                                    |   TargetType varchar(255) NOT NULL,                                                                                                                              |
|                                                    |   GroupID varchar(26) NOT NULL,                                                                                                                                  |
|                                                    |   FieldID varchar(26) NOT NULL,                                                                                                                                  |
|                                                    |   Value json,                                                                                                                                                    |
|                                                    |   CreateAt bigint(20),                                                                                                                                           |
|                                                    |   UpdateAt bigint(20),                                                                                                                                           |
|                                                    |   DeleteAt bigint(20),                                                                                                                                           |
|                                                    |   UNIQUE(GroupID, TargetID, FieldID, DeleteAt)                                                                                                                   |
|                                                    |  );                                                                                                                                                              |
|                                                    |  SET @preparedStatement = (SELECT IF(                                                                                                                            |
|                                                    |   (                                                                                                                                                              |
|                                                    |      SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS                                                                                                          |
|                                                    |      WHERE table_name = 'PropertyValues'                                                                                                                         |
|                                                    |      AND table_schema = DATABASE()                                                                                                                               |
|                                                    |      AND index_name = 'idx_propertyvalues_targetid_groupid'                                                                                                      |
|                                                    |   ) > 0,                                                                                                                                                         |
|                                                    |   'SELECT 1',                                                                                                                                                    |
|                                                    |   'CREATE INDEX idx_propertyvalues_targetid_groupid ON PropertyValues (TargetID, GroupID);'                                                                      |
|                                                    |  ));                                                                                                                                                             |
|                                                    |  PREPARE createIndexIfNotExists FROM @preparedStatement;                                                                                                         |
|                                                    |  EXECUTE createIndexIfNotExists;                                                                                                                                 |
|                                                    |  DEALLOCATE PREPARE createIndexIfNotExists;                                                                                                                      |
|                                                    |<strong>PostgreSQL</strong>:                                                                                                                                                  |

|                                                    | |
|                                                    |  CREATE TABLE IF NOT EXISTS PropertyGroups (                                                                                                                     |
|                                                    |   ID varchar(26) PRIMARY KEY,                                                                                                                                    |
|                                                    |   Name varchar(64) NOT NULL,                                                                                                                                     |
|                                                    |   UNIQUE(Name)                                                                                                                                                   |
|                                                    |  );                                                                                                                                                              |
|                                                    |  DO                                                                                                                                                              |
|                                                    |  BEGIN                                                                                                                                                           |
|                                                    |    IF NOT EXISTS (SELECT * FROM pg_type typ                                                                                                                      |
|                                                    |                          INNER JOIN pg_namespace nsp ON nsp.oid = typ.typnamespace                                                                               |
|                                                    |                      WHERE nsp.nspname = current_schema()                                                                                                        |
|                                                    |                          AND typ.typname = 'property_field_type') THEN                                                                                           |
|                                                    |   CREATE TYPE property_field_type AS ENUM (                                                                                                                      |
|                                                    |      'text',                                                                                                                                                     |
|                                                    |      'select',                                                                                                                                                   |
|                                                    |      'multiselect',                                                                                                                                              |
|                                                    |      'date',                                                                                                                                                     |
|                                                    |      'user',                                                                                                                                                     |
|                                                    |      'multiuser'                                                                                                                                                 |
|                                                    |   );                                                                                                                                                             |
|                                                    |    END IF;                                                                                                                                                       |
|                                                    |  END;                                                                                                                                                            |
|                                                    |  LANGUAGE plpgsql;                                                                                                                                               |
|                                                    |  CREATE TABLE IF NOT EXISTS PropertyFields (                                                                                                                     |
|                                                    |   ID varchar(26) PRIMARY KEY,                                                                                                                                    |
|                                                    |   GroupID varchar(26) NOT NULL,                                                                                                                                  |
|                                                    |   Name varchar(255) NOT NULL,                                                                                                                                    |
|                                                    |   Type property_field_type,                                                                                                                                      |
|                                                    |   Attrs jsonb,                                                                                                                                                   |
|                                                    |   TargetID varchar(255),                                                                                                                                         |
|                                                    |   TargetType varchar(255),                                                                                                                                       |
|                                                    |   CreateAt bigint NOT NULL,                                                                                                                                      |
|                                                    |   UpdateAt bigint NOT NULL,                                                                                                                                      |
|                                                    |   DeleteAt bigint NOT NULL                                                                                                                                       |
|                                                    |  );                                                                                                                                                              |
|                                                    |  CREATE UNIQUE INDEX IF NOT EXISTS idx_propertyfields_unique ON PropertyFields (GroupID, TargetID, Name) WHERE DeleteAt = 0;                                     |
|                                                    |  CREATE TABLE IF NOT EXISTS PropertyValues (                                                                                                                     |
|                                                    |   ID varchar(26) PRIMARY KEY,                                                                                                                                    |
|                                                    |   TargetID varchar(255) NOT NULL,                                                                                                                                |
|                                                    |   TargetType varchar(255) NOT NULL,                                                                                                                              |
|                                                    |   GroupID varchar(26) NOT NULL,                                                                                                                                  |
|                                                    |   FieldID varchar(26) NOT NULL,                                                                                                                                  |
|                                                    |   Value jsonb NOT NULL,                                                                                                                                          |
|                                                    |   CreateAt bigint NOT NULL,                                                                                                                                      |
|                                                    |   UpdateAt bigint NOT NULL,                                                                                                                                      |
|                                                    |   DeleteAt bigint NOT NULL                                                                                                                                       |
|                                                    |  );                                                                                                                                                              |
|                                                    |  CREATE UNIQUE INDEX IF NOT EXISTS idx_propertyvalues_unique ON PropertyValues (GroupID, TargetID, FieldID) WHERE DeleteAt = 0;                                  |
|                                                    |  CREATE INDEX IF NOT EXISTS idx_propertyvalues_targetid_groupid ON PropertyValues (TargetID, GroupID);                                                           |
|                                                    |      ``                                                                                                                                                          |
<table><thead><tr><th>v10.4</th><th>There are no important upgrade notes in v10.4 release.</th></tr><tr><th>v10.3</th><th>The Classic Mobile App has been phased out. Please download the new v2 Mobile App from the <a href="https://apps.apple.com/us/app/mattermost/id1257222717">Apple App Store</a> or <a href="https://play.google.com/store/apps/details?id=com.mattermost.rn">Google Play Store</a>. See more details in the <a href="https://forum.mattermost.com/t/classic-mobile-app-deprecation/18703">classic mobile app deprecation</a> Mattermost forum post.</th></tr><tr><th>v10.2</th><th>Docker Content Trust (DCT) for signing Docker image artifacts has been replaced by Sigstore Cosign in v10.2 (November, 2024). If you rely on artifact verification using DCT, please <a href="https://edu.chainguard.dev/open-source/sigstore/cosign/how-to-install-cosign/">transition to using Cosign</a>. See the <a href="https://forum.mattermost.com/t/upcoming-dct-deprecation/19275">upcoming DCT deprecation</a> Mattermost forum post for more details.</th></tr><tr><th>v10.1</th><th>There are no important upgrade notes in v10.1 release.</th></tr><tr><th>v10.0</th><th>We no longer support new installations using MySQL starting in v10. All new customers and/or deployments will only be supported with the minimum supported version of the PostgreSQL database. End of support for MySQL is targeted for Mattermost v11.</th></tr></thead></table>
|                                                    | Apps Framework is deprecated for new installs. Please extend Mattermost using webhooks, slash commands, OAuth2 apps, and plugins.                                |
|                                                    | Mattermost v10 introduces Playbooks v2 for all Enterprise licensed customers. Professional SKU customers may continue to use Playbooks v1 uninterrupted which    |
|                                                    | will be maintained and supported until September 2025, followed by an appropriate grandfathering strategy. More detailed information and the discussion are      |
|                                                    | available on our <a href="https://forum.mattermost.com/t/clarification-on-playbooks-in-mattermost-v10/20563">forums here</a>.                                             |
|                                                    | Renamed <code>Channel Moderation</code> to <code>Advanced Access Control</code> in the channel management section in the<strong>System Console</strong>.                                       |

|                                                    | Renamed announcement banner feature to “system-wide notifications”.                                                                                              |

|                                                    | Renamed “Collapsed Reply Threads” to “Threaded Discussions” in the System Console.                                                                               |

|                                                    | Renamed “System Roles” to “Delegated Granular Administration” in the System Console.                                                                             |

|                                                    | Renamed "Office 365" to "Entra ID" for SSO logins.                                                                                                               |

|                                                    | Fully deprecated the <code>/api/v4/image</code> endpoint when the image proxy is disabled.                                                                                |

|                                                    | Pre-packaged <a href="https://github.com/mattermost/mattermost-plugin-calls/releases/tag/v1.0.1">Calls plugin v1.0.1</a>. This includes breaking changes including        | 
|                                                    | the removal of group calls from unlicensed servers in order to focus supportability and quality on licensed servers. Unlicensed servers can continue to use      |
|                                                    | Calls in direct message channels, which represent the majority of activity.                                                                                      |

|                                                    | Removed deprecated <code>Config.ProductSettings</code>, <code>LdapSettings.Trace</code>, and <code>AdvancedLoggingConfig</code> configuration fields.                                       |

|                                                    | Removed deprecated <code>pageSize</code> query parameter from most API endpoints.                                                                                         |

|                                                    | Deprecated the experimental Strict CSRF token enforcement. This feature will be fully removed in Mattermost v11.                                                 |
<table><thead><tr><th>v9.11</th><th>Added support for Elasticsearch v8. Also added Beta support for OpenSearch v1.x and v2.x. A new config setting <code>ElasticsearchSettings.Backend</code> has been added to differentiate between Elasticsearch and OpenSearch. The default value is <code>elasticsearch</code> which breaks support for AWS Elasticsearch v7.10.x since the official v8 client only works from Elasticsearch v7.11+ versions. 
Note

- For AWS customers on OpenSearch, you must modify Mattermost configuration from <code>elasticsearch</code> to <code>opensearch</code> and disable compatibility mode. See the <a href="https://docs.aws.amazon.com/opensearch-service/latest/developerguide/version-migration.html">OpenSearch documentation</a> for details on upgrading. - After upgrading the Mattermost server, use <a href="/docs/mattermost/manage/mmctl/#mmctl-config-set" class="doc-ref">mmctl</a> or edit the config manually, then restart the Mattermost server. - If you are using OpenSearch, you <strong>must</strong> set the backend to <code>opensearch</code>. Otherwise Mattermost will not work. If you are using Elasticsearch v8, be sure to set <code>action.destructive_requires_name</code> to <code>false</code> in <code>elasticsearch.yml</code> to allow for wildcard operations to work.</th></tr><tr><th>v9.10</th><th>There are no important upgrade notes in v9.10 release.</th></tr><tr><th>v9.9</th><th>There are no important upgrade notes in v9.9 release.</th></tr><tr><th>v9.8</th><th>There are no important upgrade notes in v9.8 release.</th></tr><tr><th>v9.7</th><th>There are no important upgrade notes in v9.7 release.</th></tr><tr><th>v9.6</th><th>There are no important upgrade notes in v9.6 release.</th></tr><tr><th>v9.5</th><th>We have stopped supporting MySQL v5.7 since it's at the end of life. We urge customers to upgrade their MySQL instance at their earliest convenience.</th></tr></thead></table> | | Added safety limit error message in compiled Team Edition and Enterprise Edition deployments when enterprise scale and access control automation features are | | | unavailable and count of users who are registered and not deactivated exceeds 10,000. | | | <a href="/docs/mattermost/manage/admin/error-codes/" class="doc-ref">ERROR_SAFETY_LIMITS_EXCEEDED</a>. | <table><thead><tr><th>v9.4</th><th>There are no important upgrade notes in v9.4 release.</th></tr><tr><th>v9.3</th><th>There are no important upgrade notes in v9.3 release.</th></tr><tr><th>v9.2</th><th>Fixed data retention policies to run jobs when any custom retention policy is enabled even when the global retention policy is set to "keep-forever". Before this fix, the enabled custom data retention policies wouldn't run as long as the global data retention policy was set to "keep-forever" or was disabled. After the fix, the custom data retention policies will run automatically even when the global data retention policy is set to "keep-forever". Once the server is upgraded, posts may unintentionally be deleted. Admins should make sure to disable all custom data retention policies before upgrading, and then re-enable them again after upgrading.</th></tr><tr><th>v9.1</th><th>Minimum supported Desktop App version is now v5.3. OAuth/SAML flows were modified to include <code>desktop_login</code> which makes earlier versions incompatible.</th></tr><tr><th>v9.0</th><th>Removed the deprecated Insights feature.</th></tr></thead></table> | | Mattermost Boards and various other plugins have transitioned to being fully community supported. See this | | | <a href="https://forum.mattermost.com/t/upcoming-product-changes-to-boards-and-various-plugins/16669">forum post</a> for more details. | | | The <code>channel_viewed</code> websocket event was changed to <code>multiple_channels_viewed</code>, and is now only triggered for channels that actually have unread messages. | <table><thead><tr><th>v8.1</th><th>In v8.1.2, improved performance on data retention <code>DeleteOrphanedRows</code> queries. New migration for a new table: <strong>MySQL</strong>: CREATE TABLE IF NOT EXISTS RetentionIdsForDeletion(Id VARCHAR(26) NOT NULL, TableName VARCHAR(64), Ids json, PRIMARY KEY (Id ), KEY idx_retentionidsfordeletion_tablename (TableName)) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4; <code><strong>PostgreSQL</strong>: CREATE TABLE IF NOT EXISTS retentionidsfordeletion(id VARCHAR(26) PRIMARY KEY, tablename VARCHAR(64), ids VARCHAR(26) []); CREATE INDEX IF NOT EXISTS idx_retentionidsfordeletion_tablename ON retentionidsfordeletion( tablename); </code> Hard deleting a user or a channel will now also clean up associated reactions. Removed feature flag <code>DataRetentionConcurrencyEnabled</code>. Data retention now runs without concurrency in order to avoid any performance degradation. Added a new configuration setting <code>DataRetentionSettings.RetentionIdsBatchSize</code>, which allows admins to configure how many batches of IDs will be fetched at a time when deleting orphaned reactions. The default value is 100.</th></tr><tr><th>v8.0</th><th>Insights has been deprecated for all new instances and for existing servers that upgrade to v8.0. See more details in <a href="https://forum.mattermost.com/t/proposal-to-revise-our-insights-feature-due-to-known-performance-issues/16212">this forum post</a> on why Insights has been deprecated.</th></tr></thead></table> | | The Focalboard plugin is now disabled by default for all new instances and can be enabled in the<strong>System Console > Plugin settings</strong>. | | | The Channel Export and Apps plugins are now disabled by default. | | | Apps Bar is now enabled by default for on-prem servers. <code>ExperimentalSettings.EnableAppBar</code> was also renamed to <code>ExperimentalSettings.DisableAppBar</code>. | | | See the :ref: `configuration settings <administration-guide/configure/experimental-configuration-settings:disable-apps-bar><a href="https://forum.mattermost.com/t/channel-header-plugin-changes/13551">documentation, and | | | `this forum article</a> for details. | | | In the main `server package`, the Go module path has changed from <code>github.com/mattermost/mattermost-server/server/v8</code> to | | | <code>github.com/mattermost/mattermost/server/v8</code>. But with the introduction of the <a href="https://github.com/mattermost/mattermost/tree/master/server/public">public` submodule, it should no longer be necessary for third-party code to | | | import this `server` package. | | | Introduced the `public</a> submodule, housing the familiar `model` and `plugin` packages, | | | but now discretely versioned from the server. It is no longer necessary to `go get` a particular commit hash, as Go programs and plugins can now opt-in to | | | importing `github.com/mattermost/mattermost-server/server/public` and managing versions idiomatically. While this submodule has not yet shipped a v1 and will | | | introduce breaking changes before stabilizing the API, it remains both forwards and backwards compatible with the Mattermost server itself. | | | As part of the `public` submodule above, a <code>context.Context</code> is now passed to <code>model.Client4</code> methods. | | | Removed support for PostgreSQL v10. The new minimum PostgreSQL version is now v11. | | | The Mattermost public API for Go is now available as a distinctly versioned package. Instead of pinning a particular commit hash, use idiomatic Go to add this | | | package as a dependency: go get `github.com/mattermost/mattermost-server/server/public`. This relocated Go API maintains backwards compatibility with Mattermost | | | v7. Furthermore, the existing Go API previously at github.com/mattermost/mattermost-server/v6/model remains forward compatible with Mattermost v8, but may not | | | contain newer features. Plugins do not need to be recompiled, but developers may opt in to using the new package to simplify their build process. The new public | | | package is shipping alongside Mattermost v8 as version 0.5.0 to allow for some additional code refactoring before releasing as v1 later this year. | | | Three configuration fields have been added, <code>LogSettings.AdvancedLoggingJSON</code>, <code>ExperimentalAuditSettings.AdvancedLoggingJSON</code>, and | | | <code>NotificationLogSettings.AdvancedLoggingJSON</code> which support multi-line JSON, escaped JSON as a string, or a filename that points to a file containing JSON. | | | The <code>AdvancedLoggingConfig</code> fields have been deprecated. | | | The Go MySQL driver has changed the <code>maxAllowedPacket</code> size from 4MiB to 64MiB. This is to make it consistent with the change in the server side default value | | | from MySQL 5.7 to MySQL 8.0. If your <code>max_allowed_packet</code> setting is not 64MiB, then please update the MySQL config DSN with an additional param of | | | <code>maxAllowedPacket</code> to match with the server side value. Alternatively, a value of 0 can be set to to automatically fetch the server side value, on every new | | | connection, which has a performance overhead. | | | Removed <code>ExperimentalSettings.PatchPluginsReactDOM</code>. If this setting was previously enabled, confirm that: | | | 1. All Mattermost-supported plugins are updated to the latest versions. | | | 2. Any other plugins have been updated to support React 17. See the section for v7.7 release for more information. | | | Removed deprecated <code>PermissionUseSlashCommands</code>. | | | Removed deprecated <code>model.CommandArgs.Session</code>. | | | For servers wanting to allow websockets to connect from origins other than the origin of the site URL, please set the <code>ServiceSettings.AllowCorsFrom</code> | | | <a href="/docs/mattermost/configure/integrations/#enable-cross-origin-requests-from" class="doc-ref">configuration setting</a>. Also ensure that | | | the <code>siteURL</code> is set correctly. | | | In v8.0 release, the following repositories are merged into one: <code>mattermost-server</code>, <code>mattermost-webapp</code> and <code>mmctl</code>. | | | Developers should read the updated <a href="https://developers.mattermost.com/contribute/developer-setup/">Developer Guide</a> for details. | | | Fixed an issue caused by a migration in the previous release. Query takes around 11ms on a PostgreSQL 14 DB t3.medium RDS instance. Locks on the preferences | | | table will only be acquired if there are rows to delete, but the time taken is negligible. | | | Fixed an issue where a user would still see threads in the threads view of channels they have left. Migration execution time in PostgreSQL: Execution time: | | | 58.11 sec, DELETE 2766690. Migration execution time in MySQL: Query OK, 2766769 rows affected (4 min 47.57 sec). | | | For servers wanting to allow websockets to connect from other origins, please set the <code>ServiceSettings.AllowCorsFrom</code> config setting. | | | The file info stats query is now optimized by denormalizing the <code>channelID</code> column into the table itself. This will speed up the query to get the file count | | | for a channel when selecting the right-hand pane. Migration times: | | | On a PostgreSQL 12.14 DB with 1731 rows in FileInfo and 11M posts, it took around 0.27s | | | On a MySQL 8.0.31 DB with 1405 rows in FileInfo and 11M posts, it took around 0.3s | <table><thead><tr><th>v7.10</th><th>In v7.10.1, fixed an issue caused by a migration in the previous release. Query takes around 11ms on a PostgreSQL 14 DB t3.medium RDS instance. Locks on the preferences table will only be acquired if there are rows to delete, but the time taken is negligible.</th></tr></thead></table> | | In v7.10.1, fixed an issue where a user would still see threads in the threads view of channels they have left. Migration execution time in MySQL: Query OK, | | | 2766769 rows affected (4 min 47.57 sec). Migration execution time in PostgreSQL: 58.11 sec, DELETE 2766690. | | | In v7.10.3, for servers wanting to allow websockets to connect from origins other than the origin of the site URL, please set the | | | <code>ServiceSettings.AllowCorsFrom</code> | | | <a href="/docs/mattermost/configure/integrations/#enable-cross-origin-requests-from" class="doc-ref">configuration setting</a>. Also ensure that | | | the <code>siteURL</code> is set correctly. | <table><thead><tr><th>v7.9</th><th>Added a new index on <code>Posts(OriginalId)</code>. For a database with 11.8 million posts, on a machine with a i7-11800H CPU (8 cores, 16 threads), 32GiB of RAM and SSD, the index creation takes 98.51s on MYSQL and 2.6s on PostgreSQL. - In PostgreSQL databases, the <code>Posts</code> table will be locked during index creation. To avoid locking this table, admins can create the index manually before performing the upgrade using the following non-blocking query: <code>CREATE INDEX CONCURRENTLY idx_posts_original_id ON Posts(OriginalId);</code>. - Admins managing PostgreSQL deployments containing fewer posts may prefer that the migration process creates the index, and accept that <code>Posts</code> table will remain locked until the migration is complete.</th></tr></thead></table> | | In v7.9.4, fixed an issue where a user would still see threads in the threads view of channels they have left. Migration execution time in MySQL: Query OK, | | | 2766769 rows affected (4 min 47.57 sec). Migration execution time in PostgreSQL: 58.11 sec, DELETE 2766690. | | | In v7.9.4, backported a fix related Oauth 2. Query times depend on if you have rows to delete or not. | | | With no rows to delete: | | | - MySQL v5.7.12: 9ms | | | - PostgreSQL v10: 21ms | | | 4 rows: | | | - MySQL v5.7.12: 17.2ms | | | - PostgreSQL v10: 9.9ms | | | Those times are based off the following table sizes: | | | - Preferences: 2 million records | | | - <code>oauthaccessdata</code> and sessions: 10 records | | | You can assess the number of impacted rows by running the following: | | | <strong>PostgreSQL</strong>: | | | | | | SELECT count(o.*) | | | FROM oauthaccessdata o | | | WHERE NOT EXISTS ( | | | SELECT p.* | | | FROM preferences p | | | WHERE o.clientid = p.name | | | AND o.userid = p. | | | userid | | | AND p.category = | | | 'oauth_app' | | | ); | | |<strong>MySQL</strong>: | | | | | | SELECT COUNT(o.`Token`) | | | FROM OAuthAccessData o | | | LEFT JOIN Preferences p ON o. | | | clientid = p.name | | | AND o.userid = p.userid | | | AND p.category = 'oauth_app' | | | INNER JOIN Sessions s ON o.token = s | | | .token | | | WHERE p.name IS NULL; | | | Locks on the <code>oauthaccessdata</code> and sessions table will only be acquired if there are rows to delete. | | | In v7.9.5, for servers wanting to allow websockets to connect from origins other than the origin of the site URL, please set the | | | <code>ServiceSettings.AllowCorsFrom</code> | | | <a href="/docs/mattermost/configure/integrations/#enable-cross-origin-requests-from" class="doc-ref">configuration setting</a>. Also ensure that | | | the <code>siteURL</code> is set correctly. | <table><thead><tr><th>v7.8</th><th><a href="/docs/mattermost/configure/site-configuration/#message-priority" class="doc-ref">Message Priority & Acknowledgement</a> is now enabled by default for all instances. You may disable this feature in the System Console by going to<strong>Posts > Message Priority</strong> or via the config <code>PostPriority</code> setting.</th></tr></thead></table> | | In v7.8.5, fixed an issue where a user would still see threads in the threads view of channels they have left. Migration execution time in MySQL: Query OK, | | | 2766769 rows affected (4 min 47.57 sec). Migration execution time in PostgreSQL: 58.11 sec, DELETE 2766690. | | | In v7.8.5, backported a fix related Oauth 2. Query times depend on if you have rows to delete or not. | | | With no rows to delete: | | | - MySQL v5.7.12: 9ms | | | - PostgreSQL v10: 21ms | | | 4 rows: | | | - MySQL v5.7.12: 17.2ms | | | - PostgreSQL v10: 9.9ms | | | Those times are based off the following table sizes: | | | - Preferences: 2 million records | | | - <code>oauthaccessdata</code> and sessions: 10 records | | | You can assess the number of impacted rows by running the following: | | | <strong>PostgreSQL</strong>: | | | | | | SELECT count(o.*) | | | FROM oauthaccessdata o | | | WHERE NOT EXISTS ( | | | SELECT p.* | | | FROM preferences p | | | WHERE o.clientid = p.name | | | AND o.userid = p. | | | userid | | | AND p.category = | | | 'oauth_app' | | | ); | | |<strong>MySQL</strong>: | | | | | | SELECT COUNT(o.`Token`) | | | FROM OAuthAccessData o | | | LEFT JOIN Preferences p ON o. | | | clientid = p.name | | | AND o.userid = p.userid | | | AND p.category = 'oauth_app' | | | INNER JOIN Sessions s ON o.token = s | | | .token | | | WHERE p.name IS NULL; | | | Locks on the <code>oauthaccessdata</code> and sessions table will only be acquired if there are rows to delete. | | | In v7.8.7, for servers wanting to allow websockets to connect from origins other than the origin of the site URL, please set the | | | <code>ServiceSettings.AllowCorsFrom</code> | | | <a href="/docs/mattermost/configure/integrations/#enable-cross-origin-requests-from" class="doc-ref">configuration setting</a>. Also ensure that | | | the <code>siteURL</code> is set correctly. | | | In v7.8.11, improved performance on data retention <code>DeleteOrphanedRows</code> queries. | | | New migration for a new table: | | |<strong>MySQL</strong>: | | | | | | CREATE TABLE | | | IF NOT EXISTS | | | RetentionIdsForDeletion(Id | | | VARCHAR(26) NOT NULL, | | | TableName VARCHAR(64), | | | Ids json, PRIMARY KEY (Id | | | ), KEY | | | idx_retentionidsfordeletion_tablename | | | (TableName)) ENGINE = | | | InnoDB DEFAULT CHARSET = | | | utf8mb4; | | | `` | | |<strong>PostgreSQL</strong>: | | | | | | CREATE TABLE | | | IF NOT EXISTS | | | retentionidsfordeletion(id | | | VARCHAR(26) PRIMARY KEY, | | | tablename VARCHAR(64), | | | ids VARCHAR(26) []); | | | CREATE INDEX | | | IF NOT EXISTS | | | idx_retentionidsfordeletion_tablename | | | ON retentionidsfordeletion( | | | tablename); | | | `` | | | Hard deleting a user or a channel will now also clean up associated reactions. | | | Removed feature flag <code>DataRetentionConcurrencyEnabled</code>. Data retention now runs without concurrency in order to avoid any performance degradation. | | | Added a new configuration setting <code>DataRetentionSettings.RetentionIdsBatchSize</code>, which allows admins to configure how many batches of IDs will be fetched at | | | a time when deleting orphaned reactions. The default value is 100. | <table><thead><tr><th>v7.7</th><th>Plugins with a webapp component may need to be updated to work with Mattermost v7.7 release and the updated <code>React v17</code> dependency. This is to avoid plugins crashing with an error about <code>findDOMNode</code> being called on an unmounted component. While our <a href="https://github.com/mattermost/mattermost-plugin-starter-template">starter template</a> depended on an external version of <code>React</code>, it did not do the same for <code>ReactDOM</code>. Plugins need to update their <code>webpack.config.js</code> directives to externalize <code>ReactDOM</code>. For reference, see https://github.com/mattermost/mattermost-plugin-playbooks/pull/1489. Server-side only plugins are unaffected. This change can be done for existing plugins any time prior to upgrading to Mattermost v7.7 and is backwards compatible with older versions of Mattermost. If you run into issues, you can either enable <code>ExperimentalSettings.PatchPluginsReactDOM</code> or just disable the affected plugin while it's updated.</th></tr></thead></table> | | Denormalized <code>Threads</code> table by adding the <code>ThreadTeamId</code> column. Even though it denormalizes the schema, we gain performance by removing the unnessesary | | | joins. | | | Test results for schema changes are outlined below: | | | instance: <code>db.r5.large</code> | | | size of <code>Threads</code> table: 846313 rows | | | number of posts: 12 million | | | number of reactions: 2.5 million | | |<strong>MySQL:</strong> | | | | | | -- Drop any existing TeamId column from 000094_threads_teamid.up.sql | | | SET @preparedStatement = (SELECT IF( | | | EXISTS(`` | | | SELECT 1 FROM INFORMATION_SCHEMA.STATISTICS | | | WHERE table_name = 'Threads' | | | AND table_schema = DATABASE() | | | AND column_name = 'TeamId' | | | ), | | | 'ALTER TABLE Threads DROP COLUMN TeamId;', | | | 'SELECT 1;' | | | )); | | | PREPARE removeColumnIfExists FROM @preparedStatement; | | | EXECUTE removeColumnIfExists; | | | DEALLOCATE PREPARE removeColumnIfExists; | | | SET @preparedStatement = (SELECT IF( | | | NOT EXISTS( | | | SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS | | | WHERE table_name = 'Threads' | | | AND table_schema = DATABASE() | | | AND column_name = 'ThreadTeamId' | | | ), | | | 'ALTER TABLE Threads ADD COLUMN ThreadTeamId varchar(26) DEFAULT NULL;', | | | 'SELECT 1;' | | | )); | | | PREPARE addColumnIfNotExists FROM @preparedStatement; | | | EXECUTE addColumnIfNotExists; | | | DEALLOCATE PREPARE addColumnIfNotExists; | | | Query OK, 0 rows affected (7.71 sec) | | | UPDATE Threads, Channels | | | SET Threads.ThreadTeamId = Channels.TeamId | | | WHERE Channels.Id = Threads.ChannelId | | | AND Threads.ThreadTeamId IS NULL; | | | Query OK, 846313 rows affected (51.32 sec) | | | Rows matched: 846313 Changed: 846313 Warnings: 0 | | |<strong>PostgreSQL:</strong> | | | | | | -- Drop any existing TeamId column from 000094_threads_teamid.up.sql | | | ALTER TABLE threads DROP COLUMN IF EXISTS teamid; | | | ALTER TABLE threads ADD COLUMN IF NOT EXISTS threadteamid VARCHAR(26); | | | ALTER TABLE | | | Time: 2.236 ms | | | UPDATE threads | | | SET threadteamid = channels. | | | teamid | | | FROM channels | | | WHERE threads.threadteamid IS | | | NULL | | | AND channels.id = threads. | | | channelid; | | | UPDATE 847646 | | | Time: 29744.608 ms (00:29.745) | | |<strong>Backwards-compatibility:</strong> | | | A previous version of Mattermost can run with the new schema changes | | | <strong>Table locks or impact to existing operations on the table:</strong> | | | Table locks - Threads table | | | Queries posted above can be run prior to upgrading Mattermost for both MySQL and PostgreSQL. After schema changes migration becomes instantaneous (0.78 sec). | | | Starting with the Calls version shipping with v7.7, there's now a minimum version requirement when using the external RTCD service. This means that if Calls is | | | configured to use the external service, customers need to upgrade RTCD first to at least version 0.8.0 or the plugin will fail to start. | | | In v7.7.2, <a href="/docs/mattermost/configure/site-configuration/#message-priority" class="doc-ref">Message Priority & Acknowledgement</a> is now enabled by | | | default for all instances. You may disable this feature in the System Console by going to <strong>Posts > Message Priority</strong> or via the config <code>PostPriority</code> | | | setting. | <table><thead><tr><th>v7.5</th><th>Added a new schema migration to ensure <code>ParentId</code> column is dropped from the <code>Posts</code> table. Depending on the table size, if the column is not dropped before, a significant spike in database CPU usage is expected on MySQL databases. Writes to the table will be limited during the migration.</th></tr></thead></table> | | For <code>PluginRegistry.registerCustomRoute</code>, when you register a custom route component, you must specify a CSS <code>grid-area</code> in order for it to be placed | | | properly into the root layout (recommended: <code>grid-area: center</code>). | <table><thead><tr><th>v7.3</th><th>Boards is moving from a channel-based to a role-based permissions system. The migration will happen automatically, but your administrator should perform a backup prior to the upgrade. We removed workspaces, so if you were a member of many boards prior to migration, they will now all appear under the same sidebar.</th></tr><tr><th>v7.2</th><th>Several schema changes impose additional database constraints to make the data more strict. All the commands listed below were tested on a 8 core, 16GB RAM machine. Here are the times recorded: <strong>PostgreSQL (131869 channels, 2 teams)</strong>: - <code>CREATE TYPE channel_type AS ENUM ('P', 'G', 'O', 'D');</code> took 14.114 milliseconds - <code>ALTER TABLE channels alter column type type channel_type using type::channel_type;</code> took 3856.790 milliseconds (3.857 seconds) - <code>CREATE TYPE team_type AS ENUM ('I', 'O');</code> took 4.191 milliseconds - <code>ALTER TABLE teams alter column type type team_type using type::team_type;</code> took 116.205 milliseconds - <code>CREATE TYPE upload_session_type AS ENUM ('attachment', 'import');</code> took 4.266 milliseconds - <code>ALTER TABLE uploadsessions alter column type type upload_session_type using type::upload_session_type;</code> took 37.099 milliseconds <strong>MySQL (270959 channels, 2 teams)</strong>: - <code>ALTER TABLE Channels MODIFY COLUMN Type ENUM("D", "O", "G", "P");</code> took 13.24 seconds - <code>ALTER TABLE Teams MODIFY COLUMN Type ENUM("I", "O");</code> took 0.04 seconds - <code>ALTER TABLE UploadSessions MODIFY COLUMN Type ENUM("attachment", "import");</code> took 0.03 seconds</th></tr><tr><th>v7.1</th><th>A new configuration option <code>MaxImageDecoderConcurrency</code> indicates how many images can be decoded concurrently at once. The default is -1, and the value indicates the number of CPUs present. This affects the total memory consumption of the server. The maximum memory of a single image is dictated by <code>MaxImageResolution <em> 24 bytes</code>. Therefore, we recommend that <code>MaxImageResolution </em> MaxImageDecoderConcurrency * 24</code> should be less than the allocated memory for image decoding.</th></tr></thead></table> | | Mattermost v7.1 introduces schema changes in the form of a new column and its index. Our test results for the schema changes are included below: | | | - MySQL 12M Posts, 2.5M Reactions - ~1min 34s (instance: PC with 8 cores, 16GB RAM) | | | - PostgreSQL 12M Posts, 2.5M Reactions - ~1min 18s (instance: db.r5.2xlarge) | | | You can run the following SQL queries before the upgrade to obtain a lock on <code>Reactions</code> table, so that users' reactions posted during this time won't be | | | reflected in the database until the migrations are complete. This is fully backwards-compatible. | | | MySQL: | | | - <code>ALTER TABLE Reactions ADD COLUMN ChannelId varchar(26) NOT NULL DEFAULT "";</code> | | | - <code>UPDATE Reactions SET ChannelId = COALESCE((select ChannelId from Posts where Posts.Id = Reactions.PostId), '') WHERE ChannelId="";</code> | | | - <code>CREATE INDEX idx_reactions_channel_id ON Reactions(ChannelId) LOCK=NONE;</code> | | | PostgreSQL: | | | - <code>ALTER TABLE reactions ADD COLUMN IF NOT EXISTS channelid varchar(26) NOT NULL DEFAULT '';</code> | | | - <code>UPDATE reactions SET channelid = COALESCE((select channelid from posts where posts.id = reactions.postid), '') WHERE channelid='';</code> | | | - <code>CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_reactions_channel_id on reactions (channelid);</code> | <table><thead><tr><th>v7.0</th><th><strong>IMPORTANT:</strong> Session length configuration settings have changed from using a unit of <em>days</em> to <em>hours</em>. Instances using a config.json file or a database configuration for the following values should be automatically migrated to the new units, but instances using environment variables must make the following changes: 1. replace <code>MM_SERVICESETTINGS_SESSIONLENGTHWEBINDAYS</code> with <code>MM_SERVICESETTINGS_SESSIONLENGTHWEBINHOURS</code> (x24 the value). 2. replace <code>MM_SERVICESETTINGS_SESSIONLENGTHMOBILEINDAYS</code> with <code>MM_SERVICESETTINGS_SESSIONLENGTHMOBILEINHOURS</code> (x24 the value). 3. replace <code>MM_SERVICESETTINGS_SESSIONLENGTHSSOINDAYS</code> with <code>MM_SERVICESETTINGS_SESSIONLENGTHSSOINHOURS</code> (x24 the value).</th></tr></thead></table> | | MySQL self-hosted customers may notice the migration taking longer than usual when having a large number of rows in FileInfo table. For MySQL, it takes around | | | 19 seconds for a table of size 700,000 rows. The time required for PostgreSQL is negligible. The testing was performed on a machine with specifications of | | | <code>CPU - Intel i7 6-cores @ 2.6 GHz</code> and <code>Memory - 16 GB</code>. | | | When a new configuration setting via <strong>System Console > Experimental > Features > Enable App Bar</strong> is enabled, all channel header icons registered by plugins | | | will be moved to the new Apps Bar, even if they do not explicitly use the new registry function to render a component there. The setting for Apps Bar defaults | | | to <code>false</code> for self-hosted deployments. | | | The value of <code>ServiceSettings.TrustedProxyIPHeader</code> defaults to empty from now on. A previous bug prevented this from happening in certain conditions. | | | Customers are requested to check for these values in their config and set them to nil if necessary. See more details | | | <a href="/docs/mattermost/configure/environment-configuration-settings/#trusted-proxy-ip-header" class="doc-ref">here</a>. | | | <a href="/docs/mattermost/collaborate/organize-conversations/" class="doc-ref">Collapsed Reply Threads</a> is now generally available and enabled by default for new | | | Mattermost servers. For servers upgrading to v7.0 and later, please reference | | | <a href="https://support.mattermost.com/hc/en-us/articles/6880701948564-Administrator-s-guide-to-enabling-Collapsed-Reply-Threads">this article</a> for more information | | | and guidance on enabling the feature. | <table><thead><tr><th>v6.7</th><th>New schema changes were introduced in the form of a new index. The following summarizes the test results measuring how long it took for the database queries to run with these schema changes: MySQL 7M Posts - ~17s (Instance: db.r5.xlarge) MySQL 9M Posts - 2min 12s (Instance: db.r5.large) Postgres 7M Posts - ~9s (Instance: db.r5.xlarge) For customers wanting a zero downtime upgrade, they are encouraged to apply this index prior to doing the upgrade. This is fully backwards compatible and will not acquire any table lock or affect any existing operations on the table when run manually. Else, the queries will run during the upgrade process and will lock the table in non-MySQL environments. Run the following to apply this index: For MySQL: <code>CREATE INDEX idx_posts_create_at_id on Posts(CreateAt, Id) LOCK=NONE;</code> For Postgres: <code>CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_posts_create_at_id on posts(createat, id);</code></th></tr></thead></table> | | In v6.7.1, the value of <code>ServiceSettings.TrustedProxyIPHeader</code> defaults to empty from now on. A previous bug prevented this from happening in certain | | | conditions. Customers are requested to check for these values in their config and set them to nil if necessary. See more details | | | <a href="/docs/mattermost/configure/environment-configuration-settings/#trusted-proxy-ip-header" class="doc-ref">here</a>. | <table><thead><tr><th>v6.6</th><th>The Apps Framework protocol for binding/form submissions has changed, by separating the single `call` into separate `submit`, `form`, `refresh` and `lookup` calls. If any users have created their own Apps, they have to be updated to the new system.</th></tr></thead></table> | | Channel admins can now configure <a href="/docs/mattermost/collaborate/create-channels/" class="doc-ref">certain actions</a> to be executed automatically based on trigger | | | conditions without writing any code. Users running an older Playbooks release need to upgrade their Playbooks instance to at least v1.26 to take advantage of | | | the channel actions functionality. | | | In v6.6.2, the value of <code>ServiceSettings.TrustedProxyIPHeader</code> defaults to empty from now on. A previous bug prevented this from happening in certain | | | conditions. Customers are requested to check for these values in their config and set them to nil if necessary. See more details | | | <a href="/docs/mattermost/configure/environment-configuration-settings/#trusted-proxy-ip-header" class="doc-ref">here</a>. | <table><thead><tr><th>v6.5</th><th>The <code>mattermost version</code> CLI command does not interact with the database anymore. Therefore the database version is not going to be printed. Also, the database migrations are not going to be applied with the version sub command. <a href="/docs/mattermost/manage/command-line/#mattermost-db-migrate" class="doc-ref">A new db migrate sub command</a> is added to enable administrators to trigger migrations.</th></tr></thead></table> | | In v6.5.2, the value of <code>ServiceSettings.TrustedProxyIPHeader</code> defaults to empty from now on. A previous bug prevented this from happening in certain | | | conditions. Customers are requested to check for these values in their config and set them to nil if necessary. See more details | | | <a href="/docs/mattermost/configure/environment-configuration-settings/#trusted-proxy-ip-header" class="doc-ref">here</a>. | <table><thead><tr><th>v6.4</th><th>A new schema migration system has been introduced, so we strongly recommend backing up the database before updating the server to this version. The new migration system will run through all existing migrations to record them to a new table. This will only happen for the first run in order to migrate the application to the new system. The table where the migration information is stored is called <code>db_migrations</code>. Additionally, a <code>db_lock</code> table is used to prevent multiple installations from running migrations in parallel. In case of an error while applying the migrations, please check this table first. Any downtime depends on how many records the database has and whether there are missing migrations in the schema. If you encounter an issue please file <a href="https://github.com/mattermost/mattermost-server/issues">an Issue</a> by including the failing migration name, database driver/version, and the server logs. On MySQL, if you encounter an error "Failed to apply database migrations" when upgrading to v6.4.0, it means that there is a mismatch between the table collation and the default database collation. You can manually fix this by changing the database collation with <code>ALTER DATABASE <YOUR_DB_NAME> COLLATE = 'utf8mb4_general_ci',</code>. Then do the server upgrade again and the migration will be successful. It has been commonly observed on MySQL 8+ systems to have an error <code>Error 1267: Illegal mix of collations</code> when upgrading due to changing the default collation. This is caused by the database and the tables having different collations. If you get this error, please change the collations to have the same value with, for example, <code>ALTER DATABASE <db_name> COLLATE = '<collation>'</code>.</th></tr></thead></table> | | The new migration system requires the MySQL database user to have additional <em>EXECUTE</em>, <em>CREATE ROUTINE</em>, <em>ALTER ROUTINE</em> and <em>REFERENCES</em> privileges to run | | | schema migrations. | <table><thead><tr><th>v6.3</th><th>In v6.3.3, the default for <code>ThreadAutoFollow</code> has been changed to <code>false</code>. This does not affect existing configurations where this value is already set to <code>true</code>.</th></tr></thead></table> | | In v6.3.9, the value of <code>ServiceSettings.TrustedProxyIPHeader</code> defaults to empty from now on. A previous bug prevented this from happening in certain | | | conditions. Customers are requested to check for these values in their config and set them to nil if necessary. See more details | | | <a href="/docs/mattermost/configure/environment-configuration-settings/#trusted-proxy-ip-header" class="doc-ref">here</a>. | <table><thead><tr><th>v6.2</th><th>Channel results in the channel autocomplete will include private channels. Customers using <a href="/docs/mattermost/configure/bleve-search/" class="doc-ref">Bleve</a> or <a href="/docs/mattermost/scale/elasticsearch/" class="doc-ref">Elasticsearch</a> for autocomplete will have to reindex their data to get the new results. Since this can take a long time, we suggest disabling autocomplete and running indexing in the background. When this is complete, re-enable autocomplete.

Note

Only channel members see private channel names in autocomplete results.</th></tr></thead></table> | | In v6.2.3, the default for <code>ThreadAutoFollow</code> has been changed to <code>false</code>. This does not affect existing configurations where this value is already set to | | | <code>true</code>. | | | Mattermost Boards requires <code>EnableReliableWebSockets</code> setting to be manually set to <code>true</code> for real-time updates to appear correctly. | <table><thead><tr><th>v6.1</th><th>Please refer to <a href="https://gist.github.com/streamer45/997b726a86b5d2a624ac2af435a66086">the schema migration analysis</a> when upgrading to v6.1.</th></tr></thead></table> | | The Bleve index has been updated to use the scorch index type. This new default index type features some efficiency improvements which means that the indexes | | | use significantly less disk space. To use this new type of index, after upgrading the server version, run a purge operation and then a reindex from the Bleve | | | section of the System Console. Bleve is still compatible with the old indexes, so the currently indexed data will work fine if the purge and reindex is not run. | | | A composite index has been added to the jobs table for better query performance. For some customers with a large jobs table, this can take a long time, so we | | | recommend adding the index during off-hours, and then running the migration. A table with more than 1 million rows can be considered as large enough to be | | | updated prior to the upgrade. | | | - For PostgreSQL: <code>create index concurrently idx_jobs_status_type on jobs (status,type);</code> | | | - For MySQL: <code>create index idx_jobs_status_type on Jobs (Status,Type);</code> | | | In v6.1.3, the default for <code>ThreadAutoFollow</code> has been changed to <code>false</code>. This does not affect existing configurations where this value is already set to | | | <code>true</code>. | | | Mattermost Boards requires <code>EnableReliableWebSockets</code> setting to be manually set to <code>true</code> for real-time updates to appear correctly. | <table><thead><tr><th>v6.0</th><th>Longer migration times can be expected. - See <a href="https://gist.github.com/streamer45/59b3582118913d4fc5e8ff81ea78b055">this document</a> for the estimated upgrade times with datasets of 10+ million posts. - See <a href="https://gist.github.com/streamer45/868c451164f6e8069d8b398685a31b6e">this document</a> for the estimated upgrade times with datasets of 70+ million posts. The field type of Data in <code>model.ClusterMessage</code> was changed to []byte from string. A v6 server is incompatible to run along with a v5 server in a cluster. Customers upgrading from 5.x to 6.x cannot do a High Availability upgrade. While upgrading, it is required that no other v5 server runs when a v6 server is brought up. A v6 server will run significant database schema changes that can cause a large startup time depending on the dataset size. Zero downtime will not be possible, but depending on the efforts made during the migration process, it can be minimized to a large extent. 1. Low effort, long downtime - This is the usual process of starting a v6 server normally. This has two implications: during the migration process, various tables will be locked which will render those tables read-only during that period. Secondly, once the server finishes migration and starts the application, no other v5 server can run in the cluster. 2. Medium effort, medium downtime - This process will require SQL queries to be executed manually on the server. To avoid causing a table lock, a customer can choose to use the pt-online-schema-change tool for MySQL. For Postgres, the table locking is very minimal. The advantage is that since there are a lot of queries, the customer can take their own time to run individual queries during off-hours. All queries except #11 are safe to be executed this way. Then the usual method of (1) can be followed. 3. High effort, low downtime - This process requires everything of (2), plus it tries to minimize the impact of query #11. We can do this by following step 2, and then starting v6 along with a running v5 server, and then monitor the application logs. As soon as the v6 application starts up, we need to bring down a v5 node. This minimizes the downtime to only a few seconds. It is recommended to start Mattermost directly and not through systemctl to avoid the server process getting killed during the migration. This can happen since the value of <code>TimeoutStartSec</code> in the provided systemctl service file is set to one hour. Customers using the Mattermost Kubernetes operator should be aware of the above migration information and choose the path that is most appropriate for them. If (1) is acceptable, then the normal upgrade process using the operator will suffice. For minimum downtime, follow (2) before using the operator to update Mattermost following the normal upgrade process.</th></tr></thead></table> | | While trying to upgrade to a Mattermost version >= 6.0.x, you might encounter the following error: ``Failed to alter column type. It is likely you have invalid | | | JSON values in the column. Please fix the values manually and run the migration again.`` | | | This means that the particular column has some invalid JSON values which need to be fixed manually. A common fix that is known to work is to wipe out all | | | <code>\u0000</code> characters. | | | Please follow these steps: | | | 1. Check the affected values by: <code>SELECT COUNT(*) FROM <table> WHERE <column> LIKE '%\u0000%';</code> | | | 2. If you get a count more than 0, check those values manually, and confirm they are okay to be removed. | | | 3. Remove them by <code>UPDATE <table> SET <column> = regexp_replace(<column>, '\u0000', '', 'g') where <column> like '%\u0000%';</code> | | | Then try to start Mattermost again. | | | Please see <a href="https://docs.mattermost.com/product-overview/unsupported-legacy-releases" target="_blank" rel="noopener noreferrer" class="doc-ref">unsupported legacy releases</a> documentation for a list of deprecations in this release. | | | Focalboard plugin has been renamed to Mattermost Boards, and v0.9.1 (released with Mattermost v6.0) is now enabled by default. | | | The advanced logging configuration schema changed. This is a breaking change relative to 5.x. See updated | | | <a href="/docs/mattermost/manage/logging/" class="doc-ref">documentation</a>. | | | The existing theme names and colors, including "Mattermost", "Organization", "Mattermost Dark", and "Windows Dark" have been updated to the new "Denim", | | | "Quartz", "Indigo", and "Onyx" theme names and colors, respectively. Anyone using the existing themes will see slightly modified theme colors after their | | | server or workspace is upgraded. The theme variables for the existing "Mattermost", "Organization", "Mattermost Dark", and "Windows Dark" themes will still be | | | accessible in <a href="https://docs.mattermost.com/end-user-guide/preferences/customize-your-theme" target="_blank" rel="noopener noreferrer" class="doc-ref">our documentation</a>. A custom theme can be created with these theme variables if desired. | | | Custom themes are unaffected by this change. | | | Some breaking changes to plugins are included: | | | - Support for left-hand side-specific bot icons was dropped. | | | - Removed a deprecated "Backend" field from the plugin manifest. | | | - Converted the "Executables" field in the plugin manifest to a map. | | | Mattermost Boards requires <code>EnableReliableWebSockets</code> setting to be manually set to <code>true</code> for real-time updates to appear correctly. | <table><thead><tr><th>v5.38.0</th><th>The “config watcher” (the mechanism that automatically reloads the <code>config.json</code> file) has been removed in favor of the <code>mmctl config reload</code> command, which must be run to apply configuration changes after they are made on disk. This change improves configuration performance and robustness.</th></tr></thead></table> | | v5.38 adds fixes for some of the incorrect mention counts and unreads around threads and channels since the introduction of Collapsed Reply Threads (Beta). This | | | fix is done through a SQL migration, and it may take several minutes to complete for large databases. The <code>fixCRTChannelMembershipCounts</code> fix takes 1 minute | | | and 20 seconds for a database containing approximately four million channel memberships and about 130,000 channels. The <code>fixCRTThreadCountsAndUnreads</code> fix | | | takes about 3 minutes and 30 seconds for a database containing 56367 threads, 124587 thread memberships, and 220801 channel memberships. These are on MySQL | | | v5.6.51. | | | Focalboard v0.8.2 (released with Mattermost v5.38.0) requires Mattermost v5.37+ due to the new database connection system. | <table><thead><tr><th>v5.37.0</th><th>The <code>platform</code> binary and “--platform” flag have been removed. If you are using the “--platform” flag or are using the <code>platform</code> binary directly to run the Mattermost server application via a systemd file or custom script, you will be required to use only the mattermost binary.</th></tr></thead></table> | | <a href="https://mattermost.com/blog/collapsed-reply-threads-beta/">Collapsed Reply Threads</a> are available as Beta in Mattermost Server | | | v5.37 and later. It’s expected that you may experience bugs as we stabilize the feature. In particular, please be aware of | | | <a href="/docs/mattermost/collaborate/organize-conversations/#known-issues" class="doc-ref">the known issues documented here</a>. | | | v5.37 adds support for emoji standard v13.0. If you have added a custom emoji in the past that uses one of the new system names, then it is going to get | | | overwritten by the system emoji. The workaround is to change the custom emoji name. | | | Parts of Incident Collaboration are now available to all Mattermost editions. As part of this update, Incident Collaboration will require a minimum server | | | version of v5.37. To learn more about what is available in each edition, visit <a href="https://mattermost.com/pricing">our pricing page</a>. | | | In v5.37.8, the default for <code>ThreadAutoFollow</code> has been changed to <code>false</code>. This does not affect existing configurations where this value is already set to | | | <code>true</code>. | <table><thead><tr><th>v5.36.0</th><th>Gossip clustering mode is now in General Availability and is no longer available as an option. All cluster traffic will always use the gossip protocol. The config setting <code>UseExperimentalGossip</code> has no effect and has only been kept for compatibility purposes. The setting to use gossip has been removed from the System Console.

Note

For High Availability upgrades, all nodes in the cluster must use a single protocol. If an existing system is not currently using gossip, one node in a cluster can't be upgraded while other nodes in the cluster use an older version. Customers must either use gossip for their High Availability upgrade, or customers must shut down all nodes, perform the upgrade, and then bring all nodes back up.</th></tr></thead></table> | | To enable Focalboard, open the Marketplace from the sidebar menu, install the Focalboard plugin, then click on <strong>Configure</strong>, enable it, and save. Update your | | | NGINX or Apache web proxy config. | <table><thead><tr><th>v5.35.0</th><th>Due to the introduction of backend database architecture required for upcoming new features, Shared Channels and Collapsed Reply Threads, the performance of the migration process for the v5.35 release (May 16, 2021) has been noticeably affected. Depending on the size, type, and version of the database, longer than usual upgrade times should be expected. This can vary from a couple of minutes (average case) to hours (worst case, MySQL 5.x only). A moderate to significant spike in database CPU usage should also be expected during this process. More details on the <a href="https://gist.github.com/streamer45/9aee4906639a49ebde68b2f3c0f924c1">performance impact of the migration and possible mitigation strategies</a> are available.</th></tr></thead></table> | | The existing password generation logic used during the bulk user import process was comparatively weak. Hence it's advised for admins to immediately reset the | | | passwords for all the users who were generated during the bulk import process and whose password has not been changed even once. | | | v5.35.0 introduces a new feature to search for files. Search results for files shared in the past may be incomplete until a | | | <a href="/docs/mattermost/manage/mmctl/#mmctl-extract" class="doc-ref">content extraction command</a> is executed to extract | | | and index the content of files already in the database. Instances running Elasticsearch or Bleve search backends will also need to execute a Bulk Indexing after | | | the content extraction is complete. Please see more details in <a href="https://mattermost.com/blog/file-search/">this blog post</a>. | <table><thead><tr><th>v5.34.1</th><th>v5.34.1 fixes an issue where upgrading to v5.34.0 runs a migration that can cause timeouts on MySQL installations. Upgrading to v5.34.1 may also execute missing migrations that were scheduled for v5.32.0. These additions can be lengthy on very big MySQL (version 5.x) installations. - Altering of <code>Posts.FileIds</code> type (PostgreSQL only) - Added new column <code>ThreadMemberships.UnreadMentions</code> - Added new column <code>Channels.Shared</code> - Added new column <code>Reactions.UpdateAt</code> - Added new column <code>Reactions.DeleteAt</code></th></tr><tr><th>v5.33.0</th><th>Deleting a reaction is now a soft delete in the <code>Reactions</code> table. A schema update is required and may take up to 15 seconds on first run with large data sets.</th></tr></thead></table> | | WebSocket handshakes done with HTTP version lower than 1.1 will result in a warning, and the server will transparently upgrade the version to 1.1 to comply with | | | the WebSocket RFC. This is done to work around incorrect Nginx (and other proxy) configs that do not set the <code>proxy_http_version</code> directive to 1.1. This | | | facility will be removed in a future Mattermost version and it is strongly recommended to fix the proxy configuration to correctly use the WebSocket protocol. | <table><thead><tr><th>v5.32.0</th><th><code>ExperimentalChannelOrganization</code>, <code>EnableXToLeaveChannelsFromLHS</code>, <code>CloseUnusedDirectMessages</code>, and <code>ExperimentalHideTownSquareinLHS</code> settings are only functional if the Legacy Sidebar (<code>EnableLegacySidebar</code>) is enabled since they are not compatible with the new sidebar experience. <code>ExperimentalChannelSidebarOrganization</code> has been deprecated, since the <a href="https://mattermost.com/blog/custom-collapsible-channel-categories/">new sidebar is now enabled for all users</a>.</th></tr></thead></table> | | Breaking changes to the Golang client API were introduced: <code>GetPostThread</code>, <code>GetPostsForChannel</code>, <code>GetPostsSince</code>, <code>GetPostsAfter</code>, <code>GetPostsBefore</code>, | | | and <code>GetPostsAroundLastUnread</code> now require an additional collapsedThreads parameter to be passed. Any client making use of these functions will need to update | | | them when upgrading its dependencies. | | | <a href="https://go.dev/doc/go1.15">A breaking change was introduced when upgrading the Go version to v1.15.5</a> where user logins fail with AD/LDAP Sync | | | when the certificate of the LDAP Server has no Subject Alternative Name (SAN) in it. Creating a new certificate on the AD/LDAP Server with the SAN inside fixes | | | this. | | | TLS versions 1.0 and 1.1 have been deprecated by browser vendors. Starting in Mattermost Server v5.32 (February 16), mmctl returns an error when connected to | | | Mattermost servers deployed with these TLS versions. System admins will need to explicitly add a flag in their commands to continue to use them. We recommend | | | upgrading to TLS version 1.2 or higher. | <table><thead><tr><th>v5.31.0</th><th>For Mobile Apps v1.42.0+, the minimum server version is set to v5.31.3 as v5.31.3 fixed an issue where the server version was reported as v5.30.0.</th></tr><tr><th>v5.29.0</th><th>A new configuration setting <code>ThreadAutoFollow</code> has been added to support Collapsed Reply Threads releasing in beta in Q1 2021. This setting is enabled by default and may affect server performance. It is recommended to review our <a href="/docs/mattermost/deploy/requirements/#hardware-requirements" class="doc-ref">documentation on hardware requirements</a> to ensure your servers are appropriately scaled for the size of your user base.</th></tr></thead></table> | | Disabled the xmlsec1-based SAML library in favor of the re-enabled and improved SAML library. | <table><thead><tr><th>v5.28.0</th><th>Now when the service crashes, it will generate a coredump instead of just dumping the stack trace to the console. This allows us to preserve the full information of the crash to help with debugging it. For more information about coredumps, please see: https://man7.org/linux/man-pages/man5/core.5.html.</th></tr></thead></table> | | In-product notices have been introduced to keep system admins and end users informed of the latest product enhancements available in new server and desktop | | | versions. <a href="/docs/mattermost/manage/in-product-notices/" class="doc-ref">Learn more about in-product notices</a> and how to disable them in our documentation. | | | Disabled the xmlsec1-based SAML library in favor of the re-enabled and improved SAML library. | <table><thead><tr><th>v5.27.0</th><th>Disabled the xmlsec1-based SAML library in favor of the re-enabled and improved SAML library.</th></tr><tr><th>v5.26.0</th><th>In v5.26, Elasticsearch indexes needed to be recreated. Admins should re-index Elasticsearch using the <strong>Purge index</strong> and then <strong>Index now</strong> button so that all the changes will be included in the index. Systems may be left with a limited search during the indexing, so it should be done during a time when there is little to no activity because it may take several hours.</th></tr></thead></table> | | An <code>EnableExperimentalGossipEncryption</code> option was added under <code>ClusterSettings</code>. If set to <code>true</code>, and <code>UseExperimentalGossip</code> is also <code>true</code>, | | | all communication through the cluster using the gossip protocol will be encrypted. The encryption uses <code>AES-256</code> by default, and it is not kept configurable | | | by design. However, if one wishes, they can set the value in Systems table manually for the <code>ClusterEncryptionKey</code> row. A key is a byte array converted to | | | base64. It should be either 16, 24, or 32 bytes to select AES-128, AES-192, or AES-256. | | | To update the key, one can execute: | | | <code>UPDATE Systems SET Value='<value>' WHERE Name='ClusterEncryptionKey';</code> in MySQL and | | | <code>UPDATE systems SET value='<value>' WHERE name='ClusterEncryptionKey'</code> for PostgreSQL. | | | For any change in this config setting to take effect, the whole cluster must be shut down first. Then the config change made, and then restarted. In a cluster, | | | all servers either will completely use encryption or not. There cannot be any partial usage. | | | SAML Setting "Use Improved SAML Library (Beta)" was forcefully disabled. | | | PostgreSQL ended long-term support for <a href="https://www.postgresql.org/support/versioning">version 9.4 in February 2020</a>. From v5.26 Mattermost officially | | | supports PostgreSQL version 10 as PostgreSQL 9.4 is no longer supported. New installs will require PostgreSQL 10+. Previous Mattermost versions, including our | | | current ESR, will continue to be compatible with PostgreSQL 9.4. PostgreSQL 9.4 and all 9.x versions are now fully deprecated in our v5.30 release | | | (December 16, 2020). Follow the Upgrading Section within <a href="https://www.postgresql.org/support/versioning/">the PostgreSQL documentation</a>. | <table><thead><tr><th>v5.25.0</th><th>Some incorrect instructions regarding SAML setup with Active Directory ADFS for setting the “Relying Party Trust Identifier” were corrected. Although the settings will continue to work, it is encouraged that you <a href="/docs/mattermost/onboard/sso-saml-adfs-msws2016/#add-a-relying-party-trust" class="doc-ref">modify those settings</a>.</th></tr></thead></table> | | Disabled the xmlsec1-based SAML library in favor of the re-enabled and improved SAML library. | <table><thead><tr><th>v5.24.0</th><th>A new configuration setting, <code>ExtendSessionLengthWithActivity</code> automatically extends sessions to keep users logged in if they are active in their Mattermost apps. It is recommended to enable this setting to improve user experience if compliant with your organization's policies. <a href="https://mattermost.com/blog/session-expiry-experience">Learn more here</a>.</th></tr></thead></table> | | The <code>mattermost_http_request_duration_seconds</code> histogram metric (in Enterprise Edition) has been removed. This information was already captured by | | | <code>mattermost_api_time</code>, which also contains the API handler name, HTTP method, and the response code. | | | As an example, if you are using | | | <code>rate(mattermost_http_request_duration_seconds_sum{server=~"$var"}[5m]) / rate(mattermost_http_request_duration_seconds_count{server=~"$var"}[5m])</code> | | | to measure average call duration, it needs to be replaced with | | | <code>sum(rate(mattermost_api_time_sum{server=~"$var"}[5m])) by (instance) / sum(rate(mattermost_api_time_count{server=~"$var"}[5m])) by (instance)</code>. | | | Due to fixing performance issues related to emoji reactions, the performance of the upgrade has been affected in that the schema upgrade now takes more time in | | | environments with lots of reactions in their database. These environments are recommended to perform the schema migration during low usage times and potentially | | | in advance of the upgrade. Since this migration happens before the Mattermost server is fully launched, non-High Availability installs will be unreachable | | | during this time. | | | The migration is a single line of SQL and can be applied directly to the database through the MySQL/PSQL command line clients if you prefer to decouple this | | | from restarting the Mattermost server. It is fully backwards compatible so the schema change can be applied to any previous version of Mattermost without issue. | | | During the time the schema change is running (~30s per million rows in the Reactions table), if end users attempt to react to posts, the emoji reactions will | | | not load for end users. | | | MySQL: <code>ALTER TABLE Reactions DROP PRIMARY KEY, ADD PRIMARY KEY (PostId, UserId, EmojiName);</code> | | | PostgreSQL: <code>ALTER TABLE reactions DROP CONSTRAINT reactions_pkey, ADD PRIMARY KEY (PostId, UserId, EmojiName);</code> | | | On mobile apps, users will not be able to see LDAP group mentions (E20 feature) in the autocomplete dropdown. Users will still receive notifications if they are | | | part of an LDAP group. However, the group mention keyword will not be highlighted. | | | SAML Setting "Use Improved SAML Library (Beta)" was forcefully disabled. Follow instructions at | | | https://docs.mattermost.com/administration-guide/onboard/sso-saml.html for enabling SAML using the feature-equivalent <code>xmlsec1</code> utility. | <table><thead><tr><th>v5.22.0</th><th>Due to fixing performance issues related to emoji reactions, the performance of the upgrade has been affected in that the schema upgrade now takes more time in environments with lots of reactions in their database. These environments are recommended to perform the schema migration during low usage times and potentially in advance of the upgrade. Since this migration happens before the Mattermost server is fully launched, non-High Availability installs will be unreachable during this time. The migration is a single line of SQL and can be applied directly to the database through the MySQL/PSQL command line clients if you prefer to decouple this from restarting the Mattermost server. It is fully backwards compatible so the schema change can be applied to any previous version of Mattermost without issue. During the time the schema change is running (~30s per million rows in the Reactions table), if end users attempt to react to posts, the emoji reactions will not load for end users. MySQL: <code>ALTER TABLE Reactions DROP PRIMARY KEY, ADD PRIMARY KEY (PostId, UserId, EmojiName);</code> Postgres: <code>ALTER TABLE reactions DROP CONSTRAINT reactions_pkey, ADD PRIMARY KEY (PostId, UserId, EmojiName);</code></th></tr></thead></table> | | The Channel Moderation Settings feature is supported on mobile app versions v1.30 and later. In earlier versions of the mobile app, users who attempt to post or | | | react to posts without proper permissions will see an error. | | | Direct access to the <code>Props</code> field in the <code>model.Post</code> structure has been deprecated. The available <code>GetProps()</code> and <code>SetProps()</code> methods should now be | | | used. Also, direct copy of the <code>model.Post</code> structure must be avoided in favor of the provided <code>Clone()</code> method. | | | SAML Setting "Use Improved SAML Library (Beta)" was forcefully disabled. Follow instructions at | | | https://docs.mattermost.com/administration-guide/onboard/sso-saml.html for enabling SAML using the feature-equivalent <code>xmlsec1</code> utility. | <table><thead><tr><th>v5.21.0</th><th>Honour key value expiry in KVCompareAndSet, KVCompareAndDelete, and KVList. We also improved handling of plugin key value race conditions and deleted keys in Postgres.</th></tr></thead></table> | | SAML Setting "Use Improved SAML Library (Beta)" was forcefully disabled. Follow instructions at | | | https://docs.mattermost.com/administration-guide/onboard/sso-saml.html for enabling SAML using the feature-equivalent <code>xmlsec1</code> utility. | <table><thead><tr><th>v5.20.0</th><th>Any <a href="https://developers.mattermost.com/integrate/admin-guide/admin-plugins-beta/#pre-packaged-plugins">pre-packaged plugin</a> that is not enabled in the <code>config.json</code> will no longer install automatically, but can continue to be installed via the <a href="https://developers.mattermost.com/integrate/admin-guide/admin-plugins-beta/#plugin-marketplace">Plugin Marketplace</a>.</th></tr></thead></table> | | Boolean elements from interactive dialogs are no longer serialized as strings. While we try to avoid breaking changes, this change was necessary to allow | | | both the web and mobile apps to work with the boolean elements introduced with v5.16. | <table><thead><tr><th>v5.19.0</th><th><code>LockTeammateNameDisplay</code> setting was moved to Enterprise Edition E20 as it was erroneously available in Team Edition and Enterprise Edition E10.</th></tr><tr><th>v5.18.0</th><th>Marking a post unread from the mobile app requires v1.26 or later. If using v5.18, but mobile is on v1.25 or earlier, marking a post unread from webapp/desktop will only be reflected on mobile the next time the app launches or is brought to the foreground.</th></tr></thead></table> | | The Go module path of <code>mattermost-server</code> was changed to comply with the Go module version specification. Developers using Go modules with | | | <code>mattermost-server</code> as a dependency must change the module and import paths to <code>github.com/mattermost/mattermost-server/v5</code> when upgrade this dependency | | | to `v5.18`. See `<https://go.dev/blog/v2-go-modules>`__ for further information. | | | Removed <code>Team.InviteId</code> from the related Websocket event and sanitized it on all team API endpoints for users without invite permissions. | | | Removed the ability to change the type of a channel using the <code>PUT /channels/{channel_id}</code> API endpoint. The new <code>PUT /channels/{channel_id}/privacy</code> | | | endpoint should be used for that purpose. | <table><thead><tr><th>v5.16.0</th><th>Support for Internet Explorer (IE11) is removed. See <a href="https://forum.mattermost.com/t/mattermost-is-dropping-support-for-internet-explorer-ie11-in-v5-16/7575">this forum post</a> to learn more.</th></tr></thead></table> | | The <a href="https://github.com/mattermost/desktop/blob/master/CHANGELOG.md">Mattermost Desktop v4.3.0</a> release includes a change to how desktop notifications are sent| | | sent from non-secure URLs <code>http://</code>. Organizations using non-secure Mattermost Servers <code>http://</code> will need to update to Mattermost Server versions 5.16.0+, | | | 5.15.1, 5.14.4 or 5.9.5 (ESR) to continue receiving desktop notifications when using Mattermost Desktop v4.3.0 or later. | | | When enabling <a href="/docs/mattermost/onboard/guest-accounts/" class="doc-ref">Guest Accounts</a>, all users who have the ability to invite users will be able to | | | invite guests by default. System admins will need to remove this permission on each role via <strong>System Console > Permissions Schemes</strong>. In Mattermost Server | | | version 5.17, the system admin will be the only role to automatically get the invite guest permission, however the fix will not be applicable in 5.16 due to | | | database migration processes. | <table><thead><tr><th>v5.14.0</th><th>Webhooks are now only displayed if the user is the creator of the webhook or a system administrator.</th></tr></thead></table> | | With the update from Google+ to Google People, system admins need to ensure the <code>GoogleSettings.Scope</code> config.json setting is set to <code>profile email</code> and | | | <code>UserAPIEndpoint</code> setting should be set to <code>https://people.googleapis.com/v1/people/me?personFields=names,emailAddresses,nicknames,metadata</code> per | | | <a href="/docs/mattermost/onboard/sso-google/" class="doc-ref">updated documentation</a>. | <table><thead><tr><th>v5.12.0</th><th>If your plugin uses the <code>DeleteEphemeralMessage</code> plugin API, update it to accept a <code>postId string</code> parameter. See <a href="https://developers.mattermost.com/extend/plugins/server/reference/#API.DeleteEphemeralPost">documentation</a> to learn more.</th></tr></thead></table> | | Image link and YouTube previews do not display unless <strong>System Console > Enable Link Previews</strong> is enabled. Please ensure that your Mattermost server is | | | connected to the internet and has network access to the websites from which previews are expected to appear. | | | <a href="https://forum.mattermost.com/t/link-previews-managed-server-side-in-v5-12-and-later/7712">Learn more here</a>. | | | <code>ExperimentalEnablePostMetadata</code> setting was removed. Post metadata, including post dimensions, is now stored in the database to correct scroll position and | | | eliminate scroll jumps as content loads in a channel. | | | Added the ability to enforce the administration of teams/channels with Group Sync. If Group Sync is enabled, all team and channel admin designations will be | | | lost upon upgrade. It is highly recommended that prior to upgrading, Team and channel admins are added to admin-specific LDAP groups corresponding to their | | | teams and channels. After upgrading, those groups will need to be role-synced to the Team or channel admin role. | <table><thead><tr><th>v5.11.0</th><th>If your integration uses <code>Update.Props == nil</code> to clear <code>Props</code>, this will no longer work in 5.11+. Instead, use <code>Update.Props == {}</code> to clear properties. This change was made because <code>Update.Props == nil</code> unintentionally cleared all <code>Props</code>, such as the profile picture, instead of preserving them.</th></tr><tr><th>v5.10.0</th><th><code>SupportedTimezonesPath</code> setting in config.json and changes to timezones in the UI based on the <code>timezones.json</code> file was removed. This was made to support <a href="/docs/mattermost/configure/configuration-in-your-database/" class="doc-ref">storing configurations in the database</a>.</th></tr><tr><th>v5.9.0</th><th>If <code>DisableLegacyMfa</code> setting in <code>config.json</code> is set to <code>true</code> and <a href="/docs/mattermost/onboard/mfa/" class="doc-ref">multi-factor authentication</a> is enabled, ensure your users have upgraded to mobile app version 1.17 or later. Otherwise, users who have MFA enabled may not be able to log in successfully. If the setting is not defined in the <code>config.json</code> file, the <code>DisableLegacyMfa</code> setting is set to <code>false</code> by default to ensure no breaking changes. We recommend setting <code>DisableLegacyMfa</code> to <code>true</code> for additional security hardening.</th></tr></thead></table> | | The public IP of the Mattermost application server is considered a reserved IP for additional security hardening in the context of untrusted external requests | | | such as Open Graph metadata, webhooks, or slash commands. | | | <a href="/docs/mattermost/configure/environment-configuration-settings/#allow-untrusted-internal-connections" class="doc-ref">See documentation</a> for additional information. | <table><thead><tr><th>v5.8.0</th><th>The local image proxy has been added, and images displayed within the client are now affected by the <code>AllowUntrustedInternalConnections</code> setting. <a href="https://docs.mattermost.com/deployment-guide/server/image-proxy#local-image-proxy" target="_blank" rel="noopener noreferrer" class="doc-ref">See documentation</a> for more details if you have trouble loading images.</th></tr><tr><th>v5.6.0</th><th>Built-in WebRTC is removed. See <a href="https://forum.mattermost.com/t/built-in-webrtc-video-and-audio-calls-removed-in-v5-6- in-favor-of-open-source-plugins/5998">here for more details</a>.</th></tr></thead></table> | | If <code>EnablePublicChannelsMaterialization</code> setting in <code>config.json</code> is set to <code>false</code>, an offline migration prior to upgrade may be required to synchronize | | | the materialized table for public channels to increase channel search performance in the channel switcher (CTRL/CMD+K), channel autocomplete (~), and elsewhere | | | in the UI. Use the following steps: | | | 1. Shut down your application servers. | | | 2. Connect to your Mattermost database. | | | 3. Execute the following queries: | | | | | | DELETE FROM PublicChannels; | | | INSERT INTO PublicChannels | | | (Id, DeleteAt, TeamId, DisplayName, Name, Header, Purpose) | | | SELECT | | | c.Id, c.DeleteAt, c.TeamId, c.DisplayName, c.Name, c.Header, c.Purpose | | | FROM | | | Channels c | | | WHERE | | | c.Type = 'O'; | | | The queries above rebuild the materialized <code>PublicChannels</code> table without modifying the authoritative <code>Channels</code> table. | | |

Note

| | | This migration is not required if the experimental <code>PublicChannels</code> feature was never disabled. This feature launched in Mattermost v5.4 with a | | | temporary flag to disable should an issue arise, but nothing prompted doing so. If you did not modify this setting, there is no need to perform this migration. | <table><thead><tr><th>v5.4.0</th><th>Mattermost mobile app version 1.13+ is required. File uploads will fail on earlier mobile app versions.</th></tr></thead></table> | | In certain upgrade scenarios the new<strong>Allow Team Administrators to edit others posts</strong> setting under <strong>General</strong> then <strong>Users and Teams</strong> may be | | | set to <strong>True</strong> while the Mattermost default in 5.1 and earlier and with new 5.4+ installations is <strong>False</strong>. | <table><thead><tr><th>v5.3.0</th><th>Those servers with Elasticsearch enabled will notice that hashtag search is case-sensitive.</th></tr><tr><th>v5.2.0</th><th>Those servers upgrading from v4.1 - v4.4 directly to v5.2 or later and have Jira enabled will need to re-enable the Jira plugin after an upgrade.</th></tr><tr><th>v5.1.0</th><th><code>mattermost export</code> CLI command is renamed to <code>mattermost export schedule</code>. Make sure to update your scripts if you use this command.</th></tr><tr><th>v5.0.0</th><th>All API v3 endpoints are removed. <a href="https://api.mattermost.com/#tag/APIv3-Deprecation">See documentation</a> to learn how to migrate your integrations to API v4.</th></tr></thead></table> | | <code>platform</code> binary is renamed to <code>mattermost</code> for a clearer install and upgrade experience. You should point your <code>systemd</code> service file at the new | | | <code>mattermost</code> binary. All command line tools, including the bulk loading tool and developer tools, are also be renamed from <code>platform</code> to <code>mattermost</code>. | | | A Mattermost user setting to configure desktop notification duration in <strong>Account Settings > Notifications > Desktop Notifications</strong> is removed. | | | Slash commands configured to receive a GET request will have the payload being encoded in the query string instead of receiving it in the body of the request, | | | consistent with standard HTTP requests. Although unlikely, this could break custom slash commands that use GET requests incorrectly. | | | A new <code>config.json</code> setting to whitelist types of protocols for auto-linking will be added. | | | If you rely on custom protocols auto-linking in Mattermost, whitelist them in <code>config.json</code> before upgrading. | | | A new <code>config.json</code> setting to disable the <a href="https://api.mattermost.com/#tag/teams%2Fpaths%2F~1teams~1%7Bteam_id%7D%2Fput">permanent APIv4 delete team parameter | | |</a> is added. The setting will be off by default for all new and existing | | | installs, except those deployed on GitLab Omnibus. If you reply on the APIv4 parameter, enable the setting in <code>config.json</code> before upgrading. | | | An unused <code>ExtraUpdateAt</code> field will be removed from the channel modal. | | | This release includes support for post messages longer than the default of 4000 characters, but may require a manual database migration. This migration is | | | entirely optional, and need only be done if you want to enable post messages up to 16383 characters. For many installations, no migration will be required, or | | | the old limit remains sufficient. | | | To check your current post limit after upgrading to 5.0.0, look for a log message on startup: | | | <code>[2018/03/27 09:08:00 EDT] [INFO] Post.Message supports at most 16383 characters (65535 bytes)</code> | | | As of 5.0.0, the maximum post message size is 16383 (multi-byte) characters. If your logs show a number less than this limit and you want to enable longer | | | post messages, you will need to manually migrate your database as described below. This migration can be slow for larger <code>Posts</code> tables, so it's best to | | | schedule this upgrade during off-peak hours. | | | To migrate a MySQL database, connect to your database and run the following: | | | <code>ALTER TABLE Posts MODIFY COLUMN Message TEXT;</code> | | | To migrate a PostgreSQL database, connect to your database and run the following: | | | <code>ALTER TABLE Posts ALTER COLUMN Message TYPE VARCHAR(65535);</code> | | | Restart your Mattermost instances. | | | Deployments on Enterprise E20 will need to enable <code>RunJobs</code> in the <code>config.json</code> and allow the permissions migration to complete before using <a href="/docs/mattermost/onboard/advanced-permissions/" class="doc-ref">Team | | | Override Schemes</a>. | <table><thead><tr><th>v4.10.0</th><th>Old email invitation links will no longer work due to a bug fix where teams could be re-joined via the link. Team invite links copied from the Team Invite Link dialog, password reset links and email verification links are not affected and are still valid.</th></tr></thead></table> | | Server logs written to <strong>System Console > Logs</strong> and to the <code>mattermost.log</code> file specified in <strong>System Console > Logging > File Log Directory</strong> | | | now use JSON formatting. If you have built a tool that parses the server logs and sends them to an external system, make sure it supports the JSON format. | | | Team icons with transparency will be filled with a white background in the Team sidebar. | | | Those servers with SAML authentication enabled should upgrade during non-peak hours. SAML email addresses are migrated to lowercase to prevent login issues, | | | which could result in longer than usual upgrade time. | | | If you use PostgreSQL database and the password contains special characters (e.g. <code>[]</code>), escape them in your password, e.g., xxx[]xxx will be xxx%5B%5Dxxx. | <table><thead><tr><th>v4.9.0</th><th>To improve the production use of Mattermost with Docker, the Docker image is now running a as non-root user and listening on port 8000. Please read the <a href="https://github.com/mattermost/mattermost-docker#upgrading-mattermost-to-49">upgrade instructions</a> for important changes to existing installations.</th></tr></thead></table> | | Several configuration settings have been migrated to roles in the database and changing their <code>config.json</code> values no longer takes effect. These permissions | | | can still be modified by their respective System Console settings as before. The affected <code>config.json</code> settings are: | | | - <code>RestrictPublicChannelManagement</code>, | | | - <code>RestrictPrivateChannelManagement</code>, | | | - <code>RestrictPublicChannelCreation</code>, | | | - <code>RestrictPrivateChannelCreation</code>, | | | - <code>RestrictPublicChannelDeletion</code>, | | | - <code>RestrictPrivateChannelDeletion</code>, | | | - <code>RestrictPrivateChannelManageMembers</code>, | | | - <code>EnableTeamCreation</code>, | | | - <code>EnableOnlyAdminIntegrations</code>, | | | - <code>RestrictPostDelete</code>, | | | - <code>AllowEditPost</code>, | | | - <code>RestrictTeamInvite</code>, | | | - <code>RestrictCustomEmojiCreation</code>. | | | The behavior of the <code>config.json</code> setting <code>PostEditTimeLimit</code> has been updated to accommodate the migration to a roles based permission system. | | | When post editing is permitted, set <code>"PostEditTimeLimit": -1</code> to allow editing anytime, or set <code>"PostEditTimeLimit"</code> to a positive integer to restrict | | | editing time in seconds. If post editing is disabled, this setting does not apply. | | | If using Let's Encrypt without a proxy server, the server will fail to start with an error message unless the <a href="/docs/mattermost/configure/environment-configuration-settings/#forward-port-80-to-443" class="doc-ref">Forward80To443 | | |</a> <code>config.json</code> setting is set to <code>true</code>. | | | If forwarding port 80 to 443, the server will fail to start with an error message unless the <a href="/docs/mattermost/configure/environment-configuration-settings/#web-server-listen-address" class="doc-ref">ListenAddress | | |</a> <code>config.json</code> setting is set to listen on port 443. | <table><thead><tr><th>v4.6.2</th><th>If using Let's Encrypt without a proxy server, forward port 80 through a firewall, with the <a href="/docs/mattermost/configure/environment-configuration-settings/#forward-port-80-to-443" class="doc-ref">Forward80To443</a> <code>config.json</code> setting set to <code>true</code> to complete the Let's Encrypt certification.</th></tr><tr><th>v4.4.0</th><th>Composite database indexes were added to the <code>Posts</code> table. This may lead to longer upgrade times for servers with more than one million messages.</th></tr></thead></table> | | LDAP sync now depends on email. Make sure all users on your AD/LDAP server have an email address or that their account is deactivated in Mattermost. | <table><thead><tr><th>v4.2.0</th><th>Mattermost now handles multiple content types for integrations, including plaintext content type. If your integration suddenly prints the JSON payload data instead of rendering the generated message, make sure your integration is returning the <code>application/json</code> content-type to retain previous behavior.</th></tr></thead></table> | | By default, user-supplied URLs such as those used for Open Graph metadata, webhooks, or slash commands will no longer be allowed to connect to reserved IP | | | addresses including loopback or link-local addresses used for internal networks. | | | This change may cause private integrations to break in testing environments, which may point to a URL such as http://127.0.0.1:1021/my-command. | | | If you point private integrations to such URLs, you may whitelist such domains, IP addresses, or CIDR notations via the | | | <a href="/docs/mattermost/configure/environment-configuration-settings/#allow-untrusted-internal-connections" class="doc-ref">Allowed Untrusted Internal Connections</a> | | | configuration setting in your local environment. Although not recommended, you may also whitelist the addresses in your production environments. See | | | <a href="/docs/mattermost/configure/environment-configuration-settings/#allow-untrusted-internal-connections" class="doc-ref">documentation to learn more</a>. | | | Push notification, OAuth 2.0 and WebRTC server URLs are trusted and not affected by this setting. | | | Uploaded file attachments are now grouped by day and stored in <code>/data/<date-of-upload-as-YYYYMMDD>/teams/...</code> of your file storage system. | | | Mattermost `/platform<code> repo has been separated to </code>/mattermost-webapp<code> and </code>/mattermost-server``. This may affect you if you have a private fork of the | | | <code>/platform</code> repo. <a href="https://forum.mattermost.com/t/mattermost-separating-platform-into-two-repositories-on-september-6th/3708">More details here</a>. | <table><thead><tr><th>v4.0.0</th><th>(High Availability only) You must manually add new items to the <code>ClusterSettings</code> section of your existing <code>config.json</code>.</th></tr><tr><th>v3.9.0</th><th>Old email invitation links, password reset links, and email verification links will no longer work due to a security change. Team invite links copied from the Team Invite Link dialog are not affected and are still valid.</th></tr><tr><th>v3.8.0</th><th>A change is required in the proxy configuration. If you’re using NGINX: 1. Open the NGINX configuration file as root. The file is usually <code>/etc/nginx/sites-available/mattermost</code> but might be different on your system. 2. Locate the line: <code>location /api/v3/users/websocket {</code> 3. Replace the line with <code>location ~ /api/v[0-9]+/(users/)?websocket$ {</code> If you are using a proxy other than NGINX, make the equivalent change to that proxy's configuration.</th></tr></thead></table> | | You need to verify settings in the System Console due to a security-related change. | | | 1. Go to the the GENERAL section of the System Console | | | 2. Click <strong>Logging</strong> | | | 3. Make sure that the <strong>File Log Directory</strong> field is either empty or has a directory path only. It must not have a filename as part of the path. | | | Backwards compatibility with the old CLI tool was removed. If you have any scripts that rely on the old CLI, they must be revised to use the | | | <a href="/docs/mattermost/manage/command-line/" class="doc-ref">new CLI</a>. | <table><thead><tr><th>v3.6.0</th><th>Update the maximum number of files that can be open. On RHEL6 and Ubuntu 14.04: - Verify that the line <code>limit nofile 50000 50000</code> is included in the <code>/etc/init/mattermost.conf</code> file. On RHEL7 and Ubuntu 16.04: - Verify that the line <code>LimitNOFILE=49152</code> is included in the <code>/etc/systemd/system/mattermost.service</code> file.</th></tr></thead></table> | | (Enterprise Only) | | | Previous <code>config.json</code> values for restricting Public and Private channel management will be used as the default values for new settings for restricting | | | Public and Private channel creation and deletion. | <table><thead><tr><th>v3.4.0</th><th>If public links are enabled, existing public links will no longer be valid. This is because in earlier versions, existing public links were not invalidated when the Public Link Salt was regenerated. You must update any place where you have published these links.</th></tr></thead></table> .. _000141_add_remoteid_channelid_to_post_acknowledgements.down.sql: https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/postgres/000141_add_remoteid_channelid_to_post_acknowledgements.down.sql .. _000141_add_remoteid_channelid_to_post_acknowledgements.up.sql: https://github.com/mattermost/mattermost/blob/release-10.10/server/channels/db/migrations/postgres/000141_add_remoteid_channelid_to_post_acknowledgements.up.sql .. _this guide: https://github.com/mattermost/mattermost-plugin-agents/blob/master/docs/upgrading_to_2.0.md <h2 id="추가-업그레이드-노트">추가 업그레이드 노트</h2> <div class="admonition note"><div class="admonition-title">Note