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

## DBA를 위한 핵심 내용

MySQL 8.0.20은 hash join 확대, doublewrite 구조 변경, binlog 트랜잭션 압축, 권한 세분화가 핵심입니다. 성능 개선 폭이 큰 반면 정렬 메모리·공간 인덱스·복제 채널 설정에서 행동 변화가 있으므로, 웹 검색 기준 대규모 외부 회귀 이슈는 확인되지 않았지만 부하 테스트 후 적용하는 것이 안전합니다.

1. nested block loop가 사용되던 더 많은 경우에 hash join이 사용됩니다. 조인 성능은 개선될 수 있으나 메모리 사용과 실행 계획이 바뀔 수 있으므로 대형 조인·`NOT EXISTS`·세미조인 쿼리는 `EXPLAIN ANALYZE`로 비교해야 합니다.
2. InnoDB doublewrite 버퍼가 시스템 tablespace 밖의 doublewrite 파일로 이동되었습니다. 쓰기 지연과 처리량 개선이 기대되지만, `innodb_doublewrite_dir`, 파일 수, 배치 크기 설정과 파일시스템 배치를 운영 표준에 맞게 검토해야 합니다.
3. `JSON`/`GEOMETRY` 컬럼 정렬 시 packed addon을 사용하도록 바뀌어 성능이 좋아질 수 있지만, 매우 큰 값과 작은 `sort_buffer_size` 조합에서는 OOM이 발생할 수 있습니다. 대형 JSON 정렬 쿼리가 있는 시스템은 정렬 버퍼와 임시 공간을 재평가하십시오.
4. 바이너리 로그 트랜잭션 압축이 추가되었습니다. `binlog_transaction_compression=ON`은 스토리지와 네트워크를 절약하지만 CPU 비용과 복제 지연 영향을 함께 측정해야 하며, 압축 레벨은 워크로드별로 조정해야 합니다.
5. `SHOW_ROUTINE` 권한이 추가되어 루틴 백업용 계정에 전역 `SELECT`를 주지 않아도 됩니다. 업그레이드 시 기존 전역 `SELECT` 보유 계정에는 자동 부여될 수 있으므로 최소 권한 모델로 재정리하십시오.
6. 공간 인덱스가 있는 테이블은 업그레이드 후 인덱스 재생성이 필요한 호환되지 않는 수정이 포함되었습니다. 또한 `VALUES()` in `ON DUPLICATE KEY UPDATE`, `SELECT ... INTO` 위치, `JSON_TABLE()` 절 순서 등 사용 중단 문법을 애플리케이션 SQL에서 제거해야 합니다.

## 계정 관리 관련 사항

