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

## DBA를 위한 핵심 내용

MySQL 8.0.21은 Group Replication 안정성 기본값, InnoDB redo 비활성화, mysqldump 권한 요구 변경이 DBA에게 가장 직접적입니다. 특히 백업 계정 권한 변경은 실제 운영에서 혼란을 만든 사례가 있으므로, 업그레이드 전 백업·복제·Group Replication 설정 검토가 필요합니다. ([DBA StackExchange](https://dba.stackexchange.com/questions/271981/access-denied-you-need-at-least-one-of-the-process-privileges-for-this-ope))

1. `INFORMATION_SCHEMA.FILES` 접근에 `PROCESS` 권한이 필요해졌고, `mysqldump`가 tablespace 정보를 덤프할 때도 영향을 받습니다. 백업 계정에 `PROCESS`를 부여할지, 아니면 `mysqldump --no-tablespaces`로 우회할지 정책을 정해야 합니다.
2. `ALTER INSTANCE DISABLE/ENABLE INNODB REDO_LOG`가 추가되었습니다. 신규 인스턴스 대량 적재 속도 향상에 유용하지만, redo 비활성화 중 장애가 발생하면 복구 불가 데이터 손상 위험이 있으므로 운영 데이터베이스 일반 작업에는 사용하지 않는 것이 안전합니다.
3. Group Replication에서 `binlog_checksum=CRC32` 기본값을 사용할 수 있게 되었고, auto-rejoin 기본값이 3회로 변경되며 expel timeout 기본값도 늘었습니다. 네트워크 일시 장애 복원성은 좋아지지만, 자동 재조인 중 오래된 읽기 가능성과 XCom 메시지 캐시 크기 부족 경고를 점검해야 합니다.
4. InnoDB tablespace 경로 검증 비활성화, `DATA DIRECTORY` 생성 위치 제한, lock system 샤딩이 도입되었습니다. tablespace 파일 수가 많은 환경은 시작 시간 개선을 기대할 수 있으나, 외부 디렉터리 tablespace는 `innodb_directories` 설정 누락 시 위치가 바뀔 수 있습니다.
5. JSON 컬럼 인덱싱을 쉽게 하는 `JSON_VALUE()`와 `prefer_ordering_index` optimizer switch가 추가되었습니다. JSON 검색 성능 개선 기회가 있지만, `ORDER BY ... LIMIT` 쿼리의 실행 계획이 기대와 다르면 새 스위치로 회피할 수 있습니다.
6. 5.7에서 8.0 업그레이드 관련 full-text/general tablespace, 고아 이벤트, partition discard, clone/Group Replication 복구 관련 수정이 많습니다. 업그레이드 리허설에서는 full-text 인덱스, `DATA DIRECTORY`, Group Replication clone recovery, 백업 권한을 별도 체크리스트로 검증하십시오.

## 계정 관리 관련 사항

- 이제 MySQL 사용자 계정을 생성하거나 업데이트할 때 사용자별 주석과 속성을 설정할 수 있습니다. 사용자 주석은 [`CREATE USER`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/create-user.html) 또는 [`ALTER USER`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/alter-user.html) 문과 함께 사용되는 `COMMENT` 절의 인수로 전달되는 임의의 텍스트로 구성됩니다. 사용자 속성은 이 두 문 중 하나와 함께 사용되는 `ATTRIBUTE` 절의 인수로 전달되는 JSON 객체 형식의 데이터로 구성됩니다. 속성에는 JSON 객체 표기법의 유효한 키-값 쌍을 포함할 수 있습니다.

  예를 들어, 다음 두 문 중 첫 번째 문은 주석 텍스트 `This is Bill's user account`가 있는 사용자 계정 `bill@localhost`를 생성합니다. 두 번째 문은 키 `email`과 값 `bill@example.com`을 사용하여 이 계정에 사용자 속성을 추가합니다.

  ```
  CREATE USER 'bill'@'localhost' COMMENT 'This is Bill\'s user account';

  ALTER USER 'mary'@'localhost'
      ATTRIBUTE '{"email":"bill@example.com"}';
  ```

  동일한 `CREATE USER` 또는 `ALTER USER` 문에서는 `COMMENT` 또는 `ATTRIBUTE` 중 하나만 사용할 수 있습니다.

  사용자 주석과 사용자 속성은 내부적으로 JSON 객체로 함께 저장되며, 주석 텍스트는 키가 `comment`인 요소의 값으로 저장됩니다. [`INFORMATION_SCHEMA.USER_ATTRIBUTES`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-user-attributes-table.html) 테이블의 `ATTRIBUTE` 컬럼에서 사용자 주석과 사용자 속성 정보를 조회할 수 있습니다. 이 데이터는 JSON 형식이므로 MySQL의 JSON 함수와 연산자를 사용하여 작업할 수 있습니다([JSON Functions](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/json-functions.html) 참조). 기존 사용자 속성에 대한 변경 사항은 [`JSON_MERGE_PATCH()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/json-modification-functions.html#function_json-merge-patch)를 사용한 것처럼 현재 값과 병합됩니다. 새 키-값 쌍은 속성에 추가되고, 기존 키에 대한 새 값은 이전 값을 덮어씁니다.

  사용자 속성에서 지정된 키-값 쌍을 제거하려면 `ALTER USER user ATTRIBUTE '{"key":null}'`을 사용하십시오.

  자세한 정보와 예시는 [CREATE USER Statement](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/create-user.html), [ALTER USER Statement](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/alter-user.html), 및 [The INFORMATION_SCHEMA USER_ATTRIBUTES Table](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-user-attributes-table.html)을 참조하십시오. (WL #13562)

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

## C API 관련 사항

- OpenSSL 권고에 따라 C 클라이언트 라이브러리의 `x509_check_host()` 및 `X509_check_ip_asc()` 호출은 각각 `X509_VERIFY_PARAM_set1_host()` 및 `X509_VERIFY_PARAM_set1_ip_asc()` 호출로 대체되었습니다. (Bug #29684791)
- MySQL C API는 이제 비동기 함수에 대해 압축을 지원합니다. 이는 [`mysql_options()`](https://docs.oracle.com/cd/E17952_01/c-api-8.0-en/mysql-options.html) 함수의 `MYSQL_OPT_COMPRESSION_ALGORITHMS` 및 `MYSQL_OPT_ZSTD_COMPRESSION_LEVEL` 옵션이 이제 동기 작업뿐만 아니라 비동기 작업에도 영향을 준다는 의미입니다. [mysql_options()](https://docs.oracle.com/cd/E17952_01/c-api-8.0-en/mysql-options.html)를 참조하십시오.

  기여해 주신 Facebook에 감사드립니다. (Bug #96802, Bug #30284871, WL #13510)

## 컴파일 관련 사항

- 서버 빌드를 위한 Boost 라이브러리의 최소 버전은 이제 1.72.0입니다. (Bug #30963985)

## 설정 관련 사항

- `tcmalloc`은 더 이상 **mysqld_safe** [`--malloc-lib`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/mysqld-safe.html#option_mysqld_safe_malloc-lib) 옵션에 허용되는 값이 아닙니다. (Bug #31372027)

## 연결 관리 관련 사항

- MySQL Server는 일반 클라이언트 연결을 위한 “main” 네트워크 인터페이스를 지원하며, 선택적으로 관리용 클라이언트 연결을 위한 관리 네트워크 인터페이스를 지원합니다. 이전에는 main 및 관리 인터페이스가 암호화된 연결을 위한 인증서 및 키 파일과 같은 동일한 TLS 설정을 사용했습니다. 이제 관리 인터페이스에 대해 TLS 구성 자료를 별도로 설정할 수 있습니다:

  - 관리 인터페이스에 특별히 적용되는 새 설정 파라미터가 있습니다.
  - [`ALTER INSTANCE RELOAD TLS`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/alter-instance.html#alter-instance-reload-tls) 문이 TLS 컨텍스트를 다시 로드할 채널(인터페이스)을 지정할 수 있게 하는 `FOR CHANNEL` 절로 확장되었습니다.
  - 새 Performance Schema [`tls_channel_status`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/performance-schema-tls-channel-status-table.html) 테이블은 main 및 관리 인터페이스에 대한 TLS 컨텍스트 속성을 노출합니다.
  - 이전 버전과의 호환성을 위해, 관리 인터페이스에 대해 기본값이 아닌 TLS 파라미터 값이 설정되지 않는 한 관리 인터페이스는 main 인터페이스와 동일한 TLS 컨텍스트를 사용합니다.

  자세한 내용은 [Administrative Interface Support for Encrypted Connections](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/administrative-connection-interface.html#administrative-interface-encrypted-connections), [ALTER INSTANCE Statement](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/alter-instance.html), 및 [The tls_channel_status Table](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/performance-schema-tls-channel-status-table.html)을 참조하십시오. (WL #13850)

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

- **파티셔닝:** 인덱스 접두사를 가진 컬럼은 테이블의 파티셔닝 키 일부로 지원되지 않습니다. 이전에는 이러한 컬럼이 키로 파티셔닝된 테이블을 생성, 변경 또는 업그레이드할 때 참조되면 서버가 단순히 제외했으며, 제안된 파티셔닝 함수가 접두사를 가진 컬럼만 사용하여 실제 문제 원인을 식별하지 않는 오류 메시지와 함께 구문이 실패한 경우를 제외하고는 이러한 제외가 발생했다는 표시가 없었습니다. 이 동작은 이제 사용 중단 예정이며, 향후 릴리스에서는 제안된 파티셔닝 키에 이러한 컬럼을 사용하면 해당 컬럼이 나타나는 [`CREATE TABLE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/create-table.html) 또는 [`ALTER TABLE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/alter-table.html) 구문이 거부되도록 제거될 수 있습니다.

  인덱스 접두사를 사용하는 하나 이상의 컬럼이 파티셔닝 키 일부로 지정되면, 이제 이러한 각 컬럼에 대해 경고가 생성됩니다. 또한 제안된 파티셔닝 키에 지정된 모든 컬럼이 인덱스 접두사를 사용하기 때문에 [`CREATE TABLE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/create-table.html) 또는 [`ALTER TABLE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/alter-table.html) 구문이 거부되는 경우, 반환되는 오류 메시지는 이제 구문이 성공하지 못한 이유를 명확히 나타냅니다. 여기에는 빈 `PARTITION BY KEY()` 절을 사용하여 파티셔닝 함수에 제안된 컬럼이 테이블의 기본 키에 있는 컬럼으로 암시적으로 정의되는 경우도 포함됩니다.

  자세한 정보와 예시는 [Column index prefixes not supported for key partitioning](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/partitioning-limitations.html#partitioning-limitations-prefixes) 및 [KEY Partitioning](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/partitioning-key.html)을 참조하십시오. (Bug #29941932, Bug #29941959, Bug #31100205, WL #13588)

  References: See also: Bug #29942014.

## JSON 관련 사항

- [`JSON`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/json.html) 컬럼에 인덱스를 생성하는 작업을 단순화하는 [`JSON_VALUE()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/json-search-functions.html#function_json-value) 함수가 추가되었습니다. `JSON_VALUE(json_doc, path RETURNING type)` 호출은 [`CAST`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/cast-functions.html#function_cast)`(`[`JSON_UNQUOTE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/json-modification-functions.html#function_json-unquote)`(`[`JSON_EXTRACT(json_doc, path)`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/json-search-functions.html#function_json-extract)`) AS type)` 호출과 동일하며, 여기서 *`json_doc`*는 JSON 문서이고, *`path`*는 문서 내의 단일 값을 가리키는 JSON 경로 표현식이며, *`type`*은 *`CAST()`*와 호환되는 데이터 타입입니다. `RETURNING type`은 선택 사항입니다. 반환 타입을 지정하지 않으면 `JSON_VALUE()`는 [`VARCHAR(512)`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/char.html)를 반환합니다.

  `JSON_VALUE()`는 [`JSON_TABLE()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/json-table-functions.html#function_json-table)과 함께 사용되는 것과 유사한 `ON EMPTY` 및 `ON ERROR` 절도 지원합니다.

  다음과 같이 `JSON_VALUE()`를 사용하여 [`JSON`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/json.html) 컬럼에 인덱스를 생성할 수 있습니다:

  ```
  CREATE TABLE inventory(
      items JSON,
      INDEX i1 ( (JSON_VALUE(items, '$.name' RETURNING CHAR(50))) ),
      INDEX i2 ( (JSON_VALUE(items, '$.price' RETURNING DECIMAL(5,2))) ),
      INDEX i3 ( (JSON_VALUE(items, '$.quantity' RETURNING UNSIGNED)) )
  );
  ```

  `items` 컬럼에 `'{"name": "hat", "price": "22.95", "quantity": "17"}'`와 같은 값이 포함되어 있다고 가정하면, 다음과 같이 이러한 인덱스를 사용할 수 있는 쿼리를 실행할 수 있습니다:

  ```
  SELECT items->"$.price" FROM inventory
      WHERE JSON_VALUE(items, '$.name' RETURNING CHAR(50)) = "hat";

  SELECT * FROM inventory
      WHERE JSON_VALUE(items, '$.price' RETURNING DECIMAL(5,2)) <= 100.01;

  SELECT items->"$.name" AS item, items->"$.price" AS amount
      FROM inventory
      WHERE JSON_VALUE(items, '$.quantity' RETURNING UNSIGNED) > 500;
  ```

  자세한 정보와 예제는 [`JSON_VALUE()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/json-search-functions.html#function_json-value) 함수 설명을 참조하십시오. (WL #12228)

## Optimizer 관련 사항

- MySQL은 `LIMIT` 절이 있는 모든 `ORDER BY` 또는 `GROUP BY` 쿼리에 대해, 이렇게 하면 더 빠르게 실행된다고 판단할 때마다 Optimizer가 선택한 다른 모든 선택을 재정의하고 정렬된 인덱스 사용을 시도합니다. 이러한 판단을 내리는 알고리즘은 데이터 분포 및 기타 조건에 대해 특정 가정을 하기 때문에, 항상 완전히 정확하지는 않을 수 있으며, 이러한 쿼리에 대해 다른 최적화를 선택하면 더 나은 성능을 제공할 수 있는 경우도 있습니다. 이러한 상황을 처리하기 위해 이제 [`optimizer_switch`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_optimizer_switch) 시스템 변수의 [`prefer_ordering_index`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/switchable-optimizations.html#optflag_prefer-ordering-index) 플래그를 `off`로 설정하여 이 최적화를 비활성화할 수 있습니다.

  이 플래그 및 사용 예에 대한 자세한 내용은 [Switchable Optimizations](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/switchable-optimizations.html) 및 [LIMIT Query Optimization](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/limit-optimization.html)을 참조하십시오.

  기여해 주신 Jeremy Cole에게 감사드립니다. (Bug #97001, Bug #30348211, WL #13929)

  참조: 함께 참조하십시오: Bug #31686878.
- `[NOT] IN` 또는 `[NOT] EXISTS` 조건자를 가진 서브쿼리를 사용하는 단일 테이블 [`UPDATE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/update.html) 또는 [`DELETE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/delete.html) 문은 이제 많은 경우 세미조인 변환 또는 서브쿼리 구체화를 사용할 수 있습니다. 이는 해당 문이 `LIMIT` 또는 `ORDER BY`를 사용하지 않고, 서브쿼리에 사용된 Optimizer 힌트 또는 [`optimizer_switch`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_optimizer_switch) 서버 시스템 변수의 값에 의해 세미조인 또는 서브쿼리 구체화가 허용되는 경우 수행할 수 있습니다.

  적합한 단일 테이블 `DELETE` 또는 `UPDATE`에 대해 세미조인 최적화 또는 서브쿼리 구체화가 사용되는 경우, Optimizer 추적에 `join_optimization` 객체가 존재하는 것을 통해 확인할 수 있습니다. 또한 [`EXPLAIN FORMAT=TREE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/explain.html)의 출력을 확인하여 변환이 수행되는지 확인할 수도 있습니다. 최적화가 수행되지 않으면 이 출력은 `<not executable by iterator executor>`를 표시하는 반면, 다중 테이블 문은 전체 플랜을 보고합니다.

  이 작업의 일환으로, 트랜잭션 격리 수준이 [`REPEATABLE READ`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/innodb-transaction-isolation-levels.html#isolevel_repeatable-read)보다 약한 경우 [`InnoDB`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/innodb-storage-engine.html) 테이블의 다중 테이블 `UPDATE`에서 이제 semi-consistent read가 지원됩니다. (Bug #35794, Bug #96423, Bug #11748293, Bug #30139244, WL #6507)
- [`optimizer_switch`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_optimizer_switch) 플래그 [`subquery_to_derived`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/switchable-optimizations.html#optflag_subquery-to-derived)가 추가되었습니다. 이 플래그가 `on`으로 설정되면 Optimizer는 조건에 맞는 스칼라 서브쿼리를 파생 테이블에 대한 left outer join(일부 경우에는 inner join)으로 변환합니다. 이 최적화는 다음 조건을 충족하는 서브쿼리에 적용될 수 있습니다:

  - 하나 이상의 집계 함수를 사용하지만 `GROUP BY`는 사용하지 않습니다.
  - `SELECT`, `WHERE`, `JOIN` 또는 `HAVING` 절의 일부입니다.
  - 상관 서브쿼리가 아닙니다.
  - 비결정적 함수를 사용하지 않습니다.

  [`MIN()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/aggregate-functions.html#function_min) 또는 [`MAX()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/aggregate-functions.html#function_max)를 사용하도록 다시 작성할 수 있는 `ANY` 및 `ALL` 서브쿼리도 영향을 받지 않습니다.

  `subquery_to_derived=on`인 경우, 이 최적화는 `IN`, `NOT IN`, `EXISTS` 또는 `NOT EXISTS`의 인수이며 `GROUP BY` 절을 포함하지 않는 테이블 서브쿼리에도 적용될 수 있습니다.

  `subquery_to_derived` 플래그는 기본적으로 `off`로 설정됩니다. 이는 일반적으로 성능을 개선하지 않으며, 주된 의도된 용도가 대부분 테스트 목적이기 때문입니다.

  자세한 내용과 예시는 [Switchable Optimizations](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/switchable-optimizations.html)를 참조하십시오. [Optimizing Derived Tables, View References, and Common Table Expressions with Merging or Materialization](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/derived-table-optimization.html) 및 [LIMIT Query Optimization](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/limit-optimization.html)도 참조하십시오. (WL #13851)

- MySQL 8.0.18에서 수행된 작업을 기반으로, 이제 서버는 문자열 데이터 타입을 숫자 또는 시간 타입의 데이터 타입과 비교할 때 불일치를 방지하기 위해 쿼리에 캐스트를 주입합니다. 숫자 타입과 시간 타입을 비교할 때와 마찬가지로, 이제 Optimizer는 인수의 데이터 타입과 예상 데이터 타입이 일치하지 않는 표현식 및 조건 내부의 item tree에 캐스팅 작업을 추가합니다. 이렇게 하면 문자열 타입을 숫자 또는 시간 타입과 비교하는 쿼리가 SQL 표준을 준수하는 쿼리와 동등해지며, 동시에 이전 MySQL 릴리스와의 하위 호환성이 유지됩니다. 이제 이러한 캐스트는 표준 숫자 비교 연산자([`=`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/assignment-operators.html#operator_assign-equal), [`>=`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/comparison-operators.html#operator_greater-than-or-equal), [`>`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/comparison-operators.html#operator_greater-than), [`<`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/comparison-operators.html#operator_less-than), [`<=`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/comparison-operators.html#operator_less-than-or-equal), [`<>`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/comparison-operators.html#operator_not-equal)/[`!=`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/comparison-operators.html#operator_not-equal), 및 [`<=>`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/comparison-operators.html#operator_equal-to)) 중 하나를 사용하여 문자열 값을 숫자 또는 시간 값과 비교할 때마다 수행됩니다.

  이제 이러한 암시적 캐스트는 문자열 타입([`CHAR`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/char.html), [`VARCHAR`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/char.html), [`BINARY`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/binary-varbinary.html), [`VARBINARY`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/binary-varbinary.html), [`BLOB`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/blob.html), [`TEXT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/blob.html), [`ENUM`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/enum.html), 또는 [`SET`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/set.html))과 숫자 타입([`SMALLINT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/integer-types.html), [`TINYINT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/integer-types.html), [`MEDIUMINT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/integer-types.html), [`INT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/integer-types.html)/[`INTEGER`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/integer-types.html), [`BIGINT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/integer-types.html); [`DECIMAL`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/fixed-point-types.html)/[`NUMERIC`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/fixed-point-types.html); [`FLOAT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/floating-point-types.html), [`DOUBLE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/floating-point-types.html), [`REAL`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/floating-point-types.html); 및 [`BIT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/bit-type.html)) 사이에서 문자열 값을 [`DOUBLE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/floating-point-types.html)로 캐스팅하여 수행됩니다. 숫자 값이 이미 `DOUBLE`, [`FLOAT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/floating-point-types.html), 또는 [`REAL`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/floating-point-types.html) 타입이 아닌 경우, 해당 값도 [`DOUBLE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/floating-point-types.html)로 캐스팅됩니다. [`YEAR`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/year.html) 값도 문자열 값과 비교될 때 `DOUBLE`로 캐스팅됩니다(문자열 값도 마찬가지입니다). 문자열 타입과 [`TIMESTAMP`](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) 값 사이의 이러한 비교에서는 인수가 `DATETIME`으로 캐스팅됩니다. 문자열 타입을 [`DATE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/datetime.html) 값과 비교할 때는 문자열이 `DATE`로 캐스팅됩니다.

  예를 들어, `SELECT * FROM t1 JOIN t2 ON t1.char_col = t2.int_col`과 같은 쿼리는 `SELECT * FROM t1 JOIN t2 ON CAST(t1.char_col AS DOUBLE) = CAST(t2.int_col AS DOUBLE)`로 다시 작성되어 실행되며, `SELECT * FROM t1 JOIN t2 ON t1.varchar_col = t2.timestamp_col`은 실행 전에 `SELECT * FROM t1 JOIN t2 ON CAST(t1.varchar_col AS DATETIME) = CAST(t2.timestamp_col AS DATETIME)`으로 변환됩니다.

  지정된 쿼리에 캐스트가 삽입되는 시점은 [`EXPLAIN ANALYZE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/explain.html#explain-analyze), `EXPLAIN FORMAT=JSON` 또는 `EXPLAIN FORMAT=TREE`의 출력을 확인하여 볼 수 있습니다. `EXPLAIN [FORMAT=TRADITIONAL]`도 사용할 수 있지만, 이 경우 다시 작성된 쿼리를 보려면 `EXPLAIN` 문 실행 후 [`SHOW WARNINGS`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/show-warnings.html)를 실행해야 합니다.

  이 변경으로 인해 쿼리 결과나 성능에 차이가 발생할 것으로 예상되지는 않습니다. (WL #13456)

## 패키징 관련 사항

- RPM 및 Debian 패키지의 경우, 클라이언트 측 플러그인이 서버 패키지에서 클라이언트 패키지로 이동되었습니다. 또한 클라이언트 측 플러그인의 디버그 버전이 테스트 패키지로 이동되었습니다. (Bug #31123564, Bug #31336340)
- Windows용 MSI 패키지에는 더 이상 레거시 서버 데이터 컴포넌트가 포함되지 않습니다. (Bug #31060177)
- 번들로 제공되는 Protobuf 라이브러리가 버전 3.6.1에서 버전 3.11로 업그레이드되었습니다. (Bug #31000511, Bug #98852)
- MySQL과 함께 번들로 제공되는 `libevent` 라이브러리가 버전 2.1.11로 업그레이드되었습니다. 또한 [`WITH_LIBEVENT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/source-configuration-options.html#option_cmake_with_libevent) **CMake** 옵션에 대해 다음 두 가지 변경 사항이 적용되었습니다:

  - `yes`는 더 이상 `system`의 동의어로 허용되지 않습니다. 대신 `system`을 사용하십시오.
  - `system`이 지정되었지만 시스템 `libevent`를 찾을 수 없는 경우, 더 이상 누락된 시스템 라이브러리 대신 번들 버전이 사용되지 않으며, 대신 오류가 발생합니다.

  (Bug #30926742)

- MySQL과 함께 번들로 제공되는 ICU (International Components for Unicode) 라이브러리가 버전 65.1로 업그레이드되었습니다.

## Pluggable Authentication 관련 사항

- SASL LDAP 인증을 구현하는 MySQL Enterprise Edition `authentication_ldap_sasl` 플러그인은 여러 인증 방식을 지원하지만, 호스트 시스템 설정에 따라 모두 사용할 수 있지는 않을 수 있습니다. 새 [`Authentication_ldap_sasl_supported_methods`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-status-variables.html#statvar_Authentication_ldap_sasl_supported_methods) 상태 변수는 지원되는 방식을 검색할 수 있게 합니다. 해당 값은 지원되는 방식 이름을 공백으로 구분하여 구성된 문자열입니다. 예: `"SCRAM-SHA1 GSSAPI"` (WL #13876)

## 보안 관련 사항

- **호환되지 않는 변경:** [`INFORMATION_SCHEMA.FILES`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-files-table.html) 테이블에 접근하려면 이제 [`PROCESS`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/privileges-provided.html#priv_process) 권한이 필요합니다.

  이 변경은 [`FILES`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-files-table.html) 테이블의 테이블스페이스 정보에 접근하는 **mysqldump** 명령 사용자에게 영향을 미치며, 따라서 이제 해당 명령에도 [`PROCESS`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/privileges-provided.html#priv_process) 권한이 필요합니다. 테이블스페이스 정보를 덤프할 필요가 없는 사용자는 [`--no-tablespaces`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/mysqldump.html#option_mysqldump_no-tablespaces) 옵션을 사용하여 **mysqldump**를 호출함으로써 이 요구 사항을 우회할 수 있습니다. (Bug #30350829)
- OpenSSL 라이브러리가 번들로 제공되는 플랫폼의 경우, MySQL Server에 링크된 OpenSSL 라이브러리가 버전 1.1.1g로 업데이트되었습니다. 새 OpenSSL 버전에서 수정된 문제는 [https://www.openssl.org/news/cl111.txt](https://www.openssl.org/news/cl111.txt) 및 [https://www.openssl.org/news/vulnerabilities.html](https://www.openssl.org/news/vulnerabilities.html)에 설명되어 있습니다. (Bug #31296697)
- 이전에는 [`LOAD DATA`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/load-data.html) 문에 대한 `LOCAL` 데이터 로드 기능을 클라이언트 측에서 제어할 때, 클라이언트가 접근할 수 있는 모든 파일에 대해 활성화하거나 완전히 비활성화하는 방식만 사용할 수 있었습니다. [`mysql_options()`](https://docs.oracle.com/cd/E17952_01/c-api-8.0-en/mysql-options.html) C API 함수를 위한 새로운 `MYSQL_OPT_LOAD_DATA_LOCAL_DIR` 옵션을 사용하면 클라이언트가 지정된 디렉터리에 있는 파일로 `LOCAL` 데이터 로드를 제한할 수 있습니다. [Security Considerations for LOAD DATA LOCAL](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/load-data-local-security.html)을 참조하십시오. (WL #13168)

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

- **mysql-test-run.pl**은 더 이상 명령 옵션의 고유한 접두사를 허용하지 않습니다. 완전한 옵션 이름을 지정해야 합니다. (Bug #31390127)
- MySQL 테스트가 googletest 1.10.0을 사용하도록 업데이트되었습니다. (Bug #31364750)
- `innodb.innodb_mysql` 테스트 케이스는 출력 로우 순서의 비결정성을 피하도록 업데이트되었습니다. 기여해 주신 Facebook에 감사드립니다. (Bug #30810572, Bug #98377)
- **mysql-test-run.pl**은 이제 사용할 수 있는 포트 범위를 검색할 때 제외할 포트 범위를 지정하기 위한 `--mtr-port-exclude` 옵션을 지원합니다. 동일한 효과를 얻기 위해 `MTR_PORT_EXCLUDE` 환경 변수를 설정할 수도 있습니다. 기여해 주신 Facebook에 감사드립니다. (Bug #30809607)
- **CTRL**+**C**(SIGINT)를 수신하면 중단하는 것에 더해, **mysql-test-run.pl**은 이제 해당 시점까지 실패한 테스트 케이스 목록도 표시합니다. (Bug #30407014)

## X 플러그인 관련 사항

- 달러 기호($)가 전체 문서를 참조하는 데 사용된 경우, X Plugin은 해당 참조가 사용된 컨텍스트에 따라 서로 다르게 처리했습니다. 이제 이 동작이 표준화되었습니다. (Bug #31374713)
- 글로벌 SQL 모드의 특정 설정에서 X Plugin의 인증 프로세스가 올바른 사용자 암호를 받아들이지 못했습니다. 이제 인증 프로세스는 일관성을 보장하기 위해 글로벌 SQL 모드의 설정과 독립적으로 작동합니다. (Bug #31086109)

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

- **중요한 변경; Group Replication:** 기본적으로, 복제 소스 서버는 기본값이 `CRC32` 설정인 시스템 변수 [`binlog_checksum`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/replication-options-binary-log.html#sysvar_binlog_checksum)에 지정된 대로 바이너리 로그의 각 이벤트에 체크섬을 기록합니다. 이전에는 Group Replication이 바이너리 로그에 체크섬이 존재하는 것을 지원하지 않았으므로, 그룹 멤버가 될 서버 인스턴스를 설정할 때 [`binlog_checksum`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/replication-options-binary-log.html#sysvar_binlog_checksum)를 `NONE`으로 설정해야 했습니다. 이 요구 사항은 이제 제거되었으며, 기본값을 사용할 수 있습니다. [`binlog_checksum`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/replication-options-binary-log.html#sysvar_binlog_checksum) 설정은 그룹의 모든 멤버에서 동일할 필요가 없습니다.

  Group Replication은 `group_replication_applier` 채널에서 들어오는 이벤트를 검증하는 데 체크섬을 사용하지 않는다는 점에 유의하십시오. 이벤트가 여러 소스에서 해당 릴레이 로그에 기록되고, 체크섬이 생성되는 시점인 원본 서버의 바이너리 로그에 실제로 기록되기 전에 기록되기 때문입니다. 체크섬은 `group_replication_recovery` 채널 및 그룹 멤버의 기타 모든 복제 채널에서 이벤트의 무결성을 검증하는 데 사용됩니다. (WL #9038)
- **Performance:** 16진수 숫자 문자열을 그 바이너리 표현에 매핑하기 위한 조회 테이블을 도입하여 [`UNHEX()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/string-functions.html#function_unhex) 함수 구현을 개선했습니다. 이 변경으로 테스트에서 해당 함수의 실행 속도가 8배 이상 빨라졌습니다. (Bug #31173103)
- **InnoDB:** 이제 [`ALTER INSTANCE {ENABLE|DISABLE} INNODB REDO_LOG`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/alter-instance.html) 문법을 사용하여 리두 로깅을 활성화 및 비활성화할 수 있습니다. 이 기능은 새 MySQL 인스턴스에 데이터를 로드하기 위한 것입니다. 리두 로깅을 비활성화하면 리두 로그 쓰기를 피하여 데이터 로드 속도를 높이는 데 도움이 됩니다.

  새로운 [`INNODB_REDO_LOG_ENABLE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/privileges-provided.html#priv_innodb-redo-log-enable) 권한은 리두 로깅을 활성화 및 비활성화할 수 있도록 합니다.

  새로운 [`Innodb_redo_log_enabled`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-status-variables.html#statvar_Innodb_redo_log_enabled) 상태 변수는 리두 로깅 상태를 모니터링할 수 있도록 합니다.

  [Redo Logging 비활성화](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/innodb-redo-log.html#innodb-disable-redo-logging)를 참조하십시오. (WL #13795)
- **InnoDB:** 사용량이 많은 시스템에서 undo 테이블스페이스를 truncate하면, 버퍼 풀에서 이전 undo 테이블스페이스 페이지를 제거하고 새 undo 테이블스페이스의 초기 페이지를 디스크로 플러시하는 관련 플러시 작업으로 인해 성능에 영향을 줄 수 있었습니다. 이 문제를 해결하기 위해 플러시 작업이 제거되었습니다.

  이전 undo 테이블스페이스 페이지는 이제 가장 오래 사용되지 않은 상태가 될 때 수동적으로 해제되거나, 다음 전체 checkpoint에서 제거됩니다. 이제 새 undo 테이블스페이스의 초기 페이지는 truncate 작업 중에 디스크로 플러시되는 대신 redo 로그에 기록되며, 이로 인해 undo 테이블스페이스 truncate 작업의 내구성도 향상됩니다.

  undo 테이블스페이스 truncate 작업이 과도하게 많이 수행되어 발생할 수 있는 잠재적 문제를 방지하기 위해, checkpoint 사이에 동일한 undo 테이블스페이스에 대한 truncate 작업은 이제 64회로 제한됩니다. 이 제한을 초과하면 undo 테이블스페이스를 여전히 비활성 상태로 만들 수 있지만, 다음 checkpoint 이후까지 truncate되지 않습니다.

  더 이상 사용되지 않는 undo truncate 플러시 작업과 연결된 [`INNODB_METRICS`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-innodb-metrics-table.html) 카운터가 제거되었습니다. 제거된 카운터에는 `undo_truncate_sweep_count`, `undo_truncate_sweep_usec`, `undo_truncate_flush_count`, `undo_truncate_flush_usec`가 포함됩니다.

  [Undo Tablespaces](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/innodb-undo-tablespaces.html)를 참조하십시오. (WL #11819)
- **InnoDB:** 시작 시 `InnoDB`는 테이블스페이스 파일이 다른 위치로 이동된 경우에 대비하여, 알려진 테이블스페이스 파일의 경로를 데이터 딕셔너리에 저장된 테이블스페이스 파일 경로와 비교하여 검증합니다. 새로운 [`innodb_validate_tablespace_paths`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/innodb-parameters.html#sysvar_innodb_validate_tablespace_paths) 변수는 테이블스페이스 경로 검증을 비활성화할 수 있게 합니다. 이 기능은 테이블스페이스 파일이 이동되지 않는 환경을 대상으로 합니다. 테이블스페이스 경로 검증을 비활성화하면 테이블스페이스 파일 수가 많은 시스템에서 시작 시간이 개선됩니다.

  자세한 내용은 [Disabling Tablespace Path Validation](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/innodb-disabling-tablespace-path-validation.html)을 참조하십시오. (WL #14008)

- **InnoDB:** `DATA DIRECTORY` 절을 사용하여 데이터 디렉터리 외부에 생성된 테이블 및 테이블 파티션 데이터 파일은 이제 `InnoDB`에 알려진 디렉터리로 제한됩니다. 이 변경으로 데이터베이스 관리자는 테이블스페이스 데이터 파일이 생성되는 위치를 제어할 수 있으며, 복구 중에 데이터 파일을 찾을 수 있도록 보장합니다.

  일반 테이블스페이스 및 file-per-table 테이블스페이스 데이터 파일(`.ibd` 파일)은 해당 디렉터리가 `InnoDB`에 알려져 있지 않은 한 더 이상 undo 테이블스페이스 디렉터리([`innodb_undo_directory`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/innodb-parameters.html#sysvar_innodb_undo_directory))에 생성할 수 없습니다.

  알려진 디렉터리는 [`datadir`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_datadir), [`innodb_data_home_dir`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/innodb-parameters.html#sysvar_innodb_data_home_dir), [`innodb_directories`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/innodb-parameters.html#sysvar_innodb_directories) 변수로 정의된 디렉터리입니다.

  file-per-table 테이블스페이스에 있는 `InnoDB` 테이블을 truncate하면 기존 테이블스페이스를 삭제하고 새 테이블스페이스를 생성합니다. MySQL 8.0.21부터, 테이블스페이스가 이전 버전으로 생성되었고 현재 테이블스페이스 디렉터리를 알 수 없는 경우 `InnoDB`는 새 테이블스페이스를 기본 위치에 생성하고 오류 로그에 경고를 기록합니다. [`TRUNCATE TABLE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/truncate-table.html)이 테이블스페이스를 현재 위치에 생성하도록 하려면 [`TRUNCATE TABLE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/truncate-table.html)을 실행하기 전에 해당 디렉터리를 [`innodb_directories`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/innodb-parameters.html#sysvar_innodb_directories) 설정에 추가하십시오. (WL #13065)
- **InnoDB:** 테이블 및 로우 리소스에 대한 잠금 큐 접근이 필요한 작업의 동시성을 개선하기 위해, 잠금 시스템 mutex(`lock_sys->mutex`)가 샤딩된 래치로 대체되었고, 잠금 큐가 테이블 및 페이지 *잠금 큐 샤드*로 그룹화되었으며 각 샤드는 전용 mutex로 보호됩니다. 이전에는 단일 잠금 시스템 mutex가 모든 잠금 큐를 보호했으며, 이는 높은 동시성 시스템에서 경합 지점이었습니다. 새로운 샤딩 구현은 잠금 큐에 대한 더 세분화된 접근을 허용합니다.

  잠금 시스템 mutex(`lock_sys->mutex`)는 다음 샤딩된 래치로 대체되었습니다:

- 64개의 읽기-쓰기 잠금 객체(`rw_lock_t`)로 구성된 전역 래치(`lock_sys->latches.global_latch`)입니다. 개별 잠금 큐에 접근하려면 공유 전역 래치와 잠금 큐 샤드의 래치가 필요합니다. 모든 잠금 큐에 접근해야 하는 작업은 배타적 전역 래치를 획득하며, 이는 모든 테이블 및 페이지 잠금 큐 샤드를 래치합니다.
  - 테이블 샤드 래치(`lock_sys->latches.table_shards.mutexes`)는 512개의 뮤텍스 배열로 구현되며, 각 뮤텍스는 512개 테이블 잠금 큐 샤드 중 하나에 전용으로 사용됩니다.
  - 페이지 샤드 래치(`lock_sys->latches.page_shards.mutexes`)는 512개의 뮤텍스 배열로 구현되며, 각 뮤텍스는 512개 페이지 잠금 큐 샤드 중 하나에 전용으로 사용됩니다.

  단일 잠금 시스템 뮤텍스를 모니터링하기 위한 Performance Schema `wait/synch/mutex/innodb/lock_mutex` 계측은 새로운 전역, 테이블 샤드 및 페이지 샤드 래치를 모니터링하기 위한 계측으로 대체되었습니다:

  - `wait/synch/sxlock/innodb/lock_sys_global_rw_lock`
  - `wait/synch/mutex/innodb/lock_sys_table_mutex`
  - `wait/synch/mutex/innodb/lock_sys_page_mutex`

  (WL #10314)

- **Group Replication:** 이제 Group Replication 그룹 멤버는 조인하는 멤버가 분산 복구 중 상태 전송을 위해 자신에게 연결할 때 사용할 수 있는 IP 주소 목록을 알릴 수 있습니다. 이전에는 기존 멤버의 표준 SQL 클라이언트 연결이 이 용도와 클라이언트 트래픽 용도에 함께 사용되었습니다. 대신 분산 복구 엔드포인트를 알리면 네트워크 인프라에서 분산 복구 트래픽(원격 클로닝 작업 및 바이너리 로그의 상태 전송으로 구성됨)에 대한 제어가 향상됩니다. 멤버의 분산 복구 엔드포인트 목록은 새 [`group_replication_advertise_recovery_endpoints`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/group-replication-system-variables.html#sysvar_group_replication_advertise_recovery_endpoints) 시스템 변수를 사용하여 지정되며, SQL 클라이언트 연결이 분산 복구에 사용되는 경우 적용될 동일한 SSL 요구 사항이 적용됩니다. (WL #13767)

- **Group Replication:** 이제 [`START GROUP_REPLICATION`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/start-group-replication.html) 문에서 `USER`, `PASSWORD`, `DEFAULT_AUTH` 옵션을 사용하여 분산 복구용 사용자 자격 증명을 지정할 수 있습니다. 이러한 자격 증명은 `group_replication_recovery` 채널에서 분산 복구에 사용됩니다. [`START GROUP_REPLICATION`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/start-group-replication.html)에서 사용자 자격 증명을 지정하면, 자격 증명은 메모리에만 저장되며 [`STOP GROUP_REPLICATION`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/stop-group-replication.html) 문 또는 서버 종료에 의해 제거됩니다. 이러한 자격 증명은 [`CHANGE MASTER TO`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/change-master-to.html) 문을 사용하여 설정되고 복제 메타데이터 저장소에 저장되는 사용자 자격 증명을 대체할 수 있으므로, Group Replication 서버를 무단 접근으로부터 보호하는 데 도움이 될 수 있습니다.

  사용자 자격 증명을 제공하는 새 방법은 서버 시작 시 Group Replication을 자동으로 시작하는 것과 호환되지 않습니다. 이전에 [`CHANGE MASTER TO`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/change-master-to.html) 문을 사용하여 사용자 자격 증명이 설정된 경우, [`START GROUP_REPLICATION`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/start-group-replication.html)에서 지정한 자격 증명이 이러한 자격 증명보다 우선합니다. 그러나 [`START GROUP_REPLICATION`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/start-group-replication.html)이 사용자 자격 증명 없이 지정된 경우에는 복제 메타데이터 저장소의 자격 증명이 사용되며, 이는 [`group_replication_start_on_boot`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/group-replication-system-variables.html#sysvar_group_replication_start_on_boot) 시스템 변수가 `ON`으로 설정된 경우 자동 시작 시 발생합니다(분산 복구를 위한 원격 클로닝 작업 이후를 포함합니다). [`START GROUP_REPLICATION`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/start-group-replication.html)에서 사용자 자격 증명을 지정함으로써 얻을 수 있는 보안상의 이점을 확보하려면, [`group_replication_start_on_boot`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/group-replication-system-variables.html#sysvar_group_replication_start_on_boot)이 `OFF`로 설정되어 있는지 확인하고(기본값은 `ON`입니다), [`CHANGE MASTER TO`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/change-master-to.html) 문을 사용하여 `group_replication_recovery` 채널에 대해 이전에 설정된 모든 사용자 자격 증명을 지우십시오. (WL #13768)

- **Group Replication:** [`group_replication_message_cache_size`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/group-replication-system-variables.html#sysvar_group_replication_message_cache_size) 시스템 변수로 지정되는 Group Replication의 XCom 메시지 캐시 최대 크기에 대한 최소 설정값이 약 1 GB에서 134217728바이트, 즉 약 128 MB로 줄었습니다. 이 크기 제한은 캐시에 저장되는 데이터에만 적용되며, 캐시 구조에는 추가로 50 MB의 메모리가 필요합니다. 모든 그룹 멤버에 동일한 캐시 크기 제한을 설정해야 합니다. 이전에는 최소 설정값이기도 했던 기본 XCom 메시지 캐시 크기 1 GB는 변경되지 않았습니다.

  더 작은 메시지 캐시 크기는 사용 가능한 메모리 양이 제한되어 있고 네트워크 연결성이 좋은 호스트에 배포할 수 있도록 제공됩니다. 호스트가 불안정한 네트워크에 있는 경우 매우 낮은 [`group_replication_message_cache_size`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/group-replication-system-variables.html#sysvar_group_replication_message_cache_size) 설정을 사용하는 것은 권장되지 않습니다. 더 작은 메시지 캐시는 일시적인 연결 손실 후 그룹 멤버가 다시 연결하기 어렵게 만들기 때문입니다. 멤버가 일시적으로 부재한 동안 교환된 일부 메시지가 최대 크기 제한에 도달했기 때문에 다른 멤버의 XCom 메시지 캐시에서 삭제된 경우, 해당 멤버는 메시지 캐시를 사용하여 다시 연결할 수 없습니다. 메시지 캐시를 사용하는 것보다 더 느린 프로세스인 분산 복구를 통해 트랜잭션을 가져오기 위해 그룹을 떠난 후 다시 참여해야 하지만, 이 경우에도 멤버는 운영자 개입 없이 이러한 방식으로 다시 참여할 수 있습니다.

  MySQL 8.0.21부터는 기본적으로 멤버가 그룹에서 추방되기 전에 5초의 추방 타임아웃이 추가됩니다([`group_replication_member_expel_timeout`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/group-replication-system-variables.html#sysvar_group_replication_member_expel_timeout) 시스템 변수로 지정됨). 따라서 이 기본 설정에서는 XCom 메시지 캐시가 이제 이전처럼 5초 기간(초기 5초 감지 기간만)이 아니라 10초 기간(추방 타임아웃과 초기 5초 감지 기간을 더한 기간) 동안 그룹에서 교환된 메시지를 저장해야 합니다. (WL #13979)

- **Group Replication:** [`group_replication_member_expel_timeout`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/group-replication-system-variables.html#sysvar_group_replication_member_expel_timeout)는 Group Replication 그룹 멤버가 실패한 것으로 의심되는 멤버를 그룹에서 추방하기 전에, 의심 상태를 생성한 후 대기하는 시간을 초 단위로 지정합니다. 의심 상태가 생성되기 전의 최초 5초 감지 기간은 이 시간의 일부로 계산되지 않습니다.

  이전에는 [`group_replication_member_expel_timeout`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/group-replication-system-variables.html#sysvar_group_replication_member_expel_timeout)로 지정되는 대기 기간의 기본값이 0이었으며, 이는 의심되는 멤버가 5초 감지 기간이 끝난 직후 추방될 수 있음을 의미했습니다. 사용자 피드백에 따라, 이제 대기 기간의 기본값은 5초이며, 그룹과의 연결이 끊어진 멤버가 그룹에 다시 연결할 수 있도록 총 10초가 제공됩니다. 멤버가 이 시간 내에 다시 연결하면, 그룹에서 추방되어 다시 참여하기 위해 자동 재참여 절차 또는 수동 운영자 개입이 필요해지는 대신, XCom 메시지 캐시에서 누락된 메시지를 복구하고 자동으로 `ONLINE` 상태로 돌아갈 수 있습니다.

  이전에 멤버가 추방되기 전의 이전 기본 시간(5초 감지 기간만 해당)에 예상되는 메시지 볼륨을 기준으로 XCom 메시지 캐시의 크기를 조정한 경우, 기본 시간을 10초로 두 배 늘리는 새 추방 타임아웃을 고려하도록 [`group_replication_message_cache_size`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/group-replication-system-variables.html#sysvar_group_replication_message_cache_size) 설정을 늘리십시오. 새 기본 추방 타임아웃을 사용하면 활성 그룹 멤버에서 GCS의 경고 메시지가 표시되기 시작할 수 있으며, 현재 연결할 수 없는 멤버가 복구에 필요할 가능성이 있는 메시지가 메시지 캐시에서 제거되었다고 명시합니다. 이 메시지는 멤버가 다시 연결하기 위해 메시지 캐시를 사용할 필요가 있었으며, 멤버가 추방되기 전의 현재 대기 기간을 지원하기에 캐시 크기가 충분하지 않을 수 있음을 보여줍니다. (WL #13773)

- **Group Replication:** Group Replication 자동 재조인 기능은 이제 기본적으로 활성화됩니다. MySQL 8.0.16부터 사용할 수 있는 [`group_replication_autorejoin_tries`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/group-replication-system-variables.html#sysvar_group_replication_autorejoin_tries) 시스템 변수는 추방되었거나 도달 불가능 다수결 타임아웃에 도달한 멤버가 그룹에 자동으로 다시 조인하려고 시도하게 합니다. 원래 기본값이 0이어서 자동 재조인이 활성화되지 않았던 이 시스템 변수는 이제 기본값이 3이며, 이는 멤버가 추방되거나 도달 불가능 다수결 타임아웃이 발생한 경우 그룹에 다시 조인하기 위해 세 번 시도함을 의미합니다. 각 시도 사이에 멤버는 5분 동안 대기합니다. 지정된 시도 횟수가 소진될 때까지 멤버가 다시 조인하지 못하고 중지되지도 않은 경우, 멤버는 [`group_replication_exit_state_action`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/group-replication-system-variables.html#sysvar_group_replication_exit_state_action) 시스템 변수로 지정된 동작을 진행합니다.

  자동 재조인 기능은 특히 일시적인 네트워크 문제가 비교적 흔한 경우 멤버를 그룹으로 다시 가져오기 위한 수동 개입 필요성을 최소화합니다. 자동 재조인 시도 중 및 시도 사이에 멤버는 super read only 모드로 유지되며 쓰기를 허용하지 않습니다. 그러나 멤버에서 읽기는 여전히 수행할 수 있으며, 시간이 지남에 따라 오래된 읽기가 발생할 가능성이 증가합니다. 멤버를 오프라인으로 전환하기 위해 개입하려면, [`STOP GROUP_REPLICATION`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/stop-group-replication.html) 문을 사용하거나 서버를 종료하여 언제든지 멤버를 수동으로 중지할 수 있습니다. 어떤 기간 동안에도 오래된 읽기가 발생할 가능성을 허용할 수 없는 경우 [`group_replication_autorejoin_tries`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/group-replication-system-variables.html#sysvar_group_replication_autorejoin_tries) 시스템 변수를 0으로 설정하십시오. 이 경우 멤버가 그룹에서 추방되거나 도달 불가능 다수결 타임아웃에 도달할 때마다 운영자 개입이 필요합니다. (WL #13706)

- 이전에는 [`--disabled-storage-engines`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_disabled_storage_engines) 옵션이 옵션 값에 나열된 스토리지 엔진 주변의 공백을 무시하지 않았습니다. 이제 엔진 이름 주변의 공백은 무시됩니다. (Bug #31373361, Bug #99632)
- 새로운 `HANDLE_FATAL_SIGNALS` **CMake** 옵션은 Address Sanitizer 및 Undefined Behavior Sanitizer 빌드가 치명적 시그널을 처리할 때 MySQL 내부 함수가 아니라 sanitizer 런타임 라이브러리를 사용할지 여부를 설정할 수 있게 합니다. 이 옵션의 기본값은 sanitizer 빌드가 아닌 경우 `ON`, sanitizer 빌드인 경우 `OFF`입니다. 옵션이 `OFF`이면 SIGBUS, SIGILL 및 SIGSEGV에 대해 내부 함수가 아니라 기본 동작이 사용됩니다. (Bug #31068443)
- `GROUP BY`에서 두 번 이상 반복되는 컬럼을 (별칭을 통해) 사용하고 `ROLLUP`과 결합하면 MySQL 5.7과 다른 동작이 발생했습니다. 예:

  ```
  SELECT a, b AS a, COUNT(*) FROM t1 GROUP BY a, b WITH ROLLUP;
  ```

  이러한 쿼리의 동작은 MySQL 5.7과 더 잘 일치하도록 변경되었습니다. 그러나 향후 동작이 다시 변경되거나 이러한 쿼리가 유효하지 않게 될 수 있으므로 피해야 합니다. (Bug #30921780, Bug #98663)
- **comp_err**는 특정 입력 파일 문제에 대해 더 나은 오류 메시지를 제공합니다. 기여해 주신 Facebook에 감사드립니다. (Bug #30810629, Bug #98390)
- 이제 MySQL Server Docker 컨테이너는 클라이언트 세션 내에서 서버 재시작을 지원합니다(예를 들어 클라이언트가 [RESTART](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/restart.html) 문을 실행할 때 또는 [InnoDB Cluster 인스턴스 설정](https://docs.oracle.com/cd/E17952_01/mysql-shell-8.0-en/deploying-production-innodb-cluster.html) 중에 발생합니다). 이 중요한 기능을 활성화하려면 컨테이너를 시작할 때 **docker run** 옵션 `--restart`를 값 `on-failure`로 설정해야 합니다. 자세한 내용은 [MySQL Server 인스턴스 시작](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/docker-mysql-getting-started.html#docker-starting-mysql-server)을 참조하십시오. (Bug #30750730)
- 이제 [`EXPLAIN ANALYZE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/explain.html#explain-analyze)는 `FORMAT` 옵션을 지원합니다. 현재 `TREE`가 지원되는 유일한 형식입니다. (Bug #30315224)

- [`read_only`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_read_only) 또는 [`super_read_only`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_super_read_only)가 활성화된 경우 더 이상 [`ALTER INSTANCE ROTATE INNODB MASTER KEY`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/alter-instance.html#alter-instance-rotate-innodb-master-key)가 허용되지 않습니다. (Bug #30274240)
- Atomic DDL을 지원하는 스토리지 엔진에서, 로우 기반 복제를 사용할 때 [`CREATE TABLE... SELECT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/create-table-select.html) 문은 이제 바이너리 로그에 하나의 트랜잭션으로 기록됩니다. 이전에는 테이블을 생성하는 트랜잭션 하나와 데이터를 삽입하는 다른 트랜잭션 하나, 이렇게 두 개의 트랜잭션으로 기록되었습니다. 이 변경으로 [`CREATE TABLE... SELECT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/create-table-select.html) 문은 이제 로우 기반 복제에 안전하며 GTID 기반 복제와 함께 사용하는 것이 허용됩니다. 자세한 내용은 [Atomic Data Definition Statement Support](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/atomic-ddl.html)를 참조하십시오. (Bug #11756034, Bug #47899, WL #13355)
- 이제 [`LOAD XML`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/load-xml.html)은 가져올 XML 파일의 `CDATA` 섹션을 지원합니다. (Bug #98199, Bug #30753708)
- 이제 X Plugin의 [`mysqlx_bind_address`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/x-plugin-options-system-variables.html#sysvar_mysqlx_bind_address) 시스템 변수는 MySQL Server의 [`bind_address`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_bind_address) 시스템 변수와 마찬가지로 여러 IP 주소를 허용하여, X Plugin이 여러 네트워크 소켓에서 TCP/IP 연결을 수신할 수 있게 합니다.

  동작상의 중요한 차이는 MySQL Server의 경우 주소 목록에 오류가 있으면 서버가 시작되지 않지만, X Plugin(필수 플러그인이 아님)은 이렇게 동작하지 않는다는 점입니다. X Plugin에서는 나열된 주소 중 하나를 구문 분석할 수 없거나 X Plugin이 해당 주소에 바인드할 수 없는 경우 해당 주소를 건너뛰고, 오류 메시지를 기록하며, X Plugin은 나머지 각 주소에 바인드하려고 시도합니다. X Plugin의 [`Mysqlx_address`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/x-plugin-status-variables.html#statvar_Mysqlx_address) 상태 변수는 목록에서 바인드가 성공한 주소만 표시합니다. 나열된 주소 중 어느 것도 성공적으로 바인드되지 않으면, X Plugin은 X Protocol을 사용할 수 없다는 오류 메시지를 기록합니다. (WL #12715)

- `ENGINE_ATTRIBUTE` 및 `SECONDARY_ENGINE_ATTRIBUTE` 옵션이 [`CREATE TABLE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/create-table.html), [`ALTER TABLE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/alter-table.html), [`CREATE INDEX`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/create-index.html) 문법에 추가되었습니다. `ENGINE_ATTRIBUTE` 옵션은 [`CREATE TABLESPACE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/create-tablespace.html) 및 [`ALTER TABLESPACE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/alter-tablespace.html) 문법에도 추가되었습니다. 테이블, 컬럼, 인덱스 및 테이블스페이스에 대해 스토리지 엔진 속성을 정의할 수 있게 하는 새 옵션은 향후 사용을 위해 예약되어 있습니다.

  테이블, 컬럼, 인덱스 및 테이블스페이스에 대한 스토리지 엔진 속성을 쿼리하기 위해 다음 [`INFORMATION_SCHEMA`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema.html) 테이블이 추가되었습니다. 값은 데이터 딕셔너리에 저장됩니다. 이 테이블은 향후 사용을 위해 예약되어 있습니다.

  - [`INFORMATION_SCHEMA.TABLES_EXTENSIONS`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-tables-extensions-table.html)
  - [`INFORMATION_SCHEMA.COLUMNS_EXTENSIONS`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-columns-extensions-table.html)
  - [`INFORMATION_SCHEMA.TABLE_CONSTRAINTS_EXTENSIONS`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-table-constraints-extensions-table.html)
  - [`INFORMATION_SCHEMA.TABLESPACES_EXTENSIONS`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-tablespaces-extensions-table.html)

  (WL #13341)

- MySQL Server의 기본 로깅 레벨은 정보성 로그 메시지를 생략하며, 여기에는 이전에 그룹 멤버십 변경과 같이 오류 상황이 아닌 Group Replication의 일부 중요한 수명 주기 이벤트가 포함되었습니다. 이제 복제 그룹의 중요한 이벤트에 대한 메시지는 시스템 메시지로 재분류되어, 서버 로깅 레벨과 관계없이 항상 서버 오류 로그에 표시됩니다. 따라서 운영자는 서버가 복제 그룹에 속했던 전체 이력을 검토할 수 있습니다. 또한 그룹 통신 계층의 소켓 바인드 오류는 정보 메시지에서 오류 메시지로 재분류되었습니다. (WL #13769)

## 수정된 버그

- **InnoDB:** `JSON` 배열 컬럼에 대한 `GROUP BY` 작업이 잘못된 타입 캐스팅으로 인해 MySQL의 UBSan 빌드에서 실패를 발생시켰습니다. (Bug #31451475)
- **InnoDB:** 여러 `InnoDB` 오류 로그 메시지가 심볼 값 없이 정의되어 있었습니다. (Bug #31401028)
- **InnoDB:** doublewrite flush 및 sync 작업과 관련된 데이터 파일 쓰기 실패 후 단일 페이지 쓰기를 위한 파일 세그먼트가 해제되지 않았습니다. (Bug #31370227)
- **InnoDB:** undo 테이블스페이스 잘라내기가 truncate 작업 전후에 동일한 space ID를 사용할 때 접근되던 코드가 제거되었습니다. 해당 시나리오는 더 이상 발생하지 않습니다. 잘라내기된 undo 테이블스페이스는 다른 space ID를 가진 새 undo 테이블스페이스 데이터 파일로 대체됩니다. (Bug #31354435)
- **InnoDB:** undo 테이블스페이스에 대해 예약된 space ID의 범위가 undo 테이블스페이스당 512개에서 400000개로 증가했습니다. (Bug #31340834)
- **InnoDB:** `ddl_log` 테이블에 로그를 삽입하는 동안 발생한 오류가 반환되지 않아 작업이 성공한 것처럼 보였으며, 테이블스페이스 암호화 작업을 수행하는 동안 트랜잭션이 등록되지 않았습니다. (Bug #31236217)
- **InnoDB:** `lob::purge()` 함수는 insert 작업이 삭제 표시된 레코드를 수정할 때 생성되는 undo 로그 레코드 타입(`TRX_UNDO_UPD_DEL_REC`)에 대해 LOB를 올바르게 해제하지 않았습니다. (Bug #31222046, Bug #99339)

- **InnoDB:** 삭제된 파티션을 재빌드하려고 시도한 후 종료 오류가 발생했습니다. (Bug #31215415)
- **InnoDB:** 디렉터리 또는 파일 경로 검색을 담당하는 내부 `get_real_path()` 함수가 경로가 파일인지 디렉터리인지 확인하기 전에 후행 구분자를 제거하도록 수정되었습니다. 또한 경로가 존재하지 않거나 파일 또는 하위 디렉터리로 식별될 수 없는 경우, basename에 세 글자 접미사가 있으면 이 함수는 이제 해당 경로를 파일로 간주합니다. (Bug #31215160)
- **InnoDB:** 테이블스페이스 관련 오류 메시지가 수정되었습니다. (Bug #31205520, Bug #31205441)
- **InnoDB:** 잠재적인 컴파일 문제를 방지하기 위해, `__attribute__((const))` 및 `__attribute__((pure))` 속성이 내부 `InnoDB` 함수에서 제거되었습니다. (Bug #31153123)
- **InnoDB:** 히스토그램 샘플링을 위해 읽기 스레드를 생성할 때 병렬 읽기 스레드 제한이 준수되지 않아 어설션 실패가 발생했습니다. (Bug #31151218)
- **InnoDB:** 히스토그램 통계 생성을 위해 레코드를 샘플링할 때 트랜잭션 읽기 뷰가 확인되지 않았습니다. (Bug #31151077)
- **InnoDB:** I/O 완료 루틴이 다른 스레드가 보유한 래치로 인해 LRU 목록 뮤텍스를 획득할 수 없었습니다. (Bug #31128739)

- **InnoDB:** 연결 가능한 트랜잭션 스레드가 메인 스레드에서 이미 예약한 `InnoDB` 티켓을 요청하여 데드락이 발생했습니다. 또한 이 데드락 시나리오에서 서버가 [`KILL`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/kill.html) 문에 응답하지 못했습니다. (Bug #31090777)
- **InnoDB:** 모듈 소유자로 정의된 카운터에 대한 [`INNODB_METRICS`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-innodb-metrics-table.html) 테이블의 `AVG_COUNT_RESET` 값이 NULL을 보고했습니다. `METRIC_AVG_VALUE_RESET` 필드가 잘못 NULL로 표시되었습니다. 기여해 주신 Fungo Wang에게 감사드립니다. (Bug #31084706, Bug #98990)
- **InnoDB:** 시작 시, undo 테이블스페이스 truncate 작업 중 예기치 않은 중지가 발생한 후 일부 롤백 세그먼트 헤더 페이지가 손상된 것으로 발견되었습니다. 헤더 페이지가 기록되는 동안 롤백 세그먼트 헤더 페이지의 암호화가 시작되어 일부 헤더 페이지가 예상과 달리 암호화되지 않았습니다. (Bug #31045160)

- **InnoDB:** 잠금 시스템(`lock_sys`) 코드의 여러 측면이 리팩터링되었으며, `lock_sys`의 `lock_rec_block_validate()` 및 `lock_test_prdt_pacge_lock()` 함수 관련 문제가 수정되었습니다. `lock_rec_block_validate()` 함수는 다른 함수를 반복적으로 호출했으며, 이로 인해 특정 상황에서 잠금이 검증되지 않을 수 있었습니다. 구현에는 잠재적인 이차 시간 복잡도도 있었습니다. `lock_test_prdt_page_lock()` 함수는 의도한 대로 모든 잠금을 반복 처리하지 않았습니다. (Bug #31001732)
- **InnoDB:** [`temptable_max_ram`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_temptable_max_ram) 임계값을 초과한 후 메모리 매핑 파일을 사용하면 성능 저하가 발생했습니다. (Bug #30952983, Bug #98739)
- **InnoDB:** 디버그 모드에서 잘못 정의된 `COMPRESSION` 절이 있는 테이블에 대해 [`DROP TABLE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/drop-table.html) 작업을 수행하면 실패가 발생했습니다. `InnoDB`는 적절한 처리를 위해 호출자에게 오류를 반환하지 않았습니다. (Bug #30899683, Bug #98593)
- **InnoDB:** history list 길이가 0에 가까워질 때 purge thread 활동이 과도하여 CPU 리소스를 낭비하고 mutex 경합을 유발했습니다. (Bug #30875956)

- **InnoDB:** MySQL 8.0.18에서 도입된 회귀로 인해 [`INFORMATION_SCHEMA.INNODB_COLUMNS`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-innodb-columns-table.html) 쿼리 성능이 영향을 받았습니다. 파티션 컬럼 정보를 검색하기 위해 스키마 및 테이블 데이터 딕셔너리 객체가 반복적으로 가져와졌습니다. (Bug #30837086, Bug #98449)

  References: 이 문제는 다음 버그의 회귀입니다: Bug #93033, Bug #28869903.
- **InnoDB:** `.cfg` 파일을 사용하는 [`ALTER TABLE... IMPORT TABLESPACE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/alter-table.html) 작업이 “Incorrect key file for table” 오류와 함께 실패했습니다. `row_import::m_flags` 멤버가 초기화되지 않았습니다. (Bug #30830441)
- **InnoDB:** 파티션을 폐기한 후 수행된 [`DROP TABLE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/drop-table.html) 작업이 관련 데이터 파일을 제거하지 않았으며, [`DROP DATABASE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/drop-database.html)는 데이터베이스 디렉터리를 제거할 수 없음을 나타내는 오류와 함께 실패했습니다. 폐기된 파티션이 있는 파티션된 테이블이 존재하는 경우 MySQL 5.7에서 MySQL 8.0으로의 업그레이드도 실패했습니다. 데이터 딕셔너리에서 `DISCARD` 속성이 파티션 객체 대신 테이블 객체에 적용되었으며, 이로 인해 모든 파티션이 폐기된 것처럼 보였습니다. (Bug #30818917)

- **InnoDB:** 서버가 “ibuf cursor restoration fails” 오류와 함께 간헐적으로 실패했습니다. (Bug #30770380, Bug #91033)
- **InnoDB:** 한 테이블에서 다른 테이블로 데이터를 복사하는 [`ALTER TABLE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/alter-table.html) 작업이 “Out of range value for column” 오류를 반환했습니다. 다중 로우 삽입 작업에 필요한 `AUTO_INCREMENT` 로우 수를 추적하는 카운터가 벌크 삽입 작업 후 항상 0으로 다시 설정되지는 않았습니다. (Bug #30765952, Bug #98211)
- **InnoDB:** 내부 TempTable `records_in_range()` 핸들러 함수에는 디버그 빌드에서 어설션 실패를, 일부 쿼리에 대해 일반 빌드에서 빈 결과 집합을 발생시키는 `DBUG_ABORT()` 호출이 포함되어 있었습니다. (Bug #30716037)
- **InnoDB:** `btr_cur_pessimistic_update()` 함수가 `lob::purge()` 호출로 인해 발생한 커서 위치 변경을 처리하지 못했습니다. (Bug #30712878)
- **InnoDB:** `DELETE IGNORE` 작업 중 타입 변환 실패로 인해 어설션 실패가 발생했습니다. `JSON` 값이 예상 값으로 변환되지 않았습니다. (Bug #30664660)
- **InnoDB:** purge 작업에서 null LOB 참조가 발생하여 어설션 실패가 발생했습니다. (Bug #30658887)
- **InnoDB:** `TempTable` 스토리지 엔진에서 메모리를 할당 해제할 때 청크 크기가 올바르게 계산되지 않아 `SELECT DISTINCT` 쿼리 성능에 회귀가 발생했습니다. (Bug #30562964)

- **InnoDB:** thread pool 플러그인을 사용하는 동안 TempTable 스토리지 엔진에서 segmentation fault가 발생했습니다. TempTable의 thread-local 변수는 단일 클라이언트 연결에서 실행된 문에 대해 서로 다른 스레드를 사용하는 방식과 호환되지 않았습니다. 또한 thread local 변수를 사용하면 thread-local 변수가 사용하는 메모리가 스레드 수명 동안 계속 할당된 상태로 남아 있기 때문에 과도한 메모리 소비가 발생했습니다. 이러한 문제를 해결하기 위해 thread-local 변수가 캐싱 메커니즘으로 대체되었습니다. (Bug #30050452, Bug #31116036, Bug #99136)
- **InnoDB:** 종료 중에 치명적인 “page still fixed or dirty” 오류가 발생했습니다. (Bug #29759555, Bug #95285)

  References: 이 문제는 다음 버그의 회귀입니다: Bug #29207450.
- **Partitioning:** `ORDER BY`를 사용한 파티셔닝된 테이블에 대한 쿼리가 다음 조건에서 정렬되지 않은 결과를 반환했습니다:

  - 테이블에 컬럼 중 하나에 대한 접두사가 있는 복합 인덱스가 있었습니다.
  - 쿼리의 `WHERE` 절에 접두사가 지정된 컬럼에 대한 동등 조건이 포함되어 있었습니다.
  - 접두사가 지정된 컬럼이 인덱스의 가장 왼쪽 컬럼이었습니다.
  - `ORDER BY`에 사용된 컬럼이 인덱스의 가장 오른쪽 컬럼이었습니다.
  - `ORDER BY`를 처리하는 데 해당 인덱스가 사용되었습니다.

  제안을 제공해 주신 Quanan Han에게 감사드립니다. (Bug #84070, Bug #25207522)

- **Replication:** 그룹의 일관성 수준([`group_replication_consistency`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/group-replication-system-variables.html#sysvar_group_replication_consistency) 시스템 변수로 설정)이 `BEFORE` 또는 `BEFORE_AND_AFTER`로 설정된 경우, 프라이머리 장애 조치가 발생할 때 교착 상태가 발생할 수 있었습니다. 이제 이 상황을 피하기 위해 프라이머리 장애 조치가 다르게 등록됩니다. (Bug #31175066, Bug #98643)

- **Replication:** 복제 소스 서버가 종료되고 다시 시작되면, 해당 서버의 [`MEMORY`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/memory-storage-engine.html) 테이블은 비어 있게 됩니다. 이 효과를 복제본으로 복제하기 위해, 소스가 시작 후 특정 [`MEMORY`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/memory-storage-engine.html) 테이블을 처음 사용할 때 해당 테이블에 대한 [`DELETE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/delete.html) 문을 바이너리 로그에 기록하여 해당 테이블을 비워야 함을 복제본에 알립니다. 이전에는 생성된 [`DELETE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/delete.html) 문이 현재 세션의 바이너리 로그 문 캐시에 기록되었으며, 이로 인해 같은 GTID 아래 다른 문과 함께 로깅되거나 `BEGIN` 및 `COMMIT` 문 없이 로깅될 수 있었습니다. 또한 일부 상황에서는 생성된 [`DELETE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/delete.html) 문이 이를 트리거한 트랜잭션에 의도된 GTID를 소비할 수 있었습니다. 이제 생성된 [`DELETE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/delete.html) 문은 함께 제공되는 `BEGIN` 및 `COMMIT` 문과 함께 로깅되며, 결과 트랜잭션은 문 캐시에 기록된 직후 바이너리 로그로 플러시되어 항상 자체 GTID를 받고 다른 트랜잭션과 분리되어 유지됩니다. (Bug #30527929, Bug #25681518, Bug #77729)

- **Replication:** MySQL 8.0.14의 패치 이후, 함수 호출에 임시 테이블에 대한 작업이 포함된 경우 [`binlog_format = MIXED`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/replication-options-binary-log.html#sysvar_binlog_format)가 설정되어 있으면 해당 호출이 문장 형식으로 바이너리 로그에 기록될 수 있었습니다. 이로 인해 함수 호출이 포함된 경우 [`CREATE TEMPORARY TABLE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/create-temporary-table.html) 문이 바이너리 로그에 잘못 기록되었습니다. 추가 분석 이후, 저장 함수 및 트리거의 임시 테이블 작업은 복제에 문제를 일으킬 가능성이 높으므로 이제 문장 형식의 바이너리 로깅에 안전하지 않은 것으로 표시됩니다. [`binlog_format = MIXED`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/replication-options-binary-log.html#sysvar_binlog_format)가 설정된 경우, 이러한 작업은 이제 로우 형식으로 로깅됩니다. (Bug #30395151, Bug #30320009)

- **Replication:** MySQL 8.0.14 및 MySQL 5.7.25에서 시스템 변수 [`binlog_transaction_dependency_tracking`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/replication-options-binary-log.html#sysvar_binlog_transaction_dependency_tracking) 및 [`binlog_transaction_dependency_history_size`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/replication-options-binary-log.html#sysvar_binlog_transaction_dependency_history_size)와 관련된 데드락 시나리오에 대해 적용된 수정으로 인해, 트랜잭션 종속성 추적에 사용되는 writeset 히스토리가 동시 업데이트로부터 보호되지 않는 부작용이 있었습니다. 이제 writeset 히스토리와 추적 모드는 액세스될 때마다 올바르게 잠깁니다. (Bug #29719364, Bug #95181)

  참조: 다음도 참조하십시오: Bug #28511326, Bug #91941.

- **Replication:** [`CHANGE MASTER TO`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/change-master-to.html) 문이 `MASTER_USER`를 비어 있는 값(`MASTER_USER=''`)으로 지정하여 실행된 경우, 해당 문은 성공하고 복제 메타데이터 리포지토리에 이전에 지정된 사용자 이름을 모두 지웠습니다. 그러나 이후에 리포지토리에서 정보가 읽히는 경우, 예를 들어 Group Replication 채널의 자동 재시작 중에는 기본 사용자 이름이 해당 채널에 대체될 수 있었습니다. 이 문제는 이제 수정되었으므로, MySQL 8.0.21부터는 복제 채널을 시작하는 [`START SLAVE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/start-slave.html) 문 또는 [`START GROUP_REPLICATION`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/start-group-replication.html) 문을 사용하여 항상 사용자 자격 증명을 제공하는 경우 비어 있는 `MASTER_USER` 사용자 이름을 설정하는 것이 유효한 접근 방식입니다. 이 접근 방식은 복제 채널이 재시작될 때 항상 운영자의 개입이 필요하다는 의미이지만, 사용자 자격 증명은 복제 메타데이터 리포지토리에 기록되지 않습니다.

  [`CHANGE MASTER TO`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/change-master-to.html) 문에 대한 문서도 `MASTER_USER=''`를 지정할 수 있으며, 그 결과 발생하는 오류는 비어 있는 자격 증명으로 복제 채널을 시작하려고 시도하는 경우에만 발생한다는 점을 명확히 하도록 수정되었습니다. (Bug #27357189)

- **Group Replication:** 모든 사용자 연결을 제어하는 [`group_replication_consistency`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/group-replication-system-variables.html#sysvar_group_replication_consistency) 시스템 변수에 대해 설정된 전역 값은 사용자 연결과 유사한 방식으로 처리되는 SQL API를 사용하는 MySQL Server 모듈에 대한 Group Replication의 내부 연결에 적용됩니다. 이로 인해 예를 들어 분산 복구 중 clone 플러그인 상태를 확인할 때 Group Replication이 [`group_replication_consistency`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/group-replication-system-variables.html#sysvar_group_replication_consistency)의 사용을 오류로 보고하는 경우가 있었습니다. 이제 SQL API를 사용하는 이러한 내부 연결은 일관성 수준 `EVENTUAL`을 사용하며, 이는 [`group_replication_consistency`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/group-replication-system-variables.html#sysvar_group_replication_consistency)를 사용할 수 있기 전의 동작과 일치하고 오류 메시지를 발생시키지 않습니다. (Bug #31303354, Bug #99345)

- **Group Replication:** Windows에서 Group Replication이 새 쓰기 이벤트를 기다리기 위해 Windows API 함수 SleepConditionVariableCS를 사용하면서, Group Replication이 2일 이상 실행된 후 이 함수로 인해 CPU 사용량이 눈에 띄게 높아졌으며, 이는 MySQL 서버 인스턴스를 재시작하면 수정될 수 있었지만 이후 시간이 지나면서 이전처럼 다시 증가했습니다. 이는 SleepConditionVariableCS 함수가 호출되는 timeout을 계산하기 위해 두 개의 clock 함수를 사용했기 때문에 발생했으며, 이 두 함수가 시간이 지나면서 서로 상대적으로 drift되어 timeout이 점진적으로 짧아지고 함수 호출이 더 빈번해졌습니다. Windows에서는 timeout을 계산하기 위해 단일 clock의 현재 시간을 사용하도록 하여 이 문제가 수정되었습니다. (Bug #31117930)
- **Group Replication:** 분산 복구가 진행 중인 동안 Group Replication이 중지되면, donor로 선택된 멤버의 레코드에 액세스하려는 시도로 인해 메모리 문제가 발생할 수 있었습니다. 이제 이 레코드는 분산 복구 상태와 함께 로컬에 유지됩니다. (Bug #31069563)

- **Group Replication:** Group Replication의 분산 복구에 원격 클로닝 작업이 포함되는 경우, 이를 나타내기 위해 서버에 설정된 플래그는 서버 인스턴스가 재시작될 때까지 계속 설정된 상태로 유지됩니다. 이전에는 서버에서 Group Replication이 중지되었다가 재시작되면, 원격 클로닝 작업 후 시작할 때 클로닝된 데이터 테이블과 불일치가 없도록 하기 위해 필요한 것처럼 해당 플래그로 인해 Group Replication이 `group_replication_applier` 채널의 릴레이 로그 파일을 제거했습니다. 제거된 릴레이 로그 파일에 적용되지 않은 트랜잭션이 있는 경우, 해당 멤버는 이후 그룹을 부트스트랩하는 데 사용할 수 없었지만, 다른 멤버에서 트랜잭션을 가져와 그룹에 성공적으로 조인할 수는 있었습니다. 이제 Group Replication은 두 번째 또는 그 이후 시작 시 해당 플래그를 무시하며, 원격 클로닝 작업 후 처음 시작될 때만 릴레이 로그 파일을 제거합니다. (Bug #31059680)

- **Group Replication:** 데이터 불일치 가능성을 방지하기 위해, Group Replication은 동일한 서버의 이전 인카네이션이 아직 멤버로 나열되어 있는 동안 동일한 서버의 새 인카네이션(주소는 같지만 새 식별자를 가짐)이 그룹에 참여하지 못하도록 차단합니다. 이전에는 Group Replication Group Communication System (GCS)이 서버로 메시지를 보내려고 시도하는 동안 해당 서버의 이전 인카네이션에 대한 연결을 활성 상태로 처리했으며, 소켓이 오류를 반환할 때에만 연결이 비활성 상태임을 인식했는데, 이에는 상당한 시간이 걸릴 수 있었습니다. 해당 기간 동안에는 기존 멤버가 이전 인카네이션에 대한 연결을 계속 기다리고 있었기 때문에 서버의 새 인카네이션에 연결하지 않았고, 그 결과 서버의 새 인카네이션은 그룹에 참여할 수 없었습니다. 이제 GCS는 메시지를 성공적으로 보낼 수 있는 동안에만 서버에 대한 연결을 활성 상태로 처리합니다. 소켓이 더 이상 쓰기 가능하지 않으면 서버 연결은 비활성 상태로 처리되고 선제적으로 닫힙니다. 연결 닫기는 그룹 멤버가 해당 서버 주소로 재연결을 시도하도록 트리거하며, 이때 서버의 새 인카네이션에 대한 연결이 설정되어 새 인카네이션이 그룹에 참여할 수 있습니다. (Bug #30770577)

- **Group Replication:** Group Replication은 single-primary 모드에서 multi-primary 모드로 전환할 때 알림을 브로드캐스트하지 않았습니다. 이제 라우팅에서 사용할 수 있도록 변경 사항이 통지됩니다. (Bug #30738896)

- **Group Replication:** 그룹에 대해 지정된 멤버십을 강제하기 위해 [`group_replication_force_members`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/group-replication-system-variables.html#sysvar_group_replication_force_members) 시스템 변수를 설정하는 작업은, 다른 멤버가 이미 [`group_replication_force_members`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/group-replication-system-variables.html#sysvar_group_replication_force_members) 작업을 구동하고 있던 멤버의 추방을 요청한 경우 실패할 수 있었습니다. [`group_replication_force_members`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/group-replication-system-variables.html#sysvar_group_replication_force_members) 시스템 변수로 지정된 설정을 구현하는 작업은 대기 중인 모든 그룹 재구성이 먼저 수행되도록 강제했습니다. 이들 중 하나가, 해당 멤버에 설정된 추방 제한 시간이 만료되었기 때문에 시스템 변수가 설정된 멤버를 성공적으로 추방하면, 작업이 시간 초과되어 완료에 실패했습니다. 이 상황을 방지하기 위해, 이제 Group Replication은 [`group_replication_force_members`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/group-replication-system-variables.html#sysvar_group_replication_force_members) 시스템 변수로 지정된 새 설정 구현을 직접 진행하고, 대기 중인 다른 모든 그룹 재구성을 무시합니다. (Bug #29820966)

- **Group Replication:** Group Replication에서 다른 그룹 멤버에 대한 연결 추적은 나가는 연결이 아니라 들어오는 연결만 고려했습니다. 이는 예를 들어 방화벽 설정 문제로 멤버 A에서 멤버 B로 나가는 연결이 끊어졌지만 멤버 B에서 멤버 A로 들어오는 연결은 온전한 경우, 멤버 A의 메시지가 멤버 B에 도달하지 못하고 있음에도 멤버 A가 멤버 B의 상태를 `ONLINE`으로 표시한다는 의미였습니다. 멤버 B는 멤버 A의 상태를 `UNREACHABLE`로 표시했습니다. 이제 그룹 멤버가 활성 연결을 가진 다른 그룹 멤버로부터 ping을 수신하기 시작하면(이 경우 멤버 A가 멤버 B로부터 ping을 수신하면), 이는 연결 문제의 지표로 처리됩니다. 충분한 ping이 수신되면 ping의 수신자(이 경우 멤버 A)가 연결을 종료하여, 두 멤버 모두에서 연결 상태가 일관되도록 합니다. (Bug #25660161, Bug #84796)
- **JSON:** [`JSON_TABLE()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/json-table-functions.html#function_json-table)에 전달된 표현식과 경로가 JSON null을 산출할 때, 이 함수는 요구된 대로 SQL `NULL`을 반환하는 대신 오류를 발생시켰습니다. (Bug #31345503)

- **JSON:** MySQL 5.7 및 MySQL 8.0.17 이전의 MySQL 8.0에서, 서버는 여기 표시된 것처럼 JSON boolean 값을 `IS TRUE`로 직접 테스트할 때 해당 SQL 대응 값으로 변환하려고 시도했습니다:

  ```
  mysql> CREATE TABLE test (id INT, col JSON);

  mysql> INSERT INTO test VALUES (1, '{"val":true}'), (2, '{"val":false}');

  mysql> SELECT id, col, col->"$.val" FROM test WHERE col->"$.val" IS TRUE;
  +------+---------------+--------------+
  | id   | col           | col->"$.val" |
  +------+---------------+--------------+
  |    1 | {"val": true} | true         |
  +------+---------------+--------------+
  ```

  SQL 조건의 모든 조건자가 완전하도록 보장하기 위해 MySQL 8.0.17에서 수행된 작업의 결과로(즉, `WHERE value` 형식의 조건은 `WHERE value <> 0`으로 다시 작성됩니다), 그리고 `WHERE` 또는 `ON` 절의 `NOT IN` 또는 `NOT EXISTS` 조건이 안티조인으로 변환되도록 한 결과로, SQL boolean 컨텍스트에서 JSON 값을 평가하면 JSON 정수 0과의 암시적 비교가 수행됩니다. 이는 앞서 표시된 쿼리가 MySQL 8.0.17 이상에서 다음 결과를 반환한다는 뜻입니다:

  ```
  mysql> SELECT id, col, col->"$.val" FROM test WHERE col->"$.val" IS TRUE;
  +------+----------------+--------------+
  | id   | col            | col->"$.val" |
  +------+----------------+--------------+
  |    1 | {"val": true}  | true         |
  |    2 | {"val": false} | false        |
  +------+----------------+--------------+
  ```

  이러한 경우 서버는 이제 경고도 제공합니다: SQL boolean 컨텍스트에서 JSON 값을 평가하면 JSON integer 0과의 암시적 비교가 수행됩니다. 이것이 원하는 동작이 아니면 JSON_VALUE RETURNING을 사용하여 JSON을 SQL 숫자 타입으로 변환하는 것을 고려하십시오. 따라서 이제 쿼리는 여기 표시된 것처럼 [`JSON_VALUE()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/json-search-functions.html#function_json-value)를 사용하여 다시 작성할 수 있습니다:

  ```
  mysql> SELECT id, col, col->"$.val" FROM test
      ->     WHERE JSON_VALUE(col, "$.val" RETURNING UNSIGNED) IS TRUE;
  +------+---------------+--------------+
  | id   | col           | col->"$.val" |
  +------+---------------+--------------+
  |    1 | {"val": true} | true         |
  +------+---------------+--------------+
  ```

  (Bug #31168181)

- **JSON:** 다중 값 인덱스를 가진 테이블에 대한 `GROUP BY` 쿼리가 서버에서 항상 올바르게 처리되지는 않았습니다. (Bug #31152942)
- [`log_error_services`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_log_error_services)가 persisted된 경우, 일부 경우에는 시작 중 잘못된 시점에 적용될 수 있었습니다. (Bug #31464539)
- 특정 수동 grant 테이블 수정 후 [`SHOW CREATE USER`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/show-create-user.html)가 서버 종료를 유발할 수 있었습니다. (Bug #31462844)

- partial revoke의 일부 인메모리 업데이트가 잘못된 권한을 생성할 수 있었습니다. (Bug #31430086)
- [`log_error_verbosity`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_log_error_verbosity)가 [`SET PERSIST`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/set-variable.html)를 사용하여 설정된 경우, 서버 시작 중에 충분히 이르게 적용되지 않아 `InnoDB` 초기화에 영향을 주지 못했습니다. (Bug #31410674)
- 파서가 생성 컬럼 표현식에서 서브쿼리를 거부하기 전에 잘못하여 어설션을 발생시켰습니다. (Bug #31396191)
- 이 릴리스는 퇴화 hash join(즉, 조인 조건이 없는 hash join)에 대해 다음 두 가지 마이크로 최적화를 수행합니다:

  - 퇴화 hash antijoin 또는 semijoin의 경우, hash 테이블을 빌드할 때 `LIMIT 1`을 추가합니다. 이보다 더 많은 로우가 있어도 결과를 변경할 수 없기 때문입니다.
  - 비어 있지 않은 hash 테이블이 있는 퇴화 hash antijoin의 경우, 외부 쪽 스캔을 피합니다.

  이러한 변경은 함께, hash antijoin으로의 재작성으로 인해 재작성되지 않은 `NOT EXISTS` 쿼리가 Optimizer에 의해 실행되고 “zero rows found”로 대체되던 성능 회귀를 처리합니다. 대신 nested loop가 사용되는 경우를 처리하기 위해, `NOT EXISTS` 내부의 비상관 서브쿼리는 더 이상 antijoin으로 변환되지 않습니다.

  이 수정은 `constant NOT IN (non_correlated_subquery)`를 사용하는 서브쿼리에도 적용됩니다. (Bug #31376809)

- [`-DWITH_EDITLINE=system`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/source-configuration-options.html#option_cmake_with_editline)으로 설정하면 이전 라이브러리 버전에서 컴파일 실패가 발생했습니다. (Bug #31366715)
- 이전 MySQL 배포판에서 번들로 제공되는 `libedit` 라이브러리 업그레이드로 인해, 해당 라이브러리를 사용하는 빌드에서 일부 상황에서 **mysql** 클라이언트의 **CTRL**+**C**(SIGINT)가 적용되려면 뒤이어 Enter를 입력해야 하는 문제가 발생했습니다. (Bug #31360025)
- `AUTO_INCREMENT`와 `DEFAULT` 값 표현식을 모두 사용하여 선언된 컬럼은 허용되지 않는 조합이지만, [`ALTER TABLE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/alter-table.html)이 `AUTO_INCREMENT` 컬럼에 대한 `SET DEFAULT (expr)` 작업에서 오류를 생성하지 못했습니다. (Bug #31331454)
- [`protocol_compression_algorithms`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_protocol_compression_algorithms) 시스템 변수를 빈 문자열로 설정할 수 있었습니다. 더 이상 허용되지 않습니다. (Bug #31326231)

- MySQL 서버 내부에서 사용되는 조회 함수는 인수가 모호할 때 정수 -1을 반환합니다. 이 값이 이후 계산에서 인수로 사용되기 전에 부호 없는 값으로 변환될 때 정의되지 않은 동작이 발생했습니다. 이제 함수가 -1을 반환하면 이를 오류로 처리하며, 해당 값은 더 이상 사용되지 않습니다. (Bug #31326120)
- 특정 경우에 부호 있는 값의 부정이 정의되지 않은 동작으로 이어졌습니다. 이 문제가 발생하지 않도록, 이제 부정할 값은 부호 없는 값으로 처리됩니다. (Bug #31325602)
- [`WEIGHT_STRING()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/string-functions.html#function_weight-string) 함수가 정수 인수에 대해 항상 올바른 결과를 반환하지는 않았습니다. (Bug #31321257)

  참조: 이 문제는 다음 버그의 회귀입니다: Bug #30776132.
- [`CONCAT('')`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/string-functions.html#function_concat) 또는 [`CONCAT_WS('')`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/string-functions.html#function_concat-ws)를 변수에 할당하면 변수가 빈 문자열이 아니라 `NULL`로 설정되었습니다. (Bug #31320716, Bug #99485, Bug #31413167, Bug #99722)
- 일부 상황에서 권한 제한이 무시될 수 있었던 문제를 수정했습니다. (Bug #31306814, Bug #31315692)

- 로우를 잠그기 위한 특정 [`SELECT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/select.html) 문 권한이 제대로 검사되지 않아 다른 사용자를 잘못 차단할 수 있었습니다. (Bug #31293065)
- filesort를 수행할 때, 정렬되는 서브셀렉트가 NULL 가능이 아니더라도 내부 함수가 실패 시 때때로 `NULL`을 반환할 수 있었습니다. (Bug #31281602)
- 바이너리 로그에 대한 문 재작성이 Windows에서 비효율적이었습니다. (Bug #31260698)

  참조: 이 문제는 다음 버그의 회귀입니다: Bug #30654405.
- 메모리에서 익명 사용자를 표현하는 방식의 불일치로 인해 권한 부여 작업을 수행하는 동안 문제가 발생할 수 있었습니다. (Bug #31246179)
- 관리 연결 인터페이스가 활성화된 경우, 레이스 컨디션으로 인해 주 연결 인터페이스에서 Unix 소켓 파일 연결을 수락하는 데 문제가 발생할 수 있었습니다. (Bug #31241872)
- 역할이 `WITH ADMIN OPTION`과 함께 부여된 경우, 피부여자는 해당 역할을 활성화한 후에만 역할을 관리할 수 있었습니다. (Bug #31237368)
- `default_roles` 또는 `role_edges` 시스템 테이블의 유효하지 않은 로우로 인해 서버 오동작이 발생할 수 있었습니다. (Bug #31217385)
- 런타임의 컴포넌트 초기화 해제 실패로 인해 종료 시 오류 로그에 메시지가 반복해서 기록될 수 있었습니다. (Bug #31217037)
- 익명 사용자에게 역할을 부여하는 것에 대한 금지가 불완전하게 적용되었습니다. (Bug #31215017)
- 권한 상승 문제가 수정되었습니다. (Bug #31210226)

- `keyring_hashicorp` keyring 플러그인은 해당 설정 파라미터 값에 대해 충분한 유효성 검사를 수행하지 않았습니다. (Bug #31205363)
- `keyring_hashicorp` keyring 플러그인은 바이너리 로그 암호화([`binlog_encryption`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/replication-options-binary-log.html#sysvar_binlog_encryption) 시스템 변수를 설정하여)를 활성화하는 것을 허용하지 않았습니다. (Bug #31204841)
- `keyring_hashicorp` keyring 플러그인은 `audit_log` 플러그인이 암호화 비밀번호를 설정하는 것을 허용하지 않았습니다. (Bug #31197670)
- [`REGEXP_SUBSTR()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/regexp.html#function_regexp-substr)를 `ORDER BY` 절과 함께 사용하는 일부 쿼리는 서버에서 올바르게 처리되지 않았습니다. (Bug #31184858)
- 포인터 산술이 `nullptr`에 적용되던 일부 사례가 수정되었습니다. (Bug #31172750)
- 사용 가능한 파일 디스크립터가 모두 소진된 경우, [`mysql_real_connect()`](https://docs.oracle.com/cd/E17952_01/c-api-8.0-en/mysql-real-connect.html)는 클라이언트를 종료하게 했습니다. (Bug #31151052)
- **killall** 명령을 사용하여 **mysqld** 종료를 시작하면 종료 시작을 나타내는 메시지가 로그에 기록되지 않았습니다. 이 문제가 수정되었습니다. (Bug #31121907)

- 잘못된 호스트로 [`mysql_real_connect_nonblocking()`](https://docs.oracle.com/cd/E17952_01/c-api-8.0-en/mysql-real-connect-nonblocking.html)을 호출하면 [`mysql_close()`](https://docs.oracle.com/cd/E17952_01/c-api-8.0-en/mysql-close.html) 호출 시 클라이언트가 종료될 수 있었습니다. (Bug #31104389, Bug #99112)
- Debian 패키지의 경우 설치 실패를 유발할 수 있던 Python 2 의존성이 제거되었습니다. (Bug #31099324)
- `lf_hash_insert()`의 잠재적 메모리 누수가 수정되었습니다. (Bug #31090258, Bug #99078)
- LDAP SASL 인증 플러그인 내에서 `sasl_client_done()`을 여러 번 호출하면 일부 경우 정의되지 않은 동작이 발생할 수 있었습니다. (Bug #31088206)
- thread pool 플러그인이 활성화된 상태에서 높은 동시성 조건은 클라이언트 컨텍스트 손실을 유발하여 서버 종료로 이어질 수 있었습니다. (Bug #31085322)
- [`mysql_use_result()`](https://docs.oracle.com/cd/E17952_01/c-api-8.0-en/mysql-use-result.html)를 사용하여 처리된 결과 집합의 경우, [`mysql_fetch_row_nonblocking()`](https://docs.oracle.com/cd/E17952_01/c-api-8.0-en/mysql-fetch-row-nonblocking.html)이 로우 수를 증가시키지 않았으므로 모든 로우를 가져온 후 [`mysql_num_rows()`](https://docs.oracle.com/cd/E17952_01/c-api-8.0-en/mysql-num-rows.html)가 잘못된 로우 수를 반환했습니다. (Bug #31082201, Bug #99073)
- 실제로 평가된 적이 없던 `EXISTS()`에 대한 불필요한 최적화가 제거되었습니다. (Bug #31069510)

- [`--skip-grant-tables`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-options.html#option_mysqld_skip-grant-tables) 옵션으로 시작된 서버에서 [`partial_revokes`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_partial_revokes) 시스템 변수를 활성화하면 서버가 종료되었습니다. (Bug #31066069, Bug #31202963)
- 외부 참조가 있는 재귀 common table expression을 사용한 쿼리가 잘못된 결과를 반환할 수 있었습니다. (Bug #31066001, Bug #99025)
- 최소 문자 길이가 1바이트보다 큰 멀티바이트 캐릭터셋에 대해 파서가 실패할 수 있었습니다. (Bug #31063981)
- 일부 경우에 [`LEAST()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/comparison-operators.html#function_least) 함수가 NULL이 허용되지 않는 입력에 대해 `NULL`을 반환할 수 있었습니다. (Bug #31054254)

  참조: 이 문제는 다음 버그의 회귀입니다: Bug #25123839.
- `MYSQL_OPT_CONNECT_TIMEOUT` 옵션이 설정된 경우 [`mysql_real_connect_nonblocking()`](https://docs.oracle.com/cd/E17952_01/c-api-8.0-en/mysql-real-connect-nonblocking.html)이 차단되었습니다. (Bug #31049390, Bug #98980)
- null 로우를 반환하기 위한 [`mysql_fetch_row_nonblocking()`](https://docs.oracle.com/cd/E17952_01/c-api-8.0-en/mysql-fetch-row-nonblocking.html) C API 함수의 마지막 호출이 오류를 설정하지 않아야 할 때 오류를 설정하고 있었습니다. (Bug #31048553, Bug #98947)

- Windows에서 기본 연결 유형은 named pipe를 사용합니다. TCP/SSL 연결을 대상으로 하는 nonblocking C API는 이를 고려하지 않아 클라이언트가 종료되도록 했습니다. 이제 문제를 나타내는 오류 메시지를 생성합니다. (Bug #31047717)
- 사용자가 존재하지 않아 인증에 실패한 X Plugin 연결이 전역 [`audit_log_filter_id`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/audit-log-reference.html#sysvar_audit_log_filter_id) 시스템 변수를 수정했습니다. (Bug #31025461)
- [`LOAD DATA`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/load-data.html)는 입력 파일 로우를 파싱할 때 숨겨진 생성 컬럼을 무시하지 않았습니다. (Bug #31024266, Bug #98925)
- 메타데이터 잠금 하위 시스템에서 pinbox 고갈이 오해의 소지가 있는 오류 메시지를 생성할 수 있었습니다. (Bug #31019269, Bug #98911)
- [`CREATE TABLE... SELECT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/create-table-select.html)는 functional index가 포함된 경우 실패했습니다. (Bug #31017765, Bug #98896)
- X Protocol 연결의 경우, 스레드 수가 증가함에 따라 발생하는 경미한 성능 저하를 제거하기 위해 전역 세션 mutex 검사가 개선되었습니다. (Bug #31000043)
- 특정 경우에는 여러 하위 쿼리를 포함하는 쿼리를 실행하면 서버의 계획되지 않은 종료로 이어질 수 있었습니다. (Bug #30975826)

- [`SHOW CREATE TRIGGER`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/show-create-trigger.html)는 [`FLUSH TABLES WITH READ LOCK`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/flush.html#flush-tables-with-read-lock)이 적용 중이면 실패했습니다. (Bug #30964944)
- `INFORMATION_SCHEMA` 뷰의 기반이 되는 특정 데이터 딕셔너리 테이블에 대해 과도한 접근 검사가 수행되어 [`SHOW COLUMNS`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/show-columns.html) 성능이 느려졌습니다. 성능을 개선하기 위해 이러한 검사가 줄어들었습니다.

  또한 `INFORMATION_SCHEMA` 쿼리로 구현된 여러 [`SHOW`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/show.html) 문은 [`optimizer_switch`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_optimizer_switch) 시스템 변수에 대해 [`derived_merge`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/switchable-optimizations.html#optflag_derived-merge) 플래그를 활성화하면 이점이 있는 것으로 확인되었습니다. 이제 이러한 쿼리는 플래그 세션 값과 관계없이 더 나은 성능을 위해 내부적으로 해당 플래그를 일시적으로 활성화합니다. 영향을 받는 쿼리는 다음과 같습니다:

  ```
  SHOW SCHEMAS
  SHOW TABLES
  SHOW TABLE STATUS
  SHOW COLUMNS
  SHOW KEYS
  SHOW EVENTS
  SHOW TRIGGERS
  SHOW PROCEDURE STATUS
  SHOW FUNCTION STATUS
  SHOW CHARACTER SET
  SHOW COLLATION
  ```

  (Bug #30962261, Bug #98750, Bug #30921214)

- case-sensitive 콜레이션을 사용할 때와 case-insensitive 콜레이션을 사용할 때 별도로 실행된, 그 외에는 동일한 두 쿼리는 각각 한 로우와 두 로우를 반환했습니다. 동일한 두 프레디케이트가 `AND`를 사용하여 단일 쿼리로 결합되었을 때는 하나의 로우만 반환되어야 했지만 두 로우가 반환되었습니다. (Bug #30961924)
- 표시 폭이 255보다 큰 [`SET`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/set.html) 컬럼에 대한 [`ALTER TABLE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/alter-table.html)은 그 외에는 가능하더라도 in-place로 수행되지 않았습니다. (Bug #30943642, Bug #98523)
- 서버는 yottabyte 단위의 숫자가 출력하기에 너무 큰지 확인할 때, double로 표현할 수 없는 `ULLONG_MAX`와 값을 double로 비교했습니다. 이로 인해 `ULLONG_MAX` yottabyte 바로 위의 double 값이 `0Y`로 출력되었으며, 이 잘못된 변환은 Clang 10에서 보고되었습니다. (Bug #30927590)
- [`CREATE RESOURCE GROUP`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/create-resource-group.html)와 같은 리소스 그룹 SQL 문은 X Protocol을 사용하는 연결에서 작동하지 않았습니다. (Bug #30900411)
- [`SHOW GRANTS`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/show-grants.html)는 함수 권한을 프로시저 권한으로 표시할 수 있었습니다. (Bug #30896461, Bug #98570)

- 여러 클라이언트가 동시에 연결될 때 `audit_log` 플러그인이 연결 이벤트를 잘못 처리했습니다. (Bug #30893593)
- `LOCK_ORDER` 도구가 빈 의존성 그래프에 대해 문법 오류를 보고했습니다. 이제 빈 그래프가 허용됩니다.

  `LOCK_ORDER` 도구는 스레드 목록 유지 관리를 잘못 처리하여 예상치 못한 동작을 보일 수 있었습니다. (Bug #30889192)
- MySQL 5.7에서 업그레이드할 때 `root`에 [`REPLICATION_APPLIER`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/privileges-provided.html#priv_replication-applier) 권한이 부여되지 않았습니다. (Bug #30783149)
- [`gen_range()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/data-masking-component-functions.html#function_gen-range) 사용자 정의 함수가 인수를 잘못 처리하여 서버 종료를 일으킬 수 있었습니다. (Bug #30763294)
- [`UPDATE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/update.html) 처리 중 내부 인메모리 테이블을 `InnoDB`로 변환하면 키 길이 오류가 발생할 수 있었습니다. (Bug #30674616)
- (항상 전역인) 동적 권한을 프로시저 또는 함수 수준에서 부여하려는 시도가 오류를 발생시키지 않았습니다. (Bug #30628160)
- 테이블 값 생성자가 `LIMIT` 절을 무시했습니다. 이제 이 절이 고려됩니다. 예를 들어 `VALUES ROW(1), ROW(2), ROW(3) LIMIT 2`는 1과 2를 출력합니다. (Bug #30602659)

- `*`(단일 별표 문자)라는 이름의 컬럼을 정의할 수 있지만, ``SELECT `*` ``가 `SELECT *`와 동일하게 처리되어 쿼리에서 이 컬럼만 선택할 수 없었습니다. 다시 말해, 별표 문자가 백틱으로 둘러싸여 있더라도 모든 테이블 컬럼 목록으로 확장되었습니다. (Bug #30528450)
- [`FROM_DAYS()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/date-and-time-functions.html#function_from-days) 함수가 범위를 벗어난 결과(연도 > 9999)를 생성할 수 있었습니다. (Bug #30455845, Bug #97340)
- 디버그 빌드의 경우, `mysql.func` 테이블을 `MyISAM`으로 변경하면(어떤 경우에도 권장되지 않는 작업입니다) 서버가 종료되었습니다. 이제 이 작업은 금지됩니다. (Bug #30248138, Bug #96692)
- `INFORMATION_SCHEMA` [`KEY_COLUMN_USAGE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-key-column-usage-table.html) 및 [`TABLE_CONSTRAINTS`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-table-constraints-table.html) 뷰에 대한 쿼리는 해당 정의에서 [`UNION`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/union.html)을 사용하기 때문에 느릴 수 있었습니다. Optimizer가 인덱스를 더 잘 사용할 수 있도록 [`UNION`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/union.html)을 `LATERAL` 테이블로 이동하도록 이 뷰들이 다시 작성되었습니다. (Bug #30216864, Bug #30766181, Bug #98238)

- 특정 경우에 `LIMIT` 절로 인해 옵티마이저가 테이블에서 읽어야 하는 로우가 0개라고 잘못 추정했습니다. (Bug #30204811)

  참조: 이 문제는 다음 버그의 회귀입니다: Bug #29487181.
- 내부 패킷 길이 함수가 잘못된 정수 타입의 값을 반환했습니다. (Bug #30139031)
- **mysqldump**가 [`INSERT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/insert.html) 문의 길이를 계산할 때 [`VARBINARY`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/binary-varbinary.html) 문자열에 사용되는 `_binary` 캐릭터셋 introducer를 고려하지 않았습니다. (Bug #29998457, Bug #96053)
- prefix 키로 정의된 파티셔닝된 테이블을 업그레이드하는 동안 오류 로그에 출력된 메시지가 충분한 세부 정보를 제공하지 않았습니다. 이제 스키마, 테이블, 컬럼 및 prefix 길이를 나타내는 자세한 경고가 출력됩니다. (Bug #29942014)

  참조: 다음도 참조하십시오: Bug #31100205.
- [`mysql_store_result()`](https://docs.oracle.com/cd/E17952_01/c-api-8.0-en/mysql-store-result.html)가 유효하지 않은 데이터 패킷을 감지하지 못할 수 있었습니다. (Bug #29921423)
- 외래 키 관계에서 자식 테이블을 생성하는 과정에서 엔진 대체가 발생하면 assertion이 발생했습니다. (Bug #29899151, Bug #95743)
- **mysqltest** 및 **mysql-test-run.pl**은 더 이상 `--sleep` 명령줄 옵션을 지원하지 않습니다. **mysqltest**는 더 이상 `real_sleep` 명령을 지원하지 않습니다. (Bug #29770237)

- 서버는 허용되는 최대 길이(255자)보다 긴 이름을 가진 호스트에 대한 연결을 허용했습니다. (Bug #29704941)
- 첫 번째 테이블의 키를 업데이트하는 다중 테이블 [`UPDATE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/update.html)에서 임시 테이블 전략이 사용된 경우, 중복 항목이 임시 테이블에 기록될 수 있었고, 이어서 `Can't find record` 오류가 발생할 수 있었습니다. (Bug #28716103)
- 서버가 쿼리를 최적화할 때 `GROUP BY`가 있는 서브쿼리가 외부 select에서 사용되는 일부 경우에도, 이 서브쿼리를 때때로 잘못 제거했습니다. 이는 해당 서브쿼리가 집계 함수도 사용하는 경우에 발생할 수 있었습니다. (Bug #28240054)
- [`NAME_CONST()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/miscellaneous-functions.html#function_name-const) 함수의 강제 변환 가능성이 잘못 평가되었습니다. (Bug #26319675)
- 스토리지 엔진에서 로우를 읽을 때, “더 이상 레코드 없음” 이외의 오류가 무시될 수 있었으며, 이로 인해 이후 문제가 발생할 수 있었습니다. (Bug #20162055)
- 다중 테이블 업데이트가 임시 테이블을 사용하는 경우, 이러한 사용이 해당 작업이 수행된 [`UPDATE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/update.html) 문의 성능에 영향을 줄 수 있었음에도 [`EXPLAIN FORMAT=TREE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/explain.html) 출력에는 표시되지 않았습니다. (Bug #17978975)

- 중복 제거를 위한 filesort를 수행할 때, 예를 들어 `SELECT DISTINCT`를 실행할 때는 이후에 `ORDER BY`를 충족하기 위해 다른 정렬을 수행해야 할 수 있습니다. 이러한 `ORDER BY`가 조인 전체가 아니라 조인의 첫 번째 테이블로 푸시다운된 경우, 이 최종 정렬이 실제로 수행되지 않았습니다. (Bug #99687, Bug #31397840)
- MySQL 8.0.20에서 수행된 리팩터링 작업으로 인해 nullable이 아닌 컬럼의 `GROUP BY`에 대한 단일 로우 버퍼링이 올바르게 작동하지 않았으며, 이러한 컬럼이 outer join의 내부 테이블일 수 있고 따라서 복사해야 하는 `NULL` 플래그를 가질 수 있다는 점을 고려하지 않았습니다. 임시 테이블이 없는 `GROUP BY`에서는 이로 인해 `NULL` 플래그가 이전 출력 로우가 아니라 다음 출력 로우에서 오게 되었고, 반환된 데이터가 일관되지 않게 되었습니다. (Bug #99398, Bug #31252625)

  참조: 이 문제는 다음의 회귀입니다: Bug #30460528.
- [`DECIMAL`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/fixed-point-types.html) 또는 [`FLOAT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/floating-point-types.html) 타입의 상수가 왼쪽 피연산자이고 정수 컬럼 값이 오른쪽 피연산자인 경우에 대한 상수 폴딩 코드의 논리적 오류로 인해 잘못된 결과가 생성되었습니다. (Bug #99145, Bug #31110614)

- 조건자가 `0`과 `-0`을 비교하고 이들 중 적어도 하나가 부동소수점 값인 쿼리가 잘못된 결과를 반환했습니다. (Bug #99122, Bug #31102789)
- 슬라이스를 사용하지 않고 롤업을 다시 구현했습니다. 이를 통해 다음 알려진 문제가 수정되었습니다:

  - `GROUP BY... WITH ROLLUP`의 반복 컬럼이 잘못된 결과를 산출했습니다. 즉, `GROUP BY a, b, a WITH ROLLUP` 형식의 `GROUP BY`가 결과의 일부 컬럼 이름에 대해 잘못해서 `NULL`을 생성했습니다.
  - 결과를 출력하는 데 임시 테이블이 필요하지 않은 `GROUP BY... WITH ROLLUP`도 출력에서 예상되는 컬럼 이름 중 적어도 하나 대신 잘못된 `NULL`을 생성했습니다.

  (Bug #98768, Bug #99141, Bug #26227613, Bug #29134467, Bug #30967158, Bug #30969045, Bug #31110494)

- `SELECT DISTINCT(`[`HEX(`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/string-functions.html#function_hex)[`WEIGHT_STRING(varchar_column)))`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/string-functions.html#function_weight-string)가 잘린 결과를 반환했습니다. (Bug #98592, Bug #30898753)

- [`MAX()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/aggregate-functions.html#function_max), [`MIN()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/aggregate-functions.html#function_min), 또는 둘 모두를 `GROUP BY` 절과 함께 사용하는 쿼리의 오류 처리 문제로 인해, 이러한 쿼리는 오류로 인해 즉시 종료되어야 하는 경우에도 가능한 모든 반복을 거칠 때까지 실행을 계속했습니다. (Bug #98242, Bug #30769515)
- [`LEAST()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/comparison-operators.html#function_least), [`GREATEST()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/comparison-operators.html#function_greatest) 및 기타 함수와 [`UNION`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/union.html)에 대한 타입 전파 코드를 리팩터링한 후, [`ENUM`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/enum.html)과 같은 데이터 타입에 대한 결과 타입 조정이 계산된 정수 데이터 타입도 signed 값과 unsigned 값을 모두 수용할 수 없는 타입으로 대체했습니다. (Bug #95148, Bug #29698617)

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