---
title: "MySQL 8.0.29 릴리스 노트"
description: "MySQL 8.0.29 Community Server 릴리스 노트를 한국어로 번역하고, DBA가 참고해야 할 핵심 내용을 함께 정리하였습니다."
tags: [ MySQL, 릴리스노트 ]
image: "mysql-release-note.png"
author: "Oracle"
published: "2022-04-26"
updated: ""
source_url: "https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-29.html"
---

## DBA를 위한 핵심 내용

MySQL 8.0.29는 운영 측면에서 `ALGORITHM=INSTANT` DDL 확장, 바이너리 로그 자동 정리 제어, 영구 시스템 변수 보안 저장 방식 변경이 핵심입니다. 특히 외부에서 크게 지적된 위험은 8.0.29의 INSTANT ADD/DROP COLUMN 관련 redo log 변경과 crash recovery/backup prepare 경로의 데이터 손상 가능성 및 XtraBackup 호환성 문제입니다. 따라서 이 버전은 단순 패치 업그레이드가 아니라 DDL, 백업, 복구 검증을 포함한 변경 관리 대상으로 보아야 합니다. ([Percona INSTANT ADD/DROP Columns](https://www.percona.com/blog/percona-xtrabackup-8-0-29-and-instant-add-drop-columns/), [Percona XtraBackup incompatibilities](https://www.percona.com/blog/mysql-8-0-29-and-percona-xtrabackup-incompatibilities/))

1. `ALTER TABLE ... DROP COLUMN` 및 임의 위치 `ADD COLUMN`이 `ALGORITHM=INSTANT`로 가능해졌지만, 64개 row version 제한과 `INFORMATION_SCHEMA.INNODB_TABLES.TOTAL_ROW_VERSIONS` 모니터링이 필요합니다. 8.0.29에서는 외부에서 INSTANT DDL 관련 데이터 손상 및 백업 호환성 리스크가 보고되었으므로, 적용 전 전체 백업/복구 리허설과 INSTANT DDL 사용 제한 정책을 권장합니다.
2. `mysqld-auto.cnf`는 `SET PERSIST` 실행 후 새 형식으로 바뀔 수 있으며 이전 MySQL 버전에서 읽을 수 없습니다. keyring 컴포넌트 위치도 데이터 디렉터리 밖으로 관리해야 하므로 롤백 계획과 keyring 초기화 순서를 점검해야 합니다.
3. `binlog_expire_logs_auto_purge`가 추가되어 바이너리 로그 자동 삭제를 명시적으로 제어할 수 있습니다. PITR, 지연 복제, 외부 백업 도구의 보존 정책과 충돌하지 않도록 `binlog_expire_logs_seconds`/`expire_logs_days`와 함께 재검토해야 합니다.
4. Group Replication은 `group_replication_set_as_primary()`에 timeout을 지정할 수 있어 primary 전환 시 무한 대기를 줄일 수 있습니다. 다만 timeout 만료 시 커밋 전 트랜잭션 연결이 끊길 수 있으므로 운영 절차에 영향 범위를 반영해야 합니다.
5. `utf8` 표시가 `utf8mb3`로 바뀌고, 비표준 날짜/시간 리터럴 구분자 경고가 추가되며, `replica_parallel_type` 등 여러 변수가 사용 중단되었습니다. 배포 스크립트, 스키마 비교 도구, 경고 수집 정책의 오탐을 사전에 조정해야 합니다.

## Authentication 관련 사항

- FIDO 인증자 데이터의 최대 크기가 증가했습니다. (Bug #33655192)

## 캐릭터셋 지원

- **중요 사항:** 서버는 이제 다음 경우에 `utf8`이 아니라 `utf8mb3`를 사용합니다:

  - `SHOW` SQL 문([`SHOW CREATE TABLE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/show-create-table.html), [`SHOW CREATE VIEW`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/show-create-view.html), [`SHOW CREATE DATABASE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/show-create-database.html))의 출력에서
  - 유효하지 않은 문자열을 보고할 때.

  (Bug #33385252, Bug #33395007)

- 서버는 이제 내장 캐릭터셋에서 데이터 딕셔너리 테이블을 채울 때 캐릭터셋 이름에 대해 별칭 `utf8` 대신 `utf8mb3`를 사용합니다. 이는 여기에 나열된 MySQL Information Schema 테이블에서 캐릭터셋 및 관련 정보 표시 방식에 영향을 줍니다:

  - [`CHARACTER_SETS`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-character-sets-table.html)
  - [`COLLATIONS`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-collations-table.html)
  - [`COLUMNS`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-columns-table.html)
  - [`COLLATION_CHARACTER_SET_APPLICABILITY`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-collation-character-set-applicability-table.html)
  - [`PARAMETERS`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-parameters-table.html)
  - [`ROUTINES`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-routines-table.html)
  - [`SCHEMATA`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-schemata-table.html)

  이 변경 사항은 SQL [`SHOW CHARACTER SET`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/show-character-set.html), [`SHOW COLLATION`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/show-collation.html), [`SHOW CREATE DATABASE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/show-create-database.html), [`SHOW CREATE TABLE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/show-create-table.html) 문의 출력에도 영향을 줍니다. (Bug #30624990)

## 컴파일 관련 사항

- **InnoDB:** 관련 문제를 해결한 후 C4100, C4127, C4245 및 C4389 MSVC++ level 4 컴파일러 경고가 다시 활성화되었습니다. (Bug #33437498, Bug #33571677)
- GCC 11은 이제 EL7 또는 EL8에서 MySQL을 빌드하기 위해 지원되는 컴파일러입니다. 이 컴파일러는 `devtoolset-11`(EL7) 또는 `gcc-toolset-11`(EL8) 패키지에서 사용할 수 있습니다. 또한 `libmysqlclient` C API 라이브러리를 기반으로 하는 서드파티 애플리케이션을 빌드할 때도 GCC 11을 사용하는 것이 권장됩니다. (Bug #33730302)
- 서버를 Bison 3.8.1 이상으로 컴파일할 수 없었습니다. (Bug #33488047)

## 사용 중단 및 제거 관련 사항

- **중요 변경:** 이전에는 MySQL이 [`TIME`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/time.html), [`DATE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/datetime.html), [`DATETIME`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/datetime.html), [`TIMESTAMP`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/datetime.html) 리터럴에서 임의의 구분 기호와 임의 개수의 구분 기호를 허용했으며, `DATETIME` 및 `TIMESTAMP` 리터럴의 날짜 값과 시간 값 앞, 뒤, 사이에서도 임의 개수의 공백을 허용했습니다. 이 동작은 이제 사용 중단되었으며, 향후 MySQL 버전에서 제거될 것으로 예상해야 합니다. 이번 릴리스부터 비표준 또는 초과 구분 기호나 공백 문자를 사용하면 이제 Delimiter '*`char`*' in position *`pos`* in datetime value '*`value`*' at row *`rownum`* is superfluous and is deprecated 형식의 경고가 발생하고, 이어서 Please remove가 표시되거나, 적절한 대체 문자를 제안할 수 있는 경우 Prefer the standard '*`replacementchar`*'가 표시됩니다.

  사용 중단 경고는 리터럴 값에서 처음 발견된 비표준 구분 기호 또는 공백 문자에 대해서만 반환됩니다. 예시는 다음과 같습니다:

  ```
  mysql> SELECT DATE"2020/02/20";
  +------------------+
  | DATE"2020/02/20" |
  +------------------+
  | 2020-02-20       |
  +------------------+
  1 row in set, 1 warning (0.00 sec)

  mysql> SHOW WARNINGS\G
  *************************** 1. row ***************************
    Level: Warning
     Code: 4095
  Message: Delimiter '/' in position 4 in datetime value '2020/02/20' at row 1 is
  deprecated. Prefer the standard '-'. 
  1 row in set (0.00 sec)
  ```

  이러한 경고는 strict mode에서 오류로 승격되지 않습니다.

  자세한 정보와 예시는 [String and Numeric Literals in Date and Time Context](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/date-and-time-literals.html#date-and-time-string-numeric-literals)를 참조하십시오. (WL #13601)
- **복제:** [`replica_parallel_type`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/replication-options-replica.html#sysvar_replica_parallel_type) 시스템 변수는 이제 사용 중단되었습니다. 이 변수를 읽거나 설정할 때마다, 또는 동등한 옵션이 `my.cnf`에 설정될 때마다, 서버는 이제 다음과 같이 사용 중단 경고를 발생시킵니다:

  ```sql
  mysql> SELECT @@replica_parallel_type; SHOW WARNINGS\G
  +-------------------------+
  | @@replica_parallel_type |
  +-------------------------+
  | LOGICAL_CLOCK           |
  +-------------------------+
  1 row in set, 1 warning (0.00 sec)

  *************************** 1. row ***************************
    Level: Warning
     Code: 1287
  Message: '@@replica_parallel_type' is deprecated and will be removed in a future
  release. 
  1 row in set (0.00 sec)
  ```

  이 변수와 동등한 서버 옵션 `--replica-parallel-type`은 향후 MySQL 릴리스에서 제거될 것으로 예상해야 합니다.
- [`myisam_repair_threads`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_myisam_repair_threads) 시스템 변수와 **myisamchk** [`--parallel-recover`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/myisamchk-repair-options.html#option_myisamchk_parallel-recover) 옵션은 사용 중단되었습니다. 둘 모두에 대한 지원은 향후 MySQL 릴리스에서 제거될 것으로 예상하십시오.

  [`myisam_repair_threads`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_myisam_repair_threads)에 대해 1(기본값)이 아닌 값은 경고를 발생시킵니다. (WL #14937)
- 서버 시스템 변수 [`query_prealloc_size`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_query_prealloc_size)와 [`transaction_prealloc_size`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_transaction_prealloc_size)는 이제 사용 중단되었으며, 이들 중 하나 또는 둘 모두를 설정해도 더 이상 MySQL 서버에서 아무 효과가 없습니다. 이 변수들은 향후 MySQL 릴리스에서 제거될 것으로 예상하십시오.

  자세한 내용은 문서([Server System Variables](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html))에서 이러한 변수에 대한 설명을 참조하십시오. (WL #13720)

  참조: 다음도 참조하십시오: Bug #26940369.
- 이전에 테스트에서 사용되었고 일반적으로 프로덕션 설정에서는 필요하지 않은 **mysqld**의 [`--abort-slave-event-count`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/replication-options-replica.html#option_mysqld_abort-slave-event-count) 및 `--disconnect-slave-event-count` 옵션은 사용 중단되었습니다. 이 옵션들은 향후 MySQL 버전에서 제거될 것으로 예상하십시오. (WL #14526)

## SQL 함수 및 연산자 관련 사항

- `NULL`과 값을 비교하는 표현식을 기반으로 하는 집계 함수가 `NULL`을 올바르게 무시하지 않았습니다. (Bug #33624777, Bug #105762)
- 최적화 중 집계 함수가 평가될 때는 `WHERE` 조건이 이미 평가되었다고 가정하며, 따라서 이를 제거할 수 있습니다. 제거하기 전에 Optimizer는 `make_cond_for_table()` 호출을 수행하여 `WHERE` 조건에 테이블 독립적인 조건이 있는지 확인합니다. 조건이 비용이 많이 든다고 간주된 경우(예: 저장 프로시저를 사용한 경우), 테이블 독립적인 조건이 있다고 잘못 가정했습니다. `make_cond_for_table()` 호출에서 비용이 많이 드는 조건을 제외하여 이 문제를 수정했습니다.

  또한 함수 `f()`가 어떤 테이블도 사용하지 않는 `f() = 1`과 같이 평가 비용이 많이 드는 상수 조건은 종종 잘못된 결과를 초래했습니다. 대부분의 경우, 조건이 실행에 대해 상수이면 `WHERE` 조건을 최적화할 때 평가되며, 너무 비용이 많이 든다고 간주되면 이를 건너뜁니다. 현재 문제는 암시적으로 그룹화된 쿼리를 최적화하는 동안 조건을 건너뛰었기 때문에 발생했습니다. 이를 방지하기 위해 이제 집계 전에 이러한 조건을 평가합니다. (Bug #33305617)
- [`DEFAULT()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/miscellaneous-functions.html#function_default) 함수에서 사용하는 컬럼이 해당 인수를 수정할 때 내부적으로 `READ`로 표시되지 않았습니다. (Bug #33142135)

## Optimizer 관련 사항

- [`LOAD DATA`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/load-data.html)를 사용하여 로드 중인 테이블의 컬럼이 [`SET`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/set-variable.html) 문 내부에서 사용된 서브쿼리의 `WHERE` 절에서 사용된 경우, 해당 컬럼이 `unknown`으로 보고되었습니다. (Bug #33714885)
- 인덱스 조회(`eq_ref`)를 수행한 집계 쿼리가 일부 경우에 잘못된 결과를 반환할 수 있었습니다. 이는 실행 계획이 임시 테이블에서의 집계 대신 스트리밍 집계를 사용했을 때 확인되었습니다.

  이 문제는 집계 노드 아래에서 `eq_ref` 캐시를 비활성화하여 수정되었습니다. (Bug #33491183)

  References: 이 문제는 다음의 회귀입니다: Bug #100614, Bug #31790217.
- 파생 구체화 테이블 조건 푸시다운 최적화를 이제 대부분의 유니온과 함께 사용할 수 있습니다. 이는 외부 `WHERE` 조건을 이제 구체화된 파생 테이블 또는 뷰의 쿼리 표현식에 있는 모든 쿼리 블록으로 푸시다운할 수 있음을 의미합니다.

  여기에 표시된 SQL 문을 사용하여 테이블 `t1` 및 `t2`를 생성한 다음, 이 두 테이블을 기반으로 뷰 `v`를 생성한다고 가정합니다:

  ```
  CREATE TABLE t1 (
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    c1 INT, 
    KEY i1 (c1)
  );

  CREATE TABLE t2 (
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    c1 INT, 
    KEY i1 (c1)
  );

  CREATE OR REPLACE VIEW v AS
       SELECT id, c1 FROM t1
       UNION ALL
       SELECT id, c1 FROM t2;
  ```

  이제 쿼리 `SELECT * FROM v WHERE c1 = 12`가 실행되면, [`EXPLAIN`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/explain.html#explain-execution-plan)의 출력에서 여기에 표시된 것처럼 조건 `c1 = 12`가 뷰 `v`의 두 쿼리 블록 모두로 푸시다운됩니다:

  ```
  mysql> EXPLAIN FORMAT=TREE SELECT * FROM v WHERE c1 = 12\G
  *************************** 1. row ***************************
  EXPLAIN: -> Table scan on v  (cost=1.26..2.52 rows=2)
      -> Union materialize  (cost=2.16..3.42 rows=2)
          -> Covering index lookup on t1 using i1 (c1=12)  (cost=0.35 rows=1)
          -> Covering index lookup on t2 using i1 (c1=12)  (cost=0.35 rows=1)

  1 row in set (0.00 sec)
  ```

  이제 대부분의 `UNION` 쿼리에 대해 이 작업을 수행할 수 있습니다. 예외 및 추가 정보는 [Derived Condition Pushdown Optimization](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/derived-condition-pushdown-optimization.html)을 참조하십시오. (Bug #24012, Bug #36802, Bug #106006, Bug #11746156, Bug #11748590, Bug #13650627, Bug #30587347, Bug #33318096, Bug #33738597, WL #13730)

## Performance Schema 관련 사항

- 새로운 Performance Schema 계측은 쿼리가 `PRIMARY` 또는 `SECONDARY` 엔진에서 처리되었는지에 대한 정보를 수집하며, 여기서 `PRIMARY` 엔진은 `InnoDB`이고 `SECONDARY` 엔진은 MySQL HeatWave입니다. 이 계측은 MySQL HeatWave가 포함된 MySQL Database Service와 함께 사용하기 위한 것입니다.

  두 개의 새로운 Performance Schema 테이블 컬럼이 추가되었습니다:

  - 쿼리가 `PRIMARY` 또는 `SECONDARY` 엔진에서 처리되었는지를 나타내는 `EXECUTION_ENGINE` 컬럼이 Performance Schema statement event 테이블([Performance Schema Statement Event Tables](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/performance-schema-statement-tables.html) 참조)과 [`performance_scema.threads`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/performance-schema-threads-table.html) 및 [`performance_scema.processlist`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/performance-schema-processlist-table.html) 테이블에 추가되었습니다.
  - 쿼리가 `SECONDARY` 엔진에서 처리된 횟수를 나타내는 `COUNT_SECONDARY` 컬럼이 Performance Schema statement summary 테이블([Statement Summary Tables](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/performance-schema-statement-summary-tables.html) 참조)에 추가되었습니다.

  `execution_engine` 컬럼도 MySQL [`sys`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/sys-schema.html) Schema의 `sys.processlist` 및 `sys.x$processlist` 뷰에 추가되었습니다. (WL #14346)

## 보안 관련 사항

- OpenSSL 라이브러리가 번들로 제공되는 플랫폼의 경우, MySQL Server에 링크된 OpenSSL 라이브러리가 1.1.1l에서 1.1.1n 버전으로 업데이트되었습니다. OpenSSL에서 수정된 문제는 [https://www.openssl.org/news/cl111.txt](https://www.openssl.org/news/cl111.txt) 및 [http://www.openssl.org/news/vulnerabilities.html](http://www.openssl.org/news/vulnerabilities.html)에 설명되어 있습니다. (Bug #33840722, Bug #33970835)

## SQL 문법 관련 사항

- [`CREATE FUNCTION`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/create-function.html), [`CREATE PROCEDURE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/create-procedure.html), 및 [`CREATE TRIGGER`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/create-trigger.html) 문에 대해 이제 `IF NOT EXISTS` 옵션이 지원됩니다.

  저장 함수 생성을 위해 사용되는 `CREATE FUNCTION` 및 `CREATE PROCEDURE`의 경우, 이 옵션은 동일한 이름을 가진 루틴이 이미 있을 때 오류가 발생하지 않도록 합니다. 로드 가능 함수를 생성하는 데 사용되는 [`CREATE FUNCTION`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/create-function-loadable.html)의 경우, 이 옵션은 해당 이름을 가진 로드 가능 함수가 이미 존재하는 경우 오류를 방지합니다. `CREATE TRIGGER`의 경우, 이 옵션은 동일한 테이블 및 동일한 스키마에 동일한 이름의 트리거가 이미 있을 때 오류가 발생하지 않도록 합니다. 이는 스크립팅, 신속한 (재)배포, 복제, 및 반복 사용 가능성이 있는 기타 경우에서 이러한 문의 사용 편의성을 향상하기 위한 것입니다.

  이 개선 사항은 이러한 문의 문법을 이미 모두 `IF NOT EXISTS`를 지원하는 [`CREATE DATABASE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/create-database.html), [`CREATE TABLE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/create-table.html), [`CREATE USER`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/create-user.html), 및 [`CREATE EVENT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/create-event.html)의 문법과 더 일관되게 만듭니다. 또한 이는 [`DROP PROCEDURE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/drop-procedure.html), [`DROP FUNCTION`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/drop-function.html), 및 [`DROP TRIGGER`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/drop-trigger.html)에서 이미 지원되는 `IF EXISTS` 옵션을 보완합니다.

  자세한 내용은 [Stored Objects](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/stored-objects.html) 및 [Function Name Resolution](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/function-resolution.html#function-name-resolution)을 참조하십시오. [Replication of CREATE TABLE... SELECT Statements](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/replication-features-create-select.html)도 참조하십시오. (Bug #15287, Bug #11745440, WL #14722)

  참조: 함께 참조하십시오: Bug #33301931.

## 테스트 스위트 관련 사항

- `--async-client` 옵션과 함께 Valgrind에서 발생하는 `heap-use-after-free` 오류를 줄이기 위해 이제 널 포인터가 검사됩니다. (Bug #33702755)

## XA Transaction 관련 사항

- **Group Replication:** 일부 시나리오에서 Group Replication은 다른 연결에서 준비된 XA 트랜잭션을 커밋할 수 없었기 때문에 문제가 발생했습니다. 이러한 문제를 해결하기 위해 MySQL은 이제 분리된 XA 트랜잭션을 지원합니다. 준비가 완료되면 XA 트랜잭션은 더 이상 현재 세션에 연결되지 않습니다. 이는 [`XA PREPARE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/xa-statements.html)를 실행하는 과정의 일부로 발생합니다. 준비된 XA 트랜잭션은 다른 연결에서 커밋하거나 롤백할 수 있으며, 현재 세션은 준비된 XA 트랜잭션이 완료되기를 기다리지 않고 다른 XA 또는 로컬 트랜잭션을 시작할 수 있습니다.

  이 기능에 대한 지원은 이번 릴리스에서 도입된 [`xa_detach_on_prepare`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_xa_detach_on_prepare) 시스템 변수를 `OFF`로 설정하여 비활성화하고 기존 동작을 복원할 수 있습니다. 기본값은 `ON`이며, 특히 복제 설정에서 권장됩니다.

  분리된 XA 트랜잭션 지원이 활성화된 경우(`xa_detach_on_prepare = ON`) XA 트랜잭션 내에서 임시 테이블을 사용할 수 없다는 점을 알고 있어야 합니다.

  자세한 내용은 [XA Transaction States](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/xa-states.html) 및 [Server Instance Configuration](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/group-replication-requirements.html#group-replication-configuration)을 참조하십시오. (Bug #100163, Bug #31599926, WL #14700)

## X 플러그인 관련 사항

- classic MySQL 프로토콜과 X Protocol의 Unix 소켓 잠금 파일 간 형식 차이로 인해 다른 프로토콜의 파일이 있으면 서버가 시작되지 않을 수 있었습니다. MySQL Database Service 인스턴스처럼 파일을 수동으로 제거할 수 없는 인스턴스를 위해, 이제 프로토콜은 해당 파일에 동일한 형식을 사용합니다. (Bug #31468581)

## 추가되거나 변경된 기능

- **호환되지 않는 변경:** MySQL Server는 이제 개인 키 또는 비밀번호와 같은 민감한 데이터를 포함하는 안전하게 영구 저장된 시스템 변수 값을 저장하고, 해당 값의 조회를 제한하는 기능을 갖습니다. 현재 민감한 것으로 표시된 MySQL Server 시스템 변수는 없지만, 새로운 기능은 향후 민감한 데이터를 포함하는 시스템 변수를 안전하게 영구 저장할 수 있게 합니다. 영구 저장된 시스템 변수 값의 안전한 저장소를 지원하려면, 이 기능을 지원하지 않는 keyring 플러그인이 아니라 keyring 컴포넌트가 MySQL Server 인스턴스에서 활성화되어야 합니다.

  이 변경의 일부로, 이제 컴포넌트 keyring 파일은 MySQL Server 데이터 디렉터리를 초기화하기 전에 로드됩니다. 이는 더 이상 이러한 파일을 MySQL 데이터 디렉터리에 보관할 수 없음을 의미합니다.

  영구 저장된 시스템 변수가 저장되는 운영 체제 파일에서, 민감한 시스템 변수의 이름과 값은 이를 복호화하기 위해 생성된 파일 키와 함께 암호화된 형식으로 저장됩니다. 생성된 파일 키는 다시 keyring에 저장된 마스터 키를 사용하여 암호화됩니다. MySQL 8.0.29로 업그레이드한 후에는 [`SET PERSIST`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/set-variable.html) 또는 `SET PERSIST ONLY` 문이 처음 실행될 때까지 `mysqld-auto.cnf` 옵션 파일의 형식이 동일하게 유지되며, 그 시점에는 관련된 시스템 변수가 민감하지 않더라도 새 형식으로 변경됩니다. 새 형식을 사용하는 옵션 파일은 MySQL Server의 이전 릴리스에서 읽을 수 없습니다.

  새로운 시스템 변수 [`persist_sensitive_variables_in_plaintext`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_persist_sensitive_variables_in_plaintext)는 `SET PERSIST`를 사용하여 값을 설정할 때 keyring 컴포넌트 지원을 사용할 수 없는 경우, 서버가 민감한 시스템 변수의 값을 암호화되지 않은 형식으로 저장하도록 허용되는지 여부를 제어합니다. 기본 설정인 `ON`은 keyring 컴포넌트 지원을 사용할 수 있으면 값을 암호화하고, 사용할 수 없으면 경고와 함께 암호화하지 않은 상태로 영구 저장합니다. 이 설정은 또한 암호화된 시스템 변수 값을 복호화할 수 없는 경우에도 서버가 시작되도록 허용하며, 이 경우 해당 변수의 기본값이 사용됩니다. 가장 안전한 설정인 `OFF`로 `persist_sensitive_variables_in_plaintext`가 설정되면, keyring 컴포넌트 지원을 사용할 수 없는 경우 민감한 시스템 변수 값을 영구 저장할 수 없으며, 암호화된 시스템 변수 값을 복호화할 수 없는 경우 서버가 시작되지 않습니다.

  민감한 시스템 변수의 값은 처리될 때도 보호됩니다. 민감한 시스템 변수에 대해 `SET` 문이 실행되면, 해당 쿼리는 일반 로그와 감사 로그에 기록되기 전에 그 값을 `redacted`로 대체하도록 다시 작성됩니다. 새 권한 [`SENSITIVE_VARIABLES_OBSERVER`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/privileges-provided.html#priv_sensitive-variables-observer)는 보유자가 Performance Schema 테이블 [`global_variables`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/performance-schema-system-variable-tables.html), [`session_variables`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/performance-schema-system-variable-tables.html), [`variables_by_thread`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/performance-schema-system-variable-tables.html), 및 [`persisted_variables`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/performance-schema-persisted-variables-table.html)에서 민감한 시스템 변수의 값을 보고, 해당 값을 반환하는 [`SELECT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/select.html) 문을 실행하며, 연결의 세션 트래커에서 해당 변수에 대한 변경 사항을 추적할 수 있도록 합니다. 이 권한이 없는 사용자는 해당 시스템 변수 값을 볼 수 없습니다. (WL #13469)
- **InnoDB:** 코드 품질을 개선하고 디버깅을 용이하게 하기 위해, `InnoDB` 소스의 `#define` 인스턴스가 `constexpr` 지정자 또는 인라인 함수로 대체되었습니다. (WL #14680)
- **InnoDB:** 이제 `InnoDB`는 `ALGORITHM=INSTANT`를 사용하는 [`ALTER TABLE... DROP COLUMN`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/alter-table.html) 작업을 지원합니다.

  `ALGORITHM=INSTANT`를 지원하는 작업은 데이터 딕셔너리의 메타데이터만 수정합니다. 테이블 데이터는 영향을 받지 않으므로 작업이 즉시 수행됩니다. 명시적으로 지정하지 않으면, 이를 지원하는 DDL 작업에서 기본적으로 `ALGORITHM=INSTANT`가 사용됩니다.

  MySQL 8.0.29 이전에는 즉시 추가된 컬럼을 테이블의 마지막 컬럼으로만 추가할 수 있었습니다. MySQL 8.0.29부터는 즉시 추가된 컬럼을 테이블의 어느 위치에나 추가할 수 있습니다.

  즉시 추가되거나 삭제된 컬럼은 새 로우 버전을 생성합니다. 최대 64개의 로우 버전이 허용됩니다. 로우 버전 수를 추적하기 위해 [`INFORMATION_SCHEMA.INNODB_TABLES`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-innodb-tables-table.html) 테이블에 새 `TOTAL_ROW_VERSIONS` 컬럼이 추가되었습니다.

  `ALGORITHM=INSTANT`를 지원하는 DDL 작업에 대한 자세한 내용은 [Online DDL Operations](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/innodb-online-ddl-operations.html)를 참조하십시오. (WL #13899)
- **Replication:** 이제 서버에 의한 바이너리 로그 파일의 자동 제거는 이 릴리스에서 도입된 [`binlog_expire_logs_auto_purge`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/replication-options-binary-log.html#sysvar_binlog_expire_logs_auto_purge) 시스템 변수로 제어됩니다. 기본적으로 자동 제거는 활성화되어 있으며(`binlog_expire_logs_auto_purge`가 `ON`으로 설정됨), 이를 비활성화하려면 이 변수의 값을 `OFF`로 설정하십시오.

  제거하기 전에 대기할 간격은 [`binlog_expire_logs_seconds`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/replication-options-binary-log.html#sysvar_binlog_expire_logs_seconds) 및 [`expire_logs_days`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/replication-options-binary-log.html#sysvar_expire_logs_days)로 제어됩니다. 이 두 시스템 변수를 모두 0으로 설정하면 `binlog_expire_logs_auto_purge`가 `ON`으로 설정되어 있더라도 자동 제거가 수행되지 않습니다. (WL #14930)
- **Microsoft Windows:** Windows에서 jemalloc 지원을 추가하고, 공식 MySQL 바이너리에 대해 이를 활성화했습니다. 새 `WITH_WIN_JEMALLOC` CMake 옵션은 `mysqld.exe` 및/또는 `mysqld-debug.exe`와 같은 디렉터리로 복사되는 `jemalloc.dll`을 포함하는 디렉터리를 받아들이며, 메모리 관리 작업에 이를 활용합니다. `jemalloc.dll`을 찾을 수 없거나 필요한 함수를 내보내지 않는 경우 표준 메모리 함수가 사용됩니다. INFORMATION 레벨 로그 메시지는 jemalloc이 발견되어 사용되는지 여부를 기록합니다. (WL #14633)

- 새로운 [`clone_delay_after_data_drop`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/clone-plugin-options-variables.html#sysvar_clone_delay_after_data_drop) 변수는 원격 클로닝 작업 시작 시 수신자 MySQL Server 인스턴스에서 기존 데이터를 제거한 직후의 지연 기간을 지정할 수 있게 합니다. 이 지연은 도너 MySQL Server 인스턴스에서 데이터가 클론되기 전에 수신자 호스트의 파일 시스템이 공간을 해제할 수 있는 충분한 시간을 제공하기 위한 것입니다. 특정 파일 시스템은 백그라운드 프로세스에서 공간을 비동기적으로 해제합니다. 이러한 파일 시스템에서는 기존 데이터를 삭제한 후 너무 빨리 데이터를 클론하면 공간 부족으로 인해 클론 작업이 실패할 수 있습니다. 최대 지연 기간은 3600초(1시간)입니다. 기본 설정은 0(지연 없음)입니다. (Bug #32826134, WL #14857)
- `group_replication_set_as_primary` 함수는 지정된 그룹 멤버를 새 프라이머리로 지정하고 선출 프로세스를 재정의합니다. 이전에는 이 함수가 사용된 후 들어오는 트랜잭션을 포함하여 기존 프라이머리의 모든 활성 트랜잭션이 종료될 때까지 기다린 다음, 현재 프라이머리를 읽기 전용으로 만들고 새 프라이머리로 변경했습니다. 대기 시간에는 상한이 없었습니다.

  이제 실행 중인 트랜잭션에 대한 타임아웃을 설정할 수 있도록 선택적 `timeout` 파라미터를 사용할 수 있습니다. 함수를 사용할 때 실행 중인 트랜잭션에 대해 0초(즉시)부터 3600초(60분)까지의 타임아웃을 설정할 수 있습니다. 타임아웃에는 기본 설정이 없으므로, 설정하지 않으면 대기 시간에 상한이 없는 함수의 이전 동작이 계속 적용됩니다. 타임아웃이 만료되면 아직 커밋 단계에 도달하지 않은 모든 트랜잭션에 대해 클라이언트 세션이 연결 해제되어 해당 트랜잭션이 진행되지 않습니다. 커밋 단계에 도달한 트랜잭션은 완료될 수 있습니다. 타임아웃을 설정하면 그 시점부터 프라이머리에서 새 트랜잭션이 시작되는 것도 방지합니다. 명시적으로 정의된 트랜잭션(`START TRANSACTION` 또는 `BEGIN` 문 사용)은 데이터를 수정하지 않더라도 타임아웃, 연결 해제, 들어오는 트랜잭션 차단의 대상이 됩니다. 함수가 동작하는 동안 프라이머리를 검사할 수 있도록, [Permitted Queries Under Consistency Rules](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/group-replication-configuring-consistency-guarantees.html#group-replication-nonblocking)에 나열된 것처럼 데이터를 수정하지 않는 단일 문은 진행할 수 있습니다. (WL #14585)

- Key Management Interoperability Protocol (KMIP)을 사용하여 안전하게 통신하는 `keyring_okv` 키링 플러그인은 MySQL의 keyring 서비스와 함께 사용되어 Oracle Key Vault, Gemalto SafeNet KeySecure Appliance, Townsend Alliance Key Manager, Entrust KeyControl과 같은 KMIP 호환 백엔드 키링 스토리지 제품에 키링 데이터를 저장합니다. 이제 이 플러그인은 기본 서버를 사용할 수 없는 경우 백엔드 키링 스토리지 제품에 대한 백업 연결을 제공하기 위해 둘 이상의 대기 서버를 지정할 수 있도록 합니다. `okvclient.ora` 파일을 편집하여 `STANDBY_SERVER` 변수 값에 서버의 IP 주소와 포트 번호를 쉼표로 구분된 목록으로 지정하면 최대 64개의 대기 서버를 추가할 수 있습니다. 플러그인은 연결을 설정할 수 있을 때까지 대기 서버를 반복하며, 각 연결 시도마다 20초 동안 대기합니다. 따라서 대기 서버 목록을 짧고, 정확하며, 최신 상태로 유지하고, 더 이상 유효하지 않은 서버를 제거해야 합니다. 이러한 서버는 `keyring_okv` 플러그인의 연결 시간과 그에 따른 서버 시작 시간에 상당한 영향을 줄 수 있기 때문입니다. (WL #14363)
- 이러한 변수에 접근하거나 해당 변수를 업데이트하는 SQL 문을 파싱, 해석, 실행하는 서버 코드에서 시스템 변수에 대한 접근 격리가 이제 더 잘 강제됩니다. (WL #14529)
- MySQL Server는 이제 기본적으로 SSL 세션 재사용을 지원하며, 클라이언트가 새 연결에 대해 세션 재사용을 요청할 수 있는 기간을 설정하는 세션 캐시를 서버가 유지하는 시간을 제어하는 타임아웃 설정을 제공합니다. 모든 MySQL 클라이언트 프로그램은 세션 재사용을 지원합니다. 서버 측 및 클라이언트 측 설정 정보는 [SSL 세션 재사용](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/reusing-ssl-sessions.html)을 참조하십시오.

  또한 C 애플리케이션은 이제 C API 기능을 사용하여 암호화된 연결에 대한 세션 재사용을 활성화할 수 있습니다([SSL 세션 재사용](https://docs.oracle.com/cd/E17952_01/c-api-8.0-en/c-api-ssl-session-reuse.html) 참조). (WL #13075)

## 수정된 버그

- **InnoDB:** 즉시 추가된 컬럼이 있는 테이블에 대해 undo 레코드를 purge하려고 시도할 때 실패가 발생했습니다. (Bug #33924532)
- **InnoDB:** 우선순위가 높은 트랜잭션은 인터럽트되었을 때 대기를 중지하거나 잠금을 기다리는 동안 timeout되는 것이 허용되지 않아, 데드락이 해결되지 못했습니다. 블로킹 트랜잭션도 우선순위가 높은 경우, 이제 우선순위가 높은 트랜잭션은 인터럽트되었을 때 대기를 중지하거나 잠금 대기 timeout 기간을 초과할 때 timeout되는 것이 허용됩니다. 블로킹 트랜잭션이 우선순위가 높지 않은 경우, 우선순위가 높은 트랜잭션은 블로킹 트랜잭션이 해당 잠금을 해제할 때까지 기다립니다. (Bug #33856332)
- **InnoDB:** Windows에서 사용되던 AIO 동기화 큐가 제거되었습니다. 동기식 파일 I/O 읽기-쓰기 함수(`SyncFileIO::execute`)는 Linux에서와 같이 일반 I/O와 overlapped I/O 모두에 대해 열린 파일을 처리하도록 수정되었습니다. (Bug #33840645)
- **InnoDB:** 즉시 추가된 컬럼이 있는 테이블의 모든 파티션을 truncate한 후 테이블 버전 메타데이터가 재설정되지 않았습니다. (Bug #33822729)

- **InnoDB:** 세마포어 대기에 대한 경고를 출력하는 `srv_error_monitor_thread()` 함수가 긴 세마포어 대기를 예상대로 처리하지 못했습니다. 이 문제를 해결하기 위해, 블로킹 호출이 더 적절한 위치로 이동되었습니다. 관련 모니터 스레드 코드는 단순화되고 개선되었으며, 여러 서버 스레드에 대해 누락된 종료 신호가 추가되었습니다.

  이제 InnoDB에 의한 표준 모니터의 활성화 및 비활성화는 사용자가 설정할 수 있는 [`innodb_status_output`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/innodb-parameters.html#sysvar_innodb_status_output) 변수와 독립적으로 수행됩니다. 이 변경은 특정 시나리오에서 `InnoDB`에 의해 모니터가 활성화되었지만 이전 값으로 다시 설정되지 않았던 문제를 해결합니다. 기여해 주신 Yuhui Wang에게 감사드립니다. (Bug #33789526, Bug #93878)
- **InnoDB:** Valgrind 테스트에서 InnoDB 소스의 `rec_convert_dtuple_to_rec_old()`에서 off-by-one 오류가 확인되었습니다. (Bug #33784672)
- **InnoDB:** `InnoDB` 소스의 `mem_heap_alloc()` 함수에 대한 `UNIV_DEBUG` 변형은 Valgrind 오류 감지를 개선하도록 수정되었습니다. (Bug #33783709)
- **InnoDB:** 빠른 종료가 모든 파일을 닫기 전에 모든 활성 I/O 작업이 완료될 때까지 기다리지 않았습니다. (Bug #33768584)
- **InnoDB:** Clang 경고에서 잘못 배치된 `@return` 명령이 보고되었습니다. (Bug #33734011)

- **InnoDB:** 파티션 간 전환 시 새 레코드 잠금 배열(`m_prebuilt->new_rec_locks`)의 값이 제대로 동기화되지 않아, 잠금이 예상대로 해제되거나 해제되지 않음으로 인해 assertion failure가 발생했습니다. (Bug #33724166)
- **InnoDB:** 쓰기 요청이 완료될 때 double write buffer를 업데이트하는 함수의 race condition으로 인해 긴 semaphore wait 오류가 발생했습니다. (Bug #33712370)
- **InnoDB:** 한 함수가 인덱싱된 컬럼의 레코드를 변경하면 항상 보조 인덱스에 새 레코드를 생성해야 한다고 잘못 가정하여, 잠금 관련 assertion failure가 발생했습니다. 이 문제와 기타 유사한 사례를 해결하기 위해, 암시적 레코드 잠금을 명시적 레코드 잠금으로 변환하는 `lock_rec_convert_impl_to_expl()` 함수는 이제 암시적 레코드 잠금이 실제로 보유된 경우에만 사용됩니다. (Bug #33657235)
- **InnoDB:** `InnoDB` 소스의 여러 Doxygen 문제가 해결되었습니다. (Bug #33603036)
- **InnoDB:** 인덱스 인스턴스에 대한 null pointer 검사가 누락되어 failure가 발생했습니다. (Bug #33600109)
- **InnoDB:** 증분 백업 후 서버를 시작하면 page tracking을 사용할 수 없음을 나타내는 오류와 함께 실패했습니다. (Bug #33521528)

- **InnoDB:** `InnoDB` 복구 중 assertion failure가 발생했습니다. 이 failure는 free list 및 index list를 재설정할 수 있기 전에 로컬 mini-transaction에서 페이지가 해제된 후 발생한 서버 종료로 인한 것이었습니다. 해제된 페이지에 걸쳐 있던 free list 및 index list가 복구 중 순회되었습니다. (Bug #33454557)
- **InnoDB:** 커서가 페이지 끝에 있을 때 오른쪽 sibling 페이지에 튜플을 삽입하는 `btr_insert_into_right_sibling()` B-tree 함수가 잘못된 잠금 함수 호출로 인해 ACID violation을 일으켰습니다. (Bug #33405696)
- **InnoDB:** `COMPACT` 또는 `REDUNDANT` 로우 형식을 사용할 때 최대 로우 크기를 초과하는 테이블을 생성할 수 있었으며, 이로 인해 나중에 데이터를 삽입할 때 'Row size too large' 오류가 발생할 수 있었습니다. BLOB prefix가 [`CREATE TABLE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/create-table.html) 작업 중 수행되는 레코드 크기 검사에 포함되지 않았습니다. (Bug #33399379)
- **InnoDB:** 마스터 암호화 키(`get_master_key()`)를 가져오는 함수가 아직 초기화되지 않은 마스터 키 ID mutex(`master_key_id_mutex`)를 획득하려고 했습니다. (Bug #33067891)
- **InnoDB:** 보조 인덱스 레코드에 잠금을 설정하는 데 사용되는 `lock_sec_rec_read_check_and_lock` 잠금 시스템 함수에서 중복되고 비용이 큰 검사가 제거되었습니다. (Bug #33059387)

- **InnoDB:** `TempTable` 스토리지 엔진이 파일 가득 참 오류를 올바르게 처리하지 않았습니다. (Bug #32929392)
- **InnoDB:** [`ALTER TABLE... ALGORITHM=COPY`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/alter-table.html) 작업 중 발생한 DDL 로그 오류가 처리되지 않아, 이후 `ALTER TABLE... ALGORITHM=INPLACE` 작업 중 실패가 발생했습니다. (Bug #32716838)
- **InnoDB:** purge 스레드가 테이블스페이스가 로드되지 않은 암호화된 테이블의 undo 레코드를 처리하여 실패가 발생했습니다. (Bug #32586721)
- **InnoDB:** 한 스레드가 비동기 I/O 작업을 게시한 뒤 자신을 닫아 운영 체제 파일 작업 오류가 발생했습니다. (Bug #30567295)
- **InnoDB:** 최대 정수 컬럼 값을 초과했을 때 잘못된 `AUTO_INCREMENT` 값이 생성되었습니다. 이 오류는 최대 컬럼 값이 고려되지 않아 발생했습니다. 이 경우 이전의 유효한 `AUTO_INCREMENT` 값이 반환되어 중복 키 오류가 발생했어야 합니다. (Bug #87926, Bug #26906787)

- **InnoDB:** 트랜잭션 잠금 우선순위가 수정되어, 공유 잠금을 보유하고 있으며 배타 잠금으로 업그레이드되기를 기다리는 트랜잭션이 동일한 로우에 대한 배타 잠금을 기다리는 다른 트랜잭션보다 우선순위를 갖습니다. 즉, 이미 공유 잠금을 보유한 트랜잭션에 배타 잠금이 먼저 부여됩니다. 동일한 로우에 공유 잠금을 보유한 다른 일부 트랜잭션은 이 시나리오에서도 배타 잠금이 부여되는 것을 막을 수 있습니다.

  트랜잭션 잠금 시스템 소스의 `lock_rec_find_set_bit` 및 `lock_rec_has_expl` 함수가 최적화되었습니다. (Bug #21356, Bug #11745929)
- **Partitioning:** 일부 경우에 파티션의 `.ibd` 파일이 누락된 경우 MySQL 서버에 대한 연결 설정이 실패할 수 있었습니다. (Bug #33459653)
- **Partitioning:** MySQL 8.0.17에서 모든 `NOT IN` 및 `NOT EXISTS` 서브쿼리가 antijoin으로 변환되도록 수행된 작업 이후, 이 변환으로 생성된 중첩 outer join의 내부 부분이 테이블 파티션을 pruning하는 동안 고려되지 않았습니다. (Bug #33060953)
- **Replication:** `group_replication_consistency=AFTER`가 설정된 복제 그룹에서 새 primary가 선출된 다음 이전 primary가 재시작되면, 새 primary가 오류 메시지와 함께 그룹을 떠났습니다. 이 상황을 방지하기 위해 지연된 뷰 변경 및 트랜잭션 prepare 처리가 조정되었습니다. (Bug #33755920)

- **Replication:** 네트워크 프로바이더가 중지되는 동안 발생한 데드락으로 인해 일부 그룹 멤버에서 [`STOP GROUP_REPLICATION`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/stop-group-replication.html)이 무기한 대기할 수 있었습니다. (Bug #33044886)
- **Group Replication:** Group Replication은 auto-rejoin 프로세스에서 재참여 멤버가 오류 상태에 있는 동안 그룹에 들어갈 수 있는 유일한 유형의 인스턴스인지 너무 늦게 확인했습니다. 이 문제는 이제 수정되었습니다. (Bug #33615493)
- **Group Replication:** Group Replication은 참여 중인 멤버가 없고 단지 뷰 변경만 있는 상황에서도, 그룹 설정 작업이 실행되는 동안 멤버가 참여한다는 경고 메시지를 기록할 수 있었습니다. 이제 이 메시지는 적절한 경우에만 기록됩니다. (Bug #33378364)
- **Group Replication:** Group Replication은 이제 로컬 XCom 인스턴스에 연결하는 데 문제가 있을 때 반환되는 운영 체제 오류를 기록하므로, 방화벽이 연결을 차단하는 경우와 같은 문제를 더 쉽게 해결할 수 있습니다. (Bug #33189767, Bug #104523)

- **Group Replication:** 기본 선출이 중단되는 것을 방지하기 위해, Group Replication은 선출 중 그룹을 떠난 멤버의 확인을 더 이상 기다리지 않습니다. 확인이 보류 중이던 모든 멤버가 떠나면, Group Replication은 기본 선출이 성공적으로 완료되었다고 선언합니다. 이전에는 기본 멤버가 떠난 멤버 중 하나인 경우, 실제로는 기본 변경이 발생할 수 없었는데도 기본 변경이 발생한 것으로 잘못 명시되었습니다. 이제 기본 멤버가 선출 중 떠나면, Group Replication은 기본 변경이 없는 실패한 선출로 기본 선출을 선언합니다. (Bug #33059773)
- **Microsoft Windows:** Windows에서 WinFlexBison 지원이 추가되었습니다. (Bug #33788290)
- EL6/EL7에서 mysql-community-server-debug 설치는 상용 패키지를 설치해도 obsolete 처리되지 않았습니다. (Bug #33956760)
- MySQL Server는 비시스템 OpenSSL과 같이 cmake 빌드 시스템이 복사하는 공유 라이브러리를 대상으로 빌드할 때 ARM에서 EL7을 빌드하지 못했습니다. 이제 *--page-size*는 getconf가 보고한 값으로 설정됩니다. (Bug #33904267)
- `PROCESS` 권한이 있는 익명 사용자가 [`processlist`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/performance-schema-processlist-table.html) 테이블에서 로우를 선택할 수 없었습니다. (Bug #33869388)
- 범위 optimizer가 세션 메모리 제한을 고려하지 않았습니다. (Bug #33869004)

- 서브쿼리를 정렬할 때 동일한 filesort 작업이 서로 다른 입력으로 여러 번 실행될 수 있으며, 따라서 가장 긴 add-on 컬럼이 실행 사이에 변경될 수 있지만, 이 컬럼에 대한 버퍼는 필요할 때 다시 할당되지 않았습니다. 이제 이전에 할당된 버퍼가 충분히 크면 이를 재사용하고, 그렇지 않으면 새 버퍼를 할당합니다. (Bug #33865094)
- 구체화되어 여러 쿼리 블록에서 사용된 common table expression에서 잘못된 결과가 얻어졌습니다. 여기서 CTE를 사용한 첫 번째 쿼리 블록에는 가능한 키 정의가 여러 개 있었고, 이로 인해 내부 함수 `JOIN::finalize_derived_keys()`가 사용된 키의 정의를 위치 0으로 이동했으며, CTE를 사용하는 두 번째 쿼리 블록은 첫 번째 쿼리 블록에 대해 선택된 키의 원래 위치와 같은 위치를 차지한 인덱스를 조작했습니다. 이는 DML 문을 한 번만 준비하도록 MySQL 8.0.22에서 수행된 작업의 의도하지 않은 부작용으로 발생했습니다.

  자세한 내용은 [WITH (Common Table Expressions)](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/with.html)를 참조하십시오. (Bug #33856374)
- 저장 프로시저 및 저장 함수 실행 시 오류 처리가 개선되었습니다. (Bug #33851256)
- 뷰에서 선택하는 트리거가 항상 예상된 결과를 산출하지는 않았습니다. (Bug #33847722)

- 시간대 정보를 로드하는 동안 수행되는 계산에는 `my_time_t`의 음수 값이 필요합니다. 일반적으로 이 타입의 최솟값은 0이며, 시간대 오프셋이 없는 UNIX Epoch의 시작(`1970-01-01 00:00:00`)에 해당하고, 이는 상수 `MYTIME_MIN_VALUE`에 반영되어 있습니다. 일부 시간대 오프셋은 음수이므로, 이 최솟값은 모든 경우에 `TIME_ZONE_INFO` 데이터 구조를 설정하는 데 올바르게 동작하지 않았습니다. 이 수정으로 시간대 정보 데이터베이스 캐시를 채우는 동안 `my_time_t`에 음수 값을 사용할 수 있습니다. (Bug #33837691)
- MySQL 인스턴스가 예기치 않게 중지되었거나 `SET PERSIST` 문을 사용하여 시스템 변수 설정을 기록한 직후 재시작된 경우, 설정 파일 `mysqld-auto.cnf`가 비어 있는 상태로 남을 수 있었으며, 이 경우 서버 재시작을 진행할 수 없었습니다. 이제 영속화된 시스템 변수는 백업 파일에 기록되며, 쓰기가 성공했음이 확인된 후에만 이 파일의 이름이 `mysqld-auto.cnf`로 변경되어 원래 `mysqld-auto.cnf` 파일은 계속 사용 가능한 상태로 남아 있습니다. 재시작 시 유효한 내용이 있는 백업 파일이 발견되면 서버는 해당 파일에서 읽습니다. 그렇지 않으면 `mysqld-auto.cnf` 파일이 사용되고 백업 파일은 삭제됩니다. (Bug #33830493)
- `filesort`는 정렬 키를 계산할 때 문자열 값의 길이를 항상 올바르게 확인하지 않았습니다. (Bug #33830073)

  참조: 이 문제는 다음 버그의 회귀입니다: Bug #29739778.

- `GROUP_ID` 및 `MEMBER_ID` 컬럼으로 구성된 기본 키가 `mysql.firewall_membership` 테이블에 추가되었습니다. (Bug #33824544)
- MySQL 8.0.20에서 `WITH CHECK OPTION`이 있는 업데이트 가능한 뷰를 업데이트할 때 `rows matched` 값의 불일치에 대해 이루어진 수정은 단일 테이블의 업데이트에 대해서만 이 문제를 처리했습니다. 이번 릴리스에서는 다중 테이블 [`UPDATE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/update.html) 문에 대해서도 이 문제를 수정합니다. (Bug #33815426)

  참조: 함께 참조하십시오: Bug #30158954.
- MySQL Server에 링크된 ProtoBuf 라이브러리가 버전 3.19.4로 업데이트되었습니다. 새 Protobuf 버전에서 수정된 문제는 [https://github.com/protocolbuffers/protobuf/releases](https://github.com/protocolbuffers/protobuf/releases)에 설명되어 있습니다. (Bug #33813846)
- `utf32` 컬럼에 유효하지 않은 문자를 삽입할 수 있었습니다. (Bug #33810558)
- MySQL Enterprise Firewall 플러그인을 다시 설치하면 실패가 발생했습니다. 이 실패는 플러그인이 완전히 초기화되기 전에 이전에 지속된 firewall 시스템 변수를 업데이트하는 호출로 인해 발생했습니다. (Bug #33809478)
- [`VARCHAR`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/char.html) 또는 [`DECIMAL`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/fixed-point-types.html) 조인 컬럼을 사용하는 해시 조인이 과도한 수의 로우를 반환했습니다. `VARCHAR`를 사용하는 예는 다음과 같습니다:

  ```
  # Create and populate table
  CREATE TABLE t(a VARCHAR(10), b VARCHAR(10));
  INSERT INTO t VALUES ('x', 'xx'), ('xx', 'x');

  # 인덱스가 없으므로 해시 조인을 사용합니다
  SELECT * FROM t AS t1, t AS t2 WHERE t1.a = t2.a AND t1.b = t2.b;
  ```

  수정 전에는 방금 표시한 쿼리가 네 개의 로우를 반환했으며, 이제는 예상대로 두 개의 로우를 반환합니다. (Bug #33794977)
- [`INFORMATION_SCHEMA.KEY_COLUMN_USAGE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-key-column-usage-table.html) 테이블이 보이지 않는 키 컬럼을 나열하지 않았습니다. (Bug #33781534)
- 서버가 뷰에서 생성된 뷰에 접근한 후 적절한 정리를 수행하지 않았습니다. (Bug #33777821)
- `WITH ROLLUP`과 윈도우 함수를 사용하는 그룹화된 쿼리에서, 해당 윈도우 함수가 이미 `SELECT` 목록에 있는 집계에 대해 정렬하는 경우, 윈도우의 정렬 절을 해석할 때 추가적인(그리고 불필요한) 집계가 숨겨진 컬럼으로 추가되었습니다. (Bug #33769911)
- 데이터 마스킹 [`mask_ssn()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/data-masking-component-functions.html#function_mask-ssn) 함수가 유효한 비상수 값(하드 코딩된 값과 달리 데이터베이스 로우에서 읽은 데이터)에 대해 'String argument width too large' 오류를 반환했습니다. 또한 길이가 0인 상수 및 비상수 값(빈 문자열)이나 너무 작은 상수 값에 대해 검증이 수행되지 않았습니다. 이러한 문제는 길이 경계가 있는 문자열 입력을 사용하는 모든 데이터 마스킹 함수에 대해 해결되었습니다. (Bug #33759276)

- `ROLLUP`은 `ORDER BY` 및 윈도우 함수와 함께 사용되는 일부 경우에 올바르게 처리되지 않았습니다. (Bug #33753245)
- Doxygen 주석의 여러 문제를 수정했습니다. (Bug #33734001, Bug #33734035, Bug #33734062, Bug #33734075, Bug #33734104, Bug #33734117, Bug #33734129, Bug #33734143, Bug #33734155, Bug #33734181, Bug #33734188, Bug #33734206)
- 예를 들어 문법 오류로 인해 구문 분석할 수 없는 문은 더 이상 슬로우 쿼리 로그에 기록되지 않습니다. (Bug #33732907)
- MySQL Enterprise Thread Pool의 초기 설정을 설명하는 메시지는 이제 정보성 메시지가 아니라 SYSTEM 메시지로 발행되므로, 기본 로깅 레벨에서 표시됩니다. (Bug #33729821)
- 세션 추적과 관련된 사전 잠금 최적화가 일부 시나리오에서 재귀적 잠금을 발생시켰습니다. (Bug #33728209)
- `IN` 서브쿼리를 포함하는 union이 `ORDER BY` 절도 함께 사용할 때 항상 올바르게 처리되지는 않았습니다. (Bug #33725507)
- **mysqlpump** 클라이언트 유틸리티는 명령줄 옵션을 사용하여 비밀번호 프롬프트가 요청될 때 예기치 않게 중지될 수 있었습니다. 이 과정에서 오류가 발생하면 이제 클라이언트가 종료되기 전에 적절한 오류 메시지가 반환됩니다. (Bug #33688141)

- 다음 플랫폼에 대해 별도의 debuginfo RPM을 제공하는 표준 패키지 정책을 구현했습니다: SLES/openSUSE, 그리고 커뮤니티 EL6 및 EL7. 이제 EL6 및 EL7의 상용 버전은 Debug 대신 RelWithDebInfo 빌드 타입으로 빌드되며, 이로 인해 크기가 크게 줄어듭니다. (Bug #33663811, Bug #33684418, Bug #33664929)
- trace log를 활성화한 상태로 `mysqld`를 실행할 수 없었습니다. (Bug #33653824)
- FIDO 디바이스 등록을 위해 시작 시 `--fido-register-factor` 옵션을 사용한 경우, **mysql** 클라이언트가 [`ALTER USER`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/alter-user.html) 문에서 잘못된 문법을 사용할 수 있었으며, 그 결과 실패가 발생했습니다. 이제 이 문제가 수정되었습니다. (Bug #33650498)
- [`SET`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/set.html) 컬럼 값을 검색할 때, [`FIND_IN_SET()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/string-functions.html#function_find-in-set)의 첫 번째 인수로 전달된 사용자 변수는 같은 방식으로 사용된 상수 값과 동일한 결과를 생성하지 않았습니다.

  *예*: 여기에 표시된 것처럼 생성되고 채워진 테이블 `t1`을 고려하십시오:

  ```
  CREATE TABLE t1 (c1 SET('a', 'b', 'c', 'd'));

  INSERT INTO t1 (c1) VALUES ('a, c, d'), ('c');
  ```

  다음 쿼리의 출력에서 `var` 및 `str`에 표시된 값은 두 로우 모두에서 동일해야 하지만 그렇지 않았습니다:

  ```
  SET @a = 'c';

  SELECT FIND_IN_SET(@a, c1) AS var, FIND_IN_SET('c', c1) AS str FROM t1;
  ```

  이제 이러한 경우에는 찾는 값이 상수인지 컬럼 값인지와 관계없이 컬럼 정의에 사용된 세트 내 일치 위치를 반환하도록 합니다. (Bug #33635637)
- 이를 지원하는 인증 방법을 사용한 `SET PASSWORD` 작업이 예상된 오류 대신 경고를 생성했습니다. (Bug #33635445)
- MySQL 서버 시작 시 플러그인 디렉터리가 지정되지 않았고 사용자가 FIDO 디바이스 등록을 시도하면 **mysql** 클라이언트가 예기치 않게 중지되었습니다. 이제 이 상황이 처리되며 적절한 오류가 보고됩니다. (Bug #33631144)
- MySQL 8.0.27에서 이루어진 변경으로 필터 및 정렬을 포함하는 복합 액세스 경로에 대한 [`EXPLAIN`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/explain.html) 출력이 테이블 경로 내부에서 `MATERIALIZE` 액세스 경로로 이동되었지만, 복합 액세스 경로에 `INDEX_RANGE_SCAN`은 포함되지 않았습니다. 이로 인해 일부 경우 정의되지 않은 동작이 발생할 수 있었습니다. (Bug #33611545)

  참조: 이 문제는 다음의 회귀입니다: Bug #32788576.
- Performance Schema에 대한 [`DROP`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/privileges-provided.html#priv_drop) 권한을 취소할 수 없었습니다. (Bug #33578113)

- 내부 `CreateIteratorFromAccessPath()` 함수는 더 이상 재귀를 사용하지 않도록 다시 작성되었습니다. 이는 쿼리를 실행할 때 스택 사용량을 크게 줄일 것으로 예상됩니다. (Bug #33569770)
- **mysql** 클라이언트가 challenge-response 오류와 함께 FIDO 디바이스 등록을 시도할 때 예기치 않게 중지될 수 있었습니다. 이 문제는 이제 수정되었습니다. (Bug #33568944)
- prepared statement 또는 저장 함수로 실행된 [`INFORMATION_SCHEMA.FILES`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-files-table.html) 또는 [`INFORMATION_SCHEMA.TABLES`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-tables-table.html) 쿼리가 오래된 데이터를 반환했습니다. 데이터가 변경된 후에도 캐시된 데이터가 보고되었습니다. (Bug #33538106, Bug #105450)
- 쿼리가 다음 조건을 모두 충족할 때 잘못된 결과를 반환했습니다:

  - 결과 집합에 비결정적 요소가 있는 컬럼이 포함되었습니다.
  - 해당 컬럼이 테이블을 참조하지 않았습니다.
  - 암시적 그룹화가 있었습니다.
  - 쿼리 계획이 임시 테이블에서 집계를 사용했습니다. 이 임시 테이블은 비어 있었습니다.

  컬럼 `c1`이 있는 빈 테이블 `t`가 주어졌을 때, `INSERT INTO t SELECT MAX(t.c1), RAND(0) AS x FROM t` 문은 이러한 쿼리의 예를 제공합니다. 동일한 테이블에 삽입함으로써 쿼리 계획이 임시 테이블에서 집계하도록 보장합니다. 임시 테이블에는 `c1`에 대한 컬럼이 있으며, (단일) 결과 로우는 임시 테이블의 첫 번째 로우에서 `c1`을 선택합니다. 임시 테이블이 비어 있으면 첫 번째 로우가 없었고 `c1`은 0이 되었습니다. 이로 인해 예를 들어 `(NULL, 0.155)`가 아니라 `(NULL, 0)`이 `t`에 삽입되었습니다.

    임시 테이블에 이러한 컬럼을 저장하지 않음으로써 이 문제를 수정했습니다. (Bug #33535379)

  참조: 함께 참조하십시오: Bug #32384355.
- MySQL 8.0.27의 비밀번호 처리 변경 이후, **mysql** 클라이언트가 **Ctrl + C**로 중단되면 중단을 처리하기 위해 사용자의 비밀번호를 요구하는 비밀번호 프롬프트가 표시될 수 있었습니다. 이제 비밀번호는 프롬프트에 대한 응답으로 제공될 때(시작 시 명령줄에서 제공될 때뿐 아니라) 기록되므로, 중단을 위해 설정되는 새 연결에서 자동으로 사용될 수 있습니다. (Bug #33514253)
- 내부 `keyread` 플래그는 전체 로우가 아니라 인덱스 항목만 읽는 것을 나타냅니다. 초기화 중에 인덱스 병합 스캔에 대해 이 플래그가 설정되면, 이후 인덱스 병합 스캔의 일부로 선택된 개별 범위 스캔을 초기화할 때 이 플래그가 재설정되어 인덱스 항목 대신 로우를 읽는 것으로 표시되었습니다. 인덱스 항목을 읽는 동안 선택된 인덱스를 커버링 인덱스로 설정함으로써 이 문제를 수정했습니다. (Bug #33499071)

- page-compressed 테이블을 복제할 때 donor 호스트의 압축된 데이터 크기가 recipient 호스트의 사용 가능한 디스크 공간과 동일한 경우 데이터 복사가 중단되었습니다. recipient 호스트에 펀칭된 홀은 페이지 크기보다 작았으며, 이로 인해 디스크 단편화가 발생하여 복제된 데이터에 사용할 수 있는 공간의 양이 제한되었습니다. recipient 호스트에서 page-compressed 테이블을 처리하는 프로세스가 단편화를 줄이고 데이터 복사 속도를 개선하도록 수정되었습니다.

  플러시 속도를 개선하기 위해 clone 플러그인은 이제 홀 펀칭을 지원하는 파일 시스템에서 page-compressed 테이블을 플러시할 때 `fsync` 플러시 방식을 사용합니다. (Bug #33482747)
- 뷰를 생성할 때 서브쿼리가 상수로 간주되는 경우 resolution 중에 평가될 수 있었습니다. (Bug #33438883)
- 일반적으로 [`EXPLAIN FORMAT=TREE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/explain.html#explain-analyze) 출력에서는 로우 수를 정수로만 작성합니다. 결과가 0인 경우 이것이 0.49인지 0.00001인지 판별하기 어려웠으므로, 이러한 경우 하나의 선행 숫자를 얻을 수 있도록 충분한 정밀도를 추가합니다. (Bug #33426283)
- 일부 경우 [`VALUES`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/values.html)가 명시된 대로 동작하지 않았습니다. (Bug #33414289)

- 디버그 빌드에서 `MYSQL_TYPE_DOUBLE` 타입의 사용자 변수의 특정 조합이 [`CAST()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/cast-functions.html#function_cast) 또는 [`CONVERT()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/cast-functions.html#function_convert) 컨텍스트에서 사용될 때 assert에 도달했습니다. (Bug #33406728)
- 여러 동등 조건을 설정할 때, Optimizer가 필요하지 않은 경우에도 외부 참조를 추가했습니다. (Bug #33394701)
- MySQL 빌드에 지원되는 Boost 라이브러리의 최소 버전이 이제 1.77.0으로 상향되었습니다. (Bug #33353637)

  참조: 함께 참조하십시오: Bug #33052171.
- `Security_context` 클래스에서 중복된 `init` 및 `checkout_access_maps` 함수 코드가 제거되었습니다. (Bug #33339129, Bug #104915)
- sys 스키마 뷰 [`schema_unused_indexes`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/sys-schema-unused-indexes.html)가 올바르게 업데이트되지 않았습니다.

  [`schema_unused_indexes`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/sys-schema-unused-indexes.html)는 [`table_io_waits_summary_by_index_usage`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/performance-schema-table-wait-summary-tables.html#performance-schema-table-io-waits-summary-by-index-usage-table)에서 사용되지 않은 인덱스 정보를 검색하며, 테이블에 존재하지 않는 로우를 쿼리하는 데 해당 인덱스가 사용된 경우 데이터를 반환하지 않았습니다.

  이 릴리스부터는 로우를 찾을 수 없더라도 [`schema_unused_indexes`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/sys-schema-unused-indexes.html)가 업데이트됩니다. (Bug #33302400)

- 공통 테이블 표현식을 사용하는 일부 쿼리가 [`EXPLAIN`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/explain.html)에 의해 올바르게 처리되지 않았습니다. (Bug #33300271)
- 서버가 특정 복잡한 쿼리에 대해 인덱스 통계를 올바르게 가져오지 않았습니다. (Bug #33270516)
- 특정 상황에서 `TRUNCATE TABLE performance_schema.status_by_thread;`를 실행할 때 race condition이 발생할 수 있었습니다.

  이 수정에 기여해 주신 Facebook에 감사드립니다. (Bug #33165726)
- page cleaner 스레드가 큰 테이블에서 full-text 인덱스 생성 작업이 보유한 인덱스 페이지의 exclusive lock을 기다리다가 시간이 초과되었습니다. (Bug #33101844)
- `InnoDB` 테이블의 경우 보조 인덱스는 테이블의 프라이머리 키를 포함하도록 확장됩니다. 즉, 프라이머리 키의 일부인 모든 컬럼은 모든 보조 인덱스의 일부로 표시됩니다. 이에 대한 예외는 보조 인덱스가 unique로 정의된 경우이며, 서버는 프라이머리 키 확장을 사용하지 않습니다. 이로 인해 dynamic range scan을 위한 read set을 설정하는 동안 문제가 발생할 수 있었습니다. unique 보조 인덱스의 경우 모든 프라이머리 키 부분이 read set에 포함되도록 하여 이 문제를 수정했습니다. (Bug #33101025)

  참조: 이 문제는 다음의 회귀입니다: Bug #30417361.

- 존재하지 않는 테이블을 참조하는 기존 외래 키 제약 조건으로 인해 해당 테이블이 생성되거나 이름이 변경된 후 연결 오류가 발생할 수 있었습니다. (Bug #33054071)
- [`INSERT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/insert-on-duplicate.html) 문 실행 중 비어 있는 `VALUES`에 대한 값 목록을 생성하는 동안 숨겨진 요소가 추가되었고, 이후 debug 빌드에서 assertion이 발생했습니다. 이 문제를 해결하기 위해 이제 `VALUES` 목록이 생성될 때 숨겨진 요소를 건너뜁니다.

  자세한 내용은 [INSERT... ON DUPLICATE KEY UPDATE Statement](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/insert-on-duplicate.html)를 참조하십시오. (Bug #32774799)
- `ORDER BY`에서 표현식의 일부였던 [`SELECT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/select.html) 목록 항목에 대한 별칭이 독립 실행형 별칭과 동일한 방식으로 해석되지 않아, `ORDER BY alias`는 올바르게 해석되었지만 `ORDER BY function(alias)`는 그렇지 않았습니다. (Bug #32695670)

- 비어 있거나 존재하지 않는 keyring 소스([`keyring_file_data`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/keyring-system-variables.html#sysvar_keyring_file_data)로 지정됨)에서 수행한 오프라인 keyring 마이그레이션이 경고 없이 성공적으로 완료된 것처럼 보였습니다. 이제 keyring 마이그레이션 프로세스는 키를 가져올 때 오류를 확인합니다. 지정된 keyring 소스에서 키를 찾을 수 없는 경우, keyring에 키가 없음을 나타내는 경고 메시지가 오류 로그에 기록됩니다. (Bug #32327411)
- 항상 true인 조건을 제거할 때, 뷰를 참조하는 서브쿼리 자체가 쿼리의 다른 위치에서 참조되고 있었음에도 해당 서브쿼리가 제거되었습니다. (Bug #31946448)

  참조: 함께 참조하십시오: Bug #31216115.
- 파생 테이블을 포함하는 multiple-table [`UPDATE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/update.html) 문과 함께 사용된 경우, [`EXPLAIN`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/explain.html) 문으로 인해 서버가 종료될 수 있었습니다. (Bug #31884434)
- `--order-by-primary` 옵션과 함께 두 개 이상의 테이블에 **mysqldump**를 사용한 경우 메모리 누수가 발생했습니다. 이제 각 테이블의 로우를 정렬하기 위해 할당된 메모리는 한 번만 해제되는 것이 아니라 모든 테이블 처리 후 해제됩니다. (Bug #30042589, Bug #96178)
- **mysqld_safe** 로그 메시지의 텍스트 오류가 수정되었습니다. 기여해 주신 China Mobile의 Bin Wang에게 감사드립니다. (Bug #106590, Bug #33903639)

- 동등한 쿼리가 실행 경로가 약간 달랐기 때문에 서로 다른 결과를 반환할 수 있었습니다. 예를 들어, `Item::val_int_from_string()`과 `Item_string::val_int()`는 문자열에서 정수로의 변환에 동일한 알고리즘을 사용해야 합니다. (Bug #106517, Bug #33881339)
- 사용 중단된 `PermissionsStartOnly` systemd 옵션을 처리하도록 CMake 규칙을 업데이트했습니다. 대체 실행 파일 접두사는 systemd 231(2016년 7월)에 추가되었고, PermissionsStartOnly는 systemd 240(2018년 12월)에서 사용 중단되었습니다. 이제 사용 가능한 경우 선호되는 실행 파일 접두사가 사용됩니다. (Bug #106468, Bug #33862323)
- MySQL 8.0.22에서 구체화된 파생 테이블에 대한 조건 푸시다운을 구현하기 위해 수행된 작업 이후, 집계 함수를 포함하는 암시적으로 그룹화된 쿼리가 일부 경우에 `NULL` 대신 빈 집합을 반환했습니다. (Bug #106414, Bug #33838439)

- 바인딩된 인수로 [`DATE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/datetime.html), [`TIME`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/time.html), [`DATETIME`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/datetime.html) 또는 [`TIMESTAMP`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/datetime.html)를 사용하는 `'SELECT ?'`와 같이 준비되고 실행된 쿼리가 잘못된 컬럼 타입을 반환할 수 있었습니다. 이 문제는 각 동적 매개변수에 해당 리터럴 값을 제공하도록 이러한 쿼리를 다시 준비하던 이전 로직을 복원하여 수정되었습니다. (Bug #106352, Bug #33813951)

  참조: 이 문제는 다음의 회귀입니다: Bug #32915973.
- null-safe 비교([`≪=>`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/comparison-operators.html#operator_equal-to))가 트리거의 [`TIMESTAMP`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/datetime.html) 컬럼에 대해 올바르게 평가되지 않았습니다. (Bug #106286, Bug #33790919)

  참조: 이 문제는 다음의 회귀입니다: Bug #32942327.
- [`DECIMAL`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/fixed-point-types.html) 값을 hash join 버퍼에 쓸 때, 값이 먼저 정규화되었습니다. 이 정규화는 일부 경우 의도치 않게 값을 변경할 수 있었으며, 이로 인해 값이 잘못된 해시 버킷에 들어가고 조인에서 잘못된 결과가 반환되었습니다.

  문제는 정규화가 일부 값이 최하위 자릿수 일부를 잃게 하는 방식으로 선행 0을 제거했다는 점이었습니다. 원하는 정밀도를 계산하고 원래 값을 변경하는 대신 계산된 값을 전달하여 이를 수정했습니다. (Bug #106272, Bug #33787914)

- `DATETIME` 컬럼 `a`, `b`, `c`가 있고, 컬럼 `a`와 `c`가 `NOT NULL`로 생성된 상태에서, `c NOT`[`BETWEEN`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/comparison-operators.html#operator_between)`NULL AND`[`COALESCE(a, b)`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/comparison-operators.html#function_coalesce) 형식의 `WHERE` 조건을 가진 쿼리가 올바른 결과를 반환하지 않았습니다. 추가 조사 결과, 이러한 경우 `BETWEEN`의 두 번째 또는 세 번째 인수가 `NULL`이면 비교 결과가 반전되어, `FALSE`에 대해 `NULL`로 평가되고 `NULL`에 대해 `FALSE`로 평가되는 것으로 나타났습니다. (Bug #106267, Bug #33788832)
- `0`(`FALSE`)과 `NULL` 사이의 NULL 안전 비교가 `TRUE`를 반환할 수 있었습니다. 이 타입의 객체를 평가하는 구현은 결코 `NULL` 결과를 낼 수 없고 항상 `FALSE`를 반환해야 하는데도 그러했습니다. (Bug #105773, Bug #33630225)
- `QUICK_RANGE` 생성자가 `QUICK_RANGE` 객체 자체를 할당하는 데 사용한 것과 동일한 메모리 루트가 아니라, 키를 할당하는 데 메인 스레드 메모리 루트를 사용했습니다. 이로 인해 쿼리 계획에 대한 범위 검사를 사용하는 여러 쿼리를 실행할 때 예상보다 높은 메모리 사용량이 발생했습니다. (Bug #105331, Bug #33516707)

  참조: 함께 참조하십시오: Bug #28805105, Bug #28857990.

- [`TempTable`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/internal-temporary-tables.html) 스토리지 엔진이 사용된 경우([`internal_tmp_mem_storage_engine`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_internal_tmp_mem_storage_engine)`= TempTable`), 빈 문자열과 단일 공백 문자로 구성된 문자열이 컬럼에 포함되어 있을 때 [`VARCHAR`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/char.html) 컬럼에 대한 [`SELECT DISTINCT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/select.html)가 2개의 고유 값을 반환했습니다. 이 동작은 `PAD SPACE`가 있는 `utf8_bin` 콜레이션을 사용할 때 올바르지 않았으며, 고유 값을 선택할 때 후행 공백은 무시되어야 했습니다.

  `TempTable` 스토리지 엔진을 사용하여 생성된 임시 테이블의 경우, 두 문자열은 서로 다른 값으로 해시되었습니다. 이는 `TempTable` 해싱 함수가 항상 길이가 0인 데이터를 `0`으로 해시했기 때문입니다. (방금 설명한 경우에서 빈 문자열은 `0`으로 해시된 반면, 다른 문자열의 공백 문자는 0이 아닌 해시 값을 생성하는 데 사용되었습니다.)

  이제 `TempTable` 스토리지 엔진의 해싱 함수에서 길이가 0인 데이터에 대한 모든 특별 처리를 제거하여 이 문제가 수정되었습니다.

  기여해 주신 Brian Yue에게 감사드립니다. (Bug #105316, Bug #33506241)

- 다중 값 인덱스를 사용한 [`SELECT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/select.html) [`COUNT(*)`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/aggregate-functions.html#function_count)가 잘못된 로우 수를 보고했습니다. (Bug #104898, Bug #33334928)
- 테스트 프로그램 `main.ssl-big`가 Too many connections로 실패했습니다.

  기여해 주신 Facebook에 감사드립니다. (Bug #104377, Bug #33139204, Bug #33165693)
- MySQL이 지원하는 두 가지 타입의 히스토그램인 singleton 및 equi-height는 이전에 각각 버킷 컬렉션을 맵과 셋에 저장했습니다. 이번 릴리스에서는 두 히스토그램 타입이 이제 대신 동적 배열에 버킷을 저장하도록 변경되며, 이는 버킷에 대해 바이너리 검색을 수행할 때 간접 참조가 줄어들기 때문에 공간 오버헤드를 줄이고 선택도 추정 속도를 높입니다.

  두 타입의 히스토그램은 모두 버킷을 정렬된 순서로 삽입하여 구성되고, 버킷은 정렬된 순서로 JSON에 직렬화되므로, 동적 배열로 전환하는 데 추가 작업은 필요하지 않습니다. (Bug #104109, Bug #33045204)
- signed 변수와 unsigned 변수 사이의 잘못된 변환으로 인해 `SELECT ALL t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 > t2.c1` 형식의 쿼리에서 잘못된 결과가 발생했습니다. (Bug #102025, Bug #32302724)
- 이번 릴리스부터 Performance Schema는 콜레이션을 인식합니다. (Bug #98545, Bug #30881109)

- [`setup_actors`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/performance-schema-setup-actors-table.html)의 `ROLE` 컬럼에 32바이트보다 큰 데이터를 삽입할 때 assert 오류가 발생할 수 있었습니다. 이 릴리스부터 `ROLE` 컬럼은 CHAR(32)에서 CHAR(96)으로 증가했습니다. (Bug #74678, Bug #19947842)