- 이전에는 사용자가 자신이 정의하지 않은 루틴의 정의에 접근하려면 매우 광범위한 전역 [`SELECT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/privileges-provided.html#priv_select) 권한이 필요했습니다. 새로운 [`SHOW_ROUTINE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/privileges-provided.html#priv_show-routine) 권한은 루틴 정의에 대한 접근을 허용하는 더 제한된 범위의 권한으로 대신 부여할 수 있습니다. (즉, 관리자는 달리 전역 [`SELECT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/privileges-provided.html#priv_select)가 필요하지 않은 사용자에게서 이를 회수하고, 대신 [`SHOW_ROUTINE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/privileges-provided.html#priv_show-routine)을 부여할 수 있습니다.) 이를 통해 계정은 광범위한 권한을 요구하지 않고도 저장 루틴을 백업할 수 있습니다.

  [`SHOW_ROUTINE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/privileges-provided.html#priv_show-routine)은 다음에 대한 접근을 제공합니다:

  - [`INFORMATION_SCHEMA.ROUTINES`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-routines-table.html) 테이블의 내용.
  - [`SHOW CREATE FUNCTION`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/show-create-function.html) 및 [`SHOW CREATE PROCEDURE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/show-create-procedure.html) 문.
  - [`SHOW FUNCTION CODE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/show-function-code.html) 및 [`SHOW PROCEDURE CODE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/show-procedure-code.html) 문.
  - [`SHOW FUNCTION STATUS`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/show-function-status.html) 및 [`SHOW PROCEDURE STATUS`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/show-procedure-status.html) 문.

  이전 버전의 MySQL에서 업그레이드하는 경우, 이미 [`SHOW_ROUTINE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/privileges-provided.html#priv_show-routine)을 가진 사용자가 없는 경우 전역 [`SELECT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/privileges-provided.html#priv_select) 권한을 가진 모든 사용자에게 [`SHOW_ROUTINE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/privileges-provided.html#priv_show-routine)이 부여됩니다. (WL #9049)

## 컴파일 관련 사항

- **Solaris:** 이제 Solaris에서 MySQL을 컴파일하는 데 Clang 및 GCC를 사용할 수 있지만, 둘 다 실험적이며 현재 프로덕션 코드에는 사용할 수 없습니다. (Bug #30562248)
- EL7 및 EL8에서 **CMake** 설정은 GCC 8보다 GCC 9를 먼저 찾도록 조정되었습니다. `libmysqlclient`가 MySQL 배포판과 함께 제공되기 때문에, 해당 플랫폼에서 `libmysqlclient`를 대상으로 빌드된 클라이언트 애플리케이션이 영향을 받으며 다시 컴파일해야 할 수 있습니다. (Bug #30722756)
- Windows에서 Visual Studio에 대한 **CMake** 컴파일러 버전 검사는 Visual Studio 2019가 현재 지원되는 버전임을 나타내도록 업데이트되었습니다. (버전 검사는 [`-DFORCE_UNSUPPORTED_COMPILER=1`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/source-configuration-options.html#option_cmake_force_unsupported_compiler)을 사용하여 **CMake**를 실행하면 우회할 수 있습니다.) (Bug #30688403)

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

- **JSON:** 이전에는 [`JSON_TABLE()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/json-table-functions.html#function_json-table) 함수를 호출할 때 `ON EMPTY` 및 `ON ERROR` 절을 어느 순서로든 지정할 수 있었습니다. 이는 SQL 표준에 반하며, SQL 표준에서는 `ON EMPTY`가 지정되는 경우 항상 모든 `ON ERROR` 절보다 앞에 와야 한다고 규정합니다. 이러한 이유로, 이제 `ON ERROR`를 `ON EMPTY`보다 앞에 지정하는 것은 사용 중단되며, 그렇게 하려고 하면 서버가 경고를 발생시킵니다. 비표준 문법에 대한 지원은 향후 MySQL 버전에서 제거될 예정입니다. (WL #13512)
- [`max_length_for_sort_data`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_max_length_for_sort_data) 시스템 변수는 이를 더 이상 필요하지 않고 효과가 없게 만드는 optimizer 변경으로 인해 이제 사용 중단됩니다. (WL #13600)

  References: See also: Bug #30473261.
- [`INSERT... ON DUPLICATE KEY UPDATE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/insert-on-duplicate.html) 문에서 새 로우 값을 액세스하기 위해 [`VALUES()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/miscellaneous-functions.html#function_values)를 사용하는 것은 이제 사용 중단되며, 향후 MySQL 릴리스에서 제거될 수 있습니다. 대신 MySQL 8.0.19 이상에서 구현된 것처럼 새 로우와 해당 컬럼에 대한 별칭을 사용해야 합니다.

  예를 들어, 여기에 표시된 문은 새 로우 값을 액세스하기 위해 [`VALUES()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/miscellaneous-functions.html#function_values)를 사용합니다:

  ```
  INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6)
    ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);
  ```

  이제부터는 대신 새 로우에 대한 별칭을 사용하는 다음과 유사한 문을 사용해야 합니다:

  ```
  INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6) AS new
    ON DUPLICATE KEY UPDATE c = new.a+new.b;
  ```

  또는 여기에 표시된 것처럼 새 로우와 각 컬럼 모두에 대한 별칭을 사용할 수 있습니다:

  ```
  INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6) AS new(m,n,p)
    ON DUPLICATE KEY UPDATE c = m+n;
  ```

  자세한 정보와 예시는 [INSERT... ON DUPLICATE KEY UPDATE Statement](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/insert-on-duplicate.html)을 참조하십시오. (WL #13325)

## JSON 관련 사항

- MySQL에 포함된 `rapidjson` 라이브러리가 2020년 1월 16일 GitHub 스냅샷으로 업그레이드되었습니다. Mac OS X에서 해당 스냅샷으로 빌드할 때 발생하던 컴파일러 오류에 대한 수정이 추가되었습니다. (Bug #30898701)

## 로깅 관련 사항

- 서버에 `SIGHUP` 시그널을 보내도 더 이상 서버가 오류 로그에 상태 보고서를 기록하지 않습니다. `SIGHUP`에 대한 응답으로 서버가 수행하는 다른 동작은 계속 수행됩니다. [Unix Signal Handling in MySQL](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/unix-signal-response.html)을 참조하십시오.

  마찬가지로, **mysqladmin debug**도 더 이상 상태 보고서가 기록되도록 하지 않습니다. (Bug #30578923)
- `log_sink_json` JSON 형식 오류 로그 싱크는 이제 로그 메시지에 `ts`(타임스탬프)를 포함합니다. 이 값은 epoch(`'1970-01-01 00:00:00'` UTC) 이후의 밀리초를 나타내는 정수입니다. [Error Log Output Format](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/error-log-format.html)을 참조하십시오. (WL #13786)

## Optimizer 관련 사항

- 이제 nested block loop가 사용될 모든 경우에 해시 조인이 사용됩니다. 이는 다음 유형의 쿼리에 해시 조인을 사용할 수 있음을 의미합니다:

  - Inner non-equi-joins
  - Semijoins
  - Antijoins
  - Left outer joins
  - Right outer joins

  이는 MySQL 8.0.18에서 수행된 작업을 기반으로 하며, 적어도 하나의 equi-join 조건을 가진 쿼리에만 해시 조인을 사용할 수 있었던 구현상의 제한을 제거합니다. 또한 이제 내부 조인과 외부 조인(semijoin 및 antijoin 포함) 모두 batched key access (BKA)를 사용할 수 있으며, 이는 조인 버퍼 메모리를 점진적으로 할당하므로 개별 쿼리가 실제로 해결에 필요하지 않은 많은 양의 리소스를 사용할 필요가 없도록 합니다. 자세한 내용은 [Batched Key Access Joins](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/bnl-bka-optimization.html#bka-optimization)를 참조하십시오.

  이 수정은 이전 MySQL 버전에서 사용되던 실행기를 iterator executor로 대체하는 작업을 완료합니다. 여기에는 semijoin으로 변환되지 않은 `IN` 쿼리에 대해 `WHERE value IN (SELECT column FROM table WHERE condition)` 형식의 쿼리를 관리하던 기존 인덱스 서브쿼리 엔진의 대체와, 기존 실행기의 내부 구현에 의존하던 동일한 형식으로 materialize된 쿼리의 대체가 포함됩니다.

  자세한 내용과 예시는 [Hash Join Optimization](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/hash-joins.html)을 참조하십시오. (Bug #30528604, Bug #30473261, Bug #30912972, WL #13377, WL #13476)
- 이 릴리스는 `FORCE INDEX` 및 `IGNORE INDEX`와 같은 SQL 키워드를 사용하는 기존 인덱스 힌트와 매우 유사하게 동작하는 여러 새로운 인덱스 수준 Optimizer 힌트를 구현합니다. 이 힌트는 동등한 인덱스 힌트를 대체하기 위한 것이며, 해당 인덱스 힌트는 향후 MySQL 릴리스에서 사용 중단되고 결국 제거될 예정입니다. 새 힌트는 각각에 대한 간략한 설명과 함께 여기에 나열되어 있습니다:

  - [`JOIN_INDEX`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/optimizer-hints.html#optimizer-hints-index-level): `ref`, `range`, [`index_merge`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/switchable-optimizations.html#optflag_index-merge) 등과 같은 사용 가능한 모든 접근 방식에 대해 MySQL이 지정된 인덱스 하나 또는 여러 인덱스를 사용하도록 강제합니다. 이는 `FORCE INDEX FOR JOIN` 인덱스 힌트와 동등합니다.

    [`NO_JOIN_INDEX`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/optimizer-hints.html#optimizer-hints-index-level): 서버가 모든 접근 방식에 대해 지정된 인덱스 하나 또는 여러 인덱스를 무시하도록 합니다. 동등한 인덱스 힌트는 `IGNORE INDEX FOR JOIN`입니다.
  - [`GROUP_INDEX`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/optimizer-hints.html#optimizer-hints-index-level): 서버가 `GROUP BY` 작업에 대한 인덱스 스캔에 지정된 인덱스 하나 또는 여러 인덱스를 사용하도록 합니다. `FORCE INDEX FOR GROUP BY`와 동등합니다.

    [`NO_GROUP_INDEX`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/optimizer-hints.html#optimizer-hints-index-level): `GROUP BY` 작업에 대한 인덱스 스캔에서 지정된 인덱스 또는 인덱스들을 무시하도록 MySQL에 강제합니다. 이에 해당하는 인덱스 힌트는 `IGNORE INDEX FOR GROUP BY`입니다.
  - [`ORDER_INDEX`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/optimizer-hints.html#optimizer-hints-index-level): 로우를 정렬하는 데 지정된 인덱스 또는 인덱스들을 사용하도록 MySQL에 지시합니다. 이는 `FORCE INDEX FOR ORDER BY`와 동일합니다.

    [`NO_ORDER_INDEX`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/optimizer-hints.html#optimizer-hints-index-level): 서버가 로우 정렬을 수행하는 데 지정된 인덱스 또는 인덱스들을 사용하지 못하게 합니다. `IGNORE INDEX FOR ORDER BY`와 동일합니다.
  - [`INDEX`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/optimizer-hints.html#optimizer-hints-index-level): `JOIN_INDEX`, `GROUP_INDEX`, `ORDER_INDEX`의 조합으로 동작하여, 모든 범위에서 지정된 인덱스 또는 인덱스들을 사용하도록 서버에 강제합니다. `FORCE INDEX`와 동일합니다.

    [`NO_INDEX`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/optimizer-hints.html#optimizer-hints-index-level): `NO_JOIN_INDEX`, `NO_GROUP_INDEX`, `NO_ORDER_INDEX`의 조합으로 동작합니다. 즉, 모든 범위에서 지정된 인덱스 또는 인덱스들을 무시하도록 MySQL에 강제합니다. 이는 인덱스 힌트 `IGNORE INDEX`와 동일합니다.

  지정된 컬럼과 인덱스를 가진 테이블에서 인덱스 힌트를 사용하는 다음 쿼리를 고려하십시오:

  ```
  SELECT a,b FROM t1 USE INDEX FOR ORDER BY (i_ab) ORDER BY a;
  ```

  이 릴리스에 도입된 인덱스 수준 optimizer hint를 사용하면, 이 쿼리는 다음과 같이 다시 작성할 수 있습니다:

  ```
  SELECT /*+ ORDER_INDEX(t1 i_ab) */ a,b FROM t1 ORDER BY a;
  ```

  새 인덱스 수준 optimizer hint는 [`SELECT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/select.html), [`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) 문과 함께 사용할 수 있습니다. (이는 `FORCE INDEX` 또는 `IGNORE INDEX`를 사용하는 인덱스 힌트와 달리, 해당 인덱스 힌트는 `SELECT` 및 `UPDATE`에서만 사용할 수 있습니다.) 따라서 다음과 같은 문이 가능합니다:

  ```
  UPDATE /*+ INDEX(t1 i_ab) */ t1 SET d = 1
      WHERE a = 1 AND b = 2 AND c = 3;

  DELETE /*+ INDEX(t1 i_a,i_c) */ FROM t1
      WHERE a = 1 AND b = 2 AND c = 3;
  ```

    동일한 주석 내에 여러 힌트를 지정할 수 있습니다. 예를 들면 다음과 같습니다:

  ```
  DELETE /*+ INDEX(t1 i_a) JOIN_INDEX(t1 i_c) */
      FROM t1 WHERE a = 1 AND b = 2 AND c = 3;
  ```

  인덱스 수준 optimizer 힌트는 다른 optimizer 힌트와 동시에 사용할 수 있습니다. 그렇게 하면 인덱스 수준 힌트가 먼저 적용되며, 다른 optimizer 힌트의 효과는 인덱스 수준 힌트가 허용하는 인덱스 집합으로 제한됩니다.

  인덱스 수준 힌트는 다음과 같이 뷰를 생성할 때도 사용할 수 있습니다:

  ```
  CREATE VIEW v1 AS
      SELECT /*+ NO_INDEX(t1 i_a,i_b) */ a FROM t1
      WHERE b IN
          (SELECT /*+ NO_INDEX(t1 i_ab,i_b) */ a FROM t1 WHERE a > 3)
      ORDER BY a;
  ```

  이러한 인덱스 수준 optimizer 힌트가 인덱스 힌트와 동일한 문에서 사용되면 인덱스 힌트는 무시됩니다.

  새로운 인덱스 수준 optimizer 힌트는 `USE INDEX`가 아니라 `FORCE INDEX`와 동등합니다. 다시 말해, 하나 이상의 인덱스 수준 optimizer 힌트를 사용한다는 것은 테이블에서 로우를 찾기 위해 명명된 인덱스 중 하나를 사용할 방법이 없는 경우에만 테이블 스캔이 사용된다는 의미입니다. 지정된 `USE INDEX` 인스턴스와 동일한 인덱스 또는 인덱스 집합을 MySQL이 사용하도록 하려면 `NO_INDEX`, `NO_JOIN_INDEX`, `NO_GROUP_INDEX`, `NO_ORDER_INDEX` 또는 이들의 일부 조합을 사용할 수 있습니다.

  자세한 정보와 예시는 [Index-Level Optimizer Hints](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/optimizer-hints.html#optimizer-hints-index-level)를 참조하십시오. (WL #13538)

## 패키징 관련 사항

- 시스템 `curl` 라이브러리에 링크하지 않고 `curl`을 포함하는 바이너리 패키지가 `curl` 7.69.0을 사용하도록 업그레이드되었습니다. (Bug #30866333)
- RPM 패키지의 경우 **comp_err** 유틸리티가 `-test` 서브패키지로 이동되었으며 테스트 컴포넌트로 표시되었습니다. (Bug #30716034)
- 번들로 제공되는 `libedit` 라이브러리가 버전 3.1로 업그레이드되었습니다. (Bug #28939380, Bug #20770875, Bug #22930525, Bug #22332089, Bug #27433491, Bug #27285445, WL #13534)
- 번들로 제공되는 LZ4 라이브러리가 버전 1.9.2로 업그레이드되었습니다. 이는 Bug #30369643에서 **mysqlpump** 런타임 오류가 발생하는 것과 같은 특정 문제를 수정합니다. (WL #13690)

  참조: 다음도 참조하십시오: Bug #30369643.

## Performance Schema 관련 사항

- Performance Schema가 전역에서만 발생할 수 있고 세션별로는 발생할 수 없는 오류에 대해 세션 관련 통계를 수집했습니다. 이제 더 이상 이렇게 하지 않으므로 오류 계측에 대한 메모리 오버헤드가 줄어듭니다. 또한 전역 오류에 대한 로우는 더 이상 스레드, 계정, 사용자 또는 호스트별로 보고되는 오류 요약에 포함되지 않습니다. (Bug #30311574)

## Pluggable Authentication 관련 사항

- LDAP 서버는 LDAP 검색을 다른 LDAP 서버에 위임하도록 설정할 수 있으며, 이 기능은 LDAP referral로 알려져 있습니다. 그러나 LDAP referral을 활성화하면 특정 조건에서 LDAP 작업 오류로 인해 검색이 실패할 수 있습니다. MySQL Enterprise Edition LDAP 인증 플러그인이 referral 오류를 피할 수 있도록 새로운 [`authentication_ldap_simple_referral`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/pluggable-authentication-system-variables.html#sysvar_authentication_ldap_simple_referral) 및 [`authentication_ldap_sasl_referral`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/pluggable-authentication-system-variables.html#sysvar_authentication_ldap_sasl_referral) 시스템 변수를 사용할 수 있습니다. 이러한 변수는 각 플러그인이 MySQL 인증 중 LDAP 서버가 referral을 사용해야 하는지 여부를 제어할 수 있게 합니다. [LDAP Search Referral](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/ldap-pluggable-authentication.html#ldap-pluggable-authentication-ldap-referral)을 참조하십시오. (WL #12888)
- MySQL Enterprise Edition SASL LDAP 인증 플러그인은 이제 Linux의 MySQL 클라이언트 및 서버에 대한 인증 방법으로 GSSAPI/Kerberos를 지원합니다. 이는 Kerberos가 기본적으로 활성화되어 있는 Microsoft Active Directory를 사용하여 애플리케이션이 LDAP에 액세스하는 Linux 환경에서 유용합니다. [LDAP Authentication Methods](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/ldap-pluggable-authentication.html#ldap-pluggable-authentication-auth-methods)를 참조하십시오.

  이 기능은 Linux용 모든 RPM 및 DEB 패키지에서 사용할 수 있지만, TAR 아카이브 패키지에서는 사용할 수 없습니다. (WL #12888)

## SQL 문법 관련 사항

- 이전에는 [`SELECT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/select.html) 문에 대한 `INTO` 절이 두 위치 중 하나에 나타날 수 있었습니다:

  - `FROM` 앞:

    ```
    SELECT * INTO OUTFILE 'file_name' FROM table_name;
    ```
  - 뒤따르는 locking 절 앞:

    ```
    SELECT * FROM table_name INTO OUTFILE 'file_name' FOR UPDATE;
    ```

  이제 `INTO`는 세 번째 위치, 즉 [`SELECT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/select.html) 문 끝에 나타날 수 있습니다:

  ```
  SELECT * FROM table_name FOR UPDATE INTO OUTFILE 'file_name';
  ```

  `INTO`를 끝에 배치하는 것이 선호되는 위치입니다. locking 절 앞의 위치는 이제 사용 중단되었으며, 이에 대한 지원은 향후 MySQL 버전에서 제거됩니다. 다시 말해, `FROM` 뒤이지만 [`SELECT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/select.html)의 끝이 아닌 위치에 있는 `INTO`는 경고를 생성합니다.

  또한 `INTO`와 관련하여 [`UNION`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/union.html)에 대해 일부 변경 사항이 적용되었습니다. `INTO`를 포함하는 다음 [`UNION`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/union.html) 변형은 문법적으로 올바르며 동일한 결과를 생성합니다:

  ```
  ... UNION SELECT * FROM table_name INTO OUTFILE 'file_name';
  ... UNION (SELECT * FROM table_name) INTO OUTFILE 'file_name';
  ... UNION SELECT * INTO OUTFILE 'file_name' FROM table_name;
  ... UNION (SELECT * INTO OUTFILE 'file_name' FROM table_name);
  ```

  그러나 마지막 두 변형은 전체 쿼리 표현식(`UNION`)이 아니라 명명된 테이블에서 정보를 수집하는 것처럼 보이기 때문에 혼동을 줍니다. `INTO`를 포함하는 이 두 [`UNION`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/union.html) 변형은 이제 사용 중단되었으며, 이에 대한 지원은 향후 MySQL 버전에서 제거됩니다. 따라서:

  - 쿼리 표현식의 뒤따르는 쿼리 블록에서 `FROM` 앞에 `INTO`를 사용하면 경고가 생성됩니다.
  - 쿼리 표현식의 괄호로 묶인 뒤따르는 블록에서 `INTO`를 사용하면(`FROM`에 대한 상대적 위치와 관계없이) 경고가 생성됩니다.

  사용 중단은 모든 `INTO` 형식에 적용됩니다: `INTO OUTFILE`, `INTO DUMPFILE`, `INTO var_list`. (WL #13559)

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

- `perfschema.idx_compare_replication_applier_status` 테스트 케이스는 이전 트랜잭션 재시도 횟수 값을 저장하고 이를 새 트랜잭션 재시도 횟수 값과 비교하도록 업데이트되었습니다. 기여해 주신 Facebook에 감사드립니다. (Bug #30810627, Bug #98389)

## X 플러그인 관련 사항

- [`max_connections`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_max_connections) 서버 시스템 변수로 지정된 MySQL Server 인스턴스의 클라이언트 연결 제한에 도달한 상태에서 X Plugin이 시작되는 경우, X Plugin은 서버 설정을 가져오기 위한 세션을 생성할 수 없어 시작에 실패했습니다. 이제 X Plugin은 시작 중에 관리 세션(`mysql_admin_session` 서비스를 사용)을 생성하며, 이 세션은 클라이언트 연결 제한의 적용을 받지 않습니다. (Bug #30894981)
- 이미 X Protocol 연결이 너무 많아 X Protocol 세션을 초기화할 수 없는 경우, 오류 코드 5011 Could not open session이 반환되었습니다. 이제 이 상황에서는 더 관련성이 높은 오류 코드 1040 Too many connections가 반환됩니다. (Bug #30753637)
- JSON 참조 검증 관련 문제로 인해 검증 스키마가 있는 컬렉션을 생성할 때 오류가 발생했습니다. (Bug #30733330)
- 클라이언트에 대한 X Protocol 연결이 있는 MySQL Server 인스턴스를 종료하는 동안, X Plugin의 경쟁 조건으로 인해 유효하지 않은 클라이언트 연결이 처리 대상으로 허용될 수 있었습니다. 종료 중 클라이언트 타임아웃 검증에서 유효하지 않은 클라이언트가 무시되었기 때문에, 이러한 클라이언트는 기본값이 8시간인 `mysqlx_wait_timeout` 시스템 변수로 설정된 타임아웃에 도달할 때까지 종료를 차단했습니다. 이 문제를 방지하기 위해 이제 클라이언트 타임아웃 검증에는 유효하지 않은 상태에 있는 클라이언트도 포함됩니다. (Bug #30702685)
- MySQL 8.0 서버에 연결할 때, X Plugin은 세션에 대해 **mysql** 클라이언트가 사용하는 콜레이션과 다른 콜레이션을 설정했으며, 이로 인해 콜레이션에 의존하는 쿼리에 문제가 발생할 수 있었습니다. 이제 X Plugin은 `utf8mb4` 캐릭터셋의 기본값인 `utf8mb4_0900_ai_ci` 콜레이션을 사용합니다. (Bug #30516849)

- X Protocol 연결의 작업자 스레드는 생성 시 시스템 스레드로 식별되어 `SYS_default` 리소스 그룹에 할당되었습니다. 이러한 식별로 인해 리소스 관리를 위해 사용자 리소스 그룹에 할당될 수 없었습니다. 이제 이 스레드는 사용자 스레드로 식별되어 `USR_default` 리소스 그룹에 할당됩니다. X Protocol은 현재 `CREATE`, `ALTER`, `DROP` 및 [`SET RESOURCE GROUP`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/set-resource-group.html) 문을 지원하지 않지만, 이러한 문은 클래식 MySQL 프로토콜 연결을 사용하여 X Protocol 연결 스레드에 대해 동작할 수 있습니다. (Bug #30059288)
- 이제 X Plugin은 초기화가 시작되는 즉시 MySQL 시스템 변수에 접근할 수 있으므로, 플러그인 설치 스레드는 별도의 스레드를 시작하는 대신 필요한 연결성을 자체적으로 설정할 수 있습니다. (Bug #29127302)

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

- **중요한 변경:** 이전에는 정렬 작업에서 [`TINYBLOB`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/blob.html) 또는 [`BLOB`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/blob.html)보다 큰 blob 타입의 컬럼이 페이로드로 포함되면, 서버가 전체 로우가 아니라 로우 ID만 정렬하는 방식으로 되돌아갔습니다. 이로 인해 정렬이 완료된 후 로우 자체를 디스크에서 가져오기 위한 두 번째 패스가 발생했습니다. [`JSON`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/json.html) 및 [`GEOMETRY`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/spatial-type-overview.html) 컬럼은 내부적으로 [`LONGBLOB`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/blob.html)으로 구현되므로, 이러한 타입의 컬럼은 거의 항상 `LONGBLOB`의 최대값인 4GB보다 훨씬 짧고(`MEDIUMBLOB`의 최대값인 16MB보다도 짧은 경우에도) 동일한 동작이 발생했습니다. 이제 서버는 이러한 경우에 `TINYBLOB` 및 `BLOB` 컬럼에 대해 수행하는 것과 마찬가지로 이러한 타입의 컬럼을 packed addon으로 변환하며, 테스트에서 상당한 성능 향상이 확인되었습니다. *이와 관련된 [`MEDIUMBLOB`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/blob.html) 및 [`LONGBLOB`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/blob.html) 컬럼 처리는 변경되지 않았습니다*.

  이 개선의 한 가지 영향은 정렬 버퍼 크기가 충분하지 않은 경우 매우 큰(멀티 메가바이트) `JSON` 또는 `GEOMETRY` 컬럼 값을 포함하는 로우를 정렬하려고 할 때 Out of memory 오류가 발생할 수 있게 되었다는 점입니다. 이는 일반적인 방식으로 [`sort_buffer_size`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_sort_buffer_size) 시스템 변수 값을 늘려 보완할 수 있습니다. (Bug #30400985, Bug #30804356)
- **InnoDB:** 잠금을 기다리는 트랜잭션의 우선순위를 높이는 Contention-Aware Transaction Scheduling (CATS) 알고리즘이 개선되었습니다. 이제 트랜잭션 스케줄링 가중치 계산은 완전히 별도의 스레드에서 수행되며, 이로 인해 계산 성능과 정확도가 향상됩니다.

  트랜잭션 스케줄링에도 사용되었던 First In First Out (FIFO) 알고리즘은 제거되었습니다. CATS 알고리즘 개선으로 FIFO 알고리즘은 중복된 것이 되었습니다. 이전에 FIFO 알고리즘이 수행하던 트랜잭션 스케줄링은 이제 CATS 알고리즘이 수행합니다.

  `TRX_SCHEDULE_WEIGHT` 컬럼이 [`INFORMATION_SCHEMA.INNODB_TRX`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-innodb-trx-table.html) 테이블에 추가되었으며, 이를 통해 CATS 알고리즘이 할당한 트랜잭션 스케줄링 가중치를 쿼리할 수 있습니다.

  코드 수준 트랜잭션 스케줄링 이벤트 모니터링을 위해 다음 `INNODB_METRICS` 카운터가 추가되었습니다:

  - `lock_rec_release_attempts`

    레코드 잠금 해제를 시도한 횟수입니다.
  - `lock_rec_grant_attempts`

    레코드 잠금 부여를 시도한 횟수입니다.
  - `lock_schedule_refreshes`

    트랜잭션 스케줄 가중치를 업데이트하기 위해 wait-for 그래프를 분석한 횟수입니다.

  (WL #13486)

- **InnoDB:** doublewrite 버퍼의 스토리지 영역이 시스템 테이블스페이스에서 doublewrite 파일로 이동되었습니다. doublewrite 버퍼 스토리지 영역을 시스템 테이블스페이스 밖으로 이동하면 쓰기 지연 시간이 줄어들고, 처리량이 증가하며, doublewrite 버퍼 페이지 배치와 관련한 유연성이 제공됩니다. 고급 doublewrite 버퍼 설정을 위해 다음 시스템 변수가 도입되었습니다:

  - [`innodb_doublewrite_dir`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/innodb-parameters.html#sysvar_innodb_doublewrite_dir)

    doublewrite 버퍼 파일 디렉터리를 정의합니다.
  - [`innodb_doublewrite_files`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/innodb-parameters.html#sysvar_innodb_doublewrite_files)

    doublewrite 파일 수를 정의합니다.
  - [`innodb_doublewrite_pages`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/innodb-parameters.html#sysvar_innodb_doublewrite_pages)

    배치 쓰기에서 스레드당 doublewrite 페이지의 최대 수를 정의합니다.
  - [`innodb_doublewrite_batch_size`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/innodb-parameters.html#sysvar_innodb_doublewrite_batch_size)

    배치로 쓸 doublewrite 페이지 수를 정의합니다.

  자세한 내용은 [Doublewrite Buffer](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/innodb-doublewrite-buffer.html)를 참조하십시오. (WL #5655)
- 이제 [`EXPLAIN ANALYZE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/explain.html#explain-analyze)는 실행 중에 [`KILL QUERY`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/kill.html) 또는 **CTRL-C**를 사용하여 중지할 수 있습니다. (Bug #30787515)

- [`EXPLAIN FORMAT=TREE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/explain.html)는 이제 윈도우 함수에 대한 `inversion` 정보를 표시합니다. (Bug #30770631)
- [`EXPLAIN FORMAT=TREE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/explain.html) 출력은 평가된 윈도우 함수에 대해 더 많은 정보를 제공하고, 일반 집계에 대해 제공되는 정보와 일치하도록 개선되었습니다. (Bug #30573446, Bug #30582782)
- [`-DWITH_LTO=1`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/source-configuration-options.html#option_cmake_with_lto) **CMake** 옵션을 사용한 설정이 이제 macOS에서 작동합니다. (Bug #30125902)
- 이제 MySQL 서버 인스턴스에서 바이너리 로그 트랜잭션 압축을 활성화할 수 있습니다. 바이너리 로그 트랜잭션 압축이 활성화되면 트랜잭션 페이로드는 zstd 알고리즘을 사용해 압축된 다음, 단일 이벤트(`Transaction_payload_event`)로 서버의 바이너리 로그 파일에 기록됩니다. 압축된 트랜잭션 페이로드는 복제 스트림에서 복제본, 다른 Group Replication 그룹 멤버 또는 **mysqlbinlog**와 같은 클라이언트로 전송되는 동안 압축된 상태로 유지됩니다. 이러한 페이로드는 수신자 스레드에 의해 압축 해제되지 않으며, 여전히 압축된 상태로 릴레이 로그에 기록됩니다. 따라서 바이너리 로그 트랜잭션 압축은 트랜잭션 발생자와 수신자 양쪽(및 이들의 백업)에서 스토리지 공간을 절약하고, 트랜잭션이 서버 인스턴스 간에 전송될 때 네트워크 대역폭을 절약합니다.

  [`binlog_transaction_compression`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/replication-options-binary-log.html#sysvar_binlog_transaction_compression) 시스템 변수를 사용하여 MySQL 서버 인스턴스에서 바이너리 로그 트랜잭션 압축을 활성화할 수 있으며, 이 변수의 기본값은 `OFF`입니다. 또한 [`binlog_transaction_compression_level_zstd`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/replication-options-binary-log.html#sysvar_binlog_transaction_compression_level_zstd) 시스템 변수를 사용하여 압축에 사용되는 zstd 알고리즘의 레벨을 설정할 수 있습니다. 이 값은 1(가장 낮은 작업량)부터 22(가장 높은 작업량)까지의 압축 작업량을 결정합니다. (WL #3549)

- [`CHANGE MASTER TO`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/change-master-to.html) 문에 대한 새 옵션인 `REQUIRE_TABLE_PRIMARY_KEY_CHECK`는 복제 슬레이브가 기본 키 검사에 대한 자체 정책을 선택할 수 있게 합니다. 복제 채널에 대해 이 옵션이 `ON`으로 설정되면, 슬레이브는 복제 작업에서 [`sql_require_primary_key`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_sql_require_primary_key) 시스템 변수에 항상 `ON` 값을 사용하여 기본 키를 요구합니다. 이 옵션이 `OFF`로 설정되면, 슬레이브는 복제 작업에서 [`sql_require_primary_key`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_sql_require_primary_key) 시스템 변수에 항상 `OFF` 값을 사용하므로, 마스터가 기본 키를 요구했더라도 기본 키가 절대 요구되지 않습니다. `REQUIRE_TABLE_PRIMARY_KEY_CHECK` 옵션이 기본값인 `STREAM`으로 설정되면, 슬레이브는 각 트랜잭션에 대해 마스터에서 복제되는 값을 그대로 사용합니다.

  - 멀티소스 복제의 경우, `REQUIRE_TABLE_PRIMARY_KEY_CHECK`를 `ON` 또는 `OFF`로 설정하면 슬레이브가 서로 다른 마스터에 대한 복제 채널 전반에서 동작을 정규화하고, [`sql_require_primary_key`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_sql_require_primary_key) 시스템 변수에 대해 일관된 설정을 유지할 수 있습니다. `ON`을 사용하면 여러 마스터가 동일한 테이블 집합을 업데이트할 때 기본 키가 우발적으로 손실되는 것을 방지할 수 있습니다. `OFF`를 사용하면 기본 키를 조작할 수 있는 마스터가 그렇지 못한 마스터와 함께 동작할 수 있습니다.
  - `PRIVILEGE_CHECKS_USER`가 채널에 복제 권한 검사를 적용하도록 설정된 경우, `REQUIRE_TABLE_PRIMARY_KEY_CHECK`를 `ON` 또는 `OFF`로 설정하면 각 트랜잭션에 대해 마스터의 설정과 일치하도록 [`sql_require_primary_key`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_sql_require_primary_key) 값을 변경하는 데 필요한 제한된 세션 변수를 설정하기 위해 사용자 계정이 세션 관리 수준 권한을 가질 필요가 없음을 의미합니다.

  (WL #13239)

- MySQL 8.0.19부터 X Protocol 연결을 통해 전송되는 메시지에 대해 압축이 지원되었습니다. 서버와 클라이언트가 사용할 압축 알고리즘에 동의하면 연결을 압축할 수 있습니다. 기본적으로 서버는 Deflate, LZ4 및 zstd 압축 알고리즘을 허용하며, 또는 허용할 알고리즘만 포함하도록 `mysqlx_compression_algorithms` 시스템 변수를 설정할 수 있습니다. MySQL 8.0.19에서 X Protocol은 각 알고리즘에 대해 라이브러리 기본 압축 레벨을 사용하며, 클라이언트는 이를 협상할 수 없습니다.

  MySQL 8.0.20부터 클라이언트는 X Protocol 연결에 대한 capability 협상 중 특정 압축 레벨을 요청할 수 있습니다. X Protocol은 각 알고리즘에 대해 최대 압축 레벨을 설정하며, 이렇게 하면 클라이언트가 높은 압축 레벨을 요청하더라도 그것이 서버에서 너무 많은 리소스를 소비할 경우 서버가 이에 동의하지 않도록 방지합니다. 최대 압축 레벨은 처음에 Deflate의 경우 5, LZ4의 경우 8, zstd의 경우 11로 설정됩니다. 새 `mysqlx_deflate_max_client_compression_level`, `mysqlx_lz4_max_client_compression_level` 및 `mysqlx_zstd_max_client_compression_level` 시스템 변수를 사용하여 이러한 설정을 조정할 수 있습니다.

  X Protocol의 새 기본 압축 레벨도 성능 테스트를 통해 압축 시간과 네트워크 전송 시간 사이의 적절한 절충안으로 선택되었습니다. 이러한 기본값은 각 알고리즘의 라이브러리 기본값과 반드시 같지는 않습니다. 클라이언트가 해당 알고리즘에 대해 압축 레벨을 요청하지 않는 경우 이 기본값이 적용됩니다. 기본 압축 레벨은 처음에 Deflate의 경우 3, LZ4의 경우 2, zstd의 경우 3으로 설정됩니다. 새 `mysqlx_deflate_default_compression_level`, `mysqlx_lz4_default_compression_level` 및 `mysqlx_zstd_default_compression_level` 시스템 변수를 사용하여 이러한 설정을 조정할 수 있습니다. (WL #13034)

## 수정된 버그

- **호환되지 않는 변경:** [`ST_Contains()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/spatial-relation-functions-object-shapes.html#function_st-contains)를 사용한 일부 쿼리는 `> 0`이 추가되지 않는 한 결과를 반환하지 않았습니다.

  이전 버전의 MySQL에서 업그레이드하는 경우, spatial 인덱스가 있는 테이블에서 spatial 인덱스를 다시 생성해야 합니다.

  (Bug #30461595, Bug #97347)

- **성능:** MySQL 5.7에서 MySQL 8.0으로 업그레이드한 후 spatial 인덱스가 있는 테이블에 대한 특정 쿼리가 그만큼 효율적으로 수행되지 않았습니다. (Bug #94655, Bug #29488350)

  참조: 다음도 참조하십시오: Bug #89551, Bug #27499984.
- **NDB Cluster:** `NDB`는 root 테이블의 primary 파티션을 소유한 노드마다 하나의 `SPJ` worker를 정의합니다. 이 테이블이 임의의 fragment replica에서 읽기를 사용한 경우, [`DBTC`](https://dev.mysql.com/doc/ndb-internals/en/ndb-internals-kernel-blocks-dbtc.html)는 모든 `SPJ` worker를 동일한 [`DBSPJ`](https://dev.mysql.com/doc/ndb-internals/en/ndb-internals-kernel-blocks-dbspj.html) 인스턴스에 배치했으며, 이는 일부 `SPJ` worker의 사용을 사실상 제거했습니다. (Bug #30639165)
- **NDB Cluster:** NDB 8.0.16 또는 그 이전 버전의 **ndb_mgm** 클라이언트 바이너리를 사용하여 NDB 8.0.17 또는 그 이후 버전을 실행 중인 관리 노드에 접근할 때 `SHOW` 명령을 실행하면 Unknown field: is_single_user 오류 메시지가 생성되었습니다. (Bug #30599413)

  참조: 다음도 참조하십시오: Bug #16275500.

- **InnoDB:** 경로를 지정하지 않고 undo 데이터 파일 이름을 지정한 [`CREATE UNDO TABLESPACE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/create-tablespace.html) 작업이 [`innodb_undo_directory`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/innodb-parameters.html#sysvar_innodb_undo_directory) 변수로 지정된 디렉터리에서 동일한 이름의 기존 undo 데이터 파일을 제거했습니다. 파일 이름 충돌 검사는 [`innodb_undo_directory`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/innodb-parameters.html#sysvar_innodb_undo_directory) 변수로 지정된 디렉터리가 아니라 데이터 디렉터리에서 수행되었습니다. (Bug #30908328, Bug #98628)
- **InnoDB:** 디버그 빌드에서 MySQL 8.0.19에 도입된 회귀로 인해 뮤텍스 및 rw-lock 데드락 디버그 검사가 느려졌습니다. (Bug #30886393)

  참조: 이 문제는 다음의 회귀입니다: Bug #30628872.
- **InnoDB:** Valgrind 테스트에서 조건부 점프 또는 이동이 초기화되지 않은 값에 의존함을 나타내는 오류가 발생했습니다. 이 오류는 유효하지 않은 검증 로직으로 인한 false-positive였습니다. (Bug #30837136)
- **InnoDB:** `rw_lock_debug_mutex_enter()`(소스 파일 `sync0debug.cc` 내)에 barrier가 누락되어 스레드가 깨어나지 못한 채 대기할 수 있었습니다. (Bug #30819167)

- **InnoDB:** Linux에서 서버 초기화 속도를 개선하기 위해 이제 `posix_fallocate()`를 사용하여 redo log 파일에 대한 공간을 할당합니다. (Bug #30804431, Bug #98342)
- **InnoDB:** 데이터 딕셔너리 테이블 open 함수가 잘못된 잠금 순서로 구현되었습니다. (Bug #30782103, Bug #97825)
- **InnoDB:** MySQL 8.0.17에서 도입된 병렬 read 스레드 기능 변경으로 인해 `SELECT COUNT(*)` 성능이 저하되었습니다. 페이지가 불필요하게 디스크에서 읽혔습니다. (Bug #30766089)
- **InnoDB:** [`init_file`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_init_file) 시작 변수를 사용하여 bootstrap 스레드가 실행한 SQL 작업에 대해 DDL 로깅이 수행되지 않아, post-DDL 단계에서 제거되었어야 하는 파일이 남아 있었습니다. (Bug #30721214, Bug #98131)
- **InnoDB:** 특정 수의 레코드가 있는 테이블에서 JSON 배열로 캐스트된 컬럼에 인덱스를 추가하면 “Incorrect key file for table” 오류와 함께 실패했습니다. (Bug #30709525, Bug #98098)
- **InnoDB:** Valgrind 오류가 초기화되지 않은 `lock->writer_thread` 값이 조건부 jump에서 사용되었다고 보고했습니다. (Bug #30694177)
- **InnoDB:** 내부 버퍼 풀 통계 카운터(`n_page_gets`)가 여러 스레드에서 접근될 때 경합을 피하기 위해 페이지 번호별로 파티셔닝되었습니다. (Bug #30604841, Bug #97822)

- **InnoDB:** 테이블스페이스 가져오기 작업이 `.cfg` 파일과 데이터 딕셔너리 모두에 `ALGORITHM=INSTANT`를 사용하여 추가된 컬럼의 기본값이 포함되어 있어 스키마 불일치 오류와 함께 실패했습니다. 오류는 기본값이 서로 다른 경우에만 발생해야 합니다. (Bug #30561144)
- **InnoDB:** 느린 종료가 일부 GTID를 플러시하지 못해, 플러시되지 않은 GTID를 undo 로그에서 복구해야 했습니다. (Bug #30548229)
- **InnoDB:** Performance Schema 메모리 할당을 위해 메모리에 접두사를 할당하는 코드의 손상된 정렬 요구사항으로 인해 macOS 및 FreeBSD에 최적화된 MySQL 빌드에서 실패가 발생했습니다. (Bug #30530857)
- **InnoDB:** 가상 컬럼을 추가할 때 테이블에 대해 생성된 새 데이터 딕셔너리 객체에 누락된 데이터로 인해 assertion failure가 발생했습니다. (Bug #30524263)
- **InnoDB:** undo 테이블스페이스의 모드를 확인할 때 필요한 래치가 획득되지 않았습니다. undo 테이블스페이스가 비어 있는지 확인할 때도 필요한 래치가 획득되지 않았습니다. (Bug #30509134)
- **InnoDB:** 트랜잭션이 데이터 수정을 수행하기 전에 GTID 값을 영구 저장하기 위해 XA 트랜잭션에 update undo 로그 세그먼트를 할당하면 실패가 발생했습니다. (Bug #30456328)
- **InnoDB:** 폐기된 테이블스페이스가 있는 파티셔닝된 테이블에서 실행된 쿼리로 인해 assertion failure가 발생했습니다. (Bug #30437407, Bug #97271)

- **InnoDB:** 클러스터형 인덱스 레코드를 삭제된 것으로 표시하고 해당 레코드의 업데이트된 버전을 클러스터형 인덱스에 삽입하는 `row_upd_clust_rec_by_insert` 함수가 하위 수준 함수에 잘못된 `n_ext` 값(외부 필드의 총 개수)을 전달하여 assertion failure가 발생했습니다. (Bug #30437378)
- **InnoDB:** 복제 작업 중 종료 시점에 데이터 딕셔너리 버퍼 테이블에 대한 쓰기가 너무 늦게 수행되어 실패가 발생했습니다. 새로 생성된 dirty page가 플러시되지 않았습니다. (Bug #30427369, Bug #30405535, Bug #30405535)
- **InnoDB:** `innodb_buffer_pool_evict` 디버그 변수가 `uncompressed`로 설정된 상태에서 수행된 작업으로 인해 assertion failure가 발생했습니다. (Bug #30405531)
- **InnoDB:** boolean `recursive` 플래그 및 writer 스레드 ID에 대한 접근 순서를 제어하는 읽기-쓰기 락 코드(`rw_lock_t`)는 GCC builtins를 사용하거나 builtins를 사용할 수 없는 경우 `os_mutex`를 사용했으며, 일부 경우 C++ `std::atomic`을 사용하도록 개정되었습니다. 기여해 주신 ARM의 Yibo Cai에게 감사드립니다. (Bug #30401416, Bug #97150)
- **InnoDB:** MySQL 5.7에서 MySQL 8.0으로 업그레이드하는 동안 실패가 발생했습니다. 서버 데이터 딕셔너리 객체에 `FULLTEXT` 인덱스를 삭제한 후 남아 있는 `FTS_DOC_ID` 컬럼 및 `FTS_DOC_ID_INDEX`에 대한 정보가 누락되어 있었습니다. (Bug #30357954)

- **InnoDB:** 병렬 스캔에 대한 불필요한 메시지가 오류 로그에 출력되었습니다. (Bug #30330448)
- **InnoDB:** MySQL 5.7에서 MySQL 8.0으로 업그레이드하는 동안 `GEN_CLUST_INDEX`라는 이름의 클러스터형 인덱스가 `PRIMARY`로 이름이 변경되며, 이로 인해 클러스터형 인덱스에 대한 중복 엔트리가 `mysql.innodb_index_stats` 테이블에 추가되었습니다. (Bug #30330448)
- **InnoDB:** 여러 내부 함수가 쓰기 이벤트 슬롯을 일관되지 않은 방식으로 계산했습니다. (Bug #30228108, Bug #96519)
- **InnoDB:** 특정 상황에서 크래시 복구의 redo 로그 적용 단계 중에 테이블스페이스 암호화 키 정보가 적용되지 않을 수 있었습니다. (Bug #30209760)
- **InnoDB:** 파일 작업 실패로 인해 페이지 추적 아카이버가 실패했으며, 이로 인해 메인 스레드가 중단되어 어설션 실패가 발생했습니다. 또한 잘못되게도 페이지 추적 아카이버가 [`innodb_read_only`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/innodb-parameters.html#sysvar_innodb_read_only) 모드에서 활성화된 상태로 남아 있었습니다. (Bug #30202643)
- **InnoDB:** `ALGORITHM=INSTANT`를 사용하여 추가된 테이블 컬럼이 포함된 테이블스페이스를 임포트하려고 할 때 인덱스 손상 오류가 보고되었습니다. 이 오류는 즉시 추가된 컬럼과 연결된 메타데이터가 누락되어 발생했습니다. (Bug #30191523, Bug #96477)

- **InnoDB:** LOB 레코드를 가져오려고 시도하는 트랜잭션이 null LOB 참조를 만나 assertion failure가 발생했습니다. 그러나 이 특정 시나리오에서는 LOB 값이 아직 완전히 쓰이지 않았기 때문에 null LOB 참조가 유효했습니다. (Bug #30144303)
- **InnoDB:** 병렬 읽기 작업 중 [`autocommit`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_autocommit)이 비활성화된 상태에서 테이블 로드 작업을 롤백하면, 병렬 읽기 중 트리 구조 변경 가능성을 고려하지 않은 assertion 코드로 인해 서버가 종료되었습니다. (Bug #30060690)
- **InnoDB:** 롤백 세그먼트 메모리 객체에 유지되는 현재 크기 값이 유효하지 않은 것으로 확인되어 함수 `trx_purge_free_segment()`에서 assertion failure가 발생했습니다. 현재 크기 값을 검증하기 위해 검증 루틴(`trx_rseg_t::validateCurrSize()`)이 추가되었습니다. (Bug #29947027)
- **InnoDB:** 유효하지 않은 파라미터 값으로 실행된 prepared statement가 assertion failure를 발생시켰습니다. (Bug #29880907)
- **InnoDB:** add column 작업이 assertion failure를 발생시켰습니다. 이 실패는 dangling pointer로 인해 발생했습니다. (Bug #29866408)

  참조: 이 문제는 다음의 회귀입니다: Bug #28491099.
- **InnoDB:** 문자열 값을 받는 특정 `InnoDB` 시스템 변수를 업데이트하면 Valgrind 테스트 중 유효하지 않은 읽기 오류가 발생했습니다. (Bug #29717909, Bug #95215)

- **InnoDB:** MySQL 8.0에서 undo tablespace ID 값 변경으로 인해 추가 바이트가 필요해지면서 undo tablespace에 대한 수정의 redo log 레코드 크기가 증가했습니다. redo log 레코드 크기의 변경은 쓰기 I/O가 많은 워크로드에서 성능 저하를 유발했습니다. 이 문제를 해결하기 위해 undo tablespace에 대한 수정의 redo log 레코드 크기를 줄이도록 redo log 형식이 변경되었습니다. (Bug #29536710)
- **InnoDB:** 진행률 데이터를 포함하여 `InnoDB` 파일 쓰기에 대한 추가 정보가 이제 오류 로그에 출력됩니다. (Bug #29472295, Bug #94634)
- **InnoDB:** 공간 인덱스가 있는 테이블에 대한 insert 문이 튜플 손상으로 인해 레코드 타입 불일치 assertion을 발생시켰습니다. (Bug #29465567)
- **InnoDB:** undo log 레코드 크기를 계산하는 함수가 손상된 undo log 레코드의 경우 잘못된 길이 값을 계산할 수 있었으며, 그 결과 malloc 실패가 발생했습니다. 잘못된 계산을 감지하기 위해 assertion 코드가 추가되었습니다. (Bug #29448406, Bug #82734)

- **Replication:** 민감한 정보가 일반 텍스트로 나타나지 않도록 SQL 문을 바이너리 로그용으로 다시 작성하는 과정에서, [`SHOW PROCESSLIST`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/show-processlist.html) 문을 사용하여 쿼리를 검사하면, 해당 쿼리가 바이너리 로그에 기록될 때 손상되어 복제가 중지될 수 있었습니다. 이제 쿼리를 다시 작성하는 과정은 비공개로 유지되며, 다시 작성이 완료된 경우에만 쿼리 스레드가 업데이트됩니다. (Bug #30569003, Bug #97531, Bug #30654405)

- **Replication:** [`GRANT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/grant.html) 또는 [`REVOKE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/revoke.html) 문이 부분적으로만 실행되면 바이너리 로그에 인시던트 이벤트가 기록되며, 이로 인해 복제 슬레이브의 applier 스레드가 중지되어 슬레이브를 마스터와 수동으로 조정할 수 있습니다. 이전에는 실패한 [`GRANT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/grant.html) 또는 [`REVOKE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/revoke.html) 문이 세션에서 실행된 첫 번째 문인 경우, 인시던트 이벤트에 GTID가 적용되지 않아(해당 세션에 대한 캐시 매니저가 아직 존재하지 않았기 때문입니다) 복제 슬레이브에서 오류가 발생했습니다. 또한 [`GRANT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/grant.html) 문이 사용자를 생성했지만 권한이 잘못 지정되어 이후 실패한 상황에서는 인시던트 이벤트가 기록되지 않았으며, 이 역시 복제 슬레이브에서 오류를 발생시켰습니다. 이제 이 두 문제가 모두 수정되었습니다. (Bug #30566518, Bug #30324661)
- **Replication:** 이제 서버 시작 후 `thread/sql/compress_gtid_table` 스레드가 시작될 때 `mysql.gtid_executed` 테이블에 대해 압축이 트리거되며, 압축 프로세스가 완료되면 그 효과를 확인할 수 있습니다. (Bug #30541799)

- **Replication:** 복제 슬레이브가 마스터로부터 계획되지 않게 연결 해제된 경우, 마스터의 덤프 스레드에 대한 참조가 등록된 슬레이브 목록에서 제거되지 않을 수 있었으며, 이 경우 슬레이브 목록에 액세스하는 문이 실패했습니다. 이 문제는 이제 수정되었습니다. (Bug #29915479)
- **Replication:** 파티셔닝된 테이블이 관련된 경우, 캐시 공간 부족으로 인해 로우 이벤트를 바이너리 로그에 쓸 수 없는 상황을 서버가 올바르게 처리하지 못했습니다. 이제 이 상황에서는 적절한 오류가 반환됩니다. (Bug #29848931)
- **Replication:** [`binlog_format=MIXED`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/replication-options-binary-log.html#sysvar_binlog_format), [`tx_isolation=READ-COMMITTED`](https://docs.oracle.com/cd/E17952_01/mysql-5.7-en/server-system-variables.html#sysvar_tx_isolation), 및 [`binlog_row_image=FULL`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/replication-options-binary-log.html#sysvar_binlog_row_image) 설정에서, 트랜잭션 스토리지 엔진이 관련된 `INSERT... SELECT` 쿼리는 바이너리 로그에 기록되는 로우 이미지에서 null 값을 가진 모든 컬럼을 누락했습니다. 이는 `INSERT... SELECT` 문을 처리할 때 바이너리 로깅 형식이 선택되기 전에 컬럼이 삽입 대상으로 표시되었기 때문에 발생했습니다. 이 문제는 이제 수정되었습니다. (Bug #29110804, Bug #93423)

- **Replication:** 특정 조건에서 conditional comments의 복제가 실패할 수 있었습니다. (Bug #28388217)
- **Group Replication:** Group Replication 메시지 서비스에서 사용하는 스레드가 Performance Schema 계측에 올바르게 등록되지 않았으므로, 스레드 동작이 Performance Schema 테이블에 표시되지 않았습니다. (Bug #30824676)
- **Group Replication:** Group Replication은 분산 복구를 위한 클로닝 작업을 시작하고 관리하지만, 클로닝을 지원하도록 설정된 그룹 멤버는 사용자가 수동으로 시작하는 클로닝 작업에도 참여할 수 있습니다. MySQL 8.0.20 이전 릴리스에서는 Group Replication이 실행 중인 그룹 멤버가 작업에 포함된 경우 클로닝 작업을 수동으로 시작할 수 없었습니다. MySQL 8.0.20부터는 클로닝 작업이 수신자의 데이터를 제거하고 대체하지 않는 경우 이 작업을 수행할 수 있습니다. 따라서 Group Replication이 실행 중인 경우 클로닝 작업을 시작하는 명령문에는 `DATA DIRECTORY` 절이 포함되어야 합니다. (Bug #30798640)

- **Group Replication:** Group Replication 채널의 경우, Group Replication이 실행 중일 때 `PRIVILEGE_CHECKS_USER` 옵션과 함께 [`CHANGE MASTER TO`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/change-master-to.html) 문을 실행하면 채널의 릴레이 로그 파일이 삭제되었습니다. 이 상황에서는 릴레이 로그에서 수신되어 큐에 들어갔지만 아직 적용되지 않은 트랜잭션이 손실될 수 있었습니다. 이제 [`CHANGE MASTER TO`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/change-master-to.html) 문은 Group Replication이 실행 중이 아닐 때만 실행할 수 있습니다. (Bug #30655369)
- **Group Replication:** Group Replication 장애 감지 메커니즘은 서버가 메시지 전송을 중지하면 의심을 제기하며, 그룹 구성원의 과반수가 계속 통신 중이면 해당 구성원은 결국 축출됩니다. 그러나 장애 감지 메커니즘은 과반수에 포함된 그룹 구성원 중 하나 이상이 실제로 이미 축출 대상으로 표시되었지만 아직 그룹에서 제거되지 않은 상황을 고려하지 않았습니다. 네트워크가 불안정하고 구성원들이 서로 다른 조합으로 서로에 대한 연결을 자주 잃었다가 다시 얻는 경우, 그룹이 모든 구성원을 축출 대상으로 표시하게 될 수 있었으며, 그 이후에는 그룹이 더 이상 존재하지 않게 되어 다시 설정해야 했습니다.

  이제 Group Replication Group Communication System (GCS)은 축출 대상으로 표시된 그룹 구성원을 추적하고, 과반수가 있는지 결정할 때 해당 구성원을 의심 구성원 그룹에 있는 것처럼 처리합니다. 이렇게 하면 적어도 하나의 구성원이 그룹에 남아 그룹이 계속 존재할 수 있습니다. 축출된 구성원이 실제로 그룹에서 제거되면 GCS는 해당 구성원을 축출 대상으로 표시했던 기록을 제거하므로, 해당 구성원이 가능하다면 그룹에 다시 참여할 수 있습니다. (Bug #30640544)

- **Group Replication:** 높은 부하 조건에서 실행 중인 Group Replication이 있는 MySQL 서버에서 Performance Schema 테이블에 접근할 수 없었습니다. (Bug #30112711, Bug #30675790)
- **Group Replication:** 로컬 그룹 멤버에 대한 통계를 위해 Group Replication에서 Performance Schema로 수행하는 내부 쿼리가 그룹 멤버십 변경과 동시에 발생한 경우 실패했습니다. 이 문제를 수정하기 위해 내부 쿼리에 대한 잠금이 개선되었습니다. (Bug #30049349, Bug #30791583, Bug #30963553)

- **Group Replication:** Group Replication 분산 복구 프로세스 중, 조인하는 멤버가 그룹의 어떤 donor와도 원격 클로닝 작업을 완료할 수 없는 경우, 필요한 모든 데이터를 가져오기 위해 donor의 바이너리 로그에서 상태 전송을 사용합니다. 그러나 마지막으로 시도한 원격 클로닝 작업이 중단되어 조인하는 멤버에 불완전한 데이터가 남았거나 데이터가 없는 상태가 된 경우, 그 직후의 상태 전송 시도도 실패할 수 있었습니다. 이제 Group Replication은 실패한 원격 클로닝 작업 이후 상태 전송을 시도하기 전에, 원격 클로닝 작업이 조인하는 멤버에서 로컬 데이터를 제거하는 단계에 도달하지 않았는지 확인합니다. 데이터가 제거된 경우, 조인하는 멤버는 그룹을 떠나고 [`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) 시스템 변수로 지정된 작업을 수행합니다. (Bug #29669099, Bug #29944828)
- **Group Replication:** Performance Schema 메모리 계측 오버헤드를 줄이기 위한 이전 변경으로 인해 의도치 않게 Group Replication 성능 저하가 발생했습니다. (Bug #28719976)

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

- **Group Replication:** 특정 작업을 수행하기 전에 Group Replication은 서버에서 실행 중인 트랜잭션을 확인합니다. 이전에는 이 확인에 사용되는 서비스가 커밋 단계에 있는 트랜잭션을 세지 않았으며, 이로 인해 작업이 시간 초과될 수 있었습니다. 이제 커밋 단계에 있는 트랜잭션이 현재 진행 중인 트랜잭션 집합에 포함됩니다. (Bug #28327838)
- **JSON:** strict 모드에서 [`INSERT`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/insert.html) 문의 일부로 [`JSON_TABLE()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/json-table-functions.html#function_json-table)이 사용될 때, `ON ERROR` 절에 의해 처리되는 변환 오류로 인해 `INSERT`가 거부될 수 있었습니다. 오류가 `ON ERROR` 절에 의해 처리되므로, 실제로 `ERROR ON ERROR`가 지정되지 않는 한 문이 거부되지 않아야 합니다.

  이 문제는 `NULL ON ERROR` 또는 `DEFAULT... ON ERROR`가 지정되었거나 암시된 경우 값을 대상 타입으로 변환할 때 경고를 무시하여 수정되었습니다. (Bug #30628330)
- **JSON:** [`JSON_TABLE()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/json-table-functions.html#function_json-table)의 출력은 뷰에서 사용될 때 항상 올바르지는 않았습니다. 이 수정은 다음 문제를 바로잡습니다:

  - 컬럼 이름에 따옴표 처리가 되지 않아, 이러한 이름에 따옴표 처리가 필요한 경우 문법 오류가 발생했습니다.

- 일부 컬럼 타입이 잘못 보고되었습니다.
  - UNSIGNED와 같은 일부 컬럼 타입 속성이 손실되었습니다.
  - 컬럼 캐릭터셋 및 콜레이션이 손실되었습니다.

  (Bug #30263373)

- **JSON:** 이전에는 [`JSON_SCHEMA_VALID()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/json-validation-functions.html#function_json-schema-valid) 및 [`JSON_SCHEMA_VALIDATION_REPORT()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/json-validation-functions.html#function_json-schema-validation-report) 함수가 이들을 포함하는 prepared statement가 실행될 때마다 해당 인수가 [`JSON`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/json.html)으로 변환 가능한지 확인했으며, 이는 효율적이지도 필요하지도 않았습니다. 이제 이러한 경우에는 statement가 준비될 때 확인이 한 번만 수행됩니다. (Bug #97878, Bug #30622327)
- [`SYSTEM_USER`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/privileges-provided.html#priv_system-user) 권한이 있는 `DEFINER`를 가진 저장 객체에 대해 권한 요구 사항이 잘못 확인되었습니다. (Bug #31077699)
- MySQL 소스에서 생성된 문서에서 Clang이 보고한 여러 오류가 수정되었습니다. (Bug #30956093)
- FreeBSD에서 krb5 패키지가 이제 종속성입니다. (Bug #30887620)

- 쿼리에 동일한 공통 테이블 표현식(CTE)에 대한 여러 참조가 포함되어 있고 pseudo-comment가 CTE 정의의 경계를 가로지르는 경우, 파서가 혼란스러운 문법 오류 메시지와 함께 실패했습니다. (Bug #30871301)
- Debian 패키지를 사용한 설치의 경우, `/var/run/mysqld` 디렉터리가 생성되지 않았습니다. (Bug #30855015, Bug #98484)
- **mysqlslap**은 SQL 문이 오류를 반환할 때 해당 스레드를 올바르게 종료하지 않았습니다. 이로 인해 이미 해제된 메모리를 해제하려는 시도가 발생할 수 있었습니다. (Bug #30850310)
- X Plugin이 중복 키의 경우 삽입 또는 업데이트로 컬렉션에 문서를 추가하려고 할 때, 해당 문서가 기본 키가 아닌 필드에서 유니크 키 제약 조건을 충족하지 못한 경우, X Plugin이 반환한 오류는 이것이 문제의 원인임을 명시하지 않았습니다. 이제 적절한 오류가 반환됩니다. (Bug #30843865)
- 리졸버의 변환에서 생성된 정수 값이 boolean을 예상하는 테스트에 제공되었습니다. (Bug #30837240)
- 큰 문자열 값을 보유한 하나 이상의 컬럼에 접근하는 [`IN`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/comparison-operators.html#operator_in) 표현식을 사용하는 쿼리는 메모리 누수를 일으킬 수 있었습니다. (Bug #30814171)

- [`DELETE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/delete.html)의 대상이 공통 테이블 표현식인 경우 명령문이 제대로 작동하지 않았습니다. (Bug #30796015, Bug #98330)
- [`create_admin_listener_thread`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_create_admin_listener_thread)를 활성화하고 [`admin_address`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/server-system-variables.html#sysvar_admin_address)를 활성화하지 않은 상태로 서버를 시작하면 서버 종료 프로세스 중 비정상 종료가 발생했습니다. (Bug #30785609)
- 테이블에 같은 컬럼에 대한 기본 키와 보조 키가 모두 있었지만 길이가 서로 다른 경우, 범위 optimizer가 범위 값을 비교하기 위해 보조 인덱스에서 잘못된 키 부분을 선택했습니다. (Bug #30783011)
- 일부 경우에는 인수의 타입이 잘못된 집계 함수와 함께 `DISTINCT`를 사용했을 때 발생한 오류가 올바르게 전파되지 않았습니다. (Bug #30782687)
- 압축을 사용하는 복제의 경우, 마스터가 재시작되면 슬레이브에서 assertion이 발생할 수 있었습니다. (Bug #30774692)
- 디버그 빌드의 경우, 서버가 optimizer trace를 출력하려고 시도하는 중 종료될 수 있었습니다. (Bug #30773218, Bug #98258)
- [`mysql_real_connect_nonblocking()`](https://docs.oracle.com/cd/E17952_01/c-api-8.0-en/mysql-real-connect-nonblocking.html) C API 함수가 블로킹 동작을 보였습니다. (Bug #30771233)

- [`LOCK TABLES`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/lock-tables.html)가 활성 상태인 경우, `INFORMATION_SCHEMA` 쿼리를 처리하는 동안 서버가 내부 임시 테이블(잠금이 필요하지 않음)을 잠그려고 시도할 수 있었으며, 이로 인해 assertion이 발생했습니다. (Bug #30764651, Bug #98221)
- **mysqldump** 내부 네트워크 타임아웃이 사용량이 많거나 응답하지 않는 서버에 연결하는 상황을 수용하기 위해 700초에서 86400초로 증가했습니다. (Bug #30755992, Bug #98203)
- `-DWITH_SASL=path/to/custom/installation`로 설정하면 의도치 않게 `libsasl`이 `daemon_memcached` 플러그인에 링크되었습니다. (Bug #30755301)
- 윈도우 함수의 프레임 버퍼와 연결된 임시 테이블을 삭제한 후, 프레임 버퍼의 임시 테이블 매개변수가 정리되지 않아 복사 필드와 연결된 문자열 버퍼가 제대로 해제되지 않았습니다. (Bug #30752366)
- 이제 `-libs-compat` RPM 패키지는 `libmysqlclient.so.18`에서 심볼을 제한 없이 내보내는 문제를 피하기 위해 시스템 `zlib`으로 빌드됩니다. (Bug #30722389, Bug #98130)
- 서버가 histogram sampling을 조기에 종료하여 assertion failure가 발생했습니다. sampling 작업의 완료를 표시하던 불필요한 boolean 변수가 제거되었습니다. (Bug #30717778)

- 참여 조건 중 하나가 항상 false였기 때문에 `WHERE` 조건을 제거할 때, 구체화된 파생 테이블이 올바르게 정리되지 않아 메모리 누수가 발생했습니다. (Bug #30712243)
- 동일한 [`GEOMETRY`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/spatial-type-overview.html) 값에 대한 여러 비교가 항상 올바르게 처리되지는 않았습니다. (Bug #30697042)

  참조: 다음도 참조하십시오: Bug #30306306.
- `IN ()` 서브쿼리를 포함하는 `WHERE` 절이 추가된 경우, 일부 쿼리에 대해 [`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)가 잘못된 값을 반환할 수 있었습니다. (Bug #30691682, Bug #98047)
- 시작 시 MySQL Enterprise Firewall이 활성화되었지만 whitelist 및 user 테이블이 누락된 경우 서버 시작이 실패했습니다. (Bug #30690181)
- prepared statement의 경우, 정리된 구체화된 임시 테이블이 여전히 참조되고 있으면 재실행으로 인해 서버가 종료될 수 있었습니다. (Bug #30674598)

- [`ER_WARN_DEPRECATED_SQL_CALC_FOUND_ROWS`](https://docs.oracle.com/cd/E17952_01/mysql-errors-8.0-en/server-error-reference.html#error_er_warn_deprecated_sql_calc_found_rows) 및 [`ER_WARN_DEPRECATED_FOUND_ROWS`](https://docs.oracle.com/cd/E17952_01/mysql-errors-8.0-en/server-error-reference.html#error_er_warn_deprecated_found_rows) 오류 메시지가 오류 로그에 기록되도록 의도된 메시지 범위로 잘못 분류되었습니다. 이제 이 메시지는 클라이언트로 전송되도록 의도된 메시지로 올바르게 분류됩니다. 이전 오류는 이제 오류 로그 메시지 범위에서 `OBSOLETE_ER_WARN_DEPRECATED_SQL_CALC_FOUND_ROWS` 및 `OBSOLETE_ER_WARN_DEPRECATED_FOUND_ROWS`로 지정됩니다. (Bug #30673043)
- 외부 쿼리가 `EXISTS` 또는 `NOT EXISTS`를 사용하는 일부 서브쿼리 내 조인이 항상 올바르게 처리되지는 않았습니다. (Bug #30671329)
- `ORDER BY constant`를 사용하는 쿼리는 허용되지만, 이러한 종류의 `ORDER BY` 절은 결과에 어떠한 영향도 주지 않아야 합니다. 이러한 쿼리가 항상 올바르게 처리되지는 않았습니다. (Bug #30669493)
- `wild_case_match()`에서 누락된 범위 초과 검사가 포인터가 범위를 벗어나 읽도록 했습니다. (Bug #30668886)
- `strconvert()` 함수는 `filename` 및 `utf8_general_ci` 문자열 간 변환에 대해 안전하지 않았습니다. (Bug #30668847)
- 고정 길이 키를 사용하는 일부 filesort가 항상 올바르게 처리되지는 않았습니다. (Bug #30665034)

- 잠재적으로 매우 큰 두 문자열 컬럼(특히 `PAD SPACE` 콜레이션을 사용하는 [`BLOB`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/blob.html) 컬럼)에 대해 해시 조인을 수행할 때, MySQL은 전체 정렬 키를 로우에 저장했으며, 이로 인해 많은 양의 메모리가 필요해져 성능에 영향을 주었습니다. 이제는 콜레이션을 인식하는 해시만 저장되며, 64비트 해시 충돌이 발생하는 경우에도 잘못된 답을 방지하기 위해 동등성 비교가 추가되었습니다. (Bug #30664831)
- 최소 두 개의 테이블이 세미조인을 사용하여 최소 두 개의 다른 테이블에 조인되고, 조인 Optimizer가 loose scan을 사용하도록 선택한 경우, 왼쪽 테이블 둘 다를 중복 제거 nested loop iterator 아래에 배치할 수 있었으며, 이로 인해 과도한 중복 제거가 발생했습니다. 여러 테이블에 걸친 loose scan을 별도의 내부 구조로 처리하여 이 문제를 수정했습니다. (Bug #30659810)
- [`const`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/explain-output.html#jointype_const) 테이블과 0개 이상의 알려진 0개 로우 표현식의 유니언에서, 정확히 하나의 로우를 가진 파생 테이블이 0개의 로우를 가진 것으로 잘못 읽힐 수 있었습니다. (Bug #30655712, Bug #97967)
- MySQL 8.0.19 패치에서 잘못된 `INFORMATION_SCHEMA` 및 데이터 딕셔너리 버전 번호가 설정되었습니다. 향후 버전 정보 오류를 방지하기 위해 어설션 코드가 추가되었습니다. (Bug #30645158, Bug #97948)

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

- iterator 트리를 설정할 때, Optimizer는 이제 사소하게 참인 것으로 알려진 조건을 필터링하여 제거하고 이후 무시합니다. (Bug #30644591)
- 일부 조건에서 임시 [`MERGE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/merge-storage-engine.html) 테이블에 대해 [`SHOW COLUMNS`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/show-columns.html)를 실행하면 assertion이 발생하거나 서버 종료가 발생할 수 있었습니다. (Bug #30640463)

  참조: 이 문제는 다음의 회귀입니다: Bug #28811287, Bug #92834.
- Event Scheduler에 메모리 누수가 있었습니다. (Bug #30628268)
- 비동기 C API 함수를 사용하면 이미 해제된 메모리를 해제하는 결과가 발생할 수 있었습니다. (Bug #30596999, Bug #97805)
- `CHECK` 제약 조건이 포함된 테이블에서 특정 단순 쿼리는 과도한 메모리 할당 및 Performance Schema 호출로 인해 비효율적이었습니다. (Bug #30594613)
- 특정 상황에서 memcached 명령으로 인해 초기화되지 않은 메모리 버퍼를 읽게 되어 실패가 발생할 수 있었습니다. (Bug #30592346)
- [`INFORMATION_SCHEMA.INNODB_TABLES`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/information-schema-innodb-tables-table.html)를 채우는 동안 `InnoDB`가 스키마 및 테이블 메타데이터 요청을 발행하는 것과 스키마가 삭제되는 것 사이에 race condition이 발생할 수 있었으며, 이로 인해 `INNODB_TABLES`에 대한 사용자 쿼리가 오류를 보고했습니다. (Bug #30591967)

- 클라이언트 라이브러리가 악의적인 서버에 의해 무한 루프에 빠질 수 있었습니다. (Bug #30581726)
- [`ALTER USER`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/alter-user.html)를 사용하여 계정 `MAX_USER_CONNECTIONS` 값을 재설정해도, 현재 계정 연결이 있는 경우 해당 연결이 모두 종료될 때까지 적용되지 않았습니다. (Bug #30578217, Bug #97735)
- Optimizer가 weedout을 설정할 때, weedout의 일부인 모든 테이블에 로우 ID를 제공해야 한다고 알립니다. confluent weedout(최대 하나의 로우를 반환하는 weedout)의 경우 Optimizer는 실행기가 로우 ID 없이 weedout을 처리한다고 예상합니다. iterator 실행기에서는 confluent weedout이 `LIMIT 1`을 사용하여 구현됩니다. 일반 weedout iterator는 confluent weedout을 처리하지 않으므로 항상 로우 ID를 예상합니다. outer join의 오른쪽에서 confluent weedout이 있는 경우, confluent weedout이 일반 weedout으로 처리되어 iterator 실행기가 테이블이 제공하지 않은 로우 ID를 요청하게 했습니다. 이제 이러한 경우에도 `LIMIT 1` 최적화가 적용됩니다. (Bug #30566549, Bug #30282693)
- [`SET PERSIST`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/set-variable.html)는 변수를 잘못된 디렉터리에 지속 저장하려고 시도하여 실패할 수 있었습니다. (Bug #30561982)

- 존재하지 않는 테이블에 액세스하는 오류 조건에 대해 정의된 오류 핸들러가 있는 저장 프로그램 내에서, 해당 테이블이 존재하지 않는 데이터베이스에 이름으로 지정되어 존재하지 않는 경우 핸들러가 호출되지 않았습니다. (Bug #30561920, Bug #97682)
- MySQL에서 사용하는 duplicate weedout 최적화 전략([Semijoin 변환을 사용한 IN 및 EXISTS 서브쿼리 조건자 최적화](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/semijoins.html) 참조)은 이미 확인한 로우 ID의 내부 테이블을 사용하며, 이 ID가 들어 있는 컬럼에 고유 인덱스를 둡니다. 매우 큰 로우 ID에서 발생할 수 있듯이 고유 인덱스의 키가 너무 커지면, 서버는 대신 다른 임시 테이블과 마찬가지로 해시 필드에만 별도의 인덱스(고유하지 않음)를 두고 해시 키에 의한 중복 제거로 되돌아갔습니다. 후자의 인덱스가 올바르게 초기화되지 않았기 때문에 영향을 받는 쿼리가 올바르게 실행되지 않았으며 조기 종료로 이어질 수 있었습니다. (Bug #30556257)
- 디버그 빌드의 경우 [`LOCK TABLES`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/lock-tables.html)에서 서버가 구체화된 임시 테이블을 잘못 처리하고 어설션을 발생시킬 수 있었습니다. (Bug #30476213, Bug #97404)

- 구체화된 쿼리 블록의 내부 배열 `SELECT_LEX_UNIT::m_query_blocks_to_materialize`가 실행 사이에 재설정되지 않았으며, 이는 준비된 명령문이 두 번째로 실행될 때 더 이상 유효하지 않은 객체를 가리켰음을 의미하여 두 번째 실행이 실패하게 했습니다. (Bug #30438038)
- 컬럼 콜레이션을 변경해도 서버를 재시작할 때까지 고유 인덱스에 영향을 주지 않았습니다. (Bug #30386119, Bug #97103)
- 역할을 사용할 때 저장 함수에 대한 [`EXECUTE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/privileges-provided.html#priv_execute) 권한이 저장 프로시저에 대한 권한으로 처리되었습니다. 그 결과 함수에 대한 역할 권한으로 [`EXECUTE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/privileges-provided.html#priv_execute)를 사용할 수 없었습니다. (Bug #30376231)
- 컬럼 값이 비결정적 함수의 입력으로 사용되는 조건을 포함한 구체화된 서브쿼리가 잘못된 결과를 생성했습니다. (Bug #30368937)
- `InnoDB` memcached 플러그인에 여러 수정 사항이 적용되었습니다. 이 수정 사항은 잠재적인 교착 상태 문제, 연결 목록 래치와 관련된 문제, 오래된 flush mutex 제거를 처리했습니다. (Bug #30354225)

- `utf8mb4_0900_bin` 콜레이션을 사용한 문자열을 다른 콜레이션을 사용한 `utf8mb4` 문자열과 비교할 수 없었습니다. 이제 두 문자열 모두에 `utf8mb4_0900_bin`을 사용하여 비교가 수행됩니다. (Bug #30350111)
- 최적화 중에 MySQL은 모든 인수가 같은 것으로 간주되는 조건을 제거합니다. 예를 들어, `1 <> 1`은 제거되고 `false`로 대체됩니다. 이 과정에서 비결정적 인수를 포함하는 조건도 제거되었으며, 이로 인해 [`RAND() < RAND()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/mathematical-functions.html#function_rand)와 같은 조건이 불가능한 조건으로 간주되었습니다. 이제 옵티마이저는 비결정적 인수를 포함하는 조건을 더 이상 제거하지 않습니다. (Bug #30311271)
- 이벤트를 제거하면 이벤트 스케줄링이 방해받을 수 있었습니다. (Bug #30301356, Bug #96849)
- Event Scheduler가 Valgrind 빌드에 대해 경고를 보고했습니다. (Bug #30301340)
- clone 플러그인을 사용하는 동안 서버를 종료하면 Valgrind 오류가 발생했습니다. (Bug #30248419)
- `mysqld-auto.cnf` 파일이 잘못 구성된 경우 서버가 시작되지 않았지만(예상된 동작), 오류를 보고하지 않았습니다(예상치 못한 동작). (Bug #30169731, Bug #96501)

- [`UPDATE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/update.html) 문은 일치한 모든 로우가 업데이트되지 않은 경우, 로우가 업데이트되지 않은 이유에 따라 일치한 로우 수(found rows)가 일관되지 않게 표시될 수 있었습니다. 예를 들어, `WITH CHECK OPTION` 절이 있는 뷰를 통해 업데이트되어 업데이트되지 않은 로우는 일치한 로우로 계산되지 않았지만, 실패한 `CHECK CONSTRAINT` 때문에 업데이트되지 않은 로우는 계산되었습니다. 일관성을 위해, 이제 `WITH CHECK OPTION` 절에 실패한 로우는 일치한 로우로 계산됩니다. (Bug #30158954)
- 복제된 디렉터리에서 MySQL 서버를 재시작할 때, `InnoDB`가 서버에서 이전에 삭제한 통계 테이블의 테이블스페이스 파일을 찾을 수 없음을 나타내는 오류를 보고했습니다. (Bug #30093799)
- 서버가 쿼리 중 하나에 `ORDER BY`를 사용하는 서브쿼리가 포함된 `UNION`을 올바르게 처리하지 못했습니다. (Bug #29952565)
- `INFORMATION_SCHEMA` 쿼리의 경우, 동적 통계 테이블을 업데이트할 때 경쟁 조건으로 인해 키를 삽입하려는 시도가 여러 번 발생하여 중복 키 오류가 생성될 수 있었습니다. (Bug #29948755, Bug #95929)
- [`SHOW CREATE VIEW`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/show-create-view.html)는 문자열을 반환하는 함수에 정의된 뷰에 대해 콜레이션의 잘못된 혼합으로 실패할 수 있었습니다. (Bug #29904087)

- Performance Schema는 스레드가 삭제될 때 스레드 계측을 제거하지 못할 수 있었습니다. (Bug #29859605)
- 술어에 과학적 표기법의 숫자 값이 포함된 `WHERE` 절이 있는 쿼리가 올바르게 처리되지 않았습니다.

  또한 문자열-정수 변환이 성공하지 못했을 때, 문자열로 지정된 특정 정수를 삽입하려고 하면 서버 종료가 발생했습니다. (Bug #29723340, Bug #30441969)
- 도너 MySQL 서버 인스턴스에서 발생하는 오류(`ER_CLONE_DONOR` 오류)를 검색하고 파싱하며, 수신자에서 데이터가 삭제되었는지 확인하기 위한 내부 인터페이스가 추가되었습니다. (Bug #29682642)
- `DEFAULT` 값일 때 테이블에서 어떤 컬럼도 삭제할 수 없었습니다. (Bug #29661106)
- `CONNECTION_CONTROL` 플러그인의 경우, Performance Schema 계측은 관련 코드가 실제로 실행되지 않는 한 Performance Schema에서 발견할 수 없는 키를 사용했습니다. (Bug #29539976)
- nullable 컬럼 `c`의 경우, Optimizer는 이제 조건 `c < c`, `c > c`, `c <> c`가 항상 false이며 모든 로우에 대해 평가할 필요가 없음을 인식합니다. 기여해 주신 Daniel Black에게 감사드립니다. (nonnullable 컬럼의 경우, Optimizer는 이미 항상 false인 조건을 인식했습니다.) (Bug #29115386, Bug #93642)
- `Index.xml`에서 캐릭터셋을 재초기화하면 use-after-free 오류가 발생할 수 있었습니다. (Bug #28956360, Bug #93276)

- `sys` 스키마 [`ps_setup_reset_to_default()`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/sys-ps-setup-reset-to-default.html) 프로시저가 MySQL 8.0 기본값이 아니라 MySQL 5.7 기본값을 사용했습니다. (Bug #27636611)
- 일부 연결 암호화 cipher가 작동하지 않았습니다. (Bug #27045306)
- 이전에는 **mysqlpump**가 옵션 파일에서 `[mysql_dump]` 및 `[client]` 그룹을 읽었습니다. 이제 **mysqlpump**는 추가로 `[mysqlpump]` 그룹을 읽습니다. `[mysql_dump]` 그룹은 여전히 허용되지만 사용 중단되었습니다. (Bug #24733245, Bug #83144)
- [`SELECT DISTINCT... ORDER BY...`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/select.html) 형식의 쿼리에서, `ORDER BY`가 조인의 첫 번째 테이블로 푸시다운되었을 때 결과가 항상 올바른 순서로 정렬되지는 않았습니다. (Bug #98217, Bug #30760534)
- 가변 길이 키로 사용되는 항목에 대해 `NULL` 표시자가 제대로 기록되지 않았기 때문에, 이러한 모든 항목이 `NULL`이 아닌 것으로 간주되었으며, 특정 콜레이션을 사용할 때 이는 빈 문자열과 같은 것으로 간주되었습니다. 이 문제의 가시적인 영향 중 하나는 nullable 문자열을 사용하는 표현식으로 정렬하는 작업이 때때로 올바르게 수행되지 않았다는 점입니다. 컬럼 `c1`에 `NULL` 값과 빈 문자열 값이 모두 포함된 이러한 쿼리의 예는 다음과 같습니다:

  ```
  SELECT c1, SUBSTR(c1, 1) AS c2 FROM t ORDER BY c2;
  ```

  (Bug #98035, Bug #30687020)

- `GROUP BY` 절의 표현식에서, 이 컬럼을 포함하는 테이블이 생성될 때 사용된 컬럼 이름과 대소문자가 다른 컬럼 이름을 사용한 경우 쿼리가 부정확한 결과를 반환했습니다. 이에 대한 예는 원래 `CREATE TABLE` 문에 표시된 컬럼 이름이 `ID`였지만 쿼리에서는 `GROUP BY id`를 사용한 경우입니다.

  이는 서버가 표현식의 컬럼 이름과 테이블의 컬럼 이름을 대소문자를 구분하여 비교했기 때문에 발생했습니다. 이 문제는 이러한 비교가 예상대로 case-insensitive 방식으로 수행되도록 보장하여 수정되었습니다. (Bug #97628, Bug #98222, Bug #30541701, Bug #30761372)
- 두 다른 테이블을 조인하는 파생 테이블에 조인된 테이블을 업데이트하는 다중 테이블 [`UPDATE`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/update.html) 문이 MySQL 5.6에서와 같이 올바르게 최적화되지 않았고, 대신 파생 테이블을 생성하는 서브쿼리에 `STRAIGHT_JOIN`이 사용된 것처럼 처리되었습니다. (Bug #97418, Bug #30488700)
- [`EXPLAIN`](https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/explain.html)은 이제 `block nested loop` 대신 `hash join`을 사용합니다. 후자는 더 이상 존재하지 않으며 거의 모든 경우에서 해시 조인으로 대체되었기 때문입니다. (Bug #97299, Bug #30444550)

- 조인의 `ON` 조건에서 외부 쿼리 블록의 테이블에 있는 컬럼에 대한 참조가 작동하지 않았으며, `WHERE`에서만 사용할 수 있었습니다. 이 문제에 대한 수정으로 인해 이제 다음과 같은 쿼리가 올바르게 작동합니다:

  ```
  SELECT o.order_date FROM orders o 
  WHERE o.order_date IN  ( SELECT c.contact_name FROM customers c     
  INNER JOIN order_details od
  ON o.order_id = od.discount );  
  ```

  이전에는 이를 다음과 같이 다시 작성해야 했습니다:

  ```
  SELECT o.order_date FROM orders o 
  WHERE o.order_date IN  ( SELECT c.contact_name FROM customers c
  INNER JOIN order_details od
  ON 1 
  WHERE o.order_id = od.discount );  
  ```

  쿼리 `SELECT * FROM t1 CROSS JOIN (t2 LEFT JOIN t3 ON t1.c=3)`에서처럼 조인과 동일한 `FROM` 절에 있는 다른 테이블에 대한 참조는 외부 참조가 아니며 계속 금지됩니다. 이 경우에는 다음과 같이 lateral 조인이 필요합니다: `SELECT * FROM t1 JOIN LATERAL (SELECT * FROM t2 LEFT JOIN t3 ON t1.c=3)`. (Bug #96946, Bug #30350696)
- 복합 해시 인덱스의 첫 번째 컬럼을 기준으로 필터링하는 쿼리의 실행 계획이 이 인덱스를 잘못 사용하여 잘못된 결과를 생성했습니다. (Bug #94737, Bug #29527115)

- 외부 쿼리 블록의 테이블에 있는 컬럼을 `JOIN`의 `ON` 조건에서 참조하는 것이 동작하지 않았으며, `WHERE`에서만 사용할 수 있었습니다. 이 문제의 수정으로 다음과 같은 쿼리가 이제 올바르게 동작합니다:

  ```
  SELECT o.order_date FROM orders o
  WHERE o.order_date IN  ( SELECT c.contact_name FROM customers c
                      INNER JOIN order_details od
                      ON o.order_id = od.discount );
  ```

  이전에는 다음에 표시된 것처럼 이를 다시 작성해야 했습니다:

  ```
  SELECT o.order_date FROM orders o
  WHERE o.order_date IN  ( SELECT c.contact_name FROM customers c
                      INNER JOIN order_details od
                      ON 1
                      WHERE o.order_id = od.discount );
  ```

  `SELECT * FROM t1 CROSS JOIN (t2 LEFT JOIN t3 ON t1.c=3)` 쿼리에서처럼 `JOIN`과 동일한 `FROM` 절의 다른 테이블에 대한 참조는 외부 참조가 아니며 계속 금지됩니다. 이 경우에는 다음과 같이 lateral join이 필요합니다: `SELECT * FROM t1 JOIN LATERAL (SELECT * FROM t2 LEFT JOIN t3 ON t1.c=3)`. (Bug #35242, Bug #96946, Bug #11748138, Bug #30350696)

- 서버를 빌드하는 데 사용된 OpenSSL 버전과 라이브러리 또는 플러그인 같은 MySQL의 다른 부분에 사용된 버전이 일치하지 않을 수 있었습니다. 이로 인해 LDAP 인증 플러그인 같은 특정 기능이 동작하지 않을 수 있었습니다. 이제 모든 것을 빌드하는 데 동일한 OpenSSL 버전이 사용됩니다. (WL #13759)
- MySQL 8.0에서 `a=b AND FALSE` 같은 불가능한 표현식을 `FALSE`로 최적화하기 위해 이전에 수행된 작업은, 그러한 표현식이 outer join 조건으로 나타날 때 조인이 필터가 뒤따르는 Cartesian product로 해석된다는 사실 때문에 실행 효율을 낮출 수 있었습니다. (Bug #8202, Bug #89739, Bug #97552, Bug #11745046, Bug #27581277, Bug #30520749)

  참조: 함께 참조하십시오: Bug #98206, Bug #30756135.
